summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/lh5801
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/lh5801')
-rw-r--r--src/devices/cpu/lh5801/5801dasm.c725
-rw-r--r--src/devices/cpu/lh5801/5801tbl.inc689
-rw-r--r--src/devices/cpu/lh5801/lh5801.c254
-rw-r--r--src/devices/cpu/lh5801/lh5801.h188
4 files changed, 1856 insertions, 0 deletions
diff --git a/src/devices/cpu/lh5801/5801dasm.c b/src/devices/cpu/lh5801/5801dasm.c
new file mode 100644
index 00000000000..b622bda9de6
--- /dev/null
+++ b/src/devices/cpu/lh5801/5801dasm.c
@@ -0,0 +1,725 @@
+// license:BSD-3-Clause
+// copyright-holders:Peter Trauner
+/*****************************************************************************
+ *
+ * disasm.c
+ * portable lh5801 emulator interface
+ *
+ *
+ *****************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+
+#include "lh5801.h"
+
+enum Adr
+{
+ Imp,
+ Reg,
+ Vec, // imm byte (vector at 0xffxx)
+ Vej,
+ Imm,
+ RegImm,
+ Imm16,
+ RegImm16,
+ ME0,
+ ME0Imm,
+ Abs,
+ AbsImm,
+ ME1,
+ ME1Imm,
+ ME1Abs,
+ ME1AbsImm,
+ RelP,
+ RelM
+};
+
+enum Regs
+{
+ RegNone,
+ A,
+ XL, XH, X,
+ YL, YH, Y,
+ UL, UH, U,
+ P, S
+};
+
+static const char *const RegNames[]= {
+ 0, "A", "XL", "XH", "X", "YL", "YH", "Y", "UL", "UH", "U", "P", "S"
+};
+
+#if defined(SEC)
+#undef SEC
+#endif
+
+enum Ins
+{
+ ILL, ILL2, PREFD, NOP,
+
+ LDA, STA, LDI, LDX, STX,
+ LDE, SDE, LIN, SIN,
+ TIN, // (x++)->(y++)
+ ADC, ADI, ADR, SBC, SBI,
+ DCA, DCS, // bcd add and sub
+ CPA, CPI, CIN, // A compared with (x++)
+ AND, ANI, ORA, ORI, EOR, EAI, BIT, BII,
+ INC, DEC,
+ DRL, DRR, // digit rotates
+ ROL, ROR,
+ SHL, SHR,
+ AEX, // A nibble swap
+
+ BCR, BCS, BHR, BHS, BZR, BZS, BVR, BVS,
+ BCH, LOP, // loop with ul
+ JMP, SJP, RTN, RTI, HLT,
+ VCR, VCS, VHR, VHS, VVS, VZR, VZS,
+ VMJ, VEJ,
+ PSH, POP, ATT, TTA,
+ REC, SEC, RIE, SIE,
+
+ AM0, AM1, // load timer reg
+ ITA, // reads input port
+ ATP, // akku send to data bus
+ CDV, // clears internal divider
+ OFF, // clears bf flip flop
+ RDP, SDP,// reset display flip flop
+ RPU, SPU,// flip flop pu off
+ RPV, SPV // flip flop pv off
+};
+
+static const char *const InsNames[]={
+ "ILL", "ILL", 0, "NOP",
+ "LDA", "STA", "LDI", "LDX", "STX",
+ "LDE", "SDE", "LIN", "SIN",
+ "TIN",
+ "ADC", "ADI", "ADR", "SBC", "SBI",
+ "DCA", "DCS",
+ "CPA", "CPI", "CIN",
+ "AND", "ANI", "ORA", "ORI", "EOR", "EAI", "BIT", "BII",
+ "INC", "DEC",
+ "DRL", "DRR",
+ "ROL", "ROR",
+ "SHL", "SHR",
+ "AEX",
+ "BCR", "BCS", "BHR", "BHS", "BZR", "BZS", "BVR", "BVS",
+ "BCH", "LOP",
+ "JMP", "SJP", "RTN", "RTI", "HLT",
+ "VCR", "VCS", "VHR", "VHS", "VVS", "VZR", "VZS",
+ "VMJ", "VEJ",
+ "PSH", "POP", "ATT", "TTA",
+ "REC", "SEC", "RIE", "SIE",
+
+ "AM0", "AM1",
+ "ITA",
+ "ATP",
+ "CDV",
+ "OFF",
+ "RDP", "SDP",
+ "RPU", "SPU",
+ "RPV", "SPV",
+};
+
+struct Entry { Ins ins; Adr adr; Regs reg; };
+
+static const Entry table[0x100]={
+ { SBC, Reg, XL }, // 0
+ { SBC, ME0, X },
+ { ADC, Reg, XL },
+ { ADC, ME0, X },
+ { LDA, Reg, XL },
+ { LDA, ME0, X },
+ { CPA, Reg, XL },
+ { CPA, ME0, X },
+ { STA, Reg, XH },
+ { AND, ME0, X },
+ { STA, Reg, XL },
+ { ORA, ME0, X },
+ { DCS, ME0, X },
+ { EOR, ME0, X },
+ { STA, ME0, X },
+ { BIT, ME0, X },
+ { SBC, Reg, YL }, // 0x10
+ { SBC, ME0, Y },
+ { ADC, Reg, YL },
+ { ADC, ME0, Y },
+ { LDA, Reg, YL },
+ { LDA, ME0, Y },
+ { CPA, Reg, YL },
+ { CPA, ME0, Y },
+ { STA, Reg, YH },
+ { AND, ME0, Y },
+ { STA, Reg, YL },
+ { ORA, ME0, Y },
+ { DCS, ME0, Y },
+ { EOR, ME0, Y },
+ { STA, ME0, Y },
+ { BIT, ME0, Y },
+ { SBC, Reg, UL }, // 0x20
+ { SBC, ME0, U },
+ { ADC, Reg, UL },
+ { ADC, ME0, U },
+ { LDA, Reg, UL },
+ { LDA, ME0, U },
+ { CPA, Reg, UL },
+ { CPA, ME0, U },
+ { STA, Reg, UH },
+ { AND, ME0, U },
+ { STA, Reg, UL },
+ { ORA, ME0, U },
+ { DCS, ME0, U },
+ { EOR, ME0, U },
+ { STA, ME0, U },
+ { BIT, ME0, U },
+ { ILL }, // 0x30
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { NOP, Imp },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { INC, Reg, XL }, //0x40
+ { SIN, Reg, X },
+ { DEC, Reg, XL },
+ { SDE, Reg, X },
+ { INC, Reg, X },
+ { LIN, Reg, X },
+ { DEC, Reg, X },
+ { LDE, Reg, X },
+ { LDI, RegImm, XH },
+ { ANI, ME0Imm, X },
+ { LDI, RegImm, XL },
+ { ORI, ME0Imm, X },
+ { CPI, RegImm, XH },
+ { BII, ME0Imm, X },
+ { CPI, RegImm, XL },
+ { ADI, ME0Imm, X },
+ { INC, Reg, YL }, //0x50
+ { SIN, Reg, Y },
+ { DEC, Reg, YL },
+ { SDE, Reg, Y },
+ { INC, Reg, Y },
+ { LIN, Reg, Y },
+ { DEC, Reg, Y },
+ { LDE, Reg, Y },
+ { LDI, RegImm, YH },
+ { ANI, ME0Imm, Y },
+ { LDI, RegImm, YL },
+ { ORI, ME0Imm, Y },
+ { CPI, RegImm, YH },
+ { BII, ME0Imm, Y },
+ { CPI, RegImm, YL },
+ { ADI, ME0Imm, Y },
+ { INC, Reg, UL }, //0x60
+ { SIN, Reg, U },
+ { DEC, Reg, UL },
+ { SDE, Reg, U },
+ { INC, Reg, U },
+ { LIN, Reg, U },
+ { DEC, Reg, U },
+ { LDE, Reg, U },
+ { LDI, RegImm, UH },
+ { ANI, ME0Imm, U },
+ { LDI, RegImm, UL },
+ { ORI, ME0Imm, U },
+ { CPI, RegImm, UH },
+ { BII, ME0Imm, U },
+ { CPI, RegImm, UL },
+ { ADI, ME0Imm, U },
+ { ILL }, // 0X70
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { ILL },
+ { SBC, Reg, XH }, // 0x80
+ { BCR, RelP },
+ { ADC, Reg, XH },
+ { BCS, RelP },
+ { LDA, Reg, XH },
+ { BHR, RelP },
+ { CPA, Reg, XH },
+ { BHS, RelP },
+ { LOP, RelM },
+ { BZR, RelP },
+ { RTI, Imp },
+ { BZS, RelP },
+ { DCA, ME0, X },
+ { BVR, RelP },
+ { BCH, RelP },
+ { BVS, RelP },
+ { SBC, Reg, YH }, // 0x90
+ { BCR, RelM },
+ { ADC, Reg, YH },
+ { BCS, RelM },
+ { LDA, Reg, YH },
+ { BHR, RelM },
+ { CPA, Reg, YH },
+ { BHS, RelM },
+ { ILL },
+ { BZR, RelM },
+ { RTN, Imp },
+ { BZS, RelM },
+ { DCA, ME0, Y },
+ { BVR, RelM },
+ { BCH, RelM },
+ { BVS, RelM },
+ { SBC, Reg, UH }, // 0xa0
+ { SBC, Abs },
+ { ADC, Reg, UH },
+ { ADC, Abs },
+ { LDA, Reg, UH },
+ { LDA, Abs },
+ { CPA, Reg, UH },
+ { CPA, Abs },
+ { SPV, Imp },
+ { AND, Abs },
+ { LDI, RegImm16, S },
+ { ORA, Abs },
+ { DCA, ME0, U },
+ { EOR, Abs },
+ { STA, Abs },
+ { BIT, Abs },
+ { ILL }, //0xb0
+ { SBI },
+ { ILL },
+ { ADI, RegImm, A },
+ { ILL },
+ { LDI, RegImm, A },
+ { ILL },
+ { CPI, RegImm, A },
+ { RPV, Imp },
+ { ANI, RegImm, A },
+ { JMP, Imm16 },
+ { ORI, RegImm, A },
+ { ILL },
+ { EAI, Imm },
+ { SJP, Imm16 },
+ { BII, RegImm, A },
+ { VEJ, Vej }, // 0xc0
+ { VCR, Vec },
+ { VEJ, Vej },
+ { VCS, Vec },
+ { VEJ, Vej },
+ { VHR, Vec },
+ { VEJ, Vej },
+ { VHS, Vec },
+ { VEJ, Vej },
+ { VZR, Vec },
+ { VEJ, Vej },
+ { VZS, Vec },
+ { VEJ, Vej },
+ { VMJ, Vec },
+ { VEJ, Vej },
+ { VVS, Vec },
+ { VEJ, Vej }, // 0xd0
+ { ROR, Imp },
+ { VEJ, Vej },
+ { DRR, Imp },
+ { VEJ, Vej },
+ { SHR, Imp },
+ { VEJ, Vej },
+ { DRL, Imp },
+ { VEJ, Vej },
+ { SHL, Imp },
+ { VEJ, Vej },
+ { ROL, Imp },
+ { VEJ, Vej },
+ { INC, Reg, A },
+ { VEJ, Vej },
+ { DEC, Reg, A },
+ { VEJ, Vej }, //0xe0
+ { SPU, Imp },
+ { VEJ, Vej },
+ { RPU, Imp },
+ { VEJ, Vej },
+ { ILL },
+ { VEJ, Vej },
+ { ILL },
+ { VEJ, Vej },
+ { ANI, AbsImm },
+ { VEJ, Vej },
+ { ORI, AbsImm },
+ { VEJ, Vej },
+ { BII, AbsImm },
+ { VEJ, Vej },
+ { ADI, AbsImm },
+ { VEJ, Vej }, //0xf0
+ { AEX, Imp },
+ { VEJ, Vej },
+ { ILL },
+ { VEJ, Vej },
+ { TIN, Imp },
+ { VEJ, Vej },
+ { CIN, Imp },
+ { ILL },
+ { REC, Imp },
+ { ILL },
+ { SEC, Imp },
+ { ILL },
+ { PREFD },
+ { ILL },
+ { ILL }
+};
+static const Entry table_fd[0x100]={
+ { ILL2 }, // 0x00
+ { SBC, ME1, X },
+ { ILL2 },
+ { ADC, ME1, X },
+ { ILL2 },
+ { LDA, ME1, X },
+ { ILL2 },
+ { CPA, ME1, X },
+ { LDX, Reg, X },
+ { AND, ME1, X },
+ { POP, Reg, X },
+ { ORA, ME1, X },
+ { DCS, ME1, X },
+ { EOR, ME1, X },
+ { STA, ME1, X },
+ { BIT, ME1, X },
+ { ILL2 }, // 0x10
+ { SBC, ME1, Y },
+ { ILL2 },
+ { ADC, ME1, Y },
+ { ILL2 },
+ { LDA, ME1, Y },
+ { ILL2 },
+ { CPA, ME1, Y },
+ { LDX, Reg, Y },
+ { AND, ME1, Y },
+ { POP, Reg, Y },
+ { ORA, ME1, Y },
+ { DCS, ME1, Y },
+ { EOR, ME1, Y },
+ { STA, ME1, Y },
+ { BIT, ME1, Y },
+ { ILL2 }, // 0x20
+ { SBC, ME1, U },
+ { ILL2 },
+ { ADC, ME1, U },
+ { ILL2 },
+ { LDA, ME1, U },
+ { ILL2 },
+ { CPA, ME1, U },
+ { LDX, Reg, U },
+ { AND, ME1, U },
+ { POP, Reg, U },
+ { ORA, ME1, U },
+ { DCS, ME1, U },
+ { EOR, ME1, U },
+ { STA, ME1, U },
+ { BIT, ME1, U },
+ { ILL2 }, // 0x30
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { INC, Reg, XH }, // 0x40
+ { ILL2 },
+ { DEC, Reg, XH }, //46 in other part of manual
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { LDX, Reg, S },
+ { ANI, ME1Imm, X },
+ { STX, Reg, X },
+ { ORI, ME1Imm, X },
+ { OFF, Imp },
+ { BII, ME1Imm, X },
+ { STX, Reg, S },
+ { ADI, ME1Imm, X },
+ { INC, Reg, YH }, // 0x50
+ { ILL2 },
+ { DEC, Reg, YH }, // 56 in other part of manual
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { LDX, Reg, P },
+ { ANI, ME1Imm, Y },
+ { STX, Reg, Y },
+ { ORI, ME1Imm, Y },
+ { ILL2 },
+ { BII, ME1Imm, Y },
+ { STX, Reg, P },
+ { ADI, ME1Imm, Y },
+ { INC, Reg, UH }, // 0x60
+ { ILL2 },
+ { DEC, Reg, UH }, // 66 in other part of manual
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ANI, ME1Imm, U },
+ { STX, Reg, U },
+ { ORI, ME1Imm, U },
+ { ILL2 },
+ { BII, ME1Imm, U },
+ { ILL },
+ { ADI, ME1Imm, U },
+ { ILL2 }, // 0x70
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 }, // 0x80
+ { SIE, Imp },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { PSH, Reg, X },
+ { ILL2 },
+ { POP, Reg, A },
+ { ILL2 },
+ { DCA, ME1, X },
+ { ILL2 },
+ { CDV, Imp },
+ { ILL2 },
+ { ILL2 }, // 0x90
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { PSH, Reg, Y },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { DCA, ME1, Y },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 }, // 0xa0
+ { SBC, ME1Abs },
+ { ILL2 },
+ { ADC, ME1Abs },
+ { ILL2 },
+ { LDA, ME1Abs },
+ { ILL2 },
+ { CPA, ME1Abs },
+ { PSH, Reg, U },
+ { AND, ME1Abs },
+ { TTA, Imp },
+ { ORA, ME1Abs },
+ { DCA, ME1, U },
+ { EOR, ME1Abs },
+ { STA, ME1Abs },
+ { BIT, ME1Abs },
+ { ILL2 }, // 0xb0
+ { HLT, Imp },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ITA, Imp },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { RIE, Imp },
+ { ILL2 },
+ { RDP, Imp }, // 0xc0
+ { SDP, Imp },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { PSH, Reg, A },
+ { ILL2 },
+ { ADR, Reg, X },
+ { ILL2 },
+ { ATP, Imp },
+ { ILL2 },
+ { AM0, Imp },
+ { ILL2 },
+ { ILL2 }, // 0xd0
+ { ILL2 },
+ { ILL2 },
+ { DRR, ME1, X },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { DRL, ME1, X },
+ { ILL2 },
+ { ILL2 },
+ { ADR, Reg, Y },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { AM1, Imp },
+ { ILL2 },
+ { ILL2 }, // 0xe0
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ANI, ME1AbsImm },
+ { ADR, Reg, U },
+ { ORI, ME1AbsImm },
+ { ATT, Imp },
+ { BII, ME1AbsImm },
+ { ILL2 },
+ { ADI, ME1AbsImm },
+ { ILL2 }, // 0xf0
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 },
+ { ILL2 }
+};
+
+CPU_DISASSEMBLE( lh5801 )
+{
+ int pos = 0;
+ int oper;
+ UINT16 absolut;
+ const Entry *entry;
+ int temp;
+
+ oper=oprom[pos++];
+ entry=table+oper;
+
+ if (table[oper].ins==PREFD) {
+ oper=oprom[pos++];
+ entry=table_fd+oper;
+ }
+ switch (entry->ins) {
+ case ILL:
+ sprintf(buffer,"%s %.2x", InsNames[entry->ins], oper);break;
+ case ILL2:
+ sprintf(buffer,"%s fd%.2x", InsNames[entry->ins], oper);break;
+ default:
+ switch(entry->adr) {
+ case Imp:
+ sprintf(buffer,"%s", InsNames[entry->ins]);break;
+ case Reg:
+ sprintf(buffer,"%s %s", InsNames[entry->ins],RegNames[entry->reg]);break;
+ case RegImm:
+ sprintf(buffer,"%s %s,%.2x", InsNames[entry->ins],
+ RegNames[entry->reg], oprom[pos++]);
+ break;
+ case RegImm16:
+ absolut=oprom[pos++]<<8;
+ absolut|=oprom[pos++];
+ sprintf(buffer,"%s %s,%.4x", InsNames[entry->ins],RegNames[entry->reg],absolut );
+ break;
+ case Vec:
+ sprintf(buffer,"%s (ff%.2x)", InsNames[entry->ins],oprom[pos++]);break;
+ case Vej:
+ sprintf(buffer,"%s (ff%.2x)", InsNames[entry->ins], oper);break;
+ case Imm:
+ sprintf(buffer,"%s %.2x", InsNames[entry->ins],oprom[pos++]);break;
+ case Imm16:
+ absolut=oprom[pos++]<<8;
+ absolut|=oprom[pos++];
+ sprintf(buffer,"%s %.4x", InsNames[entry->ins],absolut );break;
+ case RelP:
+ temp=oprom[pos++];
+ sprintf(buffer,"%s %.4x", InsNames[entry->ins],pc+pos+temp );break;
+ case RelM:
+ temp=oprom[pos++];
+ sprintf(buffer,"%s %.4x", InsNames[entry->ins],pc+pos-temp );break;
+ case Abs:
+ absolut=oprom[pos++]<<8;
+ absolut|=oprom[pos++];
+ sprintf(buffer,"%s (%.4x)", InsNames[entry->ins],absolut );break;
+ case ME1Abs:
+ absolut=oprom[pos++]<<8;
+ absolut|=oprom[pos++];
+ sprintf(buffer,"%s #(%.4x)", InsNames[entry->ins],absolut );break;
+ case AbsImm:
+ absolut=oprom[pos++]<<8;
+ absolut|=oprom[pos++];
+ sprintf(buffer,"%s (%.4x),%.2x", InsNames[entry->ins],absolut,
+ oprom[pos++]);break;
+ case ME1AbsImm:
+ absolut=oprom[pos++]<<8;
+ absolut|=oprom[pos++];
+ sprintf(buffer,"%s #(%.4x),%.2x", InsNames[entry->ins],absolut,
+ oprom[pos++]);break;
+ case ME0:
+ sprintf(buffer,"%s (%s)", InsNames[entry->ins],RegNames[entry->reg] );break;
+ case ME0Imm:
+ sprintf(buffer,"%s (%s),%.2x", InsNames[entry->ins],RegNames[entry->reg],oprom[pos++] );
+ break;
+ case ME1:
+ sprintf(buffer,"%s #(%s)", InsNames[entry->ins],RegNames[entry->reg] );break;
+ case ME1Imm:
+ sprintf(buffer,"%s #(%s),%.2x", InsNames[entry->ins],RegNames[entry->reg],oprom[pos++] );
+ break;
+ }
+ }
+
+ return pos;
+}
diff --git a/src/devices/cpu/lh5801/5801tbl.inc b/src/devices/cpu/lh5801/5801tbl.inc
new file mode 100644
index 00000000000..98a8d7b1d02
--- /dev/null
+++ b/src/devices/cpu/lh5801/5801tbl.inc
@@ -0,0 +1,689 @@
+// license:BSD-3-Clause
+// copyright-holders:Peter Trauner
+/* assumed
+ res=left+right+c
+ sbc is like adc with inverted carry and right side
+ (decrement, compare the same)
+ (like in the m6502 processors)
+*/
+UINT8 lh5801_cpu_device::lh5801_add_generic(int left, int right, int carry)
+{
+ int res=left+right+carry;
+ int v,c;
+
+ m_t&=~(H|V|Z|C);
+
+ if (!(res&0xff)) m_t|=Z;
+ c=res&0x100;
+ if (c) m_t|=C;
+ if (((left&0xf)+(right&0xf)+carry)&0x10) m_t|=H;
+ v=((left&0x7f)+(right&0x7f)+carry)&0x80;
+ if ( (c&&!v)||(!c&&v) ) m_t|=V;
+
+ return res;
+}
+
+UINT16 lh5801_cpu_device::lh5801_readop_word()
+{
+ UINT16 r;
+ r=m_direct->read_byte(P++)<<8;
+ r|=m_direct->read_byte(P++);
+ return r;
+}
+
+
+void lh5801_cpu_device::lh5801_adc(UINT8 data)
+{
+ m_a=lh5801_add_generic(m_a,data,m_t&C);
+}
+
+void lh5801_cpu_device::lh5801_add_mem(address_space &space, int addr, UINT8 data)
+{
+ int v=lh5801_add_generic(space.read_byte(addr),data,0);
+ space.write_byte(addr,v);
+}
+
+void lh5801_cpu_device::lh5801_adr(PAIR *reg)
+{
+ reg->b.l=lh5801_add_generic(reg->b.l,m_a,0);
+ if (m_t&C) {
+ reg->b.h++;
+ }
+}
+
+void lh5801_cpu_device::lh5801_sbc(UINT8 data)
+{
+ m_a=lh5801_add_generic(m_a,data^0xff,m_t&C);
+}
+
+void lh5801_cpu_device::lh5801_cpa(UINT8 a, UINT8 b)
+{
+ lh5801_add_generic(a, b^0xff, 1);
+}
+
+UINT8 lh5801_cpu_device::lh5801_decimaladd_generic(int left, int right, int carry)
+{
+ int res=lh5801_add_generic(left, right, carry);
+ UINT8 da;
+
+ //DA values taken from official documentation
+ if (!(m_t&C) && !(m_t&H))
+ da = 0x9a;
+ else if (!(m_t&C) && (m_t&H))
+ da = 0xa0;
+ else if ((m_t&C) && !(m_t&H))
+ da = 0xfa;
+ else //if ((m_t&C) && (m_t&H))
+ da = 0x00;
+
+ return res + da;
+}
+
+void lh5801_cpu_device::lh5801_dca(UINT8 data)
+{
+ m_a += 0x66; //taken from official documentation
+ m_a=lh5801_decimaladd_generic(m_a, data, m_t&C);
+}
+
+void lh5801_cpu_device::lh5801_dcs(UINT8 data)
+{
+ m_a=lh5801_decimaladd_generic(m_a, data^0xff, m_t&C);
+}
+
+void lh5801_cpu_device::lh5801_and(UINT8 data)
+{
+ m_a&=data;
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_and_mem(address_space &space, int addr, UINT8 data)
+{
+ data&=space.read_byte(addr);
+ m_t&=~Z;
+ if (!data) m_t|=Z;
+ space.write_byte(addr,data);
+}
+
+void lh5801_cpu_device::lh5801_bit(UINT8 a, UINT8 b)
+{
+ m_t&=~Z;
+ if (!(a&b)) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_eor(UINT8 data)
+{
+ m_a^=data;
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_ora(UINT8 data)
+{
+ m_a|=data;
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_ora_mem(address_space &space, int addr, UINT8 data)
+{
+ data|=space.read_byte(addr);
+ m_t&=~Z;
+ if (!data) m_t|=Z;
+ space.write_byte(addr,data);
+}
+
+void lh5801_cpu_device::lh5801_lda(UINT8 data)
+{
+ m_a=data;
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_lde(PAIR *reg)
+{
+ // or z flag depends on reg
+ m_a=m_program->read_byte(reg->w.l--);
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_sde(PAIR *reg)
+{
+ m_program->write_byte(reg->w.l--, m_a);
+}
+
+void lh5801_cpu_device::lh5801_lin(PAIR *reg)
+{
+ // or z flag depends on reg
+ m_a=m_program->read_byte(reg->w.l++);
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_sin(PAIR *reg)
+{
+ m_program->write_byte(reg->w.l++, m_a);
+}
+
+void lh5801_cpu_device::lh5801_dec(UINT8 *adr)
+{
+ *adr=lh5801_add_generic(*adr,0xff,0);
+}
+
+void lh5801_cpu_device::lh5801_inc(UINT8 *adr)
+{
+ *adr=lh5801_add_generic(*adr,1,0);
+}
+
+void lh5801_cpu_device::lh5801_pop()
+{
+ m_a=m_program->read_byte(++S);
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_pop_word(PAIR *reg)
+{
+ reg->b.h=m_program->read_byte(++S);
+ reg->b.l=m_program->read_byte(++S);
+ // z flag?
+}
+
+void lh5801_cpu_device::lh5801_rtn()
+{
+ P=m_program->read_byte(++S)<<8;
+ P|=m_program->read_byte(++S);
+}
+
+void lh5801_cpu_device::lh5801_rti()
+{
+ P=m_program->read_byte(++S)<<8;
+ P|=m_program->read_byte(++S);
+ m_t=m_program->read_byte(++S);
+}
+
+void lh5801_cpu_device::lh5801_push(UINT8 data)
+{
+ m_program->write_byte(S--, data);
+}
+
+void lh5801_cpu_device::lh5801_push_word(UINT16 data)
+{
+ m_program->write_byte(S--, data&0xff);
+ m_program->write_byte(S--, data>>8);
+}
+
+void lh5801_cpu_device::lh5801_jmp(UINT16 adr)
+{
+ P=adr;
+}
+
+void lh5801_cpu_device::lh5801_branch_plus(int doit)
+{
+ UINT8 t=m_direct->read_byte(P++);
+ if (doit) {
+ m_icount-=3;
+ P+=t;
+ }
+}
+
+void lh5801_cpu_device::lh5801_branch_minus(int doit)
+{
+ UINT8 t=m_direct->read_byte(P++);
+ if (doit) {
+ m_icount-=3;
+ P-=t;
+ }
+}
+
+void lh5801_cpu_device::lh5801_lop()
+{
+ UINT8 t=m_direct->read_byte(P++);
+ m_icount-=8;
+ if (UL--) {
+ m_icount-=3;
+ P-=t;
+ }
+}
+
+void lh5801_cpu_device::lh5801_sjp()
+{
+ UINT16 n=lh5801_readop_word();
+ lh5801_push_word(P);
+ P=n;
+}
+
+void lh5801_cpu_device::lh5801_vector(int doit, int nr)
+{
+ if (doit) {
+ lh5801_push_word(P);
+ P=m_program->read_byte(0xff00+nr)<<8;
+ P|=m_program->read_byte(0xff00+nr+1);
+ m_icount-=21-8;
+ }
+ m_t&=~Z; // after the jump!?
+}
+
+void lh5801_cpu_device::lh5801_aex()
+{
+ UINT8 t=m_a;
+ m_a=(t<<4)|(t>>4);
+ // flags?
+}
+
+void lh5801_cpu_device::lh5801_drl(address_space &space, int adr)
+{
+ UINT16 t=m_a|(space.read_byte(adr)<<8);
+
+ m_a=t>>8;
+ space.write_byte(adr,t>>4);
+}
+
+void lh5801_cpu_device::lh5801_drr(address_space &space, int adr)
+{
+ UINT16 t=space.read_byte(adr)|(m_a<<8);
+
+ m_a=t;
+ space.write_byte(adr,t>>4);
+}
+
+void lh5801_cpu_device::lh5801_rol()
+{
+ // maybe use of the adder
+ int n = m_a;
+ m_a = (n<<1) | (m_t&C);
+ // flags cvhz
+ m_t&=~(H|V|Z|C);
+ if (n&0x80) m_t|=C;
+ if (!m_a) m_t|=Z;
+ if (m_a & 0x10) m_t|=H;
+ if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) m_t|=V;
+}
+
+void lh5801_cpu_device::lh5801_ror()
+{
+ int n = m_a;
+ m_a=(n | ((m_t&C)<<8))>>1;
+ // flags cvhz
+ m_t&=~(H|V|Z|C);
+ if (n&0x01) m_t|=C;
+ if (!m_a) m_t|=Z;
+ if (m_a & 0x08) m_t|=H;
+ if ((BIT(n,0) && BIT(m_a,1)) || (BIT(m_a,0) && BIT(n,1))) m_t|=V;
+}
+
+void lh5801_cpu_device::lh5801_shl()
+{
+ int n = m_a;
+ m_a<<=1;
+ // flags cvhz
+ m_t&=~(H|V|Z|C);
+ if (n&0x80) m_t|=C;
+ if (!m_a) m_t|=Z;
+ if (m_a & 0x10) m_t|=H;
+ if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) m_t|=V;
+}
+
+void lh5801_cpu_device::lh5801_shr()
+{
+ int n = m_a;
+ m_a>>=1;
+ // flags cvhz
+ m_t&=~(H|V|Z|C);
+ if (n & 0x01) m_t|=C;
+ if (!m_a) m_t|=Z;
+ if (m_a & 0x08) m_t|=H;
+ if ((BIT(n,0) && BIT(m_a,1)) || (BIT(m_a,0) && BIT(n,1))) m_t|=V;
+}
+
+void lh5801_cpu_device::lh5801_am(int value)
+{
+ m_tm=value;
+ // jfkas?jfkl?jkd?
+}
+
+void lh5801_cpu_device::lh5801_ita()
+{
+ m_a=m_in_func();
+ m_t&=~Z;
+ if (!m_a) m_t|=Z;
+}
+
+void lh5801_cpu_device::lh5801_instruction_fd()
+{
+ int oper;
+ int adr;
+
+ oper=m_direct->read_byte(P++);
+ switch (oper) {
+ case 0x01: lh5801_sbc(m_io->read_byte(X)); m_icount-=11;break;
+ case 0x03: lh5801_adc(m_io->read_byte(X)); m_icount-=11;break;
+ case 0x05: lh5801_lda(m_io->read_byte(X)); m_icount-=10;break;
+ case 0x07: lh5801_cpa(m_a, m_io->read_byte(X)); m_icount-=11;break;
+ case 0x08: X=X;m_icount-=11;break; //!!!
+ case 0x09: lh5801_and(m_io->read_byte(X)); m_icount-=11;break;
+ case 0x0a: lh5801_pop_word(&m_x); m_icount-=15;break;
+ case 0x0b: lh5801_ora(m_io->read_byte(X)); m_icount-=11;break;
+ case 0x0c: lh5801_dcs(m_io->read_byte(X)); m_icount-=17; break;
+ case 0x0d: lh5801_eor(m_io->read_byte(X)); m_icount-=11;break;
+ case 0x0e: m_io->write_byte(X,m_a); m_icount-=10;break;
+ case 0x0f: lh5801_bit(m_io->read_byte(X),m_a); m_icount-=11;break;
+ case 0x11: lh5801_sbc(m_io->read_byte(Y)); m_icount-=11;break;
+ case 0x13: lh5801_adc(m_io->read_byte(Y)); m_icount-=11;break;
+ case 0x15: lh5801_lda(m_io->read_byte(Y)); m_icount-=10;break;
+ case 0x17: lh5801_cpa(m_a, m_io->read_byte(Y)); m_icount-=11;break;
+ case 0x18: X=Y;m_icount-=11;break;
+ case 0x19: lh5801_and(m_io->read_byte(Y)); m_icount-=11;break;
+ case 0x1a: lh5801_pop_word(&m_y); m_icount-=15;break;
+ case 0x1b: lh5801_ora(m_io->read_byte(Y)); m_icount-=11;break;
+ case 0x1c: lh5801_dcs(m_io->read_byte(Y)); m_icount-=17; break;
+ case 0x1d: lh5801_eor(m_io->read_byte(Y)); m_icount-=11;break;
+ case 0x1e: m_io->write_byte(Y,m_a); m_icount-=10;break;
+ case 0x1f: lh5801_bit(m_io->read_byte(Y),m_a); m_icount-=11;break;
+ case 0x21: lh5801_sbc(m_io->read_byte(U)); m_icount-=11;break;
+ case 0x23: lh5801_adc(m_io->read_byte(U)); m_icount-=11;break;
+ case 0x25: lh5801_lda(m_io->read_byte(U)); m_icount-=10;break;
+ case 0x27: lh5801_cpa(m_a, m_io->read_byte(U)); m_icount-=11;break;
+ case 0x28: X=U;m_icount-=11;break;
+ case 0x29: lh5801_and(m_io->read_byte(U)); m_icount-=11;break;
+ case 0x2a: lh5801_pop_word(&m_u); m_icount-=15;break;
+ case 0x2b: lh5801_ora(m_io->read_byte(U)); m_icount-=11;break;
+ case 0x2c: lh5801_dcs(m_io->read_byte(U)); m_icount-=17; break;
+ case 0x2d: lh5801_eor(m_io->read_byte(U)); m_icount-=11;break;
+ case 0x2e: m_io->write_byte(U,m_a); m_icount-=10;break;
+ case 0x2f: lh5801_bit(m_io->read_byte(U),m_a); m_icount-=11;break;
+ case 0x40: lh5801_inc(&XH);m_icount-=9;break;
+ case 0x42: lh5801_dec(&XH);m_icount-=9;break;
+ case 0x48: X=S;m_icount-=11;break;
+ case 0x49: lh5801_and_mem(*m_io, X, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x4a: X=X;m_icount-=11;break; //!!!
+ case 0x4b: lh5801_ora_mem(*m_io, X, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x4c: m_bf=0;/*off !*/ m_icount-=8;break;
+ case 0x4d: lh5801_bit(m_io->read_byte(X), m_direct->read_byte(P++));m_icount-=14;break;
+ case 0x4e: S=X;m_icount-=11;break;
+ case 0x4f: lh5801_add_mem(*m_io, X, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x50: lh5801_inc(&YH);m_icount-=9;break;
+ case 0x52: lh5801_dec(&YH);m_icount-=9;break;
+ case 0x58: X=P;m_icount-=11;break;
+ case 0x59: lh5801_and_mem(*m_io, Y, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x5a: Y=X;m_icount-=11;break;
+ case 0x5b: lh5801_ora_mem(*m_io, Y, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x5d: lh5801_bit(m_io->read_byte(Y), m_direct->read_byte(P++));m_icount-=14;break;
+ case 0x5e: lh5801_jmp(X);m_icount-=11;break; // P=X
+ case 0x5f: lh5801_add_mem(*m_io, Y, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x60: lh5801_inc(&UH);m_icount-=9;break;
+ case 0x62: lh5801_dec(&UH);m_icount-=9;break;
+ case 0x69: lh5801_and_mem(*m_io, U, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x6a: U=X;m_icount-=11;break;
+ case 0x6b: lh5801_ora_mem(*m_io, U, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x6d: lh5801_bit(m_io->read_byte(X), m_direct->read_byte(P++));m_icount-=14;break;
+ case 0x6f: lh5801_add_mem(*m_io, U, m_direct->read_byte(P++)); m_icount-=17;break;
+ case 0x81: m_t|=IE; /*sie !*/m_icount-=8;break;
+ case 0x88: lh5801_push_word(X); m_icount-=14;break;
+ case 0x8a: lh5801_pop(); m_icount-=12; break;
+ case 0x8c: lh5801_dca(m_io->read_byte(X)); m_icount-=19; break;
+ case 0x8e: /*cdv clears internal devider*/m_icount-=8;break;
+ case 0x98: lh5801_push_word(Y); m_icount-=14;break;
+ case 0x9c: lh5801_dca(m_io->read_byte(Y)); m_icount-=19; break;
+ case 0xa1: lh5801_sbc(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
+ case 0xa3: lh5801_adc(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
+ case 0xa5: lh5801_lda(m_io->read_byte(lh5801_readop_word())); m_icount-=16;break;
+ case 0xa7: lh5801_cpa(m_a, m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
+ case 0xa8: lh5801_push_word(U); m_icount-=14;break;
+ case 0xa9: lh5801_and(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
+ case 0xaa: lh5801_lda(m_t); m_icount-=9;break;
+ case 0xab: lh5801_ora(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
+ case 0xac: lh5801_dca(m_io->read_byte(U)); m_icount-=19; break;
+ case 0xad: lh5801_eor(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
+ case 0xae: m_io->write_byte(lh5801_readop_word(),m_a); m_icount-=16;break;
+ case 0xaf: lh5801_bit(m_io->read_byte(lh5801_readop_word()),m_a); m_icount-=17;break;
+ case 0xb1: /*hlt*/m_icount-=8;break;
+ case 0xba: lh5801_ita();m_icount-=9;break;
+ case 0xbe: m_t&=~IE; /*rie !*/m_icount-=8;break;
+ case 0xc0: m_dp=0; /*rdp !*/m_icount-=8;break;
+ case 0xc1: m_dp=1; /*sdp !*/m_icount-=8;break;
+ case 0xc8: lh5801_push(m_a); m_icount-=11;break;
+ case 0xca: lh5801_adr(&m_x);m_icount-=11;break;
+ case 0xcc: /*atp sends a to data bus*/m_icount-=9;break;
+ case 0xce: lh5801_am(m_a); m_icount-=9; break;
+ case 0xd3: lh5801_drr(*m_io, X); m_icount-=16; break;
+ case 0xd7: lh5801_drl(*m_io, X); m_icount-=16; break;
+ case 0xda: lh5801_adr(&m_y);m_icount-=11;break;
+ case 0xde: lh5801_am(m_a|0x100); m_icount-=9; break;
+ case 0xea: lh5801_adr(&m_u);m_icount-=11;break;
+ case 0xe9:
+ adr=lh5801_readop_word();
+ lh5801_and_mem(*m_io, adr, m_direct->read_byte(P++)); m_icount-=23;
+ break;
+ case 0xeb:
+ adr=lh5801_readop_word();
+ lh5801_ora_mem(*m_io, adr, m_direct->read_byte(P++)); m_icount-=23;
+ break;
+ case 0xec: m_t=m_a; m_icount-=9;break;
+ case 0xed:
+ adr=lh5801_readop_word();
+ lh5801_bit(m_io->read_byte(adr), m_direct->read_byte(P++));
+ m_icount-=20;break;
+ case 0xef:
+ adr=lh5801_readop_word();
+ lh5801_add_mem(*m_io, adr, m_direct->read_byte(P++)); m_icount-=23;
+ break;
+
+ default:
+ logerror("lh5801 illegal opcode at %.4x fd%.2x\n",P-2, oper);
+ }
+}
+
+void lh5801_cpu_device::lh5801_instruction()
+{
+ int oper;
+ int adr;
+
+ oper=m_direct->read_byte(P++);
+ switch (oper) {
+ case 0x00: lh5801_sbc(XL); m_icount-=6;break;
+ case 0x01: lh5801_sbc(m_program->read_byte(X)); m_icount-=7;break;
+ case 0x02: lh5801_adc(XL); m_icount-=6;break;
+ case 0x03: lh5801_adc(m_program->read_byte(X)); m_icount-=7;break;
+ case 0x04: lh5801_lda(XL); m_icount-=5;break;
+ case 0x05: lh5801_lda(m_program->read_byte(X)); m_icount-=6;break;
+ case 0x06: lh5801_cpa(m_a, XL); m_icount-=6;break;
+ case 0x07: lh5801_cpa(m_a, m_program->read_byte(X)); m_icount-=7;break;
+ case 0x08: XH=m_a; m_icount-=5; break;
+ case 0x09: lh5801_and(m_program->read_byte(X)); m_icount-=7;break;
+ case 0x0a: XL=m_a; m_icount-=5; break;
+ case 0x0b: lh5801_ora(m_program->read_byte(X)); m_icount-=7;break;
+ case 0x0c: lh5801_dcs(m_program->read_byte(X)); m_icount-=13; break;
+ case 0x0d: lh5801_eor(m_program->read_byte(X)); m_icount-=7;break;
+ case 0x0e: m_program->write_byte(X,m_a); m_icount-=6;break;
+ case 0x0f: lh5801_bit(m_program->read_byte(X),m_a); m_icount-=7;break;
+ case 0x10: lh5801_sbc(YL); m_icount-=6;break;
+ case 0x11: lh5801_sbc(m_program->read_byte(Y)); m_icount-=7;break;
+ case 0x12: lh5801_adc(YL); m_icount-=6;break;
+ case 0x13: lh5801_adc(m_program->read_byte(Y)); m_icount-=7;break;
+ case 0x14: lh5801_lda(YL); m_icount-=5;break;
+ case 0x15: lh5801_lda(m_program->read_byte(Y)); m_icount-=6;break;
+ case 0x16: lh5801_cpa(m_a, YL); m_icount-=6;break;
+ case 0x17: lh5801_cpa(m_a, m_program->read_byte(Y)); m_icount-=7;break;
+ case 0x18: YH=m_a; m_icount-=5; break;
+ case 0x19: lh5801_and(m_program->read_byte(Y)); m_icount-=7;break;
+ case 0x1a: YL=m_a; m_icount-=5; break;
+ case 0x1b: lh5801_ora(m_program->read_byte(Y)); m_icount-=7;break;
+ case 0x1c: lh5801_dcs(m_program->read_byte(Y)); m_icount-=13; break;
+ case 0x1d: lh5801_eor(m_program->read_byte(Y)); m_icount-=7;break;
+ case 0x1e: m_program->write_byte(Y,m_a); m_icount-=6;break;
+ case 0x1f: lh5801_bit(m_program->read_byte(Y),m_a); m_icount-=7;break;
+ case 0x20: lh5801_sbc(UL); m_icount-=6;break;
+ case 0x21: lh5801_sbc(m_program->read_byte(U)); m_icount-=7;break;
+ case 0x22: lh5801_adc(UL); m_icount-=6;break;
+ case 0x23: lh5801_adc(m_program->read_byte(U)); m_icount-=7;break;
+ case 0x24: lh5801_lda(UL); m_icount-=5;break;
+ case 0x25: lh5801_lda(m_program->read_byte(U)); m_icount-=6;break;
+ case 0x26: lh5801_cpa(m_a, UL); m_icount-=6;break;
+ case 0x27: lh5801_cpa(m_a, m_program->read_byte(U)); m_icount-=7;break;
+ case 0x28: UH=m_a; m_icount-=5; break;
+ case 0x29: lh5801_and(m_program->read_byte(U)); m_icount-=7;break;
+ case 0x2a: UL=m_a; m_icount-=5; break;
+ case 0x2b: lh5801_ora(m_program->read_byte(U)); m_icount-=7;break;
+ case 0x2c: lh5801_dcs(m_program->read_byte(U)); m_icount-=13; break;
+ case 0x2d: lh5801_eor(m_program->read_byte(U)); m_icount-=7;break;
+ case 0x2e: m_program->write_byte(U,m_a); m_icount-=6;break;
+ case 0x2f: lh5801_bit(m_program->read_byte(U),m_a); m_icount-=7;break;
+ case 0x38: /*nop*/m_icount-=5;break;
+ case 0x40: lh5801_inc(&XL);m_icount-=5;break;
+ case 0x41: lh5801_sin(&m_x); m_icount-=6;break;
+ case 0x42: lh5801_dec(&XL);m_icount-=5;break;
+ case 0x43: lh5801_sde(&m_x); m_icount-=6;break;
+ case 0x44: X++;m_icount-=5;break;
+ case 0x45: lh5801_lin(&m_x);m_icount-=6;break;
+ case 0x46: X--;m_icount-=5;break;
+ case 0x47: lh5801_lde(&m_x);m_icount-=6;break;
+ case 0x48: XH=m_direct->read_byte(P++);m_icount-=6;break;
+ case 0x49: lh5801_and_mem(*m_program, X, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x4a: XL=m_direct->read_byte(P++);m_icount-=6;break;
+ case 0x4b: lh5801_ora_mem(*m_program, X, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x4c: lh5801_cpa(XH, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0x4d: lh5801_bit(m_program->read_byte(X), m_direct->read_byte(P++));m_icount-=10;break;
+ case 0x4e: lh5801_cpa(XL, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0x4f: lh5801_add_mem(*m_program, X, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x50: lh5801_inc(&YL);m_icount-=5;break;
+ case 0x51: lh5801_sin(&m_y); m_icount-=6;break;
+ case 0x52: lh5801_dec(&YL);m_icount-=5;break;
+ case 0x53: lh5801_sde(&m_y); m_icount-=6;break;
+ case 0x54: Y++;m_icount-=5;break;
+ case 0x55: lh5801_lin(&m_y);m_icount-=6;break;
+ case 0x56: Y--;m_icount-=5;break;
+ case 0x57: lh5801_lde(&m_y);m_icount-=6;break;
+ case 0x58: YH=m_direct->read_byte(P++);m_icount-=6;break;
+ case 0x59: lh5801_and_mem(*m_program, Y, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x5a: YL=m_direct->read_byte(P++);m_icount-=6;break;
+ case 0x5b: lh5801_ora_mem(*m_program, Y, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x5c: lh5801_cpa(YH, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0x5d: lh5801_bit(m_program->read_byte(Y), m_direct->read_byte(P++));m_icount-=10;break;
+ case 0x5e: lh5801_cpa(YL, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0x5f: lh5801_add_mem(*m_program, Y, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x60: lh5801_inc(&UL);m_icount-=5;break;
+ case 0x61: lh5801_sin(&m_u); m_icount-=6;break;
+ case 0x62: lh5801_dec(&UL);m_icount-=5;break;
+ case 0x63: lh5801_sde(&m_u); m_icount-=6;break;
+ case 0x64: U++;m_icount-=5;break;
+ case 0x65: lh5801_lin(&m_u);m_icount-=6;break;
+ case 0x66: U--;m_icount-=5;break;
+ case 0x67: lh5801_lde(&m_u);m_icount-=6;break;
+ case 0x68: UH=m_direct->read_byte(P++);m_icount-=6;break;
+ case 0x69: lh5801_and_mem(*m_program, U, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x6a: UL=m_direct->read_byte(P++);m_icount-=6;break;
+ case 0x6b: lh5801_ora_mem(*m_program, U, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x6c: lh5801_cpa(UH, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0x6d: lh5801_bit(m_program->read_byte(U), m_direct->read_byte(P++));m_icount-=10;break;
+ case 0x6e: lh5801_cpa(UL, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0x6f: lh5801_add_mem(*m_program, U, m_direct->read_byte(P++)); m_icount-=13;break;
+ case 0x80: lh5801_sbc(XH); m_icount-=6;break;
+ case 0x81: lh5801_branch_plus(!(m_t&C)); m_icount-=8; break;
+ case 0x82: lh5801_adc(XH); m_icount-=6;break;
+ case 0x83: lh5801_branch_plus(m_t&C); m_icount-=8; break;
+ case 0x84: lh5801_lda(XH); m_icount-=5;break;
+ case 0x85: lh5801_branch_plus(!(m_t&H)); m_icount-=8; break;
+ case 0x86: lh5801_cpa(m_a, XH); m_icount-=6;break;
+ case 0x87: lh5801_branch_plus(m_t&H); m_icount-=8; break;
+ case 0x88: lh5801_lop(); break;
+ case 0x89: lh5801_branch_plus(!(m_t&Z)); m_icount-=8; break;
+ case 0x8a: lh5801_rti(); m_icount-=14; break;
+ case 0x8b: lh5801_branch_plus(m_t&Z); m_icount-=8; break;
+ case 0x8c: lh5801_dca(m_program->read_byte(X)); m_icount-=15; break;
+ case 0x8d: lh5801_branch_plus(!(m_t&V)); m_icount-=8; break;
+ case 0x8e: lh5801_branch_plus(1); m_icount-=5; break;
+ case 0x8f: lh5801_branch_plus(m_t&V); m_icount-=8; break;
+ case 0x90: lh5801_sbc(YH); m_icount-=6;break;
+ case 0x91: lh5801_branch_minus(!(m_t&C)); m_icount-=8; break;
+ case 0x92: lh5801_adc(YH); m_icount-=6;break;
+ case 0x93: lh5801_branch_minus(m_t&C); m_icount-=8; break;
+ case 0x94: lh5801_lda(YH); m_icount-=5;break;
+ case 0x95: lh5801_branch_minus(!(m_t&H)); m_icount-=8; break;
+ case 0x96: lh5801_cpa(m_a, YH); m_icount-=6;break;
+ case 0x97: lh5801_branch_minus(m_t&H); m_icount-=8; break;
+ case 0x99: lh5801_branch_minus(!(m_t&Z)); m_icount-=8; break;
+ case 0x9a: lh5801_rtn(); m_icount-=11; break;
+ case 0x9b: lh5801_branch_minus(m_t&Z); m_icount-=8; break;
+ case 0x9c: lh5801_dca(m_program->read_byte(Y)); m_icount-=15; break;
+ case 0x9d: lh5801_branch_minus(!(m_t&V)); m_icount-=8; break;
+ case 0x9e: lh5801_branch_minus(1); m_icount-=6; break;
+ case 0x9f: lh5801_branch_minus(m_t&V); m_icount-=8; break;
+ case 0xa0: lh5801_sbc(UH); m_icount-=6;break;
+ case 0xa2: lh5801_adc(UH); m_icount-=6;break;
+ case 0xa1: lh5801_sbc(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
+ case 0xa3: lh5801_adc(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
+ case 0xa4: lh5801_lda(UH); m_icount-=5;break;
+ case 0xa5: lh5801_lda(m_program->read_byte(lh5801_readop_word())); m_icount-=12;break;
+ case 0xa6: lh5801_cpa(m_a, UH); m_icount-=6;break;
+ case 0xa7: lh5801_cpa(m_a, m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
+ case 0xa8: m_pv=1;/*spv!*/ m_icount-=4; break;
+ case 0xa9: lh5801_and(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
+ case 0xaa: S=lh5801_readop_word();m_icount-=6;break;
+ case 0xab: lh5801_ora(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
+ case 0xac: lh5801_dca(m_program->read_byte(U)); m_icount-=15; break;
+ case 0xad: lh5801_eor(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
+ case 0xae: m_program->write_byte(lh5801_readop_word(),m_a); m_icount-=12;break;
+ case 0xaf: lh5801_bit(m_program->read_byte(lh5801_readop_word()),m_a); m_icount-=13;break;
+ case 0xb1: lh5801_sbc(m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0xb3: lh5801_adc(m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0xb5: lh5801_lda(m_direct->read_byte(P++)); m_icount-=6;break;
+ case 0xb7: lh5801_cpa(m_a, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0xb8: m_pv=0;/*rpv!*/ m_icount-=4; break;
+ case 0xb9: lh5801_and(m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0xba: lh5801_jmp(lh5801_readop_word()); m_icount-=12;break;
+ case 0xbb: lh5801_ora(m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0xbd: lh5801_eor(m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0xbe: lh5801_sjp(); m_icount-=19; break;
+ case 0xbf: lh5801_bit(m_a, m_direct->read_byte(P++));m_icount-=7;break;
+ case 0xc1: lh5801_vector(!(m_t&C), m_direct->read_byte(P++)); m_icount-=8;break;
+ case 0xc3: lh5801_vector(m_t&C, m_direct->read_byte(P++)); m_icount-=8;break;
+ case 0xc5: lh5801_vector(!(m_t&H), m_direct->read_byte(P++)); m_icount-=8;break;
+ case 0xc7: lh5801_vector(m_t&H, m_direct->read_byte(P++)); m_icount-=8;break;
+ case 0xc9: lh5801_vector(!(m_t&Z), m_direct->read_byte(P++)); m_icount-=8;break;
+ case 0xcb: lh5801_vector(m_t&Z, m_direct->read_byte(P++)); m_icount-=8;break;
+ case 0xcd: lh5801_vector(1, m_direct->read_byte(P++)); m_icount-=7;break;
+ case 0xcf: lh5801_vector(m_t&V, m_direct->read_byte(P++)); m_icount-=8;break;
+ case 0xd1: lh5801_ror(); m_icount-=6; break;
+ case 0xd3: lh5801_drr(*m_program, X); m_icount-=12; break;
+ case 0xd5: lh5801_shr(); m_icount-=6; break;
+ case 0xd7: lh5801_drl(*m_program, X); m_icount-=12; break;
+ case 0xd9: lh5801_shl(); m_icount-=6; break;
+ case 0xdb: lh5801_rol(); m_icount-=6; break;
+ case 0xdd: lh5801_inc(&m_a);m_icount-=5;break;
+ case 0xdf: lh5801_dec(&m_a);m_icount-=5;break;
+ case 0xe1: m_pu=1;/*spu!*/ m_icount-=4; break;
+ case 0xe3: m_pu=0;/*rpu!*/ m_icount-=4; break;
+ case 0xe9:
+ adr=lh5801_readop_word();lh5801_and_mem(*m_program, adr, m_direct->read_byte(P++));
+ m_icount-=19;break;
+ case 0xeb:
+ adr=lh5801_readop_word();lh5801_ora_mem(*m_program, adr, m_direct->read_byte(P++));
+ m_icount-=19;break;
+ case 0xed:
+ adr=lh5801_readop_word();lh5801_bit(m_program->read_byte(adr), m_direct->read_byte(P++));
+ m_icount-=16;break;
+ case 0xef:
+ adr=lh5801_readop_word();
+ lh5801_add_mem(*m_program, adr, m_direct->read_byte(P++)); m_icount-=19;
+ break;
+ case 0xf1: lh5801_aex(); m_icount-=6; break;
+ case 0xf5: m_program->write_byte(Y++, m_program->read_byte(X++)); m_icount-=7; break; //tin
+ case 0xf7: lh5801_cpa(m_a, m_program->read_byte(X++));m_icount-=7; break; //cin
+ case 0xf9: m_t&=~C;m_icount-=4;break;
+ case 0xfb: m_t|=C;m_icount-=4;break;
+ case 0xfd: lh5801_instruction_fd();break;
+ case 0xc0: case 0xc2: case 0xc4: case 0xc6:
+ case 0xc8: case 0xca: case 0xcc: case 0xce:
+ case 0xd0: case 0xd2: case 0xd4: case 0xd6:
+ case 0xd8: case 0xda: case 0xdc: case 0xde:
+ case 0xe0: case 0xe2: case 0xe4: case 0xe6:
+ case 0xe8: case 0xea: case 0xec: case 0xee:
+ case 0xf0: case 0xf2: case 0xf4: case 0xf6:
+ lh5801_vector(1, oper);m_icount-=4;break;
+ default:
+ logerror("lh5801 illegal opcode at %.4x %.2x\n",P-1, oper);
+ }
+
+}
diff --git a/src/devices/cpu/lh5801/lh5801.c b/src/devices/cpu/lh5801/lh5801.c
new file mode 100644
index 00000000000..0287e0d0859
--- /dev/null
+++ b/src/devices/cpu/lh5801/lh5801.c
@@ -0,0 +1,254 @@
+// license:BSD-3-Clause
+// copyright-holders:Peter Trauner
+/*****************************************************************************
+ *
+ *
+ * 02/2011 (Sandro Ronco)
+ * - Added IO_SPACE and updated all access in ME1 memory for use it.
+ * - Implemented interrupts.
+ * - Fixed the flags in the ROL/ROR/SHL/SHR opcodes.
+ * - Fixed decimal add/sub opcodes.
+ *
+ * based on info found on an artikel for the tandy trs80 pc2
+ * and on "PC1500 Technical reference manual"
+ *
+ *****************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+
+#include "lh5801.h"
+
+#define VERBOSE 0
+
+#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
+
+enum
+{
+ LH5801_T=1,
+ LH5801_P,
+ LH5801_S,
+ LH5801_U,
+ LH5801_X,
+ LH5801_Y,
+ LH5801_A,
+
+ LH5801_TM,
+ LH5801_IN,
+ LH5801_BF,
+ LH5801_PU,
+ LH5801_PV,
+ LH5801_DP,
+ LH5801_IRQ_STATE
+};
+
+
+#define P m_p.w.l
+#define S m_s.w.l
+#define U m_u.w.l
+#define UL m_u.b.l
+#define UH m_u.b.h
+#define X m_x.w.l
+#define XL m_x.b.l
+#define XH m_x.b.h
+#define Y m_y.w.l
+#define YL m_y.b.l
+#define YH m_y.b.h
+
+#define C 0x01
+#define IE 0x02
+#define Z 0x04
+#define V 0x08
+#define H 0x10
+
+
+const device_type LH5801 = &device_creator<lh5801_cpu_device>;
+
+
+lh5801_cpu_device::lh5801_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : cpu_device(mconfig, LH5801, "LH5801", tag, owner, clock, "lh5801", __FILE__)
+ , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
+ , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0)
+ , m_in_func(*this)
+{
+}
+
+
+/***************************************************************
+ * include the opcode macros, functions and tables
+ ***************************************************************/
+#include "5801tbl.inc"
+
+void lh5801_cpu_device::device_start()
+{
+ m_program = &space(AS_PROGRAM);
+ m_io = &space(AS_IO);
+ m_direct = &m_program->direct();
+
+ m_in_func.resolve_safe(0);
+
+ m_s.w.l = 0;
+ m_p.w.l = 0;
+ m_u.w.l = 0;
+ m_x.w.l = 0;
+ m_y.w.l = 0;
+ m_tm = 0;
+ m_t = 0;
+ m_a = 0;
+ m_bf = 0;
+ m_dp = 0;
+ m_pu = 0;
+ m_pv = 0;
+ m_oldpc = 0;
+ m_irq_state = 0;
+ memset(m_ir_flipflop, 0, sizeof(m_ir_flipflop));
+ memset(m_lines_status, 0, sizeof(m_lines_status));
+ m_idle = 0;
+
+ save_item(NAME(m_s.w.l));
+ save_item(NAME(m_p.w.l));
+ save_item(NAME(m_u.w.l));
+ save_item(NAME(m_x.w.l));
+ save_item(NAME(m_y.w.l));
+ save_item(NAME(m_tm));
+ save_item(NAME(m_t));
+ save_item(NAME(m_a));
+ save_item(NAME(m_bf));
+ save_item(NAME(m_dp));
+ save_item(NAME(m_pu));
+ save_item(NAME(m_pv));
+ save_item(NAME(m_oldpc));
+ save_item(NAME(m_irq_state));
+ save_item(NAME(m_ir_flipflop));
+ save_item(NAME(m_lines_status));
+ save_item(NAME(m_idle));
+
+ state_add( LH5801_P, "P", m_p.w.l ).formatstr("%04X");
+ state_add( LH5801_S, "S", m_s.w.l ).formatstr("%04X");
+ state_add( LH5801_U, "U", m_u.w.l ).formatstr("%04X");
+ state_add( LH5801_X, "X", m_x.w.l ).formatstr("%04X");
+ state_add( LH5801_Y, "Y", m_y.w.l ).formatstr("%04X");
+ state_add( LH5801_T, "T", m_t ).formatstr("%02X");
+ state_add( LH5801_A, "A", m_a ).formatstr("%02X");
+ state_add( LH5801_TM, "TM", m_tm ).formatstr("%03X");
+ state_add( LH5801_PV, "PV", m_pv ).formatstr("%04X");
+ state_add( LH5801_PU, "PU", m_pu ).formatstr("%04X");
+ state_add( LH5801_BF, "BF", m_bf ).formatstr("%04X");
+ state_add( LH5801_DP, "DP", m_dp ).formatstr("%04X");
+
+ state_add(STATE_GENPC, "GENPC", m_p.w.l).noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", m_t).noshow().formatstr("%8s");
+
+ m_icountptr = &m_icount;
+}
+
+void lh5801_cpu_device::state_string_export(const device_state_entry &entry, std::string &str)
+{
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ strprintf(str, "%c%c%c%c%c%c%c%c",
+ m_t&0x80?'1':'0',
+ m_t&0x40?'1':'0',
+ m_t&0x20?'1':'0',
+ m_t&0x10?'H':'.',
+ m_t&0x08?'V':'.',
+ m_t&0x04?'Z':'.',
+ m_t&0x02?'I':'.',
+ m_t&0x01?'C':'.');
+ break;
+ }
+}
+
+void lh5801_cpu_device::device_reset()
+{
+ P = (m_program->read_byte(0xfffe)<<8) | m_program->read_byte(0xffff);
+
+ m_idle=0;
+
+ memset(m_ir_flipflop, 0, sizeof(m_ir_flipflop));
+ memset(m_lines_status, 0, sizeof(m_lines_status));
+}
+
+
+void lh5801_cpu_device::check_irq()
+{
+ if (m_ir_flipflop[0])
+ {
+ //NMI interrupt
+ m_ir_flipflop[0] = 0;
+ lh5801_push(m_t);
+ m_t&=~IE;
+ lh5801_push_word(P);
+ P = (m_program->read_byte(0xfffc)<<8) | m_program->read_byte(0xfffd);
+ }
+ else if (m_ir_flipflop[1] && (m_t & IE))
+ {
+ //counter interrupt (counter not yet implemented)
+ m_ir_flipflop[1] = 0;
+ lh5801_push(m_t);
+ m_t&=~IE;
+ lh5801_push_word(P);
+ P = (m_program->read_byte(0xfffa)<<8) | m_program->read_byte(0xfffb);
+ }
+ else if (m_ir_flipflop[2] && (m_t & IE))
+ {
+ //MI interrupt
+ m_ir_flipflop[2] = 0;
+ lh5801_push(m_t);
+ m_t&=~IE;
+ lh5801_push_word(P);
+ P = (m_program->read_byte(0xfff8)<<8) | m_program->read_byte(0xfff9);
+ }
+}
+
+
+void lh5801_cpu_device::execute_run()
+{
+ do
+ {
+ check_irq();
+
+ if (m_idle)
+ m_icount = 0;
+ else
+ {
+ m_oldpc = P;
+
+ debugger_instruction_hook(this, P);
+ lh5801_instruction();
+ }
+
+ } while (m_icount > 0);
+}
+
+void lh5801_cpu_device::execute_set_input(int irqline, int state)
+{
+ switch( irqline)
+ {
+ case LH5801_LINE_MI:
+ if (m_lines_status[0] == CLEAR_LINE && state == ASSERT_LINE)
+ {
+ m_idle = 0;
+ m_ir_flipflop[2] = 1;
+ }
+
+ m_lines_status[0] = state;
+ break;
+ case INPUT_LINE_NMI:
+ if (m_lines_status[1] == CLEAR_LINE && state == ASSERT_LINE)
+ {
+ m_idle = 0;
+ m_ir_flipflop[0] = 1;
+ }
+
+ m_lines_status[1] = state;
+ break;
+ }
+}
+
+offs_t lh5801_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE( lh5801 );
+ return CPU_DISASSEMBLE_NAME(lh5801)(this, buffer, pc, oprom, opram, options);
+}
diff --git a/src/devices/cpu/lh5801/lh5801.h b/src/devices/cpu/lh5801/lh5801.h
new file mode 100644
index 00000000000..e5c6aa74690
--- /dev/null
+++ b/src/devices/cpu/lh5801/lh5801.h
@@ -0,0 +1,188 @@
+// license:BSD-3-Clause
+// copyright-holders:Peter Trauner
+/*****************************************************************************
+ *
+ * cpustate->h
+ * portable lh5801 emulator interface
+ *
+ *
+ *****************************************************************************/
+#pragma once
+
+#ifndef __LH5801_H__
+#define __LH5801_H__
+
+/*
+lh5801
+
+little endian
+
+ph, pl p
+sh, sl s
+
+xh, xl x
+yh, yl y
+uh, ul u
+
+a A
+
+0 0 0 H V Z IE C
+
+TM 9bit polynominal?
+
+pu pv disp flipflops
+
+bf flipflop (break key connected)
+
+ me0, me1 chip select for 2 64kb memory blocks
+
+in0-in7 input pins
+
+ mi maskable interrupt input (fff8/9)
+ timer fffa/b
+ nmi non .. (fffc/d)
+ reset fffe/f
+e ?
+
+
+
+lh5811 chip
+pa 8bit io
+pb 8bit io
+pc 8bit
+*/
+
+
+// input lines
+enum
+{
+ LH5801_LINE_MI //maskable interrupt
+};
+
+
+#define MCFG_LH5801_IN(_devcb) \
+ lh5801_cpu_device::set_in_func(*device, DEVCB_##_devcb);
+
+
+class lh5801_cpu_device : public cpu_device
+{
+public:
+ // construction/destruction
+ lh5801_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // static configuration helpers
+ template<class _Object> static devcb_base &set_in_func(device_t &device, _Object object) { return downcast<lh5801_cpu_device &>(device).m_in_func.set_callback(object); }
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const { return 2; }
+ virtual UINT32 execute_max_cycles() const { return 19; }
+ virtual UINT32 execute_input_lines() const { return 2; }
+ virtual UINT32 execute_default_irq_vector() const { return 0; }
+ virtual void execute_run();
+ virtual void execute_set_input(int inputnum, int state);
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : NULL ); }
+
+ // device_state_interface overrides
+ void state_string_export(const device_state_entry &entry, std::string &str);
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
+ virtual UINT32 disasm_max_opcode_bytes() const { return 5; }
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+private:
+ address_space_config m_program_config;
+ address_space_config m_io_config;
+
+ devcb_read8 m_in_func;
+
+ address_space *m_program; //ME0
+ address_space *m_io; //ME1
+ direct_read_data *m_direct;
+
+ PAIR m_s;
+ PAIR m_p;
+ PAIR m_u;
+ PAIR m_x;
+ PAIR m_y;
+ int m_tm; //9 bit
+
+ UINT8 m_t, m_a;
+
+ int m_bf;
+ int m_dp;
+ int m_pu;
+ int m_pv;
+
+ UINT16 m_oldpc;
+
+ int m_irq_state;
+
+ UINT8 m_ir_flipflop[3]; //interrupt request flipflop: IR0, IR1, IR2
+ int m_lines_status[2]; //MI and NMI lines status
+
+ int m_idle;
+ int m_icount;
+
+ void check_irq();
+ void lh5801_instruction_fd();
+ void lh5801_instruction();
+ UINT8 lh5801_add_generic(int left, int right, int carry);
+ UINT16 lh5801_readop_word();
+ void lh5801_adc(UINT8 data);
+ void lh5801_add_mem(address_space &space, int addr, UINT8 data);
+ void lh5801_adr(PAIR *reg);
+ void lh5801_sbc(UINT8 data);
+ void lh5801_cpa(UINT8 a, UINT8 b);
+ UINT8 lh5801_decimaladd_generic(int left, int right, int carry);
+ void lh5801_dca(UINT8 data);
+ void lh5801_dcs(UINT8 data);
+ void lh5801_and(UINT8 data);
+ void lh5801_and_mem(address_space &space, int addr, UINT8 data);
+ void lh5801_bit(UINT8 a, UINT8 b);
+ void lh5801_eor(UINT8 data);
+ void lh5801_ora(UINT8 data);
+ void lh5801_ora_mem(address_space &space, int addr, UINT8 data);
+ void lh5801_lda(UINT8 data);
+ void lh5801_lde(PAIR *reg);
+ void lh5801_sde(PAIR *reg);
+ void lh5801_lin(PAIR *reg);
+ void lh5801_sin(PAIR *reg);
+ void lh5801_dec(UINT8 *adr);
+ void lh5801_inc(UINT8 *adr);
+ void lh5801_pop();
+ void lh5801_pop_word(PAIR *reg);
+ void lh5801_rtn();
+ void lh5801_rti();
+ void lh5801_push(UINT8 data);
+ void lh5801_push_word(UINT16 data);
+ void lh5801_jmp(UINT16 adr);
+ void lh5801_branch_plus(int doit);
+ void lh5801_branch_minus(int doit);
+ void lh5801_lop();
+ void lh5801_sjp();
+ void lh5801_vector(int doit, int nr);
+ void lh5801_aex();
+ void lh5801_drl(address_space &space, int adr);
+ void lh5801_drr(address_space &space, int adr);
+ void lh5801_rol();
+ void lh5801_ror();
+ void lh5801_shl();
+ void lh5801_shr();
+ void lh5801_am(int value);
+ void lh5801_ita();
+
+};
+
+
+extern const device_type LH5801;
+
+
+#endif /* __LH5801_H__ */