670 lines
10 KiB
Plaintext
670 lines
10 KiB
Plaintext
# sleigh specification file for Motorola 6805
|
|
define endian=big;
|
|
define alignment=1;
|
|
|
|
define space RAM type=ram_space size=2 default;
|
|
define space register type=register_space size=1;
|
|
|
|
define register offset=0x00 size=1 [ A X ];
|
|
define register offset=0x20 size=2 [ PC SP];
|
|
define register offset=0x30 size=1 [H I N Z C]; # status bits
|
|
|
|
define RAM offset=0x3ffc size=2 [ SWI_VECTOR ];
|
|
#TOKENS
|
|
|
|
define token opbyte (8)
|
|
op = (0,7)
|
|
op4_7 = (4,7)
|
|
op4_6 = (4,6)
|
|
n = (1,3)
|
|
bit_0 = (0,0)
|
|
;
|
|
|
|
define token data8 (8)
|
|
imm8 = (0,7)
|
|
rel = (0,7) signed
|
|
;
|
|
|
|
define token data (16)
|
|
imm16 = (0,15)
|
|
;
|
|
################################################################
|
|
# Psuedo Instructions
|
|
################################################################
|
|
|
|
define pcodeop readIRQ;
|
|
|
|
################################################################
|
|
REL: reloc is rel [ reloc = inst_next + rel; ] { export *:2 reloc; }
|
|
|
|
OP1: "#"imm8 is op4_6=2; imm8 { tmp:1 = imm8; export tmp; }
|
|
OP1: imm8 is op4_6=3; imm8 { export *:1 imm8; }
|
|
OP1: imm16 is op4_6=4; imm16 { export *:1 imm16; }
|
|
OP1: imm16,X is op4_6=5 & X; imm16 { tmp:2 = imm16 + zext(X); export *:1 tmp; }
|
|
OP1: imm8,X is op4_6=6 & X; imm8 { tmp:2 = imm8 + zext(X); export *:1 tmp; }
|
|
OP1: X is op4_6=7 & X { tmp:2 = zext(X); export *:1 tmp; }
|
|
|
|
ADDR: imm8 is op4_6=3; imm8 { export *:1 imm8; }
|
|
ADDR: imm16 is op4_6=4; imm16 { export *:1 imm16; }
|
|
ADDRI: imm16,X is op4_6=5 & X; imm16 { tmp:2 = imm16 + zext(X); export tmp; }
|
|
ADDRI: imm8,X is op4_6=6 & X; imm8 { tmp:2 = imm8 + zext(X); export tmp; }
|
|
ADDRI: X is op4_6=7 & X { tmp:2 = zext(X); export tmp; }
|
|
|
|
|
|
DIRECT: imm8 is imm8 { export *:1 imm8; }
|
|
|
|
:ADC OP1 is (op=0xA9 | op=0xB9 | op=0xC9 | op=0xD9 | op=0xE9 | op=0xF9) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
|
|
# compute half carry
|
|
local halfop1 = op1 & 0xF;
|
|
local halfA = A & 0xF;
|
|
local halfresult = halfop1 + halfA + C;
|
|
H = (halfresult >> 4) & 1;
|
|
|
|
local result = A + op1;
|
|
local tmpC = carry(A, op1);
|
|
|
|
A = result + C;
|
|
C = carry(result, C);
|
|
C = C | tmpC;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:ADD OP1 is (op=0xAB | op=0xBB | op=0xCB | op=0xDB | op=0xEB | op=0xFB) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
|
|
# compute half carry
|
|
local halfop1 = op1 & 0xF;
|
|
local halfA = A & 0xF;
|
|
local halfresult = halfop1 + halfA;
|
|
H = (halfresult >> 4) & 1;
|
|
|
|
C = carry(A, op1);
|
|
A = A + op1;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
|
|
:AND OP1 is (op=0xA4 | op=0xB4 | op=0xC4 | op=0xD4 | op=0xE4 | op=0xF4) ... & OP1
|
|
{
|
|
A = A & OP1;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
|
|
:ASLA is op=0x48
|
|
{
|
|
C = A >> 7;
|
|
A = A << 1;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:ASLX is op=0x58
|
|
{
|
|
C = X >> 7;
|
|
X = X << 1;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:ASL OP1 is (op=0x38 | op=0x68 | op=0x78) ... & OP1
|
|
{
|
|
local tmp = OP1;
|
|
C = tmp >> 7;
|
|
tmp = tmp << 1;
|
|
OP1 = tmp;
|
|
Z = (tmp == 0);
|
|
N = (tmp s< 0);
|
|
}
|
|
:ASRA is op=0x47
|
|
{
|
|
C = A & 1;
|
|
A = A s>> 1;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:ASRX is op=0x57
|
|
{
|
|
C = X & 1;
|
|
X = X s>> 1;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:ASR OP1 is (op=0x37 | op=0x67 | op=0x77) ... & OP1
|
|
{
|
|
local tmp = OP1;
|
|
C = tmp & 1;
|
|
tmp = tmp s>> 1;
|
|
OP1 = tmp;
|
|
Z = (tmp == 0);
|
|
N = (tmp s< 0);
|
|
}
|
|
|
|
:BCC REL is op=0x24;REL
|
|
{
|
|
if (C == 0) goto REL;
|
|
}
|
|
|
|
:BCLR n,DIRECT is op4_7=1 & bit_0=1 & n; DIRECT {
|
|
local mask = ~(1 << n);
|
|
DIRECT = DIRECT & mask;
|
|
}
|
|
:BCS REL is op=0x25;REL
|
|
{
|
|
if (C) goto REL;
|
|
}
|
|
:BEQ REL is op=0x27;REL
|
|
{
|
|
if (Z) goto REL;
|
|
}
|
|
:BHCC REL is op=0x28;REL
|
|
{
|
|
if (H == 0) goto REL;
|
|
}
|
|
:BHCS REL is op=0x29;REL
|
|
{
|
|
if (H) goto REL;
|
|
}
|
|
:BHI REL is op=0x22;REL
|
|
{
|
|
local tmp = C + Z;
|
|
if (tmp == 0) goto REL;
|
|
}
|
|
|
|
#:BHS REL is op=0x24;REL See BCC
|
|
|
|
:BIH REL is op=0x2F;REL
|
|
{
|
|
tmp:1 = readIRQ();
|
|
if (tmp) goto REL;
|
|
}
|
|
:BIL REL is op=0x2E;REL
|
|
{
|
|
tmp:1 = readIRQ();
|
|
if (tmp == 0) goto REL;
|
|
}
|
|
:BIT OP1 is (op=0xA5 | op=0xB5 | op=0xC5 | op=0xD5 | op=0xE5 | op=0xF5) ... & OP1
|
|
{
|
|
local result = A & OP1;
|
|
Z = (result == 0);
|
|
N = (result s< 0);
|
|
}
|
|
#:BLO REL is op=0x25;REL see BCS
|
|
|
|
:BLS REL is op=0x23;REL
|
|
{
|
|
local tmp = C + Z;
|
|
if (tmp) goto REL;
|
|
}
|
|
|
|
:BMC REL is op=0x2C;REL
|
|
{
|
|
if (I == 0) goto REL;
|
|
}
|
|
:BMI REL is op=0x2B;REL
|
|
{
|
|
if (N) goto REL;
|
|
}
|
|
:BMS REL is op=0x2D;REL
|
|
{
|
|
if (I) goto REL;
|
|
}
|
|
:BNE REL is op=0x26;REL
|
|
{
|
|
if (Z == 0) goto REL;
|
|
}
|
|
:BPL REL is op=0x2A;REL
|
|
{
|
|
if (N == 0) goto REL;
|
|
}
|
|
:BRA REL is op=0x20;REL
|
|
{
|
|
goto REL;
|
|
}
|
|
|
|
:BRN REL is op=0x21;REL
|
|
{
|
|
}
|
|
|
|
:BRCLR n,DIRECT,REL is op4_7=0 & bit_0=1 & n; DIRECT; REL
|
|
{
|
|
local mask = (1 << n);
|
|
local result = DIRECT & mask;
|
|
if (result == 0) goto REL;
|
|
}
|
|
|
|
:BRSET n,DIRECT,REL is op4_7=0 & bit_0=0 & n; DIRECT; REL
|
|
{
|
|
local mask = (1 << n);
|
|
local result = DIRECT & mask;
|
|
if (result != 0) goto REL;
|
|
}
|
|
|
|
:BSET n,DIRECT is op4_7=1 & bit_0=0 & n; DIRECT {
|
|
local mask = (1 << n);
|
|
DIRECT = DIRECT | mask;
|
|
}
|
|
|
|
:BSR REL is op=0xAD; REL
|
|
{
|
|
SP=SP-1;
|
|
*:2 SP = inst_next;
|
|
SP=SP-1;
|
|
call REL;
|
|
}
|
|
|
|
:CLC is op=0x98
|
|
{
|
|
C = 0;
|
|
}
|
|
|
|
:CLI is op=0x9A
|
|
{
|
|
I = 0;
|
|
}
|
|
:CLRA is op=0x4F
|
|
{
|
|
A = 0;
|
|
Z = 1;
|
|
N = 0;
|
|
}
|
|
:CLRX is op=0x5F
|
|
{
|
|
X = 0;
|
|
Z = 1;
|
|
N = 0;
|
|
}
|
|
:CLR OP1 is (op=0x3F | op=0x6F | op=0x7F) ... & OP1
|
|
{
|
|
OP1 = 0;
|
|
Z = 1;
|
|
N = 0;
|
|
}
|
|
:CMP OP1 is (op=0xA1 | op=0xB1 | op=0xC1 | op=0xD1 | op=0xE1 | op=0xF1) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
local tmp = A - op1;
|
|
Z = tmp == 0;
|
|
N = tmp s< 0;
|
|
C = (A < op1);
|
|
}
|
|
|
|
:COMA is op=0x43
|
|
{
|
|
A = ~A;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
C = 1;
|
|
}
|
|
:COMX is op=0x53
|
|
{
|
|
X = ~X;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
C = 1;
|
|
}
|
|
:COM OP1 is (op=0x33 | op=0x63 | op=0x73) ... & OP1
|
|
{
|
|
local tmp = ~OP1;
|
|
OP1 = tmp;
|
|
Z = (tmp == 0);
|
|
N = (tmp s< 0);
|
|
C = 1;
|
|
}
|
|
:CPX OP1 is (op=0xA3 | op=0xB3 | op=0xC3 | op=0xD3 | op=0xE3 | op=0xF3) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
local tmp = X - op1;
|
|
Z = tmp == 0;
|
|
N = tmp s< 0;
|
|
C = (X < op1);
|
|
}
|
|
:DECA is op=0x4A
|
|
{
|
|
A = A - 1;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:DECX is op=0x5A
|
|
{
|
|
X = X - 1;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:DEC OP1 is (op=0x3A | op=0x6A | op=0x7A) ... & OP1
|
|
{
|
|
local tmp = OP1 - 1;
|
|
OP1 = tmp;
|
|
Z = (tmp == 0);
|
|
N = (tmp s< 0);
|
|
}
|
|
:EOR OP1 is (op=0xA8 | op=0xB8 | op=0xC8 | op=0xD8 | op=0xE8 | op=0xF8) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
A = A ^ op1;
|
|
Z = A == 0;
|
|
N = A s< 0;
|
|
}
|
|
:INCA is op=0x4C
|
|
{
|
|
A = A + 1;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:INCX is op=0x5C
|
|
{
|
|
X = X + 1;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:INC OP1 is (op=0x3C | op=0x6C | op=0x7C) ... & OP1
|
|
{
|
|
local tmp = OP1 + 1;
|
|
OP1 = tmp;
|
|
Z = (tmp == 0);
|
|
N = (tmp s< 0);
|
|
}
|
|
:JMP ADDR is (op=0xBC | op=0xCC) ... & ADDR
|
|
{
|
|
goto ADDR;
|
|
}
|
|
|
|
:JMP ADDRI is (op=0xDC | op=0xEC | op=0xFC) ... & ADDRI
|
|
{
|
|
goto [ADDRI];
|
|
}
|
|
|
|
|
|
:JSR ADDR is (op=0xBD | op=0xCD) ... & ADDR
|
|
{
|
|
*:2 (SP-1) = inst_next;
|
|
SP=SP-2;
|
|
call ADDR;
|
|
}
|
|
:JSR ADDRI is (op=0xDD | op=0xED | op=0xFD) ... & ADDRI
|
|
{
|
|
*:2 (SP-1) = inst_next;
|
|
SP=SP-2;
|
|
call [ADDRI];
|
|
}
|
|
|
|
:LDA OP1 is (op=0xA6 | op=0xB6 | op=0xC6 | op=0xD6 | op=0xE6 | op=0xF6) ... & OP1
|
|
{
|
|
A = OP1;
|
|
Z = A == 0;
|
|
N = A s< 0;
|
|
}
|
|
|
|
:LDX OP1 is (op=0xAE | op=0xBE | op=0xCE | op=0xDE | op=0xEE | op=0xFE) ... & OP1
|
|
{
|
|
X = OP1;
|
|
Z = X == 0;
|
|
N = X s< 0;
|
|
}
|
|
|
|
## Logical Shift left is same as arithmetic shift left
|
|
#:LSLA is op=0x48
|
|
#:LSLX is op=0x58
|
|
#:LSL OP1 is (op=0x38 | op=0x68 | op=0x78) ... & OP1
|
|
:LSRA is op=0x44
|
|
{
|
|
C = A & 1;
|
|
A = A >> 1;
|
|
Z = (A == 0);
|
|
N = 0;
|
|
}
|
|
:LSRX is op=0x54
|
|
{
|
|
C = X & 1;
|
|
X = X >> 1;
|
|
Z = (X == 0);
|
|
N = 0;
|
|
}
|
|
:LSR OP1 is (op=0x34 | op=0x64 | op=0x74) ... & OP1
|
|
{
|
|
local tmp = OP1;
|
|
C = tmp & 1;
|
|
tmp = tmp >> 1;
|
|
OP1 = tmp;
|
|
Z = (tmp == 0);
|
|
N = 0;
|
|
}
|
|
|
|
:MUL is op=0x42
|
|
{
|
|
op1:2 = zext(A);
|
|
op2:2 = zext(X);
|
|
local result = op1 * op2;
|
|
A = result:1;
|
|
result = result >> 8;
|
|
X = result:1;
|
|
}
|
|
|
|
:NEGA is op=0x40
|
|
{
|
|
C = A != 0;
|
|
A = -A;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:NEGX is op=0x50
|
|
{
|
|
C = X != 0;
|
|
X = -X;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:NEG OP1 is (op=0x30 | op=0x60 | op=0x70) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
C = op1 != 0;
|
|
OP1 = -op1;
|
|
Z = (op1 == 0);
|
|
N = (op1 s< 0);
|
|
}
|
|
|
|
:NOP is op = 0x9D
|
|
{
|
|
}
|
|
|
|
:ORA OP1 is (op=0xAA | op=0xBA | op=0xCA | op=0xDA | op=0xEA | op=0xFA) ... & OP1
|
|
{
|
|
A = A | OP1;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
|
|
:ROLA is op=0x49
|
|
{
|
|
local tmp = C ;
|
|
C = A >> 7;
|
|
A = A << 1;
|
|
A = A | tmp;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:ROLX is op=0x59
|
|
{
|
|
local tmp = C;
|
|
C = X >> 7;
|
|
X = X << 1;
|
|
X = X | tmp;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:ROL OP1 is (op=0x39 | op=0x69 | op=0x79) ... & OP1
|
|
{
|
|
local tmpC = C;
|
|
local op1 = OP1;
|
|
C = op1 >> 7;
|
|
local result = op1 << 1;
|
|
result = result | tmpC;
|
|
OP1 = result;
|
|
Z = (result == 0);
|
|
N = (result s< 0);
|
|
}
|
|
:RORA is op=0x46
|
|
{
|
|
local tmpC = C << 7;
|
|
C = A & 1;
|
|
A = A s>> 1;
|
|
A = A | tmpC;
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:RORX is op=0x56
|
|
{
|
|
local tmpC = C << 7;
|
|
C = X & 1;
|
|
X = X s>> 1;
|
|
X = X | tmpC;
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:ROR OP1 is (op=0x36 | op=0x66 | op=0x76) ... & OP1
|
|
{
|
|
local tmpC = C << 7;
|
|
local tmp = OP1;
|
|
C = tmp & 1;
|
|
tmp = tmp s>> 1;
|
|
tmp = tmp | tmpC;
|
|
OP1 = tmp;
|
|
Z = (tmp == 0);
|
|
N = (tmp s< 0);
|
|
}
|
|
|
|
:RSP is op = 0x9C
|
|
{
|
|
SP = 0xff;
|
|
}
|
|
|
|
:RTI is op = 0x80
|
|
{
|
|
SP = SP+1;
|
|
local ccr = *:1 SP;
|
|
H = ccr[4,1];
|
|
I = ccr[3,1];
|
|
N = ccr[2,1];
|
|
Z = ccr[1,1];
|
|
C = ccr[0,1];
|
|
|
|
SP = SP+1;
|
|
A = *:1 SP;
|
|
|
|
SP = SP+1;
|
|
X = *:1 SP;
|
|
SP = SP+1;
|
|
tmp:2 = *:2 SP;
|
|
SP = SP+1;
|
|
|
|
return [tmp];
|
|
}
|
|
|
|
:RTS is op = 0x81
|
|
{
|
|
SP = SP+1;
|
|
tmp:2 = *:2 SP;
|
|
SP = SP+1;
|
|
|
|
return [tmp];
|
|
}
|
|
|
|
:SBC OP1 is (op=0xA2 | op=0xB2 | op=0xC2 | op=0xD2 | op=0xE2 | op=0xF2) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
local tmp = A - op1 - C;
|
|
Z = tmp == 0;
|
|
N = tmp s< 0;
|
|
C = ((A <= op1) * C) | (A < op1);
|
|
A = tmp;
|
|
}
|
|
|
|
:SEC is op = 0x99
|
|
{
|
|
C = 1;
|
|
}
|
|
|
|
:SEI is op = 0x9B
|
|
{
|
|
I = 1;
|
|
}
|
|
|
|
:STA OP1 is (op=0xB7 | op=0xC7 | op=0xD7 | op=0xE7 | op=0xF7) ... & OP1
|
|
{
|
|
OP1 = A;
|
|
Z = A == 0;
|
|
N = A s< 0;
|
|
}
|
|
|
|
:STOP is op=0x8E
|
|
{
|
|
I = 0;
|
|
}
|
|
|
|
:STX OP1 is (op=0xBF | op=0xCF | op=0xDF | op=0xEF | op=0xFF) ... & OP1
|
|
{
|
|
OP1 = X;
|
|
Z = X == 0;
|
|
N = X s< 0;
|
|
}
|
|
|
|
:SUB OP1 is (op=0xA0 | op=0xB0 | op=0xC0 | op=0xD0 | op=0xE0 | op=0xF0) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
C = (A < op1);
|
|
A = A - op1;
|
|
Z = A == 0;
|
|
N = A s< 0;
|
|
A = A;
|
|
}
|
|
|
|
:SWI is op=0x83
|
|
{
|
|
SP=SP-1;
|
|
*:2 SP = inst_next;
|
|
SP=SP-1;
|
|
*:1 SP = X;
|
|
SP=SP-1;
|
|
*:1 SP = A;
|
|
tmp:1 = 0b11100000 | (H << 4) | (I << 3) | (N << 2) | ( Z << 1) | C;
|
|
SP=SP-1;
|
|
*:1 SP = tmp;
|
|
I = 1;
|
|
call [SWI_VECTOR];
|
|
}
|
|
|
|
:TAX is op=0x97
|
|
{
|
|
X = A;
|
|
}
|
|
|
|
:TSTA is op=0x4D
|
|
{
|
|
Z = (A == 0);
|
|
N = (A s< 0);
|
|
}
|
|
:TSTX is op=0x5D
|
|
{
|
|
Z = (X == 0);
|
|
N = (X s< 0);
|
|
}
|
|
:TST OP1 is (op=0x3D | op=0x6D | op=0x7D) ... & OP1
|
|
{
|
|
local op1 = OP1;
|
|
Z = (op1 == 0);
|
|
N = (op1 s< 0);
|
|
}
|
|
|
|
:TXA is op=0x9F
|
|
{
|
|
A = X;
|
|
}
|
|
|
|
:WAIT is op=0x8f
|
|
{
|
|
I = 0;
|
|
}
|
|
|