--- generator/src/mem68k.c 2020/03/04 04:46:28 1.1 +++ generator/src/mem68k.c 2020/03/04 04:46:35 1.1.1.2 @@ -1,10 +1,4 @@ -/*****************************************************************************/ -/* Generator - Sega Genesis emulation - (c) James Ponder 1997-1998 */ -/*****************************************************************************/ -/* */ -/* mem68k.c */ -/* */ -/*****************************************************************************/ +/* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */ #include @@ -14,8 +8,10 @@ #include "vdp.h" #include "cpuz80.h" #include "gensound.h" +#include "gensoundi.h" #include "ui.h" +#undef DEBUG_VDP #undef DEBUG_BUS #undef DEBUG_SRAM #undef DEBUG_RAM @@ -101,8 +97,12 @@ unsigned int mem68k_cont2_left = 0; unsigned int mem68k_cont2_right = 0; unsigned int mem68k_cont2_start = 0; -static unsigned int mem68k_cont1store; -static unsigned int mem68k_cont2store; +static uint8 mem68k_cont1ctrl; +static uint8 mem68k_cont2ctrl; +static uint8 mem68k_contEctrl; +static uint8 mem68k_cont1output; +static uint8 mem68k_cont2output; +static uint8 mem68k_contEoutput; /*** memory map ***/ @@ -116,7 +116,7 @@ t_mem68k_def mem68k_def[] = { mem68k_fetch_bad_byte, mem68k_fetch_bad_word, mem68k_fetch_bad_long, mem68k_store_bad_byte, mem68k_store_bad_word, mem68k_store_bad_long }, - { 0xA00, 0xA02, mem68k_memptr_bad, + { 0xA00, 0xA10, mem68k_memptr_bad, /* note overlaps blocks below */ mem68k_fetch_sram_byte, mem68k_fetch_sram_word, mem68k_fetch_sram_long, mem68k_store_sram_byte, mem68k_store_sram_word, mem68k_store_sram_long }, @@ -128,6 +128,10 @@ t_mem68k_def mem68k_def[] = { mem68k_fetch_bank_byte, mem68k_fetch_bank_word, mem68k_fetch_bank_long, mem68k_store_bank_byte, mem68k_store_bank_word, mem68k_store_bank_long }, + { 0xA0C, 0xA10, mem68k_memptr_bad, /* this is probably more yam/bank stuff */ + mem68k_fetch_bad_byte, mem68k_fetch_bad_word, mem68k_fetch_bad_long, + mem68k_store_bad_byte, mem68k_store_bad_word, mem68k_store_bad_long }, + { 0xA10, 0xA11, mem68k_memptr_bad, mem68k_fetch_io_byte, mem68k_fetch_io_word, mem68k_fetch_io_long, mem68k_store_io_byte, mem68k_store_io_word, mem68k_store_io_long }, @@ -140,7 +144,7 @@ t_mem68k_def mem68k_def[] = { mem68k_fetch_vdp_byte, mem68k_fetch_vdp_word, mem68k_fetch_vdp_long, mem68k_store_vdp_byte, mem68k_store_vdp_word, mem68k_store_vdp_long }, - { 0xFF0, 0x1000, mem68k_memptr_ram, + { 0xE00, 0x1000, mem68k_memptr_ram, mem68k_fetch_ram_byte, mem68k_fetch_ram_word, mem68k_fetch_ram_long, mem68k_store_ram_byte, mem68k_store_ram_word, mem68k_store_ram_long }, @@ -175,6 +179,12 @@ int mem68k_init(void) } i++; } while ((mem68k_def[i].start != 0) || (mem68k_def[i].end != 0)); + mem68k_cont1ctrl = 0; + mem68k_cont2ctrl = 0; + mem68k_contEctrl = 0; + mem68k_cont1output = 0; + mem68k_cont2output = 0; + mem68k_contEoutput = 0; return 0; } @@ -193,14 +203,14 @@ uint8 *mem68k_memptr_rom(uint32 addr) return(cpu68k_rom+addr); } LOG_CRITICAL(("%08X [MEM] Invalid memory access to ROM 0x%X", regs.pc, - addr)); + addr)); return cpu68k_rom; } uint8 *mem68k_memptr_ram(uint32 addr) { - /* LOG_USER(("%08X [MEM] Executing code from RAM 0x%X\n", regs.pc, addr)); */ - addr-= 0xFF0000; + /* LOG_USER(("%08X [MEM] Executing code from RAM 0x%X", regs.pc, addr)); */ + addr&= 0xffff; return(cpu68k_ram+addr); } @@ -209,7 +219,7 @@ uint8 *mem68k_memptr_ram(uint32 addr) uint8 mem68k_fetch_bad_byte(uint32 addr) { - LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (byte) 0x%X", regs.pc, addr)); + LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (byte) 0x%X", regs.pc, addr)); return 0; } @@ -310,12 +320,13 @@ uint8 mem68k_fetch_sram_byte(uint32 addr #ifdef DEBUG_SRAM LOG_VERBOSE(("%08X [SRAM] Fetch byte from %X", regs.pc, addr)); #endif - addr-= 0xA00000; + addr&= 0x1fff; return (*(uint8 *)(cpuz80_ram+addr)); } uint16 mem68k_fetch_sram_word(uint32 addr) { + uint8 data; #ifdef DEBUG_BUS if (addr & 1) { LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr)); @@ -325,8 +336,10 @@ uint16 mem68k_fetch_sram_word(uint32 add #ifdef DEBUG_SRAM LOG_VERBOSE(("%08X [SRAM] Fetch word from %X", regs.pc, addr)); #endif - addr-= 0xA00000; - return LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr)); + addr&= 0x1fff; + /* sram word fetches are fetched with duplicated low byte data */ + data = *(uint8 *)(cpuz80_ram+addr); + return data | (data<<8); } uint32 mem68k_fetch_sram_long(uint32 addr) @@ -340,7 +353,7 @@ uint32 mem68k_fetch_sram_long(uint32 add #ifdef DEBUG_SRAM LOG_VERBOSE(("%08X [SRAM] Fetch long from %X", regs.pc, addr)); #endif - addr-= 0xA00000; + addr&= 0x1fff; #ifdef ALIGNLONGS return (LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr))<<16) | LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr+2)); @@ -354,7 +367,7 @@ void mem68k_store_sram_byte(uint32 addr, #ifdef DEBUG_SRAM LOG_VERBOSE(("%08X [SRAM] Store byte to %X", regs.pc, addr)); #endif - addr-= 0xA00000; + addr&= 0x1fff; *(uint8 *)(cpuz80_ram+addr) = data; return; } @@ -370,8 +383,9 @@ void mem68k_store_sram_word(uint32 addr, #ifdef DEBUG_SRAM LOG_VERBOSE(("%08X [SRAM] Store word to %X", regs.pc, addr)); #endif - addr-= 0xA00000; - *(uint16 *)(cpuz80_ram+addr) = LOCENDIAN16(data); + addr&= 0x1fff; + /* word writes are stored with low byte cleared */ + *(uint8 *)(cpuz80_ram+addr) = data >> 8; return; } @@ -386,7 +400,7 @@ void mem68k_store_sram_long(uint32 addr, #ifdef DEBUG_SRAM LOG_VERBOSE(("%08X [SRAM] Store byte to %X", regs.pc, addr)); #endif - addr-= 0xA00000; + addr&= 0x1fff; #ifdef ALIGNLONGS *(uint16 *)(cpuz80_ram+addr) = LOCENDIAN16((uint16)(data>>16)); *(uint16 *)(cpuz80_ram+addr+2) = LOCENDIAN16((uint16)(data)); @@ -404,7 +418,7 @@ uint8 mem68k_fetch_yam_byte(uint32 addr) addr-= 0xA04000; /* LOG_USER(("%08X [YAM] fetch (byte) 0x%X", regs.pc, addr)); */ if (addr < 4) { - return sound_ym2612fetch(addr); + return soundi_ym2612fetch(addr); } else { LOG_CRITICAL(("%08X [YAM] Invalid YAM fetch (byte) 0x%X", regs.pc, addr)); return 0; @@ -444,7 +458,7 @@ void mem68k_store_yam_byte(uint32 addr, /* LOG_USER(("%08X [YAM] (68k) store (byte) 0x%X (%d)", regs.pc, addr, data)); */ if (addr < 4) - sound_ym2612store(addr, data); + soundi_ym2612store(addr, data); else LOG_CRITICAL(("%08X [YAM] Invalid YAM store (byte) 0x%X", regs.pc, addr)); } @@ -481,7 +495,7 @@ uint8 mem68k_fetch_bank_byte(uint32 addr { /* write only */ LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (byte) 0x%X", regs.pc, - addr)); + addr)); return 0; } @@ -489,7 +503,7 @@ uint16 mem68k_fetch_bank_word(uint32 add { /* write only */ LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (word) 0x%X", regs.pc, - addr)); + addr)); return 0; } @@ -497,7 +511,7 @@ uint32 mem68k_fetch_bank_long(uint32 add { /* write only */ LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (long) 0x%X", regs.pc, - addr)); + addr)); return 0; } @@ -511,7 +525,7 @@ void mem68k_store_bank_byte(uint32 addr, cpuz80_bankwrite(data); } else { LOG_CRITICAL(("%08X [BANK] Invalid memory store (byte) 0x%X", regs.pc, - addr)); + addr)); } } @@ -525,7 +539,7 @@ void mem68k_store_bank_word(uint32 addr, cpuz80_bankwrite(data>>8); } else { LOG_CRITICAL(("%08X [BANK] Invalid memory store (word) 0x%X", regs.pc, - addr)); + addr)); } } @@ -534,7 +548,7 @@ void mem68k_store_bank_long(uint32 addr, addr-= 0xA06000; /* no longs please */ LOG_CRITICAL(("%08X [BANK] Invalid memory store (long) 0x%X", regs.pc, - addr)); + addr)); } @@ -542,129 +556,96 @@ void mem68k_store_bank_long(uint32 addr, uint8 mem68k_fetch_io_byte(uint32 addr) { - /* LOG_USER(("%08X [IO] Memory fetch (byte) 0x%X", regs.pc, addr)); */ + uint8 in; + addr-= 0xA10000; - switch (addr) { - case 0: + if ((addr & 1) == 0) { LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; - case 0x1: + } + switch (addr>>1) { + case 0: /* 0x1 */ /* version */ return (1<<5 | vdp_pal<<6 | vdp_overseas<<7); - case 0x3: - LOG_USER(("%08X [IO] getting controller 1 state - %02X store", - regs.pc, mem68k_cont1store)); - if (mem68k_cont1store & 1<<6) { - return (1<<6 | (1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 | - (1-mem68k_cont1_left)<<2 | (1-mem68k_cont1_right)<<3 | - (1-mem68k_cont1_b)<<4 | (1-mem68k_cont1_c)<<5); - } else { - return ((1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 | - (1-mem68k_cont1_a)<<4 | (1-mem68k_cont1_start)<<5); - } - case 0x5: - LOG_USER(("%08X [IO] getting controller 2 state - %02X store", - regs.pc, mem68k_cont2store)); - if (mem68k_cont2store & 1<<6) { - return (1<<6 | (1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 | - (1-mem68k_cont2_left)<<2 | (1-mem68k_cont2_right)<<3 | - (1-mem68k_cont2_b)<<4 | (1-mem68k_cont2_c)<<5); - } else { - return ((1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 | - (1-mem68k_cont2_a)<<4 | (1-mem68k_cont2_start)<<5); - } - case 0x9: - case 0xB: - return 0; + case 1: /* 0x3 */ + /* get input state */ + in = ((mem68k_cont1output & 1<<6) + ? ((1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 | + (1-mem68k_cont1_left)<<2 | (1-mem68k_cont1_right)<<3 | + (1-mem68k_cont1_b)<<4 | (1-mem68k_cont1_c)<<5) + : ((1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 | + (1-mem68k_cont1_a)<<4 | (1-mem68k_cont1_start)<<5)); + return (in & ~mem68k_cont1ctrl) | (mem68k_cont1output & mem68k_cont1ctrl); + case 2: /* 0x5 */ + /* get input state */ + in = ((mem68k_cont2output & 1<<6) + ? ((1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 | + (1-mem68k_cont2_left)<<2 | (1-mem68k_cont2_right)<<3 | + (1-mem68k_cont2_b)<<4 | (1-mem68k_cont2_c)<<5) + : ((1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 | + (1-mem68k_cont2_a)<<4 | (1-mem68k_cont2_start)<<5)); + return (in & ~mem68k_cont2ctrl) | (mem68k_cont2output & mem68k_cont2ctrl); + case 3: /* 0x7 */ + LOG_NORMAL(("%08X [IO] EXT port read", regs.pc)); + /* get input state */ + in = 0; /* BUG: unsupported */ + return (in & ~mem68k_cont1ctrl) | (mem68k_cont1output & mem68k_cont1ctrl); + case 4: /* 0x9 */ + return mem68k_cont1ctrl; + case 5: /* 0xB */ + return mem68k_cont2ctrl; + case 6: /* 0xD */ + return mem68k_contEctrl; default: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; } } uint16 mem68k_fetch_io_word(uint32 addr) { - /* LOG_USER(("%08X [IO] Memory fetch (word) 0x%X", regs.pc, addr)); */ -#ifdef DEBUG_BUS - if (addr & 1) { - LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr)); - return 0; - } -#endif - addr-= 0xA10000; - switch (addr>>1) { - case 0: /* version */ - return (1<<5 | vdp_pal<<6 | vdp_overseas<<7); - case 1: /* data 1 */ - return 0; - case 2: /* data 2 */ - return 0; - case 3: /* data E */ - return 0; - case 4: /* ctrl 1 */ - case 5: /* ctrl 2 */ - case 6: /* ctrl E */ - case 7: /* TxData 1 */ - case 8: /* RxData 1 */ - case 9: /* S-Mode 1 */ - case 10: /* TxData 2 */ - case 11: /* RxData 2 */ - case 12: /* S-Mode 2 */ - case 13: /* TxData E */ - case 14: /* RxData E */ - case 15: /* S-Mode E */ - LOG_CRITICAL(("%08X [IO] Invalid memory fetch (word) 0x%X", - regs.pc, addr)); - return 0; - default: - LOG_CRITICAL(("%08X [IO] Invalid memory fetch (word) 0x%X", - regs.pc, addr)); - return 0; - } + return mem68k_fetch_io_byte(addr+1); } uint32 mem68k_fetch_io_long(uint32 addr) { -#ifdef DEBUG_BUS - if (addr & 1) { - LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr)); - return 0; - } -#endif - if (addr >= 0xA1001E) { - LOG_CRITICAL(("%08X [IO] Invalid memory fetch (long) 0x%X", - regs.pc, addr)); - return 0; - } return (mem68k_fetch_io_word(addr)<<16) | mem68k_fetch_io_word(addr+2); } void mem68k_store_io_byte(uint32 addr, uint8 data) { - /* LOG_USER(("%08X [IO] Memory store (byte) 0x%X", regs.pc, addr)); */ addr-= 0xA10000; switch (addr) { case 0x3: - mem68k_cont1store = data; + mem68k_cont1output = data; return; case 0x5: - mem68k_cont2store = data; + mem68k_cont2output = data; + return; + case 0x7: + mem68k_contEoutput = data; + LOG_NORMAL(("%08X [IO] EXT port output set to %X", regs.pc, data)); return; case 0x9: + mem68k_cont1ctrl = data; if (data != 0x40) { - LOG_CRITICAL(("%08X [IO] Invalid controller 1 setting (0x%X)", - regs.pc, data)); + LOG_CRITICAL(("%08X [IO] Unknown controller 1 setting (0x%X)", + regs.pc, data)); } return; case 0xB: + mem68k_cont2ctrl = data; if (data != 0x40) { - LOG_CRITICAL(("%08X [IO] Invalid controller 2 setting (0x%X)", - regs.pc, data)); + LOG_CRITICAL(("%08X [IO] Unknown controller 2 setting (0x%X)", + regs.pc, data)); } return; case 0xD: + mem68k_contEctrl = data; + LOG_NORMAL(("%08X [IO] EXT port ctrl set to %X", regs.pc, data)); + return; case 0xF: case 0x11: case 0x13: @@ -674,62 +655,24 @@ void mem68k_store_io_byte(uint32 addr, u case 0x1B: case 0x1D: case 0x1F: - return; + /* return; */ default: LOG_CRITICAL(("%08X [IO] Invalid memory store (byte) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return; } } void mem68k_store_io_word(uint32 addr, uint16 data) { - /* LOG_USER(("%08X [IO] Memory store (word) 0x%X", regs.pc, addr)); */ -#ifdef DEBUG_BUS - if (addr & 1) { - LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr)); - return; - } -#endif - addr-= 0xA10000; - switch (addr>>1) { - case 1: /* data 1 */ - case 2: /* data 2 */ - case 3: /* data E */ - LOG_CRITICAL(("%08X [IO] Word store to DATA 0x%X", regs.pc, addr)); - return; - case 4: /* ctrl 1 */ - case 5: /* ctrl 2 */ - case 6: /* ctrl E */ - LOG_CRITICAL(("%08X [IO] Word store to CTRL 0x%X", regs.pc, addr)); - return; - case 7: /* TxData 1 */ - case 8: /* RxData 1 */ - case 9: /* S-Mode 1 */ - case 10: /* TxData 2 */ - case 11: /* RxData 2 */ - case 12: /* S-Mode 2 */ - case 13: /* TxData E */ - case 14: /* RxData E */ - case 15: /* S-Mode E */ - LOG_CRITICAL(("%08X [IO] Invalid memory store (word) 0x%X", - regs.pc, addr)); - return; - default: - LOG_CRITICAL(("%08X [IO] Invalid memory store (word) 0x%X", - regs.pc, addr)); - } + if (data >> 8) + LOG_CRITICAL(("%08X [IO] Word store to %X of %X", addr, data)); + mem68k_store_io_byte(addr+1, data & 0xff); } void mem68k_store_io_long(uint32 addr, uint32 data) { - addr-= 0xA10000; - if (addr >= 0x1E) { - LOG_CRITICAL(("%08X [IO] Invalid memory store (long) 0x%X", - regs.pc, addr)); - return; - } - mem68k_store_io_word(addr, (uint16)(data<<16)); + mem68k_store_io_word(addr, (uint16)(data>>16)); mem68k_store_io_word(addr+2, (uint16)data); return; } @@ -745,7 +688,7 @@ uint8 mem68k_fetch_ctrl_byte(uint32 addr return cpuz80_active ? 1 : 0; } LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (byte) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; } @@ -757,7 +700,7 @@ uint16 mem68k_fetch_ctrl_word(uint32 add return cpuz80_active ? 0x100 : 0; } LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (word) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; } @@ -766,7 +709,7 @@ uint32 mem68k_fetch_ctrl_long(uint32 add addr-= 0xA11000; /* no long access allowed */ LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (long) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; } @@ -802,7 +745,7 @@ void mem68k_store_ctrl_byte(uint32 addr, return; /* ignore low byte */ } else { LOG_CRITICAL(("%08X [CTRL] Invalid memory store (byte) 0x%X", - regs.pc, addr)); + regs.pc, addr)); } } @@ -834,7 +777,7 @@ void mem68k_store_ctrl_word(uint32 addr, } } else { LOG_CRITICAL(("%08X [CTRL] Invalid memory store (word) 0x%X", - regs.pc, addr)); + regs.pc, addr)); } } @@ -843,7 +786,7 @@ void mem68k_store_ctrl_long(uint32 addr, addr-= 0xA11000; /* no long access allowed */ LOG_CRITICAL(("%08X [CTRL] Invalid memory store (long) 0x%X", - regs.pc, addr)); + regs.pc, addr)); } @@ -851,42 +794,7 @@ void mem68k_store_ctrl_long(uint32 addr, uint8 mem68k_fetch_vdp_byte(uint32 addr) { - addr-= 0xC00000; - switch(addr) { - case 0: - case 1: - case 2: - case 3: - /* data port */ - LOG_CRITICAL(("%08X [VDP] Byte fetch from data port 0x%X", - regs.pc, addr)); - return 0; - case 4: - /* control port */ - return vdp_status()>>8; /* upper 8 bits */ - case 5: - /* control port */ - return vdp_status(); /* lower 8 bits */ - case 6: - case 7: - /* unknown control port */ - LOG_CRITICAL(("%08X [VDP] Byte fetch from control port 0x%X", - regs.pc, addr)); - return 0; - case 8: - /* hv counter */ - return mem68k_fetch_vdp_word(0xc00008)>>8; /* upper 8 bits */ - case 9: - /* hv counter */ - return mem68k_fetch_vdp_word(0xc00008); /* lower 8 bits */ - case 17: - LOG_CRITICAL(("%08X [VDP] PSG byte fetch.", regs.pc)); - return 0; - default: - LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (byte) 0x%X", - regs.pc, addr)); - return 0; - } + return (mem68k_fetch_vdp_word(addr) >> 8) & 0xff; } uint16 mem68k_fetch_vdp_word(uint32 addr) @@ -904,40 +812,48 @@ uint16 mem68k_fetch_vdp_word(uint32 addr /* data port */ #ifdef DEBUG_VDP LOG_VERBOSE(("%08X [VDP] Word fetch from data port 0x%X", - regs.pc, addr)); + regs.pc, addr)); #endif - return vdp_fetchdata_word(); + return vdp_fetchdata(); case 2: case 3: /* control port */ #ifdef DEBUG_VDP LOG_VERBOSE(("%08X [VDP] Word fetch from control port " - "(status) 0x%X", regs.pc, addr)); + "(status) 0x%X", regs.pc, addr)); #endif return vdp_status(); case 4: /* hv counter */ + { + uint8 line8; + uint16 hvcount; + + /* line counter advances at H-int */ + line8 = (vdp_line - vdp_visstartline + (vdp_event > 2 ? 1 : 0)) & 0xff; + #ifdef DEBUG_VDP - LOG_VERBOSE(("%08X [VDP] Word fetch from hv counter 0x%X", - regs.pc, addr)); + LOG_VERBOSE(("%08X [VDP] Word fetch from hv counter 0x%X", + regs.pc, addr)); #endif - /* we always return 0 for the horizontal position */ - if (vdp_interlace) { - /* interlace mode - replace lowest bit with highest bit */ - LOG_CRITICAL(("Interlace mode HV read - check this")); - return ((((vdp_line & ~1)<<8) | (vdp_line & 0x100)) & 0xff00) | - vdp_gethpos(); - } else { - /* non-interlace mode */ - LOG_VERBOSE(("%02X", vdp_gethpos())); - return (vdp_line<<8) | vdp_gethpos(); + if ((vdp_reg[12] >> 1) & 3) { + /* interlace mode - replace lowest bit with highest bit */ + hvcount = ((line8 & ~1)<<8) | (line8 & 0x100) | vdp_gethpos(); + LOG_DEBUG1(("Interlace mode HV read - check this: %04X", hvcount)); + return hvcount; + } else { + /* non-interlace mode */ + hvcount = (line8 << 8) | vdp_gethpos(); + LOG_DEBUG1(("%08X H/V counter read = %04X", regs.pc, hvcount)); + return hvcount; + } } case 8: LOG_CRITICAL(("%08X [VDP] PSG/prohibited word fetch.", regs.pc)); return 0; default: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (word) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; } } @@ -956,24 +872,26 @@ uint32 mem68k_fetch_vdp_long(uint32 addr /* data port */ #ifdef DEBUG_VDP LOG_VERBOSE(("%08X [VDP] Long fetch from data port 0x%X", - regs.pc, addr)); + regs.pc, addr)); #endif - return (vdp_fetchdata_word()<<16) | vdp_fetchdata_word(); + return (vdp_fetchdata()<<16) | vdp_fetchdata(); case 2: /* control port */ #ifdef DEBUG_VDP LOG_VERBOSE(("%08X [VDP] Long fetch from control port 0x%X", - regs.pc, addr)); + regs.pc, addr)); + LOG_CRITICAL(("%08X [VDP] Long fetch from control port 0x%X", + regs.pc, addr)); #endif return 0; case 4: /* hv counter ish */ LOG_CRITICAL(("%08X [VDP] Long fetch from hv/prohibited 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; default: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (word) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return 0; } } @@ -988,17 +906,22 @@ void mem68k_store_vdp_byte(uint32 addr, case 3: /* data port */ #ifdef DEBUG_VDP - LOG_VERBOSE(("%08X [VDP] Byte store to data port 0x%X\n", regs.pc, addr)); + LOG_VERBOSE(("%08X [VDP] Byte store to DATA of %X [%d][%X]", regs.pc, + data, vdp_reg[23]>>6, vdp_reg[1])); #endif - vdp_storedata_byte(data); + vdp_storedata(data | (data << 8)); return; case 4: case 5: case 6: case 7: + +#ifdef DEBUG_VDP + LOG_VERBOSE(("%08X [VDP] Byte store to CONTROL of %X [%d][%X]", regs.pc, + data, vdp_reg[23]>>6, vdp_reg[1])); +#endif /* control port */ - LOG_CRITICAL(("%08X [VDP] Byte store to control port 0x%X", regs.pc, - addr)); + vdp_storectrl(data | (data << 8)); return; case 8: case 9: @@ -1010,7 +933,7 @@ void mem68k_store_vdp_byte(uint32 addr, return; default: LOG_CRITICAL(("%08X [VDP] Invalid memory store (byte) 0x%X", - regs.pc, addr)); + regs.pc, addr)); return; } } @@ -1029,14 +952,16 @@ void mem68k_store_vdp_word(uint32 addr, case 1: /* data port */ #ifdef DEBUG_VDP - LOG_CRITICAL(("%08X [VDP] Word store to data port 0x%X", regs.pc, addr)); + LOG_CRITICAL(("%08X [VDP] Word store to DATA of %X [%d][%X]", regs.pc, + data, vdp_reg[23]>>6, vdp_reg[1])); #endif - vdp_storedata_word(data); + vdp_storedata(data); return; case 2: case 3: #ifdef DEBUG_VDP - LOG_VERBOSE(("%08X [VDP] Word store to control port 0x%X", regs.pc, addr)); + LOG_VERBOSE(("%08X [VDP] Word store to CONTROL of %X [%d][%X]", regs.pc, + data, vdp_reg[23]>>6, vdp_reg[1])); #endif /* control port */ vdp_storectrl(data); @@ -1050,7 +975,7 @@ void mem68k_store_vdp_word(uint32 addr, return; default: LOG_CRITICAL(("%08X [VDP] Invalid memory store (word) 0x%X", regs.pc, - addr)); + addr)); return; } } @@ -1068,15 +993,17 @@ void mem68k_store_vdp_long(uint32 addr, case 0: /* data port */ #ifdef DEBUG_VDP - LOG_VERBOSE(("%08X [VDP] Long store to data port 0x%X\n", regs.pc, addr)); + LOG_VERBOSE(("%08X [VDP] Long store to DATA of %X [%d][%X]", regs.pc, + data, vdp_reg[23]>>6, vdp_reg[1])); #endif - vdp_storedata_word((uint16)(data>>16)); - vdp_storedata_word((uint16)(data)); + vdp_storedata((uint16)(data>>16)); + vdp_storedata((uint16)(data)); return; case 2: /* control port */ #ifdef DEBUG_VDP - LOG_VERBOSE(("%08X [VDP] Long store to control port 0x%X", regs.pc, addr)); + LOG_VERBOSE(("%08X [VDP] Long store to CONTROL of %X [%d][%X]", regs.pc, + data, vdp_reg[23]>>6, vdp_reg[1])); #endif vdp_storectrl((uint16)(data>>16)); vdp_storectrl((uint16)(data)); @@ -1084,11 +1011,11 @@ void mem68k_store_vdp_long(uint32 addr, case 4: /* hv counter */ LOG_CRITICAL(("%08X [VDP] Long store to hv/prohibited 0x%X", regs.pc, - addr)); + addr)); return; default: LOG_CRITICAL(("%08X [VDP] Invalid memory store (long) 0x%X", regs.pc, - addr)); + addr)); return; } } @@ -1098,19 +1025,19 @@ void mem68k_store_vdp_long(uint32 addr, uint8 mem68k_fetch_ram_byte(uint32 addr) { - addr-= 0xFF0000; + addr&= 0xffff; return (*(uint8 *)(cpu68k_ram+addr)); } uint16 mem68k_fetch_ram_word(uint32 addr) { - addr-= 0xFF0000; + addr&= 0xffff; return LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr)); } uint32 mem68k_fetch_ram_long(uint32 addr) { - addr-= 0xFF0000; + addr&= 0xffff; #ifdef ALIGNLONGS return (LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr))<<16) | LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr+2)); @@ -1121,21 +1048,21 @@ uint32 mem68k_fetch_ram_long(uint32 addr void mem68k_store_ram_byte(uint32 addr, uint8 data) { - addr-= 0xFF0000; + addr&= 0xffff; *(uint8 *)(cpu68k_ram+addr) = data; return; } void mem68k_store_ram_word(uint32 addr, uint16 data) { - addr-= 0xFF0000; + addr&= 0xffff; *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16(data); return; } void mem68k_store_ram_long(uint32 addr, uint32 data) { - addr-= 0xFF0000; + addr&= 0xffff; #ifdef ALIGNLONGS *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16((uint16)(data>>16)); *(uint16 *)(cpu68k_ram+addr+2) = LOCENDIAN16((uint16)(data));