ultimecia

A ps1 emulator in c
Log | Files | Refs

commit 2f2ac84b9e4f9fa88fcf03f24f79e6ab8986b4dc
parent 6d2bfc8228e9b4da317cd4f689a8eb1a82b42e70
Author: edea <none@fithos.xyz>
Date:   Sun,  7 Apr 2024 19:26:20 +0300

stopped at depth ordering tables of the dma

Diffstat:
Msrc/cpu.c | 6++++++
Msrc/defs.h | 2++
Msrc/interconnect.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/main.c | 1+
Msrc/mem.c | 185++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/mem.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mtest.c | 43+++++++++++++++++++++++++++++++------------
7 files changed, 313 insertions(+), 64 deletions(-)

diff --git a/src/cpu.c b/src/cpu.c @@ -124,7 +124,9 @@ op_sw(CPU* cpu, instruction* i) if ((cpu->sr & 0x10000) != 0) { +#ifndef DEBUG printf("ignoring store while cache is isolated!\n"); +#endif return; } @@ -195,7 +197,9 @@ op_sh(CPU* cpu, instruction* i) if ((cpu->sr & 0x10000) != 0) { +#ifndef DEBUG printf("ignoring store while cache is isolated!\n"); +#endif return; } @@ -223,7 +227,9 @@ op_sb(CPU* cpu, instruction* i) if ((cpu->sr & 0x10000) != 0) { +#ifndef DEBUG printf("ignoring store while cache is isolated!\n"); +#endif return; } diff --git a/src/defs.h b/src/defs.h @@ -3,3 +3,5 @@ #define LOG_ERR(x) fprintf(stderr, (x)) #define PANIC(...) do { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } while(0) + +// #define DEBUG 1; diff --git a/src/interconnect.c b/src/interconnect.c @@ -13,7 +13,7 @@ new_interconnect(void) { Interconnect* inter = (Interconnect*)malloc(sizeof(Interconnect)); inter->bios = BIOS_new("roms/scph1001.bin"); inter->ram = RAM_new(); - inter->dma = DMA_new(); + inter->dma = DMA_new(); return inter; } @@ -265,7 +265,7 @@ INTER_store32(Interconnect* inter, u32 addr, u32 val) contains = UTIL_contains(DMA_START, DMA_SIZE, abs_addr, &offset); if (contains) { - INTER_set_dma_reg(inter->dma, offset, val); + INTER_set_dma_reg(inter->dma, offset, val); return; } @@ -312,22 +312,61 @@ INTER_store32(Interconnect* inter, u32 addr, u32 val) u32 INTER_dma_reg(DMA* dma, u32 offset) { - u32 val; - - switch (offset) { - case 0x70: val = DMA_control(dma); break; - default: fprintf(stderr, "unhandled DMA access %08X\n", offset); exit(EXIT_FAILURE); - } + u32 major, minor, val; + major = (offset & 0x70) >> 4; + minor = offset & 0xf; + + switch (major) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: + Channel* channel; + channel = &dma->channels[(Port)major]; + switch (minor) { + case 0: val = CHANNEL_base(channel); break; + case 4: val = CHANNEL_block_control(channel); break; + case 8: val = CHANNEL_control(channel); break; + default: fprintf(stderr, "Unhandled DMA read at %08X\n", offset); exit(EXIT_FAILURE); + } + break; + case 7: + switch (minor) { + case 0: val = DMA_control(dma); break; + case 4: val = DMA_interrupt(dma); break; + default: fprintf(stderr, "unhandled DMA access %08X\n", offset); exit(EXIT_FAILURE); + } + break; + default: fprintf(stderr, "unhandled DMA access %08X\n", offset); exit(EXIT_FAILURE); + } - return val; + return val; } void INTER_set_dma_reg(DMA* dma, u32 offset, u32 val) { - switch(offset) - { - case 0x70: DMA_set_control(dma, offset, val); break; - default: fprintf(stderr, "unhandled DMA write access %08X to address: %08X\n", val, offset); exit(EXIT_FAILURE); - } + u32 major, minor; + major = (offset & 0x70) >> 4; + minor = offset & 0xf; + + switch (major) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: + //printf("MAJOR: %d\n", major); + //printf("MINOR: %d\n", minor); + Channel* channel; + channel = &dma->channels[(Port)major]; + switch (minor) { + case 0: CHANNEL_set_base(channel, val); break; + case 4: CHANNEL_set_block_control(channel, val); break; + case 8: CHANNEL_set_control(channel, val); break; + default: fprintf(stderr, "Unhandled DMA write at %08X\n", offset); exit(EXIT_FAILURE); + } + break; + case 7: + switch (minor) { + case 0: DMA_set_control(dma, val); break; + case 4: DMA_set_interrupt(dma, val); break; + default: fprintf(stderr, "unhandled DMA write %08X\n", offset); exit(EXIT_FAILURE); + } + break; + default: fprintf(stderr, "unhandled DMA write %08X\n", offset); exit(EXIT_FAILURE); + } } diff --git a/src/main.c b/src/main.c @@ -26,6 +26,7 @@ main(int argc, char **argv) free(inter->bios); free(inter->ram->data); free(inter->ram); + free(inter->dma); free(inter); free(cpu); diff --git a/src/mem.c b/src/mem.c @@ -1,60 +1,185 @@ #include <stdlib.h> #include <string.h> +#include <stdio.h> #include "mem.h" #include "types.h" #include "util.h" +Channel* +CHANNEL_new(void) +{ + Channel* ch = (Channel*)malloc(sizeof(Channel)); + ch->enable = 0; + ch->direction = TO_RAM; + ch->step = INCREMENT; + ch->sync = MANUAL; + ch->base = 0; + ch->trigger = 0; + ch->chop = 0; + ch->chop_dma_sz = 0; + ch->chop_cpu_sz = 0; + ch->dummy = 0; + ch->block_size = 0; + ch->block_count = 0; + return ch; +} -DMA* -DMA_new() +u32 +CHANNEL_control(Channel* ch) +{ + u32 r; + r = 0; + + r |= ((u32)ch->direction) << 0; + r |= ((u32)ch->step) << 1; + r |= ((u32)ch->chop) << 8; + r |= ((u32)ch->sync) << 9; + r |= ((u32)ch->chop_dma_sz) << 16; + r |= ((u32)ch->chop_cpu_sz) << 20; + r |= ((u32)ch->enable) << 24; + r |= ((u32)ch->trigger) << 28; + r |= ((u32)ch->dummy) << 29; + + return r; +} + +void +CHANNEL_set_control(Channel* ch, u32 val) +{ + ch->direction = (Direction)(val & 1); + ch->step = (Step)(val >> 1); + ch->chop = (val >> 8) & 1; + ch->sync = (Sync)((val >> 9) & 3); + ch->chop_dma_sz = (u8)((val >> 16) & 7); + ch->chop_cpu_sz = (u8)((val >> 20) & 7); + ch->enable = ((val >> 24) & 1); + ch->trigger = ((val >> 28) & 1); + ch->dummy = (u8)((val >> 29) & 3); +} + +u32 +CHANNEL_base(Channel* ch) +{ + return ch->base; +} + +void +CHANNEL_set_base(Channel* ch, u32 val) +{ + ch->base = val & 0xffffff; +} + +u32 +CHANNEL_block_control(Channel* ch) +{ + u32 bs, bc; + + bs = (u32)ch->block_size; + bc = (u32)ch->block_count; + + return (bc << 16) | bs; +} + +void +CHANNEL_set_block_control(Channel* ch, u32 val) { - DMA* dma = (DMA*)malloc(sizeof(DMA)); + ch->block_size = (u16)val; + ch->block_count = (u16)(val >> 16); +} - dma->control = 0x07654321; - return dma; +DMA* +DMA_new(void) +{ + DMA* dma = (DMA*)malloc(sizeof(DMA)); + dma->control = 0x07654321; + dma->irq_en = 0; + dma->channel_irq_en = 0; + dma->channel_irq_flags = 0; + dma->force_irq = 0; + dma->irq_dummy = 0; + memset(dma->channels, 0, sizeof(Channel)*7); + return dma; } u32 DMA_control(DMA* dma) { - return dma->control; + return dma->control; } void -DMA_set_control(DMA* dma, u32 offset, u32 val) +DMA_set_control(DMA* dma, u32 val) { - dma->control = val; + dma->control = val; +} + +u8 +DMA_irq(DMA* dma) +{ + u32 channel_irq; + channel_irq = dma->channel_irq_flags & dma->channel_irq_en; + return (dma->force_irq || (dma->irq_en && channel_irq != 0)); +} + +u32 +DMA_interrupt(DMA* dma) +{ + u32 r; + r = 0; + + r |= (u32)dma->irq_dummy; + r |= ((u32)dma->force_irq) << 15; + r |= ((u32)dma->channel_irq_en) << 16; + r |= ((u32)dma->irq_en) << 23; + r |= ((u32)dma->channel_irq_flags) << 24; + r |= ((u32)DMA_irq(dma)) << 31; + + return r; +} + +void +DMA_set_interrupt(DMA* dma, u32 val) +{ + u32 ack; + + dma->irq_dummy = (u8)(val & 0x3f); + dma->force_irq = ((val >> 15) & 1) != 0; + dma->channel_irq_en = (u8)((val >> 16) & 0x7f); + dma->irq_en = ((val >> 23) & 1) != 0; + + ack = (u8)((val >> 24) & 0x3f); + dma->channel_irq_flags &= ~ack; } RAM* RAM_new(void) { - RAM* ram = (RAM*)(malloc(sizeof(RAM))); - ram->data = (u8*)(malloc(sizeof(u8) * RAM_SIZE)); + RAM* ram = (RAM*)(malloc(sizeof(RAM))); + ram->data = (u8*)(malloc(sizeof(u8) * RAM_SIZE)); - memset(ram->data, 0xca, RAM_SIZE); - return ram; + memset(ram->data, 0xca, RAM_SIZE); + return ram; } u32 RAM_load32(RAM* r, u32 offset) { - return (r->data[offset + 3] << 24) | - (r->data[offset + 2] << 16) | - (r->data[offset + 1] << 8) | - (r->data[offset + 0]); + return (r->data[offset + 3] << 24) | + (r->data[offset + 2] << 16) | + (r->data[offset + 1] << 8) | + (r->data[offset + 0]); } u16 RAM_load16(RAM* r, u32 offset) { - u16 b0, b1; + u16 b0, b1; - b0 = (u16)r->data[offset]; - b1 = (u16)r->data[offset + 1]; + b0 = (u16)r->data[offset]; + b1 = (u16)r->data[offset + 1]; - return b0 | (b1 << 8); + return b0 | (b1 << 8); } u8 @@ -73,20 +198,20 @@ void RAM_store16(RAM* r, u32 offset, u16 val) { r->data[offset]=val; - r->data[offset+1] = val >> 8; + r->data[offset+1] = val >> 8; } void RAM_store32(RAM* r, u32 offset, u32 val) { - u8 b0 = val; - u8 b1 = (val >> 8); - u8 b2 = (val >> 16); - u8 b3 = (val >> 24); - - r->data[offset + 0] = b0; - r->data[offset + 1] = b1; - r->data[offset + 2] = b2; - r->data[offset + 3] = b3; + u8 b0 = val; + u8 b1 = (val >> 8); + u8 b2 = (val >> 16); + u8 b3 = (val >> 24); + + r->data[offset + 0] = b0; + r->data[offset + 1] = b1; + r->data[offset + 2] = b2; + r->data[offset + 3] = b3; } diff --git a/src/mem.h b/src/mem.h @@ -3,20 +3,77 @@ #include "util.h" #include "types.h" -struct RAM { +typedef enum e_Direction { + TO_RAM, + FROM_RAM +} Direction; + +typedef enum e_Step { + INCREMENT, + DECREMENT, +} Step; + +typedef enum e_Sync { + MANUAL, + REQUEST, + LINKED_LIST +} Sync; + +typedef enum e_Port { + MDEC_IN, + MDEC_OUT, + GPU, + CD_ROM, + SPU, + PIO, + OTC +} Port; + +typedef struct RAM { u8* data; -}; +} RAM; + +typedef struct Channel { + u8 enable; + Direction direction; + Step step; + Sync sync; + u32 base; + u8 trigger; + u8 chop; + u8 chop_dma_sz; + u8 chop_cpu_sz; + u8 dummy; + u16 block_size; + u16 block_count; +} Channel; -struct DMA { +typedef struct DMA { u32 control; -}; + u8 irq_en; + u8 channel_irq_en; + u8 channel_irq_flags; + u8 force_irq; + u8 irq_dummy; + Channel channels[7]; +} DMA; -typedef struct DMA DMA; -typedef struct RAM RAM; -DMA* DMA_new(); +DMA* DMA_new(void); u32 DMA_control(DMA*); -void DMA_set_control(DMA*, u32, u32); +void DMA_set_control(DMA*, u32); +u8 DMA_irq(DMA*); +u32 DMA_interrupt(DMA*); +void DMA_set_interrupt(DMA*, u32); +Channel* DMA_channel(DMA*, Port); + +Channel* CHANNEL_new(void); +u32 CHANNEL_control(Channel*); +void CHANNEL_set_control(Channel*, u32); +u32 CHANNEL_base(Channel*); +void CHANNEL_set_base(Channel*, u32); +u32 CHANNEL_block_control(Channel*); +void CHANNEL_set_block_control(Channel*, u32); RAM* RAM_new(void); u8 RAM_load8(RAM*, u32); diff --git a/test.c b/test.c @@ -10,8 +10,8 @@ struct foo { void bar(struct foo *foo1) { - foo1->pc +=1; - foo1->pc == 1; + //foo1->pc +=1; + //foo1->pc == 1; } typedef struct fyk { @@ -20,22 +20,41 @@ typedef struct fyk { } fyk; int +find_second_bigger(int* lst) +{ + + int arr[] = {1,2,3,4,5,6}; + size_t length; + length = *(&arr + 1) - arr; + printf("Length iS %ZU\n", length); + return 0; +} + +int main() { - fyk f = (fyk){100, NULL}; - fyk f1 = (fyk){1, &f}; - fyk* f2 = (fyk*)malloc(sizeof(fyk)); + //fyk f = (fyk){100, NULL}; + //fyk f1 = (fyk){1, &f}; + //fyk* f2 = (fyk*)malloc(sizeof(fyk)); + + //f2 = {2, &f1}; + + //printf("Hello there F data %d\n", f2->foo->foo->val); + + //struct foo foo1 = { 1,1 }; + //printf("%d", foo1.pc); + //bar(&foo1); + //printf("%d", foo1.pc); - f2 = {2, &f1}; + //1 ? printf("hello there"), printf("what") : 0; - printf("Hello there F data %d\n", f2->foo->foo->val); + uint8_t lst[] = {69,2,3,4,5,6}; + uint8_t a = 8; - struct foo foo1 = { 1,1 }; - printf("%d", foo1.pc); - bar(&foo1); - printf("%d", foo1.pc); + printf("%d\n", *(lst + 2)); + printf("%d\n", &lst); - 1 ? printf("hello there"), printf("what") : 0; + //find_second_bigger(lst); return 0; }