diff options
| -rw-r--r-- | asm.myr | 41 |
1 files changed, 35 insertions, 6 deletions
@@ -40,8 +40,11 @@ type literal = union `Number int `Register int `Label byte[:] - `DerefAddr int - `DerefLabel byte[:] + `DerefAddr + `Keypress + `AddressRegister + `DelayTimer + `SoundTimer `Invalid ;; @@ -63,10 +66,15 @@ const parselit = {s |`std.None: -> `Invalid ;; elif s[0] == ('[' : byte) - match getnum(s[:s.len-1]) - |`std.Some(n): -> `DerefAddr(n) - |`std.None: -> `DerefLabel(s[:s.len-1]) - ;; + -> `DerefAddr + elif s[0] == ('K' : byte) + -> `Keypress + elif s[0] == ('I' : byte) + -> `AddressRegister + elif s[0] == ('D' : byte) + -> `DelayTimer + elif s[0] == ('S' : byte) + -> `SoundTimer else -> `Label(s) ;; @@ -170,6 +178,27 @@ const emitinstr = {p | _: -> `std.Err(std.fmt("invalid argument to SKNP: {}", p[1])) ;; + | "LD": + if p.len < 3 + -> `std.Err("LD missing arguments") + ;; + match (parselit(p[1]), parselit(p[2])) + | (`Register(n), `Keypress): b = `std.Some([0xf0 | (n & 0x0f), 0x0a]) + | (`Register(m), `Number(n)): b = `std.Some([0x60 | (m & 0x0f), (n & 0xff)]) + | (`Register(m), `Label(l)): b = `std.Some([0x60 | (m & 0x0f), 00]) + mark = `std.Some(strdup(l)) + | (`Register(m), `Register(n)): b = `std.Some([0x80 | (n & 0x0f), (m & 0x0f) << 1]) + | (`Register(n), `DelayTimer): b = `std.Some([0xf0 | (n & 0x0f), 0x07]) + | (`DelayTimer, `Register(n)): b = `std.Some([0xf0 | (n & 0x0f), 0x15]) + | (`SoundTimer, `Register(n)): b = `std.Some([0xf0 | (n & 0x0f), 0x18]) + | (`AddressRegister, `Number(n)): b = `std.Some([0xa0 | (n & 0x0f), (n & 0xff)]) + | (`AddressRegister, `Label(l)): b = `std.Some([0xa0, 0x00]) + mark = `std.Some(strdup(l)) + | (`DerefAddr, `Register(n)): b = `std.Some([0xf0 | (n & 0x0f), 0x55]) + | (`Register(n), `DerefAddr): b = `std.Some([0xf0 | (n & 0x0f), 0x65]) + | _: + -> `std.Err(std.fmt("invalid argument to LD: {}", p[1])) + ;; | _: -> `std.Err(std.fmt("unrecognized instruction {}", p[0])) ;; |