/* Simple 80 Processor (mz80) V1.0 -- A variant of my80 -- (C)Copyright by Naohiko Shimizu, 2001,2002. All rights are reserved. Contact information: Dr. Naohiko Shimizu School of Information Technology and Electronics, Tokai University 1117 Kitakaname, Hiratsuka-city, Kanagawa, 259-1292, Japan email: nshimizu@keyaki.cc.u-tokai.ac.jp URL: http://shimizu-lab.et.u-tokai.ac.jp/ Update informations: 18-May-2002: PUSH register conflict, SHMZ 27-Apr-2002: Add EDxx instructions, SHMZ 26-Apr-2002: Add CBxx instructions, SHMZ 26-Apr-2002: Add JR,JRC,DJNZ, SHMZ 25-Apr-2002: Add Z80 compatible registers, EXX, EXAF, DDxx, FDxx SHMZ 20-Apr-2002: Restructuring to reduce gates, SHMZ 30-Jan-2001: Generated from the SN/1 ******************************************/ %i <r256_8.h> %i <r256_8.cir> %d B 0b000 %d C 0b001 %d D 0b010 %d E 0b011 %d H 0b100 %d L 0b101 %d F 0b110 %d A 0b111 %d M 0b110 %d SPH 0b110 %d SPL 0b111 declare mz80 { bidirect data<8> ; bidirect adrs<16> ; instrin extint; instrout memory_read; instrout memory_write; instrout io_read; instrout io_write; instrout reti; instrout retn; } declare mz80core { input data<8> ; output datao<8> ; output adrs<16> ; instrin extint; instrout memory_read; instrout memory_write; instrout io_read; instrout io_write; instrout reti; instrout retn; } declare alu80 { input in1<8> ; input in2<8> ; input ci ; output out<8> ; output s,z,a,p,c; instrin add,adc,sub,sbc,and,or,xor,cmp,thr,neg; instrin rlc, rrc, rl, rr, sla, sra, sls, srl,inc,dec,incc,decc; input inb<3> ; instrin bit, res, set; instr_arg inc(in1); instr_arg dec(in1); instr_arg incc(in1,ci); instr_arg decc(in1,ci); instr_arg thr(in1); instr_arg neg(in1); instr_arg adc(in1,in2,ci); instr_arg sbc(in1,in2,ci); instr_arg add(in1,in2); instr_arg sub(in1,in2); instr_arg and(in1,in2); instr_arg or (in1,in2); instr_arg xor(in1,in2); instr_arg cmp(in1,in2); instr_arg rlc(in1); instr_arg rrc(in1); instr_arg rl(in1,ci); instr_arg rr(in1,ci); instr_arg sla(in1); instr_arg sra(in1); instr_arg srl(in1); instr_arg sls(in1); instr_arg bit(in1, inb); instr_arg res(in1, inb); instr_arg set(in1, inb); } declare cpa { input in1, in2, ci; output out, co; instrin do; instr_arg do(in1,in2,ci); } declare cpa4 { input in1<4>, in2<4>, ci; output out<4>, co; instrin do; instr_arg do(in1,in2,ci); } declare cpa8 { input in1<8>, in2<8>, ci; output out<8>, co, ca; instrin do; instr_arg do(in1,in2,ci); } module cpa { input in1, in2, ci; output out, co; instrin do; instruct do par { out = in1 @ in2 @ ci; co = (in1&in2)|(in1&ci)|(in2&ci); } } module cpa4 { input in1<4>, in2<4>, ci; output out<4>, co; cpa a1,a2,a3,a4; instrin do; instruct do par { out = a4.do(in1<3>,in2<3>,a3.co).out || a3.do(in1<2>,in2<2>,a2.co).out || a2.do(in1<1>,in2<1>,a1.co).out || a1.do(in1<0>,in2<0>,ci).out; co = a4.co; } } module cpa8 { input in1<8>, in2<8>, ci; output out<8>, co, ca; cpa4 a1,a2; instrin do; instruct do par { out = a2.do(in1<7:4>,in2<7:4>,a1.co).out || a1.do(in1<3:0>,in2<3:0>,ci).out; co = a2.co; ca = a1.co; } } declare ha { input in, ci, dec; output out, co; instrin do; instr_arg do(in,ci,dec); } declare inc4 { input in<4>, ci,dec; output out<4>, co; instrin do; instr_arg do(in,ci,dec); } declare inc8 { input in<8>, ci; output out<8>, co; instrin up,down; instr_arg up(in,ci); instr_arg down(in,ci); } module ha { input in, ci,dec; output out, co; instrin do; instruct do par { out = in @ ci; co = ((in @ dec)&ci); } } module inc4 { input in<4>, ci, dec; output out<4>, co; ha a1,a2,a3,a4; instrin do; instruct do par { out = a4.do(in<3>,a3.co,dec).out || a3.do(in<2>,a2.co,dec).out || a2.do(in<1>,a1.co,dec).out || a1.do(in<0>,ci,dec).out; co = a4.co; } } module inc8 { input in<8>, ci; output out<8>, co; inc4 a1,a2; instrin up,down; instruct up par { out = a2.do(in<7:4>,a1.co,0b0).out || a1.do(in<3:0>,ci,0b0).out; co = a2.co; } instruct down par { out = a2.do(in<7:4>,a1.co,0b1).out || a1.do(in<3:0>,ci,0b1).out; co = a2.co; } } module alu80 { input in1<8> ; input in2<8> ; input inb<3> ; input ci ; output out<8> ; output s,z,a,p,c; instrin add,adc,sub,sbc,and,or,xor,cmp,thr,neg; instrin rlc, rrc, rl, rr, sla, sra, sls, srl,inc,dec,incc,decc; instrin bit, res, set; cpa8 cpa; instruct thr par { out = in1; c = 0b0; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct neg par { out = cpa.do(0x00, ^in1, 0b1).out; c = ^cpa.co; a=^cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct inc par { out = cpa.do(in1, 0x01, 0b0).out; c = cpa.co; a=cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct add par { out = cpa.do(in1, in2, 0b0).out; c = cpa.co; a=cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct adc par { out = cpa.do(in1, in2, ci).out; c = cpa.co; a=cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct incc par { out = cpa.do(in1, 0x00, ci).out; c = cpa.co; a=cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct sub par { out = cpa.do(in1, ^in2, 0b1).out; c = ^cpa.co; a=^cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct sbc par { out = cpa.do(in1, ^in2, ^ci).out; c = ^cpa.co; a=^cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct dec par { out = cpa.do(in1, ^0x01, 0b1).out; c = ^cpa.co; a=^cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct decc par { out = cpa.do(in1, ^0x00, ^ci).out; c = ^cpa.co; a=^cpa.ca; s = out<7>; z = ^/| out; p = ^/@ out; } instruct and par { out = in1 & in2; c = 0b0; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct xor par { out = in1 @ in2; c = 0b0; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct or par { out = in1 | in2; c = 0b0; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct cmp par { out = in1; cpa.do(in1, ^in2, 0b1); c = ^cpa.co; a=^cpa.ca; s = cpa.out<7>; z = ^/| cpa.out; p = ^/@ cpa.out; } instruct rlc par { out = in1<6:0>||in1<7>; c = in1<7>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct rrc par { out = in1<0>||in1<7:1>; c = in1<0>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct rl par { out = in1<6:0>||ci; c = in1<7>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct rr par { out = ci||in1<7:1>; c = in1<0>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct sla par { out = in1<6:0>||0b0; c = in1<7>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct sra par { out = in1<7>||in1<7:1>; c = in1<0>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct srl par { out = 0b0||in1<7:1>; c = in1<0>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct sls par { out = in1<6:0>||0b1; c = in1<7>; a=0b0; s = out<7>; z = ^/| out; p = ^/@ out; } instruct bit any { inb == 0b000: z = (in1<0> & 0b1); inb == 0b001: z = (in1<1> & 0b1); inb == 0b010: z = (in1<2> & 0b1); inb == 0b011: z = (in1<3> & 0b1); inb == 0b100: z = (in1<4> & 0b1); inb == 0b101: z = (in1<5> & 0b1); inb == 0b110: z = (in1<6> & 0b1); inb == 0b111: z = (in1<7> & 0b1); } instruct set any { inb == 0b000: out = (in1 | 0x01); inb == 0b001: out = (in1 | 0x02); inb == 0b010: out = (in1 | 0x04); inb == 0b011: out = (in1 | 0x08); inb == 0b100: out = (in1 | 0x10); inb == 0b101: out = (in1 | 0x20); inb == 0b110: out = (in1 | 0x40); inb == 0b111: out = (in1 | 0x80); } instruct res any { inb == 0b000: out = (in1 & ^0x01); inb == 0b001: out = (in1 & ^0x02); inb == 0b010: out = (in1 & ^0x04); inb == 0b011: out = (in1 & ^0x08); inb == 0b100: out = (in1 & ^0x10); inb == 0b101: out = (in1 & ^0x20); inb == 0b110: out = (in1 & ^0x40); inb == 0b111: out = (in1 & ^0x80); } } declare ram { input adr<8>; bidirect data<8>; instrin read; instrin write; instr_arg read(adr); instr_arg write(adr,data); } module ram { input adr<8>; bidirect data<8>; r256_8 m; instrin read; instrin write; instruct read data = m.read(adr).dout; instruct write m.write(adr,data); } module top { output outp<8>; output adrs<16>; input inp<8>; mz80 cpu; ram ram; instruct cpu.memory_read cpu.data = ram.read(cpu.adrs<7:0>).data ; instruct cpu.memory_write ram.write(cpu.adrs<7:0>,cpu.data); instruct cpu.io_read cpu.data = inp; instruct cpu.io_write outp = cpu.data; } module mz80 { bidirect data<8> ; bidirect adrs<16> ; instrin extint; instrout memory_read; instrout memory_write; instrout io_read; instrout io_write; instrout reti; instrout retn; mz80core cpu; instruct extint cpu.extint(); instruct cpu.memory_read par { cpu.data = data ; adrs = cpu.adrs; memory_read(); } instruct cpu.io_read par { cpu.data = data ; adrs = cpu.adrs; io_read(); } instruct cpu.memory_write par { data = cpu.datao; adrs = cpu.adrs; memory_write(); } instruct cpu.io_write par { data = cpu.datao; adrs = cpu.adrs; io_write(); } } module mz80core { input data<8> ; output datao<8> ; output adrs<16> ; instrin extint; instrself start, setreg, getreg, setrx, getrx, flagchk, decop, incop, incsp, incpc, loop1, lospl, lopcl, decsp, decpc, setflag, deccb, deced; instrself dmov,dalu,dinr,ddad,dinx,dpop,dpush,dldax,dstax,dretc,drst, dalum,dret,dxthl,dpchl,dsphl,dxchg,ddi,dei,dnop; instrself dmvi,dalui,din,dout,dcc,dcall,djmp,djc,dlxi,dlda, dlhld,dshld,dsta, dexx, dexaf, ddd, dfd; instrself zjr,zjrc,zdjnz,dcb,ded,zcb,zed,zflagchk; instrself zio,zaddsub,zld,zrd,zret,zblk,zmisc,zneg; instrself zrlc, zrrc, zrl, zrr, zsla, zsra, zsls, zsrl, zbit, zres, zset; instrself fetch2, fetch3, ifetch, run0, run1, run2, run3, run4; instrself run5,run6,run7,run8, runex; instrout memory_read, memory_write; instrout io_read, io_write; instrout reti, retn; reg pch<8>,pcl<8>; /* program counter */ reg sph<8>,spl<8>; reg ixh<8>,ixl<8>; reg iyh<8>,iyl<8>; reg a0<8>,f0<8>,b0<8>,c0<8>,d0<8>,e0<8>,h0<8>,l0<8>; reg a1<8>,f1<8>,b1<8>,c1<8>,d1<8>,e1<8>,h1<8>,l1<8>; reg tc, imask, op0<8>, op1<8>, op2<8>, tmp<8>; reg_wr st0, regset, regaf ,dd, fd ; reg st1,st2 ; inc8 inc ; alu80 alu ; sel_v lo<8>, flg, rs<3>, rg<3>, v<8>, w<8>, fi<8> ; sel a<8>,f<8>,b<8>,c<8>,d<8>,e<8>,h<8>,l<8>; instr_arg memory_read(adrs); instr_arg memory_write(adrs,datao); instr_arg io_read(adrs); instr_arg io_write(adrs,datao); instr_arg setreg(rs,v); instr_arg getreg(rg); instr_arg setrx(rs,v); instr_arg getrx(rg); instr_arg decop(); instr_arg deccb(); instr_arg deced(); instr_arg setflag(fi); stage_name int { task intt() ; } stage_name if { task start(pch,pcl) ; task run(); } stage_name ex { task run(); task run1(); task run2(); task run3(); task run4(); } stage_name cb { task run(); task run1(); task run2(); task run3(); task run4(); } stage_name ed { task run(); task run1(); task run2(); task run3(); task run4(); task run5(); task run6(); task run7(); task run8(); } /* Common operations for every stages must be described here */ par{ st0 := 0b1; st1 := st0; st2 := st1; if ((st2 == 0b0) & (st1 == 0b1)) start(); any { ^regset: par { b=b0; c=c0; d=d0; e=e0; } regset: par { b=b1; c=c1; d=d1; e=e1; } ^regaf: par { a=a0; f=f0; } regaf: par { a=a1; f=f1; } } any { dd: par { h=ixh; l=ixl; } fd: par { h=iyh; l=iyl; } else: any { ^regset: par {h=h0; l=l0;} regset: par {h=h1; l=l1;} } } } instruct extint generate int.intt(); instruct start par { /* start instruction fetch */ generate if.start(0x00,0x00); imask := 0b1; } instruct loop1 lo = op1; instruct lospl lo = spl; instruct lopcl lo = pcl; instruct setreg any { ^regset & (rs == B): b0:=v; regset & (rs == B): b1:=v; ^regset & (rs == C): c0:=v; regset & (rs == C): c1:=v; ^regset & (rs == D): d0:=v; regset & (rs == D): d1:=v; ^regset & (rs == E): e0:=v; regset & (rs == E): e1:=v; rs == H: any { dd: ixh := v; fd: iyh := v; else: any { ^regset: h0:=v; regset: h1:=v; } } rs == L: any { dd: ixl := v; fd: iyl := v; else: any { ^regset: l0:=v; regset: l1:=v; } } ^regaf & (rs == F): f0:=v; ^regaf & (rs == A): a0:=v; regaf & (rs == F): f1:=v; regaf & (rs == A): a1:=v; } instruct getreg any { rg == B: lo = b; rg == C: lo = c; rg == D: lo = d; rg == E: lo = e; rg == H: lo = h; rg == L: lo = l; rg == F: lo = f; rg == A: lo = a; } instruct setrx any { rs == SPH: sph:=v; rs == SPL: spl:=v; regset & (rs == B): b1:=v; ^regset & (rs == B): b0:=v; regset & (rs == C): c1:=v; ^regset & (rs == C): c0:=v; regset & (rs == D): d1:=v; ^regset & (rs == D): d0:=v; regset & (rs == E): e1:=v; ^regset & (rs == E): e0:=v; rs == H: any { dd: ixh := v; fd: iyh := v; else: any { ^regset: h0:=v; regset: h1:=v; } } rs == L: any { dd: ixl := v; fd: iyl := v; else: any { ^regset: l0:=v; regset: l1:=v; } } } instruct getrx any { rg == B: lo = b; rg == C: lo = c; rg == D: lo = d; rg == E: lo = e; rg == H: lo = h; rg == L: lo = l; rg == SPH: lo = sph; rg == SPL: lo = spl; } instruct setflag any { ^regaf: f0:=fi; regaf: f1:=fi; } instruct flagchk any { op0<5:3> == 0b000: flg = ^f<6>; op0<5:3> == 0b001: flg = f<6>; op0<5:3> == 0b010: flg = ^f<0>; op0<5:3> == 0b011: flg = f<0>; op0<5:3> == 0b100: flg = ^f<2>; op0<5:3> == 0b101: flg = f<2>; op0<5:3> == 0b110: flg = ^f<7>; op0<5:3> == 0b111: flg = f<7>; } instruct zflagchk any { op0<4:3> == 0b00: flg = ^f<6>; op0<4:3> == 0b01: flg = f<6>; op0<4:3> == 0b10: flg = ^f<0>; op0<4:3> == 0b11: flg = f<0>; } instruct deccb any { (op0<7:6> == 0b00): zrlc(); (op0<7:6> == 0b01): zbit(); (op0<7> == 0b1): zres(); } instruct deced any { ((op0<7:6> || op0<2:1>) == 0b0100): zio(); ((op0<7:6> || op0<2:0>) == 0b01010): zaddsub(); ((op0<7:6> || op0<2:0>) == 0b01011): zld(); ((op0<7:4> || op0<2:0>) == 0b0110111): zrd(); ((op0<7:4> || op0<2:0>) == 0b0100101): zret(); ((op0<7:5> || op0<2>) == 0b1010): zblk(); ((op0<7:5> || op0<2>) == 0b0101): zmisc(); (op0 == 0x44): zneg(); } instruct decop any { (op0<7:6> == 0b01): dmov(); (op0<7:6> == 0b10): dalu(); ((op0<7:6> || op0<2:1>) == 0b0010): dinr(); ((op0<7:6> || op0<3:0>) == 0b001001): ddad(); ((op0<7:6> || op0<2:0>) == 0b00011): dinx(); ((op0<7:6> || op0<3:0>) == 0b110001): dpop(); ((op0<7:6> || op0<3:0>) == 0b110101): dpush(); ((op0<7:5> || op0<3:0>) == 0b0001010): dldax(); ((op0<7:5> || op0<3:0>) == 0b0000010): dstax(); ((op0<7:6> || op0<2:0>) == 0b11000): dretc(); ((op0<7:6> || op0<2:0>) == 0b11111): drst(); ((op0<7:6> || op0<2:0>) == 0b00111): dalum(); (op0 == 0xc9): dret(); (op0 == 0xe3): dxthl(); (op0 == 0xe9): dpchl(); (op0 == 0xf9): dsphl(); (op0 == 0xeb): dxchg(); (op0 == 0xf3): ddi(); (op0 == 0xfb): dei(); (op0 == 0x00): dnop(); ((op0<7:6>||op0<2:0>) == 0b00110): dmvi(); ((op0<7:6>||op0<2:0>) == 0b11110): dalui(); (op0 == 0xdb): din(); (op0 == 0xd3): dout(); ((op0<7:6>||op0<2:0>) == 0b11100): dcc(); ((op0<7:6>||op0<2:0>) == 0b11010): djc(); ((op0<7:6>||op0<3:0>) == 0b000001): dlxi(); (op0 == 0xcd): dcall(); (op0 == 0xc3): djmp(); (op0 == 0x3a): dlda(); (op0 == 0x2a): dlhld(); (op0 == 0x22): dshld(); (op0 == 0x32): dsta(); (op0 == 0xd9): dexx(); (op0 == 0x08): dexaf(); (op0 == 0xdd): ddd(); (op0 == 0xfd): dfd(); (op0 == 0xcb): dcb(); (op0 == 0xed): ded(); (op0 == 0x10): zdjnz(); (op0 == 0x18): zjr(); ((op0<7:5>||op0<2:0>) == 0b001000): zjrc(); } %d OP2OP1 0b00 %d HL 0b01 %d SP 0b10 %d PC 0b11 instruct incop par { op1:=alu.inc(loop1().lo).out; op2:=inc.up(op2,alu.c).out;} instruct incsp par { spl:=alu.inc(lospl().lo).out; sph:=inc.up(sph,alu.c).out;} instruct incpc par { pcl:=alu.inc(lopcl().lo).out; pch:=inc.up(pch,alu.c).out;} instruct decsp par { spl:=alu.dec(spl).out; sph:=inc.down(sph,alu.c).out;} instruct decpc par { pcl:=alu.dec(lopcl().lo).out; pch:=inc.down(pch,alu.c).out;} instruct dmov any { ex.run: par { /* MOV, HLT */ any { op0<5:0> == 0b110110: par { decpc(); ifetch(); } else: any { (op0<2:0> == M): any { dd | fd: par { fetch2(); run2(); } else: par { op1 := memory_read(h||l).data; run1(); } } else: par { op1 := getreg(op0<2:0>).lo; run1(); } } } } ex.run1: any { op0<5:3> == M: any { dd | fd: par { fetch2(); run2(); tmp := op1; } else: par { memory_write(h||l,op1); ifetch(); } } else: par { setreg(op0<5:3>,op1); ifetch(); } } ex.run2: par { op1 := alu.add(getreg(L).lo, op1).out; op2 := inc.up(h,alu.c).out; any { op0<5:3> == M: run4(); else: run3(); } } ex.run3: par { op1 := memory_read(op2||op1).data; run1(); } ex.run4: par { memory_write(op2||op1,tmp); ifetch(); } } instruct dalu any { ex.run: any { /* ALU */ (op0<2:0> == M): any { dd | fd: par { fetch2(); run2(); } else: par { op1 := memory_read(h||l).data; run1(); } } else: par { op1 := getreg(op0<2:0>).lo; run1(); } } ex.run1: par { any { op0<5:3> == 0b000: alu.add(getreg(A).lo, op1); op0<5:3> == 0b001: alu.adc(getreg(A).lo, op1, f<0>); op0<5:3> == 0b010: alu.sub(getreg(A).lo, op1); op0<5:3> == 0b011: alu.sbc(getreg(A).lo, op1, f<0>); op0<5:3> == 0b100: alu.and(getreg(A).lo, op1); op0<5:3> == 0b101: alu.xor(getreg(A).lo, op1); op0<5:3> == 0b110: alu.or(getreg(A).lo, op1); op0<5:3> == 0b111: alu.cmp(getreg(A).lo, op1); } setreg(A, alu.out); setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||alu.c); ifetch(); } ex.run2: par { op1 := alu.add(getreg(L).lo, op1).out; op2 := inc.up(h,alu.c).out; run3(); } ex.run3: par { op1 := memory_read(op2||op1).data; run1(); } } instruct dinr any { ex.run: any { /* INR,DCR */ (op0<5:3> == M): any { dd | fd: par { fetch2(); run3(); } else: par { op1 := memory_read(h||l).data; run1(); } } else: par { any { ^op0<0>: alu.inc(getreg(op0<5:3>).lo); op0<0>: alu.dec(getreg(op0<5:3>).lo); } setreg(op0<5:3>, alu.out); setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||f<0>); ifetch(); } } ex.run1: par { any { ^op0<0>: alu.inc(loop1().lo); op0<0>: alu.dec(loop1().lo); } any { (dd|fd): par { tmp := alu.out; op1 := tmp; } else: op1 := alu.out; } setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||f<0>); run2(); } ex.run2: par { any { (dd|fd) : memory_write(op2||op1, tmp); else: memory_write(h||l, op1); } ifetch(); } ex.run3: par { op1 := alu.add(getreg(L).lo, op1).out; op2 := inc.up(h,alu.c).out; run4(); } ex.run4: par { op1 := memory_read(op2||op1).data; tmp := op1; run1(); } } instruct ddad any { ex.run: par { /* DAD */ setrx(L, alu.add(getrx(op0<5:4>||0b1).lo, l).out); tc := alu.c; run1(); } ex.run1: par { setrx(H,alu.adc(getrx(op0<5:4> || 0b0).lo, h, tc).out); setflag(f<7:1>||alu.c); ifetch(); } } instruct dinx any { ex.run: par { /* INX,DCX */ any { ^op0<3>: alu.inc(getrx(op0<5:4> || 0b1).lo); op0<3>: alu.dec(getrx(op0<5:4> || 0b1).lo); } setrx(op0<5:4> || 0b1, alu.out); tc := alu.c; run1(); } ex.run1: par { any { ^op0<3>: alu.incc(getrx(op0<5:4> || 0b0).lo, tc); op0<3>: alu.decc(getrx(op0<5:4> || 0b0).lo, tc); } setrx(op0<5:4> || 0b0, alu.out); ifetch(); } } instruct dpop any { ex.run: par { /* POP */ setreg(op0<5:4> || 0b1, memory_read(sph||spl).data); incsp(); run1(); } ex.run1: par { setreg(op0<5:4> || 0b0, memory_read(sph || spl).data); incsp(); ifetch(); } } instruct dpush any { ex.run: par { /* PUSH */ decsp(); run1(); } ex.run1: par { memory_write(sph || spl, getreg(op0<5:4> || 0b0).lo); decsp(); run2(); } ex.run2: par { memory_write(sph || spl, getreg(op0<5:4> || 0b1).lo); ifetch(); } } instruct dldax par { /* LDAX */ any { ^op0<4>: setreg(A,memory_read(b||c).data); else: setreg(A,memory_read(d||e).data); } ifetch(); } instruct dstax par { /* STAX */ any { ^op0<4>: memory_write(b||c,a); else: memory_write(d||e,a); } ifetch(); } instruct dretc any { ex.run: any { /* RETC */ flagchk().flg : dret(); else: ifetch(); } ex.run1: dret(); } instruct dret any { ex.run: par { pcl := memory_read(sph||spl).data; incsp(); run1(); } ex.run1: par { pch := memory_read(sph || spl).data; incsp(); ifetch(); } } instruct drst any { ex.run: par { op1 := 0b00 || op0<5:3> || 0b000; op2 := 0x00; decsp(); run3(); } else: dcall(); } instruct dalum any { ex.run: par { /* ALU MISC */ any { op0<5:3> == 0b000: par { /* RLC */ setreg(A,alu.rlc(getreg(A).lo).out); setflag(f<7:1> || alu.c); ifetch(); } op0<5:3> == 0b001: par { /* RRC */ setreg(A,alu.rrc(getreg(A).lo).out); setflag(f<7:1> || alu.c); ifetch(); } op0<5:3> == 0b010: par { /* RAL */ setreg(A,alu.rl(getreg(A).lo,f<0>).out); setflag(f<7:1> || alu.c); ifetch(); } op0<5:3> == 0b011: par { /* RAR */ setreg(A,alu.rr(getreg(A).lo,f<0>).out); setflag(f<7:1> || alu.c); ifetch(); } op0<5:3> == 0b100: par { /* DAA */ if(a<3> & (a<2> | a<1>) | f<4>) par { setreg(A,alu.add(getreg(A).lo, 0x06).out); setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||alu.c); } run1(); } op0<5:3> == 0b101: par { /* CMA */ setreg(A,^a); ifetch(); } op0<5:3> == 0b110: par { /* STC */ setflag(f<7:1> || 0b1); ifetch(); } op0<5:3> == 0b111: par { /* CMC */ setflag(f<7:1> || ^f<0>); ifetch(); } } } ex.run1: par { if(a<7> & (a<6> | a<5>) | f<0>) par { setreg(A,alu.add(getreg(A).lo, 0x60).out); setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||alu.c); } ifetch(); } } instruct dxthl any { ex.run: par { /* XTHL */ op1:=memory_read(sph||spl).data; run1(); } ex.run1: par { memory_write(sph || spl, l); setreg(L,op1); incsp(); run2(); } ex.run2: par { op1:=memory_read(sph || spl).data; run3(); } ex.run3: par { setreg(H, op1); memory_write(sph || spl, h); decsp(); ifetch(); } } instruct dpchl par { pch := h; pcl := l; ifetch(); } instruct dsphl any { ex.run: par { /* SPHL */ setrx(SPH, getreg(H).lo); run1(); } ex.run1: par { setrx(SPL, getreg(L).lo); ifetch(); } } instruct dxchg any { ex.run: par { /* XCHG */ op1 := getreg(H).lo; run1(); } ex.run1: par { setreg(H, getreg(D).lo); run2(); } ex.run2: par { setreg(D, op1); op1 := getreg(L).lo; run3(); } ex.run3: par { setreg(L, getreg(E).lo); run4(); } ex.run4: par { setreg(E, op1); ifetch(); } } instruct ddi par { imask := 0b1; ifetch(); } instruct dei par { imask := 0b0; ifetch(); } instruct dnop par { ifetch(); } instruct dmvi any { ex.run: par { /* MVI */ fetch2(); run1(); } else: dmov(); } instruct dalui any { ex.run: par { /* ALU */ fetch2(); run1(); } else: dalu(); } instruct din any { ex.run: par {fetch2(); run1(); } ex.run1: par { /* IN */ setreg(A,io_read(0x00 || op1).data); ifetch(); } } instruct dout any { ex.run: par {fetch2(); run1(); } ex.run1: par { /* OUT */ io_write(0x00 || op1,a); ifetch(); } } instruct dcc any { ex.run: par {fetch2(); run1(); } ex.run1: par {fetch3(); run2(); } ex.run2: any { /* CC */ flagchk().flg: dcall(); else: ifetch(); } else: dcall(); } instruct dcall any { ex.run: par {fetch2(); run1(); } ex.run1: par {fetch3(); run2(); } ex.run2: par { /* CALL */ decsp(); run3(); } ex.run3: par { memory_write(sph || spl, pch); decsp(); run4(); } ex.run4: par { memory_write(sph || spl, pcl); djmp(); } } instruct djmp any { ex.run: par {fetch2(); run1(); } ex.run1: par {fetch3(); run2(); } else: par { /* JMP */ pcl := op1; pch := op2; ifetch(); } } instruct djc any { ex.run: par {fetch2(); run1(); } ex.run1: par {fetch3(); run2(); } ex.ru