# HG changeset patch # User Mike Pavone # Date 1357364829 28800 # Node ID 42c031184e8a665ce4c66ec60a2e4beb113c6e2d # Parent 79958b95526f77391d7d83d0db2b2ba249cf1b08 Implement access to Z80 RAM diff -r 79958b95526f -r 42c031184e8a blastem.c --- a/blastem.c Thu Jan 03 22:49:21 2013 -0800 +++ b/blastem.c Fri Jan 04 21:47:09 2013 -0800 @@ -9,6 +9,7 @@ #define CARTRIDGE_WORDS 0x200000 #define RAM_WORDS 32 * 1024 +#define Z80_RAM_BYTES 8 * 1024 #define MCLKS_PER_68K 7 //TODO: Figure out the exact value for this #define MCLKS_PER_FRAME (MCLKS_LINE*262) @@ -16,6 +17,7 @@ uint16_t cart[CARTRIDGE_WORDS]; uint16_t ram[RAM_WORDS]; +uint8_t z80_ram[Z80_RAM_BYTES]; io_port gamepad_1; io_port gamepad_2; @@ -275,50 +277,64 @@ m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value) { - if (location < 0x100) { - switch(location/2) - { - case 0x1: - io_data_write(&gamepad_1, context, value); - break; - case 0x2: - io_data_write(&gamepad_2, context, value); - break; - case 0x3://PORT C Data - break; - case 0x4: - gamepad_1.control = value; - break; - case 0x5: - gamepad_2.control = value; - break; + if (location < 0x10000) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; + } + if (!(busack || reset)) { + location &= 0x7FFF; + if (location < 0x4000) { + z80_ram[location & 0x1FFF] = value; + } } } else { - if (location == 0x1100) { - if (busack_cycle > context->current_cycle) { - busack = new_busack; - busack_cycle = CYCLE_NEVER; + location &= 0x1FFF; + if (location < 0x100) { + switch(location/2) + { + case 0x1: + io_data_write(&gamepad_1, context, value); + break; + case 0x2: + io_data_write(&gamepad_2, context, value); + break; + case 0x3://PORT C Data + break; + case 0x4: + gamepad_1.control = value; + break; + case 0x5: + gamepad_2.control = value; + break; } - if (value & 1) { - busreq = 1; - if(!reset) { - busack_cycle = context->current_cycle + Z80_ACK_DELAY; - new_busack = 0; + } else { + if (location == 0x1100) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; } - } else { - busreq = 0; - busack_cycle = CYCLE_NEVER; - busack = 1; - } - } else if (location == 0x1200) { - if (value & 1) { - if (reset && busreq) { - new_busack = 0; - busack_cycle = context->current_cycle + Z80_ACK_DELAY; + if (value & 1) { + busreq = 1; + if(!reset) { + busack_cycle = context->current_cycle + Z80_ACK_DELAY; + new_busack = 0; + } + } else { + busreq = 0; + busack_cycle = CYCLE_NEVER; + busack = 1; } - reset = 0; - } else { - reset = 1; + } else if (location == 0x1200) { + if (value & 1) { + if (reset && busreq) { + new_busack = 0; + busack_cycle = context->current_cycle + Z80_ACK_DELAY; + } + reset = 0; + } else { + reset = 1; + } } } } @@ -327,51 +343,65 @@ m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value) { - if (location < 0x100) { - switch(location/2) - { - case 0x1: - io_data_write(&gamepad_1, context, value); - break; - case 0x2: - io_data_write(&gamepad_2, context, value); - break; - case 0x3://PORT C Data - break; - case 0x4: - gamepad_1.control = value; - break; - case 0x5: - gamepad_2.control = value; - break; + if (location < 0x10000) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; + } + if (!(busack || reset)) { + location &= 0x7FFF; + if (location < 0x4000) { + z80_ram[location & 0x1FFE] = value >> 8; + } } } else { - //printf("IO Write of %X to %X @ %d\n", value, location, context->current_cycle); - if (location == 0x1100) { - if (busack_cycle > context->current_cycle) { - busack = new_busack; - busack_cycle = CYCLE_NEVER; + location &= 0x1FFF; + if (location < 0x100) { + switch(location/2) + { + case 0x1: + io_data_write(&gamepad_1, context, value); + break; + case 0x2: + io_data_write(&gamepad_2, context, value); + break; + case 0x3://PORT C Data + break; + case 0x4: + gamepad_1.control = value; + break; + case 0x5: + gamepad_2.control = value; + break; } - if (value & 0x100) { - busreq = 1; - if(!reset) { - busack_cycle = context->current_cycle + Z80_ACK_DELAY; - new_busack = 0; + } else { + //printf("IO Write of %X to %X @ %d\n", value, location, context->current_cycle); + if (location == 0x1100) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; } - } else { - busreq = 0; - busack_cycle = CYCLE_NEVER; - busack = 1; - } - } else if (location == 0x1200) { - if (value & 0x100) { - if (reset && busreq) { - new_busack = 0; - busack_cycle = context->current_cycle + Z80_ACK_DELAY; + if (value & 0x100) { + busreq = 1; + if(!reset) { + busack_cycle = context->current_cycle + Z80_ACK_DELAY; + new_busack = 0; + } + } else { + busreq = 0; + busack_cycle = CYCLE_NEVER; + busack = 1; } - reset = 0; - } else { - reset = 1; + } else if (location == 0x1200) { + if (value & 0x100) { + if (reset && busreq) { + new_busack = 0; + busack_cycle = context->current_cycle + Z80_ACK_DELAY; + } + reset = 0; + } else { + reset = 1; + } } } } @@ -386,41 +416,59 @@ m68k_context * io_read(uint32_t location, m68k_context * context) { - if (location < 0x100) { - switch(location/2) - { - case 0x0: - //version bits should be 0 for now since we're not emulating TMSS - //Not sure about the other bits - context->value = version_reg; - break; - case 0x1: - io_data_read(&gamepad_1, context); - break; - case 0x2: - io_data_read(&gamepad_2, context); - break; - case 0x3://PORT C Data - break; - case 0x4: - context->value = gamepad_1.control; - break; - case 0x5: - context->value = gamepad_2.control; - break; + if (location < 0x10000) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; + } + if (!(busack || reset)) { + location &= 0x7FFF; + if (location < 0x4000) { + context->value = z80_ram[location & 0x1FFF]; + } else { + context->value = 0xFF; + } + } else { + context->value = 0xFF; } } else { - if (location == 0x1100) { - if (busack_cycle > context->current_cycle) { - busack = new_busack; - busack_cycle = CYCLE_NEVER; + location &= 0x1FFF; + if (location < 0x100) { + switch(location/2) + { + case 0x0: + //version bits should be 0 for now since we're not emulating TMSS + //Not sure about the other bits + context->value = version_reg; + break; + case 0x1: + io_data_read(&gamepad_1, context); + break; + case 0x2: + io_data_read(&gamepad_2, context); + break; + case 0x3://PORT C Data + break; + case 0x4: + context->value = gamepad_1.control; + break; + case 0x5: + context->value = gamepad_2.control; + break; } - context->value = reset || busack; - //printf("Byte read of BUSREQ returned %d @ %d (reset: %d, busack: %d)\n", context->value, context->current_cycle, reset, busack); - } else if (location == 0x1200) { - context->value = !reset; } else { - printf("Byte read of unknown IO location: %X\n", location); + if (location == 0x1100) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; + } + context->value = reset || busack; + //printf("Byte read of BUSREQ returned %d @ %d (reset: %d, busack: %d)\n", context->value, context->current_cycle, reset, busack); + } else if (location == 0x1200) { + context->value = !reset; + } else { + printf("Byte read of unknown IO location: %X\n", location); + } } } return context; @@ -428,47 +476,66 @@ m68k_context * io_read_w(uint32_t location, m68k_context * context) { - if (location < 0x100) { - switch(location/2) - { - case 0x0: - //version bits should be 0 for now since we're not emulating TMSS - //Not sure about the other bits - context->value = 0; - break; - case 0x1: - io_data_read(&gamepad_1, context); - break; - case 0x2: - io_data_read(&gamepad_2, context); - break; - case 0x3://PORT C Data - break; - case 0x4: - context->value = gamepad_1.control; - break; - case 0x5: - context->value = gamepad_2.control; - break; - case 0x6: - //PORT C Control - context->value = 0; - break; + if (location < 0x10000) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; + } + if (!(busack || reset)) { + location &= 0x7FFF; + if (location < 0x4000) { + context->value = z80_ram[location & 0x1FFE]; + context->value |= context->value << 8; + } else { + context->value = 0xFFFF; + } + } else { + context->value = 0xFFFF; } - context->value = context->value | (context->value << 8); - //printf("Word read to %X returned %d\n", location, context->value); } else { - if (location == 0x1100) { - if (busack_cycle > context->current_cycle) { - busack = new_busack; - busack_cycle = CYCLE_NEVER; + location &= 0x1FFF; + if (location < 0x100) { + switch(location/2) + { + case 0x0: + //version bits should be 0 for now since we're not emulating TMSS + //Not sure about the other bits + context->value = 0; + break; + case 0x1: + io_data_read(&gamepad_1, context); + break; + case 0x2: + io_data_read(&gamepad_2, context); + break; + case 0x3://PORT C Data + break; + case 0x4: + context->value = gamepad_1.control; + break; + case 0x5: + context->value = gamepad_2.control; + break; + case 0x6: + //PORT C Control + context->value = 0; + break; } - context->value = (reset || busack) << 8; - //printf("Word read of BUSREQ returned %d\n", context->value); - } else if (location == 0x1200) { - context->value = (!reset) << 8; + context->value = context->value | (context->value << 8); + //printf("Word read to %X returned %d\n", location, context->value); } else { - printf("Word read of unknown IO location: %X\n", location); + if (location == 0x1100) { + if (busack_cycle > context->current_cycle) { + busack = new_busack; + busack_cycle = CYCLE_NEVER; + } + context->value = (reset || busack) << 8; + //printf("Word read of BUSREQ returned %d\n", context->value); + } else if (location == 0x1200) { + context->value = (!reset) << 8; + } else { + printf("Word read of unknown IO location: %X\n", location); + } } } return context; diff -r 79958b95526f -r 42c031184e8a runtime.S --- a/runtime.S Thu Jan 03 22:49:21 2013 -0800 +++ b/runtime.S Fri Jan 04 21:47:09 2013 -0800 @@ -175,7 +175,7 @@ do_io_write: call m68k_save_context - and $0x1FFF, %edi + and $0x1FFFF, %edi mov %ecx, %edx call io_write mov %rax, %rsi @@ -183,7 +183,7 @@ ret do_io_read: mov %ecx, %edi - and $0x1FFF, %edi + and $0x1FFFF, %edi call m68k_save_context call io_read mov %rax, %rsi @@ -193,7 +193,7 @@ do_io_write_w: call m68k_save_context - and $0x1FFF, %edi + and $0x1FFFF, %edi mov %ecx, %edx call io_write_w mov %rax, %rsi @@ -201,7 +201,7 @@ ret do_io_read_w: mov %ecx, %edi - and $0x1FFF, %edi + and $0x1FFFF, %edi call m68k_save_context call io_read_w mov %rax, %rsi @@ -223,7 +223,7 @@ jae workram_w cmp $0xC00000, %edi jae vdp_psg_w - cmp $0xA10000, %edi + cmp $0xA00000, %edi jb not_io_w cmp $0xA12000, %edi jae not_io_w @@ -300,7 +300,7 @@ jae workram_wb cmp $0xC00000, %edi jae vdp_psg_wb - cmp $0xA10000, %edi + cmp $0xA00000, %edi jb not_io_wb cmp $0xA12000, %edi jae not_io_wb @@ -373,7 +373,7 @@ jae workram cmp $0xC00000, %ecx jae vdp_psg - cmp $0xA10000, %ecx + cmp $0xA00000, %ecx jb not_io cmp $0xA12000, %ecx jae not_io @@ -421,7 +421,7 @@ jae workram_b cmp $0xC00000, %ecx jae vdp_psg_b - cmp $0xA10000, %ecx + cmp $0xA00000, %ecx jb not_io_b cmp $0xA12000, %ecx jae not_io_b