commit 6c13b12f96500015a1c704d5cd1be23d8ca144d5
parent 56986bc1d6f9bb29f08ff7d27f0a3e93d994ff18
Author: noone <vazkats@gmail.com>
Date: Tue, 27 May 2025 20:53:43 +0300
Skeleton of cdrom (completely incomplete)
I won't mess around with the software renderer anymore
I think it's ok for now
Diffstat:
11 files changed, 207 insertions(+), 36 deletions(-)
diff --git a/makefile b/makefile
@@ -1,5 +1,5 @@
mac:
- cc -g src/*.c -o bin/ultimecia -I/opt/homebrew/include/ -L/opt/homebrew/lib/ -lSDL2
+ cc -g src/*.c -o bin/ultimecia -I/opt/homebrew/include/ -I/opt/homebrew/include/lua5.4 -L/opt/homebrew/lib/ -lSDL2 -llua
bsd:
cc -O0 -g src/*.c -o bin/ultimecia -I/usr/local/include -L/usr/local/lib -lSDL2
win:
diff --git a/src/cdrom.c b/src/cdrom.c
@@ -0,0 +1,53 @@
+/* CDRom Drive */
+#include "cdrom.h"
+#include <stdlib.h>
+#include <string.h>
+
+cdrom*
+cdrom_new()
+{
+ cdrom* cd = (cdrom*)malloc(sizeof(cdrom*));
+ return cd;
+}
+
+u8
+cdrom_fifo_is_empty(fifo fifo)
+{
+ return fifo.write_idx == fifo.read_idx;
+}
+
+u8
+cdrom_fifo_is_full(fifo fifo)
+{
+ return fifo.write_idx == (fifo.read_idx ^ 0x10);
+}
+
+void
+cdrom_store8(cdrom* cd, u32 off, u8 val)
+{
+ off &= 0x3;
+}
+
+void
+cdrom_write(cdrom* cd, u32 offset, u8 val)
+{
+ u32 reg = ((cd->status & STATUS_INDEX_MASK) * 3) + (offset - 1);
+ switch (reg) {
+ case 0:
+ {
+ //DEBUG_LOG("cdrom command register <- 0x{:02X} ({})", value, s_command_info[value].name);
+ cdrom_command(cd, val);
+ return;
+ }
+ default:
+ return;
+ }
+
+ return;
+}
+
+void
+cdrom_command(cdrom* cd, u8 com)
+{
+
+}
diff --git a/src/cdrom.h b/src/cdrom.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include "types.h"
+
+enum {
+ cdrom_raw_sector_size = 2352,
+ cdrom_data_sector_size = 2048,
+ cdrom_sector_sync_size = 12,
+ cdrom_sector_header_size = 4,
+ cdrom_mode1_header_size = 4,
+ cdrom_mode2_header_size = 12,
+ cdrom_mode2_data_sector_size = 2336, // header + edc
+ cdrom_frames_per_second = 75, // "sectors", or "timecode frames" (not "channel frames")
+ cdrom_seconds_per_minute = 60,
+ cdrom_frames_per_minute = cdrom_frames_per_second * cdrom_seconds_per_minute,
+ cdrom_subchannel_bytes_per_frame = 12,
+ cdrom_lead_out_sector_count = 6750,
+ cdrom_all_subcode_size = 96,
+ cdrom_audio_sample_rate = 44100,
+ cdrom_audio_channels = 2,
+};
+
+typedef struct fifo {
+ // Data buffer
+ u8 buffer[16];
+ // Write pointer (4bits + carry)
+ u8 write_idx;
+ // Read pointer (4bits + carry)
+ u8 read_idx;
+} fifo;
+
+
+#define STATUS_INDEX_MASK 0x03
+#define STATUS_ADPBUSY_MASK 0x04
+#define STATUS_PRMEMPT_MASK 0x08
+#define STATUS_PRMWRDY_MASK 0x10
+#define STATUS_RSLRRDY_MASK 0x20
+#define STATUS_DRQSTS_MASK 0x40
+#define STATUS_BUSYSTS_MASK 0x80
+
+typedef struct cdrom {
+ u8 status; /* Status Register */
+ /// Command parameter FIFO
+ fifo host_params;
+ fifo host_response;
+
+ u8 command;
+ u8 irq_flags;
+ u8 irq_mask;
+
+ u8 sb[2340];
+ u32 SB_in;
+} cdrom;
+
+cdrom* cdrom_new();
+
+void cdrom_store8(cdrom*, u32, u8);
+void cdrom_store16(cdrom*, u32, u16);
+void cdrom_store32(cdrom*, u32, u32);
+void cdrom_write(cdrom*, u32, u8);
+void cdrom_load();
+
+void cdrom_load8(cdrom*, u8);
+void cdrom_load16(cdrom*, u16);
+void cdrom_load32(cdrom*, u32);
+
+u8 cdrom_fifo_is_empty(fifo);
+u8 cdrom_fifo_is_full(fifo);
+u8 cdrom_fifo_push();
+
+void cdrom_command(cdrom*, u8);
diff --git a/src/interconnect.c b/src/interconnect.c
@@ -8,6 +8,7 @@
#include "types.h"
#include "defs.h"
#include "gpu.h"
+#include "cdrom.h"
Interconnect*
new_interconnect(void) {
@@ -16,6 +17,7 @@ new_interconnect(void) {
inter->ram = RAM_new();
inter->dma = DMA_new();
inter->gpu = GPU_new();
+ inter->cdrom = cdrom_new();
return inter;
}
@@ -168,7 +170,7 @@ INTER_load32(Interconnect* inter, u32 addr)
exit(EXIT_FAILURE);
}
- void
+void
INTER_store8(Interconnect* inter, u32 addr, u8 val)
{
u32 offset;
@@ -195,6 +197,16 @@ INTER_store8(Interconnect* inter, u32 addr, u8 val)
return;
}
+ contains = UTIL_contains(CDROM_START, CDROM_SIZE, abs_addr, &offset);
+ if (contains)
+ {
+ fprintf(stderr, "GODDAMN! We reached the CDROM register at %08X\n", abs_addr);
+ fprintf(stderr, "And the value is %08X\n", val);
+ cdrom_write(inter->cdrom, offset, val);
+ exit(EXIT_FAILURE);
+ //return;
+ }
+
fprintf(stderr, "Unhandled Store8 At Address %08X\n", abs_addr);
exit(EXIT_FAILURE);
}
@@ -363,7 +375,7 @@ INTER_store32(Interconnect* inter, u32 addr, u32 val)
exit(EXIT_FAILURE);
}
- u32
+u32
INTER_dma_reg(Interconnect* inter, u32 offset)
{
u32 major, minor, val;
diff --git a/src/interconnect.h b/src/interconnect.h
@@ -4,12 +4,14 @@
#include "mem.h"
#include "gpu.h"
#include "types.h"
+#include "cdrom.h"
struct Interconnect {
- BIOS* bios;
- RAM* ram;
- DMA* dma;
- GPU* gpu;
+ BIOS* bios;
+ RAM* ram;
+ DMA* dma;
+ GPU* gpu;
+ cdrom* cdrom;
};
typedef struct Interconnect Interconnect;
diff --git a/src/main.c b/src/main.c
@@ -1,5 +1,8 @@
#include <stdlib.h>
#include <SDL2/SDL.h>
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
#include "cpu.h"
#include "interconnect.h"
@@ -17,6 +20,8 @@ main(int argc, char **argv)
REN *ren;
CPU *cpu;
Interconnect *inter;
+ //lua_State *L = luaL_newstate();
+ //luaL_openlibs(L);
SDL_Init(SDL_INIT_VIDEO);
inter = new_interconnect();
@@ -40,7 +45,7 @@ main(int argc, char **argv)
SDL_Quit();
exit(1);
} else if (ev.key.keysym.sym == SDLK_a) {
- SDL_Log("A pressed");
+ fprintf(stderr, "The data %d\n;", inter->cdrom->host_params.buffer[0]);
break;
}
}
@@ -53,9 +58,12 @@ main(int argc, char **argv)
free(inter->ram);
free(inter->dma);
free(inter->gpu);
+ free(inter->cdrom);
free(inter);
free(cpu);
+ //lua_close(L);
+
SDL_Quit();
return 0;
diff --git a/src/sr.c b/src/sr.c
@@ -106,20 +106,20 @@ C_new(u32 b)
return c;
};
-void REN_FB_set(REN* ren, i32 x, i32 y, C c) {
+void REN_FB_set(REN* ren, i32 x, i32 y, u8 r, u8 g, u8 b) {
u32 *fb;
if (!ren->fb || x < 0 || y < 0 || x >= W || y >= H) return;
-
+
// Clamp color values
- c.r = c.r > 255 ? 255 : c.r;
- c.g = c.g > 255 ? 255 : c.g;
- c.b = c.b > 255 ? 255 : c.b;
-
+ r = r > 255 ? 255 : r;
+ g = g > 255 ? 255 : g;
+ b = b > 255 ? 255 : b;
+
// Direct write instead of memcpy
fb = ren->fb + (x + y * W);
- *fb = (c.r) | (c.g << 8) | (c.b << 16);
+ *fb = r | (g << 8) | (b << 16);
}
//C*
@@ -146,7 +146,7 @@ REN_new()
}
// Draw a scanline with color interpolation
-void
+void
draw_scanline(REN* ren, int y, int x1, C c1, int x2, C c2)
{
if (x1 > x2) {
@@ -163,13 +163,13 @@ draw_scanline(REN* ren, int y, int x1, C c1, int x2, C c2)
float r = c1.r, g = c1.g, b = c1.b;
for (int x = x1; x <= x2; x++) {
- REN_FB_set(ren, x, y, (C){r,g,b});
+ REN_FB_set(ren, x, y, (u8)r,(u8)g,(u8)b);
r += dr; g += dg; b += db;
}
}
// Rasterize triangle with color interpolation
-void
+void
REN_triangle(REN* ren, ivec2 verts[3], C colors[3])
{
// Check for degenerate triangles
@@ -201,12 +201,14 @@ REN_triangle(REN* ren, ivec2 verts[3], C colors[3])
i32 db12 = ((colors[2].b - colors[1].b) << 16) / (verts[2].y - verts[1].y + 1);
// Rasterize top part
- i32 xL = verts[0].x << 16, rL = colors[0].r << 16, gL = colors[0].g << 16, bL = colors[0].b << 16;
- i32 xR = verts[0].x << 16, rR = colors[0].r << 16, gR = colors[0].g << 16, bR = colors[0].b << 16;
+ i32 xL = verts[0].x << 16;
+ u32 rL = colors[0].r << 16, gL = colors[0].g << 16, bL = colors[0].b << 16;
+ i32 xR = verts[0].x << 16;
+ u32 rR = colors[0].r << 16, gR = colors[0].g << 16, bR = colors[0].b << 16;
for (i32 y = verts[0].y; y < verts[1].y; y++) {
- draw_scanline(ren, y, xL >> 16, (C){rL >> 16, gL >> 16, bL >> 16},
- xR >> 16, (C){rR >> 16, gR >> 16, bR >> 16});
+ draw_scanline(ren, y, xL >> 16, (C){(u8)(rL >> 16), (u8)(gL >> 16), (u8)(bL >> 16)},
+ xR >> 16, (C){(u8)(rR >> 16), (u8)(gR >> 16), (u8)(bR >> 16)});
xL += dx01; rL += dr01; gL += dg01; bL += db01;
xR += dx02; rR += dr02; gR += dg02; bR += db02;
}
@@ -214,8 +216,8 @@ REN_triangle(REN* ren, ivec2 verts[3], C colors[3])
// Rasterize bottom part
xL = verts[1].x << 16, rL = colors[1].r << 16, gL = colors[1].g << 16, bL = colors[1].b << 16;
for (i32 y = verts[1].y; y < verts[2].y; y++) {
- draw_scanline(ren, y, xL >> 16, (C){rL >> 16, gL >> 16, bL >> 16},
- xR >> 16, (C){rR >> 16, gR >> 16, bR >> 16});
+ draw_scanline(ren, y, xL >> 16, (C){(u8)(rL >> 16), (u8)(gL >> 16), (u8)(bL >> 16)},
+ xR >> 16, (C){(u8)(rR >> 16), (u8)(gR >> 16), (u8)(bR >> 16)});
xL += dx12; rL += dr12; gL += dg12; bL += db12;
xR += dx02; rR += dr02; gR += dg02; bR += db02;
}
@@ -255,7 +257,7 @@ REN_push_quad(REN* ren, ivec2 verts[4], C colors[4])
}
}
-void
+void
REN_flush(REN* ren) {
u32 i;
for (i = 0; i < ren->nvertices; i += 3)
@@ -277,7 +279,7 @@ REN_display(REN* ren)
if (ren->nvertices > 0) {
REN_flush(ren);
}
-
+
REN_draw(ren);
SDL_RenderPresent(ren->renderer);
}
diff --git a/src/sr.h b/src/sr.h
@@ -6,8 +6,8 @@
#define W 640
#define H 480
-#define WIN_W 1280
-#define WIN_H 960
+#define WIN_W 640
+#define WIN_H 480
#define VERTEX_BUFFER_LEN 64*1024
#define VEC2I_SWAP(x, y) { ivec2 temp = x; x = y; y = temp; }
diff --git a/src/tags b/src/tags
@@ -2,8 +2,15 @@ BIOS bios.h /^struct BIOS {$/
BIOS_load32 bios.c /^BIOS_load32(BIOS* b, u32 offset)$/
BIOS_load8 bios.c /^u8 BIOS_load8(BIOS* b, u32 offset) { return b->dat/
BIOS_new bios.c /^BIOS_new(const char* path)$/
-Bool tags /^Bool types.h \/^typedef uint8_t Bool;$\/$/
+Bool tags /^Bool tags \/^Bool types.h \\\/^typedef uint8_t Bo/
C sr.h /^typedef struct {u8 b;u8 g;u8 r;} C;$/
+CDROM cdrom.h /^}CDROM;$/
+CDROM_Fifo cdrom.h /^} CDROM_Fifo;$/
+CDROM_Fifo_is_empty cdrom.c /^CDROM_Fifo_is_empty(CDROM_Fifo fifo)$/
+CDROM_Fifo_is_full cdrom.c /^CDROM_Fifo_is_full(CDROM_Fifo fifo)$/
+CDROM_new cdrom.c /^CDROM_new()$/
+CDROM_store8 cdrom.c /^CDROM_store8(CDROM* cd, u32 off, u8 val)$/
+CDROM_write cdrom.c /^void CDROM_write(u32 offset, u8 val)$/
CHANNEL_active mem.c /^CHANNEL_active(Channel* ch)$/
CHANNEL_base mem.c /^CHANNEL_base(Channel* ch)$/
CHANNEL_block_control mem.c /^CHANNEL_block_control(Channel* ch)$/
@@ -43,16 +50,17 @@ FIELD gpu.h /^} FIELD;$/
GP0_MODE gpu.h /^} GP0_MODE;$/
GPU gpu.h /^} GPU;$/
GPU_CMD_BUFFER gpu.h /^} GPU_CMD_BUFFER;$/
-GPU_CMD_BUFFER_clear gpu.c /^GPU_CMD_BUFFER_clear(GPU_CMD_BUFFER* cmd_buffer) $/
+GPU_CMD_BUFFER_clear gpu.c /^GPU_CMD_BUFFER_clear(GPU_CMD_BUFFER* cmd_buffer)$/
GPU_CMD_BUFFER_new gpu.c /^GPU_CMD_BUFFER_new(void)$/
GPU_CMD_BUFFER_push_word gpu.c /^GPU_CMD_BUFFER_push_word(GPU_CMD_BUFFER* cmd_buffe/
+GPU_LOG defs.h /^#define GPU_LOG(fmt, ...) \\$/
GPU_gp0 gpu.c /^GPU_gp0(GPU* gpu, u32 val)$/
GPU_gp0_clear_cache gpu.c /^void GPU_gp0_clear_cache(GPU* gpu) { \/* Not imple/
GPU_gp0_draw_mode gpu.c /^GPU_gp0_draw_mode(GPU* gpu)$/
GPU_gp0_drawing_area_bottom_right gpu.c /^GPU_gp0_drawing_area_bottom_right(GPU* gpu)$/
GPU_gp0_drawing_area_top_left gpu.c /^GPU_gp0_drawing_area_top_left(GPU* gpu)$/
GPU_gp0_drawing_offset gpu.c /^GPU_gp0_drawing_offset(GPU* gpu)$/
-GPU_gp0_image_load gpu.c /^GPU_gp0_image_load(GPU* gpu) $/
+GPU_gp0_image_load gpu.c /^GPU_gp0_image_load(GPU* gpu)$/
GPU_gp0_image_store gpu.c /^GPU_gp0_image_store(GPU* gpu)$/
GPU_gp0_mask_bit_setting gpu.c /^GPU_gp0_mask_bit_setting(GPU* gpu)$/
GPU_gp0_nop gpu.c /^void GPU_gp0_nop(GPU* gpu) {}$/
@@ -106,13 +114,14 @@ RAM_store16 mem.c /^RAM_store16(RAM* r, u32 offset, u16 val)$/
RAM_store32 mem.c /^RAM_store32(RAM* r, u32 offset, u32 val)$/
RAM_store8 mem.c /^RAM_store8(RAM* r, u32 offset, u8 val)$/
REN sr.h /^} REN;$/
-REN_FB_set sr.c /^void REN_FB_set(REN* ren, i32 x, i32 y, C c) { (!r/
+REN_FB_set sr.c /^void REN_FB_set(REN* ren, i32 x, i32 y, u8 r, u8 g/
REN_display sr.c /^REN_display(REN* ren)$/
REN_draw sr.c /^REN_draw(REN* ren)$/
+REN_flush sr.c /^REN_flush(REN* ren) {$/
REN_new sr.c /^REN_new()$/
REN_push_quad sr.c /^REN_push_quad(REN* ren, ivec2 verts[4], C colors[4/
REN_push_triangle sr.c /^REN_push_triangle(REN* ren, ivec2 verts[3], C colo/
-REN_triangle sr.c /^void REN_triangle(REN* ren, ivec2 verts[3], C colo/
+REN_triangle sr.c /^REN_triangle(REN* ren, ivec2 verts[3], C colors[3]/
SHADERS_gradient_shader shaders.c /^SHADERS_gradient_shader(float alpha, float beta, f/
Step mem.h /^} Step;$/
Sync mem.h /^} Sync;$/
@@ -123,6 +132,7 @@ VMODE gpu.h /^} VMODE;$/
branch cpu.c /^branch(CPU* cpu, u32 offset)$/
checked_addi32 util.c /^checked_addi32(i32 a, i32 b, i32* res)$/
checked_subi32 util.c /^checked_subi32(i32 a, i32 b, i32* res)$/
+draw_scanline sr.c /^draw_scanline(REN* ren, int y, int x1, C c1, int x/
exception cpu.c /^exception(CPU* cpu, EXCEPTION cause)$/
i16 types.h /^typedef int16_t i16;$/
i32 types.h /^typedef int32_t i32;$/
@@ -209,6 +219,9 @@ op_xori cpu.c /^op_xori(CPU* cpu, instruction* i)$/
point sr.h /^typedef struct { double x, y, z; } point;$/
reg cpu.c /^u32 reg(CPU* cpu, u32 reg) { return cpu->out_regs[/
set_reg cpu.c /^void set_reg(CPU* cpu, u32 reg, u32 val) { cpu->ou/
+swap_color util.c /^swap_color(C *a, C *b) { C temp = *a; *a = *b; *b /
+swap_int util.c /^swap_int(int *a, int *b) { int temp = *a; *a = *b;/
+swap_vec2 util.c /^swap_vec2(ivec2 *a, ivec2 *b) { ivec2 temp = *a; */
u16 types.h /^typedef uint16_t u16;$/
u32 types.h /^typedef uint32_t u32;$/
u64 types.h /^typedef uint64_t u64;$/
diff --git a/src/util.h b/src/util.h
@@ -39,6 +39,9 @@
#define GPU_START 0x1F801810
#define GPU_SIZE 8
+#define CDROM_START 0x1F801800
+#define CDROM_SIZE 12
+
u32 UTIL_contains(u32, u32, u32, u32*);
u8 checked_addi32(i32, i32, i32*);
u8 checked_subi32(i32, i32, i32*);
diff --git a/test.cc b/test.cc
@@ -2,7 +2,12 @@
#include <stdint.h>
#include <stdlib.h>
-namespace FOO
+
+enum HEY {
+ DAFAQ = 0x1
+}
+
+namespace FOO
{
typedef struct fyk {
@@ -39,7 +44,7 @@ main()
/* Thought i would try ternary but I am not sure if this actually works */
int val = 800;
- int test = (val >> 7 & 3) ? 0 ? 100 ? 1 ? 200 ? 2 ? 300 : 0 : 0 : 0 : 0 : 0 : 0;
+ int test = (val >> 7 & 3) ? 0 ? 100 ? 1 ? 200 ? 2 ? 300 : 0 : 0 : 0 : 0 : 0 : 0;
printf("\n%d\n", test);
@@ -47,5 +52,7 @@ main()
FOO::ho x = FOO::ONE;
return 0;
-}
+
+ HEY a = HEY.DAFUQ;
+}