From 329ada55f1a0b4e55078bd178dcbe845d414f9c0 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 16 Oct 2023 19:24:51 +0000 Subject: [PATCH] add code loading and test program This was used to troubleshoot video output and framebuffer configuration registers. --- .gitignore | 3 +- alt.lds | 71 ++++++ client.py | 68 ++++++ common.mk | 7 +- load.c | 127 +++++++++++ load.h | 4 + main.c | 262 +++------------------- regs/gen/systembus.py | 11 + regs/systembus.csv | 182 +++++++-------- regs/systembus.ods | Bin 21064 -> 21478 bytes rgb.c | 32 +++ rgb.h | 15 ++ systembus.h | 506 +++++++++++++++++++++--------------------- test.c | 147 ++++++++++++ vga.c | 193 ++++++++++++++++ vga.h | 5 + 16 files changed, 1063 insertions(+), 570 deletions(-) create mode 100644 alt.lds create mode 100644 client.py create mode 100644 load.c create mode 100644 load.h create mode 100644 rgb.c create mode 100644 rgb.h create mode 100644 test.c create mode 100644 vga.c create mode 100644 vga.h diff --git a/.gitignore b/.gitignore index 762b381..a610673 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,6 @@ __pycache__ *.iso *.cdi *.o +*.out scramble -cdi4dc \ No newline at end of file +cdi4dc diff --git a/alt.lds b/alt.lds new file mode 100644 index 0000000..db089da --- /dev/null +++ b/alt.lds @@ -0,0 +1,71 @@ +OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl") +MEMORY +{ + p1ram : ORIGIN = 0xac020000, LENGTH = 16M +} +SECTIONS +{ + . = 0xac020000; + + .text ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.text.start)) + *(.text.startup.*) + *(.text.*) + *(.text) + } > p1ram + + .data ALIGN(4) : SUBALIGN(4) + { + *(.data) + *(.data.*) + } > p1ram + + .rodata ALIGN(4) : SUBALIGN(4) + { + *(.rodata) + *(.rodata.*) + } > p1ram + + .ctors ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.ctors)) + KEEP(*(.ctors.*)) + } > p1ram + + .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) + { + *(.bss) + *(.bss.*) + } > p1ram + + __p1ram_end = .; + + /DISCARD/ : + { + *(.debug*) + *(.comment*) + *(.rela*) + } + + __bss_link_start = ADDR(.bss); + __bss_link_end = ADDR(.bss) + SIZEOF(.bss); + + __ctors_link_start = ADDR(.ctors); + __ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); +} + +__p1ram_start = ORIGIN(p1ram); +__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram); + +SH7091_IC_A = 0xf0000000; +SH7091_IC_D = 0xf1000000; +SH7091_OC_A = 0xf4000000; +SH7091_OC_D = 0xf5000000; +SH7091 = 0xff000000; +HOLLY = 0xa05f8000; +SYSTEM = 0xa05F6800; +MAPLE_IF = 0xa05F6C00; +G1_IF = 0xa05F7400; +G2_IF = 0xa05F7800; +PVR_IF = 0xa05F7C00; diff --git a/client.py b/client.py new file mode 100644 index 0000000..c88a1aa --- /dev/null +++ b/client.py @@ -0,0 +1,68 @@ +import serial +import struct +import sys +import time + +dest = 0xac02_0000 + +ret = [] + +def sync(ser, b): + l = [] + for i, c in enumerate(b): + if i % 32 == 0: + print(i, end=' ') + sys.stdout.flush() + ser.write(bytes([c])) + ser.flush() + ser.flushInput() + ser.flushOutput() + time.sleep(0.01) + while ser.in_waiting > 0: + res = ser.read(ser.in_waiting) + for c in res: + l.append(c) + time.sleep(0.01) + + time.sleep(1) + res = ser.read(ser.in_waiting) + for c in res: + l.append(c) + + return bytes(l) + +def do(ser, b): + ser.flush() + ser.flushInput() + ser.flushOutput() + + ret = sync(ser, b'DATA') + print(ret) + size = len(b) + args = struct.pack(" + +#include "sh7091.h" +#include "holly.h" + +enum load_command { + CMD_NONE, + CMD_DATA, // DATA 0000 0000 {data} + CMD_JUMP, // JUMP 0000 +}; + +struct load_state { + union { + uint8_t buf[12]; + struct { + uint8_t cmd[4]; + uint32_t addr1; + uint32_t addr2; + }; + }; + uint32_t len; + enum load_command command; +}; + +static struct load_state state; + +void move(void *dest, const void *src, size_t n) +{ + uint8_t *d = dest; + const uint8_t *s = src; + + if (d==s) return; + if (d= 4) { + if (state.buf[0] == 'D' && + state.buf[1] == 'A' && + state.buf[2] == 'T' && + state.buf[3] == 'A') { + if (state.len < 12) { + return; + } else { + debug("data\n"); + state.command = CMD_DATA; + return; + } + } else if (state.buf[0] == 'J' && + state.buf[1] == 'U' && + state.buf[2] == 'M' && + state.buf[3] == 'P') { + if (state.len < 8) { + return; + } else { + debug("jump\n"); + state.command = CMD_JUMP; + } + } else { + move(&state.buf[0], &state.buf[4], state.len - 4); + state.len -= 4; + } + } else { + return; + } + break; + case CMD_DATA: + { + uint32_t * size = &state.addr1; + uint8_t * dest = (uint8_t *)state.addr2; + if (size > 0) { + SH7091.SCIF.SCFTDR2 = c; + + // write c to dest + *dest = c; + state.addr2++; + + (*size)--; + } + if (*size == 0) { + state.len = 0; + state.command = CMD_NONE; + debug("next\n"); + } + return; + break; + case CMD_JUMP: + // jump + state.len = 0; + state.command = CMD_NONE; + debug("prejump\n"); + HOLLY.VO_BORDER_COL = (31 << 11); + void (*fptr)(void) = (void (*)(void))state.addr1; + HOLLY.VO_BORDER_COL = (63 << 5) | (31 << 0); + fptr(); + debug("postjump\n"); + return; + break; + } + } + } +} diff --git a/load.h b/load.h new file mode 100644 index 0000000..9ed6ce7 --- /dev/null +++ b/load.h @@ -0,0 +1,4 @@ +#pragma once + +void load_init(); +void load_recv(uint8_t c); diff --git a/main.c b/main.c index 9b6783a..ec6aef2 100644 --- a/main.c +++ b/main.c @@ -1,262 +1,66 @@ #include #include "cache.h" +#include "load.h" #include "sh7091.h" #include "sh7091_bits.h" -#include "holly.h" - -volatile uint32_t * RAM = (volatile uint32_t *)0xa5000000; - -volatile uint32_t * SPG_STATUS = (volatile uint32_t *)0xa05f810; - -uint32_t get_cable_type() -{ - /* set all pins to input */ - SH7091.BSC.PCTRA = 0; - - /* get cable type from pins 9 + 8 */ - return SH7091.BSC.PDTRA & PDTRA__MASK; -} - -void vga1() -{ - uint16_t pclk_delay = 0x0016; - uint32_t fb_r_ctrl = HOLLY.FB_R_CTRL; - HOLLY.FB_R_CTRL = fb_r_ctrl & ~(1 << 0); // fb_enable = 0 - HOLLY.VO_CONTROL = pclk_delay << 16 | (1 << 3); // blank_video - HOLLY.FB_R_CTRL = fb_r_ctrl & (1<<23); // vclk_div, for VGA - - HOLLY.FB_R_SIZE = 0; - - uint16_t vblank_in = 0x0208; - uint16_t vblank_out = 0x0015; - HOLLY.SPG_VBLANK_INT = (vblank_out << 16) | (vblank_in << 0); - - HOLLY.SPG_CONTROL = (1 << 8); // sync_direction__output ; non-default - - uint16_t hbstart = 0x0345; // default - uint16_t hbend = 0x007e; // default - HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0); - - uint16_t hcount = 0x0359; // default - uint16_t vcount = 0x020c; // non-default - HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0); - - uint16_t vbstart = 0x0208; // non-default - uint16_t vbend = 0x0028; // non-default - HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0); - - uint16_t hswidth = 0x003f; - uint16_t vswidth = 0x0003; - uint16_t bpwidth = 0x0319; - uint16_t eqwidth = 0x000f; - HOLLY.SPG_WIDTH = - (hswidth << 0) - | (vswidth << 8) - | (bpwidth << 12) - | (eqwidth << 22); - - uint16_t startx = 0x0a8; - uint16_t starty = 0x028; - HOLLY.VO_STARTX = startx; - HOLLY.VO_STARTY = (starty << 16) | (starty << 0); - - HOLLY.SPG_HBLANK_INT = hbstart << 16; -} - -void vga2() -{ - uint16_t xsize = 640; - uint16_t ysize = 480; - - uint16_t fb_xclip_min = 0; - uint16_t fb_xclip_max = xsize-1; - HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0); - uint16_t fb_yclip_min = 0; - uint16_t fb_yclip_max = ysize-1; - HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0); - - uint16_t fb_latency = 0x09; - uint16_t fb_burstctrl = 15 - fb_latency; - uint16_t wr_burst = 0x08; - HOLLY.FB_BURSTCTRL = 0 - | (fb_burstctrl << 0) - | (fb_latency << 4) - | (wr_burst << 9) - ; - - uint32_t fb_xsize = (xsize * 16)/(32) - 1; - uint32_t fb_ysize = ysize - 3; - uint32_t fb_mod = 1; - HOLLY.FB_R_SIZE = 0 - | (fb_xsize << 0) - | (fb_ysize << 10) - | (fb_mod << 20); - - uint16_t coeff0 = 0x40; - uint16_t coeff1 = 0x80; - HOLLY.Y_COEFF = (coeff1 << 8) | (coeff0 << 0); - - uint16_t vscale_factor = 0x0400; - HOLLY.SCALER_CTL = (vscale_factor << 0); - - uint32_t fb_linestride = (xsize * 16) / 64; - HOLLY.FB_W_LINESTRIDE = fb_linestride; - - HOLLY.FB_W_CTRL = 0 - | 0b001 << 0 // fb_packmode: RGB 565 - ; - - HOLLY.FB_W_SOF1 = 0; - HOLLY.FB_W_SOF2 = 0; - HOLLY.FB_R_SOF1 = 0; - HOLLY.FB_R_SOF2 = 0; - - HOLLY.FB_R_CTRL = 0 - | 1 << 23 // vclk_div - | 0 << 22 // fb_strip_buf_en - | 0 << 16 // fb_strip_size - | 0 << 8 // fb_chroma_threshold - | 0 << 4 // fb_concat - | 1 << 2 // fb_depth - | 0 << 1 // fb_line_double - | 1 << 0 // fb_enable - ; - - *((reg32 *)0xa0702c00) = 0; -} - -void v_sync_in() -{ -#define V_SYNC (1<<13) - while (!(V_SYNC & HOLLY.SPG_STATUS)) { - asm volatile ("nop"); - } - while ((V_SYNC & HOLLY.SPG_STATUS)) { - asm volatile ("nop"); - } -#undef V_SYNC -} - -void vga() -{ - get_cable_type(); - - HOLLY.SOFTRESET = 0; - HOLLY.TEXT_CONTROL = 3; - HOLLY.FB_W_CTRL = 9; - - SH7091.SCIF.SCFTDR2 = 'g'; - /* - */ - SH7091.SCIF.SCFTDR2 = 'v'; - vga1(); - vga2(); - - v_sync_in(); - - HOLLY.VO_BORDER_COL = 31; - HOLLY.VO_CONTROL = 0x0016; -} extern uint32_t __bss_link_start __asm("__bss_link_start"); extern uint32_t __bss_link_end __asm("__bss_link_end"); -struct rgb +void serial() { - unsigned char r; - unsigned char g; - unsigned char b; -}; + SH7091.SCIF.SCSCR2 = 0; + SH7091.SCIF.SCSMR2 = 0; + SH7091.SCIF.SCBRR2 = 12; -struct hsv -{ - unsigned char h; - unsigned char s; - unsigned char v; -}; +#define SCFCR2__TFRST (1 << 2) +#define SCFCR2__RFRST (1 << 1) + SH7091.SCIF.SCFCR2 = SCFCR2__TFRST | SCFCR2__RFRST; + // tx/rx trigger on 1 byte + SH7091.SCIF.SCFCR2 = 0; -struct rgb hsv_to_rgb(struct hsv hsv) -{ - struct rgb rgb; - unsigned char region, remainder, p, q, t; + SH7091.SCIF.SCSPTR2 = 0; + SH7091.SCIF.SCLSR2 = 0; - if (hsv.s == 0) { - rgb.r = hsv.v; - rgb.g = hsv.v; - rgb.b = hsv.v; - return rgb; - } - - region = hsv.h / 43; - remainder = (hsv.h - (region * 43)) * 6; - - p = (hsv.v * (255 - hsv.s)) >> 8; - q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8; - t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8; - - switch (region) { - case 0: rgb.r = hsv.v; rgb.g = t; rgb.b = p; break; - case 1: rgb.r = q; rgb.g = hsv.v; rgb.b = p; break; - case 2: rgb.r = p; rgb.g = hsv.v; rgb.b = t; break; - case 3: rgb.r = p; rgb.g = q; rgb.b = hsv.v; break; - case 4: rgb.r = t; rgb.g = p; rgb.b = hsv.v; break; - default: rgb.r = hsv.v; rgb.g = p; rgb.b = q; break; - } - - return rgb; +#define SCSCR2__TE (1 << 5) +#define SCSCR2__RE (1 << 4) + SH7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE; } void main() { cache_init(); + // clear BSS uint32_t * start = &__bss_link_start; uint32_t * end = &__bss_link_end; while (start < end) { *start++ = 0; } - // clear BSS + serial(); -#define SCSCR2__TE (1 << 5) -#define SCSCR2__RE (1 << 4) - SH7091.SCIF.SCSCR2 = 0; - SH7091.SCIF.SCSMR2 = 0; - SH7091.SCIF.SCBRR2 = 12; - - SH7091.SCIF.SCFCR2 = (1 << 2) | (1 << 1); // tfrst rfrst - SH7091.SCIF.SCFCR2 = 0; - - SH7091.SCIF.SCSPTR2 = 0; - SH7091.SCIF.SCLSR2 = 0; - - SH7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE; - - SH7091.SCIF.SCFTDR2 = 'H'; - SH7091.SCIF.SCFTDR2 = 'e'; - SH7091.SCIF.SCFTDR2 = 'l'; - SH7091.SCIF.SCFTDR2 = 'o'; - - vga(); + load_init(); while (1) { - v_sync_in(); - SH7091.SCIF.SCFTDR2 = 'v'; - SH7091.SCIF.SCFTDR2 = 'g'; - SH7091.SCIF.SCFTDR2 = 'a'; +#define SCFSR2__ER (1 << 7) /* read error */ +#define SCFSR2__TEND (1 << 6) /* transmit end */ +#define SCFSR2__TFDE (1 << 5) /* transmit fifo data empty */ +#define SCFSR2__BRK (1 << 4) /* break detect */ +#define SCFSR2__FER (1 << 3) /* framing error */ +#define SCFSR2__PER (1 << 2) /* parity error */ +#define SCFSR2__RDF (1 << 1) /* receive FIFO data full */ +#define SCFSR2__DR (1 << 0) /* receive data ready */ - reg16 * vram = (reg16 *)0xa5000000; - for (int y = 0; y < 480; y++) { - for (int x = 0; x < 640; x++) { - struct hsv hsv = {(y * 255) / 480, 255, 255}; - struct rgb rgb = hsv_to_rgb(hsv); - vram[y * 640 + x] = (rgb.r >> 3) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 11); - } + while ((SH7091.SCIF.SCFSR2 & SCFSR2__RDF) == 0) { + // wait } - vram[0] = 0xf000; - vram[10] = 0xf0ff; - vram[11] = 0xf0ab; + while ((SH7091.SCIF.SCFDR2 & 0b11111) > 0) { + uint8_t c = SH7091.SCIF.SCFRDR2; + load_recv(c); + } + SH7091.SCIF.SCFSR2 = SH7091.SCIF.SCFSR2 & (~SCFSR2__RDF); } } diff --git a/regs/gen/systembus.py b/regs/gen/systembus.py index c42ce7d..a1d1c6e 100644 --- a/regs/gen/systembus.py +++ b/regs/gen/systembus.py @@ -6,10 +6,21 @@ from sh7091 import headers from sh7091 import blocks from generate import renderer +def blocks(rows): + blocks = [] + for row in rows: + block = row["block"] + if block not in blocks: + blocks.append(block) + + for block in blocks: + yield f'extern struct {block.lower()}_reg {block} __asm("{block}");' + input_file = sys.argv[1] rows = read_input(input_file) process = new_writer() render, out = renderer() render(headers()) render(process(rows)) +render(blocks(rows)) sys.stdout.write(out.getvalue()) diff --git a/regs/systembus.csv b/regs/systembus.csv index 7faf702..09244e7 100644 --- a/regs/systembus.csv +++ b/regs/systembus.csv @@ -45,118 +45,118 @@ "SYSTEM","150","4","G2DTNRM","RW","Normal interrupt G2-DMA startup mask" "SYSTEM","154","4","G2DTEXT","RW","External interrupt G2-DMA startup mask" ,,,,, -"MAPLE","04","4","MDSTAR","RW","Maple-DMA command table address" +"MAPLE_IF","04","4","MDSTAR","RW","Maple-DMA command table address" ,,,,, -"MAPLE","10","4","MDTSEL","RW","Maple-DMA trigger select" -"MAPLE","14","4","MDEN","RW","Maple-DMA enable" -"MAPLE","18","4","MDST","RW","Maple-DMA start" +"MAPLE_IF","10","4","MDTSEL","RW","Maple-DMA trigger select" +"MAPLE_IF","14","4","MDEN","RW","Maple-DMA enable" +"MAPLE_IF","18","4","MDST","RW","Maple-DMA start" ,,,,, -"MAPLE","80","4","MSYS","RW","Maple system control" -"MAPLE","84","4","MST","R","Maple status" -"MAPLE","88","4","MSHTCL","W","Maple-DMA hard trigger clear" -"MAPLE","8c","4","MDAPRO","W","Maple-DMA address range" +"MAPLE_IF","80","4","MSYS","RW","Maple system control" +"MAPLE_IF","84","4","MST","R","Maple status" +"MAPLE_IF","88","4","MSHTCL","W","Maple-DMA hard trigger clear" +"MAPLE_IF","8c","4","MDAPRO","W","Maple-DMA address range" ,,,,, -"MAPLE","e8","4","MMSEL","RW","Maple MSP selection" +"MAPLE_IF","e8","4","MMSEL","RW","Maple MSP selection" ,,,,, -"MAPLE","f4","4","MTXDAD","R","Maple TXD address counter" -"MAPLE","f8","4","MRXDAD","R","Maple RXD address counter" -"MAPLE","fc","4","MRXDBD","R","Maple RXD address base" +"MAPLE_IF","f4","4","MTXDAD","R","Maple TXD address counter" +"MAPLE_IF","f8","4","MRXDAD","R","Maple RXD address counter" +"MAPLE_IF","fc","4","MRXDBD","R","Maple RXD address base" ,,,,, -"G1","04","4","GDSTAR","RW","GD-DMA start address" -"G1","08","4","GDLEN","RW","GD-DMA length" -"G1","0c","4","GDDIR","RW","GD-DMA direction" +"G1_IF","04","4","GDSTAR","RW","GD-DMA start address" +"G1_IF","08","4","GDLEN","RW","GD-DMA length" +"G1_IF","0c","4","GDDIR","RW","GD-DMA direction" ,,,,, -"G1","14","4","GDEN","RW","GD-DMA enable" -"G1","18","4","GDST","RW","GD-DMA start" +"G1_IF","14","4","GDEN","RW","GD-DMA enable" +"G1_IF","18","4","GDST","RW","GD-DMA start" ,,,,, -"G1","80","4","G1RRC","W","System ROM read access timing" -"G1","84","4","G1RWC","W","System ROM write access timing" -"G1","88","4","G1FRC","W","Flash ROM read access timing" -"G1","8c","4","G1FWC","W","Flash ROM write access timing" -"G1","90","4","G1CRC","W","GD PIO read access timing" -"G1","94","4","G1CWC","W","GD PIO write access timing" +"G1_IF","80","4","G1RRC","W","System ROM read access timing" +"G1_IF","84","4","G1RWC","W","System ROM write access timing" +"G1_IF","88","4","G1FRC","W","Flash ROM read access timing" +"G1_IF","8c","4","G1FWC","W","Flash ROM write access timing" +"G1_IF","90","4","G1CRC","W","GD PIO read access timing" +"G1_IF","94","4","G1CWC","W","GD PIO write access timing" ,,,,, -"G1","a0","4","G1GDRC","W","GD-DMA read access timing" -"G1","a4","4","G1GDWC","W","GD-DMA write access timing" +"G1_IF","a0","4","G1GDRC","W","GD-DMA read access timing" +"G1_IF","a4","4","G1GDWC","W","GD-DMA write access timing" ,,,,, -"G1","b0","4","G1SYSM","R","System mode" -"G1","b4","4","G1CRDYC","W","G1IORDY signal control" -"G1","b8","4","GDAPRO","W","GD-DMA address range" +"G1_IF","b0","4","G1SYSM","R","System mode" +"G1_IF","b4","4","G1CRDYC","W","G1IORDY signal control" +"G1_IF","b8","4","GDAPRO","W","GD-DMA address range" ,,,,, -"G1","f4","4","GDSTARD","R","GD-DMA address count (on Root Bus)" -"G1","f8","4","GDLEND","R","GD-DMA transfer counter" +"G1_IF","f4","4","GDSTARD","R","GD-DMA address count (on Root Bus)" +"G1_IF","f8","4","GDLEND","R","GD-DMA transfer counter" ,,,,, -"G2","00","4","ADSTAG","RW","ACIA:G2-DMA G2 start address" -"G2","04","4","ADSTAR","RW","ACIA:G2-DMA system memory start address" -"G2","08","4","ADLEN","RW","ACIA:G2-DMA length" -"G2","0c","4","ADDIR","RW","ACIA:G2-DMA direction" -"G2","10","4","ADTSEL","RW","ACIA:G2-DMA trigger select" -"G2","14","4","ADEN","RW","ACIA:G2-DMA enable" -"G2","18","4","ADST","RW","ACIA:G2-DMA start" -"G2","1c","4","ADSUSP","RW","ACIA:G2-DMA suspend" +"G2_IF","00","4","ADSTAG","RW","ACIA:G2-DMA G2 start address" +"G2_IF","04","4","ADSTAR","RW","ACIA:G2-DMA system memory start address" +"G2_IF","08","4","ADLEN","RW","ACIA:G2-DMA length" +"G2_IF","0c","4","ADDIR","RW","ACIA:G2-DMA direction" +"G2_IF","10","4","ADTSEL","RW","ACIA:G2-DMA trigger select" +"G2_IF","14","4","ADEN","RW","ACIA:G2-DMA enable" +"G2_IF","18","4","ADST","RW","ACIA:G2-DMA start" +"G2_IF","1c","4","ADSUSP","RW","ACIA:G2-DMA suspend" ,,,,, -"G2","20","4","E1STAG","RW","Ext1:G2-DMA start address" -"G2","24","4","E1STAR","RW","Ext1:G2-DMA system memory start address" -"G2","28","4","E1LEN","RW","Ext1:G2-DMA length" -"G2","2c","4","E1DIR","RW","Ext1:G2-DMA direction" -"G2","30","4","E1TSEL","RW","Ext1:G2-DMA trigger select" -"G2","34","4","E1EN","RW","Ext1:G2-DMA enable" -"G2","38","4","E1ST","RW","Ext1:G2-DMA start" -"G2","3c","4","E1SUSP","RW","Ext1:G2-DMA suspend" +"G2_IF","20","4","E1STAG","RW","Ext1:G2-DMA start address" +"G2_IF","24","4","E1STAR","RW","Ext1:G2-DMA system memory start address" +"G2_IF","28","4","E1LEN","RW","Ext1:G2-DMA length" +"G2_IF","2c","4","E1DIR","RW","Ext1:G2-DMA direction" +"G2_IF","30","4","E1TSEL","RW","Ext1:G2-DMA trigger select" +"G2_IF","34","4","E1EN","RW","Ext1:G2-DMA enable" +"G2_IF","38","4","E1ST","RW","Ext1:G2-DMA start" +"G2_IF","3c","4","E1SUSP","RW","Ext1:G2-DMA suspend" ,,,,, -"G2","40","4","E2STAG","RW","Ext2:G2-DMA start address" -"G2","44","4","E2STAR","RW","Ext2:G2-DMA system memory start address" -"G2","48","4","E2LEN","RW","Ext2:G2-DMA length" -"G2","4c","4","E2DIR","RW","Ext2:G2-DMA direction" -"G2","50","4","E2TSEL","RW","Ext2:G2-DMA trigger select" -"G2","54","4","E2EN","RW","Ext2:G2-DMA enable" -"G2","58","4","E2ST","RW","Ext2:G2-DMA start" -"G2","5c","4","E2SUSP","RW","Ext2:G2-DMA suspend" +"G2_IF","40","4","E2STAG","RW","Ext2:G2-DMA start address" +"G2_IF","44","4","E2STAR","RW","Ext2:G2-DMA system memory start address" +"G2_IF","48","4","E2LEN","RW","Ext2:G2-DMA length" +"G2_IF","4c","4","E2DIR","RW","Ext2:G2-DMA direction" +"G2_IF","50","4","E2TSEL","RW","Ext2:G2-DMA trigger select" +"G2_IF","54","4","E2EN","RW","Ext2:G2-DMA enable" +"G2_IF","58","4","E2ST","RW","Ext2:G2-DMA start" +"G2_IF","5c","4","E2SUSP","RW","Ext2:G2-DMA suspend" ,,,,, -"G2","60","4","DDSTAG","RW","Dev:G2-DMA start address" -"G2","64","4","DDSTAR","RW","Dev:G2-DMA system memory start address" -"G2","68","4","DDLEN","RW","Dev:G2-DMA length" -"G2","6c","4","DDDIR","RW","Dev:G2-DMA direction" -"G2","70","4","DDTSEL","RW","Dev:G2-DMA trigger select" -"G2","74","4","DDEN","RW","Dev:G2-DMA enable" -"G2","78","4","DDST","RW","Dev:G2-DMA start" -"G2","7c","4","DDSUSP","RW","Dev:G2-DMA suspend" +"G2_IF","60","4","DDSTAG","RW","Dev:G2-DMA start address" +"G2_IF","64","4","DDSTAR","RW","Dev:G2-DMA system memory start address" +"G2_IF","68","4","DDLEN","RW","Dev:G2-DMA length" +"G2_IF","6c","4","DDDIR","RW","Dev:G2-DMA direction" +"G2_IF","70","4","DDTSEL","RW","Dev:G2-DMA trigger select" +"G2_IF","74","4","DDEN","RW","Dev:G2-DMA enable" +"G2_IF","78","4","DDST","RW","Dev:G2-DMA start" +"G2_IF","7c","4","DDSUSP","RW","Dev:G2-DMA suspend" ,,,,, -"G2","80","4","G2ID","R","G2 bus version" +"G2_IF","80","4","G2ID","R","G2 bus version" ,,,,, -"G2","90","4","G2DSTO","RW","G2/DS timeout" -"G2","94","4","G2TRTO","RW","G2/TR timeout" -"G2","98","4","G2MDMTO","RW","Modem unit wait timeout" -"G2","9c","4","G2MDMW","RW","Modem unit wait time" +"G2_IF","90","4","G2DSTO","RW","G2/DS timeout" +"G2_IF","94","4","G2TRTO","RW","G2/TR timeout" +"G2_IF","98","4","G2MDMTO","RW","Modem unit wait timeout" +"G2_IF","9c","4","G2MDMW","RW","Modem unit wait time" ,,,,, -"G2","bc","4","G2APRO","W","G2-DMA address range" +"G2_IF","bc","4","G2APRO","W","G2-DMA address range" ,,,,, -"G2","c0","4","ADSTAGD","R","AICA-DMA address counter (on AICA)" -"G2","c4","4","ADSTARD","R","AICA-DMA address counter (on root bus)" -"G2","c8","4","ADLEND","R","AICA-DMA transfer counter" +"G2_IF","c0","4","ADSTAGD","R","AICA-DMA address counter (on AICA)" +"G2_IF","c4","4","ADSTARD","R","AICA-DMA address counter (on root bus)" +"G2_IF","c8","4","ADLEND","R","AICA-DMA transfer counter" ,,,,, -"G2","d0","4","E1STAGD","R","Ext-DMA1 address counter (on Ext)" -"G2","d4","4","E1STARD","R","Ext-DMA1 address counter (on root bus)" -"G2","d8","4","E1LEND","R","Ext-DMA1 transfer counter" +"G2_IF","d0","4","E1STAGD","R","Ext-DMA1 address counter (on Ext)" +"G2_IF","d4","4","E1STARD","R","Ext-DMA1 address counter (on root bus)" +"G2_IF","d8","4","E1LEND","R","Ext-DMA1 transfer counter" ,,,,, -"G2","e0","4","E2STAGD","R","Ext-DMA2 address counter (on Ext)" -"G2","e4","4","E2STARD","R","Ext-DMA2 address counter (on root bus)" -"G2","e8","4","E2LEND","R","Ext-DMA2 transfer counter" +"G2_IF","e0","4","E2STAGD","R","Ext-DMA2 address counter (on Ext)" +"G2_IF","e4","4","E2STARD","R","Ext-DMA2 address counter (on root bus)" +"G2_IF","e8","4","E2LEND","R","Ext-DMA2 transfer counter" ,,,,, -"G2","f0","4","DDSTAGD","R","Dev-DMA address counter (on Dev)" -"G2","f4","4","DDSTARD","R","Dev-DMA address counter (on root bus)" -"G2","f8","4","DDLEND","R","Dev-DMA transfer counter" +"G2_IF","f0","4","DDSTAGD","R","Dev-DMA address counter (on Dev)" +"G2_IF","f4","4","DDSTARD","R","Dev-DMA address counter (on root bus)" +"G2_IF","f8","4","DDLEND","R","Dev-DMA transfer counter" ,,,,, -"PVR","00","4","PDSTAP","RW","PVR-DMA start address" -"PVR","04","4","PDSTAR","RW","PVR-DMA system memory start address" -"PVR","08","4","PDLEN","RW","PVR-DMA length" -"PVR","0c","4","PDDIR","RW","PVR-DMA direction" -"PVR","10","4","PDTSEL","RW","PVR-DMA trigger select" -"PVR","14","4","PDEN","RW","PVR-DMA enable" -"PVR","18","4","PDST","RW","PVR-DMA start" +"PVR_IF","00","4","PDSTAP","RW","PVR-DMA start address" +"PVR_IF","04","4","PDSTAR","RW","PVR-DMA system memory start address" +"PVR_IF","08","4","PDLEN","RW","PVR-DMA length" +"PVR_IF","0c","4","PDDIR","RW","PVR-DMA direction" +"PVR_IF","10","4","PDTSEL","RW","PVR-DMA trigger select" +"PVR_IF","14","4","PDEN","RW","PVR-DMA enable" +"PVR_IF","18","4","PDST","RW","PVR-DMA start" ,,,,, -"PVR","80","4","PDAPRO","W","PVR-DMA address range" +"PVR_IF","80","4","PDAPRO","W","PVR-DMA address range" ,,,,, -"PVR","f0","4","PDSTAPD","R","PVR-DMA address counter (on Ext)" -"PVR","f4","4","PDSTARD","R","PVR-DMA address counter (on root bus)" -"PVR","f8","4","PDLEND","R","PVR-DMA transfer counter" +"PVR_IF","f0","4","PDSTAPD","R","PVR-DMA address counter (on Ext)" +"PVR_IF","f4","4","PDSTARD","R","PVR-DMA address counter (on root bus)" +"PVR_IF","f8","4","PDLEND","R","PVR-DMA transfer counter" diff --git a/regs/systembus.ods b/regs/systembus.ods index fabd427f760d77aa57e1b2c7891f454bf15e7cf2..90f79c265003af24c6c16ff72a6519432887c054 100644 GIT binary patch delta 15795 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 delta 15433 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 diff --git a/rgb.c b/rgb.c new file mode 100644 index 0000000..e7f34d4 --- /dev/null +++ b/rgb.c @@ -0,0 +1,32 @@ +#include "rgb.h" + +struct rgb hsv_to_rgb(struct hsv hsv) +{ + struct rgb rgb; + unsigned char region, remainder, p, q, t; + + if (hsv.s == 0) { + rgb.r = hsv.v; + rgb.g = hsv.v; + rgb.b = hsv.v; + return rgb; + } + + region = hsv.h / 43; + remainder = (hsv.h - (region * 43)) * 6; + + p = (hsv.v * (255 - hsv.s)) >> 8; + q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8; + t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8; + + switch (region) { + case 0: rgb.r = hsv.v; rgb.g = t; rgb.b = p; break; + case 1: rgb.r = q; rgb.g = hsv.v; rgb.b = p; break; + case 2: rgb.r = p; rgb.g = hsv.v; rgb.b = t; break; + case 3: rgb.r = p; rgb.g = q; rgb.b = hsv.v; break; + case 4: rgb.r = t; rgb.g = p; rgb.b = hsv.v; break; + default: rgb.r = hsv.v; rgb.g = p; rgb.b = q; break; + } + + return rgb; +} diff --git a/rgb.h b/rgb.h new file mode 100644 index 0000000..9ff614d --- /dev/null +++ b/rgb.h @@ -0,0 +1,15 @@ +struct rgb +{ + unsigned char r; + unsigned char g; + unsigned char b; +}; + +struct hsv +{ + unsigned char h; + unsigned char s; + unsigned char v; +}; + +struct rgb hsv_to_rgb(struct hsv hsv); diff --git a/systembus.h b/systembus.h index 3da02dc..d1a5fac 100644 --- a/systembus.h +++ b/systembus.h @@ -1,52 +1,54 @@ #include #include +#include "type.h" + struct system_reg { - uint32_t C2DSTAT; /* CH2-DMA destination address */ - uint32_t C2DLEN; /* CH2-DMA length */ - uint32_t C2DST; /* CH2-DMA start */ - uint8_t _pad0[4]; - uint32_t SDSTAW; /* Sort-DMA start link table address */ - uint32_t SDBAAW; /* Sort-DMA link base address */ - uint32_t SDWLT; /* Sort-DMA link address bit width */ - uint32_t SDLAS; /* Sort-DMA link address shift control */ - uint32_t SDST; /* Sort-DMA start */ - uint8_t _pad1[28]; - uint32_t DBREQM; /* DBREQ# signal mask control */ - uint32_t BAVLWC; /* BAVL# signal wait count */ - uint32_t C2DPYRC; /* DMA (TA/Root Bus) priority count */ - uint32_t DMAXL; /* CH2-DMA maximum burst length */ - uint8_t _pad2[48]; - uint32_t TFREM; /* TA FIFO remaining amount */ - uint32_t LMMODE0; /* Via TA texture memory bus select 0 */ - uint32_t LMMODE1; /* Via TA texture memory bus select 1 */ - uint32_t FFST; /* FIFO status */ - uint32_t SFRES; /* System reset */ - uint8_t _pad3[8]; - uint32_t SBREV; /* System bus revision number */ - uint32_t RBSPLT; /* SH4 Root Bus split enable */ - uint8_t _pad4[92]; - uint32_t ISTNRM; /* Normal interrupt status */ - uint32_t ISTEXT; /* External interrupt status */ - uint32_t ISTERR; /* Error interrupt status */ - uint8_t _pad5[4]; - uint32_t IML2NRM; /* Level 2 normal interrupt mask */ - uint32_t IML2EXT; /* Level 2 external interrupt mask */ - uint32_t IML2ERR; /* Level 2 error interrupt mask */ - uint8_t _pad6[4]; - uint32_t IML4NRM; /* Level 4 normal interrupt mask */ - uint32_t IML4EXT; /* Level 4 external interrupt mask */ - uint32_t IML4ERR; /* Level 4 error interrupt mask */ - uint8_t _pad7[4]; - uint32_t IML6NRM; /* Level 6 normal interrupt mask */ - uint32_t IML6EXT; /* Level 6 external interrupt mask */ - uint32_t IML6ERR; /* Level 6 error interrupt mask */ - uint8_t _pad8[4]; - uint32_t PDTNRM; /* Normal interrupt PVR-DMA startup mask */ - uint32_t PDTEXT; /* External interrupt PVR-DMA startup mask */ - uint8_t _pad9[8]; - uint32_t G2DTNRM; /* Normal interrupt G2-DMA startup mask */ - uint32_t G2DTEXT; /* External interrupt G2-DMA startup mask */ + reg32 C2DSTAT; /* CH2-DMA destination address */ + reg32 C2DLEN; /* CH2-DMA length */ + reg32 C2DST; /* CH2-DMA start */ + reg8 _pad0[4]; + reg32 SDSTAW; /* Sort-DMA start link table address */ + reg32 SDBAAW; /* Sort-DMA link base address */ + reg32 SDWLT; /* Sort-DMA link address bit width */ + reg32 SDLAS; /* Sort-DMA link address shift control */ + reg32 SDST; /* Sort-DMA start */ + reg8 _pad1[28]; + reg32 DBREQM; /* DBREQ# signal mask control */ + reg32 BAVLWC; /* BAVL# signal wait count */ + reg32 C2DPYRC; /* DMA (TA/Root Bus) priority count */ + reg32 DMAXL; /* CH2-DMA maximum burst length */ + reg8 _pad2[48]; + reg32 TFREM; /* TA FIFO remaining amount */ + reg32 LMMODE0; /* Via TA texture memory bus select 0 */ + reg32 LMMODE1; /* Via TA texture memory bus select 1 */ + reg32 FFST; /* FIFO status */ + reg32 SFRES; /* System reset */ + reg8 _pad3[8]; + reg32 SBREV; /* System bus revision number */ + reg32 RBSPLT; /* SH4 Root Bus split enable */ + reg8 _pad4[92]; + reg32 ISTNRM; /* Normal interrupt status */ + reg32 ISTEXT; /* External interrupt status */ + reg32 ISTERR; /* Error interrupt status */ + reg8 _pad5[4]; + reg32 IML2NRM; /* Level 2 normal interrupt mask */ + reg32 IML2EXT; /* Level 2 external interrupt mask */ + reg32 IML2ERR; /* Level 2 error interrupt mask */ + reg8 _pad6[4]; + reg32 IML4NRM; /* Level 4 normal interrupt mask */ + reg32 IML4EXT; /* Level 4 external interrupt mask */ + reg32 IML4ERR; /* Level 4 error interrupt mask */ + reg8 _pad7[4]; + reg32 IML6NRM; /* Level 6 normal interrupt mask */ + reg32 IML6EXT; /* Level 6 external interrupt mask */ + reg32 IML6ERR; /* Level 6 error interrupt mask */ + reg8 _pad8[4]; + reg32 PDTNRM; /* Normal interrupt PVR-DMA startup mask */ + reg32 PDTEXT; /* External interrupt PVR-DMA startup mask */ + reg8 _pad9[8]; + reg32 G2DTNRM; /* Normal interrupt G2-DMA startup mask */ + reg32 G2DTEXT; /* External interrupt G2-DMA startup mask */ }; static_assert((offsetof (struct system_reg, C2DSTAT)) == 0x0); @@ -85,217 +87,227 @@ static_assert((offsetof (struct system_reg, PDTEXT)) == 0x144); static_assert((offsetof (struct system_reg, G2DTNRM)) == 0x150); static_assert((offsetof (struct system_reg, G2DTEXT)) == 0x154); -struct maple_reg { - uint32_t MDSTAR; /* Maple-DMA command table address */ - uint8_t _pad0[8]; - uint32_t MDTSEL; /* Maple-DMA trigger select */ - uint32_t MDEN; /* Maple-DMA enable */ - uint32_t MDST; /* Maple-DMA start */ - uint8_t _pad1[100]; - uint32_t MSYS; /* Maple system control */ - uint32_t MST; /* Maple status */ - uint32_t MSHTCL; /* Maple-DMA hard trigger clear */ - uint32_t MDAPRO; /* Maple-DMA address range */ - uint8_t _pad2[88]; - uint32_t MMSEL; /* Maple MSP selection */ - uint8_t _pad3[8]; - uint32_t MTXDAD; /* Maple TXD address counter */ - uint32_t MRXDAD; /* Maple RXD address counter */ - uint32_t MRXDBD; /* Maple RXD address base */ +struct maple_if_reg { + reg32 MDSTAR; /* Maple-DMA command table address */ + reg8 _pad0[8]; + reg32 MDTSEL; /* Maple-DMA trigger select */ + reg32 MDEN; /* Maple-DMA enable */ + reg32 MDST; /* Maple-DMA start */ + reg8 _pad1[100]; + reg32 MSYS; /* Maple system control */ + reg32 MST; /* Maple status */ + reg32 MSHTCL; /* Maple-DMA hard trigger clear */ + reg32 MDAPRO; /* Maple-DMA address range */ + reg8 _pad2[88]; + reg32 MMSEL; /* Maple MSP selection */ + reg8 _pad3[8]; + reg32 MTXDAD; /* Maple TXD address counter */ + reg32 MRXDAD; /* Maple RXD address counter */ + reg32 MRXDBD; /* Maple RXD address base */ }; -static_assert((offsetof (struct maple_reg, MDSTAR)) == 0x0); -static_assert((offsetof (struct maple_reg, MDTSEL)) == 0xc); -static_assert((offsetof (struct maple_reg, MDEN)) == 0x10); -static_assert((offsetof (struct maple_reg, MDST)) == 0x14); -static_assert((offsetof (struct maple_reg, MSYS)) == 0x7c); -static_assert((offsetof (struct maple_reg, MST)) == 0x80); -static_assert((offsetof (struct maple_reg, MSHTCL)) == 0x84); -static_assert((offsetof (struct maple_reg, MDAPRO)) == 0x88); -static_assert((offsetof (struct maple_reg, MMSEL)) == 0xe4); -static_assert((offsetof (struct maple_reg, MTXDAD)) == 0xf0); -static_assert((offsetof (struct maple_reg, MRXDAD)) == 0xf4); -static_assert((offsetof (struct maple_reg, MRXDBD)) == 0xf8); +static_assert((offsetof (struct maple_if_reg, MDSTAR)) == 0x0); +static_assert((offsetof (struct maple_if_reg, MDTSEL)) == 0xc); +static_assert((offsetof (struct maple_if_reg, MDEN)) == 0x10); +static_assert((offsetof (struct maple_if_reg, MDST)) == 0x14); +static_assert((offsetof (struct maple_if_reg, MSYS)) == 0x7c); +static_assert((offsetof (struct maple_if_reg, MST)) == 0x80); +static_assert((offsetof (struct maple_if_reg, MSHTCL)) == 0x84); +static_assert((offsetof (struct maple_if_reg, MDAPRO)) == 0x88); +static_assert((offsetof (struct maple_if_reg, MMSEL)) == 0xe4); +static_assert((offsetof (struct maple_if_reg, MTXDAD)) == 0xf0); +static_assert((offsetof (struct maple_if_reg, MRXDAD)) == 0xf4); +static_assert((offsetof (struct maple_if_reg, MRXDBD)) == 0xf8); -struct g1_reg { - uint32_t GDSTAR; /* GD-DMA start address */ - uint32_t GDLEN; /* GD-DMA length */ - uint32_t GDDIR; /* GD-DMA direction */ - uint8_t _pad0[4]; - uint32_t GDEN; /* GD-DMA enable */ - uint32_t GDST; /* GD-DMA start */ - uint8_t _pad1[100]; - uint32_t G1RRC; /* System ROM read access timing */ - uint32_t G1RWC; /* System ROM write access timing */ - uint32_t G1FRC; /* Flash ROM read access timing */ - uint32_t G1FWC; /* Flash ROM write access timing */ - uint32_t G1CRC; /* GD PIO read access timing */ - uint32_t G1CWC; /* GD PIO write access timing */ - uint8_t _pad2[8]; - uint32_t G1GDRC; /* GD-DMA read access timing */ - uint32_t G1GDWC; /* GD-DMA write access timing */ - uint8_t _pad3[8]; - uint32_t G1SYSM; /* System mode */ - uint32_t G1CRDYC; /* G1IORDY signal control */ - uint32_t GDAPRO; /* GD-DMA address range */ - uint8_t _pad4[56]; - uint32_t GDSTARD; /* GD-DMA address count (on Root Bus) */ - uint32_t GDLEND; /* GD-DMA transfer counter */ +struct g1_if_reg { + reg32 GDSTAR; /* GD-DMA start address */ + reg32 GDLEN; /* GD-DMA length */ + reg32 GDDIR; /* GD-DMA direction */ + reg8 _pad0[4]; + reg32 GDEN; /* GD-DMA enable */ + reg32 GDST; /* GD-DMA start */ + reg8 _pad1[100]; + reg32 G1RRC; /* System ROM read access timing */ + reg32 G1RWC; /* System ROM write access timing */ + reg32 G1FRC; /* Flash ROM read access timing */ + reg32 G1FWC; /* Flash ROM write access timing */ + reg32 G1CRC; /* GD PIO read access timing */ + reg32 G1CWC; /* GD PIO write access timing */ + reg8 _pad2[8]; + reg32 G1GDRC; /* GD-DMA read access timing */ + reg32 G1GDWC; /* GD-DMA write access timing */ + reg8 _pad3[8]; + reg32 G1SYSM; /* System mode */ + reg32 G1CRDYC; /* G1IORDY signal control */ + reg32 GDAPRO; /* GD-DMA address range */ + reg8 _pad4[56]; + reg32 GDSTARD; /* GD-DMA address count (on Root Bus) */ + reg32 GDLEND; /* GD-DMA transfer counter */ }; -static_assert((offsetof (struct g1_reg, GDSTAR)) == 0x0); -static_assert((offsetof (struct g1_reg, GDLEN)) == 0x4); -static_assert((offsetof (struct g1_reg, GDDIR)) == 0x8); -static_assert((offsetof (struct g1_reg, GDEN)) == 0x10); -static_assert((offsetof (struct g1_reg, GDST)) == 0x14); -static_assert((offsetof (struct g1_reg, G1RRC)) == 0x7c); -static_assert((offsetof (struct g1_reg, G1RWC)) == 0x80); -static_assert((offsetof (struct g1_reg, G1FRC)) == 0x84); -static_assert((offsetof (struct g1_reg, G1FWC)) == 0x88); -static_assert((offsetof (struct g1_reg, G1CRC)) == 0x8c); -static_assert((offsetof (struct g1_reg, G1CWC)) == 0x90); -static_assert((offsetof (struct g1_reg, G1GDRC)) == 0x9c); -static_assert((offsetof (struct g1_reg, G1GDWC)) == 0xa0); -static_assert((offsetof (struct g1_reg, G1SYSM)) == 0xac); -static_assert((offsetof (struct g1_reg, G1CRDYC)) == 0xb0); -static_assert((offsetof (struct g1_reg, GDAPRO)) == 0xb4); -static_assert((offsetof (struct g1_reg, GDSTARD)) == 0xf0); -static_assert((offsetof (struct g1_reg, GDLEND)) == 0xf4); +static_assert((offsetof (struct g1_if_reg, GDSTAR)) == 0x0); +static_assert((offsetof (struct g1_if_reg, GDLEN)) == 0x4); +static_assert((offsetof (struct g1_if_reg, GDDIR)) == 0x8); +static_assert((offsetof (struct g1_if_reg, GDEN)) == 0x10); +static_assert((offsetof (struct g1_if_reg, GDST)) == 0x14); +static_assert((offsetof (struct g1_if_reg, G1RRC)) == 0x7c); +static_assert((offsetof (struct g1_if_reg, G1RWC)) == 0x80); +static_assert((offsetof (struct g1_if_reg, G1FRC)) == 0x84); +static_assert((offsetof (struct g1_if_reg, G1FWC)) == 0x88); +static_assert((offsetof (struct g1_if_reg, G1CRC)) == 0x8c); +static_assert((offsetof (struct g1_if_reg, G1CWC)) == 0x90); +static_assert((offsetof (struct g1_if_reg, G1GDRC)) == 0x9c); +static_assert((offsetof (struct g1_if_reg, G1GDWC)) == 0xa0); +static_assert((offsetof (struct g1_if_reg, G1SYSM)) == 0xac); +static_assert((offsetof (struct g1_if_reg, G1CRDYC)) == 0xb0); +static_assert((offsetof (struct g1_if_reg, GDAPRO)) == 0xb4); +static_assert((offsetof (struct g1_if_reg, GDSTARD)) == 0xf0); +static_assert((offsetof (struct g1_if_reg, GDLEND)) == 0xf4); -struct g2_reg { - uint32_t ADSTAG; /* ACIA:G2-DMA G2 start address */ - uint32_t ADSTAR; /* ACIA:G2-DMA system memory start address */ - uint32_t ADLEN; /* ACIA:G2-DMA length */ - uint32_t ADDIR; /* ACIA:G2-DMA direction */ - uint32_t ADTSEL; /* ACIA:G2-DMA trigger select */ - uint32_t ADEN; /* ACIA:G2-DMA enable */ - uint32_t ADST; /* ACIA:G2-DMA start */ - uint32_t ADSUSP; /* ACIA:G2-DMA suspend */ - uint32_t E1STAG; /* Ext1:G2-DMA start address */ - uint32_t E1STAR; /* Ext1:G2-DMA system memory start address */ - uint32_t E1LEN; /* Ext1:G2-DMA length */ - uint32_t E1DIR; /* Ext1:G2-DMA direction */ - uint32_t E1TSEL; /* Ext1:G2-DMA trigger select */ - uint32_t E1EN; /* Ext1:G2-DMA enable */ - uint32_t E1ST; /* Ext1:G2-DMA start */ - uint32_t E1SUSP; /* Ext1:G2-DMA suspend */ - uint32_t E2STAG; /* Ext2:G2-DMA start address */ - uint32_t E2STAR; /* Ext2:G2-DMA system memory start address */ - uint32_t E2LEN; /* Ext2:G2-DMA length */ - uint32_t E2DIR; /* Ext2:G2-DMA direction */ - uint32_t E2TSEL; /* Ext2:G2-DMA trigger select */ - uint32_t E2EN; /* Ext2:G2-DMA enable */ - uint32_t E2ST; /* Ext2:G2-DMA start */ - uint32_t E2SUSP; /* Ext2:G2-DMA suspend */ - uint32_t DDSTAG; /* Dev:G2-DMA start address */ - uint32_t DDSTAR; /* Dev:G2-DMA system memory start address */ - uint32_t DDLEN; /* Dev:G2-DMA length */ - uint32_t DDDIR; /* Dev:G2-DMA direction */ - uint32_t DDTSEL; /* Dev:G2-DMA trigger select */ - uint32_t DDEN; /* Dev:G2-DMA enable */ - uint32_t DDST; /* Dev:G2-DMA start */ - uint32_t DDSUSP; /* Dev:G2-DMA suspend */ - uint32_t G2ID; /* G2 bus version */ - uint8_t _pad0[12]; - uint32_t G2DSTO; /* G2/DS timeout */ - uint32_t G2TRTO; /* G2/TR timeout */ - uint32_t G2MDMTO; /* Modem unit wait timeout */ - uint32_t G2MDMW; /* Modem unit wait time */ - uint8_t _pad1[28]; - uint32_t G2APRO; /* G2-DMA address range */ - uint32_t ADSTAGD; /* AICA-DMA address counter (on AICA) */ - uint32_t ADSTARD; /* AICA-DMA address counter (on root bus) */ - uint32_t ADLEND; /* AICA-DMA transfer counter */ - uint8_t _pad2[4]; - uint32_t E1STAGD; /* Ext-DMA1 address counter (on Ext) */ - uint32_t E1STARD; /* Ext-DMA1 address counter (on root bus) */ - uint32_t E1LEND; /* Ext-DMA1 transfer counter */ - uint8_t _pad3[4]; - uint32_t E2STAGD; /* Ext-DMA2 address counter (on Ext) */ - uint32_t E2STARD; /* Ext-DMA2 address counter (on root bus) */ - uint32_t E2LEND; /* Ext-DMA2 transfer counter */ - uint8_t _pad4[4]; - uint32_t DDSTAGD; /* Dev-DMA address counter (on Dev) */ - uint32_t DDSTARD; /* Dev-DMA address counter (on root bus) */ - uint32_t DDLEND; /* Dev-DMA transfer counter */ +struct g2_if_reg { + reg32 ADSTAG; /* ACIA:G2-DMA G2 start address */ + reg32 ADSTAR; /* ACIA:G2-DMA system memory start address */ + reg32 ADLEN; /* ACIA:G2-DMA length */ + reg32 ADDIR; /* ACIA:G2-DMA direction */ + reg32 ADTSEL; /* ACIA:G2-DMA trigger select */ + reg32 ADEN; /* ACIA:G2-DMA enable */ + reg32 ADST; /* ACIA:G2-DMA start */ + reg32 ADSUSP; /* ACIA:G2-DMA suspend */ + reg32 E1STAG; /* Ext1:G2-DMA start address */ + reg32 E1STAR; /* Ext1:G2-DMA system memory start address */ + reg32 E1LEN; /* Ext1:G2-DMA length */ + reg32 E1DIR; /* Ext1:G2-DMA direction */ + reg32 E1TSEL; /* Ext1:G2-DMA trigger select */ + reg32 E1EN; /* Ext1:G2-DMA enable */ + reg32 E1ST; /* Ext1:G2-DMA start */ + reg32 E1SUSP; /* Ext1:G2-DMA suspend */ + reg32 E2STAG; /* Ext2:G2-DMA start address */ + reg32 E2STAR; /* Ext2:G2-DMA system memory start address */ + reg32 E2LEN; /* Ext2:G2-DMA length */ + reg32 E2DIR; /* Ext2:G2-DMA direction */ + reg32 E2TSEL; /* Ext2:G2-DMA trigger select */ + reg32 E2EN; /* Ext2:G2-DMA enable */ + reg32 E2ST; /* Ext2:G2-DMA start */ + reg32 E2SUSP; /* Ext2:G2-DMA suspend */ + reg32 DDSTAG; /* Dev:G2-DMA start address */ + reg32 DDSTAR; /* Dev:G2-DMA system memory start address */ + reg32 DDLEN; /* Dev:G2-DMA length */ + reg32 DDDIR; /* Dev:G2-DMA direction */ + reg32 DDTSEL; /* Dev:G2-DMA trigger select */ + reg32 DDEN; /* Dev:G2-DMA enable */ + reg32 DDST; /* Dev:G2-DMA start */ + reg32 DDSUSP; /* Dev:G2-DMA suspend */ + reg32 G2ID; /* G2 bus version */ + reg8 _pad0[12]; + reg32 G2DSTO; /* G2/DS timeout */ + reg32 G2TRTO; /* G2/TR timeout */ + reg32 G2MDMTO; /* Modem unit wait timeout */ + reg32 G2MDMW; /* Modem unit wait time */ + reg8 _pad1[28]; + reg32 G2APRO; /* G2-DMA address range */ + reg32 ADSTAGD; /* AICA-DMA address counter (on AICA) */ + reg32 ADSTARD; /* AICA-DMA address counter (on root bus) */ + reg32 ADLEND; /* AICA-DMA transfer counter */ + reg8 _pad2[4]; + reg32 E1STAGD; /* Ext-DMA1 address counter (on Ext) */ + reg32 E1STARD; /* Ext-DMA1 address counter (on root bus) */ + reg32 E1LEND; /* Ext-DMA1 transfer counter */ + reg8 _pad3[4]; + reg32 E2STAGD; /* Ext-DMA2 address counter (on Ext) */ + reg32 E2STARD; /* Ext-DMA2 address counter (on root bus) */ + reg32 E2LEND; /* Ext-DMA2 transfer counter */ + reg8 _pad4[4]; + reg32 DDSTAGD; /* Dev-DMA address counter (on Dev) */ + reg32 DDSTARD; /* Dev-DMA address counter (on root bus) */ + reg32 DDLEND; /* Dev-DMA transfer counter */ }; -static_assert((offsetof (struct g2_reg, ADSTAG)) == 0x0); -static_assert((offsetof (struct g2_reg, ADSTAR)) == 0x4); -static_assert((offsetof (struct g2_reg, ADLEN)) == 0x8); -static_assert((offsetof (struct g2_reg, ADDIR)) == 0xc); -static_assert((offsetof (struct g2_reg, ADTSEL)) == 0x10); -static_assert((offsetof (struct g2_reg, ADEN)) == 0x14); -static_assert((offsetof (struct g2_reg, ADST)) == 0x18); -static_assert((offsetof (struct g2_reg, ADSUSP)) == 0x1c); -static_assert((offsetof (struct g2_reg, E1STAG)) == 0x20); -static_assert((offsetof (struct g2_reg, E1STAR)) == 0x24); -static_assert((offsetof (struct g2_reg, E1LEN)) == 0x28); -static_assert((offsetof (struct g2_reg, E1DIR)) == 0x2c); -static_assert((offsetof (struct g2_reg, E1TSEL)) == 0x30); -static_assert((offsetof (struct g2_reg, E1EN)) == 0x34); -static_assert((offsetof (struct g2_reg, E1ST)) == 0x38); -static_assert((offsetof (struct g2_reg, E1SUSP)) == 0x3c); -static_assert((offsetof (struct g2_reg, E2STAG)) == 0x40); -static_assert((offsetof (struct g2_reg, E2STAR)) == 0x44); -static_assert((offsetof (struct g2_reg, E2LEN)) == 0x48); -static_assert((offsetof (struct g2_reg, E2DIR)) == 0x4c); -static_assert((offsetof (struct g2_reg, E2TSEL)) == 0x50); -static_assert((offsetof (struct g2_reg, E2EN)) == 0x54); -static_assert((offsetof (struct g2_reg, E2ST)) == 0x58); -static_assert((offsetof (struct g2_reg, E2SUSP)) == 0x5c); -static_assert((offsetof (struct g2_reg, DDSTAG)) == 0x60); -static_assert((offsetof (struct g2_reg, DDSTAR)) == 0x64); -static_assert((offsetof (struct g2_reg, DDLEN)) == 0x68); -static_assert((offsetof (struct g2_reg, DDDIR)) == 0x6c); -static_assert((offsetof (struct g2_reg, DDTSEL)) == 0x70); -static_assert((offsetof (struct g2_reg, DDEN)) == 0x74); -static_assert((offsetof (struct g2_reg, DDST)) == 0x78); -static_assert((offsetof (struct g2_reg, DDSUSP)) == 0x7c); -static_assert((offsetof (struct g2_reg, G2ID)) == 0x80); -static_assert((offsetof (struct g2_reg, G2DSTO)) == 0x90); -static_assert((offsetof (struct g2_reg, G2TRTO)) == 0x94); -static_assert((offsetof (struct g2_reg, G2MDMTO)) == 0x98); -static_assert((offsetof (struct g2_reg, G2MDMW)) == 0x9c); -static_assert((offsetof (struct g2_reg, G2APRO)) == 0xbc); -static_assert((offsetof (struct g2_reg, ADSTAGD)) == 0xc0); -static_assert((offsetof (struct g2_reg, ADSTARD)) == 0xc4); -static_assert((offsetof (struct g2_reg, ADLEND)) == 0xc8); -static_assert((offsetof (struct g2_reg, E1STAGD)) == 0xd0); -static_assert((offsetof (struct g2_reg, E1STARD)) == 0xd4); -static_assert((offsetof (struct g2_reg, E1LEND)) == 0xd8); -static_assert((offsetof (struct g2_reg, E2STAGD)) == 0xe0); -static_assert((offsetof (struct g2_reg, E2STARD)) == 0xe4); -static_assert((offsetof (struct g2_reg, E2LEND)) == 0xe8); -static_assert((offsetof (struct g2_reg, DDSTAGD)) == 0xf0); -static_assert((offsetof (struct g2_reg, DDSTARD)) == 0xf4); -static_assert((offsetof (struct g2_reg, DDLEND)) == 0xf8); +static_assert((offsetof (struct g2_if_reg, ADSTAG)) == 0x0); +static_assert((offsetof (struct g2_if_reg, ADSTAR)) == 0x4); +static_assert((offsetof (struct g2_if_reg, ADLEN)) == 0x8); +static_assert((offsetof (struct g2_if_reg, ADDIR)) == 0xc); +static_assert((offsetof (struct g2_if_reg, ADTSEL)) == 0x10); +static_assert((offsetof (struct g2_if_reg, ADEN)) == 0x14); +static_assert((offsetof (struct g2_if_reg, ADST)) == 0x18); +static_assert((offsetof (struct g2_if_reg, ADSUSP)) == 0x1c); +static_assert((offsetof (struct g2_if_reg, E1STAG)) == 0x20); +static_assert((offsetof (struct g2_if_reg, E1STAR)) == 0x24); +static_assert((offsetof (struct g2_if_reg, E1LEN)) == 0x28); +static_assert((offsetof (struct g2_if_reg, E1DIR)) == 0x2c); +static_assert((offsetof (struct g2_if_reg, E1TSEL)) == 0x30); +static_assert((offsetof (struct g2_if_reg, E1EN)) == 0x34); +static_assert((offsetof (struct g2_if_reg, E1ST)) == 0x38); +static_assert((offsetof (struct g2_if_reg, E1SUSP)) == 0x3c); +static_assert((offsetof (struct g2_if_reg, E2STAG)) == 0x40); +static_assert((offsetof (struct g2_if_reg, E2STAR)) == 0x44); +static_assert((offsetof (struct g2_if_reg, E2LEN)) == 0x48); +static_assert((offsetof (struct g2_if_reg, E2DIR)) == 0x4c); +static_assert((offsetof (struct g2_if_reg, E2TSEL)) == 0x50); +static_assert((offsetof (struct g2_if_reg, E2EN)) == 0x54); +static_assert((offsetof (struct g2_if_reg, E2ST)) == 0x58); +static_assert((offsetof (struct g2_if_reg, E2SUSP)) == 0x5c); +static_assert((offsetof (struct g2_if_reg, DDSTAG)) == 0x60); +static_assert((offsetof (struct g2_if_reg, DDSTAR)) == 0x64); +static_assert((offsetof (struct g2_if_reg, DDLEN)) == 0x68); +static_assert((offsetof (struct g2_if_reg, DDDIR)) == 0x6c); +static_assert((offsetof (struct g2_if_reg, DDTSEL)) == 0x70); +static_assert((offsetof (struct g2_if_reg, DDEN)) == 0x74); +static_assert((offsetof (struct g2_if_reg, DDST)) == 0x78); +static_assert((offsetof (struct g2_if_reg, DDSUSP)) == 0x7c); +static_assert((offsetof (struct g2_if_reg, G2ID)) == 0x80); +static_assert((offsetof (struct g2_if_reg, G2DSTO)) == 0x90); +static_assert((offsetof (struct g2_if_reg, G2TRTO)) == 0x94); +static_assert((offsetof (struct g2_if_reg, G2MDMTO)) == 0x98); +static_assert((offsetof (struct g2_if_reg, G2MDMW)) == 0x9c); +static_assert((offsetof (struct g2_if_reg, G2APRO)) == 0xbc); +static_assert((offsetof (struct g2_if_reg, ADSTAGD)) == 0xc0); +static_assert((offsetof (struct g2_if_reg, ADSTARD)) == 0xc4); +static_assert((offsetof (struct g2_if_reg, ADLEND)) == 0xc8); +static_assert((offsetof (struct g2_if_reg, E1STAGD)) == 0xd0); +static_assert((offsetof (struct g2_if_reg, E1STARD)) == 0xd4); +static_assert((offsetof (struct g2_if_reg, E1LEND)) == 0xd8); +static_assert((offsetof (struct g2_if_reg, E2STAGD)) == 0xe0); +static_assert((offsetof (struct g2_if_reg, E2STARD)) == 0xe4); +static_assert((offsetof (struct g2_if_reg, E2LEND)) == 0xe8); +static_assert((offsetof (struct g2_if_reg, DDSTAGD)) == 0xf0); +static_assert((offsetof (struct g2_if_reg, DDSTARD)) == 0xf4); +static_assert((offsetof (struct g2_if_reg, DDLEND)) == 0xf8); -struct pvr_reg { - uint32_t PDSTAP; /* PVR-DMA start address */ - uint32_t PDSTAR; /* PVR-DMA system memory start address */ - uint32_t PDLEN; /* PVR-DMA length */ - uint32_t PDDIR; /* PVR-DMA direction */ - uint32_t PDTSEL; /* PVR-DMA trigger select */ - uint32_t PDEN; /* PVR-DMA enable */ - uint32_t PDST; /* PVR-DMA start */ - uint8_t _pad0[100]; - uint32_t PDAPRO; /* PVR-DMA address range */ - uint8_t _pad1[108]; - uint32_t PDSTAPD; /* PVR-DMA address counter (on Ext) */ - uint32_t PDSTARD; /* PVR-DMA address counter (on root bus) */ - uint32_t PDLEND; /* PVR-DMA transfer counter */ +struct pvr_if_reg { + reg32 PDSTAP; /* PVR-DMA start address */ + reg32 PDSTAR; /* PVR-DMA system memory start address */ + reg32 PDLEN; /* PVR-DMA length */ + reg32 PDDIR; /* PVR-DMA direction */ + reg32 PDTSEL; /* PVR-DMA trigger select */ + reg32 PDEN; /* PVR-DMA enable */ + reg32 PDST; /* PVR-DMA start */ + reg8 _pad0[100]; + reg32 PDAPRO; /* PVR-DMA address range */ + reg8 _pad1[108]; + reg32 PDSTAPD; /* PVR-DMA address counter (on Ext) */ + reg32 PDSTARD; /* PVR-DMA address counter (on root bus) */ + reg32 PDLEND; /* PVR-DMA transfer counter */ }; -static_assert((offsetof (struct pvr_reg, PDSTAP)) == 0x0); -static_assert((offsetof (struct pvr_reg, PDSTAR)) == 0x4); -static_assert((offsetof (struct pvr_reg, PDLEN)) == 0x8); -static_assert((offsetof (struct pvr_reg, PDDIR)) == 0xc); -static_assert((offsetof (struct pvr_reg, PDTSEL)) == 0x10); -static_assert((offsetof (struct pvr_reg, PDEN)) == 0x14); -static_assert((offsetof (struct pvr_reg, PDST)) == 0x18); -static_assert((offsetof (struct pvr_reg, PDAPRO)) == 0x80); -static_assert((offsetof (struct pvr_reg, PDSTAPD)) == 0xf0); -static_assert((offsetof (struct pvr_reg, PDSTARD)) == 0xf4); -static_assert((offsetof (struct pvr_reg, PDLEND)) == 0xf8); +static_assert((offsetof (struct pvr_if_reg, PDSTAP)) == 0x0); +static_assert((offsetof (struct pvr_if_reg, PDSTAR)) == 0x4); +static_assert((offsetof (struct pvr_if_reg, PDLEN)) == 0x8); +static_assert((offsetof (struct pvr_if_reg, PDDIR)) == 0xc); +static_assert((offsetof (struct pvr_if_reg, PDTSEL)) == 0x10); +static_assert((offsetof (struct pvr_if_reg, PDEN)) == 0x14); +static_assert((offsetof (struct pvr_if_reg, PDST)) == 0x18); +static_assert((offsetof (struct pvr_if_reg, PDAPRO)) == 0x80); +static_assert((offsetof (struct pvr_if_reg, PDSTAPD)) == 0xf0); +static_assert((offsetof (struct pvr_if_reg, PDSTARD)) == 0xf4); +static_assert((offsetof (struct pvr_if_reg, PDLEND)) == 0xf8); + +extern struct system_reg SYSTEM __asm("SYSTEM"); + +extern struct maple_if_reg MAPLE_IF __asm("MAPLE_IF"); + +extern struct g1_if_reg G1_IF __asm("G1_IF"); + +extern struct g2_if_reg G2_IF __asm("G2_IF"); + +extern struct pvr_if_reg PVR_IF __asm("PVR_IF"); diff --git a/test.c b/test.c new file mode 100644 index 0000000..05f2a08 --- /dev/null +++ b/test.c @@ -0,0 +1,147 @@ +#include "type.h" + +#include "rgb.h" +#include "vga.h" +#include "systembus.h" +#include "holly.h" + +void *memcpy(void *restrict dest, const void *restrict src, size_t n) +{ + unsigned char *d = dest; + const unsigned char *s = src; + for (; n; n--) *d++ = *s++; + return dest; +} + +void start(void) +{ + /* + G2_IF.ADEN = 0; + G2_IF.E1EN = 0; + G2_IF.E2EN = 0; + G2_IF.DDEN = 0; + G1_IF.GDEN = 0; + MAPLE_IF.MDEN = 0; + G2_IF.G2APRO = 0x4659404f; + */ + + HOLLY.SOFTRESET = 0b111; + HOLLY.TEXT_CONTROL = 3; + + uint16_t xsize = 640; + uint16_t ysize = 480; + + uint16_t fb_xclip_min = 0; + uint16_t fb_xclip_max = xsize-1; + HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0); + uint16_t fb_yclip_min = 0; + uint16_t fb_yclip_max = ysize-1; + HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0); + + uint32_t fb_xsize = (xsize * 16)/(32) - 1; + uint32_t fb_ysize = ysize - 3; + uint32_t fb_mod = 1; + HOLLY.FB_R_SIZE = 0 + | (fb_xsize << 0) + | (fb_ysize << 10) + | (fb_mod << 20); + + uint32_t fb_linestride = (xsize * 16) / 64; + HOLLY.FB_W_LINESTRIDE = fb_linestride; + + HOLLY.FB_W_CTRL = 0 + | 0b001 << 0 // fb_packmode: RGB 565 + ; + + HOLLY.FB_R_CTRL = 0 + | 1 << 23 // vclk_div + | 0 << 22 // fb_strip_buf_en + | 0 << 16 // fb_strip_size + | 0 << 8 // fb_chroma_threshold + | 0 << 4 // fb_concat + | 1 << 2 // fb_depth + | 0 << 1 // fb_line_double + | 1 << 0 // fb_enable + ; + + HOLLY.FB_W_SOF1 = 0; + HOLLY.FB_W_SOF2 = 0; + HOLLY.FB_R_SOF1 = 0; + HOLLY.FB_R_SOF2 = 0; + + HOLLY.VO_BORDER_COL = (31 << 11) | (31 << 0); + + uint16_t startx = 0x0a8; + uint16_t starty = 0x028; + HOLLY.VO_STARTX = startx; + HOLLY.VO_STARTY = (starty << 16) | (starty << 0); + + HOLLY.SPG_CONTROL = (1 << 8); // sync_direction__output ; non-default + + uint16_t hbstart = 0x0345; // default + uint16_t hbend = 0x007e; // default + HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0); + + uint16_t hcount = 0x0359; // default + uint16_t vcount = 0x020c; // non-default + HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0); + + uint16_t vbstart = 0x0208; // non-default + uint16_t vbend = 0x0028; // non-default + HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0); + + uint16_t hswidth = 0x003f; + uint16_t vswidth = 0x0003; + uint16_t bpwidth = 0x0319; + uint16_t eqwidth = 0x000f; + HOLLY.SPG_WIDTH = + (hswidth << 0) + | (vswidth << 8) + | (bpwidth << 12) + | (eqwidth << 22); + + HOLLY.SPG_HBLANK_INT = hbstart << 16; + + uint32_t hsync_pol = 0; + uint32_t vsync_pol = 0; + uint32_t blank_pol = 0; + uint32_t blank_video = 0; + uint32_t field_mode = 0; + uint32_t pixel_double = 0; + uint32_t pclk_delay = 0x16; + HOLLY.VO_CONTROL = 0 + | (( pclk_delay & 0x3f) << 16 ) + | (( pixel_double & 0x01) << 8 ) + | (( field_mode & 0x0f) << 4 ) + | (( blank_video & 0x01) << 3 ) + | (( blank_pol & 0x01) << 2 ) + | (( vsync_pol & 0x01) << 1 ) + | (( hsync_pol & 0x01) << 0 ); + + + HOLLY.SOFTRESET = 0b000; + + reg16 * vram = (reg16 *)0xa5000000; + v_sync_in(); + for (int y = 0; y < 480; y++) { + for (int x = 0; x < 640; x++) { + /* + struct hsv hsv = {(y * 255) / 480, 255, 255}; + struct rgb rgb = hsv_to_rgb(hsv); + vram[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0); + */ + vram[y * 640 + x] = 30 << 5 | 31 << 11; + } + } + vram[0] = 0xffff; + vram[10] = 0xffff; + vram[639] = 0xffff; + vram[307199 - (640 * 3) - 1] = 0xffff; + vram[307199 - (640 * 2) - 10] = 31 << 11; + vram[307199 - (640 * 1) - 1] = 0xffff; + //vram[307199 - (640 * 2) - 10] = 0xf0ff; + //vram[307199 - 640 - 10] = 0xf0ff; + //vram[307199 - 10] = 0xf0ff; + //vram[307199] = 0xf0ff; + +} diff --git a/vga.c b/vga.c new file mode 100644 index 0000000..a0d0308 --- /dev/null +++ b/vga.c @@ -0,0 +1,193 @@ +#include + +#include "sh7091.h" +#include "sh7091_bits.h" +#include "holly.h" + +#include "vga.h" +#include "rgb.h" + +uint32_t get_cable_type() +{ + /* set all pins to input */ + SH7091.BSC.PCTRA = 0; + + /* get cable type from pins 9 + 8 */ + return SH7091.BSC.PDTRA & PDTRA__MASK; +} + +void vga1() +{ + uint32_t fb_r_ctrl = HOLLY.FB_R_CTRL; + HOLLY.FB_R_CTRL = fb_r_ctrl & ~(1 << 0); // fb_enable = 0 + uint32_t blank_video = 1; + HOLLY.VO_CONTROL |= (blank_video << 3); // blank_video + + HOLLY.FB_R_SIZE = 0; + + uint32_t vblank_in = 0x0208; + uint32_t vblank_out = 0x0015; + HOLLY.SPG_VBLANK_INT = (vblank_out << 16) | (vblank_in << 0); + + uint32_t sync_direction = 1; + HOLLY.SPG_CONTROL = (sync_direction << 8); + + uint32_t hbstart = 0x0345; // default + uint32_t hbend = 0x007e; // default + HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0); + + uint32_t hcount = 0x0359; // default + uint32_t vcount = 0x020c; // non-default + HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0); + + uint32_t vbstart = 0x0208; // non-default + uint32_t vbend = 0x0028; // non-default + HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0); + + uint32_t hswidth = 0x003f; + uint32_t vswidth = 0x0003; + uint32_t bpwidth = 0x0319; + uint32_t eqwidth = 0x000f; + HOLLY.SPG_WIDTH = + (hswidth << 0) + | (vswidth << 8) + | (bpwidth << 12) + | (eqwidth << 22); + + uint32_t startx = 0x0a8; + uint32_t starty = 0x028; + HOLLY.VO_STARTX = startx; + HOLLY.VO_STARTY = (starty << 16) | (starty << 0); + + HOLLY.SPG_HBLANK_INT = hbstart << 16; +} + +void vga2() +{ + HOLLY.FB_BURSTCTRL = 0x00093f39; + + uint32_t xsize = 640; + uint32_t ysize = 480; + + uint32_t fb_xclip_min = 0; + uint32_t fb_xclip_max = xsize-1; + HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0); + uint32_t fb_yclip_min = 0; + uint32_t fb_yclip_max = ysize-1; + HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0); + + uint32_t fb_xsize = (xsize * 16)/(32) - 1; + uint32_t fb_ysize = ysize - 3; + uint32_t fb_mod = 1; + HOLLY.FB_R_SIZE = 0 + | (fb_xsize << 0) + | (fb_ysize << 10) + | (fb_mod << 20); + + uint32_t coeff0 = 0x40; + uint32_t coeff1 = 0x80; + HOLLY.Y_COEFF = (coeff1 << 8) | (coeff0 << 0); + + uint32_t vscale_factor = 0x0400; + HOLLY.SCALER_CTL = (vscale_factor << 0); + + uint32_t fb_linestride = (xsize * 16) / 64; + HOLLY.FB_W_LINESTRIDE = fb_linestride; + + HOLLY.FB_W_CTRL = 0 + | 0b001 << 0 // fb_packmode: RGB 565 + ; + + HOLLY.FB_W_SOF1 = 0; + HOLLY.FB_W_SOF2 = 0; + HOLLY.FB_R_SOF1 = 0; + HOLLY.FB_R_SOF2 = 0; + + HOLLY.FB_R_CTRL = 0 + | 1 << 23 // vclk_div + | 0 << 22 // fb_strip_buf_en + | 0 << 16 // fb_strip_size + | 0 << 8 // fb_chroma_threshold + | 0 << 4 // fb_concat + | 1 << 2 // fb_depth + | 0 << 1 // fb_line_double + | 1 << 0 // fb_enable + ; + + uint32_t hsync_pol = 0; + uint32_t vsync_pol = 0; + uint32_t blank_pol = 0; + uint32_t blank_video = 0; + uint32_t field_mode = 0; + uint32_t pixel_double = 0; + uint32_t pclk_delay = 0x16; + HOLLY.VO_CONTROL = 0 + | (( pclk_delay & 0x3f) << 16 ) + | (( pixel_double & 0x01) << 8 ) + | (( field_mode & 0x0f) << 4 ) + | (( blank_video & 0x01) << 3 ) + | (( blank_pol & 0x01) << 2 ) + | (( vsync_pol & 0x01) << 1 ) + | (( hsync_pol & 0x01) << 0 ); + + *((reg32 *)0xa0702c00) = 0; +} + +void v_sync_in() +{ +#define V_SYNC (1<<13) + while (!(V_SYNC & HOLLY.SPG_STATUS)) { + asm volatile ("nop"); + } + while ((V_SYNC & HOLLY.SPG_STATUS)) { + asm volatile ("nop"); + } +#undef V_SYNC +} + +void v_sync_out() +{ +#define V_SYNC (1<<13) + while ((V_SYNC & HOLLY.SPG_STATUS)) { + asm volatile ("nop"); + } + while (!(V_SYNC & HOLLY.SPG_STATUS)) { + asm volatile ("nop"); + } +#undef V_SYNC +} + +void vga() +{ + get_cable_type(); + + HOLLY.SOFTRESET = 0b111; + HOLLY.TEXT_CONTROL = 3; + HOLLY.FB_W_CTRL = 9; + + /* + */ + vga1(); + vga2(); + + v_sync_in(); + + HOLLY.VO_BORDER_COL = (63 << 5) | (31 << 0); + HOLLY.VO_CONTROL = 0x0016; + + HOLLY.SOFTRESET = 0b000; +} + +void fill_framebuffer() +{ + reg16 * vram = (reg16 *)0xa5000000; + for (int y = 0; y < 480; y++) { + for (int x = 0; x < 640; x++) { + struct hsv hsv = {(y * 255) / 480, 255, 255}; + struct rgb rgb = hsv_to_rgb(hsv); + vram[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0); + } + } + vram[0] = 0xf0ff; + vram[10] = 0xf0ff; +} diff --git a/vga.h b/vga.h new file mode 100644 index 0000000..3555293 --- /dev/null +++ b/vga.h @@ -0,0 +1,5 @@ +#pragma once + +void vga(); +void v_sync_in(); +void v_sync_out();