forked from lawrencewoodman/subleq_vic20
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
subleq.a65
211 lines (184 loc) · 5.83 KB
/
subleq.a65
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
;=====================================================================
; SUBLEQ Virtual Machine
; Author Lawrence woodman <lwoodman@vlifesystems.com>
; Date 31st March 2020
;---------------------------------------------------------------------
; Include as needed
;---------------------------------------------------------------------
; Copyright (C) 2020 Lawrence Woodman <lwoodman@vlifesystems.com>
; Licensed under an MIT licence. Please see LICENCE.md for details.
;=====================================================================
; TODO Check and document locations and probs
SL_A = $A7 ; A Operand
SL_B = $A9 ; B Operand
SL_C = $AB ; C Operand
SL_PC = $BE ; TODO Find better location
SL_HPTR = $92 ; TODO Find better location
SL_NPTR = $94 ; TODO Find better location
SL_SKIPSUB = $96 ; TODO Find better location
SL_AVAL = $3B ; TODO Find better location
; SUBLEQ Ports
SL_IN = -1
SL_OUT = -1
;-------------------------------------------------
; Run program
;-------------------------------------------------
; Args:
; SL_MEM Location of SUBLEQ memory
;-------------------------------------------------
; TODO check if A, B, and C are in range?
;-------------------------------------------------
SL_run .(
GETIN = $FFE4
CCHROUT = $FFD2
; Zero PC
lda #00
sta SL_PC
sta SL_PC+1
fetch ; Check if PC valid (PC >= 0)
lda SL_PC+1
and #128 ; Most significant bit (sign bit)
beq fetch1
jmp halt
;--------------------
; Fetch operands A,B,C
;--------------------
fetch1 ; Calc native pointer for PC
lda SL_PC
sta SL_HPTR
lda SL_PC+1
sta SL_HPTR+1
jsr SL_CalcNPTR
; Get A,B,C
ldy #05
floop lda (SL_NPTR),y
sta SL_A,y
dey
bpl floop
; Move PC to start of next operands
clc
lda SL_PC
adc #03
sta SL_PC
bcc fetchEnd
inc SL_PC+1
fetchEnd
; Check if A == -1 indicating that input should go to mem[B]
lda #00
sta SL_SKIPSUB
lda SL_A
cmp #<(SL_IN)
bne getAMemVal
lda SL_A+1
cmp #>(SL_IN)
bne getAMemVal
; Get character from input
inc SL_SKIPSUB ; Record that should skip sub
getChar jsr GETIN
cmp #00
beq getChar ; Wait until a character is pressed
sta SL_AVAL
lda #00
sta SL_AVAL+1
jmp output
getAMemVal ; Calc native pointer for A and get mem[A]
lda SL_A
sta SL_HPTR
lda SL_A+1
sta SL_HPTR+1
jsr SL_CalcNPTR
ldy #00
lda (SL_NPTR), y
sta SL_AVAL
iny
lda (SL_NPTR), y
sta SL_AVAL+1
;--------------------------------------
; Output mem[A] or input to display
; if B == -1 and move to next operands
;--------------------------------------
output ; Check if B == -1 indicating that mem[A] should be output
lda SL_B
cmp #<(SL_OUT)
bne endOutput
lda SL_B+1
cmp #>(SL_OUT)
bne endOutput
; Output LSB of mem[A] to display
lda SL_AVAL
jsr CCHROUT
jmp fetch
endOutput
; Calc native pointer B
lda SL_B
sta SL_HPTR
lda SL_B+1
sta SL_HPTR+1
jsr SL_CalcNPTR
; Check if should skip sub
lda SL_SKIPSUB
beq sub
; Store value indicated by A to mem[B]
ldy #00
lda SL_AVAL
sta (SL_NPTR), y ; SL_NPTR is B as a native pointer
iny
lda SL_AVAL+1
sta (SL_NPTR), y
jmp fetch
;-----------------------------------
; Perform subtraction
; mem[B] = mem[B] - mem[A]
; TODO create routine to repoint A and B and use before SL_Output
;-----------------------------------
; mem[B] = mem[B] - mem[A]
sub ldy #00
sec
lda (SL_NPTR), y ; SL_NPTR is B as a native pointer
sbc SL_AVAL
sta (SL_NPTR), y
iny
lda (SL_NPTR), y
sbc SL_AVAL+1
sta (SL_NPTR), y
; if (mem[B] <= 0) goto C
; SL_NPTR is B as a native pointer
lda (SL_NPTR), y ; Y is 1 from above
bmi jump
lda (SL_NPTR), y
bne fetch3
dey ; Y will now be 0
lda (SL_NPTR), y
bne fetch3
; Goto C
jump lda SL_C
sta SL_PC
lda SL_C+1
sta SL_PC+1
fetch3 jmp fetch
halt rts
.)
;---------------------------------
; Calculate the pointer to native
; memory from the host pointer.
; SL_HPTR - host pointer
; SL_NPTR - native pointer
;---------------------------------
SL_CalcNPTR ; First double SL_HPTR because host memory is
; stored as 16-bit words
clc
lda SL_HPTR
adc SL_HPTR
sta SL_NPTR
lda SL_HPTR+1
adc SL_HPTR+1
sta SL_NPTR+1
; Base pointer off SL_MEM
clc
lda SL_NPTR
adc #<SL_MEM
sta SL_NPTR
lda SL_NPTR+1
adc #>SL_MEM
sta SL_NPTR+1
rts