commit 13e7212f82ef681a5044fbb96b805811c713d7e0
parent fa1190dccb02895c82f3b65ea09e28b7a2f2d2d8
Author: edea <none@fithos.xyz>
Date: Sun, 21 Jul 2024 16:43:10 +0300
Got a bit stuck. Because I need to figure out how to typecast my GP0-GP1 functions to a method variable and assign them to the GPU struct as methods. maybe i need to change the declarations of all functions to take only the gpu struct and not needing to take the value as a second parameter.
Diffstat:
8 files changed, 105 insertions(+), 40 deletions(-)
diff --git a/build.sh b/build.sh
@@ -1 +1 @@
-cc -O3 -Wall -Wpedantic -static -Wall -pedantic -g src/*.c -o bin/ultimecia
+cc -std=c89 -O3 -Wall -Wpedantic -static -Wall -pedantic -g src/*.c -o bin/ultimecia
diff --git a/src/defs.h b/src/defs.h
@@ -2,6 +2,6 @@
#define LOG_ERR(x) fprintf(stderr, (x))
-#define PANIC(...) do { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } while(0)
+/* #define PANIC(...) do { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } while(0) */
#define DEBUG 1;
diff --git a/src/gpu.c b/src/gpu.c
@@ -90,8 +90,11 @@ GPU_gp1(GPU* gpu, u32 val)
{
case 0x00: GPU_gp1_reset(gpu, val); break;
case 0x04: GPU_gp1_dma_direction(gpu, val); break;
+ case 0x05: GPU_gp1_display_vram_start(gpu, val); break;
+ case 0x06: GPU_gp1_display_horizontal_range(gpu, val); break;
+ case 0x07: GPU_gp1_display_vertical_range(gpu, val); break;
case 0x08: GPU_gp1_display_mode(gpu, val); break;
- default: fprintf(stderr, "OP: %08X: Unhandled GP1 command %08X\n", opcode, val); exit(1);
+ default: fprintf(stderr, "OP: %08X: Unhandled GP1 command %08X\n", opcode, val); exit(1);
}
}
@@ -109,6 +112,27 @@ GPU_gp1_reset(GPU* gpu, u32 val)
gpu->display_line_end = 0x100;
}
+void
+GPU_gp1_display_horizontal_range(GPU* gpu, u32 val)
+{
+ gpu->display_horiz_start = (u16)(val & 0xfff);
+ gpu->display_horiz_end = (u16)((val >> 12) & 0xfff);
+}
+
+void
+GPU_gp1_display_vertical_range(GPU* gpu, u32 val)
+{
+ gpu->display_line_start = (u16)(val & 0x3ff);
+ gpu->display_line_end = (u16)((val >> 10) & 0x3ff);
+}
+
+void
+GPU_gp1_display_vram_start(GPU* gpu, u32 val)
+{
+ gpu->display_vram_x_start = (u16)(val & 0x3fe);
+ gpu->display_vram_y_start = (u16)((val >> 10) & 0x1ff);
+}
+
void
GPU_gp1_dma_direction(GPU* gpu, u32 val)
{
@@ -142,22 +166,25 @@ GPU_gp1_display_mode(GPU* gpu, u32 val)
void
GPU_gp0(GPU* gpu, u32 val)
{
- u32 opcode;
-
+ u32 opcode, len;
+ void (*method)(GPU*);
+
opcode = (val >> 24) & 0xff;
switch (opcode) {
- case 0x00: break;
+ case 0x00: GPU_gp0_nop(gpu, val); break;
case 0xe1: GPU_gp0_draw_mode(gpu, val); break;
case 0xe2: GPU_gp0_texture_window(gpu, val); break;
case 0xe3: GPU_gp0_drawing_area_top_left(gpu, val); break;
case 0xe4: GPU_gp0_drawing_area_bottom_right(gpu, val); break;
case 0xe5: GPU_gp0_drawing_offset(gpu, val); break;
case 0xe6: GPU_gp0_mask_bit_setting(gpu, val); break;
- default: fprintf(stderr, "OP: %08X: Unhandled GP0 command %08X\n", opcode, val); exit(1);
+ default: fprintf(stderr, "OP: %08X: Unhandled GP0 command %08X\n", opcode, val); exit(1);
}
}
+void GPU_gp0_nop(GPU* gpu, u32 val) {}
+
void
GPU_gp0_draw_mode(GPU* gpu, u32 val)
{
@@ -226,3 +253,26 @@ GPU_gp0_mask_bit_setting(GPU* gpu, u32 val)
gpu->force_set_mask_bit = val & 1;
gpu->preserve_masked_pixels = val & 2;
}
+
+GPU_CMD_BUFFER*
+GPU_CMD_BUFFER_new(void)
+{
+ GPU_CMD_BUFFER* buffer;
+
+ buffer = (GPU_CMD_BUFFER*)malloc(sizeof(GPU_CMD_BUFFER));
+ memset(buffer, 0, sizeof(GPU_CMD_BUFFER));
+
+ return buffer;
+}
+
+void GPU_CMD_BUFFER_clear(GPU_CMD_BUFFER* cmd_buffer) { cmd_buffer->len = 0; }
+
+void
+GPU_CMD_BUFFER_push_word(GPU_CMD_BUFFER* cmd_buffer, u32 word)
+{
+ if (cmd_buffer->len > 12)
+ fprintf(stderr, "OUT OF BOUNDS GPU_CMD_BUFFER"), exit(EXIT_FAILURE);
+
+ cmd_buffer->buffer[cmd_buffer->len] = word;
+ cmd_buffer->len++;
+}
diff --git a/src/gpu.h b/src/gpu.h
@@ -5,12 +5,12 @@
typedef enum _TEXTURE_DEPTH {
TD_T4BIT,
TD_T8BIT,
- TD_T15BIT,
+ TD_T15BIT
} TEXTURE_DEPTH;
typedef enum _FIELD {
F_TOP,
- F_BOTTOM,
+ F_BOTTOM
} FIELD;
typedef enum _DMA_DIRECTION {
@@ -22,14 +22,19 @@ typedef enum _DMA_DIRECTION {
typedef enum _VMODE {
VMODE_NTSC,
- VMODE_PAL,
+ VMODE_PAL
} VMODE;
typedef enum _DISPLAY_DEPTH {
DISP_DEPTH_D15BITS,
- DISP_DEPTH_D24BITS,
+ DISP_DEPTH_D24BITS
} DISPLAY_DEPTH;
+typedef struct _GPU_CMD_BUFFER {
+ u32 buffer[12];
+ u32 len;
+} GPU_CMD_BUFFER;
+
/* line 1045 in no$psx docs */
typedef struct _GPU {
u8 page_base_x;
@@ -71,15 +76,24 @@ typedef struct _GPU {
u16 display_line_start;
u16 display_line_end;
+ GPU_CMD_BUFFER* gp0_command;
+ u32 gp0_command_remaining;
+ void (*gp0_command_method) (struct _GPU*);
+
} GPU;
+/* GPU */
u8 HOR_RES_from_fields(u8, u8);
u32 HOR_RES_into_status(u8);
void GPU_gp1(GPU*, u32);
void GPU_gp1_reset(GPU*, u32); /* GP1(0x00): Reset */
void GPU_gp1_dma_direction(GPU*, u32); /* GP1(0x04): DMA Direction */
void GPU_gp1_display_mode(GPU*, u32); /* GP1(0x08): Display Mode */
+void GPU_gp1_display_vram_start(GPU*, u32); /* GP1(0x05): Display VRAM start */
+void GPU_gp1_display_horizontal_range(GPU*, u32); /* GP1(0x06): Display Horizontal Range */
+void GPU_gp1_display_vertical_range(GPU*, u32); /* GP1(0x07): Display Vertical Range */
void GPU_gp0(GPU*, u32);
+void GPU_gp0_nop(GPU*, u32);
void GPU_gp0_draw_mode(GPU*, u32);
void GPU_gp0_drawing_area_top_left(GPU*, u32); /* GP0(0xe3): Set Drawing Area top left */
void GPU_gp0_drawing_area_bottom_right(GPU*, u32); /* GP0(0xe4): Set Drawing Area bottom right */
@@ -88,3 +102,8 @@ void GPU_gp0_texture_window(GPU*, u32); /* GP0(0xe2): Set Texture Window */
void GPU_gp0_mask_bit_setting(GPU*, u32); /* GP0(0xe6): Set Mask Bit Setting */
GPU* GPU_new(void);
u32 GPU_read(GPU*);
+
+/* GPU's Command Buffer: GPU_CMD_BUFFER */
+GPU_CMD_BUFFER* GPU_CMD_BUFFER_new(void);
+void GPU_CMD_BUFFER_clear(GPU_CMD_BUFFER*);
+void GPU_CMD_BUFFER_push_word(GPU_CMD_BUFFER*, u32);
diff --git a/src/interconnect.c b/src/interconnect.c
@@ -52,7 +52,8 @@ INTER_load8(Interconnect* inter, u32 addr)
return 0;
}
- PANIC("Unhandled Load8 At Address %08X\n", addr);
+ fprintf(stderr, "Unhandled Load8 At Address %08X\n", addr);
+ exit(EXIT_FAILURE);
}
u16
@@ -95,7 +96,8 @@ INTER_load16(Interconnect* inter, u32 addr)
return 0;
}
- PANIC("Unhandled Load16 At Address %08X\n", abs_addr);
+ fprintf(stderr, "Unhandled Load16 At Address %08X\n", abs_addr);
+ exit(EXIT_FAILURE);
}
u32
@@ -161,7 +163,8 @@ INTER_load32(Interconnect* inter, u32 addr)
}
}
- PANIC("Unhandled Load32 At Address %08X\n", addr);
+ fprintf(stderr, "Unhandled Load32 At Address %08X\n", addr);
+ exit(EXIT_FAILURE);
}
void
@@ -191,7 +194,8 @@ INTER_store8(Interconnect* inter, u32 addr, u8 val)
return;
}
- PANIC("Unhandled store8 into abs_address: %08X\n", abs_addr);
+ fprintf(stderr, "Unhandled Store8 At Address %08X\n", abs_addr);
+ exit(EXIT_FAILURE);
}
void
@@ -245,7 +249,8 @@ INTER_store16(Interconnect* inter, u32 addr, u16 val)
return;
}
- PANIC("Unhandled store16 into abs_address: %08X\n", abs_addr);
+ fprintf(stderr, "Unhandled Store16 At Address %08X\n", abs_addr);
+ exit(EXIT_FAILURE);
}
void
@@ -353,7 +358,8 @@ INTER_store32(Interconnect* inter, u32 addr, u32 val)
return;
}
- PANIC("Unhandled store32 into abs_address: %08X\n", addr);
+ fprintf(stderr, "Unhandled Store32 At Address %08X\n", addr);
+ exit(EXIT_FAILURE);
}
u32
@@ -366,10 +372,6 @@ INTER_dma_reg(Interconnect* inter, u32 offset)
switch (major) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6:
- //if ((Port)major < 0) {
- // fprintf(stderr, "WHATTTTTTTTT");
- // exit(1);
- //}
channel = &inter->dma->channels[(Port)major];
switch (minor) {
@@ -424,7 +426,7 @@ INTER_set_dma_reg(Interconnect* inter, u32 offset, u32 val)
switch (minor) {
case 0: DMA_set_control(inter->dma, val); break;
case 4: DMA_set_interrupt(inter->dma, val); break;
- default: active_port = PORT_INVALID; break;// fprintf(stderr, "unhandled DMA write %08X\n", offset); exit(EXIT_FAILURE);
+ default: active_port = PORT_INVALID; break;/* fprintf(stderr, "unhandled DMA write %08X\n", offset); exit(EXIT_FAILURE); */
}
break;
default: fprintf(stderr, "unhandled DMA write %08X\n", offset); exit(EXIT_FAILURE);
@@ -472,8 +474,8 @@ INTER_do_dma_block(Interconnect* inter, Port port)
addr = ch->base;
- // printf("%d\n", port);
- // printf("%08X %08X %d\n", ch->block_size, ch->block_count, (Port)ch->step);
+ /* printf("%d\n", port);
+ / printf("%08X %08X %d\n", ch->block_size, ch->block_count, (Port)ch->step); */
if (!CHANNEL_transfer_size(ch, &remsz)) {
fprintf(stderr, "Couldn't figure out DMA block transfer size\n");
diff --git a/src/mem.c b/src/mem.c
@@ -132,14 +132,7 @@ DMA_new(void)
dma->channel_irq_flags = 0;
dma->force_irq = 0;
dma->irq_dummy = 0;
-
- //for (i = 0; i < 8; i++)
- // dma->channels[i] = *CHANNEL_new();
-
memset(dma->channels, 0, sizeof(Channel)*7);
-
- // printf("%d\n", (Port)dma->channels[1].step);
- // exit(1);
return dma;
}
diff --git a/src/mem.h b/src/mem.h
@@ -10,7 +10,7 @@ typedef enum e_Direction {
typedef enum e_Step {
STEP_INCREMENT,
- STEP_DECREMENT,
+ STEP_DECREMENT
} Step;
typedef enum e_Sync {
@@ -27,7 +27,7 @@ typedef enum e_Port {
PORT_SPU = 4,
PORT_PIO = 5,
PORT_OTC = 6,
- PORT_INVALID = 7,
+ PORT_INVALID = 7
} Port;
typedef struct RAM {
diff --git a/src/util.c b/src/util.c
@@ -3,13 +3,13 @@
#include <limits.h>
const u32 REGION_MASK[8] = {
- // KUSEG: 2048MB
+ /* KUSEG: 2048MB */
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- // KSEG0: 512MB //
+ /* KSEG0: 512MB */
0x7fffffff,
- // KSEG1: 512MB //
+ /* KSEG1: 512MB */
0x1fffffff,
- // KSEG2: 1024MB //
+ /* KSEG2: 1024MB */
0xffffffff, 0xffffffff
};
@@ -33,9 +33,10 @@ checked_addi32(i32 a, i32 b, i32* res)
u8
checked_subi32(i32 a, i32 b, i32* res)
{
- if ((b > 0 && a > INT_MAX - b) || (b < 0 && a < INT_MIN - b) || (b == 0 && a == INT_MIN)) {
- return 0; // Overflow occurred
- }
+ if ((b > 0 && a > INT_MAX - b) || (b < 0 && a < INT_MIN - b) || (b == 0 && a == INT_MIN)) {
+ return 0; /* Overflow occurred */
+ }
+
*res = a - b;
return 1;
}