diff options
Diffstat (limited to 'trunk/src/emu/cpu/h6280/h6280ops.h')
-rw-r--r-- | trunk/src/emu/cpu/h6280/h6280ops.h | 1370 |
1 files changed, 1370 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/h6280/h6280ops.h b/trunk/src/emu/cpu/h6280/h6280ops.h new file mode 100644 index 00000000000..c331cac0a00 --- /dev/null +++ b/trunk/src/emu/cpu/h6280/h6280ops.h @@ -0,0 +1,1370 @@ +/***************************************************************************** + + h6280ops.h - Addressing modes and opcode macros for the Hu6820 cpu + + Copyright Bryan McPhail, mish@tendril.co.uk + + This source code is based (with permission!) on the 6502 emulator by + Juergen Buchmueller. It is released as part of the Mame emulator project. + Let me know if you intend to use this code in any other project. + +******************************************************************************/ + +/* 6280 flags */ +#define _fC 0x01 +#define _fZ 0x02 +#define _fI 0x04 +#define _fD 0x08 +#define _fB 0x10 +#define _fT 0x20 +#define _fV 0x40 +#define _fN 0x80 + +/* some shortcuts for improved readability */ +#define A cpustate->a +#define X cpustate->x +#define Y cpustate->y +#define P cpustate->p +#define S cpustate->sp.b.l + +#define TRANSLATED(addr) ((cpustate->mmr[(addr)>>13&7] << 13) | ((addr)&0x1fff)) +#define H6280_CYCLES(cyc) \ + { \ + cpustate->ICount -= ((cyc) * cpustate->clocks_per_cycle); \ + cpustate->timer_value -= ((cyc) * cpustate->clocks_per_cycle); \ + } + +#if LAZY_FLAGS + +#define NZ cpustate->NZ +#define SET_NZ(n) \ + P &= ~_fT; \ + NZ = ((n & _fN) << 8) | n + +#else + +#define SET_NZ(n) \ + P = (P & ~(_fN|_fT|_fZ)) | \ + (n & _fN) | \ + ((n == 0) ? _fZ : 0) + +#endif + +#define EAL cpustate->ea.b.l +#define EAH cpustate->ea.b.h +#define EAW cpustate->ea.w.l +#define EAD cpustate->ea.d + +#define ZPL cpustate->zp.b.l +#define ZPH cpustate->zp.b.h +#define ZPW cpustate->zp.w.l +#define ZPD cpustate->zp.d + +#define PCL cpustate->pc.b.l +#define PCH cpustate->pc.b.h +#define PCW cpustate->pc.w.l +#define PCD cpustate->pc.d + +#define CLEAR_T \ + P &= ~_fT; + +#define DO_INTERRUPT(vector) \ +{ \ + H6280_CYCLES(7); /* 7 cycles for an int */ \ + PUSH(PCH); \ + PUSH(PCL); \ + COMPOSE_P(0,_fB); \ + PUSH(P); \ + P = (P & ~_fD) | _fI; /* knock out D and set I flag */ \ + PCL = RDMEM(cpustate, vector); \ + PCH = RDMEM(cpustate, (vector+1)); \ +} + +#define CHECK_AND_TAKE_IRQ_LINES \ + if ( cpustate->nmi_state != CLEAR_LINE ) { \ + cpustate->nmi_state = CLEAR_LINE; \ + DO_INTERRUPT(H6280_NMI_VEC); \ + } \ + else if( !(P & _fI) ) \ + { \ + if ( cpustate->irq_state[2] != CLEAR_LINE && \ + !(cpustate->irq_mask & 0x4) ) \ + { \ + DO_INTERRUPT(H6280_TIMER_VEC); \ + } else \ + if ( cpustate->irq_state[0] != CLEAR_LINE && \ + !(cpustate->irq_mask & 0x2) ) \ + { \ + DO_INTERRUPT(H6280_IRQ1_VEC); \ + (*cpustate->irq_callback)(cpustate->device, 0); \ + } else \ + if ( cpustate->irq_state[1] != CLEAR_LINE && \ + !(cpustate->irq_mask & 0x1) ) \ + { \ + DO_INTERRUPT(H6280_IRQ2_VEC); \ + (*cpustate->irq_callback)(cpustate->device, 1); \ + } \ + } + +#define CHECK_IRQ_LINES \ + if ( ! cpustate->irq_pending ) \ + cpustate->irq_pending = 2; + +/*************************************************************** + * CHECK_VDC_VCE_PENALTY + * The CPU inserts 1 clock delay when accessing the VDC or VCE + * area. + ***************************************************************/ +#define CHECK_VDC_VCE_PENALTY(addr) \ + if ( ( TRANSLATED(addr) & 0x1FF800 ) == 0x1FE000 ) { \ + H6280_CYCLES(1); \ + } + +/*************************************************************** + * RDMEM read memory + ***************************************************************/ +INLINE UINT8 RDMEM(h6280_Regs* cpustate, offs_t addr) { + CHECK_VDC_VCE_PENALTY(addr); + return cpustate->program->read_byte(TRANSLATED(addr)); +} + +/*************************************************************** + * WRMEM write memory + ***************************************************************/ +INLINE void WRMEM(h6280_Regs* cpustate, offs_t addr, UINT8 data) { + CHECK_VDC_VCE_PENALTY(addr); + cpustate->program->write_byte(TRANSLATED(addr),data); +} + +/*************************************************************** + * RDMEMZ read memory - zero page + ***************************************************************/ +#define RDMEMZ(addr) \ + cpustate->program->read_byte((cpustate->mmr[1] << 13) | ((addr)&0x1fff)); + +/*************************************************************** + * WRMEMZ write memory - zero page + ***************************************************************/ +#define WRMEMZ(addr,data) \ + cpustate->program->write_byte((cpustate->mmr[1] << 13) | ((addr)&0x1fff),data); + +/*************************************************************** + * RDMEMW read word from memory + ***************************************************************/ +#define RDMEMW(addr) \ + cpustate->program->read_byte(TRANSLATED(addr)) \ +| ( cpustate->program->read_byte(TRANSLATED(addr+1)) << 8 ) + +/*************************************************************** + * RDZPWORD read a word from a zero page address + ***************************************************************/ +#define RDZPWORD(addr) \ + ((addr&0xff)==0xff) ? \ + cpustate->program->read_byte((cpustate->mmr[1] << 13) | ((addr)&0x1fff)) \ + +(cpustate->program->read_byte((cpustate->mmr[1] << 13) | ((addr-0xff)&0x1fff))<<8) : \ + cpustate->program->read_byte((cpustate->mmr[1] << 13) | ((addr)&0x1fff)) \ + +(cpustate->program->read_byte((cpustate->mmr[1] << 13) | ((addr+1)&0x1fff))<<8) + + +/*************************************************************** + * push a register onto the stack + ***************************************************************/ +#define PUSH(Rg) cpustate->program->write_byte((cpustate->mmr[1] << 13) | cpustate->sp.d,Rg); S-- + +/*************************************************************** + * pull a register from the stack + ***************************************************************/ +#define PULL(Rg) S++; Rg = cpustate->program->read_byte((cpustate->mmr[1] << 13) | cpustate->sp.d) + +/*************************************************************** + * RDOP read an opcode + ***************************************************************/ +#define RDOP() \ + cpustate->direct->read_decrypted_byte(TRANSLATED(PCW)) + +/*************************************************************** + * RDOPARG read an opcode argument + ***************************************************************/ +#define RDOPARG() \ + cpustate->direct->read_raw_byte(TRANSLATED(PCW)) + +/*************************************************************** + * BRA branch relative + ***************************************************************/ +#define BRA(cond) \ + CLEAR_T; \ + if (cond) \ + { \ + H6280_CYCLES(4); \ + tmp = RDOPARG(); \ + PCW++; \ + EAW = PCW + (signed char)tmp; \ + PCD = EAD; \ + } \ + else \ + { \ + PCW++; \ + H6280_CYCLES(2); \ + } + +/*************************************************************** + * + * Helper macros to build the effective address + * + ***************************************************************/ + +/*************************************************************** + * EA = zero page address + ***************************************************************/ +#define EA_ZPG \ + ZPL = RDOPARG(); \ + PCW++; \ + EAD = ZPD + +/*************************************************************** + * EA = zero page address - T flag + ***************************************************************/ +#define EA_TFLG \ + ZPL = X; \ + EAD = ZPD + +/*************************************************************** + * EA = zero page address + X + ***************************************************************/ +#define EA_ZPX \ + ZPL = RDOPARG() + X; \ + PCW++; \ + EAD = ZPD + +/*************************************************************** + * EA = zero page address + Y + ***************************************************************/ +#define EA_ZPY \ + ZPL = RDOPARG() + Y; \ + PCW++; \ + EAD = ZPD + +/*************************************************************** + * EA = absolute address + ***************************************************************/ +#define EA_ABS \ + EAL = RDOPARG(); \ + PCW++; \ + EAH = RDOPARG(); \ + PCW++ + +/*************************************************************** + * EA = absolute address + X + ***************************************************************/ +#define EA_ABX \ + EA_ABS; \ + EAW += X + +/*************************************************************** + * EA = absolute address + Y + ***************************************************************/ +#define EA_ABY \ + EA_ABS; \ + EAW += Y + +/*************************************************************** + * EA = zero page indirect (65c02 pre indexed w/o X) + ***************************************************************/ +#define EA_ZPI \ + ZPL = RDOPARG(); \ + PCW++; \ + EAD = RDZPWORD(ZPD) + +/*************************************************************** + * EA = zero page + X indirect (pre indexed) + ***************************************************************/ +#define EA_IDX \ + ZPL = RDOPARG() + X; \ + PCW++; \ + EAD = RDZPWORD(ZPD); + +/*************************************************************** + * EA = zero page indirect + Y (post indexed) + ***************************************************************/ +#define EA_IDY \ + ZPL = RDOPARG(); \ + PCW++; \ + EAD = RDZPWORD(ZPD); \ + EAW += Y + +/*************************************************************** + * EA = indirect (only used by JMP) + ***************************************************************/ +#define EA_IND \ + EA_ABS; \ + tmp = RDMEM(cpustate, EAD); \ + EAD++; \ + EAH = RDMEM(cpustate, EAD); \ + EAL = tmp + +/*************************************************************** + * EA = indirect plus x (only used by JMP) + ***************************************************************/ +#define EA_IAX \ + EA_ABS; \ + EAD+=X; \ + tmp = RDMEM(cpustate, EAD); \ + EAD++; \ + EAH = RDMEM(cpustate, EAD); \ + EAL = tmp + +/* read a value into tmp */ +#define RD_IMM tmp = RDOPARG(); PCW++ +#define RD_IMM2 tmp2 = RDOPARG(); PCW++ +#define RD_ACC tmp = A +#define RD_ZPG EA_ZPG; tmp = RDMEMZ(EAD) +#define RD_ZPX EA_ZPX; tmp = RDMEMZ(EAD) +#define RD_ZPY EA_ZPY; tmp = RDMEMZ(EAD) +#define RD_ABS EA_ABS; tmp = RDMEM(cpustate, EAD) +#define RD_ABX EA_ABX; tmp = RDMEM(cpustate, EAD) +#define RD_ABY EA_ABY; tmp = RDMEM(cpustate, EAD) +#define RD_ZPI EA_ZPI; tmp = RDMEM(cpustate, EAD) +#define RD_IDX EA_IDX; tmp = RDMEM(cpustate, EAD) +#define RD_IDY EA_IDY; tmp = RDMEM(cpustate, EAD) +#define RD_TFL EA_TFLG; tflagtemp = RDMEMZ(EAD) + +/* write a value from tmp */ +#define WR_ZPG EA_ZPG; WRMEMZ(EAD, tmp) +#define WR_ZPX EA_ZPX; WRMEMZ(EAD, tmp) +#define WR_ZPY EA_ZPY; WRMEMZ(EAD, tmp) +#define WR_ABS EA_ABS; WRMEM(cpustate, EAD, tmp) +#define WR_ABX EA_ABX; WRMEM(cpustate, EAD, tmp) +#define WR_ABY EA_ABY; WRMEM(cpustate, EAD, tmp) +#define WR_ZPI EA_ZPI; WRMEM(cpustate, EAD, tmp) +#define WR_IDX EA_IDX; WRMEM(cpustate, EAD, tmp) +#define WR_IDY EA_IDY; WRMEM(cpustate, EAD, tmp) + +/* write back a value from tmp to the last EA */ +#define WB_ACC A = (UINT8)tmp; +#define WB_EA WRMEM(cpustate, EAD, tmp) +#define WB_EAZ WRMEMZ(EAD, tmp) +#define WB_TFL WRMEMZ(EAD, tflagtemp) + +/*************************************************************** + * + * Macros to emulate the 6280 opcodes + * + ***************************************************************/ + +/*************************************************************** + * compose the real flag register by + * including N and Z and set any + * SET and clear any CLR bits also + ***************************************************************/ +#if LAZY_FLAGS + +#define COMPOSE_P(SET,CLR) \ + P = (P & ~(_fN | _fZ | CLR)) | \ + (NZ >> 8) | \ + ((NZ & 0xff) ? 0 : _fZ) | \ + SET + +#else + +#define COMPOSE_P(SET,CLR) \ + P = (P & ~CLR) | SET + +#endif + +/* 6280 ******************************************************** + * ADC Add with carry + ***************************************************************/ +#define TADC \ + { \ + int tflagtemp; \ + CLEAR_T; \ + RD_TFL; \ + if (P & _fD) \ + { \ + int c = (P & _fC); \ + int lo = (tflagtemp & 0x0f) + (tmp & 0x0f) + c; \ + int hi = (tflagtemp & 0xf0) + (tmp & 0xf0); \ + P &= ~_fC; \ + if (lo > 0x09) \ + { \ + hi += 0x10; \ + lo += 0x06; \ + } \ + if (hi > 0x90) \ + hi += 0x60; \ + if (hi & 0xff00) \ + P |= _fC; \ + tflagtemp = (lo & 0x0f) + (hi & 0xf0); \ + H6280_CYCLES(1); \ + } \ + else \ + { \ + int c = (P & _fC); \ + int sum = tflagtemp + tmp + c; \ + P &= ~(_fV | _fC); \ + if (~(tflagtemp^tmp) & (tflagtemp^sum) & _fN) \ + P |= _fV; \ + if (sum & 0xff00) \ + P |= _fC; \ + tflagtemp = (UINT8) sum; \ + } \ + SET_NZ(tflagtemp); \ + WB_TFL; \ + H6280_CYCLES(3); \ + } + + +#define ADC \ + if(P & _fT) \ + TADC \ + else { \ + if (P & _fD) \ + { \ + int c = (P & _fC); \ + int lo = (A & 0x0f) + (tmp & 0x0f) + c; \ + int hi = (A & 0xf0) + (tmp & 0xf0); \ + P &= ~_fC; \ + if (lo > 0x09) \ + { \ + hi += 0x10; \ + lo += 0x06; \ + } \ + if (hi > 0x90) \ + hi += 0x60; \ + if (hi & 0xff00) \ + P |= _fC; \ + A = (lo & 0x0f) + (hi & 0xf0); \ + H6280_CYCLES(1); \ + } \ + else \ + { \ + int c = (P & _fC); \ + int sum = A + tmp + c; \ + P &= ~(_fV | _fC); \ + if (~(A^tmp) & (A^sum) & _fN) \ + P |= _fV; \ + if (sum & 0xff00) \ + P |= _fC; \ + A = (UINT8) sum; \ + } \ + SET_NZ(A); \ + } + +/* 6280 ******************************************************** + * AND Logical and + ***************************************************************/ +#define TAND \ + { \ + int tflagtemp; \ + CLEAR_T; \ + RD_TFL; \ + tflagtemp = (UINT8)(tflagtemp & tmp); \ + WB_TFL; \ + SET_NZ(tflagtemp); \ + H6280_CYCLES(3); \ + } + +#define AND \ + if(P & _fT) \ + TAND \ + else { \ + A = (UINT8)(A & tmp); \ + SET_NZ(A); \ + } + +/* 6280 ******************************************************** + * ASL Arithmetic shift left + ***************************************************************/ +#define ASL \ + CLEAR_T; \ + P = (P & ~_fC) | ((tmp >> 7) & _fC); \ + tmp = (UINT8)(tmp << 1); \ + SET_NZ(tmp) + +/* 6280 ******************************************************** + * BBR Branch if bit is reset + ***************************************************************/ +#define BBR(bit) \ + BRA(!(tmp & (1<<bit))) + +/* 6280 ******************************************************** + * BBS Branch if bit is set + ***************************************************************/ +#define BBS(bit) \ + BRA(tmp & (1<<bit)) + +/* 6280 ******************************************************** + * BCC Branch if carry clear + ***************************************************************/ +#define BCC BRA(!(P & _fC)) + +/* 6280 ******************************************************** + * BCS Branch if carry set + ***************************************************************/ +#define BCS BRA(P & _fC) + +/* 6280 ******************************************************** + * BEQ Branch if equal + ***************************************************************/ +#if LAZY_FLAGS +#define BEQ BRA(!(NZ & 0xff)) +#else +#define BEQ BRA(P & _fZ) +#endif + +/* 6280 ******************************************************** + * BIT Bit test + ***************************************************************/ +#undef BIT +#define BIT \ + P = (P & ~(_fN|_fV|_fT|_fZ)) \ + | ((tmp&0x80) ? _fN:0) \ + | ((tmp&0x40) ? _fV:0) \ + | ((tmp&A) ? 0:_fZ) + +/* 6280 ******************************************************** + * BMI Branch if minus + ***************************************************************/ +#if LAZY_FLAGS +#define BMI BRA(NZ & 0x8000) +#else +#define BMI BRA(P & _fN) +#endif + +/* 6280 ******************************************************** + * BNE Branch if not equal + ***************************************************************/ +#if LAZY_FLAGS +#define BNE BRA(NZ & 0xff) +#else +#define BNE BRA(!(P & _fZ)) +#endif + +/* 6280 ******************************************************** + * BPL Branch if plus + ***************************************************************/ +#if LAZY_FLAGS +#define BPL BRA(!(NZ & 0x8000)) +#else +#define BPL BRA(!(P & _fN)) +#endif + +/* 6280 ******************************************************** + * BRK Break + * increment PC, push PC hi, PC lo, flags (with B bit set), + * set I flag, reset D flag and jump via IRQ vector + ***************************************************************/ +#define BRK \ + logerror("BRK %04x\n",PCW); \ + CLEAR_T; \ + PCW++; \ + PUSH(PCH); \ + PUSH(PCL); \ + PUSH(P); \ + P = (P & ~_fD) | _fI; \ + PCL = RDMEM(cpustate, H6280_IRQ2_VEC); \ + PCH = RDMEM(cpustate, H6280_IRQ2_VEC+1); \ + +/* 6280 ******************************************************** + * BSR Branch to subroutine + ***************************************************************/ +#define BSR \ + PUSH(PCH); \ + PUSH(PCL); \ + H6280_CYCLES(4); /* 4 cycles here, 4 in BRA */ \ + BRA(1) + +/* 6280 ******************************************************** + * BVC Branch if overflow clear + ***************************************************************/ +#define BVC BRA(!(P & _fV)) + +/* 6280 ******************************************************** + * BVS Branch if overflow set + ***************************************************************/ +#define BVS BRA(P & _fV) + +/* 6280 ******************************************************** + * CLA Clear accumulator + ***************************************************************/ +#define CLA \ + CLEAR_T; \ + A = 0 + +/* 6280 ******************************************************** + * CLC Clear carry flag + ***************************************************************/ +#define CLC \ + CLEAR_T; \ + P &= ~_fC + +/* 6280 ******************************************************** + * CLD Clear decimal flag + ***************************************************************/ +#define CLD \ + CLEAR_T; \ + P &= ~_fD + +/* 6280 ******************************************************** + * CLI Clear interrupt flag + ***************************************************************/ +#define CLI \ + CLEAR_T; \ + if( P & _fI ) \ + { \ + P &= ~_fI; \ + CHECK_IRQ_LINES; \ + } + + +/* 6280 ******************************************************** + * CLV Clear overflow flag + ***************************************************************/ +#define CLV \ + CLEAR_T; \ + P &= ~_fV + +/* 6280 ******************************************************** + * CLX Clear index X + ***************************************************************/ +#define CLX \ + CLEAR_T; \ + X = 0 + +/* 6280 ******************************************************** + * CLY Clear index Y + ***************************************************************/ +#define CLY \ + CLEAR_T; \ + Y = 0 + +/* 6280 ******************************************************** + * CMP Compare accumulator + ***************************************************************/ +#define CMP \ + CLEAR_T; \ + P &= ~_fC; \ + if (A >= tmp) \ + P |= _fC; \ + SET_NZ((UINT8)(A - tmp)) + +/* 6280 ******************************************************** + * CPX Compare index X + ***************************************************************/ +#define CPX \ + CLEAR_T; \ + P &= ~_fC; \ + if (X >= tmp) \ + P |= _fC; \ + SET_NZ((UINT8)(X - tmp)) + +/* 6280 ******************************************************** + * CPY Compare index Y + ***************************************************************/ +#define CPY \ + CLEAR_T; \ + P &= ~_fC; \ + if (Y >= tmp) \ + P |= _fC; \ + SET_NZ((UINT8)(Y - tmp)) + +/* 6280 ******************************************************** + * DEA Decrement accumulator + ***************************************************************/ +#define DEA \ + CLEAR_T; \ + A = (UINT8)(A - 1); \ + SET_NZ(A) + +/* 6280 ******************************************************** + * DEC Decrement memory + ***************************************************************/ +#define DEC \ + CLEAR_T; \ + tmp = (UINT8)(tmp-1); \ + SET_NZ(tmp) + +/* 6280 ******************************************************** + * DEX Decrement index X + ***************************************************************/ +#define DEX \ + CLEAR_T; \ + X = (UINT8)(X - 1); \ + SET_NZ(X) + +/* 6280 ******************************************************** + * DEY Decrement index Y + ***************************************************************/ +#define DEY \ + CLEAR_T; \ + Y = (UINT8)(Y - 1); \ + SET_NZ(Y) + +/* 6280 ******************************************************** + * EOR Logical exclusive or + ***************************************************************/ +#define TEOR \ + { \ + int tflagtemp; \ + CLEAR_T; \ + RD_TFL; \ + tflagtemp = (UINT8)(tflagtemp ^ tmp); \ + WB_TFL; \ + SET_NZ(tflagtemp); \ + H6280_CYCLES(3); \ + } + +#define EOR \ + if(P & _fT) \ + TEOR \ + else { \ + A = (UINT8)(A ^ tmp); \ + SET_NZ(A); \ + } + +/* 6280 ******************************************************** + * INA Increment accumulator + ***************************************************************/ +#define INA \ + CLEAR_T; \ + A = (UINT8)(A + 1); \ + SET_NZ(A) + +/* 6280 ******************************************************** + * INC Increment memory + ***************************************************************/ +#define INC \ + CLEAR_T; \ + tmp = (UINT8)(tmp+1); \ + SET_NZ(tmp) + +/* 6280 ******************************************************** + * INX Increment index X + ***************************************************************/ +#define INX \ + CLEAR_T; \ + X = (UINT8)(X + 1); \ + SET_NZ(X) + +/* 6280 ******************************************************** + * INY Increment index Y + ***************************************************************/ +#define INY \ + CLEAR_T; \ + Y = (UINT8)(Y + 1); \ + SET_NZ(Y) + +/* 6280 ******************************************************** + * JMP Jump to address + * set PC to the effective address + ***************************************************************/ +#define JMP \ + CLEAR_T; \ + PCD = EAD; \ + +/* 6280 ******************************************************** + * JSR Jump to subroutine + * decrement PC (sic!) push PC hi, push PC lo and set + * PC to the effective address + ***************************************************************/ +#define JSR \ + CLEAR_T; \ + PCW--; \ + PUSH(PCH); \ + PUSH(PCL); \ + PCD = EAD; \ + +/* 6280 ******************************************************** + * LDA Load accumulator + ***************************************************************/ +#define LDA \ + CLEAR_T; \ + A = (UINT8)tmp; \ + SET_NZ(A) + +/* 6280 ******************************************************** + * LDX Load index X + ***************************************************************/ +#define LDX \ + CLEAR_T; \ + X = (UINT8)tmp; \ + SET_NZ(X) + +/* 6280 ******************************************************** + * LDY Load index Y + ***************************************************************/ +#define LDY \ + CLEAR_T; \ + Y = (UINT8)tmp; \ + SET_NZ(Y) + +/* 6280 ******************************************************** + * LSR Logic shift right + * 0 -> [7][6][5][4][3][2][1][0] -> C + ***************************************************************/ +#define LSR \ + CLEAR_T; \ + P = (P & ~_fC) | (tmp & _fC); \ + tmp = (UINT8)tmp >> 1; \ + SET_NZ(tmp) + +/* 6280 ******************************************************** + * NOP No operation + ***************************************************************/ +#define NOP CLEAR_T; + +/* 6280 ******************************************************** + * ORA Logical inclusive or + ***************************************************************/ + +#define TORA \ + { \ + int tflagtemp; \ + CLEAR_T; \ + RD_TFL; \ + tflagtemp = (UINT8)(tflagtemp | tmp); \ + WB_TFL; \ + SET_NZ(tflagtemp); \ + H6280_CYCLES(3); \ + } + +#define ORA \ + if(P & _fT) \ + TORA \ + else { \ + A = (UINT8)(A | tmp); \ + SET_NZ(A); \ + } + +/* 6280 ******************************************************** + * PHA Push accumulator + ***************************************************************/ +#define PHA \ + CLEAR_T; \ + PUSH(A) + +/* 6280 ******************************************************** + * PHP Push processor status (flags) + ***************************************************************/ +#define PHP \ + CLEAR_T; \ + COMPOSE_P(0,0); \ + PUSH(P) + +/* 6280 ******************************************************** + * PHX Push index X + ***************************************************************/ +#define PHX \ + CLEAR_T; \ + PUSH(X) + +/* 6280 ******************************************************** + * PHY Push index Y + ***************************************************************/ +#define PHY \ + CLEAR_T; \ + PUSH(Y) + +/* 6280 ******************************************************** + * PLA Pull accumulator + ***************************************************************/ +#define PLA \ + CLEAR_T; \ + PULL(A); \ + SET_NZ(A) + +/* 6280 ******************************************************** + * PLP Pull processor status (flags) + ***************************************************************/ +#if LAZY_FLAGS + +#define PLP \ + PULL(P); \ + P |= _fB; \ + NZ = ((P & _fN) << 8) | \ + ((P & _fZ) ^ _fZ); \ + CHECK_IRQ_LINES + +#else + +#define PLP \ + PULL(P); \ + P |= _fB; \ + CHECK_IRQ_LINES +#endif + +/* 6280 ******************************************************** + * PLX Pull index X + ***************************************************************/ +#define PLX \ + CLEAR_T; \ + PULL(X); \ + SET_NZ(X) + +/* 6280 ******************************************************** + * PLY Pull index Y + ***************************************************************/ +#define PLY \ + CLEAR_T; \ + PULL(Y); \ + SET_NZ(Y) + +/* 6280 ******************************************************** + * RMB Reset memory bit + ***************************************************************/ +#define RMB(bit) \ + CLEAR_T; \ + tmp &= ~(1<<bit) + +/* 6280 ******************************************************** + * ROL Rotate left + * new C <- [7][6][5][4][3][2][1][0] <- C + ***************************************************************/ +#define ROL \ + CLEAR_T; \ + tmp = (tmp << 1) | (P & _fC); \ + P = (P & ~_fC) | ((tmp >> 8) & _fC); \ + tmp = (UINT8)tmp; \ + SET_NZ(tmp) + +/* 6280 ******************************************************** + * ROR Rotate right + * C -> [7][6][5][4][3][2][1][0] -> new C + ***************************************************************/ +#define ROR \ + CLEAR_T; \ + tmp |= (P & _fC) << 8; \ + P = (P & ~_fC) | (tmp & _fC); \ + tmp = (UINT8)(tmp >> 1); \ + SET_NZ(tmp) + +/* 6280 ******************************************************** + * RTI Return from interrupt + * pull flags, pull PC lo, pull PC hi and increment PC + ***************************************************************/ +#if LAZY_FLAGS + +#define RTI \ + PULL(P); \ + P |= _fB; \ + NZ = ((P & _fN) << 8) | \ + ((P & _fZ) ^ _fZ); \ + PULL(PCL); \ + PULL(PCH); \ + CHECK_IRQ_LINES +#else + +#define RTI \ + PULL(P); \ + P |= _fB; \ + PULL(PCL); \ + PULL(PCH); \ + CHECK_IRQ_LINES +#endif + +/* 6280 ******************************************************** + * RTS Return from subroutine + * pull PC lo, PC hi and increment PC + ***************************************************************/ +#define RTS \ + CLEAR_T; \ + PULL(PCL); \ + PULL(PCH); \ + PCW++; + +/* 6280 ******************************************************** + * SAX Swap accumulator and index X + ***************************************************************/ +#define SAX \ + CLEAR_T; \ + tmp = X; \ + X = A; \ + A = tmp + +/* 6280 ******************************************************** + * SAY Swap accumulator and index Y + ***************************************************************/ +#define SAY \ + CLEAR_T; \ + tmp = Y; \ + Y = A; \ + A = tmp + +/* 6280 ******************************************************** + * SBC Subtract with carry + ***************************************************************/ +#define TSBC \ + { \ + int tflagtemp; \ + CLEAR_T; \ + RD_TFL; \ + if (P & _fD) \ + { \ + int c = (P & _fC) ^ _fC; \ + int sum = tflagtemp - tmp -c; \ + int lo = (tflagtemp & 0x0f) - (tmp & 0x0f) - c; \ + int hi = (tflagtemp & 0xf0) - (tmp & 0xf0); \ + P &= ~_fC; \ + if (lo & 0xf0) \ + lo -= 6; \ + if (lo & 0x80) \ + hi -= 0x10; \ + if (hi & 0x0f00) \ + hi -= 0x60; \ + if ((sum & 0xff00) == 0) \ + P |= _fC; \ + tflagtemp = (lo & 0x0f) + (hi & 0xf0); \ + H6280_CYCLES(1); \ + } \ + else \ + { \ + int c = (P & _fC) ^ _fC; \ + int sum = tflagtemp - tmp - c; \ + P &= ~(_fV | _fC); \ + if ((tflagtemp^tmp) & (tflagtemp^sum) & _fN) \ + P |= _fV; \ + if ((sum & 0xff00) == 0) \ + P |= _fC; \ + tflagtemp = (UINT8) sum; \ + } \ + SET_NZ(tflagtemp); \ + WB_TFL; \ + H6280_CYCLES(3); \ + } + +#define SBC \ + if(P & _fT) \ + TSBC \ + else { \ + if (P & _fD) \ + { \ + int c = (P & _fC) ^ _fC; \ + int sum = A - tmp - c; \ + int lo = (A & 0x0f) - (tmp & 0x0f) - c; \ + int hi = (A & 0xf0) - (tmp & 0xf0); \ + P &= ~_fC; \ + if (lo & 0xf0) \ + lo -= 6; \ + if (lo & 0x80) \ + hi -= 0x10; \ + if (hi & 0x0f00) \ + hi -= 0x60; \ + if ((sum & 0xff00) == 0) \ + P |= _fC; \ + A = (lo & 0x0f) + (hi & 0xf0); \ + H6280_CYCLES(1); \ + } \ + else \ + { \ + int c = (P & _fC) ^ _fC; \ + int sum = A - tmp - c; \ + P &= ~(_fV | _fC); \ + if ((A^tmp) & (A^sum) & _fN) \ + P |= _fV; \ + if ((sum & 0xff00) == 0) \ + P |= _fC; \ + A = (UINT8) sum; \ + } \ + SET_NZ(A); \ + } + +/* 6280 ******************************************************** + * SEC Set carry flag + ***************************************************************/ +#if defined(SEC) +#undef SEC +#endif +#define SEC \ + CLEAR_T; \ + P |= _fC + +/* 6280 ******************************************************** + * SED Set decimal flag + ***************************************************************/ +#define SED \ + CLEAR_T; \ + P |= _fD + +/* 6280 ******************************************************** + * SEI Set interrupt flag + ***************************************************************/ +#define SEI \ + CLEAR_T; \ + P |= _fI + +/* 6280 ******************************************************** + * SET Set t flag + ***************************************************************/ +#define SET \ + P |= _fT; + +/* 6280 ******************************************************** + * SMB Set memory bit + ***************************************************************/ +#define SMB(bit) \ + CLEAR_T; \ + tmp |= (1<<bit) + +/* 6280 ******************************************************** + * ST0 Store at hardware address 0 + ***************************************************************/ +#define ST0 \ + CLEAR_T; \ + cpustate->io->write_byte(0x0000,tmp) + +/* 6280 ******************************************************** + * ST1 Store at hardware address 2 + ***************************************************************/ +#define ST1 \ + CLEAR_T; \ + cpustate->io->write_byte(0x0002,tmp) + +/* 6280 ******************************************************** + * ST2 Store at hardware address 3 + ***************************************************************/ +#define ST2 \ + CLEAR_T; \ + cpustate->io->write_byte(0x0003,tmp) + +/* 6280 ******************************************************** + * STA Store accumulator + ***************************************************************/ +#define STA \ + CLEAR_T; \ + tmp = A + +/* 6280 ******************************************************** + * STX Store index X + ***************************************************************/ +#define STX \ + CLEAR_T; \ + tmp = X + +/* 6280 ******************************************************** + * STY Store index Y + ***************************************************************/ +#define STY \ + CLEAR_T; \ + tmp = Y + +/* 6280 ******************************************************** + * STZ Store zero + ***************************************************************/ +#define STZ \ + CLEAR_T; \ + tmp = 0 + +/* H6280 ******************************************************* + * SXY Swap index X and index Y + ***************************************************************/ +#define SXY \ + CLEAR_T; \ + tmp = X; \ + X = Y; \ + Y = tmp + +/* H6280 ******************************************************* + * TAI Transfer Alternate Increment + ***************************************************************/ +#define TAI \ + CLEAR_T; \ + from=RDMEMW(PCW); \ + to =RDMEMW(PCW+2); \ + length=RDMEMW(PCW+4); \ + PCW+=6; \ + alternate=0; \ + if (!length) length = 0x10000; \ + H6280_CYCLES( ((6 * length) + 17) ); \ + while ((length--) != 0) { \ + WRMEM(cpustate, to,RDMEM(cpustate, from+alternate)); \ + to++; \ + alternate ^= 1; \ + } + +/* H6280 ******************************************************* + * TAM Transfer accumulator to memory mapper register(s) + ***************************************************************/ +#define TAM \ + CLEAR_T; \ + if (tmp&0x01) cpustate->mmr[0] = A; \ + if (tmp&0x02) cpustate->mmr[1] = A; \ + if (tmp&0x04) cpustate->mmr[2] = A; \ + if (tmp&0x08) cpustate->mmr[3] = A; \ + if (tmp&0x10) cpustate->mmr[4] = A; \ + if (tmp&0x20) cpustate->mmr[5] = A; \ + if (tmp&0x40) cpustate->mmr[6] = A; \ + if (tmp&0x80) cpustate->mmr[7] = A + +/* 6280 ******************************************************** + * TAX Transfer accumulator to index X + ***************************************************************/ +#define TAX \ + CLEAR_T; \ + X = A; \ + SET_NZ(X) + +/* 6280 ******************************************************** + * TAY Transfer accumulator to index Y + ***************************************************************/ +#define TAY \ + CLEAR_T; \ + Y = A; \ + SET_NZ(Y) + +/* 6280 ******************************************************** + * TDD Transfer Decrement Decrement + ***************************************************************/ +#define TDD \ + CLEAR_T; \ + from=RDMEMW(PCW); \ + to =RDMEMW(PCW+2); \ + length=RDMEMW(PCW+4); \ + PCW+=6; \ + if (!length) length = 0x10000; \ + H6280_CYCLES( ((6 * length) + 17) ); \ + while ((length--) != 0) { \ + WRMEM(cpustate, to,RDMEM(cpustate, from)); \ + to--; \ + from--; \ + } + +/* 6280 ******************************************************** + * TIA Transfer Increment Alternate + ***************************************************************/ +#define TIA \ + CLEAR_T; \ + from=RDMEMW(PCW); \ + to =RDMEMW(PCW+2); \ + length=RDMEMW(PCW+4); \ + PCW+=6; \ + alternate=0; \ + if (!length) length = 0x10000; \ + H6280_CYCLES( ((6 * length) + 17) ); \ + while ((length--) != 0) { \ + WRMEM(cpustate, to+alternate,RDMEM(cpustate, from)); \ + from++; \ + alternate ^= 1; \ + } + +/* 6280 ******************************************************** + * TII Transfer Increment Increment + ***************************************************************/ +#define TII \ + CLEAR_T; \ + from=RDMEMW(PCW); \ + to =RDMEMW(PCW+2); \ + length=RDMEMW(PCW+4); \ + PCW+=6; \ + if (!length) length = 0x10000; \ + H6280_CYCLES( ((6 * length) + 17) ); \ + while ((length--) != 0) { \ + WRMEM(cpustate, to,RDMEM(cpustate, from)); \ + to++; \ + from++; \ + } + +/* 6280 ******************************************************** + * TIN Transfer block, source increments every loop + ***************************************************************/ +#define TIN \ + CLEAR_T; \ + from=RDMEMW(PCW); \ + to =RDMEMW(PCW+2); \ + length=RDMEMW(PCW+4); \ + PCW+=6; \ + if (!length) length = 0x10000; \ + H6280_CYCLES( ((6 * length) + 17) ); \ + while ((length--) != 0) { \ + WRMEM(cpustate, to,RDMEM(cpustate, from)); \ + from++; \ + } + +/* 6280 ******************************************************** + * TMA Transfer memory mapper register(s) to accumulator + * the highest bit set in tmp is the one that counts + ***************************************************************/ +#define TMA \ + CLEAR_T; \ + if (tmp&0x01) A = cpustate->mmr[0]; \ + if (tmp&0x02) A = cpustate->mmr[1]; \ + if (tmp&0x04) A = cpustate->mmr[2]; \ + if (tmp&0x08) A = cpustate->mmr[3]; \ + if (tmp&0x10) A = cpustate->mmr[4]; \ + if (tmp&0x20) A = cpustate->mmr[5]; \ + if (tmp&0x40) A = cpustate->mmr[6]; \ + if (tmp&0x80) A = cpustate->mmr[7] + +/* 6280 ******************************************************** + * TRB Test and reset bits + ***************************************************************/ +#define TRB \ + CLEAR_T; \ + P = (P & ~(_fN|_fV|_fT|_fZ)) \ + | ((tmp&0x80) ? _fN:0) \ + | ((tmp&0x40) ? _fV:0) \ + | ((tmp&~A) ? 0:_fZ); \ + tmp &= ~A + +/* 6280 ******************************************************** + * TSB Test and set bits + ***************************************************************/ +#define TSB \ + CLEAR_T; \ + P = (P & ~(_fN|_fV|_fT|_fZ)) \ + | ((tmp&0x80) ? _fN:0) \ + | ((tmp&0x40) ? _fV:0) \ + | ((tmp|A) ? 0:_fZ); \ + tmp |= A + +/* 6280 ******************************************************** + * TSX Transfer stack LSB to index X + ***************************************************************/ +#define TSX \ + CLEAR_T; \ + X = S; \ + SET_NZ(X) + +/* 6280 ******************************************************** + * TST + ***************************************************************/ +#define TST \ + P = (P & ~(_fN|_fV|_fT|_fZ)) \ + | ((tmp&0x80) ? _fN:0) \ + | ((tmp&0x40) ? _fV:0) \ + | ((tmp&tmp2) ? 0:_fZ) + +/* 6280 ******************************************************** + * TXA Transfer index X to accumulator + ***************************************************************/ +#define TXA \ + CLEAR_T; \ + A = X; \ + SET_NZ(A) + +/* 6280 ******************************************************** + * TXS Transfer index X to stack LSB + * no flags changed (sic!) + ***************************************************************/ +#define TXS \ + CLEAR_T; \ + S = X + +/* 6280 ******************************************************** + * TYA Transfer index Y to accumulator + ***************************************************************/ +#define TYA \ + CLEAR_T; \ + A = Y; \ + SET_NZ(A) + +/* 6280 ******************************************************** + * CSH Set CPU in high speed mode + ***************************************************************/ +#define CSH \ + cpustate->clocks_per_cycle = 1; + +/* 6280 ******************************************************** + * CSL Set CPU in low speed mode + ***************************************************************/ +#define CSL \ + cpustate->clocks_per_cycle = 4; |