-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvecbuggy.asm
3269 lines (3083 loc) · 102 KB
/
vecbuggy.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
* a09 assembler directive to stop listing file wordwrap
SETLI 160
* "Buggy machine language monitor and rudimentary O.S. version 1.0"
*
* Use-case: Load and start Buggy. Load and start program.
* Press key to NMI to Buggy. Set breakpoint then exit.
* Program resumes. Hits breakpoint and enters Buggy. At this point
* need to know that "Exit" from Buggy should take us back to the
* program.
*
* Memory Map:
* - Designed to be RAM-resident at D000-FFFF (loaded in when *********
* the ROM is disabled). *********
* - Avoids address space $FFD0-FFDF, used for I/O in multicomp. ******
*
* I/O:
* ***TBD***
*
* Interrupts:
* multicomp timer interrupt is on IRQ.
* multicomp single-step logic is on NMI
*
*
* Memory map of VecBuggy on Vectrex
* $0000-$00FF Vectrex cart headerr.
* $0100-$3FFF Monitor ROM code.
* -----------------------------------------------------------
* $C880-$C8BF I/O routine vectors & system vars.(rmbs)(wsstart)
* $C8C0-$C8FF *Unused*
* $C900-$C97F Xmodem buffer 0, serial input buffer. (rambufs)
* $C980-$C9FF Xmodem buffer 1, serial output buffer.
* $CA00-$CA7F Input Line Buffer.
* $CA80-$CAFF Interrupt vectors and monitor variables.(endvars)
* $CB00-$CB80 System stack (grows down from ramfree).
* $CB80-$CBEA *Unused* (ramfree)
* -----------------------------------------------------------
* $8000-$BFFF FT245R Tx/Rx.
* $D000-$D000 FT245R PB6 Data Available
* -----------------------------------------------------------
* * Define memory map
* ramstart equ $0000 ;RAM start of local storage
* wsstart equ $e000 ;RAM start of workspace
* rambufs equ wsstart+$100
* ramfree equ wsstart+$400 ;free RAM after local storage
* codestart equ $e400
wsstart equ $C800 ;RAM start of workspace
rambufs equ $C900
ramfree equ $CB00 ;Free RAM after local storage
ramstart equ $CB00 ;RAM start of local storage
* FT245R USB to Parallel FIFO interface (Serial Port)
aciasta equ $D000 ;RO Status port of VDU pseudo ACIA
* aciactl equ $0000 ;WO Control port of VDU pseudo ACIA
aciadat equ $8000 ;Data port of VDU pseudo ACIA
* Reserved direct page addresses
org wsstart
* I/O routine vectors.
getchar rmb 3 ;Jump to osgetc
putchar rmb 3 ;Jump to osputc
getline rmb 3 ;Jump to osgetl
putline rmb 3 ;Jump to osputl
putcr rmb 3 ;Jump to oscr
getpoll rmb 3 ;Jump to osgetpoll
xopenin rmb 3 ;Jump to xopin
xopenout rmb 3 ;Jump to xopout
xabortin rmb 3 ;Jump to xabtin
xclosein rmb 3 ;Jump to xclsin
xcloseout rmb 3 ;Jump to xclsout
delay rmb 3 ;Jump to osdly
* wsstart+$24
* System variables in the direct 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 ;0: CRLF after disassembly 1: no CRLF
* wsstart+$33
* I/O buffers.
buflen equ $80 ;Length of input line buffer.
org rambufs
buf0 rmb $80 ;Xmodem buffer 0, serial input buffer.
buf1 rmb $80 ;Xmodem buffer 1, serial output buffer.
linebuf rmb buflen ;Input line buffer.
* [NAC HACK 2015Jul16] since the buffer uses X to address it (ie, non ZP)
* move it elsewhere and use ZP for system variables! Likewise, the vectors
* need not be in the ZP.
* Interrupt vectors (start at $E280)
* 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/T commands.
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
* Variables 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 operand (0--2)
uncert rmb 1 ;Flag to indicate that op is unknown.
dpsetting rmb 2
endvars equ *
* 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.
***************************************************************
* Mandatory Vectrex cartridge header
music1 equ $FD0D ; address of a (BIOS ROM) music
org 0
fcc "g GCE 2020" ; 'g' is copyright sign
fcb $80 ; ending with $80
fdb music1 ; music from the rom
fcb $F8,$50,$20,-$56 ; height, width, rel y, rel x (from 0,0)
fcc "VECBUGGY" ; some game information,
fcb $80 ; ending with $80
fcb 0 ; end of game header
***************************************************************
* Monitor code starts here.
reset orcc #$FF ;Disable interrupts.
lda #wsstart/256
tfr a,dp ;Set direct page register
clr <disflg
lds #ramfree ;Stack grows down from here
ldx #intvectbl ;ROM location of exception vector table
ldu #swi3vec ;destination in RAM
ldb #intvecend-intvectbl
bsr blockmove ;Initialize interrupt vectors from ROM.
ldx #osvectbl ;ROM location of I/O vector table
ldu #getchar ;destination in RAM
ldb #osvecend-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: cc,a,b,dp,xh,xl,yh,yl,uh,ul,pch,pcl
* pc is initialized to ramstart, the rest to zero.
ldx #0
tfr x,y
ldu #ramstart
pshs u,x ; pcl pch ul uh
pshs y,x ; yl yh xl xh
pshs y,x ; dp b a cc
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 outnts
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 rts ;With an FT245, nothing to init
***************************************************************
* O.S. routine to read a character into B register.
osgetc ldb #$40 ;6522 VIA PB6 line used to read
bitb aciasta ;data ready signal
bne osgetc
ldb aciadat
rts
***************************************************************
* O.S. routine to check if there is a character ready to be read.
osgetpoll ldb #$40 ;6522 VIA PB6 line used to read
bitb aciasta ;data ready signal
bne poltrue
clrb
rts
poltrue ldb #$ff
rts
***************************************************************
* O.S. routine to write the character in the B register.
osputc stb aciadat
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 null-terminated string at addr X
outnts pshs x,b
outnts1 ldb ,x+
beq outnts2
* jsr <putchar
jsr putchar
bra outnts1
outnts2 puls x,b
rts
***************************************************************
timerirq inc <timer+2 ; [NAC HACK 2015Jul15] surely this is backwards? LSbyte s/b timer
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
***************************************************************
* The J command returns here.
stakregs pshs x ;Stack something where the pc comes
pshs cc,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.
lda #wsstart/256
tfr a,dp ;Restore direct page register
jsr disarm ;Disarm the breakpoints.
jsr dispregs
* Command loop
cmdline jsr <xcloseout
sts savesp
ldb #'.'
jsr <putchar ;Prompt
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]
***************************************************************
* Error: bad command arguments
argerr jsr <xabortin
ldx #badargs
jsr outnts
jsr <putcr
jmp cmdline
***************************************************************
* Command: Unknown command handling routine.
unk jsr <xabortin
ldx #unknown
jsr outnts
jsr <putcr
jmp cmdline
***************************************************************
* Command: H, help
help ldx #mhelp ;Print a help message.
jsr outnts
jmp cmdline
***************************************************************
* 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 if 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 X 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
***************************************************************
* Command: D hex/ascii dump of memory
* Syntax: D or Daddr or Daddr,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
***************************************************************
* Command: E, enter hex bytes or ascii string.
* Syntax E or E<addr> or E<addr> <bytes> or E<addr>"string"
* [NAC HACK 2015Jul12] bytes need to be 2 characters.
* . to exit, - to go back 1 location
enter ldx #linebuf+1
jsr scanhex
beq ent1
std addr
ent1 bsr entline
lbne cmdline ;No bytes, then enter interactively.
ent2 ldd addr
jsr outd
ldb #' '
jsr <putchar ;Display addr + 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 ASCII string at address X, Z if empty.
entline jsr skipspace
tstb
beq entexit
cmpb #'.' ; . to exit
beq entexit
cmpb #'-' ; - to go back 1 location
bne entnbk
ldy addr
leay -1,y
bra entdone
entnbk cmpb #'"' ; " to start string
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 #'"' ; " to end string
beq entdone
sta ,y+
bra entl3
entdone sty addr
andcc #$fb
rts
entexit orcc #$04
rts
***************************************************************
* Command: I, inspect 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 it in hex.
jsr <putcr
jmp cmdline
***************************************************************
* Command: C, calculate result of simple hex expression
*Syntax Chexnum{+|-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
***************************************************************
* Command: G, jump (go) 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 cc,b,a,dp,x,y,u,pc
***************************************************************
* Command: J, 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.
***************************************************************
* Command: P, 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
***************************************************************
* Command: T, single step trace an instruction.
* Syntax T
*
trace jsr traceone
jsr dispregs
jmp cmdline
traceone orcc #$50 ;Disable interrupts.
ldd ,s++
std oldpc ;Remove "traceone" return address from
;the stack -- it is in the way!
ldd #traceret
std nmivec+1 ;Adjust NMI vector.
lda ,s ;Grab CC
ora #$80
sta ,s ;Write back with ENTIRE=1
***************************************************************
* multicomp09 has a blob of hardware that triggers an NMI with*
* specific timing as the result of a specific memory write. *
* Refer to the description in mem_mapper2.vhd and the *
* waveforms on the WIKI. Do not mess with this instruction *
* sequence!! *
lda #$10 ;Set bit 4 *
* sta mmuadr *
rti ;Resume application *
***************************************************************
* Come here after the execution of 1 instruction at the target PC.
* Full system state is (back) on the stack.
traceret ldd #endirq ;[NAC HACK 2015Oct01] BUG!! Should save/restore the value
std nmivec+1 ;Restore NMI vector.
lda #wsstart/256
tfr a,dp ;Restore direct page register
jmp [oldpc] ;back to caller of "traceone"
***************************************************************
* 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' ;incremented 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
ldb #'P'
ldy 12,s
bsr disp16
jsr disdecode
jsr disdisp ;Disassemble instruction at PC
jsr <putcr
rts
***************************************************************
* Command: R, display or alter the registers.
* Syntax R or R<letter><hex>
regs ldx #linebuf+1
jsr skipspace
tstb
bne setreg
bsr dispregs ;Display regs if nothing follows.
jmp cmdline
setreg ldy #regtab
clra
andb #CASEMASK ;Make letter uppercase.
sr1 tst ,y
lbeq argerr ;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 breakpoints: replace the byte at each breakpoint address
* with an SWI instruction.
arm ldx #brkpoints*3+bpaddr ; [NAC HACK 2015Aug23] portability: AS9 eval l->r
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
***************************************************************
* Command: B, 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 outnts
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
***************************************************************
* Command: S, load/dump memory using Motorola S record format
* Syntax SO<addr> or or S1<bytes> or S9<bytes> to load memory
* Syntax SS<addr>,<len> to dump memory
srec ldx #linebuf+1
ldb ,x+
andb #CASEMASK
cmpb #'O'
beq setsorg
cmpb #'S'
beq sendrec
ldb -1,x
clr <temp3
cmpb #'1'
beq readrec
cmpb #'9'
bne srecerr
inc <temp3
readrec clr <temp2+1 ;clear checksum.
bsr addchk
suba #2 ;discount the address bytes from the count.
sta <temp3+1 ;Read length byte.
bsr addchk
pshs a
bsr addchk
puls b
exg a,b ;Read address into d.
ldu sorg
beq rr1
ldu soffs
bne rr1
pshs d ;Sorg is nonzero and soffs is zero, now
subd sorg ;set soffs
std soffs
puls d
rr1 subd soffs ;Subtract the address offset.
tfr d,y
rr2 bsr addchk
dec <temp3+1