0
|
1 ;Buggy machine language monitor and rudimentary O.S. version 1.0
|
|
2
|
|
3 * Memory map of SBC
|
|
4 * $0-$40 Zero page variables reserved by monitor and O.S.
|
|
5 * $40-$FF Zero page portion for user programs.
|
|
6 * $100-$17F Xmodem buffer 0, terminal input buffer,
|
|
7 * $180-$1FF Xmodem buffer 1, terminal output buffer.
|
|
8 * $200-$27F Terminal input line.
|
|
9 * $280-$2FF Variables reserved by monitor and O.S.
|
|
10 * $300-$400 System stack.
|
|
11 * $400-$7FFF RAM for user programs and data.
|
|
12 * $8000-$DFFF PROM for user programs.
|
|
13 * $E000-$E1FF I/O addresses.
|
|
14 * $E200-$E3FF Reserved.
|
|
15 * $E400-$FFFF Monitor ROM
|
|
16
|
|
17 * Reserved Zero page addresses
|
|
18 org $0000
|
|
19 * First the I/O routine vectors.
|
|
20 getchar rmb 3 ;Jump to getchar routine.
|
|
21 putchar rmb 3 ;Jump to putchar routine.
|
|
22 getline rmb 3 ;Jump to getline routine.
|
|
23 putline rmb 3 ;Jump to putline routine.
|
|
24 putcr rmb 3 ;Jump to putcr routine.
|
|
25 getpoll rmb 3 ;Jump to getpoll routine.
|
|
26 xopenin rmb 3 ;Jump to xopenin routine.
|
|
27 xopenout rmb 3 ;Jump to xopenout routine.
|
|
28 xabortin rmb 3 ;Jump to xabortin routine.
|
|
29 xclosein rmb 3 ;Jump to xclosein routine.
|
|
30 xcloseout rmb 3 ;Jump to xcloseout routine.
|
|
31 delay rmb 3 ;Jump to delay routine.
|
|
32
|
|
33 *Next the system variables in the zero page.
|
|
34 temp rmb 2 ;hex scanning/disasm
|
|
35 temp2 rmb 2 ;Hex scanning/disasm
|
|
36 temp3 rmb 2 ;Used in Srecords, H command
|
|
37 timer rmb 3 ;3 byte timer, incremented every 20ms
|
|
38 xpacknum rmb 1 ;Packet number for XMODEM block,
|
|
39 xsum rmb 1 ;XMODEM checksum
|
|
40 lastok rmb 1 ;flag to indicate last block was OK
|
|
41 xcount rmb 1 ;Count of characters in buffer.
|
|
42 xmode rmb 1 ;XMODEM mode, 0 none, 1 out, 2 in.
|
|
43 disflg rmb 1
|
|
44
|
|
45 * I/O buffers.
|
|
46 buflen equ 128 ;Length of input line buffer.
|
|
47 org $100
|
|
48 buf0 rmb 128 ;Xmodem buffer 0, serial input buffer.
|
|
49 buf1 rmb 128 ;Xmodem buffer 1, serial output buffer.
|
|
50 linebuf rmb buflen ;Input line buffer.
|
|
51
|
|
52
|
|
53 * Interrupt vectors (start at $280)
|
|
54 * All interrupts except RESET are vectored through jumps.
|
|
55 * FIRQ is timer interrupt, IRQ is ACIA interrupt.
|
|
56 swi3vec rmb 3
|
|
57 swi2vec rmb 3
|
|
58 firqvec rmb 3
|
|
59 irqvec rmb 3
|
|
60 swivec rmb 3
|
|
61 nmivec rmb 3
|
|
62 xerrvec rmb 3 ;Error handler for XMODEM error.
|
|
63 exprvec rmb 3 ;Expression evaluator in assembler.
|
|
64 asmerrvec rmb 3 ;Error handler for assembler errors.
|
|
65 pseudovec rmb 3 ;Vector for asm pseudo instructions.
|
|
66
|
|
67 * Next the non zero page system variables.
|
|
68 oldpc rmb 2 ;Saved pc value for J command.
|
|
69 addr rmb 2 ;Address parameter.
|
|
70 length rmb 2 ;Length parameter.
|
|
71
|
|
72 brkpoints equ 8 ;Number of settable breakpoints.
|
|
73 bpaddr rmb brkpoints*3 ;Address and byte for each break point.
|
|
74 stepbp rmb 3 ;Address of P command break point.
|
|
75
|
|
76 sorg rmb 2 ;Origin address of S record entry.
|
|
77 soffs rmb 2 ;Offset load adrr-addr in record
|
|
78
|
|
79 oldgetc rmb 2 ;Old getchar address.
|
|
80 oldputc rmb 2 ;Old putchar address.
|
|
81 oldputcr rmb 2 ;Old putcr address.
|
|
82 lastterm rmb 1 ;Last terminating character.
|
|
83 filler rmb 1 ;Filler at end of XMODEM file.
|
|
84 xmcr rmb 1 ;end-of-line characters for XMODEM send.
|
|
85 savesp rmb 2 ;Save sp to restore it on error.
|
|
86 nxtadd rmb 2
|
|
87
|
|
88 * Following variables are used by assembler/disassembler.
|
|
89 prebyte rmb 1
|
|
90 opc1 rmb 1
|
|
91 opcode rmb 1
|
|
92 postbyte rmb 1
|
|
93 amode rmb 1
|
|
94 operand rmb 2
|
|
95 mnembuf rmb 5 ;Buffer to store capitalized mnemonic.
|
|
96 opsize rmb 1 ;SIze (in bytes) of extra oeprand (0--2)
|
|
97 uncert rmb 1 ;Flag to indicate that op is unknown.
|
|
98 dpsetting rmb 2
|
|
99
|
|
100 endvars equ *
|
|
101
|
|
102 ramstart equ $400 ;first free RAM address.
|
|
103
|
|
104 ramtop equ $8000 ;top of RAM.
|
|
105
|
|
106 * I/O port addresses
|
|
107 aciactl equ $e000 ;Control port of ACIA
|
|
108 aciasta equ $e000 ;Status port of ACIA
|
|
109 aciadat equ $e001 ;Data port of ACIA
|
|
110
|
|
111 * ASCII control characters.
|
|
112 SOH equ 1
|
|
113 EOT equ 4
|
|
114 ACK equ 6
|
|
115 BS equ 8
|
|
116 TAB equ 9
|
|
117 LF equ 10
|
|
118 CR equ 13
|
|
119 NAK equ 21
|
|
120 CAN equ 24
|
|
121 DEL equ 127
|
|
122
|
|
123 CASEMASK equ $DF ;Mask to make lowercase into uppercase.
|
|
124
|
|
125 * Monitor ROM starts here.
|
|
126 org $E400
|
|
127
|
|
128 reset orcc #$FF ;Disable interrupts.
|
|
129 clra
|
|
130 tfr a,dp ;Set direct page register to 0.
|
|
131 clr disflg
|
|
132 lds #ramstart
|
|
133 ldx #intvectbl
|
|
134 ldu #swi3vec
|
|
135 ldb #osvectbl-intvectbl
|
|
136 bsr blockmove ;Initialize interrupt vectors from ROM.
|
|
137 ldx #osvectbl
|
|
138 ldu #0
|
|
139 ldb #endvecs-osvectbl
|
|
140 bsr blockmove ;Initialize I/O vectors from ROM.
|
|
141 bsr initacia ;Initialize serial port.
|
|
142 andcc #$0 ;Enable interrupts
|
|
143 * Put the 'saved' registers of the program being monitored on top of the
|
|
144 * stack. There are 12 bytes on the stack for cc,b,a,dp,x,y,u and pc
|
|
145 * pc is initialized to $400, the rest to zero.
|
|
146 ldx #0
|
|
147 tfr x,y
|
|
148 ldu #ramstart
|
|
149 pshs x,u
|
|
150 pshs x,y
|
|
151 pshs x,y
|
|
152 ldx #oldpc
|
|
153 ldb #endvars-oldpc
|
|
154 clvar clr ,x+
|
|
155 decb
|
|
156 bne clvar ;Clear the variable area.
|
|
157 ldd #$1A03
|
|
158 std filler ;Set XMODEM filler and end-of-line.
|
|
159 ldx #welcome
|
|
160 jsr outcount
|
|
161 jsr putcr ;Print a welcome message.
|
|
162 jmp cmdline
|
|
163 * Block move routine, from X to U length B. Modifies them all and A.
|
|
164 blockmove lda ,x+
|
|
165 sta ,u+
|
|
166 decb
|
|
167 bne blockmove
|
|
168 rts
|
|
169
|
|
170 * Initialize serial communications port, buffers, interrupts.
|
|
171 initacia ldb #$03
|
|
172 stb aciactl
|
|
173 ldb #%00110101
|
|
174 rts
|
|
175
|
|
176 * O.S. routine to read a character into B register.
|
|
177 osgetc ldb aciasta
|
|
178 bitb #$01
|
|
179 beq osgetc
|
|
180 ldb aciadat
|
|
181 rts
|
|
182
|
|
183 ;O.S. rotuine to check if there is a character ready to be read.
|
|
184 osgetpoll ldb aciasta
|
|
185 bitb #$01
|
|
186 bne poltrue
|
|
187 clrb
|
|
188 rts
|
|
189 poltrue ldb #$ff
|
|
190 rts
|
|
191
|
|
192 * O.S. routine to write the character in the B register.
|
|
193 osputc pshs a
|
|
194 putcloop lda aciasta
|
|
195 bita #$02
|
|
196 beq putcloop
|
|
197 stb aciadat
|
|
198 puls a
|
|
199 rts
|
|
200
|
|
201 * O.S. routine to read a line into memory at address X, at most B chars
|
|
202 * long, return actual length in B. Permit backspace editing.
|
|
203 osgetl pshs a,x
|
|
204 stb temp
|
|
205 clra
|
|
206 osgetl1 jsr getchar
|
|
207 andb #$7F
|
|
208 cmpb #BS
|
|
209 beq backsp
|
|
210 cmpb #DEL
|
|
211 bne osgetl2
|
|
212 backsp tsta ;Recognize BS and DEL as backspace key.
|
|
213 beq osgetl1 ;ignore if line already zero length.
|
|
214 ldb #BS
|
|
215 jsr putchar
|
|
216 ldb #' '
|
|
217 jsr putchar
|
|
218 ldb #BS ;Send BS,space,BS. This erases last
|
|
219 jsr putchar ;character on most terminals.
|
|
220 leax -1,x ;Decrement address.
|
|
221 deca
|
|
222 bra osgetl1
|
|
223 osgetl2 cmpb #CR
|
|
224 beq newline
|
|
225 cmpb #LF
|
|
226 bne osgetl3 ;CR or LF character ends line.
|
|
227 ldb lastterm
|
|
228 cmpb #CR
|
|
229 beq osgetl1 ;Ignore LF if it comes after CR
|
|
230 ldb #LF
|
|
231 newline stb lastterm
|
|
232 jsr putcr
|
|
233 tfr a,b ;Move length to B
|
|
234 puls a,x ;restore registers.
|
|
235 rts ;<--- Here is the exit point.
|
|
236 osgetl3 cmpb #TAB
|
|
237 beq dotab
|
|
238 cmpb #' '
|
|
239 blo osgetl1 ;Ignore control characters.
|
|
240 cmpa temp
|
|
241 beq osgetl1 ;Ignore char if line full.
|
|
242 jsr putchar ;Echo the character.
|
|
243 stb ,x+ ;Store it in memory.
|
|
244 inca
|
|
245 bra osgetl1
|
|
246 dotab ldb #' '
|
|
247 cmpa temp
|
|
248 beq osgetl1
|
|
249 jsr putchar
|
|
250 stb ,x+
|
|
251 inca
|
|
252 bita #7 ;Insert spaces until length mod 8=0
|
|
253 bne dotab
|
|
254 bra osgetl1
|
|
255
|
|
256 * O.S. routine to write a line starting at address X, B chars long.
|
|
257 osputl pshs a,b,x
|
|
258 tfr b,a
|
|
259 tsta
|
|
260 beq osputl1
|
|
261 osputl2 ldb ,x+
|
|
262 jsr putchar
|
|
263 deca
|
|
264 bne osputl2
|
|
265 osputl1 puls a,b,x
|
|
266 rts
|
|
267
|
|
268 * O.S. routine to terminate a line.
|
|
269 oscr pshs b
|
|
270 ldb #CR
|
|
271 jsr putchar
|
|
272 ldb #LF
|
|
273 jsr putchar ;Send the CR and LF characters.
|
|
274 puls b
|
|
275 rts
|
|
276
|
|
277 * Output a counted string at addr X
|
|
278 outcount pshs x,b
|
|
279 ldb ,x+
|
|
280 jsr putline
|
|
281 puls x,b
|
|
282 rts
|
|
283
|
|
284 timerirq inc timer+2
|
|
285 bne endirq
|
|
286 inc timer+1
|
|
287 bne endirq
|
|
288 inc timer
|
|
289 rti
|
|
290 aciairq nop
|
|
291 endirq rti
|
|
292
|
|
293 * Wait D times 20ms.
|
|
294 osdly addd timer+1
|
|
295 dlyloop cmpd timer+1
|
|
296 bne dlyloop
|
|
297 rts
|
|
298
|
|
299 * This table will be copied to the interrupt vector area in RAM.
|
|
300 intvectbl jmp endirq
|
|
301 jmp endirq
|
|
302 jmp timerirq
|
|
303 jmp aciairq
|
|
304 jmp unlaunch
|
|
305 jmp endirq
|
|
306 jmp xerrhand
|
|
307 jmp expr
|
|
308 jmp asmerrvec
|
|
309 jmp pseudo
|
|
310 * And this one to the I/O vector table.
|
|
311 osvectbl jmp osgetc
|
|
312 jmp osputc
|
|
313 jmp osgetl
|
|
314 jmp osputl
|
|
315 jmp oscr
|
|
316 jmp osgetpoll
|
|
317 jmp xopin
|
|
318 jmp xopout
|
|
319 jmp xabtin
|
|
320 jmp xclsin
|
|
321 jmp xclsout
|
|
322 jmp osdly
|
|
323 endvecs equ *
|
|
324
|
|
325 * The J command returns here.
|
|
326 stakregs pshs x ;Stack something where the pc comes
|
|
327 pshs ccr,b,a,dp,x,y,u ;Stack the normal registers.
|
|
328 ldx oldpc
|
|
329 stx 10,s ;Stack the old pc value.
|
|
330 bra unlaunch1
|
|
331 * The G and P commands return here through a breakpoint.
|
|
332 * Registers are already stacked.
|
|
333 unlaunch ldd 10,s
|
|
334 subd #1
|
|
335 std 10,s ;Decrement pc before breakpoint
|
|
336 unlaunch1 andcc #$0 ;reenable the interrupts.
|
|
337 jsr disarm ;Disarm the breakpoints.
|
|
338 jsr dispregs
|
|
339 cmdline jsr xcloseout
|
|
340 sts savesp
|
|
341 ldb #'.'
|
|
342 jsr putchar
|
|
343 ldx #linebuf
|
|
344 ldb #buflen
|
|
345 jsr getline
|
|
346 tstb
|
|
347 beq cmdline ;Ignore line if it is empty
|
|
348 abx
|
|
349 clr ,x ;Make location after line zero.
|
|
350 ldx #linebuf
|
|
351 ldb ,x+
|
|
352 andb #CASEMASK ;Make 1st char uppercase.
|
|
353 subb #'A'
|
|
354 bcs unk
|
|
355 cmpb #26
|
|
356 bcc unk ;Unknown cmd if it is not a letter.
|
|
357 ldx #cmdtab
|
|
358 aslb ;Index into command table.
|
|
359 jmp [b,x]
|
|
360
|
|
361 cmdtab fdb asm,break,calc,dump
|
|
362 fdb enter,find,go,help
|
|
363 fdb inp,jump,unk,unk
|
|
364 fdb move,unk,unk,prog
|
|
365 fdb unk,regs,srec,trace
|
|
366 fdb unasm,unk,unk,xmodem
|
|
367 fdb unk,unk
|
|
368
|
|
369 * Unknown command handling routine.
|
|
370 unk jsr xabortin
|
|
371 ldx #unknown
|
|
372 jsr outcount
|
|
373 jsr putcr
|
|
374 jmp cmdline
|
|
375
|
|
376 help ldx #mhelp ;Print a help message.
|
|
377 help1 ldb ,x+
|
|
378 beq endhlp
|
|
379 lbsr osputc
|
|
380 bra help1
|
|
381 endhlp jmp cmdline
|
|
382 mhelp fcb CR,LF
|
|
383 fcc 'Commands list'
|
|
384 fcb CR,LF
|
|
385
|
|
386 fcc '-------------'
|
|
387 fcb CR,LF
|
|
388
|
|
389 fcc 'Asm '
|
|
390 fcc '{Aaddr}'
|
|
391 fcb CR,LF
|
|
392
|
|
393 fcc 'Unasm '
|
|
394 fcc '{U or Uaddr or Uaddr,length}'
|
|
395 fcb CR,LF
|
|
396
|
|
397 fcc 'Dump '
|
|
398 fcc '{D or D<addr> or D<addr>,<length>}'
|
|
399 fcb CR,LF
|
|
400
|
|
401 fcc 'Enter '
|
|
402 fcc '{E or E<addr> or E<addr> <bytes> or E<addr>string}'
|
|
403 fcb CR,LF
|
|
404
|
|
405 fcc 'Break '
|
|
406 fcc '{B or B<addr>. B displays, B<addr> sets or clears breakpoint}'
|
|
407 fcb CR,LF
|
|
408
|
|
409 fcc 'Find '
|
|
410 fcb "{Faddr bytes or Faddr",34,"ascii",34,"}"
|
|
411 fcb CR,LF
|
|
412
|
|
413 fcc 'Go '
|
|
414 fcc '{G or G<addr>}'
|
|
415 fcb CR,LF
|
|
416
|
|
417 fcc 'Calc '
|
|
418 fcc '{Chexnum{+|-hexnum}}'
|
|
419 fcb CR,LF
|
|
420
|
|
421 fcc 'Inp '
|
|
422 fcc '{Iaddr}'
|
|
423 fcb CR,LF
|
|
424
|
|
425 fcc 'Jump '
|
|
426 fcc '{J<addr>}'
|
|
427 fcb CR,LF
|
|
428
|
|
429 fcc 'Move '
|
|
430 fcc '{M<addr1>,<addr2>,<lenght>}'
|
|
431 fcb CR,LF
|
|
432
|
|
433 fcc 'Prog '
|
|
434 fcc '{P}'
|
|
435 fcb CR,LF
|
|
436
|
|
437 fcc 'Regs '
|
|
438 fcc '{R or R<letter><hex>}'
|
|
439 fcb CR,LF
|
|
440
|
|
441 fcc 'Srec '
|
|
442 fcc '{SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes>}'
|
|
443 fcb CR,LF
|
|
444
|
|
445 fcc 'Trace '
|
|
446 fcc '{T}'
|
|
447 fcb CR,LF
|
|
448
|
|
449 fcc 'Xmodem '
|
|
450 fcc '{XSaddr,len XLaddr,len XX XOcrlf,filler, XSSaddr,len}'
|
|
451 fcb CR,LF
|
|
452
|
|
453 fcc 'Help '
|
|
454 fcc '{H}'
|
|
455 fcb CR,LF,0
|
|
456
|
|
457
|
|
458
|
|
459 * Here are some useful messages.
|
|
460 welcome fcb unknown-welcome-1
|
|
461 fcc "Welcome to BUGGY version 1.0"
|
|
462 unknown fcb brkmsg-unknown-1
|
|
463 fcc "Unknown command"
|
|
464 brkmsg fcb clrmsg-brkmsg-1
|
|
465 fcc "Breakpoint set"
|
|
466 clrmsg fcb fullmsg-clrmsg-1
|
|
467 fcc "Breakpoint cleared"
|
|
468 fullmsg fcb smsg-fullmsg-1
|
|
469 fcc "Breakpoints full"
|
|
470 smsg fcb lastrec-smsg-1
|
|
471 fcc "Error in S record"
|
|
472 lastrec fcb xsmsg-lastrec-1
|
|
473 fcc "S9030000FC"
|
|
474 xsmsg fcb xrmsg-xsmsg-1
|
|
475 fcc "Start XMODEM Send"
|
|
476 xrmsg fcb xamsg-xrmsg-1
|
|
477 fcc "Start XMODEM Receive"
|
|
478 xamsg fcb invmmsg-xamsg-1
|
|
479 fcc "XMODEM transfer aborted"
|
|
480 invmmsg fcb exprmsg-invmmsg-1
|
|
481 fcc "Invalid mnemonic"
|
|
482 exprmsg fcb modemsg-exprmsg-1
|
|
483 fcc "Expression error"
|
|
484 modemsg fcb brmsg-modemsg-1
|
|
485 fcc "Addressing mode error"
|
|
486 brmsg fcb endmsg-brmsg-1
|
|
487 fcc "Branch too long"
|
|
488 endmsg equ *
|
|
489
|
|
490 * Output hex digit contained in A
|
|
491 hexdigit adda #$90
|
|
492 daa
|
|
493 adca #$40
|
|
494 daa ;It's the standard conversion trick ascii
|
|
495 tfr a,b ;to hex without branching.
|
|
496 jsr putchar
|
|
497 rts
|
|
498
|
|
499 * Output contents of A as two hex digits
|
|
500 outbyte pshs a
|
|
501 lsra
|
|
502 lsra
|
|
503 lsra
|
|
504 lsra
|
|
505 bsr hexdigit
|
|
506 puls a
|
|
507 anda #$0f
|
|
508 bra hexdigit
|
|
509
|
|
510 * Output contents of d as four hex digits
|
|
511 outd pshs b
|
|
512 bsr outbyte
|
|
513 puls a
|
|
514 bsr outbyte
|
|
515 rts
|
|
516
|
|
517 * Skip X past spaces, B is first non-space character.
|
|
518 skipspace ldb ,x+
|
|
519 cmpb #' '
|
|
520 beq skipspace
|
|
521 rts
|
|
522
|
|
523 * Convert ascii hex digit in B register to binary Z flag set if no hex digit.
|
|
524 convb subb #'0'
|
|
525 blo convexit
|
|
526 cmpb #9
|
|
527 bls cb2
|
|
528 andb #CASEMASK ;Make uppercase.
|
|
529 subb #7 ;If higher than digit 9 it must be a letter.
|
|
530 cmpb #9
|
|
531 bls convexit
|
|
532 cmpb #15
|
|
533 bhi convexit
|
|
534 cb2 andcc #$FB ;clear zero
|
|
535 rts
|
|
536 convexit orcc #$04
|
|
537 rts
|
|
538
|
|
539 scanexit ldd temp
|
|
540 leax -1,x
|
|
541 tst temp2
|
|
542 rts <-- exit point of scanhex
|
|
543
|
|
544 * Scan for hexadecimal number at address X return in D, Z flag is set it no
|
|
545 * number found.
|
|
546 scanhex clr temp
|
|
547 clr temp+1
|
|
548 clr temp2
|
|
549 bsr skipspace
|
|
550 scloop jsr convb
|
|
551 beq scanexit
|
|
552 pshs b
|
|
553 ldd temp
|
|
554 aslb
|
|
555 rola
|
|
556 aslb
|
|
557 rola
|
|
558 aslb
|
|
559 rola
|
|
560 aslb
|
|
561 rola
|
|
562 addb ,s+
|
|
563 std temp
|
|
564 inc temp2
|
|
565 ldb ,x+
|
|
566 bra scloop
|
|
567
|
|
568 scan2parms std length
|
|
569 bsr scanhex
|
|
570 beq sp2
|
|
571 std addr
|
|
572 bsr skipspace
|
|
573 cmpb #','
|
|
574 bne sp2
|
|
575 bsr scanhex
|
|
576 beq sp2
|
|
577 std length
|
|
578 sp2 rts
|
|
579
|
|
580 * Scan two hexdigits at in and convert to byte into A, Z flag if error.
|
|
581 scanbyte bsr skipspace
|
|
582 bsr convb
|
|
583 beq sb1
|
|
584 tfr b,a
|
|
585 ldb ,x+
|
|
586 bsr convb
|
|
587 beq sb1
|
|
588 asla
|
|
589 asla
|
|
590 asla
|
|
591 asla
|
|
592 stb temp
|
|
593 adda temp
|
|
594 andcc #$fb ;Clear zero flag
|
|
595 sb1 rts
|
|
596
|
|
597
|
|
598 * This is the code for the D command, hex/ascii dump of memory
|
|
599 * Syntax: D or D<addr> or D<addr>,<length>
|
|
600 dump ldx #linebuf+1
|
|
601 ldd #$40
|
|
602 jsr scan2parms ;Scan address and length, default length=64
|
|
603 ldy addr
|
|
604 dh1 lda #16
|
|
605 sta temp+1
|
|
606 tfr y,d
|
|
607 jsr outd
|
|
608 ldb #' '
|
|
609 jsr putchar
|
|
610 dh2 lda ,y+ ;display row of 16 mem locations as hex
|
|
611 jsr outbyte
|
|
612 ldb #' '
|
|
613 lda temp+1
|
|
614 cmpa #9
|
|
615 bne dh6
|
|
616 ldb #'-' ;Do a - after the eighth byte.
|
|
617 dh6 jsr putchar
|
|
618 dec temp+1
|
|
619 bne dh2
|
|
620 leay -16,y ;And now for the ascii dump.
|
|
621 lda #16
|
|
622 dh3 ldb ,y+
|
|
623 cmpb #' '
|
|
624 bhs dh4
|
|
625 ldb #'.'
|
|
626 dh4 cmpb #DEL
|
|
627 blo dh5
|
|
628 ldb #'.' ;Convert all nonprintables to .
|
|
629 dh5 jsr putchar
|
|
630 deca
|
|
631 bne dh3
|
|
632 jsr putcr
|
|
633 ldd length
|
|
634 subd #16
|
|
635 std length
|
|
636 bhi dh1
|
|
637 sty addr
|
|
638 jmp cmdline
|
|
639
|
|
640 * This is the code for the E command, enter hex bytes or ascii string.
|
|
641 * Syntax E or E<addr> or E<addr> <bytes> or E<addr>"string"
|
|
642 enter ldx #linebuf+1
|
|
643 jsr scanhex
|
|
644 beq ent1
|
|
645 std addr
|
|
646 ent1 bsr entline
|
|
647 lbne cmdline ;No bytes, then enter interactively.
|
|
648 ent2 ldb #'E'
|
|
649 jsr putchar
|
|
650 ldd addr
|
|
651 jsr outd
|
|
652 ldb #' '
|
|
653 jsr putchar ;Display Eaddr + space
|
|
654 lda [addr]
|
|
655 jsr outbyte
|
|
656 ldb #' '
|
|
657 jsr putchar
|
|
658 ldx #linebuf
|
|
659 ldb #buflen
|
|
660 jsr getline ;Get the line.
|
|
661 tstb
|
|
662 beq skipbyte
|
|
663 abx
|
|
664 clr ,x
|
|
665 ldx #linebuf
|
|
666 bsr entline
|
|
667 bne ent2
|
|
668 jmp cmdline
|
|
669 skipbyte ldd addr
|
|
670 addd #1
|
|
671 std addr
|
|
672 bra ent2
|
|
673
|
|
674 * Enter a line of hex bytes or ascci string at address X, Z if empty.
|
|
675 entline jsr skipspace
|
|
676 tstb
|
|
677 beq entexit
|
|
678 cmpb #'.'
|
|
679 beq entexit
|
|
680 cmpb #'"'
|
|
681 beq entasc
|
|
682 leax -1,x
|
|
683 ldy addr
|
|
684 entl2 jsr scanbyte ;Enter hex digits.
|
|
685 beq entdone
|
|
686 sta ,y+
|
|
687 bra entl2
|
|
688 entasc ldy addr
|
|
689 entl3 lda ,x+
|
|
690 tsta
|
|
691 beq entdone
|
|
692 cmpa #'"'
|
|
693 beq entdone
|
|
694 sta ,y+
|
|
695 bra entl3
|
|
696 entdone sty addr
|
|
697 andcc #$fb
|
|
698 rts
|
|
699 entexit orcc #$04
|
|
700 rts
|
|
701
|
|
702 *This is the code for the I command, display the contents of an address
|
|
703 * Syntax: Iaddr
|
|
704 inp ldx #linebuf+1
|
|
705 jsr scanhex
|
|
706 tfr d,x
|
|
707 lda ,x ;Read the byte from memory.
|
|
708 jsr outbyte ;Display itin hex.
|
|
709 jsr putcr
|
|
710 jmp cmdline
|
|
711
|
|
712 *This is the code for the H command, display result of simple hex expression
|
|
713 *Syntax Hhexnum{+|-hexnum}
|
|
714 calc ldx #linebuf+1
|
|
715 jsr scanhex
|
|
716 std temp3
|
|
717 hexloop jsr skipspace
|
|
718 cmpb #'+'
|
|
719 bne hex1
|
|
720 jsr scanhex
|
|
721 addd temp3
|
|
722 std temp3
|
|
723 bra hexloop
|
|
724 hex1 cmpb #'-'
|
|
725 bne hexend
|
|
726 jsr scanhex
|
|
727 comb
|
|
728 coma
|
|
729 addd #1
|
|
730 addd temp3
|
|
731 std temp3
|
|
732 bra hexloop
|
|
733 hexend ldd temp3
|
|
734 jsr outd
|
|
735 jsr putcr
|
|
736 jmp cmdline
|
|
737
|
|
738 * This is the code for the G command, jump to the program
|
|
739 * Syntax G or G<addr>
|
|
740 go ldx #linebuf+1
|
|
741 jsr scanhex
|
|
742 beq launch
|
|
743 std 10,s ;Store parameter in pc location.
|
|
744 launch jsr arm ;Arm the breakpoints.
|
|
745 puls ccr,b,a,dp,x,y,u,pc
|
|
746
|
|
747 * This is the code for the J command, run a subroutine.
|
|
748 * Syntax J<addr>
|
|
749 jump ldx #linebuf+1
|
|
750 ldd 10,s
|
|
751 std oldpc ;Save old pc
|
|
752 jsr scanhex
|
|
753 std 10,s ;Store parameter in PC location
|
|
754 tfr s,x
|
|
755 leas -2,s
|
|
756 tfr s,u
|
|
757 ldb #12 ;Move the saved register set 2 addresses
|
|
758 jsr blockmove ;down on the stack.
|
|
759 ldd #stakregs
|
|
760 std 12,s ;Prepare subroutine return address.
|
|
761 bra launch ;Jump to the routine.
|
|
762
|
|
763
|
|
764 * This is the code for the P command, run instruction followed by breakpoint
|
|
765 * Syntax P
|
|
766 prog ldy 10,s ;Get program counter value.
|
|
767 jsr disdecode ;Find out location past current insn.
|
|
768 sty stepbp
|
|
769 bra launch
|
|
770
|
|
771 * This is the code for the T command, single step trace an instruction.
|
|
772 * Syntax T
|
|
773 trace jsr traceone
|
|
774 jsr dispregs
|
|
775 jmp cmdline
|
|
776
|
|
777 traceone orcc #$50 ;Disable the interrupts.
|
|
778 ldd ,s++
|
|
779 std oldpc ;Remove saved pc from stack.
|
|
780 ldd #traceret
|
|
781 std firqvec+1 ;Adjust timer IRQ vector.
|
|
782 sync ;Synchronize on the next timer interrupt.
|
|
783 ;1 cycle
|
|
784 ldx #4441 ;3 cycles
|
|
785 traceloop leax -1,x ;6 cycles\x4441= 39969 cycles.
|
|
786 bne traceloop ;3 cycles/
|
|
787 nop ;2 cycles.
|
|
788 nop ;2 cycles.
|
|
789 nop ;2 cycles.
|
|
790 brn traceret ;3 cycles.
|
|
791 puls x,y,u,a,b,dp,cc,pc ;17 cycles, total=39999 20ms @ 2MHz
|
|
792 ;Pull all registers and execute.
|
|
793 ;Is timed such that next timer IRQ
|
|
794 ;occurs right after it.
|
|
795 traceret puls cc
|
|
796 pshs x,y,u,a,b,dp,cc;Store full register set instead of cc.
|
|
797 ldd #timerirq
|
|
798 std firqvec+1 ;Restore timer IRQ vector.
|
|
799 jmp [oldpc]
|
|
800
|
|
801
|
|
802 * Display the contents of 8 bit register, name in B, contents in A
|
|
803 disp8 jsr putchar
|
|
804 ldb #'='
|
|
805 jsr putchar
|
|
806 jsr outbyte
|
|
807 ldb #' '
|
|
808 jsr putchar
|
|
809 rts
|
|
810
|
|
811 * Display the contents of 16 bit register, name in B, contents in Y
|
|
812 disp16 jsr putchar
|
|
813 ldb #'='
|
|
814 jsr putchar
|
|
815 tfr y,d
|
|
816 jsr outd
|
|
817 ldb #' '
|
|
818 jsr putchar
|
|
819 rts
|
|
820
|
|
821 * Display the contents of the registers and disassemble instruction at
|
|
822 * PC location.
|
|
823 dispregs ldb #'X'
|
|
824 ldy 6,s ;Note that there's one return address on
|
|
825 bsr disp16 ;stack so saved register offsets are
|
|
826 ldb #'Y' ;inremented by 2.
|
|
827 ldy 8,s
|
|
828 bsr disp16
|
|
829 ldb #'U'
|
|
830 ldy 10,s
|
|
831 bsr disp16
|
|
832 ldb #'S'
|
|
833 tfr s,y
|
|
834 leay 14,y ;S of the running program is 12 higher,
|
|
835 ;because regs are not stacked when running.
|
|
836 bsr disp16
|
|
837 ldb #'A'
|
|
838 lda 3,s
|
|
839 bsr disp8
|
|
840 ldb #'B'
|
|
841 lda 4,s
|
|
842 bsr disp8
|
|
843 ldb #'D'
|
|
844 lda 5,s
|
|
845 bsr disp8
|
|
846 ldb #'C'
|
|
847 lda 2,s
|
|
848 bsr disp8
|
|
849 jsr putcr
|
|
850 ldb #'P'
|
|
851 ldy 12,s
|
|
852 bsr disp16
|
|
853 jsr disdecode
|
|
854 jsr disdisp ;Disassemble instruction at PC
|
|
855 jsr putcr
|
|
856 rts
|
|
857
|
|
858
|
|
859 * This is the code for the R command, display or alter the registers.
|
|
860 * Syntax R or R<letter><hex>
|
|
861 regs ldx #linebuf+1
|
|
862 jsr skipspace
|
|
863 tstb
|
|
864 bne setreg
|
|
865 bsr dispregs ;Display regs ifnothing follows.
|
|
866 jmp cmdline
|
|
867 setreg ldy #regtab
|
|
868 clra
|
|
869 andb #CASEMASK ;Make letter uppercase.
|
|
870 sr1 tst ,y
|
|
871 lbeq unk ;At end of register tab, unknown reg
|
|
872 cmpb ,y+
|
|
873 beq sr2 ;Found the register?
|
|
874 inca
|
|
875 bra sr1
|
|
876 sr2 pshs a
|
|
877 jsr scanhex ;Convert the hex argument.
|
|
878 pshs d
|
|
879 lda 2,s ;Get register number.
|
|
880 cmpa #4
|
|
881 bcc sr3
|
|
882 ldb 1,s ;It's 8 bit.
|
|
883 leas 3,s ;Remove temp stuff from stack.
|
|
884 stb a,s ;Store it in the reg on stack.
|
|
885 jmp cmdline
|
|
886 sr3 cmpa #8
|
|
887 bcc sr4
|
|
888 puls x ;It's 16 bit.
|
|
889 leas 1,s
|
|
890 lsla
|
|
891 suba #4 ;Convert reg no to stack offset.
|
|
892 stx a,s
|
|
893 jmp cmdline
|
|
894 sr4 puls u ;It's the stack pointer.
|
|
895 leas 1,s
|
|
896 leau -12,u
|
|
897 tfr s,x
|
|
898 tfr u,s ;Set new stack pointer.
|
|
899 ldb #12
|
|
900 jsr blockmove ;Move register set to new stack location.
|
|
901 jmp cmdline
|
|
902
|
|
903 regtab FCC "CABDXYUPS "
|
|
904
|
|
905 * Disarm the breakpoints, this is replace the SWI instructions with the
|
|
906 * original byte.
|
|
907 disarm ldx #bpaddr
|
|
908 lda #brkpoints+1
|
|
909 disarm1 ldu ,x++
|
|
910 ldb ,x+ ;Get address in u, byte in b
|
|
911 cmpu #0
|
|
912 beq disarm2
|
|
913 stb ,u
|
|
914 disarm2 deca
|
|
915 bne disarm1
|
|
916 ldu #0
|
|
917 stu -3,x ;Clear the step breakpoint.
|
|
918 rts
|
|
919
|
|
920 * Arm the breakponts, this is replace the byte at the breakpoint address
|
|
921 * with an SWI instruction.
|
|
922 arm ldx #bpaddr+brkpoints*3
|
|
923 lda #brkpoints+1 ;Arm them in reverse order of disarming.
|
|
924 arm1 ldu ,x ;Get address in u.
|
|
925 beq arm2
|
|
926 ldb ,u
|
|
927 stb 2,x
|
|
928 cmpu 12,s ;Compare to program counter location
|
|
929 beq arm2
|
|
930 ldb #$3F
|
|
931 stb ,u ;Store SWI instruction if not equal.
|
|
932 arm2 leax -3,x
|
|
933 deca
|
|
934 bne arm1
|
|
935 rts
|
|
936
|
|
937 * This is the code for the break command, set, clear display breakpoints.
|
|
938 * Syntax B or B<addr>. B displays, B<addr> sets or clears breakpoint.
|
|
939 break lda #brkpoints
|
|
940 sta temp2+1 ;Store number of breakpoints to visit.
|
|
941 ldx #linebuf+1
|
|
942 jsr scanhex
|
|
943 beq dispbp ;No number then display breakpoints
|
|
944 ldx #bpaddr
|
|
945 ldu #0
|
|
946 tfr u,y
|
|
947 bp1 cmpd ,x
|
|
948 beq clearit ;Found the breakpoint, so clear it,
|
|
949 cmpu ,x ;Is location zero
|
|
950 bne bp2
|
|
951 tfr x,y ;Set free address to y
|
|
952 bp2 leax 3,x
|
|
953 dec temp2+1
|
|
954 bne bp1
|
|
955 cmpy #0 ;Address not found in list of breakpoints
|
|
956 beq bpfull ;Was free address found.
|
|
957 std ,y ;If so, store breakpoint there.
|
|
958 ldx #brkmsg
|
|
959 bpexit jsr outcount
|
|
960 jsr putcr
|
|
961 jmp cmdline
|
|
962 clearit clra
|
|
963 clrb
|
|
964 std ,x
|
|
965 ldx #clrmsg
|
|
966 bra bpexit
|
|
967 bpfull ldx #fullmsg
|
|
968 bra bpexit
|
|
969
|
|
970 dispbp ldx #bpaddr
|
|
971 dbp1 ldd ,x
|
|
972 beq dbp2
|
|
973 jsr outd
|
|
974 ldb #' '
|
|
975 jsr putchar
|
|
976 dbp2 leax 3,x
|
|
977 dec temp2+1
|
|
978 bne dbp1
|
|
979 jsr putcr
|
|
980 jmp cmdline
|
|
981
|
|
982 * Scan hex byte into a and add it to check sum in temp2+1
|
|
983 addchk jsr scanbyte
|
|
984 lbeq srecerr
|
|
985 tfr a,b
|
|
986 addb temp2+1
|
|
987 stb temp2+1
|
|
988 rts
|
|
989
|
|
990 * This tis the code for the S command, the Motorola S records entry.
|
|
991 * Syntax SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes>
|
|
992 srec ldx #linebuf+1
|
|
993 ldb ,x+
|
|
994 andb #CASEMASK
|
|
995 cmpb #'O'
|
|
996 beq setsorg
|
|
997 cmpb #'S'
|
|
998 beq sendrec
|
|
999 ldb -1,x
|
|
1000 clr temp3
|
|
1001 cmpb #'1'
|
|
1002 beq readrec
|
|
1003 cmpb #'9'
|
|
1004 bne srecerr
|
|
1005 inc temp3
|
|
1006 readrec clr temp2+1 ;clear checksum.
|
|
1007 bsr addchk
|
|
1008 suba #2 ;discount the address bytes from the count.
|
|
1009 sta temp3+1 ;Read length byte.
|
|
1010 bsr addchk
|
|
1011 pshs a
|
|
1012 bsr addchk
|
|
1013 puls b
|
|
1014 exg a,b ;Read address into d.
|
|
1015 ldu sorg
|
|
1016 beq rr1
|
|
1017 ldu soffs
|
|
1018 bne rr1
|
|
1019 pshs d ;Sorg is nonzero and soffs is zero, now
|
|
1020 subd sorg ;set soffs
|
|
1021 std soffs
|
|
1022 puls d
|
|
1023 rr1 subd soffs ;Subtract the address offset.
|
|
1024 tfr d,y
|
|
1025 rr2 bsr addchk
|
|
1026 dec temp3+1
|
|
1027 beq endrec
|
|
1028 sta ,y+
|
|
1029 bra rr2
|
|
1030 endrec inc temp2+1 ;Check checksum.
|
|
1031 bne srecerr
|
|
1032 tst temp3
|
|
1033 lbeq cmdline ;Was it no S9 record?
|
|
1034 cmpy #0
|
|
1035 beq endrec1
|
|
1036 sty 10,s ;Store address into program counter.
|
|
1037 endrec1 clra
|
|
1038 clrb
|
|
1039 std sorg ;Reset sorg, next S loads will be normal.
|
|
1040 std soffs
|
|
1041 jmp cmdline
|
|
1042 srecerr jsr xabortin
|
|
1043 ldx #smsg ;Error in srecord, display message.
|
|
1044 jsr outcount
|
|
1045 jsr putcr
|
|
1046 jmp cmdline
|
|
1047 setsorg jsr scanhex ;Set S record origin.
|
|
1048 std sorg
|
|
1049 clra
|
|
1050 clrb
|
|
1051 std soffs
|
|
1052 jmp cmdline
|
|
1053 * Send a memory region as S-records.
|
|
1054 sendrec ldd #$100 ;Scan address and length parameter.
|
|
1055 jsr scan2parms
|
|
1056 ldd sorg
|
|
1057 beq ss1
|
|
1058 ldd addr
|
|
1059 subd sorg
|
|
1060 std soffs ;Compute offset for origin.
|
|
1061 ss1 ldd length
|
|
1062 beq endss ;All bytes sent?
|
|
1063 cmpd #16
|
|
1064 blo ss2
|
|
1065 ldb #16 ;If more than 16 left, then send 16.
|
|
1066 ss2 stb temp
|
|
1067 negb
|
|
1068 ldu length
|
|
1069 leau b,u
|
|
1070 stu length ;Discount line length from length.
|
|
1071 ldb #'S'
|
|
1072 jsr putchar
|
|
1073 ldb #'1'
|
|
1074 jsr putchar
|
|
1075 clr temp+1 ;Clear check sum
|
|
1076 ldb temp
|
|
1077 addb #3
|
|
1078 bsr checkout ;Output byte b as hex and add to check sum.
|
|
1079 ldd addr
|
|
1080 tfr d,y
|
|
1081 subd soffs
|
|
1082 exg a,b
|
|
1083 bsr checkout
|
|
1084 exg a,b
|
|
1085 bsr checkout ;Output address (add into check sum)
|
|
1086 ss3 ldb ,y+
|
|
1087 bsr checkout
|
|
1088 dec temp
|
|
1089 bne ss3
|
|
1090 sty addr
|
|
1091 ldb temp+1
|
|
1092 comb
|
|
1093 bsr checkout ;Output checksum byte.
|
|
1094 jsr putcr
|
|
1095 bra ss1
|
|
1096 endss ldx #lastrec
|
|
1097 jsr outcount
|
|
1098 jsr putcr
|
|
1099 jmp cmdline
|
|
1100 * Output byte in register B and add it into check sum at temp+1
|
|
1101 checkout pshs a
|
|
1102 tfr b,a
|
|
1103 addb temp+1
|
|
1104 stb temp+1
|
|
1105 jsr outbyte
|
|
1106 puls a
|
|
1107 rts
|
|
1108
|
|
1109 * This is the code for the M command, move memory region.
|
|
1110 * Syntax: Maddr1,addr2,length
|
|
1111 move ldx #linebuf+1
|
|
1112 jsr scanhex
|
|
1113 lbeq unk
|
|
1114 std temp3
|
|
1115 jsr skipspace
|
|
1116 cmpb #','
|
|
1117 lbne unk
|
|
1118 jsr scanhex
|
|
1119 lbeq unk
|
|
1120 tfr d,u
|
|
1121 jsr skipspace
|
|
1122 cmpb #','
|
|
1123 lbne unk
|
|
1124 jsr scanhex
|
|
1125 lbeq unk
|
|
1126 tfr d,y ;Read the argument separated by commas
|
|
1127 ldx temp3 ;src addr to x, dest addr to u, length to y
|
|
1128 ;Don't tolerate syntax deviations.
|
|
1129 mvloop lda ,x+
|
|
1130 sta ,u+
|
|
1131 leay -1,y
|
|
1132 bne mvloop ;Perform the block move.
|
|
1133 jmp cmdline
|
|
1134
|
|
1135
|
|
1136 * This is the code for the F command, find byte/ascii string in memory.
|
|
1137 * Syntax: Faddr bytes or Faddr "ascii"
|
|
1138 find ldx #linebuf+1
|
|
1139 jsr scanhex
|
|
1140 tfr d,y ;Scan the start address.
|
|
1141 jsr skipspace
|
|
1142 cmpb #'"'
|
|
1143 bne findhex
|
|
1144 ldu #linebuf ;Quote found, so scan for quoted string.
|
|
1145 clra
|
|
1146 fstrloop ldb ,x+
|
|
1147 beq startsrch ;End of line without final quote.
|
|
1148 cmpb #'"'
|
|
1149 beq startsrch ;End quote found
|
|
1150 stb ,u+
|
|
1151 inca
|
|
1152 bra fstrloop
|
|
1153 findhex ldu #linebuf ;Convert string of hex bytes.
|
|
1154 leax -1,x ;String will be stored at start of line
|
|
1155 clra ;buffer and may overwrite part of the
|
|
1156 fhexloop pshs a ;already converted string.
|
|
1157 jsr scanbyte
|
|
1158 tfr a,b
|
|
1159 puls a
|
|
1160 beq startsrch
|
|
1161 stb ,u+
|
|
1162 inca
|
|
1163 bra fhexloop
|
|
1164 startsrch tsta ;Start searching, start addr in Y,
|
|
1165 ;string starts at linebuf, length A
|
|
1166 lbeq cmdline ;Quit with zero length string.
|
|
1167 clr temp3
|
|
1168 sta temp3+1
|
|
1169 srchloop tfr y,x
|
|
1170 lda temp3+1
|
|
1171 cmpx #$e100
|
|
1172 bcc srch1
|
|
1173 leax a,x
|
|
1174 cmpx #$e000 ;Stop at I/O addresses.
|
|
1175 lbcc cmdline
|
|
1176 srch1 tfr y,x
|
|
1177 ldu #linebuf
|
|
1178 srch2 ldb ,x+
|
|
1179 cmpb ,u+
|
|
1180 bne srch3 ;Not equal, try next address.
|
|
1181 deca
|
|
1182 bne srch2
|
|
1183 tfr y,d
|
|
1184 jsr outd ;String found
|
|
1185 jsr putcr
|
|
1186 inc temp3
|
|
1187 lda temp3
|
|
1188 cmpa #$10
|
|
1189 lbeq cmdline ;If 10 matches found, just stop.
|
|
1190 srch3 leay 1,y
|
|
1191 bra srchloop
|
|
1192
|
|
1193 * Send the contents of the xmodem buffer and get it acknowledged, zero flag
|
|
1194 * is set if transfer aborted.
|
|
1195 xsendbuf ldb #SOH
|
|
1196 jsr osputc ;Send SOH
|
|
1197 ldb xpacknum
|
|
1198 jsr osputc ;Send block number.
|
|
1199 comb
|
|
1200 jsr osputc ;and its complement.
|
|
1201 clr xsum
|
|
1202 lda #128
|
|
1203 ldx #buf0
|
|
1204 xsloop ldb ,x
|
|
1205 addb xsum
|
|
1206 stb xsum
|
|
1207 ldb ,x+
|
|
1208 jsr osputc
|
|
1209 deca
|
|
1210 bne xsloop ;Send the buffer contents.
|
|
1211 ldb xsum
|
|
1212 jsr osputc ;Send the check sum
|
|
1213 waitack jsr osgetc
|
|
1214 cmpb #CAN
|
|
1215 beq xsabt ;^X for abort.
|
|
1216 cmpb #NAK
|
|
1217 beq xsendbuf ;Send again if NAK
|
|
1218 cmpb #ACK
|
|
1219 bne waitack
|
|
1220 inc xpacknum
|
|
1221 xsok andcc #$fb ;Clear zero flag after ACK
|
|
1222 xsabt rts
|
|
1223
|
|
1224 * Start an XMODEM send session.
|
|
1225 xsendinit ldb #1
|
|
1226 stb xpacknum ;Initialize block number.
|
|
1227 waitnak jsr osgetc
|
|
1228 cmpb #CAN
|
|
1229 beq xsabt ;If ^X exit with zero flag.
|
|
1230 cmpb #NAK
|
|
1231 beq xsok
|
|
1232 bra waitnak ;Wait until NAK received.
|
|
1233
|
|
1234 * Send ETX and wait for ack.
|
|
1235 xsendeot ldb #EOT
|
|
1236 jsr osputc
|
|
1237 waitack2 jsr osgetc
|
|
1238 cmpb #CAN
|
|
1239 beq xsabt
|
|
1240 cmpb #NAK
|
|
1241 beq xsendeot
|
|
1242 cmpb #ACK
|
|
1243 beq xsok
|
|
1244 bra waitack2
|
|
1245
|
|
1246 * Read character into B with a timeout of A seconds, Carry set if timeout.
|
|
1247 gettimeout asla
|
|
1248 ldb #50
|
|
1249 mul
|
|
1250 tfr b,a
|
|
1251 adda timer+2
|
|
1252 gt1 jsr osgetpoll
|
|
1253 tstb
|
|
1254 bne gtexit
|
|
1255 cmpa timer+2
|
|
1256 bne gt1
|
|
1257 orcc #$1
|
|
1258 rts
|
|
1259 gtexit jsr osgetc
|
|
1260 andcc #$fe
|
|
1261 rts
|
|
1262
|
|
1263 * Wait until line becomes quiet.
|
|
1264 purge lda #3
|
|
1265 jsr gettimeout
|
|
1266 bcc purge
|
|
1267 rts
|
|
1268
|
|
1269 * Receive an XMODEM block and wait till it is OK, Z set if etx.
|
|
1270 xrcvbuf lda #3
|
|
1271 tst lastok
|
|
1272 beq sendnak
|
|
1273 ldb #ACK
|
|
1274 jsr osputc ;Send an ack.
|
|
1275 lda #5
|
|
1276 bra startblock
|
|
1277 sendnak ldb #NAK
|
|
1278 jsr osputc ;Send a NAK
|
|
1279 startblock clr lastok
|
|
1280 bsr gettimeout
|
|
1281 lda #3
|
|
1282 bcs sendnak ;Keep sending NAKs when timed out.
|
|
1283 cmpb #EOT
|
|
1284 beq xrcveot ;End of file reached, acknowledge EOT.
|
|
1285 cmpb #SOH
|
|
1286 bne purgeit ;Not, SOH, bad block.
|
|
1287 lda #1
|
|
1288 bsr gettimeout
|
|
1289 bcs purgeit
|
|
1290 cmpb xpacknum ;Is it the right block?
|
|
1291 beq xr1
|
|
1292 incb
|
|
1293 cmpb xpacknum ;Was it the previous block.
|
|
1294 bne purgeit
|
|
1295 inc lastok
|
|
1296 xr1 stb xsum
|
|
1297 lda #1
|
|
1298 bsr gettimeout
|
|
1299 bcs purgeit
|
|
1300 comb
|
|
1301 cmpb xsum ;Is the complement of the block number OK
|
|
1302 bne purgeit
|
|
1303 ldx #buf0
|
|
1304 clr xsum
|
|
1305 xrloop lda #1
|
|
1306 bsr gettimeout
|
|
1307 bcs purgeit
|
|
1308 stb ,x+
|
|
1309 addb xsum
|
|
1310 stb xsum
|
|
1311 cmpx #buf0+128
|
|
1312 bne xrloop ;Get the data bytes.
|
|
1313 lda #1
|
|
1314 bsr gettimeout
|
|
1315 bcs purgeit
|
|
1316 cmpb xsum
|
|
1317 bne purgeit ;Check the check sum.
|
|
1318 tst lastok
|
|
1319 bne xrcvbuf ;Block was the previous block, get next one
|
|
1320 inc lastok
|
|
1321 inc xpacknum
|
|
1322 andcc #$fb
|
|
1323 rts
|
|
1324 purgeit jsr purge
|
|
1325 bra sendnak
|
|
1326 xrcveot lda #3 ;EOT was received.
|
|
1327 ldb #ACK
|
|
1328 ackloop jsr osputc
|
|
1329 deca
|
|
1330 bne ackloop ;Send 3 acks in a row.
|
|
1331 rts
|
|
1332
|
|
1333
|
|
1334 savevecs ldx getchar+1
|
|
1335 stx oldgetc
|
|
1336 ldx putchar+1
|
|
1337 stx oldputc
|
|
1338 ldx putcr+1
|
|
1339 stx oldputcr
|
|
1340 clr lastterm
|
|
1341 rts
|
|
1342
|
|
1343 rstvecs ldx oldgetc
|
|
1344 stx getchar+1
|
|
1345 ldx oldputc
|
|
1346 stx putchar+1
|
|
1347 ldx oldputcr
|
|
1348 stx putcr+1
|
|
1349 clr lastterm
|
|
1350 rts
|
|
1351
|
|
1352 * O.S. routine to open input through XMODEM transfer.
|
|
1353 xopin pshs x,a,b
|
|
1354 ldx #xsmsg
|
|
1355 jsr outcount
|
|
1356 jsr putcr ;Display message to start XMODEM send.
|
|
1357 bsr savevecs
|
|
1358 ldx #noop
|
|
1359 stx putchar+1 ;Disable character output.
|
|
1360 ldx #xgetc
|
|
1361 stx getchar+1 ;
|
|
1362 clr lastok
|
|
1363 clr xcount
|
|
1364 lda #1
|
|
1365 sta xpacknum
|
|
1366 inca
|
|
1367 sta xmode ;set xmode to 2.
|
|
1368 puls x,a,b,pc
|
|
1369
|
|
1370 * O.S. routine to open output through XMODEM transfer.
|
|
1371 xopout pshs x,a,b
|
|
1372 bsr savevecs
|
|
1373 ldx #xrmsg
|
|
1374 jsr outcount ;Display message to start XMODEM receive
|
|
1375 jsr putcr
|
|
1376 ldx #xputc
|
|
1377 stx putchar+1
|
|
1378 ldx #xputcr
|
|
1379 stx putcr+1
|
|
1380 jsr xsendinit
|
|
1381 lbeq xerror
|
|
1382 clr xcount
|
|
1383 lda #1
|
|
1384 sta xmode
|
|
1385 puls x,a,b,pc
|
|
1386
|
|
1387
|
|
1388 * O.S. routine to abort input through XMODEM transfer.
|
|
1389 xabtin lda xmode
|
|
1390 cmpa #2
|
|
1391 bne xclsend
|
|
1392 jsr purge
|
|
1393 ldb #CAN
|
|
1394 lda #8
|
|
1395 xabtloop jsr osputc
|
|
1396 deca
|
|
1397 bne xabtloop ;Send 8 CAN characters to kill transfer.
|
|
1398 bsr rstvecs
|
|
1399 clr xmode
|
|
1400 ldx #xamsg
|
|
1401 jsr outcount
|
|
1402 jsr putcr ;Send diagnostic message.
|
|
1403 rts
|
|
1404
|
|
1405 * O.S. routine to close output through XMODEM transfer.
|
|
1406 xclsout lda xmode
|
|
1407 cmpa #1
|
|
1408 bne xclsend
|
|
1409 tst xcount
|
|
1410 beq xclsdone
|
|
1411 lda #128
|
|
1412 suba xcount
|
|
1413 xclsloop ldb filler
|
|
1414 bsr xputc
|
|
1415 deca
|
|
1416 bne xclsloop ;Transfer filler chars to force block out.
|
|
1417 xclsdone jsr xsendeot ;Send EOT
|
|
1418 lbeq xerror
|
|
1419 jsr rstvecs
|
|
1420 clr xmode
|
|
1421 xclsend rts
|
|
1422
|
|
1423 * O.S. routine to close input through XMODEM, by gobbling up the remaining
|
|
1424 * bytes.
|
|
1425 xclsin ldb xmode
|
|
1426 cmpb #2
|
|
1427 bne xclsend
|
|
1428 jsr putchar
|
|
1429 bra xclsin
|
|
1430
|
|
1431 * putchar routine for XMODEM
|
|
1432 xputc pshs x,a,b
|
|
1433 lda xcount
|
|
1434 inc xcount
|
|
1435 ldx #buf0
|
|
1436 stb a,x ;Store character in XMODEM buffer.
|
|
1437 cmpa #127
|
|
1438 bne xputc1 ;is buffer full?
|
|
1439 clr xcount
|
|
1440 pshs y,u
|
|
1441 jsr xsendbuf
|
|
1442 lbeq xerror
|
|
1443 puls y,u
|
|
1444 xputc1 puls x,a,b,pc
|
|
1445
|
|
1446 * putcr routine for XMODEM
|
|
1447 xputcr pshs b
|
|
1448 ldb xmcr
|
|
1449 bitb #2
|
|
1450 beq xputcr1
|
|
1451 ldb #CR
|
|
1452 bsr xputc
|
|
1453 xputcr1 ldb xmcr
|
|
1454 bitb #1
|
|
1455 beq xputcr2
|
|
1456 ldb #LF
|
|
1457 bsr xputc
|
|
1458 xputcr2 puls b
|
|
1459 rts
|
|
1460
|
|
1461 * getchar routine for XMODEM
|
|
1462 xgetc pshs x,a
|
|
1463 tst xcount ;No characters left?
|
|
1464 bne xgetc1
|
|
1465 pshs y,u
|
|
1466 jsr xrcvbuf ;Receive new block.
|
|
1467 puls y,u
|
|
1468 beq xgetcterm ;End of input?
|
|
1469 lda #128
|
|
1470 sta xcount
|
|
1471 xgetc1 lda xcount
|
|
1472 nega
|
|
1473 ldx #buf0+128
|
|
1474 ldb a,x ;Get character from buffer
|
|
1475 dec xcount
|
|
1476 puls x,a,pc
|
|
1477 xgetcterm jsr rstvecs
|
|
1478 clr xmode
|
|
1479 ldb filler
|
|
1480 puls x,a,pc
|
|
1481
|
|
1482 xerror jsr rstvecs ;Restore I/O vectors
|
|
1483 clr xmode
|
|
1484 ldx #xamsg
|
|
1485 jsr outcount
|
|
1486 jsr putcr
|
|
1487 jmp xerrvec
|
|
1488
|
|
1489 xerrhand lds savesp
|
|
1490 jmp cmdline
|
|
1491
|
|
1492 * This is the code for the X command, various XMODEM related commands.
|
|
1493 * Syntax: XSaddr,len XLaddr,len XX XOcrlf,filler, XSSaddr,len
|
|
1494 xmodem ldx #linebuf+1
|
|
1495 lda ,x+
|
|
1496 anda #CASEMASK ;Convert to uppercase.
|
|
1497 cmpa #'X'
|
|
1498 beq xeq
|
|
1499 cmpa #'L'
|
|
1500 beq xload
|
|
1501 cmpa #'O'
|
|
1502 beq xopts
|
|
1503 cmpa #'S'
|
|
1504 lbne unk
|
|
1505 lda ,x
|
|
1506 anda #CASEMASK
|
|
1507 cmpa #'S'
|
|
1508 beq xss
|
|
1509 ldd #$100 ;XSaddr,len command.
|
|
1510 jsr scan2parms ;Send binary through XMODEM
|
|
1511 jsr xopenout
|
|
1512 ldu addr
|
|
1513 ldy length
|
|
1514 xsbinloop ldb ,u+
|
|
1515 jsr putchar
|
|
1516 leay -1,y
|
|
1517 bne xsbinloop ;Send all the bytes through XMODEM.
|
|
1518 jmp cmdline
|
|
1519 xss leax 1,x ;XSSaddr,len command.
|
|
1520 jsr xopenout ;Send Srecords through XMODEM
|
|
1521 jmp sendrec
|
|
1522 xload jsr scanhex ;XLaddr command
|
|
1523 tfr d,y ;Load binary through XMODEM
|
|
1524 jsr xopenin
|
|
1525 xlodloop jsr getchar
|
|
1526 tst xmode ;File ended? then done
|
|
1527 lbeq cmdline
|
|
1528 stb ,y+
|
|
1529 bra xlodloop
|
|
1530 xeq jsr xopenin ;XX command
|
|
1531 jmp cmdline ;Execute commands received from XMODEM
|
|
1532 xopts ldd #$1a
|
|
1533 jsr scan2parms
|
|
1534 lda addr+1
|
|
1535 sta xmcr
|
|
1536 lda length+1
|
|
1537 sta filler
|
|
1538 jmp cmdline
|
|
1539
|
|
1540 * mnemonics table, ordered alphabetically.
|
|
1541 * 5 bytes name, 1 byte category, 2 bytes opcode, 8 bytes total.
|
|
1542 mnemtab fcc "ABX "
|
|
1543 fcb 0
|
|
1544 fdb $3a
|
|
1545 fcc "ADCA "
|
|
1546 fcb 7
|
|
1547 fdb $89
|
|
1548 fcc "ADCB "
|
|
1549 fcb 7
|
|
1550 fdb $c9
|
|
1551 fcc "ADDA "
|
|
1552 fcb 7
|
|
1553 fdb $8b
|
|
1554 fcc "ADDB "
|
|
1555 fcb 7
|
|
1556 fdb $cb
|
|
1557 fcc "ADDD "
|
|
1558 fcb 8
|
|
1559 fdb $c3
|
|
1560 fcc "ANDA "
|
|
1561 fcb 7
|
|
1562 fdb $84
|
|
1563 fcc "ANDB "
|
|
1564 fcb 7
|
|
1565 fdb $c4
|
|
1566 fcc "ANDCC"
|
|
1567 fcb 2
|
|
1568 fdb $1c
|
|
1569 fcc "ASL "
|
|
1570 fcb 10
|
|
1571 fdb $08
|
|
1572 fcc "ASLA "
|
|
1573 fcb 0
|
|
1574 fdb $48
|
|
1575 fcc "ASLB "
|
|
1576 fcb 0
|
|
1577 fdb $58
|
|
1578 fcc "ASR "
|
|
1579 fcb 10
|
|
1580 fdb $07
|
|
1581 fcc "ASRA "
|
|
1582 fcb 0
|
|
1583 fdb $47
|
|
1584 fcc "ASRB "
|
|
1585 fcb 0
|
|
1586 fdb $57
|
|
1587 fcc "BCC "
|
|
1588 fcb 4
|
|
1589 fdb $24
|
|
1590 fcc "BCS "
|
|
1591 fcb 4
|
|
1592 fdb $25
|
|
1593 fcc "BEQ "
|
|
1594 fcb 4
|
|
1595 fdb $27
|
|
1596 fcc "BGE "
|
|
1597 fcb 4
|
|
1598 fdb $2c
|
|
1599 fcc "BGT "
|
|
1600 fcb 4
|
|
1601 fdb $2e
|
|
1602 fcc "BHI "
|
|
1603 fcb 4
|
|
1604 fdb $22
|
|
1605 fcc "BHS "
|
|
1606 fcb 4
|
|
1607 fdb $24
|
|
1608 fcc "BITA "
|
|
1609 fcb 7
|
|
1610 fdb $85
|
|
1611 fcc "BITB "
|
|
1612 fcb 7
|
|
1613 fdb $c5
|
|
1614 fcc "BLE "
|
|
1615 fcb 4
|
|
1616 fdb $2f
|
|
1617 fcc "BLO "
|
|
1618 fcb 4
|
|
1619 fdb $25
|
|
1620 fcc "BLS "
|
|
1621 fcb 4
|
|
1622 fdb $23
|
|
1623 fcc "BLT "
|
|
1624 fcb 4
|
|
1625 fdb $2d
|
|
1626 fcc "BMI "
|
|
1627 fcb 4
|
|
1628 fdb $2b
|
|
1629 fcc "BNE "
|
|
1630 fcb 4
|
|
1631 fdb $26
|
|
1632 fcc "BPL "
|
|
1633 fcb 4
|
|
1634 fdb $2a
|
|
1635 fcc "BRA "
|
|
1636 fcb 4
|
|
1637 fdb $20
|
|
1638 fcc "BRN "
|
|
1639 fcb 4
|
|
1640 fdb $21
|
|
1641 mnembsr fcc "BSR "
|
|
1642 fcb 4
|
|
1643 fdb $8d
|
|
1644 fcc "BVC "
|
|
1645 fcb 4
|
|
1646 fdb $28
|
|
1647 fcc "BVS "
|
|
1648 fcb 4
|
|
1649 fdb $29
|
|
1650 fcc "CLR "
|
|
1651 fcb 10
|
|
1652 fdb $0f
|
|
1653 fcc "CLRA "
|
|
1654 fcb 0
|
|
1655 fdb $4f
|
|
1656 fcc "CLRB "
|
|
1657 fcb 0
|
|
1658 fdb $5f
|
|
1659 fcc "CMPA "
|
|
1660 fcb 7
|
|
1661 fdb $81
|
|
1662 fcc "CMPB "
|
|
1663 fcb 7
|
|
1664 fdb $c1
|
|
1665 fcc "CMPD "
|
|
1666 fcb 9
|
|
1667 fdb $1083
|
|
1668 fcc "CMPS "
|
|
1669 fcb 9
|
|
1670 fdb $118c
|
|
1671 fcc "CMPU "
|
|
1672 fcb 9
|
|
1673 fdb $1183
|
|
1674 fcc "CMPX "
|
|
1675 fcb 8
|
|
1676 fdb $8c
|
|
1677 fcc "CMPY "
|
|
1678 fcb 9
|
|
1679 fdb $108c
|
|
1680 fcc "COM "
|
|
1681 fcb 10
|
|
1682 fdb $03
|
|
1683 fcc "COMA "
|
|
1684 fcb 0
|
|
1685 fdb $43
|
|
1686 fcc "COMB "
|
|
1687 fcb 0
|
|
1688 fdb $53
|
|
1689 fcc "CWAI "
|
|
1690 fcb 2
|
|
1691 fdb $3c
|
|
1692 fcc "DAA "
|
|
1693 fcb 0
|
|
1694 fdb $19
|
|
1695 fcc "DEC "
|
|
1696 fcb 10
|
|
1697 fdb $0a
|
|
1698 fcc "DECA "
|
|
1699 fcb 0
|
|
1700 fdb $4a
|
|
1701 fcc "DECB "
|
|
1702 fcb 0
|
|
1703 fdb $5a
|
|
1704 fcc "EORA "
|
|
1705 fcb 7
|
|
1706 fdb $88
|
|
1707 fcc "EORB "
|
|
1708 fcb 7
|
|
1709 fdb $c8
|
|
1710 fcc "EQU "
|
|
1711 fcb 13
|
|
1712 fdb 0
|
|
1713 fcc "EXG "
|
|
1714 fcb 11
|
|
1715 fdb $1e
|
|
1716 mnemfcb fcc "FCB "
|
|
1717 fcb 13
|
|
1718 fdb 1
|
|
1719 fcc "FCC "
|
|
1720 fcb 13
|
|
1721 fdb 2
|
|
1722 fcc "FDB "
|
|
1723 fcb 13
|
|
1724 fdb 3
|
|
1725 fcc "INC "
|
|
1726 fcb 10
|
|
1727 fdb $0c
|
|
1728 fcc "INCA "
|
|
1729 fcb 0
|
|
1730 fdb $4c
|
|
1731 fcc "INCB "
|
|
1732 fcb 0
|
|
1733 fdb $5c
|
|
1734 fcc "JMP "
|
|
1735 fcb 10
|
|
1736 fdb $0e
|
|
1737 mnemjsr fcc "JSR "
|
|
1738 fcb 8
|
|
1739 fdb $8d
|
|
1740 fcc "LBCC "
|
|
1741 fcb 5
|
|
1742 fdb $1024
|
|
1743 fcc "LBCS "
|
|
1744 fcb 5
|
|
1745 fdb $1025
|
|
1746 fcc "LBEQ "
|
|
1747 fcb 5
|
|
1748 fdb $1027
|
|
1749 fcc "LBGE "
|
|
1750 fcb 5
|
|
1751 fdb $102c
|
|
1752 fcc "LBGT "
|
|
1753 fcb 5
|
|
1754 fdb $102e
|
|
1755 fcc "LBHI "
|
|
1756 fcb 5
|
|
1757 fdb $1022
|
|
1758 fcc "LBHS "
|
|
1759 fcb 5
|
|
1760 fdb $1024
|
|
1761 fcc "LBLE "
|
|
1762 fcb 5
|
|
1763 fdb $102f
|
|
1764 fcc "LBLO "
|
|
1765 fcb 5
|
|
1766 fdb $1025
|
|
1767 fcc "LBLS "
|
|
1768 fcb 5
|
|
1769 fdb $1023
|
|
1770 fcc "LBLT "
|
|
1771 fcb 5
|
|
1772 fdb $102d
|
|
1773 fcc "LBMI "
|
|
1774 fcb 5
|
|
1775 fdb $102b
|
|
1776 fcc "LBNE "
|
|
1777 fcb 5
|
|
1778 fdb $1026
|
|
1779 fcc "LBPL "
|
|
1780 fcb 5
|
|
1781 fdb $102a
|
|
1782 fcc "LBRA "
|
|
1783 fcb 6
|
|
1784 fdb $16
|
|
1785 fcc "LBRN "
|
|
1786 fcb 5
|
|
1787 fdb $1021
|
|
1788 fcc "LBSR "
|
|
1789 fcb 6
|
|
1790 fdb $17
|
|
1791 fcc "LBVC "
|
|
1792 fcb 5
|
|
1793 fdb $1028
|
|
1794 fcc "LBVS "
|
|
1795 fcb 5
|
|
1796 fdb $1029
|
|
1797 fcc "LDA "
|
|
1798 fcb 7
|
|
1799 fdb $86
|
|
1800 fcc "LDB "
|
|
1801 fcb 7
|
|
1802 fdb $c6
|
|
1803 fcc "LDD "
|
|
1804 fcb 8
|
|
1805 fdb $cc
|
|
1806 fcc "LDS "
|
|
1807 fcb 9
|
|
1808 fdb $10ce
|
|
1809 fcc "LDU "
|
|
1810 fcb 8
|
|
1811 fdb $ce
|
|
1812 fcc "LDX "
|
|
1813 fcb 8
|
|
1814 fdb $8e
|
|
1815 fcc "LDY "
|
|
1816 fcb 9
|
|
1817 fdb $108e
|
|
1818 fcc "LEAS "
|
|
1819 fcb 3
|
|
1820 fdb $32
|
|
1821 fcc "LEAU "
|
|
1822 fcb 3
|
|
1823 fdb $33
|
|
1824 fcc "LEAX "
|
|
1825 fcb 3
|
|
1826 fdb $30
|
|
1827 fcc "LEAY "
|
|
1828 fcb 3
|
|
1829 fdb $31
|
|
1830 fcc "LSL "
|
|
1831 fcb 10
|
|
1832 fdb $08
|
|
1833 fcc "LSLA "
|
|
1834 fcb 0
|
|
1835 fdb $48
|
|
1836 fcc "LSLB "
|
|
1837 fcb 0
|
|
1838 fdb $58
|
|
1839 fcc "LSR "
|
|
1840 fcb 10
|
|
1841 fdb $04
|
|
1842 fcc "LSRA "
|
|
1843 fcb 0
|
|
1844 fdb $44
|
|
1845 fcc "LSRB "
|
|
1846 fcb 0
|
|
1847 fdb $54
|
|
1848 fcc "MUL "
|
|
1849 fcb 0
|
|
1850 fdb $3d
|
|
1851 fcc "NEG "
|
|
1852 fcb 10
|
|
1853 fdb $00
|
|
1854 fcc "NEGA "
|
|
1855 fcb 0
|
|
1856 fdb $40
|
|
1857 fcc "NEGB "
|
|
1858 fcb 0
|
|
1859 fdb $50
|
|
1860 fcc "NOP "
|
|
1861 fcb 0
|
|
1862 fdb $12
|
|
1863 fcc "ORA "
|
|
1864 fcb 7
|
|
1865 fdb $8a
|
|
1866 fcc "ORB "
|
|
1867 fcb 7
|
|
1868 fdb $ca
|
|
1869 fcc "ORCC "
|
|
1870 fcb 2
|
|
1871 fdb $1a
|
|
1872 fcc "ORG "
|
|
1873 fcb 13
|
|
1874 fdb 4
|
|
1875 fcc "PSHS "
|
|
1876 fcb 12
|
|
1877 fdb $34
|
|
1878 fcc "PSHU "
|
|
1879 fcb 12
|
|
1880 fdb $36
|
|
1881 fcc "PULS "
|
|
1882 fcb 12
|
|
1883 fdb $35
|
|
1884 fcc "PULU "
|
|
1885 fcb 12
|
|
1886 fdb $37
|
|
1887 fcc "RMB "
|
|
1888 fcb 13
|
|
1889 fdb 5
|
|
1890 fcc "ROL "
|
|
1891 fcb 10
|
|
1892 fdb $09
|
|
1893 fcc "ROLA "
|
|
1894 fcb 0
|
|
1895 fdb $49
|
|
1896 fcc "ROLB "
|
|
1897 fcb 0
|
|
1898 fdb $59
|
|
1899 fcc "ROR "
|
|
1900 fcb 10
|
|
1901 fdb $06
|
|
1902 fcc "RORA "
|
|
1903 fcb 0
|
|
1904 fdb $46
|
|
1905 fcc "RORB "
|
|
1906 fcb 0
|
|
1907 fdb $56
|
|
1908 fcc "RTI "
|
|
1909 fcb 0
|
|
1910 fdb $3b
|
|
1911 fcc "RTS "
|
|
1912 fcb 0
|
|
1913 fdb $39
|
|
1914 fcc "SBCA "
|
|
1915 fcb 7
|
|
1916 fdb $82
|
|
1917 fcc "SBCB "
|
|
1918 fcb 7
|
|
1919 fdb $c2
|
|
1920 fcc "SET "
|
|
1921 fcb 13
|
|
1922 fdb 6
|
|
1923 fcc "SETDP"
|
|
1924 fcb 13
|
|
1925 fdb 7
|
|
1926 fcc "SEX "
|
|
1927 fcb 0
|
|
1928 fdb $1d
|
|
1929 fcc "STA "
|
|
1930 fcb 7
|
|
1931 fdb $87
|
|
1932 fcc "STB "
|
|
1933 fcb 7
|
|
1934 fdb $c7
|
|
1935 fcc "STD "
|
|
1936 fcb 8
|
|
1937 fdb $cd
|
|
1938 fcc "STS "
|
|
1939 fcb 9
|
|
1940 fdb $10cf
|
|
1941 fcc "STU "
|
|
1942 fcb 8
|
|
1943 fdb $cf
|
|
1944 fcc "STX "
|
|
1945 fcb 8
|
|
1946 fdb $8f
|
|
1947 fcc "STY "
|
|
1948 fcb 9
|
|
1949 fdb $108f
|
|
1950 fcc "SUBA "
|
|
1951 fcb 7
|
|
1952 fdb $80
|
|
1953 fcc "SUBB "
|
|
1954 fcb 7
|
|
1955 fdb $c0
|
|
1956 fcc "SUBD "
|
|
1957 fcb 8
|
|
1958 fdb $83
|
|
1959 fcc "SWI "
|
|
1960 fcb 0
|
|
1961 fdb $3f
|
|
1962 fcb "SWI2 "
|
|
1963 fcb 1
|
|
1964 fdb $103f
|
|
1965 fcb "SWI3 "
|
|
1966 fcb 1
|
|
1967 fdb $113f
|
|
1968 fcc "SYNC "
|
|
1969 fcb 0
|
|
1970 fdb $13
|
|
1971 fcc "TFR "
|
|
1972 fcb 11
|
|
1973 fdb $1f
|
|
1974 fcc "TST "
|
|
1975 fcb 10
|
|
1976 fdb $0d
|
|
1977 fcc "TSTA "
|
|
1978 fcb 0
|
|
1979 fdb $4d
|
|
1980 fcc "TSTB "
|
|
1981 fcb 0
|
|
1982 fdb $5d
|
|
1983
|
|
1984 mnemsize equ (*-mnemtab)/8
|
|
1985
|
|
1986 * Register table for PUSH/PULL and TFR/EXG instructions.
|
|
1987 * 3 bytes for name, 1 for tfr/exg, 1 for push/pull, 5 total
|
|
1988 asmregtab fcc "X "
|
|
1989 fcb $01,$10
|
|
1990 fcc "Y "
|
|
1991 fcb $02,$20
|
|
1992 aregu fcc "U "
|
|
1993 fcb $03,$40
|
|
1994 aregs fcc "S "
|
|
1995 fcb $04,$40
|
|
1996 fcc "PC "
|
|
1997 fcb $05,$80
|
|
1998 fcc "A "
|
|
1999 fcb $08,$02
|
|
2000 fcc "B "
|
|
2001 fcb $09,$04
|
|
2002 fcc "D "
|
|
2003 fcb $00,$06
|
|
2004 fcc "CC "
|
|
2005 fcb $0a,$01
|
|
2006 fcc "CCR"
|
|
2007 fcb $0a,$01
|
|
2008 fcc "DP "
|
|
2009 fcb $0b,$08
|
|
2010 fcc "DPR"
|
|
2011 fcb $0b,$08
|
|
2012 reginval fcc "? "
|
|
2013
|
|
2014 ixregs fcc "XYUS"
|
|
2015
|
|
2016 * opcode offsets to basic opcode, depends on first nibble.
|
|
2017 opcoffs fcb 0,0,0,0,0,0,-$60,-$70
|
|
2018 fcb 0,-$10,-$20,-$30,0,-$10,-$20,-$30
|
|
2019 * mode depending on first nibble of opcode.
|
|
2020 modetab fcb 3,0,0,0,0,0,5,4,1,3,5,4,1,3,5,4
|
|
2021 * mode depending on category code stored in mnemtab
|
|
2022 modetab2 fcb 0,0,1,5,6,7,7,1,2,2,0,8,9
|
|
2023 * modes in this context: 0 no operands, 1 8-bit immediate, 2 16 bit imm,
|
|
2024 * 3, 8-bit address, 4 16 bit address, 5 indexed with postbyte, 6 short
|
|
2025 * relative, 7 long relative, 8 pushpul, 9 tftetx
|
|
2026
|
|
2027 * Decode instruction pointed to by Y for disassembly (and to find out
|
|
2028 * how long it is). On return, U points to appropriate mnemonic table entry,
|
|
2029 * Y points past instruction.
|
|
2030 * It's rather clumsy code, but we do want to reuse the same table
|
|
2031 * as used with assembling.
|
|
2032 disdecode clr prebyte
|
|
2033 clr amode
|
|
2034 lda ,y+
|
|
2035 cmpa #$10
|
|
2036 beq ddec1
|
|
2037 cmpa #$11
|
|
2038 bne ddec2
|
|
2039 ddec1 sta prebyte ;Store $10 or $11 prebyte.
|
|
2040 lda ,y+ ;Get new opcode.
|
|
2041 ddec2 sta opcode
|
|
2042 lsra
|
|
2043 lsra
|
|
2044 lsra
|
|
2045 lsra ;Get high nibble.
|
|
2046 ldx #modetab
|
|
2047 ldb a,x
|
|
2048 stb amode
|
|
2049 ldx #opcoffs
|
|
2050 lda a,x
|
|
2051 adda opcode ;Add opcode offset to opcode.
|
|
2052 ddec4 sta opc1 ;Store the 'basis' opcode.
|
|
2053 ldu #mnemtab
|
|
2054 ldx #mnemsize
|
|
2055 ddecloop ldb #13
|
|
2056 cmpb 5,u ;Compare category code with 13
|
|
2057 beq ddec3 ;13=pseudo op, no valid opcode
|
|
2058 ldd prebyte
|
|
2059 cmpd 6,u
|
|
2060 beq ddecfound ;Opcode&prebyte agree, operation found.
|
|
2061 ddec3 leau 8,u ;point to next mnemonic
|
|
2062 leax -1,x
|
|
2063 bne ddecloop
|
|
2064 ldu #mnemfcb ;mnemonic not found, use FCB byte.
|
|
2065 lda #3
|
|
2066 sta amode ;Store mode 3, 8 bit address.
|
|
2067 lda opcode
|
|
2068 tst prebyte
|
|
2069 beq ddec5
|
|
2070 lda prebyte ;if it was the combination prebyte
|
|
2071 clr prebyte ;and opcode that was not found,
|
|
2072 leay -1,y ;FCB just the prebyte
|
|
2073 ddec5 sta operand+1 ;The byte must be stored as operand.
|
|
2074 rts
|
|
2075 ddecfound cmpu #mnembsr
|
|
2076 bne ddec6
|
|
2077 lda #$8d ;Is it really the BSR opcode?
|
|
2078 cmpa opcode
|
|
2079 beq ddec6
|
|
2080 ldu #mnemjsr ;We mistakenly found BSR instead of JSR
|
|
2081 ddec6 lda amode
|
|
2082 anda #$FE
|
|
2083 bne ddec7
|
|
2084 lda 5,u ;nibble-dependent mode was 0 or 1,
|
|
2085 ldx #modetab2 ;use category dependent mode instead.
|
|
2086 lda a,x
|
|
2087 sta amode
|
|
2088 ddec7 lda amode
|
|
2089 asla
|
|
2090 ldx #disdectab
|
|
2091 jmp [a,x] ;jump dependent on definitive mode.
|
|
2092 disdectab fdb noop,opdec1,opdec2,opdec1,opdec2,opdecidx
|
|
2093 fdb opdec1,opdec2,opdecpb,opdecpb
|
|
2094 disdectab1 fdb noop,noop,noop,noop,noop,noop,noop,noop
|
|
2095 fdb opdec1,opdec2,noop,noop,opdec1,opdec2,noop,opdec2
|
|
2096 opdec1 ldb ,y+
|
|
2097 sex
|
|
2098 od1a std operand
|
|
2099 noop rts
|
|
2100 opdec2 ldd ,y++
|
|
2101 bra od1a
|
|
2102 opdecpb ldb ,y+
|
|
2103 odpa stb postbyte
|
|
2104 rts
|
|
2105 opdecidx ldb ,y+
|
|
2106 bpl odpa ;postbytes <$80 have no extra operands.
|
|
2107 stb postbyte
|
|
2108 andb #$0f
|
|
2109 aslb
|
|
2110 ldx #disdectab1
|
|
2111 jmp [b,x]
|
|
2112
|
|
2113 * Display disassembled instruction after the invocation of disdecode.
|
|
2114 * U points to mnemonic table entry.
|
|
2115 disdisp tfr u,x
|
|
2116 ldb #5
|
|
2117 jsr putline ;Display the mnemonic.
|
|
2118 ldb #' '
|
|
2119 jsr putchar
|
|
2120 lda amode
|
|
2121 asla
|
|
2122 ldx #disdisptab
|
|
2123 jmp [a,x] ;Perform action dependent on mode.
|
|
2124 disdisptab fdb noop,disim8,disim16,disadr8,disadr16
|
|
2125 fdb disidx,disrel8,disrel16,distfr,dispush
|
|
2126 disim8 bsr puthash
|
|
2127 bra disadr8
|
|
2128 disim16 bsr puthash
|
|
2129 disadr16 bsr putdol
|
|
2130 ldd operand
|
|
2131 jmp outd
|
|
2132 disadr8 bsr putdol
|
|
2133 lda operand+1
|
|
2134 jmp outbyte
|
|
2135 disrel8 bsr putdol
|
|
2136 ldb operand+1
|
|
2137 sex
|
|
2138 dr8a sty temp
|
|
2139 addd temp
|
|
2140 jmp outd
|
|
2141 disrel16 bsr putdol
|
|
2142 ldd operand
|
|
2143 bra dr8a
|
|
2144
|
|
2145 puthash ldb #'#'
|
|
2146 jmp putchar
|
|
2147 putdol ldb #'$'
|
|
2148 jmp putchar
|
|
2149 putcomma ldb #','
|
|
2150 jmp putchar
|
|
2151 putspace ldb #' '
|
|
2152 jmp putchar
|
|
2153
|
|
2154 dispush ldb #12
|
|
2155 ldx #asmregtab ;Walk through the register table.
|
|
2156 clr temp
|
|
2157 regloop lda postbyte
|
|
2158 anda 4,x
|
|
2159 beq dispush1 ;Is bit corresponding to reg set in postbyte
|
|
2160 cmpx #aregu
|
|
2161 bne dispush3
|
|
2162 sta temp+1
|
|
2163 lda opcode
|
|
2164 anda #2
|
|
2165 bne dispush1 ;no u register in pshu pulu.
|
|
2166 lda temp+1
|
|
2167 dispush3 cmpx #aregs
|
|
2168 bne dispush4
|
|
2169 sta temp+1
|
|
2170 lda opcode
|
|
2171 anda #2
|
|
2172 beq dispush1 ;no s register in pshs puls.
|
|
2173 lda temp+1
|
|
2174 dispush4 coma
|
|
2175 anda postbyte ;remove the bits from postbyte.
|
|
2176 sta postbyte
|
|
2177 pshs b
|
|
2178 tst temp
|
|
2179 beq dispush2
|
|
2180 bsr putcomma ;print comma after first register.
|
|
2181 dispush2 bsr disregname
|
|
2182 inc temp
|
|
2183 puls b
|
|
2184 dispush1 leax 5,x
|
|
2185 decb
|
|
2186 bne regloop
|
|
2187 rts
|
|
2188
|
|
2189 distfr lda postbyte
|
|
2190 lsra
|
|
2191 lsra
|
|
2192 lsra
|
|
2193 lsra
|
|
2194 bsr distfrsub
|
|
2195 bsr putcomma
|
|
2196 lda postbyte
|
|
2197 anda #$0f
|
|
2198 distfrsub ldb #12
|
|
2199 ldx #asmregtab
|
|
2200 distfrloop cmpa 3,x
|
|
2201 beq distfrend
|
|
2202 leax 5,x
|
|
2203 decb
|
|
2204 bne distfrloop
|
|
2205 distfrend bsr disregname
|
|
2206 rts
|
|
2207
|
|
2208 disregname lda #3
|
|
2209 tfr x,u
|
|
2210 drnloop ldb ,u+
|
|
2211 cmpb #' '
|
|
2212 beq drnend
|
|
2213 jsr putchar
|
|
2214 deca
|
|
2215 bne drnloop
|
|
2216 drnend rts
|
|
2217
|
|
2218 disidxreg lda postbyte
|
|
2219 lsra
|
|
2220 lsra
|
|
2221 lsra
|
|
2222 lsra
|
|
2223 lsra
|
|
2224 anda #3
|
|
2225 ldx #ixregs
|
|
2226 ldb a,x
|
|
2227 jmp putchar
|
|
2228
|
|
2229 disidx clr temp
|
|
2230 lda postbyte
|
|
2231 bmi disidx1
|
|
2232 anda #$1f
|
|
2233 bita #$10
|
|
2234 bne negoffs
|
|
2235 jsr outdecbyte
|
|
2236 bra discomma
|
|
2237 negoffs ldb #'-'
|
|
2238 jsr putchar
|
|
2239 ora #$f0
|
|
2240 nega
|
|
2241 jsr outdecbyte
|
|
2242 discomma jsr putcomma ;Display ,Xreg and terminating ]
|
|
2243 disindex bsr disidxreg
|
|
2244 disindir tst temp ;Display ] if indirect.
|
|
2245 beq disidxend
|
|
2246 ldb #']'
|
|
2247 jsr putchar
|
|
2248 disidxend rts
|
|
2249 disidx1 bita #$10
|
|
2250 beq disidx2
|
|
2251 ldb #'['
|
|
2252 jsr putchar
|
|
2253 inc temp
|
|
2254 disidx2 lda postbyte
|
|
2255 anda #$0f
|
|
2256 asla
|
|
2257 ldx #disidxtab
|
|
2258 jmp [a,x] ;Jump to routine for indexed mode
|
|
2259 disadec2 lda #2
|
|
2260 bra disadeca
|
|
2261 disadec1 lda #1
|
|
2262 disadeca jsr putcomma
|
|
2263 disadloop ldb #'-'
|
|
2264 jsr putchar
|
|
2265 deca
|
|
2266 bne disadloop
|
|
2267 bra disindex
|
|
2268 disainc2 lda #2
|
|
2269 bra disainca
|
|
2270 disainc1 lda #1
|
|
2271 disainca sta temp+1
|
|
2272 jsr putcomma
|
|
2273 jsr disidxreg
|
|
2274 lda temp+1
|
|
2275 disailoop ldb #'+'
|
|
2276 jsr putchar
|
|
2277 deca
|
|
2278 bne disailoop
|
|
2279 jmp disindir
|
|
2280 disax ldb #'A'
|
|
2281 jsr putchar
|
|
2282 jmp discomma
|
|
2283 disbx ldb #'B'
|
|
2284 jsr putchar
|
|
2285 jmp discomma
|
|
2286 disdx ldb #'D'
|
|
2287 jsr putchar
|
|
2288 jmp discomma
|
|
2289 disinval ldb #'?'
|
|
2290 jsr putchar
|
|
2291 jmp disindir
|
|
2292 disnx lda operand+1
|
|
2293 bmi disnxneg
|
|
2294 disnx1 jsr putdol
|
|
2295 jsr outbyte
|
|
2296 jmp discomma
|
|
2297 disnxneg ldb #'-'
|
|
2298 jsr putchar
|
|
2299 nega
|
|
2300 bra disnx1
|
|
2301 disnnx jsr putdol
|
|
2302 ldd operand
|
|
2303 jsr outd
|
|
2304 jmp discomma
|
|
2305 disnpc jsr putdol
|
|
2306 ldb operand+1
|
|
2307 sex
|
|
2308 disnpca sty temp2
|
|
2309 addd temp2
|
|
2310 jsr outd
|
|
2311 ldx #commapc
|
|
2312 ldb #4
|
|
2313 jsr putline
|
|
2314 jmp disindir
|
|
2315 disnnpc jsr putdol
|
|
2316 ldd operand
|
|
2317 bra disnpca
|
|
2318 disdirect jsr putdol
|
|
2319 ldd operand
|
|
2320 jsr outd
|
|
2321 jmp disindir
|
|
2322
|
|
2323 commapc fcc ",PCR"
|
|
2324
|
|
2325 disidxtab fdb disainc1,disainc2,disadec1,disadec2
|
|
2326 fdb discomma,disbx,disax,disinval
|
|
2327 fdb disnx,disnnx,disinval,disdx
|
|
2328 fdb disnpc,disnnpc,disinval,disdirect
|
|
2329
|
|
2330 * Display byte A in decimal (0<=A<20)
|
|
2331 outdecbyte cmpa #10
|
|
2332 blo odb1
|
|
2333 suba #10
|
|
2334 ldb #'1'
|
|
2335 jsr putchar
|
|
2336 odb1 adda #'0'
|
|
2337 tfr a,b
|
|
2338 jmp putchar
|
|
2339
|
|
2340 * This is the code for the U command, unassemble instructions in memory.
|
|
2341 * Syntax: U or Uaddr or Uaddr,length
|
|
2342 unasm bsr disasm
|
|
2343 jmp cmdline
|
|
2344 disasm ldx #linebuf+1
|
|
2345 ldd #20
|
|
2346 jsr scan2parms ;Scan address,length parameters.
|
|
2347 dis1 ldd addr
|
|
2348 addd length
|
|
2349 std length
|
|
2350 ldy addr
|
|
2351 unasmloop tfr y,d
|
|
2352 jsr outd ;Display instruction address
|
|
2353 jsr putspace
|
|
2354 pshs y
|
|
2355 jsr disdecode
|
|
2356 puls x
|
|
2357 sty temp
|
|
2358 clr temp2
|
|
2359 unadishex lda ,x+
|
|
2360 jsr outbyte
|
|
2361 inc temp2
|
|
2362 inc temp2
|
|
2363 cmpx temp
|
|
2364 bne unadishex ;Display instruction bytes as hex.
|
|
2365 unadisspc ldb #' '
|
|
2366 jsr putchar
|
|
2367 inc temp2
|
|
2368 lda #11
|
|
2369 cmpa temp2 ;Fill out with spaces to width 11.
|
|
2370 bne unadisspc
|
|
2371 bne unadishex
|
|
2372 jsr disdisp ;Display disassembled instruction.
|
|
2373 tst disflg
|
|
2374 bne skipcr
|
|
2375 jsr putcr
|
|
2376 skipcr cmpy length
|
|
2377 bls unasmloop
|
|
2378 sty addr
|
|
2379 rts
|
|
2380
|
|
2381 * Simple 'expression evaluator' for assembler.
|
|
2382 expr ldb ,x
|
|
2383 cmpb #'-'
|
|
2384 bne pos
|
|
2385 clrb
|
|
2386 leax 1,x
|
|
2387 pos pshs b
|
|
2388 bsr scanfact
|
|
2389 beq exprend1
|
|
2390 tst ,s+
|
|
2391 bne exprend ;Was the minus sign there.
|
|
2392 coma
|
|
2393 comb
|
|
2394 addd #1
|
|
2395 andcc #$fb ;Clear Z flag for valid result.
|
|
2396 exprend rts
|
|
2397 exprend1 puls b
|
|
2398 rts
|
|
2399
|
|
2400 scanfact ldb ,x+
|
|
2401 cmpb #'$'
|
|
2402 lbeq scanhex ;Hex number if starting with dollar.
|
|
2403 cmpb #'''
|
|
2404 bne scandec ;char if starting with ' else decimal
|
|
2405 ldb ,x+
|
|
2406 lda ,x
|
|
2407 cmpa #'''
|
|
2408 bne scanchar2
|
|
2409 leax 1,x ;Increment past final quote if it's there.
|
|
2410 scanchar2 clra
|
|
2411 andcc #$fb ;Clear zero flag.
|
|
2412 rts
|
|
2413 scandec cmpb #'0'
|
|
2414 blo noexpr
|
|
2415 cmpb #'9'
|
|
2416 bhi noexpr
|
|
2417 clr temp
|
|
2418 clr temp+1
|
|
2419 scandloop subb #'0'
|
|
2420 bcs sdexit
|
|
2421 cmpb #10
|
|
2422 bcc sdexit
|
|
2423 pshs b
|
|
2424 ldd temp
|
|
2425 aslb
|
|
2426 rola
|
|
2427 pshs d
|
|
2428 aslb
|
|
2429 rola
|
|
2430 aslb
|
|
2431 rola
|
|
2432 addd ,s++ ;Multiply number by 10.
|
|
2433 addb ,s+
|
|
2434 adca #0 ;Add digit to 10.
|
|
2435 std temp
|
|
2436 ldb ,x+ ;Get next character.
|
|
2437 bra scandloop
|
|
2438 sdexit ldd temp
|
|
2439 leax -1,x
|
|
2440 andcc #$fb
|
|
2441 rts
|
|
2442 noexpr orcc #$04
|
|
2443 rts
|
|
2444
|
|
2445 * Assemble the instruction pointed to by X.
|
|
2446 * Fisrt stage: copy mnemonic to mnemonic buffer.
|
|
2447 asminstr lda #5
|
|
2448 ldu #mnembuf
|
|
2449 mncploop ldb ,x+
|
|
2450 beq mncpexit
|
|
2451 cmpb #' '
|
|
2452 beq mncpexit ;Mnemonic ends at first space or null
|
|
2453 andb #CASEMASK
|
|
2454 cmpb #'A'
|
|
2455 blo nolet
|
|
2456 cmpb #'Z'
|
|
2457 bls mnemcp1 ;Capitalize letters, but only letters.
|
|
2458 nolet ldb -1,x
|
|
2459 mnemcp1 stb ,u+ ;Copy to mnemonic buffer.
|
|
2460 deca
|
|
2461 bne mncploop
|
|
2462 mncpexit tsta
|
|
2463 beq mncpdone
|
|
2464 ldb #' '
|
|
2465 mnfilloop stb ,u+
|
|
2466 deca
|
|
2467 bne mnfilloop ;Fill the rest of mnem buffer with spaces.
|
|
2468 * Second stage: look mnemonic up using binary search.
|
|
2469 mncpdone stx temp3
|
|
2470 clr temp ;Low index=0
|
|
2471 lda #mnemsize
|
|
2472 sta temp+1 ;High index=mnemsize.
|
|
2473 bsrchloop ldb temp+1
|
|
2474 cmpb #$ff
|
|
2475 beq invmnem ;lower limit -1?
|
|
2476 cmpb temp
|
|
2477 blo invmnem ;hi index lower than low index?
|
|
2478 clra
|
|
2479 addb temp ;Add indexes.
|
|
2480 adca #0
|
|
2481 lsra
|
|
2482 rorb ;Divide by 2 to get average
|
|
2483 stb temp2
|
|
2484 aslb
|
|
2485 rola
|
|
2486 aslb
|
|
2487 rola
|
|
2488 aslb
|
|
2489 rola ;Multiply by 8 to get offset.
|
|
2490 ldu #mnemtab
|
|
2491 leau d,u ;Add offset to table base
|
|
2492 tfr u,y
|
|
2493 lda #5
|
|
2494 ldx #mnembuf
|
|
2495 bscmploop ldb ,x+
|
|
2496 cmpb ,y+
|
|
2497 bne bscmpexit ;Characters don't match?
|
|
2498 deca
|
|
2499 bne bscmploop
|
|
2500 jmp mnemfound ;We found the mnemonic.
|
|
2501 bscmpexit ldb temp2
|
|
2502 bcc bscmplower
|
|
2503 decb
|
|
2504 stb temp+1 ;mnembuf<table, adjust high limit.
|
|
2505 bra bsrchloop
|
|
2506 bscmplower incb
|
|
2507 stb temp ;mnembuf>table, adjust low limit.
|
|
2508 bra bsrchloop
|
|
2509 invmnem ldx #invmmsg
|
|
2510 jmp asmerrvec
|
|
2511 * Stage 3: Perform routine depending on category code.
|
|
2512 mnemfound clr uncert
|
|
2513 ldy addr
|
|
2514 lda 5,u
|
|
2515 asla
|
|
2516 ldx #asmtab
|
|
2517 jsr [a,x]
|
|
2518 sty addr
|
|
2519 rts
|
|
2520 asmtab fdb onebyte,twobyte,immbyte,lea
|
|
2521 fdb sbranch,lbranch,lbra,acc8
|
|
2522 fdb dreg1,dreg2,oneaddr,tfrexg
|
|
2523 fdb pushpul,pseudovec
|
|
2524
|
|
2525 putbyte stb ,y+
|
|
2526 rts
|
|
2527 putword std ,y++
|
|
2528 rts
|
|
2529
|
|
2530 onebyte ldb 7,u ;Cat 0, one byte opcode w/o operands RTS
|
|
2531 bra putbyte
|
|
2532 twobyte ldd 6,u ;Cat 1, two byte opcode w/o operands SWI2
|
|
2533 bra putword
|
|
2534 immbyte ldb 7,u ;Cat 2, opcode w/ immdiate operand ANDCC
|
|
2535 bsr putbyte
|
|
2536 jsr scanops
|
|
2537 ldb amode
|
|
2538 cmpb #1
|
|
2539 lbne moderr
|
|
2540 ldb operand+1
|
|
2541 bra putbyte
|
|
2542 lea ldb 7,u ;Cat 3, LEA
|
|
2543 bsr putbyte
|
|
2544 jsr scanops
|
|
2545 lda amode
|
|
2546 cmpa #1
|
|
2547 lbeq moderr ;No immediate w/ lea
|
|
2548 cmpa #3
|
|
2549 lbhs doaddr
|
|
2550 jsr set3
|
|
2551 lda #$8f
|
|
2552 sta postbyte
|
|
2553 lda #2
|
|
2554 sta opsize ;Use 8F nn nn for direct mode.
|
|
2555 jmp doaddr
|
|
2556 sbranch ldb 7,u ;Cat 4, short branch instructions
|
|
2557 bsr putbyte
|
|
2558 jsr startop
|
|
2559 leax -1,x
|
|
2560 jsr exprvec
|
|
2561 lbeq exprerr
|
|
2562 jmp shortrel
|
|
2563 lbranch ldd 6,u ;Cat 5, long brach w/ two byte opcode
|
|
2564 bsr putword
|
|
2565 lbra1 jsr startop
|
|
2566 leax -1,x
|
|
2567 jsr exprvec
|
|
2568 lbeq exprerr
|
|
2569 jmp longrel
|
|
2570 lbra ldb 7,u ;Cat 6, long branch w/ one byte opcode.
|
|
2571 jsr putbyte
|
|
2572 bra lbra1
|
|
2573 acc8 lda #1 ;Cat 7, 8-bit two operand instructions ADDA
|
|
2574 sta opsize
|
|
2575 jsr scanops
|
|
2576 jsr adjopc
|
|
2577 jsr putbyte
|
|
2578 jmp doaddr
|
|
2579 dreg1 lda #2 ;Cat 8, 16-bit 2operand insns 1byte opc LDX
|
|
2580 sta opsize
|
|
2581 jsr scanops
|
|
2582 jsr adjopc
|
|
2583 jsr putbyte
|
|
2584 jmp doaddr
|
|
2585 dreg2 lda #2 ;Cat 9, 16-bit 2operand insns 2byte opc LDY
|
|
2586 sta opsize
|
|
2587 jsr scanops
|
|
2588 jsr adjopc
|
|
2589 lda 6,u
|
|
2590 jsr putword
|
|
2591 jmp doaddr
|
|
2592 oneaddr jsr scanops ;Cat 10, one-operand insns NEG..CLR
|
|
2593 ldb 7,u
|
|
2594 lda amode
|
|
2595 cmpa #1
|
|
2596 lbeq moderr ;No immediate mode
|
|
2597 cmpa #3
|
|
2598 bhs oaind ;indexed etc
|
|
2599 lda opsize
|
|
2600 deca
|
|
2601 beq oadir
|
|
2602 addb #$10 ;Add $70 for extended direct.
|
|
2603 oaind addb #$60 ;And $60 for indexed etc.
|
|
2604 oadir jsr putbyte ;And nothing for direct8.
|
|
2605 jmp doaddr
|
|
2606 tfrexg jsr startop ;Cat 11, TFR and EXG
|
|
2607 leax -1,x
|
|
2608 ldb 7,u
|
|
2609 jsr putbyte
|
|
2610 jsr findreg
|
|
2611 ldb ,u
|
|
2612 aslb
|
|
2613 aslb
|
|
2614 aslb
|
|
2615 aslb
|
|
2616 stb postbyte
|
|
2617 ldb ,x+
|
|
2618 cmpb #','
|
|
2619 lbne moderr
|
|
2620 jsr findreg
|
|
2621 ldb ,u
|
|
2622 orb postbyte
|
|
2623 jmp putbyte
|
|
2624 pushpul jsr startop ;Cat 12, PSH and PUL
|
|
2625 leax -1,x
|
|
2626 ldb 7,u
|
|
2627 jsr putbyte
|
|
2628 clr postbyte
|
|
2629 pploop jsr findreg
|
|
2630 ldb 1,u
|
|
2631 orb postbyte
|
|
2632 stb postbyte
|
|
2633 ldb ,x+
|
|
2634 cmpb #','
|
|
2635 beq pploop
|
|
2636 leax -1,x
|
|
2637 ldb postbyte
|
|
2638 jmp putbyte
|
|
2639 pseudo ldb 7,u ;Cat 13, pseudo oeprations
|
|
2640 aslb
|
|
2641 ldx #pseudotab
|
|
2642 jmp [b,x]
|
|
2643 pseudotab fdb pseudoend,dofcb,dofcc,dofdb
|
|
2644 fdb doorg,dormb,pseudoend,pseudoend
|
|
2645 dofcb jsr startop
|
|
2646 leax -1,x
|
|
2647 fcbloop jsr exprvec
|
|
2648 lbeq exprerr
|
|
2649 jsr putbyte
|
|
2650 ldb ,x+
|
|
2651 cmpb #','
|
|
2652 beq fcbloop
|
|
2653 pseudoend rts
|
|
2654 dofcc jsr startop
|
|
2655 tfr b,a ;Save delimiter.
|
|
2656 fccloop ldb ,x+
|
|
2657 beq pseudoend
|
|
2658 pshs a
|
|
2659 cmpb ,s+
|
|
2660 beq pseudoend
|
|
2661 jsr putbyte
|
|
2662 bra fccloop
|
|
2663 dofdb jsr startop
|
|
2664 leax -1,x
|
|
2665 fdbloop jsr exprvec
|
|
2666 lbeq exprerr
|
|
2667 jsr putword
|
|
2668 ldb ,x+
|
|
2669 cmpb #','
|
|
2670 beq fdbloop
|
|
2671 rts
|
|
2672 doorg jsr startop
|
|
2673 leax -1,x
|
|
2674 jsr exprvec
|
|
2675 lbeq exprerr
|
|
2676 tfr d,y
|
|
2677 rts
|
|
2678 dormb jsr startop
|
|
2679 leax -1,x
|
|
2680 jsr exprvec
|
|
2681 lbeq exprerr
|
|
2682 leay d,y
|
|
2683 rts
|
|
2684
|
|
2685
|
|
2686 * Adjust opcdoe depending on mode (in $80-$FF range)
|
|
2687 adjopc ldb 7,u
|
|
2688 lda amode
|
|
2689 cmpa #2
|
|
2690 beq adjdir ;Is it direct?
|
|
2691 cmpa #3
|
|
2692 bhs adjind ;Indexed etc?
|
|
2693 rts ;Not, then immediate, no adjust.
|
|
2694 adjind addb #$20 ;Add $20 to opcode for indexed etc modes.
|
|
2695 rts
|
|
2696 adjdir addb #$10 ;Add $10 to opcode for direct8
|
|
2697 lda opsize
|
|
2698 deca
|
|
2699 bne adjind ;If opsize=2, add another $20 for extended16
|
|
2700 rts
|
|
2701
|
|
2702 * Start scanning of operands.
|
|
2703 startop ldx temp3
|
|
2704 clr amode
|
|
2705 jmp skipspace
|
|
2706
|
|
2707 * amode settings in assembler: 1=immediate, 2=direct/extended, 3=indexed
|
|
2708 * etc. 4=pc relative, 5=indirect, 6=pcrelative and indirect.
|
|
2709
|
|
2710 * This subroutine scans the assembler operands.
|
|
2711 scanops bsr startop
|
|
2712 cmpb #'['
|
|
2713 bne noindir
|
|
2714 lda #5 ;operand starts with [, then indirect.
|
|
2715 sta amode
|
|
2716 ldb ,x+
|
|
2717 noindir cmpb #'#'
|
|
2718 lbeq doimm
|
|
2719 cmpb #','
|
|
2720 lbeq dospecial
|
|
2721 andb #CASEMASK ;Convert to uppercase.
|
|
2722 lda #$86
|
|
2723 cmpb #'A'
|
|
2724 beq scanacidx
|
|
2725 lda #$85
|
|
2726 cmpb #'B'
|
|
2727 beq scanacidx
|
|
2728 lda #$8B
|
|
2729 cmpb #'D'
|
|
2730 bne scanlab
|
|
2731 scanacidx ldb ,x+ ;Could it be A,X B,X or D,X
|
|
2732 cmpb #','
|
|
2733 bne nocomma
|
|
2734 sta postbyte
|
|
2735 clr opsize
|
|
2736 jsr set3
|
|
2737 jsr scanixreg
|
|
2738 bra scanend
|
|
2739 nocomma leax -1,x
|
|
2740 scanlab leax -1,x ;Point to the start of the operand
|
|
2741 jsr exprvec
|
|
2742 lbeq exprerr
|
|
2743 std operand
|
|
2744 tst uncert
|
|
2745 bne opsz2 ;Go for extended if operand unknown.
|
|
2746 subd dpsetting
|
|
2747 tsta ;Can we use 8-bit operand?
|
|
2748 bne opsz2
|
|
2749 inca
|
|
2750 bra opsz1
|
|
2751 opsz2 lda #2
|
|
2752 opsz1 sta opsize ;Set opsize depending on magnitude of op.
|
|
2753 lda amode
|
|
2754 cmpa #5
|
|
2755 bne opsz3 ;Or was it indirect.
|
|
2756 lda #2 ;Then we have postbyte and opsize=2
|
|
2757 sta opsize
|
|
2758 lda #$8F
|
|
2759 sta postbyte
|
|
2760 bra opsz4
|
|
2761 opsz3 lda #2
|
|
2762 sta amode ;Assume direct or absolute addressing
|
|
2763 opsz4 ldb ,x+
|
|
2764 cmpb #','
|
|
2765 lbeq doindex ;If followed by, then indexed.
|
|
2766 scanend lda amode
|
|
2767 cmpa #5
|
|
2768 blo scanend2 ;Was it an indirect mode?
|
|
2769 lda postbyte
|
|
2770 ora #$10 ;Set indirect bit.
|
|
2771 sta postbyte
|
|
2772 ldb ,x+
|
|
2773 cmpb #']' ;Check for the other ]
|
|
2774 lbeq moderr
|
|
2775 scanend2 rts
|
|
2776 doimm jsr exprvec ;Immediate addressing.
|
|
2777 lbeq exprerr
|
|
2778 std operand
|
|
2779 lda amode
|
|
2780 cmpa #5
|
|
2781 lbeq moderr ;Inirect mode w/ imm is illegal.
|
|
2782 lda #$01
|
|
2783 sta amode
|
|
2784 rts
|
|
2785 dospecial jsr set3
|
|
2786 clr opsize
|
|
2787 clra
|
|
2788 adecloop ldb ,x+
|
|
2789 cmpb #'-'
|
|
2790 bne adecend
|
|
2791 inca ;Count the - signs for autodecrement.
|
|
2792 bra adecloop
|
|
2793 adecend leax -1,x
|
|
2794 cmpa #2
|
|
2795 lbhi moderr
|
|
2796 tsta
|
|
2797 bne autodec
|
|
2798 clr postbyte
|
|
2799 jsr scanixreg
|
|
2800 clra
|
|
2801 aincloop ldb ,x+
|
|
2802 cmpb #'+'
|
|
2803 bne aincend
|
|
2804 inca
|
|
2805 bra aincloop ;Count the + signs for autoincrement.
|
|
2806 aincend leax -1,x
|
|
2807 cmpa #2
|
|
2808 lbhi moderr
|
|
2809 tsta
|
|
2810 bne autoinc
|
|
2811 lda #$84
|
|
2812 ora postbyte
|
|
2813 sta postbyte
|
|
2814 bra scanend
|
|
2815 autoinc adda #$7f
|
|
2816 ora postbyte
|
|
2817 sta postbyte
|
|
2818 bra scanend
|
|
2819 autodec adda #$81
|
|
2820 sta postbyte
|
|
2821 jsr scanixreg
|
|
2822 lbra scanend
|
|
2823 doindex clr postbyte
|
|
2824 jsr set3
|
|
2825 ldb ,x+
|
|
2826 andb #CASEMASK ;Convert to uppercase.
|
|
2827 cmpb #'P'
|
|
2828 lbeq dopcrel ;Check for PC relative.
|
|
2829 leax -1,x
|
|
2830 clr opsize
|
|
2831 bsr scanixreg
|
|
2832 ldd operand
|
|
2833 tst uncert
|
|
2834 bne longindex ;Go for long index if operand unknown.
|
|
2835 cmpd #-16
|
|
2836 blt shortindex
|
|
2837 cmpd #15
|
|
2838 bgt shortindex
|
|
2839 lda amode
|
|
2840 cmpa #5
|
|
2841 beq shortind1 ;Indirect may not be 5-bit index
|
|
2842 ;It's a five-bit index.
|
|
2843 andb #$1f
|
|
2844 orb postbyte
|
|
2845 stb postbyte
|
|
2846 lbra scanend
|
|
2847 shortindex cmpd #-128
|
|
2848 blt longindex
|
|
2849 cmpd #127
|
|
2850 bgt longindex
|
|
2851 shortind1 inc opsize
|
|
2852 ldb #$88
|
|
2853 orb postbyte
|
|
2854 stb postbyte
|
|
2855 lbra scanend
|
|
2856 longindex lda #$2
|
|
2857 sta opsize
|
|
2858 ldb #$89
|
|
2859 orb postbyte
|
|
2860 stb postbyte
|
|
2861 lbra scanend
|
|
2862 dopcrel ldb ,x+
|
|
2863 andb #CASEMASK ;Convert to uppercase
|
|
2864 cmpb #'C'
|
|
2865 blo pcrelend
|
|
2866 cmpb #'R'
|
|
2867 bhi pcrelend
|
|
2868 bra dopcrel ;Scan past the ,PCR
|
|
2869 pcrelend leax -1,x
|
|
2870 ldb #$8C
|
|
2871 orb postbyte ;Set postbyte
|
|
2872 stb postbyte
|
|
2873 inc amode ;Set addr mode to PCR
|
|
2874 lbra scanend
|
|
2875
|
|
2876 * Scan for one of the 4 index registers and adjust postbyte.
|
|
2877 scanixreg ldb ,x+
|
|
2878 andb #CASEMASK ;Convert to uppercase.
|
|
2879 pshs x
|
|
2880 ldx #ixregs
|
|
2881 clra
|
|
2882 scidxloop cmpb ,x+
|
|
2883 beq ixfound
|
|
2884 adda #$20
|
|
2885 bpl scidxloop
|
|
2886 jmp moderr ;Index register not found where expected.
|
|
2887 ixfound ora postbyte
|
|
2888 sta postbyte ;Set index reg bits in postbyte.
|
|
2889 puls x
|
|
2890 rts
|
|
2891
|
|
2892 * This routine sets amode to 3, if it was less.
|
|
2893 set3 lda amode
|
|
2894 cmpa #3
|
|
2895 bhs set3a
|
|
2896 lda #3
|
|
2897 sta amode
|
|
2898 set3a rts
|
|
2899
|
|
2900 * This subroutine lays down the address.
|
|
2901 doaddr lda amode
|
|
2902 cmpa #3
|
|
2903 blo doa1
|
|
2904 ldb postbyte
|
|
2905 jsr putbyte
|
|
2906 lda amode
|
|
2907 anda #1
|
|
2908 beq doapcrel ;pc rel modes.
|
|
2909 doa1 lda opsize
|
|
2910 tsta
|
|
2911 beq set3a
|
|
2912 deca
|
|
2913 beq doa2
|
|
2914 ldd operand
|
|
2915 jmp putword
|
|
2916 doa2 ldb operand+1
|
|
2917 jmp putbyte
|
|
2918 doapcrel sty addr
|
|
2919 ldd operand
|
|
2920 subd addr
|
|
2921 subd #1
|
|
2922 tst uncert
|
|
2923 bne pcrlong
|
|
2924 cmpd #-128
|
|
2925 blt pcrlong
|
|
2926 cmpd #-127
|
|
2927 bgt pcrlong
|
|
2928 lda #1
|
|
2929 sta opsize
|
|
2930 jmp putbyte
|
|
2931 pcrlong subd #1
|
|
2932 leay -1,y
|
|
2933 inc postbyte
|
|
2934 pshs d
|
|
2935 ldb postbyte
|
|
2936 jsr putbyte
|
|
2937 lda #2
|
|
2938 sta opsize
|
|
2939 puls d
|
|
2940 jmp putword
|
|
2941
|
|
2942 * This routine checks and lays down short relative address.
|
|
2943 shortrel sty addr
|
|
2944 subd addr
|
|
2945 subd #1
|
|
2946 cmpd #-128
|
|
2947 blt brerr
|
|
2948 cmpd #127
|
|
2949 bgt brerr
|
|
2950 jsr putbyte
|
|
2951 lda #4
|
|
2952 sta amode
|
|
2953 lda #1
|
|
2954 sta opsize
|
|
2955 rts
|
|
2956 * This routine lays down long relative address.
|
|
2957 longrel sty addr
|
|
2958 subd addr
|
|
2959 subd #2
|
|
2960 jsr putword
|
|
2961 lda #4
|
|
2962 sta amode
|
|
2963 lda #2
|
|
2964 sta opsize
|
|
2965 rts
|
|
2966
|
|
2967 brerr ldx #brmsg
|
|
2968 jmp asmerrvec
|
|
2969 exprerr ldx #exprmsg
|
|
2970 jmp asmerrvec
|
|
2971 moderr ldx #modemsg
|
|
2972 jmp asmerrvec
|
|
2973 asmerr pshs x
|
|
2974 jsr xabortin
|
|
2975 puls x
|
|
2976 jsr outcount
|
|
2977 jsr putcr
|
|
2978 lds savesp
|
|
2979 jmp cmdline
|
|
2980
|
|
2981 * Find register for TFR and PSH instruction
|
|
2982 findreg ldb #12
|
|
2983 pshs y,b
|
|
2984 ldu #asmregtab
|
|
2985 findregloop tfr x,y
|
|
2986 lda #3
|
|
2987 frcmps ldb ,u
|
|
2988 cmpb #' '
|
|
2989 bne frcmps1
|
|
2990 ldb ,y
|
|
2991 cmpb #'A'
|
|
2992 blt frfound
|
|
2993 frcmps1 ldb ,y+
|
|
2994 andb #CASEMASK
|
|
2995 cmpb ,u+
|
|
2996 bne frnextreg
|
|
2997 deca
|
|
2998 bne frcmps
|
|
2999 inca
|
|
3000 bra frfound
|
|
3001 frnextreg inca
|
|
3002 leau a,u
|
|
3003 dec ,s
|
|
3004 bne findregloop
|
|
3005 lbra moderr
|
|
3006 frfound leau a,u
|
|
3007 tfr y,x
|
|
3008 puls y,b
|
|
3009 rts
|
|
3010
|
|
3011 * This is the code for the A command, assemble instructions.
|
|
3012 * Syntax: Aaddr
|
|
3013 asm ldx #linebuf+1
|
|
3014 jsr scanhex
|
|
3015 std addr
|
|
3016 inc disflg
|
|
3017
|
|
3018
|
|
3019 asmloop ldy #0
|
|
3020 sty length
|
|
3021 ldd addr
|
|
3022 pshs d
|
|
3023 jsr dis1 ;display unassembled line
|
|
3024 ldd addr
|
|
3025 std nxtadd
|
|
3026
|
|
3027 puls d
|
|
3028 std addr
|
|
3029
|
|
3030 * ldd addr
|
|
3031 * jsr outd
|
|
3032
|
|
3033 ldb #TAB
|
|
3034 jsr putchar ;Print TAB
|
|
3035 ldx #linebuf
|
|
3036 ldb #128
|
|
3037 jsr getline ;Get new line
|
|
3038 tstb
|
|
3039 beq next
|
|
3040
|
|
3041 *** beq asmend ;Exit on empty line.
|
|
3042 abx
|
|
3043 clr ,x ;Make line zero terminated.
|
|
3044 ldx #linebuf
|
|
3045 lda ,x
|
|
3046 cmpa #'.'
|
|
3047 beq asmend
|
|
3048 jsr asminstr
|
|
3049 bra asmloop
|
|
3050
|
|
3051 next ldd nxtadd
|
|
3052 std addr
|
|
3053 bra asmloop
|
|
3054
|
|
3055 asmend clr disflg
|
|
3056 jmp cmdline
|
|
3057
|
|
3058
|
|
3059 * Jump table for monitor routines that are usable by other programs.
|
|
3060 org $ffc0
|
|
3061 jmp outbyte
|
|
3062 jmp outd
|
|
3063 jmp scanbyte
|
|
3064 jmp scanhex
|
|
3065 jmp scanfact
|
|
3066 jmp asminstr
|
|
3067
|
|
3068
|
|
3069 * Interrupt vector addresses at top of ROM. Most are vectored through jumps
|
|
3070 * in RAM.
|
|
3071 org $fff2
|
|
3072 fdb swi3vec
|
|
3073 fdb swi2vec
|
|
3074 fdb firqvec
|
|
3075 fdb irqvec
|
|
3076 fdb swivec
|
|
3077 fdb nmivec
|
|
3078 fdb reset
|
|
3079
|
|
3080 end
|