diff --git a/bsxmac.xcodeproj/project.pbxproj b/bsxmac.xcodeproj/project.pbxproj index 2c40a38..7882fcc 100644 --- a/bsxmac.xcodeproj/project.pbxproj +++ b/bsxmac.xcodeproj/project.pbxproj @@ -7,8 +7,6 @@ objects = { /* Begin PBXFileReference section */ - B309DC412C489D4500A7FE20 /* sdl_events.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sdl_events.h; sourceTree = ""; }; - B309DC422C489D4500A7FE20 /* sdl_events.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sdl_events.c; sourceTree = ""; }; B334DFC62C485851001B5E35 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; B334DFC72C485851001B5E35 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; B334DFC82C485851001B5E35 /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cpu.c; sourceTree = ""; }; @@ -35,16 +33,14 @@ B334DFDD2C485851001B5E35 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; B334DFDE2C485851001B5E35 /* video.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = video.c; sourceTree = ""; }; B334DFDF2C485851001B5E35 /* video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = video.h; sourceTree = ""; }; - B3C64FF12C496BE3005A12B6 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - B3C64FF22C496BF4005A12B6 /* todo.org */ = {isa = PBXFileReference; lastKnownFileType = text; path = todo.org; sourceTree = ""; }; + B39316E82C63CE84008E5892 /* controllers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = controllers.c; sourceTree = ""; }; + B39316E92C63CE84008E5892 /* controllers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = controllers.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ B334DFBB2C4857EB001B5E35 = { isa = PBXGroup; children = ( - B3C64FF22C496BF4005A12B6 /* todo.org */, - B3C64FF12C496BE3005A12B6 /* README.md */, B334DFC62C485851001B5E35 /* Makefile */, B334DFE02C485851001B5E35 /* src */, ); @@ -78,8 +74,8 @@ B334DFDD2C485851001B5E35 /* util.h */, B334DFDE2C485851001B5E35 /* video.c */, B334DFDF2C485851001B5E35 /* video.h */, - B309DC422C489D4500A7FE20 /* sdl_events.c */, - B309DC412C489D4500A7FE20 /* sdl_events.h */, + B39316E92C63CE84008E5892 /* controllers.h */, + B39316E82C63CE84008E5892 /* controllers.c */, ); path = src; sourceTree = ""; diff --git a/doc/detailed-memory-map.org b/doc/detailed-memory-map.org new file mode 100644 index 0000000..205e487 --- /dev/null +++ b/doc/detailed-memory-map.org @@ -0,0 +1,105 @@ +* I/O is at $00:df00 - $00:dfff, and is always mapped in. + *note* Any RAM that might also be mapped to this range is ignored. + +* ROM0 logic + ROM0 low if CS4 XOR CS7 low. + +* Booted Memory Map + $00:0000-$00:deff : SRAM + -- *todo* where will direct page & stack be? -- + $00:df00-$00:dfff : I/O + $df00-$00:df1f : VERA + $df20 : PD4 (data register, port 4) + $df21 : PD5 (data register, port 5) + $df22 : PD6 (data register, port 6) + $df23 : PD7 (data register, port 7) + $df24 : PDD4 (direction register, port 4) + $df25 : PDD5 (direction register, port 5) + $df26 : PDD6 (direction register, port 6) + $df27 : PCS7 (port 7 chip select) + | --- | ---- | ----------------- | ---------- | ----------------------------------------------------------------------- | + | bit | name | address | booted val | notes | + | --- | ---- | ----------------- | ---------- | ----------------------------------------------------------------------- | + | 7 | CS7 | $c0:0000-$ff:ffff | 1 | Used with CS4 to generate ROM0 | + | 6 | CS6 | $40:0000-$bf:ffff | 1 | Wired to cartridge and expansion ports. | + | 5 | CS5 | $00:0000-$3f:ffff | 1 | Enables SRAM | + | 4 | CS4 | $00:8000-$00:ffff | 0 | Used during boot, disabled afterwards. Used with CS7 to generate ROM0. | + | 3 | CS3 | | 0 | Used as GPIO (which port?) | + | 2 | CS2 | | 0 | Used as GPIO (which port?) | + | 1 | CS1 | $00:dfc0-$00:dfff | 1 | 0 = PIB SRAM, 1 = Clock Port | + | 0 | CS0 | $00:df00-$00:df1f | 1 | 0 = GPIO control, 1 = VERA | + | --- | ---- | ----------------- | ---------- | ----------------------------------------------------------------------- | + $df28-df3f : unused / reserved + $df40 : BCR (bus control register) + bit 0: 0: address & data pins are GPIO + 1: address & data pins are buses. + *note* we always have this set to 1. + $df41 : SSCR (system speed control register) + $df42 : TCR (timer control register) + $df43 : TER (timer enable register) + $df44 : TIFR (timer interrupt flag register) + $df45 : EIFR (edge interrupt enable register) + $df46 : TIER (timer interrupt enable register) + $df47 : EIER (edge interrupt enable register) + $df48 : UIFR (UART interrupt flag register) + $df49 : UIER (UART interrupt enable register) + $df4a-df4f : unused / reserved + [$df50-df6f : timer register memory map] + $df5a : T5LL (Timer 5 Latch Low) + $df5b : T5LH (Timer 5 Latch High) + $df6a : T5CL (Timer 5 Counter Low) + $df6b : T5CH (Timer 5 Counter High) + [$df70-dfbf : Communication Registers (2.5.1)] + *todo* not sure what we use from here yet. + $dfc0-dfff : Clock Port (64 bytes) + $00:e000-$00:ffff : SRAM + $01:0000-$3f:ffff : SRAM + $04:0000-$bf:ffff : Cartridge & Expansion + $c0:0000-$ff:ffff : ROM + +* timers & special IRQs + *todo* irne64 - !VIRQ + *todo* irqt5 + +* cpu pins to signals note: !xyz should be interpreted as xyz with overline + | ---- | ---------- | -------------- | -------------- | ----------- | ----------- | ------------- | ----------- | + | pin# | pin name | signal (I/O) | control bit | signal cb 0 | signal cb 1 | direction reg | data reg | + | ---- | ---------- | -------------- | -------------- | ----------- | ----------- | ------------- | ----------- | + | 5 | p4.5 (P45) | MISO (I) | PIBER0 | P45 | PIRS0 | PDD4 $df24:5 | PD4 $df20:5 | + | 6 | p4.6 (P46) | SD_CD (I) | PIBER0 | P46 | PIRS1 | PDD4 $df24:6 | PD4 $df20:6 | + | 7 | p4.7 (P47) | SD_WP (I) | PIBER0 | P47 | PIRS2 | PDD4 $df24:7 | PD4 $df20:7 | + | 8 | p5.0 (P50) | SNES_CLK (O) | PIBER0 | P50 | PID0 | PDD5 $df25:0 | PD5 $df21:0 | + | 9 | p5.1 (P51) | SNES_LATCH (O) | PIBER0 | P51 | PID1 | PDD5 $df25:1 | PD5 $df21:1 | + | 10 | p5.2 (P52) | SNES_DATA0 (I) | PIBER0 | P52 | PID2 | PDD5 $df25:2 | PD5 $df21:2 | + | 11 | p5.3 (P53) | SNES_DATA1 (I) | PIBER0 | P53 | PID3 | PDD5 $df25:3 | PD5 $df21:3 | + | 12 | p5.4 (P54) | SNES_DATA2 (I) | PIBER0 | P54 | PID4 | PDD5 $df25:4 | PD5 $df21:4 | + | 13 | p5.5 (P55) | SNES_DATA3 (I) | PIBER0 | P55 | PID5 | PDD5 $df25:5 | PD5 $df21:5 | + | 22 | p6.4 (P64) | !VIRQ (I) | ACSR25 | P64 | RXD2 | PDD6 $df26:4 | PD6 $df22:6 | + | 72 | !CS0 (P70) | !I/O0 (O) | PCS70 | P70 | CS0B | PCS7 $df27:0 | PD7 $df23:0 | + | 73 | !CS1 (P71) | !I/O1 (O) | PCS71 | P71 | CS1B | PCS7 $df27:1 | PD7 $df23:1 | + | 74 | p7.2 (P72) | !FLASH_SS (O) | PCS72 | P72 | CS2B | PCS7 $df27:2 | PD7 $df23:2 | + | 75 | p7.3 (P73) | SCK (O) | PCS73 | P73 | CS3B | PCS7 $df27:3 | PD7 $df23:3 | + | 80 | !CS4 (P74) | !CS4 (O) | PCS74 | P74 | CS4B | PCS7 $df27:4 | PD7 $df23:4 | + | 81 | !CS5 (P75) | !CS5 (O) | PCS75 | P75 | CS5B | PCS7 $df27:5 | PD7 $df23:5 | + | 82 | !CS6 (P76) | !CS6 (O) | PCS76 | P76 | CS6B | PCS7 $df27:6 | PD7 $df23:6 | + | 83 | !CS7 (P77) | !CS7 (O) | PCS77 | P77 | CS7B | PCS7 $df27:7 | PD7 $df23:7 | + | 94 | TG0 (TG0) | TG0 (O) | TCR31 | n/a | TG0 | n/a | n/a | + | 95 | TG1 (TG1) | TG1 (O) | TCR33 | n/a | TG1 | n/a | n/a | + | 98 | p4.2 (P42) | !FPGA_RES (O) | PIBER0 | P42 | PIIB | PDD4 $df24:2 | PD4 $df20:2 | + | 99 | p4.3 (P43) | CDONE (I+O) | PIBER0*PIBER1B | P43 | PIWEB | PDD4 $df24:3 | PD4 $df20:3 | + | 100 | p4.4 (P44) | MOSI (O) | PIBER0*PIBER1B | P44 | PIRS0 | PDD4 $df24:4 | PD4 $df20:4 | + | ---- | ---------- | -------------- | -------------- | ----------- | ----------- | ------------- | ----------- | + +* How to read/write a signal? +So MISO (in the current prototype) is set to P4.5, that is, bit five of port 4. So since MISO is an input, +you would set bit five of PDD4 (port 4 data direction) to zero; then bit five of PD4 (port 4 data) will always +read the current value of that input line. [see 2.5.4 I/O Register Memory Map] I'm not sure the cb names are helpful. + +TG0 and TG1 are not usable this way; they are only available to the tone generator, which uses an internal timer +to produce a sine wave on either or both. + +SCK is currently wired to P7.2; this is a pin shared with /CS2, which is unused. We set PCS7 bit 2 to zero, and then +the state of bit 2 of PD7 will always be reflected on the pin (there is no PDD7, as port 7 is always an output). + +I/00 is a renamed /CS0, and goes low whenever memory from 0x00DF000 to 00x00DF1F is accessed as long as bit zero of PCS7 +is high. diff --git a/doc/hardware-updates.org b/doc/hardware-updates.org index 2abbe22..4effee7 100644 --- a/doc/hardware-updates.org +++ b/doc/hardware-updates.org @@ -1,5 +1,35 @@ hardware updates +* problems +** 32 bit timestamps (cycle counts) + - we use unsigned 32 bit ints for timestamps. + - "timestamps" are misnomers, they're cycle counts. + - a 32 bit int has a max value of 4,294,967,295 cycles. + at 8 Mhz, this is equivalent to 536.87 seconds, or just under 9 minutes. + - a 64 bit unsigned int has a max value of 18,446,744,073,709,551,615 + at 8 Mhz, this is equivalent to 2305843009213.69 seconds, which we'll never see. +** E_UPDATE(v) -> EMUL_hardwareUpdate(v) is confusing + - dispatch::doUpdate() calls EMUL_hardwareUpdate() based on cpu_update_period. + - cpu_update_period is a number of cycles, and roughly gives us our update resolution. + - since instructions take anywhere from 2-8 cycles, this can be slightly off. +** Need to handle timing, i.e. lock to 8 Mhz. + - VICE updates timing every video frame (60 hz.) + - We need to update our per-cycle loop based on +* possible changes + - change the naming of 'timestamp' to 'cyclecount'. + - move to 'uint64_t' instead of 'word32' for timestamp/cyclecount + -> will want to hunt down all uses of word32 to make sure of what we have. + - get rid of E_UPDATE macro. Consider renaming EMUL_hardwareUpdate to just hardwareUpdate. + + + + + + + + +* ---- old notes ---- + * hardware updates take place at regular intervals: - screen refresh (60 hz) - system timer (100 hz) diff --git a/doc/todo.org b/doc/todo.org index 3509565..e969add 100644 --- a/doc/todo.org +++ b/doc/todo.org @@ -1,28 +1,16 @@ -* DONE add 65c265 compatibility -** DONE Change hard coded vectors to defined ones based on tables below. -** DONE Change references to '260' to '262' -** DONE Change references to '1300' to '1310' -** DONE Add '0,0,' to cpu_cycle_table (5 places?) -** DONE Add 'irne64' flag (like irq flag) and appropriate code in dispatch.c - -> cpu_irne64 CPU_addIrne64()/CPU_clearIrne64 -** DONE Add 'irqt5' flag and appropriate code in dispatch.c - -> cpu_irqt5 CPU_addIrqt5()/CPU_clearIrqt5 -** DONE update table.c * TODO Need a Vera demo with new kernel code * TODO address timing - bsx just runs flat out right now, want stable 8 Mhz. - instrumentation: how fast are we going? -* TODO Rename sdl_events.c/sdl_events.h -* TODO Keyboard Device. -** TODO 1) Create a new Keyboard device. - - base this on bexemu/keyboard.c - - takes 80 bytes in memory (might want to cut this down) -** TODO 2) Patch the Keyboard device into main.c (mem read/write) - - maybe at $DF20-$DF6F -* TODO SDL_Event logic - - update sdl_events.c logic to process keyboard events and put them info memory. -* DONE Possibly rewrite dispatch loop to be more readable. - - we don't *have* to be as general as the library intends. -* TODO Add more hardware to emulation. -** TODO 65C816 Timer(s) - Start with Timer #5 for now. - - includes interrupt processing. +* TODO hardware updates + - VERA + - SDL Events (Keyboard & Controllers) + - Timer 5. -> calls CPU_addIrqt5() + *question* How do the timers work? Do they count FCLK cycles? + we might have to update timer 5 by more than 1 at a time. (i.e. depends on cycles) +* TODO add other I/O & 65c265 features +** TODO Timer 5 +** NOTE PCS7 set to post boot values is 'baked in'. Reading / Writing PCS7 should be a nop. +** TODO Keyboard / Controllers [under development] +** TODO SD Port [under development] +** TODO Clock Port [under development] diff --git a/src/sdl_events.c b/src/controllers.c similarity index 92% rename from src/sdl_events.c rename to src/controllers.c index f55830c..2ad1f92 100644 --- a/src/sdl_events.c +++ b/src/controllers.c @@ -1,5 +1,5 @@ #include "cpu.h" -#include "sdl_events.h" +#include "controllers.h" #include extern int dispatch_quit; @@ -15,11 +15,11 @@ void keyboard_init() { } -byte keyboard_read(u_int8_t register) { +byte keyboard_read(u_int8_t reg) { return 0; } -void keyboard_write(u_int8_t register, byte value) { +void keyboard_write(u_int8_t reg, byte value) { } diff --git a/src/controllers.h b/src/controllers.h new file mode 100644 index 0000000..25f21ba --- /dev/null +++ b/src/controllers.h @@ -0,0 +1,7 @@ +#ifndef controllers_h +#define controllers_h + +#include +#include + +#endif /* controllers_h */ diff --git a/src/cpu.c b/src/cpu.c index 66b9661..935b645 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -24,11 +24,7 @@ int cpu_irne64; int cpu_irqt5; word32 cpu_update_period; -#if defined( __sparc__ ) && defined( __GNUC__ ) -register word32 cpu_cycle_count asm ("g5"); -#else word32 cpu_cycle_count; -#endif void CPU_setUpdatePeriod(word32 period) { diff --git a/src/cpu.h b/src/cpu.h index cf28f89..7446939 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -111,14 +111,7 @@ extern union { /* Program Counter */ /* Current cycle count */ - -#if defined ( __sparc__ ) && defined ( __GNUC__ ) -register word32 cpu_cycle_count asm ("g5"); -#else extern word32 cpu_cycle_count; -#endif - - /* These are the core memory access macros used in the 65816 emulator. * Set these to point to routines which handle your emulated machine's diff --git a/src/sdl_events.h b/src/sdl_events.h deleted file mode 100644 index 4d85190..0000000 --- a/src/sdl_events.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef sdl_events_h -#define sdl_events_h - -#include -#include - -#endif /* sdl_events_h */ diff --git a/src/video.c b/src/video.c index b9660af..36bee07 100644 --- a/src/video.c +++ b/src/video.c @@ -185,9 +185,6 @@ uint16_t ntsc_scan_pos_y; int frame_count = 0; static uint8_t framebuffer[SCREEN_WIDTH * SCREEN_HEIGHT * 4]; -#ifndef __EMSCRIPTEN__ -static uint8_t png_buffer[SCREEN_WIDTH * SCREEN_HEIGHT * 3]; -#endif static const uint16_t default_palette[] = { 0x000,0xfff,0x800,0xafe,0xc4c,0x0c5,0x00a,0xee7,0xd85,0x640,0xf77,0x333,0x777,0xaf6,0x08f,0xbbb,0x000,0x111,0x222,0x333,0x444,0x555,0x666,0x777,0x888,0x999,0xaaa,0xbbb,0xccc,0xddd,0xeee,0xfff,0x211,0x433,0x644,0x866,0xa88,0xc99,0xfbb,0x211,0x422,0x633,0x844,0xa55,0xc66,0xf77,0x200,0x411,0x611,0x822,0xa22,0xc33,0xf33,0x200,0x400,0x600,0x800,0xa00,0xc00,0xf00,0x221,0x443,0x664,0x886,0xaa8,0xcc9,0xfeb,0x211,0x432,0x653,0x874,0xa95,0xcb6,0xfd7,0x210,0x431,0x651,0x862,0xa82,0xca3,0xfc3,0x210,0x430,0x640,0x860,0xa80,0xc90,0xfb0,0x121,0x343,0x564,0x786,0x9a8,0xbc9,0xdfb,0x121,0x342,0x463,0x684,0x8a5,0x9c6,0xbf7,0x120,0x241,0x461,0x582,0x6a2,0x8c3,0x9f3,0x120,0x240,0x360,0x480,0x5a0,0x6c0,0x7f0,0x121,0x343,0x465,0x686,0x8a8,0x9ca,0xbfc,0x121,0x242,0x364,0x485,0x5a6,0x6c8,0x7f9,0x020,0x141,0x162,0x283,0x2a4,0x3c5,0x3f6,0x020,0x041,0x061,0x082,0x0a2,0x0c3,0x0f3,0x122,0x344,0x466,0x688,0x8aa,0x9cc,0xbff,0x122,0x244,0x366,0x488,0x5aa,0x6cc,0x7ff,0x022,0x144,0x166,0x288,0x2aa,0x3cc,0x3ff,0x022,0x044,0x066,0x088,0x0aa,0x0cc,0x0ff,0x112,0x334,0x456,0x668,0x88a,0x9ac,0xbcf,0x112,0x224,0x346,0x458,0x56a,0x68c,0x79f,0x002,0x114,0x126,0x238,0x24a,0x35c,0x36f,0x002,0x014,0x016,0x028,0x02a,0x03c,0x03f,0x112,0x334,0x546,0x768,0x98a,0xb9c,0xdbf,0x112,0x324,0x436,0x648,0x85a,0x96c,0xb7f,0x102,0x214,0x416,0x528,0x62a,0x83c,0x93f,0x102,0x204,0x306,0x408,0x50a,0x60c,0x70f,0x212,0x434,0x646,0x868,0xa8a,0xc9c,0xfbe,0x211,0x423,0x635,0x847,0xa59,0xc6b,0xf7d,0x201,0x413,0x615,0x826,0xa28,0xc3a,0xf3c,0x201,0x403,0x604,0x806,0xa08,0xc09,0xf0b @@ -1180,11 +1177,8 @@ update_isr_and_coll(uint16_t y, uint16_t compare) } } -// _video_step() used to be video_step(), but it was too linked to the CPU. -// now calling a new video_step() on a 60hz frequency instead. - bool -_video_step(float mhz, float steps, bool midline) +video_step(float mhz, float steps, bool midline) { uint16_t y = 0; bool ntsc_mode = reg_composer[0] & 2; @@ -1272,16 +1266,16 @@ _video_step(float mhz, float steps, bool midline) // new video_step() does an entire frame at a time. // todo: eventually remove steps/midline params. -bool video_step(float mhz, float steps, bool midline) -{ - for (int y = 0; y < 480; y++) { - for (int x = 0; x < 640; x++) { - _video_step(mhz, 1, midline); - } - } +// bool video_step(float mhz, float steps, bool midline) +// { +// for (int y = 0; y < 480; y++) { +// for (int x = 0; x < 640; x++) { +// _video_step(mhz, 1, midline); +// } +// } - return true; -} +// return true; +// } bool video_get_irq_out() @@ -1499,7 +1493,7 @@ video_space_read_range(uint8_t* dest, uint32_t address, uint32_t size) if (address >= ADDR_VRAM_START && (address+size) <= ADDR_VRAM_END) { memcpy(dest, &video_ram[address], size); } else { - for(int i = 0; i < size; ++i) { + for(uint32_t i = 0; i < size; ++i) { *dest++ = video_space_read(address + i); } } @@ -2008,7 +2002,7 @@ video_update_title(const char* window_title) SDL_SetWindowTitle(window, window_title); } -bool video_is_tilemap_address(int addr) +bool video_is_tilemap_address(uint32_t addr) { for (int l = 0; l < 2; ++l) { struct video_layer_properties *props = &layer_properties[l]; @@ -2024,7 +2018,7 @@ bool video_is_tilemap_address(int addr) return false; } -bool video_is_tiledata_address(int addr) +bool video_is_tiledata_address(uint32_t addr) { for (int l = 0; l < 2; ++l) { struct video_layer_properties *props = &layer_properties[l]; @@ -2041,7 +2035,7 @@ bool video_is_tiledata_address(int addr) return false; } -bool video_is_special_address(int addr) +bool video_is_special_address(uint32_t addr) { return addr >= 0x1F9C0; } diff --git a/src/video.h b/src/video.h index 0ebfeee..e435cd3 100644 --- a/src/video.h +++ b/src/video.h @@ -29,9 +29,9 @@ void via1_write(uint8_t reg, uint8_t value); uint8_t video_space_read(uint32_t address); void video_space_write(uint32_t address, uint8_t value); -bool video_is_tilemap_address(int addr); -bool video_is_tiledata_address(int addr); -bool video_is_special_address(int addr); +bool video_is_tilemap_address(uint32_t addr); +bool video_is_tiledata_address(uint32_t addr); +bool video_is_special_address(uint32_t addr); uint32_t video_get_address(uint8_t sel);