-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathmonitor.s
307 lines (278 loc) · 7.03 KB
/
monitor.s
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# Warren's monitor ROM for the CSCvon8 CPU
# (c) 2019, GPL3
#define printstr(x) LHA x; STO A strptr; LCA x; STO A strptr+1; JSR puts
#define putc(x) LCA x; JOU .; OUT A
#define getc(x) JIU .; INA; STO A x
#define JOUT(x) JOU .; OUT x
#define JINA JIU .; INA
main: NOP # Six NOPs are needed for the CPU to
NOP # "settle down" after Reset# goes high
NOP
NOP
NOP
NOP
LCB $00 # Print out the welcome message
1: LDA welcome,B
JAZ prompt
JOUT(A)
LDB B+1
JMP 1b
prompt: putc('>') # Print out the prompt
putc(' ')
getc(cmdchar) # Get the command letter and
JOUT(A) # echo it out to the user
LCB '\n' # Loop when we get a newline
JEQ prompt
LCB '\r' # Loop when we get a carriage return
JEQ prompt
STO 0 hexcnt # Set count of hex chars to zero
sploop: JINA # Get further characters and echo them
JOUT(A)
LCB ' ' # Skip spaces
JEQ sploop
LCB '\n' # Exit when we get a newline
JEQ docmd
LCB '\r' # Exit when we get a carriage return
JEQ docmd
LDB hexcnt # Assume it's a hex digit, store it
STO A hexchar,B
STO B+1 hexcnt # Increment the counter
LCA $03
JEQ waitnl # Exit loop when B==3 (highest offset)
JMP sploop # Otherwise loop back
waitnl: JINA # Echo chars until a '\n' or '\r'
JOUT(A)
LCB '\n'
JEQ cvtaddr
LCB '\r'
JEQ cvtaddr
JMP waitnl
cvtaddr: JSR hexcvt # Convert the four characters into an address
docmd: JOUT('\n')
LDA cmdchar # Get the command character
LCB '?' # ?, print the usage
JEQ printusage
LCB 'D' # D and d, dump memory
JEQ dump
LCB 'd'
JEQ dump
LCB 'R' # R and r, run code at addr
JEQ run
LCB 'r'
JEQ run
LCB 'C' # C and c, change memory
JEQ change
LCB 'c'
JEQ change
LCB 'X' # X and x, exit csim
JEQ terminate
LCB 'x'
JEQ terminate
newprompt:
JOUT('\r')
JOUT('\n')
JMP prompt
terminate:
JMP $FFFF
printusage:
printstr(usage)
JMP prompt
run: LCB $70 # Set a JMP instruction
STO B jmpaddr # at the jmpaddr and go there
JMP jmpaddr
JMP prompt
dump: LCB $0F # Set a count of 15, which will be 16
STO B count
LDB addr # Print out the address in hex
STO B hexchar
JSR prhex
LDB addr+1
STO B hexchar
JSR prhex
JOUT(':')
JOUT(' ')
1: LIA addr # Get a byte through the pointer
STO A hexchar
JSR prhex # Print it in hex
JOUT(' ') # followed by a space
LDB count # Decrement the count
LDB B-1
JBN 2f # Exit when we get to $FF
STO B count
LDB addr+1 # Keep going, so move the pointer up
STO B+1 addr+1
JMP 1b # and loop back
2: JOUT('\r')
JOUT('\n') # End of loop, print a newline
LDB addr+1 # Also bump up the address for the next dump
STO B+1 addr+1
TST B+1 JC 3f
JMP prompt
3: LDB addr
STO B+1 addr
JMP prompt
change:
printstr(setstr)
changeloop:
JINA # Get a character and echo it
JOUT(A)
LCB ' '
JEQ changeloop # Start afresh for spaces and newlines
LCB '\n'
JEQ changeloop
LCB '\r'
JEQ changeloop
LCB 'Z' # If we get a 'Z' or 'z', end of changes
JEQ newprompt
LCB 'z'
JEQ newprompt
STO A hexchar # Store first hex nibble, do it again
JINA # Get a character and echo it
JOUT(A)
LCB ' '
JEQ changeloop # Start afresh for spaces and newlines
LCB '\n'
JEQ changeloop
LCB '\r'
JEQ changeloop
LCB 'Z' # If we get a 'Z' or 'z', end of changes
JEQ newprompt
LCB 'z'
JEQ newprompt
STO A hexchar2 # Store second hex nibble
JSR bytecvt # Convert to a single byte in cmdchar
LDA cmdchar
SIA addr # Store the byte through the addr pointer
LDB addr+1 # Increment the addr pointer
STO B+1 addr+1
TST B+1 JC 1f
JMP changeloop
1: LDB addr
STO B+1 addr
JMP changeloop
## puts subroutine
##
puts: LIA strptr # Get character through the ptr
JAZ 1f # Exit when we get the NUL character
JOU . # Print out the character
OUT A
LDB strptr+1 # Increment the low byte of the pointer
STO B+1 strptr+1
JMP puts # and loop back
1: RTS puts
## hexcvt subroutine. Given four hex digits stored in the hexchar
# buffer, convert them into a 16-bit big endian address
# stored in addr.
hexcvt: LDB hexchar # Get the first character
LCA $3F # Add on $3F
LDA A+B
JAN 1f # If -ve, was A-F
LDA B
JMP 2f # Otherwise, was a 0-9 char
1: LCB $0A # Add on $0A to convert char to nibble
LDA A+B
2: LCB $04
STO addr A<<B # Save top nibble into addr
LDB hexchar2 # Repeat the process on the 2nd char
LCA $3F # Add on $3F
LDA A+B
JAN 3f # If -ve, was A-F
LDA B
JMP 4f # Otherwise, was a 0-9 char
3: LCB $0A # Add on $0A to convert char to nibble
LDA A+B
4: LCB $0F # Get the low nibble
LDB A&B
LDA addr
STO addr A|B # Combine both nibbles and store
LDB hexchar3 # Repeat the process on the 3rd char
LCA $3F # Add on $3F
LDA A+B
JAN 5f # If -ve, was A-F
LDA B
JMP 6f # Otherwise, was a 0-9 char
5: LCB $0A # Add on $0A to convert char to nibble
LDA A+B
6: LCB $04
STO addr+1 A<<B # Save top nibble into addr
LDB hexchar4 # Repeat the process on the 4th char
LCA $3F # Add on $3F
LDA A+B
JAN 7f # If -ve, was A-F
LDA B
JMP 8f # Otherwise, was a 0-9 char
7: LCB $0A # Add on $0A to convert char to nibble
LDA A+B
8: LCB $0F # Get the low nibble
LDB A&B
LDA addr+1
STO addr+1 A|B # Combine both nibbles and store
RTS hexcvt
## bytecvt subroutine. Given two hex digits stored in the hexchar
# buffer, convert them into a 8-bit value stored in cmdchar
bytecvt:
LDB hexchar # Get the first character
LCA $3F # Add on $3F
LDA A+B
JAN 1f # If -ve, was A-F
LDA B
JMP 2f # Otherwise, was a 0-9 char
1: LCB $0A # Add on $0A to convert char to nibble
LDA A+B
2: LCB $04
STO cmdchar A<<B # Save top nibble into addr
LDB hexchar2 # Repeat the process on the 2nd char
LCA $3F # Add on $3F
LDA A+B
JAN 3f # If -ve, was A-F
LDA B
JMP 4f # Otherwise, was a 0-9 char
3: LCB $0A # Add on $0A to convert char to nibble
LDA A+B
4: LCB $0F # Get the low nibble
LDB A&B
LDA cmdchar
STO cmdchar A|B # Combine both nibbles and store
RTS bytecvt
# prhex function: Print the value in hexchar
# out as two hex digits
prhex: LDA hexchar # Load a copy of A
LCB $04 # Get high nibble of A
LDA A>>B
LCB $09
JGT 1f # Skip if in range A to F
LCB $30 # Otherwise add '0'
JMP 2f # and print it
1: LCB $37 # Add 55 to get it in 'A' to 'F'
2: LDA A+B
JOUT(A)
LDA hexchar # Get A back again
LCB $0F # Get the low nibble of A
LDA A&B
LCB $09
JGT 1f # Skip if in range A to F
LCB $30 # Otherwise add '0'
JMP 2f # and print it
1: LCB $37 # Add 55 to get it in 'A' to 'F'
2: LDA A+B
JOUT(A)
RTS prhex
# String constants
PAG
welcome: STR "[2J[HCSCvon8 Monitor, $Revision: 1.15 $, type ? for help\n\n"
usage: STR "Usage: D dump, C change, R run, ? help, X exit\n"
setstr: STR "Enter space separated hex digits, end with Z\n\n"
ORG $FF00
hexchar: HEX "00" # Place to store four hex chars, page aligned
hexchar2: HEX "00"
hexchar3: HEX "00"
hexchar4: HEX "00"
strptr: HEX "00" # String pointer for puts
HEX "00"
cmdchar: HEX "00" # Command character
hexcnt: HEX "00" # Count of hex chars left to store
jmpaddr: HEX "00"
addr: HEX "80" # Address used by all commands
HEX "00"
count: HEX "00" # 16-bit counter, used when loading a program
HEX "00"