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:
| M | src/cpu.c | | | 6 | ++++++ |
| M | src/defs.h | | | 2 | ++ |
| M | src/interconnect.c | | | 67 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
| M | src/main.c | | | 1 | + |
| M | src/mem.c | | | 185 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
| M | src/mem.h | | | 73 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
| M | test.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;
}