remake assembler with customasm, misc, need to clean up
This commit is contained in:
parent
717a9d9b08
commit
7aa99412ba
5
arch-8608-template.asm
Normal file
5
arch-8608-template.asm
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua)
|
||||
#ruledef {
|
||||
%s
|
||||
}
|
792
arch-8608.asm
Normal file
792
arch-8608.asm
Normal file
@ -0,0 +1,792 @@
|
||||
|
||||
; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua)
|
||||
#ruledef {
|
||||
rst => $00
|
||||
hlt => $F0
|
||||
run => $F1
|
||||
int => $F2
|
||||
brk => $F3
|
||||
irt => $F4
|
||||
nop => $FF
|
||||
ien => $F5
|
||||
idi => $F6
|
||||
inc p => $12
|
||||
dec p => $15
|
||||
inc q => $13
|
||||
dec q => $16
|
||||
inc a => $10
|
||||
dec a => $11
|
||||
icc a => $1B
|
||||
inc b => $19
|
||||
dec b => $1A
|
||||
icc b => $1C
|
||||
inc c => $17
|
||||
dec c => $18
|
||||
icc c => $1D
|
||||
tst a => $14
|
||||
tst b => $1E
|
||||
tst c => $1F
|
||||
inc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$2B @ value`8
|
||||
}
|
||||
inc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$2B @ mvalue`8
|
||||
}
|
||||
dec *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$2C @ value`8
|
||||
}
|
||||
dec *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$2C @ mvalue`8
|
||||
}
|
||||
icc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$2D @ value`8
|
||||
}
|
||||
icc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$2D @ mvalue`8
|
||||
}
|
||||
tst *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$2E @ value`8
|
||||
}
|
||||
tst *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$2E @ mvalue`8
|
||||
}
|
||||
adp {value: i8} => $4A @ value
|
||||
adq {value: i8} => $4B @ value
|
||||
ads {value: i8} => $4C @ value
|
||||
adp b => $E6
|
||||
adq b => $E7
|
||||
ads b => $E8
|
||||
add {value: i8} => $24 @ value
|
||||
adb {value: i8} => $72 @ value
|
||||
adc {value: i8} => $73 @ value
|
||||
sub {value: i8} => $70 @ value
|
||||
sbb {value: i8} => $99 @ value
|
||||
sbc {value: i8} => $9A @ value
|
||||
acc {value: i8} => $78 @ value
|
||||
scc {value: i8} => $79 @ value
|
||||
cmp {value: i8} => $71 @ value
|
||||
and {value: i8} => $74 @ value
|
||||
ior {value: i8} => $75 @ value
|
||||
xor {value: i8} => $76 @ value
|
||||
ann {value: i8} => $77 @ value
|
||||
shl {value: i8} => $D0 @ value
|
||||
shr {value: i8} => $D1 @ value
|
||||
rol {value: i8} => $D2 @ value
|
||||
ror {value: i8} => $D3 @ value
|
||||
sra {value: i8} => $D4 @ value
|
||||
add *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$AE @ value`8
|
||||
}
|
||||
add *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$AE @ mvalue`8
|
||||
}
|
||||
adb *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$9B @ value`8
|
||||
}
|
||||
adb *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$9B @ mvalue`8
|
||||
}
|
||||
adc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$9C @ value`8
|
||||
}
|
||||
adc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$9C @ mvalue`8
|
||||
}
|
||||
sub *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$AF @ value`8
|
||||
}
|
||||
sub *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$AF @ mvalue`8
|
||||
}
|
||||
sbb *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$9D @ value`8
|
||||
}
|
||||
sbb *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$9D @ mvalue`8
|
||||
}
|
||||
sbc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$9E @ value`8
|
||||
}
|
||||
sbc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$9E @ mvalue`8
|
||||
}
|
||||
acc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$B5 @ value`8
|
||||
}
|
||||
acc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$B5 @ mvalue`8
|
||||
}
|
||||
scc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$B7 @ value`8
|
||||
}
|
||||
scc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$B7 @ mvalue`8
|
||||
}
|
||||
cmp *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$B0 @ value`8
|
||||
}
|
||||
cmp *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$B0 @ mvalue`8
|
||||
}
|
||||
and *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$B1 @ value`8
|
||||
}
|
||||
and *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$B1 @ mvalue`8
|
||||
}
|
||||
ior *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$B2 @ value`8
|
||||
}
|
||||
ior *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$B2 @ mvalue`8
|
||||
}
|
||||
xor *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$B3 @ value`8
|
||||
}
|
||||
xor *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$B3 @ mvalue`8
|
||||
}
|
||||
ann *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$B4 @ value`8
|
||||
}
|
||||
ann *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$B4 @ mvalue`8
|
||||
}
|
||||
shl *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$D5 @ value`8
|
||||
}
|
||||
shl *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$D5 @ mvalue`8
|
||||
}
|
||||
shr *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$D6 @ value`8
|
||||
}
|
||||
shr *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$D6 @ mvalue`8
|
||||
}
|
||||
rol *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$D7 @ value`8
|
||||
}
|
||||
rol *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$D7 @ mvalue`8
|
||||
}
|
||||
ror *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$D8 @ value`8
|
||||
}
|
||||
ror *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$D8 @ mvalue`8
|
||||
}
|
||||
sra *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$D9 @ value`8
|
||||
}
|
||||
sra *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$D9 @ mvalue`8
|
||||
}
|
||||
add b => $A0
|
||||
adc b => $9F
|
||||
sub b => $A1
|
||||
sbc b => $B6
|
||||
acc b => $B8
|
||||
scc b => $B9
|
||||
cmp b => $A2
|
||||
and b => $A3
|
||||
ior b => $A4
|
||||
xor b => $A5
|
||||
ann b => $A6
|
||||
shl b => $DA
|
||||
shr b => $DB
|
||||
rol b => $DC
|
||||
ror b => $DD
|
||||
sra b => $DE
|
||||
add c => $A7
|
||||
adb c => $BD
|
||||
sub c => $A8
|
||||
sbb c => $BC
|
||||
acc c => $BA
|
||||
scc c => $BB
|
||||
cmp c => $A9
|
||||
and c => $AA
|
||||
ior c => $AB
|
||||
xor c => $AC
|
||||
ann c => $AD
|
||||
shl c => $DF
|
||||
shr c => $4D
|
||||
rol c => $3E
|
||||
ror c => $3F
|
||||
sra c => $2F
|
||||
adb a => $BE
|
||||
sbb a => $BF
|
||||
adc a => $4E
|
||||
sbc a => $4F
|
||||
jmp {value: i16} => $60 @ value
|
||||
jsr {value: i16} => $63 @ value
|
||||
jss {value: i16} => $E2 @ value
|
||||
jmp p => $64
|
||||
jmp q => $66
|
||||
ret => $66
|
||||
jsr p => $65
|
||||
jsr q => $67
|
||||
jss p => $E4
|
||||
jss q => $E5
|
||||
rts => $E1
|
||||
jpr {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jpr: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jpr: Relative jump target is too far away")
|
||||
$31 @ reladdr`8
|
||||
}
|
||||
jnz {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jnz: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jnz: Relative jump target is too far away")
|
||||
$30 @ reladdr`8
|
||||
}
|
||||
jne {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jne: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jne: Relative jump target is too far away")
|
||||
$30 @ reladdr`8
|
||||
}
|
||||
jpz {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jpz: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jpz: Relative jump target is too far away")
|
||||
$32 @ reladdr`8
|
||||
}
|
||||
jeq {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jeq: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jeq: Relative jump target is too far away")
|
||||
$32 @ reladdr`8
|
||||
}
|
||||
jlt {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jlt: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jlt: Relative jump target is too far away")
|
||||
$33 @ reladdr`8
|
||||
}
|
||||
jge {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jge: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jge: Relative jump target is too far away")
|
||||
$34 @ reladdr`8
|
||||
}
|
||||
jgt {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jgt: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jgt: Relative jump target is too far away")
|
||||
$35 @ reladdr`8
|
||||
}
|
||||
jle {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "jle: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "jle: Relative jump target is too far away")
|
||||
$36 @ reladdr`8
|
||||
}
|
||||
psh a => $40
|
||||
psh b => $44
|
||||
psh c => $45
|
||||
psh f => $E9
|
||||
psh p => $41
|
||||
psh q => $46
|
||||
pop a => $42
|
||||
pop b => $47
|
||||
pop c => $48
|
||||
pop f => $EA
|
||||
pop p => $43
|
||||
pop q => $49
|
||||
psh {value: i8} => $3B @ value
|
||||
phw {value: i16} => $3C @ value
|
||||
lda {value: i8} => $20 @ value
|
||||
ldb {value: i8} => $26 @ value
|
||||
ldc {value: i8} => $27 @ value
|
||||
lda *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$28 @ value`8
|
||||
}
|
||||
lda *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$28 @ mvalue`8
|
||||
}
|
||||
ldb *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$29 @ value`8
|
||||
}
|
||||
ldb *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$29 @ mvalue`8
|
||||
}
|
||||
ldc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$2A @ value`8
|
||||
}
|
||||
ldc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$2A @ mvalue`8
|
||||
}
|
||||
sta *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$96 @ value`8
|
||||
}
|
||||
sta *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$96 @ mvalue`8
|
||||
}
|
||||
stb *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$97 @ value`8
|
||||
}
|
||||
stb *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$97 @ mvalue`8
|
||||
}
|
||||
stc *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$98 @ value`8
|
||||
}
|
||||
stc *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$98 @ mvalue`8
|
||||
}
|
||||
lda *{value: i16} => $51 @ value
|
||||
ldb *{value: i16} => $56 @ value
|
||||
ldc *{value: i16} => $57 @ value
|
||||
sta *{value: i16} => $50 @ value
|
||||
stb *{value: i16} => $58 @ value
|
||||
stc *{value: i16} => $59 @ value
|
||||
lda *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$01 @ value`16
|
||||
}
|
||||
lda *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$01 @ mvalue`16
|
||||
}
|
||||
ldb *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$F7 @ value`16
|
||||
}
|
||||
ldb *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$F7 @ mvalue`16
|
||||
}
|
||||
ldc *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$FE @ value`16
|
||||
}
|
||||
ldc *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$FE @ mvalue`16
|
||||
}
|
||||
lda *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$EB @ value`16
|
||||
}
|
||||
lda *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$EB @ mvalue`16
|
||||
}
|
||||
ldb *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$08 @ value`16
|
||||
}
|
||||
ldb *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$08 @ mvalue`16
|
||||
}
|
||||
ldc *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$09 @ value`16
|
||||
}
|
||||
ldc *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$09 @ mvalue`16
|
||||
}
|
||||
sta *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$0A @ value`16
|
||||
}
|
||||
sta *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$0A @ mvalue`16
|
||||
}
|
||||
stb *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$0B @ value`16
|
||||
}
|
||||
stb *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$0B @ mvalue`16
|
||||
}
|
||||
stc *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$0C @ value`16
|
||||
}
|
||||
stc *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$0C @ mvalue`16
|
||||
}
|
||||
sta *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$0D @ value`16
|
||||
}
|
||||
sta *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$0D @ mvalue`16
|
||||
}
|
||||
stb *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$0E @ value`16
|
||||
}
|
||||
stb *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$0E @ mvalue`16
|
||||
}
|
||||
stc *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$0F @ value`16
|
||||
}
|
||||
stc *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$0F @ mvalue`16
|
||||
}
|
||||
lda *p => $53
|
||||
ldb *p => $5E
|
||||
ldc *p => $5F
|
||||
lda *q => $55
|
||||
ldb *q => $61
|
||||
ldc *q => $62
|
||||
sta *p => $52
|
||||
stb *p => $5A
|
||||
stc *p => $5B
|
||||
sta *q => $54
|
||||
stb *q => $5C
|
||||
stc *q => $5D
|
||||
lda *p++ => $C6
|
||||
ldb *p++ => $C7
|
||||
ldc *p++ => $C8
|
||||
lda *q++ => $C9
|
||||
ldb *q++ => $CA
|
||||
ldc *q++ => $CB
|
||||
sta *p++ => $C0
|
||||
stb *p++ => $C1
|
||||
stc *p++ => $C2
|
||||
sta *q++ => $C3
|
||||
stb *q++ => $C4
|
||||
stc *q++ => $C5
|
||||
ldp {value: i16} => $21 @ value
|
||||
ldq {value: i16} => $23 @ value
|
||||
lds {value: i16} => $25 @ value
|
||||
ldv {value: i16} => $22 @ value
|
||||
ldp *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$7A @ value`8
|
||||
}
|
||||
ldp *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$7A @ mvalue`8
|
||||
}
|
||||
ldq *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$7B @ value`8
|
||||
}
|
||||
ldq *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$7B @ mvalue`8
|
||||
}
|
||||
stp *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$7E @ value`8
|
||||
}
|
||||
stp *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$7E @ mvalue`8
|
||||
}
|
||||
stq *s+{value: i8} => {
|
||||
assert(value <= 127, "Relative address is too far away")
|
||||
assert(value >= -128, "Relative address is too far away")
|
||||
$7F @ value`8
|
||||
}
|
||||
stq *s-{value: i8} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 127, "Relative address is too far away")
|
||||
assert(mvalue >= -128, "Relative address is too far away")
|
||||
$7F @ mvalue`8
|
||||
}
|
||||
ldp *{value: i16} => $68 @ value
|
||||
ldq *{value: i16} => $6A @ value
|
||||
stp *{value: i16} => $6C @ value
|
||||
stq *{value: i16} => $6E @ value
|
||||
ldp *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$EC @ value`16
|
||||
}
|
||||
ldp *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$EC @ mvalue`16
|
||||
}
|
||||
ldq *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$EE @ value`16
|
||||
}
|
||||
ldq *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$EE @ mvalue`16
|
||||
}
|
||||
ldp *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$F8 @ value`16
|
||||
}
|
||||
ldp *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$F8 @ mvalue`16
|
||||
}
|
||||
ldq *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$FA @ value`16
|
||||
}
|
||||
ldq *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$FA @ mvalue`16
|
||||
}
|
||||
stq *p+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$06 @ value`16
|
||||
}
|
||||
stq *p-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$06 @ mvalue`16
|
||||
}
|
||||
stp *q+{value: i16} => {
|
||||
assert(value <= 32767, "Relative address is too far away")
|
||||
assert(value >= -32768, "Relative address is too far away")
|
||||
$FC @ value`16
|
||||
}
|
||||
stp *q-{value: i16} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= 32767, "Relative address is too far away")
|
||||
assert(mvalue >= -32768, "Relative address is too far away")
|
||||
$FC @ mvalue`16
|
||||
}
|
||||
ldp *p => $92
|
||||
ldq *p => $93
|
||||
ldp *q => $94
|
||||
ldq *q => $95
|
||||
stp *q => $7C
|
||||
stq *p => $7D
|
||||
ldq *p++ => $CC
|
||||
ldp *q++ => $CD
|
||||
stp *q++ => $CE
|
||||
stq *p++ => $CF
|
||||
lda b => $80
|
||||
lda c => $81
|
||||
ldb a => $82
|
||||
ldb c => $83
|
||||
ldc a => $84
|
||||
ldc b => $85
|
||||
lda pl => $86
|
||||
lda ph => $87
|
||||
lda ql => $88
|
||||
lda qh => $89
|
||||
ldb pl => $37
|
||||
ldc ph => $38
|
||||
ldb ql => $39
|
||||
ldc qh => $3A
|
||||
ldp q => $8A
|
||||
ldp s => $8B
|
||||
ldp v => $8C
|
||||
ldp i => $8D
|
||||
ldp cb => $91
|
||||
ldq cb => $E0
|
||||
ldq p => $8E
|
||||
lds p => $8F
|
||||
ldv p => $90
|
||||
}
|
723
assembler-8608-deprecated.lua
Normal file
723
assembler-8608-deprecated.lua
Normal file
@ -0,0 +1,723 @@
|
||||
|
||||
local function loadutf8table(fn)
|
||||
local tt = {}
|
||||
for l in io.lines(fn) do if l~="" then
|
||||
local c, d = l:match("^([^ ]+) (.+)$")
|
||||
local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end;
|
||||
tt[c] = t
|
||||
end end
|
||||
return tt
|
||||
end
|
||||
local utf8table = loadutf8table((RelPath or "./").."utf8table.txt")
|
||||
|
||||
local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end
|
||||
local function getutf8len(c)
|
||||
local d = c:byte()
|
||||
if bit.band(d, 0xE0)==0xC0 then return 2
|
||||
elseif bit.band(d, 0xF0)==0xE0 then return 3
|
||||
elseif bit.band(d, 0xF8)==0xF0 then return 4
|
||||
else error("invalid utf8 first byte: "..string.format("%02X", d)) end
|
||||
end
|
||||
local function validWordsFromInstrs(instrs)
|
||||
local words = {}
|
||||
for mnem, _ in pairs(instrs) do
|
||||
for word in mnem:gmatch("[^ ]+") do
|
||||
words[word] = true
|
||||
end
|
||||
end
|
||||
return words
|
||||
end
|
||||
local function lobyte(n) return n%256 end
|
||||
local function hibyte(n) return math.floor(n/256) end
|
||||
local function decodeNumber(n)
|
||||
n = trim(n)
|
||||
local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end;
|
||||
if n:sub(1, 1)=="$" then return sign*(tonumber(n:sub(2, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
|
||||
elseif n:sub(1, 2)=="0x" then return sign*(tonumber(n:sub(3, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-2)/2)
|
||||
elseif n:sub(#n, #n)=="h" and n:find("^[0-9a-fA-F]+h$") then return sign*(tonumber(n:sub(1, #n-1), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
|
||||
elseif n:sub(1, 2)=="0b" then return sign*(tonumber(n:sub(3, #n ), 2) or error("invalid binary number "..n)), math.ceil((#n-2)/8)
|
||||
elseif n:sub(#n, #n)=="b" and n:find("^[01]+b$") then return sign*(tonumber(n:sub(1, #n-1), 2) or error("invalid binary number "..n)), math.ceil((#n-1)/8)
|
||||
elseif n:sub(1, 3)=="lo(" and n:sub(#n, #n)==")" then return lobyte(decodeNumber(n:sub(4, #n-1))), 1
|
||||
elseif n:sub(1, 3)=="hi(" and n:sub(#n, #n)==")" then return hibyte(decodeNumber(n:sub(4, #n-1))), 1
|
||||
elseif n:find("^[0-9]+$") then
|
||||
local v = sign*(tonumber(n) or error("invalid decimal number "..n))
|
||||
if v>=-128 and v<=255 then return v, 1
|
||||
elseif v>=-32768 and v<=65535 then return v, 2
|
||||
else error("out-of-range number "..v) end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
local function mnemFromLine(line, instrs, validWords)
|
||||
local imms = {}
|
||||
local function addNum(n)
|
||||
n = trim(n)
|
||||
local val, len = decodeNumber(n)
|
||||
assert(val and len, "invalid number "..n)
|
||||
local linei8 = line:gsub(n, "imm8", 1, true):lower()
|
||||
local linei16 = line:gsub(n, "imm16", 1, true):lower()
|
||||
if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end
|
||||
table.insert(imms, { val = val, len = len } )
|
||||
return " imm"..(len*8).." "
|
||||
end
|
||||
local function addLabel(n)
|
||||
n = trim(n)
|
||||
local len = 2
|
||||
local linei8 = line:gsub(n, "imm8", 1, true):lower()
|
||||
if instrs[linei8] then len = 1 end
|
||||
table.insert(imms, { label = n, len = len } )
|
||||
return " imm"..(len*8).." "
|
||||
end
|
||||
|
||||
local mnem = " "..line:gsub(" ", " ").." "
|
||||
mnem = mnem:gsub("%- *", " %+%-")
|
||||
mnem = mnem:gsub("([%*%+])", " %1 ")
|
||||
mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ " , function(n) return addNum (n) end)
|
||||
mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ " , function(n) return addNum (n) end)
|
||||
mnem = mnem:gsub(" %-?0b[01]+ " , function(n) return addNum (n) end)
|
||||
mnem = mnem:gsub(" %-?[0-9a-fA-F]+h " , function(n) if not validWords[trim(n)] then return addNum (n) end end)
|
||||
mnem = mnem:gsub(" %-?[01]+b " , function(n) if not validWords[trim(n)] then return addNum (n) end end)
|
||||
mnem = mnem:gsub(" %-?[0-9]+ " , function(n) if not validWords[trim(n)] then return addNum (n) end end)
|
||||
mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end)
|
||||
mnem = trim(mnem):gsub(" +", " "):lower()
|
||||
|
||||
if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end
|
||||
|
||||
return mnem, imms
|
||||
end
|
||||
local function addByte(state, val, code)
|
||||
assert(val>=-128 and val<=255, "invalid byte "..val)
|
||||
assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
|
||||
state.memory[state.curAddr] = val%256
|
||||
if code then state.codeMap[state.curAddr] = true end
|
||||
state.curAddr = state.curAddr + 1
|
||||
end
|
||||
local function addWord(state, val, code)
|
||||
assert(val>=0 and val<=65535, "invalid word "..val)
|
||||
addByte(state, math.floor(val/256), code)
|
||||
addByte(state, val%256, code)
|
||||
end
|
||||
local function addSpace(state, len)
|
||||
for i = 1, len do
|
||||
assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
|
||||
state.memory[state.curAddr] = false
|
||||
state.curAddr = state.curAddr + 1
|
||||
end
|
||||
end
|
||||
local function assembleInstruction(line, state, instrs, validWords)
|
||||
local mnem, imms = mnemFromLine(line, instrs, validWords)
|
||||
local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")")
|
||||
local writeimms = true
|
||||
local padlen = 0
|
||||
local isInstr
|
||||
if type(opcode)=="function" then
|
||||
padlen, writeimms = opcode(imms)
|
||||
addSpace(state, padlen)
|
||||
elseif opcode>=0 then
|
||||
isInstr = true
|
||||
addByte(state, opcode, isInstr)
|
||||
end
|
||||
if writeimms then
|
||||
for _, imm in ipairs(imms) do
|
||||
if imm.val then
|
||||
if imm.len==1 then addByte(state, imm.val, isInstr)
|
||||
elseif imm.len==2 then addWord(state, imm.val, isInstr)
|
||||
else error("invalid imm len") end
|
||||
elseif imm.label then
|
||||
table.insert(state.labelReplacements, {
|
||||
name = imm.label,
|
||||
addr = state.curAddr,
|
||||
len = imm.len,
|
||||
rel = imm.len==1,
|
||||
isCode = isInstr,
|
||||
})
|
||||
state.curAddr = state.curAddr + imm.len
|
||||
else error("invalid imm") end
|
||||
end
|
||||
end
|
||||
end
|
||||
local directiveFunctions = {
|
||||
fn = function(state, fn) state.fileName = fn end,
|
||||
ln = function(state, ln) state.lineNum = tonumber(ln) end,
|
||||
org = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end,
|
||||
align = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end,
|
||||
define = true,
|
||||
space = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end,
|
||||
}
|
||||
local function postEvaluateExpression(expr, labels)
|
||||
|
||||
end
|
||||
local function assembleCode(code, instrs, uexprs)
|
||||
local validWords = validWordsFromInstrs(instrs)
|
||||
|
||||
local state = {
|
||||
lineNum = 0,
|
||||
fileName = "",
|
||||
curAddr = 0,
|
||||
memory = {},
|
||||
codeMap = {},
|
||||
labelReplacements = {},
|
||||
labelAddrs = {},
|
||||
}
|
||||
|
||||
for line in code:gmatch("[^\n]+") do
|
||||
line = trim(line)
|
||||
if line:sub(1, 1)=="." then -- directive
|
||||
local dir, rest = line:match("^%.([^ ]+) *(.*)$")
|
||||
assert(dir and rest, "no directive on line "..line)
|
||||
local dirf = directiveFunctions[dir] or error("invalid directive "..dir)
|
||||
dirf(state, rest)
|
||||
elseif line:sub(#line, #line)==":" then -- label
|
||||
local name = line:sub(1, #line-1)
|
||||
assert(not state.labelAddrs[name], "redefinition of label "..name)
|
||||
state.labelAddrs[name] = state.curAddr
|
||||
elseif line:find("[^ ]") then
|
||||
assembleInstruction(line, state, instrs, validWords)
|
||||
end
|
||||
end
|
||||
|
||||
for _, rep in ipairs(state.labelReplacements) do
|
||||
local expr = uexprs[rep.name]
|
||||
if expr then
|
||||
local val = postEvaluateExpression(expr, state.labelAddrs)
|
||||
if rep.len==1 then addByte(state, val, rep.isCode)
|
||||
elseif rep.len==2 then addWord(state, val, rep.isCode)
|
||||
else error("invalid expr replace len "..rep.len) end
|
||||
else
|
||||
local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name)
|
||||
state.curAddr = rep.addr
|
||||
if rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode)
|
||||
elseif rep.len==2 then addWord(state, labelAddr , rep.isCode)
|
||||
else error("invalid labelreplace len "..rep.len) end
|
||||
end
|
||||
end
|
||||
|
||||
return state.memory, state.codeMap
|
||||
end
|
||||
|
||||
local function readFile(fn)
|
||||
local fi, err = io.open(fn, "r")
|
||||
if not fi then error("could not open file "..fn..": "..err) end
|
||||
local text = fi:read("*a")
|
||||
fi:close()
|
||||
return text
|
||||
end
|
||||
|
||||
local function separateCommas(l)
|
||||
local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c;
|
||||
end
|
||||
local function evaluateExpression(expr, uexprs)
|
||||
expr = expr:gsub("[^%+%-%*%/]+", function(word)
|
||||
local val = decodeNumber(word) or error("invalid number in expression: "..word)
|
||||
return val
|
||||
end)
|
||||
assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr)
|
||||
local exprf = loadstring("return "..expr)
|
||||
local eval = exprf() or error("invalid expr: "..expr)
|
||||
return eval
|
||||
end
|
||||
local function preprocessCode(code)
|
||||
code = "\n"..code.."\n"
|
||||
|
||||
-- apply brace labels and scoped labels
|
||||
local curscope = ""
|
||||
local codet = {}
|
||||
local wordt = {}
|
||||
local lastword = ""
|
||||
local function addword(word)
|
||||
lastword = word
|
||||
if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end
|
||||
table.insert(codet, word)
|
||||
end
|
||||
for i = 1, #code do
|
||||
local c = code:sub(i, i)
|
||||
if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c)
|
||||
else
|
||||
if #wordt>0 then
|
||||
addword(table.concat(wordt))
|
||||
wordt = {}
|
||||
end
|
||||
if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then
|
||||
curscope = lastword
|
||||
end
|
||||
table.insert(codet, c)
|
||||
end
|
||||
end
|
||||
|
||||
code = "\n"..table.concat(codet).."\n"
|
||||
|
||||
-- apply function macros
|
||||
local funcmacros = {}
|
||||
code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl)
|
||||
local argt = separateCommas(args)
|
||||
for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end
|
||||
repl = " "..repl.." "
|
||||
local invoc = 0
|
||||
funcmacros[name] = function(b, callargs)
|
||||
invoc = invoc + 1
|
||||
local callargt = separateCommas(callargs)
|
||||
local callrepl = repl
|
||||
for argidx, arg in ipairs(argt) do
|
||||
local callarg = callargt[argidx]
|
||||
callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2")
|
||||
end
|
||||
callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_")
|
||||
return b..callrepl
|
||||
end
|
||||
return ""
|
||||
end)
|
||||
for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end
|
||||
|
||||
-- apply simple macros
|
||||
local simplemacros = {}
|
||||
code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl)
|
||||
assert(not simplemacros[name], "Redefinition of macro "..name)
|
||||
simplemacros[name] = repl
|
||||
return ""
|
||||
end)
|
||||
--for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end
|
||||
for name, repl in pairs(simplemacros) do
|
||||
local invoc = 0
|
||||
code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a)
|
||||
invoc = invoc+1
|
||||
return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a
|
||||
end)
|
||||
print(name, code)
|
||||
end
|
||||
|
||||
code = code:gsub("\\\\", "\n")
|
||||
|
||||
local uexprs = {}
|
||||
|
||||
local codet = {}
|
||||
local exprt = {}
|
||||
local parenLevel = 0
|
||||
for i = 1, #code do
|
||||
local c = code:sub(i, i)
|
||||
if c=="(" then
|
||||
if parenLevel>0 then table.insert(exprt, c) end
|
||||
parenLevel = parenLevel+1
|
||||
elseif c==")" then
|
||||
parenLevel = parenLevel-1
|
||||
if parenLevel==0 then
|
||||
table.insert(codet, evaluateExpression(table.concat(exprt), uexprs))
|
||||
exprt = {}
|
||||
else
|
||||
table.insert(exprt, c)
|
||||
end
|
||||
else
|
||||
if parenLevel==0 then table.insert(codet, c)
|
||||
else table.insert(exprt, c) end
|
||||
end
|
||||
end
|
||||
code = table.concat(codet)
|
||||
|
||||
return code, uexprs
|
||||
end
|
||||
local function fixCode(code)
|
||||
code = code:gsub(",", " ")
|
||||
code = code:gsub(":([^\\/])", ":\n%1")
|
||||
code = code:gsub("[ \t]+:", ":")
|
||||
code = code:gsub("%]", " %] ")
|
||||
code = code:gsub("%[", " %[ ")
|
||||
code = code:gsub("%*", " %* ")
|
||||
code = code:gsub("\n[ \t\r\n]*", "\n")
|
||||
code = code:gsub(" +", " ")
|
||||
|
||||
return code
|
||||
end
|
||||
local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", }
|
||||
local prefixIdx = 0
|
||||
local function prefixCode(code, fn) -- fix strings, add line numbers
|
||||
prefixIdx = prefixIdx + 1
|
||||
|
||||
local outt = {}
|
||||
local outnextnl = {}
|
||||
local linenum = 1
|
||||
local skipnl = false
|
||||
local function last() return outt[#outt] end
|
||||
local function out(c) assert(type(c)=="string"); table.insert(outt, c); end
|
||||
local function outn(n) out("$"..string.format("%02X", n)) out("\\") end
|
||||
local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end
|
||||
local state = "code" -- code, comment, string, stringesc, commentml
|
||||
|
||||
local lastbracelabel = 0
|
||||
local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end
|
||||
local bracestack = {}
|
||||
local bracehasmid = {}
|
||||
local lastnl = false
|
||||
|
||||
local utf8str = ""
|
||||
local utf8len = 0
|
||||
|
||||
local function newline()
|
||||
lastnl = true
|
||||
for _, v in ipairs(outnextnl) do
|
||||
if v=="\n" and skipnl then out("\\")
|
||||
else out(v) end
|
||||
end; outnextnl = {};
|
||||
end
|
||||
|
||||
out(".ln 1"); out("\n");
|
||||
local i = 1
|
||||
while i <= #code do
|
||||
local c = code:sub(i, i)
|
||||
local cn = code:sub(i+1, i+1)
|
||||
local cp = code:sub(i-1, i-1)
|
||||
|
||||
if state=="code" then
|
||||
if c=="\r" then
|
||||
elseif c=="\n" then -- (c=="/" and cn~="/" and cn~="*")
|
||||
linenum = linenum+1
|
||||
if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end
|
||||
newline()
|
||||
skipnl = false
|
||||
elseif c=="#" or c==";" or (c=="/" and cn=="/") then state = "comment"
|
||||
elseif c=="/" and cn=="*" then state = "commentml"
|
||||
elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end
|
||||
elseif c=="\"" then state = "string" lastnl = false
|
||||
elseif c=="\\" then skipnl = true; out("\\");
|
||||
elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true;
|
||||
elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false
|
||||
elseif c=="{" then
|
||||
table.insert(bracestack, bracelabel())
|
||||
if not lastnl then out(bracestack[#bracestack].."MID") end
|
||||
outnext(bracestack[#bracestack].."START:"); outnext("\n");
|
||||
elseif c=="}" then
|
||||
if not lastnl then out(bracestack[#bracestack].."START") end
|
||||
if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end
|
||||
outnext(bracestack[#bracestack].."END:"); outnext("\n");
|
||||
bracehasmid[#bracestack] = nil
|
||||
bracestack[#bracestack] = nil
|
||||
elseif c=="|" then
|
||||
if not lastnl then out(bracestack[#bracestack].."END") end
|
||||
outnext(bracestack[#bracestack].."MID:"); outnext("\n");
|
||||
bracehasmid[#bracestack] = true
|
||||
else error("invalid char "..c) end
|
||||
elseif state=="comment" then
|
||||
if c=="\n" then state = "code" out("\n") newline() end
|
||||
elseif state=="commentml" then
|
||||
if c=="/" and cp=="*" then state = "code" end
|
||||
elseif state=="string" then
|
||||
if c=="\\" then state = "stringesc"
|
||||
elseif c=="\"" then state = "code"
|
||||
elseif c:byte()>=128 then
|
||||
utf8str = c
|
||||
utf8len = getutf8len(c)
|
||||
state = "stringutf8"
|
||||
else outn(c:byte()) end
|
||||
elseif state=="stringesc" then
|
||||
outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string";
|
||||
elseif state=="stringutf8" then
|
||||
utf8str = utf8str..c
|
||||
if #utf8str == utf8len then
|
||||
local valt = utf8table[utf8str]
|
||||
if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end;
|
||||
error("Unrecognized UTF-8 character: "..datastr); end
|
||||
for i, v in ipairs(valt) do outn(v) end
|
||||
state = "string"
|
||||
end
|
||||
end
|
||||
|
||||
i = i+1
|
||||
end
|
||||
assert(#bracestack==0, "unclosed brace")
|
||||
local code2 = table.concat(outt)
|
||||
|
||||
return code2
|
||||
end
|
||||
local function fixFilename(fn)
|
||||
fn = fn:gsub("[^a-zA-Z0-9_]", "_")
|
||||
return fn
|
||||
end
|
||||
local function includeFile(fn)
|
||||
local code = readFile(fn)
|
||||
code = prefixCode(code, fn)
|
||||
local fnf = fixFilename(fn)
|
||||
code = ".fn "..fnf.."\n"..code
|
||||
code = code:gsub(".include ([^\r\n]+)", function(fn2)
|
||||
fn2 = fn:gsub("[^\\/]+$", "")..fn2
|
||||
return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n"
|
||||
end)
|
||||
return code
|
||||
end
|
||||
local function instrsFromArch(arch)
|
||||
local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end
|
||||
local instrs = {
|
||||
imm8 = function() return 0, true end,
|
||||
imm16 = function() return 0, true end,
|
||||
byte = function() return 1, false end,
|
||||
word = function() return 2, false end,
|
||||
["byte imm8"] = function() return 0, true end,
|
||||
["word imm16"] = function() return 0, true end,
|
||||
["byte [ imm8 ]" ] = function(imms) return arraySize(imms) , false end,
|
||||
["byte [ imm16 ]"] = function(imms) return arraySize(imms) , false end,
|
||||
["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end,
|
||||
["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end,
|
||||
}
|
||||
local function addMnem(mnem, opcode)
|
||||
instrs[mnem] = opcode
|
||||
if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end
|
||||
end
|
||||
for _, instr in ipairs(arch.instructions) do
|
||||
if instr.mnem then
|
||||
local mnem = instr.mnem
|
||||
mnem = mnem:gsub("([%*%+%-])", " %1 ")
|
||||
mnem = trim(mnem):gsub(" +", " ")
|
||||
addMnem(mnem, instr.opcode)
|
||||
local alias = arch.aliases[trim(mnem)]
|
||||
if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end
|
||||
end
|
||||
end
|
||||
return instrs
|
||||
end
|
||||
local function assembleFile(fn, arch)
|
||||
local code = includeFile(fn)
|
||||
code, uexprs = preprocessCode(code)
|
||||
code = fixCode(code)
|
||||
local instrs = instrsFromArch(arch)
|
||||
local mem, code = assembleCode(code, instrs, uexprs)
|
||||
return mem, code
|
||||
end
|
||||
|
||||
local function mnemsFromArch(arch)
|
||||
local mnems = {}
|
||||
for _, instr in ipairs(arch.instructions) do
|
||||
if instr.mnem then
|
||||
local len = 1
|
||||
for l in instr.mnem:gmatch("imm([0-9]+)") do len = len + tonumber(l)/8 end
|
||||
mnems[instr.opcode] = { mnem = instr.mnem, rel = instr.rel, jmp = instr.jmp, len = len, }
|
||||
end
|
||||
end
|
||||
return mnems
|
||||
end
|
||||
local function toSigned8(x) return x>=128 and x-256 or x end
|
||||
local function disassembleMemory(mem, code, arch)
|
||||
local mnems = mnemsFromArch(arch)
|
||||
|
||||
local addr = 0
|
||||
local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end
|
||||
local lastaddr = 0
|
||||
local jmpaddrs = {}
|
||||
while addr<=0xFFFF do
|
||||
local startaddr = addr
|
||||
local opcode = nextByte()
|
||||
if opcode and ((not code) or code[startaddr]) then
|
||||
local mnem = mnems[opcode]
|
||||
if mnem then
|
||||
if mnem.jmp then
|
||||
local jmpdest
|
||||
if mnem.rel then jmpdest = toSigned8(nextByte(0)) + addr
|
||||
else jmpdest = nextByte(0)*256 + nextByte(0)
|
||||
end
|
||||
if jmpdest then
|
||||
if not jmpaddrs[jmpdest] then
|
||||
jmpaddrs[jmpdest] = { rel = mnem.rel, from = {}, }
|
||||
end
|
||||
table.insert(jmpaddrs[jmpdest].from, startaddr)
|
||||
jmpaddrs[jmpdest].rel = jmpaddrs[jmpdest].rel and mnem.rel
|
||||
end
|
||||
else
|
||||
addr = addr + mnem.len - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local labelnum, subnum = 0, 0
|
||||
for _, jmp in pairs(jmpaddrs) do
|
||||
if jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1;
|
||||
else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
addr = 0
|
||||
while addr<=0xFFFF do
|
||||
local startaddr = addr
|
||||
local opcode = nextByte()
|
||||
if opcode and ((not code) or code[startaddr]) then
|
||||
local line = {}
|
||||
local mnem = mnems[opcode].mnem or "???"
|
||||
table.insert(line, trim(mnem:gsub("imm[0-9]+", "")))
|
||||
local tlen = 1
|
||||
for lens in mnem:gmatch("imm([0-9]+)") do local len = tonumber(lens)/8
|
||||
if len==1 then
|
||||
local data = nextByte(0)
|
||||
local jmp
|
||||
if mnems[opcode].rel then
|
||||
local jmpdest = (addr + toSigned8(data))%65536
|
||||
jmp = jmpaddrs[jmpdest]
|
||||
if jmp then
|
||||
table.insert(line, jmp.name)
|
||||
--table.insert(line, ";")
|
||||
--table.insert(line, "$"..string.format("%04X", jmpdest)..",")
|
||||
end
|
||||
end
|
||||
if not jmp then table.insert(line, "$"..string.format("%02X", data)) end
|
||||
elseif len==2 then
|
||||
local data = nextByte(0)*256 + nextByte(0)
|
||||
local jmp
|
||||
if mnems[opcode].jmp then
|
||||
local jmpdest = data
|
||||
jmp = jmpaddrs[jmpdest]
|
||||
if jmp then
|
||||
table.insert(line, jmp.name)
|
||||
--table.insert(line, ";")
|
||||
end
|
||||
end
|
||||
if not jmp then table.insert(line, "$"..string.format("%04X", data)) end
|
||||
else error("invalid imm len") end
|
||||
tlen = tlen + len
|
||||
end
|
||||
local lineb = {}
|
||||
for i = addr-tlen, addr-1 do
|
||||
table.insert(lineb, string.format("%02X", mem[i] or 0))
|
||||
end
|
||||
local label = ""
|
||||
local jmp = jmpaddrs[startaddr]
|
||||
if jmp then label = jmp.name..":" end
|
||||
local lb = table.concat(lineb, " ")
|
||||
if lastaddr~=addr-tlen then table.insert(lines, "...") end
|
||||
table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " "))
|
||||
lastaddr = addr
|
||||
end
|
||||
end
|
||||
return table.concat(lines, "\n")
|
||||
end
|
||||
local function memToHex(hex)
|
||||
local mem = {}
|
||||
local addr = 0
|
||||
for d in hex:gmatch("[0-9a-fA-F][0-9a-fA-F]") do
|
||||
mem[addr] = tonumber(d, 16)
|
||||
addr = addr+1
|
||||
end
|
||||
return mem
|
||||
end
|
||||
local function disassembleHex(hex, arch)
|
||||
return disassembleMemory(memToHex(hex), arch)
|
||||
end
|
||||
|
||||
local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> "
|
||||
local printableChars = {}; for i = 1, #printableCharsS do printableChars[printableCharsS:sub(i, i)] = true end;
|
||||
local function toPrintableChar(n)
|
||||
local c = string.char(n)
|
||||
return printableChars[c] and c or "?"
|
||||
end
|
||||
local function printMemory(mem)
|
||||
local anynonempty = false
|
||||
local lastbase = -16
|
||||
local lastline = ""
|
||||
local numreps = 0
|
||||
local lines = {}
|
||||
local function closereps(base)
|
||||
if numreps~=0 then
|
||||
table.insert(lines, "(repeated "..numreps.." more times, up to "..string.format("%04X", base+15)..")")
|
||||
numreps = 0
|
||||
end
|
||||
end
|
||||
for base = 0, 0xFFF0, 16 do
|
||||
local line = {}
|
||||
local strt = {}
|
||||
local nonempty = false
|
||||
for addr = base, base+15 do
|
||||
if addr%4==0 then table.insert(line, " ") end
|
||||
if mem[addr]==false then
|
||||
nonempty = true
|
||||
table.insert(line, "XX ")
|
||||
table.insert(strt, "X")
|
||||
elseif mem[addr] then
|
||||
nonempty = true
|
||||
table.insert(line, string.format("%02X", mem[addr]).." ")
|
||||
table.insert(strt, toPrintableChar(mem[addr]))
|
||||
else
|
||||
table.insert(line, "-- ")
|
||||
table.insert(strt, "-")
|
||||
end
|
||||
end
|
||||
if nonempty then
|
||||
local l = table.concat(line)
|
||||
if l~=lastline or base~=lastbase+16 then
|
||||
closereps(base-16)
|
||||
if base ~= lastbase+16 then table.insert(lines, "...") end
|
||||
table.insert(lines, string.format("%04X", base).." | "..l.." | "..table.concat(strt))
|
||||
else
|
||||
numreps = numreps+1
|
||||
end
|
||||
lastline = l
|
||||
lastbase = base
|
||||
anynonempty = true
|
||||
end
|
||||
end
|
||||
closereps(lastbase)
|
||||
if not anynonempty then table.insert(lines, "Empty") end
|
||||
|
||||
return table.concat(lines, "\n")
|
||||
end
|
||||
|
||||
local HasTs = ts~=nil
|
||||
local ts = ts or {
|
||||
call = function() end,
|
||||
eval = function() end,
|
||||
}
|
||||
ts.eval [[
|
||||
function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); }
|
||||
function commandPlantBrick() { commandToServer('plantBrick'); }
|
||||
]]
|
||||
local function plantBrickAt(brickpos, pos)
|
||||
local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3]
|
||||
ts.call("commandShiftBrick", dy, -dx, dz)
|
||||
ts.call("commandPlantBrick")
|
||||
brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3]
|
||||
end
|
||||
local function buildMemory(mem, romsize, offset, len)
|
||||
offset = offset or 0
|
||||
|
||||
local rombytes = romsize[1]*romsize[2]*romsize[3]/8
|
||||
if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end
|
||||
if not len then
|
||||
for i = 0, 0xFFFF do
|
||||
if mem[i] and (i<offset or i>=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end
|
||||
end
|
||||
end
|
||||
|
||||
local brickpos = {0, 0, 0}
|
||||
for x = 0, romsize[1]-1 do
|
||||
for y = 0, romsize[2]-1 do
|
||||
for z = 0, romsize[3]-1 do
|
||||
local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8))
|
||||
local pow = math.pow(2, z%8)
|
||||
local data = (addr>=offset and ((not len) or addr<offset+len) and mem[addr]) or 0
|
||||
local bit = math.floor(data/pow)%2
|
||||
if bit==1 then plantBrickAt(brickpos, {x, -y, z}) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
|
||||
if HasTs or (not AsmIncluded) then
|
||||
function AssembleBuildFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes);
|
||||
local arch = require("rom-8608-defs")
|
||||
local mem, code = assembleFile(fn, arch)
|
||||
print(""..fn:match("[^/\\]+$").."\n")
|
||||
|
||||
print("Memory Dump:")
|
||||
print(printMemory(mem))
|
||||
print()
|
||||
print("Disassembly:")
|
||||
print(disassembleMemory(mem, code, arch))
|
||||
print()
|
||||
|
||||
assert(#romsize==3, "incorrect rom size")
|
||||
buildMemory(mem, romsize, offset, len)
|
||||
end
|
||||
ts.eval [[
|
||||
function AssembleBuildFile(%fn, %romsize, %offset, %len) { luacall("AssembleBuildFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); }
|
||||
]]
|
||||
if not HasTs then AssembleBuildFile(arg[1] or "../8608programs/test.asm", "16 16 8", "0", "256") end
|
||||
end
|
||||
|
||||
return {
|
||||
assembleFile = assembleFile,
|
||||
disassembleMemory = disassembleMemory,
|
||||
printMemory = printMemory,
|
||||
}
|
@ -1,483 +1,89 @@
|
||||
|
||||
local function loadutf8table(fn)
|
||||
local tt = {}
|
||||
for l in io.lines(fn) do if l~="" then
|
||||
local c, d = l:match("^([^ ]+) (.+)$")
|
||||
local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end;
|
||||
tt[c] = t
|
||||
end end
|
||||
return tt
|
||||
end
|
||||
local utf8table = loadutf8table((RelPath or "./").."utf8table.txt")
|
||||
|
||||
local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end
|
||||
local function getutf8len(c)
|
||||
local d = c:byte()
|
||||
if bit.band(d, 0xE0)==0xC0 then return 2
|
||||
elseif bit.band(d, 0xF0)==0xE0 then return 3
|
||||
elseif bit.band(d, 0xF8)==0xF0 then return 4
|
||||
else error("invalid utf8 first byte: "..string.format("%02X", d)) end
|
||||
|
||||
local function getCodeDir()
|
||||
local f0 = arg[0]:gsub("/", "\\")
|
||||
local d0 = f0:match("(.+)[\\][^\\]+$") or "."
|
||||
return d0
|
||||
end
|
||||
local function validWordsFromInstrs(instrs)
|
||||
local words = {}
|
||||
for mnem, _ in pairs(instrs) do
|
||||
for word in mnem:gmatch("[^ ]+") do
|
||||
words[word] = true
|
||||
end
|
||||
end
|
||||
return words
|
||||
|
||||
local function popenResult(cmd)
|
||||
local fp = io.popen(cmd)
|
||||
local out = fp:read("*a")
|
||||
fp:close()
|
||||
return out
|
||||
end
|
||||
local function lobyte(n) return n%256 end
|
||||
local function hibyte(n) return math.floor(n/256) end
|
||||
local function decodeNumber(n)
|
||||
n = trim(n)
|
||||
local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end;
|
||||
if n:sub(1, 1)=="$" then return sign*(tonumber(n:sub(2, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
|
||||
elseif n:sub(1, 2)=="0x" then return sign*(tonumber(n:sub(3, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-2)/2)
|
||||
elseif n:sub(#n, #n)=="h" and n:find("^[0-9a-fA-F]+h$") then return sign*(tonumber(n:sub(1, #n-1), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2)
|
||||
elseif n:sub(1, 2)=="0b" then return sign*(tonumber(n:sub(3, #n ), 2) or error("invalid binary number "..n)), math.ceil((#n-2)/8)
|
||||
elseif n:sub(#n, #n)=="b" and n:find("^[01]+b$") then return sign*(tonumber(n:sub(1, #n-1), 2) or error("invalid binary number "..n)), math.ceil((#n-1)/8)
|
||||
elseif n:sub(1, 3)=="lo(" and n:sub(#n, #n)==")" then return lobyte(decodeNumber(n:sub(4, #n-1))), 1
|
||||
elseif n:sub(1, 3)=="hi(" and n:sub(#n, #n)==")" then return hibyte(decodeNumber(n:sub(4, #n-1))), 1
|
||||
elseif n:find("^[0-9]+$") then
|
||||
local v = sign*(tonumber(n) or error("invalid decimal number "..n))
|
||||
if v>=-128 and v<=255 then return v, 1
|
||||
elseif v>=-32768 and v<=65535 then return v, 2
|
||||
else error("out-of-range number "..v) end
|
||||
|
||||
local function memFromCustomasmHexstr(out)
|
||||
local mem = {}
|
||||
local addr = 0
|
||||
for hexS in out:gmatch("[0-9a-fA-F][0-9a-fA-F]") do
|
||||
local val = tonumber(hexS, 16)
|
||||
if val~=0 then
|
||||
mem[addr] = val
|
||||
end
|
||||
addr = addr + 1
|
||||
end
|
||||
local code = nil
|
||||
local symbols = nil
|
||||
return mem, code, symbols
|
||||
end
|
||||
|
||||
local function toData(s)
|
||||
local d = {}
|
||||
for p in s:gmatch("[0-9a-zA-Z][0-9a-zA-Z]") do
|
||||
table.insert(d, tonumber(p, 16))
|
||||
end
|
||||
return d
|
||||
end
|
||||
local function memFromCustomasmAnnotated(out)
|
||||
local mem = {}
|
||||
local code = {}
|
||||
local symbols = {}
|
||||
|
||||
local lastLabel = {}
|
||||
|
||||
for line in out:gmatch("[^\r\n]+") do
|
||||
if not line:find("^ outp | addr | data %(base 16%)$") then
|
||||
local addrS, dataS, comment = line:match("^[^|]+ | ([^|]+) | ([^;]+) ; (.+)$")
|
||||
local addr = tonumber(addrS, 16)
|
||||
local data = toData(dataS)
|
||||
if comment:sub(#comment, #comment)==":" then
|
||||
assert(#data==0)
|
||||
local label = comment:sub(1, #comment-1)
|
||||
local noDots = label:gsub("^%.+", "")
|
||||
local numDots = #label - #noDots
|
||||
local fullLabel = numDots>0 and lastLabel[numDots-1].."."..noDots or label
|
||||
lastLabel[numDots] = fullLabel
|
||||
symbols[addr] = fullLabel
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
local function mnemFromLine(line, instrs, validWords)
|
||||
local imms = {}
|
||||
local function addNum(n)
|
||||
n = trim(n)
|
||||
local val, len = decodeNumber(n)
|
||||
assert(val and len, "invalid number "..n)
|
||||
local linei8 = line:gsub(n, "imm8", 1, true):lower()
|
||||
local linei16 = line:gsub(n, "imm16", 1, true):lower()
|
||||
if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end
|
||||
table.insert(imms, { val = val, len = len } )
|
||||
return " imm"..(len*8).." "
|
||||
end
|
||||
local function addLabel(n)
|
||||
n = trim(n)
|
||||
local len = 2
|
||||
local linei8 = line:gsub(n, "imm8", 1, true):lower()
|
||||
if instrs[linei8] then len = 1 end
|
||||
table.insert(imms, { label = n, len = len } )
|
||||
return " imm"..(len*8).." "
|
||||
end
|
||||
|
||||
local mnem = " "..line:gsub(" ", " ").." "
|
||||
mnem = mnem:gsub("%- *", " %+%-")
|
||||
mnem = mnem:gsub("([%*%+])", " %1 ")
|
||||
mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ " , function(n) return addNum (n) end)
|
||||
mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ " , function(n) return addNum (n) end)
|
||||
mnem = mnem:gsub(" %-?0b[01]+ " , function(n) return addNum (n) end)
|
||||
mnem = mnem:gsub(" %-?[0-9a-fA-F]+h " , function(n) if not validWords[trim(n)] then return addNum (n) end end)
|
||||
mnem = mnem:gsub(" %-?[01]+b " , function(n) if not validWords[trim(n)] then return addNum (n) end end)
|
||||
mnem = mnem:gsub(" %-?[0-9]+ " , function(n) if not validWords[trim(n)] then return addNum (n) end end)
|
||||
mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end)
|
||||
mnem = trim(mnem):gsub(" +", " "):lower()
|
||||
|
||||
if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end
|
||||
|
||||
return mnem, imms
|
||||
end
|
||||
local function addByte(state, val, code)
|
||||
assert(val>=-128 and val<=255, "invalid byte "..val)
|
||||
assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
|
||||
state.memory[state.curAddr] = val%256
|
||||
if code then state.codeMap[state.curAddr] = true end
|
||||
state.curAddr = state.curAddr + 1
|
||||
end
|
||||
local function addWord(state, val, code)
|
||||
assert(val>=0 and val<=65535, "invalid word "..val)
|
||||
addByte(state, math.floor(val/256), code)
|
||||
addByte(state, val%256, code)
|
||||
end
|
||||
local function addSpace(state, len)
|
||||
for i = 1, len do
|
||||
assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
|
||||
state.memory[state.curAddr] = false
|
||||
state.curAddr = state.curAddr + 1
|
||||
end
|
||||
end
|
||||
local function assembleInstruction(line, state, instrs, validWords)
|
||||
local mnem, imms = mnemFromLine(line, instrs, validWords)
|
||||
local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")")
|
||||
local writeimms = true
|
||||
local padlen = 0
|
||||
local isInstr
|
||||
if type(opcode)=="function" then
|
||||
padlen, writeimms = opcode(imms)
|
||||
addSpace(state, padlen)
|
||||
elseif opcode>=0 then
|
||||
isInstr = true
|
||||
addByte(state, opcode, isInstr)
|
||||
end
|
||||
if writeimms then
|
||||
for _, imm in ipairs(imms) do
|
||||
if imm.val then
|
||||
if imm.len==1 then addByte(state, imm.val, isInstr)
|
||||
elseif imm.len==2 then addWord(state, imm.val, isInstr)
|
||||
else error("invalid imm len") end
|
||||
elseif imm.label then
|
||||
table.insert(state.labelReplacements, {
|
||||
name = imm.label,
|
||||
addr = state.curAddr,
|
||||
len = imm.len,
|
||||
rel = imm.len==1,
|
||||
isCode = isInstr,
|
||||
})
|
||||
state.curAddr = state.curAddr + imm.len
|
||||
else error("invalid imm") end
|
||||
end
|
||||
end
|
||||
end
|
||||
local directiveFunctions = {
|
||||
fn = function(state, fn) state.fileName = fn end,
|
||||
ln = function(state, ln) state.lineNum = tonumber(ln) end,
|
||||
org = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end,
|
||||
align = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end,
|
||||
define = true,
|
||||
space = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end,
|
||||
}
|
||||
local function postEvaluateExpression(expr, labels)
|
||||
|
||||
end
|
||||
local function assembleCode(code, instrs, uexprs)
|
||||
local validWords = validWordsFromInstrs(instrs)
|
||||
|
||||
local state = {
|
||||
lineNum = 0,
|
||||
fileName = "",
|
||||
curAddr = 0,
|
||||
memory = {},
|
||||
codeMap = {},
|
||||
labelReplacements = {},
|
||||
labelAddrs = {},
|
||||
}
|
||||
|
||||
for line in code:gmatch("[^\n]+") do
|
||||
line = trim(line)
|
||||
if line:sub(1, 1)=="." then -- directive
|
||||
local dir, rest = line:match("^%.([^ ]+) *(.*)$")
|
||||
assert(dir and rest, "no directive on line "..line)
|
||||
local dirf = directiveFunctions[dir] or error("invalid directive "..dir)
|
||||
dirf(state, rest)
|
||||
elseif line:sub(#line, #line)==":" then -- label
|
||||
local name = line:sub(1, #line-1)
|
||||
assert(not state.labelAddrs[name], "redefinition of label "..name)
|
||||
state.labelAddrs[name] = state.curAddr
|
||||
elseif line:find("[^ ]") then
|
||||
assembleInstruction(line, state, instrs, validWords)
|
||||
end
|
||||
end
|
||||
|
||||
for _, rep in ipairs(state.labelReplacements) do
|
||||
local expr = uexprs[rep.name]
|
||||
if expr then
|
||||
local val = postEvaluateExpression(expr, state.labelAddrs)
|
||||
if rep.len==1 then addByte(state, val, rep.isCode)
|
||||
elseif rep.len==2 then addWord(state, val, rep.isCode)
|
||||
else error("invalid expr replace len "..rep.len) end
|
||||
else
|
||||
local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name)
|
||||
state.curAddr = rep.addr
|
||||
if rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode)
|
||||
elseif rep.len==2 then addWord(state, labelAddr , rep.isCode)
|
||||
else error("invalid labelreplace len "..rep.len) end
|
||||
end
|
||||
end
|
||||
|
||||
return state.memory, state.codeMap
|
||||
end
|
||||
|
||||
local function readFile(fn)
|
||||
local fi, err = io.open(fn, "r")
|
||||
if not fi then error("could not open file "..fn..": "..err) end
|
||||
local text = fi:read("*a")
|
||||
fi:close()
|
||||
return text
|
||||
end
|
||||
|
||||
local function separateCommas(l)
|
||||
local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c;
|
||||
end
|
||||
local function evaluateExpression(expr, uexprs)
|
||||
expr = expr:gsub("[^%+%-%*%/]+", function(word)
|
||||
local val = decodeNumber(word) or error("invalid number in expression: "..word)
|
||||
return val
|
||||
end)
|
||||
assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr)
|
||||
local exprf = loadstring("return "..expr)
|
||||
local eval = exprf() or error("invalid expr: "..expr)
|
||||
return eval
|
||||
end
|
||||
local function preprocessCode(code)
|
||||
code = "\n"..code.."\n"
|
||||
|
||||
-- apply brace labels and scoped labels
|
||||
local curscope = ""
|
||||
local codet = {}
|
||||
local wordt = {}
|
||||
local lastword = ""
|
||||
local function addword(word)
|
||||
lastword = word
|
||||
if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end
|
||||
table.insert(codet, word)
|
||||
end
|
||||
for i = 1, #code do
|
||||
local c = code:sub(i, i)
|
||||
if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c)
|
||||
else
|
||||
if #wordt>0 then
|
||||
addword(table.concat(wordt))
|
||||
wordt = {}
|
||||
end
|
||||
if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then
|
||||
curscope = lastword
|
||||
end
|
||||
table.insert(codet, c)
|
||||
end
|
||||
end
|
||||
|
||||
code = "\n"..table.concat(codet).."\n"
|
||||
|
||||
-- apply function macros
|
||||
local funcmacros = {}
|
||||
code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl)
|
||||
local argt = separateCommas(args)
|
||||
for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end
|
||||
repl = " "..repl.." "
|
||||
local invoc = 0
|
||||
funcmacros[name] = function(b, callargs)
|
||||
invoc = invoc + 1
|
||||
local callargt = separateCommas(callargs)
|
||||
local callrepl = repl
|
||||
for argidx, arg in ipairs(argt) do
|
||||
local callarg = callargt[argidx]
|
||||
callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2")
|
||||
end
|
||||
callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_")
|
||||
return b..callrepl
|
||||
end
|
||||
return ""
|
||||
end)
|
||||
for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end
|
||||
|
||||
-- apply simple macros
|
||||
local simplemacros = {}
|
||||
code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl)
|
||||
assert(not simplemacros[name], "Redefinition of macro "..name)
|
||||
simplemacros[name] = repl
|
||||
return ""
|
||||
end)
|
||||
--for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end
|
||||
for name, repl in pairs(simplemacros) do
|
||||
local invoc = 0
|
||||
code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a)
|
||||
invoc = invoc+1
|
||||
return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a
|
||||
end)
|
||||
print(name, code)
|
||||
end
|
||||
|
||||
code = code:gsub("\\\\", "\n")
|
||||
|
||||
local uexprs = {}
|
||||
|
||||
local codet = {}
|
||||
local exprt = {}
|
||||
local parenLevel = 0
|
||||
for i = 1, #code do
|
||||
local c = code:sub(i, i)
|
||||
if c=="(" then
|
||||
if parenLevel>0 then table.insert(exprt, c) end
|
||||
parenLevel = parenLevel+1
|
||||
elseif c==")" then
|
||||
parenLevel = parenLevel-1
|
||||
if parenLevel==0 then
|
||||
table.insert(codet, evaluateExpression(table.concat(exprt), uexprs))
|
||||
exprt = {}
|
||||
else
|
||||
table.insert(exprt, c)
|
||||
if comment:match("^[a-z]+") then
|
||||
for i, v in ipairs(data) do
|
||||
mem [addr+i-1] = v
|
||||
code[addr+i-1] = true
|
||||
end
|
||||
else
|
||||
if parenLevel==0 then table.insert(codet, c)
|
||||
else table.insert(exprt, c) end
|
||||
for i, v in ipairs(data) do
|
||||
mem [addr+i-1] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
code = table.concat(codet)
|
||||
|
||||
return code, uexprs
|
||||
return mem, code, symbols
|
||||
end
|
||||
local function fixCode(code)
|
||||
code = code:gsub(",", " ")
|
||||
code = code:gsub(":([^\\/])", ":\n%1")
|
||||
code = code:gsub("[ \t]+:", ":")
|
||||
code = code:gsub("%]", " %] ")
|
||||
code = code:gsub("%[", " %[ ")
|
||||
code = code:gsub("%*", " %* ")
|
||||
code = code:gsub("\n[ \t\r\n]*", "\n")
|
||||
code = code:gsub(" +", " ")
|
||||
|
||||
return code
|
||||
local function fullPath(fn)
|
||||
return popenResult(getCodeDir().."\\fullPath.bat \""..fn.."\"")
|
||||
end
|
||||
local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", }
|
||||
local prefixIdx = 0
|
||||
local function prefixCode(code, fn) -- fix strings, add line numbers
|
||||
prefixIdx = prefixIdx + 1
|
||||
|
||||
local outt = {}
|
||||
local outnextnl = {}
|
||||
local linenum = 1
|
||||
local skipnl = false
|
||||
local function last() return outt[#outt] end
|
||||
local function out(c) assert(type(c)=="string"); table.insert(outt, c); end
|
||||
local function outn(n) out("$"..string.format("%02X", n)) out("\\") end
|
||||
local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end
|
||||
local state = "code" -- code, comment, string, stringesc, commentml
|
||||
|
||||
local lastbracelabel = 0
|
||||
local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end
|
||||
local bracestack = {}
|
||||
local bracehasmid = {}
|
||||
local lastnl = false
|
||||
|
||||
local utf8str = ""
|
||||
local utf8len = 0
|
||||
|
||||
local function newline()
|
||||
lastnl = true
|
||||
for _, v in ipairs(outnextnl) do
|
||||
if v=="\n" and skipnl then out("\\")
|
||||
else out(v) end
|
||||
end; outnextnl = {};
|
||||
end
|
||||
|
||||
out(".ln 1"); out("\n");
|
||||
local i = 1
|
||||
while i <= #code do
|
||||
local c = code:sub(i, i)
|
||||
local cn = code:sub(i+1, i+1)
|
||||
local cp = code:sub(i-1, i-1)
|
||||
|
||||
if state=="code" then
|
||||
if c=="\r" then
|
||||
elseif c=="\n" then -- (c=="/" and cn~="/" and cn~="*")
|
||||
linenum = linenum+1
|
||||
if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end
|
||||
newline()
|
||||
skipnl = false
|
||||
elseif c=="#" or c==";" or (c=="/" and cn=="/") then state = "comment"
|
||||
elseif c=="/" and cn=="*" then state = "commentml"
|
||||
elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end
|
||||
elseif c=="\"" then state = "string" lastnl = false
|
||||
elseif c=="\\" then skipnl = true; out("\\");
|
||||
elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true;
|
||||
elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false
|
||||
elseif c=="{" then
|
||||
table.insert(bracestack, bracelabel())
|
||||
if not lastnl then out(bracestack[#bracestack].."MID") end
|
||||
outnext(bracestack[#bracestack].."START:"); outnext("\n");
|
||||
elseif c=="}" then
|
||||
if not lastnl then out(bracestack[#bracestack].."START") end
|
||||
if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end
|
||||
outnext(bracestack[#bracestack].."END:"); outnext("\n");
|
||||
bracehasmid[#bracestack] = nil
|
||||
bracestack[#bracestack] = nil
|
||||
elseif c=="|" then
|
||||
if not lastnl then out(bracestack[#bracestack].."END") end
|
||||
outnext(bracestack[#bracestack].."MID:"); outnext("\n");
|
||||
bracehasmid[#bracestack] = true
|
||||
else error("invalid char "..c) end
|
||||
elseif state=="comment" then
|
||||
if c=="\n" then state = "code" out("\n") newline() end
|
||||
elseif state=="commentml" then
|
||||
if c=="/" and cp=="*" then state = "code" end
|
||||
elseif state=="string" then
|
||||
if c=="\\" then state = "stringesc"
|
||||
elseif c=="\"" then state = "code"
|
||||
elseif c:byte()>=128 then
|
||||
utf8str = c
|
||||
utf8len = getutf8len(c)
|
||||
state = "stringutf8"
|
||||
else outn(c:byte()) end
|
||||
elseif state=="stringesc" then
|
||||
outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string";
|
||||
elseif state=="stringutf8" then
|
||||
utf8str = utf8str..c
|
||||
if #utf8str == utf8len then
|
||||
local valt = utf8table[utf8str]
|
||||
if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end;
|
||||
error("Unrecognized UTF-8 character: "..datastr); end
|
||||
for i, v in ipairs(valt) do outn(v) end
|
||||
state = "string"
|
||||
end
|
||||
end
|
||||
|
||||
i = i+1
|
||||
end
|
||||
assert(#bracestack==0, "unclosed brace")
|
||||
local code2 = table.concat(outt)
|
||||
|
||||
return code2
|
||||
end
|
||||
local function fixFilename(fn)
|
||||
fn = fn:gsub("[^a-zA-Z0-9_]", "_")
|
||||
return fn
|
||||
end
|
||||
local function includeFile(fn)
|
||||
local code = readFile(fn)
|
||||
code = prefixCode(code, fn)
|
||||
local fnf = fixFilename(fn)
|
||||
code = ".fn "..fnf.."\n"..code
|
||||
code = code:gsub(".include ([^\r\n]+)", function(fn2)
|
||||
fn2 = fn:gsub("[^\\/]+$", "")..fn2
|
||||
return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n"
|
||||
end)
|
||||
return code
|
||||
end
|
||||
local function instrsFromArch(arch)
|
||||
local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end
|
||||
local instrs = {
|
||||
imm8 = function() return 0, true end,
|
||||
imm16 = function() return 0, true end,
|
||||
byte = function() return 1, false end,
|
||||
word = function() return 2, false end,
|
||||
["byte imm8"] = function() return 0, true end,
|
||||
["word imm16"] = function() return 0, true end,
|
||||
["byte [ imm8 ]" ] = function(imms) return arraySize(imms) , false end,
|
||||
["byte [ imm16 ]"] = function(imms) return arraySize(imms) , false end,
|
||||
["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end,
|
||||
["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end,
|
||||
}
|
||||
local function addMnem(mnem, opcode)
|
||||
instrs[mnem] = opcode
|
||||
if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end
|
||||
end
|
||||
for _, instr in ipairs(arch.instructions) do
|
||||
if instr.mnem then
|
||||
local mnem = instr.mnem
|
||||
mnem = mnem:gsub("([%*%+%-])", " %1 ")
|
||||
mnem = trim(mnem):gsub(" +", " ")
|
||||
addMnem(mnem, instr.opcode)
|
||||
local alias = arch.aliases[trim(mnem)]
|
||||
if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end
|
||||
end
|
||||
end
|
||||
return instrs
|
||||
end
|
||||
local function assembleFile(fn, arch)
|
||||
local code = includeFile(fn)
|
||||
code, uexprs = preprocessCode(code)
|
||||
code = fixCode(code)
|
||||
local instrs = instrsFromArch(arch)
|
||||
local mem, code = assembleCode(code, instrs, uexprs)
|
||||
return mem, code
|
||||
local fnf = fullPath(fn)
|
||||
--local out = popenResult("customasm -p -q --format hexstr \""..fnf.."\"")
|
||||
--return memFromCustomasmHexstr(out)
|
||||
local out = popenResult("customasm -p -q --format annotated,base:16,group:2 \""..fnf.."\"")
|
||||
return memFromCustomasmAnnotated(out)
|
||||
end
|
||||
|
||||
local function mnemsFromArch(arch)
|
||||
@ -491,8 +97,11 @@ local function mnemsFromArch(arch)
|
||||
end
|
||||
return mnems
|
||||
end
|
||||
|
||||
local function symbolCrunchDots(s) return s:gsub("[^%.]+%.", "%.").."" end
|
||||
|
||||
local function toSigned8(x) return x>=128 and x-256 or x end
|
||||
local function disassembleMemory(mem, code, arch)
|
||||
local function disassembleMemory(arch, mem, code, symbols)
|
||||
local mnems = mnemsFromArch(arch)
|
||||
|
||||
local addr = 0
|
||||
@ -524,11 +133,13 @@ local function disassembleMemory(mem, code, arch)
|
||||
end
|
||||
end
|
||||
local labelnum, subnum = 0, 0
|
||||
for _, jmp in pairs(jmpaddrs) do
|
||||
if jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1;
|
||||
for dest, jmp in pairs(jmpaddrs) do
|
||||
if symbols[dest] then jmp.name = symbolCrunchDots(symbols[dest])
|
||||
elseif jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1;
|
||||
else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end
|
||||
end
|
||||
|
||||
local maxLabelLen = 20
|
||||
local lines = {}
|
||||
addr = 0
|
||||
while addr<=0xFFFF do
|
||||
@ -574,11 +185,14 @@ local function disassembleMemory(mem, code, arch)
|
||||
end
|
||||
local label = ""
|
||||
local jmp = jmpaddrs[startaddr]
|
||||
if jmp then label = jmp.name..":" end
|
||||
if symbols[startaddr] then label = symbolCrunchDots(symbols[startaddr])..":"
|
||||
elseif jmp then label = jmp.name..":" end
|
||||
local lb = table.concat(lineb, " ")
|
||||
if lastaddr~=addr-tlen then table.insert(lines, "...") end
|
||||
table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " "))
|
||||
table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(maxLabelLen-#label)..label.." "..table.concat(line, " "))
|
||||
lastaddr = addr
|
||||
elseif opcode and opcode~=0 then
|
||||
table.insert(lines, "data: "..string.format("%02X", opcode))
|
||||
end
|
||||
end
|
||||
return table.concat(lines, "\n")
|
||||
@ -593,7 +207,7 @@ local function memToHex(hex)
|
||||
return mem
|
||||
end
|
||||
local function disassembleHex(hex, arch)
|
||||
return disassembleMemory(memToHex(hex), arch)
|
||||
return disassembleMemory(arch, memToHex(hex), nil, nil)
|
||||
end
|
||||
|
||||
local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> "
|
||||
@ -693,31 +307,15 @@ local function buildMemory(mem, romsize, offset, len)
|
||||
end
|
||||
end
|
||||
|
||||
local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
|
||||
if HasTs or (not AsmIncluded) then
|
||||
function AssembleBuildFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes);
|
||||
local arch = require("rom-8608-defs")
|
||||
local mem, code = assembleFile(fn, arch)
|
||||
print(""..fn:match("[^/\\]+$").."\n")
|
||||
|
||||
print("Memory Dump:")
|
||||
print(printMemory(mem))
|
||||
print()
|
||||
print("Disassembly:")
|
||||
print(disassembleMemory(mem, code, arch))
|
||||
print()
|
||||
|
||||
assert(#romsize==3, "incorrect rom size")
|
||||
buildMemory(mem, romsize, offset, len)
|
||||
end
|
||||
ts.eval [[
|
||||
function AssembleBuildFile(%fn, %romsize, %offset, %len) { luacall("AssembleBuildFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); }
|
||||
]]
|
||||
if not HasTs then AssembleBuildFile(arg[1] or "../8608programs/test.asm", "16 16 8", "0", "256") end
|
||||
end
|
||||
|
||||
return {
|
||||
if arg[1] then
|
||||
local fn = arg[1]
|
||||
local mem, code, symbols = assembleFile(fn)
|
||||
local arch = dofile(getCodeDir().."\\rom-8608-defs.lua")
|
||||
print(disassembleMemory(arch, mem, code, symbols))
|
||||
else
|
||||
return {
|
||||
assembleFile = assembleFile,
|
||||
disassembleMemory = disassembleMemory,
|
||||
printMemory = printMemory,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
70
bin-builder.lua
Normal file
70
bin-builder.lua
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
local ts = ts or {
|
||||
call = function() end,
|
||||
eval = function() end,
|
||||
}
|
||||
|
||||
ts.eval [[
|
||||
function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); }
|
||||
function commandPlantBrick() { commandToServer('plantBrick'); }
|
||||
]]
|
||||
local function plantBrickAt(brickpos, pos)
|
||||
local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3]
|
||||
ts.call("commandShiftBrick", dy, -dx, dz)
|
||||
ts.call("commandPlantBrick")
|
||||
brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3]
|
||||
end
|
||||
local function buildMemory(mem, romsize, offset, len)
|
||||
if type(romsize)~="table" or #romsize<3 then error("You must specify a ROM size.") end
|
||||
offset = offset or 0
|
||||
|
||||
local rombytes = romsize[1]*romsize[2]*romsize[3]/8
|
||||
if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end
|
||||
if not len then
|
||||
for i = 0, 0xFFFF do
|
||||
if mem[i] and (i<offset or i>=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end
|
||||
end
|
||||
end
|
||||
|
||||
local brickpos = {0, 0, 0}
|
||||
for x = 0, romsize[1]-1 do
|
||||
for y = 0, romsize[2]-1 do
|
||||
for z = 0, romsize[3]-1 do
|
||||
local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8))
|
||||
local pow = math.pow(2, z%8)
|
||||
local data = (addr>=offset and ((not len) or addr<offset+len) and mem[addr]) or 0
|
||||
local bit = math.floor(data/pow)%2
|
||||
if bit==1 then plantBrickAt(brickpos, {x, -y, z}) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function memFromBinFile(fn)
|
||||
local fi = io.open(fn, "rb") or error("Could not open file: \""..fn.."\"")
|
||||
local text = fi:read("*a")
|
||||
fi:close()
|
||||
|
||||
local mem = {}
|
||||
--local seenNonzero = false
|
||||
for i = 1, #text do
|
||||
local c = text:sub(i, i):byte()
|
||||
--if c~=0 then seenNonzero = true end
|
||||
--if seenNonzero then
|
||||
-- mem[i-1] = c
|
||||
--end
|
||||
if c~=0 then mem[i-1] = c end
|
||||
end
|
||||
return mem
|
||||
end
|
||||
|
||||
local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
|
||||
|
||||
function BuildBinFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes);
|
||||
local mem = memFromBinFile(fn)
|
||||
buildMemory(mem, romsize, offset, len)
|
||||
end
|
||||
|
||||
ts.eval [[
|
||||
function BuildBinFile(%fn, %romsize, %offset, %len) { luacall("BuildBinFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); }
|
||||
]]
|
@ -11,13 +11,14 @@
|
||||
#define loadut readmemory(wordut)
|
||||
#define loadutp1 readmemory((wordut+1)%65536)
|
||||
#define loadp readmemory(cpu->p)
|
||||
#define loadpinc readmemory(cpu->p++)
|
||||
#define loadpp1 readmemory((cpu->p+1)%65536)
|
||||
#define loadq readmemory(cpu->q)
|
||||
#define loadqinc readmemory(cpu->q++)
|
||||
#define loadpinc readmemory((cpu->p++)%65536)
|
||||
#define loadqinc readmemory((cpu->q++)%65536)
|
||||
#define loadpp1 readmemory((cpu->p+1)%65536)
|
||||
#define loadqp1 readmemory((cpu->q+1)%65536)
|
||||
#define loadput readmemory((cpu->p+wordut)%65536)
|
||||
#define loadqut readmemory((cpu->q+wordut)%65536)
|
||||
#define signed8(x) (x>=128 ? x|0xFF00 : x)
|
||||
|
||||
#define setzf(x) cpu->nz=(x!=0);
|
||||
#define loadimmedt cpu->t = loadimmed;
|
||||
#define loadimm161 cpu->u = loadimmed;
|
||||
@ -31,11 +32,13 @@
|
||||
#define storeut(x) writememory(wordut, x);
|
||||
#define storeutp1(x) writememory((wordut+1)%65536, x);
|
||||
#define storep(x) writememory(cpu->p, x);
|
||||
#define storepinc(x) writememory(cpu->p++, x);
|
||||
#define storepp1(x) writememory((cpu->p+1)%65536, x);
|
||||
#define storeq(x) writememory(cpu->q, x);
|
||||
#define storepinc(x) writememory(cpu->p++, x);
|
||||
#define storeqinc(x) writememory(cpu->q++, x);
|
||||
#define storepp1(x) writememory((cpu->p+1)%65536, x);
|
||||
#define storeqp1(x) writememory((cpu->q+1)%65536, x);
|
||||
#define storeput(x) writememory((cpu->p+wordut)%65536, x);
|
||||
#define storequt(x) writememory((cpu->q+wordut)%65536, x);
|
||||
#define pushretaddr1 writememory(cpu->s++, hibyte((cpu->i-1)%65536));
|
||||
#define pushretaddr2 writememory(cpu->s++, lobyte((cpu->i-1)%65536));
|
||||
#define lni cpu->instr = readmemory(cpu->i++); cpu->cycle = 0;
|
||||
|
Binary file not shown.
@ -241,7 +241,7 @@ local function pdLinesFromDasm(dasm)
|
||||
end
|
||||
return lines, addrLines, lineAddrs
|
||||
end
|
||||
local function InitProgramDisplay(pd, data, code, arch)
|
||||
local function InitProgramDisplay(pd, arch, data, code, symbols)
|
||||
pd.width = 256
|
||||
pd.height = 12+pd.fontHeight*pd.numLines-3
|
||||
lg.print("Program", pd.scrX, pd.scrY-16)
|
||||
@ -249,7 +249,7 @@ local function InitProgramDisplay(pd, data, code, arch)
|
||||
pd.firstLine = 1
|
||||
pd.data = data
|
||||
pd.code = code
|
||||
local dasm = asm.disassembleMemory(data, code, arch)
|
||||
local dasm = asm.disassembleMemory(arch, data, code, symbols)
|
||||
pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasm)
|
||||
pd.midLine = math.floor(pd.numLines/2)
|
||||
end
|
||||
@ -490,13 +490,13 @@ WriteMemory = function(mem, addr, val)
|
||||
end
|
||||
end
|
||||
local function AssembleToMemory(mem, fn, arch)
|
||||
local data, code = asm.assembleFile(fn, arch)
|
||||
local data, code, symbols = asm.assembleFile(fn)
|
||||
for addr = 0, 65535 do
|
||||
if data[addr] then
|
||||
mem.c.data[addr] = data[addr]
|
||||
end
|
||||
end
|
||||
return data, code
|
||||
return data, code, symbols
|
||||
end
|
||||
|
||||
ffi.cdef [[
|
||||
@ -631,8 +631,8 @@ function love.load()
|
||||
InitCharDisplay(CharDisplay)
|
||||
InitRegDisplay(RegDisplay)
|
||||
InitStackDisplay(StackDisplay)
|
||||
local data, code = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch)
|
||||
InitProgramDisplay(ProgramDisplay, data, code, Arch)
|
||||
local data, code, symbols = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch)
|
||||
InitProgramDisplay(ProgramDisplay, Arch, data, code, symbols)
|
||||
for _, md in ipairs(MemoryDisplays) do InitMemoryDisplay(md) end
|
||||
RedrawWindow()
|
||||
lg.setCanvas()
|
||||
|
@ -1,6 +1,47 @@
|
||||
// Auto-generated by gendefs.lua
|
||||
|
||||
void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->irq=0; cpu->ifg=0; cpu->rfg=1; cpu->ien=0; lni; }
|
||||
void cpu_instr_1_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_1_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_1_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadput; setzf(cpu->a); cpu->cycle++; }
|
||||
void cpu_instr_1_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_6_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_6_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_6_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; }
|
||||
void cpu_instr_6_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; }
|
||||
void cpu_instr_6_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_8_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_8_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_8_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqut; setzf(cpu->b); cpu->cycle++; }
|
||||
void cpu_instr_8_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_9_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_9_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_9_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqut; setzf(cpu->c); cpu->cycle++; }
|
||||
void cpu_instr_9_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_10_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_10_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_10_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->a); cpu->cycle++; }
|
||||
void cpu_instr_10_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_11_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_11_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_11_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->b); cpu->cycle++; }
|
||||
void cpu_instr_11_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_12_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_12_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_12_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->c); cpu->cycle++; }
|
||||
void cpu_instr_12_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_13_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_13_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_13_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->a); cpu->cycle++; }
|
||||
void cpu_instr_13_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_14_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_14_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_14_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->b); cpu->cycle++; }
|
||||
void cpu_instr_14_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_15_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_15_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_15_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->c); cpu->cycle++; }
|
||||
void cpu_instr_15_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1 ); lni; }
|
||||
void cpu_instr_17_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1 ); lni; }
|
||||
void cpu_instr_18_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p++; lni; }
|
||||
@ -440,6 +481,20 @@ void cpu_instr_233_0(struct CPU* const cpu, struct Memory* const mem) { int f =
|
||||
void cpu_instr_233_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { int f=popbyte; cpu->nz = f&1; cpu->cf = (f>>1)&1; cpu->cycle++; }
|
||||
void cpu_instr_234_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_235_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_235_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_235_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqut; setzf(cpu->a); cpu->cycle++; }
|
||||
void cpu_instr_235_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_236_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_236_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_236_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; }
|
||||
void cpu_instr_236_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
|
||||
void cpu_instr_236_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
|
||||
void cpu_instr_238_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_238_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_238_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; }
|
||||
void cpu_instr_238_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
|
||||
void cpu_instr_238_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
|
||||
void cpu_instr_240_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=0; lni; }
|
||||
void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=1; lni; }
|
||||
void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=(t-1)%65536; lni; }
|
||||
@ -447,25 +502,48 @@ void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg
|
||||
void cpu_instr_244_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=0; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; }
|
||||
void cpu_instr_245_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; }
|
||||
void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; }
|
||||
void cpu_instr_247_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_247_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_247_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadput; setzf(cpu->b); cpu->cycle++; }
|
||||
void cpu_instr_247_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_248_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_248_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_248_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; }
|
||||
void cpu_instr_248_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
|
||||
void cpu_instr_248_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
|
||||
void cpu_instr_250_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_250_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_250_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; }
|
||||
void cpu_instr_250_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
|
||||
void cpu_instr_250_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
|
||||
void cpu_instr_252_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_252_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_252_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->p)); cpu->cycle++; }
|
||||
void cpu_instr_252_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; }
|
||||
void cpu_instr_252_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_254_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||
void cpu_instr_254_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||
void cpu_instr_254_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadput; setzf(cpu->c); cpu->cycle++; }
|
||||
void cpu_instr_254_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
|
||||
CPUInstruction CPUInstructions[256][8] = {
|
||||
{cpu_instr_0_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_1_0,cpu_instr_1_1,cpu_instr_1_2,cpu_instr_1_3,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_6_0,cpu_instr_6_1,cpu_instr_6_2,cpu_instr_6_3,cpu_instr_6_4,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_8_0,cpu_instr_8_1,cpu_instr_8_2,cpu_instr_8_3,0,0,0,0},
|
||||
{cpu_instr_9_0,cpu_instr_9_1,cpu_instr_9_2,cpu_instr_9_3,0,0,0,0},
|
||||
{cpu_instr_10_0,cpu_instr_10_1,cpu_instr_10_2,cpu_instr_10_3,0,0,0,0},
|
||||
{cpu_instr_11_0,cpu_instr_11_1,cpu_instr_11_2,cpu_instr_11_3,0,0,0,0},
|
||||
{cpu_instr_12_0,cpu_instr_12_1,cpu_instr_12_2,cpu_instr_12_3,0,0,0,0},
|
||||
{cpu_instr_13_0,cpu_instr_13_1,cpu_instr_13_2,cpu_instr_13_3,0,0,0,0},
|
||||
{cpu_instr_14_0,cpu_instr_14_1,cpu_instr_14_2,cpu_instr_14_3,0,0,0,0},
|
||||
{cpu_instr_15_0,cpu_instr_15_1,cpu_instr_15_2,cpu_instr_15_3,0,0,0,0},
|
||||
{cpu_instr_16_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_17_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_18_0,0,0,0,0,0,0,0},
|
||||
@ -685,10 +763,10 @@ CPUInstruction CPUInstructions[256][8] = {
|
||||
{cpu_instr_232_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_233_0,cpu_instr_233_1,0,0,0,0,0,0},
|
||||
{cpu_instr_234_0,cpu_instr_234_1,0,0,0,0,0,0},
|
||||
{cpu_instr_235_0,cpu_instr_235_1,cpu_instr_235_2,cpu_instr_235_3,0,0,0,0},
|
||||
{cpu_instr_236_0,cpu_instr_236_1,cpu_instr_236_2,cpu_instr_236_3,cpu_instr_236_4,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_238_0,cpu_instr_238_1,cpu_instr_238_2,cpu_instr_238_3,cpu_instr_238_4,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_240_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_241_0,0,0,0,0,0,0,0},
|
||||
@ -697,13 +775,13 @@ CPUInstruction CPUInstructions[256][8] = {
|
||||
{cpu_instr_244_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_245_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_246_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_247_0,cpu_instr_247_1,cpu_instr_247_2,cpu_instr_247_3,0,0,0,0},
|
||||
{cpu_instr_248_0,cpu_instr_248_1,cpu_instr_248_2,cpu_instr_248_3,cpu_instr_248_4,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_250_0,cpu_instr_250_1,cpu_instr_250_2,cpu_instr_250_3,cpu_instr_250_4,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_252_0,cpu_instr_252_1,cpu_instr_252_2,cpu_instr_252_3,cpu_instr_252_4,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_254_0,cpu_instr_254_1,cpu_instr_254_2,cpu_instr_254_3,0,0,0,0},
|
||||
{cpu_instr_255_0,0,0,0,0,0,0,0},
|
||||
};
|
||||
|
@ -1,4 +1,6 @@
|
||||
|
||||
-- copied from Brick_LuaLogic/bricks/input/keyboard-global.luas
|
||||
|
||||
return {
|
||||
["backspace"] = 8,
|
||||
["tab"] = 9,
|
||||
|
1
fullPath.bat
Normal file
1
fullPath.bat
Normal file
@ -0,0 +1 @@
|
||||
@echo %~dpnx1
|
@ -129,10 +129,10 @@ rts E1 3 I=*(----S)+1
|
||||
jpr imm8 31 2 I+=imm8
|
||||
jnz imm8 30 2 I+=imm8 if !Zero
|
||||
jpz imm8 32 2 I+=imm8 if Zero
|
||||
jge imm8 33 2 I+=imm8 if !Carry
|
||||
jlt imm8 34 2 I+=imm8 if Carry
|
||||
jgt imm8 35 2 I+=imm8 if !Zero & !Carry
|
||||
jle imm8 36 2 I+=imm8 if Zero | Carry
|
||||
jlt imm8 33 2 I+=imm8 if !Carry
|
||||
jge imm8 34 2 I+=imm8 if Carry
|
||||
jgt imm8 35 2 I+=imm8 if !Zero & Carry
|
||||
jle imm8 36 2 I+=imm8 if Zero | !Carry
|
||||
|
||||
Stack (S):
|
||||
psh a 40 2 *(S++)=A
|
||||
@ -166,30 +166,42 @@ ldc *imm16 57 4 C=*imm16, update zero flag
|
||||
sta *imm16 50 4 *imm16=A
|
||||
stb *imm16 58 4 *imm16=B
|
||||
stc *imm16 59 4 *imm16=C
|
||||
sta *p 52 2 *P=A
|
||||
stb *p 5A 2 *P=B
|
||||
stc *p 5B 2 *P=C
|
||||
sta *q 54 2 *Q=A
|
||||
stb *q 5C 2 *Q=B
|
||||
stc *q 5D 2 *Q=C
|
||||
lda *p+imm16 01 4 A=*P+imm16, update zero flag
|
||||
ldb *p+imm16 F7 4 B=*P+imm16, update zero flag
|
||||
ldc *p+imm16 FE 4 C=*P+imm16, update zero flag
|
||||
lda *q+imm16 EB 4 A=*Q+imm16, update zero flag
|
||||
ldb *q+imm16 08 4 B=*Q+imm16, update zero flag
|
||||
ldc *q+imm16 09 4 C=*Q+imm16, update zero flag
|
||||
sta *p+imm16 0A 4 *P+imm16=A
|
||||
stb *p+imm16 0B 4 *P+imm16=B
|
||||
stc *p+imm16 0C 4 *P+imm16=C
|
||||
sta *q+imm16 0D 4 *Q+imm16=A
|
||||
stb *q+imm16 0E 4 *Q+imm16=B
|
||||
stc *q+imm16 0F 4 *Q+imm16=C
|
||||
lda *p 53 2 A=*P, update zero flag
|
||||
ldb *p 5E 2 B=*P, update zero flag
|
||||
ldc *p 5F 2 C=*P, update zero flag
|
||||
lda *q 55 2 A=*Q, update zero flag
|
||||
ldb *q 61 2 B=*Q, update zero flag
|
||||
ldc *q 62 2 C=*Q, update zero flag
|
||||
sta *p++ C0 2 *P++=A
|
||||
stb *p++ C1 2 *P++=B
|
||||
stc *p++ C2 2 *P++=C
|
||||
sta *q++ C3 2 *Q++=A
|
||||
stb *q++ C4 2 *Q++=B
|
||||
stc *q++ C5 2 *Q++=C
|
||||
sta *p 52 2 *P=A
|
||||
stb *p 5A 2 *P=B
|
||||
stc *p 5B 2 *P=C
|
||||
sta *q 54 2 *Q=A
|
||||
stb *q 5C 2 *Q=B
|
||||
stc *q 5D 2 *Q=C
|
||||
lda *p++ C6 2 A=*P++, update zero flag
|
||||
ldb *p++ C7 2 B=*P++, update zero flag
|
||||
ldc *p++ C8 2 C=*P++, update zero flag
|
||||
lda *q++ C9 2 A=*Q++, update zero flag
|
||||
ldb *q++ CA 2 B=*Q++, update zero flag
|
||||
ldc *q++ CB 2 C=*Q++, update zero flag
|
||||
sta *p++ C0 2 *P++=A
|
||||
stb *p++ C1 2 *P++=B
|
||||
stc *p++ C2 2 *P++=C
|
||||
sta *q++ C3 2 *Q++=A
|
||||
stb *q++ C4 2 *Q++=B
|
||||
stc *q++ C5 2 *Q++=C
|
||||
|
||||
16-bit Load/Store (W):
|
||||
ldp imm16 21 3 P=imm16
|
||||
@ -204,6 +216,12 @@ ldp *imm16 68 5 P=*imm16
|
||||
ldq *imm16 6A 5 Q=*imm16
|
||||
stp *imm16 6C 5 *imm16=P
|
||||
stq *imm16 6E 5 *imm16=Q
|
||||
ldp *p+imm16 EC 5 P=*P+imm16
|
||||
ldq *p+imm16 EE 5 Q=*P+imm16
|
||||
ldp *q+imm16 F8 5 P=*Q+imm16
|
||||
ldq *q+imm16 FA 5 Q=*Q+imm16
|
||||
stq *p+imm16 06 5 *P+imm16=Q
|
||||
stp *q+imm16 FC 5 *Q+imm16=P
|
||||
ldp *p 92 3 P=*P
|
||||
ldq *p 93 3 Q=*P
|
||||
ldp *q 94 3 P=*Q
|
||||
@ -240,9 +258,9 @@ ldq p 8E 1 Q=P
|
||||
lds p 8F 1 S=P
|
||||
ldv p 90 1 V=P
|
||||
|
||||
Opcodes used: 228/255
|
||||
Opcodes used: 252/255
|
||||
0123456789ABCDEF
|
||||
00 | C---------------
|
||||
00 | CB----WWBBBBBBBB
|
||||
10 | UUIIUIIUUUUUUUUU
|
||||
20 | BWWWAWBBBBBUUUUA
|
||||
30 | JJJJJJJMMMMSSSAA
|
||||
@ -256,5 +274,5 @@ A0 | AAAAAAAAAAAAAAAA
|
||||
B0 | AAAAAAAAAAAAAAAA
|
||||
C0 | BBBBBBBBBBBBWWWW
|
||||
D0 | AAAAAAAAAAAAAAAA
|
||||
E0 | MJJJJJXXXSS-----
|
||||
F0 | CCCCCCC--------C
|
||||
E0 | MJJJJJXXXSSBWWWW
|
||||
F0 | CCCCCCCBWWWWWWBC
|
||||
|
@ -70,6 +70,70 @@ local function sigsFromRoms(roms)
|
||||
return sigs
|
||||
end
|
||||
|
||||
local relJmpStr = [[
|
||||
%s {addr} => {
|
||||
reladdr = addr - $ - 2
|
||||
assert(reladdr <= 127, "%s: Relative jump target is too far away")
|
||||
assert(reladdr >= -128, "%s: Relative jump target is too far away")
|
||||
%s @ reladdr`8
|
||||
}]]
|
||||
local wordRelStr = [[
|
||||
%s+{value: i%i} => {
|
||||
assert(value <= %i, "Relative address is too far away")
|
||||
assert(value >= %i, "Relative address is too far away")
|
||||
%s @ value`%i
|
||||
}
|
||||
%s-{value: i%i} => {
|
||||
mvalue = -value
|
||||
assert(mvalue <= %i, "Relative address is too far away")
|
||||
assert(mvalue >= %i, "Relative address is too far away")
|
||||
%s @ mvalue`%i
|
||||
}]]
|
||||
|
||||
local function getAsmCode(mnem, instr)
|
||||
local reljmp = instr.jmp and instr.rel
|
||||
local opcodeS = string.format("$%02X", instr.opcode)
|
||||
|
||||
if reljmp then
|
||||
assert(mnem:find("imm8"), "relative jump without imm8")
|
||||
local mnemPart = mnem:gsub(" imm8", "")
|
||||
return string.format(relJmpStr,
|
||||
mnemPart, mnemPart, mnemPart,
|
||||
opcodeS
|
||||
)
|
||||
elseif mnem:find("%+imm") then
|
||||
local mnemPart, bitsS = mnem:match("^([^%+]+)%+imm([0-9]+)$")
|
||||
local bits = tonumber(bitsS)
|
||||
local maxVal = math.pow(2, bits-1)-1
|
||||
local minVal = -math.pow(2, bits-1)
|
||||
return string.format(wordRelStr,
|
||||
mnemPart, bits, maxVal, minVal, opcodeS, bits,
|
||||
mnemPart, bits, maxVal, minVal, opcodeS, bits
|
||||
)
|
||||
elseif mnem:find("imm8") then
|
||||
mnem = mnem:gsub("imm8", "{value: i8}")
|
||||
return mnem.." => "..opcodeS.." @ value"
|
||||
elseif mnem:find("imm16") then
|
||||
mnem = mnem:gsub("imm16", "{value: i16}")
|
||||
return mnem.." => "..opcodeS.." @ value"
|
||||
else
|
||||
return mnem.." => "..opcodeS
|
||||
end
|
||||
end
|
||||
local function getAsmsFromInstr(instr, aliases)
|
||||
local mnem = instr.mnem
|
||||
local t = {}
|
||||
if mnem then
|
||||
table.insert(t, getAsmCode(mnem, instr))
|
||||
if aliases[mnem] then
|
||||
for _, mnem2 in ipairs(aliases[mnem]) do
|
||||
table.insert(t, getAsmCode(mnem2, instr))
|
||||
end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local function archToUcode(arch)
|
||||
local sigs = sigsFromRoms(arch.roms)
|
||||
local ops = arch.operations
|
||||
@ -78,6 +142,7 @@ local function archToUcode(arch)
|
||||
local opcodesUsed = {}
|
||||
local numOpcodesUsed = 0
|
||||
local infolines = {}
|
||||
local asmlines = {}
|
||||
local catlet = "X"
|
||||
for _, instr in ipairs(arch.instructions) do
|
||||
if instr.category then
|
||||
@ -105,6 +170,9 @@ local function archToUcode(arch)
|
||||
if instr.desc then
|
||||
table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).." "..ncycles.." "..instr.desc.."\n")
|
||||
end
|
||||
|
||||
local asms = getAsmsFromInstr(instr, arch.aliases)
|
||||
for _, a in ipairs(asms) do table.insert(asmlines, a) end
|
||||
end
|
||||
end
|
||||
|
||||
@ -120,15 +188,28 @@ local function archToUcode(arch)
|
||||
table.insert(lt, "\n")
|
||||
end
|
||||
|
||||
-- Output instruction list
|
||||
local info = table.concat(infolines).."\n"..table.concat(lt)
|
||||
print(info)
|
||||
|
||||
--print(info)
|
||||
local fo = io.open("instructionList.txt", "w")
|
||||
if fo then
|
||||
fo:write(info)
|
||||
fo:close()
|
||||
end
|
||||
|
||||
|
||||
-- Output customASM definitions
|
||||
local fi = io.open("arch-8608-template.asm")
|
||||
local asmDataStr = fi:read("*a")
|
||||
fi:close()
|
||||
|
||||
local asmTable = string.format(asmDataStr, table.concat(asmlines, "\n\t"))
|
||||
local fo = io.open("arch-8608.asm", "w")
|
||||
if fo then
|
||||
fo:write(asmTable)
|
||||
fo:close()
|
||||
end
|
||||
|
||||
return ucode
|
||||
end
|
||||
|
@ -72,14 +72,20 @@ operations = {
|
||||
load162 = {"adrInc","loadReg","memSaveT"},
|
||||
store161 = { "storeReg"},
|
||||
store162 = {"adrInc","storeReg"},
|
||||
loadUTU = {"adrrUT","loadReg","memSaveU"},
|
||||
storeUT = {"adrrUT","storeReg"},
|
||||
loadUTU = {"adrrUT", "loadReg","memSaveU"},
|
||||
loadUTUP = {"adrrUT","adrlP","loadReg","memSaveU"},
|
||||
loadUTUQ = {"adrrUT","adrlQ","loadReg","memSaveU"},
|
||||
storeUT = {"adrrUT", "storeReg"},
|
||||
storeUTP = {"adrrUT","adrlP","storeReg"},
|
||||
storeUTQ = {"adrrUT","adrlQ","storeReg"},
|
||||
memSaveFlags = {"memSaveNZ"},
|
||||
|
||||
adwrUT = {"adwrhU","adwrlT"},
|
||||
adrrUT = {"adrrhU","adrrlT"},
|
||||
adwrCB = {"adwrhC","adwrlB"},
|
||||
adwIncUT = {"adwrUT","adwInc"},
|
||||
adwIncUT = {"adwrUT", "adwInc"},
|
||||
adwIncUTP = {"adwrUT","adwlP","adwInc"},
|
||||
adwIncUTQ = {"adwrUT","adwlQ","adwInc"},
|
||||
adwP = {"adwlP","adwSaveP"},
|
||||
adwQ = {"adwlQ","adwSaveQ"},
|
||||
adwS = {"adwlS","adwSaveS"},
|
||||
@ -159,10 +165,10 @@ instructions = {
|
||||
{ mnem="tst a" , opcode=0x14, {"alulA", "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} },
|
||||
{ mnem="tst b" , opcode=0x1E, {"alulB", "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} },
|
||||
{ mnem="tst c" , opcode=0x1F, {"alulC", "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} },
|
||||
{ mnem="inc *s+imm8", opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1 );","instrloadpre"} },
|
||||
{ mnem="dec *s+imm8", opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1 );","instrloadpre"} },
|
||||
{ mnem="icc *s+imm8", opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU", "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} },
|
||||
{ mnem="tst *s+imm8", opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU", "aluOpCmp" ,"instrNext"}, desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} },
|
||||
{ mnem="inc *s+imm8" , opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1 );","instrloadpre"} },
|
||||
{ mnem="dec *s+imm8" , opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1 );","instrloadpre"} },
|
||||
{ mnem="icc *s+imm8" , opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU", "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} },
|
||||
{ mnem="tst *s+imm8" , opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU", "aluOpCmp" ,"instrNext"}, desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} },
|
||||
|
||||
{ category = "16-bit Arithmetic", catlet = "X"},
|
||||
{ mnem="adp imm8" , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} },
|
||||
@ -191,24 +197,24 @@ instructions = {
|
||||
{ mnem="rol imm8" , opcode=0xD2, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
|
||||
{ mnem="ror imm8" , opcode=0xD3, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
|
||||
{ mnem="sra imm8" , opcode=0xD4, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
|
||||
{ mnem="add *s+imm8", opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} },
|
||||
{ mnem="adb *s+imm8", opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} },
|
||||
{ mnem="adc *s+imm8", opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} },
|
||||
{ mnem="sub *s+imm8", opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} },
|
||||
{ mnem="sbb *s+imm8", opcode=0x9D, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
|
||||
{ mnem="sbc *s+imm8", opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
|
||||
{ mnem="acc *s+imm8", opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
|
||||
{ mnem="scc *s+imm8", opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} },
|
||||
{ mnem="cmp *s+imm8", opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
|
||||
{ mnem="and *s+imm8", opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="ior *s+imm8", opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="xor *s+imm8", opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="ann *s+imm8", opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=~cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="shl *s+imm8", opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="shr *s+imm8", opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="rol *s+imm8", opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
|
||||
{ mnem="ror *s+imm8", opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
|
||||
{ mnem="sra *s+imm8", opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
|
||||
{ mnem="add *s+imm8" , opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} },
|
||||
{ mnem="adb *s+imm8" , opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} },
|
||||
{ mnem="adc *s+imm8" , opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} },
|
||||
{ mnem="sub *s+imm8" , opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} },
|
||||
{ mnem="sbb *s+imm8" , opcode=0x9D, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
|
||||
{ mnem="sbc *s+imm8" , opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
|
||||
{ mnem="acc *s+imm8" , opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
|
||||
{ mnem="scc *s+imm8" , opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} },
|
||||
{ mnem="cmp *s+imm8" , opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
|
||||
{ mnem="and *s+imm8" , opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="ior *s+imm8" , opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="xor *s+imm8" , opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="ann *s+imm8" , opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=~cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="shl *s+imm8" , opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="shr *s+imm8" , opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} },
|
||||
{ mnem="rol *s+imm8" , opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
|
||||
{ mnem="ror *s+imm8" , opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
|
||||
{ mnem="sra *s+imm8" , opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
|
||||
{ mnem="add b" , opcode=0xA0, {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags" , ccode={"addf(cpu.a,cpu.b); lni;"} },
|
||||
{ mnem="adc b" , opcode=0x9F, {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags" , ccode={"addf(cpu.c,cpu.b); lni;"} },
|
||||
{ mnem="sub b" , opcode=0xA1, {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags" , ccode={"subf(cpu.a,cpu.b); lni;"} },
|
||||
@ -246,7 +252,7 @@ instructions = {
|
||||
{ mnem="adc a" , opcode=0x4E, {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags" , ccode={"addf(cpu.c,cpu.a); lni;"} },
|
||||
{ mnem="sbc a" , opcode=0x4F, {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags" , ccode={"subf(cpu.c,cpu.a); lni;"} },
|
||||
|
||||
{ category = "Jumps", catlet="J" },
|
||||
{ category = "Jumps" , catlet="J" },
|
||||
{ mnem="jmp imm16" , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT" }, desc="I=imm16" , ccode={"loadimm161","loadimm162","jmpabsut"} },
|
||||
{ mnem="jsr imm16" , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} },
|
||||
{ mnem="jss imm16" , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} },
|
||||
@ -265,7 +271,7 @@ instructions = {
|
||||
{ mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if( cpu.nz && cpu.cf ) { jmprelt } else { lni }"} },
|
||||
{ mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} },
|
||||
|
||||
{ category = "Stack", catlet="S" },
|
||||
{ category = "Stack" , catlet="S" },
|
||||
{ mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} },
|
||||
{ mnem="psh b" , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} },
|
||||
{ mnem="psh c" , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} },
|
||||
@ -285,56 +291,74 @@ instructions = {
|
||||
{ mnem="lda imm8" , opcode=0x20, {"loadImmed", "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb imm8" , opcode=0x26, {"loadImmed", "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc imm8" , opcode=0x27, {"loadImmed", "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="lda *s+imm8", opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *s+imm8", opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *s+imm8", opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="sta *s+imm8", opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
|
||||
{ mnem="stb *s+imm8", opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
|
||||
{ mnem="stc *s+imm8", opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
|
||||
{ mnem="lda *imm16" , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *imm16" , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *imm16" , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="sta *imm16" , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurA","instrSub3"}, {"instrNext"}, desc="*imm16=A", ccode={"loadimm161","loadimm162","storeut(cpu.a);","lni;"} },
|
||||
{ mnem="stb *imm16" , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurB","instrSub3"}, {"instrNext"}, desc="*imm16=B", ccode={"loadimm161","loadimm162","storeut(cpu.b);","lni;"} },
|
||||
{ mnem="stc *imm16" , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurC","instrSub3"}, {"instrNext"}, desc="*imm16=C", ccode={"loadimm161","loadimm162","storeut(cpu.c);","lni;"} },
|
||||
{ mnem="sta *p" , opcode=0x52, {"adrlP","storeReg","alurA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} },
|
||||
{ mnem="stb *p" , opcode=0x5A, {"adrlP","storeReg","alurB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} },
|
||||
{ mnem="stc *p" , opcode=0x5B, {"adrlP","storeReg","alurC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} },
|
||||
{ mnem="sta *q" , opcode=0x54, {"adrlQ","storeReg","alurA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} },
|
||||
{ mnem="stb *q" , opcode=0x5C, {"adrlQ","storeReg","alurB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} },
|
||||
{ mnem="stc *q" , opcode=0x5D, {"adrlQ","storeReg","alurC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} },
|
||||
{ mnem="lda *p" , opcode=0x53, {"adrlP","loadReg","memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *p" , opcode=0x5E, {"adrlP","loadReg","memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *p" , opcode=0x5F, {"adrlP","loadReg","memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="lda *q" , opcode=0x55, {"adrlQ","loadReg","memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *q" , opcode=0x61, {"adrlQ","loadReg","memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *q" , opcode=0x62, {"adrlQ","loadReg","memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="sta *p++" , opcode=0xC0, {"adrlP","storeReg","alurA", "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} },
|
||||
{ mnem="stb *p++" , opcode=0xC1, {"adrlP","storeReg","alurB", "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} },
|
||||
{ mnem="stc *p++" , opcode=0xC2, {"adrlP","storeReg","alurC", "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} },
|
||||
{ mnem="sta *q++" , opcode=0xC3, {"adrlQ","storeReg","alurA", "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} },
|
||||
{ mnem="stb *q++" , opcode=0xC4, {"adrlQ","storeReg","alurB", "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} },
|
||||
{ mnem="stc *q++" , opcode=0xC5, {"adrlQ","storeReg","alurC", "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} },
|
||||
{ mnem="lda *p++" , opcode=0xC6, {"adrlP","loadReg","memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *p++" , opcode=0xC7, {"adrlP","loadReg","memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *p++" , opcode=0xC8, {"adrlP","loadReg","memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="lda *q++" , opcode=0xC9, {"adrlQ","loadReg","memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *q++" , opcode=0xCA, {"adrlQ","loadReg","memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *q++" , opcode=0xCB, {"adrlQ","loadReg","memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="lda *s+imm8" , opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *s+imm8" , opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *s+imm8" , opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="sta *s+imm8" , opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
|
||||
{ mnem="stb *s+imm8" , opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
|
||||
{ mnem="stc *s+imm8" , opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
|
||||
{ mnem="lda *imm16" , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);", "lni;"} },
|
||||
{ mnem="ldb *imm16" , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);", "lni;"} },
|
||||
{ mnem="ldc *imm16" , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);", "lni;"} },
|
||||
{ mnem="sta *imm16" , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*imm16=A", ccode={"loadimm161","loadimm162","storeut(cpu.a);", "lni;"} },
|
||||
{ mnem="stb *imm16" , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*imm16=B", ccode={"loadimm161","loadimm162","storeut(cpu.b);", "lni;"} },
|
||||
{ mnem="stc *imm16" , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*imm16=C", ccode={"loadimm161","loadimm162","storeut(cpu.c);", "lni;"} },
|
||||
{ mnem="lda *p+imm16", opcode=0x01, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadput; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *p+imm16", opcode=0xF7, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadput; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *p+imm16", opcode=0xFE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadput; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="lda *q+imm16", opcode=0xEB, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadqut; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *q+imm16", opcode=0x08, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadqut; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *q+imm16", opcode=0x09, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadqut; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="sta *p+imm16", opcode=0x0A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*P+imm16=A", ccode={"loadimm161","loadimm162","storeput(cpu.a);", "lni;"} },
|
||||
{ mnem="stb *p+imm16", opcode=0x0B, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*P+imm16=B", ccode={"loadimm161","loadimm162","storeput(cpu.b);", "lni;"} },
|
||||
{ mnem="stc *p+imm16", opcode=0x0C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*P+imm16=C", ccode={"loadimm161","loadimm162","storeput(cpu.c);", "lni;"} },
|
||||
{ mnem="sta *q+imm16", opcode=0x0D, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=A", ccode={"loadimm161","loadimm162","storequt(cpu.a);", "lni;"} },
|
||||
{ mnem="stb *q+imm16", opcode=0x0E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=B", ccode={"loadimm161","loadimm162","storequt(cpu.b);", "lni;"} },
|
||||
{ mnem="stc *q+imm16", opcode=0x0F, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=C", ccode={"loadimm161","loadimm162","storequt(cpu.c);", "lni;"} },
|
||||
{ mnem="lda *p" , opcode=0x53, {"adrlP","loadReg", "memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *p" , opcode=0x5E, {"adrlP","loadReg", "memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *p" , opcode=0x5F, {"adrlP","loadReg", "memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="lda *q" , opcode=0x55, {"adrlQ","loadReg", "memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *q" , opcode=0x61, {"adrlQ","loadReg", "memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *q" , opcode=0x62, {"adrlQ","loadReg", "memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="sta *p" , opcode=0x52, {"adrlP","storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} },
|
||||
{ mnem="stb *p" , opcode=0x5A, {"adrlP","storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} },
|
||||
{ mnem="stc *p" , opcode=0x5B, {"adrlP","storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} },
|
||||
{ mnem="sta *q" , opcode=0x54, {"adrlQ","storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} },
|
||||
{ mnem="stb *q" , opcode=0x5C, {"adrlQ","storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} },
|
||||
{ mnem="stc *q" , opcode=0x5D, {"adrlQ","storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} },
|
||||
{ mnem="lda *p++" , opcode=0xC6, {"adrlP","loadReg", "memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *p++" , opcode=0xC7, {"adrlP","loadReg", "memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *p++" , opcode=0xC8, {"adrlP","loadReg", "memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="lda *q++" , opcode=0xC9, {"adrlQ","loadReg", "memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} },
|
||||
{ mnem="ldb *q++" , opcode=0xCA, {"adrlQ","loadReg", "memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} },
|
||||
{ mnem="ldc *q++" , opcode=0xCB, {"adrlQ","loadReg", "memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} },
|
||||
{ mnem="sta *p++" , opcode=0xC0, {"adrlP","storeReg","alurA", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} },
|
||||
{ mnem="stb *p++" , opcode=0xC1, {"adrlP","storeReg","alurB", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} },
|
||||
{ mnem="stc *p++" , opcode=0xC2, {"adrlP","storeReg","alurC", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} },
|
||||
{ mnem="sta *q++" , opcode=0xC3, {"adrlQ","storeReg","alurA", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} },
|
||||
{ mnem="stb *q++" , opcode=0xC4, {"adrlQ","storeReg","alurB", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} },
|
||||
{ mnem="stc *q++" , opcode=0xC5, {"adrlQ","storeReg","alurC", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} },
|
||||
|
||||
{ category = "16-bit Load/Store", catlet="W" },
|
||||
{ mnem="ldp imm16" , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} },
|
||||
{ mnem="ldq imm16" , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} },
|
||||
{ mnem="lds imm16" , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} },
|
||||
{ mnem="ldv imm16" , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} },
|
||||
{ mnem="ldp *s+imm8", opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
|
||||
{ mnem="ldq *s+imm8", opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
|
||||
{ mnem="stp *s+imm8", opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} },
|
||||
{ mnem="stq *s+imm8", opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} },
|
||||
{ mnem="ldp *imm16" , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveP","instrSub3"}, {"adrlP","loadRegT","instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69
|
||||
{ mnem="ldq *imm16" , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT","instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B
|
||||
{ mnem="stp *imm16" , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurPH","instrSub3"}, {"storeUT","adrInc","alurPL","instrSub4"}, {"instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"} }, -- 0x6D
|
||||
{ mnem="stq *imm16" , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurQH","instrSub3"}, {"storeUT","adrInc","alurQL","instrSub4"}, {"instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"} }, -- 0x6F
|
||||
{ mnem="ldp *s+imm8" , opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
|
||||
{ mnem="ldq *s+imm8" , opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
|
||||
{ mnem="stp *s+imm8" , opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} },
|
||||
{ mnem="stq *s+imm8" , opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} },
|
||||
{ mnem="ldp *imm16" , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69
|
||||
{ mnem="ldq *imm16" , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B
|
||||
{ mnem="stp *imm16" , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurPH", "instrSub3"}, {"storeUT","adrInc","alurPL", "instrSub4"}, { "instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } }, -- 0x6D
|
||||
{ mnem="stq *imm16" , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurQH", "instrSub3"}, {"storeUT","adrInc","alurQL", "instrSub4"}, { "instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } }, -- 0x6F
|
||||
{ mnem="ldp *p+imm16", opcode=0xEC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xED
|
||||
{ mnem="ldq *p+imm16", opcode=0xEE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xEF
|
||||
{ mnem="ldp *q+imm16", opcode=0xF8, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xF9
|
||||
{ mnem="ldq *q+imm16", opcode=0xFA, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xFB
|
||||
{ mnem="stq *p+imm16", opcode=0x06, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTQ","alurQH", "instrSub3"}, {"storeUTQ","adrInc","alurQL","instrSub4"}, { "instrNext"}, desc="*P+imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } }, -- 0x07
|
||||
{ mnem="stp *q+imm16", opcode=0xFC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTP","alurPH", "instrSub3"}, {"storeUTP","adrInc","alurPL","instrSub4"}, { "instrNext"}, desc="*Q+imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } }, -- 0xFD
|
||||
{ mnem="ldp *p" , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} },
|
||||
{ mnem="ldq *p" , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} },
|
||||
{ mnem="ldp *q" , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} },
|
||||
@ -346,7 +370,7 @@ instructions = {
|
||||
{ mnem="stp *q++" , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} },
|
||||
{ mnem="stq *p++" , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} },
|
||||
|
||||
{ category = "Moves", catlet="M" },
|
||||
{ category = "Moves" , catlet="M" },
|
||||
{ mnem="lda b" , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} },
|
||||
{ mnem="lda c" , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} },
|
||||
{ mnem="ldb a" , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} },
|
||||
@ -373,8 +397,8 @@ instructions = {
|
||||
},
|
||||
|
||||
aliases = {
|
||||
["jpz imm8"] = {"jeq imm8"},
|
||||
["jnz imm8"] = {"jne imm8"},
|
||||
["jpz imm8" ] = {"jeq imm8"},
|
||||
["jnz imm8" ] = {"jne imm8"},
|
||||
["jmp q" ] = {"ret" },
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user