summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/h83002/h8ops.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/h83002/h8ops.h')
-rw-r--r--trunk/src/emu/cpu/h83002/h8ops.h4220
1 files changed, 4220 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/h83002/h8ops.h b/trunk/src/emu/cpu/h83002/h8ops.h
new file mode 100644
index 00000000000..d1ae0307481
--- /dev/null
+++ b/trunk/src/emu/cpu/h83002/h8ops.h
@@ -0,0 +1,4220 @@
+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_rotr8(h83xx_state *h8, UINT8 src);
+static UINT16 h8_rotr16(h83xx_state *h8, UINT16 src);
+static UINT32 h8_rotr32(h83xx_state *h8, UINT32 src);
+
+static UINT8 h8_rotxr8(h83xx_state *h8, UINT8 src);
+static UINT16 h8_rotxr16(h83xx_state *h8, UINT16 src);
+static UINT32 h8_rotxr32(h83xx_state *h8, UINT32 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_bild8(h83xx_state *h8, UINT8 src, UINT8 dst); // inverts and 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 void h8_band8(h83xx_state *h8, UINT8 src, UINT8 dst);
+
+static INT16 h8_mulxs8(h83xx_state *h8, INT8 src, INT8 dst);
+static INT32 h8_mulxs16(h83xx_state *h8, INT16 src, INT16 dst);
+static UINT16 h8_divxs8(h83xx_state *h8, INT8 src, INT16 dst);
+static UINT32 h8_divxs16(h83xx_state *h8, INT16 src, INT32 dst);
+
+static CPU_EXECUTE(h8)
+{
+ h83xx_state *h8 = get_safe_token(device);
+ UINT16 opcode=0;
+
+ h8_check_irqs(h8);
+
+ while ((h8->cyccnt > 0) && (!h8->h8err))
+ {
+ h8->ppc = h8->pc;
+
+ debugger_instruction_hook(device, h8->pc);
+
+ opcode = h8_readop16(h8, 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;
+ 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);
+ }
+}
+
+static void h8_group0(h83xx_state *h8, UINT16 opcode)
+{
+ switch((opcode>>8)&0xf)
+ {
+ case 0:
+ // nop
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0x1:
+ // 0140 = LDC/STC.W
+ if (opcode == 0x0140)
+ {
+ ext16 = h8_mem_read16(h8, h8->pc);
+ h8->pc+=2;
+ switch((ext16>>8) & 0xff)
+ {
+ case 0x69:
+ // ERd
+ if (ext16 & 0x80)
+ {
+ h8_setreg8(h8, (ext16>>4)&7, h8_get_ccr(h8));
+ }
+ else
+ {
+ udata8 = h8_getreg8(h8, (ext16>>4)&7);
+ h8_set_ccr(h8, udata8);
+ }
+ H8_IFETCH_TIMING(1);
+ break;
+
+ case 0x6f:
+ // @(disp, ERd)
+ sdata16=h8_mem_read16(h8, 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)
+ {
+ h8_mem_write8(address24, h8_get_ccr(h8));
+ }
+ else
+ {
+ udata8 = h8_mem_read8(address24);
+ h8_set_ccr(h8, udata8);
+ }
+ H8_BYTE_TIMING(1, sdata16);
+ break;
+
+ case 0x78:
+ // @(disp24, ERd)
+ srcreg = (ext16 >> 4) & 7;
+
+ // 6b20
+ udata16 = h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ dstreg = udata16 & 7;
+
+ address24 = h8_mem_read32(h8, h8->pc);
+ h8->pc += 4;
+ address24 += h8_getreg32(h8, srcreg);
+ address24 &= H8_ADDR_MASK;
+ if (udata16 == 0x6b20)
+ {
+ udata8 = h8_mem_read8(address24);
+ h8_set_ccr(h8, udata8);
+ }
+ else if (udata16 == 0x6ba0)
+ {
+ h8_mem_write8(address24, h8_get_ccr(h8));
+ }
+ else
+ {
+ h8->h8err = 1;
+ }
+ H8_IFETCH_TIMING(5);
+ H8_WORD_TIMING(2, address24);
+ break;
+
+ case 0x6d:
+ // stc.w ccr,-@ERd / ldc @ERd+, ccr
+ srcreg = (ext16>>4)&7;
+ if (ext16 & 0x80)
+ {
+ h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)-2);
+ address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK;
+ h8_mem_write8(address24, h8_get_ccr(h8));
+ }
+ else
+ {
+ address24 = h8_getreg32(h8, srcreg) & H8_ADDR_MASK;
+ h8_setreg32(h8, srcreg, h8_getreg32(h8, srcreg)+2);
+ udata8 = h8_mem_read8(address24);
+ h8_set_ccr(h8, udata8);
+ }
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING(1, address24);
+ H8_IOP_TIMING(2);
+ break;
+
+ case 0x6b:
+ if ((ext16&0xff) == 0x00) // 16 bit absolute
+ {
+ address24=h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ if (address24 & 0x8000)
+ address24 |= 0xff0000;
+ udata8 = h8_mem_read8(address24);
+ h8_set_ccr(h8, udata8);
+ H8_IFETCH_TIMING(4);
+ H8_BYTE_TIMING(1, address24);
+ }
+ else if ((ext16&0xff) == 0x20) // 24 bit absolute
+ {
+ address24=h8_mem_read32(h8, h8->pc);
+ h8->pc += 4;
+ udata8 = h8_mem_read8(address24);
+ h8_set_ccr(h8, udata8);
+ H8_IFETCH_TIMING(4);
+ H8_BYTE_TIMING(1, address24);
+ }
+ else if ((ext16&0xff) == 0x80) // 16 bit absolute
+ {
+ address24=h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ if (address24 & 0x8000)
+ address24 |= 0xff0000;
+ h8_mem_write8(address24, h8_get_ccr(h8));
+ H8_IFETCH_TIMING(3);
+ H8_BYTE_TIMING(1, address24);
+ }
+ else if ((ext16&0xff) == 0xa0) // 24 bit absolute
+ {
+ address24=h8_mem_read32(h8, h8->pc);
+ h8->pc += 4;
+ h8_mem_write8(address24, h8_get_ccr(h8));
+ H8_IFETCH_TIMING(4);
+ H8_BYTE_TIMING(1, address24);
+ }
+ else
+ {
+ h8->h8err = 1;
+ }
+ break;
+ }
+ break;
+ }
+
+ // 01yx 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, 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, 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, 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, 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 0x0:
+ // mov.l @aa:16, ERx
+ address24=h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ if (address24 & 0x8000)
+ address24 |= 0xff0000;
+ udata32=h8_mem_read32(h8, address24);
+ h8_mov32(h8, udata32); // flags only
+ h8_setreg32(h8, ext16 & 0x7, udata32);
+ H8_IFETCH_TIMING(4);
+ H8_WORD_TIMING(2, address24);
+ break;
+ case 0x2:
+ // mov.l @aa:24, ERx
+ address24=h8_mem_read32(h8, h8->pc);
+ h8->pc += 4;
+ udata32=h8_mem_read32(h8, 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, h8->pc);
+ h8->pc += 4;
+ udata32=h8_getreg32(h8, ext16 & 0x7);
+ h8_mov32(h8, udata32); // flags only
+ h8_mem_write32(h8, address24, udata32);
+ H8_IFETCH_TIMING(4);
+ H8_WORD_TIMING(2, address24);
+ break;
+ case 0x8:
+ // mov.l ERx, @aa:16
+ address24=h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ if (address24 & 0x8000)
+ address24 |= 0xff0000;
+ udata32=h8_getreg32(h8, ext16 & 0x7);
+ h8_mov32(h8, udata32); // flags only
+ h8_mem_write32(h8, address24, udata32);
+ H8_IFETCH_TIMING(3);
+ 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(h8, 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(h8, 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, 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(h8, address24, udata32);
+ }
+ else
+ {
+ udata32 = h8_mem_read32(h8, 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, h8->pc);
+ h8->pc += 2;
+ dstreg = udata16 & 7;
+
+ address24 = h8_mem_read32(h8, 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(h8, address24, udata32);
+ }
+ else if ( (!(ext16 & 0x80)) && ((udata16 & ~7) == 0x6b20) )
+ {
+ udata32 = h8_mem_read32(h8, 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;
+ // ldm/stm
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ ext16 = h8_mem_read16(h8, h8->pc);
+ h8->pc+=2;
+
+ // # of registers to save
+ sdata8 = ((opcode>>4) & 0xf);
+
+ // check LDM or STM
+ if (ext16 & 0x80) // STM
+ {
+ srcreg = (ext16 & 7);
+ for (int i = 0; i <= sdata8; i++)
+ {
+ h8_setreg32(h8, 7, h8_getreg32(h8, 7)-4);
+ address24 = h8_getreg32(h8, 7) & H8_ADDR_MASK;
+ udata32 = h8_getreg32(h8, srcreg+i);
+ h8_mem_write32(h8, address24, udata32);
+ H8_IFETCH_TIMING(2);
+ H8_WORD_TIMING(2, address24);
+ H8_IOP_TIMING(2);
+ }
+ }
+ else // LDM
+ {
+ srcreg = (ext16 & 7);
+ for (int i = 0; i <= sdata8; i++)
+ {
+ address24 = h8_getreg32(h8, 7) & H8_ADDR_MASK;
+ h8_setreg32(h8, 7, h8_getreg32(h8, 7)+4);
+ udata32 = h8_mem_read32(h8, address24);
+ h8_setreg32(h8, srcreg-i, udata32);
+ H8_IFETCH_TIMING(2);
+ H8_WORD_TIMING(2, address24);
+ H8_IOP_TIMING(2);
+ }
+ }
+ break;
+ case 0x8: // sleep
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xc:
+ // mulxs
+ ext16 = h8_mem_read16(h8, h8->pc);
+ h8->pc+=2;
+ if(((ext16>>8) & 0xf) == 0) // .b (8x8 = 16)
+ {
+ sdata16 = h8_getreg8(h8, ext16 & 0xf); // Rd
+ sdata8 = h8_getreg8(h8, (ext16>>4) & 0xf); // Rs
+ sdata16 = h8_mulxs8(h8, sdata8, sdata16);
+ h8_setreg16(h8, ext16 & 0xf, sdata16);
+ H8_IFETCH_TIMING(2);
+ H8_IOP_TIMING(12);
+ }
+ else if(((ext16>>8) & 0xf) == 2) // .w
+ {
+ 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, h8->pc);
+ h8->pc+=2;
+ if(((ext16>>8) & 0xf) == 0)
+ {
+ sdata16 = h8_getreg16(h8, ext16 & 0xf);
+ sdata8 = h8_getreg8(h8, (ext16>>4) & 0xf);
+ sdata16 = h8_divxs8(h8, sdata8, sdata16);
+ h8_setreg16(h8, ext16 & 0xf, sdata16);
+ H8_IFETCH_TIMING(2);
+ H8_IOP_TIMING(12);
+ }
+ 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;
+ case 0x7:
+ // ldc
+ h8_set_ccr(h8, opcode & 0xff);
+ H8_IFETCH_TIMING(1)
+ break;
+ 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:
+ // shll.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 0x4:
+ // shll.b #2, Rx
+ udata8 = h8_getreg8(h8, opcode & 0xf);
+ udata8 = h8_shll8(h8, udata8);
+ udata8 = h8_shll8(h8, udata8);
+ h8_setreg8(h8, opcode & 0xf, udata8);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0x5:
+ // shll.w #2, Rx
+ udata16 = h8_getreg16(h8, opcode & 0xf);
+ udata16 = h8_shll16(h8, udata16);
+ udata16 = h8_shll16(h8, udata16);
+ h8_setreg16(h8, opcode & 0xf, udata16);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0x7:
+ // shll.l #2, Rx
+ udata32 = h8_getreg32(h8, opcode & 0x7);
+ udata32 = h8_shll32(h8, udata32);
+ 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;
+ case 0xc:
+ // shal.b #2, Rx
+ udata8 = h8_getreg8(h8, opcode & 0xf);
+ udata8 = h8_shal8(h8, udata8);
+ udata8 = h8_shal8(h8, udata8);
+ h8_setreg8(h8, opcode & 0xf, udata8);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xd:
+ // shal.w #2, Rx
+ udata16 = h8_getreg16(h8, opcode & 0xf);
+ udata16 = h8_shal16(h8, udata16);
+ udata16 = h8_shal16(h8, udata16);
+ h8_setreg16(h8, opcode & 0xf, udata16);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xf:
+ // shal.l #2, ERx
+ udata32 = h8_getreg32(h8, opcode & 0x7);
+ udata32 = h8_shal32(h8, udata32);
+ 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 0x4:
+ // shlr.b #2, rx
+ udata8 = h8_getreg8(h8, opcode & 0xf);
+ udata8 = h8_shlr8(h8, udata8);
+ udata8 = h8_shlr8(h8, udata8);
+ h8_setreg8(h8, opcode & 0xf, udata8);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0x5:
+ // shlr.w #2, rx
+ udata16 = h8_getreg16(h8, opcode & 0xf);
+ udata16 = h8_shlr16(h8, udata16);
+ udata16 = h8_shlr16(h8, udata16);
+ h8_setreg16(h8, opcode & 0xf, udata16);
+ H8_IFETCH_TIMING(1);
+ break;
+ // shlr.l #2, rx
+ case 0x7:
+ udata32 = h8_getreg32(h8, opcode & 0x7);
+ udata32 = h8_shlr32(h8, udata32);
+ 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;
+ case 0xc:
+ // shar.b #2, rx
+ udata8 = h8_getreg8(h8, opcode & 0xf);
+ udata8 = h8_shar8(h8, udata8);
+ udata8 = h8_shar8(h8, udata8);
+ h8_setreg8(h8, opcode & 0xf, udata8);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xd:
+ // shar.w #2, rx
+ udata16 = h8_getreg16(h8, opcode & 0xf);
+ udata16 = h8_shar16(h8, udata16);
+ udata16 = h8_shar16(h8, udata16);
+ h8_setreg16(h8, opcode & 0xf, udata16);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xf:
+ // shar.l #2, rx
+ udata32 = h8_getreg32(h8, opcode & 0x7);
+ udata32 = h8_shar32(h8, udata32);
+ 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;
+ case 0xc:
+ // rotl.b #2, Rx
+ udata8 = h8_getreg8(h8, opcode & 0xf);
+ udata8 = h8_rotl8(h8, udata8);
+ udata8 = h8_rotl8(h8, udata8);
+ h8_setreg8(h8, opcode & 0xf, udata8);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xd:
+ // rotl.w #2, Rx
+ udata16 = h8_getreg16(h8, opcode & 0xf);
+ udata16 = h8_rotl16(h8, udata16);
+ udata16 = h8_rotl16(h8, udata16);
+ h8_setreg16(h8, opcode & 0xf, udata16);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xf:
+ // rotl.l #2, ERx
+ udata32 = h8_getreg32(h8, opcode & 0x7);
+ udata32 = h8_rotl32(h8, udata32);
+ 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;
+ case 0x3:
+ // rotxr.l Rx
+ udata32 = h8_getreg32(h8, opcode & 0xf);
+ udata32 = h8_rotxr32(h8, udata32);
+ h8_setreg32(h8, opcode & 0xf, udata32);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0x8:
+ // rotr.b Rx
+ udata8 = h8_getreg8(h8, opcode & 0xf);
+ udata8 = h8_rotr8(h8, udata8);
+ h8_setreg8(h8, opcode & 0xf, udata8);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0x9:
+ // rotr.w Rx
+ udata16 = h8_getreg16(h8, opcode & 0xf);
+ udata16 = h8_rotr16(h8, udata16);
+ h8_setreg16(h8, opcode & 0xf, udata16);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xb:
+ // rotr.l Rx
+ udata32 = h8_getreg32(h8, opcode & 0xf);
+ udata32 = h8_rotr32(h8, udata32);
+ h8_setreg32(h8, opcode & 0xf, udata32);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xc:
+ // rotr.b #2, Rx
+ udata8 = h8_getreg8(h8, opcode & 0xf);
+ udata8 = h8_rotr8(h8, udata8);
+ udata8 = h8_rotr8(h8, udata8);
+ h8_setreg8(h8, opcode & 0xf, udata8);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xd:
+ // rotr.w #2, Rx
+ udata16 = h8_getreg16(h8, opcode & 0xf);
+ udata16 = h8_rotr16(h8, udata16);
+ udata16 = h8_rotr16(h8, udata16);
+ h8_setreg16(h8, opcode & 0xf, udata16);
+ H8_IFETCH_TIMING(1);
+ break;
+ case 0xf:
+ // rotr.l #2, Rx
+ udata32 = h8_getreg32(h8, opcode & 0xf);
+ udata32 = h8_rotr32(h8, udata32);
+ udata32 = h8_rotr32(h8, udata32);
+ h8_setreg32(h8, opcode & 0xf, udata32);
+ 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, h8_getreg32(h8, H8_SP));
+ h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)+4);
+ // extended mode
+ h8->pc = udata32 & 0xffffff;
+ 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, h8_getreg32(h8, H8_SP), h8->pc);
+ h8->pc = h8->pc + sdata8;
+ H8_IFETCH_TIMING(2); H8_STACK_TIMING(2);
+ break;
+ case 0x6:
+ // rte
+ if(opcode == 0x5670)
+ {
+ // restore CCR
+ udata8 = (UINT8)h8_mem_read16(h8, 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->mode_8bit)
+ {
+ udata16 = h8_mem_read16(h8, h8_getreg16(h8, H8_SP));
+ h8_setreg16(h8, H8_SP, h8_getreg16(h8, H8_SP)+2);
+
+ h8->pc = udata16;
+ }
+ else
+ {
+ // extended mode restore PC
+ udata32 = h8_mem_read32(h8, h8_getreg32(h8, H8_SP));
+ h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)+4);
+
+ // extended mode
+ h8->pc = udata32;
+ }
+ // must do this last, because set_ccr() does a check_irq()
+ h8_set_ccr(h8, udata8);
+ 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, h8->pc);
+ h8->pc += 2;
+ if( h8_branch(h8, (opcode >> 4) & 0xf) == 1) h8->pc += sdata16;
+ H8_IOP_TIMING(2)
+ }
+ break;
+ case 0x9:
+ // jmp @erd
+ address24 = h8_getreg32(h8, (opcode>>4)&7);
+ address24 &= H8_ADDR_MASK;
+ h8->pc = address24;
+ H8_IFETCH_TIMING(2);
+ break;
+ // jmp @aa:24
+ case 0xa:
+ address24 = h8_mem_read32(h8, h8->pc-2);
+ address24 &= H8_ADDR_MASK;
+ h8->pc = address24;
+ 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, h8->pc);
+ h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4);
+ h8_mem_write32(h8, h8_getreg32(h8, H8_SP), h8->pc+2);
+ h8->pc += sdata16 + 2;
+ 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, h8_getreg32(h8, H8_SP), h8->pc);
+ h8->pc = address24;
+ H8_STACK_TIMING(2);
+ H8_IOP_TIMING(2);
+ break;
+ case 0xe:
+ // jsr @aa:24
+ address24=h8_mem_read32(h8, 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, h8_getreg32(h8, H8_SP), h8->pc+2);
+ h8->pc = address24;
+ 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(h8, 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(h8, 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, 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, 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 0x3: // bclr #x, @imm:24
+ address24=h8_mem_read32(h8, h8->pc);
+ h8->pc += 4;
+ udata16 = h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ switch ((udata16 >> 8) & 0xff)
+ {
+ case 0x60 : // bset Rn, @abs:24
+ udata8 = h8_mem_read8(address24);
+ udata8 = h8_bset8(h8, h8_getreg8(h8, (udata16 >> 4) & 0xf), udata8);
+ h8_mem_write8(address24, udata8);
+ H8_BYTE_TIMING(2, address24);
+ break;
+ case 0x61 : // bnot Rn, @abs:24
+ udata8 = h8_mem_read8(address24);
+ udata8 = h8_bnot8(h8, h8_getreg8(h8, (udata16 >> 4) & 0xf), udata8);
+ h8_mem_write8(address24, udata8);
+ H8_BYTE_TIMING(2, address24);
+ break;
+ case 0x62 : // bclr Rn, @abs:24
+ udata8 = h8_mem_read8(address24);
+ udata8 = h8_bclr8(h8, h8_getreg8(h8, (udata16 >> 4) & 0xf), udata8);
+ h8_mem_write8(address24, udata8);
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING(2, address24);
+ break;
+ case 0x63 : // btst Rn, @abs:24
+ udata8 = h8_mem_read8(address24);
+ h8_btst8(h8, h8_getreg8(h8, (udata16 >> 4) & 0xf), udata8);
+ h8_mem_write8(address24, udata8);
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING(2, address24);
+ break;
+ case 0x70 : // bset #imm, @abs:24
+ udata8 = h8_mem_read8(address24);
+ udata8 = h8_bset8(h8, (udata16 >> 4) & 7, udata8);
+ h8_mem_write8(address24, udata8);
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING(2, address24);
+ break;
+ case 0x71 : // bnot #imm, @abs:24
+ udata8 = h8_mem_read8(address24);
+ udata8 = h8_bnot8(h8, (udata16 >> 4) & 7, udata8);
+ h8_mem_write8(address24, udata8);
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING(2, address24);
+ break;
+ case 0x72 : // bclr #imm, @abs:24
+ udata8 = h8_mem_read8(address24);
+ udata8 = h8_bclr8(h8, (udata16 >> 4) & 7, udata8);
+ h8_mem_write8(address24, udata8);
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING(2, address24);
+ break;
+ case 0x73 : // btst #imm, @abs:24
+ udata8 = h8_mem_read8(address24);
+ h8_btst8(h8, (udata16 >> 4) & 7, udata8);
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING(1, address24);
+ break;
+ }
+ break;
+ case 0x8:
+ sdata16=h8_mem_read16(h8, 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, 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, h8->pc);
+ address24 = sdata16;
+ address24 &= H8_ADDR_MASK;
+ h8->pc += 2;
+ udata16 = h8_mem_read16(h8, 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, h8->pc);
+ h8->pc += 4;
+ udata16=h8_mem_read16(h8, 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, 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(h8, address24, udata16);
+ H8_IFETCH_TIMING(2);
+ H8_WORD_TIMING(1, address24);
+ break;
+ case 0xa: // pass
+ address24=h8_mem_read32(h8, h8->pc);
+ h8->pc += 4;
+ udata16=h8_getreg16(h8, opcode & 0xf);
+ h8_mov16(h8, udata16); // flags only
+ h8_mem_write16(h8, 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(h8, 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(h8, 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, 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, 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(h8, address24, udata16);
+ }
+ else
+ {
+ udata16 = h8_mem_read16(h8, 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)&0x7)
+ {
+ case 0: udata8 = h8_bset8(h8, bitnr, udata8); h8_setreg8(h8, dstreg, udata8); H8_IFETCH_TIMING(1); break;
+ case 1: udata8 = h8_bnot8(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 4: h8_bor8(h8, bitnr, udata8); H8_IFETCH_TIMING(1); break;
+ case 5: h8_bxor8(h8, bitnr, udata8); H8_IFETCH_TIMING(1); break;
+ case 6: h8_band8(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)
+ {
+ case 7: h8_bild8(h8, bitnr, udata8); H8_IFETCH_TIMING(1); break;
+ 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, h8->pc);
+ h8->pc += 2;
+ udata32 = h8_mem_read32(h8, 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(h8, 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(h8, 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, 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, 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:
+ switch (opcode & 0xff)
+ {
+ case 0xd4: // eepmov.w
+ {
+ ext16 = h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ if (ext16 != 0x598f)
+ {
+ logerror("H8/3xx: Unk. eepmov form\n");
+ h8->h8err = 1;
+ }
+ else
+ {
+ UINT16 cnt = h8_getreg16(h8, 4);
+
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING((2*cnt)+2, h8->regs[5]);
+
+ 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);
+ }
+ }
+ break;
+
+ case 0x5c: // eepmov.b
+ {
+ ext16 = h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ if (ext16 != 0x598f)
+ {
+ logerror("H8/3xx: Unk. eepmov form\n");
+ h8->h8err = 1;
+ }
+ else
+ {
+ UINT8 cnt = h8_getreg8(h8, 8+4);
+
+ H8_IFETCH_TIMING(2);
+ H8_BYTE_TIMING((2*cnt)+2, h8->regs[5]);
+
+ while (cnt > 0)
+ {
+ h8_mem_write8(h8->regs[6], h8_mem_read8(h8->regs[5]));
+ h8->regs[5]++;
+ h8->regs[6]++;
+ cnt--;
+ }
+ h8_setreg8(h8, 8+4, 0);
+ }
+ }
+ break;
+
+ default:
+ 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, 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;
+ // bld.b #imm, @Rn
+ case 0x77:
+ udata16 = h8_mem_read16(h8, h8->pc);
+ h8->pc += 2;
+ dstreg = (opcode>>4) & 7;
+ h8_bld8(h8, (udata16>>4) & 7, h8_mem_read8(h8_getreg16(h8, dstreg)));
+ H8_IFETCH_TIMING(1);
+ H8_WORD_TIMING(1, h8_getreg16(h8, dstreg));
+ break;
+
+
+
+
+ default:
+ h8->h8err=1;
+ }
+ }
+ break;
+ case 0xd:
+ ext16 = h8_mem_read16(h8, 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, 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 0x71:
+ bitnr = (ext16>>4)&7;
+ if(ext16&0x80) h8->h8err = 1;
+ udata8 = h8_bnot8(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)
+ {
+ h8_bist8(h8, bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24);
+ }
+ 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)
+ {
+ h8_bild8(h8, bitnr, udata8); H8_IFETCH_TIMING(2); H8_BYTE_TIMING(2, address24);
+ }
+ 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<<bit)) == 0)
+ {
+ h8->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 void h8_bild8(h83xx_state *h8, UINT8 bit, UINT8 dst)
+{
+ // load inverted 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<<src);
+}
+
+static UINT8 h8_bst8(h83xx_state *h8, UINT8 src, UINT8 dst)
+{
+ UINT8 res;
+
+ // store carry flag in bit position
+ if(h8->h8cflag == 1)
+ {
+ res = dst | (1<<src);
+ }
+ else
+ {
+ res = dst & ~(1<<src); // mask off
+ }
+ return res;
+}
+
+static UINT8 h8_bist8(h83xx_state *h8, UINT8 src, UINT8 dst)
+{
+ UINT8 res;
+
+ // store inverse of carry flag in bit position
+ if(h8->h8cflag == 0)
+ {
+ res = dst | (1<<src);
+ }
+ else
+ {
+ res = dst & ~(1<<src); // mask off
+ }
+ return res;
+}
+
+static UINT8 h8_bset8(h83xx_state *h8, UINT8 src, UINT8 dst)
+{
+ // pass
+ UINT8 res;
+ res = dst | (1<<src);
+ return res;
+}
+
+// does not affect result, res in C flag only
+static void h8_bor8(h83xx_state *h8, UINT8 src, UINT8 dst)
+{
+ dst >>= src;
+ dst &= 0x1;
+ h8->h8cflag |= dst;
+}
+
+// does not affect result, res in C flag only
+static void h8_band8(h83xx_state *h8, UINT8 src, UINT8 dst)
+{
+ dst >>= src;
+ dst &= 0x1;
+ h8->h8cflag &= dst;
+}
+
+// does not affect result, res in C flag only
+static void h8_bxor8(h83xx_state *h8, UINT8 src, UINT8 dst)
+{
+ dst >>= src;
+ dst &= 0x1;
+ h8->h8cflag ^= dst;
+}
+
+static UINT8 h8_bclr8(h83xx_state *h8, UINT8 src, UINT8 dst)
+{
+ // pass
+ UINT8 res;
+ res = dst & ~(1<<src);
+ return res;
+}
+
+static INT8 h8_neg8(h83xx_state *h8, INT8 src)
+{
+ INT8 res;
+
+ if((UINT8)src == 0x80)
+ {
+ // overflow !
+ h8->h8vflag = 1;
+ res = (INT8)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 = (INT16)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 UINT8 h8_rotr8(h83xx_state *h8, UINT8 src)
+{
+ UINT8 res;
+
+ // rotate right, not through carry
+ res = src>>1;
+ if (src & 1) 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_rotr16(h83xx_state *h8, UINT16 src)
+{
+ UINT16 res;
+
+ // rotate right, not through carry
+ res = src>>1;
+ if (src & 1) 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 UINT32 h8_rotr32(h83xx_state *h8, UINT32 src)
+{
+ UINT32 res;
+
+ // rotate right, not through carry
+ res = src>>1;
+ if (src & 1) res |= 0x80000000; // put cflag in upper bit
+ h8->h8cflag = 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 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 UINT32 h8_rotxr32(h83xx_state *h8, UINT32 src)
+{
+ UINT32 res;
+
+ // rotate through carry right
+ res = src>>1;
+ if(h8->h8cflag)res |= 0x80000000; // put cflag in upper bit
+ h8->h8cflag = 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_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 INT16 h8_mulxs8(h83xx_state *h8, INT8 src, INT8 dst)
+{
+ INT16 res;
+
+ res = (INT16)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 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 UINT16 h8_divxs8(h83xx_state *h8, INT8 src, INT16 dst)
+{
+ // NOT tested !
+ UINT16 res,r1,r2;
+ INT8 remainder, quotient;
+
+ if(src!=0)
+ {
+ quotient = dst/src;
+ h8->h8zflag = 0;
+ }
+ else
+ {
+ quotient = 0;
+ h8->h8zflag = 1;
+ }
+ remainder = dst%src;
+
+ r1=*(&quotient);
+ r2=*(&remainder);
+ res=(r2<<8)|r1;
+
+ h8->h8nflag = (quotient<0)?1: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=*(&quotient);
+ 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;
+}
+