diff --git a/alt.lds b/alt.lds index 71bdccc..18b36ba 100644 --- a/alt.lds +++ b/alt.lds @@ -39,6 +39,12 @@ SECTIONS *(.bss.*) } > p1ram + .text.p2ram ALIGN(4) : SUBALIGN(4) + { + *(.p2ram) + *(.p2ram.*) + } > p1ram + __p1ram_end = .; /DISCARD/ : diff --git a/client.py b/client.py index 402351c..656a2eb 100644 --- a/client.py +++ b/client.py @@ -3,36 +3,57 @@ import struct import sys import time +#dest = 0xac21_0000 dest = 0xac02_0000 ret = [] -def sync(ser, b): +def sync(ser, b, wait=1): 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) + time.sleep(1000 / 1000000) + if ser.in_waiting == 0: + time.sleep(0.01) while ser.in_waiting > 0: res = ser.read(ser.in_waiting) - for c in res: - l.append(c) + l.extend(res) time.sleep(0.01) - time.sleep(1) + time.sleep(wait) res = ser.read(ser.in_waiting) - for c in res: - l.append(c) + l.extend(res) + + return bytes(l) + +def symmetric(ser, b): + l = [] + for i, c in enumerate(b): + if i % 32 == 0: + print(i, end=' ') + sys.stdout.flush() + while True: + if ser.in_waiting: + res = ser.read(ser.in_waiting) + l.extend(res) + if len(l) + 8 >= i: + break + else: + time.sleep(0.001) + + ser.write(bytes([c])) + + time.sleep(0.1) + res = ser.read(ser.in_waiting) + l.extend(res) return bytes(l) def do(ser, b): - ser.read(ser.in_waiting) + _ = ser.read(ser.in_waiting) ser.flush() ser.flushInput() ser.flushOutput() @@ -45,15 +66,19 @@ def do(ser, b): print("dargs", args) ret = sync(ser, args) print(ret) + if ret != b'data\n': + do(ser, b) - ret = sync(ser, b) + ret = symmetric(ser, b) print(ret[-5:]) if ret[:-5] != b: print("ret != b; dumped to asdf.bin") with open('asdf.bin', 'wb') as f: f.write(ret[:-5]) + print("did not jump") + return - ret = sync(ser, b'JUMP') + ret = sync(ser, b'JUMP', wait=0) args = struct.pack("(buf); @@ -35,15 +37,15 @@ void background_parameter(volatile uint32_t * buf) parameter->vertex[0].x = 0.f; parameter->vertex[0].y = 0.f; parameter->vertex[0].z = 1.f/100000; - parameter->vertex[0].base_color = 0xff300000; + parameter->vertex[0].base_color = 0x00000000; - parameter->vertex[1].x = 0.f; - parameter->vertex[1].y = 480.f; + parameter->vertex[1].x = 639.f; + parameter->vertex[1].y = 0.f; parameter->vertex[1].z = 1.f/100000; - parameter->vertex[1].base_color = 0xff300000; + parameter->vertex[1].base_color = 0x00000000; - parameter->vertex[2].x = 640.f; - parameter->vertex[2].y = 0.f; + parameter->vertex[2].x = 639.f; + parameter->vertex[2].y = 479.f; parameter->vertex[2].z = 1.f/100000; - parameter->vertex[2].base_color = 0xff300000; + parameter->vertex[2].base_color = 0x00000000; } diff --git a/holly/region_array.cpp b/holly/region_array.cpp index 3052b79..64e139a 100644 --- a/holly/region_array.cpp +++ b/holly/region_array.cpp @@ -45,7 +45,10 @@ void region_array(volatile uint32_t * buf, for (uint32_t y = 0; y < height; y++) { for (uint32_t x = 0; x < width; x++) { region_array[ix].tile = REGION_ARRAY__TILE_Y_POSITION(y) - | REGION_ARRAY__TILE_X_POSITION(x); + | REGION_ARRAY__TILE_X_POSITION(x); + + if (y == (height - 1) && x == (width - 1)) + region_array[ix].tile |= REGION_ARRAY__LAST_REGION; uint32_t tile_index = y * width + x; constexpr uint32_t opaque_list_opb_size = 16 * 4; // in bytes; this must match O_OPB in TA_ALLOC_CTRL diff --git a/load.cpp b/load.cpp index 0184672..49b1b7d 100644 --- a/load.cpp +++ b/load.cpp @@ -1,6 +1,7 @@ #include #include "sh7091.h" +#include "sh7091_bits.h" #include "holly.h" enum load_command { @@ -47,6 +48,7 @@ void debug(const char * s) { char c; while ((c = *s++)) { + while ((sh7091.SCIF.SCFSR2 & SCFSR2__TDFE) == 0); sh7091.SCIF.SCFTDR2 = (uint8_t)c; } } diff --git a/main.cpp b/main.cpp index c475e78..2924ea5 100644 --- a/main.cpp +++ b/main.cpp @@ -7,6 +7,9 @@ #include "sh7091.h" #include "sh7091_bits.h" #include "memorymap.h" +#include "systembus.h" +#include "holly.h" +#include "holly/core_bits.h" #include "rgb.h" #include "scene.h" @@ -30,6 +33,22 @@ void serial() sh7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE; } +inline void serial_char(const char c) +{ + // wait for transmit fifo to become empty + while ((sh7091.SCIF.SCFSR2 & SCFSR2__TDFE) == 0); + + sh7091.SCIF.SCFTDR2 = static_cast(c); +} + +void serial_string(const char * s) +{ + return; + while (*s != '\0') { + serial_char(*s++); + } +} + extern "C" void main() { @@ -42,7 +61,7 @@ void main() *start++ = 0; } - serial(); + //serial(); vga(); @@ -58,39 +77,31 @@ void main() } + holly.SOFTRESET = softreset::pipeline_soft_reset + | softreset::ta_soft_reset; + holly.SOFTRESET = 0; + + system.LMMODE0 = 1; + system.LMMODE1 = 1; + + v_sync_out(); + v_sync_in(); + scene_holly_init(); + scene_init_texture_memory(); + + int frame = 0; + while (1) { - v_sync_in(); - scene_holly_init(); - scene_init_texture_memory(); scene_ta_init(); scene_geometry_transfer(); scene_wait_opaque_list(); - scene_start_render(); + scene_start_render(frame); + frame = !frame; // I do not understand why, but flycast does not show the first-rendered // framebuffer. + + v_sync_out(); v_sync_in(); - scene_ta_init(); - scene_geometry_transfer(); - scene_wait_opaque_list(); - scene_start_render(); - - // do nothing forever - while(1); - - /* - load_init(); - - while (1) { - while ((sh7091.SCIF.SCFSR2 & SCFSR2__RDF) == 0) { - // wait - } - 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/scene.cpp b/scene.cpp index f452764..7123887 100644 --- a/scene.cpp +++ b/scene.cpp @@ -3,8 +3,10 @@ #include "holly/region_array.h" #include "holly/background.h" #include "holly/ta_parameter.h" +#include "holly/core_bits.h" #include "holly.h" #include "ta.h" +#include "sh7091.h" #include "memorymap.h" #include "storequeue.h" @@ -17,13 +19,20 @@ struct texture_memory_alloc { uint32_t _res0[ 0x20 / 4]; // (the TA may clobber 4 bytes starting at TA_OL_LIMIT) uint32_t region_array[0x00002000 / 4]; // REGION_BASE uint32_t background[0x00000020 / 4]; // ISP_BACKGND_T - uint32_t framebuffer[0x00096000 / 4]; // FB_R_SOF1 / FB_W_SOF1 + uint32_t framebuffer[2][0x00096000 / 4]; // FB_R_SOF1 / FB_W_SOF1 }; +/* + 0,-.5 + | + --- + -0.5,0.5 | 0.5,0.5 + */ + float scene_triangle[3][3] = { - { 320.f, 120.f, 1/10.f}, - { 440.f, 360.f, 1/10.f}, - { 200.f, 360.f, 1/10.f}, + { 0.f, -0.5f, 1/10.f}, + { 0.5f, 0.5f, 1/10.f}, + { -0.5f, 0.5f, 1/10.f}, }; void scene_holly_init() @@ -83,9 +92,10 @@ void scene_ta_init() holly.TA_ISP_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); holly.TA_ISP_LIMIT = (offsetof (struct texture_memory_alloc, object_list)); // the end of isp_tsp_parameters holly.TA_OL_BASE = (offsetof (struct texture_memory_alloc, object_list)); - holly.TA_OL_LIMIT = (offsetof (struct texture_memory_alloc, region_array)); // the end of the object_list - holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)) - + (640 / 32) * (320 / 32) * 16 * 4; + holly.TA_OL_LIMIT = (offsetof (struct texture_memory_alloc, _res0)); // the end of the object_list + holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)); + //holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)) + // + (640 / 32) * (320 / 32) * 16 * 4; holly.TA_LIST_INIT = TA_LIST_INIT__LIST_INIT; @@ -100,8 +110,12 @@ void scene_wait_opaque_list() system.ISTNRM = SB_ISTNRM__TAEOINT; } +static float theta = 0; +constexpr float degree = 0.01745329f; + void scene_geometry_transfer() { + /* triangle(store_queue); sq_transfer_32byte(ta_fifo_polygon_converter); @@ -120,6 +134,50 @@ void scene_geometry_transfer() end_of_list(store_queue); sq_transfer_32byte(ta_fifo_polygon_converter); + */ + uint32_t __attribute__((aligned(32))) scene[(32 * 5) / 4]; + triangle(&scene[(32 * 0) / 4]); + for (int i = 0; i < 3; i++) { + bool end_of_strip = i == 2; + + float x = scene_triangle[i][0]; + float y = scene_triangle[i][1]; + + x = x * __builtin_cosf(theta) - y * __builtin_sinf(theta); + y = x * __builtin_sinf(theta) + y * __builtin_cosf(theta); + x *= 240.f; + y *= 240.f; + x += 320.f; + y += 240.f; + + vertex(&scene[(32 * (i + 1)) / 4], + x, // x + y, // y + scene_triangle[i][2], // z + 0xffff00ff, // base_color + end_of_strip); + } + end_of_list(&scene[(32 * 4) / 4]); + theta += degree; + + volatile uint32_t _dummy = sh7091.DMAC.CHCR2; + (void)_dummy; + sh7091.DMAC.CHCR2 = 0; + sh7091.DMAC.SAR2 = reinterpret_cast(&scene[0]); + sh7091.DMAC.DMATCR2 = (32 * 5) / 32; + // SM(1) {source address increment} + // | RS(2) {external request, single address mode} + // | TM {burst mode} + // | TS(2) {32-byte block} + // | DE {enable channel} + sh7091.DMAC.CHCR2 = 0x12c1; + sh7091.DMAC.DMAOR = 0x8201; + system.C2DSTAT = 0x10000000; + system.C2DLEN = 32 * 5; + system.C2DST = 1; + + while ((system.ISTNRM & (1 << 19)) == 0); + system.ISTNRM = (1 << 19); } void scene_init_texture_memory() @@ -134,7 +192,7 @@ void scene_init_texture_memory() ); } -void scene_start_render() +void scene_start_render(int fb) { holly.REGION_BASE = (offsetof (struct texture_memory_alloc, region_array)); holly.PARAM_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); @@ -144,10 +202,17 @@ void scene_start_render() | ISP_BACKGND_T__SKIP(1); holly.ISP_BACKGND_D = _i(1.f/100000); - holly.FB_W_CTRL = FB_W_CTRL__FB_PACKMODE__565_RGB; - holly.FB_W_LINESTRIDE = 640 / 8; - holly.FB_W_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)); - holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)); + //holly.SOFTRESET = softreset::pipeline_soft_reset; + + holly.FB_W_CTRL = 1 << 3 | FB_W_CTRL__FB_PACKMODE__565_RGB; + holly.FB_W_LINESTRIDE = (640 * 2) / 8; + + int w_fb = (!(!fb)) * 0x00096000; + int r_fb = (!fb) * 0x00096000; + holly.FB_W_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + w_fb; + holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + r_fb; + + //holly.SOFTRESET = 0; holly.STARTRENDER = 1; } diff --git a/scene.h b/scene.h index ad77bce..0326f6b 100644 --- a/scene.h +++ b/scene.h @@ -5,4 +5,4 @@ void scene_ta_init(); void scene_init_texture_memory(); void scene_geometry_transfer(); void scene_wait_opaque_list(); -void scene_start_render(); +void scene_start_render(int fb); diff --git a/serial_main.cpp b/serial_main.cpp new file mode 100644 index 0000000..e3d0d4a --- /dev/null +++ b/serial_main.cpp @@ -0,0 +1,32 @@ +#include "sh7091.h" +#include "sh7091_bits.h" + +#include "cache.h" +#include "load.h" + +extern uint32_t __bss_link_start __asm("__bss_link_start"); +extern uint32_t __bss_link_end __asm("__bss_link_end"); + +void main() +{ + cache_init(); + + uint32_t * start = &__bss_link_start; + uint32_t * end = &__bss_link_end; + while (start < end) { + *start++ = 0; + } + + load_init(); + + while (1) { + while ((sh7091.SCIF.SCFSR2 & SCFSR2__TDFE) == 0) { + // wait + } + 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/sh7091_bits.h b/sh7091_bits.h index c0807d5..794b464 100644 --- a/sh7091_bits.h +++ b/sh7091_bits.h @@ -22,7 +22,7 @@ #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__TDFE (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 */ diff --git a/storequeue.cpp b/storequeue.cpp index e3d05ed..be5f210 100644 --- a/storequeue.cpp +++ b/storequeue.cpp @@ -4,7 +4,8 @@ void sq_transfer_32byte(volatile void * dst) { // dst typically 0x10000000 (ta polygon converter) - sh7091.CCN.QACR0 = ((reinterpret_cast(dst) >> 26) & 0b111) << 2; + //sh7091.CCN.QACR0 = ((reinterpret_cast(dst) >> 26) & 0b111) << 2; + sh7091.CCN.QACR0 = 0xac; // start 32-byte transfer from store queue 0 (SQ0) to QACR0 asm volatile ("pref @%0" diff --git a/vga.cpp b/vga.cpp index 4720a30..aaaa3e7 100644 --- a/vga.cpp +++ b/vga.cpp @@ -136,6 +136,9 @@ void vga() | vo_border_col::blue(0x00); holly.VO_CONTROL = vo_control::pclk_delay(0x16); + holly.SDRAM_CFG = 0x15D1C951; + holly.SDRAM_REFRESH = 0x00000020; + v_sync_in(); holly.SOFTRESET = 0;