Fix a couple bugs in z80 assembly, support addresses + function args
This commit is contained in:
parent
4f40b3851b
commit
fb0c141653
35
asm/z80.fnl
35
asm/z80.fnl
|
@ -39,13 +39,6 @@
|
|||
(fn opform [opcode matchers prefixgen]
|
||||
(chain-op opcode #(try-parse-op $1 matchers prefixgen)))
|
||||
|
||||
(fn is-addr? [param] (= (type param) :string))
|
||||
(fn addr [param] (when (is-addr? param) {:addr param}))
|
||||
(fn rel-addr [param] (when (is-addr? param) {:rel8 param}))
|
||||
(fn num [param] (when (= (type param) :number) {:num param}))
|
||||
(fn imm16 [param] (when (= (type param) :number) {:imm16 param}))
|
||||
(fn imm8 [param] (when (= (type param) :number) {:imm8 param}))
|
||||
|
||||
(fn table-matcher [tbl key]
|
||||
(let [lookup (collect [i val (ipairs tbl)] val (- i 1))]
|
||||
(fn [param] (case (. lookup param) octet {key octet}))))
|
||||
|
@ -55,6 +48,18 @@
|
|||
#(when (argmatch [:hl] $1) {:reg 6})))
|
||||
(local rp (table-matcher [:bc :de :hl :sp] :rp))
|
||||
(local rp2 (table-matcher [:bc :de :hl :af] :rp))
|
||||
|
||||
(fn is-addr? [param] (and (= (type param) :string)
|
||||
(not= param :ix) (not= param :iy)
|
||||
(= (reg param) nil) (= (rp param) nil) (= (rp2 param) nil)))
|
||||
(fn is-computed? [param] (= (type param) :function))
|
||||
(fn is-number? [param] (= (type param) :number))
|
||||
(fn rel-addr [param] (when (is-addr? param) {:rel8 param}))
|
||||
(fn num [param] (when (or (is-number? param) (is-computed? param)) {:num param}))
|
||||
(fn imm16 [param] (when (or (is-number? param) (is-computed? param) (is-addr? param)) {:imm16 param}))
|
||||
(fn imm8 [param] (when (or (is-number? param) (is-computed? param)) {:imm8 param}))
|
||||
(local addr imm16)
|
||||
|
||||
(fn im [arg] (match arg
|
||||
0 {:im 0}
|
||||
1 {:im 2}
|
||||
|
@ -167,7 +172,7 @@
|
|||
; ED prefix
|
||||
(opform :in [reg [:c]] #(when (not= $1.reg 6) (.. "\xed" (xyz 1 $1.reg 0))))
|
||||
(opform :in [[:c]] #(.. "\xed" (xyz 1 6 0)))
|
||||
(opform :out [reg [:c]] #(when (not= $1.reg 6) (.. "\xed" (xyz 1 $1.reg 1))))
|
||||
(opform :out [[:c] reg] #(when (not= $1.reg 6) (.. "\xed" (xyz 1 $1.reg 1))))
|
||||
(opform :out [[:c]] #(.. "\xed" (xyz 1 6 1)))
|
||||
(opform :sbc [:hl rp] #(.. "\xed" (xpqz 1 $1.rp 0 2)))
|
||||
(opform :adc [:hl rp] #(.. "\xed" (xpqz 1 $1.rp 1 2)))
|
||||
|
@ -222,19 +227,23 @@
|
|||
(fn op-pdat.size [op env]
|
||||
(+ (length op.prefix)
|
||||
(case op
|
||||
{: addr} 2
|
||||
{: rel8} 1
|
||||
{: imm16} 2
|
||||
{: imm8} 1
|
||||
_ 0)))
|
||||
|
||||
(fn decode-number [param env]
|
||||
(case (type param)
|
||||
:number param
|
||||
:string (env:lookup-addr param)
|
||||
:function (param (setmetatable {} {:__index #(env:lookup-addr $2)}) env)))
|
||||
|
||||
(fn op-pdat.bytes [op env]
|
||||
(.. op.prefix
|
||||
(case op
|
||||
{: addr} (int16-to-bytes (env:lookup-addr addr))
|
||||
{: rel8} (int8-to-bytes (- (env:lookup-addr rel8) op.addr))
|
||||
{: imm16} (int16-to-bytes imm16)
|
||||
{: imm8} (int8-to-bytes imm8)
|
||||
{: rel8} (int8-to-bytes (- (env:lookup-addr rel8) (+ op.addr 2)))
|
||||
{: imm16} (int16-to-bytes (decode-number imm16 env))
|
||||
{: imm8} (int8-to-bytes (decode-number imm8 env))
|
||||
_ "")))
|
||||
|
||||
{: opcodes : parse-op : op-pdat : try-parse-op}
|
||||
|
|
Loading…
Reference in a new issue