-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMONCommands.asm
967 lines (825 loc) · 28 KB
/
MONCommands.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
;***************************************************************************
; PROGRAM: MONCommands
; PURPOSE: Subroutines for all monitor commands
; ASSEMBLER: original: TASM 3.2 , converted to z80pack/z80asm
; LICENCE: The MIT Licence
; AUTHOR : MCook
; CREATE DATE : 06 May 15 / 2021-01-01
;***************************************************************************
HEXLINES: EQU 17 ; FIXIT: There is a off-by-one-error here
;***************************************************************************
;HELP_COMMAND
;Function: Print help dialogue box
;***************************************************************************
HLPMSG1: DEFB 'ZMC80 Monitor Command List', 0Dh, 0Ah, EOS
HLPMSG2: DEFB '? - view command list', 0Dh, 0Ah, EOS
HLPMSGc: DEFB 'C - clear screen', 0Dh, 0Ah, EOS
HLPMSGd: DEFB 'D - print 100h bytes from specified location', 0Dh, 0Ah, EOS
HLPMSGe: DEFB 'E - edit bytes in memory', 0Dh, 0Ah, EOS
HLPMSGf: DEFB 'F - fill memory range with value', 0Dh, 0Ah, EOS
HLPMSGg: DEFB 'G - jump to memory address', 0Dh, 0Ah, EOS
HLPMSGk: DEFB 'K - call to memory address', 0Dh, 0Ah, EOS
HLPMSGm: DEFB 'M - copy bytes in memory', 0Dh, 0Ah, EOS
HLPMSGo: DEFB 'O - write byte to output port', 0Dh, 0Ah, EOS
HLPMSGp: DEFB 'P - print port scan (00-FF)', 0Dh, 0Ah, EOS
HLPMSGr: DEFB 'R - monitor reset', 0Dh, 0Ah, EOS
HLPMSGq: DEFB 'Q - test MPF keyboard', 0Dh, 0Ah, EOS
HLPMSGs: DEFB 'S - calculate checksum for memory range', 0Dh, 0Ah, EOS
HLPMSGt: DEFB 'T - test memory range', 0Dh, 0Ah, EOS
HLPMSGz: DEFB 'Z - dump user registers (STEP)', 0Dh, 0Ah, EOS
HLPMSG8: DEFB '+ - print next block of memory', 0Dh, 0Ah, EOS
HLPMSG9: DEFB '- - print previous block of memory', 0Dh, 0Ah, EOS
HELP_COMMAND:
LD HL, HLPMSG1 ;Print some messages
CALL PRINT_STRING
LD HL, HLPMSG2
CALL PRINT_STRING
LD HL, HLPMSGc
CALL PRINT_STRING
LD HL, HLPMSGd
CALL PRINT_STRING
LD HL, HLPMSGe
CALL PRINT_STRING
LD HL, HLPMSGf
CALL PRINT_STRING
LD HL, HLPMSGg
CALL PRINT_STRING
LD HL, HLPMSGk
CALL PRINT_STRING
LD HL, HLPMSGm
CALL PRINT_STRING
LD HL, HLPMSGo
CALL PRINT_STRING
LD HL, HLPMSGp
CALL PRINT_STRING
LD HL, HLPMSGq
CALL PRINT_STRING
LD HL, HLPMSGr
CALL PRINT_STRING
LD HL, HLPMSGs
CALL PRINT_STRING
LD HL, HLPMSGt
CALL PRINT_STRING
LD HL, HLPMSGz
CALL PRINT_STRING
LD HL, HLPMSG8
CALL PRINT_STRING
LD HL, HLPMSG9
CALL PRINT_STRING
LD A, EOS ;Load $FF into Acc so MON_COMMAND finishes
RET
;***************************************************************************
;MEMORY_DUMP_COMMAND
;Function: Print $80 databytes from specified location
;***************************************************************************
MDC_1: DEFB 'Memory Dump Command', 0Dh, 0Ah, EOS
MDC_2: DEFB 'Location to start in 4 digit HEX: ',EOS
MDC_3: DEFB ' 0 1 2 3 4 5 6 7 8 9 A B C D E F', 0Dh, 0Ah, EOS
MDCMD:
LD HL,MDC_1 ;Print some messages
CALL PRINT_STRING
LD HL,MDC_2
CALL PRINT_STRING
CALL GETHEXWORD ;HL now points to databyte location
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD (DMPADDR), HL ;Keep address for next/prev.
PUSH HL ;Save HL that holds databyte location on stack
CALL PRINT_NEW_LINE ;Print some messages
CALL PRINT_NEW_LINE
LD HL, MDC_3
CALL PRINT_STRING
POP HL ;Restore HL that holds databyte location on stack
MDNXTPR: LD C,HEXLINES ;Register C holds counter of dump lines to print
MDLINE:
LD DE, ASCDMPBUF
LD B,16 ;Register B holds counter of dump bytes to print
CALL PRINTHWORD ;Print dump line address in hex form
LD A,' ' ;Print spacer
CALL PRINT_CHAR
DEC C ;Decrement C to keep track of number of lines printed
MDBYTES:
LD A,(HL) ;Load Acc with databyte HL points to
CALL PRINTHBYTE ;Print databyte in HEX form
CALL CHAR2BUF ;Store ASCII char
LD A,' ' ;Print spacer
CALL PRINT_CHAR
INC HL ;Increase HL to next address pointer
DJNZ MDBYTES ;Print 16 bytes out since B holds 16
LD A,' ' ;Print spacer
CALL PRINT_CHAR ;
LD A, EOS
LD (ASCDMPEND), A ;Make sure there is a EOS
PUSH HL
LD HL, ASCDMPBUF ;Point HL to ASCII buffer
CALL PRINT_STRING ;Print buffer
POP HL
LD B,C ;Load B with C to keep track of number of lines printed
CALL PRINT_NEW_LINE ;Get ready for next dump line
DJNZ MDLINE ;Print 16 line out since C holds 16 and we load B with C
LD A,EOS ;Load $FF into Acc so MON_COMMAND finishes
RET
CHAR2BUF:
CALL MKPRINT
LD (DE), A
INC DE
RET
;***************************************************************************
;MEMORY_MOVE_COMMAND
;Function: Copy data blocks in memory
;***************************************************************************
MVC_1: DEFB 'Move Data Command', 0Dh, 0Ah, EOS
MVC_S: DEFB 'Start Location: ', EOS
MVC_E: DEFB 'End Location: ', EOS
MVC_D: DEFB 'Destination Location: ', EOS
MOVE_COMMAND:
LD HL, MVC_1 ; Print some messages
CALL PRINT_STRING
LD HL, MVC_S
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD (MVADDR), HL
CALL PRINT_NEW_LINE
LD HL, MVC_E
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD (MVADDR+2), HL
CALL PRINT_NEW_LINE
LD HL, MVC_D
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD (MVADDR+4), HL
CALL PRINT_NEW_LINE
;***************************************************************************
; Adapted copy from MPF-1(B) Monitor
;***************************************************************************
ld hl, MVADDR
call GETP ; Fix BC contents from address, to size
jp c, MERR
ld de, (MVADDR+4)
sbc hl, de
jr nc, MVUP
MVDN: ex de, hl
add hl, bc
dec hl
ex de, hl
ld hl, (MVADDR+2)
lddr
inc de
RET
MVUP:
add hl,de
ldir
dec de
RET;
MERR:
LD A, E_PARAM
LD (ERRFLAG), A
RET;
GETP:
ld e, (hl) ; MVADDR
inc hl
ld d, (hl) ; MVADDR+1
inc hl
ld c, (hl) ; MVADDR+2
inc hl
ld h, (hl) ; MVADDR+3
ld l, c
or a
sbc hl, de
ld c, l
ld b, h
inc bc
ex de, hl
ret
;***************************************************************************
; End copy from MPF-1(B) Monitor
;***************************************************************************
;***************************************************************************
; Memory Fill Command
; Function: Fill a memory block
;***************************************************************************
MFC_1: DEFB 'Fill Memory Command', 0Dh, 0Ah, EOS
MFC_D: DEFB 'Data value (one byte): ', EOS
FILL_COMMAND:
LD HL, MFC_1 ; Print some messages
CALL PRINT_STRING
LD HL, MVC_S ; Start msg.
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD (MVADDR), HL ; Start val.
CALL PRINT_NEW_LINE
LD HL, MVC_E ; End msg.
CALL PRINT_STRING
CALL GETHEXWORD
LD (MVADDR+2), HL ; End val.
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD DE, (MVADDR) ; Start
SBC HL, DE ; Make sure end is past start...
JR C, F_ORDERR
LD HL, (MVADDR+2)
CALL PRINT_NEW_LINE
LD HL, MFC_D
CALL PRINT_STRING
CALL GETHEXBYTE
LD (MVADDR+4), A
LD A, (ERRFLAG)
CP E_NONE
RET NZ
CALL PRINT_NEW_LINE
LD DE, (MVADDR) ; Start
LD HL, (MVADDR+2) ; End
SBC HL, DE ; Size
LD B, H
LD C, L
LD A, (MVADDR+4) ; Fill value
LD HL, (MVADDR) ; First source location
LD (HL), A ; seed the fill block
LD DE, (MVADDR) ; First dest. location
INC DE ;
LDIR
RET
F_ORDERR:
LD A, E_PARAM
LD (ERRFLAG), A
RET
;***************************************************************************
; Next Page Memory Dump Command
; Function: Print the next block of memory
;***************************************************************************
NEXTP_COMMAND:
LD HL,MDC_3
CALL PRINT_STRING
LD HL, (DMPADDR)
INC H
LD (DMPADDR), HL
JP MDNXTPR
;***************************************************************************
; Previous Page Memory Dump Command
; Function: Print the previous block of memory
;***************************************************************************
PREVP_COMMAND:
LD HL,MDC_3
CALL PRINT_STRING
LD HL, (DMPADDR)
DEC H
LD (DMPADDR), HL
JP MDNXTPR
;***************************************************************************
; Edit Memory Command
; Function: Edit bytes in memory
;***************************************************************************
EDIT_COMMAND:
LD HL, MVC_S ; Start msg.
CALL PRINT_STRING
CALL GETHEXWORD ; Get first address
LD A, (ERRFLAG)
CP E_NONE
RET NZ
EDIT_LP:
LD A, ':'
CALL PRINT_CHAR
LD A, ' '
CALL PRINT_CHAR
LD A, (HL) ; Print original value
CALL PRINTHBYTE
LD A, '>'
CALL PRINT_CHAR
LD A, ' '
CALL PRINT_CHAR
CALL GETHEXBYTE
LD (MVADDR+4), A
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD A, (MVADDR+4)
LD (HL), A ; Write new value
CALL PRINT_NEW_LINE
INC HL
CALL PRINTHWORD
JR EDIT_LP ; Only way out is type a non-hex char...
;***************************************************************************
;PORT_SCAN_COMMAND
;Function: Print $100 databytes from specified location
;***************************************************************************
PSC_1: DEFB 'Port Scan Command', 0Dh, 0Ah, EOS
PSC_3: DEFB ' 0 1 2 3 4 5 6 7 8 9 A B C D E F', 0Dh, 0Ah, EOS
PSCOMMAND:
LD HL,PSC_1 ;Print some messages
CALL PRINT_STRING
LD HL,PSC_3 ;Print some messages
CALL PRINT_STRING
LD BC, 0h
XOR A
PS_NEWPL: ; Start new line, start with port address
LD A,C
CALL PRINTHBYTE
LD A, ' '
CALL PRINT_CHAR ; address - contents separator
CALL PRINT_CHAR
PS_LOOP: ; Print port contents
IN A, (C)
CALL PRINTHBYTE
LD A, ' '
CALL PRINT_CHAR ; inter-port-contents separator
INC BC
XOR A
ADD A, B
JR NZ, PS_END ; check for all ports done
LD A, C
AND 00Fh ; multiples of 16
JR NZ, PS_LOOP ; line not yet full
CALL PRINT_NEW_LINE
JR PS_NEWPL
PS_CONT: ; continue on same line
LD A, ' '
CALL PRINT_CHAR
JR PS_LOOP
PS_END: ; done all ports
RET
; untested code, 2023-04-24
;***************************************************************************
; Port Write Command
; Function: Write byte to port
;***************************************************************************
MPW_1: DEFB 'Write data to port Command', 0Dh, 0Ah
MPW_P: DEFB 'Port & data: ', EOS
PW_COMMAND:
LD HL, MPW_1
CALL PRINT_STRING
CALL GETHEXBYTE
LD (MVADDR), A ; Misuse Move address buffer to store port
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD A, ' '
CALL PRINT_CHAR
CALL GETHEXBYTE
LD (MVADDR+1), A
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD A, (MVADDR)
LD C, A
LD A, (MVADDR+1)
OUT (C), A
RET
;***************************************************************************
; Jump to memory Command
; Function: Execute a program at memory location
;***************************************************************************
MGo_1: DEFB 'Execute program in memory Command', 0Dh, 0Ah, EOS
MGo_2: DEFB 'Memory location: ', EOS
GO_COMMAND:
LD HL, MGo_1 ; Print some messages
CALL PRINT_STRING
LD HL, MGo_2 ; Print some messages
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
JP (HL) ; Jump
;***************************************************************************
; Call to memory Command
; Function: Execute a program at memory location and expect a RET
;***************************************************************************
MCl_1: DEFB 'Call program in memory Command', 0Dh, 0Ah, EOS
CL_COMMAND:
LD HL, MCl_1 ; Print some messages
CALL PRINT_STRING
LD HL, MGo_2 ; Print some messages
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD DE, MON_COMMAND
PUSH DE ; Add a suitable return address to the stack
JP (HL)
RET
;***************************************************************************
; Checksum generator. Add memory values in a three byte counter. The last
; included location is end point - 1.
; Function: Calculate checksum for address range in three bytes
;***************************************************************************
CCKSM_1: DEFB 'Calculate checksum for memory range Command', 0Dh, 0Ah, EOS
CCKSM_2: DEFB 'Start location: ', EOS
CCKSM_3: DEFB 'End location: ', EOS
CCKSM_4: DEFB 'Checksum: ', EOS
CCKSM_COMMAND:
LD HL, CCKSM_1
CALL PRINT_STRING
LD HL, CCKSM_2 ; start
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD (MVADDR+0), HL
CALL PRINT_NEW_LINE
LD HL, CCKSM_3 ; end
CALL PRINT_STRING
CALL GETHEXWORD
LD A, (ERRFLAG)
CP E_NONE
RET NZ
LD (MVADDR+2), HL
CALL PRINT_NEW_LINE
LD BC, (MVADDR+0) ; starting point
LD DE, (MVADDR+2) ; end point
LD HL, 0 ; the checksum value
LD A, 0
LD (CHKSUM_C), A ; checksum overflow
CCSM_1: ; main checksum loop
LD A, C
CP E
JR NZ, CCSM_3 ; on no match in LSB, skip the MSB
LD A, B
CP D
JR Z, CCSM_4 ; MSB matches too
CCSM_3: ; still going, add next value to checksum
LD A, (BC)
ADD A, L
LD L, A
JR NC, CCSM_2 ; check carry in checksum LSB
LD A, H
ADD A, 1
LD H, A
JR NC, CCSM_2
LD A, (CHKSUM_C)
INC A
LD (CHKSUM_C), A
CCSM_2: ; done this value
INC BC
JR CCSM_1
CCSM_4: ; running address matches end, done
PUSH HL
LD HL, CCKSM_4 ; end
CALL PRINT_STRING
LD A, (CHKSUM_C)
CALL PRINTHBYTE ; checksum overflow first
POP HL
CALL PRINTHWORD
CALL PRINT_NEW_LINE
RET
;***************************************************************************
; Load hex-intel record
;
;***************************************************************************
HEXI_COMMAND:
; :0C 2000 00 C31820C39421C3B62AC3812A 50
; sz addr typ data chk
; This part reads the record into the buffer.
; Note the ':' is already eaten by the command interpreter.
HEXI_COMMAND:
LD A, 1
LD (MUTE), A
LD HL, UPLOADBUF
LD (RX_READ_P), HL
LD (RX_WRITE_P), HL
HXI_LOOP:
CALL UART_RX_RDY
CALL UART_RX
LD HL, (RX_WRITE_P)
LD (HL), A
INC HL
LD (RX_WRITE_P), HL
AND A
CP LF
JR Z, HXI_RCVD
JR HXI_LOOP
HXI_RCVD: ; the record is received, echo the start address
LD A, 0
LD (MUTE), A
LD HL, UPLOADBUF + 2 ; Point to the first address char.
LD B, 4
HXIADRLP:
LD A, (HL)
CALL PRINT_CHAR
INC HL
DJNZ HXIADRLP
LD A, (HL)
CALL PRINT_CHAR
CALL PRINT_NEW_LINE
HXI_PROC: ; processing the record
LD HL, UPLOADBUF
CALL CHARS2BYTE ; get record size
LD (ULSIZE), A ; store it
CALL CHARS2BYTE ; get record address, MSB
LD (IECADDR+1), A ;
CALL CHARS2BYTE ; get record address, LSB
LD (IECADDR), A
CALL CHARS2BYTE ; get record type
LD (IERECTYPE), A
CP 00h ; compare to end record
JR Z, HXI_ENDR
LD A, (ULSIZE)
LD B, A ; set up DJNZ loop
LD DE, (IECADDR)
HXD_LOOP:
CALL CHARS2BYTE ; get data byte
LD (DE), A ; store it at target location
INC DE
DJNZ HXD_LOOP ; repeat for all data bytes
CALL CHARS2BYTE ; Get checksum
HXI_ENDR: ; Done
RET
USERAF: EQU 01FBCh
USERBC: EQU 01FBEh
USERDE: EQU 01FC0h
USERHL: EQU 01FC2h
UAFP: EQU 01FC4h
UBCP: EQU 01FC6h
UDEP: EQU 01FC8h
UHLP: EQU 01FCAh
USERIX: EQU 01FCCh
USERIY: EQU 01FCEh
USERSP: EQU 01FD0h
USERIF: EQU 01FD2h
FLAGH: EQU 01FD4h
FLAGL: EQU 01FD6h
FLAGHP: EQU 01FD8h
FLAGLP: EQU 01FDAh
USERPC: EQU 01FDCh
RDLN_1: DEFB ' AF BC DE HL IX IY AF', 027h, ' BC', 027h, ' DE', 027h, ' HL', 027h, EOS
RDLN_3: DEFB ' SP PC IF SZ-H-PNC SZ-H-PNC', 027h , EOS
REGDUMP_COMMAND:
LD HL, RDLN_1
CALL PRINT_STRING
CALL PRINT_NEW_LINE
LD HL, (USERAF)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (USERBC)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (USERDE)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (USERHL)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (USERIX)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (USERIY)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (UAFP)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (UBCP)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (UDEP)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (UHLP)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
CALL PRINT_NEW_LINE
LD HL, RDLN_3
CALL PRINT_STRING
CALL PRINT_NEW_LINE
LD HL, (USERSP)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (USERPC)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
LD HL, (USERIF)
CALL PRINTHWORD
LD A, ' '
CALL PRINT_CHAR
CALL PRINT_CHAR
LD A, (USERAF+1)
CALL PRT8BIT
LD A, ' '
CALL PRINT_CHAR
LD A, ' '
CALL PRINT_CHAR
LD A, (UAFP+1)
CALL PRT8BIT
RET
REGDMPJ:
CALL REGDUMP_COMMAND
JP MPFMON ; return to monitor
; RAM test
; Tssss eeee
TRC_1: DEFB 'RAM Test Command', 0Dh, 0Ah, EOS
TRC_2: DEFB 'Location to start in 4 digit HEX: ', EOS
TRC_3: DEFB 0Dh, 0Ah, 'Location to end in 4 digit HEX: ', EOS
TRC_4: DEFB 0Dh, 0Ah, 'Start address should be before End address', EOS
TRAM_COMMAND:
LD HL,TRC_1 ;Print some messages
CALL PRINT_STRING
LD HL,TRC_2
CALL PRINT_STRING
CALL GETHEXWORD ;HL now points to databyte location
LD (MVADDR), HL
LD HL,TRC_3
CALL PRINT_STRING
CALL GETHEXWORD ;HL now points to databyte location
LD (MVADDR+2), HL
LD A, (MVADDR+3) ; End MSB
LD HL, MVADDR+1 ; (Start MSB)
CP (HL) ; A - (HL)
JR Z, _TC_ZERO ; When MSBs are on same page, test LSBs
JR C, _TC_NEGM ; When Start MSB > End MSB, report error, exit
_TC_POS:
CALL MTEST ; When End page (MSB) is larger than Start (MSB), go to test
JR _TC_DONE
_TC_ZERO:
LD A, (MVADDR+2) ; End LSB
LD HL, MVADDR+0 ; (Start LSB)
CP (HL) ; A - (HL)
JR C, _TC_NEGL ; When Start LSB > End LSB, report error, exit
CALL MTEST ; When End page (LSB) is larger than Start (LSB), go to test
JR _TC_DONE
_TC_NEGM:
_TC_NEGL:
LD HL, TRC_4
CALL PRINT_STRING
JR _TC_DONE
_TC_DONE:
RET
MTC_1: DEFB 0Dh, 0Ah, ' Pass 1: ??h to 00h ', EOS
MTC_2: DEFB 0Dh, 0Ah, ' Pass 2: 00h to 55h ', EOS
MTC_3: DEFB 0Dh, 0Ah, ' Pass 3: 55h to AAh ', EOS
MTC_4: DEFB 0Dh, 0Ah, ' Pass 4: AAh to FFh ', EOS
MTC_5: DEFB 0Dh, 0Ah, ' Memory OK', EOS
MTCER1: DEFB ' Error at: ', EOS
MTCER2: DEFB ' value expected: ', EOS
MTCER3: DEFB ', found: ', EOS
MTEST:
; Test strategy in four passes:
; 1. Loop through start to end and for each memory location:
; Set to 00h and check new value
; 2. Loop through start to end and for each memory location:
; Check old value (00h)
; Set new value 55h
; Check new value
; 3. Loop through start to end and for each memory location:
; Check old value (55h)
; Set new value AAh
; Check new value
; 4. Loop through start to end and for each memory location:
; Check old value (AAh)
; Set new value FFh
; Check new value
; Report start of each pass.
; Report address of first incorrect value and terminate
; MVADDR/MVADDR+1 : start address, MVADDR+2/MVADDR+3 : end address
; MVADDR+4 : actual value, MVADDR+5 : expected value
; D : new value, E : old value
LD IX, MVADDR
; Pass 1 ; check only new value (write phase)
LD HL, MTC_1
CALL PRINT_STRING
LD HL, (MVADDR+0)
LD BC, (MVADDR+2)
LD E, 64
LD D, 000h
LD A, 1
LD (MTPHFLAG), A
CALL MCHECK
JR C, _MTDONE ; skip other tests on error
; Pass 2 ; check old value and new value (read & write phase)
LD HL, MTC_2
CALL PRINT_STRING
LD HL, (MVADDR+0) ; reset start address
LD E, 000h ; old value
LD D, 055h ; new value
LD A, 2
LD (MTPHFLAG), A
CALL MCHECK
JR C, _MTDONE ; skip other tests on error
; Pass 3
LD HL, MTC_3
CALL PRINT_STRING
LD HL, (MVADDR+0) ; reset start address
LD E, 055h ; old value
LD D, 0AAh ; new value
LD A, 3
LD (MTPHFLAG), A
CALL MCHECK
JR C, _MTDONE ; skip other tests on error
; Pass 4
LD HL, MTC_4
CALL PRINT_STRING
LD HL, (MVADDR+0) ; reset start address
LD E, 0AAh ; old value
LD D, 0FFh ; new value
LD A, 4
LD (MTPHFLAG), A
CALL MCHECK
JR C, _MTDONE ; skip other tests on error
LD HL, MTC_5 ; Ok text
CALL PRINT_STRING
_MTDONE
RET
MCHECK
_MCLOOP
LD A, (MTPHFLAG)
CP 1
JR Z, _MCSKIPOLD ; Skip old value check for pass 1
; old value check
LD A, E
LD (IX+5), A ; store expected value
LD A, (HL) ; read mem
LD (IX+4), A ; store actual value
CP (IX+5) ; compare with expected
JR NZ, _MTLPER1 ; jump to error when unequal
_MCSKIPOLD
; new value write
LD A, D
LD (HL), A ; write new value
LD (IX+5), A ; store expected value
; new value check
LD A, (HL) ; read new value
LD (IX+4), A ; store actual value
CP (IX+5) ; compare with expected
JR NZ, _MTLPER2 ; jump to error when unequal
CALL CPADDR ;
INC HL ;
JR NZ, _MCLOOP ;
AND A ; 'Clear Carry flag'
LD A, 1
JR _MCDONE
; Error handling
_MTLPER1
PUSH AF
CALL PRINT_NEW_LINE
LD A, '1'
CALL PRINT_CHAR
LD A, '.'
CALL PRINT_CHAR
POP AF
JR _MTLPER
_MTLPER2
PUSH AF
CALL PRINT_NEW_LINE
LD A, '2'
CALL PRINT_CHAR
LD A, '.'
CALL PRINT_CHAR
POP AF
_MTLPER:
PUSH HL ; keep actual location
LD HL, MTCER1 ; at text
CALL PRINT_STRING
POP HL
CALL PRINTHWORD
LD HL, MTCER2 ; expected text
CALL PRINT_STRING
LD A, (MVADDR+5) ; expected value
CALL PRINTHBYTE
LD HL, MTCER3 ; actual found text
CALL PRINT_STRING
LD A, (MVADDR+4) ; actual value
CALL PRINTHBYTE
CALL PRINT_NEW_LINE
SCF ; Flag the error for calling routine
_MCDONE
RET
; **********************************************************************
; CPADDR - Compare two addresses, Z-flag set when equal
; HL contains current address, BC contains end address
; Z-flag set when equal
; **********************************************************************
CPADDR:
LD A, B ; End MSB
CP H ; end MSB - current MSB : B - H
JR NZ, _CPDONE ; When MSBs are unequal
LD A, C ; End LSB
CP L ; end LSB - current LSB ; C - L
_CPDONE:
RET