From 6c1655976f4f81e7f5fec31a34e0b566c3c227c5 Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Wed, 19 Nov 2008 03:29:10 +0000 Subject: [PATCH] Big H8 update H8: - Added support for 8-bit H8 family MCUs, starting with the H8/3344 - Pointer-ified all H8 cores - Some cleanup and renames toward additional future work System 23: - Added extremely preliminary support for I/O boards with the H8/3344 - Added new game: Motocross Go! (MG3 Ver. A) [credit Guru] --- .gitattributes | 6 +- src/emu/cpu/cpu.mak | 32 +- src/emu/cpu/h83002/{h83002.h => h8.h} | 39 +- src/emu/cpu/h83002/h83002.c | 4162 ------------------------- src/emu/cpu/h83002/h8_16.c | 653 ++++ src/emu/cpu/h83002/h8_8.c | 603 ++++ src/emu/cpu/h83002/h8disasm.c | 50 +- src/emu/cpu/h83002/h8ops.h | 3551 +++++++++++++++++++++ src/emu/cpu/h83002/h8periph.c | 460 +-- src/emu/cpu/h83002/h8priv.h | 36 +- src/emu/cpuintrf.c | 4 + src/emu/cpuintrf.h | 1 + src/mame/drivers/bishjan.c | 4 +- src/mame/drivers/itgambl2.c | 2 +- src/mame/drivers/itgambl3.c | 2 +- src/mame/drivers/itgamble.c | 2 +- src/mame/drivers/lastfght.c | 4 +- src/mame/drivers/metro.c | 10 +- src/mame/drivers/namcond1.c | 6 +- src/mame/drivers/namcos12.c | 12 +- src/mame/drivers/namcos23.c | 134 +- src/mame/mame.mak | 1 + src/mame/mamedriv.c | 1 + 23 files changed, 5304 insertions(+), 4471 deletions(-) rename src/emu/cpu/h83002/{h83002.h => h8.h} (59%) delete mode 100644 src/emu/cpu/h83002/h83002.c create mode 100644 src/emu/cpu/h83002/h8_16.c create mode 100644 src/emu/cpu/h83002/h8_8.c create mode 100644 src/emu/cpu/h83002/h8ops.h diff --git a/.gitattributes b/.gitattributes index 6e968aa5b20..d61dffbfc0c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -113,9 +113,11 @@ src/emu/cpu/h6280/h6280.c svneol=native#text/plain src/emu/cpu/h6280/h6280.h svneol=native#text/plain src/emu/cpu/h6280/h6280ops.h svneol=native#text/plain src/emu/cpu/h6280/tblh6280.c svneol=native#text/plain -src/emu/cpu/h83002/h83002.c svneol=native#text/plain -src/emu/cpu/h83002/h83002.h svneol=native#text/plain +src/emu/cpu/h83002/h8.h svneol=native#text/plain +src/emu/cpu/h83002/h8_16.c svneol=native#text/plain +src/emu/cpu/h83002/h8_8.c svneol=native#text/plain src/emu/cpu/h83002/h8disasm.c svneol=native#text/plain +src/emu/cpu/h83002/h8ops.h svneol=native#text/plain src/emu/cpu/h83002/h8periph.c svneol=native#text/plain src/emu/cpu/h83002/h8priv.h svneol=native#text/plain src/emu/cpu/hd6309/6309dasm.c svneol=native#text/plain diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index 642c14d0fff..01a713e2d6f 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -470,21 +470,21 @@ $(CPUOBJ)/hd6309/hd6309.o: $(CPUSRC)/hd6309/hd6309.c \ $(CPUSRC)/hd6309/6309tbl.c - #------------------------------------------------- -# Hitachi H8/3002 +# Hitachi H8/30xx (16/32-bit H8/3xx series) #------------------------------------------------- CPUDEFS += -DHAS_H83002=$(if $(filter H83002,$(CPUS)),1,0) ifneq ($(filter H83002,$(CPUS)),) OBJDIRS += $(CPUOBJ)/h83002 -CPUOBJS += $(CPUOBJ)/h83002/h83002.o $(CPUOBJ)/h83002/h8periph.o +CPUOBJS += $(CPUOBJ)/h83002/h8_16.o $(CPUOBJ)/h83002/h8periph.o DBGOBJS += $(CPUOBJ)/h83002/h8disasm.o endif -$(CPUOBJ)/h83002/h83002.o: $(CPUSRC)/h83002/h83002.c \ - $(CPUSRC)/h83002/h83002.h \ +$(CPUOBJ)/h83002/h8_16.o: $(CPUSRC)/h83002/h8_16.c \ + $(CPUSRC)/h83002/h8.h \ + $(CPUSRC)/h83002/h8ops.h \ $(CPUSRC)/h83002/h8priv.h $(CPUOBJ)/h83002/h8disasm.o: $(CPUSRC)/h83002/h8disasm.c @@ -493,6 +493,28 @@ $(CPUOBJ)/h83002/h8periph.o: $(CPUSRC)/h83002/h8periph.c \ $(CPUSRC)/h83002/h8priv.h +#------------------------------------------------- +# Hitachi H8/3344 (8/16-bit H8/3xx series) +#------------------------------------------------- + +CPUDEFS += -DHAS_H83344=$(if $(filter H83344,$(CPUS)),1,0) + +ifneq ($(filter H83344,$(CPUS)),) +OBJDIRS += $(CPUOBJ)/h83002 +CPUOBJS += $(CPUOBJ)/h83002/h8_8.o $(CPUOBJ)/h83002/h8periph.o +DBGOBJS += $(CPUOBJ)/h83002/h8disasm.o +endif + +$(CPUOBJ)/h83002/h8_8.o: $(CPUSRC)/h83002/h8_8.c \ + $(CPUSRC)/h83002/h8.h \ + $(CPUSRC)/h83002/h8ops.h \ + $(CPUSRC)/h83002/h8priv.h + +$(CPUOBJ)/h83002/h8disasm.o: $(CPUSRC)/h83002/h8disasm.c + +$(CPUOBJ)/h83002/h8periph.o: $(CPUSRC)/h83002/h8periph.c \ + $(CPUSRC)/h83002/h8priv.h + #------------------------------------------------- # Hitachi SH1/SH2 #------------------------------------------------- diff --git a/src/emu/cpu/h83002/h83002.h b/src/emu/cpu/h83002/h8.h similarity index 59% rename from src/emu/cpu/h83002/h83002.h rename to src/emu/cpu/h83002/h8.h index d37a580b80e..d396f7a24fe 100644 --- a/src/emu/cpu/h83002/h83002.h +++ b/src/emu/cpu/h83002/h8.h @@ -35,7 +35,7 @@ enum H8_CCR }; -// external interrupt lines +// external input lines enum { H8_IRQ0 = 0, @@ -43,20 +43,33 @@ enum H8_IRQ2, H8_IRQ3, H8_IRQ4, - H8_IRQ5 + H8_IRQ5, + H8_IRQ6, // IRQs 6+ only available on 8-bit H8/3xx + H8_IRQ7, + H8_NMI, + + H8_METRO_TIMER_HACK, // as described. this needs to be fixed. + + H8_SCI_0_RX, // incoming character on SCI 0 + H8_SCI_1_RX, // incoming character on SCI 1 }; // I/O ports enum { // digital I/O ports - H8_PORT4 = 0, // 0 - H8_PORT6, // 1 - H8_PORT7, // 2 - H8_PORT8, // 3 - H8_PORT9, // 4 - H8_PORTA, // 5 - H8_PORTB, // 6 + // ports 4-B are valid on 16-bit H8/3xx, ports 1-9 on 8-bit H8/3xx + H8_PORT_1 = 0, // 0 + H8_PORT_2, // 1 + H8_PORT_3, // 2 + H8_PORT_4, // 3 + H8_PORT_5, // 4 + H8_PORT_6, // 5 + H8_PORT_7, // 6 + H8_PORT_8, // 7 + H8_PORT_9, // 8 + H8_PORT_A, // 9 + H8_PORT_B, // A // analog inputs H8_ADC_0_H = 0x10, @@ -69,12 +82,12 @@ enum H8_ADC_3_L, // serial ports - H8_SERIAL_A = 0x20, - H8_SERIAL_B + H8_SERIAL_0 = 0x20, + H8_SERIAL_1, }; +CPU_GET_INFO( h8_300 ); CPU_GET_INFO( h8_3002 ); - -void h8_3002_InterruptRequest(UINT8 source); +CPU_GET_INFO( h8_3344 ); #endif /* __H83002_H__ */ diff --git a/src/emu/cpu/h83002/h83002.c b/src/emu/cpu/h83002/h83002.c deleted file mode 100644 index 086db93dac2..00000000000 --- a/src/emu/cpu/h83002/h83002.c +++ /dev/null @@ -1,4162 +0,0 @@ -/*************************************************************************** - - h83002.c: Hitachi H8/3002 microcontroller emulator - - Original by The_Author & DynaChicken for the ZiNc emulator. - - Rewrite for MAME by R. Belmont, including... - - Changed types to MAME standards - - Added MAME cpuintrf glue - - Put all per-CPU state in a struct - - Fixed ADD flag calcs - - Added support for all 8 flag bits - - Added cycle timing (probably not right yet) - - Fixed and optimized interrupt handling - - Optimized main execution loop - - Added new opcodes for ND-1 and System 23 BIOS programs - - Improved I/O and timer support - - Fixed major error in 7Cxx/7Dxx series bit opcodes where the wrong - instructions were being picked. - - TS 20060412 Added exts.l, sub.l, divxs.w (buggy), jsr @reg, rotxl.l reg, mov.l @(adr, reg), reg - LE 20070903 Added divxu.b shal.l extu.w dec.l #Imm,Rd subx.b - LE 20080202 Separated 3002/3044/3007, Added or.l shal.l rotl.l not.l neg.l exts.w - sub/or/xor.l #Imm:32,ERd bset/bnot/bclr.b Rn,@ERd bst/bist.b #Imm:3,@ERd bnot.b #Imm:3,@ERd - - Note: The H8/3000 series is normally back-compatible to the 8-bit H8/300, - but the 3002 does not include "emulation mode" - it always runs in full - 16/32-bit ("advanced") mode. So this core is not suitable for general - H8/300 emulation. - -****************************************************************************/ - -#include "debugger.h" -#include "h83002.h" -#include "h8priv.h" - -#define H8_SP (7) - -#define h8_mem_read8(x) program_read_byte_16be(x) -#define h8_mem_read16(x) program_read_word_16be(x) -#define h8_mem_write8(x, y) program_write_byte_16be(x, y) -#define h8_mem_write16(x, y) program_write_word_16be(x, y) - -// timing macros -// note: we assume a system 12 - type setup where external access is 3+1 states -// timing will be off somewhat for other configurations. -#define H8_IFETCH_TIMING(x) h8_cyccnt -= (x) * 4; -#define H8_BRANCH_TIMING(x) h8_cyccnt -= (x) * 4; -#define H8_STACK_TIMING(x) h8_cyccnt -= (x) * 4; -#define H8_BYTE_TIMING(x, adr) if (address24 >= 0xffff10) h8_cyccnt -= (x) * 3; else h8_cyccnt -= (x) * 4; -#define H8_WORD_TIMING(x, adr) if (address24 >= 0xffff10) h8_cyccnt -= (x) * 3; else h8_cyccnt -= (x) * 4; -#define H8_IOP_TIMING(x) h8_cyccnt -= (x); - -INLINE UINT32 h8_mem_read32(offs_t address) -{ - UINT32 result = program_read_word_16be(address) << 16; - return result | program_read_word_16be(address + 2); -} - -INLINE void h8_mem_write32(offs_t address, UINT32 data) -{ - program_write_word_16be(address, data >> 16); - program_write_word_16be(address + 2, data); -} - - -h83002_state h8; - -static INT32 h8_cyccnt; - -static UINT32 udata32, address24; -static INT32 sdata32; -static UINT16 udata16, ext16; -static INT16 sdata16; -static UINT8 udata8; -static INT8 sdata8; -static UINT8 srcreg, dstreg; - -/* internal functions */ - -static void h8_check_irqs(void); - -static void h8_group0(UINT16 opcode); -static void h8_group1(UINT16 opcode); -static void h8_group5(UINT16 opcode); -static void h8_group6(UINT16 opcode); -static void h8_group7(UINT16 opcode); - -static int h8_branch(UINT8 condition); - -static UINT8 h8_mov8(UINT8 src); -static UINT16 h8_mov16(UINT16 src); -static UINT32 h8_mov32(UINT32 src); - -static UINT8 h8_add8(UINT8 src, UINT8 dst); -static UINT16 h8_add16(UINT16 src, UINT16 dst); -static UINT32 h8_add32(UINT32 src, UINT32 dst); - -static UINT8 h8_sub8(UINT8 src, UINT8 dst); -static UINT16 h8_sub16(UINT16 src, UINT16 dst); -static UINT32 h8_sub32(UINT32 src, UINT32 dst); - -static UINT8 h8_addx8(UINT8 src, UINT8 dst); - -static void h8_cmp8(UINT8 src, UINT8 dst); -static void h8_cmp16(UINT16 src, UINT16 dst); -static void h8_cmp32(UINT32 src, UINT32 dst); -static UINT8 h8_subx8(UINT8 src, UINT8 dst); - -static UINT8 h8_or8(UINT8 src, UINT8 dst); -static UINT16 h8_or16(UINT16 src, UINT16 dst); -static UINT32 h8_or32(UINT32 src, UINT32 dst); - -static UINT8 h8_xor8(UINT8 src, UINT8 dst); -static UINT16 h8_xor16(UINT16 src, UINT16 dst); -static UINT32 h8_xor32(UINT32 src, UINT32 dst); - -static UINT8 h8_and8(UINT8 src, UINT8 dst); -static UINT16 h8_and16(UINT16 src, UINT16 dst); -static UINT32 h8_and32(UINT32 src, UINT32 dst); - -static INT8 h8_neg8(INT8 src); -static INT16 h8_neg16(INT16 src); -static INT32 h8_neg32(INT32 src); - -static UINT16 h8_divxu8 (UINT16 dst, UINT8 src); -static UINT32 h8_divxu16(UINT32 dst, UINT16 src); - -static UINT8 h8_not8(UINT8 src); -static UINT16 h8_not16(UINT16 src); -static UINT32 h8_not32(UINT32 src); - -static UINT8 h8_rotl8(UINT8 src); -static UINT16 h8_rotl16(UINT16 src); -static UINT32 h8_rotl32(UINT32 src); - -static UINT8 h8_rotxl8(UINT8 src); -static UINT16 h8_rotxl16(UINT16 src); -static UINT32 h8_rotxl32(UINT32 src); - -static UINT8 h8_rotxr8(UINT8 src); -static UINT16 h8_rotxr16(UINT16 src); - -static UINT8 h8_shll8(UINT8 src); -static UINT16 h8_shll16(UINT16 src); -static UINT32 h8_shll32(UINT32 src); - -static UINT8 h8_shlr8(UINT8 src); -static UINT16 h8_shlr16(UINT16 src); -static UINT32 h8_shlr32(UINT32 src); - -static INT8 h8_shal8(INT8 src); -static INT16 h8_shal16(INT16 src); -static INT32 h8_shal32(INT32 src); - -static INT8 h8_shar8(INT8 src); -static INT16 h8_shar16(INT16 src); -static INT32 h8_shar32(INT32 src); - -static UINT8 h8_dec8(UINT8 src); -static UINT16 h8_dec16(UINT16 src); -static UINT32 h8_dec32(UINT32 src); - -static UINT8 h8_inc8(UINT8 src); -static UINT16 h8_inc16(UINT16 src); -static UINT32 h8_inc32(UINT32 src); - -static UINT8 h8_bnot8(UINT8 src, UINT8 dst); -static UINT8 h8_bst8(UINT8 src, UINT8 dst); -static UINT8 h8_bist8(UINT8 src, UINT8 dst); -static UINT8 h8_bset8(UINT8 src, UINT8 dst); -static UINT8 h8_bclr8(UINT8 src, UINT8 dst); -static void h8_btst8(UINT8 src, UINT8 dst); -static void h8_bld8(UINT8 src, UINT8 dst); // loads to carry -static void h8_bor8(UINT8 src, UINT8 dst); // result in carry -//static void h8_bxor8(UINT8 src, UINT8 dst); - -static INT32 h8_mulxs16(INT16 src, INT16 dst); -static UINT32 h8_divxs16(INT16 src, INT32 dst); - -/* implementation */ - -extern CPU_DISASSEMBLE( h8 ); - -void h8_3002_InterruptRequest(UINT8 source) -{ - if(source>31) - { - h8.h8_IRQrequestH |= (1<<(source-32)); - } - else - { - h8.h8_IRQrequestL |= (1< 7) - { - return h8.regs[reg-8]>>16; - } - else - { - return h8.regs[reg]; - } -} - -static void h8_setreg16(UINT8 reg, UINT16 data) -{ - if(reg > 7) - { - h8.regs[reg-8] &= 0xffff; - h8.regs[reg-8] |= data<<16; - } - else - { - h8.regs[reg] &= 0xffff0000; - h8.regs[reg] |= data; - } -} - -static UINT8 h8_getreg8(UINT8 reg) -{ - if(reg > 7) - { - return h8.regs[reg-8]; - } - else - { - return h8.regs[reg]>>8; - } -} - -static void h8_setreg8(UINT8 reg, UINT8 data) -{ - if(reg > 7) - { - h8.regs[reg-8] &= 0xffffff00; - h8.regs[reg-8] |= data; - } - else - { - h8.regs[reg] &= 0xffff00ff; - h8.regs[reg] |= data<<8; - } -} - -static UINT32 h8_getreg32(UINT8 reg) -{ - return h8.regs[reg]; -} - -static void h8_setreg32(UINT8 reg, UINT32 data) -{ - h8.regs[reg] = data; -} - -static STATE_POSTLOAD( h8_onstateload ) -{ - h8_set_ccr(h8.ccr); -} - -static CPU_INIT( h8 ) -{ - memset(&h8, 0, sizeof(h8)); - h8.h8iflag = 1; - - h8.irq_cb = irqcallback; - h8.device = device; - - state_save_register_item("H8/3002", device->tag, 0, h8.h8err); - state_save_register_item_array("H8/3002", device->tag, 0, h8.regs); - state_save_register_item("H8/3002", device->tag, 0, h8.pc); - state_save_register_item("H8/3002", device->tag, 0, h8.ppc); - state_save_register_item("H8/3002", device->tag, 0, h8.h8_IRQrequestH); - state_save_register_item("H8/3002", device->tag, 0, h8.h8_IRQrequestL); - state_save_register_item("H8/3002", device->tag, 0, h8.ccr); - - state_save_register_item_array("H8/3002", device->tag, 0, h8.per_regs); - state_save_register_item("H8/3002", device->tag, 0, h8.h8TSTR); - state_save_register_item_array("H8/3002", device->tag, 0, h8.h8TCNT); - - state_save_register_postload(device->machine, h8_onstateload, NULL); - - h8_itu_init(); -} - -static CPU_INIT( h8_3007 ) -{ - CPU_INIT_CALL(h8); - h8_3007_itu_init(); -} - -static CPU_RESET( h8 ) -{ - h8.h8err = 0; - h8.pc = h8_mem_read32(0) & 0xffffff; - change_pc(h8.pc); - - // disable timers - h8.h8TSTR = 0; - - h8_itu_reset(); -} - -static void h8_GenException(UINT8 vectornr) -{ - // push PC on stack - // extended mode stack push! - h8_setreg32(H8_SP, h8_getreg32(H8_SP)-4); - h8_mem_write32(h8_getreg32(H8_SP), h8.pc); - // push ccr - h8_setreg32(H8_SP, h8_getreg32(H8_SP)-2); - h8_mem_write16(h8_getreg32(H8_SP), h8_get_ccr()); - - // generate address from vector - h8_set_ccr(h8_get_ccr() | 0x80); - if (h8.h8uiflag == 0) - h8_set_ccr(h8_get_ccr() | 0x40); - h8.pc = h8_mem_read32(vectornr * 4) & 0xffffff; - change_pc(h8.pc); - - // I couldn't find timing info for exceptions, so this is a guess (based on JSR/BSR) - H8_IFETCH_TIMING(2); - H8_STACK_TIMING(2); -} - -static int h8_get_priority(UINT8 bit) -{ - int res = 0; - switch(bit) - { - case 12: // IRQ0 - if (h8.per_regs[0xF8]&0x80) res = 1; break; - case 13: // IRQ1 - if (h8.per_regs[0xF8]&0x40) res = 1; break; - case 14: // IRQ2 - case 15: // IRQ3 - if (h8.per_regs[0xF8]&0x20) res = 1; break; - case 16: // IRQ4 - case 17: // IRQ5 - if (h8.per_regs[0xF8]&0x10) res = 1; break; - } - return res; -} - -static void h8_check_irqs(void) -{ - int lv = -1; - if (h8.h8iflag == 0) - { - lv = 0; - } - else - { - if ((h8.per_regs[0xF2]&0x08)/*SYSCR*/ == 0) - { - if (h8.h8uiflag == 0) - lv = 1; - } - } - - // any interrupts wanted and can accept ? - if(((h8.h8_IRQrequestH != 0) || (h8.h8_IRQrequestL != 0)) && (lv >= 0)) - { - UINT8 bit, source; - // which one ? - for(bit = 0, source = 0xff; source == 0xff && bit < 32; bit++) - { - if( h8.h8_IRQrequestL & (1<= lv) - { - // mask off - h8.h8_IRQrequestL &= ~(1<= lv) - { - // mask off - h8.h8_IRQrequestH &= ~(1<= 12 && source <= 17) - { - (*h8.irq_cb)(h8.device, source - 12 + H8_IRQ0); - } - - if (source != 0xff) - h8_GenException(source); - } -} - -static CPU_EXECUTE( h8 ) -{ - UINT16 opcode=0; - - h8_cyccnt = cycles; - - h8_check_irqs(); - - while ((h8_cyccnt > 0) && (!h8.h8err)) - { - h8.ppc = h8.pc; - - debugger_instruction_hook(device->machine, h8.pc); - - opcode = program_decrypted_read_word(h8.pc); -// mame_printf_debug("[%06x]: %04x => %x\n", h8.pc, opcode, (opcode>>12)&0xf); - h8.pc += 2; - - switch((opcode>>12) & 0xf) - { - case 0x0: - h8_group0(opcode); - break; - case 0x1: - h8_group1(opcode); - break; - case 0x2: - // mov.b @xx:8, Rd (abs) - dstreg = (opcode>>8) & 0xf; - udata8 = h8_mem_read8(0xffff00+(opcode & 0xff)); - h8_mov8(udata8); // flags calculation, dont care about others - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x3: // pass - // mov.b Rs, @xx:8 (abs) - srcreg = (opcode>>8) & 0xf; - udata8 = h8_getreg8(srcreg); - h8_mov8(udata8); // flags calculation, dont care about others - h8_mem_write8(0xffff00+(opcode & 0xff), udata8); - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING(1, 0xffff00+(opcode & 0xff)); - break; - case 0x4: - // bcc @xx:8 - sdata8 = (opcode & 0xff); - if( h8_branch((opcode >> 8) & 0xf) == 1)h8.pc += sdata8; - change_pc(h8.pc); - break; - case 0x5: - h8_group5(opcode); - break; - case 0x6: - h8_group6(opcode); - break; - case 0x7: - h8_group7(opcode); - break; - case 0x8: - // add.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - udata8 = h8_add8(opcode & 0xff, h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1) - break; - case 0x9: - // addx.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - udata8 = h8_addx8(opcode & 0xff, h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1) - break; - case 0xa: - // cmp.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - h8_cmp8(opcode & 0xff, h8_getreg8(dstreg)); - H8_IFETCH_TIMING(1); - break; - case 0xb: - // subx.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - udata8 = h8_subx8(opcode & 0xff, h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0xc: - // or.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - udata8 = h8_or8(opcode & 0xff, h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0xd: - // xor.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - udata8 = h8_xor8(opcode & 0xff, h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0xe: // pass - // and.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - udata8 = h8_and8(opcode & 0xff, h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1) - break; - case 0xf: // pass - // mov.b #xx:8, Rd - dstreg = (opcode>>8) & 0xf; - udata8 = h8_mov8(opcode & 0xff); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - } - } - - if (h8.h8err) - { - fatalerror("H8/3002: Unknown opcode (PC=%x) %x", h8.ppc, opcode); - - } - - return cycles - h8_cyccnt; -} - -static void h8_group0(UINT16 opcode) -{ - switch((opcode>>8)&0xf) - { - case 0: - // nop - H8_IFETCH_TIMING(1); - break; - case 0x1: - // 010x where x should always be 0! - if((opcode & 0xf) != 0) - { - h8.h8err = 1; - break; - } - switch((opcode>>4) & 0xf) - { - // 0100 mov.l prefix - case 0xf: // and.l Rn, Rn - ext16 = h8_mem_read16(h8.pc); - h8.pc += 2; - if (ext16 & 0x88) - { - h8.h8err = 1; - } - else - { - dstreg = ext16 & 0x7; - switch((ext16>>8)&0xff) - { - case 0x64: // or.l ERs, ERd - udata32 = h8_or32(h8_getreg32((ext16>>4) & 0x7), h8_getreg32(dstreg)); - break; - case 0x65: // xor.l ERs, ERd - udata32 = h8_xor32(h8_getreg32((ext16>>4) & 0x7), h8_getreg32(dstreg)); - break; - case 0x66: // and.l ERs, ERd - udata32 = h8_and32(h8_getreg32((ext16>>4) & 0x7), h8_getreg32(dstreg)); - break; - default: - h8.h8err = 1; - return; - } - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(2); - } - break; - - case 0: - ext16 = h8_mem_read16(h8.pc); - h8.pc+=2; - switch((ext16 >> 8) & 0xff) - { - case 0x69: - if((ext16 & 0x80) == 0x80) - { - // mov.l rx, @rx - udata32 = h8_mov32(h8_getreg32(ext16 & 7)); - h8_mem_write32(h8_getreg32((ext16 >> 4) & 7), udata32); - H8_IFETCH_TIMING(2); - H8_WORD_TIMING(2, h8_getreg32((ext16 >> 4) & 7)); - } - else - { - // mov.l @rx, rx - udata32 = h8_mem_read32(h8_getreg32( (ext16 >> 4) &7)); - h8_mov32(udata32); - h8_setreg32(ext16 & 7, udata32); - H8_IFETCH_TIMING(2); - H8_WORD_TIMING(2, h8_getreg32( (ext16 >> 4) &7)); - } - break; - case 0x6b: - // mov.l rx, @xx / mov.l @xx, rx - switch((ext16 >> 4)&0xf) - { - case 0x2: - // mov.l @aa:24, erx - address24=h8_mem_read32(h8.pc); - h8.pc += 4; - udata32=h8_mem_read32(address24); - h8_mov32(udata32); // flags only - h8_setreg32(ext16 & 0x7, udata32); - H8_IFETCH_TIMING(4); - H8_WORD_TIMING(2, address24); - break; - case 0xa: - // mov.l erx, @aa:24 - address24=h8_mem_read32(h8.pc); - h8.pc += 4; - udata32=h8_getreg32(ext16 & 0x7); - h8_mov32(udata32); // flags only - h8_mem_write32(address24, udata32); - H8_IFETCH_TIMING(4); - H8_WORD_TIMING(2, address24); - break; - default: - h8.h8err = 1; - break; - } - break; - case 0x6d: - if(ext16 & 0x80) - { - // mov.l rs, @-erd - srcreg = (ext16>>4)&7; - h8_setreg32(srcreg, h8_getreg32(srcreg)-4); - address24 = h8_getreg32(srcreg) & 0xffffff; - udata32 = h8_getreg32(ext16 & 0x7); - h8_mem_write32(address24, udata32); - H8_IFETCH_TIMING(2); - H8_WORD_TIMING(2, address24); - H8_IOP_TIMING(2); - } - else - { - // mov.l @ers+, rd - srcreg = (ext16 >>4)&7; - address24 = h8_getreg32(srcreg) & 0xffffff; - h8_setreg32(srcreg, h8_getreg32(srcreg)+4); - udata32 = h8_mem_read32(address24); - h8_setreg32(ext16 & 0x7, udata32); - H8_IFETCH_TIMING(2); - H8_WORD_TIMING(2, address24); - H8_IOP_TIMING(2); - } - h8_mov32(udata32); - break; - case 0x6f: - // mov.l @(displ16 + Rs), rd - sdata16=h8_mem_read16(h8.pc); // sign extend displacements ! - h8.pc += 2; - address24 = (h8_getreg32((ext16 >> 4)&7)) & 0xffffff; - address24 += sdata16; - H8_IFETCH_TIMING(3); - H8_WORD_TIMING(2, address24); - if(ext16 & 0x80) - { - udata32 = h8_getreg32(ext16 & 0x7); - h8_mem_write32(address24, udata32); - } - else - { - udata32 = h8_mem_read32(address24); - h8_setreg32(ext16 & 0x7, udata32); - } - h8_mov32(udata32); - break; - case 0x78: - // prefix for - // mov.l (@aa:x, rx), Rx - //00000A10 010078606B2600201AC2 MOV.L @($00201AC2,ER6),ER6 - // mov.l @(displ24 + Rs), rd - srcreg = (ext16 >> 4) & 7; - - // 6b20 - udata16 = h8_mem_read16(h8.pc); - h8.pc += 2; - dstreg = udata16 & 7; - - address24 = h8_mem_read32(h8.pc); - h8.pc += 4; - address24 += h8_getreg32(srcreg); - address24 &= 0xffffff; - - if ( (ext16 & 0x80) && ((udata16 & ~7) == 0x6ba0) ) - { - udata32 = h8_getreg32(dstreg); - h8_mem_write32(address24, udata32); - } - else if ( (!(ext16 & 0x80)) && ((udata16 & ~7) == 0x6b20) ) - { - udata32 = h8_mem_read32(address24); - h8_setreg32(dstreg, udata32); - } - else - { - h8.h8err = 1; - } - - h8_mov32(udata32); - - H8_IFETCH_TIMING(5); - H8_WORD_TIMING(2, address24); - - break; - default: - h8.h8err = 1; - break; - } - break; - case 0xc: - // mulxs - ext16 = h8_mem_read16(h8.pc); - h8.pc+=2; - if(((ext16>>8) & 0xf) == 0) - { - h8.h8err = 1; - } - else if(((ext16>>8) & 0xf) == 2) - { - sdata32 = h8_getreg32(ext16 & 0x7); - sdata16 = h8_getreg16((ext16>>4) & 0xf); - sdata32 = h8_mulxs16(sdata16, sdata32); - h8_setreg32(ext16 & 0x7, sdata32); - H8_IFETCH_TIMING(2); - H8_IOP_TIMING(20); - } - else - { - logerror("H8/3002: Unk. group 0 mulxs %x\n", opcode); - h8.h8err = 1; - } - break; - - case 0xd: - //divxs - probbaly buggy (flags?) - ext16 = h8_mem_read16(h8.pc); - h8.pc+=2; - if(((ext16>>8) & 0xf) == 0) - { - h8.h8err = 1; - } - else if(((ext16>>8) & 0xf) == 3) - { - sdata32 = h8_getreg32(ext16 & 0x7); - sdata16 = h8_getreg16((ext16>>4) & 0xf); - sdata32 = h8_divxs16(sdata16, sdata32); - h8_setreg32(ext16 & 0x7, sdata32); - H8_IFETCH_TIMING(2); - H8_IOP_TIMING(20); - } - else - { - h8.h8err = 1; - } - - - break; - - default: - h8.h8err = 1; - break; - } - break; - case 0x2: - // stc ccr, rd - if(((opcode>>4) & 0xf) == 0) - { - h8_setreg8(opcode & 0xf, h8_get_ccr()); - H8_IFETCH_TIMING(1); - } - else - { - logerror("H8/3002: Unk. group 0 2 %x\n", opcode); - h8.h8err = 1; - } - break; - case 0x3: - // ldc rd, ccr - if(((opcode>>4) & 0xf) == 0) - { - udata8 = h8_getreg8(opcode & 0xf); - h8_set_ccr(udata8); - H8_IFETCH_TIMING(1); - } - else - { - logerror("H8/3002: Unk. group 0 3 %x\n", opcode); - h8.h8err = 1; - } - break; - case 0x4: // pass - // orc - udata8 = h8_or8(opcode & 0xff, h8_get_ccr()); - h8_set_ccr(udata8); - H8_IFETCH_TIMING(1); - break; - case 0x6: - // andc - udata8 = h8_and8(opcode & 0xff, h8_get_ccr()); - h8_set_ccr(udata8); - H8_IFETCH_TIMING(1) - break; - // ldc - case 0x8: - // add.b rx, ry - dstreg = opcode & 0xf; - udata8 = h8_add8(h8_getreg8((opcode>>4) &0xf), h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1) - break; - // add.w rx, ry - case 0x9: - dstreg = opcode & 0xf; - udata16 = h8_add16(h8_getreg16((opcode>>4) &0xf), h8_getreg16(dstreg)); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1) - break; - // inc.b rx - case 0xA: - if(opcode&0x80) - { - if(opcode & 0x8) - { - logerror("H8/3002: Unk. group 0 a %x\n", opcode); - h8.h8err = 1; - } - else - { - dstreg = opcode & 0x7; - udata32 = h8_add32(h8_getreg32((opcode>>4) &0x7), h8_getreg32(dstreg)); - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1) - } - } - else - { - if(opcode & 0xf0) - { - logerror("H8/3002: Unk. group 0 a2 %x\n", opcode); - h8.h8err =1; - } - else - { - dstreg = opcode & 0xf; - udata8 = h8_inc8(h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - } - } - break; - case 0xb: - switch((opcode>>4)& 0xf) - { - case 0: - if(opcode & 8) - { - h8.h8err = 1; - } - else - { - dstreg = opcode & 7; - udata32 = h8_getreg32(dstreg) + 1; - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1) - } - break; - case 5: - dstreg = opcode & 0xf; - udata16 = h8_inc16(h8_getreg16(dstreg)); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 7: - dstreg = opcode & 0x7; - udata32 = h8_inc32(h8_getreg32(dstreg)); - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - case 8: - if(opcode & 8) - { - h8.h8err = 1; - } - else - { - dstreg = opcode & 7; - udata32 = h8_getreg32(dstreg) + 2; - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1) - } - break; - case 9: - if(opcode & 8) - { - h8.h8err = 1; - } - else - { - dstreg = opcode & 7; - udata32 = h8_getreg32(dstreg) + 4; - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1) - } - break; - case 0xd: - dstreg = opcode & 0xf; - udata16 = h8_inc16(h8_getreg16(dstreg)); - if(h8.h8vflag) - { - udata16 = h8_inc16(udata16); // slow and easy - h8.h8vflag = 1; - } - else - udata16 = h8_inc16(udata16); // slow and easy - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 0xf: - dstreg = opcode & 0x7; - udata32 = h8_inc32(h8_getreg32(dstreg)); - if(h8.h8vflag) - { - udata32 = h8_inc32(udata32); // slow and easy - h8.h8vflag = 1; - } - else - udata32 = h8_inc32(udata32); // slow and easy - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - default: - logerror("H8/3002: Unk. group 0 b %x\n", opcode); - h8.h8err = 1; - break; - } - break; - // mov.b rx, ry - case 0xc: // pass - dstreg = opcode & 0xf; - udata8 = h8_mov8(h8_getreg8((opcode>>4) &0xf)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0xd: - // mov.w rx, ry - dstreg = opcode & 0xf; - udata16 = h8_mov16(h8_getreg16((opcode>>4) &0xf)); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 0xf: - if(opcode & 0x80) - { - if(opcode & 8) - { - logerror("H8/3002: Unk. group 0 f %x\n", opcode); - h8.h8err = 1; - } - else - { - dstreg = opcode & 0x7; - udata32 = h8_mov32(h8_getreg32((opcode>>4) &0x7)); - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - } - } - else - { - h8.h8err = 1; - logerror("H8/3002: Unk. group 0 f2 %x\n", opcode); - if((opcode & 0xf0) !=0) - { - h8.h8err = 1; - } - else - { - h8.h8err = 1; - } - } - break; - default: - logerror("H8/3002: Unk. group 0 tdef %x\n", opcode); - h8.h8err = 1; - break; - } -} - -static void h8_group1(UINT16 opcode) -{ - switch((opcode>>8)&0xf) - { - case 0x0: - switch((opcode>>4)&0xf) - { - case 0x0: - // shll.b Rx - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_shll8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x1: - // shll.w Rx - udata16 = h8_getreg16(opcode & 0xf); - udata16 = h8_shll16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - break; - case 0x3: - // shal.l Rx - udata32 = h8_getreg32(opcode & 0x7); - udata32 = h8_shll32(udata32); - h8_setreg32(opcode & 0x7, udata32); - H8_IFETCH_TIMING(1); - break; - - case 0x8: - // shal.b Rx - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_shal8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x9: - // shal.w Rx - udata16 = h8_getreg16(opcode & 0xf); - udata16 = h8_shal16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - break; - case 0xb: - // shal.l ERx - udata32 = h8_getreg32(opcode & 0x7); - udata32 = h8_shal32(udata32); - h8_setreg32(opcode & 0x7, udata32); - H8_IFETCH_TIMING(1); - break; - - default: - logerror("H8/3002: Unk. group 1 0 %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0x1: - switch((opcode>>4)&0xf) - { - case 0x0: - // shlr.b rx - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_shlr8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x1: - // shlr.w rx - udata16 = h8_getreg16(opcode & 0xf); - udata16 = h8_shlr16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - break; - // shlr.l rx - case 0x3: - udata32 = h8_getreg32(opcode & 0x7); - udata32 = h8_shlr32(udata32); - h8_setreg32(opcode & 0x7, udata32); - H8_IFETCH_TIMING(1); - break; - case 0x8: - // shar.b rx - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_shar8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x9: - // shar.w rx - udata16 = h8_getreg16(opcode & 0xf); - udata16 = h8_shar16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - break; - case 0xb: - // shar.l rx - udata32 = h8_getreg32(opcode & 0x7); - udata32 = h8_shar32(udata32); - h8_setreg32(opcode & 0x7, udata32); - H8_IFETCH_TIMING(1); - break; - default: - logerror("H8/3002: Unk. group 1 1 %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0x2: - switch((opcode>>4)&0xf) - { - case 0x0: - // rotxl.b Rx - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_rotxl8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x1: - // rotxl.w Rx - udata16 = h8_getreg16(opcode & 0xf); - udata16 = h8_rotxl16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - break; - - case 0x3: - // rotxl.l Rx - udata32 = h8_getreg32(opcode & 0x7); - udata32 = h8_rotxl32(udata32); - h8_setreg32(opcode & 0xf, udata32); - H8_IFETCH_TIMING(1); - break; - - case 0x8: - // rotl.b Rx - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_rotl8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x9: - // rotl.w Rx - udata16 = h8_getreg16(opcode & 0xf); - udata16 = h8_rotl16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - break; - case 0xb: - // rotl.l ERx - udata32 = h8_getreg32(opcode & 0x7); - udata32 = h8_rotl32(udata32); - h8_setreg32(opcode & 0x7, udata32); - H8_IFETCH_TIMING(1); - break; - - default: - logerror("H8/3002: Unk. group 1 2 %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0x3: - switch((opcode>>4)&0xf) - { - case 0x0: - // rotxr.b Rx - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_rotxr8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x1: - // rotxr.w Rx - udata16 = h8_getreg16(opcode & 0xf); - udata16 = h8_rotxr16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - break; - default: - logerror("H8/3002: Unk. group 1 3 %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0x4: - // or.b rs, rd - dstreg = opcode & 0xf; - udata8 = h8_or8(h8_getreg8((opcode>>4) &0xf), h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x5: - // xor.b rs, rd - dstreg = opcode & 0xf; - udata8 = h8_xor8(h8_getreg8((opcode>>4) &0xf), h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x6: - // and.b rs, rd - dstreg = opcode & 0xf; - udata8 = h8_and8(h8_getreg8((opcode>>4) &0xf), h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1) - break; - // not - case 0x7: - switch((opcode>>4)&0xf) - { - case 0x0: - // not.b Rx - dstreg = opcode & 0xf; - udata8 = h8_not8(h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x1: - // not.w Rx - dstreg = opcode & 0xf; - udata16 = h8_not16(h8_getreg16(dstreg)); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 0x3: - // not.l ERx - dstreg = opcode & 0x7; - udata32 = h8_not32(h8_getreg32(dstreg)); - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - - case 0x5: - // extu.w Rx - dstreg = opcode & 0xf; - udata16 = h8_getreg16(dstreg) & 0x00ff; - h8_setreg16(dstreg, udata16); - h8.h8nflag = 0; - h8.h8vflag = 0; - h8.h8zflag = ((udata16 == 0) ? 1 : 0); - H8_IFETCH_TIMING(1); - break; - case 0x7: - // extu.l Rx - dstreg = opcode & 0x7; - udata32 = h8_getreg32(dstreg) & 0x0000ffff; - h8_setreg32(dstreg, udata32); - h8.h8nflag = 0; - h8.h8vflag = 0; - h8.h8zflag = ((udata32 == 0) ? 1 : 0); - H8_IFETCH_TIMING(1); - break; - case 0x8: - // neg.b Rx - dstreg = opcode & 0xf; - sdata8 = h8_neg8(h8_getreg8(dstreg)); - h8_setreg8(dstreg, sdata8); - H8_IFETCH_TIMING(1); - break; - case 0x9: - // neg.w Rx - dstreg = opcode & 0xf; - sdata16 = h8_neg16(h8_getreg16(dstreg)); - h8_setreg16(dstreg, sdata16); - H8_IFETCH_TIMING(1); - break; - case 0xb: - // neg.l ERx - dstreg = opcode & 0x7; - sdata32 = h8_neg32(h8_getreg32(dstreg)); - h8_setreg32(dstreg, sdata32); - H8_IFETCH_TIMING(1); - break; - case 0xd: - // exts.w Rx - dstreg = opcode & 0xf; - udata16=h8_getreg16(dstreg)&0xff; - if(udata16&0x80) - { - udata16|=0xff00; - } - h8_setreg16(dstreg, udata16); - - h8.h8vflag = 0; - h8.h8nflag = (udata16 & 0xff00) ? 1 : 0; - h8.h8zflag = (udata16) ? 0 : 1; - - H8_IFETCH_TIMING(1); - break; - - case 0xf: - // exts.l Rx - dstreg = opcode & 0x7; - udata32=h8_getreg32(dstreg)&0xffff; - if(udata32&0x8000) - { - udata32|=0xffff0000; - } - h8_setreg32(dstreg, udata32); - - h8.h8vflag = 0; - h8.h8nflag = (udata32 & 0xffff0000) ? 1 : 0; - h8.h8zflag = (udata32) ? 0 : 1; - - H8_IFETCH_TIMING(1); - break; - - default: - logerror("H8/3002: Unk. group 1 7-9 %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0x8: - // sub.b rs, rd - dstreg = opcode & 0xf; - udata8 = h8_sub8(h8_getreg8((opcode>>4) &0xf), h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0x9: - // sub.w rs, rd - dstreg = opcode & 0xf; - udata16 = h8_sub16(h8_getreg16((opcode>>4) &0xf), h8_getreg16(dstreg)); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - // sub.b rx - case 0xA: - if(opcode&0x80) - { - //logerror("H8/3002: Unk. group 1 A %x\n", opcode); - - // sub.l rs,rd - dstreg = opcode & 0x7; - udata32=h8_sub32(h8_getreg32((opcode>>4) &0x7), h8_getreg32(dstreg)); - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(2); - break; - - } - else - { - if(opcode & 0xf0) - { - logerror("H8/3002: Unk. group A2 0 %x\n", opcode); - h8.h8err = 1; - } - else - { - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_dec8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - } - } - break; - // - case 0xb: - switch((opcode>>4)& 0xf) - { - case 0: // subs.l #1, rN (decrement without touching flags) - dstreg = opcode & 0x7; - udata32 = h8_getreg32(dstreg); - udata32--; - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - case 5: // dec.w #1, rN - dstreg = opcode & 0xf; - udata16 = h8_dec16(h8_getreg16(dstreg)); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 7: // dec.l #1, rN - dstreg = opcode & 0x7; - udata32 = h8_dec32(h8_getreg32(dstreg)); - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - case 8: // subs.l #2, rN (decrement without touching flags) - dstreg = opcode & 0x7; - udata32 = h8_getreg32(dstreg); - udata32-=2; - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - case 9: // subs.l #4, rN (decrement without touching flags) - dstreg = opcode & 0x7; - udata32 = h8_getreg32(dstreg); - udata32-=4; - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - case 0xd: // dec.w #2, rN - dstreg = opcode & 0xf; - udata16 = h8_dec16(h8_getreg16(dstreg)); - if (h8.h8vflag) - { - udata16 = h8_dec16(udata16); - h8.h8vflag = 1; - } - else - udata16 = h8_dec16(udata16); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 0xf: // dec.l #2, rN - dstreg = opcode & 0x7; - udata32 = h8_dec32(h8_getreg32(dstreg)); - if (h8.h8vflag) - { - udata32 = h8_dec32(udata32); - h8.h8vflag = 1; - } - else - udata32 = h8_dec32(udata32); - h8_setreg32(dstreg, udata32); - H8_IFETCH_TIMING(1); - break; - - default: - logerror("H8/3002: Unk. group 1 B %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0xc: - // cmp.b rs, rd - h8_cmp8(h8_getreg8((opcode>>4) &0xf), h8_getreg8(opcode & 0xf)); - H8_IFETCH_TIMING(1); - break; - case 0xd: - // cmp.w rx, ry - h8_cmp16(h8_getreg16((opcode>>4) &0xf), h8_getreg16(opcode & 0xf)); - H8_IFETCH_TIMING(1); - break; - case 0xe: - // subx.b rx, ry - dstreg = opcode & 0xf; - udata8 = h8_subx8(h8_getreg8((opcode>>4) &0xf), h8_getreg8(dstreg)); - h8_setreg8(dstreg, udata8); - H8_IFETCH_TIMING(1); - break; - case 0xf: - if(opcode & 0x80) - { - if(opcode & 8) - { - logerror("H8/3002: Unk. group 1 f %x\n", opcode); - h8.h8err = 1; - } - else - { - h8_cmp32(h8_getreg32((opcode>>4) & 0x7), h8_getreg32(opcode & 0x7)); - H8_IFETCH_TIMING(1); - } - } - else - { - logerror("H8/3002: Unk. group 1 f2 %x\n", opcode); - h8.h8err = 1; - } - break; - default: - logerror("H8/3002: Unk. group 1 def %x\n", opcode); - h8.h8err = 1; - break; - } -} - - -static void h8_group5(UINT16 opcode) -{ - switch((opcode>>8)&0xf) - { - case 0x0: - // mulxu.b - udata8 = h8_getreg8((opcode>>4)&0xf); - udata16 = h8_getreg16(opcode & 0xf); - udata16 &= 0xff; - udata16 = udata16*udata8; - // no flags modified! - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - H8_IOP_TIMING(12); - break; - case 0x1: - // divxu.b - udata8 = h8_getreg8((opcode>>4)&0xf); - udata16 = h8_getreg16(opcode & 0x0f); - udata16 = h8_divxu8(udata16,udata8); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - H8_IOP_TIMING(12); - break; - case 0x2: - // mulxu.w - udata16 = h8_getreg16((opcode>>4)&0xf); - udata32 = h8_getreg32(opcode & 7); - udata32 &= 0xffff; - udata32 = udata32*udata16; - // no flags modified! - h8_setreg32(opcode & 7, udata32); - H8_IFETCH_TIMING(1); - H8_IOP_TIMING(20); - break; - case 0x3: - // divxu.w - udata16 = h8_getreg16((opcode>>4)&0xf); - udata32 = h8_getreg32(opcode & 7); - udata32 = h8_divxu16(udata32,udata16); - h8_setreg32(opcode & 7, udata32); - H8_IFETCH_TIMING(1); - H8_IOP_TIMING(20); - break; - case 0x4: - if(opcode == 0x5470) - { - // rts - udata32 = h8_mem_read32(h8_getreg32(H8_SP)); - h8_setreg32(H8_SP, h8_getreg32(H8_SP)+4); - // extended mode - h8.pc = udata32; - change_pc(h8.pc); - H8_IFETCH_TIMING(2); - H8_STACK_TIMING(2); - H8_IOP_TIMING(2); - } - else - { - logerror("H8/3002: Unk. group 5 1 %x\n", opcode); - h8.h8err = 1; - } - break; - case 0x5: - // bsr 8 - sdata8 = opcode & 0xff; - // extended mode stack push! - h8_setreg32(H8_SP, h8_getreg32(H8_SP)-4); - h8_mem_write32(h8_getreg32(H8_SP), h8.pc); - h8.pc = h8.pc + sdata8; - change_pc(h8.pc); - H8_IFETCH_TIMING(2); H8_STACK_TIMING(2); - break; - case 0x6: - // rte - if(opcode == 0x5670) - { - // restore CCR - udata16 = h8_mem_read16(h8_getreg32(H8_SP)); - h8_setreg32(H8_SP, h8_getreg32(H8_SP)+2); - // extended mode restore PC - udata32 = h8_mem_read32(h8_getreg32(H8_SP)); - h8_setreg32(H8_SP, h8_getreg32(H8_SP)+4); - // extended mode - h8.pc = udata32; - change_pc(h8.pc); - // must do this last, because set_ccr() does a check_irq() - h8_set_ccr((UINT8)udata16); - H8_IFETCH_TIMING(2); - H8_STACK_TIMING(2); - H8_IOP_TIMING(2); - } - else - { - logerror("H8/3002: Unk. group 5 6 %x\n", opcode); - h8.h8err = 1; - } - break; - // trapa - case 0x7: - logerror("H8/3002: Unk. group 5 7 %x\n", opcode); - h8.h8err = 1; - break; - case 0x8: - // bcc @xx:16 - if(opcode & 0xf) - { - logerror("H8/3002: Unk. group 5 8 %x\n", opcode); - h8.h8err = 1; - } - else - { - sdata16 = h8_mem_read16(h8.pc); - h8.pc += 2; - if( h8_branch((opcode >> 4) & 0xf) == 1)h8.pc += sdata16; - change_pc(h8.pc); - H8_IOP_TIMING(2) - } - break; - case 0x9: - // jmp @erd - address24 = h8_getreg32((opcode>>4)&7); - address24 &= 0xffffff; - h8.pc = address24; - change_pc(h8.pc); - H8_IFETCH_TIMING(2); - break; - // jmp @aa:24 - case 0xa: - address24=h8_mem_read32(h8.pc-2); - address24 &= 0xffffff; - h8.pc = address24; - change_pc(h8.pc); - H8_IFETCH_TIMING(2); - H8_IOP_TIMING(2); - break; - // jmp @aa:8 - case 0xc: - if(opcode & 0xff) - { - logerror("H8/3002: Unk. group 5 c %x\n", opcode); - h8.h8err = 1; - } - else - { - // bsr d:16 - sdata16=h8_mem_read16(h8.pc); - h8_setreg32(H8_SP, h8_getreg32(H8_SP)-4); - h8_mem_write32(h8_getreg32(H8_SP), h8.pc+2); - h8.pc += sdata16 + 2; - change_pc(h8.pc); - H8_IFETCH_TIMING(2); H8_STACK_TIMING(2); H8_IOP_TIMING(2); - } - break; - case 0xd: - // jsr @reg - address24=h8_getreg32((opcode>>4)&7); - address24 &= 0xffffff; - // extended mode stack push! - h8_setreg32(H8_SP, h8_getreg32(H8_SP)-4); - h8_mem_write32(h8_getreg32(H8_SP), h8.pc); - h8.pc = address24; - change_pc(h8.pc); - H8_STACK_TIMING(2); - H8_IOP_TIMING(2); - break; - case 0xe: - // jsr @aa:24 - address24=h8_mem_read32(h8.pc-2); - address24 &= 0xffffff; - // extended mode stack push! - h8_setreg32(H8_SP, h8_getreg32(H8_SP)-4); - h8_mem_write32(h8_getreg32(H8_SP), h8.pc+2); - h8.pc = address24; - change_pc(h8.pc); - H8_IFETCH_TIMING(2); - H8_STACK_TIMING(2); - H8_IOP_TIMING(2); - break; - // jsr @aa:8 - default: - logerror("H8/3002: Unk. group 5 def %x\n", opcode); - h8.h8err = 1; - break; - } -} - -static void h8_group6(UINT16 opcode) -{ - switch((opcode>>8)&0xf) - { - case 0:case 1:case 2:case 3: - { - UINT8 bitnr; - - dstreg = opcode & 0xf; - udata8 = h8_getreg8(dstreg); - bitnr = h8_getreg8((opcode>>4)& 0xf)&7; - - switch((opcode>>8)&0xf) - { - case 0: udata8 = h8_bset8(bitnr, udata8); h8_setreg8(dstreg, udata8); H8_IFETCH_TIMING(1); break; - case 2: udata8 = h8_bclr8(bitnr, udata8); h8_setreg8(dstreg, udata8); H8_IFETCH_TIMING(1); break; - case 3: h8_btst8(bitnr, udata8); H8_IFETCH_TIMING(1); break; - default: - logerror("H8/3002: Unk. group 6 def 0-3-0 %x\n", opcode); - h8.h8err = 1; - break; - } - } - break; - case 0x4: - // or.w rs, rd - dstreg = opcode & 0xf; - udata16 = h8_getreg16(dstreg); - udata16 = h8_or16(h8_getreg16((opcode>>4) & 0xf), udata16); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 0x5: - // xor.w rs, rd - dstreg = opcode & 0xf; - udata16 = h8_getreg16(dstreg); - udata16 = h8_xor16(h8_getreg16((opcode>>4) & 0xf), udata16); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1); - break; - case 0x6: - // and.w rs, rd - dstreg = opcode & 0xf; - udata16 = h8_getreg16(dstreg); - udata16 = h8_and16(h8_getreg16((opcode>>4) & 0xf), udata16); - h8_setreg16(dstreg, udata16); - H8_IFETCH_TIMING(1) - break; - case 0x7: - // bst/bist #imm, rd - if(opcode & 0x80) - { - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_bist8((opcode>>4) & 7, udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - } - else - { - udata8 = h8_getreg8(opcode & 0xf); - udata8 = h8_bst8((opcode>>4) & 7, udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - } - break; - case 0x8: - if(opcode & 0x80) - { - // mov.b rx, @rx - udata8 = h8_getreg8(opcode & 0xf); - address24 = h8_getreg32((opcode>>4)&7) & 0xffffff; - h8_mov8(udata8); - h8_mem_write8(address24, udata8); - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING(1, address24); - } - else - { - // mov.b @rx, rx - address24 = h8_getreg32((opcode>>4)&7) & 0xffffff; - udata8 = h8_mem_read8(address24); - h8_mov8(udata8); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING(1, address24); - } - break; - case 0x9: - if(opcode & 0x80) - { - // mov.w rx, @rx - address24 = h8_getreg32((opcode>>4)&7) & 0xffffff; - udata16 = h8_getreg16(opcode & 0xf); - h8_mov16(udata16); - h8_mem_write16(address24, udata16); - H8_IFETCH_TIMING(1); - H8_WORD_TIMING(1, address24); - } - else - { - // mov.w @rx, rx - address24 = h8_getreg32((opcode>>4)&7) & 0xffffff; - udata16 = h8_mem_read16(address24); - h8_mov16(udata16); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - H8_WORD_TIMING(1, address24); - } - break; - case 0xa: - // mov.b rx, @xx - switch((opcode>>4)&0xf) - { - case 0x0: - sdata16=h8_mem_read16(h8.pc); - h8.pc += 2; - address24 = sdata16 & 0xffffff; - udata8=h8_mem_read8(address24); - h8_mov8(udata8); // flags only - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING(1, address24); - break; - case 0x2: - address24=h8_mem_read32(h8.pc); - h8.pc += 4; - udata8=h8_mem_read8(address24); - h8_mov8(udata8); // flags only - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(2); - H8_BYTE_TIMING(1, address24); - break; - case 0x8: - sdata16=h8_mem_read16(h8.pc); - h8.pc += 2; - address24 = sdata16 & 0xffffff; - udata8=h8_getreg8(opcode & 0xf); - h8_mov8(udata8); // flags only - h8_mem_write8(address24, udata8); - H8_IFETCH_TIMING(3); - H8_BYTE_TIMING(1, address24); - break; - case 0xa: // pass - address24=h8_mem_read32(h8.pc); - h8.pc += 4; - udata8=h8_getreg8(opcode & 0xf); - h8_mov8(udata8); // flags only - h8_mem_write8(address24, udata8); - H8_IFETCH_TIMING(3); - H8_BYTE_TIMING(1, address24); - break; - default: - logerror("H8/3002: Unk. group 6 a %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0xb: - // mov.w rx, @xx / mov.w @xx, rx - switch((opcode>>4)&0xf) - { - case 0x0: - sdata16=h8_mem_read16(h8.pc); - address24 = sdata16; - address24 &= 0xffffff; - h8.pc += 2; - udata16=h8_mem_read16(address24); - h8_mov16(udata16); // flags only - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(2); - H8_WORD_TIMING(1, address24); - break; - case 0x2: - address24=h8_mem_read32(h8.pc); - h8.pc += 4; - udata16=h8_mem_read16(address24); - h8_mov16(udata16); // flags only - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(4); - H8_WORD_TIMING(1, address24); - break; - case 0x8: - sdata16=h8_mem_read16(h8.pc); - address24 = sdata16; - address24 &= 0xffffff; - h8.pc += 2; - udata16=h8_getreg16(opcode & 0xf); - h8_mov16(udata16); // flags only - h8_mem_write16(address24, udata16); - H8_IFETCH_TIMING(2); - H8_WORD_TIMING(1, address24); - break; - case 0xa: // pass - address24=h8_mem_read32(h8.pc); - h8.pc += 4; - udata16=h8_getreg16(opcode & 0xf); - h8_mov16(udata16); // flags only - h8_mem_write16(address24, udata16); - H8_IFETCH_TIMING(4); - H8_WORD_TIMING(1, address24); - break; - default: - logerror("H8/3002: Unk. group 6b %x\n", opcode); - h8.h8err = 1; - break; - } - break; - case 0xc: - if(opcode & 0x80) - { - // mov.b rx, @-erx - srcreg = (opcode>>4)&7; - h8_setreg32(srcreg, h8_getreg32(srcreg)-1); - address24 = h8_getreg32(srcreg) & 0xffffff; - udata8 = h8_getreg8(opcode & 0xf); - h8_mem_write8(address24, udata8); - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING(1, address24); - H8_IOP_TIMING(2); - } - else - { - // mov.b @erx+,rx - srcreg = (opcode>>4)&7; - address24 = h8_getreg32(srcreg) & 0xffffff; - h8_setreg32(srcreg, h8_getreg32(srcreg)+1); - udata8 = h8_mem_read8(address24); - h8_setreg8(opcode & 0xf, udata8); - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING(1, address24); - H8_IOP_TIMING(2); - } - h8_mov8(udata8); - break; - case 0xd: - if(opcode & 0x80) - { - // mov.w rs, @-erd - srcreg = (opcode>>4)&7; - h8_setreg32(srcreg, h8_getreg32(srcreg)-2); - address24 = h8_getreg32(srcreg) & 0xffffff; - udata16 = h8_getreg16(opcode & 0xf); - h8_mem_write16(address24, udata16); - H8_IFETCH_TIMING(1); - H8_WORD_TIMING(1, address24); - H8_IOP_TIMING(2); - } - else - { - // mov.w @ers+, rd - srcreg = (opcode>>4)&7; - address24 = h8_getreg32(srcreg) & 0xffffff; - h8_setreg32(srcreg, h8_getreg32(srcreg)+2); - udata16 = h8_mem_read16(address24); - h8_setreg16(opcode & 0xf, udata16); - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING(1, address24); - H8_IOP_TIMING(2); - } - h8_mov16(udata16); - break; - case 0xe: // pass - // mov.b @(displ16 + Rs), rd - sdata16=h8_mem_read16(h8.pc); // sign extend displacements ! - h8.pc += 2; - address24 = (h8_getreg32((opcode>>4)&7)) & 0xffffff; - address24 += sdata16; - if(opcode & 0x80) - { - udata8 = h8_getreg8(opcode & 0xf); - h8_mem_write8(address24, udata8); - } - else - { - udata8 = h8_mem_read8(address24); - h8_setreg8(opcode & 0xf, udata8); - } - h8_mov8(udata8); - H8_IFETCH_TIMING(2); - H8_BYTE_TIMING(1, address24); - break; - case 0xf: - // mov.w @(displ16 + Rs), rd - sdata16=h8_mem_read16(h8.pc); // sign extend displacements ! - h8.pc += 2; - address24 = (h8_getreg32((opcode>>4)&7)) & 0xffffff; - address24 += sdata16; - if(opcode & 0x80) - { - udata16 = h8_getreg16(opcode & 0xf); - h8_mem_write16(address24, udata16); - } - else - { - udata16 = h8_mem_read16(address24); - h8_setreg16(opcode & 0xf, udata16); - } - h8_mov16(udata16); - H8_IFETCH_TIMING(2); - H8_WORD_TIMING(1, address24); - break; - default: - logerror("H8/3002: Unk. group 6 def %x\n", opcode); - h8.h8err = 1; - break; - } -} - -static void h8_group7(UINT16 opcode) -{ - switch((opcode>>8)&0xf) - { - case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7: - { - UINT8 bitnr; - - dstreg = opcode & 0xf; - udata8 = h8_getreg8(dstreg); - bitnr = (opcode>>4)&7; - - if(((opcode>>4)&0x8) == 0) - { - switch((opcode>>8)&7) - { - case 0: udata8 = h8_bset8(bitnr, udata8); h8_setreg8(dstreg, udata8); H8_IFETCH_TIMING(1); break; - case 2: udata8 = h8_bclr8(bitnr, udata8); h8_setreg8(dstreg, udata8);H8_IFETCH_TIMING(1);break; - case 3: h8_btst8(bitnr, udata8); H8_IFETCH_TIMING(1); break; - case 7: h8_bld8(bitnr, udata8); H8_IFETCH_TIMING(1); break; - default: - logerror("H8/3002: Unk. group 7 0-7 def %x\n", opcode); - h8.h8err = 1; - break; - } - } - else - { - switch((opcode>>8)&7) - { - default: - logerror("H8/3002: Unk. group 7 0-7-1 def %x\n", opcode); - h8.h8err = 1; - break; - } - } - } - break; - case 0x8: - ext16 = h8_mem_read16(h8.pc); - h8.pc += 2; - udata32 = h8_mem_read32(h8.pc); - h8.pc += 4; - - if(((ext16>>8) & 0xf) == 0xa) - { - if(((ext16>>4) & 0xf) == 0xa) - { - udata8 = h8_getreg8(ext16 & 0xf); - h8_mov8(udata8); // update flags ! - udata32 += h8_getreg32((opcode >> 4) & 7); - h8_mem_write8(udata32, udata8); - } - else - { - udata32 += h8_getreg32((opcode >> 4) & 7); - udata8 = h8_mem_read8(udata32); - h8_mov8(udata8); // update flags ! - h8_setreg8(ext16 & 0xf, udata8); - } - H8_BYTE_TIMING(1, udata32); - H8_IFETCH_TIMING(4); - } - else if ((ext16 & 0xfff0) == 0x6b20) // mov.w @(24-bit direct, rN), rM - { - udata32 += h8_getreg32((opcode >> 4) & 7); - udata16 = h8_mem_read16(udata32); - h8_setreg16(ext16 & 0xf, udata16); - h8_mov16(udata16); // update flags ! - H8_WORD_TIMING(1, udata32); - H8_IFETCH_TIMING(4); - } - else if ((ext16 & 0xfff0) == 0x6ba0) // mov.w rM, @(24-bit direct, rN) - { - udata32 += h8_getreg32((opcode >> 4) & 7); - udata16 = h8_getreg16(ext16 & 0xf); - h8_mem_write16(udata32, udata16); - h8_mov16(udata16); // update flags ! - H8_WORD_TIMING(1, udata32); - H8_IFETCH_TIMING(4); - } - else - { - logerror("H8/3002: Unk. group 7 8 %x\n", opcode); - h8.h8err = 1; - } - break; - - - // xxx.w #aa:16, rd - case 0x9: - if( ((opcode>>4) & 0xf) > 0x6) - { - logerror("H8/3002: Unk. group 7 9 %x\n", opcode); - h8.h8err = 1; - } - else - { - UINT16 dst16; - udata16 = h8_mem_read16(h8.pc); - h8.pc += 2; - dstreg = opcode&0xf; - dst16 = h8_getreg16(dstreg); - - switch((opcode>>4)&7) - { - case 0: dst16 = h8_mov16(udata16); h8_setreg16(dstreg, dst16); H8_IFETCH_TIMING(2);break; - case 1: dst16 = h8_add16(udata16, dst16); h8_setreg16(dstreg, dst16); H8_IFETCH_TIMING(2); break; - case 2: h8_cmp16(udata16, dst16); H8_IFETCH_TIMING(2); break; - case 3: dst16 = h8_sub16(udata16, dst16); h8_setreg16(dstreg, dst16); H8_IFETCH_TIMING(2); break; - case 4: dst16 = h8_or16(udata16, dst16); h8_setreg16(dstreg, dst16); H8_IFETCH_TIMING(2); break; - case 5: dst16 = h8_xor16(udata16, dst16); h8_setreg16(dstreg, dst16); H8_IFETCH_TIMING(2); break; - case 6: dst16 = h8_and16(udata16, dst16); h8_setreg16(dstreg, dst16); H8_IFETCH_TIMING(2); break; - default: - logerror("H8/3002: Unk. group 7 9 %x\n", opcode); - h8.h8err = 1; - break; - } - } - break; - // xxx.l #aa:32, erd - case 0xa: - if( (((opcode>>4) & 0xf) > 0x6) || (opcode & 0x8)) - { - logerror("H8/3002: Unk. group 7 a %x\n", opcode); - h8.h8err = 1; - } - else - { - UINT32 dst32; - udata32 = h8_mem_read32(h8.pc); - dstreg = opcode&0x7; - h8.pc +=4; - dst32 = h8_getreg32(dstreg); - - switch((opcode>>4)&7) - { - case 0: dst32 = h8_mov32(udata32); h8_setreg32(dstreg, dst32); H8_IFETCH_TIMING(3); break; - case 1: dst32 = h8_add32(udata32, dst32); h8_setreg32(dstreg, dst32); H8_IFETCH_TIMING(3); break; - case 2: h8_cmp32(udata32, dst32); H8_IFETCH_TIMING(3); break; - case 3: dst32 = h8_sub32(udata32, dst32); h8_setreg32(dstreg, dst32); H8_IFETCH_TIMING(3); break; - case 4: dst32 = h8_or32(udata32, dst32); h8_setreg32(dstreg, dst32); H8_IFETCH_TIMING(3); break; - case 5: dst32 = h8_xor32(udata32, dst32); h8_setreg32(dstreg, dst32); H8_IFETCH_TIMING(3); break; - case 6: dst32 = h8_and32(udata32, dst32); h8_setreg32(dstreg, dst32); H8_IFETCH_TIMING(3); break; - default: - logerror("H8/3002: Unk. group 7 a2 %x\n", opcode); - h8.h8err = 1; - break; - } - } - break; - // eepmov - case 0xb: - if ((opcode & 0xff) == 0xd4) - { - UINT16 cnt = h8_getreg16(4); - - H8_IFETCH_TIMING(1); - H8_BYTE_TIMING((2*cnt)+2, h8.regs[5]); - - // eepmov.w - while (cnt > 0) - { - h8_mem_write8(h8.regs[6], h8_mem_read8(h8.regs[5])); - h8.regs[5]++; - h8.regs[6]++; - cnt--; - } - h8_setreg16(4, 0); - h8.pc += 2; - } - else - { - logerror("H8/3002: Unk. eepmov form\n"); - h8.h8err = 1; - } - break; - // bxx.b #xx:3, @rd - case 0xc: - { - UINT8 bitnr; - - address24 = h8_getreg32((opcode>>4) & 0x7); - udata8 = h8_mem_read8(address24); - H8_BYTE_TIMING(1, address24); - - ext16 = h8_mem_read16(h8.pc); - h8.pc += 2; - H8_IFETCH_TIMING(2); - - switch(ext16>>8) - { - // BTST Rn,@ERd - case 0x63: - srcreg = (ext16>>4)&0xf; - bitnr = h8_getreg8(srcreg)&7; - h8_btst8(bitnr, udata8); - break; - // btst.b #imm, @Rn - case 0x73: - bitnr = (ext16>>4)&7; - h8_btst8(bitnr, udata8); - break; - default: - h8.h8err=1; - } - } - break; - case 0xd: - ext16 = h8_mem_read16(h8.pc); - h8.pc += 2; - address24 = h8_getreg32((opcode>>4) & 0x7); - H8_IFETCH_TIMING(2); - H8_BYTE_TIMING(1, address24); - switch(ext16>>8) - { - // bset/bnot/bclr.b Rn, @ERd - case 0x60: - if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8.h8err=1; break; } - h8_mem_write8(address24, h8_bset8(h8_getreg16((ext16>>4)&0xf)&7, h8_mem_read8(address24))); - break; - case 0x61: - if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8.h8err=1; break; } - h8_mem_write8(address24, h8_bnot8(h8_getreg16((ext16>>4)&0xf)&7, h8_mem_read8(address24))); - break; - case 0x62: - if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8.h8err=1; break; } - h8_mem_write8(address24, h8_bclr8(h8_getreg16((ext16>>4)&0xf)&7, h8_mem_read8(address24))); - break; - - case 0x67: // bst/bist.b #Imm:3, @ERd - if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8.h8err=1; break; } - if ((ext16 & 0x80)!=0) - { - h8_mem_write8(address24, h8_bist8((ext16>>4)&7, h8_mem_read8(address24))); - } - else - { - h8_mem_write8(address24, h8_bst8((ext16>>4)&7, h8_mem_read8(address24))); - } - break; - - // bset/bnot/bclr.b #Imm:3, @ERd - case 0x70: - if (((opcode & 0x8f)!=0)||((ext16 & 0x8f)!=0)) { h8.h8err=1; break; } - h8_mem_write8(address24, h8_bset8((ext16>>4)&7, h8_mem_read8(address24))); - break; - case 0x71: - if (((opcode & 0x8f)!=0)||((ext16 & 0x8f)!=0)) { h8.h8err=1; break; } - h8_mem_write8(address24, h8_bnot8((ext16>>4)&7, h8_mem_read8(address24))); - break; - case 0x72: - if (((opcode & 0x8f)!=0)||((ext16 & 0x8f)!=0)) { h8.h8err=1; break; } - h8_mem_write8(address24, h8_bclr8((ext16>>4)&7, h8_mem_read8(address24))); - break; - } - break; - - // bxxx.b #imm, @aa:8 - case 0xe: - case 0xf: - { - UINT8 bitnr=0; - ext16 = h8_mem_read16(h8.pc); - h8.pc += 2; - address24 = 0xffff00 + (opcode & 0xff); - udata8 = h8_mem_read8(address24); - - switch((ext16>>8)&0xff) - { - case 0x30: - case 0x60: - bitnr = (ext16>>4)&7; - udata8 = h8_bset8(bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); - break; - case 0x70: - bitnr = (ext16>>4)&7; - if(ext16&0x80) h8.h8err = 1; - udata8 = h8_bset8(bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); - break; - case 0x32: - case 0x62: - bitnr = h8_getreg8((ext16>>4)&0xf)&7; - udata8 = h8_bclr8(bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); - break; - case 0x72: - bitnr = (ext16>>4)&7; - if(ext16&0x80) h8.h8err = 1; - udata8 = h8_bclr8(bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); - break; - case 0x63: - bitnr = h8_getreg8((ext16>>4)&0xf)&7; - h8_btst8(bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(1, address24); - break; - case 0x73: - bitnr = (ext16>>4)&7; - if(ext16&0x80) h8.h8err = 1; - h8_btst8(bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(1, address24); - break; - case 0x74: - bitnr = (ext16>>4)&7; - if(ext16&0x80) - { - // bior - h8.h8err = 1; - } - else - { - h8_bor8(bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(1, address24); - } - break; - case 0x67: - bitnr = (ext16>>4)&7; - if(ext16&0x80) - { - // bist - h8.h8err = 1; - } - else - { - h8_bst8(bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); - } - break; - case 0x77: - bitnr = (ext16>>4)&7; - if(ext16&0x80) - { - // bild - h8.h8err = 1; - } - else - { - h8_bld8(bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); - } - break; - default: - h8.h8err = 1; - break; - } - if(h8.h8err) - logerror("H8/3002: Unk. group 7 e %x\n", opcode); - } - break; - default: - logerror("H8/3002: Unk. group 7 def %x\n", opcode); - h8.h8err = 1; - break; - } -} - - -static UINT8 h8_mov8(UINT8 src) -{ - // N and Z modified - h8.h8nflag = (src>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(src==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return src; -} - -static UINT16 h8_mov16(UINT16 src) -{ - // N and Z modified - h8.h8nflag = (src>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(src==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - return src; -} - -static UINT32 h8_mov32(UINT32 src) -{ - // N and Z modified - h8.h8nflag = (src>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(src==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return src; -} - -static UINT8 h8_sub8(UINT8 src, UINT8 dst) -{ - UINT16 res; - - res = (UINT16)dst - src; - // H,N,Z,V,C modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = (((src^dst) & (res^dst))>>7) & 1; - h8.h8cflag = (res >> 8) & 1; - - // zflag - if((res&0xff)==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - h8.h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; - - return res; -} - -static UINT16 h8_sub16(UINT16 src, UINT16 dst) -{ - UINT32 res; - - res = (UINT32)dst - src; - // H,N,Z,V,C modified - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = (((src^dst) & (res^dst))>>15) & 1; - h8.h8cflag = (res >> 16) & 1; - // h8.h8hflag = (res>>28) & 1; - - // zflag - if((res&0xffff)==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - h8.h8hflag = ((src^dst^res) & 0x1000) ? 1 : 0; - - return res; -} - -static UINT32 h8_sub32(UINT32 src, UINT32 dst) -{ - UINT64 res; - - res = (UINT64)dst - src; - // H,N,Z,V,C modified - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = (((src^dst) & (res^dst))>>31) & 1; - h8.h8cflag = (res >> 32) & 1; - // h8.h8hflag = (res>>28) & 1; - - // zflag - if((res&0xffffffff)==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - h8.h8hflag = ((src^dst^res) & 0x10000000) ? 1 : 0; - - return res; -} - - - - -static UINT8 h8_add8(UINT8 src, UINT8 dst) -{ - UINT16 res; - - res = (UINT16)src + dst; - // H,N,Z,V,C modified - h8.h8nflag = (res & 0x80) ? 1 : 0; - h8.h8vflag = ((src^res) & (dst^res) & 0x80) ? 1 : 0; - h8.h8cflag = (res & 0x100) ? 1 : 0; - h8.h8zflag = (res & 0xff) ? 0 : 1; - h8.h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; - - return (UINT8)res; -} - -static UINT16 h8_add16(UINT16 src, UINT16 dst) -{ - UINT32 res; - - res = (UINT32)src + dst; - // H,N,Z,V,C modified - h8.h8nflag = (res & 0x8000) ? 1 : 0; - h8.h8vflag = ((src^res) & (dst^res) & 0x8000) ? 1 : 0; - h8.h8cflag = (res & 0x10000) ? 1 : 0; - h8.h8zflag = (res & 0xffff) ? 0 : 1; - h8.h8hflag = ((src^dst^res) & 0x1000) ? 1 : 0; - - return res; -} - -static UINT32 h8_add32(UINT32 src, UINT32 dst) -{ - UINT64 res; - - res = (UINT64)src + dst; - // H,N,Z,V,C modified - h8.h8nflag = (res & 0x80000000) ? 1 : 0; - h8.h8vflag = (((src^res) & (dst^res)) & 0x80000000) ? 1 : 0; - h8.h8cflag = ((res) & (((UINT64)1) << 32)) ? 1 : 0; - h8.h8zflag = (res & 0xffffffff) ? 0 : 1; - h8.h8hflag = ((src^dst^res) & 0x10000000) ? 1 : 0; - - return res; -} - - -static UINT8 h8_addx8(UINT8 src, UINT8 dst) -{ - UINT16 res; - - res = (UINT16)src + dst + h8.h8cflag; - // H,N,Z,V,C modified - h8.h8nflag = (res & 0x80) ? 1 : 0; - h8.h8vflag = ((src^res) & (dst^res) & 0x80) ? 1 : 0; - h8.h8cflag = (res >> 8) & 1; - h8.h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; - h8.h8zflag = (res & 0xff) ? 0 : h8.h8zflag; - - return (UINT8)res; -} - -static void h8_cmp8(UINT8 src, UINT8 dst) -{ - UINT16 res = (UINT16)dst - src; - - h8.h8cflag = (res & 0x100) ? 1 : 0; - h8.h8vflag = (((dst) ^ (src)) & ((dst) ^ (res)) & 0x80) ? 1 : 0; - h8.h8zflag = ((res & 0xff) == 0) ? 1 : 0; - h8.h8nflag = (res & 0x80) ? 1 : 0; - h8.h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; -} - -static void h8_cmp16(UINT16 src, UINT16 dst) -{ - UINT32 res = (UINT32)dst - src; - - h8.h8cflag = (res & 0x10000) ? 1 : 0; - h8.h8vflag = (((dst) ^ (src)) & ((dst) ^ (res)) & 0x8000) ? 1 : 0; - h8.h8zflag = ((res & 0xffff) == 0) ? 1 : 0; - h8.h8nflag = (res & 0x8000) ? 1 : 0; - h8.h8hflag = ((src^dst^res) & 0x1000) ? 1 : 0; -} - -static void h8_cmp32(UINT32 src, UINT32 dst) -{ - UINT64 res = (UINT64)dst - src; - - h8.h8cflag = (res & (UINT64)U64(0x100000000)) ? 1 : 0; - h8.h8vflag = (((dst) ^ (src)) & ((dst) ^ (res)) & 0x80000000) ? 1 : 0; - h8.h8zflag = ((res & 0xffffffff) == 0) ? 1 : 0; - h8.h8nflag = (res & 0x80000000) ? 1 : 0; - h8.h8hflag = ((src^dst^res) & 0x10000000) ? 1 : 0; -} - - -static UINT8 h8_subx8(UINT8 src, UINT8 dst) -{ - UINT16 res; - - res = (UINT16)dst - src - (h8.h8cflag) ? 1 : 0; - // H,N,Z,V,C modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = (((src^dst) & (res^dst))>>7) & 1; - h8.h8cflag = (res >> 8) & 1; - - // zflag - if((res&0xff)==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - h8.h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; - - return res; -} - -static UINT8 h8_or8(UINT8 src, UINT8 dst) -{ - UINT8 res; - res = src | dst; - - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_or16(UINT16 src, UINT16 dst) -{ - UINT16 res; - res = src | dst; - - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_or32(UINT32 src, UINT32 dst) -{ - UINT32 res; - res = src | dst; - - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_xor8(UINT8 src, UINT8 dst) -{ - UINT8 res; - res = src ^ dst; - - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_xor16(UINT16 src, UINT16 dst) -{ - UINT16 res; - res = src ^ dst; - - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_xor32(UINT32 src, UINT32 dst) -{ - UINT32 res; - res = src ^ dst; - - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_and8(UINT8 src, UINT8 dst) -{ - UINT8 res; - - res = src & dst; - // N and Z modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_and16(UINT16 src, UINT16 dst) -{ - UINT16 res; - - res = src & dst; - // N and Z modified - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_and32(UINT32 src, UINT32 dst) -{ - UINT32 res; - - res = src & dst; - // N and Z modified - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static void h8_btst8(UINT8 bit, UINT8 dst) -{ - // test single bit and update Z flag - if( (dst & (1<> bit) & 1; -} - -static UINT8 h8_bnot8(UINT8 src, UINT8 dst) -{ - // invert single bit, no effect on C flag - return dst ^ (1<>= src; - dst &= 0x1; - h8.h8cflag ^= dst; -} -#endif - -static UINT8 h8_bclr8(UINT8 src, UINT8 dst) -{ - // pass - UINT8 res; - res = dst & ~(1<>7) & 1; - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - h8.h8hflag = ((src|res)&0x08) ? 1 : 0; - h8.h8cflag = ((src|res)&0x80) ? 1 : 0; - - return res; -} - -static INT16 h8_neg16(INT16 src) -{ - INT16 res; - - if((UINT16)src == 0x8000) - { - // overflow ! - h8.h8vflag = 1; - res = 0x8000; - } - else - { - h8.h8vflag = 0; - res = 0-src; - } - - // N and Z modified - h8.h8nflag = (res>>15) & 1; - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - h8.h8hflag = ((src|res)&0x0800) ? 1 : 0; - h8.h8cflag = ((src|res)&0x8000) ? 1 : 0; - - return res; -} - -static INT32 h8_neg32(INT32 src) -{ - INT32 res; - - if((UINT32)src == 0x80000000) - { - // overflow ! - h8.h8vflag = 1; - res = 0x80000000; - } - else - { - h8.h8vflag = 0; - res = 0-src; - } - - // N and Z modified - h8.h8nflag = (res>>31) & 1; - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - h8.h8hflag = ((src|res)&0x08000000) ? 1 : 0; - h8.h8cflag = ((src|res)&0x80000000) ? 1 : 0; - - return res; -} - -static UINT8 h8_not8(UINT8 src) -{ - UINT8 res; - - res = ~src; - - // N and Z modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_not16(UINT16 src) -{ - UINT16 res; - - res = ~src; - - // N and Z modified - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_not32(UINT32 src) -{ - UINT32 res; - - res = ~src; - - // N and Z modified - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_rotxr8(UINT8 src) -{ - UINT8 res; - - // rotate through carry right - res = src>>1; - if(h8.h8cflag)res |= 0x80; // put cflag in upper bit - h8.h8cflag = src & 1; - - // N and Z modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_rotxr16(UINT16 src) -{ - UINT16 res; - - // rotate through carry right - res = src>>1; - if(h8.h8cflag)res |= 0x8000; // put cflag in upper bit - h8.h8cflag = src & 1; - - // N and Z modified - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_rotxl8(UINT8 src) -{ - UINT8 res; - - // rotate through carry - res = src<<1; - res |= (h8.h8cflag & 1); - h8.h8cflag = (src>>7) & 1; - - // N and Z modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_rotxl16(UINT16 src) -{ - UINT16 res; - - // rotate through carry - res = src<<1; - res |= (h8.h8cflag & 1); - h8.h8cflag = (src>>15) & 1; - - // N and Z modified - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_rotxl32(UINT32 src) -{ - UINT32 res; - - // rotate through carry - res = src<<1; - res |= (h8.h8cflag & 1); - h8.h8cflag = (src>>31) & 1; - - // N and Z modified - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - - -static UINT8 h8_rotl8(UINT8 src) -{ - UINT8 res; - - // rotate - res = src<<1; - h8.h8cflag = (src>>7) & 1; - res |= (h8.h8cflag & 1); - - // N and Z modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_rotl16(UINT16 src) -{ - UINT16 res; - - // rotate - res = src<<1; - h8.h8cflag = (src>>15) & 1; - res |= (h8.h8cflag & 1); - - // N and Z modified - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_rotl32(UINT32 src) -{ - UINT32 res; - - // rotate - res = src<<1; - h8.h8cflag = (src>>31) & 1; - res |= (h8.h8cflag & 1); - - // N and Z modified - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_shll8(UINT8 src) -{ - UINT8 res; - h8.h8cflag = (src>>7) & 1; - res = src<<1; - // N and Z modified - h8.h8nflag = (res>>7) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_shll16(UINT16 src) -{ - UINT16 res; - h8.h8cflag = (src>>15) & 1; - res = src<<1; - // N and Z modified - h8.h8nflag = (res>>15) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_shll32(UINT32 src) -{ - UINT32 res; - h8.h8cflag = (src>>31) & 1; - res = src<<1; - // N and Z modified - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_shlr8(UINT8 src) -{ - UINT8 res; - h8.h8cflag = src&1; - res = src>>1; - // N and Z modified - h8.h8nflag = 0; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_shlr16(UINT16 src) -{ - UINT16 res; - h8.h8cflag = src&1; - res = src>>1; - // N and Z modified - h8.h8nflag = 0; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_shlr32(UINT32 src) -{ - UINT32 res; - h8.h8cflag = src&1; - res = src>>1; - - // N and Z modified, V always cleared - h8.h8nflag = 0; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static INT8 h8_shar8(INT8 src) -{ - INT8 res; - h8.h8cflag = src&1; - res = (src>>1)|(src&0x80); - // N and Z modified - h8.h8nflag = (res>>7)&1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static INT16 h8_shar16(INT16 src) -{ - INT16 res; - h8.h8cflag = src&1; - res = (src>>1)|(src&0x8000); - // N and Z modified - h8.h8nflag = (res>>15)&1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static INT32 h8_shar32(INT32 src) -{ - INT32 res; - - h8.h8cflag = src&1; - res = (src>>1)|(src&0x80000000); - // N and Z modified - h8.h8nflag = (res>>31) & 1; - h8.h8vflag = 0; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static INT8 h8_shal8(INT8 src) -{ - INT8 res; - - h8.h8cflag = (src>>7)&1; - res = src<<1; - // N and Z modified - h8.h8nflag = (res>>7)&1; - h8.h8vflag = (src ^ res) >> 7; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static INT16 h8_shal16(INT16 src) -{ - INT16 res; - - h8.h8cflag = (src>>15)&1; - res = src<<1; - // N and Z modified - h8.h8nflag = (res>>15)&1; - h8.h8vflag = (src ^ res) >> 15; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static INT32 h8_shal32(INT32 src) -{ - INT32 res; - - h8.h8cflag = (src>>31)&1; - res = src<<1; - // N and Z modified - h8.h8nflag = (res>>31)&1; - h8.h8vflag = (src ^ res) >> 31; - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_dec8(UINT8 src) -{ - UINT8 res; - - res = src - 1; - // N and Z modified - h8.h8nflag = (res>>7)&1; - if(src == 0x80) - { - h8.h8vflag = 1; - } - else - { - h8.h8vflag = 0; - } - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_dec16(UINT16 src) -{ - UINT16 res; - - res = src - 1; - // N and Z modified - h8.h8nflag = (res>>15)&1; - if(src == 0x8000) - { - h8.h8vflag = 1; - } - else - { - h8.h8vflag = 0; - } - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_dec32(UINT32 src) -{ - UINT32 res; - - res = src - 1; - // N and Z modified - h8.h8nflag = (res>>31)&1; - if(src == 0x80000000) - { - h8.h8vflag = 1; - } - else - { - h8.h8vflag = 0; - } - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT8 h8_inc8(UINT8 src) -{ - UINT8 res; - - res = src + 1; - // N and Z modified - h8.h8nflag = (res>>7)&1; - if(src == 0x7f) - { - h8.h8vflag = 1; - } - else - { - h8.h8vflag = 0; - } - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT16 h8_inc16(UINT16 src) -{ - UINT16 res; - - res = src + 1; - // N and Z modified - h8.h8nflag = (res>>15)&1; - if(src == 0x7fff) - { - h8.h8vflag = 1; - } - else - { - h8.h8vflag = 0; - } - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static UINT32 h8_inc32(UINT32 src) -{ - UINT32 res; - - res = src + 1; - // N and Z modified - h8.h8nflag = (res>>31)&1; - if(src == 0x7fffffff) - { - h8.h8vflag = 1; - } - else - { - h8.h8vflag = 0; - } - - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - - return res; -} - -static INT32 h8_mulxs16(INT16 src, INT16 dst) -{ - INT32 res; - - res = (INT32)src * dst; - - // N and Z modified - h8.h8nflag = (res>>31)&1; - // zflag - if(res==0) - { - h8.h8zflag = 1; - } - else - { - h8.h8zflag = 0; - } - return res; -} - -static UINT32 h8_divxs16(INT16 src, INT32 dst) -{ - // NOT tested ! - UINT32 res,r1,r2; - INT16 remainder, quotient; - - if(src!=0) - { - quotient = dst/src; - h8.h8zflag = 0; - } - else - { - quotient = 0; - h8.h8zflag = 1; - } - remainder = dst%src; - - r1=*("ient); - r2=*(&remainder); - res=(r2<<16)|r1; - - h8.h8nflag = (quotient<0)?1:0; - - return res; - -} - -static UINT16 h8_divxu8(UINT16 dst, UINT8 src) -{ - UINT8 remainder, quotient; - UINT16 res = 0; - // N and Z modified - h8.h8nflag = (src>>7)&1; - // zflag - if(src==0) - { - h8.h8zflag = 1; - // dont do anything on division by zero ! - } - else - { - h8.h8zflag = 0; - quotient = dst / src; - remainder = dst % src; - res = (remainder << 8) | quotient; - } - return res; -} - -static UINT32 h8_divxu16(UINT32 dst, UINT16 src) -{ - UINT16 remainder, quotient; - UINT32 res = 0; - // N and Z modified - h8.h8nflag = (src>>15)&1; - // zflag - if(src==0) - { - h8.h8zflag = 1; - // dont do anything on division by zero ! - } - else - { - h8.h8zflag = 0; - quotient = dst / src; - remainder = dst % src; - res = (remainder << 16) | quotient; - } - return res; -} - -// input: branch condition -// output: 1 if condition met, 0 if not condition met -static int h8_branch(UINT8 condition) -{ - int taken = 0; - - // a branch always eats 2 ifetch states, regardless of if it's taken - H8_IFETCH_TIMING(2) - - switch(condition) - { - case 0: // bt - taken = 1; - break; - case 1: // bf - break; - case 2: // bhi (C | Z) == 0) - if((h8.h8cflag | h8.h8zflag) == 0)taken = 1; - break; - case 3: // bls - if((h8.h8cflag | h8.h8zflag) == 1)taken = 1; - break; - case 4: // bcc C = 0 - if(h8.h8cflag == 0)taken = 1; - break; - case 5: // bcs C = 1 - if(h8.h8cflag == 1)taken = 1; - break; - case 6: // bne Z = 0 - if(h8.h8zflag == 0)taken = 1; - break; - case 7: // beq Z = 1 - if(h8.h8zflag == 1)taken = 1; - break; - case 8: // bvc V = 0 - h8.h8err = 1; - if(h8.h8vflag == 0)taken = 1; - break; - case 9: // bvs V = 1 - h8.h8err = 1; - if(h8.h8vflag == 1)taken = 1; - break; - case 0xa: // bpl N = 0 - if(h8.h8nflag == 0)taken = 1; - break; - case 0xb: // bmi N = 1 - if(h8.h8nflag == 1)taken = 1; - break; - case 0xc: // bge (N ^ V) = 0 - if((h8.h8nflag ^ h8.h8vflag) == 0)taken = 1; - break; - case 0xd: // blt (N ^ V) = 1 - if((h8.h8nflag ^ h8.h8vflag) == 1)taken = 1; - break; - case 0xe: // bgt (Z | (N ^ V)) = 0 - if((h8.h8zflag | (h8.h8nflag ^ h8.h8vflag)) == 0)taken = 1; - break; - case 0xf: // ble (Z | (N ^ V)) = 1 - if((h8.h8zflag | (h8.h8nflag ^ h8.h8vflag)) == 1)taken = 1; - break; - } - return taken; -} - -// MAME interface stuff - -static CPU_GET_CONTEXT( h8 ) -{ - *(h83002_state *)dst = h8; -} - -static CPU_SET_CONTEXT( h8 ) -{ - h8 = *(h83002_state *)src; -} - -static CPU_SET_INFO( h8 ) -{ - switch(state) { - case CPUINFO_INT_PC: h8.pc = info->i; change_pc(h8.pc); break; - case CPUINFO_INT_REGISTER + H8_PC: h8.pc = info->i; change_pc(h8.pc); break; - case CPUINFO_INT_REGISTER + H8_CCR: h8_set_ccr(info->i); break; - - case CPUINFO_INT_REGISTER + H8_E0: h8.regs[0] = info->i; break; - case CPUINFO_INT_REGISTER + H8_E1: h8.regs[1] = info->i; break; - case CPUINFO_INT_REGISTER + H8_E2: h8.regs[2] = info->i; break; - case CPUINFO_INT_REGISTER + H8_E3: h8.regs[3] = info->i; break; - case CPUINFO_INT_REGISTER + H8_E4: h8.regs[4] = info->i; break; - case CPUINFO_INT_REGISTER + H8_E5: h8.regs[5] = info->i; break; - case CPUINFO_INT_REGISTER + H8_E6: h8.regs[6] = info->i; break; - case CPUINFO_INT_REGISTER + H8_E7: h8.regs[7] = info->i; break; - - case CPUINFO_INT_INPUT_STATE + H8_IRQ0: if (info->i) h8_3002_InterruptRequest(12); break; - case CPUINFO_INT_INPUT_STATE + H8_IRQ1: if (info->i) h8_3002_InterruptRequest(13); break; - case CPUINFO_INT_INPUT_STATE + H8_IRQ2: if (info->i) h8_3002_InterruptRequest(14); break; - case CPUINFO_INT_INPUT_STATE + H8_IRQ3: if (info->i) h8_3002_InterruptRequest(15); break; - case CPUINFO_INT_INPUT_STATE + H8_IRQ4: if (info->i) h8_3002_InterruptRequest(16); break; - case CPUINFO_INT_INPUT_STATE + H8_IRQ5: if (info->i) h8_3002_InterruptRequest(17); break; - - default: - fatalerror("h8_set_info unknown request %x", state); - break; - } -} - -static READ16_HANDLER( h8_itu_r ) -{ - if (mem_mask == 0xffff) - { - // 16-bit read - return h8_register_read8(offset*2 + 0xffff10)<<8 | h8_register_read8((offset*2) + 1 + 0xffff10); - } - else if (mem_mask == 0xff00) - { - return h8_register_read8(offset*2 + 0xffff10)<<8; - } - else if (mem_mask == 0x00ff) - { - return h8_register_read8((offset*2) + 1 + 0xffff10); - } - - return 0; -} - -static WRITE16_HANDLER( h8_itu_w ) -{ - if (mem_mask == 0xffff) - { - // 16-bit write - h8_register_write8(offset*2 + 0xffff10, data>>8); - h8_register_write8((offset*2) + 1 + 0xffff10, data&0xff); - } - else if (mem_mask == 0xff00) - { - h8_register_write8(offset*2 + 0xffff10, data>>8); - } - else if (mem_mask == 0x00ff) - { - h8_register_write8((offset*2) + 1 + 0xffff10, data&0xff); - } -} - -static READ16_HANDLER( h8_3007_itu_r ) -{ - if (mem_mask == 0xffff) - { - // 16-bit read - return h8_3007_register_read8(offset*2 + 0xffff20)<<8 | h8_3007_register_read8((offset*2) + 1 + 0xffff20); - } - else if (mem_mask == 0xff00) - { - return h8_3007_register_read8(offset*2 + 0xffff20)<<8; - } - else if (mem_mask == 0x00ff) - { - return h8_3007_register_read8((offset*2) + 1 + 0xffff20); - } - - return 0; -} -static WRITE16_HANDLER( h8_3007_itu_w ) -{ - if (mem_mask == 0xffff) - { - // 16-bit write - h8_3007_register_write8(offset*2 + 0xffff20, data>>8); - h8_3007_register_write8((offset*2) + 1 + 0xffff20, data&0xff); - } - else if (mem_mask == 0xff00) - { - h8_3007_register_write8(offset*2 + 0xffff20, data>>8); - } - else if (mem_mask == 0x00ff) - { - h8_3007_register_write8((offset*2) + 1 + 0xffff20, data&0xff); - } -} - -static READ16_HANDLER( h8_3007_itu1_r ) -{ - if (mem_mask == 0xffff) - { - // 16-bit read - return h8_3007_register1_read8(offset*2 + 0xfee000)<<8 | h8_3007_register1_read8((offset*2) + 1 + 0xfee000); - } - else if (mem_mask == 0xff00) - { - return h8_3007_register1_read8(offset*2 + 0xfee000)<<8; - } - else if (mem_mask == 0x00ff) - { - return h8_3007_register1_read8((offset*2) + 1 + 0xfee000); - } - - return 0; -} -static WRITE16_HANDLER( h8_3007_itu1_w ) -{ - if (mem_mask == 0xffff) - { - // 16-bit write - h8_3007_register1_write8(offset*2 + 0xfee000, data>>8); - h8_3007_register1_write8((offset*2) + 1 + 0xfee000, data&0xff); - } - else if (mem_mask == 0xff00) - { - h8_3007_register1_write8(offset*2 + 0xfee000, data>>8); - } - else if (mem_mask == 0x00ff) - { - h8_3007_register1_write8((offset*2) + 1 + 0xfee000, data&0xff); - } -} - -// On-board RAM and peripherals -static ADDRESS_MAP_START( h8_3002_internal_map, ADDRESS_SPACE_PROGRAM, 16 ) - // 512B RAM - AM_RANGE(0xfffd10, 0xffff0f) AM_RAM - AM_RANGE(0xffff10, 0xffffff) AM_READWRITE( h8_itu_r, h8_itu_w ) -ADDRESS_MAP_END - -static ADDRESS_MAP_START( h8_3044_internal_map, ADDRESS_SPACE_PROGRAM, 16 ) - // 32k ROM, 2k RAM - AM_RANGE(0xfff710, 0xffff0f) AM_RAM - AM_RANGE(0xffff1c, 0xffffff) AM_READWRITE( h8_itu_r, h8_itu_w ) -ADDRESS_MAP_END - -static ADDRESS_MAP_START( h8_3007_internal_map, ADDRESS_SPACE_PROGRAM, 16 ) - // ROM-less, 4k RAM - AM_RANGE(0xfee000, 0xfee0ff) AM_READWRITE( h8_3007_itu1_r, h8_3007_itu1_w ) - AM_RANGE(0xffef20, 0xffff1f) AM_RAM - AM_RANGE(0xffff20, 0xffffe9) AM_READWRITE( h8_3007_itu_r, h8_3007_itu_w ) -ADDRESS_MAP_END - - -CPU_GET_INFO( h8_3002 ) -{ - switch(state) { - // Interface functions and variables - case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(h8); break; - case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(h8); break; - case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(h8); break; - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8); break; - case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(h8); break; - case CPUINFO_PTR_EXIT: info->exit = 0; break; - case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(h8); break; - case CPUINFO_PTR_BURN: info->burn = 0; break; - case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(h8); break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &h8_cyccnt; break; - case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(h83002_state); break; - case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break; - case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 10; break; - - // Bus sizes - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 24; break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; - - // Internal maps - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(h8_3002_internal_map); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map16 = NULL; break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map16 = NULL; break; - - // CPU misc parameters - case CPUINFO_STR_NAME: strcpy(info->s, "H8/3002"); break; - case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; - case CPUINFO_STR_FLAGS: strcpy(info->s, h8_get_ccr_str()); break; - case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break; - case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; - case CPUINFO_INT_INPUT_LINES: info->i = 16; break; - case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = -1; break; - - // CPU main state - case CPUINFO_INT_PC: info->i = h8.pc; break; - case CPUINFO_INT_PREVIOUSPC: info->i = h8.ppc; break; - - case CPUINFO_INT_REGISTER + H8_PC: info->i = h8.pc; break; - case CPUINFO_INT_REGISTER + H8_CCR: info->i = h8_get_ccr(); break; - - case CPUINFO_INT_REGISTER + H8_E0: info->i = h8.regs[0]; break; - case CPUINFO_INT_REGISTER + H8_E1: info->i = h8.regs[1]; break; - case CPUINFO_INT_REGISTER + H8_E2: info->i = h8.regs[2]; break; - case CPUINFO_INT_REGISTER + H8_E3: info->i = h8.regs[3]; break; - case CPUINFO_INT_REGISTER + H8_E4: info->i = h8.regs[4]; break; - case CPUINFO_INT_REGISTER + H8_E5: info->i = h8.regs[5]; break; - case CPUINFO_INT_REGISTER + H8_E6: info->i = h8.regs[6]; break; - case CPUINFO_INT_REGISTER + H8_E7: info->i = h8.regs[7]; break; - - // CPU debug stuff - case CPUINFO_STR_REGISTER + H8_PC: sprintf(info->s, "PC :%08x", h8.pc); break; - case CPUINFO_STR_REGISTER + H8_CCR: sprintf(info->s, "CCR :%08x", h8_get_ccr()); break; - - case CPUINFO_STR_REGISTER + H8_E0: sprintf(info->s, "ER0 :%08x", h8.regs[0]); break; - case CPUINFO_STR_REGISTER + H8_E1: sprintf(info->s, "ER1 :%08x", h8.regs[1]); break; - case CPUINFO_STR_REGISTER + H8_E2: sprintf(info->s, "ER2 :%08x", h8.regs[2]); break; - case CPUINFO_STR_REGISTER + H8_E3: sprintf(info->s, "ER3 :%08x", h8.regs[3]); break; - case CPUINFO_STR_REGISTER + H8_E4: sprintf(info->s, "ER4 :%08x", h8.regs[4]); break; - case CPUINFO_STR_REGISTER + H8_E5: sprintf(info->s, "ER5 :%08x", h8.regs[5]); break; - case CPUINFO_STR_REGISTER + H8_E6: sprintf(info->s, "ER6 :%08x", h8.regs[6]); break; - case CPUINFO_STR_REGISTER + H8_E7: sprintf(info->s, " SP :%08x", h8.regs[7]); break; - } -} - -CPU_GET_INFO( h8_3044 ) -{ - switch (state) - { - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(h8_3044_internal_map); break; - case CPUINFO_STR_NAME: strcpy(info->s, "H8/3044"); break; - default: - CPU_GET_INFO_CALL(h8_3002); - } -} - -CPU_GET_INFO( h8_3007 ) -{ - switch (state) - { - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = address_map_h8_3007_internal_map; break; - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8_3007); break; - case CPUINFO_STR_NAME: strcpy(info->s, "H8/3007"); break; - default: - CPU_GET_INFO_CALL(h8_3002); - } -} diff --git a/src/emu/cpu/h83002/h8_16.c b/src/emu/cpu/h83002/h8_16.c new file mode 100644 index 00000000000..f9b9f222509 --- /dev/null +++ b/src/emu/cpu/h83002/h8_16.c @@ -0,0 +1,653 @@ +/*************************************************************************** + + h8_16.c: Hitachi H8/3xx series 16/32-bit microcontroller emulator + + Original by The_Author & DynaChicken for the ZiNc emulator. + MAME changes by R. Belmont, Luca Elia, and Tomasz Slanina. + + TS 20060412 Added exts.l, sub.l, divxs.w (buggy), jsr @reg, rotxl.l reg, mov.l @(adr, reg), reg + LE 20070903 Added divxu.b shal.l extu.w dec.l #Imm,Rd subx.b + LE 20080202 Separated 3002/3044/3007, Added or.l shal.l rotl.l not.l neg.l exts.w + sub/or/xor.l #Imm:32,ERd bset/bnot/bclr.b Rn,@ERd bst/bist.b #Imm:3,@ERd bnot.b #Imm:3,@ERd + +****************************************************************************/ + +#include "debugger.h" +#include "h8.h" +#include "h8priv.h" + +#define H8_SP (7) + +#define h8_mem_read8(x) program_read_byte_16be(x) +#define h8_mem_read16(x) program_read_word_16be(x) +#define h8_mem_write8(x, y) program_write_byte_16be(x, y) +#define h8_mem_write16(x, y) program_write_word_16be(x, y) +#define h8_readop16(x) program_decrypted_read_word(x) + +// timing macros +// note: we assume a system 12 - type setup where external access is 3+1 states +// timing will be off somewhat for other configurations. +#define H8_IFETCH_TIMING(x) h8->cyccnt -= (x) * 4; +#define H8_BRANCH_TIMING(x) h8->cyccnt -= (x) * 4; +#define H8_STACK_TIMING(x) h8->cyccnt -= (x) * 4; +#define H8_BYTE_TIMING(x, adr) if (address24 >= 0xffff10) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4; +#define H8_WORD_TIMING(x, adr) if (address24 >= 0xffff10) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4; +#define H8_IOP_TIMING(x) h8->cyccnt -= (x); + +INLINE UINT32 h8_mem_read32(offs_t address) +{ + UINT32 result = program_read_word_16be(address) << 16; + return result | program_read_word_16be(address + 2); +} + +INLINE void h8_mem_write32(offs_t address, UINT32 data) +{ + program_write_word_16be(address, data >> 16); + program_write_word_16be(address + 2, data); +} + +static void *token; +static void h8_check_irqs(h83xx_state *h8); + +/* implementation */ + +extern offs_t h8_disasm(char *output, offs_t address, const UINT8 *oprom, const UINT8 *opram, UINT32 addr_mask); + +// disassembly hook for varients with 24-bit address bus (e.g. H8/3044) +static CPU_DISASSEMBLE(h8_24) +{ + return h8_disasm(buffer, pc, oprom, opram, 0xffffff); +} + +// disassembly hook for full 32-bit address bus +static CPU_DISASSEMBLE(h8_32) +{ + return h8_disasm(buffer, pc, oprom, opram, 0xffffffff); +} + +void h8_3002_InterruptRequest(h83xx_state *h8, UINT8 source) +{ + if(source>31) + { + h8->h8_IRQrequestH |= (1<<(source-32)); + } + else + { + h8->h8_IRQrequestL |= (1<ccr = 0; + if(h8->h8nflag)h8->ccr |= NFLAG; + if(h8->h8zflag)h8->ccr |= ZFLAG; + if(h8->h8vflag)h8->ccr |= VFLAG; + if(h8->h8cflag)h8->ccr |= CFLAG; + if(h8->h8uflag)h8->ccr |= UFLAG; + if(h8->h8hflag)h8->ccr |= HFLAG; + if(h8->h8uiflag)h8->ccr |= UIFLAG; + if(h8->h8iflag)h8->ccr |= IFLAG; + return h8->ccr; +} + +static char *h8_get_ccr_str(h83xx_state *h8) +{ + static char res[8]; + + memset(res, 0, 8); + if(h8->h8iflag) strcat(res, "I"); else strcat(res, "i"); + if(h8->h8uiflag)strcat(res, "U"); else strcat(res, "u"); + if(h8->h8hflag) strcat(res, "H"); else strcat(res, "h"); + if(h8->h8uflag) strcat(res, "U"); else strcat(res, "u"); + if(h8->h8nflag) strcat(res, "N"); else strcat(res, "n"); + if(h8->h8zflag) strcat(res, "Z"); else strcat(res, "z"); + if(h8->h8vflag) strcat(res, "V"); else strcat(res, "v"); + if(h8->h8cflag) strcat(res, "C"); else strcat(res, "c"); + + return res; +} + +static void h8_set_ccr(h83xx_state *h8, UINT8 data) +{ + h8->ccr = data; + + h8->h8nflag = 0; + h8->h8zflag = 0; + h8->h8vflag = 0; + h8->h8cflag = 0; + h8->h8hflag = 0; + h8->h8iflag = 0; + h8->h8uflag = 0; + h8->h8uiflag = 0; + + if(h8->ccr & NFLAG) h8->h8nflag = 1; + if(h8->ccr & ZFLAG) h8->h8zflag = 1; + if(h8->ccr & VFLAG) h8->h8vflag = 1; + if(h8->ccr & CFLAG) h8->h8cflag = 1; + if(h8->ccr & HFLAG) h8->h8hflag = 1; + if(h8->ccr & UFLAG) h8->h8uflag = 1; + if(h8->ccr & UIFLAG) h8->h8uiflag = 1; + if(h8->ccr & IFLAG) h8->h8iflag = 1; + + h8_check_irqs(h8); +} + +static INT16 h8_getreg16(h83xx_state *h8, UINT8 reg) +{ + if(reg > 7) + { + return h8->regs[reg-8]>>16; + } + else + { + return h8->regs[reg]; + } +} + +static void h8_setreg16(h83xx_state *h8, UINT8 reg, UINT16 data) +{ + if(reg > 7) + { + h8->regs[reg-8] &= 0xffff; + h8->regs[reg-8] |= data<<16; + } + else + { + h8->regs[reg] &= 0xffff0000; + h8->regs[reg] |= data; + } +} + +static UINT8 h8_getreg8(h83xx_state *h8, UINT8 reg) +{ + if(reg > 7) + { + return h8->regs[reg-8]; + } + else + { + return h8->regs[reg]>>8; + } +} + +static void h8_setreg8(h83xx_state *h8, UINT8 reg, UINT8 data) +{ + if(reg > 7) + { + h8->regs[reg-8] &= 0xffffff00; + h8->regs[reg-8] |= data; + } + else + { + h8->regs[reg] &= 0xffff00ff; + h8->regs[reg] |= data<<8; + } +} + +static UINT32 h8_getreg32(h83xx_state *h8, UINT8 reg) +{ + return h8->regs[reg]; +} + +static void h8_setreg32(h83xx_state *h8, UINT8 reg, UINT32 data) +{ + h8->regs[reg] = data; +} + +static STATE_POSTLOAD( h8_onstateload ) +{ + h83xx_state *h8 = (h83xx_state *)param; + + h8_set_ccr(h8, h8->ccr); +} + +static CPU_INIT(h8) +{ + h83xx_state *h8 = device->token; + + token = device->token; + + h8->h8iflag = 1; + h8->irq_cb = irqcallback; + h8->device = device; + + h8->h8300_mode = 0; + + state_save_register_item("H8/3002", device->tag, 0, h8->h8err); + state_save_register_item_array("H8/3002", device->tag, 0, h8->regs); + state_save_register_item("H8/3002", device->tag, 0, h8->pc); + state_save_register_item("H8/3002", device->tag, 0, h8->ppc); + state_save_register_item("H8/3002", device->tag, 0, h8->h8_IRQrequestH); + state_save_register_item("H8/3002", device->tag, 0, h8->h8_IRQrequestL); + state_save_register_item("H8/3002", device->tag, 0, h8->ccr); + state_save_register_item("H8/3002", device->tag, 0, h8->h8300_mode); + + state_save_register_item_array("H8/3002", device->tag, 0, h8->per_regs); + state_save_register_item("H8/3002", device->tag, 0, h8->h8TSTR); + state_save_register_item_array("H8/3002", device->tag, 0, h8->h8TCNT); + + state_save_register_postload(device->machine, h8_onstateload, h8); + + h8_itu_init(h8); +} + +static CPU_INIT(h8_3007) +{ + h83xx_state *h8 = device->token; + + token = device->token; + + CPU_INIT_CALL(h8); + h8_3007_itu_init(h8); +} + +static CPU_RESET(h8) +{ + h83xx_state *h8 = device->token; + + h8->h8err = 0; + h8->pc = h8_mem_read32(0) & 0xffffff; + change_pc(h8->pc); + + // disable timers + h8->h8TSTR = 0; + + h8_itu_reset(h8); +} + +static void h8_GenException(h83xx_state *h8, UINT8 vectornr) +{ + // push PC on stack + // extended mode stack push! + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4); + h8_mem_write32(h8_getreg32(h8, H8_SP), h8->pc); + // push ccr + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-2); + h8_mem_write16(h8_getreg32(h8, H8_SP), h8_get_ccr(h8)); + + // generate address from vector + h8_set_ccr(h8, h8_get_ccr(h8) | 0x80); + if (h8->h8uiflag == 0) + h8_set_ccr(h8, h8_get_ccr(h8) | 0x40); + h8->pc = h8_mem_read32(vectornr * 4) & 0xffffff; + change_pc(h8->pc); + + // I couldn't find timing info for exceptions, so this is a guess (based on JSR/BSR) + H8_IFETCH_TIMING(2); + H8_STACK_TIMING(2); +} + +static int h8_get_priority(h83xx_state *h8, UINT8 bit) +{ + int res = 0; + switch(bit) + { + case 12: // IRQ0 + if (h8->per_regs[0xF8]&0x80) res = 1; break; + case 13: // IRQ1 + if (h8->per_regs[0xF8]&0x40) res = 1; break; + case 14: // IRQ2 + case 15: // IRQ3 + if (h8->per_regs[0xF8]&0x20) res = 1; break; + case 16: // IRQ4 + case 17: // IRQ5 + if (h8->per_regs[0xF8]&0x10) res = 1; break; + } + return res; +} + +static void h8_check_irqs(h83xx_state *h8) +{ + int lv = -1; + if (h8->h8iflag == 0) + { + lv = 0; + } + else + { + if ((h8->per_regs[0xF2]&0x08)/*SYSCR*/ == 0) + { + if (h8->h8uiflag == 0) + lv = 1; + } + } + + // any interrupts wanted and can accept ? + if(((h8->h8_IRQrequestH != 0) || (h8->h8_IRQrequestL != 0)) && (lv >= 0)) + { + UINT8 bit, source; + // which one ? + for(bit = 0, source = 0xff; source == 0xff && bit < 32; bit++) + { + if( h8->h8_IRQrequestL & (1<= lv) + { + // mask off + h8->h8_IRQrequestL &= ~(1<h8_IRQrequestH & (1<= lv) + { + // mask off + h8->h8_IRQrequestH &= ~(1<= 12 && source <= 17) + { + (*h8->irq_cb)(h8->device, source - 12 + H8_IRQ0); + } + + if (source != 0xff) + h8_GenException(h8, source); + } +} + +#define H8_ADDR_MASK 0xffffff +#include "h8ops.h" + +// MAME interface stuff + +static CPU_GET_CONTEXT( h8 ) +{ +} + +static CPU_SET_CONTEXT( h8 ) +{ + if (src) + { + token = src; + } +} + +static CPU_SET_INFO( h8 ) +{ + h83xx_state *h8 = device->token; + + switch(state) { + case CPUINFO_INT_PC: h8->pc = info->i; change_pc(h8->pc); break; + case CPUINFO_INT_REGISTER + H8_PC: h8->pc = info->i; change_pc(h8->pc); break; + case CPUINFO_INT_REGISTER + H8_CCR: h8_set_ccr(h8, info->i); break; + + case CPUINFO_INT_REGISTER + H8_E0: h8->regs[0] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E1: h8->regs[1] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E2: h8->regs[2] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E3: h8->regs[3] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E4: h8->regs[4] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E5: h8->regs[5] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E6: h8->regs[6] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E7: h8->regs[7] = info->i; break; + + case CPUINFO_INT_INPUT_STATE + H8_IRQ0: if (info->i) h8_3002_InterruptRequest(h8, 12); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ1: if (info->i) h8_3002_InterruptRequest(h8, 13); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ2: if (info->i) h8_3002_InterruptRequest(h8, 14); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ3: if (info->i) h8_3002_InterruptRequest(h8, 15); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ4: if (info->i) h8_3002_InterruptRequest(h8, 16); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ5: if (info->i) h8_3002_InterruptRequest(h8, 17); break; + + case CPUINFO_INT_INPUT_STATE + H8_METRO_TIMER_HACK: if (info->i) h8_3002_InterruptRequest(h8, 24); break; + + case CPUINFO_INT_INPUT_STATE + H8_SCI_0_RX: if (info->i) h8_3002_InterruptRequest(h8, 53); break; + case CPUINFO_INT_INPUT_STATE + H8_SCI_1_RX: if (info->i) h8_3002_InterruptRequest(h8, 57); break; + + default: + fatalerror("h8_set_info unknown request %x", state); + break; + } +} + +static READ16_HANDLER( h8_itu_r ) +{ + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + if (mem_mask == 0xffff) + { + // 16-bit read + return h8_register_read8(h8, offset*2 + 0xffff10)<<8 | h8_register_read8(h8, (offset*2) + 1 + 0xffff10); + } + else if (mem_mask == 0xff00) + { + return h8_register_read8(h8, offset*2 + 0xffff10)<<8; + } + else if (mem_mask == 0x00ff) + { + return h8_register_read8(h8, (offset*2) + 1 + 0xffff10); + } + + return 0; +} + +static WRITE16_HANDLER( h8_itu_w ) +{ + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + if (mem_mask == 0xffff) + { + // 16-bit write + h8_register_write8(h8, offset*2 + 0xffff10, data>>8); + h8_register_write8(h8, (offset*2) + 1 + 0xffff10, data&0xff); + } + else if (mem_mask == 0xff00) + { + h8_register_write8(h8, offset*2 + 0xffff10, data>>8); + } + else if (mem_mask == 0x00ff) + { + h8_register_write8(h8, (offset*2) + 1 + 0xffff10, data&0xff); + } +} + +static READ16_HANDLER( h8_3007_itu_r ) +{ + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + if (mem_mask == 0xffff) + { + // 16-bit read + return h8_3007_register_read8(h8, offset*2 + 0xffff20)<<8 | h8_3007_register_read8(h8, (offset*2) + 1 + 0xffff20); + } + else if (mem_mask == 0xff00) + { + return h8_3007_register_read8(h8, offset*2 + 0xffff20)<<8; + } + else if (mem_mask == 0x00ff) + { + return h8_3007_register_read8(h8, (offset*2) + 1 + 0xffff20); + } + + return 0; +} +static WRITE16_HANDLER( h8_3007_itu_w ) +{ + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + if (mem_mask == 0xffff) + { + // 16-bit write + h8_3007_register_write8(h8, offset*2 + 0xffff20, data>>8); + h8_3007_register_write8(h8, (offset*2) + 1 + 0xffff20, data&0xff); + } + else if (mem_mask == 0xff00) + { + h8_3007_register_write8(h8, offset*2 + 0xffff20, data>>8); + } + else if (mem_mask == 0x00ff) + { + h8_3007_register_write8(h8, (offset*2) + 1 + 0xffff20, data&0xff); + } +} + +static READ16_HANDLER( h8_3007_itu1_r ) +{ + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + if (mem_mask == 0xffff) + { + // 16-bit read + return h8_3007_register1_read8(h8, offset*2 + 0xfee000)<<8 | h8_3007_register1_read8(h8, (offset*2) + 1 + 0xfee000); + } + else if (mem_mask == 0xff00) + { + return h8_3007_register1_read8(h8, offset*2 + 0xfee000)<<8; + } + else if (mem_mask == 0x00ff) + { + return h8_3007_register1_read8(h8, (offset*2) + 1 + 0xfee000); + } + + return 0; +} +static WRITE16_HANDLER( h8_3007_itu1_w ) +{ + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + if (mem_mask == 0xffff) + { + // 16-bit write + h8_3007_register1_write8(h8, offset*2 + 0xfee000, data>>8); + h8_3007_register1_write8(h8, (offset*2) + 1 + 0xfee000, data&0xff); + } + else if (mem_mask == 0xff00) + { + h8_3007_register1_write8(h8, offset*2 + 0xfee000, data>>8); + } + else if (mem_mask == 0x00ff) + { + h8_3007_register1_write8(h8, (offset*2) + 1 + 0xfee000, data&0xff); + } +} + +// On-board RAM and peripherals +static ADDRESS_MAP_START( h8_3002_internal_map, ADDRESS_SPACE_PROGRAM, 16 ) + // 512B RAM + AM_RANGE(0xfffd10, 0xffff0f) AM_RAM + AM_RANGE(0xffff10, 0xffffff) AM_READWRITE( h8_itu_r, h8_itu_w ) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( h8_3044_internal_map, ADDRESS_SPACE_PROGRAM, 16 ) + // 32k ROM, 2k RAM + AM_RANGE(0xfff710, 0xffff0f) AM_RAM + AM_RANGE(0xffff1c, 0xffffff) AM_READWRITE( h8_itu_r, h8_itu_w ) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( h8_3007_internal_map, ADDRESS_SPACE_PROGRAM, 16 ) + // ROM-less, 4k RAM + AM_RANGE(0xfee000, 0xfee0ff) AM_READWRITE( h8_3007_itu1_r, h8_3007_itu1_w ) + AM_RANGE(0xffef20, 0xffff1f) AM_RAM + AM_RANGE(0xffff20, 0xffffe9) AM_READWRITE( h8_3007_itu_r, h8_3007_itu_w ) +ADDRESS_MAP_END + +CPU_GET_INFO( h8_3002 ) +{ + h83xx_state *h8 = (device != NULL) ? device->token : NULL; + + switch(state) { + // Interface functions and variables + case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(h8); break; + case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(h8); break; + case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(h8); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8); break; + case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(h8); break; + case CPUINFO_PTR_EXIT: info->exit = 0; break; + case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(h8); break; + case CPUINFO_PTR_BURN: info->burn = 0; break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(h8_32); break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &h8->cyccnt; break; + case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(h83xx_state); break; + case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break; + case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 10; break; + + // Bus sizes + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 24; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; + + // Internal maps + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(h8_3002_internal_map); break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map16 = NULL; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map16 = NULL; break; + + // CPU misc parameters + case CPUINFO_STR_NAME: strcpy(info->s, "H8/3002"); break; + case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; + case CPUINFO_STR_FLAGS: strcpy(info->s, h8_get_ccr_str(h8)); break; + case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break; + case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; + case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; + case CPUINFO_INT_INPUT_LINES: info->i = 16; break; + case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = -1; break; + + // CPU main state + case CPUINFO_INT_PC: info->i = h8->pc; break; + case CPUINFO_INT_PREVIOUSPC: info->i = h8->ppc; break; + + case CPUINFO_INT_REGISTER + H8_PC: info->i = h8->pc; break; + case CPUINFO_INT_REGISTER + H8_CCR: info->i = h8_get_ccr(h8); break; + + case CPUINFO_INT_REGISTER + H8_E0: info->i = h8->regs[0]; break; + case CPUINFO_INT_REGISTER + H8_E1: info->i = h8->regs[1]; break; + case CPUINFO_INT_REGISTER + H8_E2: info->i = h8->regs[2]; break; + case CPUINFO_INT_REGISTER + H8_E3: info->i = h8->regs[3]; break; + case CPUINFO_INT_REGISTER + H8_E4: info->i = h8->regs[4]; break; + case CPUINFO_INT_REGISTER + H8_E5: info->i = h8->regs[5]; break; + case CPUINFO_INT_REGISTER + H8_E6: info->i = h8->regs[6]; break; + case CPUINFO_INT_REGISTER + H8_E7: info->i = h8->regs[7]; break; + + // CPU debug stuff + case CPUINFO_STR_REGISTER + H8_PC: sprintf(info->s, "PC :%08x", h8->pc); break; + case CPUINFO_STR_REGISTER + H8_CCR: sprintf(info->s, "CCR :%08x", h8_get_ccr(h8)); break; + + case CPUINFO_STR_REGISTER + H8_E0: sprintf(info->s, "ER0 :%08x", h8->regs[0]); break; + case CPUINFO_STR_REGISTER + H8_E1: sprintf(info->s, "ER1 :%08x", h8->regs[1]); break; + case CPUINFO_STR_REGISTER + H8_E2: sprintf(info->s, "ER2 :%08x", h8->regs[2]); break; + case CPUINFO_STR_REGISTER + H8_E3: sprintf(info->s, "ER3 :%08x", h8->regs[3]); break; + case CPUINFO_STR_REGISTER + H8_E4: sprintf(info->s, "ER4 :%08x", h8->regs[4]); break; + case CPUINFO_STR_REGISTER + H8_E5: sprintf(info->s, "ER5 :%08x", h8->regs[5]); break; + case CPUINFO_STR_REGISTER + H8_E6: sprintf(info->s, "ER6 :%08x", h8->regs[6]); break; + case CPUINFO_STR_REGISTER + H8_E7: sprintf(info->s, " SP :%08x", h8->regs[7]); break; + } +} + +CPU_GET_INFO( h8_3044 ) +{ + switch (state) + { + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(h8_3044_internal_map); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(h8_24); break; + case CPUINFO_STR_NAME: strcpy(info->s, "H8/3044"); break; + default: + CPU_GET_INFO_CALL(h8_3002); + } +} + +CPU_GET_INFO( h8_3007 ) +{ + switch (state) + { + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = address_map_h8_3007_internal_map; break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8_3007); break; + case CPUINFO_STR_NAME: strcpy(info->s, "H8/3007"); break; + default: + CPU_GET_INFO_CALL(h8_3002); + } +} diff --git a/src/emu/cpu/h83002/h8_8.c b/src/emu/cpu/h83002/h8_8.c new file mode 100644 index 00000000000..ad0d8c3391b --- /dev/null +++ b/src/emu/cpu/h83002/h8_8.c @@ -0,0 +1,603 @@ +/*************************************************************************** + + h8_8.c: Hitachi H8/3xx 8/16-bit microcontroller emulator + + Based on H8/300 series 16/32-bit emulator h83002.c. + Reference: Renesas Technology H8/3337 Group Hardware Manual + + By R. Belmont + +****************************************************************************/ + +#include "debugger.h" +#include "deprecat.h" +#include "h8.h" +#include "h8priv.h" + +#define H8_SP (7) + +#define h8_mem_read8(x) program_read_byte_8be(x) +#define h8_mem_write8(x, y) program_write_byte_8be(x, y) + +// timing macros +#define H8_IFETCH_TIMING(x) h8->cyccnt -= (x) * 4; +#define H8_BRANCH_TIMING(x) h8->cyccnt -= (x) * 4; +#define H8_STACK_TIMING(x) h8->cyccnt -= (x) * 4; +#define H8_BYTE_TIMING(x, adr) if (address24 >= 0xff90) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4; +#define H8_WORD_TIMING(x, adr) if (address24 >= 0xff90) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4; +#define H8_IOP_TIMING(x) h8->cyccnt -= (x); + +INLINE UINT16 h8_mem_read16(offs_t address) +{ + UINT16 result = program_read_byte_8be(address)<<8; + return result | program_read_byte_8be(address+1); +} + +INLINE UINT16 h8_readop16(offs_t address) +{ + UINT16 result = program_decrypted_read_byte(address)<<8; + return result | program_decrypted_read_byte(address+1); +} + +INLINE void h8_mem_write16(offs_t address, UINT16 data) +{ + program_write_byte_8be(address, data >> 8); + program_write_byte_8be(address+1, data); +} + +INLINE UINT32 h8_mem_read32(offs_t address) +{ + UINT32 result = program_read_byte_8be(address) << 24; + result |= program_read_byte_8be(address+1) << 16; + result |= program_read_byte_8be(address+2) << 8; + result |= program_read_byte_8be(address+3); + + return result; +} + +INLINE void h8_mem_write32(offs_t address, UINT32 data) +{ + program_write_byte_8be(address, data >> 24); + program_write_byte_8be(address+1, data >> 16); + program_write_byte_8be(address+2, data >> 8); + program_write_byte_8be(address+3, data); +} + +static void *token; +static void h8_check_irqs(h83xx_state *h8); + +/* implementation */ + +extern offs_t h8_disasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 addrmask); + +static CPU_DISASSEMBLE(h8) +{ + return h8_disasm(buffer, pc, oprom, opram, 0xffff); +} + +void h8_300_InterruptRequest(h83xx_state *h8, UINT8 source) +{ + if(source>31) + { + h8->h8_IRQrequestH |= (1<<(source-32)); + } + else + { + h8->h8_IRQrequestL |= (1<ccr = 0; + if(h8->h8nflag)h8->ccr |= NFLAG; + if(h8->h8zflag)h8->ccr |= ZFLAG; + if(h8->h8vflag)h8->ccr |= VFLAG; + if(h8->h8cflag)h8->ccr |= CFLAG; + if(h8->h8uflag)h8->ccr |= UFLAG; + if(h8->h8hflag)h8->ccr |= HFLAG; + if(h8->h8uiflag)h8->ccr |= UIFLAG; + if(h8->h8iflag)h8->ccr |= IFLAG; + return h8->ccr; +} + +static char *h8_get_ccr_str(h83xx_state *h8) +{ + static char res[8]; + + memset(res, 0, 8); + if(h8->h8iflag) strcat(res, "I"); else strcat(res, "i"); + if(h8->h8uiflag)strcat(res, "U"); else strcat(res, "u"); + if(h8->h8hflag) strcat(res, "H"); else strcat(res, "h"); + if(h8->h8uflag) strcat(res, "U"); else strcat(res, "u"); + if(h8->h8nflag) strcat(res, "N"); else strcat(res, "n"); + if(h8->h8zflag) strcat(res, "Z"); else strcat(res, "z"); + if(h8->h8vflag) strcat(res, "V"); else strcat(res, "v"); + if(h8->h8cflag) strcat(res, "C"); else strcat(res, "c"); + + return res; +} + +static void h8_set_ccr(h83xx_state *h8, UINT8 data) +{ + h8->ccr = data; + + h8->h8nflag = 0; + h8->h8zflag = 0; + h8->h8vflag = 0; + h8->h8cflag = 0; + h8->h8hflag = 0; + h8->h8iflag = 0; + h8->h8uflag = 0; + h8->h8uiflag = 0; + + if(h8->ccr & NFLAG) h8->h8nflag = 1; + if(h8->ccr & ZFLAG) h8->h8zflag = 1; + if(h8->ccr & VFLAG) h8->h8vflag = 1; + if(h8->ccr & CFLAG) h8->h8cflag = 1; + if(h8->ccr & HFLAG) h8->h8hflag = 1; + if(h8->ccr & UFLAG) h8->h8uflag = 1; + if(h8->ccr & UIFLAG) h8->h8uiflag = 1; + if(h8->ccr & IFLAG) h8->h8iflag = 1; + + h8_check_irqs(h8); +} + +static INT16 h8_getreg16(h83xx_state *h8, UINT8 reg) +{ + if(reg > 7) + { + return h8->regs[reg-8]>>16; + } + else + { + return h8->regs[reg]; + } +} + +static void h8_setreg16(h83xx_state *h8, UINT8 reg, UINT16 data) +{ + if(reg > 7) + { + h8->regs[reg-8] &= 0xffff; + h8->regs[reg-8] |= data<<16; + } + else + { + h8->regs[reg] &= 0xffff0000; + h8->regs[reg] |= data; + } +} + +static UINT8 h8_getreg8(h83xx_state *h8, UINT8 reg) +{ + if(reg > 7) + { + return h8->regs[reg-8]; + } + else + { + return h8->regs[reg]>>8; + } +} + +static void h8_setreg8(h83xx_state *h8, UINT8 reg, UINT8 data) +{ + if(reg > 7) + { + h8->regs[reg-8] &= 0xffffff00; + h8->regs[reg-8] |= data; + } + else + { + h8->regs[reg] &= 0xffff00ff; + h8->regs[reg] |= data<<8; + } +} + +static UINT32 h8_getreg32(h83xx_state *h8, UINT8 reg) +{ + return h8->regs[reg]; +} + +static void h8_setreg32(h83xx_state *h8, UINT8 reg, UINT32 data) +{ + h8->regs[reg] = data; +} + +static STATE_POSTLOAD( h8_onstateload ) +{ + h83xx_state *h8 = (h83xx_state *)param; + + h8_set_ccr(h8, h8->ccr); +} + +static CPU_INIT(h8bit) +{ + h83xx_state *h8 = device->token; + + h8->h8iflag = 1; + + h8->irq_cb = irqcallback; + h8->device = device; + + h8->h8300_mode = 1; + + state_save_register_item("H8/300", device->tag, 0, h8->h8err); + state_save_register_item_array("H8/300", device->tag, 0, h8->regs); + state_save_register_item("H8/300", device->tag, 0, h8->pc); + state_save_register_item("H8/300", device->tag, 0, h8->ppc); + state_save_register_item("H8/300", device->tag, 0, h8->h8_IRQrequestH); + state_save_register_item("H8/300", device->tag, 0, h8->h8_IRQrequestL); + state_save_register_item("H8/300", device->tag, 0, h8->ccr); + state_save_register_item("H8/300", device->tag, 0, h8->h8300_mode); + + state_save_register_item_array("H8/300", device->tag, 0, h8->per_regs); + state_save_register_item("H8/300", device->tag, 0, h8->h8TSTR); + state_save_register_item_array("H8/300", device->tag, 0, h8->h8TCNT); + + state_save_register_postload(Machine, h8_onstateload, h8); +} + +static CPU_RESET(h8bit) +{ + h83xx_state *h8 = device->token; + + h8->h8err = 0; + h8->pc = h8_mem_read16(0); + change_pc(h8->pc); + + // disable timers + h8->h8TSTR = 0; +} + +static void h8_GenException(h83xx_state *h8, UINT8 vectornr) +{ + // push PC on stack + h8_setreg16(h8, H8_SP, h8_getreg16(h8, H8_SP)-2); + h8_mem_write16(h8_getreg16(h8, H8_SP), h8->pc); + // push ccr + h8_setreg16(h8, H8_SP, h8_getreg16(h8, H8_SP)-2); + h8_mem_write16(h8_getreg16(h8, H8_SP), h8_get_ccr(h8)); + + // generate address from vector + h8_set_ccr(h8, h8_get_ccr(h8) | 0x80); + if (h8->h8uiflag == 0) + h8_set_ccr(h8, h8_get_ccr(h8) | 0x40); + h8->pc = h8_mem_read16(vectornr * 2) & 0xffff; + change_pc(h8->pc); + + // I couldn't find timing info for exceptions, so this is a guess (based on JSR/BSR) + H8_IFETCH_TIMING(2); + H8_STACK_TIMING(2); +} + +static int h8_get_priority(h83xx_state *h8, UINT8 bit) +{ + int res = 0; + switch(bit) + { + case 12: // IRQ0 + if (h8->per_regs[0xF8]&0x80) res = 1; break; + case 13: // IRQ1 + if (h8->per_regs[0xF8]&0x40) res = 1; break; + case 14: // IRQ2 + case 15: // IRQ3 + if (h8->per_regs[0xF8]&0x20) res = 1; break; + case 16: // IRQ4 + case 17: // IRQ5 + if (h8->per_regs[0xF8]&0x10) res = 1; break; + } + return res; +} + +static void h8_check_irqs(h83xx_state *h8) +{ + int lv = -1; + + if (h8->h8iflag == 0) + { + lv = 0; + } + + // any interrupts wanted and can accept ? + if(((h8->h8_IRQrequestH != 0) || (h8->h8_IRQrequestL != 0)) && (lv >= 0)) + { + UINT8 bit, source; + // which one ? + for(bit = 0, source = 0xff; source == 0xff && bit < 32; bit++) + { + if( h8->h8_IRQrequestL & (1<= lv) + { + // mask off + h8->h8_IRQrequestL &= ~(1<h8_IRQrequestH & (1<= lv) + { + // mask off + h8->h8_IRQrequestH &= ~(1<= 3 && source <= 11) + { + (*h8->irq_cb)(h8->device, source - 3 + H8_NMI); + } + + if (source != 0xff) + { + h8_GenException(h8, source); + } + } +} + +#define H8_ADDR_MASK 0xffff +#include "h8ops.h" + +// MAME interface stuff + +static CPU_GET_CONTEXT( h8 ) +{ +} + +static CPU_SET_CONTEXT( h8 ) +{ + if (src) + { + token = src; + } +} + +static CPU_SET_INFO( h8 ) +{ + h83xx_state *h8 = device->token; + + switch(state) { + case CPUINFO_INT_PC: h8->pc = info->i; change_pc(h8->pc); break; + case CPUINFO_INT_REGISTER + H8_PC: h8->pc = info->i; change_pc(h8->pc); break; + case CPUINFO_INT_REGISTER + H8_CCR: h8_set_ccr(h8, info->i); break; + + case CPUINFO_INT_REGISTER + H8_E0: h8->regs[0] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E1: h8->regs[1] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E2: h8->regs[2] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E3: h8->regs[3] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E4: h8->regs[4] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E5: h8->regs[5] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E6: h8->regs[6] = info->i; break; + case CPUINFO_INT_REGISTER + H8_E7: h8->regs[7] = info->i; break; + + case CPUINFO_INT_INPUT_STATE + H8_NMI: if (info->i) h8_300_InterruptRequest(h8, 3); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ0: if (info->i) h8_300_InterruptRequest(h8, 4); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ1: if (info->i) h8_300_InterruptRequest(h8, 5); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ2: if (info->i) h8_300_InterruptRequest(h8, 6); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ3: if (info->i) h8_300_InterruptRequest(h8, 7); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ4: if (info->i) h8_300_InterruptRequest(h8, 8); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ5: if (info->i) h8_300_InterruptRequest(h8, 9); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ6: if (info->i) h8_300_InterruptRequest(h8, 10); break; + case CPUINFO_INT_INPUT_STATE + H8_IRQ7: if (info->i) h8_300_InterruptRequest(h8, 11); break; + + case CPUINFO_INT_INPUT_STATE + H8_SCI_0_RX: if (info->i) h8_300_InterruptRequest(h8, 28); break; + case CPUINFO_INT_INPUT_STATE + H8_SCI_1_RX: if (info->i) h8_300_InterruptRequest(h8, 32); break; + + default: + fatalerror("h8_set_info unknown request %x", state); + break; + } +} + +static READ8_HANDLER( h8330_itu_r ) +{ + UINT8 val; + UINT8 reg; + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + reg = (offset + 0x88) & 0xff; + + switch(reg) + { + case 0x8d: // serial Rx 1 + val = io_read_byte(H8_SERIAL_1); + break; + case 0xb2: // port 1 data + val = io_read_byte(H8_PORT_1); + break; + case 0xb3: // port 2 data + val = io_read_byte(H8_PORT_2); + break; + case 0xb6: // port 3 data + val = io_read_byte(H8_PORT_3); + break; + case 0xb7: // port 4 data + val = io_read_byte(H8_PORT_4); + break; + case 0xba: // port 5 data + val = io_read_byte(H8_PORT_5); + break; + case 0xbb: // port 6 data + val = io_read_byte(H8_PORT_6); + break; + case 0xbe: // port 7 data + val = io_read_byte(H8_PORT_7); + break; + case 0xbf: // port 8 data + val = io_read_byte(H8_PORT_8); + break; + case 0xc1: // port 9 data + val = io_read_byte(H8_PORT_9); + break; + case 0xdc: // serial status + val = 0x87; + break; + case 0xdd: // serial Rx 0 + val = io_read_byte(H8_SERIAL_0); + break; + default: + val = h8->per_regs[reg]; + break; + } + + return val; +} + +static WRITE8_HANDLER( h8330_itu_w ) +{ + UINT8 reg; + h83xx_state *h8 = (h83xx_state *)space->cpu->token; + + reg = (offset + 0x88) & 0xff; + + switch (reg) + { + case 0x8b: // serial Tx 1 + io_write_byte(H8_SERIAL_1, data); + break; + case 0xb2: // port 1 data + io_write_byte(H8_PORT_1, data); + break; + case 0xb3: // port 2 data + io_write_byte(H8_PORT_2, data); + break; + case 0xb6: // port 3 data + io_write_byte(H8_PORT_3, data); + break; + case 0xb7: // port 4 data + io_write_byte(H8_PORT_4, data); + break; + case 0xba: // port 5 data + io_write_byte(H8_PORT_5, data); + break; + case 0xbb: // port 6 data + io_write_byte(H8_PORT_6, data); + break; + case 0xbe: // port 7 data + io_write_byte(H8_PORT_7, data); + break; + case 0xbf: // port 8 data + io_write_byte(H8_PORT_8, data); + break; + case 0xc1: // port 9 data + io_write_byte(H8_PORT_9, data); + break; + case 0xdb: // serial Tx 0 + io_write_byte(H8_SERIAL_0, data); + break; + + case 0xd8: + case 0xda: + case 0xdc: + case 0xd9: + break; + + case 0x88: + case 0x8a: + case 0x8c: + case 0x89: + break; + + case 0xc3: + break; + + case 0xc7: + break; + } + + h8->per_regs[reg] = data; +} + +static ADDRESS_MAP_START( h8_3344_internal_map, ADDRESS_SPACE_PROGRAM, 8 ) + // 512B RAM + AM_RANGE(0xfb80, 0xff7f) AM_RAM + AM_RANGE(0xff88, 0xffff) AM_READWRITE( h8330_itu_r, h8330_itu_w ) +ADDRESS_MAP_END + +CPU_GET_INFO( h8_3344 ) +{ + h83xx_state *h8 = (device != NULL) ? device->token : NULL; + + switch(state) { + // Interface functions and variables + case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(h8); break; + case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(h8); break; + case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(h8); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8bit); break; + case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(h8bit); break; + case CPUINFO_PTR_EXIT: info->exit = 0; break; + case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(h8); break; + case CPUINFO_PTR_BURN: info->burn = 0; break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(h8); break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &h8->cyccnt; break; + case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(h83xx_state); break; + case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break; + case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 10; break; + + // Bus sizes + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; + + // Internal maps + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_h8_3344_internal_map; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = NULL; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map16 = NULL; break; + + // CPU misc parameters + case CPUINFO_STR_NAME: strcpy(info->s, "H8/3344"); break; + case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; + case CPUINFO_STR_FLAGS: strcpy(info->s, h8_get_ccr_str(h8)); break; + case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break; + case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; + case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; + case CPUINFO_INT_INPUT_LINES: info->i = 16; break; + case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = -1; break; + + // CPU main state + case CPUINFO_INT_PC: info->i = h8->pc; break; + case CPUINFO_INT_PREVIOUSPC: info->i = h8->ppc; break; + + case CPUINFO_INT_REGISTER + H8_PC: info->i = h8->pc; break; + case CPUINFO_INT_REGISTER + H8_CCR: info->i = h8_get_ccr(h8); break; + + case CPUINFO_INT_REGISTER + H8_E0: info->i = h8->regs[0]; break; + case CPUINFO_INT_REGISTER + H8_E1: info->i = h8->regs[1]; break; + case CPUINFO_INT_REGISTER + H8_E2: info->i = h8->regs[2]; break; + case CPUINFO_INT_REGISTER + H8_E3: info->i = h8->regs[3]; break; + case CPUINFO_INT_REGISTER + H8_E4: info->i = h8->regs[4]; break; + case CPUINFO_INT_REGISTER + H8_E5: info->i = h8->regs[5]; break; + case CPUINFO_INT_REGISTER + H8_E6: info->i = h8->regs[6]; break; + case CPUINFO_INT_REGISTER + H8_E7: info->i = h8->regs[7]; break; + + // CPU debug stuff + case CPUINFO_STR_REGISTER + H8_PC: sprintf(info->s, "PC :%08x", h8->pc); break; + case CPUINFO_STR_REGISTER + H8_CCR: sprintf(info->s, "CCR :%08x", h8_get_ccr(h8)); break; + + case CPUINFO_STR_REGISTER + H8_E0: sprintf(info->s, " R0 :%08x", h8->regs[0]); break; + case CPUINFO_STR_REGISTER + H8_E1: sprintf(info->s, " R1 :%08x", h8->regs[1]); break; + case CPUINFO_STR_REGISTER + H8_E2: sprintf(info->s, " R2 :%08x", h8->regs[2]); break; + case CPUINFO_STR_REGISTER + H8_E3: sprintf(info->s, " R3 :%08x", h8->regs[3]); break; + case CPUINFO_STR_REGISTER + H8_E4: sprintf(info->s, " R4 :%08x", h8->regs[4]); break; + case CPUINFO_STR_REGISTER + H8_E5: sprintf(info->s, " R5 :%08x", h8->regs[5]); break; + case CPUINFO_STR_REGISTER + H8_E6: sprintf(info->s, " R6 :%08x", h8->regs[6]); break; + case CPUINFO_STR_REGISTER + H8_E7: sprintf(info->s, " SP :%08x", h8->regs[7]); break; + } +} + diff --git a/src/emu/cpu/h83002/h8disasm.c b/src/emu/cpu/h83002/h8disasm.c index fceb7d9b76f..c032aa826b1 100644 --- a/src/emu/cpu/h83002/h8disasm.c +++ b/src/emu/cpu/h83002/h8disasm.c @@ -1,6 +1,6 @@ /*************************************************************************** - h8disasm.c: Hitachi H8/3000 series disassembler + h8disasm.c: Hitachi H8/3xx series disassembler Original by The_Author & DynaChicken for the ZiNc emulator. @@ -9,7 +9,7 @@ ****************************************************************************/ #include "debugger.h" -#include "h83002.h" +#include "h8.h" static const char *const bit_instr[8] = {"bset", "bnot", "bclr", "btst", "bor", "bxor", "band", "bld"}; static const char *const bit_instr2[8] = {"bset", "bnot", "bclr", "btst", "bior", "bixor", "biand", "bild"}; @@ -20,16 +20,16 @@ static const char *const reg_names32[8] = {"ER0", "ER1", "ER2", "ER3", "ER4", " static const char *const reg_names16[16] = {"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7"}; static const char *const reg_names8[16] = {"R0H", "R1H", "R2H", "R3H", "R4H", "R5H", "R6H", "R7H","R0L", "R1L", "R2L", "R3L", "R4L", "R5L", "R6L", "R7L"}; -static UINT32 h8disasm_0(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom); -static UINT32 h8disasm_1(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom); -static UINT32 h8disasm_5(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom); -static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom); -static UINT32 h8disasm_7(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom); +static UINT32 h8disasm_0(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom); +static UINT32 h8disasm_1(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom); +static UINT32 h8disasm_5(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom); +static UINT32 h8disasm_6(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom, UINT32 addr_mask); +static UINT32 h8disasm_7(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom, UINT32 addr_mask); #define h8_mem_read16(x) ((oprom[x] << 8) | oprom[(x) + 1]) #define h8_mem_read32(x) ((oprom[x] << 24) | (oprom[(x) + 1] << 16) | (oprom[(x) + 2] << 8) | oprom[(x) + 3]) -CPU_DISASSEMBLE( h8 ) +offs_t h8_disasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 addr_mask) { UINT32 size = 0; UINT16 opcode; @@ -46,18 +46,18 @@ CPU_DISASSEMBLE( h8 ) break; // mov.b @xx:8, Rd (abs) case 0x2: - sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, 0xffff00 | (opcode & 0xff), reg_names8[(opcode>>8) & 0xf]); + sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, (0xffff00 | (opcode & 0xff))&addr_mask, reg_names8[(opcode>>8) & 0xf]); size = 2; break; // mov.b Rs, @xx:8 (abs) case 0x3: - sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[(opcode>>8) & 0xf], 0xfffff00 | (opcode & 0xff)); + sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[(opcode>>8) & 0xf], (0xfffff00 | (opcode & 0xff))&addr_mask); size = 2; break; // bcc @xx:8 case 0x4: pc += 2; - sprintf(buffer, "%4.4x %s %8.8x", opcode, branch_instr[(opcode >> 8) & 0xf], pc + (INT8)(opcode &0xff)); + sprintf(buffer, "%4.4x %s %8.8x", opcode, branch_instr[(opcode >> 8) & 0xf], (pc + (INT8)(opcode &0xff))&addr_mask); size = 2; break; // group 5 @@ -65,10 +65,10 @@ CPU_DISASSEMBLE( h8 ) size = h8disasm_5(pc, opcode, buffer, oprom); break; case 0x6: - size = h8disasm_6(pc, opcode, buffer, oprom); + size = h8disasm_6(pc, opcode, buffer, oprom, addr_mask); break; case 0x7: - size = h8disasm_7(pc, opcode, buffer, oprom); + size = h8disasm_7(pc, opcode, buffer, oprom, addr_mask); break; case 0x8: // add.b #xx:8, Rd @@ -930,7 +930,7 @@ static UINT32 h8disasm_5(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op return size; } -static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom) +static UINT32 h8disasm_6(UINT32 address, UINT32 opcode, char *buffer, const UINT8 *oprom, UINT32 addr_mask) { UINT32 size = 2; UINT32 data32; @@ -1011,17 +1011,17 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op break; case 0x2: data32=h8_mem_read32(2); - sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, data32, reg_names8[opcode & 0xf]); + sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, data32&addr_mask, reg_names8[opcode & 0xf]); size = 6; break; case 0x8: data16=h8_mem_read16(2); - sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data16); + sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data16&addr_mask); size = 4; break; case 0xa: data32=h8_mem_read32(2); - sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data32); + sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data32&addr_mask); size = 6; break; default: @@ -1036,22 +1036,22 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op { case 0x0: data16=h8_mem_read16(2); - sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data16, reg_names16[opcode & 0xf]); + sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data16&addr_mask, reg_names16[opcode & 0xf]); size = 4; break; case 0x2: data32=h8_mem_read32(2); - sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data32, reg_names16[opcode & 0xf]); + sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data32&addr_mask, reg_names16[opcode & 0xf]); size = 6; break; case 0x8: data16=h8_mem_read16(2); - sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data16); + sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data16&addr_mask); size = 4; break; case 0xa: data32=h8_mem_read32(2); - sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data32); + sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data32&addr_mask); size = 6; break; default: @@ -1092,7 +1092,7 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op sprintf(buffer, "%4.4x mov.b %s,@(%x, %s)", opcode, reg_names8[opcode &0xf], data16, reg_names32[(opcode>>4)&7]); } else - { + { sprintf(buffer, "%4.4x mov.b @(%x, %s), %s", opcode, data16, reg_names32[(opcode>>4)&7], reg_names8[opcode &0xf]); } size = 4; @@ -1117,7 +1117,7 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op return size; } -static UINT32 h8disasm_7(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom) +static UINT32 h8disasm_7(UINT32 address, UINT32 opcode, char *buffer, const UINT8 *oprom, UINT32 addr_mask) { UINT32 size = 2; UINT32 data32; @@ -1255,11 +1255,11 @@ static UINT32 h8disasm_7(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op data16 = h8_mem_read16(2); if(((data16>>4)&0x8) == 0) { - sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr[(data16>>8)&7], (data16>>4)&7, 0xffffff00 + (opcode & 0xff)); + sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr[(data16>>8)&7], (data16>>4)&7, (0xffffff00 + (opcode & 0xff))&addr_mask); } else { - sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr2[(data16>>8)&7], (data16>>4)&7, 0xffffff00 + (opcode & 0xff)); + sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr2[(data16>>8)&7], (data16>>4)&7, (0xffffff00 + (opcode & 0xff))&addr_mask); } size = 4; break; diff --git a/src/emu/cpu/h83002/h8ops.h b/src/emu/cpu/h83002/h8ops.h new file mode 100644 index 00000000000..e4efcb9b143 --- /dev/null +++ b/src/emu/cpu/h83002/h8ops.h @@ -0,0 +1,3551 @@ +static UINT32 udata32, address24; +static INT32 sdata32; +static UINT16 udata16, ext16; +static INT16 sdata16; +static UINT8 udata8; +static INT8 sdata8; +static UINT8 srcreg, dstreg; + +static void h8_group0(h83xx_state *h8, UINT16 opcode); +static void h8_group1(h83xx_state *h8, UINT16 opcode); +static void h8_group5(h83xx_state *h8, UINT16 opcode); +static void h8_group6(h83xx_state *h8, UINT16 opcode); +static void h8_group7(h83xx_state *h8, UINT16 opcode); + +static int h8_branch(h83xx_state *h8, UINT8 condition); + +static UINT8 h8_mov8(h83xx_state *h8, UINT8 src); +static UINT16 h8_mov16(h83xx_state *h8, UINT16 src); +static UINT32 h8_mov32(h83xx_state *h8, UINT32 src); + +static UINT8 h8_add8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT16 h8_add16(h83xx_state *h8, UINT16 src, UINT16 dst); +static UINT32 h8_add32(h83xx_state *h8, UINT32 src, UINT32 dst); + +static UINT8 h8_sub8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT16 h8_sub16(h83xx_state *h8, UINT16 src, UINT16 dst); +static UINT32 h8_sub32(h83xx_state *h8, UINT32 src, UINT32 dst); + +static UINT8 h8_addx8(h83xx_state *h8, UINT8 src, UINT8 dst); + +static void h8_cmp8(h83xx_state *h8, UINT8 src, UINT8 dst); +static void h8_cmp16(h83xx_state *h8, UINT16 src, UINT16 dst); +static void h8_cmp32(h83xx_state *h8, UINT32 src, UINT32 dst); +static UINT8 h8_subx8(h83xx_state *h8, UINT8 src, UINT8 dst); + +static UINT8 h8_or8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT16 h8_or16(h83xx_state *h8, UINT16 src, UINT16 dst); +static UINT32 h8_or32(h83xx_state *h8, UINT32 src, UINT32 dst); + +static UINT8 h8_xor8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT16 h8_xor16(h83xx_state *h8, UINT16 src, UINT16 dst); +static UINT32 h8_xor32(h83xx_state *h8, UINT32 src, UINT32 dst); + +static UINT8 h8_and8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT16 h8_and16(h83xx_state *h8, UINT16 src, UINT16 dst); +static UINT32 h8_and32(h83xx_state *h8, UINT32 src, UINT32 dst); + +static INT8 h8_neg8(h83xx_state *h8, INT8 src); +static INT16 h8_neg16(h83xx_state *h8, INT16 src); +static INT32 h8_neg32(h83xx_state *h8, INT32 src); + +static UINT16 h8_divxu8 (h83xx_state *h8, UINT16 dst, UINT8 src); +static UINT32 h8_divxu16(h83xx_state *h8, UINT32 dst, UINT16 src); + +static UINT8 h8_not8(h83xx_state *h8, UINT8 src); +static UINT16 h8_not16(h83xx_state *h8, UINT16 src); +static UINT32 h8_not32(h83xx_state *h8, UINT32 src); + +static UINT8 h8_rotl8(h83xx_state *h8, UINT8 src); +static UINT16 h8_rotl16(h83xx_state *h8, UINT16 src); +static UINT32 h8_rotl32(h83xx_state *h8, UINT32 src); + +static UINT8 h8_rotxl8(h83xx_state *h8, UINT8 src); +static UINT16 h8_rotxl16(h83xx_state *h8, UINT16 src); +static UINT32 h8_rotxl32(h83xx_state *h8, UINT32 src); + +static UINT8 h8_rotxr8(h83xx_state *h8, UINT8 src); +static UINT16 h8_rotxr16(h83xx_state *h8, UINT16 src); + +static UINT8 h8_shll8(h83xx_state *h8, UINT8 src); +static UINT16 h8_shll16(h83xx_state *h8, UINT16 src); +static UINT32 h8_shll32(h83xx_state *h8, UINT32 src); + +static UINT8 h8_shlr8(h83xx_state *h8, UINT8 src); +static UINT16 h8_shlr16(h83xx_state *h8, UINT16 src); +static UINT32 h8_shlr32(h83xx_state *h8, UINT32 src); + +static INT8 h8_shal8(h83xx_state *h8, INT8 src); +static INT16 h8_shal16(h83xx_state *h8, INT16 src); +static INT32 h8_shal32(h83xx_state *h8, INT32 src); + +static INT8 h8_shar8(h83xx_state *h8, INT8 src); +static INT16 h8_shar16(h83xx_state *h8, INT16 src); +static INT32 h8_shar32(h83xx_state *h8, INT32 src); + +static UINT8 h8_dec8(h83xx_state *h8, UINT8 src); +static UINT16 h8_dec16(h83xx_state *h8, UINT16 src); +static UINT32 h8_dec32(h83xx_state *h8, UINT32 src); + +static UINT8 h8_inc8(h83xx_state *h8, UINT8 src); +static UINT16 h8_inc16(h83xx_state *h8, UINT16 src); +static UINT32 h8_inc32(h83xx_state *h8, UINT32 src); + +static UINT8 h8_bnot8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT8 h8_bst8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT8 h8_bist8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT8 h8_bset8(h83xx_state *h8, UINT8 src, UINT8 dst); +static UINT8 h8_bclr8(h83xx_state *h8, UINT8 src, UINT8 dst); +static void h8_btst8(h83xx_state *h8, UINT8 src, UINT8 dst); +static void h8_bld8(h83xx_state *h8, UINT8 src, UINT8 dst); // loads to carry +static void h8_bor8(h83xx_state *h8, UINT8 src, UINT8 dst); // result in carry +//static void h8_bxor8(h83xx_state *h8, UINT8 src, UINT8 dst); + +static INT32 h8_mulxs16(h83xx_state *h8, INT16 src, INT16 dst); +static UINT32 h8_divxs16(h83xx_state *h8, INT16 src, INT32 dst); + +static CPU_EXECUTE(h8) +{ + h83xx_state *h8 = device->token; + UINT16 opcode=0; + + h8->cyccnt = cycles; + + h8_check_irqs(h8); + + while ((h8->cyccnt > 0) && (!h8->h8err)) + { + h8->ppc = h8->pc; + + debugger_instruction_hook(device->machine, h8->pc); + + opcode = h8_readop16(h8->pc); + h8->pc += 2; + + switch((opcode>>12) & 0xf) + { + case 0x0: + h8_group0(h8, opcode); + break; + case 0x1: + h8_group1(h8, opcode); + break; + case 0x2: + // mov.b @xx:8, Rd (abs) + dstreg = (opcode>>8) & 0xf; + udata8 = h8_mem_read8(0xffff00+(opcode & 0xff)); + h8_mov8(h8, udata8); // flags calculation, dont care about others + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x3: // pass + // mov.b Rs, @xx:8 (abs) + srcreg = (opcode>>8) & 0xf; + udata8 = h8_getreg8(h8, srcreg); + h8_mov8(h8, udata8); // flags calculation, dont care about others + h8_mem_write8(0xffff00+(opcode & 0xff), udata8); + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING(1, 0xffff00+(opcode & 0xff)); + break; + case 0x4: + // bcc @xx:8 + sdata8 = (opcode & 0xff); + if( h8_branch(h8, (opcode >> 8) & 0xf) == 1) h8->pc += sdata8; + change_pc(h8->pc); + break; + case 0x5: + h8_group5(h8, opcode); + break; + case 0x6: + h8_group6(h8, opcode); + break; + case 0x7: + h8_group7(h8, opcode); + break; + case 0x8: + // add.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + udata8 = h8_add8(h8, opcode & 0xff, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1) + break; + case 0x9: + // addx.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + udata8 = h8_addx8(h8, opcode & 0xff, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1) + break; + case 0xa: + // cmp.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + h8_cmp8(h8, opcode & 0xff, h8_getreg8(h8, dstreg)); + H8_IFETCH_TIMING(1); + break; + case 0xb: + // subx.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + udata8 = h8_subx8(h8, opcode & 0xff, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0xc: + // or.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + udata8 = h8_or8(h8, opcode & 0xff, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0xd: + // xor.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + udata8 = h8_xor8(h8, opcode & 0xff, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0xe: // pass + // and.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + udata8 = h8_and8(h8, opcode & 0xff, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1) + break; + case 0xf: // pass + // mov.b #xx:8, Rd + dstreg = (opcode>>8) & 0xf; + udata8 = h8_mov8(h8, opcode & 0xff); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + } + } + + if (h8->h8err) + { + fatalerror("H8/3xx: Unknown opcode (PC=%x) %x", h8->ppc, opcode); + + } + + return cycles - h8->cyccnt; +} + +static void h8_group0(h83xx_state *h8, UINT16 opcode) +{ + switch((opcode>>8)&0xf) + { + case 0: + // nop + H8_IFETCH_TIMING(1); + break; + case 0x1: + // 010x where x should always be 0! + if((opcode & 0xf) != 0) + { + h8->h8err = 1; + break; + } + switch((opcode>>4) & 0xf) + { + // 0100 mov.l prefix + case 0xf: // and.l Rn, Rn + ext16 = h8_mem_read16(h8->pc); + h8->pc += 2; + if (ext16 & 0x88) + { + h8->h8err = 1; + } + else + { + dstreg = ext16 & 0x7; + switch((ext16>>8)&0xff) + { + case 0x64: // or.l ERs, ERd + udata32 = h8_or32(h8, h8_getreg32(h8, (ext16>>4) & 0x7), h8_getreg32(h8, dstreg)); + break; + case 0x65: // xor.l ERs, ERd + udata32 = h8_xor32(h8, h8_getreg32(h8, (ext16>>4) & 0x7), h8_getreg32(h8, dstreg)); + break; + case 0x66: // and.l ERs, ERd + udata32 = h8_and32(h8, h8_getreg32(h8, (ext16>>4) & 0x7), h8_getreg32(h8, dstreg)); + break; + default: + h8->h8err = 1; + return; + } + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(2); + } + break; + + case 0: + ext16 = h8_mem_read16(h8->pc); + h8->pc+=2; + switch((ext16 >> 8) & 0xff) + { + case 0x69: + if((ext16 & 0x80) == 0x80) + { + // mov.l rx, @rx + udata32 = h8_mov32(h8, h8_getreg32(h8, ext16 & 7)); + h8_mem_write32(h8_getreg32(h8, (ext16 >> 4) & 7), udata32); + H8_IFETCH_TIMING(2); + H8_WORD_TIMING(2, h8_getreg32(h8, (ext16 >> 4) & 7)); + } + else + { + // mov.l @rx, rx + udata32 = h8_mem_read32(h8_getreg32(h8, (ext16 >> 4) &7)); + h8_mov32(h8, udata32); + h8_setreg32(h8, ext16 & 7, udata32); + H8_IFETCH_TIMING(2); + H8_WORD_TIMING(2, h8_getreg32(h8, (ext16 >> 4) &7)); + } + break; + case 0x6b: + // mov.l rx, @xx / mov.l @xx, rx + switch((ext16 >> 4)&0xf) + { + case 0x2: + // mov.l @aa:24, erx + address24=h8_mem_read32(h8->pc); + h8->pc += 4; + udata32=h8_mem_read32(address24); + h8_mov32(h8, udata32); // flags only + h8_setreg32(h8, ext16 & 0x7, udata32); + H8_IFETCH_TIMING(4); + H8_WORD_TIMING(2, address24); + break; + case 0xa: + // mov.l erx, @aa:24 + address24=h8_mem_read32(h8->pc); + h8->pc += 4; + udata32=h8_getreg32(h8, ext16 & 0x7); + h8_mov32(h8, udata32); // flags only + h8_mem_write32(address24, udata32); + H8_IFETCH_TIMING(4); + H8_WORD_TIMING(2, address24); + break; + default: + h8->h8err = 1; + break; + } + break; + case 0x6d: + if(ext16 & 0x80) + { + // mov.l rs, @-erd + srcreg = (ext16>>4)&7; + h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)-4); + address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK; + udata32 = h8_getreg32(h8, ext16 & 0x7); + h8_mem_write32(address24, udata32); + H8_IFETCH_TIMING(2); + H8_WORD_TIMING(2, address24); + H8_IOP_TIMING(2); + } + else + { + // mov.l @ers+, rd + srcreg = (ext16 >>4)&7; + address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK; + h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)+4); + udata32 = h8_mem_read32(address24); + h8_setreg32(h8, ext16 & 0x7, udata32); + H8_IFETCH_TIMING(2); + H8_WORD_TIMING(2, address24); + H8_IOP_TIMING(2); + } + h8_mov32(h8, udata32); + break; + case 0x6f: + // mov.l @(displ16 + Rs), rd + sdata16=h8_mem_read16(h8->pc); // sign extend displacements ! + h8->pc += 2; + address24 = (h8_getreg32(h8, (ext16 >> 4)&7)) & H8_ADDR_MASK; + address24 += sdata16; + H8_IFETCH_TIMING(3); + H8_WORD_TIMING(2, address24); + if(ext16 & 0x80) + { + udata32 = h8_getreg32(h8, ext16 & 0x7); + h8_mem_write32(address24, udata32); + } + else + { + udata32 = h8_mem_read32(address24); + h8_setreg32(h8, ext16 & 0x7, udata32); + } + h8_mov32(h8, udata32); + break; + case 0x78: + // prefix for + // mov.l (@aa:x, rx), Rx + //00000A10 010078606B2600201AC2 MOV.L @($00201AC2,ER6),ER6 + // mov.l @(displ24 + Rs), rd + srcreg = (ext16 >> 4) & 7; + + // 6b20 + udata16 = h8_mem_read16(h8->pc); + h8->pc += 2; + dstreg = udata16 & 7; + + address24 = h8_mem_read32(h8->pc); + h8->pc += 4; + address24 += h8_getreg32(h8, srcreg); + address24 &= H8_ADDR_MASK; + + if ( (ext16 & 0x80) && ((udata16 & ~7) == 0x6ba0) ) + { + udata32 = h8_getreg32(h8, dstreg); + h8_mem_write32(address24, udata32); + } + else if ( (!(ext16 & 0x80)) && ((udata16 & ~7) == 0x6b20) ) + { + udata32 = h8_mem_read32(address24); + h8_setreg32(h8, dstreg, udata32); + } + else + { + h8->h8err = 1; + } + + h8_mov32(h8, udata32); + + H8_IFETCH_TIMING(5); + H8_WORD_TIMING(2, address24); + + break; + default: + h8->h8err = 1; + break; + } + break; + case 0xc: + // mulxs + ext16 = h8_mem_read16(h8->pc); + h8->pc+=2; + if(((ext16>>8) & 0xf) == 0) + { + h8->h8err = 1; + } + else if(((ext16>>8) & 0xf) == 2) + { + sdata32 = h8_getreg32(h8, ext16 & 0x7); + sdata16 = h8_getreg16(h8, (ext16>>4) & 0xf); + sdata32 = h8_mulxs16(h8, sdata16, sdata32); + h8_setreg32(h8, ext16 & 0x7, sdata32); + H8_IFETCH_TIMING(2); + H8_IOP_TIMING(20); + } + else + { + logerror("H8/3xx: Unk. group 0 mulxs %x\n", opcode); + h8->h8err = 1; + } + break; + + case 0xd: + //divxs - probably buggy (flags?) + ext16 = h8_mem_read16(h8->pc); + h8->pc+=2; + if(((ext16>>8) & 0xf) == 0) + { + h8->h8err = 1; + } + else if(((ext16>>8) & 0xf) == 3) + { + sdata32 = h8_getreg32(h8, ext16 & 0x7); + sdata16 = h8_getreg16(h8, (ext16>>4) & 0xf); + sdata32 = h8_divxs16(h8, sdata16, sdata32); + h8_setreg32(h8, ext16 & 0x7, sdata32); + H8_IFETCH_TIMING(2); + H8_IOP_TIMING(20); + } + else + { + h8->h8err = 1; + } + + + break; + + default: + h8->h8err = 1; + break; + } + break; + case 0x2: + // stc ccr, rd + if(((opcode>>4) & 0xf) == 0) + { + h8_setreg8(h8, opcode & 0xf, h8_get_ccr(h8)); + H8_IFETCH_TIMING(1); + } + else + { + logerror("H8/3xx: Unk. group 0 2 %x\n", opcode); + h8->h8err = 1; + } + break; + case 0x3: + // ldc rd, ccr + if(((opcode>>4) & 0xf) == 0) + { + udata8 = h8_getreg8(h8, opcode & 0xf); + h8_set_ccr(h8, udata8); + H8_IFETCH_TIMING(1); + } + else + { + logerror("H8/3xx: Unk. group 0 3 %x\n", opcode); + h8->h8err = 1; + } + break; + case 0x4: // pass + // orc + udata8 = h8_or8(h8, opcode & 0xff, h8_get_ccr(h8)); + h8_set_ccr(h8, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x6: + // andc + udata8 = h8_and8(h8, opcode & 0xff, h8_get_ccr(h8)); + h8_set_ccr(h8, udata8); + H8_IFETCH_TIMING(1) + break; + // ldc + case 0x8: + // add.b rx, ry + dstreg = opcode & 0xf; + udata8 = h8_add8(h8, h8_getreg8(h8, (opcode>>4) &0xf), h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1) + break; + // add.w rx, ry + case 0x9: + dstreg = opcode & 0xf; + udata16 = h8_add16(h8, h8_getreg16(h8, (opcode>>4) &0xf), h8_getreg16(h8, dstreg)); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1) + break; + // inc.b rx + case 0xA: + if(opcode&0x80) + { + if(opcode & 0x8) + { + logerror("H8/3xx: Unk. group 0 a %x\n", opcode); + h8->h8err = 1; + } + else + { + dstreg = opcode & 0x7; + udata32 = h8_add32(h8, h8_getreg32(h8, (opcode>>4) &0x7), h8_getreg32(h8, dstreg)); + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1) + } + } + else + { + if(opcode & 0xf0) + { + logerror("H8/3xx: Unk. group 0 a2 %x\n", opcode); + h8->h8err =1; + } + else + { + dstreg = opcode & 0xf; + udata8 = h8_inc8(h8, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + } + } + break; + case 0xb: + switch((opcode>>4)& 0xf) + { + case 0: + if(opcode & 8) + { + h8->h8err = 1; + } + else + { + dstreg = opcode & 7; + udata32 = h8_getreg32(h8, dstreg) + 1; + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1) + } + break; + case 5: + dstreg = opcode & 0xf; + udata16 = h8_inc16(h8, h8_getreg16(h8, dstreg)); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 7: + dstreg = opcode & 0x7; + udata32 = h8_inc32(h8, h8_getreg32(h8, dstreg)); + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + case 8: + if(opcode & 8) + { + h8->h8err = 1; + } + else + { + dstreg = opcode & 7; + udata32 = h8_getreg32(h8, dstreg) + 2; + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1) + } + break; + case 9: + if(opcode & 8) + { + h8->h8err = 1; + } + else + { + dstreg = opcode & 7; + udata32 = h8_getreg32(h8, dstreg) + 4; + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1) + } + break; + case 0xd: + dstreg = opcode & 0xf; + udata16 = h8_inc16(h8, h8_getreg16(h8, dstreg)); + if(h8->h8vflag) + { + udata16 = h8_inc16(h8, udata16); // slow and easy + h8->h8vflag = 1; + } + else + udata16 = h8_inc16(h8, udata16); // slow and easy + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 0xf: + dstreg = opcode & 0x7; + udata32 = h8_inc32(h8, h8_getreg32(h8, dstreg)); + if(h8->h8vflag) + { + udata32 = h8_inc32(h8, udata32); // slow and easy + h8->h8vflag = 1; + } + else + udata32 = h8_inc32(h8, udata32); // slow and easy + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + default: + logerror("H8/3xx: Unk. group 0 b %x\n", opcode); + h8->h8err = 1; + break; + } + break; + // mov.b rx, ry + case 0xc: // pass + dstreg = opcode & 0xf; + udata8 = h8_mov8(h8, h8_getreg8(h8, (opcode>>4) &0xf)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0xd: + // mov.w rx, ry + dstreg = opcode & 0xf; + udata16 = h8_mov16(h8, h8_getreg16(h8, (opcode>>4) &0xf)); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 0xf: + if(opcode & 0x80) + { + if(opcode & 8) + { + logerror("H8/3xx: Unk. group 0 f %x\n", opcode); + h8->h8err = 1; + } + else + { + dstreg = opcode & 0x7; + udata32 = h8_mov32(h8, h8_getreg32(h8, (opcode>>4) &0x7)); + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + } + } + else + { + h8->h8err = 1; + logerror("H8/3xx: Unk. group 0 f2 %x\n", opcode); + if((opcode & 0xf0) !=0) + { + h8->h8err = 1; + } + else + { + h8->h8err = 1; + } + } + break; + default: + logerror("H8/3xx: Unk. group 0 tdef %x\n", opcode); + h8->h8err = 1; + break; + } +} + +static void h8_group1(h83xx_state *h8, UINT16 opcode) +{ + switch((opcode>>8)&0xf) + { + case 0x0: + switch((opcode>>4)&0xf) + { + case 0x0: + // shll.b Rx + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_shll8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x1: + // shll.w Rx + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 = h8_shll16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + break; + case 0x3: + // shal.l Rx + udata32 = h8_getreg32(h8, opcode & 0x7); + udata32 = h8_shll32(h8, udata32); + h8_setreg32(h8, opcode & 0x7, udata32); + H8_IFETCH_TIMING(1); + break; + + case 0x8: + // shal.b Rx + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_shal8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x9: + // shal.w Rx + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 = h8_shal16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + break; + case 0xb: + // shal.l ERx + udata32 = h8_getreg32(h8, opcode & 0x7); + udata32 = h8_shal32(h8, udata32); + h8_setreg32(h8, opcode & 0x7, udata32); + H8_IFETCH_TIMING(1); + break; + + default: + logerror("H8/3xx: Unk. group 1 0 %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0x1: + switch((opcode>>4)&0xf) + { + case 0x0: + // shlr.b rx + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_shlr8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x1: + // shlr.w rx + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 = h8_shlr16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + break; + // shlr.l rx + case 0x3: + udata32 = h8_getreg32(h8, opcode & 0x7); + udata32 = h8_shlr32(h8, udata32); + h8_setreg32(h8, opcode & 0x7, udata32); + H8_IFETCH_TIMING(1); + break; + case 0x8: + // shar.b rx + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_shar8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x9: + // shar.w rx + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 = h8_shar16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + break; + case 0xb: + // shar.l rx + udata32 = h8_getreg32(h8, opcode & 0x7); + udata32 = h8_shar32(h8, udata32); + h8_setreg32(h8, opcode & 0x7, udata32); + H8_IFETCH_TIMING(1); + break; + default: + logerror("H8/3xx: Unk. group 1 1 %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0x2: + switch((opcode>>4)&0xf) + { + case 0x0: + // rotxl.b Rx + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_rotxl8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x1: + // rotxl.w Rx + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 = h8_rotxl16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + break; + + case 0x3: + // rotxl.l Rx + udata32 = h8_getreg32(h8, opcode & 0x7); + udata32 = h8_rotxl32(h8, udata32); + h8_setreg32(h8, opcode & 0xf, udata32); + H8_IFETCH_TIMING(1); + break; + + case 0x8: + // rotl.b Rx + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_rotl8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x9: + // rotl.w Rx + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 = h8_rotl16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + break; + case 0xb: + // rotl.l ERx + udata32 = h8_getreg32(h8, opcode & 0x7); + udata32 = h8_rotl32(h8, udata32); + h8_setreg32(h8, opcode & 0x7, udata32); + H8_IFETCH_TIMING(1); + break; + + default: + logerror("H8/3xx: Unk. group 1 2 %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0x3: + switch((opcode>>4)&0xf) + { + case 0x0: + // rotxr.b Rx + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_rotxr8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x1: + // rotxr.w Rx + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 = h8_rotxr16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + break; + default: + logerror("H8/3xx: Unk. group 1 3 %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0x4: + // or.b rs, rd + dstreg = opcode & 0xf; + udata8 = h8_or8(h8, h8_getreg8(h8, (opcode>>4) &0xf), h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x5: + // xor.b rs, rd + dstreg = opcode & 0xf; + udata8 = h8_xor8(h8, h8_getreg8(h8, (opcode>>4) &0xf), h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x6: + // and.b rs, rd + dstreg = opcode & 0xf; + udata8 = h8_and8(h8, h8_getreg8(h8, (opcode>>4) &0xf), h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1) + break; + // not + case 0x7: + switch((opcode>>4)&0xf) + { + case 0x0: + // not.b Rx + dstreg = opcode & 0xf; + udata8 = h8_not8(h8, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x1: + // not.w Rx + dstreg = opcode & 0xf; + udata16 = h8_not16(h8, h8_getreg16(h8, dstreg)); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 0x3: + // not.l ERx + dstreg = opcode & 0x7; + udata32 = h8_not32(h8, h8_getreg32(h8, dstreg)); + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + + case 0x5: + // extu.w Rx + dstreg = opcode & 0xf; + udata16 = h8_getreg16(h8, dstreg) & 0x00ff; + h8_setreg16(h8, dstreg, udata16); + h8->h8nflag = 0; + h8->h8vflag = 0; + h8->h8zflag = ((udata16 == 0) ? 1 : 0); + H8_IFETCH_TIMING(1); + break; + case 0x7: + // extu.l Rx + dstreg = opcode & 0x7; + udata32 = h8_getreg32(h8, dstreg) & 0x0000ffff; + h8_setreg32(h8, dstreg, udata32); + h8->h8nflag = 0; + h8->h8vflag = 0; + h8->h8zflag = ((udata32 == 0) ? 1 : 0); + H8_IFETCH_TIMING(1); + break; + case 0x8: + // neg.b Rx + dstreg = opcode & 0xf; + sdata8 = h8_neg8(h8, h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, sdata8); + H8_IFETCH_TIMING(1); + break; + case 0x9: + // neg.w Rx + dstreg = opcode & 0xf; + sdata16 = h8_neg16(h8, h8_getreg16(h8, dstreg)); + h8_setreg16(h8, dstreg, sdata16); + H8_IFETCH_TIMING(1); + break; + case 0xb: + // neg.l ERx + dstreg = opcode & 0x7; + sdata32 = h8_neg32(h8, h8_getreg32(h8, dstreg)); + h8_setreg32(h8, dstreg, sdata32); + H8_IFETCH_TIMING(1); + break; + case 0xd: + // exts.w Rx + dstreg = opcode & 0xf; + udata16=h8_getreg16(h8, dstreg)&0xff; + if(udata16&0x80) + { + udata16|=0xff00; + } + h8_setreg16(h8, dstreg, udata16); + + h8->h8vflag = 0; + h8->h8nflag = (udata16 & 0xff00) ? 1 : 0; + h8->h8zflag = (udata16) ? 0 : 1; + + H8_IFETCH_TIMING(1); + break; + + case 0xf: + // exts.l Rx + dstreg = opcode & 0x7; + udata32=h8_getreg32(h8, dstreg)&0xffff; + if(udata32&0x8000) + { + udata32|=0xffff0000; + } + h8_setreg32(h8, dstreg, udata32); + + h8->h8vflag = 0; + h8->h8nflag = (udata32 & 0xffff0000) ? 1 : 0; + h8->h8zflag = (udata32) ? 0 : 1; + + H8_IFETCH_TIMING(1); + break; + + default: + logerror("H8/3xx: Unk. group 1 7-9 %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0x8: + // sub.b rs, rd + dstreg = opcode & 0xf; + udata8 = h8_sub8(h8, h8_getreg8(h8, (opcode>>4) &0xf), h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0x9: + // sub.w rs, rd + dstreg = opcode & 0xf; + udata16 = h8_sub16(h8, h8_getreg16(h8, (opcode>>4) &0xf), h8_getreg16(h8, dstreg)); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + // sub.b rx + case 0xA: + if(opcode&0x80) + { + //logerror("H8/3xx: Unk. group 1 A %x\n", opcode); + + // sub.l rs,rd + dstreg = opcode & 0x7; + udata32=h8_sub32(h8, h8_getreg32(h8, (opcode>>4) &0x7), h8_getreg32(h8, dstreg)); + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(2); + break; + + } + else + { + if(opcode & 0xf0) + { + logerror("H8/3xx: Unk. group A2 0 %x\n", opcode); + h8->h8err = 1; + } + else + { + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_dec8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + } + } + break; + // + case 0xb: + switch((opcode>>4)& 0xf) + { + case 0: // subs.l #1, rN (decrement without touching flags) + dstreg = opcode & 0x7; + udata32 = h8_getreg32(h8, dstreg); + udata32--; + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + case 5: // dec.w #1, rN + dstreg = opcode & 0xf; + udata16 = h8_dec16(h8, h8_getreg16(h8, dstreg)); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 7: // dec.l #1, rN + dstreg = opcode & 0x7; + udata32 = h8_dec32(h8, h8_getreg32(h8, dstreg)); + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + case 8: // subs.l #2, rN (decrement without touching flags) + dstreg = opcode & 0x7; + udata32 = h8_getreg32(h8, dstreg); + udata32-=2; + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + case 9: // subs.l #4, rN (decrement without touching flags) + dstreg = opcode & 0x7; + udata32 = h8_getreg32(h8, dstreg); + udata32-=4; + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + case 0xd: // dec.w #2, rN + dstreg = opcode & 0xf; + udata16 = h8_dec16(h8, h8_getreg16(h8, dstreg)); + if (h8->h8vflag) + { + udata16 = h8_dec16(h8, udata16); + h8->h8vflag = 1; + } + else + udata16 = h8_dec16(h8, udata16); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 0xf: // dec.l #2, rN + dstreg = opcode & 0x7; + udata32 = h8_dec32(h8, h8_getreg32(h8, dstreg)); + if (h8->h8vflag) + { + udata32 = h8_dec32(h8, udata32); + h8->h8vflag = 1; + } + else + udata32 = h8_dec32(h8, udata32); + h8_setreg32(h8, dstreg, udata32); + H8_IFETCH_TIMING(1); + break; + + default: + logerror("H8/3xx: Unk. group 1 B %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0xc: + // cmp.b rs, rd + h8_cmp8(h8, h8_getreg8(h8, (opcode>>4) &0xf), h8_getreg8(h8, opcode & 0xf)); + H8_IFETCH_TIMING(1); + break; + case 0xd: + // cmp.w rx, ry + h8_cmp16(h8, h8_getreg16(h8, (opcode>>4) &0xf), h8_getreg16(h8, opcode & 0xf)); + H8_IFETCH_TIMING(1); + break; + case 0xe: + // subx.b rx, ry + dstreg = opcode & 0xf; + udata8 = h8_subx8(h8, h8_getreg8(h8, (opcode>>4) &0xf), h8_getreg8(h8, dstreg)); + h8_setreg8(h8, dstreg, udata8); + H8_IFETCH_TIMING(1); + break; + case 0xf: + if(opcode & 0x80) + { + if(opcode & 8) + { + logerror("H8/3xx: Unk. group 1 f %x\n", opcode); + h8->h8err = 1; + } + else + { + h8_cmp32(h8, h8_getreg32(h8, (opcode>>4) & 0x7), h8_getreg32(h8, opcode & 0x7)); + H8_IFETCH_TIMING(1); + } + } + else + { + logerror("H8/3xx: Unk. group 1 f2 %x\n", opcode); + h8->h8err = 1; + } + break; + default: + logerror("H8/3xx: Unk. group 1 def %x\n", opcode); + h8->h8err = 1; + break; + } +} + + +static void h8_group5(h83xx_state *h8, UINT16 opcode) +{ + switch((opcode>>8)&0xf) + { + case 0x0: + // mulxu.b + udata8 = h8_getreg8(h8, (opcode>>4)&0xf); + udata16 = h8_getreg16(h8, opcode & 0xf); + udata16 &= 0xff; + udata16 = udata16*udata8; + // no flags modified! + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + H8_IOP_TIMING(12); + break; + case 0x1: + // divxu.b + udata8 = h8_getreg8(h8, (opcode>>4)&0xf); + udata16 = h8_getreg16(h8, opcode & 0x0f); + udata16 = h8_divxu8(h8, udata16,udata8); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + H8_IOP_TIMING(12); + break; + case 0x2: + // mulxu.w + udata16 = h8_getreg16(h8, (opcode>>4)&0xf); + udata32 = h8_getreg32(h8, opcode & 7); + udata32 &= 0xffff; + udata32 = udata32*udata16; + // no flags modified! + h8_setreg32(h8, opcode & 7, udata32); + H8_IFETCH_TIMING(1); + H8_IOP_TIMING(20); + break; + case 0x3: + // divxu.w + udata16 = h8_getreg16(h8, (opcode>>4)&0xf); + udata32 = h8_getreg32(h8, opcode & 7); + udata32 = h8_divxu16(h8, udata32,udata16); + h8_setreg32(h8, opcode & 7, udata32); + H8_IFETCH_TIMING(1); + H8_IOP_TIMING(20); + break; + case 0x4: + if(opcode == 0x5470) + { + // rts + udata32 = h8_mem_read32(h8_getreg32(h8, H8_SP)); + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)+4); + // extended mode + h8->pc = udata32; + change_pc(h8->pc); + H8_IFETCH_TIMING(2); + H8_STACK_TIMING(2); + H8_IOP_TIMING(2); + } + else + { + logerror("H8/3xx: Unk. group 5 1 %x\n", opcode); + h8->h8err = 1; + } + break; + case 0x5: + // bsr 8 + sdata8 = opcode & 0xff; + // extended mode stack push! + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4); + h8_mem_write32(h8_getreg32(h8, H8_SP), h8->pc); + h8->pc = h8->pc + sdata8; + change_pc(h8->pc); + H8_IFETCH_TIMING(2); H8_STACK_TIMING(2); + break; + case 0x6: + // rte + if(opcode == 0x5670) + { + // restore CCR + udata16 = h8_mem_read16(h8_getreg32(h8, H8_SP)); + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)+2); + + // check if PC is 16 or 24/32 bits wide + if (h8->h8300_mode) + { + udata16 = h8_mem_read16(h8_getreg16(h8, H8_SP)); + h8_setreg16(h8, H8_SP, h8_getreg16(h8, H8_SP)+2); + + h8->pc = udata16; + change_pc(h8->pc); + } + else + { + // extended mode restore PC + udata32 = h8_mem_read32(h8_getreg32(h8, H8_SP)); + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)+4); + + // extended mode + h8->pc = udata32; + change_pc(h8->pc); + } + // must do this last, because set_ccr() does a check_irq() + h8_set_ccr(h8, (UINT8)udata16); + H8_IFETCH_TIMING(2); + H8_STACK_TIMING(2); + H8_IOP_TIMING(2); + } + else + { + logerror("H8/3xx: Unk. group 5 6 %x\n", opcode); + h8->h8err = 1; + } + break; + // trapa + case 0x7: + logerror("H8/3xx: Unk. group 5 7 %x\n", opcode); + h8->h8err = 1; + break; + case 0x8: + // bcc @xx:16 + if(opcode & 0xf) + { + logerror("H8/3xx: Unk. group 5 8 %x\n", opcode); + h8->h8err = 1; + } + else + { + sdata16 = h8_mem_read16(h8->pc); + h8->pc += 2; + if( h8_branch(h8, (opcode >> 4) & 0xf) == 1) h8->pc += sdata16; + change_pc(h8->pc); + H8_IOP_TIMING(2) + } + break; + case 0x9: + // jmp @erd + address24 = h8_getreg32(h8, (opcode>>4)&7); + address24 &= H8_ADDR_MASK; + h8->pc = address24; + change_pc(h8->pc); + H8_IFETCH_TIMING(2); + break; + // jmp @aa:24 + case 0xa: + address24 = h8_mem_read32(h8->pc-2); + address24 &= H8_ADDR_MASK; + h8->pc = address24; + change_pc(h8->pc); + H8_IFETCH_TIMING(2); + H8_IOP_TIMING(2); + break; + // jmp @aa:8 + case 0xc: + if(opcode & 0xff) + { + logerror("H8/3xx: Unk. group 5 c %x\n", opcode); + h8->h8err = 1; + } + else + { + // bsr d:16 + sdata16=h8_mem_read16(h8->pc); + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4); + h8_mem_write32(h8_getreg32(h8, H8_SP), h8->pc+2); + h8->pc += sdata16 + 2; + change_pc(h8->pc); + H8_IFETCH_TIMING(2); H8_STACK_TIMING(2); H8_IOP_TIMING(2); + } + break; + case 0xd: + // jsr @reg + address24=h8_getreg32(h8, (opcode>>4)&7); + address24 &= H8_ADDR_MASK; + // extended mode stack push! + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4); + h8_mem_write32(h8_getreg32(h8, H8_SP), h8->pc); + h8->pc = address24; + change_pc(h8->pc); + H8_STACK_TIMING(2); + H8_IOP_TIMING(2); + break; + case 0xe: + // jsr @aa:24 + address24=h8_mem_read32(h8->pc-2); + address24 &= H8_ADDR_MASK; + // extended mode stack push! + h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4); + h8_mem_write32(h8_getreg32(h8, H8_SP), h8->pc+2); + h8->pc = address24; + change_pc(h8->pc); + H8_IFETCH_TIMING(2); + H8_STACK_TIMING(2); + H8_IOP_TIMING(2); + break; + // jsr @aa:8 + default: + logerror("H8: Unk. group 5 def %x\n", opcode); + h8->h8err = 1; + break; + } +} + +static void h8_group6(h83xx_state *h8, UINT16 opcode) +{ + switch((opcode>>8)&0xf) + { + case 0:case 1:case 2:case 3: + { + UINT8 bitnr; + + dstreg = opcode & 0xf; + udata8 = h8_getreg8(h8, dstreg); + bitnr = h8_getreg8(h8, (opcode>>4)& 0xf)&7; + + switch((opcode>>8)&0xf) + { + case 0: udata8 = h8_bset8(h8, bitnr, udata8); h8_setreg8(h8, dstreg, udata8); H8_IFETCH_TIMING(1); break; + case 2: udata8 = h8_bclr8(h8, bitnr, udata8); h8_setreg8(h8, dstreg, udata8); H8_IFETCH_TIMING(1); break; + case 3: h8_btst8(h8, bitnr, udata8); H8_IFETCH_TIMING(1); break; + default: + logerror("H8/3xx: Unk. group 6 def 0-3-0 %x\n", opcode); + h8->h8err = 1; + break; + } + } + break; + case 0x4: + // or.w rs, rd + dstreg = opcode & 0xf; + udata16 = h8_getreg16(h8, dstreg); + udata16 = h8_or16(h8, h8_getreg16(h8, (opcode>>4) & 0xf), udata16); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 0x5: + // xor.w rs, rd + dstreg = opcode & 0xf; + udata16 = h8_getreg16(h8, dstreg); + udata16 = h8_xor16(h8, h8_getreg16(h8, (opcode>>4) & 0xf), udata16); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1); + break; + case 0x6: + // and.w rs, rd + dstreg = opcode & 0xf; + udata16 = h8_getreg16(h8, dstreg); + udata16 = h8_and16(h8, h8_getreg16(h8, (opcode>>4) & 0xf), udata16); + h8_setreg16(h8, dstreg, udata16); + H8_IFETCH_TIMING(1) + break; + case 0x7: + // bst/bist #imm, rd + if(opcode & 0x80) + { + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_bist8(h8, (opcode>>4) & 7, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + } + else + { + udata8 = h8_getreg8(h8, opcode & 0xf); + udata8 = h8_bst8(h8, (opcode>>4) & 7, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + } + break; + case 0x8: + if(opcode & 0x80) + { + // mov.b rx, @rx + udata8 = h8_getreg8(h8, opcode & 0xf); + address24 = h8_getreg32(h8, (opcode>>4)&7) & H8_ADDR_MASK; + h8_mov8(h8, udata8); + h8_mem_write8(address24, udata8); + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING(1, address24); + } + else + { + // mov.b @rx, rx + address24 = h8_getreg32(h8, (opcode>>4)&7) & H8_ADDR_MASK; + udata8 = h8_mem_read8(address24); + h8_mov8(h8, udata8); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING(1, address24); + } + break; + case 0x9: + if(opcode & 0x80) + { + // mov.w rx, @rx + address24 = h8_getreg32(h8, (opcode>>4)&7) & H8_ADDR_MASK; + udata16 = h8_getreg16(h8, opcode & 0xf); + h8_mov16(h8, udata16); + h8_mem_write16(address24, udata16); + H8_IFETCH_TIMING(1); + H8_WORD_TIMING(1, address24); + } + else + { + // mov.w @rx, rx + address24 = h8_getreg32(h8, (opcode>>4)&7) & H8_ADDR_MASK; + udata16 = h8_mem_read16(address24); + h8_mov16(h8, udata16); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + H8_WORD_TIMING(1, address24); + } + break; + case 0xa: + // mov.b rx, @xx + switch((opcode>>4)&0xf) + { + case 0x0: + sdata16=h8_mem_read16(h8->pc); + h8->pc += 2; + address24 = sdata16 & H8_ADDR_MASK; + udata8=h8_mem_read8(address24); + h8_mov8(h8, udata8); // flags only + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING(1, address24); + break; + case 0x2: + address24=h8_mem_read32(h8->pc); + h8->pc += 4; + udata8=h8_mem_read8(address24); + h8_mov8(h8, udata8); // flags only + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(2); + H8_BYTE_TIMING(1, address24); + break; + case 0x8: + sdata16=h8_mem_read16(h8->pc); + h8->pc += 2; + address24 = sdata16 & H8_ADDR_MASK; + udata8=h8_getreg8(h8, opcode & 0xf); + h8_mov8(h8, udata8); // flags only + h8_mem_write8(address24, udata8); + H8_IFETCH_TIMING(3); + H8_BYTE_TIMING(1, address24); + break; + case 0xa: + address24=h8_mem_read32(h8->pc); + h8->pc += 4; + udata8=h8_getreg8(h8, opcode & 0xf); + h8_mov8(h8, udata8); // flags only + h8_mem_write8(address24, udata8); + H8_IFETCH_TIMING(3); + H8_BYTE_TIMING(1, address24); + break; + default: + logerror("H8/3xx: Unk. group 6 a %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0xb: + // mov.w rx, @xx / mov.w @xx, rx + switch((opcode>>4)&0xf) + { + case 0x0: + sdata16=h8_mem_read16(h8->pc); + address24 = sdata16; + address24 &= H8_ADDR_MASK; + h8->pc += 2; + udata16 = h8_mem_read16(address24); + h8_mov16(h8, udata16); // flags only + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(2); + H8_WORD_TIMING(1, address24); + break; + case 0x2: + address24=h8_mem_read32(h8->pc); + h8->pc += 4; + udata16=h8_mem_read16(address24); + h8_mov16(h8, udata16); // flags only + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(4); + H8_WORD_TIMING(1, address24); + break; + case 0x8: + sdata16=h8_mem_read16(h8->pc); + address24 = sdata16; + address24 &= H8_ADDR_MASK; + h8->pc += 2; + udata16=h8_getreg16(h8, opcode & 0xf); + h8_mov16(h8, udata16); // flags only + h8_mem_write16(address24, udata16); + H8_IFETCH_TIMING(2); + H8_WORD_TIMING(1, address24); + break; + case 0xa: // pass + address24=h8_mem_read32(h8->pc); + h8->pc += 4; + udata16=h8_getreg16(h8, opcode & 0xf); + h8_mov16(h8, udata16); // flags only + h8_mem_write16(address24, udata16); + H8_IFETCH_TIMING(4); + H8_WORD_TIMING(1, address24); + break; + default: + logerror("H8/3xx: Unk. group 6b %x\n", opcode); + h8->h8err = 1; + break; + } + break; + case 0xc: + if(opcode & 0x80) + { + // mov.b rx, @-erx + srcreg = (opcode>>4)&7; + h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)-1); + address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK; + udata8 = h8_getreg8(h8, opcode & 0xf); + h8_mem_write8(address24, udata8); + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING(1, address24); + H8_IOP_TIMING(2); + } + else + { + // mov.b @erx+,rx + srcreg = (opcode>>4)&7; + address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK; + h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)+1); + udata8 = h8_mem_read8(address24); + h8_setreg8(h8, opcode & 0xf, udata8); + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING(1, address24); + H8_IOP_TIMING(2); + } + h8_mov8(h8, udata8); + break; + case 0xd: + if(opcode & 0x80) + { + // mov.w rs, @-erd + srcreg = (opcode>>4)&7; + h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)-2); + address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK; + udata16 = h8_getreg16(h8, opcode & 0xf); + h8_mem_write16(address24, udata16); + H8_IFETCH_TIMING(1); + H8_WORD_TIMING(1, address24); + H8_IOP_TIMING(2); + } + else + { + // mov.w @ers+, rd + srcreg = (opcode>>4)&7; + address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK; + h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)+2); + udata16 = h8_mem_read16(address24); + h8_setreg16(h8, opcode & 0xf, udata16); + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING(1, address24); + H8_IOP_TIMING(2); + } + h8_mov16(h8, udata16); + break; + case 0xe: + // mov.b @(displ16 + Rs), rd + sdata16=h8_mem_read16(h8->pc); // sign extend displacements ! + h8->pc += 2; + address24 = (h8_getreg32(h8, (opcode>>4)&7)) & H8_ADDR_MASK; + address24 += sdata16; + if(opcode & 0x80) + { + udata8 = h8_getreg8(h8, opcode & 0xf); + h8_mem_write8(address24, udata8); + } + else + { + udata8 = h8_mem_read8(address24); + h8_setreg8(h8, opcode & 0xf, udata8); + } + h8_mov8(h8, udata8); + H8_IFETCH_TIMING(2); + H8_BYTE_TIMING(1, address24); + break; + case 0xf: + // mov.w @(displ16 + Rs), rd + sdata16=h8_mem_read16(h8->pc); // sign extend displacements ! + h8->pc += 2; + address24 = (h8_getreg32(h8, (opcode>>4)&7)) & H8_ADDR_MASK; + address24 += sdata16; + if(opcode & 0x80) + { + udata16 = h8_getreg16(h8, opcode & 0xf); + h8_mem_write16(address24, udata16); + } + else + { + udata16 = h8_mem_read16(address24); + h8_setreg16(h8, opcode & 0xf, udata16); + } + h8_mov16(h8, udata16); + H8_IFETCH_TIMING(2); + H8_WORD_TIMING(1, address24); + break; + default: + logerror("H8/3xx: Unk. group 6 def %x\n", opcode); + h8->h8err = 1; + break; + } +} + +static void h8_group7(h83xx_state *h8, UINT16 opcode) +{ + switch((opcode>>8)&0xf) + { + case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7: + { + UINT8 bitnr; + + dstreg = opcode & 0xf; + udata8 = h8_getreg8(h8, dstreg); + bitnr = (opcode>>4)&7; + + if(((opcode>>4)&0x8) == 0) + { + switch((opcode>>8)&7) + { + case 0: udata8 = h8_bset8(h8, bitnr, udata8); h8_setreg8(h8, dstreg, udata8); H8_IFETCH_TIMING(1); break; + case 2: udata8 = h8_bclr8(h8, bitnr, udata8); h8_setreg8(h8, dstreg, udata8);H8_IFETCH_TIMING(1);break; + case 3: h8_btst8(h8, bitnr, udata8); H8_IFETCH_TIMING(1); break; + case 7: h8_bld8(h8, bitnr, udata8); H8_IFETCH_TIMING(1); break; + default: + logerror("H8/3xx: Unk. group 7 0-7 def %x\n", opcode); + h8->h8err = 1; + break; + } + } + else + { + switch((opcode>>8)&7) + { + default: + logerror("H8/3xx: Unk. group 7 0-7-1 def %x\n", opcode); + h8->h8err = 1; + break; + } + } + } + break; + case 0x8: + ext16 = h8_mem_read16(h8->pc); + h8->pc += 2; + udata32 = h8_mem_read32(h8->pc); + h8->pc += 4; + + if(((ext16>>8) & 0xf) == 0xa) + { + if(((ext16>>4) & 0xf) == 0xa) + { + udata8 = h8_getreg8(h8, ext16 & 0xf); + h8_mov8(h8, udata8); // update flags ! + udata32 += h8_getreg32(h8, (opcode >> 4) & 7); + h8_mem_write8(udata32, udata8); + } + else + { + udata32 += h8_getreg32(h8, (opcode >> 4) & 7); + udata8 = h8_mem_read8(udata32); + h8_mov8(h8, udata8); // update flags ! + h8_setreg8(h8, ext16 & 0xf, udata8); + } + H8_BYTE_TIMING(1, udata32); + H8_IFETCH_TIMING(4); + } + else if ((ext16 & 0xfff0) == 0x6b20) // mov.w @(24-bit direct, rN), rM + { + udata32 += h8_getreg32(h8, (opcode >> 4) & 7); + udata16 = h8_mem_read16(udata32); + h8_setreg16(h8, ext16 & 0xf, udata16); + h8_mov16(h8, udata16); // update flags ! + H8_WORD_TIMING(1, udata32); + H8_IFETCH_TIMING(4); + } + else if ((ext16 & 0xfff0) == 0x6ba0) // mov.w rM, @(24-bit direct, rN) + { + udata32 += h8_getreg32(h8, (opcode >> 4) & 7); + udata16 = h8_getreg16(h8, ext16 & 0xf); + h8_mem_write16(udata32, udata16); + h8_mov16(h8, udata16); // update flags ! + H8_WORD_TIMING(1, udata32); + H8_IFETCH_TIMING(4); + } + else + { + logerror("H8/3xx: Unk. group 7 8 %x\n", opcode); + h8->h8err = 1; + } + break; + + + // xxx.w #aa:16, rd + case 0x9: + if( ((opcode>>4) & 0xf) > 0x6) + { + logerror("H8/3xx: Unk. group 7 9 %x\n", opcode); + h8->h8err = 1; + } + else + { + UINT16 dst16; + udata16 = h8_mem_read16(h8->pc); + h8->pc += 2; + dstreg = opcode&0xf; + dst16 = h8_getreg16(h8, dstreg); + + switch((opcode>>4)&7) + { + case 0: dst16 = h8_mov16(h8, udata16); h8_setreg16(h8, dstreg, dst16); H8_IFETCH_TIMING(2);break; + case 1: dst16 = h8_add16(h8, udata16, dst16); h8_setreg16(h8, dstreg, dst16); H8_IFETCH_TIMING(2); break; + case 2: h8_cmp16(h8, udata16, dst16); H8_IFETCH_TIMING(2); break; + case 3: dst16 = h8_sub16(h8, udata16, dst16); h8_setreg16(h8, dstreg, dst16); H8_IFETCH_TIMING(2); break; + case 4: dst16 = h8_or16(h8, udata16, dst16); h8_setreg16(h8, dstreg, dst16); H8_IFETCH_TIMING(2); break; + case 5: dst16 = h8_xor16(h8, udata16, dst16); h8_setreg16(h8, dstreg, dst16); H8_IFETCH_TIMING(2); break; + case 6: dst16 = h8_and16(h8, udata16, dst16); h8_setreg16(h8, dstreg, dst16); H8_IFETCH_TIMING(2); break; + default: + logerror("H8/3xx: Unk. group 7 9 %x\n", opcode); + h8->h8err = 1; + break; + } + } + break; + // xxx.l #aa:32, erd + case 0xa: + if( (((opcode>>4) & 0xf) > 0x6) || (opcode & 0x8)) + { + logerror("H8/3xx: Unk. group 7 a %x\n", opcode); + h8->h8err = 1; + } + else + { + UINT32 dst32; + udata32 = h8_mem_read32(h8->pc); + dstreg = opcode&0x7; + h8->pc +=4; + dst32 = h8_getreg32(h8, dstreg); + + switch((opcode>>4)&7) + { + case 0: dst32 = h8_mov32(h8, udata32); h8_setreg32(h8, dstreg, dst32); H8_IFETCH_TIMING(3); break; + case 1: dst32 = h8_add32(h8, udata32, dst32); h8_setreg32(h8, dstreg, dst32); H8_IFETCH_TIMING(3); break; + case 2: h8_cmp32(h8, udata32, dst32); H8_IFETCH_TIMING(3); break; + case 3: dst32 = h8_sub32(h8, udata32, dst32); h8_setreg32(h8, dstreg, dst32); H8_IFETCH_TIMING(3); break; + case 4: dst32 = h8_or32(h8, udata32, dst32); h8_setreg32(h8, dstreg, dst32); H8_IFETCH_TIMING(3); break; + case 5: dst32 = h8_xor32(h8, udata32, dst32); h8_setreg32(h8, dstreg, dst32); H8_IFETCH_TIMING(3); break; + case 6: dst32 = h8_and32(h8, udata32, dst32); h8_setreg32(h8, dstreg, dst32); H8_IFETCH_TIMING(3); break; + default: + logerror("H8/3xx: Unk. group 7 a2 %x\n", opcode); + h8->h8err = 1; + break; + } + } + break; + // eepmov + case 0xb: + if ((opcode & 0xff) == 0xd4) + { + UINT16 cnt = h8_getreg16(h8, 4); + + H8_IFETCH_TIMING(1); + H8_BYTE_TIMING((2*cnt)+2, h8->regs[5]); + + // eepmov.w + while (cnt > 0) + { + h8_mem_write8(h8->regs[6], h8_mem_read8(h8->regs[5])); + h8->regs[5]++; + h8->regs[6]++; + cnt--; + } + h8_setreg16(h8, 4, 0); + h8->pc += 2; + } + else + { + logerror("H8/3xx: Unk. eepmov form\n"); + h8->h8err = 1; + } + break; + // bxx.b #xx:3, @rd + case 0xc: + { + UINT8 bitnr; + + address24 = h8_getreg32(h8, (opcode>>4) & 0x7); + udata8 = h8_mem_read8(address24); + H8_BYTE_TIMING(1, address24); + + ext16 = h8_mem_read16(h8->pc); + h8->pc += 2; + H8_IFETCH_TIMING(2); + + switch(ext16>>8) + { + // BTST Rn,@ERd + case 0x63: + srcreg = (ext16>>4)&0xf; + bitnr = h8_getreg8(h8, srcreg)&7; + h8_btst8(h8, bitnr, udata8); + break; + // btst.b #imm, @Rn + case 0x73: + bitnr = (ext16>>4)&7; + h8_btst8(h8, bitnr, udata8); + break; + default: + h8->h8err=1; + } + } + break; + case 0xd: + ext16 = h8_mem_read16(h8->pc); + h8->pc += 2; + address24 = h8_getreg32(h8, (opcode>>4) & 0x7); + H8_IFETCH_TIMING(2); + H8_BYTE_TIMING(1, address24); + switch(ext16>>8) + { + // bset/bnot/bclr.b Rn, @ERd + case 0x60: + if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8->h8err=1; break; } + h8_mem_write8(address24, h8_bset8(h8, h8_getreg16(h8, (ext16>>4)&0xf)&7, h8_mem_read8(address24))); + break; + case 0x61: + if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8->h8err=1; break; } + h8_mem_write8(address24, h8_bnot8(h8, h8_getreg16(h8, (ext16>>4)&0xf)&7, h8_mem_read8(address24))); + break; + case 0x62: + if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8->h8err=1; break; } + h8_mem_write8(address24, h8_bclr8(h8, h8_getreg16(h8, (ext16>>4)&0xf)&7, h8_mem_read8(address24))); + break; + + case 0x67: // bst/bist.b #Imm:3, @ERd + if (((opcode & 0x8f)!=0)||((ext16 & 0x0f)!=0)) { h8->h8err=1; break; } + if ((ext16 & 0x80)!=0) + { + h8_mem_write8(address24, h8_bist8(h8, (ext16>>4)&7, h8_mem_read8(address24))); + } + else + { + h8_mem_write8(address24, h8_bst8(h8, (ext16>>4)&7, h8_mem_read8(address24))); + } + break; + + // bset/bnot/bclr.b #Imm:3, @ERd + case 0x70: + if (((opcode & 0x8f)!=0)||((ext16 & 0x8f)!=0)) { h8->h8err=1; break; } + h8_mem_write8(address24, h8_bset8(h8, (ext16>>4)&7, h8_mem_read8(address24))); + break; + case 0x71: + if (((opcode & 0x8f)!=0)||((ext16 & 0x8f)!=0)) { h8->h8err=1; break; } + h8_mem_write8(address24, h8_bnot8(h8, (ext16>>4)&7, h8_mem_read8(address24))); + break; + case 0x72: + if (((opcode & 0x8f)!=0)||((ext16 & 0x8f)!=0)) { h8->h8err=1; break; } + h8_mem_write8(address24, h8_bclr8(h8, (ext16>>4)&7, h8_mem_read8(address24))); + break; + } + break; + + // bxxx.b #imm, @aa:8 + case 0xe: + case 0xf: + { + UINT8 bitnr=0; + ext16 = h8_mem_read16(h8->pc); + h8->pc += 2; + address24 = 0xffff00 + (opcode & 0xff); + udata8 = h8_mem_read8(address24); + + switch((ext16>>8)&0xff) + { + case 0x30: + case 0x60: + bitnr = (ext16>>4)&7; + udata8 = h8_bset8(h8, bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); + break; + case 0x70: + bitnr = (ext16>>4)&7; + if(ext16&0x80) h8->h8err = 1; + udata8 = h8_bset8(h8, bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); + break; + case 0x32: + case 0x62: + bitnr = h8_getreg8(h8, (ext16>>4)&0xf)&7; + udata8 = h8_bclr8(h8, bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); + break; + case 0x72: + bitnr = (ext16>>4)&7; + if(ext16&0x80) h8->h8err = 1; + udata8 = h8_bclr8(h8, bitnr, udata8); h8_mem_write8(address24, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); + break; + case 0x63: + bitnr = h8_getreg8(h8, (ext16>>4)&0xf)&7; + h8_btst8(h8, bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(1, address24); + break; + case 0x73: + bitnr = (ext16>>4)&7; + if(ext16&0x80) h8->h8err = 1; + h8_btst8(h8, bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(1, address24); + break; + case 0x74: + bitnr = (ext16>>4)&7; + if(ext16&0x80) + { + // bior + h8->h8err = 1; + } + else + { + h8_bor8(h8, bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(1, address24); + } + break; + case 0x67: + bitnr = (ext16>>4)&7; + if(ext16&0x80) + { + // bist + h8->h8err = 1; + } + else + { + h8_bst8(h8, bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); + } + break; + case 0x77: + bitnr = (ext16>>4)&7; + if(ext16&0x80) + { + // bild + h8->h8err = 1; + } + else + { + h8_bld8(h8, bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24); + } + break; + default: + h8->h8err = 1; + break; + } + if(h8->h8err) + logerror("H8/3xx: Unk. group 7 e %x\n", opcode); + } + break; + default: + logerror("H8/3xx: Unk. group 7 def %x\n", opcode); + h8->h8err = 1; + break; + } +} + + +static UINT8 h8_mov8(h83xx_state *h8, UINT8 src) +{ + // N and Z modified + h8->h8nflag = (src>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(src==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return src; +} + +static UINT16 h8_mov16(h83xx_state *h8, UINT16 src) +{ + // N and Z modified + h8->h8nflag = (src>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(src==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + return src; +} + +static UINT32 h8_mov32(h83xx_state *h8, UINT32 src) +{ + // N and Z modified + h8->h8nflag = (src>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(src==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return src; +} + +static UINT8 h8_sub8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT16 res; + + res = (UINT16)dst - src; + // H,N,Z,V,C modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = (((src^dst) & (res^dst))>>7) & 1; + h8->h8cflag = (res >> 8) & 1; + + // zflag + if((res&0xff)==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + h8->h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; + + return res; +} + +static UINT16 h8_sub16(h83xx_state *h8, UINT16 src, UINT16 dst) +{ + UINT32 res; + + res = (UINT32)dst - src; + // H,N,Z,V,C modified + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = (((src^dst) & (res^dst))>>15) & 1; + h8->h8cflag = (res >> 16) & 1; + // h8->h8hflag = (res>>28) & 1; + + // zflag + if((res&0xffff)==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + h8->h8hflag = ((src^dst^res) & 0x1000) ? 1 : 0; + + return res; +} + +static UINT32 h8_sub32(h83xx_state *h8, UINT32 src, UINT32 dst) +{ + UINT64 res; + + res = (UINT64)dst - src; + // H,N,Z,V,C modified + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = (((src^dst) & (res^dst))>>31) & 1; + h8->h8cflag = (res >> 32) & 1; + // h8->h8hflag = (res>>28) & 1; + + // zflag + if((res&0xffffffff)==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + h8->h8hflag = ((src^dst^res) & 0x10000000) ? 1 : 0; + + return res; +} + + + + +static UINT8 h8_add8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT16 res; + + res = (UINT16)src + dst; + // H,N,Z,V,C modified + h8->h8nflag = (res & 0x80) ? 1 : 0; + h8->h8vflag = ((src^res) & (dst^res) & 0x80) ? 1 : 0; + h8->h8cflag = (res & 0x100) ? 1 : 0; + h8->h8zflag = (res & 0xff) ? 0 : 1; + h8->h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; + + return (UINT8)res; +} + +static UINT16 h8_add16(h83xx_state *h8, UINT16 src, UINT16 dst) +{ + UINT32 res; + + res = (UINT32)src + dst; + // H,N,Z,V,C modified + h8->h8nflag = (res & 0x8000) ? 1 : 0; + h8->h8vflag = ((src^res) & (dst^res) & 0x8000) ? 1 : 0; + h8->h8cflag = (res & 0x10000) ? 1 : 0; + h8->h8zflag = (res & 0xffff) ? 0 : 1; + h8->h8hflag = ((src^dst^res) & 0x1000) ? 1 : 0; + + return res; +} + +static UINT32 h8_add32(h83xx_state *h8, UINT32 src, UINT32 dst) +{ + UINT64 res; + + res = (UINT64)src + dst; + // H,N,Z,V,C modified + h8->h8nflag = (res & 0x80000000) ? 1 : 0; + h8->h8vflag = (((src^res) & (dst^res)) & 0x80000000) ? 1 : 0; + h8->h8cflag = ((res) & (((UINT64)1) << 32)) ? 1 : 0; + h8->h8zflag = (res & 0xffffffff) ? 0 : 1; + h8->h8hflag = ((src^dst^res) & 0x10000000) ? 1 : 0; + + return res; +} + + +static UINT8 h8_addx8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT16 res; + + res = (UINT16)src + dst + h8->h8cflag; + // H,N,Z,V,C modified + h8->h8nflag = (res & 0x80) ? 1 : 0; + h8->h8vflag = ((src^res) & (dst^res) & 0x80) ? 1 : 0; + h8->h8cflag = (res >> 8) & 1; + h8->h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; + h8->h8zflag = (res & 0xff) ? 0 : h8->h8zflag; + + return (UINT8)res; +} + +static void h8_cmp8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT16 res = (UINT16)dst - src; + + h8->h8cflag = (res & 0x100) ? 1 : 0; + h8->h8vflag = (((dst) ^ (src)) & ((dst) ^ (res)) & 0x80) ? 1 : 0; + h8->h8zflag = ((res & 0xff) == 0) ? 1 : 0; + h8->h8nflag = (res & 0x80) ? 1 : 0; + h8->h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; +} + +static void h8_cmp16(h83xx_state *h8, UINT16 src, UINT16 dst) +{ + UINT32 res = (UINT32)dst - src; + + h8->h8cflag = (res & 0x10000) ? 1 : 0; + h8->h8vflag = (((dst) ^ (src)) & ((dst) ^ (res)) & 0x8000) ? 1 : 0; + h8->h8zflag = ((res & 0xffff) == 0) ? 1 : 0; + h8->h8nflag = (res & 0x8000) ? 1 : 0; + h8->h8hflag = ((src^dst^res) & 0x1000) ? 1 : 0; +} + +static void h8_cmp32(h83xx_state *h8, UINT32 src, UINT32 dst) +{ + UINT64 res = (UINT64)dst - src; + + h8->h8cflag = (res & (UINT64)U64(0x100000000)) ? 1 : 0; + h8->h8vflag = (((dst) ^ (src)) & ((dst) ^ (res)) & 0x80000000) ? 1 : 0; + h8->h8zflag = ((res & 0xffffffff) == 0) ? 1 : 0; + h8->h8nflag = (res & 0x80000000) ? 1 : 0; + h8->h8hflag = ((src^dst^res) & 0x10000000) ? 1 : 0; +} + + +static UINT8 h8_subx8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT16 res; + + res = (UINT16)dst - src - (h8->h8cflag) ? 1 : 0; + // H,N,Z,V,C modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = (((src^dst) & (res^dst))>>7) & 1; + h8->h8cflag = (res >> 8) & 1; + + // zflag + if((res&0xff)==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + h8->h8hflag = ((src^dst^res) & 0x10) ? 1 : 0; + + return res; +} + +static UINT8 h8_or8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT8 res; + res = src | dst; + + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_or16(h83xx_state *h8, UINT16 src, UINT16 dst) +{ + UINT16 res; + res = src | dst; + + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_or32(h83xx_state *h8, UINT32 src, UINT32 dst) +{ + UINT32 res; + res = src | dst; + + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_xor8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT8 res; + res = src ^ dst; + + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_xor16(h83xx_state *h8, UINT16 src, UINT16 dst) +{ + UINT16 res; + res = src ^ dst; + + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_xor32(h83xx_state *h8, UINT32 src, UINT32 dst) +{ + UINT32 res; + res = src ^ dst; + + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_and8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + UINT8 res; + + res = src & dst; + // N and Z modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_and16(h83xx_state *h8, UINT16 src, UINT16 dst) +{ + UINT16 res; + + res = src & dst; + // N and Z modified + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_and32(h83xx_state *h8, UINT32 src, UINT32 dst) +{ + UINT32 res; + + res = src & dst; + // N and Z modified + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static void h8_btst8(h83xx_state *h8, UINT8 bit, UINT8 dst) +{ + // test single bit and update Z flag + if( (dst & (1<h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } +} + +static void h8_bld8(h83xx_state *h8, UINT8 bit, UINT8 dst) +{ + // load bit to carry + h8->h8cflag = (dst >> bit) & 1; +} + +static UINT8 h8_bnot8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + // invert single bit, no effect on C flag + return dst ^ (1<h8cflag == 1) + { + res = dst | (1<h8cflag == 0) + { + res = dst | (1<h8cflag |= res ? 1 : 0; +} + +#ifdef UNUSED_FUNCTION +static void h8_bxor8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + dst >>= src; + dst &= 0x1; + h8->h8cflag ^= dst; +} +#endif + +static UINT8 h8_bclr8(h83xx_state *h8, UINT8 src, UINT8 dst) +{ + // pass + UINT8 res; + res = dst & ~(1<h8vflag = 1; + res = 0x80; + } + else + { + h8->h8vflag = 0; + res = 0-src; + } + + // N and Z modified + h8->h8nflag = (res>>7) & 1; + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + h8->h8hflag = ((src|res)&0x08) ? 1 : 0; + h8->h8cflag = ((src|res)&0x80) ? 1 : 0; + + return res; +} + +static INT16 h8_neg16(h83xx_state *h8, INT16 src) +{ + INT16 res; + + if((UINT16)src == 0x8000) + { + // overflow ! + h8->h8vflag = 1; + res = 0x8000; + } + else + { + h8->h8vflag = 0; + res = 0-src; + } + + // N and Z modified + h8->h8nflag = (res>>15) & 1; + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + h8->h8hflag = ((src|res)&0x0800) ? 1 : 0; + h8->h8cflag = ((src|res)&0x8000) ? 1 : 0; + + return res; +} + +static INT32 h8_neg32(h83xx_state *h8, INT32 src) +{ + INT32 res; + + if((UINT32)src == 0x80000000) + { + // overflow ! + h8->h8vflag = 1; + res = 0x80000000; + } + else + { + h8->h8vflag = 0; + res = 0-src; + } + + // N and Z modified + h8->h8nflag = (res>>31) & 1; + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + h8->h8hflag = ((src|res)&0x08000000) ? 1 : 0; + h8->h8cflag = ((src|res)&0x80000000) ? 1 : 0; + + return res; +} + +static UINT8 h8_not8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + + res = ~src; + + // N and Z modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_not16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + + res = ~src; + + // N and Z modified + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_not32(h83xx_state *h8, UINT32 src) +{ + UINT32 res; + + res = ~src; + + // N and Z modified + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_rotxr8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + + // rotate through carry right + res = src>>1; + if(h8->h8cflag)res |= 0x80; // put cflag in upper bit + h8->h8cflag = src & 1; + + // N and Z modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_rotxr16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + + // rotate through carry right + res = src>>1; + if(h8->h8cflag)res |= 0x8000; // put cflag in upper bit + h8->h8cflag = src & 1; + + // N and Z modified + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_rotxl8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + + // rotate through carry + res = src<<1; + res |= (h8->h8cflag & 1); + h8->h8cflag = (src>>7) & 1; + + // N and Z modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_rotxl16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + + // rotate through carry + res = src<<1; + res |= (h8->h8cflag & 1); + h8->h8cflag = (src>>15) & 1; + + // N and Z modified + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_rotxl32(h83xx_state *h8, UINT32 src) +{ + UINT32 res; + + // rotate through carry + res = src<<1; + res |= (h8->h8cflag & 1); + h8->h8cflag = (src>>31) & 1; + + // N and Z modified + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + + +static UINT8 h8_rotl8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + + // rotate + res = src<<1; + h8->h8cflag = (src>>7) & 1; + res |= (h8->h8cflag & 1); + + // N and Z modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_rotl16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + + // rotate + res = src<<1; + h8->h8cflag = (src>>15) & 1; + res |= (h8->h8cflag & 1); + + // N and Z modified + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_rotl32(h83xx_state *h8, UINT32 src) +{ + UINT32 res; + + // rotate + res = src<<1; + h8->h8cflag = (src>>31) & 1; + res |= (h8->h8cflag & 1); + + // N and Z modified + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_shll8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + h8->h8cflag = (src>>7) & 1; + res = src<<1; + // N and Z modified + h8->h8nflag = (res>>7) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_shll16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + h8->h8cflag = (src>>15) & 1; + res = src<<1; + // N and Z modified + h8->h8nflag = (res>>15) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_shll32(h83xx_state *h8, UINT32 src) +{ + UINT32 res; + h8->h8cflag = (src>>31) & 1; + res = src<<1; + // N and Z modified + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_shlr8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + h8->h8cflag = src&1; + res = src>>1; + // N and Z modified + h8->h8nflag = 0; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_shlr16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + h8->h8cflag = src&1; + res = src>>1; + // N and Z modified + h8->h8nflag = 0; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_shlr32(h83xx_state *h8, UINT32 src) +{ + UINT32 res; + h8->h8cflag = src&1; + res = src>>1; + + // N and Z modified, V always cleared + h8->h8nflag = 0; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static INT8 h8_shar8(h83xx_state *h8, INT8 src) +{ + INT8 res; + h8->h8cflag = src&1; + res = (src>>1)|(src&0x80); + // N and Z modified + h8->h8nflag = (res>>7)&1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static INT16 h8_shar16(h83xx_state *h8, INT16 src) +{ + INT16 res; + h8->h8cflag = src&1; + res = (src>>1)|(src&0x8000); + // N and Z modified + h8->h8nflag = (res>>15)&1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static INT32 h8_shar32(h83xx_state *h8, INT32 src) +{ + INT32 res; + + h8->h8cflag = src&1; + res = (src>>1)|(src&0x80000000); + // N and Z modified + h8->h8nflag = (res>>31) & 1; + h8->h8vflag = 0; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static INT8 h8_shal8(h83xx_state *h8, INT8 src) +{ + INT8 res; + + h8->h8cflag = (src>>7)&1; + res = src<<1; + // N and Z modified + h8->h8nflag = (res>>7)&1; + h8->h8vflag = (src ^ res) >> 7; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static INT16 h8_shal16(h83xx_state *h8, INT16 src) +{ + INT16 res; + + h8->h8cflag = (src>>15)&1; + res = src<<1; + // N and Z modified + h8->h8nflag = (res>>15)&1; + h8->h8vflag = (src ^ res) >> 15; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static INT32 h8_shal32(h83xx_state *h8, INT32 src) +{ + INT32 res; + + h8->h8cflag = (src>>31)&1; + res = src<<1; + // N and Z modified + h8->h8nflag = (res>>31)&1; + h8->h8vflag = (src ^ res) >> 31; + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_dec8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + + res = src - 1; + // N and Z modified + h8->h8nflag = (res>>7)&1; + if(src == 0x80) + { + h8->h8vflag = 1; + } + else + { + h8->h8vflag = 0; + } + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_dec16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + + res = src - 1; + // N and Z modified + h8->h8nflag = (res>>15)&1; + if(src == 0x8000) + { + h8->h8vflag = 1; + } + else + { + h8->h8vflag = 0; + } + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_dec32(h83xx_state *h8, UINT32 src) +{ + UINT32 res; + + res = src - 1; + // N and Z modified + h8->h8nflag = (res>>31)&1; + if(src == 0x80000000) + { + h8->h8vflag = 1; + } + else + { + h8->h8vflag = 0; + } + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT8 h8_inc8(h83xx_state *h8, UINT8 src) +{ + UINT8 res; + + res = src + 1; + // N and Z modified + h8->h8nflag = (res>>7)&1; + if(src == 0x7f) + { + h8->h8vflag = 1; + } + else + { + h8->h8vflag = 0; + } + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT16 h8_inc16(h83xx_state *h8, UINT16 src) +{ + UINT16 res; + + res = src + 1; + // N and Z modified + h8->h8nflag = (res>>15)&1; + if(src == 0x7fff) + { + h8->h8vflag = 1; + } + else + { + h8->h8vflag = 0; + } + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static UINT32 h8_inc32(h83xx_state *h8, UINT32 src) +{ + UINT32 res; + + res = src + 1; + // N and Z modified + h8->h8nflag = (res>>31)&1; + if(src == 0x7fffffff) + { + h8->h8vflag = 1; + } + else + { + h8->h8vflag = 0; + } + + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + + return res; +} + +static INT32 h8_mulxs16(h83xx_state *h8, INT16 src, INT16 dst) +{ + INT32 res; + + res = (INT32)src * dst; + + // N and Z modified + h8->h8nflag = (res>>31)&1; + // zflag + if(res==0) + { + h8->h8zflag = 1; + } + else + { + h8->h8zflag = 0; + } + return res; +} + +static UINT32 h8_divxs16(h83xx_state *h8, INT16 src, INT32 dst) +{ + // NOT tested ! + UINT32 res,r1,r2; + INT16 remainder, quotient; + + if(src!=0) + { + quotient = dst/src; + h8->h8zflag = 0; + } + else + { + quotient = 0; + h8->h8zflag = 1; + } + remainder = dst%src; + + r1=*("ient); + r2=*(&remainder); + res=(r2<<16)|r1; + + h8->h8nflag = (quotient<0)?1:0; + + return res; + +} + +static UINT16 h8_divxu8(h83xx_state *h8, UINT16 dst, UINT8 src) +{ + UINT8 remainder, quotient; + UINT16 res = 0; + // N and Z modified + h8->h8nflag = (src>>7)&1; + // zflag + if(src==0) + { + h8->h8zflag = 1; + // dont do anything on division by zero ! + } + else + { + h8->h8zflag = 0; + quotient = dst / src; + remainder = dst % src; + res = (remainder << 8) | quotient; + } + return res; +} + +static UINT32 h8_divxu16(h83xx_state *h8, UINT32 dst, UINT16 src) +{ + UINT16 remainder, quotient; + UINT32 res = 0; + // N and Z modified + h8->h8nflag = (src>>15)&1; + // zflag + if(src==0) + { + h8->h8zflag = 1; + // dont do anything on division by zero ! + } + else + { + h8->h8zflag = 0; + quotient = dst / src; + remainder = dst % src; + res = (remainder << 16) | quotient; + } + return res; +} + +// input: branch condition +// output: 1 if condition met, 0 if not condition met +static int h8_branch(h83xx_state *h8, UINT8 condition) +{ + int taken = 0; + + // a branch always eats 2 ifetch states, regardless of if it's taken + H8_IFETCH_TIMING(2) + + switch(condition) + { + case 0: // bt + taken = 1; + break; + case 1: // bf + break; + case 2: // bhi (C | Z) == 0) + if((h8->h8cflag | h8->h8zflag) == 0)taken = 1; + break; + case 3: // bls + if((h8->h8cflag | h8->h8zflag) == 1)taken = 1; + break; + case 4: // bcc C = 0 + if(h8->h8cflag == 0)taken = 1; + break; + case 5: // bcs C = 1 + if(h8->h8cflag == 1)taken = 1; + break; + case 6: // bne Z = 0 + if(h8->h8zflag == 0)taken = 1; + break; + case 7: // beq Z = 1 + if(h8->h8zflag == 1)taken = 1; + break; + case 8: // bvc V = 0 + h8->h8err = 1; + if(h8->h8vflag == 0)taken = 1; + break; + case 9: // bvs V = 1 + h8->h8err = 1; + if(h8->h8vflag == 1)taken = 1; + break; + case 0xa: // bpl N = 0 + if(h8->h8nflag == 0)taken = 1; + break; + case 0xb: // bmi N = 1 + if(h8->h8nflag == 1)taken = 1; + break; + case 0xc: // bge (N ^ V) = 0 + if((h8->h8nflag ^ h8->h8vflag) == 0)taken = 1; + break; + case 0xd: // blt (N ^ V) = 1 + if((h8->h8nflag ^ h8->h8vflag) == 1)taken = 1; + break; + case 0xe: // bgt (Z | (N ^ V)) = 0 + if((h8->h8zflag | (h8->h8nflag ^ h8->h8vflag)) == 0)taken = 1; + break; + case 0xf: // ble (Z | (N ^ V)) = 1 + if((h8->h8zflag | (h8->h8nflag ^ h8->h8vflag)) == 1)taken = 1; + break; + } + return taken; +} + diff --git a/src/emu/cpu/h83002/h8periph.c b/src/emu/cpu/h83002/h8periph.c index 9be7a760f18..fb2b344805f 100644 --- a/src/emu/cpu/h83002/h8periph.c +++ b/src/emu/cpu/h83002/h8periph.c @@ -11,7 +11,7 @@ #include "debugger.h" #include "deprecat.h" #include "cpuexec.h" -#include "h83002.h" +#include "h8.h" #include "h8priv.h" #define H8_REG_START (0x00ffff10) @@ -39,99 +39,135 @@ static const UINT8 tier[5] = { TIER0, TIER1, TIER2, TIER3, TIER4 }; static const UINT8 tcr[5] = { TCR0, TCR1, TCR2, TCR3, TCR4 }; static const int tscales[4] = { 1, 2, 4, 8 }; -static TIMER_CALLBACK( h8itu_timer_cb ) -{ +extern void h8_3002_InterruptRequest(h83xx_state *h8, UINT8 source); +extern void *h8_token; - int which = (int)(FPTR)ptr; - timer_adjust_oneshot(h8.timer[which], attotime_never, 0); - h8.h8TCNT[which] = 0; - h8.per_regs[tsr[which]] |= 4; +static void h8itu_timer_expire(h83xx_state *h8, int which) +{ + timer_adjust_oneshot(h8->timer[which], attotime_never, 0); + h8->h8TCNT[which] = 0; + h8->per_regs[tsr[which]] |= 4; // interrupt on overflow ? - if(h8.per_regs[tier[which]] & 4) + if(h8->per_regs[tier[which]] & 4) { - h8_3002_InterruptRequest(26 + 4*which); + h8_3002_InterruptRequest(h8, 26 + 4*which); } } -static void h8_itu_refresh_timer(int tnum) +static TIMER_CALLBACK( h8itu_timer_0_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_timer_expire(h8, 0); +} + +static TIMER_CALLBACK( h8itu_timer_1_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_timer_expire(h8, 1); +} + +static TIMER_CALLBACK( h8itu_timer_2_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_timer_expire(h8, 2); +} + +static TIMER_CALLBACK( h8itu_timer_3_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_timer_expire(h8, 3); +} + +static TIMER_CALLBACK( h8itu_timer_4_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_timer_expire(h8, 4); +} + +static void h8_itu_refresh_timer(h83xx_state *h8, int tnum) { int ourTCR = 0; int ourTVAL = 0; attotime period; - ourTCR = h8.per_regs[tcr[tnum]]; - ourTVAL = h8.h8TCNT[tnum]; + ourTCR = h8->per_regs[tcr[tnum]]; + ourTVAL = h8->h8TCNT[tnum]; - period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8.cpu_number])), tscales[ourTCR & 3] * (65536 - ourTVAL)); + period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8->cpu_number])), tscales[ourTCR & 3] * (65536 - ourTVAL)); if (ourTCR & 4) { logerror("H8/3002: Timer %d is using an external clock. Unsupported!\n", tnum); } - timer_adjust_oneshot(h8.timer[tnum], period, 0); + timer_adjust_oneshot(h8->timer[tnum], period, 0); } -static void h8_itu_sync_timers(int tnum) +static void h8_itu_sync_timers(h83xx_state *h8, int tnum) { int ourTCR = 0; attotime cycle_time, cur; UINT16 ratio; - ourTCR = h8.per_regs[tcr[tnum]]; + ourTCR = h8->per_regs[tcr[tnum]]; // get the time per unit - cycle_time = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8.cpu_number])), tscales[ourTCR & 3]); - cur = timer_timeelapsed(h8.timer[tnum]); + cycle_time = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8->cpu_number])), tscales[ourTCR & 3]); + cur = timer_timeelapsed(h8->timer[tnum]); ratio = attotime_to_double(cur) / attotime_to_double(cycle_time); - h8.h8TCNT[tnum] = ratio; + h8->h8TCNT[tnum] = ratio; } -UINT8 h8_itu_read8(UINT8 reg) +UINT8 h8_itu_read8(h83xx_state *h8, UINT8 reg) { UINT8 val; switch(reg) { case 0x60: - val = h8.h8TSTR; + val = h8->h8TSTR; break; case 0x68: - h8_itu_sync_timers(0); - val = h8.h8TCNT[0]>>8; + h8_itu_sync_timers(h8, 0); + val = h8->h8TCNT[0]>>8; break; case 0x69: - h8_itu_sync_timers(0); - val = h8.h8TCNT[0]&0xff; + h8_itu_sync_timers(h8, 0); + val = h8->h8TCNT[0]&0xff; break; case 0x72: - h8_itu_sync_timers(1); - val = h8.h8TCNT[1]>>8; + h8_itu_sync_timers(h8, 1); + val = h8->h8TCNT[1]>>8; break; case 0x73: - h8_itu_sync_timers(1); - val = h8.h8TCNT[1]&0xff; + h8_itu_sync_timers(h8, 1); + val = h8->h8TCNT[1]&0xff; break; case 0x7c: - h8_itu_sync_timers(2); - val = h8.h8TCNT[2]>>8; + h8_itu_sync_timers(h8, 2); + val = h8->h8TCNT[2]>>8; break; case 0x7d: - h8_itu_sync_timers(2); - val = h8.h8TCNT[2]&0xff; + h8_itu_sync_timers(h8, 2); + val = h8->h8TCNT[2]&0xff; break; case 0x86: - h8_itu_sync_timers(3); - val = h8.h8TCNT[3]>>8; + h8_itu_sync_timers(h8, 3); + val = h8->h8TCNT[3]>>8; break; case 0x87: - h8_itu_sync_timers(3); - val = h8.h8TCNT[3]&0xff; + h8_itu_sync_timers(h8, 3); + val = h8->h8TCNT[3]&0xff; break; default: - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; break; } @@ -139,102 +175,102 @@ UINT8 h8_itu_read8(UINT8 reg) return val; } -void h8_itu_write8(UINT8 reg, UINT8 val) +void h8_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val) { - h8.per_regs[reg] = val; + h8->per_regs[reg] = val; switch(reg) { case 0x60: - if ((val & 1) && !(h8.h8TSTR & 1)) + if ((val & 1) && !(h8->h8TSTR & 1)) { - h8_itu_refresh_timer(0); + h8_itu_refresh_timer(h8, 0); } - if ((val & 2) && !(h8.h8TSTR & 2)) + if ((val & 2) && !(h8->h8TSTR & 2)) { - h8_itu_refresh_timer(1); + h8_itu_refresh_timer(h8, 1); } - if ((val & 4) && !(h8.h8TSTR & 4)) + if ((val & 4) && !(h8->h8TSTR & 4)) { - h8_itu_refresh_timer(2); + h8_itu_refresh_timer(h8, 2); } - if ((val & 8) && !(h8.h8TSTR & 8)) + if ((val & 8) && !(h8->h8TSTR & 8)) { - h8_itu_refresh_timer(3); + h8_itu_refresh_timer(h8, 3); } - if ((val & 0x10) && !(h8.h8TSTR & 0x10)) + if ((val & 0x10) && !(h8->h8TSTR & 0x10)) { - h8_itu_refresh_timer(4); + h8_itu_refresh_timer(h8, 4); } - h8.h8TSTR = val; + h8->h8TSTR = val; break; case 0x68: - h8.h8TCNT[0] = (val<<8) | (h8.h8TCNT[0] & 0xff); - if (h8.h8TSTR & 1) + h8->h8TCNT[0] = (val<<8) | (h8->h8TCNT[0] & 0xff); + if (h8->h8TSTR & 1) { - h8_itu_refresh_timer(0); + h8_itu_refresh_timer(h8, 0); } break; case 0x69: - h8.h8TCNT[0] = (val) | (h8.h8TCNT[0] & 0xff00); - if (h8.h8TSTR & 1) + h8->h8TCNT[0] = (val) | (h8->h8TCNT[0] & 0xff00); + if (h8->h8TSTR & 1) { - h8_itu_refresh_timer(0); + h8_itu_refresh_timer(h8, 0); } break; case 0x72: - h8.h8TCNT[1] = (val<<8) | (h8.h8TCNT[1] & 0xff); - if (h8.h8TSTR & 2) + h8->h8TCNT[1] = (val<<8) | (h8->h8TCNT[1] & 0xff); + if (h8->h8TSTR & 2) { - h8_itu_refresh_timer(1); + h8_itu_refresh_timer(h8, 1); } break; case 0x73: - h8.h8TCNT[1] = (val) | (h8.h8TCNT[1] & 0xff00); - if (h8.h8TSTR & 2) + h8->h8TCNT[1] = (val) | (h8->h8TCNT[1] & 0xff00); + if (h8->h8TSTR & 2) { - h8_itu_refresh_timer(1); + h8_itu_refresh_timer(h8, 1); } break; case 0x7c: - h8.h8TCNT[2] = (val<<8) | (h8.h8TCNT[2] & 0xff); - if (h8.h8TSTR & 4) + h8->h8TCNT[2] = (val<<8) | (h8->h8TCNT[2] & 0xff); + if (h8->h8TSTR & 4) { - h8_itu_refresh_timer(2); + h8_itu_refresh_timer(h8, 2); } break; case 0x7d: - h8.h8TCNT[2] = (val) | (h8.h8TCNT[2] & 0xff00); - if (h8.h8TSTR & 4) + h8->h8TCNT[2] = (val) | (h8->h8TCNT[2] & 0xff00); + if (h8->h8TSTR & 4) { - h8_itu_refresh_timer(2); + h8_itu_refresh_timer(h8, 2); } break; case 0x86: - h8.h8TCNT[3] = (val<<8) | (h8.h8TCNT[3] & 0xff); - if (h8.h8TSTR & 8) + h8->h8TCNT[3] = (val<<8) | (h8->h8TCNT[3] & 0xff); + if (h8->h8TSTR & 8) { - h8_itu_refresh_timer(3); + h8_itu_refresh_timer(h8, 3); } break; case 0x87: - h8.h8TCNT[3] = (val) | (h8.h8TCNT[3] & 0xff00); - if (h8.h8TSTR & 8) + h8->h8TCNT[3] = (val) | (h8->h8TCNT[3] & 0xff00); + if (h8->h8TSTR & 8) { - h8_itu_refresh_timer(3); + h8_itu_refresh_timer(h8, 3); } break; case 0x96: - h8.h8TCNT[4] = (val<<8) | (h8.h8TCNT[4] & 0xff); - if (h8.h8TSTR & 0x10) + h8->h8TCNT[4] = (val<<8) | (h8->h8TCNT[4] & 0xff); + if (h8->h8TSTR & 0x10) { - h8_itu_refresh_timer(4); + h8_itu_refresh_timer(h8, 4); } break; case 0x97: - h8.h8TCNT[4] = (val) | (h8.h8TCNT[4] & 0xff00); - if (h8.h8TSTR & 0x10) + h8->h8TCNT[4] = (val) | (h8->h8TCNT[4] & 0xff00); + if (h8->h8TSTR & 0x10) { - h8_itu_refresh_timer(4); + h8_itu_refresh_timer(h8, 4); } break; default: @@ -253,26 +289,26 @@ UINT8 h8_debugger_itu_read8(UINT8 reg) #endif -static UINT8 h8_ISR_r(void) +static UINT8 h8_ISR_r(h83xx_state *h8) { UINT8 res = 0; int i; for (i = 0; i < 6; i++) - if (h8.h8_IRQrequestL & (1 << (12+i))) res |= (1 << i); + if (h8->h8_IRQrequestL & (1 << (12+i))) res |= (1 << i); return res; } -static void h8_ISR_w(UINT8 val) +static void h8_ISR_w(h83xx_state *h8, UINT8 val) { int i; for (i = 0; i < 6; i++) - if ((~val) & (1 << i)) h8.h8_IRQrequestL &= ~(1 << (12+i)); + if ((~val) & (1 << i)) h8->h8_IRQrequestL &= ~(1 << (12+i)); } -UINT8 h8_register_read8(UINT32 address) +UINT8 h8_register_read8(h83xx_state *h8, UINT32 address) { UINT8 val; UINT8 reg; @@ -283,25 +319,25 @@ UINT8 h8_register_read8(UINT32 address) if(reg >= 0x60 && reg <= 0x9f) { - return h8_itu_read8(reg); + return h8_itu_read8(h8, reg); } else { switch(reg) { case 0xb4: // serial port A status - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; val |= 0xc4; // transmit finished, receive ready, no errors break; case 0xb5: // serial port A receive - val = io_read_byte(H8_SERIAL_A); + val = io_read_byte(H8_SERIAL_0); break; case 0xbc: // serial port B status - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; val |= 0xc4; // transmit finished, receive ready, no errors break; case 0xbd: // serial port B receive - val = io_read_byte(H8_SERIAL_B); + val = io_read_byte(H8_SERIAL_1); break; case 0xe0: val = io_read_byte(H8_ADC_0_H); @@ -331,32 +367,32 @@ UINT8 h8_register_read8(UINT32 address) val = 0x80; break; case 0xc7: // port 4 data - val = io_read_byte(H8_PORT4); + val = io_read_byte(H8_PORT_4); break; case 0xcb: // port 6 data - val = io_read_byte(H8_PORT6); + val = io_read_byte(H8_PORT_6); break; case 0xce: // port 7 data - val = io_read_byte(H8_PORT7); + val = io_read_byte(H8_PORT_7); break; case 0xcf: // port 8 data - val = io_read_byte(H8_PORT8); + val = io_read_byte(H8_PORT_8); break; case 0xd2: // port 9 data - val = io_read_byte(H8_PORT9); + val = io_read_byte(H8_PORT_9); break; case 0xd3: // port a data - val = io_read_byte(H8_PORTA); + val = io_read_byte(H8_PORT_A); break; case 0xd6: // port b data - val = io_read_byte(H8_PORTB); + val = io_read_byte(H8_PORT_B); break; case 0xf6: - val = h8_ISR_r(); + val = h8_ISR_r(h8); break; default: - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; break; } } @@ -364,7 +400,7 @@ UINT8 h8_register_read8(UINT32 address) return val; } -void h8_register_write8(UINT32 address, UINT8 val) +void h8_register_write8(h83xx_state *h8, UINT32 address, UINT8 val) { UINT8 reg; @@ -374,167 +410,189 @@ void h8_register_write8(UINT32 address, UINT8 val) if(reg >= 0x60 && reg <= 0x9f) { - h8_itu_write8(reg, val); + h8_itu_write8(h8, reg, val); } switch (reg) { case 0xb3: - io_write_byte(H8_SERIAL_A, val); + io_write_byte(H8_SERIAL_0, val); break; case 0xbb: - io_write_byte(H8_SERIAL_B, val); + io_write_byte(H8_SERIAL_1, val); break; case 0xc7: - io_write_byte(H8_PORT4, val); + io_write_byte(H8_PORT_4, val); break; case 0xcb: // port 6 data - io_write_byte(H8_PORT6, val); + io_write_byte(H8_PORT_6, val); break; case 0xce: // port 7 data - io_write_byte(H8_PORT7, val); + io_write_byte(H8_PORT_7, val); break; case 0xcf: // port 8 data - io_write_byte(H8_PORT8, val); + io_write_byte(H8_PORT_8, val); break; case 0xd2: // port 9 data - io_write_byte(H8_PORT9, val); + io_write_byte(H8_PORT_9, val); break; case 0xd3: // port a data - io_write_byte(H8_PORTA, val); + io_write_byte(H8_PORT_A, val); break; case 0xd6: // port b data - io_write_byte(H8_PORTB, val); + io_write_byte(H8_PORT_B, val); break; case 0xf6: - h8_ISR_w(val); + h8_ISR_w(h8, val); break; } - h8.per_regs[reg] = val; + h8->per_regs[reg] = val; } -static void h8_3007_itu_refresh_timer(int tnum) +static void h8_3007_itu_refresh_timer(h83xx_state *h8, int tnum) { attotime period; - int ourTCR = h8.per_regs[0x68+(tnum*8)]; + int ourTCR = h8->per_regs[0x68+(tnum*8)]; - period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8.cpu_number])), tscales[ourTCR & 3]); + period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8->cpu_number])), tscales[ourTCR & 3]); if (ourTCR & 4) { logerror("H8/3007: Timer %d is using an external clock. Unsupported!\n", tnum); } - timer_adjust_oneshot(h8.timer[tnum], period, 0); + timer_adjust_oneshot(h8->timer[tnum], period, 0); } -static TIMER_CALLBACK( h8itu_3007_timer_cb ) +static void h8itu_3007_timer_expire(h83xx_state *h8, int tnum) { - int tnum = (int)(FPTR)ptr; int base = 0x68 + (tnum*8); - UINT16 count = (h8.per_regs[base + 0x2]<<8) | h8.per_regs[base + 0x3]; + UINT16 count; + + count = (h8->per_regs[base + 0x2]<<8) | h8->per_regs[base + 0x3]; count++; //logerror("h8/3007 timer %d count = %04x\n",tnum,count); // GRA match - if ((h8.per_regs[base + 0x1] & 0x03) && (count == ((h8.per_regs[base + 0x4]<<8) | h8.per_regs[base + 0x5]))) + if ((h8->per_regs[base + 0x1] & 0x03) && (count == ((h8->per_regs[base + 0x4]<<8) | h8->per_regs[base + 0x5]))) { - if ((h8.per_regs[base + 0x0] & 0x60) == 0x20) + if ((h8->per_regs[base + 0x0] & 0x60) == 0x20) { //logerror("h8/3007 timer %d GRA match, restarting\n",tnum); count = 0; - h8_3007_itu_refresh_timer(tnum); + h8_3007_itu_refresh_timer(h8, tnum); } else { //logerror("h8/3007 timer %d GRA match, stopping\n",tnum); - timer_adjust_oneshot(h8.timer[tnum], attotime_never, 0); + timer_adjust_oneshot(h8->timer[tnum], attotime_never, 0); } - h8.per_regs[0x64] |= 1<per_regs[0x64] |= 1<per_regs[0x64] & (4<per_regs[base + 0x1] & 0x30) && (count == ((h8->per_regs[base + 0x6]<<8) | h8->per_regs[base + 0x7]))) { - if ((h8.per_regs[base + 0x0] & 0x60) == 0x40) + if ((h8->per_regs[base + 0x0] & 0x60) == 0x40) { //logerror("h8/3007 timer %d GRB match, restarting\n",tnum); count = 0; - h8_3007_itu_refresh_timer(tnum); + h8_3007_itu_refresh_timer(h8, tnum); } else { //logerror("h8/3007 timer %d GRB match, stopping\n",tnum); - timer_adjust_oneshot(h8.timer[tnum], attotime_never, 0); + timer_adjust_oneshot(h8->timer[tnum], attotime_never, 0); } - h8.per_regs[0x65] |= 1<per_regs[0x65] |= 1<per_regs[0x65] & (4<per_regs[base + 0x1] & 0x33) == 0) && (count == 0)) { //logerror("h8/3007 timer %d OVF match, restarting\n",tnum); - h8.per_regs[0x66] |= 1<per_regs[0x66] |= 1<per_regs[0x66] & (4<> 8; - h8.per_regs[base + 0x3] = count & 0xff; + h8->per_regs[base + 0x2] = count >> 8; + h8->per_regs[base + 0x3] = count & 0xff; } -UINT8 h8_3007_itu_read8(UINT8 reg) +static TIMER_CALLBACK( h8itu_3007_timer_0_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_3007_timer_expire(h8, 0); +} + +static TIMER_CALLBACK( h8itu_3007_timer_1_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_3007_timer_expire(h8, 1); +} + +static TIMER_CALLBACK( h8itu_3007_timer_2_cb ) +{ + h83xx_state *h8 = (h83xx_state *)ptr; + + h8itu_3007_timer_expire(h8, 2); +} + +UINT8 h8_3007_itu_read8(h83xx_state *h8, UINT8 reg) { UINT8 val; switch(reg) { case 0x60: - val = h8.h8TSTR | 0xf8; + val = h8->h8TSTR | 0xf8; break; default: - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; break; } return val; } -void h8_3007_itu_write8(UINT8 reg, UINT8 val) +void h8_3007_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val) { //logerror("%06x: h8/3007 reg %02x = %02x\n",cpu_get_pc(machine->activecpu),reg,val); - h8.per_regs[reg] = val; + h8->per_regs[reg] = val; switch(reg) { case 0x60: - if ((val & 1) && !(h8.h8TSTR & 1)) + if ((val & 1) && !(h8->h8TSTR & 1)) { - h8_3007_itu_refresh_timer(0); + h8_3007_itu_refresh_timer(h8, 0); } - if ((val & 2) && !(h8.h8TSTR & 2)) + if ((val & 2) && !(h8->h8TSTR & 2)) { - h8_3007_itu_refresh_timer(1); + h8_3007_itu_refresh_timer(h8, 1); } - if ((val & 4) && !(h8.h8TSTR & 4)) + if ((val & 4) && !(h8->h8TSTR & 4)) { - h8_3007_itu_refresh_timer(2); + h8_3007_itu_refresh_timer(h8, 2); } - h8.h8TSTR = val; + h8->h8TSTR = val; break; default: val = 0; @@ -542,7 +600,7 @@ void h8_3007_itu_write8(UINT8 reg, UINT8 val) } } -UINT8 h8_3007_register_read8(UINT32 address) +UINT8 h8_3007_register_read8(h83xx_state *h8, UINT32 address) { UINT8 val; UINT8 reg; @@ -553,25 +611,25 @@ UINT8 h8_3007_register_read8(UINT32 address) if(reg >= 0x60 && reg <= 0x7f) { - return h8_3007_itu_read8(reg); + return h8_3007_itu_read8(h8, reg); } else { switch(reg) { case 0xb4: // serial port A status - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; val |= 0xc4; // transmit finished, receive ready, no errors break; case 0xb5: // serial port A receive - val = io_read_byte(H8_SERIAL_A); + val = io_read_byte(H8_SERIAL_0); break; case 0xbc: // serial port B status - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; val |= 0xc4; // transmit finished, receive ready, no errors break; case 0xbd: // serial port B receive - val = io_read_byte(H8_SERIAL_B); + val = io_read_byte(H8_SERIAL_1); break; case 0xe0: val = io_read_byte(H8_ADC_0_H); @@ -602,28 +660,28 @@ UINT8 h8_3007_register_read8(UINT32 address) break; case 0xd3: // port 4 data - val = io_read_byte(H8_PORT4); + val = io_read_byte(H8_PORT_4); break; case 0xd5: // port 6 data - val = io_read_byte(H8_PORT6); + val = io_read_byte(H8_PORT_6); break; case 0xd6: // port 7 data - val = io_read_byte(H8_PORT7); + val = io_read_byte(H8_PORT_7); break; case 0xd7: // port 8 data - val = io_read_byte(H8_PORT8); + val = io_read_byte(H8_PORT_8); break; case 0xd8: // port 9 data - val = io_read_byte(H8_PORT9); + val = io_read_byte(H8_PORT_9); break; case 0xd9: // port a data - val = io_read_byte(H8_PORTA); + val = io_read_byte(H8_PORT_A); break; case 0xda: // port b data - val = io_read_byte(H8_PORTB); + val = io_read_byte(H8_PORT_B); break; default: - val = h8.per_regs[reg]; + val = h8->per_regs[reg]; break; } } @@ -631,7 +689,7 @@ UINT8 h8_3007_register_read8(UINT32 address) return val; } -void h8_3007_register_write8(UINT32 address, UINT8 val) +void h8_3007_register_write8(h83xx_state *h8, UINT32 address, UINT8 val) { UINT8 reg; @@ -639,98 +697,98 @@ void h8_3007_register_write8(UINT32 address, UINT8 val) reg = address & 0xff; - h8.per_regs[reg] = val; + h8->per_regs[reg] = val; if(reg >= 0x60 && reg <= 0x7f) { - h8_3007_itu_write8(reg, val); + h8_3007_itu_write8(h8, reg, val); } else { switch (reg) { case 0xb3: - io_write_byte(H8_SERIAL_A, val); + io_write_byte(H8_SERIAL_0, val); break; case 0xbb: - io_write_byte(H8_SERIAL_B, val); + io_write_byte(H8_SERIAL_1, val); break; case 0xd3: - io_write_byte(H8_PORT4, val); + io_write_byte(H8_PORT_4, val); break; case 0xd5: // port 6 data - io_write_byte(H8_PORT6, val); + io_write_byte(H8_PORT_6, val); break; case 0xd6: // port 7 data - io_write_byte(H8_PORT7, val); + io_write_byte(H8_PORT_7, val); break; case 0xd7: // port 8 data - io_write_byte(H8_PORT8, val); + io_write_byte(H8_PORT_8, val); break; case 0xd8: // port 9 data - io_write_byte(H8_PORT9, val); + io_write_byte(H8_PORT_9, val); break; case 0xd9: // port a data - io_write_byte(H8_PORTA, val); + io_write_byte(H8_PORT_A, val); break; case 0xda: // port b data - io_write_byte(H8_PORTB, val); + io_write_byte(H8_PORT_B, val); break; } } } -UINT8 h8_3007_register1_read8(UINT32 address) +UINT8 h8_3007_register1_read8(h83xx_state *h8, UINT32 address) { switch (address) { - case 0xfee012: return h8.per_regs[0xF2]; // SYSCR - case 0xfee016: return h8_ISR_r(); // ISR - case 0xfee018: return h8.per_regs[0xF8]; // IPRA + case 0xfee012: return h8->per_regs[0xF2]; // SYSCR + case 0xfee016: return h8_ISR_r(h8); // ISR + case 0xfee018: return h8->per_regs[0xF8]; // IPRA } logerror("cpu #%d (PC=%08X): unmapped I/O(1) byte read from %08X\n",cpunum_get_active(),cpu_get_pc(Machine->activecpu),address); return 0; } -void h8_3007_register1_write8(UINT32 address, UINT8 val) +void h8_3007_register1_write8(h83xx_state *h8, UINT32 address, UINT8 val) { switch (address) { - case 0xfee012: h8.per_regs[0xF2] = val; return; // SYSCR - case 0xfee016: h8_ISR_w(val); return; // ISR - case 0xfee018: h8.per_regs[0xF8] = val; return; // IPRA + case 0xfee012: h8->per_regs[0xF2] = val; return; // SYSCR + case 0xfee016: h8_ISR_w(h8, val); return; // ISR + case 0xfee018: h8->per_regs[0xF8] = val; return; // IPRA } logerror("cpu #%d (PC=%08X): unmapped I/O(1) byte write to %08X = %02X\n",cpunum_get_active(),cpu_get_pc(Machine->activecpu),address,val); } -void h8_3007_itu_init(void) +void h8_3007_itu_init(h83xx_state *h8) { - int i; + h8->timer[0] = timer_alloc(h8itu_3007_timer_0_cb, h8); + h8->timer[1] = timer_alloc(h8itu_3007_timer_1_cb, h8); + h8->timer[2] = timer_alloc(h8itu_3007_timer_2_cb, h8); - for (i=0; i<3; i++) - h8.timer[i] = timer_alloc(h8itu_3007_timer_cb, (void*)(FPTR)i); - - h8_itu_reset(); + h8_itu_reset(h8); } -void h8_itu_init(void) +void h8_itu_init(h83xx_state *h8) { - int i; + h8->timer[0] = timer_alloc(h8itu_timer_0_cb, h8); + h8->timer[1] = timer_alloc(h8itu_timer_1_cb, h8); + h8->timer[2] = timer_alloc(h8itu_timer_2_cb, h8); + h8->timer[3] = timer_alloc(h8itu_timer_3_cb, h8); + h8->timer[4] = timer_alloc(h8itu_timer_4_cb, h8); - for (i=0; i<5; i++) - h8.timer[i] = timer_alloc(h8itu_timer_cb, (void*)(FPTR)i); + h8_itu_reset(h8); - h8_itu_reset(); - - h8.cpu_number = cpunum_get_active(); + h8->cpu_number = cpunum_get_active(); } -void h8_itu_reset(void) +void h8_itu_reset(h83xx_state *h8) { int i; // stop all the timers for (i=0; i<5; i++) - timer_adjust_oneshot(h8.timer[i], attotime_never, 0); + timer_adjust_oneshot(h8->timer[i], attotime_never, 0); } diff --git a/src/emu/cpu/h83002/h8priv.h b/src/emu/cpu/h83002/h8priv.h index 266c8c7d90a..42add048242 100644 --- a/src/emu/cpu/h83002/h8priv.h +++ b/src/emu/cpu/h83002/h8priv.h @@ -9,14 +9,16 @@ #ifndef __H8PRIV_H__ #define __H8PRIV_H__ -typedef struct _h83002_state h83002_state; -struct _h83002_state +typedef struct _h83xx_state h83xx_state; +struct _h83xx_state { // main CPU stuff UINT32 h8err; UINT32 regs[8]; UINT32 pc, ppc; + UINT32 h8_IRQrequestH, h8_IRQrequestL; + INT32 cyccnt; UINT8 ccr; UINT8 h8nflag, h8vflag, h8cflag, h8zflag, h8iflag, h8hflag; @@ -35,24 +37,24 @@ struct _h83002_state emu_timer *timer[5]; int cpu_number; - + int h8300_mode; }; +extern h83xx_state h8; -extern h83002_state h8; -UINT8 h8_register_read8(UINT32 address); -UINT8 h8_3007_register_read8(UINT32 address); -UINT8 h8_3007_register1_read8(UINT32 address); -void h8_register_write8(UINT32 address, UINT8 val); -void h8_3007_register_write8(UINT32 address, UINT8 val); -void h8_3007_register1_write8(UINT32 address, UINT8 val); +UINT8 h8_register_read8(h83xx_state *h8, UINT32 address); +UINT8 h8_3007_register_read8(h83xx_state *h8, UINT32 address); +UINT8 h8_3007_register1_read8(h83xx_state *h8, UINT32 address); +void h8_register_write8(h83xx_state *h8, UINT32 address, UINT8 val); +void h8_3007_register_write8(h83xx_state *h8, UINT32 address, UINT8 val); +void h8_3007_register1_write8(h83xx_state *h8, UINT32 address, UINT8 val); -void h8_itu_init(void); -void h8_3007_itu_init(void); -void h8_itu_reset(void); -UINT8 h8_itu_read8(UINT8 reg); -UINT8 h8_3007_itu_read8(UINT8 reg); -void h8_itu_write8(UINT8 reg, UINT8 val); -void h8_3007_itu_write8(UINT8 reg, UINT8 val); +void h8_itu_init(h83xx_state *h8); +void h8_3007_itu_init(h83xx_state *h8); +void h8_itu_reset(h83xx_state *h8); +UINT8 h8_itu_read8(h83xx_state *h8, UINT8 reg); +UINT8 h8_3007_itu_read8(h83xx_state *h8, UINT8 reg); +void h8_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val); +void h8_3007_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val); #endif /* __H8PRIV_H__ */ diff --git a/src/emu/cpuintrf.c b/src/emu/cpuintrf.c index ed37820c350..4bb387ca064 100644 --- a/src/emu/cpuintrf.c +++ b/src/emu/cpuintrf.c @@ -209,6 +209,7 @@ CPU_GET_INFO( i960 ); CPU_GET_INFO( h8_3002 ); CPU_GET_INFO( h8_3007 ); CPU_GET_INFO( h8_3044 ); +CPU_GET_INFO( h8_3344 ); CPU_GET_INFO( v810 ); CPU_GET_INFO( m37702 ); CPU_GET_INFO( m37710 ); @@ -745,6 +746,9 @@ static const struct #if (HAS_I960) { CPU_I960, CPU_GET_INFO_NAME(i960) }, #endif +#if (HAS_H83344) + { CPU_H83344, CPU_GET_INFO_NAME(h8_3344) }, +#endif #if (HAS_H83002) { CPU_H83002, CPU_GET_INFO_NAME(h8_3002) }, { CPU_H83007, CPU_GET_INFO_NAME(h8_3007) }, diff --git a/src/emu/cpuintrf.h b/src/emu/cpuintrf.h index 82182ac19e2..b8f6fe224b3 100644 --- a/src/emu/cpuintrf.h +++ b/src/emu/cpuintrf.h @@ -375,6 +375,7 @@ enum _cpu_type CPU_H83002, CPU_H83007, CPU_H83044, + CPU_H83344, CPU_V810, CPU_M37702, CPU_M37710, diff --git a/src/mame/drivers/bishjan.c b/src/mame/drivers/bishjan.c index 7ddeb8927e4..50946116367 100644 --- a/src/mame/drivers/bishjan.c +++ b/src/mame/drivers/bishjan.c @@ -47,7 +47,7 @@ Notes: #include "driver.h" #include "deprecat.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #define BISHJAN_DEBUG 0 @@ -435,7 +435,7 @@ static INTERRUPT_GEN( bishjan_interrupt ) cpu_set_input_line(device, 0, PULSE_LINE); break; default: - h8_3002_InterruptRequest(24); + cpu_set_input_line(device->machine->cpu[0], H8_METRO_TIMER_HACK, HOLD_LINE); break; } } diff --git a/src/mame/drivers/itgambl2.c b/src/mame/drivers/itgambl2.c index 1fe479eb4e3..17004b7f7f3 100644 --- a/src/mame/drivers/itgambl2.c +++ b/src/mame/drivers/itgambl2.c @@ -52,7 +52,7 @@ #define SND_CLOCK XTAL_14_31818MHz #include "driver.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #include "sound/upd7759.h" diff --git a/src/mame/drivers/itgambl3.c b/src/mame/drivers/itgambl3.c index 30a2380111a..72d46bc665b 100644 --- a/src/mame/drivers/itgambl3.c +++ b/src/mame/drivers/itgambl3.c @@ -41,7 +41,7 @@ #define MAIN_CLOCK XTAL_16MHz #include "driver.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #include "sound/okim6295.h" diff --git a/src/mame/drivers/itgamble.c b/src/mame/drivers/itgamble.c index 8c809f6d646..d3e58b15866 100644 --- a/src/mame/drivers/itgamble.c +++ b/src/mame/drivers/itgamble.c @@ -54,7 +54,7 @@ #define EJOLLYX5_MAIN_CLOCK XTAL_16MHz #include "driver.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #include "sound/okim6295.h" diff --git a/src/mame/drivers/lastfght.c b/src/mame/drivers/lastfght.c index 66e2ebb7e02..90e0ebd6d10 100644 --- a/src/mame/drivers/lastfght.c +++ b/src/mame/drivers/lastfght.c @@ -64,7 +64,7 @@ Notes: #include "driver.h" #include "deprecat.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" /*************************************************************************** Video Hardware @@ -455,7 +455,7 @@ static INTERRUPT_GEN( unknown_interrupt ) cpu_set_input_line(device, 0, PULSE_LINE); break; default: - h8_3002_InterruptRequest(24); + cpu_set_input_line(device->machine->cpu[0], H8_METRO_TIMER_HACK, HOLD_LINE); break; } } diff --git a/src/mame/drivers/metro.c b/src/mame/drivers/metro.c index 5a88e233d9c..b377fecf582 100644 --- a/src/mame/drivers/metro.c +++ b/src/mame/drivers/metro.c @@ -82,7 +82,7 @@ driver modified by Eisuke Watanabe #include "driver.h" #include "deprecat.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #include "cpu/upd7810/upd7810.h" #include "machine/eeprom.h" #include "video/konamiic.h" @@ -2188,9 +2188,9 @@ static WRITE8_HANDLER( puzzlet_portb_w ) } static ADDRESS_MAP_START( puzzlet_io_map, ADDRESS_SPACE_IO, 8 ) - AM_RANGE( H8_PORT7, H8_PORT7 ) AM_READ_PORT("IN2") - AM_RANGE( H8_SERIAL_B, H8_SERIAL_B ) AM_READ_PORT("IN0") // coin - AM_RANGE( H8_PORTB, H8_PORTB ) AM_READ_PORT("DSW0") AM_WRITE( puzzlet_portb_w ) + AM_RANGE( H8_PORT_7, H8_PORT_7 ) AM_READ_PORT("IN2") + AM_RANGE( H8_SERIAL_1, H8_SERIAL_1 ) AM_READ_PORT("IN0") // coin + AM_RANGE( H8_PORT_B, H8_PORT_B ) AM_READ_PORT("DSW0") AM_WRITE( puzzlet_portb_w ) ADDRESS_MAP_END @@ -4693,7 +4693,7 @@ static INTERRUPT_GEN( puzzlet_interrupt ) default: // timer - h8_3002_InterruptRequest(24); + cpu_set_input_line(device->machine->cpu[0], H8_METRO_TIMER_HACK, HOLD_LINE); break; } } diff --git a/src/mame/drivers/namcond1.c b/src/mame/drivers/namcond1.c index 2c9803dbd1e..b13c805a273 100644 --- a/src/mame/drivers/namcond1.c +++ b/src/mame/drivers/namcond1.c @@ -67,7 +67,7 @@ Notes: #include "driver.h" #include "video/ygv608.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #include "namcond1.h" #include "sound/c352.h" #include "machine/at28c16.h" @@ -259,8 +259,8 @@ static ADDRESS_MAP_START( nd1h8rwmap, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_END static ADDRESS_MAP_START( nd1h8iomap, ADDRESS_SPACE_IO, 8 ) - AM_RANGE(H8_PORT7, H8_PORT7) AM_READ( mcu_p7_read ) - AM_RANGE(H8_PORTA, H8_PORTA) AM_READWRITE( mcu_pa_read, mcu_pa_write ) + AM_RANGE(H8_PORT_7, H8_PORT_7) AM_READ( mcu_p7_read ) + AM_RANGE(H8_PORT_A, H8_PORT_A) AM_READWRITE( mcu_pa_read, mcu_pa_write ) AM_RANGE(H8_ADC_0_L, H8_ADC_3_H) AM_NOP // MCU reads these, but the games have no analog controls ADDRESS_MAP_END diff --git a/src/mame/drivers/namcos12.c b/src/mame/drivers/namcos12.c index 93c356b0dd8..1f14b7c0e90 100644 --- a/src/mame/drivers/namcos12.c +++ b/src/mame/drivers/namcos12.c @@ -924,7 +924,7 @@ Notes: #include "driver.h" #include "deprecat.h" #include "cpu/mips/psx.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #include "includes/psx.h" #include "machine/at28c16.h" #include "sound/c352.h" @@ -1421,11 +1421,11 @@ static READ8_HANDLER( s12_mcu_gun_v_r ) } static ADDRESS_MAP_START( s12h8iomap, ADDRESS_SPACE_IO, 8 ) - AM_RANGE(H8_PORT7, H8_PORT7) AM_READ_PORT("DSW") - AM_RANGE(H8_PORT8, H8_PORT8) AM_READ( s12_mcu_p8_r ) AM_WRITENOP - AM_RANGE(H8_PORTA, H8_PORTA) AM_READWRITE( s12_mcu_pa_r, s12_mcu_pa_w ) - AM_RANGE(H8_PORTB, H8_PORTB) AM_READWRITE( s12_mcu_portB_r, s12_mcu_portB_w ) - AM_RANGE(H8_SERIAL_B, H8_SERIAL_B) AM_READ( s12_mcu_rtc_r ) AM_WRITE( s12_mcu_settings_w ) + AM_RANGE(H8_PORT_7, H8_PORT_7) AM_READ_PORT("DSW") + AM_RANGE(H8_PORT_8, H8_PORT_8) AM_READ( s12_mcu_p8_r ) AM_WRITENOP + AM_RANGE(H8_PORT_A, H8_PORT_A) AM_READWRITE( s12_mcu_pa_r, s12_mcu_pa_w ) + AM_RANGE(H8_PORT_B, H8_PORT_B) AM_READWRITE( s12_mcu_portB_r, s12_mcu_portB_w ) + AM_RANGE(H8_SERIAL_1, H8_SERIAL_1) AM_READ( s12_mcu_rtc_r ) AM_WRITE( s12_mcu_settings_w ) AM_RANGE(H8_ADC_0_H, H8_ADC_0_L) AM_NOP AM_RANGE(H8_ADC_1_H, H8_ADC_1_L) AM_READ( s12_mcu_gun_h_r ) // golgo 13 gun X-axis AM_RANGE(H8_ADC_2_H, H8_ADC_2_L) AM_READ( s12_mcu_gun_v_r ) // golgo 13 gun Y-axis diff --git a/src/mame/drivers/namcos23.c b/src/mame/drivers/namcos23.c index 8af9e052743..b5fa4c53d66 100644 --- a/src/mame/drivers/namcos23.c +++ b/src/mame/drivers/namcos23.c @@ -2,27 +2,32 @@ Namco System 22.5 and (Super) System 23 Extremely preliminary driver by R. Belmont, thanks to Phil Stroffolino & Olivier Galibert - Hardware: R4650 (MIPS III with IDT special instructions) main CPU @ 166 MHz - H8/3002 MCU for sound/inputs - Custom polygon hardware - 1 text tilemap - Sprites? + Hardware: * R4650 (MIPS III with IDT special instructions) main CPU. + 133 MHz for Gorgon, 166 MHz for System 23 and Super System 23, and + 200 MHz for Super System 23 Evolution 2. + * H8/3002 MCU for sound/inputs + * Custom polygon hardware + * 1 text tilemap + + Gorgon and System 23 use an I/O board based on the Namco C78, which is a Renesas H8/3334 MCU + (8-bit version of the H8/3002). + + Super System 23 uses a PIC16Cxx-based I/O board. In both cases the I/O boards' MCUs apparently are connected + to the H8/3002's serial port, similar to System 22 where one 37702 reads the I/O and communicates serially + with the second 37702 which is the traditional "subcpu". NOTES: - First 128k of main program ROM is the BIOS, and after that is a 64-bit MIPS ELF image. - - Text layer is (almost?) identical to System 22 & Super System 22. TODO: - Palette is not right. - - H8/3002 does not handshake. Protocol should be the same as System 12 where the MIPS - writes 0x3163 to offset 0x3002 in the shared RAM and the H8/3002 notices and sets it to 0x7106. - The H8 currently never reads that location (core bug?). + - H8/3002 does not handshake. Looks like it needs to speak serially with the I/O board. - - Hook up actual inputs via the 2 serial latches at d00004 and d00006. + - Hook up actual inputs (?) via the 2 serial latches at d00004 and d00006. Works like this: write to d00004, then read d00004 12 times. Ditto at - d00006. This gives 24 bits of inputs from the I/O board (?). + d00006. This gives 24 bits of inputs (?) from the I/O board (?). - The entire 3D subsystem. Is there a DSP living down there? If not, why the 300k download on initial startup? @@ -45,15 +50,15 @@ Note! This document is a Work-In-Progress and will be updated from time to time This document covers all the known Namco System 23 / Super System 23 games, including.... *Angler King Namco, 1999 System 23 *Final Furlong Namco, 1997 System 23 -*Gunmen Wars Namco, 1998 System 23 -*Motocross Go! Namco, 1997 System 23 +Gunmen Wars Namco, 1998 System 23 [not dumped, but have] +Motocross Go! Namco, 1997 System 23 *Panic Park Namco, 1998 System 23 Rapid River Namco, 1997 System 22.5/Gorgon Time Crisis II Namco, 1997 System 23 *Underground King Namco, 1998 System 23 *Downhill Bikers Namco, 199? System 23 -GP 500 Namco, 1999 Super System 23 -Crisis Zone Namco, 2000 Super System 23 [not dumped, but have] +500 GP Namco, 1999 Super System 23 +Crisis Zone Namco, 2000 Super System 23 Evolution 2 [not dumped, but have] Final Furlong 2 Namco, 1999 Super System 23 *Guitar Jam Namco, 1999 Super System 23 *Race On! Namco, 1998 Super System 23 @@ -732,7 +737,7 @@ Notes: #include "driver.h" #include "cpu/mips/mips3.h" -#include "cpu/h83002/h83002.h" +#include "cpu/h83002/h8.h" #include "sound/c352.h" static int ss23_vstat = 0, hstat = 0, vstate = 0; @@ -1055,7 +1060,7 @@ static ADDRESS_MAP_START( ss23_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0x06a30000, 0x06a3ffff) AM_RAM AM_RANGE(0x06820008, 0x0682000f) AM_READ( ss23_vstat_r ) // vblank status? AM_RANGE(0x08000000, 0x08017fff) AM_RAM - AM_RANGE(0x0d000000, 0x0d000007) AM_READ(sysctl_stat_r) + AM_RANGE(0x0d000000, 0x0d000007) AM_READ(sysctl_stat_r) AM_WRITENOP AM_RANGE(0x0fc00000, 0x0fffffff) AM_WRITENOP AM_ROM AM_REGION("user1", 0) AM_RANGE(0x1fc00000, 0x1fffffff) AM_WRITENOP AM_ROM AM_REGION("user1", 0) ADDRESS_MAP_END @@ -1074,6 +1079,15 @@ static READ16_HANDLER( sharedram_sub_r ) return shared16[BYTE_XOR_BE(offset)]; } +#if 1 +static WRITE16_HANDLER(cause_sync_w) +{ + UINT16 *shared16 = (UINT16 *)namcos23_shared_ram; + + shared16[BYTE_XOR_BE(0x4052/2)] = 0; +} +#endif + /* H8/3002 MCU stuff */ static ADDRESS_MAP_START( s23h8rwmap, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM) @@ -1082,7 +1096,7 @@ static ADDRESS_MAP_START( s23h8rwmap, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x300000, 0x300001) AM_READNOP //AM_READ_PORT("IN1") AM_RANGE(0x300002, 0x300003) AM_READNOP //AM_READ_PORT("IN2") AM_RANGE(0x300010, 0x300011) AM_NOP - AM_RANGE(0x300030, 0x300031) AM_NOP + AM_RANGE(0x300030, 0x300031) AM_WRITE(cause_sync_w) // cheats comms with I/O board and makes SUBCPU TEST pass ADDRESS_MAP_END static READ8_HANDLER( s23_mcu_p8_r ) @@ -1200,11 +1214,11 @@ static WRITE8_HANDLER( s23_mcu_settings_w ) } static ADDRESS_MAP_START( s23h8iomap, ADDRESS_SPACE_IO, 8 ) - AM_RANGE(H8_PORT7, H8_PORT7) AM_READ( input_port_0_r ) - AM_RANGE(H8_PORT8, H8_PORT8) AM_READ( s23_mcu_p8_r ) AM_WRITENOP - AM_RANGE(H8_PORTA, H8_PORTA) AM_READWRITE( s23_mcu_pa_r, s23_mcu_pa_w ) - AM_RANGE(H8_PORTB, H8_PORTB) AM_READWRITE( s23_mcu_portB_r, s23_mcu_portB_w ) - AM_RANGE(H8_SERIAL_B, H8_SERIAL_B) AM_READ( s23_mcu_rtc_r ) AM_WRITE( s23_mcu_settings_w ) + AM_RANGE(H8_PORT_7, H8_PORT_7) AM_READ( input_port_0_r ) + AM_RANGE(H8_PORT_8, H8_PORT_8) AM_READ( s23_mcu_p8_r ) AM_WRITENOP + AM_RANGE(H8_PORT_A, H8_PORT_A) AM_READWRITE( s23_mcu_pa_r, s23_mcu_pa_w ) + AM_RANGE(H8_PORT_B, H8_PORT_B) AM_READWRITE( s23_mcu_portB_r, s23_mcu_portB_w ) + AM_RANGE(H8_SERIAL_1, H8_SERIAL_1) AM_READ( s23_mcu_rtc_r ) AM_WRITE( s23_mcu_settings_w ) AM_RANGE(H8_ADC_0_H, H8_ADC_0_L) AM_NOP AM_RANGE(H8_ADC_1_H, H8_ADC_1_L) AM_NOP AM_RANGE(H8_ADC_2_H, H8_ADC_2_L) AM_NOP @@ -1212,10 +1226,18 @@ static ADDRESS_MAP_START( s23h8iomap, ADDRESS_SPACE_IO, 8 ) ADDRESS_MAP_END +/* H8/3334 (Namco C78) I/O board MCU */ +static ADDRESS_MAP_START( s23iobrdmap, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x0fff) AM_READ(SMH_ROM) + AM_RANGE(0xc000, 0xdfff) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( s23iobrdiomap, ADDRESS_SPACE_IO, 8 ) +ADDRESS_MAP_END static DRIVER_INIT(ss23) { - } +} static const gfx_layout namcos23_cg_layout = { @@ -1279,6 +1301,8 @@ static MACHINE_DRIVER_START( gorgon ) MDRV_CPU_IO_MAP( s23h8iomap, 0 ) MDRV_CPU_VBLANK_INT("main", irq1_line_pulse) + MDRV_INTERLEAVE(1000) + MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -1315,6 +1339,13 @@ static MACHINE_DRIVER_START( s23 ) MDRV_CPU_IO_MAP( s23h8iomap, 0 ) MDRV_CPU_VBLANK_INT("main", irq1_line_pulse) + MDRV_CPU_ADD("ioboard", H83344, 14745600 ) + MDRV_CPU_PROGRAM_MAP( s23iobrdmap, 0 ) + MDRV_CPU_IO_MAP( s23iobrdiomap, 0 ) + MDRV_CPU_VBLANK_INT("main", irq1_line_pulse) + + + MDRV_INTERLEAVE(1000) MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_REFRESH_RATE(60) @@ -1353,6 +1384,8 @@ static MACHINE_DRIVER_START( ss23 ) MDRV_CPU_IO_MAP( s23h8iomap, 0 ) MDRV_CPU_VBLANK_INT("main", irq1_line_pulse) + MDRV_INTERLEAVE(1000) + MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -1436,6 +1469,53 @@ ROM_START( rapidrvr ) ROM_LOAD( "rd1waveh.3s", 0x800000, 0x800000, CRC(ef0136b5) SHA1(a6d923ededca168fe555e0b86a72f53bec5424cc) ) ROM_END +ROM_START( motoxgo ) + ROM_REGION32_BE( 0x400000, "user1", 0 ) /* 4 megs for main R4650 code */ + ROM_LOAD16_BYTE( "mg3vera.ic2", 0x000000, 0x200000, CRC(1bf06f00) SHA1(e9d04e9f19bff7a58cb280dd1d5db12801b68ba0) ) + ROM_LOAD16_BYTE( "mg3vera.ic1", 0x000001, 0x200000, CRC(f5e6e25b) SHA1(1de30e8e831be66987112645a9db3a3001b89fe6) ) + + ROM_REGION( 0x80000, "audio", 0 ) /* Hitachi H8/3002 MCU code */ + ROM_LOAD16_WORD_SWAP( "mg3vera.ic3", 0x000000, 0x080000, CRC(9e3d46a8) SHA1(9ffa5b91ea51cc0fb97def25ce47efa3441f3c6f) ) + + ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/3344 MCU code */ + ROM_LOAD( "asca-3a.ic14", 0x000000, 0x040000, CRC(8e9266e5) SHA1(ffa8782ca641d71d57df23ed1c5911db05d3df97) ) + + ROM_REGION( 0x20000, "exioboard", 0 ) /* "extra" I/O board (uses Fujitsu MB90611A MCU) */ + ROM_LOAD( "mg1prog0a.3a", 0x000000, 0x020000, CRC(b2b5be8f) SHA1(803652b7b8fde2196b7fb742ba8b9843e4fcd2de) ) + + ROM_REGION( 0x2000000, "sprite", ROMREGION_ERASEFF ) /* sprite? tilemap? tiles */ + ROM_LOAD16_BYTE( "mg1mtal.2h", 0x000000, 0x800000, CRC(fdad0f0a) SHA1(420d50f012af40f80b196d3aae320376e6c32367) ) + ROM_LOAD16_BYTE( "mg1mtah.2j", 0x000001, 0x800000, CRC(845f4768) SHA1(9c03b1f6dcd9d1f43c2958d855221be7f9415c47) ) + + ROM_REGION( 0x2000000, "textile", ROMREGION_ERASEFF ) /* texture tiles */ + ROM_LOAD( "mg1cgum.4j", 0x000000, 0x800000, CRC(46a77d73) SHA1(132ce2452ee68ba374e98b59032ac0a1a277078d) ) + ROM_LOAD( "mg1cgll.4m", 0x000000, 0x800000, CRC(175dfe34) SHA1(66ae35b0084159aea1afeb1a6486fffa635992b5) ) + ROM_LOAD( "mg1cglm.4k", 0x000000, 0x800000, CRC(b3e648e7) SHA1(98018ae2276f905a7f74e1dab540a44247524436) ) + + ROM_REGION( 0x2000000, "textile2", ROMREGION_ERASEFF ) /* second copy of texture tiles */ + ROM_LOAD( "mg1cgum.5j", 0x000000, 0x800000, CRC(46a77d73) SHA1(132ce2452ee68ba374e98b59032ac0a1a277078d) ) + ROM_LOAD( "mg1cgll.5m", 0x000000, 0x800000, CRC(175dfe34) SHA1(66ae35b0084159aea1afeb1a6486fffa635992b5) ) + ROM_LOAD( "mg1cglm.5k", 0x000000, 0x800000, CRC(b3e648e7) SHA1(98018ae2276f905a7f74e1dab540a44247524436) ) + + ROM_REGION( 0x600000, "textilemap", ROMREGION_ERASEFF ) /* texture tilemap */ + ROM_LOAD( "mg1ccrl.7f", 0x000000, 0x400000, CRC(5372e300) SHA1(63a49782289ed93a321ca7d193241fb83ca97e6b) ) + ROM_LOAD( "mg1ccrh.7e", 0x400000, 0x200000, CRC(2e77597d) SHA1(58dd83c1b0c08115e728c5e7dea5e62135b821ba) ) + + ROM_REGION( 0x600000, "textilemap2", ROMREGION_ERASEFF) /* second copy of texture tilemap */ + ROM_LOAD( "mg1ccrl.7m", 0x000000, 0x400000, CRC(5372e300) SHA1(63a49782289ed93a321ca7d193241fb83ca97e6b) ) + ROM_LOAD( "mg1ccrh.7k", 0x400000, 0x200000, CRC(2e77597d) SHA1(58dd83c1b0c08115e728c5e7dea5e62135b821ba) ) + + ROM_REGION32_LE( 0x2000000, "pointrom", ROMREGION_ERASEFF ) /* 3D model data */ + ROM_LOAD32_WORD( "mg1pt0l.7c", 0x000000, 0x400000, CRC(3b9e95d3) SHA1(d7823ed6c590669ccd4098ed439599a3eb814ed1) ) + ROM_LOAD32_WORD( "mg1pt0h.7a", 0x000002, 0x400000, CRC(c9ba1b47) SHA1(42ec0638edb4c502ff0a340c4cf590bdd767cfe2) ) + ROM_LOAD32_WORD( "mg1pt1h.5a", 0x800000, 0x400000, CRC(8d4f7097) SHA1(004e9ed0b5d6ce83ffadb9bd429fa7560abdb598) ) + ROM_LOAD32_WORD( "mg1pt1l.5c", 0x800002, 0x400000, CRC(0dd2f358) SHA1(3537e6be3fec9fec8d5a8dd02d9cf67b3805f8f0) ) + + ROM_REGION( 0x1000000, "c352", ROMREGION_ERASEFF ) /* C352 PCM samples */ + ROM_LOAD( "mg1wavel.2c", 0x000000, 0x800000, CRC(f78b1b4d) SHA1(47cd654ec0a69de0dc81b8d83692eebf5611228b) ) + ROM_LOAD( "mg1waveh.2a", 0x800000, 0x800000, CRC(8cb73877) SHA1(2e2b170c7ff889770c13b4ab7ac316b386ada153) ) +ROM_END + ROM_START( timecrs2 ) ROM_REGION32_BE( 0x400000, "user1", 0 ) /* 4 megs for main R4650 code */ ROM_LOAD16_BYTE( "tss3verb.2", 0x000000, 0x200000, CRC(c7be691f) SHA1(5e2e7a0db3d8ce6dfeb6c0d99e9fe6a9f9cab467) ) @@ -1444,6 +1524,9 @@ ROM_START( timecrs2 ) ROM_REGION( 0x80000, "audio", 0 ) /* Hitachi H8/3002 MCU code */ ROM_LOAD16_WORD_SWAP( "tss3verb.3", 0x000000, 0x080000, CRC(41e41994) SHA1(eabc1a307c329070bfc6486cb68169c94ff8a162) ) + ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/3344 MCU code */ + ROM_LOAD( "tssioprog.ic3", 0x000000, 0x040000, CRC(edad4538) SHA1(1330189184a636328d956c0e435f8d9ad2e96a80) ) + ROM_REGION( 0x2000000, "sprite", 0 ) /* sprite? tilemap? tiles */ ROM_LOAD16_BYTE( "tss1mtal.2h", 0x0000000, 0x800000, CRC(bfc79190) SHA1(04bda00c4cc5660d27af4f3b0ee3550dea8d3805) ) ROM_LOAD16_BYTE( "tss1mtah.2j", 0x0000001, 0x800000, CRC(697c26ed) SHA1(72f6f69e89496ba0c6183b35c3bde71f5a3c721f) ) @@ -1481,7 +1564,7 @@ ROM_START( timcrs2b ) ROM_REGION( 0x80000, "audio", 0 ) /* Hitachi H8/3002 MCU code */ ROM_LOAD16_WORD_SWAP( "tss3verb.3", 0x000000, 0x080000, CRC(41e41994) SHA1(eabc1a307c329070bfc6486cb68169c94ff8a162) ) - ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/300 MCU code */ + ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/3344 MCU code */ ROM_LOAD( "tssioprog.ic3", 0x000000, 0x040000, CRC(edad4538) SHA1(1330189184a636328d956c0e435f8d9ad2e96a80) ) ROM_REGION( 0x2000000, "sprite", 0 ) /* sprite? tilemap? tiles */ @@ -1637,6 +1720,7 @@ ROM_END /* Games */ GAME( 1997, rapidrvr, 0, gorgon, 0, ss23, ROT0, "Namco", "Rapid River (RD3 Ver. C)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND ) +GAME( 1997, motoxgo, 0, s23, 0, ss23, ROT0, "Namco", "Motocross Go! (MG3 Ver. A)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND ) GAME( 1997, timecrs2, 0, s23, 0, ss23, ROT0, "Namco", "Time Crisis 2 (TSS3 Ver. B)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND ) GAME( 1997, timcrs2b, timecrs2, s23, 0, ss23, ROT0, "Namco", "Time Crisis 2 (TSS2 Ver. B)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND ) GAME( 1999, 500gp, 0, ss23, 0, ss23, ROT0, "Namco", "500GP", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND ) diff --git a/src/mame/mame.mak b/src/mame/mame.mak index ca5070c315b..3dd863a426d 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -184,6 +184,7 @@ CPUS += GMS30C2216 CPUS += GMS30C2232 CPUS += I960 CPUS += H83002 +CPUS += H83344 CPUS += V810 CPUS += M37702 CPUS += M37710 diff --git a/src/mame/mamedriv.c b/src/mame/mamedriv.c index 0a31d4fea0d..1968df5a52b 100644 --- a/src/mame/mamedriv.c +++ b/src/mame/mamedriv.c @@ -862,6 +862,7 @@ const game_driver * const drivers[] = /* Namco System 23 */ DRIVER( rapidrvr ) /* (c) 1997 */ + DRIVER( motoxgo ) /* (c) 1997 */ DRIVER( timecrs2 ) /* (c) 1997 */ DRIVER( timcrs2b ) /* (c) 1997 */ DRIVER( 500gp ) /* (c) 1999 */