-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmon2.asm
3080 lines (2920 loc) · 58 KB
/
mon2.asm
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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;Buggy machine language monitor and rudimentary O.S. version 1.0
* Memory map of SBC
* $0-$40 Zero page variables reserved by monitor and O.S.
* $40-$FF Zero page portion for user programs.
* $100-$17F Xmodem buffer 0, terminal input buffer,
* $180-$1FF Xmodem buffer 1, terminal output buffer.
* $200-$27F Terminal input line.
* $280-$2FF Variables reserved by monitor and O.S.
* $300-$400 System stack.
* $400-$7FFF RAM for user programs and data.
* $8000-$DFFF PROM for user programs.
* $E000-$E1FF I/O addresses.
* $E200-$E3FF Reserved.
* $E400-$FFFF Monitor ROM
* Reserved Zero page addresses
org $0000
* First the I/O routine vectors.
getchar rmb 3 ;Jump to getchar routine.
putchar rmb 3 ;Jump to putchar routine.
getline rmb 3 ;Jump to getline routine.
putline rmb 3 ;Jump to putline routine.
putcr rmb 3 ;Jump to putcr routine.
getpoll rmb 3 ;Jump to getpoll routine.
xopenin rmb 3 ;Jump to xopenin routine.
xopenout rmb 3 ;Jump to xopenout routine.
xabortin rmb 3 ;Jump to xabortin routine.
xclosein rmb 3 ;Jump to xclosein routine.
xcloseout rmb 3 ;Jump to xcloseout routine.
delay rmb 3 ;Jump to delay routine.
*Next the system variables in the zero page.
temp rmb 2 ;hex scanning/disasm
temp2 rmb 2 ;Hex scanning/disasm
temp3 rmb 2 ;Used in Srecords, H command
timer rmb 3 ;3 byte timer, incremented every 20ms
xpacknum rmb 1 ;Packet number for XMODEM block,
xsum rmb 1 ;XMODEM checksum
lastok rmb 1 ;flag to indicate last block was OK
xcount rmb 1 ;Count of characters in buffer.
xmode rmb 1 ;XMODEM mode, 0 none, 1 out, 2 in.
disflg rmb 1
* I/O buffers.
buflen equ 128 ;Length of input line buffer.
org $100
buf0 rmb 128 ;Xmodem buffer 0, serial input buffer.
buf1 rmb 128 ;Xmodem buffer 1, serial output buffer.
linebuf rmb buflen ;Input line buffer.
* Interrupt vectors (start at $280)
* All interrupts except RESET are vectored through jumps.
* FIRQ is timer interrupt, IRQ is ACIA interrupt.
swi3vec rmb 3
swi2vec rmb 3
firqvec rmb 3
irqvec rmb 3
swivec rmb 3
nmivec rmb 3
xerrvec rmb 3 ;Error handler for XMODEM error.
exprvec rmb 3 ;Expression evaluator in assembler.
asmerrvec rmb 3 ;Error handler for assembler errors.
pseudovec rmb 3 ;Vector for asm pseudo instructions.
* Next the non zero page system variables.
oldpc rmb 2 ;Saved pc value for J command.
addr rmb 2 ;Address parameter.
length rmb 2 ;Length parameter.
brkpoints equ 8 ;Number of settable breakpoints.
bpaddr rmb brkpoints*3 ;Address and byte for each break point.
stepbp rmb 3 ;Address of P command break point.
sorg rmb 2 ;Origin address of S record entry.
soffs rmb 2 ;Offset load adrr-addr in record
oldgetc rmb 2 ;Old getchar address.
oldputc rmb 2 ;Old putchar address.
oldputcr rmb 2 ;Old putcr address.
lastterm rmb 1 ;Last terminating character.
filler rmb 1 ;Filler at end of XMODEM file.
xmcr rmb 1 ;end-of-line characters for XMODEM send.
savesp rmb 2 ;Save sp to restore it on error.
nxtadd rmb 2
* Following variables are used by assembler/disassembler.
prebyte rmb 1
opc1 rmb 1
opcode rmb 1
postbyte rmb 1
amode rmb 1
operand rmb 2
mnembuf rmb 5 ;Buffer to store capitalized mnemonic.
opsize rmb 1 ;SIze (in bytes) of extra oeprand (0--2)
uncert rmb 1 ;Flag to indicate that op is unknown.
dpsetting rmb 2
endvars equ *
ramstart equ $400 ;first free RAM address.
ramtop equ $8000 ;top of RAM.
* I/O port addresses
aciactl equ $e000 ;Control port of ACIA
aciasta equ $e000 ;Status port of ACIA
aciadat equ $e001 ;Data port of ACIA
* ASCII control characters.
SOH equ 1
EOT equ 4
ACK equ 6
BS equ 8
TAB equ 9
LF equ 10
CR equ 13
NAK equ 21
CAN equ 24
DEL equ 127
CASEMASK equ $DF ;Mask to make lowercase into uppercase.
* Monitor ROM starts here.
org $E400
reset orcc #$FF ;Disable interrupts.
clra
tfr a,dp ;Set direct page register to 0.
clr disflg
lds #ramstart
ldx #intvectbl
ldu #swi3vec
ldb #osvectbl-intvectbl
bsr blockmove ;Initialize interrupt vectors from ROM.
ldx #osvectbl
ldu #0
ldb #endvecs-osvectbl
bsr blockmove ;Initialize I/O vectors from ROM.
bsr initacia ;Initialize serial port.
andcc #$0 ;Enable interrupts
* Put the 'saved' registers of the program being monitored on top of the
* stack. There are 12 bytes on the stack for cc,b,a,dp,x,y,u and pc
* pc is initialized to $400, the rest to zero.
ldx #0
tfr x,y
ldu #ramstart
pshs x,u
pshs x,y
pshs x,y
ldx #oldpc
ldb #endvars-oldpc
clvar clr ,x+
decb
bne clvar ;Clear the variable area.
ldd #$1A03
std filler ;Set XMODEM filler and end-of-line.
ldx #welcome
jsr outcount
jsr putcr ;Print a welcome message.
jmp cmdline
* Block move routine, from X to U length B. Modifies them all and A.
blockmove lda ,x+
sta ,u+
decb
bne blockmove
rts
* Initialize serial communications port, buffers, interrupts.
initacia ldb #$03
stb aciactl
ldb #%00110101
rts
* O.S. routine to read a character into B register.
osgetc ldb aciasta
bitb #$01
beq osgetc
ldb aciadat
rts
;O.S. rotuine to check if there is a character ready to be read.
osgetpoll ldb aciasta
bitb #$01
bne poltrue
clrb
rts
poltrue ldb #$ff
rts
* O.S. routine to write the character in the B register.
osputc pshs a
putcloop lda aciasta
bita #$02
beq putcloop
stb aciadat
puls a
rts
* O.S. routine to read a line into memory at address X, at most B chars
* long, return actual length in B. Permit backspace editing.
osgetl pshs a,x
stb temp
clra
osgetl1 jsr getchar
andb #$7F
cmpb #BS
beq backsp
cmpb #DEL
bne osgetl2
backsp tsta ;Recognize BS and DEL as backspace key.
beq osgetl1 ;ignore if line already zero length.
ldb #BS
jsr putchar
ldb #' '
jsr putchar
ldb #BS ;Send BS,space,BS. This erases last
jsr putchar ;character on most terminals.
leax -1,x ;Decrement address.
deca
bra osgetl1
osgetl2 cmpb #CR
beq newline
cmpb #LF
bne osgetl3 ;CR or LF character ends line.
ldb lastterm
cmpb #CR
beq osgetl1 ;Ignore LF if it comes after CR
ldb #LF
newline stb lastterm
jsr putcr
tfr a,b ;Move length to B
puls a,x ;restore registers.
rts ;<--- Here is the exit point.
osgetl3 cmpb #TAB
beq dotab
cmpb #' '
blo osgetl1 ;Ignore control characters.
cmpa temp
beq osgetl1 ;Ignore char if line full.
jsr putchar ;Echo the character.
stb ,x+ ;Store it in memory.
inca
bra osgetl1
dotab ldb #' '
cmpa temp
beq osgetl1
jsr putchar
stb ,x+
inca
bita #7 ;Insert spaces until length mod 8=0
bne dotab
bra osgetl1
* O.S. routine to write a line starting at address X, B chars long.
osputl pshs a,b,x
tfr b,a
tsta
beq osputl1
osputl2 ldb ,x+
jsr putchar
deca
bne osputl2
osputl1 puls a,b,x
rts
* O.S. routine to terminate a line.
oscr pshs b
ldb #CR
jsr putchar
ldb #LF
jsr putchar ;Send the CR and LF characters.
puls b
rts
* Output a counted string at addr X
outcount pshs x,b
ldb ,x+
jsr putline
puls x,b
rts
timerirq inc timer+2
bne endirq
inc timer+1
bne endirq
inc timer
rti
aciairq nop
endirq rti
* Wait D times 20ms.
osdly addd timer+1
dlyloop cmpd timer+1
bne dlyloop
rts
* This table will be copied to the interrupt vector area in RAM.
intvectbl jmp endirq
jmp endirq
jmp timerirq
jmp aciairq
jmp unlaunch
jmp endirq
jmp xerrhand
jmp expr
jmp asmerrvec
jmp pseudo
* And this one to the I/O vector table.
osvectbl jmp osgetc
jmp osputc
jmp osgetl
jmp osputl
jmp oscr
jmp osgetpoll
jmp xopin
jmp xopout
jmp xabtin
jmp xclsin
jmp xclsout
jmp osdly
endvecs equ *
* The J command returns here.
stakregs pshs x ;Stack something where the pc comes
pshs ccr,b,a,dp,x,y,u ;Stack the normal registers.
ldx oldpc
stx 10,s ;Stack the old pc value.
bra unlaunch1
* The G and P commands return here through a breakpoint.
* Registers are already stacked.
unlaunch ldd 10,s
subd #1
std 10,s ;Decrement pc before breakpoint
unlaunch1 andcc #$0 ;reenable the interrupts.
jsr disarm ;Disarm the breakpoints.
jsr dispregs
cmdline jsr xcloseout
sts savesp
ldb #'.'
jsr putchar
ldx #linebuf
ldb #buflen
jsr getline
tstb
beq cmdline ;Ignore line if it is empty
abx
clr ,x ;Make location after line zero.
ldx #linebuf
ldb ,x+
andb #CASEMASK ;Make 1st char uppercase.
subb #'A'
bcs unk
cmpb #26
bcc unk ;Unknown cmd if it is not a letter.
ldx #cmdtab
aslb ;Index into command table.
jmp [b,x]
cmdtab fdb asm,break,calc,dump
fdb enter,find,go,help
fdb inp,jump,unk,unk
fdb move,unk,unk,prog
fdb unk,regs,srec,trace
fdb unasm,unk,unk,xmodem
fdb unk,unk
* Unknown command handling routine.
unk jsr xabortin
ldx #unknown
jsr outcount
jsr putcr
jmp cmdline
help ldx #mhelp ;Print a help message.
help1 ldb ,x+
beq endhlp
lbsr osputc
bra help1
endhlp jmp cmdline
mhelp fcb CR,LF
fcc 'Commands list'
fcb CR,LF
fcc '-------------'
fcb CR,LF
fcc 'Asm '
fcc '{Aaddr}'
fcb CR,LF
fcc 'Unasm '
fcc '{U or Uaddr or Uaddr,length}'
fcb CR,LF
fcc 'Dump '
fcc '{D or D<addr> or D<addr>,<length>}'
fcb CR,LF
fcc 'Enter '
fcc '{E or E<addr> or E<addr> <bytes> or E<addr>string}'
fcb CR,LF
fcc 'Break '
fcc '{B or B<addr>. B displays, B<addr> sets or clears breakpoint}'
fcb CR,LF
fcc 'Find '
fcb "{Faddr bytes or Faddr",34,"ascii",34,"}"
fcb CR,LF
fcc 'Go '
fcc '{G or G<addr>}'
fcb CR,LF
fcc 'Calc '
fcc '{Chexnum{+|-hexnum}}'
fcb CR,LF
fcc 'Inp '
fcc '{Iaddr}'
fcb CR,LF
fcc 'Jump '
fcc '{J<addr>}'
fcb CR,LF
fcc 'Move '
fcc '{M<addr1>,<addr2>,<lenght>}'
fcb CR,LF
fcc 'Prog '
fcc '{P}'
fcb CR,LF
fcc 'Regs '
fcc '{R or R<letter><hex>}'
fcb CR,LF
fcc 'Srec '
fcc '{SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes>}'
fcb CR,LF
fcc 'Trace '
fcc '{T}'
fcb CR,LF
fcc 'Xmodem '
fcc '{XSaddr,len XLaddr,len XX XOcrlf,filler, XSSaddr,len}'
fcb CR,LF
fcc 'Help '
fcc '{H}'
fcb CR,LF,0
* Here are some useful messages.
welcome fcb unknown-welcome-1
fcc "Welcome to BUGGY version 1.0"
unknown fcb brkmsg-unknown-1
fcc "Unknown command"
brkmsg fcb clrmsg-brkmsg-1
fcc "Breakpoint set"
clrmsg fcb fullmsg-clrmsg-1
fcc "Breakpoint cleared"
fullmsg fcb smsg-fullmsg-1
fcc "Breakpoints full"
smsg fcb lastrec-smsg-1
fcc "Error in S record"
lastrec fcb xsmsg-lastrec-1
fcc "S9030000FC"
xsmsg fcb xrmsg-xsmsg-1
fcc "Start XMODEM Send"
xrmsg fcb xamsg-xrmsg-1
fcc "Start XMODEM Receive"
xamsg fcb invmmsg-xamsg-1
fcc "XMODEM transfer aborted"
invmmsg fcb exprmsg-invmmsg-1
fcc "Invalid mnemonic"
exprmsg fcb modemsg-exprmsg-1
fcc "Expression error"
modemsg fcb brmsg-modemsg-1
fcc "Addressing mode error"
brmsg fcb endmsg-brmsg-1
fcc "Branch too long"
endmsg equ *
* Output hex digit contained in A
hexdigit adda #$90
daa
adca #$40
daa ;It's the standard conversion trick ascii
tfr a,b ;to hex without branching.
jsr putchar
rts
* Output contents of A as two hex digits
outbyte pshs a
lsra
lsra
lsra
lsra
bsr hexdigit
puls a
anda #$0f
bra hexdigit
* Output contents of d as four hex digits
outd pshs b
bsr outbyte
puls a
bsr outbyte
rts
* Skip X past spaces, B is first non-space character.
skipspace ldb ,x+
cmpb #' '
beq skipspace
rts
* Convert ascii hex digit in B register to binary Z flag set if no hex digit.
convb subb #'0'
blo convexit
cmpb #9
bls cb2
andb #CASEMASK ;Make uppercase.
subb #7 ;If higher than digit 9 it must be a letter.
cmpb #9
bls convexit
cmpb #15
bhi convexit
cb2 andcc #$FB ;clear zero
rts
convexit orcc #$04
rts
scanexit ldd temp
leax -1,x
tst temp2
rts <-- exit point of scanhex
* Scan for hexadecimal number at address X return in D, Z flag is set it no
* number found.
scanhex clr temp
clr temp+1
clr temp2
bsr skipspace
scloop jsr convb
beq scanexit
pshs b
ldd temp
aslb
rola
aslb
rola
aslb
rola
aslb
rola
addb ,s+
std temp
inc temp2
ldb ,x+
bra scloop
scan2parms std length
bsr scanhex
beq sp2
std addr
bsr skipspace
cmpb #','
bne sp2
bsr scanhex
beq sp2
std length
sp2 rts
* Scan two hexdigits at in and convert to byte into A, Z flag if error.
scanbyte bsr skipspace
bsr convb
beq sb1
tfr b,a
ldb ,x+
bsr convb
beq sb1
asla
asla
asla
asla
stb temp
adda temp
andcc #$fb ;Clear zero flag
sb1 rts
* This is the code for the D command, hex/ascii dump of memory
* Syntax: D or D<addr> or D<addr>,<length>
dump ldx #linebuf+1
ldd #$40
jsr scan2parms ;Scan address and length, default length=64
ldy addr
dh1 lda #16
sta temp+1
tfr y,d
jsr outd
ldb #' '
jsr putchar
dh2 lda ,y+ ;display row of 16 mem locations as hex
jsr outbyte
ldb #' '
lda temp+1
cmpa #9
bne dh6
ldb #'-' ;Do a - after the eighth byte.
dh6 jsr putchar
dec temp+1
bne dh2
leay -16,y ;And now for the ascii dump.
lda #16
dh3 ldb ,y+
cmpb #' '
bhs dh4
ldb #'.'
dh4 cmpb #DEL
blo dh5
ldb #'.' ;Convert all nonprintables to .
dh5 jsr putchar
deca
bne dh3
jsr putcr
ldd length
subd #16
std length
bhi dh1
sty addr
jmp cmdline
* This is the code for the E command, enter hex bytes or ascii string.
* Syntax E or E<addr> or E<addr> <bytes> or E<addr>"string"
enter ldx #linebuf+1
jsr scanhex
beq ent1
std addr
ent1 bsr entline
lbne cmdline ;No bytes, then enter interactively.
ent2 ldb #'E'
jsr putchar
ldd addr
jsr outd
ldb #' '
jsr putchar ;Display Eaddr + space
lda [addr]
jsr outbyte
ldb #' '
jsr putchar
ldx #linebuf
ldb #buflen
jsr getline ;Get the line.
tstb
beq skipbyte
abx
clr ,x
ldx #linebuf
bsr entline
bne ent2
jmp cmdline
skipbyte ldd addr
addd #1
std addr
bra ent2
* Enter a line of hex bytes or ascci string at address X, Z if empty.
entline jsr skipspace
tstb
beq entexit
cmpb #'.'
beq entexit
cmpb #'"'
beq entasc
leax -1,x
ldy addr
entl2 jsr scanbyte ;Enter hex digits.
beq entdone
sta ,y+
bra entl2
entasc ldy addr
entl3 lda ,x+
tsta
beq entdone
cmpa #'"'
beq entdone
sta ,y+
bra entl3
entdone sty addr
andcc #$fb
rts
entexit orcc #$04
rts
*This is the code for the I command, display the contents of an address
* Syntax: Iaddr
inp ldx #linebuf+1
jsr scanhex
tfr d,x
lda ,x ;Read the byte from memory.
jsr outbyte ;Display itin hex.
jsr putcr
jmp cmdline
*This is the code for the H command, display result of simple hex expression
*Syntax Hhexnum{+|-hexnum}
calc ldx #linebuf+1
jsr scanhex
std temp3
hexloop jsr skipspace
cmpb #'+'
bne hex1
jsr scanhex
addd temp3
std temp3
bra hexloop
hex1 cmpb #'-'
bne hexend
jsr scanhex
comb
coma
addd #1
addd temp3
std temp3
bra hexloop
hexend ldd temp3
jsr outd
jsr putcr
jmp cmdline
* This is the code for the G command, jump to the program
* Syntax G or G<addr>
go ldx #linebuf+1
jsr scanhex
beq launch
std 10,s ;Store parameter in pc location.
launch jsr arm ;Arm the breakpoints.
puls ccr,b,a,dp,x,y,u,pc
* This is the code for the J command, run a subroutine.
* Syntax J<addr>
jump ldx #linebuf+1
ldd 10,s
std oldpc ;Save old pc
jsr scanhex
std 10,s ;Store parameter in PC location
tfr s,x
leas -2,s
tfr s,u
ldb #12 ;Move the saved register set 2 addresses
jsr blockmove ;down on the stack.
ldd #stakregs
std 12,s ;Prepare subroutine return address.
bra launch ;Jump to the routine.
* This is the code for the P command, run instruction followed by breakpoint
* Syntax P
prog ldy 10,s ;Get program counter value.
jsr disdecode ;Find out location past current insn.
sty stepbp
bra launch
* This is the code for the T command, single step trace an instruction.
* Syntax T
trace jsr traceone
jsr dispregs
jmp cmdline
traceone orcc #$50 ;Disable the interrupts.
ldd ,s++
std oldpc ;Remove saved pc from stack.
ldd #traceret
std firqvec+1 ;Adjust timer IRQ vector.
sync ;Synchronize on the next timer interrupt.
;1 cycle
ldx #4441 ;3 cycles
traceloop leax -1,x ;6 cycles\x4441= 39969 cycles.
bne traceloop ;3 cycles/
nop ;2 cycles.
nop ;2 cycles.
nop ;2 cycles.
brn traceret ;3 cycles.
puls x,y,u,a,b,dp,cc,pc ;17 cycles, total=39999 20ms @ 2MHz
;Pull all registers and execute.
;Is timed such that next timer IRQ
;occurs right after it.
traceret puls cc
pshs x,y,u,a,b,dp,cc;Store full register set instead of cc.
ldd #timerirq
std firqvec+1 ;Restore timer IRQ vector.
jmp [oldpc]
* Display the contents of 8 bit register, name in B, contents in A
disp8 jsr putchar
ldb #'='
jsr putchar
jsr outbyte
ldb #' '
jsr putchar
rts
* Display the contents of 16 bit register, name in B, contents in Y
disp16 jsr putchar
ldb #'='
jsr putchar
tfr y,d
jsr outd
ldb #' '
jsr putchar
rts
* Display the contents of the registers and disassemble instruction at
* PC location.
dispregs ldb #'X'
ldy 6,s ;Note that there's one return address on
bsr disp16 ;stack so saved register offsets are
ldb #'Y' ;inremented by 2.
ldy 8,s
bsr disp16
ldb #'U'
ldy 10,s
bsr disp16
ldb #'S'
tfr s,y
leay 14,y ;S of the running program is 12 higher,
;because regs are not stacked when running.
bsr disp16
ldb #'A'
lda 3,s
bsr disp8
ldb #'B'
lda 4,s
bsr disp8
ldb #'D'
lda 5,s
bsr disp8
ldb #'C'
lda 2,s
bsr disp8
jsr putcr
ldb #'P'
ldy 12,s
bsr disp16
jsr disdecode
jsr disdisp ;Disassemble instruction at PC
jsr putcr
rts
* This is the code for the R command, display or alter the registers.
* Syntax R or R<letter><hex>
regs ldx #linebuf+1
jsr skipspace
tstb
bne setreg
bsr dispregs ;Display regs ifnothing follows.
jmp cmdline
setreg ldy #regtab
clra
andb #CASEMASK ;Make letter uppercase.
sr1 tst ,y
lbeq unk ;At end of register tab, unknown reg
cmpb ,y+
beq sr2 ;Found the register?
inca
bra sr1
sr2 pshs a
jsr scanhex ;Convert the hex argument.
pshs d
lda 2,s ;Get register number.
cmpa #4
bcc sr3
ldb 1,s ;It's 8 bit.
leas 3,s ;Remove temp stuff from stack.
stb a,s ;Store it in the reg on stack.
jmp cmdline
sr3 cmpa #8
bcc sr4
puls x ;It's 16 bit.
leas 1,s
lsla
suba #4 ;Convert reg no to stack offset.
stx a,s
jmp cmdline
sr4 puls u ;It's the stack pointer.
leas 1,s
leau -12,u
tfr s,x
tfr u,s ;Set new stack pointer.
ldb #12
jsr blockmove ;Move register set to new stack location.
jmp cmdline
regtab FCC "CABDXYUPS "
* Disarm the breakpoints, this is replace the SWI instructions with the
* original byte.
disarm ldx #bpaddr
lda #brkpoints+1
disarm1 ldu ,x++
ldb ,x+ ;Get address in u, byte in b
cmpu #0
beq disarm2
stb ,u
disarm2 deca
bne disarm1
ldu #0
stu -3,x ;Clear the step breakpoint.
rts
* Arm the breakponts, this is replace the byte at the breakpoint address
* with an SWI instruction.
arm ldx #bpaddr+brkpoints*3
lda #brkpoints+1 ;Arm them in reverse order of disarming.
arm1 ldu ,x ;Get address in u.
beq arm2
ldb ,u
stb 2,x
cmpu 12,s ;Compare to program counter location
beq arm2
ldb #$3F
stb ,u ;Store SWI instruction if not equal.
arm2 leax -3,x
deca
bne arm1
rts
* This is the code for the break command, set, clear display breakpoints.
* Syntax B or B<addr>. B displays, B<addr> sets or clears breakpoint.
break lda #brkpoints
sta temp2+1 ;Store number of breakpoints to visit.
ldx #linebuf+1
jsr scanhex
beq dispbp ;No number then display breakpoints
ldx #bpaddr
ldu #0
tfr u,y
bp1 cmpd ,x
beq clearit ;Found the breakpoint, so clear it,
cmpu ,x ;Is location zero
bne bp2
tfr x,y ;Set free address to y
bp2 leax 3,x
dec temp2+1
bne bp1
cmpy #0 ;Address not found in list of breakpoints
beq bpfull ;Was free address found.
std ,y ;If so, store breakpoint there.
ldx #brkmsg
bpexit jsr outcount
jsr putcr
jmp cmdline
clearit clra
clrb
std ,x
ldx #clrmsg
bra bpexit
bpfull ldx #fullmsg
bra bpexit
dispbp ldx #bpaddr
dbp1 ldd ,x
beq dbp2
jsr outd
ldb #' '
jsr putchar
dbp2 leax 3,x
dec temp2+1
bne dbp1
jsr putcr
jmp cmdline
* Scan hex byte into a and add it to check sum in temp2+1
addchk jsr scanbyte
lbeq srecerr
tfr a,b
addb temp2+1
stb temp2+1
rts
* This tis the code for the S command, the Motorola S records entry.
* Syntax SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes>
srec ldx #linebuf+1
ldb ,x+
andb #CASEMASK
cmpb #'O'
beq setsorg
cmpb #'S'
beq sendrec
ldb -1,x
clr temp3