summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i8085
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/i8085')
-rw-r--r--src/devices/cpu/i8085/8085dasm.cpp798
-rw-r--r--src/devices/cpu/i8085/8085dasm.h24
-rw-r--r--src/devices/cpu/i8085/i8085.cpp1914
-rw-r--r--src/devices/cpu/i8085/i8085.h141
-rw-r--r--src/devices/cpu/i8085/i8085cpu.h188
5 files changed, 1588 insertions, 1477 deletions
diff --git a/src/devices/cpu/i8085/8085dasm.cpp b/src/devices/cpu/i8085/8085dasm.cpp
index 5f898c86464..36d4640afb5 100644
--- a/src/devices/cpu/i8085/8085dasm.cpp
+++ b/src/devices/cpu/i8085/8085dasm.cpp
@@ -2,544 +2,284 @@
// copyright-holders:Juergen Buchmueller
/*****************************************************************************
*
- * 8085dasm.c
* Portable I8085A disassembler
*
+ * TODO:
+ * - add I8080?
+ *
*****************************************************************************/
#include "emu.h"
+#include "8085dasm.h"
-/* 8080/8085A mnemonics were more irritation than information
- What would you guess "CP $3456" to mean? It's not compare,
- but call if plus ... therefore: */
-//#define Z80_MNEMONICS
-
-#define OP(A) oprom[(A) - PC]
-#define ARG(A) opram[(A) - PC]
-#define ARGW(A) (opram[(A) - PC] | (opram[(A) + 1 - PC] << 8))
+u32 i8085_disassembler::opcode_alignment() const
+{
+ return 1;
+}
-CPU_DISASSEMBLE(i8085)
+offs_t i8085_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
- uint32_t flags = 0;
+ offs_t flags = 0;
uint8_t op;
- unsigned PC = pc;
- switch (op = OP(pc++))
+ unsigned prevpc = pc;
+ switch (op = opcodes.r8(pc++))
{
-#ifdef Z80_MNEMONICS
- case 0x00: util::stream_format(stream, "nop"); break;
- case 0x01: util::stream_format(stream, "ld bc,$%04x", ARGW(pc)); pc+=2; break;
- case 0x02: util::stream_format(stream, "ld (bc),a"); break;
- case 0x03: util::stream_format(stream, "inc bc"); break;
- case 0x04: util::stream_format(stream, "inc b"); break;
- case 0x05: util::stream_format(stream, "dec b"); break;
- case 0x06: util::stream_format(stream, "ld b,$%02x", ARG(pc)); pc++; break;
- case 0x07: util::stream_format(stream, "rlca"); break;
- case 0x08: util::stream_format(stream, "sub hl,bc (*)"); break;
- case 0x09: util::stream_format(stream, "add hl,bc"); break;
- case 0x0a: util::stream_format(stream, "ld a,(bc)"); break;
- case 0x0b: util::stream_format(stream, "dec bc"); break;
- case 0x0c: util::stream_format(stream, "inc c"); break;
- case 0x0d: util::stream_format(stream, "dec c"); break;
- case 0x0e: util::stream_format(stream, "ld c,$%02x", ARG(pc)); pc++; break;
- case 0x0f: util::stream_format(stream, "rrca"); break;
- case 0x10: util::stream_format(stream, "sra hl (*)"); break;
- case 0x11: util::stream_format(stream, "ld de,$%04x", ARGW(pc)); pc+=2; break;
- case 0x12: util::stream_format(stream, "ld (de),a"); break;
- case 0x13: util::stream_format(stream, "inc de"); break;
- case 0x14: util::stream_format(stream, "inc d"); break;
- case 0x15: util::stream_format(stream, "dec d"); break;
- case 0x16: util::stream_format(stream, "ld d,$%02x", ARG(pc)); pc++; break;
- case 0x17: util::stream_format(stream, "rla"); break;
- case 0x18: util::stream_format(stream, "rl de (*)"); break;
- case 0x19: util::stream_format(stream, "add hl,de"); break;
- case 0x1a: util::stream_format(stream, "ld a,(de)"); break;
- case 0x1b: util::stream_format(stream, "dec de"); break;
- case 0x1c: util::stream_format(stream, "inc e"); break;
- case 0x1d: util::stream_format(stream, "dec e"); break;
- case 0x1e: util::stream_format(stream, "ld e,$%02x", ARG(pc)); pc++; break;
- case 0x1f: util::stream_format(stream, "rra"); break;
- case 0x20: util::stream_format(stream, "rim"); break;
- case 0x21: util::stream_format(stream, "ld hl,$%04x", ARGW(pc)); pc+=2; break;
- case 0x22: util::stream_format(stream, "ld ($%04x),hl", ARGW(pc)); pc+=2;break;
- case 0x23: util::stream_format(stream, "inc hl"); break;
- case 0x24: util::stream_format(stream, "inc h"); break;
- case 0x25: util::stream_format(stream, "dec h"); break;
- case 0x26: util::stream_format(stream, "ld h,$%02x", ARG(pc)); pc++; break;
- case 0x27: util::stream_format(stream, "daa"); break;
- case 0x28: util::stream_format(stream, "ld de,hl+$%02x (*)",ARG(pc));pc++;break;
- case 0x29: util::stream_format(stream, "add hl,hl"); break;
- case 0x2a: util::stream_format(stream, "ld hl,($%04x)", ARGW(pc)); pc+=2;break;
- case 0x2b: util::stream_format(stream, "dec hl"); break;
- case 0x2c: util::stream_format(stream, "inc l"); break;
- case 0x2d: util::stream_format(stream, "dec l"); break;
- case 0x2e: util::stream_format(stream, "ld l,$%02x", ARG(pc)); pc++; break;
- case 0x2f: util::stream_format(stream, "cpl"); break;
- case 0x30: util::stream_format(stream, "sim"); break;
- case 0x31: util::stream_format(stream, "ld sp,$%04x", ARGW(pc)); pc+=2; break;
- case 0x32: util::stream_format(stream, "ld ($%04x),a", ARGW(pc)); pc+=2; break;
- case 0x33: util::stream_format(stream, "inc sp"); break;
- case 0x34: util::stream_format(stream, "inc (hl)"); break;
- case 0x35: util::stream_format(stream, "dec (hl)"); break;
- case 0x36: util::stream_format(stream, "ld (hl),$%02x", ARG(pc)); pc++; break;
- case 0x37: util::stream_format(stream, "scf"); break;
- case 0x38: util::stream_format(stream, "ld de,sp+$%02x (*)",ARG(pc));pc++;break;
- case 0x39: util::stream_format(stream, "add hl,sp"); break;
- case 0x3a: util::stream_format(stream, "ld a,($%04x)", ARGW(pc)); pc+=2; break;
- case 0x3b: util::stream_format(stream, "dec sp"); break;
- case 0x3c: util::stream_format(stream, "inc a"); break;
- case 0x3d: util::stream_format(stream, "dec a"); break;
- case 0x3e: util::stream_format(stream, "ld a,$%02x", ARG(pc)); pc++; break;
- case 0x3f: util::stream_format(stream, "ccf"); break;
- case 0x40: util::stream_format(stream, "ld b,b"); break;
- case 0x41: util::stream_format(stream, "ld b,c"); break;
- case 0x42: util::stream_format(stream, "ld b,d"); break;
- case 0x43: util::stream_format(stream, "ld b,e"); break;
- case 0x44: util::stream_format(stream, "ld b,h"); break;
- case 0x45: util::stream_format(stream, "ld b,l"); break;
- case 0x46: util::stream_format(stream, "ld b,(hl)"); break;
- case 0x47: util::stream_format(stream, "ld b,a"); break;
- case 0x48: util::stream_format(stream, "ld c,b"); break;
- case 0x49: util::stream_format(stream, "ld c,c"); break;
- case 0x4a: util::stream_format(stream, "ld c,d"); break;
- case 0x4b: util::stream_format(stream, "ld c,e"); break;
- case 0x4c: util::stream_format(stream, "ld c,h"); break;
- case 0x4d: util::stream_format(stream, "ld c,l"); break;
- case 0x4e: util::stream_format(stream, "ld c,(hl)"); break;
- case 0x4f: util::stream_format(stream, "ld c,a"); break;
- case 0x50: util::stream_format(stream, "ld d,b"); break;
- case 0x51: util::stream_format(stream, "ld d,c"); break;
- case 0x52: util::stream_format(stream, "ld d,d"); break;
- case 0x53: util::stream_format(stream, "ld d,e"); break;
- case 0x54: util::stream_format(stream, "ld d,h"); break;
- case 0x55: util::stream_format(stream, "ld d,l"); break;
- case 0x56: util::stream_format(stream, "ld d,(hl)"); break;
- case 0x57: util::stream_format(stream, "ld d,a"); break;
- case 0x58: util::stream_format(stream, "ld e,b"); break;
- case 0x59: util::stream_format(stream, "ld e,c"); break;
- case 0x5a: util::stream_format(stream, "ld e,d"); break;
- case 0x5b: util::stream_format(stream, "ld e,e"); break;
- case 0x5c: util::stream_format(stream, "ld e,h"); break;
- case 0x5d: util::stream_format(stream, "ld e,l"); break;
- case 0x5e: util::stream_format(stream, "ld e,(hl)"); break;
- case 0x5f: util::stream_format(stream, "ld e,a"); break;
- case 0x60: util::stream_format(stream, "ld h,b"); break;
- case 0x61: util::stream_format(stream, "ld h,c"); break;
- case 0x62: util::stream_format(stream, "ld h,d"); break;
- case 0x63: util::stream_format(stream, "ld h,e"); break;
- case 0x64: util::stream_format(stream, "ld h,h"); break;
- case 0x65: util::stream_format(stream, "ld h,l"); break;
- case 0x66: util::stream_format(stream, "ld h,(hl)"); break;
- case 0x67: util::stream_format(stream, "ld h,a"); break;
- case 0x68: util::stream_format(stream, "ld l,b"); break;
- case 0x69: util::stream_format(stream, "ld l,c"); break;
- case 0x6a: util::stream_format(stream, "ld l,d"); break;
- case 0x6b: util::stream_format(stream, "ld l,e"); break;
- case 0x6c: util::stream_format(stream, "ld l,h"); break;
- case 0x6d: util::stream_format(stream, "ld l,l"); break;
- case 0x6e: util::stream_format(stream, "ld l,(hl)"); break;
- case 0x6f: util::stream_format(stream, "ld l,a"); break;
- case 0x70: util::stream_format(stream, "ld (hl),b"); break;
- case 0x71: util::stream_format(stream, "ld (hl),c"); break;
- case 0x72: util::stream_format(stream, "ld (hl),d"); break;
- case 0x73: util::stream_format(stream, "ld (hl),e"); break;
- case 0x74: util::stream_format(stream, "ld (hl),h"); break;
- case 0x75: util::stream_format(stream, "ld (hl),l"); break;
- case 0x76: util::stream_format(stream, "halt"); break;
- case 0x77: util::stream_format(stream, "ld (hl),a"); break;
- case 0x78: util::stream_format(stream, "ld a,b"); break;
- case 0x79: util::stream_format(stream, "ld a,c"); break;
- case 0x7a: util::stream_format(stream, "ld a,d"); break;
- case 0x7b: util::stream_format(stream, "ld a,e"); break;
- case 0x7c: util::stream_format(stream, "ld a,h"); break;
- case 0x7d: util::stream_format(stream, "ld a,l"); break;
- case 0x7e: util::stream_format(stream, "ld a,(hl)"); break;
- case 0x7f: util::stream_format(stream, "ld a,a"); break;
- case 0x80: util::stream_format(stream, "add a,b"); break;
- case 0x81: util::stream_format(stream, "add a,c"); break;
- case 0x82: util::stream_format(stream, "add a,d"); break;
- case 0x83: util::stream_format(stream, "add a,e"); break;
- case 0x84: util::stream_format(stream, "add a,h"); break;
- case 0x85: util::stream_format(stream, "add a,l"); break;
- case 0x86: util::stream_format(stream, "add a,(hl)"); break;
- case 0x87: util::stream_format(stream, "add a,a"); break;
- case 0x88: util::stream_format(stream, "adc a,b"); break;
- case 0x89: util::stream_format(stream, "adc a,c"); break;
- case 0x8a: util::stream_format(stream, "adc a,d"); break;
- case 0x8b: util::stream_format(stream, "adc a,e"); break;
- case 0x8c: util::stream_format(stream, "adc a,h"); break;
- case 0x8d: util::stream_format(stream, "adc a,l"); break;
- case 0x8e: util::stream_format(stream, "adc a,(hl)"); break;
- case 0x8f: util::stream_format(stream, "adc a,a"); break;
- case 0x90: util::stream_format(stream, "sub b"); break;
- case 0x91: util::stream_format(stream, "sub c"); break;
- case 0x92: util::stream_format(stream, "sub d"); break;
- case 0x93: util::stream_format(stream, "sub e"); break;
- case 0x94: util::stream_format(stream, "sub h"); break;
- case 0x95: util::stream_format(stream, "sub l"); break;
- case 0x96: util::stream_format(stream, "sub (hl)"); break;
- case 0x97: util::stream_format(stream, "sub a"); break;
- case 0x98: util::stream_format(stream, "sbc a,b"); break;
- case 0x99: util::stream_format(stream, "sbc a,c"); break;
- case 0x9a: util::stream_format(stream, "sbc a,d"); break;
- case 0x9b: util::stream_format(stream, "sbc a,e"); break;
- case 0x9c: util::stream_format(stream, "sbc a,h"); break;
- case 0x9d: util::stream_format(stream, "sbc a,l"); break;
- case 0x9e: util::stream_format(stream, "sbc a,(hl)"); break;
- case 0x9f: util::stream_format(stream, "sbc a,a"); break;
- case 0xa0: util::stream_format(stream, "and b"); break;
- case 0xa1: util::stream_format(stream, "and c"); break;
- case 0xa2: util::stream_format(stream, "and d"); break;
- case 0xa3: util::stream_format(stream, "and e"); break;
- case 0xa4: util::stream_format(stream, "and h"); break;
- case 0xa5: util::stream_format(stream, "and l"); break;
- case 0xa6: util::stream_format(stream, "and (hl)"); break;
- case 0xa7: util::stream_format(stream, "and a"); break;
- case 0xa8: util::stream_format(stream, "xor b"); break;
- case 0xa9: util::stream_format(stream, "xor c"); break;
- case 0xaa: util::stream_format(stream, "xor d"); break;
- case 0xab: util::stream_format(stream, "xor e"); break;
- case 0xac: util::stream_format(stream, "xor h"); break;
- case 0xad: util::stream_format(stream, "xor l"); break;
- case 0xae: util::stream_format(stream, "xor (hl)"); break;
- case 0xaf: util::stream_format(stream, "xor a"); break;
- case 0xb0: util::stream_format(stream, "or b"); break;
- case 0xb1: util::stream_format(stream, "or c"); break;
- case 0xb2: util::stream_format(stream, "or d"); break;
- case 0xb3: util::stream_format(stream, "or e"); break;
- case 0xb4: util::stream_format(stream, "or h"); break;
- case 0xb5: util::stream_format(stream, "or l"); break;
- case 0xb6: util::stream_format(stream, "or (hl)"); break;
- case 0xb7: util::stream_format(stream, "or a"); break;
- case 0xb8: util::stream_format(stream, "cp b"); break;
- case 0xb9: util::stream_format(stream, "cp c"); break;
- case 0xba: util::stream_format(stream, "cp d"); break;
- case 0xbb: util::stream_format(stream, "cp e"); break;
- case 0xbc: util::stream_format(stream, "cp h"); break;
- case 0xbd: util::stream_format(stream, "cp l"); break;
- case 0xbe: util::stream_format(stream, "cp (hl)"); break;
- case 0xbf: util::stream_format(stream, "cp a"); break;
- case 0xc0: util::stream_format(stream, "ret nz"); flags = DASMFLAG_STEP_OUT; break;
- case 0xc1: util::stream_format(stream, "pop bc"); break;
- case 0xc2: util::stream_format(stream, "jp nz,$%04x", ARGW(pc)); pc+=2; break;
- case 0xc3: util::stream_format(stream, "jp $%04x", ARGW(pc)); pc+=2; break;
- case 0xc4: util::stream_format(stream, "call nz,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xc5: util::stream_format(stream, "push bc"); break;
- case 0xc6: util::stream_format(stream, "add a,$%02x", ARG(pc)); pc++; break;
- case 0xc7: util::stream_format(stream, "rst $00"); flags = DASMFLAG_STEP_OVER; break;
- case 0xc8: util::stream_format(stream, "ret z"); flags = DASMFLAG_STEP_OUT; break;
- case 0xc9: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break;
- case 0xca: util::stream_format(stream, "jp z,$%04x", ARGW(pc)); pc+=2; break;
- case 0xcb: util::stream_format(stream, "rst v,$40 (*)"); flags = DASMFLAG_STEP_OVER; break;
- case 0xcc: util::stream_format(stream, "call z,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xcd: util::stream_format(stream, "call $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xce: util::stream_format(stream, "adc a,$%02x", ARG(pc)); pc++; break;
- case 0xcf: util::stream_format(stream, "rst $08"); flags = DASMFLAG_STEP_OVER; break;
- case 0xd0: util::stream_format(stream, "ret nc"); flags = DASMFLAG_STEP_OUT; break;
- case 0xd1: util::stream_format(stream, "pop de"); break;
- case 0xd2: util::stream_format(stream, "jp nc,$%04x", ARGW(pc)); pc+=2; break;
- case 0xd3: util::stream_format(stream, "out ($%02x),a", ARG(pc)); pc++; break;
- case 0xd4: util::stream_format(stream, "call nc,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xd5: util::stream_format(stream, "push de"); break;
- case 0xd6: util::stream_format(stream, "sub $%02x", ARG(pc)); pc++; break;
- case 0xd7: util::stream_format(stream, "rst $10"); flags = DASMFLAG_STEP_OVER; break;
- case 0xd8: util::stream_format(stream, "ret c"); break;
- case 0xd9: util::stream_format(stream, "ld (de),hl (*)"); break;
- case 0xda: util::stream_format(stream, "jp c,$%04x", ARGW(pc)); pc+=2; break;
- case 0xdb: util::stream_format(stream, "in a,($%02x)", ARG(pc)); pc++; break;
- case 0xdc: util::stream_format(stream, "call c,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xdd: util::stream_format(stream, "jp nx,$%04x (*)",ARGW(pc));pc+=2;break;
- case 0xde: util::stream_format(stream, "sub $%02x", ARG(pc)); pc++; break;
- case 0xdf: util::stream_format(stream, "rst $18"); flags = DASMFLAG_STEP_OVER; break;
- case 0xe0: util::stream_format(stream, "ret pe"); break;
- case 0xe1: util::stream_format(stream, "pop hl"); break;
- case 0xe2: util::stream_format(stream, "jp pe,$%04x", ARGW(pc)); pc+=2; break;
- case 0xe3: util::stream_format(stream, "ex (sp),hl"); break;
- case 0xe4: util::stream_format(stream, "call pe,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xe5: util::stream_format(stream, "push hl"); break;
- case 0xe6: util::stream_format(stream, "and $%02x", ARG(pc)); pc++; break;
- case 0xe7: util::stream_format(stream, "rst $20"); flags = DASMFLAG_STEP_OVER; break;
- case 0xe8: util::stream_format(stream, "ret po"); break;
- case 0xe9: util::stream_format(stream, "jp (hl)"); break;
- case 0xea: util::stream_format(stream, "jp po,$%04x", ARGW(pc)); pc+=2; break;
- case 0xeb: util::stream_format(stream, "ex de,hl"); break;
- case 0xec: util::stream_format(stream, "call po,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xed: util::stream_format(stream, "ld hl,(de) (*)"); break;
- case 0xee: util::stream_format(stream, "xor $%02x", ARG(pc)); pc++; break;
- case 0xef: util::stream_format(stream, "rst $28"); flags = DASMFLAG_STEP_OVER; break;
- case 0xf0: util::stream_format(stream, "ret p"); break;
- case 0xf1: util::stream_format(stream, "pop af"); break;
- case 0xf2: util::stream_format(stream, "jp p,$%04x", ARGW(pc)); pc+=2; break;
- case 0xf3: util::stream_format(stream, "di"); break;
- case 0xf4: util::stream_format(stream, "cp $%04x", ARGW(pc)); pc+=2; break;
- case 0xf5: util::stream_format(stream, "push af"); break;
- case 0xf6: util::stream_format(stream, "or $%02x", ARG(pc)); pc++; break;
- case 0xf7: util::stream_format(stream, "rst $30"); flags = DASMFLAG_STEP_OVER; break;
- case 0xf8: util::stream_format(stream, "ret m"); break;
- case 0xf9: util::stream_format(stream, "ld sp,hl"); break;
- case 0xfa: util::stream_format(stream, "jp m,$%04x", ARGW(pc)); pc+=2; break;
- case 0xfb: util::stream_format(stream, "ei"); break;
- case 0xfc: util::stream_format(stream, "call m,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xfd: util::stream_format(stream, "jp x,$%04x (*)",ARGW(pc));pc+=2; break;
- case 0xfe: util::stream_format(stream, "cp $%02x", ARG(pc)); pc++; break;
- case 0xff: util::stream_format(stream, "rst $38"); flags = DASMFLAG_STEP_OVER; break;
-#else
- case 0x00: util::stream_format(stream, "nop"); break;
- case 0x01: util::stream_format(stream, "lxi b,$%04x", ARGW(pc)); pc+=2; break;
- case 0x02: util::stream_format(stream, "stax b"); break;
- case 0x03: util::stream_format(stream, "inx b"); break;
- case 0x04: util::stream_format(stream, "inr b"); break;
- case 0x05: util::stream_format(stream, "dcr b"); break;
- case 0x06: util::stream_format(stream, "mvi b,$%02x", ARG(pc)); pc++; break;
- case 0x07: util::stream_format(stream, "rlc"); break;
- case 0x08: util::stream_format(stream, "dsub (*)"); break;
- case 0x09: util::stream_format(stream, "dad b"); break;
- case 0x0a: util::stream_format(stream, "ldax b"); break;
- case 0x0b: util::stream_format(stream, "dcx b"); break;
- case 0x0c: util::stream_format(stream, "inr c"); break;
- case 0x0d: util::stream_format(stream, "dcr c"); break;
- case 0x0e: util::stream_format(stream, "mvi c,$%02x", ARG(pc)); pc++; break;
- case 0x0f: util::stream_format(stream, "rrc"); break;
- case 0x10: util::stream_format(stream, "asrh (*)"); break;
- case 0x11: util::stream_format(stream, "lxi d,$%04x", ARGW(pc)); pc+=2; break;
- case 0x12: util::stream_format(stream, "stax d"); break;
- case 0x13: util::stream_format(stream, "inx d"); break;
- case 0x14: util::stream_format(stream, "inr d"); break;
- case 0x15: util::stream_format(stream, "dcr d"); break;
- case 0x16: util::stream_format(stream, "mvi d,$%02x", ARG(pc)); pc++; break;
- case 0x17: util::stream_format(stream, "ral"); break;
- case 0x18: util::stream_format(stream, "rlde (*)"); break;
- case 0x19: util::stream_format(stream, "dad d"); break;
- case 0x1a: util::stream_format(stream, "ldax d"); break;
- case 0x1b: util::stream_format(stream, "dcx d"); break;
- case 0x1c: util::stream_format(stream, "inr e"); break;
- case 0x1d: util::stream_format(stream, "dcr e"); break;
- case 0x1e: util::stream_format(stream, "mvi e,$%02x", ARG(pc)); pc++; break;
- case 0x1f: util::stream_format(stream, "rar"); break;
- case 0x20: util::stream_format(stream, "rim"); break;
- case 0x21: util::stream_format(stream, "lxi h,$%04x", ARGW(pc)); pc+=2; break;
- case 0x22: util::stream_format(stream, "shld $%04x", ARGW(pc)); pc+=2; break;
- case 0x23: util::stream_format(stream, "inx h"); break;
- case 0x24: util::stream_format(stream, "inr h"); break;
- case 0x25: util::stream_format(stream, "dcr h"); break;
- case 0x26: util::stream_format(stream, "mvi h,$%02x", ARG(pc)); pc++; break;
- case 0x27: util::stream_format(stream, "daa"); break;
- case 0x28: util::stream_format(stream, "ldeh $%02x (*)", ARG(pc)); pc++; break;
- case 0x29: util::stream_format(stream, "dad h"); break;
- case 0x2a: util::stream_format(stream, "lhld $%04x", ARGW(pc)); pc+=2; break;
- case 0x2b: util::stream_format(stream, "dcx h"); break;
- case 0x2c: util::stream_format(stream, "inr l"); break;
- case 0x2d: util::stream_format(stream, "dcr l"); break;
- case 0x2e: util::stream_format(stream, "mvi l,$%02x", ARG(pc)); pc++; break;
- case 0x2f: util::stream_format(stream, "cma"); break;
- case 0x30: util::stream_format(stream, "sim"); break;
- case 0x31: util::stream_format(stream, "lxi sp,$%04x", ARGW(pc)); pc+=2; break;
- case 0x32: util::stream_format(stream, "stax $%04x", ARGW(pc)); pc+=2; break;
- case 0x33: util::stream_format(stream, "inx sp"); break;
- case 0x34: util::stream_format(stream, "inr m"); break;
- case 0x35: util::stream_format(stream, "dcr m"); break;
- case 0x36: util::stream_format(stream, "mvi m,$%02x", ARG(pc)); pc++; break;
- case 0x37: util::stream_format(stream, "stc"); break;
- case 0x38: util::stream_format(stream, "ldes $%02x (*)", ARG(pc)); pc++; break;
- case 0x39: util::stream_format(stream, "dad sp"); break;
- case 0x3a: util::stream_format(stream, "ldax $%04x", ARGW(pc)); pc+=2; break;
- case 0x3b: util::stream_format(stream, "dcx sp"); break;
- case 0x3c: util::stream_format(stream, "inr a"); break;
- case 0x3d: util::stream_format(stream, "dcr a"); break;
- case 0x3e: util::stream_format(stream, "mvi a,$%02x", ARG(pc)); pc++; break;
- case 0x3f: util::stream_format(stream, "cmc"); break;
- case 0x40: util::stream_format(stream, "mov b,b"); break;
- case 0x41: util::stream_format(stream, "mov b,c"); break;
- case 0x42: util::stream_format(stream, "mov b,d"); break;
- case 0x43: util::stream_format(stream, "mov b,e"); break;
- case 0x44: util::stream_format(stream, "mov b,h"); break;
- case 0x45: util::stream_format(stream, "mov b,l"); break;
- case 0x46: util::stream_format(stream, "mov b,m"); break;
- case 0x47: util::stream_format(stream, "mov b,a"); break;
- case 0x48: util::stream_format(stream, "mov c,b"); break;
- case 0x49: util::stream_format(stream, "mov c,c"); break;
- case 0x4a: util::stream_format(stream, "mov c,d"); break;
- case 0x4b: util::stream_format(stream, "mov c,e"); break;
- case 0x4c: util::stream_format(stream, "mov c,h"); break;
- case 0x4d: util::stream_format(stream, "mov c,l"); break;
- case 0x4e: util::stream_format(stream, "mov c,m"); break;
- case 0x4f: util::stream_format(stream, "mov c,a"); break;
- case 0x50: util::stream_format(stream, "mov d,b"); break;
- case 0x51: util::stream_format(stream, "mov d,c"); break;
- case 0x52: util::stream_format(stream, "mov d,d"); break;
- case 0x53: util::stream_format(stream, "mov d,e"); break;
- case 0x54: util::stream_format(stream, "mov d,h"); break;
- case 0x55: util::stream_format(stream, "mov d,l"); break;
- case 0x56: util::stream_format(stream, "mov d,m"); break;
- case 0x57: util::stream_format(stream, "mov d,a"); break;
- case 0x58: util::stream_format(stream, "mov e,b"); break;
- case 0x59: util::stream_format(stream, "mov e,c"); break;
- case 0x5a: util::stream_format(stream, "mov e,d"); break;
- case 0x5b: util::stream_format(stream, "mov e,e"); break;
- case 0x5c: util::stream_format(stream, "mov e,h"); break;
- case 0x5d: util::stream_format(stream, "mov e,l"); break;
- case 0x5e: util::stream_format(stream, "mov e,m"); break;
- case 0x5f: util::stream_format(stream, "mov e,a"); break;
- case 0x60: util::stream_format(stream, "mov h,b"); break;
- case 0x61: util::stream_format(stream, "mov h,c"); break;
- case 0x62: util::stream_format(stream, "mov h,d"); break;
- case 0x63: util::stream_format(stream, "mov h,e"); break;
- case 0x64: util::stream_format(stream, "mov h,h"); break;
- case 0x65: util::stream_format(stream, "mov h,l"); break;
- case 0x66: util::stream_format(stream, "mov h,m"); break;
- case 0x67: util::stream_format(stream, "mov h,a"); break;
- case 0x68: util::stream_format(stream, "mov l,b"); break;
- case 0x69: util::stream_format(stream, "mov l,c"); break;
- case 0x6a: util::stream_format(stream, "mov l,d"); break;
- case 0x6b: util::stream_format(stream, "mov l,e"); break;
- case 0x6c: util::stream_format(stream, "mov l,h"); break;
- case 0x6d: util::stream_format(stream, "mov l,l"); break;
- case 0x6e: util::stream_format(stream, "mov l,m"); break;
- case 0x6f: util::stream_format(stream, "mov l,a"); break;
- case 0x70: util::stream_format(stream, "mov m,b"); break;
- case 0x71: util::stream_format(stream, "mov m,c"); break;
- case 0x72: util::stream_format(stream, "mov m,d"); break;
- case 0x73: util::stream_format(stream, "mov m,e"); break;
- case 0x74: util::stream_format(stream, "mov m,h"); break;
- case 0x75: util::stream_format(stream, "mov m,l"); break;
- case 0x76: util::stream_format(stream, "hlt"); break;
- case 0x77: util::stream_format(stream, "mov m,a"); break;
- case 0x78: util::stream_format(stream, "mov a,b"); break;
- case 0x79: util::stream_format(stream, "mov a,c"); break;
- case 0x7a: util::stream_format(stream, "mov a,d"); break;
- case 0x7b: util::stream_format(stream, "mov a,e"); break;
- case 0x7c: util::stream_format(stream, "mov a,h"); break;
- case 0x7d: util::stream_format(stream, "mov a,l"); break;
- case 0x7e: util::stream_format(stream, "mov a,m"); break;
- case 0x7f: util::stream_format(stream, "mov a,a"); break;
- case 0x80: util::stream_format(stream, "add b"); break;
- case 0x81: util::stream_format(stream, "add c"); break;
- case 0x82: util::stream_format(stream, "add d"); break;
- case 0x83: util::stream_format(stream, "add e"); break;
- case 0x84: util::stream_format(stream, "add h"); break;
- case 0x85: util::stream_format(stream, "add l"); break;
- case 0x86: util::stream_format(stream, "add m"); break;
- case 0x87: util::stream_format(stream, "add a"); break;
- case 0x88: util::stream_format(stream, "adc b"); break;
- case 0x89: util::stream_format(stream, "adc c"); break;
- case 0x8a: util::stream_format(stream, "adc d"); break;
- case 0x8b: util::stream_format(stream, "adc e"); break;
- case 0x8c: util::stream_format(stream, "adc h"); break;
- case 0x8d: util::stream_format(stream, "adc l"); break;
- case 0x8e: util::stream_format(stream, "adc m"); break;
- case 0x8f: util::stream_format(stream, "adc a"); break;
- case 0x90: util::stream_format(stream, "sub b"); break;
- case 0x91: util::stream_format(stream, "sub c"); break;
- case 0x92: util::stream_format(stream, "sub d"); break;
- case 0x93: util::stream_format(stream, "sub e"); break;
- case 0x94: util::stream_format(stream, "sub h"); break;
- case 0x95: util::stream_format(stream, "sub l"); break;
- case 0x96: util::stream_format(stream, "sub m"); break;
- case 0x97: util::stream_format(stream, "sub a"); break;
- case 0x98: util::stream_format(stream, "sbb b"); break;
- case 0x99: util::stream_format(stream, "sbb c"); break;
- case 0x9a: util::stream_format(stream, "sbb d"); break;
- case 0x9b: util::stream_format(stream, "sbb e"); break;
- case 0x9c: util::stream_format(stream, "sbb h"); break;
- case 0x9d: util::stream_format(stream, "sbb l"); break;
- case 0x9e: util::stream_format(stream, "sbb m"); break;
- case 0x9f: util::stream_format(stream, "sbb a"); break;
- case 0xa0: util::stream_format(stream, "ana b"); break;
- case 0xa1: util::stream_format(stream, "ana c"); break;
- case 0xa2: util::stream_format(stream, "ana d"); break;
- case 0xa3: util::stream_format(stream, "ana e"); break;
- case 0xa4: util::stream_format(stream, "ana h"); break;
- case 0xa5: util::stream_format(stream, "ana l"); break;
- case 0xa6: util::stream_format(stream, "ana m"); break;
- case 0xa7: util::stream_format(stream, "ana a"); break;
- case 0xa8: util::stream_format(stream, "xra b"); break;
- case 0xa9: util::stream_format(stream, "xra c"); break;
- case 0xaa: util::stream_format(stream, "xra d"); break;
- case 0xab: util::stream_format(stream, "xra e"); break;
- case 0xac: util::stream_format(stream, "xra h"); break;
- case 0xad: util::stream_format(stream, "xra l"); break;
- case 0xae: util::stream_format(stream, "xra m"); break;
- case 0xaf: util::stream_format(stream, "xra a"); break;
- case 0xb0: util::stream_format(stream, "ora b"); break;
- case 0xb1: util::stream_format(stream, "ora c"); break;
- case 0xb2: util::stream_format(stream, "ora d"); break;
- case 0xb3: util::stream_format(stream, "ora e"); break;
- case 0xb4: util::stream_format(stream, "ora h"); break;
- case 0xb5: util::stream_format(stream, "ora l"); break;
- case 0xb6: util::stream_format(stream, "ora m"); break;
- case 0xb7: util::stream_format(stream, "ora a"); break;
- case 0xb8: util::stream_format(stream, "cmp b"); break;
- case 0xb9: util::stream_format(stream, "cmp c"); break;
- case 0xba: util::stream_format(stream, "cmp d"); break;
- case 0xbb: util::stream_format(stream, "cmp e"); break;
- case 0xbc: util::stream_format(stream, "cmp h"); break;
- case 0xbd: util::stream_format(stream, "cmp l"); break;
- case 0xbe: util::stream_format(stream, "cmp m"); break;
- case 0xbf: util::stream_format(stream, "cmp a"); break;
- case 0xc0: util::stream_format(stream, "rnz"); flags = DASMFLAG_STEP_OUT; break;
- case 0xc1: util::stream_format(stream, "pop b"); break;
- case 0xc2: util::stream_format(stream, "jnz $%04x", ARGW(pc)); pc+=2; break;
- case 0xc3: util::stream_format(stream, "jmp $%04x", ARGW(pc)); pc+=2; break;
- case 0xc4: util::stream_format(stream, "cnz $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xc5: util::stream_format(stream, "push b"); break;
- case 0xc6: util::stream_format(stream, "adi $%02x", ARG(pc)); pc++; break;
- case 0xc7: util::stream_format(stream, "rst 0"); flags = DASMFLAG_STEP_OVER; break;
- case 0xc8: util::stream_format(stream, "rz"); flags = DASMFLAG_STEP_OUT; break;
- case 0xc9: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break;
- case 0xca: util::stream_format(stream, "jz $%04x", ARGW(pc)); pc+=2; break;
- case 0xcb: util::stream_format(stream, "rstv 8 (*)"); flags = DASMFLAG_STEP_OVER; break;
- case 0xcc: util::stream_format(stream, "cz $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xcd: util::stream_format(stream, "call $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xce: util::stream_format(stream, "aci $%02x", ARG(pc)); pc++; break;
- case 0xcf: util::stream_format(stream, "rst 1"); flags = DASMFLAG_STEP_OVER; break;
- case 0xd0: util::stream_format(stream, "rnc"); flags = DASMFLAG_STEP_OUT; break;
- case 0xd1: util::stream_format(stream, "pop d"); break;
- case 0xd2: util::stream_format(stream, "jnc $%04x", ARGW(pc)); pc+=2; break;
- case 0xd3: util::stream_format(stream, "out $%02x", ARG(pc)); pc++; break;
- case 0xd4: util::stream_format(stream, "cnc $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xd5: util::stream_format(stream, "push d"); break;
- case 0xd6: util::stream_format(stream, "sui $%02x", ARG(pc)); pc++; break;
- case 0xd7: util::stream_format(stream, "rst 2"); flags = DASMFLAG_STEP_OVER; break;
- case 0xd8: util::stream_format(stream, "rc"); flags = DASMFLAG_STEP_OUT; break;
- case 0xd9: util::stream_format(stream, "shlx d (*)"); break;
- case 0xda: util::stream_format(stream, "jc $%04x", ARGW(pc)); pc+=2; break;
- case 0xdb: util::stream_format(stream, "in $%02x", ARG(pc)); pc++; break;
- case 0xdc: util::stream_format(stream, "cc $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xdd: util::stream_format(stream, "jnx $%04x (*)", ARGW(pc)); pc+=2; break;
- case 0xde: util::stream_format(stream, "sbi $%02x", ARG(pc)); pc++; break;
- case 0xdf: util::stream_format(stream, "rst 3"); flags = DASMFLAG_STEP_OVER; break;
- case 0xe0: util::stream_format(stream, "rpo"); flags = DASMFLAG_STEP_OUT; break;
- case 0xe1: util::stream_format(stream, "pop h"); break;
- case 0xe2: util::stream_format(stream, "jpo $%04x", ARGW(pc)); pc+=2; break;
- case 0xe3: util::stream_format(stream, "xthl"); break;
- case 0xe4: util::stream_format(stream, "cpo $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xe5: util::stream_format(stream, "push h"); break;
- case 0xe6: util::stream_format(stream, "ani $%02x", ARG(pc)); pc++; break;
- case 0xe7: util::stream_format(stream, "rst 4"); flags = DASMFLAG_STEP_OVER; break;
- case 0xe8: util::stream_format(stream, "rpe"); flags = DASMFLAG_STEP_OUT; break;
- case 0xe9: util::stream_format(stream, "pchl"); break;
- case 0xea: util::stream_format(stream, "jpe $%04x", ARGW(pc)); pc+=2; break;
- case 0xeb: util::stream_format(stream, "xchg"); break;
- case 0xec: util::stream_format(stream, "cpe $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xed: util::stream_format(stream, "lhlx d (*)"); break;
- case 0xee: util::stream_format(stream, "xri $%02x", ARG(pc)); pc++; break;
- case 0xef: util::stream_format(stream, "rst 5"); flags = DASMFLAG_STEP_OVER; break;
- case 0xf0: util::stream_format(stream, "rp"); flags = DASMFLAG_STEP_OUT; break;
- case 0xf1: util::stream_format(stream, "pop psw"); break;
- case 0xf2: util::stream_format(stream, "jp $%04x", ARGW(pc)); pc+=2; break;
- case 0xf3: util::stream_format(stream, "di"); break;
- case 0xf4: util::stream_format(stream, "cp $%04x", ARGW(pc)); pc+=2; break;
- case 0xf5: util::stream_format(stream, "push psw"); break;
- case 0xf6: util::stream_format(stream, "ori $%02x", ARG(pc)); pc++; break;
- case 0xf7: util::stream_format(stream, "rst 6"); flags = DASMFLAG_STEP_OVER; break;
- case 0xf8: util::stream_format(stream, "rm"); flags = DASMFLAG_STEP_OUT; break;
- case 0xf9: util::stream_format(stream, "sphl"); break;
- case 0xfa: util::stream_format(stream, "jm $%04x", ARGW(pc)); pc+=2; break;
- case 0xfb: util::stream_format(stream, "ei"); break;
- case 0xfc: util::stream_format(stream, "cm $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break;
- case 0xfd: util::stream_format(stream, "jx $%04x (*)", ARGW(pc)); pc+=2; break;
- case 0xfe: util::stream_format(stream, "cpi $%02x", ARG(pc)); pc++; break;
- case 0xff: util::stream_format(stream, "rst 7"); flags = DASMFLAG_STEP_OVER; break;
-#endif
+ case 0x00: util::stream_format(stream, "nop"); break;
+ case 0x01: util::stream_format(stream, "lxi b,$%04x", params.r16(pc)); pc+=2; break;
+ case 0x02: util::stream_format(stream, "stax b"); break;
+ case 0x03: util::stream_format(stream, "inx b"); break;
+ case 0x04: util::stream_format(stream, "inr b"); break;
+ case 0x05: util::stream_format(stream, "dcr b"); break;
+ case 0x06: util::stream_format(stream, "mvi b,$%02x", params.r8(pc)); pc++; break;
+ case 0x07: util::stream_format(stream, "rlc"); break;
+ case 0x08: util::stream_format(stream, "dsub (*)"); break;
+ case 0x09: util::stream_format(stream, "dad b"); break;
+ case 0x0a: util::stream_format(stream, "ldax b"); break;
+ case 0x0b: util::stream_format(stream, "dcx b"); break;
+ case 0x0c: util::stream_format(stream, "inr c"); break;
+ case 0x0d: util::stream_format(stream, "dcr c"); break;
+ case 0x0e: util::stream_format(stream, "mvi c,$%02x", params.r8(pc)); pc++; break;
+ case 0x0f: util::stream_format(stream, "rrc"); break;
+ case 0x10: util::stream_format(stream, "asrh (*)"); break;
+ case 0x11: util::stream_format(stream, "lxi d,$%04x", params.r16(pc)); pc+=2; break;
+ case 0x12: util::stream_format(stream, "stax d"); break;
+ case 0x13: util::stream_format(stream, "inx d"); break;
+ case 0x14: util::stream_format(stream, "inr d"); break;
+ case 0x15: util::stream_format(stream, "dcr d"); break;
+ case 0x16: util::stream_format(stream, "mvi d,$%02x", params.r8(pc)); pc++; break;
+ case 0x17: util::stream_format(stream, "ral"); break;
+ case 0x18: util::stream_format(stream, "rlde (*)"); break;
+ case 0x19: util::stream_format(stream, "dad d"); break;
+ case 0x1a: util::stream_format(stream, "ldax d"); break;
+ case 0x1b: util::stream_format(stream, "dcx d"); break;
+ case 0x1c: util::stream_format(stream, "inr e"); break;
+ case 0x1d: util::stream_format(stream, "dcr e"); break;
+ case 0x1e: util::stream_format(stream, "mvi e,$%02x", params.r8(pc)); pc++; break;
+ case 0x1f: util::stream_format(stream, "rar"); break;
+ case 0x20: util::stream_format(stream, "rim"); break;
+ case 0x21: util::stream_format(stream, "lxi h,$%04x", params.r16(pc)); pc+=2; break;
+ case 0x22: util::stream_format(stream, "shld $%04x", params.r16(pc)); pc+=2; break;
+ case 0x23: util::stream_format(stream, "inx h"); break;
+ case 0x24: util::stream_format(stream, "inr h"); break;
+ case 0x25: util::stream_format(stream, "dcr h"); break;
+ case 0x26: util::stream_format(stream, "mvi h,$%02x", params.r8(pc)); pc++; break;
+ case 0x27: util::stream_format(stream, "daa"); break;
+ case 0x28: util::stream_format(stream, "ldeh $%02x (*)", params.r8(pc)); pc++; break;
+ case 0x29: util::stream_format(stream, "dad h"); break;
+ case 0x2a: util::stream_format(stream, "lhld $%04x", params.r16(pc)); pc+=2; break;
+ case 0x2b: util::stream_format(stream, "dcx h"); break;
+ case 0x2c: util::stream_format(stream, "inr l"); break;
+ case 0x2d: util::stream_format(stream, "dcr l"); break;
+ case 0x2e: util::stream_format(stream, "mvi l,$%02x", params.r8(pc)); pc++; break;
+ case 0x2f: util::stream_format(stream, "cma"); break;
+ case 0x30: util::stream_format(stream, "sim"); break;
+ case 0x31: util::stream_format(stream, "lxi sp,$%04x", params.r16(pc)); pc+=2; break;
+ case 0x32: util::stream_format(stream, "stax $%04x", params.r16(pc)); pc+=2; break;
+ case 0x33: util::stream_format(stream, "inx sp"); break;
+ case 0x34: util::stream_format(stream, "inr m"); break;
+ case 0x35: util::stream_format(stream, "dcr m"); break;
+ case 0x36: util::stream_format(stream, "mvi m,$%02x", params.r8(pc)); pc++; break;
+ case 0x37: util::stream_format(stream, "stc"); break;
+ case 0x38: util::stream_format(stream, "ldes $%02x (*)", params.r8(pc)); pc++; break;
+ case 0x39: util::stream_format(stream, "dad sp"); break;
+ case 0x3a: util::stream_format(stream, "ldax $%04x", params.r16(pc)); pc+=2; break;
+ case 0x3b: util::stream_format(stream, "dcx sp"); break;
+ case 0x3c: util::stream_format(stream, "inr a"); break;
+ case 0x3d: util::stream_format(stream, "dcr a"); break;
+ case 0x3e: util::stream_format(stream, "mvi a,$%02x", params.r8(pc)); pc++; break;
+ case 0x3f: util::stream_format(stream, "cmc"); break;
+ case 0x40: util::stream_format(stream, "mov b,b"); break;
+ case 0x41: util::stream_format(stream, "mov b,c"); break;
+ case 0x42: util::stream_format(stream, "mov b,d"); break;
+ case 0x43: util::stream_format(stream, "mov b,e"); break;
+ case 0x44: util::stream_format(stream, "mov b,h"); break;
+ case 0x45: util::stream_format(stream, "mov b,l"); break;
+ case 0x46: util::stream_format(stream, "mov b,m"); break;
+ case 0x47: util::stream_format(stream, "mov b,a"); break;
+ case 0x48: util::stream_format(stream, "mov c,b"); break;
+ case 0x49: util::stream_format(stream, "mov c,c"); break;
+ case 0x4a: util::stream_format(stream, "mov c,d"); break;
+ case 0x4b: util::stream_format(stream, "mov c,e"); break;
+ case 0x4c: util::stream_format(stream, "mov c,h"); break;
+ case 0x4d: util::stream_format(stream, "mov c,l"); break;
+ case 0x4e: util::stream_format(stream, "mov c,m"); break;
+ case 0x4f: util::stream_format(stream, "mov c,a"); break;
+ case 0x50: util::stream_format(stream, "mov d,b"); break;
+ case 0x51: util::stream_format(stream, "mov d,c"); break;
+ case 0x52: util::stream_format(stream, "mov d,d"); break;
+ case 0x53: util::stream_format(stream, "mov d,e"); break;
+ case 0x54: util::stream_format(stream, "mov d,h"); break;
+ case 0x55: util::stream_format(stream, "mov d,l"); break;
+ case 0x56: util::stream_format(stream, "mov d,m"); break;
+ case 0x57: util::stream_format(stream, "mov d,a"); break;
+ case 0x58: util::stream_format(stream, "mov e,b"); break;
+ case 0x59: util::stream_format(stream, "mov e,c"); break;
+ case 0x5a: util::stream_format(stream, "mov e,d"); break;
+ case 0x5b: util::stream_format(stream, "mov e,e"); break;
+ case 0x5c: util::stream_format(stream, "mov e,h"); break;
+ case 0x5d: util::stream_format(stream, "mov e,l"); break;
+ case 0x5e: util::stream_format(stream, "mov e,m"); break;
+ case 0x5f: util::stream_format(stream, "mov e,a"); break;
+ case 0x60: util::stream_format(stream, "mov h,b"); break;
+ case 0x61: util::stream_format(stream, "mov h,c"); break;
+ case 0x62: util::stream_format(stream, "mov h,d"); break;
+ case 0x63: util::stream_format(stream, "mov h,e"); break;
+ case 0x64: util::stream_format(stream, "mov h,h"); break;
+ case 0x65: util::stream_format(stream, "mov h,l"); break;
+ case 0x66: util::stream_format(stream, "mov h,m"); break;
+ case 0x67: util::stream_format(stream, "mov h,a"); break;
+ case 0x68: util::stream_format(stream, "mov l,b"); break;
+ case 0x69: util::stream_format(stream, "mov l,c"); break;
+ case 0x6a: util::stream_format(stream, "mov l,d"); break;
+ case 0x6b: util::stream_format(stream, "mov l,e"); break;
+ case 0x6c: util::stream_format(stream, "mov l,h"); break;
+ case 0x6d: util::stream_format(stream, "mov l,l"); break;
+ case 0x6e: util::stream_format(stream, "mov l,m"); break;
+ case 0x6f: util::stream_format(stream, "mov l,a"); break;
+ case 0x70: util::stream_format(stream, "mov m,b"); break;
+ case 0x71: util::stream_format(stream, "mov m,c"); break;
+ case 0x72: util::stream_format(stream, "mov m,d"); break;
+ case 0x73: util::stream_format(stream, "mov m,e"); break;
+ case 0x74: util::stream_format(stream, "mov m,h"); break;
+ case 0x75: util::stream_format(stream, "mov m,l"); break;
+ case 0x76: util::stream_format(stream, "hlt"); break;
+ case 0x77: util::stream_format(stream, "mov m,a"); break;
+ case 0x78: util::stream_format(stream, "mov a,b"); break;
+ case 0x79: util::stream_format(stream, "mov a,c"); break;
+ case 0x7a: util::stream_format(stream, "mov a,d"); break;
+ case 0x7b: util::stream_format(stream, "mov a,e"); break;
+ case 0x7c: util::stream_format(stream, "mov a,h"); break;
+ case 0x7d: util::stream_format(stream, "mov a,l"); break;
+ case 0x7e: util::stream_format(stream, "mov a,m"); break;
+ case 0x7f: util::stream_format(stream, "mov a,a"); break;
+ case 0x80: util::stream_format(stream, "add b"); break;
+ case 0x81: util::stream_format(stream, "add c"); break;
+ case 0x82: util::stream_format(stream, "add d"); break;
+ case 0x83: util::stream_format(stream, "add e"); break;
+ case 0x84: util::stream_format(stream, "add h"); break;
+ case 0x85: util::stream_format(stream, "add l"); break;
+ case 0x86: util::stream_format(stream, "add m"); break;
+ case 0x87: util::stream_format(stream, "add a"); break;
+ case 0x88: util::stream_format(stream, "adc b"); break;
+ case 0x89: util::stream_format(stream, "adc c"); break;
+ case 0x8a: util::stream_format(stream, "adc d"); break;
+ case 0x8b: util::stream_format(stream, "adc e"); break;
+ case 0x8c: util::stream_format(stream, "adc h"); break;
+ case 0x8d: util::stream_format(stream, "adc l"); break;
+ case 0x8e: util::stream_format(stream, "adc m"); break;
+ case 0x8f: util::stream_format(stream, "adc a"); break;
+ case 0x90: util::stream_format(stream, "sub b"); break;
+ case 0x91: util::stream_format(stream, "sub c"); break;
+ case 0x92: util::stream_format(stream, "sub d"); break;
+ case 0x93: util::stream_format(stream, "sub e"); break;
+ case 0x94: util::stream_format(stream, "sub h"); break;
+ case 0x95: util::stream_format(stream, "sub l"); break;
+ case 0x96: util::stream_format(stream, "sub m"); break;
+ case 0x97: util::stream_format(stream, "sub a"); break;
+ case 0x98: util::stream_format(stream, "sbb b"); break;
+ case 0x99: util::stream_format(stream, "sbb c"); break;
+ case 0x9a: util::stream_format(stream, "sbb d"); break;
+ case 0x9b: util::stream_format(stream, "sbb e"); break;
+ case 0x9c: util::stream_format(stream, "sbb h"); break;
+ case 0x9d: util::stream_format(stream, "sbb l"); break;
+ case 0x9e: util::stream_format(stream, "sbb m"); break;
+ case 0x9f: util::stream_format(stream, "sbb a"); break;
+ case 0xa0: util::stream_format(stream, "ana b"); break;
+ case 0xa1: util::stream_format(stream, "ana c"); break;
+ case 0xa2: util::stream_format(stream, "ana d"); break;
+ case 0xa3: util::stream_format(stream, "ana e"); break;
+ case 0xa4: util::stream_format(stream, "ana h"); break;
+ case 0xa5: util::stream_format(stream, "ana l"); break;
+ case 0xa6: util::stream_format(stream, "ana m"); break;
+ case 0xa7: util::stream_format(stream, "ana a"); break;
+ case 0xa8: util::stream_format(stream, "xra b"); break;
+ case 0xa9: util::stream_format(stream, "xra c"); break;
+ case 0xaa: util::stream_format(stream, "xra d"); break;
+ case 0xab: util::stream_format(stream, "xra e"); break;
+ case 0xac: util::stream_format(stream, "xra h"); break;
+ case 0xad: util::stream_format(stream, "xra l"); break;
+ case 0xae: util::stream_format(stream, "xra m"); break;
+ case 0xaf: util::stream_format(stream, "xra a"); break;
+ case 0xb0: util::stream_format(stream, "ora b"); break;
+ case 0xb1: util::stream_format(stream, "ora c"); break;
+ case 0xb2: util::stream_format(stream, "ora d"); break;
+ case 0xb3: util::stream_format(stream, "ora e"); break;
+ case 0xb4: util::stream_format(stream, "ora h"); break;
+ case 0xb5: util::stream_format(stream, "ora l"); break;
+ case 0xb6: util::stream_format(stream, "ora m"); break;
+ case 0xb7: util::stream_format(stream, "ora a"); break;
+ case 0xb8: util::stream_format(stream, "cmp b"); break;
+ case 0xb9: util::stream_format(stream, "cmp c"); break;
+ case 0xba: util::stream_format(stream, "cmp d"); break;
+ case 0xbb: util::stream_format(stream, "cmp e"); break;
+ case 0xbc: util::stream_format(stream, "cmp h"); break;
+ case 0xbd: util::stream_format(stream, "cmp l"); break;
+ case 0xbe: util::stream_format(stream, "cmp m"); break;
+ case 0xbf: util::stream_format(stream, "cmp a"); break;
+ case 0xc0: util::stream_format(stream, "rnz"); flags = STEP_OUT; break;
+ case 0xc1: util::stream_format(stream, "pop b"); break;
+ case 0xc2: util::stream_format(stream, "jnz $%04x", params.r16(pc)); pc+=2; break;
+ case 0xc3: util::stream_format(stream, "jmp $%04x", params.r16(pc)); pc+=2; break;
+ case 0xc4: util::stream_format(stream, "cnz $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xc5: util::stream_format(stream, "push b"); break;
+ case 0xc6: util::stream_format(stream, "adi $%02x", params.r8(pc)); pc++; break;
+ case 0xc7: util::stream_format(stream, "rst 0"); flags = STEP_OVER; break;
+ case 0xc8: util::stream_format(stream, "rz"); flags = STEP_OUT; break;
+ case 0xc9: util::stream_format(stream, "ret"); flags = STEP_OUT; break;
+ case 0xca: util::stream_format(stream, "jz $%04x", params.r16(pc)); pc+=2; break;
+ case 0xcb: util::stream_format(stream, "rstv 8 (*)"); flags = STEP_OVER; break;
+ case 0xcc: util::stream_format(stream, "cz $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xcd: util::stream_format(stream, "call $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xce: util::stream_format(stream, "aci $%02x", params.r8(pc)); pc++; break;
+ case 0xcf: util::stream_format(stream, "rst 1"); flags = STEP_OVER; break;
+ case 0xd0: util::stream_format(stream, "rnc"); flags = STEP_OUT; break;
+ case 0xd1: util::stream_format(stream, "pop d"); break;
+ case 0xd2: util::stream_format(stream, "jnc $%04x", params.r16(pc)); pc+=2; break;
+ case 0xd3: util::stream_format(stream, "out $%02x", params.r8(pc)); pc++; break;
+ case 0xd4: util::stream_format(stream, "cnc $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xd5: util::stream_format(stream, "push d"); break;
+ case 0xd6: util::stream_format(stream, "sui $%02x", params.r8(pc)); pc++; break;
+ case 0xd7: util::stream_format(stream, "rst 2"); flags = STEP_OVER; break;
+ case 0xd8: util::stream_format(stream, "rc"); flags = STEP_OUT; break;
+ case 0xd9: util::stream_format(stream, "shlx d (*)"); break;
+ case 0xda: util::stream_format(stream, "jc $%04x", params.r16(pc)); pc+=2; break;
+ case 0xdb: util::stream_format(stream, "in $%02x", params.r8(pc)); pc++; break;
+ case 0xdc: util::stream_format(stream, "cc $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xdd: util::stream_format(stream, "jnx $%04x (*)", params.r16(pc)); pc+=2; break;
+ case 0xde: util::stream_format(stream, "sbi $%02x", params.r8(pc)); pc++; break;
+ case 0xdf: util::stream_format(stream, "rst 3"); flags = STEP_OVER; break;
+ case 0xe0: util::stream_format(stream, "rpo"); flags = STEP_OUT; break;
+ case 0xe1: util::stream_format(stream, "pop h"); break;
+ case 0xe2: util::stream_format(stream, "jpo $%04x", params.r16(pc)); pc+=2; break;
+ case 0xe3: util::stream_format(stream, "xthl"); break;
+ case 0xe4: util::stream_format(stream, "cpo $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xe5: util::stream_format(stream, "push h"); break;
+ case 0xe6: util::stream_format(stream, "ani $%02x", params.r8(pc)); pc++; break;
+ case 0xe7: util::stream_format(stream, "rst 4"); flags = STEP_OVER; break;
+ case 0xe8: util::stream_format(stream, "rpe"); flags = STEP_OUT; break;
+ case 0xe9: util::stream_format(stream, "pchl"); break;
+ case 0xea: util::stream_format(stream, "jpe $%04x", params.r16(pc)); pc+=2; break;
+ case 0xeb: util::stream_format(stream, "xchg"); break;
+ case 0xec: util::stream_format(stream, "cpe $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xed: util::stream_format(stream, "lhlx d (*)"); break;
+ case 0xee: util::stream_format(stream, "xri $%02x", params.r8(pc)); pc++; break;
+ case 0xef: util::stream_format(stream, "rst 5"); flags = STEP_OVER; break;
+ case 0xf0: util::stream_format(stream, "rp"); flags = STEP_OUT; break;
+ case 0xf1: util::stream_format(stream, "pop psw"); break;
+ case 0xf2: util::stream_format(stream, "jp $%04x", params.r16(pc)); pc+=2; break;
+ case 0xf3: util::stream_format(stream, "di"); break;
+ case 0xf4: util::stream_format(stream, "cp $%04x", params.r16(pc)); pc+=2; break;
+ case 0xf5: util::stream_format(stream, "push psw"); break;
+ case 0xf6: util::stream_format(stream, "ori $%02x", params.r8(pc)); pc++; break;
+ case 0xf7: util::stream_format(stream, "rst 6"); flags = STEP_OVER; break;
+ case 0xf8: util::stream_format(stream, "rm"); flags = STEP_OUT; break;
+ case 0xf9: util::stream_format(stream, "sphl"); break;
+ case 0xfa: util::stream_format(stream, "jm $%04x", params.r16(pc)); pc+=2; break;
+ case 0xfb: util::stream_format(stream, "ei"); break;
+ case 0xfc: util::stream_format(stream, "cm $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break;
+ case 0xfd: util::stream_format(stream, "jx $%04x (*)", params.r16(pc)); pc+=2; break;
+ case 0xfe: util::stream_format(stream, "cpi $%02x", params.r8(pc)); pc++; break;
+ case 0xff: util::stream_format(stream, "rst 7"); flags = STEP_OVER; break;
}
- return (pc - PC) | flags | DASMFLAG_SUPPORTED;
+ return (pc - prevpc) | flags | SUPPORTED;
}
diff --git a/src/devices/cpu/i8085/8085dasm.h b/src/devices/cpu/i8085/8085dasm.h
new file mode 100644
index 00000000000..1aad019848d
--- /dev/null
+++ b/src/devices/cpu/i8085/8085dasm.h
@@ -0,0 +1,24 @@
+// license:BSD-3-Clause
+// copyright-holders:Juergen Buchmueller
+/*****************************************************************************
+ *
+ * Portable I8085A disassembler
+ *
+ *****************************************************************************/
+
+#ifndef MAME_CPU_I8085_8085DASM_H
+#define MAME_CPU_I8085_8085DASM_H
+
+#pragma once
+
+class i8085_disassembler : public util::disasm_interface
+{
+public:
+ i8085_disassembler() = default;
+ virtual ~i8085_disassembler() = default;
+
+ virtual u32 opcode_alignment() const override;
+ virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+};
+
+#endif
diff --git a/src/devices/cpu/i8085/i8085.cpp b/src/devices/cpu/i8085/i8085.cpp
index 75a2360dc63..5e984464cf3 100644
--- a/src/devices/cpu/i8085/i8085.cpp
+++ b/src/devices/cpu/i8085/i8085.cpp
@@ -1,13 +1,19 @@
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller, hap
+// thanks-to:Marcel De Kogel
/*****************************************************************************
*
- * i8085.c
* Portable I8085A emulator V1.2
*
* Copyright Juergen Buchmueller, all rights reserved.
* Partially based on information out of Z80Em by Marcel De Kogel
*
+ * TODO:
+ * - 8085 DAA fails on 8080/8085 CPU Exerciser
+ * - not sure if 8085 DSUB H flag is correct
+ *
+ * ---------------------------------------------------------------------------
+ *
* changes in V1.3
* - Added undocumented opcodes for the 8085A, based on a german
* book about microcomputers: "Mikrocomputertechnik mit dem
@@ -103,23 +109,38 @@
#include "emu.h"
#include "debugger.h"
#include "i8085.h"
-#include "i8085cpu.h"
+#include "8085dasm.h"
#define VERBOSE 0
#include "logmacro.h"
-#define CPUTYPE_8080 0
-#define CPUTYPE_8085 1
-
-
/***************************************************************************
- MACROS
+ CONSTANTS
***************************************************************************/
-#define IS_8080() (m_cputype == CPUTYPE_8080)
-#define IS_8085() (m_cputype == CPUTYPE_8085)
-
+constexpr u8 SF = 0x80;
+constexpr u8 ZF = 0x40;
+constexpr u8 X5F = 0x20;
+constexpr u8 HF = 0x10;
+constexpr u8 X3F = 0x08;
+constexpr u8 PF = 0x04;
+constexpr u8 VF = 0x02;
+constexpr u8 CF = 0x01;
+
+constexpr u8 IM_SID = 0x80;
+constexpr u8 IM_I75 = 0x40;
+constexpr u8 IM_I65 = 0x20;
+constexpr u8 IM_I55 = 0x10;
+constexpr u8 IM_IE = 0x08;
+constexpr u8 IM_M75 = 0x04;
+constexpr u8 IM_M65 = 0x02;
+constexpr u8 IM_M55 = 0x01;
+
+constexpr u16 ADDR_TRAP = 0x0024;
+constexpr u16 ADDR_RST55 = 0x002c;
+constexpr u16 ADDR_RST65 = 0x0034;
+constexpr u16 ADDR_RST75 = 0x003c;
/***************************************************************************
@@ -127,7 +148,7 @@
***************************************************************************/
/* cycles lookup */
-const uint8_t i8085a_cpu_device::lut_cycles_8080[256]={
+const u8 i8085a_cpu_device::lut_cycles_8080[256]={
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 0 */ 4, 10,7, 5, 5, 5, 7, 4, 4, 10,7, 5, 5, 5, 7, 4,
/* 1 */ 4, 10,7, 5, 5, 5, 7, 4, 4, 10,7, 5, 5, 5, 7, 4,
@@ -145,7 +166,7 @@ const uint8_t i8085a_cpu_device::lut_cycles_8080[256]={
/* D */ 5, 10,10,10,11,11,7, 11,5, 10,10,10,11,11,7, 11,
/* E */ 5, 10,10,18,11,11,7, 11,5, 5, 10,5, 11,11,7, 11,
/* F */ 5, 10,10,4, 11,11,7, 11,5, 5, 10,4, 11,11,7, 11 };
-const uint8_t i8085a_cpu_device::lut_cycles_8085[256]={
+const u8 i8085a_cpu_device::lut_cycles_8085[256]={
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 0 */ 4, 10,7, 6, 4, 4, 7, 4, 10,10,7, 6, 4, 4, 7, 4,
/* 1 */ 7, 10,7, 6, 4, 4, 7, 4, 10,10,7, 6, 4, 4, 7, 4,
@@ -165,13 +186,13 @@ const uint8_t i8085a_cpu_device::lut_cycles_8085[256]={
/* F */ 6, 10,10,4, 11,12,7, 12,6, 6, 10,4, 11,10,7, 12 };
/* special cases (partially taken care of elsewhere):
- base c taken? not taken?
-M_RET 8080 5 +6(11) -0 (conditional)
-M_RET 8085 6 +6(12) -0 (conditional)
-M_JMP 8080 10 +0 -0
-M_JMP 8085 10 +0 -3(7)
-M_CALL 8080 11 +6(17) -0
-M_CALL 8085 11 +7(18) -2(9)
+ base c taken? not taken?
+op_ret 8080 5 +6(11) -0 (conditional)
+op_ret 8085 6 +6(12) -0 (conditional)
+op_jmp 8080 10 +0 -0
+op_jmp 8085 10 +0 -3(7)
+op_call 8080 11 +6(17) -0
+op_call 8085 11 +7(18) -2(9)
*/
@@ -181,16 +202,16 @@ DEFINE_DEVICE_TYPE(I8080A, i8080a_cpu_device, "i8080a", "8080A")
DEFINE_DEVICE_TYPE(I8085A, i8085a_cpu_device, "i8085a", "8085A")
-i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : i8085a_cpu_device(mconfig, I8085A, tag, owner, clock, CPUTYPE_8085)
+i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : i8085a_cpu_device(mconfig, I8085A, tag, owner, clock, CPUTYPE_8085A)
{
}
-
-i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cputype)
+i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int cputype)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
, m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0)
+ , m_opcode_config("opcodes", ENDIANNESS_LITTLE, 8, 16, 0)
, m_out_status_func(*this)
, m_out_inte_func(*this)
, m_in_sid_func(*this)
@@ -199,21 +220,23 @@ i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type
{
}
-
-i8080_cpu_device::i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8080_cpu_device::i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: i8085a_cpu_device(mconfig, I8080, tag, owner, clock, CPUTYPE_8080)
{
}
-
-i8080a_cpu_device::i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : i8085a_cpu_device(mconfig, I8080A, tag, owner, clock, CPUTYPE_8080)
+i8080a_cpu_device::i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : i8085a_cpu_device(mconfig, I8080A, tag, owner, clock, CPUTYPE_8080A)
{
}
device_memory_interface::space_config_vector i8085a_cpu_device::memory_space_config() const
{
- return space_config_vector {
+ return has_configured_map(AS_OPCODES) ? space_config_vector {
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_IO, &m_io_config),
+ std::make_pair(AS_OPCODES, &m_opcode_config)
+ } : space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config),
std::make_pair(AS_IO, &m_io_config)
};
@@ -235,664 +258,18 @@ void i8085a_cpu_device::device_clock_changed()
}
-void i8085a_cpu_device::set_sod(int state)
-{
- if (state != 0 && m_sod_state == 0)
- {
- m_sod_state = 1;
- m_out_sod_func(m_sod_state);
- }
- else if (state == 0 && m_sod_state != 0)
- {
- m_sod_state = 0;
- m_out_sod_func(m_sod_state);
- }
-}
-
-
-void i8085a_cpu_device::set_inte(int state)
-{
- if (state != 0 && (m_IM & IM_IE) == 0)
- {
- m_IM |= IM_IE;
- m_out_inte_func(1);
- }
- else if (state == 0 && (m_IM & IM_IE) != 0)
- {
- m_IM &= ~IM_IE;
- m_out_inte_func(0);
- }
-}
-
-
-void i8085a_cpu_device::set_status(uint8_t status)
-{
- if (status != m_STATUS)
- m_out_status_func(status);
-
- m_STATUS = status;
-}
-
-
-uint8_t i8085a_cpu_device::get_rim_value()
-{
- uint8_t result = m_IM;
- int sid = m_in_sid_func();
-
- /* copy live RST5.5 and RST6.5 states */
- result &= ~(IM_I65 | IM_I55);
- if (m_irq_state[I8085_RST65_LINE]) result |= IM_I65;
- if (m_irq_state[I8085_RST55_LINE]) result |= IM_I55;
-
- /* fetch the SID bit if we have a callback */
- result = (result & ~IM_SID) | (sid ? IM_SID : 0);
-
- return result;
-}
-
-
-void i8085a_cpu_device::break_halt_for_interrupt()
-{
- /* de-halt if necessary */
- if (m_HALT)
- {
- m_PC.w.l++;
- m_HALT = 0;
- set_status(0x26); /* int ack while halt */
- }
- else
- set_status(0x23); /* int ack */
-}
-
-
-uint8_t i8085a_cpu_device::ROP()
-{
- set_status(0xa2); // instruction fetch
- return m_direct->read_byte(m_PC.w.l++);
-}
-
-uint8_t i8085a_cpu_device::ARG()
-{
- return m_direct->read_byte(m_PC.w.l++);
-}
-
-uint16_t i8085a_cpu_device::ARG16()
-{
- uint16_t w;
- w = m_direct->read_byte(m_PC.d);
- m_PC.w.l++;
- w += m_direct->read_byte(m_PC.d) << 8;
- m_PC.w.l++;
- return w;
-}
-
-uint8_t i8085a_cpu_device::RM(uint32_t a)
-{
- set_status(0x82); // memory read
- return m_program->read_byte(a);
-}
-
-void i8085a_cpu_device::WM(uint32_t a, uint8_t v)
-{
- set_status(0x00); // memory write
- m_program->write_byte(a, v);
-}
-
-
-void i8085a_cpu_device::check_for_interrupts()
-{
- /* TRAP is the highest priority */
- if (m_trap_pending)
- {
- /* the first RIM after a TRAP reflects the original IE state; remember it here,
- setting the high bit to indicate it is valid */
- m_trap_im_copy = m_IM | 0x80;
-
- /* reset the pending state */
- m_trap_pending = false;
-
- /* break out of HALT state and call the IRQ ack callback */
- break_halt_for_interrupt();
- standard_irq_callback(INPUT_LINE_NMI);
-
- /* push the PC and jump to $0024 */
- M_PUSH(PC);
- set_inte(0);
- m_PC.w.l = ADDR_TRAP;
- m_icount -= 11;
- }
-
- /* followed by RST7.5 */
- else if ((m_IM & IM_I75) && !(m_IM & IM_M75) && (m_IM & IM_IE))
- {
- /* reset the pending state (which is CPU-visible via the RIM instruction) */
- m_IM &= ~IM_I75;
-
- /* break out of HALT state and call the IRQ ack callback */
- break_halt_for_interrupt();
- standard_irq_callback(I8085_RST75_LINE);
-
- /* push the PC and jump to $003C */
- M_PUSH(PC);
- set_inte(0);
- m_PC.w.l = ADDR_RST75;
- m_icount -= 11;
- }
-
- /* followed by RST6.5 */
- else if (m_irq_state[I8085_RST65_LINE] && !(m_IM & IM_M65) && (m_IM & IM_IE))
- {
- /* break out of HALT state and call the IRQ ack callback */
- break_halt_for_interrupt();
- standard_irq_callback(I8085_RST65_LINE);
-
- /* push the PC and jump to $0034 */
- M_PUSH(PC);
- set_inte(0);
- m_PC.w.l = ADDR_RST65;
- m_icount -= 11;
- }
-
- /* followed by RST5.5 */
- else if (m_irq_state[I8085_RST55_LINE] && !(m_IM & IM_M55) && (m_IM & IM_IE))
- {
- /* break out of HALT state and call the IRQ ack callback */
- break_halt_for_interrupt();
- standard_irq_callback(I8085_RST55_LINE);
-
- /* push the PC and jump to $002C */
- M_PUSH(PC);
- set_inte(0);
- m_PC.w.l = ADDR_RST55;
- m_icount -= 11;
- }
-
- /* followed by classic INTR */
- else if (m_irq_state[I8085_INTR_LINE] && (m_IM & IM_IE))
- {
- uint32_t vector;
-
- /* break out of HALT state and call the IRQ ack callback */
- break_halt_for_interrupt();
- vector = standard_irq_callback(I8085_INTR_LINE);
-
- /* use the resulting vector as an opcode to execute */
- set_inte(0);
- switch (vector & 0xff0000)
- {
- case 0xcd0000: /* CALL nnnn */
- m_icount -= 7;
- M_PUSH(PC);
- case 0xc30000: /* JMP nnnn */
- m_icount -= 10;
- m_PC.d = vector & 0xffff;
- break;
-
- default:
- LOG("i8085 take int $%02x\n", vector);
- execute_one(vector & 0xff);
- break;
- }
- }
-}
-
-
-void i8085a_cpu_device::execute_one(int opcode)
-{
- m_icount -= lut_cycles[opcode];
-
- switch (opcode)
- {
- case 0x00: break; /* NOP */
- case 0x01: m_BC.w.l = ARG16(); break; /* LXI B,nnnn */
- case 0x02: WM(m_BC.d, m_AF.b.h); break; /* STAX B */
- case 0x03: m_BC.w.l++; /* INX B */
- if (IS_8085()) { if (m_BC.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x04: M_INR(m_BC.b.h); break; /* INR B */
- case 0x05: M_DCR(m_BC.b.h); break; /* DCR B */
- case 0x06: M_MVI(m_BC.b.h); break; /* MVI B,nn */
- case 0x07: M_RLC; break; /* RLC */
-
- case 0x08: if (IS_8085()) { M_DSUB(); } /* DSUB */
- /* else { ; } */ /* NOP undocumented */
- break;
- case 0x09: M_DAD(BC); break; /* DAD B */
- case 0x0a: m_AF.b.h = RM(m_BC.d); break; /* LDAX B */
- case 0x0b: m_BC.w.l--; /* DCX B */
- if (IS_8085()) { if (m_BC.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x0c: M_INR(m_BC.b.l); break; /* INR C */
- case 0x0d: M_DCR(m_BC.b.l); break; /* DCR C */
- case 0x0e: M_MVI(m_BC.b.l); break; /* MVI C,nn */
- case 0x0f: M_RRC; break; /* RRC */
-
- case 0x10: if (IS_8085()) { /* ASRH */
- m_AF.b.l = (m_AF.b.l & ~CF) | (m_HL.b.l & CF);
- m_HL.w.l = (m_HL.w.l >> 1);
- } /* else { ; } */ /* NOP undocumented */
- break;
- case 0x11: m_DE.w.l = ARG16(); break; /* LXI D,nnnn */
- case 0x12: WM(m_DE.d, m_AF.b.h); break; /* STAX D */
- case 0x13: m_DE.w.l++; /* INX D */
- if (IS_8085()) { if (m_DE.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x14: M_INR(m_DE.b.h); break; /* INR D */
- case 0x15: M_DCR(m_DE.b.h); break; /* DCR D */
- case 0x16: M_MVI(m_DE.b.h); break; /* MVI D,nn */
- case 0x17: M_RAL; break; /* RAL */
-
- case 0x18: if (IS_8085()) { /* RLDE */
- m_AF.b.l = (m_AF.b.l & ~(CF | VF)) | (m_DE.b.h >> 7);
- m_DE.w.l = (m_DE.w.l << 1) | (m_DE.w.l >> 15);
- if (0 != (((m_DE.w.l >> 15) ^ m_AF.b.l) & CF)) m_AF.b.l |= VF;
- } /* else { ; } */ /* NOP undocumented */
- break;
- case 0x19: M_DAD(DE); break; /* DAD D */
- case 0x1a: m_AF.b.h = RM(m_DE.d); break; /* LDAX D */
- case 0x1b: m_DE.w.l--; /* DCX D */
- if (IS_8085()) { if (m_DE.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x1c: M_INR(m_DE.b.l); break; /* INR E */
- case 0x1d: M_DCR(m_DE.b.l); break; /* DCR E */
- case 0x1e: M_MVI(m_DE.b.l); break; /* MVI E,nn */
- case 0x1f: M_RAR; break; /* RAR */
-
- case 0x20: if (IS_8085()) { /* RIM */
- m_AF.b.h = get_rim_value();
-
- /* if we have remembered state from taking a TRAP, fix up the IE flag here */
- if (m_trap_im_copy & 0x80) m_AF.b.h = (m_AF.b.h & ~IM_IE) | (m_trap_im_copy & IM_IE);
- m_trap_im_copy = 0;
- } /* else { ; } */ /* NOP undocumented */
- break;
- case 0x21: m_HL.w.l = ARG16(); break; /* LXI H,nnnn */
- case 0x22: m_WZ.w.l = ARG16(); /* SHLD nnnn */
- WM(m_WZ.d, m_HL.b.l); m_WZ.w.l++;
- WM(m_WZ.d, m_HL.b.h);
- break;
- case 0x23: m_HL.w.l++; /* INX H */
- if (IS_8085()) { if (m_HL.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x24: M_INR(m_HL.b.h); break; /* INR H */
- case 0x25: M_DCR(m_HL.b.h); break; /* DCR H */
- case 0x26: M_MVI(m_HL.b.h); break; /* MVI H,nn */
- case 0x27: m_WZ.b.h = m_AF.b.h; /* DAA */
- if (IS_8085() && m_AF.b.l&VF) {
- if ((m_AF.b.l&HF) | ((m_AF.b.h&0xf)>9)) m_WZ.b.h-=6;
- if ((m_AF.b.l&CF) | (m_AF.b.h>0x99)) m_WZ.b.h-=0x60;
- }
- else {
- if ((m_AF.b.l&HF) | ((m_AF.b.h&0xf)>9)) m_WZ.b.h+=6;
- if ((m_AF.b.l&CF) | (m_AF.b.h>0x99)) m_WZ.b.h+=0x60;
- }
-
- m_AF.b.l=(m_AF.b.l&3) | (m_AF.b.h&0x28) | (m_AF.b.h>0x99) | ((m_AF.b.h^m_WZ.b.h)&0x10) | ZSP[m_WZ.b.h];
- m_AF.b.h=m_WZ.b.h;
- break;
-
- case 0x28: if (IS_8085()) { /* LDEH nn */
- m_WZ.d = ARG();
- m_DE.d = (m_HL.d + m_WZ.d) & 0xffff;
- } /* else { ; } */ /* NOP undocumented */
- break;
- case 0x29: M_DAD(HL); break; /* DAD H */
- case 0x2a: m_WZ.d = ARG16(); /* LHLD nnnn */
- m_HL.b.l = RM(m_WZ.d); m_WZ.w.l++;
- m_HL.b.h = RM(m_WZ.d);
- break;
- case 0x2b: m_HL.w.l--; /* DCX H */
- if (IS_8085()) { if (m_HL.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x2c: M_INR(m_HL.b.l); break; /* INR L */
- case 0x2d: M_DCR(m_HL.b.l); break; /* DCR L */
- case 0x2e: M_MVI(m_HL.b.l); break; /* MVI L,nn */
- case 0x2f: m_AF.b.h ^= 0xff; /* CMA */
- if (IS_8085()) m_AF.b.l |= HF | VF;
- break;
-
- case 0x30: if (IS_8085()) { /* SIM */
- /* if bit 3 is set, bits 0-2 become the new masks */
- if (m_AF.b.h & 0x08) {
- m_IM &= ~(IM_M55 | IM_M65 | IM_M75 | IM_I55 | IM_I65);
- m_IM |= m_AF.b.h & (IM_M55 | IM_M65 | IM_M75);
-
- /* update live state based on the new masks */
- if ((m_IM & IM_M55) == 0 && m_irq_state[I8085_RST55_LINE]) m_IM |= IM_I55;
- if ((m_IM & IM_M65) == 0 && m_irq_state[I8085_RST65_LINE]) m_IM |= IM_I65;
- }
-
- /* bit if 4 is set, the 7.5 flip-flop is cleared */
- if (m_AF.b.h & 0x10) m_IM &= ~IM_I75;
-
- /* if bit 6 is set, then bit 7 is the new SOD state */
- if (m_AF.b.h & 0x40) set_sod(m_AF.b.h >> 7);
-
- /* check for revealed interrupts */
- check_for_interrupts();
- } /* else { ; } */ /* NOP undocumented */
- break;
- case 0x31: m_SP.w.l = ARG16(); break; /* LXI SP,nnnn */
- case 0x32: m_WZ.d = ARG16(); /* STAX nnnn */
- WM(m_WZ.d, m_AF.b.h);
- break;
- case 0x33: m_SP.w.l++; /* INX SP */
- if (IS_8085()) { if (m_SP.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x34: m_WZ.b.l = RM(m_HL.d); /* INR M */
- M_INR(m_WZ.b.l);
- WM(m_HL.d, m_WZ.b.l);
- break;
- case 0x35: m_WZ.b.l = RM(m_HL.d); /* DCR M */
- M_DCR(m_WZ.b.l);
- WM(m_HL.d, m_WZ.b.l);
- break;
- case 0x36: m_WZ.b.l = ARG(); /* MVI M,nn */
- WM(m_HL.d, m_WZ.b.l);
- break;
- case 0x37: m_AF.b.l = (m_AF.b.l & 0xfe) | CF; break; /* STC */
-
- case 0x38: if (IS_8085()) { /* LDES nn */
- m_WZ.d = ARG();
- m_DE.d = (m_SP.d + m_WZ.d) & 0xffff;
- } /* else { ; } */ /* NOP undocumented */
- break;
- case 0x39: M_DAD(SP); break; /* DAD SP */
- case 0x3a: m_WZ.d = ARG16(); /* LDAX nnnn */
- m_AF.b.h = RM(m_WZ.d);
- break;
- case 0x3b: m_SP.w.l--; /* DCX SP */
- if (IS_8085()) { if (m_SP.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; }
- break;
- case 0x3c: M_INR(m_AF.b.h); break; /* INR A */
- case 0x3d: M_DCR(m_AF.b.h); break; /* DCR A */
- case 0x3e: M_MVI(m_AF.b.h); break; /* MVI A,nn */
- case 0x3f: m_AF.b.l = (m_AF.b.l & 0xfe) | (~m_AF.b.l & CF); break; /* CMC */
-
- case 0x40: break; /* MOV B,B */
- case 0x41: m_BC.b.h = m_BC.b.l; break; /* MOV B,C */
- case 0x42: m_BC.b.h = m_DE.b.h; break; /* MOV B,D */
- case 0x43: m_BC.b.h = m_DE.b.l; break; /* MOV B,E */
- case 0x44: m_BC.b.h = m_HL.b.h; break; /* MOV B,H */
- case 0x45: m_BC.b.h = m_HL.b.l; break; /* MOV B,L */
- case 0x46: m_BC.b.h = RM(m_HL.d); break; /* MOV B,M */
- case 0x47: m_BC.b.h = m_AF.b.h; break; /* MOV B,A */
-
- case 0x48: m_BC.b.l = m_BC.b.h; break; /* MOV C,B */
- case 0x49: break; /* MOV C,C */
- case 0x4a: m_BC.b.l = m_DE.b.h; break; /* MOV C,D */
- case 0x4b: m_BC.b.l = m_DE.b.l; break; /* MOV C,E */
- case 0x4c: m_BC.b.l = m_HL.b.h; break; /* MOV C,H */
- case 0x4d: m_BC.b.l = m_HL.b.l; break; /* MOV C,L */
- case 0x4e: m_BC.b.l = RM(m_HL.d); break; /* MOV C,M */
- case 0x4f: m_BC.b.l = m_AF.b.h; break; /* MOV C,A */
-
- case 0x50: m_DE.b.h = m_BC.b.h; break; /* MOV D,B */
- case 0x51: m_DE.b.h = m_BC.b.l; break; /* MOV D,C */
- case 0x52: break; /* MOV D,D */
- case 0x53: m_DE.b.h = m_DE.b.l; break; /* MOV D,E */
- case 0x54: m_DE.b.h = m_HL.b.h; break; /* MOV D,H */
- case 0x55: m_DE.b.h = m_HL.b.l; break; /* MOV D,L */
- case 0x56: m_DE.b.h = RM(m_HL.d); break; /* MOV D,M */
- case 0x57: m_DE.b.h = m_AF.b.h; break; /* MOV D,A */
-
- case 0x58: m_DE.b.l = m_BC.b.h; break; /* MOV E,B */
- case 0x59: m_DE.b.l = m_BC.b.l; break; /* MOV E,C */
- case 0x5a: m_DE.b.l = m_DE.b.h; break; /* MOV E,D */
- case 0x5b: break; /* MOV E,E */
- case 0x5c: m_DE.b.l = m_HL.b.h; break; /* MOV E,H */
- case 0x5d: m_DE.b.l = m_HL.b.l; break; /* MOV E,L */
- case 0x5e: m_DE.b.l = RM(m_HL.d); break; /* MOV E,M */
- case 0x5f: m_DE.b.l = m_AF.b.h; break; /* MOV E,A */
-
- case 0x60: m_HL.b.h = m_BC.b.h; break; /* MOV H,B */
- case 0x61: m_HL.b.h = m_BC.b.l; break; /* MOV H,C */
- case 0x62: m_HL.b.h = m_DE.b.h; break; /* MOV H,D */
- case 0x63: m_HL.b.h = m_DE.b.l; break; /* MOV H,E */
- case 0x64: break; /* MOV H,H */
- case 0x65: m_HL.b.h = m_HL.b.l; break; /* MOV H,L */
- case 0x66: m_HL.b.h = RM(m_HL.d); break; /* MOV H,M */
- case 0x67: m_HL.b.h = m_AF.b.h; break; /* MOV H,A */
-
- case 0x68: m_HL.b.l = m_BC.b.h; break; /* MOV L,B */
- case 0x69: m_HL.b.l = m_BC.b.l; break; /* MOV L,C */
- case 0x6a: m_HL.b.l = m_DE.b.h; break; /* MOV L,D */
- case 0x6b: m_HL.b.l = m_DE.b.l; break; /* MOV L,E */
- case 0x6c: m_HL.b.l = m_HL.b.h; break; /* MOV L,H */
- case 0x6d: break; /* MOV L,L */
- case 0x6e: m_HL.b.l = RM(m_HL.d); break; /* MOV L,M */
- case 0x6f: m_HL.b.l = m_AF.b.h; break; /* MOV L,A */
-
- case 0x70: WM(m_HL.d, m_BC.b.h); break; /* MOV M,B */
- case 0x71: WM(m_HL.d, m_BC.b.l); break; /* MOV M,C */
- case 0x72: WM(m_HL.d, m_DE.b.h); break; /* MOV M,D */
- case 0x73: WM(m_HL.d, m_DE.b.l); break; /* MOV M,E */
- case 0x74: WM(m_HL.d, m_HL.b.h); break; /* MOV M,H */
- case 0x75: WM(m_HL.d, m_HL.b.l); break; /* MOV M,L */
- case 0x76: m_PC.w.l--; m_HALT = 1; /* HLT */
- set_status(0x8a); // halt acknowledge
- break;
- case 0x77: WM(m_HL.d, m_AF.b.h); break; /* MOV M,A */
-
- case 0x78: m_AF.b.h = m_BC.b.h; break; /* MOV A,B */
- case 0x79: m_AF.b.h = m_BC.b.l; break; /* MOV A,C */
- case 0x7a: m_AF.b.h = m_DE.b.h; break; /* MOV A,D */
- case 0x7b: m_AF.b.h = m_DE.b.l; break; /* MOV A,E */
- case 0x7c: m_AF.b.h = m_HL.b.h; break; /* MOV A,H */
- case 0x7d: m_AF.b.h = m_HL.b.l; break; /* MOV A,L */
- case 0x7e: m_AF.b.h = RM(m_HL.d); break; /* MOV A,M */
- case 0x7f: break; /* MOV A,A */
-
- case 0x80: M_ADD(m_BC.b.h); break; /* ADD B */
- case 0x81: M_ADD(m_BC.b.l); break; /* ADD C */
- case 0x82: M_ADD(m_DE.b.h); break; /* ADD D */
- case 0x83: M_ADD(m_DE.b.l); break; /* ADD E */
- case 0x84: M_ADD(m_HL.b.h); break; /* ADD H */
- case 0x85: M_ADD(m_HL.b.l); break; /* ADD L */
- case 0x86: m_WZ.b.l = RM(m_HL.d); M_ADD(m_WZ.b.l); break; /* ADD M */
- case 0x87: M_ADD(m_AF.b.h); break; /* ADD A */
-
- case 0x88: M_ADC(m_BC.b.h); break; /* ADC B */
- case 0x89: M_ADC(m_BC.b.l); break; /* ADC C */
- case 0x8a: M_ADC(m_DE.b.h); break; /* ADC D */
- case 0x8b: M_ADC(m_DE.b.l); break; /* ADC E */
- case 0x8c: M_ADC(m_HL.b.h); break; /* ADC H */
- case 0x8d: M_ADC(m_HL.b.l); break; /* ADC L */
- case 0x8e: m_WZ.b.l = RM(m_HL.d); M_ADC(m_WZ.b.l); break; /* ADC M */
- case 0x8f: M_ADC(m_AF.b.h); break; /* ADC A */
-
- case 0x90: M_SUB(m_BC.b.h); break; /* SUB B */
- case 0x91: M_SUB(m_BC.b.l); break; /* SUB C */
- case 0x92: M_SUB(m_DE.b.h); break; /* SUB D */
- case 0x93: M_SUB(m_DE.b.l); break; /* SUB E */
- case 0x94: M_SUB(m_HL.b.h); break; /* SUB H */
- case 0x95: M_SUB(m_HL.b.l); break; /* SUB L */
- case 0x96: m_WZ.b.l = RM(m_HL.d); M_SUB(m_WZ.b.l); break; /* SUB M */
- case 0x97: M_SUB(m_AF.b.h); break; /* SUB A */
-
- case 0x98: M_SBB(m_BC.b.h); break; /* SBB B */
- case 0x99: M_SBB(m_BC.b.l); break; /* SBB C */
- case 0x9a: M_SBB(m_DE.b.h); break; /* SBB D */
- case 0x9b: M_SBB(m_DE.b.l); break; /* SBB E */
- case 0x9c: M_SBB(m_HL.b.h); break; /* SBB H */
- case 0x9d: M_SBB(m_HL.b.l); break; /* SBB L */
- case 0x9e: m_WZ.b.l = RM(m_HL.d); M_SBB(m_WZ.b.l); break; /* SBB M */
- case 0x9f: M_SBB(m_AF.b.h); break; /* SBB A */
-
- case 0xa0: M_ANA(m_BC.b.h); break; /* ANA B */
- case 0xa1: M_ANA(m_BC.b.l); break; /* ANA C */
- case 0xa2: M_ANA(m_DE.b.h); break; /* ANA D */
- case 0xa3: M_ANA(m_DE.b.l); break; /* ANA E */
- case 0xa4: M_ANA(m_HL.b.h); break; /* ANA H */
- case 0xa5: M_ANA(m_HL.b.l); break; /* ANA L */
- case 0xa6: m_WZ.b.l = RM(m_HL.d); M_ANA(m_WZ.b.l); break; /* ANA M */
- case 0xa7: M_ANA(m_AF.b.h); break; /* ANA A */
-
- case 0xa8: M_XRA(m_BC.b.h); break; /* XRA B */
- case 0xa9: M_XRA(m_BC.b.l); break; /* XRA C */
- case 0xaa: M_XRA(m_DE.b.h); break; /* XRA D */
- case 0xab: M_XRA(m_DE.b.l); break; /* XRA E */
- case 0xac: M_XRA(m_HL.b.h); break; /* XRA H */
- case 0xad: M_XRA(m_HL.b.l); break; /* XRA L */
- case 0xae: m_WZ.b.l = RM(m_HL.d); M_XRA(m_WZ.b.l); break; /* XRA M */
- case 0xaf: M_XRA(m_AF.b.h); break; /* XRA A */
-
- case 0xb0: M_ORA(m_BC.b.h); break; /* ORA B */
- case 0xb1: M_ORA(m_BC.b.l); break; /* ORA C */
- case 0xb2: M_ORA(m_DE.b.h); break; /* ORA D */
- case 0xb3: M_ORA(m_DE.b.l); break; /* ORA E */
- case 0xb4: M_ORA(m_HL.b.h); break; /* ORA H */
- case 0xb5: M_ORA(m_HL.b.l); break; /* ORA L */
- case 0xb6: m_WZ.b.l = RM(m_HL.d); M_ORA(m_WZ.b.l); break; /* ORA M */
- case 0xb7: M_ORA(m_AF.b.h); break; /* ORA A */
-
- case 0xb8: M_CMP(m_BC.b.h); break; /* CMP B */
- case 0xb9: M_CMP(m_BC.b.l); break; /* CMP C */
- case 0xba: M_CMP(m_DE.b.h); break; /* CMP D */
- case 0xbb: M_CMP(m_DE.b.l); break; /* CMP E */
- case 0xbc: M_CMP(m_HL.b.h); break; /* CMP H */
- case 0xbd: M_CMP(m_HL.b.l); break; /* CMP L */
- case 0xbe: m_WZ.b.l = RM(m_HL.d); M_CMP(m_WZ.b.l); break; /* CMP M */
- case 0xbf: M_CMP(m_AF.b.h); break; /* CMP A */
-
- case 0xc0: M_RET( !(m_AF.b.l & ZF) ); break; /* RNZ */
- case 0xc1: M_POP(BC); break; /* POP B */
- case 0xc2: M_JMP( !(m_AF.b.l & ZF) ); break; /* JNZ nnnn */
- case 0xc3: M_JMP(1); break; /* JMP nnnn */
- case 0xc4: M_CALL( !(m_AF.b.l & ZF) ); break; /* CNZ nnnn */
- case 0xc5: M_PUSH(BC); break; /* PUSH B */
- case 0xc6: m_WZ.b.l = ARG(); M_ADD(m_WZ.b.l); break; /* ADI nn */
- case 0xc7: M_RST(0); break; /* RST 0 */
-
- case 0xc8: M_RET( m_AF.b.l & ZF ); break; /* RZ */
- case 0xc9: M_POP(PC); break; /* RET */
- case 0xca: M_JMP( m_AF.b.l & ZF ); break; /* JZ nnnn */
- case 0xcb: if (IS_8085()) { /* RST V */
- if (m_AF.b.l & VF) { M_RST(8); }
- else m_icount += 6; // RST not taken
- } else { M_JMP(1); } /* JMP nnnn undocumented */
- break;
- case 0xcc: M_CALL( m_AF.b.l & ZF ); break; /* CZ nnnn */
- case 0xcd: M_CALL(1); break; /* CALL nnnn */
- case 0xce: m_WZ.b.l = ARG(); M_ADC(m_WZ.b.l); break; /* ACI nn */
- case 0xcf: M_RST(1); break; /* RST 1 */
-
- case 0xd0: M_RET( !(m_AF.b.l & CF) ); break; /* RNC */
- case 0xd1: M_POP(DE); break; /* POP D */
- case 0xd2: M_JMP( !(m_AF.b.l & CF) ); break; /* JNC nnnn */
- case 0xd3: M_OUT; break; /* OUT nn */
- case 0xd4: M_CALL( !(m_AF.b.l & CF) ); break; /* CNC nnnn */
- case 0xd5: M_PUSH(DE); break; /* PUSH D */
- case 0xd6: m_WZ.b.l = ARG(); M_SUB(m_WZ.b.l); break; /* SUI nn */
- case 0xd7: M_RST(2); break; /* RST 2 */
-
- case 0xd8: M_RET( m_AF.b.l & CF ); break; /* RC */
- case 0xd9: if (IS_8085()) { /* SHLX */
- m_WZ.w.l = m_DE.w.l;
- WM(m_WZ.d, m_HL.b.l); m_WZ.w.l++;
- WM(m_WZ.d, m_HL.b.h);
- } else { M_POP(PC); } /* RET undocumented */
- break;
- case 0xda: M_JMP( m_AF.b.l & CF ); break; /* JC nnnn */
- case 0xdb: M_IN; break; /* IN nn */
- case 0xdc: M_CALL( m_AF.b.l & CF ); break; /* CC nnnn */
- case 0xdd: if (IS_8085()) { M_JMP( !(m_AF.b.l & X5F) ); } /* JNX nnnn */
- else { M_CALL(1); } /* CALL nnnn undocumented */
- break;
- case 0xde: m_WZ.b.l = ARG(); M_SBB(m_WZ.b.l); break; /* SBI nn */
- case 0xdf: M_RST(3); break; /* RST 3 */
-
- case 0xe0: M_RET( !(m_AF.b.l & PF) ); break; /* RPO */
- case 0xe1: M_POP(HL); break; /* POP H */
- case 0xe2: M_JMP( !(m_AF.b.l & PF) ); break; /* JPO nnnn */
- case 0xe3: M_POP(WZ); M_PUSH(HL); /* XTHL */
- m_HL.d = m_WZ.d;
- break;
- case 0xe4: M_CALL( !(m_AF.b.l & PF) ); break; /* CPO nnnn */
- case 0xe5: M_PUSH(HL); break; /* PUSH H */
- case 0xe6: m_WZ.b.l = ARG(); M_ANA(m_WZ.b.l); break; /* ANI nn */
- case 0xe7: M_RST(4); break; /* RST 4 */
-
- case 0xe8: M_RET( m_AF.b.l & PF ); break; /* RPE */
- case 0xe9: m_PC.d = m_HL.w.l; break; /* PCHL */
- case 0xea: M_JMP( m_AF.b.l & PF ); break; /* JPE nnnn */
- case 0xeb: m_WZ.d = m_DE.d; /* XCHG */
- m_DE.d = m_HL.d;
- m_HL.d = m_WZ.d;
- break;
- case 0xec: M_CALL( m_AF.b.l & PF ); break; /* CPE nnnn */
- case 0xed: if (IS_8085()) { /* LHLX */
- m_WZ.w.l = m_DE.w.l;
- m_HL.b.l = RM(m_WZ.d); m_WZ.w.l++;
- m_HL.b.h = RM(m_WZ.d);
- } else { M_CALL(1); } /* CALL nnnn undocumented */
- break;
- case 0xee: m_WZ.b.l = ARG(); M_XRA(m_WZ.b.l); break; /* XRI nn */
- case 0xef: M_RST(5); break; /* RST 5 */
-
- case 0xf0: M_RET( !(m_AF.b.l&SF) ); break; /* RP */
- case 0xf1: M_POP(AF); break; /* POP A */
- case 0xf2: M_JMP( !(m_AF.b.l & SF) ); break; /* JP nnnn */
- case 0xf3: set_inte(0); break; /* DI */
- case 0xf4: M_CALL( !(m_AF.b.l & SF) ); break; /* CP nnnn */
- case 0xf5: if (IS_8080()) m_AF.b.l = (m_AF.b.l&~(X3F|X5F))|VF; // on 8080, VF=1 and X3F=0 and X5F=0 always! (we don't have to check for it elsewhere)
- M_PUSH(AF); break; /* PUSH A */
- case 0xf6: m_WZ.b.l = ARG(); M_ORA(m_WZ.b.l); break; /* ORI nn */
- case 0xf7: M_RST(6); break; /* RST 6 */
-
- case 0xf8: M_RET( m_AF.b.l & SF ); break; /* RM */
- case 0xf9: m_SP.d = m_HL.d; break; /* SPHL */
- case 0xfa: M_JMP( m_AF.b.l & SF ); break; /* JM nnnn */
- case 0xfb: set_inte(1); m_after_ei = 2; break; /* EI */
- case 0xfc: M_CALL( m_AF.b.l & SF ); break; /* CM nnnn */
- case 0xfd: if (IS_8085()) { M_JMP( m_AF.b.l & X5F ); } /* JX nnnn */
- else { M_CALL(1); } /* CALL nnnn undocumented */
- break;
- case 0xfe: m_WZ.b.l = ARG(); M_CMP(m_WZ.b.l); break; /* CPI nn */
- case 0xff: M_RST(7); break; /* RST 7 */
- }
-}
-
-
-/***************************************************************************
- COMMON EXECUTION
-***************************************************************************/
-
-void i8085a_cpu_device::execute_run()
-{
- /* check for TRAPs before diving in (can't do others because of after_ei) */
- if (m_trap_pending || m_after_ei == 0)
- check_for_interrupts();
-
- do
- {
- debugger_instruction_hook(this, m_PC.d);
-
- /* the instruction after an EI does not take an interrupt, so
- we cannot check immediately; handle post-EI behavior here */
- if (m_after_ei != 0 && --m_after_ei == 0)
- check_for_interrupts();
-
- /* here we go... */
- execute_one(ROP());
-
- } while (m_icount > 0);
-}
-
-
-
/***************************************************************************
CORE INITIALIZATION
***************************************************************************/
void i8085a_cpu_device::init_tables()
{
- uint8_t zs;
+ u8 zs;
int i, p;
for (i = 0; i < 256; i++)
{
/* cycles */
- lut_cycles[i] = m_cputype?lut_cycles_8085[i]:lut_cycles_8080[i];
+ lut_cycles[i] = is_8085() ? lut_cycles_8085[i] : lut_cycles_8080[i];
/* flags */
zs = 0;
@@ -907,12 +284,11 @@ void i8085a_cpu_device::init_tables()
if (i&32) ++p;
if (i&64) ++p;
if (i&128) ++p;
- ZS[i] = zs;
- ZSP[i] = zs | ((p&1) ? 0 : PF);
+ lut_zs[i] = zs;
+ lut_zsp[i] = zs | ((p&1) ? 0 : PF);
}
}
-
void i8085a_cpu_device::device_start()
{
m_PC.d = 0;
@@ -922,9 +298,9 @@ void i8085a_cpu_device::device_start()
m_DE.d = 0;
m_HL.d = 0;
m_WZ.d = 0;
- m_HALT = 0;
- m_IM = 0;
- m_STATUS = 0;
+ m_halt = 0;
+ m_im = 0;
+ m_status = 0;
m_after_ei = 0;
m_nmi_state = 0;
m_irq_state[3] = m_irq_state[2] = m_irq_state[1] = m_irq_state[0] = 0;
@@ -955,14 +331,15 @@ void i8085a_cpu_device::device_start()
state_add(I8085_BC, "BC", m_BC.w.l);
state_add(I8085_DE, "DE", m_DE.w.l);
state_add(I8085_HL, "HL", m_HL.w.l);
- state_add(I8085_STATUS, "STATUS", m_STATUS);
+ state_add(I8085_STATUS, "STATUS", m_status);
state_add(I8085_SOD, "SOD", m_sod_state).mask(0x1);
state_add(I8085_SID, "SID", m_ietemp).mask(0x1).callimport().callexport();
state_add(I8085_INTE, "INTE", m_ietemp).mask(0x1).callimport().callexport();
}
m_program = &space(AS_PROGRAM);
- m_direct = &m_program->direct();
+ m_direct = m_program->direct<0>();
+ m_opcode_direct = has_space(AS_OPCODES) ? space(AS_OPCODES).direct<0>() : m_direct;
m_io = &space(AS_IO);
/* resolve callbacks */
@@ -978,9 +355,9 @@ void i8085a_cpu_device::device_start()
save_item(NAME(m_BC.w.l));
save_item(NAME(m_DE.w.l));
save_item(NAME(m_HL.w.l));
- save_item(NAME(m_HALT));
- save_item(NAME(m_IM));
- save_item(NAME(m_STATUS));
+ save_item(NAME(m_halt));
+ save_item(NAME(m_im));
+ save_item(NAME(m_status));
save_item(NAME(m_after_ei));
save_item(NAME(m_nmi_state));
save_item(NAME(m_irq_state));
@@ -999,9 +376,9 @@ void i8085a_cpu_device::device_start()
void i8085a_cpu_device::device_reset()
{
m_PC.d = 0;
- m_HALT = 0;
- m_IM &= ~IM_I75;
- m_IM |= IM_M55 | IM_M65 | IM_M75;
+ m_halt = 0;
+ m_im &= ~IM_I75;
+ m_im |= IM_M55 | IM_M65 | IM_M75;
m_after_ei = false;
m_trap_pending = false;
m_trap_im_copy = 0;
@@ -1010,7 +387,6 @@ void i8085a_cpu_device::device_reset()
}
-
/***************************************************************************
COMMON STATE IMPORT/EXPORT
***************************************************************************/
@@ -1022,22 +398,22 @@ void i8085a_cpu_device::state_import(const device_state_entry &entry)
case I8085_SID:
if (m_ietemp)
{
- m_IM |= IM_SID;
+ m_im |= IM_SID;
}
else
{
- m_IM &= ~IM_SID;
+ m_im &= ~IM_SID;
}
break;
case I8085_INTE:
if (m_ietemp)
{
- m_IM |= IM_IE;
+ m_im |= IM_IE;
}
else
{
- m_IM &= ~IM_IE;
+ m_im &= ~IM_IE;
}
break;
@@ -1046,17 +422,16 @@ void i8085a_cpu_device::state_import(const device_state_entry &entry)
}
}
-
void i8085a_cpu_device::state_export(const device_state_entry &entry)
{
switch (entry.index())
{
case I8085_SID:
- m_ietemp = ((m_IM & IM_SID) != 0) && m_in_sid_func() != 0;
+ m_ietemp = ((m_im & IM_SID) != 0) && m_in_sid_func() != 0;
break;
case I8085_INTE:
- m_ietemp = ((m_IM & IM_IE) != 0);
+ m_ietemp = ((m_im & IM_IE) != 0);
break;
default:
@@ -1082,6 +457,15 @@ void i8085a_cpu_device::state_string_export(const device_state_entry &entry, std
}
}
+util::disasm_interface *i8085a_cpu_device::create_disassembler()
+{
+ return new i8085_disassembler;
+}
+
+
+/***************************************************************************
+ INTERRUPTS
+***************************************************************************/
void i8085a_cpu_device::execute_set_input(int irqline, int state)
{
@@ -1099,7 +483,7 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state)
else if (irqline == I8085_RST75_LINE)
{
if (!m_irq_state[I8085_RST75_LINE] && newstate)
- m_IM |= IM_I75;
+ m_im |= IM_I75;
m_irq_state[I8085_RST75_LINE] = newstate;
}
@@ -1108,9 +492,1133 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state)
m_irq_state[irqline] = state;
}
+void i8085a_cpu_device::break_halt_for_interrupt()
+{
+ /* de-halt if necessary */
+ if (m_halt)
+ {
+ m_PC.w.l++;
+ m_halt = 0;
+ set_status(0x26); /* int ack while halt */
+ }
+ else
+ set_status(0x23); /* int ack */
+}
+
+void i8085a_cpu_device::check_for_interrupts()
+{
+ /* TRAP is the highest priority */
+ if (m_trap_pending)
+ {
+ /* the first RIM after a TRAP reflects the original IE state; remember it here,
+ setting the high bit to indicate it is valid */
+ m_trap_im_copy = m_im | 0x80;
+
+ /* reset the pending state */
+ m_trap_pending = false;
+
+ /* break out of HALT state and call the IRQ ack callback */
+ break_halt_for_interrupt();
+ standard_irq_callback(INPUT_LINE_NMI);
+
+ /* push the PC and jump to $0024 */
+ op_push(m_PC);
+ set_inte(0);
+ m_PC.w.l = ADDR_TRAP;
+ m_icount -= 11;
+ }
+
+ /* followed by RST7.5 */
+ else if ((m_im & IM_I75) && !(m_im & IM_M75) && (m_im & IM_IE))
+ {
+ /* reset the pending state (which is CPU-visible via the RIM instruction) */
+ m_im &= ~IM_I75;
+
+ /* break out of HALT state and call the IRQ ack callback */
+ break_halt_for_interrupt();
+ standard_irq_callback(I8085_RST75_LINE);
+
+ /* push the PC and jump to $003C */
+ op_push(m_PC);
+ set_inte(0);
+ m_PC.w.l = ADDR_RST75;
+ m_icount -= 11;
+ }
+
+ /* followed by RST6.5 */
+ else if (m_irq_state[I8085_RST65_LINE] && !(m_im & IM_M65) && (m_im & IM_IE))
+ {
+ /* break out of HALT state and call the IRQ ack callback */
+ break_halt_for_interrupt();
+ standard_irq_callback(I8085_RST65_LINE);
+
+ /* push the PC and jump to $0034 */
+ op_push(m_PC);
+ set_inte(0);
+ m_PC.w.l = ADDR_RST65;
+ m_icount -= 11;
+ }
+
+ /* followed by RST5.5 */
+ else if (m_irq_state[I8085_RST55_LINE] && !(m_im & IM_M55) && (m_im & IM_IE))
+ {
+ /* break out of HALT state and call the IRQ ack callback */
+ break_halt_for_interrupt();
+ standard_irq_callback(I8085_RST55_LINE);
+
+ /* push the PC and jump to $002C */
+ op_push(m_PC);
+ set_inte(0);
+ m_PC.w.l = ADDR_RST55;
+ m_icount -= 11;
+ }
+
+ /* followed by classic INTR */
+ else if (m_irq_state[I8085_INTR_LINE] && (m_im & IM_IE))
+ {
+ u32 vector;
+
+ /* break out of HALT state and call the IRQ ack callback */
+ break_halt_for_interrupt();
+ vector = standard_irq_callback(I8085_INTR_LINE);
+
+ /* use the resulting vector as an opcode to execute */
+ set_inte(0);
+ switch (vector & 0xff0000)
+ {
+ case 0xcd0000: /* CALL nnnn */
+ m_icount -= 7;
+ op_push(m_PC);
+ case 0xc30000: /* JMP nnnn */
+ m_icount -= 10;
+ m_PC.d = vector & 0xffff;
+ break;
+
+ default:
+ LOG("i8085 take int $%02x\n", vector);
+ execute_one(vector & 0xff);
+ break;
+ }
+ }
+}
+
+
+/***************************************************************************
+ OPCODE HELPERS
+***************************************************************************/
-offs_t i8085a_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
+void i8085a_cpu_device::set_sod(int state)
{
- extern CPU_DISASSEMBLE( i8085 );
- return CPU_DISASSEMBLE_NAME(i8085)(this, stream, pc, oprom, opram, options);
+ if (state != 0 && m_sod_state == 0)
+ {
+ m_sod_state = 1;
+ m_out_sod_func(m_sod_state);
+ }
+ else if (state == 0 && m_sod_state != 0)
+ {
+ m_sod_state = 0;
+ m_out_sod_func(m_sod_state);
+ }
+}
+
+void i8085a_cpu_device::set_inte(int state)
+{
+ if (state != 0 && (m_im & IM_IE) == 0)
+ {
+ m_im |= IM_IE;
+ m_out_inte_func(1);
+ }
+ else if (state == 0 && (m_im & IM_IE) != 0)
+ {
+ m_im &= ~IM_IE;
+ m_out_inte_func(0);
+ }
+}
+
+void i8085a_cpu_device::set_status(u8 status)
+{
+ if (status != m_status)
+ m_out_status_func(status);
+
+ m_status = status;
+}
+
+u8 i8085a_cpu_device::get_rim_value()
+{
+ u8 result = m_im;
+ int sid = m_in_sid_func();
+
+ /* copy live RST5.5 and RST6.5 states */
+ result &= ~(IM_I65 | IM_I55);
+ if (m_irq_state[I8085_RST65_LINE]) result |= IM_I65;
+ if (m_irq_state[I8085_RST55_LINE]) result |= IM_I55;
+
+ /* fetch the SID bit if we have a callback */
+ result = (result & ~IM_SID) | (sid ? IM_SID : 0);
+
+ return result;
+}
+
+// memory access
+u8 i8085a_cpu_device::read_arg()
+{
+ return m_direct->read_byte(m_PC.w.l++);
+}
+
+PAIR i8085a_cpu_device::read_arg16()
+{
+ PAIR p;
+ p.b.l = m_direct->read_byte(m_PC.w.l++);
+ p.b.h = m_direct->read_byte(m_PC.w.l++);
+ return p;
+}
+
+u8 i8085a_cpu_device::read_op()
+{
+ set_status(0xa2); // instruction fetch
+ return m_opcode_direct->read_byte(m_PC.w.l++);
+}
+
+u8 i8085a_cpu_device::read_mem(u32 a)
+{
+ set_status(0x82); // memory read
+ return m_program->read_byte(a);
+}
+
+void i8085a_cpu_device::write_mem(u32 a, u8 v)
+{
+ set_status(0x00); // memory write
+ m_program->write_byte(a, v);
+}
+
+void i8085a_cpu_device::op_push(PAIR p)
+{
+ set_status(0x04); // stack push
+ m_program->write_byte(--m_SP.w.l, p.b.h);
+ m_program->write_byte(--m_SP.w.l, p.b.l);
+}
+
+PAIR i8085a_cpu_device::op_pop()
+{
+ PAIR p;
+ set_status(0x86); // stack pop
+ p.b.l = m_program->read_byte(m_SP.w.l++);
+ p.b.h = m_program->read_byte(m_SP.w.l++);
+ return p;
+}
+
+// logical
+void i8085a_cpu_device::op_ora(u8 v)
+{
+ m_AF.b.h |= v;
+ m_AF.b.l = lut_zsp[m_AF.b.h];
+}
+
+void i8085a_cpu_device::op_xra(u8 v)
+{
+ m_AF.b.h ^= v;
+ m_AF.b.l = lut_zsp[m_AF.b.h];
+}
+
+void i8085a_cpu_device::op_ana(u8 v)
+{
+ u8 hc = ((m_AF.b.h | v) << 1) & HF;
+ m_AF.b.h &= v;
+ m_AF.b.l = lut_zsp[m_AF.b.h];
+ if (is_8085())
+ m_AF.b.l |= HF;
+ else
+ m_AF.b.l |= hc;
+}
+
+// increase / decrease
+u8 i8085a_cpu_device::op_inr(u8 v)
+{
+ u8 hc = ((v & 0x0f) == 0x0f) ? HF : 0;
+ m_AF.b.l = (m_AF.b.l & CF) | lut_zsp[++v] | hc;
+ return v;
+}
+
+u8 i8085a_cpu_device::op_dcr(u8 v)
+{
+ u8 hc = ((v & 0x0f) != 0x00) ? HF : 0;
+ m_AF.b.l = (m_AF.b.l & CF) | lut_zsp[--v] | hc | VF;
+ return v;
+}
+
+// arithmetic
+void i8085a_cpu_device::op_add(u8 v)
+{
+ int q = m_AF.b.h + v;
+ m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | ((m_AF.b.h ^ q ^ v) & HF);
+ m_AF.b.h = q;
+}
+
+void i8085a_cpu_device::op_adc(u8 v)
+{
+ int q = m_AF.b.h + v + (m_AF.b.l & CF);
+ m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | ((m_AF.b.h ^ q ^ v) & HF);
+ m_AF.b.h = q;
+}
+
+void i8085a_cpu_device::op_sub(u8 v)
+{
+ int q = m_AF.b.h - v;
+ m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF;
+ m_AF.b.h = q;
+}
+
+void i8085a_cpu_device::op_sbb(u8 v)
+{
+ int q = m_AF.b.h - v - (m_AF.b.l & CF);
+ m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF;
+ m_AF.b.h = q;
+}
+
+void i8085a_cpu_device::op_cmp(u8 v)
+{
+ int q = m_AF.b.h - v;
+ m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF;
+}
+
+void i8085a_cpu_device::op_dad(u16 v)
+{
+ int q = m_HL.w.l + v;
+ m_AF.b.l = (m_AF.b.l & ~CF) | (q >> 16 & CF);
+ m_HL.w.l = q;
+}
+
+// jumps
+void i8085a_cpu_device::op_jmp(int cond)
+{
+ // on 8085, jump if condition is not satisfied is shorter
+ if (cond)
+ m_PC = read_arg16();
+ else
+ {
+ m_PC.w.l += 2;
+ m_icount += (is_8085()) ? 3 : 0;
+ }
+}
+
+void i8085a_cpu_device::op_call(int cond)
+{
+ // on 8085, call if condition is not satisfied is 9 ticks
+ if (cond)
+ {
+ PAIR p = read_arg16();
+ m_icount -= (is_8085()) ? 7 : 6 ;
+ op_push(m_PC);
+ m_PC = p;
+ }
+ else
+ {
+ m_PC.w.l += 2;
+ m_icount += (is_8085()) ? 2 : 0;
+ }
+}
+
+void i8085a_cpu_device::op_ret(int cond)
+{
+ // conditional RET only
+ if (cond)
+ {
+ m_icount -= 6;
+ m_PC = op_pop();
+ }
+}
+
+void i8085a_cpu_device::op_rst(u8 v)
+{
+ op_push(m_PC);
+ m_PC.d = 8 * v;
+}
+
+
+/***************************************************************************
+ COMMON EXECUTION
+***************************************************************************/
+
+void i8085a_cpu_device::execute_run()
+{
+ /* check for TRAPs before diving in (can't do others because of after_ei) */
+ if (m_trap_pending || m_after_ei == 0)
+ check_for_interrupts();
+
+ do
+ {
+ debugger_instruction_hook(this, m_PC.d);
+
+ /* the instruction after an EI does not take an interrupt, so
+ we cannot check immediately; handle post-EI behavior here */
+ if (m_after_ei != 0 && --m_after_ei == 0)
+ check_for_interrupts();
+
+ /* here we go... */
+ execute_one(read_op());
+
+ } while (m_icount > 0);
+}
+
+void i8085a_cpu_device::execute_one(int opcode)
+{
+ m_icount -= lut_cycles[opcode];
+
+ switch (opcode)
+ {
+ case 0x00: // NOP
+ break;
+ case 0x01: // LXI B,nnnn
+ m_BC = read_arg16();
+ break;
+ case 0x02: // STAX B
+ write_mem(m_BC.d, m_AF.b.h);
+ break;
+ case 0x03: // INX B
+ m_BC.w.l++;
+ if (is_8085())
+ {
+ if (m_BC.w.l == 0x0000)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x04: // INR B
+ m_BC.b.h = op_inr(m_BC.b.h);
+ break;
+ case 0x05: // DCR B
+ m_BC.b.h = op_dcr(m_BC.b.h);
+ break;
+ case 0x06: // MVI B,nn
+ m_BC.b.h = read_arg();
+ break;
+ case 0x07: // RLC
+ m_AF.b.h = (m_AF.b.h << 1) | (m_AF.b.h >> 7);
+ m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF);
+ break;
+
+ case 0x08: // 8085: DSUB, otherwise undocumented NOP
+ if (is_8085())
+ {
+ int q = m_HL.b.l - m_BC.b.l;
+ m_AF.b.l = lut_zs[q & 0xff] | ((q >> 8) & CF) | VF | ((m_HL.b.l ^ q ^ m_BC.b.l) & HF) | (((m_BC.b.l ^ m_HL.b.l) & (m_HL.b.l ^ q) & SF) >> 5);
+ m_HL.b.l = q;
+ q = m_HL.b.h - m_BC.b.h - (m_AF.b.l & CF);
+ m_AF.b.l = lut_zs[q & 0xff] | ((q >> 8) & CF) | VF | ((m_HL.b.h ^ q ^ m_BC.b.h) & HF) | (((m_BC.b.h ^ m_HL.b.h) & (m_HL.b.h ^ q) & SF) >> 5);
+ if (m_HL.b.l != 0)
+ m_AF.b.l &= ~ZF;
+ }
+ break;
+ case 0x09: // DAD B
+ op_dad(m_BC.w.l);
+ break;
+ case 0x0a: // LDAX B
+ m_AF.b.h = read_mem(m_BC.d);
+ break;
+ case 0x0b: // DCX B
+ m_BC.w.l--;
+ if (is_8085())
+ {
+ if (m_BC.w.l == 0xffff)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x0c: // INR C
+ m_BC.b.l = op_inr(m_BC.b.l);
+ break;
+ case 0x0d: // DCR C
+ m_BC.b.l = op_dcr(m_BC.b.l);
+ break;
+ case 0x0e: // MVI C,nn
+ m_BC.b.l = read_arg();
+ break;
+ case 0x0f: // RRC
+ m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF);
+ m_AF.b.h = (m_AF.b.h >> 1) | (m_AF.b.h << 7);
+ break;
+
+ case 0x10: // 8085: ASRH, otherwise undocumented NOP
+ if (is_8085())
+ {
+ m_AF.b.l = (m_AF.b.l & ~CF) | (m_HL.b.l & CF);
+ m_HL.w.l = (m_HL.w.l >> 1);
+ }
+ break;
+ case 0x11: // LXI D,nnnn
+ m_DE = read_arg16();
+ break;
+ case 0x12: // STAX D
+ write_mem(m_DE.d, m_AF.b.h);
+ break;
+ case 0x13: // INX D
+ m_DE.w.l++;
+ if (is_8085())
+ {
+ if (m_DE.w.l == 0x0000)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x14: // INR D
+ m_DE.b.h = op_inr(m_DE.b.h);
+ break;
+ case 0x15: // DCR D
+ m_DE.b.h = op_dcr(m_DE.b.h);
+ break;
+ case 0x16: // MVI D,nn
+ m_DE.b.h = read_arg();
+ break;
+ case 0x17: // RAL
+ {
+ int c = m_AF.b.l & CF;
+ m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h >> 7);
+ m_AF.b.h = (m_AF.b.h << 1) | c;
+ break;
+ }
+
+ case 0x18: // 8085: RLDE, otherwise undocumented NOP
+ if (is_8085())
+ {
+ m_AF.b.l = (m_AF.b.l & ~(CF | VF)) | (m_DE.b.h >> 7);
+ m_DE.w.l = (m_DE.w.l << 1) | (m_DE.w.l >> 15);
+ if ((((m_DE.w.l >> 15) ^ m_AF.b.l) & CF) != 0)
+ m_AF.b.l |= VF;
+ }
+ break;
+ case 0x19: // DAD D
+ op_dad(m_DE.w.l);
+ break;
+ case 0x1a: // LDAX D
+ m_AF.b.h = read_mem(m_DE.d);
+ break;
+ case 0x1b: // DCX D
+ m_DE.w.l--;
+ if (is_8085())
+ {
+ if (m_DE.w.l == 0xffff)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x1c: // INR E
+ m_DE.b.l = op_inr(m_DE.b.l);
+ break;
+ case 0x1d: // DCR E
+ m_DE.b.l = op_dcr(m_DE.b.l);
+ break;
+ case 0x1e: // MVI E,nn
+ m_DE.b.l = read_arg();
+ break;
+ case 0x1f: // RAR
+ {
+ int c = (m_AF.b.l & CF) << 7;
+ m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF);
+ m_AF.b.h = (m_AF.b.h >> 1) | c;
+ break;
+ }
+
+ case 0x20: // 8085: RIM, otherwise undocumented NOP
+ if (is_8085())
+ {
+ m_AF.b.h = get_rim_value();
+
+ // if we have remembered state from taking a TRAP, fix up the IE flag here
+ if (m_trap_im_copy & 0x80)
+ m_AF.b.h = (m_AF.b.h & ~IM_IE) | (m_trap_im_copy & IM_IE);
+ m_trap_im_copy = 0;
+ }
+ break;
+ case 0x21: // LXI H,nnnn
+ m_HL = read_arg16();
+ break;
+ case 0x22: // SHLD nnnn
+ m_WZ = read_arg16();
+ write_mem(m_WZ.d, m_HL.b.l);
+ m_WZ.w.l++;
+ write_mem(m_WZ.d, m_HL.b.h);
+ break;
+ case 0x23: // INX H
+ m_HL.w.l++;
+ if (is_8085())
+ {
+ if (m_HL.w.l == 0x0000)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x24: // INR H
+ m_HL.b.h = op_inr(m_HL.b.h);
+ break;
+ case 0x25: // DCR H
+ m_HL.b.h = op_dcr(m_HL.b.h);
+ break;
+ case 0x26: // MVI H,nn
+ m_HL.b.h = read_arg();
+ break;
+ case 0x27: // DAA
+ m_WZ.b.h = m_AF.b.h;
+ if (is_8085() && m_AF.b.l & VF)
+ {
+ if ((m_AF.b.l & HF) || ((m_AF.b.h & 0xf) > 9))
+ m_WZ.b.h -= 6;
+ if ((m_AF.b.l & CF) || (m_AF.b.h > 0x99))
+ m_WZ.b.h -= 0x60;
+ }
+ else
+ {
+ if ((m_AF.b.l & HF) || ((m_AF.b.h & 0xf) > 9))
+ m_WZ.b.h += 6;
+ if ((m_AF.b.l & CF) || (m_AF.b.h > 0x99))
+ m_WZ.b.h += 0x60;
+ }
+
+ m_AF.b.l = (m_AF.b.l & 3) | (m_AF.b.h & 0x28) | ((m_AF.b.h > 0x99) ? 1 : 0) | ((m_AF.b.h ^ m_WZ.b.h) & 0x10) | lut_zsp[m_WZ.b.h];
+ m_AF.b.h = m_WZ.b.h;
+ break;
+
+ case 0x28: // 8085: LDEH nn, otherwise undocumented NOP
+ if (is_8085())
+ {
+ m_WZ.d = read_arg();
+ m_DE.d = (m_HL.d + m_WZ.d) & 0xffff;
+ }
+ break;
+ case 0x29: // DAD H
+ op_dad(m_HL.w.l);
+ break;
+ case 0x2a: // LHLD nnnn
+ m_WZ = read_arg16();
+ m_HL.b.l = read_mem(m_WZ.d);
+ m_WZ.w.l++;
+ m_HL.b.h = read_mem(m_WZ.d);
+ break;
+ case 0x2b: // DCX H
+ m_HL.w.l--;
+ if (is_8085())
+ {
+ if (m_HL.w.l == 0xffff)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x2c: // INR L
+ m_HL.b.l = op_inr(m_HL.b.l);
+ break;
+ case 0x2d: // DCR L
+ m_HL.b.l = op_dcr(m_HL.b.l);
+ break;
+ case 0x2e: // MVI L,nn
+ m_HL.b.l = read_arg();
+ break;
+ case 0x2f: // CMA
+ m_AF.b.h ^= 0xff;
+ if (is_8085())
+ m_AF.b.l |= HF | VF;
+ break;
+
+ case 0x30: // 8085: SIM, otherwise undocumented NOP
+ if (is_8085())
+ {
+ // if bit 3 is set, bits 0-2 become the new masks
+ if (m_AF.b.h & 0x08)
+ {
+ m_im &= ~(IM_M55 | IM_M65 | IM_M75 | IM_I55 | IM_I65);
+ m_im |= m_AF.b.h & (IM_M55 | IM_M65 | IM_M75);
+
+ // update live state based on the new masks
+ if ((m_im & IM_M55) == 0 && m_irq_state[I8085_RST55_LINE])
+ m_im |= IM_I55;
+ if ((m_im & IM_M65) == 0 && m_irq_state[I8085_RST65_LINE])
+ m_im |= IM_I65;
+ }
+
+ // bit if 4 is set, the 7.5 flip-flop is cleared
+ if (m_AF.b.h & 0x10)
+ m_im &= ~IM_I75;
+
+ // if bit 6 is set, then bit 7 is the new SOD state
+ if (m_AF.b.h & 0x40)
+ set_sod(m_AF.b.h >> 7);
+
+ // check for revealed interrupts
+ check_for_interrupts();
+ }
+ break;
+ case 0x31: // LXI SP,nnnn
+ m_SP = read_arg16();
+ break;
+ case 0x32: // STAX nnnn
+ m_WZ = read_arg16();
+ write_mem(m_WZ.d, m_AF.b.h);
+ break;
+ case 0x33: // INX SP
+ m_SP.w.l++;
+ if (is_8085())
+ {
+ if (m_SP.w.l == 0x0000)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x34: // INR M
+ m_WZ.b.l = op_inr(read_mem(m_HL.d));
+ write_mem(m_HL.d, m_WZ.b.l);
+ break;
+ case 0x35: // DCR M
+ m_WZ.b.l = op_dcr(read_mem(m_HL.d));
+ write_mem(m_HL.d, m_WZ.b.l);
+ break;
+ case 0x36: // MVI M,nn
+ m_WZ.b.l = read_arg();
+ write_mem(m_HL.d, m_WZ.b.l);
+ break;
+ case 0x37: // STC
+ m_AF.b.l = (m_AF.b.l & 0xfe) | CF;
+ break;
+
+ case 0x38: // 8085: LDES nn, otherwise undocumented NOP
+ if (is_8085())
+ {
+ m_WZ.d = read_arg();
+ m_DE.d = (m_SP.d + m_WZ.d) & 0xffff;
+ }
+ break;
+ case 0x39: // DAD SP
+ op_dad(m_SP.w.l);
+ break;
+ case 0x3a: // LDAX nnnn
+ m_WZ = read_arg16();
+ m_AF.b.h = read_mem(m_WZ.d);
+ break;
+ case 0x3b: // DCX SP
+ m_SP.w.l--;
+ if (is_8085())
+ {
+ if (m_SP.w.l == 0xffff)
+ m_AF.b.l |= X5F;
+ else
+ m_AF.b.l &= ~X5F;
+ }
+ break;
+ case 0x3c: // INR A
+ m_AF.b.h = op_inr(m_AF.b.h);
+ break;
+ case 0x3d: // DCR A
+ m_AF.b.h = op_dcr(m_AF.b.h);
+ break;
+ case 0x3e: // MVI A,nn
+ m_AF.b.h = read_arg();
+ break;
+ case 0x3f: // CMC
+ m_AF.b.l = (m_AF.b.l & 0xfe) | (~m_AF.b.l & CF);
+ break;
+
+ // MOV [B/C/D/E/H/L/M/A],[B/C/D/E/H/L/M/A]
+ case 0x40: break; // MOV B,B
+ case 0x41: m_BC.b.h = m_BC.b.l; break;
+ case 0x42: m_BC.b.h = m_DE.b.h; break;
+ case 0x43: m_BC.b.h = m_DE.b.l; break;
+ case 0x44: m_BC.b.h = m_HL.b.h; break;
+ case 0x45: m_BC.b.h = m_HL.b.l; break;
+ case 0x46: m_BC.b.h = read_mem(m_HL.d); break;
+ case 0x47: m_BC.b.h = m_AF.b.h; break;
+
+ case 0x48: m_BC.b.l = m_BC.b.h; break;
+ case 0x49: break; // MOV C,C
+ case 0x4a: m_BC.b.l = m_DE.b.h; break;
+ case 0x4b: m_BC.b.l = m_DE.b.l; break;
+ case 0x4c: m_BC.b.l = m_HL.b.h; break;
+ case 0x4d: m_BC.b.l = m_HL.b.l; break;
+ case 0x4e: m_BC.b.l = read_mem(m_HL.d); break;
+ case 0x4f: m_BC.b.l = m_AF.b.h; break;
+
+ case 0x50: m_DE.b.h = m_BC.b.h; break;
+ case 0x51: m_DE.b.h = m_BC.b.l; break;
+ case 0x52: break; // MOV D,D
+ case 0x53: m_DE.b.h = m_DE.b.l; break;
+ case 0x54: m_DE.b.h = m_HL.b.h; break;
+ case 0x55: m_DE.b.h = m_HL.b.l; break;
+ case 0x56: m_DE.b.h = read_mem(m_HL.d); break;
+ case 0x57: m_DE.b.h = m_AF.b.h; break;
+
+ case 0x58: m_DE.b.l = m_BC.b.h; break;
+ case 0x59: m_DE.b.l = m_BC.b.l; break;
+ case 0x5a: m_DE.b.l = m_DE.b.h; break;
+ case 0x5b: break; // MOV E,E
+ case 0x5c: m_DE.b.l = m_HL.b.h; break;
+ case 0x5d: m_DE.b.l = m_HL.b.l; break;
+ case 0x5e: m_DE.b.l = read_mem(m_HL.d); break;
+ case 0x5f: m_DE.b.l = m_AF.b.h; break;
+
+ case 0x60: m_HL.b.h = m_BC.b.h; break;
+ case 0x61: m_HL.b.h = m_BC.b.l; break;
+ case 0x62: m_HL.b.h = m_DE.b.h; break;
+ case 0x63: m_HL.b.h = m_DE.b.l; break;
+ case 0x64: break; // MOV H,H
+ case 0x65: m_HL.b.h = m_HL.b.l; break;
+ case 0x66: m_HL.b.h = read_mem(m_HL.d); break;
+ case 0x67: m_HL.b.h = m_AF.b.h; break;
+
+ case 0x68: m_HL.b.l = m_BC.b.h; break;
+ case 0x69: m_HL.b.l = m_BC.b.l; break;
+ case 0x6a: m_HL.b.l = m_DE.b.h; break;
+ case 0x6b: m_HL.b.l = m_DE.b.l; break;
+ case 0x6c: m_HL.b.l = m_HL.b.h; break;
+ case 0x6d: break; // MOV L,L
+ case 0x6e: m_HL.b.l = read_mem(m_HL.d); break;
+ case 0x6f: m_HL.b.l = m_AF.b.h; break;
+
+ case 0x70: write_mem(m_HL.d, m_BC.b.h); break;
+ case 0x71: write_mem(m_HL.d, m_BC.b.l); break;
+ case 0x72: write_mem(m_HL.d, m_DE.b.h); break;
+ case 0x73: write_mem(m_HL.d, m_DE.b.l); break;
+ case 0x74: write_mem(m_HL.d, m_HL.b.h); break;
+ case 0x75: write_mem(m_HL.d, m_HL.b.l); break;
+ case 0x76: // HLT (instead of MOV M,M)
+ m_PC.w.l--;
+ m_halt = 1;
+ set_status(0x8a); // halt acknowledge
+ break;
+ case 0x77: write_mem(m_HL.d, m_AF.b.h); break;
+
+ case 0x78: m_AF.b.h = m_BC.b.h; break;
+ case 0x79: m_AF.b.h = m_BC.b.l; break;
+ case 0x7a: m_AF.b.h = m_DE.b.h; break;
+ case 0x7b: m_AF.b.h = m_DE.b.l; break;
+ case 0x7c: m_AF.b.h = m_HL.b.h; break;
+ case 0x7d: m_AF.b.h = m_HL.b.l; break;
+ case 0x7e: m_AF.b.h = read_mem(m_HL.d); break;
+ case 0x7f: break; // MOV A,A
+
+ // alu op [B/C/D/E/H/L/M/A]
+ case 0x80: op_add(m_BC.b.h); break;
+ case 0x81: op_add(m_BC.b.l); break;
+ case 0x82: op_add(m_DE.b.h); break;
+ case 0x83: op_add(m_DE.b.l); break;
+ case 0x84: op_add(m_HL.b.h); break;
+ case 0x85: op_add(m_HL.b.l); break;
+ case 0x86: m_WZ.b.l = read_mem(m_HL.d); op_add(m_WZ.b.l); break;
+ case 0x87: op_add(m_AF.b.h); break;
+
+ case 0x88: op_adc(m_BC.b.h); break;
+ case 0x89: op_adc(m_BC.b.l); break;
+ case 0x8a: op_adc(m_DE.b.h); break;
+ case 0x8b: op_adc(m_DE.b.l); break;
+ case 0x8c: op_adc(m_HL.b.h); break;
+ case 0x8d: op_adc(m_HL.b.l); break;
+ case 0x8e: m_WZ.b.l = read_mem(m_HL.d); op_adc(m_WZ.b.l); break;
+ case 0x8f: op_adc(m_AF.b.h); break;
+
+ case 0x90: op_sub(m_BC.b.h); break;
+ case 0x91: op_sub(m_BC.b.l); break;
+ case 0x92: op_sub(m_DE.b.h); break;
+ case 0x93: op_sub(m_DE.b.l); break;
+ case 0x94: op_sub(m_HL.b.h); break;
+ case 0x95: op_sub(m_HL.b.l); break;
+ case 0x96: m_WZ.b.l = read_mem(m_HL.d); op_sub(m_WZ.b.l); break;
+ case 0x97: op_sub(m_AF.b.h); break;
+
+ case 0x98: op_sbb(m_BC.b.h); break;
+ case 0x99: op_sbb(m_BC.b.l); break;
+ case 0x9a: op_sbb(m_DE.b.h); break;
+ case 0x9b: op_sbb(m_DE.b.l); break;
+ case 0x9c: op_sbb(m_HL.b.h); break;
+ case 0x9d: op_sbb(m_HL.b.l); break;
+ case 0x9e: m_WZ.b.l = read_mem(m_HL.d); op_sbb(m_WZ.b.l); break;
+ case 0x9f: op_sbb(m_AF.b.h); break;
+
+ case 0xa0: op_ana(m_BC.b.h); break;
+ case 0xa1: op_ana(m_BC.b.l); break;
+ case 0xa2: op_ana(m_DE.b.h); break;
+ case 0xa3: op_ana(m_DE.b.l); break;
+ case 0xa4: op_ana(m_HL.b.h); break;
+ case 0xa5: op_ana(m_HL.b.l); break;
+ case 0xa6: m_WZ.b.l = read_mem(m_HL.d); op_ana(m_WZ.b.l); break;
+ case 0xa7: op_ana(m_AF.b.h); break;
+
+ case 0xa8: op_xra(m_BC.b.h); break;
+ case 0xa9: op_xra(m_BC.b.l); break;
+ case 0xaa: op_xra(m_DE.b.h); break;
+ case 0xab: op_xra(m_DE.b.l); break;
+ case 0xac: op_xra(m_HL.b.h); break;
+ case 0xad: op_xra(m_HL.b.l); break;
+ case 0xae: m_WZ.b.l = read_mem(m_HL.d); op_xra(m_WZ.b.l); break;
+ case 0xaf: op_xra(m_AF.b.h); break;
+
+ case 0xb0: op_ora(m_BC.b.h); break;
+ case 0xb1: op_ora(m_BC.b.l); break;
+ case 0xb2: op_ora(m_DE.b.h); break;
+ case 0xb3: op_ora(m_DE.b.l); break;
+ case 0xb4: op_ora(m_HL.b.h); break;
+ case 0xb5: op_ora(m_HL.b.l); break;
+ case 0xb6: m_WZ.b.l = read_mem(m_HL.d); op_ora(m_WZ.b.l); break;
+ case 0xb7: op_ora(m_AF.b.h); break;
+
+ case 0xb8: op_cmp(m_BC.b.h); break;
+ case 0xb9: op_cmp(m_BC.b.l); break;
+ case 0xba: op_cmp(m_DE.b.h); break;
+ case 0xbb: op_cmp(m_DE.b.l); break;
+ case 0xbc: op_cmp(m_HL.b.h); break;
+ case 0xbd: op_cmp(m_HL.b.l); break;
+ case 0xbe: m_WZ.b.l = read_mem(m_HL.d); op_cmp(m_WZ.b.l); break;
+ case 0xbf: op_cmp(m_AF.b.h); break;
+
+ case 0xc0: // RNZ
+ op_ret(!(m_AF.b.l & ZF));
+ break;
+ case 0xc1: // POP B
+ m_BC = op_pop();
+ break;
+ case 0xc2: // JNZ nnnn
+ op_jmp(!(m_AF.b.l & ZF));
+ break;
+ case 0xc3: // JMP nnnn
+ op_jmp(1);
+ break;
+ case 0xc4: // CNZ nnnn
+ op_call(!(m_AF.b.l & ZF));
+ break;
+ case 0xc5: // PUSH B
+ op_push(m_BC);
+ break;
+ case 0xc6: // ADI nn
+ m_WZ.b.l = read_arg();
+ op_add(m_WZ.b.l);
+ break;
+ case 0xc7: // RST 0
+ op_rst(0);
+ break;
+
+ case 0xc8: // RZ
+ op_ret(m_AF.b.l & ZF);
+ break;
+ case 0xc9: // RET
+ m_PC = op_pop();
+ break;
+ case 0xca: // JZ nnnn
+ op_jmp(m_AF.b.l & ZF);
+ break;
+ case 0xcb: // 8085: RST V, otherwise undocumented JMP nnnn
+ if (is_8085())
+ {
+ if (m_AF.b.l & VF)
+ op_rst(8);
+ else
+ m_icount += 6; // RST not taken
+ }
+ else
+ op_jmp(1);
+ break;
+ case 0xcc: // CZ nnnn
+ op_call(m_AF.b.l & ZF);
+ break;
+ case 0xcd: // CALL nnnn
+ op_call(1);
+ break;
+ case 0xce: // ACI nn
+ m_WZ.b.l = read_arg();
+ op_adc(m_WZ.b.l);
+ break;
+ case 0xcf: // RST 1
+ op_rst(1);
+ break;
+
+ case 0xd0: // RNC
+ op_ret(!(m_AF.b.l & CF));
+ break;
+ case 0xd1: // POP D
+ m_DE = op_pop();
+ break;
+ case 0xd2: // JNC nnnn
+ op_jmp(!(m_AF.b.l & CF));
+ break;
+ case 0xd3: // OUT nn
+ set_status(0x10);
+ m_WZ.d = read_arg();
+ m_io->write_byte(m_WZ.d, m_AF.b.h);
+ break;
+ case 0xd4: // CNC nnnn
+ op_call(!(m_AF.b.l & CF));
+ break;
+ case 0xd5: // PUSH D
+ op_push(m_DE);
+ break;
+ case 0xd6: // SUI nn
+ m_WZ.b.l = read_arg();
+ op_sub(m_WZ.b.l);
+ break;
+ case 0xd7: // RST 2
+ op_rst(2);
+ break;
+
+ case 0xd8: // RC
+ op_ret(m_AF.b.l & CF);
+ break;
+ case 0xd9: // 8085: SHLX, otherwise undocumented RET
+ if (is_8085())
+ {
+ m_WZ.w.l = m_DE.w.l;
+ write_mem(m_WZ.d, m_HL.b.l);
+ m_WZ.w.l++;
+ write_mem(m_WZ.d, m_HL.b.h);
+ }
+ else
+ m_PC = op_pop();
+ break;
+ case 0xda: // JC nnnn
+ op_jmp(m_AF.b.l & CF);
+ break;
+ case 0xdb: // IN nn
+ set_status(0x42);
+ m_WZ.d = read_arg();
+ m_AF.b.h = m_io->read_byte(m_WZ.d);
+ break;
+ case 0xdc: // CC nnnn
+ op_call(m_AF.b.l & CF);
+ break;
+ case 0xdd: // 8085: JNX nnnn, otherwise undocumented CALL nnnn
+ if (is_8085())
+ op_jmp(!(m_AF.b.l & X5F));
+ else
+ op_call(1);
+ break;
+ case 0xde: // SBI nn
+ m_WZ.b.l = read_arg();
+ op_sbb(m_WZ.b.l);
+ break;
+ case 0xdf: // RST 3
+ op_rst(3);
+ break;
+
+ case 0xe0: // RPO
+ op_ret(!(m_AF.b.l & PF));
+ break;
+ case 0xe1: // POP H
+ m_HL = op_pop();
+ break;
+ case 0xe2: // JPO nnnn
+ op_jmp(!(m_AF.b.l & PF));
+ break;
+ case 0xe3: // XTHL
+ m_WZ = op_pop();
+ op_push(m_HL);
+ m_HL.d = m_WZ.d;
+ break;
+ case 0xe4: // CPO nnnn
+ op_call(!(m_AF.b.l & PF));
+ break;
+ case 0xe5: // PUSH H
+ op_push(m_HL);
+ break;
+ case 0xe6: // ANI nn
+ m_WZ.b.l = read_arg();
+ op_ana(m_WZ.b.l);
+ break;
+ case 0xe7: // RST 4
+ op_rst(4);
+ break;
+
+ case 0xe8: // RPE
+ op_ret(m_AF.b.l & PF);
+ break;
+ case 0xe9: // PCHL
+ m_PC.d = m_HL.w.l;
+ break;
+ case 0xea: // JPE nnnn
+ op_jmp(m_AF.b.l & PF);
+ break;
+ case 0xeb: // XCHG
+ m_WZ.d = m_DE.d;
+ m_DE.d = m_HL.d;
+ m_HL.d = m_WZ.d;
+ break;
+ case 0xec: // CPE nnnn
+ op_call(m_AF.b.l & PF);
+ break;
+ case 0xed: // 8085: LHLX, otherwise undocumented CALL nnnn
+ if (is_8085())
+ {
+ m_WZ.w.l = m_DE.w.l;
+ m_HL.b.l = read_mem(m_WZ.d);
+ m_WZ.w.l++;
+ m_HL.b.h = read_mem(m_WZ.d);
+ }
+ else
+ op_call(1);
+ break;
+ case 0xee: // XRI nn
+ m_WZ.b.l = read_arg();
+ op_xra(m_WZ.b.l);
+ break;
+ case 0xef: // RST 5
+ op_rst(5);
+ break;
+
+ case 0xf0: // RP
+ op_ret(!(m_AF.b.l & SF));
+ break;
+ case 0xf1: // POP A
+ m_AF = op_pop();
+ break;
+ case 0xf2: // JP nnnn
+ op_jmp(!(m_AF.b.l & SF));
+ break;
+ case 0xf3: // DI
+ set_inte(0);
+ break;
+ case 0xf4: // CP nnnn
+ op_call(!(m_AF.b.l & SF));
+ break;
+ case 0xf5: // PUSH A
+ // on 8080, VF=1 and X3F=0 and X5F=0 always! (we don't have to check for it elsewhere)
+ if (is_8080())
+ m_AF.b.l = (m_AF.b.l & ~(X3F | X5F)) | VF;
+ op_push(m_AF);
+ break;
+ case 0xf6: // ORI nn
+ m_WZ.b.l = read_arg();
+ op_ora(m_WZ.b.l);
+ break;
+ case 0xf7: // RST 6
+ op_rst(6);
+ break;
+
+ case 0xf8: // RM
+ op_ret(m_AF.b.l & SF);
+ break;
+ case 0xf9: // SPHL
+ m_SP.d = m_HL.d;
+ break;
+ case 0xfa: // JM nnnn
+ op_jmp(m_AF.b.l & SF);
+ break;
+ case 0xfb: // EI
+ set_inte(1);
+ m_after_ei = 2;
+ break;
+ case 0xfc: // CM nnnn
+ op_call(m_AF.b.l & SF);
+ break;
+ case 0xfd: // 8085: JX nnnn, otherwise undocumented CALL nnnn
+ if (is_8085())
+ op_jmp(m_AF.b.l & X5F);
+ else
+ op_call(1);
+ break;
+ case 0xfe: // CPI nn
+ m_WZ.b.l = read_arg();
+ op_cmp(m_WZ.b.l);
+ break;
+ case 0xff: // RST 7
+ op_rst(7);
+ break;
+ } // end big switch
}
diff --git a/src/devices/cpu/i8085/i8085.h b/src/devices/cpu/i8085/i8085.h
index 41f681f8897..b4ab5901c1f 100644
--- a/src/devices/cpu/i8085/i8085.h
+++ b/src/devices/cpu/i8085/i8085.h
@@ -53,17 +53,17 @@ public:
I8085_HALT, I8085_IM
};
- static constexpr uint8_t STATUS_INTA = 0x01;
- static constexpr uint8_t STATUS_WO = 0x02;
- static constexpr uint8_t STATUS_STACK = 0x04;
- static constexpr uint8_t STATUS_HLTA = 0x08;
- static constexpr uint8_t STATUS_OUT = 0x10;
- static constexpr uint8_t STATUS_M1 = 0x20;
- static constexpr uint8_t STATUS_INP = 0x40;
- static constexpr uint8_t STATUS_MEMR = 0x80;
+ static constexpr u8 STATUS_INTA = 0x01;
+ static constexpr u8 STATUS_WO = 0x02;
+ static constexpr u8 STATUS_STACK = 0x04;
+ static constexpr u8 STATUS_HLTA = 0x08;
+ static constexpr u8 STATUS_OUT = 0x10;
+ static constexpr u8 STATUS_M1 = 0x20;
+ static constexpr u8 STATUS_INP = 0x40;
+ static constexpr u8 STATUS_MEMR = 0x80;
// construction/destruction
- i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// static configuration helpers
template <class Object> static devcb_base &set_out_status_func(device_t &device, Object &&cb) { return downcast<i8085a_cpu_device &>(device).m_out_status_func.set_callback(std::forward<Object>(cb)); }
@@ -73,7 +73,7 @@ public:
static void static_set_clk_out(device_t &device, clock_update_delegate &&clk_out) { downcast<i8085a_cpu_device &>(device).m_clk_out_func = std::move(clk_out); }
protected:
- i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cputype);
+ i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int cputype);
// device-level overrides
virtual void device_config_complete() override;
@@ -82,14 +82,14 @@ protected:
virtual void device_reset() override;
// device_execute_interface overrides
- virtual uint32_t execute_min_cycles() const override { return 4; }
- virtual uint32_t execute_max_cycles() const override { return 16; }
- virtual uint32_t execute_input_lines() const override { return 4; }
- virtual uint32_t execute_default_irq_vector() const override { return 0xff; }
+ virtual u32 execute_min_cycles() const override { return 4; }
+ virtual u32 execute_max_cycles() const override { return 16; }
+ virtual u32 execute_input_lines() const override { return 4; }
+ virtual u32 execute_default_irq_vector() const override { return 0xff; }
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
- virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 2 - 1) / 2; }
- virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 2); }
+ virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return (clocks + 2 - 1) / 2; }
+ virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return (cycles * 2); }
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
@@ -100,62 +100,89 @@ protected:
virtual void state_import(const device_state_entry &entry) override;
// device_disasm_interface overrides
- virtual uint32_t disasm_min_opcode_bytes() const override { return 1; }
- virtual uint32_t disasm_max_opcode_bytes() const override { return 3; }
- virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override;
+ virtual util::disasm_interface *create_disassembler() override;
+
+ enum
+ {
+ CPUTYPE_8080 = 0,
+ CPUTYPE_8080A,
+ CPUTYPE_8085A
+ };
private:
address_space_config m_program_config;
address_space_config m_io_config;
+ address_space_config m_opcode_config;
- devcb_write8 m_out_status_func;
- devcb_write_line m_out_inte_func;
- devcb_read_line m_in_sid_func;
- devcb_write_line m_out_sod_func;
+ devcb_write8 m_out_status_func;
+ devcb_write_line m_out_inte_func;
+ devcb_read_line m_in_sid_func;
+ devcb_write_line m_out_sod_func;
clock_update_delegate m_clk_out_func;
- int m_cputype; /* 0 8080, 1 8085A */
- PAIR m_PC,m_SP,m_AF,m_BC,m_DE,m_HL,m_WZ;
- uint8_t m_HALT;
- uint8_t m_IM; /* interrupt mask (8085A only) */
- uint8_t m_STATUS; /* status word */
+ inline bool is_8080() { return m_cputype == CPUTYPE_8080 || m_cputype == CPUTYPE_8080A; }
+ inline bool is_8085() { return m_cputype == CPUTYPE_8085A; }
+ int m_cputype;
+
+ PAIR m_PC,m_SP,m_AF,m_BC,m_DE,m_HL,m_WZ;
+ u8 m_halt;
+ u8 m_im; /* interrupt mask (8085A only) */
+ u8 m_status; /* status word */
- uint8_t m_after_ei; /* post-EI processing; starts at 2, check for ints at 0 */
- uint8_t m_nmi_state; /* raw NMI line state */
- uint8_t m_irq_state[4]; /* raw IRQ line states */
- uint8_t m_trap_pending; /* TRAP interrupt latched? */
- uint8_t m_trap_im_copy; /* copy of IM register when TRAP was taken */
- uint8_t m_sod_state; /* state of the SOD line */
+ u8 m_after_ei; /* post-EI processing; starts at 2, check for ints at 0 */
+ u8 m_nmi_state; /* raw NMI line state */
+ u8 m_irq_state[4]; /* raw IRQ line states */
+ u8 m_trap_pending; /* TRAP interrupt latched? */
+ u8 m_trap_im_copy; /* copy of IM register when TRAP was taken */
+ u8 m_sod_state; /* state of the SOD line */
- bool m_ietemp; /* import/export temp space */
+ bool m_ietemp; /* import/export temp space */
address_space *m_program;
- direct_read_data *m_direct;
+ direct_read_data<0> *m_direct;
+ direct_read_data<0> *m_opcode_direct;
address_space *m_io;
- int m_icount;
+ int m_icount;
/* cycles lookup */
- static const uint8_t lut_cycles_8080[256];
- static const uint8_t lut_cycles_8085[256];
- uint8_t lut_cycles[256];
+ static const u8 lut_cycles_8080[256];
+ static const u8 lut_cycles_8085[256];
+ u8 lut_cycles[256];
/* flags lookup */
- uint8_t ZS[256];
- uint8_t ZSP[256];
+ u8 lut_zs[256];
+ u8 lut_zsp[256];
void set_sod(int state);
void set_inte(int state);
- void set_status(uint8_t status);
- uint8_t get_rim_value();
+ void set_status(u8 status);
+ u8 get_rim_value();
void break_halt_for_interrupt();
- uint8_t ROP();
- uint8_t ARG();
- uint16_t ARG16();
- uint8_t RM(uint32_t a);
- void WM(uint32_t a, uint8_t v);
+ u8 read_op();
+ u8 read_arg();
+ PAIR read_arg16();
+ u8 read_mem(u32 a);
+ void write_mem(u32 a, u8 v);
+ void op_push(PAIR p);
+ PAIR op_pop();
void check_for_interrupts();
void execute_one(int opcode);
void init_tables();
+ void op_ora(u8 v);
+ void op_xra(u8 v);
+ void op_ana(u8 v);
+ u8 op_inr(u8 v);
+ u8 op_dcr(u8 v);
+ void op_add(u8 v);
+ void op_adc(u8 v);
+ void op_sub(u8 v);
+ void op_sbb(u8 v);
+ void op_cmp(u8 v);
+ void op_dad(u16 v);
+ void op_jmp(int cond);
+ void op_call(int cond);
+ void op_ret(int cond);
+ void op_rst(u8 v);
};
@@ -163,12 +190,12 @@ class i8080_cpu_device : public i8085a_cpu_device
{
public:
// construction/destruction
- i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
- virtual uint32_t execute_input_lines() const override { return 1; }
- virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return clocks; }
- virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return cycles; }
+ virtual u32 execute_input_lines() const override { return 1; }
+ virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return clocks; }
+ virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return cycles; }
};
@@ -176,12 +203,12 @@ class i8080a_cpu_device : public i8085a_cpu_device
{
public:
// construction/destruction
- i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
- virtual uint32_t execute_input_lines() const override { return 1; }
- virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return clocks; }
- virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return cycles; }
+ virtual u32 execute_input_lines() const override { return 1; }
+ virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return clocks; }
+ virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return cycles; }
};
diff --git a/src/devices/cpu/i8085/i8085cpu.h b/src/devices/cpu/i8085/i8085cpu.h
deleted file mode 100644
index a41e96f06c7..00000000000
--- a/src/devices/cpu/i8085/i8085cpu.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Juergen Buchmueller, hap
-/*******************************************************
- *
- * Portable (hopefully ;-) 8085A emulator
- *
- * Written by J. Buchmueller for use with MAME
- *
- * Partially based on Z80Em by Marcel De Kogel
- *
- * CPU related macros
- *
- *******************************************************/
-
-
-#define SF 0x80
-#define ZF 0x40
-#define X5F 0x20
-#define HF 0x10
-#define X3F 0x08
-#define PF 0x04
-#define VF 0x02
-#define CF 0x01
-
-#define IM_SID 0x80
-#define IM_I75 0x40
-#define IM_I65 0x20
-#define IM_I55 0x10
-#define IM_IE 0x08
-#define IM_M75 0x04
-#define IM_M65 0x02
-#define IM_M55 0x01
-
-#define ADDR_TRAP 0x0024
-#define ADDR_RST55 0x002c
-#define ADDR_RST65 0x0034
-#define ADDR_RST75 0x003c
-#define ADDR_INTR 0x0038
-
-
-#define M_MVI(R) R=ARG()
-
-/* rotate */
-#define M_RLC { \
- m_AF.b.h = (m_AF.b.h << 1) | (m_AF.b.h >> 7); \
- m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \
-}
-
-#define M_RRC { \
- m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \
- m_AF.b.h = (m_AF.b.h >> 1) | (m_AF.b.h << 7); \
-}
-
-#define M_RAL { \
- int c = m_AF.b.l&CF; \
- m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h >> 7); \
- m_AF.b.h = (m_AF.b.h << 1) | c; \
-}
-
-#define M_RAR { \
- int c = (m_AF.b.l&CF) << 7; \
- m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \
- m_AF.b.h = (m_AF.b.h >> 1) | c; \
-}
-
-/* logical */
-#define M_ORA(R) m_AF.b.h|=R; m_AF.b.l=ZSP[m_AF.b.h]
-#define M_XRA(R) m_AF.b.h^=R; m_AF.b.l=ZSP[m_AF.b.h]
-#define M_ANA(R) {uint8_t hc = ((m_AF.b.h | R)<<1) & HF; m_AF.b.h&=R; m_AF.b.l=ZSP[m_AF.b.h]; if(IS_8085()) { m_AF.b.l |= HF; } else {m_AF.b.l |= hc; } }
-
-/* increase / decrease */
-#define M_INR(R) {uint8_t hc = ((R & 0x0f) == 0x0f) ? HF : 0; ++R; m_AF.b.l= (m_AF.b.l & CF ) | ZSP[R] | hc; }
-#define M_DCR(R) {uint8_t hc = ((R & 0x0f) != 0x00) ? HF : 0; --R; m_AF.b.l= (m_AF.b.l & CF ) | ZSP[R] | hc | VF; }
-
-/* arithmetic */
-#define M_ADD(R) { \
- int q = m_AF.b.h+R; \
- m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|((m_AF.b.h^q^R)&HF); \
- m_AF.b.h=q; \
-}
-
-#define M_ADC(R) { \
- int q = m_AF.b.h+R+(m_AF.b.l&CF); \
- m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|((m_AF.b.h^q^R)&HF); \
- m_AF.b.h=q; \
-}
-
-#define M_SUB(R) { \
- int q = m_AF.b.h-R; \
- m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \
- m_AF.b.h=q; \
-}
-
-#define M_SBB(R) { \
- int q = m_AF.b.h-R-(m_AF.b.l&CF); \
- m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \
- m_AF.b.h=q; \
-}
-
-#define M_CMP(R) { \
- int q = m_AF.b.h-R; \
- m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \
-}
-
-#define M_DAD(R) { \
- int q = m_HL.d + m_##R.d; \
- m_AF.b.l = (m_AF.b.l & ~CF) | (q>>16 & CF ); \
- m_HL.w.l = q; \
-}
-
-// DSUB is 8085-only, not sure if H flag handling is correct
-#define M_DSUB() { \
- int q = m_HL.b.l-m_BC.b.l; \
- m_AF.b.l=ZS[q&255]|((q>>8)&CF)|VF| \
- ((m_HL.b.l^q^m_BC.b.l)&HF)| \
- (((m_BC.b.l^m_HL.b.l)&(m_HL.b.l^q)&SF)>>5); \
- m_HL.b.l=q; \
- q = m_HL.b.h-m_BC.b.h-(m_AF.b.l&CF); \
- m_AF.b.l=ZS[q&255]|((q>>8)&CF)|VF| \
- ((m_HL.b.h^q^m_BC.b.h)&HF)| \
- (((m_BC.b.h^m_HL.b.h)&(m_HL.b.h^q)&SF)>>5); \
- if (m_HL.b.l!=0) m_AF.b.l&=~ZF; \
-}
-
-/* i/o */
-#define M_IN \
- set_status(0x42); \
- m_WZ.d=ARG(); \
- m_AF.b.h=m_io->read_byte(m_WZ.d);
-
-#define M_OUT \
- set_status(0x10); \
- m_WZ.d=ARG(); \
- m_io->write_byte(m_WZ.d,m_AF.b.h)
-
-/* stack */
-#define M_PUSH(R) { \
- set_status(0x04); \
- m_program->write_byte(--m_SP.w.l, m_##R.b.h); \
- m_program->write_byte(--m_SP.w.l, m_##R.b.l); \
-}
-
-#define M_POP(R) { \
- set_status(0x86); \
- m_##R.b.l = m_program->read_byte(m_SP.w.l++); \
- m_##R.b.h = m_program->read_byte(m_SP.w.l++); \
-}
-
-/* jumps */
-// On 8085 jump if condition is not satisfied is shorter
-#define M_JMP(cc) { \
- if (cc) { \
- m_PC.w.l = ARG16(); \
- } else { \
- m_PC.w.l += 2; \
- m_icount += (IS_8085()) ? 3 : 0; \
- } \
-}
-
-// On 8085 call if condition is not satisfied is 9 ticks
-#define M_CALL(cc) \
-{ \
- if (cc) \
- { \
- uint16_t a = ARG16(); \
- m_icount -= (IS_8085()) ? 7 : 6 ; \
- M_PUSH(PC); \
- m_PC.d = a; \
- } else { \
- m_PC.w.l += 2; \
- m_icount += (IS_8085()) ? 2 : 0; \
- } \
-}
-
-// conditional RET only
-#define M_RET(cc) \
-{ \
- if (cc) \
- { \
- m_icount -= 6; \
- M_POP(PC); \
- } \
-}
-
-#define M_RST(nn) { \
- M_PUSH(PC); \
- m_PC.d = 8 * nn; \
-}