drive/solve/solve.s
2022-07-13 13:03:54 -04:00

404 lines
6.4 KiB
ArmAsm

; vim: ft=nasm
s:
%macro i_nop 0
db 0x00
%endmacro
%define np i_nop
%macro i_halt 1
db 0x01
db %1
%endmacro
%define ht i_halt
; load <mem> <value>
%macro i_load 2
db 0x10
db %1
db %2
%endmacro
%define ld i_load
; send <device> <mem>
%macro i_send 2
db 0x20
db %1
db %2
%endmacro
%define sd i_send
; get <mem> <device>
%macro i_get 2
db 0x21
db %1
db %2
%endmacro
%define gt i_get
; jlt <a>, <b>, <loc>
; a < b
%macro i_less 3
db 0x50
db %1
db %2
db (%3 >> 8) & 0xff
db %3 & 0xff
%endmacro
%define jl i_less
; jle <a>, <b>, <loc>
; a <= b
%macro i_leq 3
db 0x51
db %1
db %2
db (%3 >> 8) & 0xff
db %3 & 0xff
%endmacro
%define le i_leq
%macro break 0
sd disp, 0x00
sd disp, 0x01
sd disp, 0x02
sd disp, 0x03
np
%endmacro
%define inp 0
%define disp 1
%define arith 2
%define tape 3
gt 0x00, inp
gt 0x01, inp
gt 0x02, inp
gt 0x03, inp
; [a, b, c, d] -> mem
sd tape, 0x00
sd tape, 0x02
sd tape, 0x01
sd tape, 0x03
; {a, b, c, d}
sd arith, 0x00
sd arith, 0x03
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x03, arith
; [i[0], i[1], i[2], i[3] + i[0]]
; - add i[3] and i[0]
sd arith, 0x01
sd arith, 0x03
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x03, arith
; [i[0], i[1], i[2], (i[3] + i[0]) ^ i[1]]
; - xor i[1] with i[3] + i[0], pop from arith
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[0] + i[1], i[1], i[2], (i[3] + i[0]) ^ i[1]]
; - add i[0] and i[1], pop from arith
sd arith, 0x00
sd arith, 0x02
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x02, arith
; [i[0] + i[1], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor i[0] + i[1] with i[2], pop from arith
sd arith, 0x00
sd arith, 0x02
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[2], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor (i[0] + i[1]) ^ i[2] with i[0] + i[1], pop from arith
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x01, arith
sd arith, 0x01
; [i[2], i[2] + i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - add i[2] + i[1], pop from arith | store i[2] + i[1] in arith
gt 0x01, tape
sd arith, 0x01
; [i[2], i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - pop i[3] from tape use previous i[1] + i[2] from arith to xor
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x01, arith
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - use previous i[1] + i[2] from arith to xor and pop
sd arith, 0x00
gt 0x00, tape
; [i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[2] in arith, pop i[1] from tape
sd arith, 0x00
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[2] + i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[1] in arith, add, pop
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor i[2] + i[1] with (i[2] + i[1]) ^ i[3]
sd arith, 0x00
gt 0x00, tape
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[3] in arith, pop i[2] from tape
sd arith, 0x00
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[2] + i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[2] in arith, add to i[3]
sd arith, 0x00
gt 0x00, tape
; [i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[2] + i[3] in arith, pop i[0] from tape
sd arith, 0x00
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [(i[2] + i[3]) ^ i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor in arith
sd tape, 0x00
sd tape, 0x01
sd tape, 0x02
sd tape, 0x03
gt 0x01, tape
gt 0x02, tape
gt 0x03, tape
gt 0x00, tape
; push all to tape
; pop all back into mem in correct spot
; stage 1 done
; :b [a, b, c, d] (, ,)
sd tape, 0x01
; :b [a, b, c, d] (b, , )
sd arith, 0x01
; :b [a, 0, c, d] (b, 0, +)
ld 0x01, 0x00
sd arith, 0x01
ld 0x01, 0x01
sd arith, 0x01
; :b [a, t, c, d] (b, 0, +)
sd tape, 0x03
gt 0x01, tape
; :b t [a, t, c, d] (b, 0, +)
sd tape, 0x01
; :b t [a, b, c, d] ()
gt 0x01, arith
loop:
; :b t c [a * c, b, 0, d] ()
sd tape, 0x02
sd tape, 0x03 ; :b t c d [a, b, c, d]
sd tape, 0x00
gt 0x03, tape ; :b t c d [a, b, c, a]
multip:
sd arith, 0x02
ld 0x02, 0x01
sd arith, 0x02
ld 0x02, 0x02 ; sub 1 from c
sd arith, 0x02
gt 0x02, arith
sd arith, 0x00
sd arith, 0x03
ld 0x00, 0x01 ; a + a
sd arith, 0x00
gt 0x00, arith
sd tape, 0x00 ; :b t c d a+a [a+a, b, c-1, a]
ld 0x00, 0x01 ; :b t c d a+a [1, b, c-1, a]
le 0x02, 0x00, leavemul - s
gt 0x00, tape ; put back a + a
; :b t c d [a+a, b, c-1, a]
le 0x00, 0x00, multip - s ; jump to mul
leavemul:
gt 0x00, tape
gt 0x03, tape
gt 0x02, tape
; :b t [a * c, b, c, d] ()
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; :b t [a * c + b, b, c, d] ()
modulo:
jl 0x00, 0x03, leavemod - s
sd arith, 0x00
sd arith, 0x03
sd tape, 0x00
ld 0x00, 0x02
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
le 0x00, 0x00, modulo - s
leavemod:
; :b t [(ac + b) % d, b, c, d] ()
gt 0x01, tape
; :b [(ac + b) % d, t, c, d] ()
sd arith, 0x01
ld 0x01, 0x01
; :b [(ac + b) % d, 1, c, d] (t, )
sd arith, 0x01
ld 0x01, 0x02
sd arith, 0x01
; :b [(ac + b) % d, 1, c, d] (t, 1, -)
gt 0x01, arith
; :b [(ac + b) % d, t-1, c, d] ()
sd tape, 0x02
ld 0x02, 0x00
le 0x01, 0x02, finish - s
gt 0x02, tape
; if t - 1 leq 0 -> jump out
; else -> continue
sd arith, 0x02
; :b [(ac + b) % d, t-1, c, d] (c, ,)
ld 0x02, 0x00
sd arith, 0x02
ld 0x02, 0x01
sd arith, 0x02
; :b [(ac + b) % d, t-1, 0, d] (c, 0, +)
gt 0x02, tape
; : [(ac + b) % d, t-1, b, d] (c, 0, +)
sd tape, 0x02
; :b [(ac + b) % d, t-1, b, d] (c, 0, +)
sd tape, 0x01
; :b t-1 [(ac + b) % d, t-1, b, d] (c, 0, +)
sd tape, 0x02
; :b t-1 b [(ac + b) % d, t-1, b, d] (c, 0, +)
gt 0x02, arith
; :b t-1 b [(ac + b) % d, t-1, c, d] ()
gt 0x01, tape
; :b t-1 [(ac + b) % d, b, c, d] ()
le 0x03, 0x03, loop - s
; if d leq d -> jump loop
finish:
gt 0x02, tape
gt 0x01, tape
sd disp, 0x00
sd disp, 0x01
sd disp, 0x02
sd disp, 0x03
; finish things
;le 0x00, 0x01, label
;sd disp, 0x00
;label:
; sd disp, 0x01