MCUME/MCUME_pico/picoo2em/cpu.c

1597 wiersze
32 KiB
C

/*
* O2EM Freeware Odyssey2 / Videopac+ Emulator
*
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
*
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
*
* http://o2em.sourceforge.net
*
*
*
* 8048 microcontroller emulation
*/
#include <stdio.h>
#include "types.h"
#include "vmachine.h"
//#include "voice.h"
#include "vdc.h"
//#include "vpp.h"
#include "cpu.h"
Byte acc; /* Accumulator */
ADDRESS pc; /* Program counter */
long clk; /* clock */
Byte itimer; /* Internal timer */
Byte reg_pnt; /* pointer to register bank */
Byte timer_on; /* 0=timer off/1=timer on */
Byte count_on; /* 0=count off/1=count on */
Byte psw; /* Processor status word */
Byte sp; /* Stack pointer (part of psw) */
Byte p1; /* I/O port 1 */
Byte p2; /* I/O port 2 */
Byte xirq_pend; /* external IRQ pending */
Byte tirq_pend; /* timer IRQ pending */
Byte t_flag; /* Timer flag */
static ADDRESS lastpc;
static ADDRESS A11; /* PC bit 11 */
static ADDRESS A11ff;
static Byte bs; /* Register Bank (part of psw) */
static Byte f0; /* Flag Bit (part of psw) */
static Byte f1; /* Flag Bit 1 */
static Byte ac; /* Aux Carry (part of psw) */
static Byte cy; /* Carry flag (part of psw) */
static Byte xirq_en; /* external IRQ's enabled */
static Byte tirq_en; /* Timer IRQ enabled */
static Byte irq_ex; /* IRQ executing */
static int master_count;
#define push(d) {intRAM[sp++] = (d); if (sp > 23) sp = 8;}
#define pull() (sp--, (sp < 8)?(sp=23):0, intRAM[sp])
#define make_psw() {psw = (cy << 7) | ac | f0 | bs | 0x08; psw = psw | ((sp - 8) >> 1);}
#define illegal(o) {}
#define undef(i) {printf("** unimplemented instruction %x, %x**\n",i,pc);}
void init_cpu(void){
pc=0;
sp=8;
bs=0;
p1=p2=0xFF;
ac=cy=f0=0;
A11=A11ff=0;
timer_on=0;
count_on=0;
reg_pnt=0;
tirq_en=xirq_en=irq_ex=xirq_pend=tirq_pend=0;
}
void ext_IRQ(void){
int_clk = 5; /* length of pulse on /INT */
if (xirq_en && !irq_ex) {
irq_ex=1;
xirq_pend=0;
clk+=2;
make_psw();
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = 0x03;
A11ff=A11;
A11=0;
}
if (pendirq && (!xirq_en)) xirq_pend=1;
}
void tim_IRQ(void){
if (tirq_en && !irq_ex) {
irq_ex=2;
tirq_pend=0;
clk+=2;
make_psw();
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = 0x07;
A11ff=A11;
A11=0;
}
if (pendirq && (!tirq_en)) tirq_pend=1;
}
void make_psw_debug(void){
make_psw();
}
void cpu_exec(void) {
Byte op;
ADDRESS adr;
Byte dat;
int temp;
for (;;) {
clk=0;
lastpc=pc;
op=rom[pc++];
switch (op) {
case 0x00: /* NOP */
clk++;
break;
case 0x01: /* ILL */
illegal(op);
clk++;
break;
case 0x02: /* OUTL BUS,A */
clk+=2;
undef(0x02);
break;
case 0x03: /* ADD A,#data */
clk+=2;
cy=ac=0;
dat=rom[pc++];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x04: /* JMP */
pc=rom[pc] | A11;
clk+=2;
break;
case 0x05: /* EN I */
xirq_en=1;
clk++;
break;
case 0x06: /* ILL */
clk++;
illegal(op);
break;
case 0x07: /* DEC A */
acc--;
clk++;
break;
case 0x08: /* INS A,BUS*/
clk+=2;
acc=in_bus();
break;
case 0x09: /* IN A,Pp */
acc=p1;
clk+=2;
break;
case 0x0A: /* IN A,Pp */
acc=read_P2();
clk+=2;
break;
case 0x0B: /* ILL */
clk++;
illegal(op);
case 0x0C: /* MOVD A,P4 */
clk+=2;
//acc=read_PB(0);
break;
case 0x0D: /* MOVD A,P5 */
clk+=2;
//acc=read_PB(1);
break;
case 0x0E: /* MOVD A,P6 */
clk+=2;
//acc=read_PB(2);
break;
case 0x0F: /* MOVD A,P7 */
clk+=2;
//acc=read_PB(3);
break;
case 0x10: /* INC @Ri */
intRAM[intRAM[reg_pnt] & 0x3F]++;
clk++;
break;
case 0x11: /* INC @Ri */
intRAM[intRAM[reg_pnt+1] & 0x3F]++;
clk++;
break;
case 0x12: /* JBb address */
clk+=2;
dat = rom[pc];
if (acc & 0x01)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x13: /* ADDC A,#data */
clk+=2;
dat=rom[pc++];
ac=0;
if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x14: /* CALL */
make_psw();
adr = rom[pc] | A11;
pc++;
clk+=2;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0x15: /* DIS I */
xirq_en=0;
clk++;
break;
case 0x16: /* JTF */
clk+=2;
dat = rom[pc];
if (t_flag)
pc=(pc & 0xF00) | dat;
else
pc++;
t_flag=0;
break;
case 0x17: /* INC A */
acc++;
clk++;
break;
case 0x18: /* INC Rr */
intRAM[reg_pnt]++;
clk++;
break;
case 0x19: /* INC Rr */
intRAM[reg_pnt+1]++;
clk++;
break;
case 0x1A: /* INC Rr */
intRAM[reg_pnt+2]++;
clk++;
break;
case 0x1B: /* INC Rr */
intRAM[reg_pnt+3]++;
clk++;
break;
case 0x1C: /* INC Rr */
intRAM[reg_pnt+4]++;
clk++;
break;
case 0x1D: /* INC Rr */
intRAM[reg_pnt+5]++;
clk++;
break;
case 0x1E: /* INC Rr */
intRAM[reg_pnt+6]++;
clk++;
break;
case 0x1F: /* INC Rr */
intRAM[reg_pnt+7]++;
clk++;
break;
case 0x20: /* XCH A,@Ri */
clk++;
dat=acc;
acc=intRAM[intRAM[reg_pnt] & 0x3F];
intRAM[intRAM[reg_pnt] & 0x3F] = dat;
break;
case 0x21: /* XCH A,@Ri */
clk++;
dat=acc;
acc=intRAM[intRAM[reg_pnt+1] & 0x3F];
intRAM[intRAM[reg_pnt+1] & 0x3F] = dat;
break;
case 0x22: /* ILL */
illegal(op);
break;
case 0x23: /* MOV a,#data */
clk+=2;
acc = rom[pc++];
break;
case 0x24: /* JMP */
pc=rom[pc] | 0x100 | A11;
clk+=2;
break;
case 0x25: /* EN TCNTI */
tirq_en=1;
clk++;
break;
case 0x26: /* JNT0 */
clk+=2;
dat = rom[pc];
//JMH if (!get_voice_status())
// pc=(pc & 0xF00) | dat;
// else
pc++;
break;
case 0x27: /* CLR A */
clk++;
acc=0;
break;
case 0x28: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt];
intRAM[reg_pnt]=dat;
clk++;
break;
case 0x29: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt+1];
intRAM[reg_pnt+1]=dat;
clk++;
break;
case 0x2A: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt+2];
intRAM[reg_pnt+2]=dat;
clk++;
break;
case 0x2B: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt+3];
intRAM[reg_pnt+3]=dat;
clk++;
break;
case 0x2C: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt+4];
intRAM[reg_pnt+4]=dat;
clk++;
break;
case 0x2D: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt+5];
intRAM[reg_pnt+5]=dat;
clk++;
break;
case 0x2E: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt+6];
intRAM[reg_pnt+6]=dat;
clk++;
break;
case 0x2F: /* XCH A,Rr */
dat=acc;
acc=intRAM[reg_pnt+7];
intRAM[reg_pnt+7]=dat;
clk++;
break;
case 0x30: /* XCHD A,@Ri */
clk++;
adr=intRAM[reg_pnt] & 0x3F;
dat=acc & 0x0F;
acc=acc & 0xF0;
acc=acc | (intRAM[adr] & 0x0F);
intRAM[adr] &= 0xF0;
intRAM[adr] |= dat;
break;
case 0x31: /* XCHD A,@Ri */
clk++;
adr=intRAM[reg_pnt+1] & 0x3F;
dat=acc & 0x0F;
acc=acc & 0xF0;
acc=acc | (intRAM[adr] & 0x0F);
intRAM[adr] &= 0xF0;
intRAM[adr] |= dat;
break;
case 0x32: /* JBb address */
clk+=2;
dat=rom[pc];
if (acc & 0x02)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x33: /* ILL */
clk++;
illegal(op);
break;
case 0x34: /* CALL */
make_psw();
adr = rom[pc] | 0x100 | A11;
pc++;
clk+=2;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0x35: /* DIS TCNTI */
tirq_en=0;
tirq_pend=0;
clk++;
break;
case 0x36: /* JT0 */
clk+=2;
dat=rom[pc];
// JMH if (get_voice_status())
// pc=(pc & 0xF00) | dat;
// else
pc++;
break;
case 0x37: /* CPL A */
acc = acc ^ 0xFF;
clk++;
break;
case 0x38: /* ILL */
clk++;
illegal(op);
break;
case 0x39: /* OUTL P1,A */
clk+=2;
write_p1(acc);
break;
case 0x3A: /* OUTL P2,A */
clk+=2;
p2=acc;
break;
case 0x3B: /* ILL */
clk++;
illegal(op);
break;
case 0x3C: /* MOVD P4,A */
clk+=2;
//write_PB(0,acc);
break;
case 0x3D: /* MOVD P5,A */
clk+=2;
//write_PB(1,acc);
break;
case 0x3E: /* MOVD P6,A */
clk+=2;
//write_PB(2,acc);
break;
case 0x3F: /* MOVD P7,A */
clk+=2;
//write_PB(3,acc);
break;
case 0x40: /* ORL A,@Ri */
clk++;
acc = acc | intRAM[intRAM[reg_pnt] & 0x3F];
break;
case 0x41: /* ORL A,@Ri */
clk++;
acc = acc | intRAM[intRAM[reg_pnt+1] & 0x3F];
break;
case 0x42: /* MOV A,T */
clk++;
acc = itimer;
break;
case 0x43: /* ORL A,#data */
clk+=2;
acc = acc | rom[pc++];
break;
case 0x44: /* JMP */
pc=rom[pc] | 0x200 | A11;
clk+=2;
break;
case 0x45: /* STRT CNT */
/* printf("START: %d=%d\n",master_clk/22,itimer); */
count_on=1;
clk++;
break;
case 0x46: /* JNT1 */
clk+=2;
dat = rom[pc];
if (!read_t1())
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x47: /* SWAP A */
clk++;
dat=(acc & 0xF0) >> 4;
acc = acc << 4;
acc = acc | dat;
break;
case 0x48: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt];
break;
case 0x49: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt+1];
break;
case 0x4A: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt+2];
break;
case 0x4B: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt+3];
break;
case 0x4C: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt+4];
break;
case 0x4D: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt+5];
break;
case 0x4E: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt+6];
break;
case 0x4F: /* ORL A,Rr */
clk++;
acc = acc | intRAM[reg_pnt+7];
break;
case 0x50: /* ANL A,@Ri */
acc = acc & intRAM[intRAM[reg_pnt] & 0x3F];
clk++;
break;
case 0x51: /* ANL A,@Ri */
acc = acc & intRAM[intRAM[reg_pnt+1] & 0x3F];
clk++;
break;
case 0x52: /* JBb address */
clk+=2;
dat=rom[pc];
if (acc & 0x04)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x53: /* ANL A,#data */
clk+=2;
acc = acc & rom[pc++];
break;
case 0x54: /* CALL */
make_psw();
adr = rom[pc] | 0x200 | A11;
pc++;
clk+=2;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0x55: /* STRT T */
timer_on=1;
clk++;
break;
case 0x56: /* JT1 */
clk+=2;
dat = rom[pc];
if (read_t1())
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x57: /* DA A */
clk++;
if (((acc & 0x0F) > 0x09) || ac) acc+=6;
dat = (acc & 0xF0) >> 4;
if ((dat > 9) || cy) {
dat+=6;
cy=1;
}
else {
cy=0;
}
/* if (dat > 0x0F) cy=1; */
acc = (acc & 0x0F) | (dat << 4);
break;
case 0x58: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt];
break;
case 0x59: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt+1];
break;
case 0x5A: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt+2];
break;
case 0x5B: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt+3];
break;
case 0x5C: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt+4];
break;
case 0x5D: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt+5];
break;
case 0x5E: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt+6];
break;
case 0x5F: /* ANL A,Rr */
clk++;
acc = acc & intRAM[reg_pnt+7];
break;
case 0x60: /* ADD A,@Ri */
clk++;
cy=ac=0;
dat=intRAM[intRAM[reg_pnt] & 0x3F];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x61: /* ADD A,@Ri */
clk++;
cy=ac=0;
dat=intRAM[intRAM[reg_pnt+1] & 0x3F];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x62: /* MOV T,A */
clk++;
itimer=acc;
break;
case 0x63: /* ILL */
clk++;
illegal(op);
break;
case 0x64: /* JMP */
pc=rom[pc] | 0x300 | A11;
clk+=2;
break;
case 0x65: /* STOP TCNT */
clk++;
/* printf("STOP %d\n",master_clk/22); */
count_on=timer_on=0;
break;
case 0x66: /* ILL */
clk++;
illegal(op);
break;
case 0x67: /* RRC A */
dat=cy;
cy=acc & 0x01;
acc = acc >> 1;
if (dat)
acc = acc | 0x80;
else
acc = acc & 0x7F;
clk++;
break;
case 0x68: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x69: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt+1];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x6A: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt+2];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x6B: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt+3];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x6C: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt+4];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x6D: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt+5];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x6E: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt+6];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x6F: /* ADD A,Rr */
clk++;
cy=ac=0;
dat=intRAM[reg_pnt+7];
if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) ac=0x40;
temp=acc+dat;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x70: /* ADDC A,@Ri */
clk++;
ac=0;
dat=intRAM[intRAM[reg_pnt] & 0x3F];
if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x71: /* ADDC A,@Ri */
clk++;
ac=0;
dat=intRAM[intRAM[reg_pnt+1] & 0x3F];
if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x72: /* JBb address */
clk+=2;
dat=rom[pc];
if (acc & 0x08)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x73: /* ILL */
clk++;
illegal(op);
break;
case 0x74: /* CALL */
make_psw();
adr = rom[pc] | 0x300 | A11;
pc++;
clk+=2;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0x75: /* EN CLK */
clk++;
undef(op);
break;
case 0x76: /* JF1 address */
clk+=2;
dat=rom[pc];
if (f1)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x77: /* RR A */
clk++;
dat=acc & 0x01;
acc = acc >> 1;
if (dat)
acc = acc | 0x80;
else
acc = acc & 0x7f;
break;
case 0x78: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x79: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt+1];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x7A: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt+2];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x7B: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt+3];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x7C: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt+4];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x7D: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt+5];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x7E: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt+6];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x7F: /* ADDC A,Rr */
clk++;
ac=0;
dat=intRAM[reg_pnt+7];
if (((acc & 0x0f) + (dat & 0x0f)+cy) > 0x0f) ac=0x40;
temp=acc+dat+cy;
cy=0;
if (temp > 0xFF) cy=1;
acc=(temp & 0xFF);
break;
case 0x80: /* MOVX A,@Ri */
acc=ext_read(intRAM[reg_pnt]);
clk+=2;
break;
case 0x81: /* MOVX A,@Ri */
acc=ext_read(intRAM[reg_pnt+1]);
clk+=2;
break;
case 0x82: /* ILL */
clk++;
illegal(op);
break;
case 0x83: /* RET */
pc = ((pull() & 0x0F) << 8);
pc = pc | pull();
break;
case 0x84: /* JMP */
pc=rom[pc] | 0x400 | A11;
clk+=2;
break;
case 0x85: /* CLR F0 */
clk++;
f0=0;
break;
case 0x86: /* JNI address */
clk+=2;
dat=rom[pc];
if (int_clk > 0)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
break;
case 0x87: /* ILL */
illegal(op);
clk++;
break;
case 0x88: /* BUS,#data */
clk+=2;
undef(op);
break;
case 0x89: /* ORL Pp,#data */
write_p1(p1 | rom[pc++]);
clk+=2;
break;
case 0x8A: /* ORL Pp,#data */
p2 = p2 | rom[pc++];
clk+=2;
break;
case 0x8B: /* ILL */
illegal(op);
clk++;
break;
case 0x8C: /* ORLD P4,A */
//write_PB(0,read_PB(0)|acc);
clk+=2;
break;
case 0x8D: /* ORLD P5,A */
//write_PB(1,read_PB(1)|acc);
clk+=2;
break;
case 0x8E: /* ORLD P6,A */
//write_PB(2,read_PB(2)|acc);
clk+=2;
break;
case 0x8F: /* ORLD P7,A */
//write_PB(3,read_PB(3)|acc);
clk+=2;
break;
case 0x90: /* MOVX @Ri,A */
ext_write(acc,intRAM[reg_pnt]);
clk+=2;
break;
case 0x91: /* MOVX @Ri,A */
ext_write(acc,intRAM[reg_pnt+1]);
clk+=2;
break;
case 0x92: /* JBb address */
clk+=2;
dat=rom[pc];
if (acc & 0x10)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x93: /* RETR*/
/* printf("RETR %d\n",master_clk/22); */
clk+=2;
dat=pull();
pc = (dat & 0x0F) << 8;
cy = (dat & 0x80) >> 7;
ac = dat & 0x40;
f0 = dat & 0x20;
bs = dat & 0x10;
if (bs)
reg_pnt=24;
else
reg_pnt=0;
pc = pc | pull();
irq_ex=0;
A11=A11ff;
break;
case 0x94: /* CALL */
make_psw();
adr = rom[pc] | 0x400 | A11;
pc++;
clk+=2;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0x95: /* CPL F0 */
f0 = f0 ^ 0x20;
clk++;
break;
case 0x96: /* JNZ address */
clk+=2;
dat=rom[pc];
if (acc != 0)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0x97: /* CLR C */
cy=0;
clk++;
break;
case 0x98: /* ANL BUS,#data */
clk+=2;
undef(op);
break;
case 0x99: /* ANL Pp,#data */
write_p1(p1 & rom[pc++]);
clk+=2;
break;
case 0x9A: /* ANL Pp,#data */
p2 = p2 & rom[pc++];
clk+=2;
break;
case 0x9B: /* ILL */
illegal(op);
clk++;
break;
case 0x9C: /* ANLD P4,A */
//write_PB(0,read_PB(0)&acc);
clk+=2;
break;
case 0x9D: /* ANLD P5,A */
//write_PB(1,read_PB(1)&acc);
clk+=2;
break;
case 0x9E: /* ANLD P6,A */
//write_PB(2,read_PB(2)&acc);
clk+=2;
break;
case 0x9F: /* ANLD P7,A */
//write_PB(3,read_PB(3)&acc);
clk+=2;
break;
case 0xA0: /* MOV @Ri,A */
intRAM[intRAM[reg_pnt] & 0x3F]=acc;
clk++;
break;
case 0xA1: /* MOV @Ri,A */
intRAM[intRAM[reg_pnt+1] & 0x3F]=acc;
clk++;
break;
case 0xA2: /* ILL */
clk++;
illegal(op);
break;
case 0xA3: /* MOVP A,@A */
acc=rom[(pc & 0xF00) | acc];
clk+=2;
break;
case 0xA4: /* JMP */
pc=rom[pc] | 0x500 | A11;
clk+=2;
break;
case 0xA5: /* CLR F1 */
clk++;
f1=0;
break;
case 0xA6: /* ILL */
illegal(op);
clk++;
break;
case 0xA7: /* CPL C */
cy = cy ^ 0x01;
clk++;
break;
case 0xA8: /* MOV Rr,A */
intRAM[reg_pnt] = acc;
break;
case 0xA9: /* MOV Rr,A */
intRAM[reg_pnt+1] = acc;
break;
case 0xAA: /* MOV Rr,A */
intRAM[reg_pnt+2] = acc;
break;
case 0xAB: /* MOV Rr,A */
intRAM[reg_pnt+3] = acc;
break;
case 0xAC: /* MOV Rr,A */
intRAM[reg_pnt+4] = acc;
break;
case 0xAD: /* MOV Rr,A */
intRAM[reg_pnt+5] = acc;
break;
case 0xAE: /* MOV Rr,A */
intRAM[reg_pnt+6] = acc;
break;
case 0xAF: /* MOV Rr,A */
intRAM[reg_pnt+7] = acc;
break;
case 0xB0: /* MOV @Ri,#data */
intRAM[intRAM[reg_pnt] & 0x3F]=rom[pc++];
clk+=2;
break;
case 0xB1: /* MOV @Ri,#data */
intRAM[intRAM[reg_pnt+1] & 0x3F]=rom[pc++];
clk+=2;
break;
case 0xB2: /* JBb address */
clk+=2;
dat=rom[pc];
if (acc & 0x20)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0xB3: /* JMPP @A */
adr = (pc & 0xF00) | acc;
pc=(pc & 0xF00) | rom[adr];
clk+=2;
break;
case 0xB4: /* CALL */
make_psw();
adr = rom[pc] | 0x500 | A11;
pc++;
clk+=2;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0xB5: /* CPL F1 */
f1 = f1 ^ 0x01;
clk++;
break;
case 0xB6: /* JF0 address */
clk+=2;
dat=rom[pc];
if (f0)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0xB7: /* ILL */
clk++;
illegal(op);
break;
case 0xB8: /* MOV Rr,#data */
intRAM[reg_pnt]=rom[pc++];
clk+=2;
break;
case 0xB9: /* MOV Rr,#data */
intRAM[reg_pnt+1]=rom[pc++];
clk+=2;
break;
case 0xBA: /* MOV Rr,#data */
intRAM[reg_pnt+2]=rom[pc++];
clk+=2;
break;
case 0xBB: /* MOV Rr,#data */
intRAM[reg_pnt+3]=rom[pc++];
clk+=2;
break;
case 0xBC: /* MOV Rr,#data */
intRAM[reg_pnt+4]=rom[pc++];
clk+=2;
break;
case 0xBD: /* MOV Rr,#data */
intRAM[reg_pnt+5]=rom[pc++];
clk+=2;
break;
case 0xBE: /* MOV Rr,#data */
intRAM[reg_pnt+6]=rom[pc++];
clk+=2;
break;
case 0xBF: /* MOV Rr,#data */
intRAM[reg_pnt+7]=rom[pc++];
clk+=2;
break;
case 0xC0: /* ILL */
illegal(op);
clk++;
break;
case 0xC1: /* ILL */
illegal(op);
clk++;
break;
case 0xC2: /* ILL */
illegal(op);
clk++;
break;
case 0xC3: /* ILL */
illegal(op);
clk++;
break;
case 0xC4: /* JMP */
pc=rom[pc] | 0x600 | A11;
clk+=2;
break;
case 0xC5: /* SEL RB0 */
bs=reg_pnt=0;
clk++;
break;
case 0xC6: /* JZ address */
clk+=2;
dat=rom[pc];
if (acc == 0)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0xC7: /* MOV A,PSW */
clk++;
make_psw();
acc=psw;
break;
case 0xC8: /* DEC Rr */
intRAM[reg_pnt]--;
clk++;
break;
case 0xC9: /* DEC Rr */
intRAM[reg_pnt+1]--;
clk++;
break;
case 0xCA: /* DEC Rr */
intRAM[reg_pnt+2]--;
clk++;
break;
case 0xCB: /* DEC Rr */
intRAM[reg_pnt+3]--;
clk++;
break;
case 0xCC: /* DEC Rr */
intRAM[reg_pnt+4]--;
clk++;
break;
case 0xCD: /* DEC Rr */
intRAM[reg_pnt+5]--;
clk++;
break;
case 0xCE: /* DEC Rr */
intRAM[reg_pnt+6]--;
clk++;
break;
case 0xCF: /* DEC Rr */
intRAM[reg_pnt+7]--;
clk++;
break;
case 0xD0: /* XRL A,@Ri */
acc = acc ^ intRAM[intRAM[reg_pnt] & 0x3F];
clk++;
break;
case 0xD1: /* XRL A,@Ri */
acc = acc ^ intRAM[intRAM[reg_pnt+1] & 0x3F];
clk++;
break;
case 0xD2: /* JBb address */
clk+=2;
dat = rom[pc];
if (acc & 0x40)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0xD3: /* XRL A,#data */
clk+=2;
acc = acc ^ rom[pc++];
break;
case 0xD4: /* CALL */
make_psw();
adr = rom[pc] | 0x600 | A11;
pc++;
clk+=2;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0xD5: /* SEL RB1 */
bs=0x10;
reg_pnt=24;
clk++;
break;
case 0xD6: /* ILL */
illegal(op);
clk++;
break;
case 0xD7: /* MOV PSW,A */
psw=acc;
clk++;
cy = (psw & 0x80) >> 7;
ac = psw & 0x40;
f0 = psw & 0x20;
bs = psw & 0x10;
if (bs)
reg_pnt = 24;
else
reg_pnt = 0;
sp = (psw & 0x07) << 1;
sp+=8;
break;
case 0xD8: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt];
clk++;
break;
case 0xD9: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt+1];
clk++;
break;
case 0xDA: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt+2];
clk++;
break;
case 0xDB: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt+3];
clk++;
break;
case 0xDC: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt+4];
clk++;
break;
case 0xDD: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt+5];
clk++;
break;
case 0xDE: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt+6];
clk++;
break;
case 0xDF: /* XRL A,Rr */
acc = acc ^ intRAM[reg_pnt+7];
clk++;
break;
case 0xE0: /* ILL */
clk++;
illegal(op);
break;
case 0xE1: /* ILL */
clk++;
illegal(op);
break;
case 0xE2: /* ILL */
clk++;
illegal(op);
break;
case 0xE3: /* MOVP3 A,@A */
adr = 0x300 | acc;
acc=rom[adr];
clk+=2;
break;
case 0xE4: /* JMP */
pc=rom[pc] | 0x700 | A11;
clk+=2;
break;
case 0xE5: /* SEL MB0 */
A11=0;
A11ff = 0;
clk++;
break;
case 0xE6: /* JNC address */
clk+=2;
dat=rom[pc];
if (!cy)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0xE7: /* RL A */
clk++;
dat=acc & 0x80;
acc = acc << 1;
if (dat)
acc = acc | 0x01;
else
acc = acc & 0xFE;
break;
case 0xE8: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt]--;
dat=rom[pc];
if (intRAM[reg_pnt] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xE9: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt+1]--;
dat=rom[pc];
if (intRAM[reg_pnt+1] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xEA: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt+2]--;
dat=rom[pc];
if (intRAM[reg_pnt+2] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xEB: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt+3]--;
dat=rom[pc];
if (intRAM[reg_pnt+3] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xEC: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt+4]--;
dat=rom[pc];
if (intRAM[reg_pnt+4] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xED: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt+5]--;
dat=rom[pc];
if (intRAM[reg_pnt+5] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xEE: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt+6]--;
dat=rom[pc];
if (intRAM[reg_pnt+6] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xEF: /* DJNZ Rr,address */
clk+=2;
intRAM[reg_pnt+7]--;
dat=rom[pc];
if (intRAM[reg_pnt+7] != 0) {
pc = pc & 0xF00;
pc = pc | dat;
} else pc++;
break;
case 0xF0: /* MOV A,@Ri */
clk++;
acc=intRAM[intRAM[reg_pnt] & 0x3F];
break;
case 0xF1: /* MOV A,@Ri */
clk++;
acc=intRAM[intRAM[reg_pnt + 1] & 0x3F];
break;
case 0xF2: /* JBb address */
clk+=2;
dat=rom[pc];
if (acc & 0x80)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0xF3: /* ILL */
illegal(op);
clk++;
break;
case 0xF4: /* CALL */
clk+=2;
make_psw();
adr = rom[pc] | 0x700 | A11;
pc++;
push(pc & 0xFF);
push(((pc & 0xF00) >> 8) | (psw & 0xF0));
pc = adr;
break;
case 0xF5: /* SEL MB1 */
if (irq_ex) {
A11ff = 0x800;
}
else
{
A11=0x800;
A11ff = 0x800;
}
clk++;
break;
case 0xF6: /* JC address */
clk+=2;
dat=rom[pc];
if (cy)
pc=(pc & 0xF00) | dat;
else
pc++;
break;
case 0xF7: /* RLC A */
dat=cy;
cy=(acc & 0x80) >> 7;
acc = acc << 1;
if (dat)
acc = acc | 0x01;
else
acc = acc & 0xFE;
clk++;
break;
case 0xF8: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt];
break;
case 0xF9: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt + 1];
break;
case 0xFA: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt + 2];
break;
case 0xFB: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt + 3];
break;
case 0xFC: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt + 4];
break;
case 0xFD: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt + 5];
break;
case 0xFE: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt + 6];
break;
case 0xFF: /* MOV A,Rr */
clk++;
acc = intRAM[reg_pnt + 7];
break;
}
master_clk+=clk;
h_clk+=clk;
clk_counter+=clk;
/* flag for JNI */
if (int_clk > clk)
int_clk -= clk;
else
int_clk = 0;
/* pending IRQs */
if (xirq_pend) ext_IRQ();
if (tirq_pend) tim_IRQ();
if (h_clk > LINECNT-1) {
h_clk-=LINECNT;
if (enahirq && (VDCwrite[0xA0] & 0x01)) ext_IRQ();
if (count_on && mstate == 0) {
itimer++;
if (itimer == 0) {
t_flag=1;
tim_IRQ();
if (!ccolflag) {
clear_collision();
ccolflag=1;
}
draw_region();
}
}
}
if (timer_on) {
master_count+=clk;
if (master_count > 31) {
master_count-=31;
itimer++;
if (itimer == 0) {
t_flag=1;
tim_IRQ();
}
}
}
if ((mstate==0) && (master_clk > VBLCLK))
handle_vbl();
if ((mstate==1) && (master_clk > evblclk)) {
handle_evbl();
break;
}
if (app_data.debug) break;
}
}