forked from wwarthen/RomWBW
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzcpr.mac
2020 lines (2015 loc) · 51 KB
/
zcpr.mac
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
; DATE 06/02/21 08:08:00
;
; TITLE ZCPR Console Command Processor - Version D&J
; SUBTTL Last Modified: 10 August 1997
; CP/M Z80 Command Processor Replacement (CPR) Version 1.0
; CCPZ CREATED AND CUSTOMIZED FOR ARIES-II BY RLC
; FURTHER MODIFIED BY RGF AS V2.0
; FURTHER MODIFIED BY RLC AS V2.1
; FURTHER MODIFIED BY KBP AS V2.2
; FURTHER MODIFIED BY RLC AS V2.4 (V2.3 skipped)
; FURTHER MODIFIED BY RLC AS V2.5
; FURTHER MODIFIED BY RLC AS V2.6
; FURTHER MODIFIED BY SBB AS V2.7
; FURTHER MODIFIED BY RLC AS V2.8
; FURTHER MODIFIED BY RLC AS V2.9
; FURTHER MODIFIED BY RLC AS V3.0
; FURTHER MODIFIED BY RLC AS V3.1
; FURTHER MODIFIED BY RLC AS V4.0
; ZCPR VERSION 1.0 CREATED FROM CCPZ VERSION 4.0 BY RLC IN
; A COORDINATED EFFORT WITH CCP-GROUP
; FURTHER MODIFIED BY SBB (AS CCPZ-V4.1 11/27/81)
; & MORE MODS BY ROBERT FISHER (CA. 12/1/81)
; [RETROFITTED TO ZCPR BY BEN BRONSON (12/22/81) AS ZCPR-BB]
;
; FURTHER MODIFIED BY DCK AS Version D&J
;
; ZCPR is a group effort by CCP-GROUP, whose active membership involved
; in this project consists of the following:
; RLC - Richard Conn
; RGF - Ron Fowler
; KBP - Keith Peterson
; FJW - Frank Wancho
; The following individual also provided a contribution:
; SBB - Steve Bogolub
;
; (Note by BB: SBB's and R Fisher's changes came too late in the
; history of CCPZ to be included in the first release of ZCPR)
;
; Extensive modifications to add ERAQ, DIR for all usrnum,
; LIST x.x P, and fix TYPE when FF encountered was done by Don
; Kirkpatrick, 20 September 1986.
;
; DCK - Don Kirkpatrick
;
; Further modified for better polling during LIST/TYPE, 16 July 1987.
;
; Further modified to include boot command and to permit multiple
; commands per line. Fixed bug in jump. Modified type so character
; is not echoed, 4 July 1988.
;
; Modified to add PAGE command 31 December 1989.
;
; Added BELL and SAK (Strike Any Key) command.
;
; Added ZCPR3 style drive/user number to all FCB parsing. For Example:
; A>c4: Changes to drive C/user 4
; A>c4:<program> Runs <program> found on drive C/user 4
; A>dir c4: Gives directory of drive C/user 4
; A>ren <new name>=c4:<old name>
; Renames file found on drive C/user 4
; Both the drive and user number are optional; 15: is a valid designation.
; S1 in the FCB is used to store the user number. If S1 contains a valid
; user number, bit 7 will be set. If no user number is specified, S1 will
; contain 0.
;
; Added POKE and changed SCL to a toggle, 12 August 1992.
;
; Added PEEK 30 August 1993.
;
; Added CLS 10 August 1997 and fixed two bugs. One caused the system to
; hang if the command to log into another drive was given while logged
; into a drive from which the disk had been removed. The other caused
; a warm boot to return to the prior user area if the new user number
; had been selected using the USER command (although not if the user area
; had been changed using the du: command).
;
;******** Structure Notes ********
;
; This CPR is divided into a number of major sections. The following
; is an outline of these sections and the names of the major routines
; located therein.
;
; Section Function/Routines
; ------- -----------------
;
; -- Opening Comments, Equates, and Macro Definitions
;
; 0 JUMP Table into CPR
;
; 1 Buffers
;
; 2 CPR Starting Modules
; CPR1 CPR RESTRT
;
; 3 Utilities
; CRLF PRINTC PRINT PRINTS BELL
; CLS CONOUT BREAK CHKETX ABORT
; READF READ WRITE DEFDMA DMASET
; SEARF SEARDE SEARN OPENF OPEN
; CLOSE CREATE BDOSFN SUBKIL DELETE
; TLOGIN DLOGIN LOGIN NEWUSR RSTUSR
; SETUSR BDOSEA BDOSJP BDOSBC BDOSDE
;
; 4 CPR Utilities
; PROMPT REDBUF CNVBUF UCASE SDELM
; ADVAN SBLANK ADDAH NUMBER A2NUM
; HEXNUM USRNUM ERROR DIRPTR ULOGIN
; SCANER SCANT SCANF CMDSER
;
; 5 CPR-Resident Commands and Functions
; 5A DIR DIRPR PRFN
; 5B ERA
; 5C ERAQ PRNNF
; 5D SAK REPLY
; 5E CLS
; 5F BELL
; 5G LIST
; 5H TYPE PAGER
; 5I EJECT
; 5J SAVE
; 5K REN
; 5L USER SUSER
; 5M DFU
; 5N SCL
; 5O PEEK
; 5P POKE
; 5Q JUMP
; 5R COM UPDATE
; 5S GO CLLPRG ERRLOG ERRJMP
; 5T GET MEMLD PRNLE
; BIOS BOOT
;
;
FALSE EQU 0
TRUE EQU NOT FALSE
;
;
; CUSTOMIZATION EQUATES
;
; The following equates may be used to customize this CPR for the user's
; system and integration technique. The following constants are provided:
;
; TEST - TRUE to build at intermediate address to debug via debugger.
;
; COMLD - TRUE to test and execute as a .com file.
;
; REL - TRUE if integration is to be done via MOVCPM.
;
; BASE - Base Address of user's CP/M system (normally 0 for DR version).
; This equate eases modification by non-standard CP/M (eg. H89).
;
; P2DOS - Address of BDOS/P2DOS.
;
TEST EQU FALSE ;SET TO LOAD/RUN AT 8000H FOR DEBUG
COMLD EQU FALSE ;SET TO LOAD AND EXECUTE AS A .COM FILE
REL EQU FALSE ;SET TO TRUE FOR MOVCPM INTEGRATION
;LEAVE ALL FALSE FOR SYSGEN IMAGE
;
BASE EQU 0 ;BASE OF CP/M SYSTEM
;P2DOS EQU 0E400H ;BASE OF BDOS/P2DOS (original)
P2DOS EQU 0D800H ;BASE OF BDOS/P2DOS (Retro-Brew)
ZCPRSZ EQU 00800H ;SIZE OF ZCPR
P2DOSSZ EQU 00E00H ;SIZE OF P2DOS
BIOS EQU P2DOS+P2DOSSZ ;BASE OF BIOS
CPRLOC DEFL P2DOS-ZCPRSZ ;STANDARD EXECUTION ADDRESS
;
IF REL
CPRLOC DEFL 0 ;MOVCPM IMAGE
ENDIF
;
IF TEST
CPRLOC DEFL 8000H
ELSE
BOOT EQU BIOS ;BIOS COLD BOOT ENTRY
LISTST EQU BIOS+002DH ;ENTRY POINT FOR LIST STATUS
ENDIF
;
; The following is presented as an option, but is not normally user-customize-
; able. A basic design choice had to be made in the design of ZCPR concerning
; the execution of SUBMIT files. The original CCP had a problem in this sense
; in that it ALWAYS looked for the SUBMIT file from drive A: and the SUBMIT
; program itself (SUBMIT.COM) would place the $$$.SUB file on the currently
; default drive. When the user was logged into B: and he issued a SUBMIT
; command, the $$$.SUB was placed on B: and did not execute. The CPR looked
; for $$$.SUB on A: and never found it.
;
; After much debate it was decided to have ZCPR perform the same type of
; function as CCP (look for the $$$.SUB file on A:), but the problem with
; SUBMIT.COM still exists. Hence, RGF designed SuperSUB and RLC took his
; SuperSUB and designed SUB from it; both programs are set up to allow the
; selection at assembly time of creating the $$$.SUB on the default drive
; or on drive A:.
;
; A final definition of the Indirect Command File ($$$.SUB or SUBMIT
; File) is presented as follows:
;
; "An Indirect Command File is one which contains
; a series of commands exactly as they would be
; entered from a CP/M Console. The SUBMIT Command
; (or SUB Command) reads this file and transforms
; it for processing by the ZCPR (the $$$.SUB File).
; ZCPR will then execute the commands indicated
; EXACTLY as if they were typed at the Console."
;
; Hence, to permit this to happen, the $$$.SUB file must always
; be present on a specific drive, and A: is the choice for said drive.
; With this facility engaged as such, Indirect Command Files like:
;
; DIR
; B:
; DIR
;
; can be executed, even though the currently default drive is changed
; during execution. If the $$$.SUB file was present on the currently
; default drive, the above series of commands would not work since the
; ZCPR would be looking for $$$.SUB on the default drive, and switching
; default drives without moving the $$$.SUB file as well would cause
; processing to abort.
;
; Note that the same problem can occur if the user number of the
; $$$.SUB file is not predefined. It is assumed that the $$$.SUB file
; is located on user 0 of the specified drive.
;
; The trick of using the $ flag returned by DISK RESET is used to
; to speed the search for a $*.* file on drive A. This trick will not
; work if the $$$.SUB file is located on another drive.
;
;
; Under the ZCPR, three command levels exist:
;
; (1) that command issued by the user from his console at the '>' prompt
; (2) that command issued by a $$$.SUB file at the '$' prompt
; (3) that command issued by a user program by placing the command into
; CIBUFF and setting the character count in CBUFF
;
; To use CIBUFF, the user program stores the command line and character
; count; ZCPR will initialize the pointers properly, store the ending zero,
; and capitalize the command line for processing. Once the command line is
; properly stored, the user executes the command line by reentering ZCPR
; through CPRLOC [NOTE: The C register MUST contain a valid User/Disk Flag
; (see location 4) at this time.]
;
;
; Directory customization equates
;
TWOCOL EQU FALSE ;TRUE FOR TWO-COLUMN DIRECTORY DISPLAY
WIDE EQU TRUE ;TRUE IF WIDE DIRECTORY DISPLAY
FENCE EQU '|' ;CHARACTER BETWEEN FILES
USRDLM EQU ':' ;CHARACTER BETWEEN USER NUMBER AND FILE
USRFLG EQU 'A' ;LIST $SYS AND $DIR FOR ALL USER NUMBERS
SYSFLG EQU 'B' ;LIST $SYS AND $DIR
SOFLG EQU 'S' ;LIST $SYS ONLY
;
; List and Type command customization equates
;
NLINES EQU 22 ;NUMBER OF LINES ON CRT PAGE
NLINEP EQU 60 ;NUMBER OF LINES ON LIST DEVICE
FFKILL EQU TRUE ;TRUE SUPPRESSES FF UNTIL FIRST CHARACTER
PGDFLG EQU 'P' ;TYPE AND LIST COMMAND DEFAULT TOGGLE
NOSTAT EQU FALSE ;SET TO TRUE IF BIOS LISTST NOT IMPLEMENTED
;
; Other customization equates
;
BUFLEN EQU 80 ;SIZE OF COMMAND INPUT BUFFER
MAXUSR EQU 15 ;MAXIMUM USER NUMBER ACCESSIBLE
DEFUSR EQU 0 ;DEFAULT USER NUMBER FOR COM FILES
DEFDRV EQU 'A' ;DEFAULT DRIVE FOR COM FILES
SPRMPT EQU '$' ;CPR PROMPT INDICATING SUBMIT COMMAND
COMCHR EQU '%' ;BEGIN COMMENT CHARACTER
CMDCHR EQU ';' ;BEGIN NEXT COMMAND CHARACTER
NUMBASE EQU 'H' ;CHARACTER USED TO SPECIFY HEXIDECIMAL BASE
RECFLG EQU 'R' ;CHARACTER FOR SAVE COMMAND TO SAVE RECORDS
SUPRES EQU TRUE ;TRUE TO SUPPRESS USER NUMBER FOR USER 0
MULTPL EQU TRUE ;TRUE TO ALLOW MULTIPLE COMMANDS ON ONE LINE
REBOOT EQU TRUE ;TRUE TO INCLUDE BOOT COMMAND
CLSCHR EQU 1AH ;CHARACTER TO CLEAR TERMINAL SCREEN
ESC EQU 1BH ;VT100 LEAD-IN CHAR. (FOR 'CLS')
;
IF TEST
CPRMPT EQU '<' ;CPR PROMPT INDICATING TEST MODE
ELSE
CPRMPT EQU '>' ;CPR PROMPT INDICATING USER COMMAND
ENDIF
;
; END OF CUSTOMIZATION SECTION
;
ETX EQU 03H
BELL EQU 07H
BS EQU 08H
TAB EQU 09H
LF EQU 0AH
FF EQU 0CH
CR EQU 0DH
;
WBOOT EQU BASE+0000H ;CP/M WARM BOOT ADDRESS
UDFLAG EQU BASE+0004H ;USER NUMBER IN HIGH NIBBLE, DISK IN LOW
BDOS EQU BASE+0005H ;BDOS FUNCTION CALL ENTRY POINT
TFCB EQU BASE+005CH ;DEFAULT FCB BUFFER
TBUFF EQU BASE+0080H ;DEFAULT DISK I/O BUFFER
TPA EQU BASE+0100H ;BASE OF TPA
;
;
;**** Section 0 ****
;
.Z80
ASEG
ORG 100H
;
; LOADER FOR TEST PURPOSES
; ALLOWS ONE TO EXECUTE ZCPR AS A .COM FILE
;
IF COMLD OR TEST
LD HL,BGNXFR
LD DE,CPRLOC
LD BC,ENDLD-BGNXFR
LDIR
LD BC,(UDFLAG)
JP CPRLOC
BGNXFR EQU $
ENDIF
;
.PHASE CPRLOC
;
; ENTRY POINTS INTO ZCPR
;
; If the ZCPR is entered at location CPRLOC (at the JUMP to CPR), then
; the default command in CIBUFF will be processed. If the ZCPR is entered
; at location CPRLOC+3 (at the JUMP to CPR1), then the default command in
; CIBUFF will NOT be processed.
;
; NOTE: Entry into ZCPR in this way is permitted under ZCPR Version 4.0,
; but in order for this to work, CIBUFF and CBUFF MUST be initialized properly
; AND the C register MUST contain a valid User/Disk Flag (see Location 4: the
; most significant nibble contains the User Number and the least significant
; nibble contains the Disk Number.)
;
; Some user programs (such as SYNONYM3) attempt to use the default
; command facility. Under the original CPR, it was necessary to initialize
; a pointer located at the end of the command buffer to point to the first
; byte in the command buffer. Under Version 4.x of ZCPR, this is no longer
; the case. This pointer, CIBPTR (Command Input Buffer PoinTeR), has been
; moved and the former location is now reserved for the stack. ZCPR
; Version 4.x automatically initializes CIBPTR in all cases.
;
ENTRY:
JP CPR ; Process potential default command
JP CPR1 ; Do NOT process potential default command
;
;**** Section 1 ****
;
; BUFFERS ET AL
;
; INPUT COMMAND LINE AND DEFAULT COMMAND
;
; The command line to be executed is stored here. This command line
; is generated in one of three ways:
;
; (1) by the user entering it through the BDOS READLN function at
; the du> prompt [user input from keyboard].
; (2) by the SUBMIT File Facility placing it there from a $$$.SUB
; file.
; (3) by an external program or user placing the required command
; into this buffer.
;
; In all cases, the command line is placed into the buffer starting at
; CIBUFF. This line contains the last character but NOT the Carriage
; Return, and the count is of all characters in the command line up to and
; including the last character. This count is placed into location CBUFF
; (immediately before the command line at CIBUFF.) If ZCPR is entered via
; CPRLOC, the command line is then parsed, interpreted, and the indicated
; command is executed. ZCPR places the terminating zero after the command
; and CIBPTR is properly initialized.
;
; WARNING: The command line must NOT exceed BUFLEN characters in length.
; For user programs which load this command, the value of BUFLEN can be
; obtained by examining the byte at CPRLOC+6.
;
; It is now possible to place multiple commands on one line. Each command
; is separated from its neighbor by a ";". This feature only works for ZCPR
; commands and programs that return to ZCPR via a RET instruction. Any
; warm boot reloads ZCPR and destroys the contents of the command buffer.
; The multiple command feature may be turned off with the SCL command.
;
;MBUFF: DEFB BUFLEN ;MAXIMUM BUFFER LENGTH
MBUFF: DEFB BUFEND-CIBUFF ;MAXIMUM BUFFER LENGTH
CBUFF: DEFB 0 ;NUMBER OF CHARACTERS IN COMMAND LINE
CIBUFF: DB ' ' ;DEFAULT (COLD BOOT) COMMAND 13
DEFB 0 ;COMMAND STRING TERMINATOR 14
DEFB ' ZCPR-D&J of 17 May 2021 ' ;44
DEFB 0 ;TERMINATOR FOR DUMP IDENTIFICATION 45
; DEFS BUFLEN-($-CIBUFF)+1
db 0,0,0,0,0,0,0,0 ;53
db 0,0,0,0,0,0,0,0 ;61
db 0,0,0,0,0,0,0,0 ;69
db 0,0,0,0,0,0,0,0 ;77
db 0,0,0,0,0,0,0,0 ;85
db 0,0,0,0,0,0,0,0 ;93
db 0,0,0 ;96
; DEFB 0,0,0,0,0,0,0,0 ;101
; DEFB 0,0,0 ;104
; DEFB 0,0,0,0,0,0,0,0 ;109
; DEFB 0,0,0,0,0,0,0,0 ;118
BUFEND EQU $
; DEFW 0 ;SENTINEL FOR STACK END
db 0,0
DEFS 24,0 ;STACK AREA
STACK EQU $ ;TOP OF STACK
;
; SUBMIT FILE CONTROL BLOCK
;
SUBDN: DEFB 1 ;DISK DRIVE (A: CONTAINS $$$.SUB)
SUBFN: DEFB '$$$ ' ;FILE NAME
SUBFT: DEFB 'SUB' ;FILE TYPE
SUBEX: DEFB 0 ;EXTENT NUMBER
SUBS1 EQU SUBDN+13 ;S1
SUBS2 EQU SUBDN+14 ;S2
SUBRC EQU SUBDN+15 ;RECORD COUNT
SUBDM EQU SUBDN+16 ;DISK GROUP MAP
SUBCR EQU SUBDN+32 ;CURRENT RECORD NUMBER
;
; COMMAND FILE CONTROL BLOCK
;
FCBDN: db 0 ;DISK DRIVE
FCBFN: db 0,0,0,0,0,0,0,0 ;FILE NAME
FCBFT: db 0,0,0 ;FILE TYPE
FCBEX: db 0 ;EXTENT NUMBER
FCBS1: db 0 ;S1
FCBS2: db 0 ;S2
FCBRC: db 0 ;RECORD COUNT
FCBDM: db 0,0,0,0,0,0,0,0 ;DISK GROUP MAP
db 0,0,0,0,0,0,0,0
FCBCR: db 0 ;CURRENT RECORD NUMBER
;
; Type and List Variables
;
CHRCNT: db 0 ;CHARACTER COUNT FOR TYPE AND LIST
LNCNT: db 0 ;LINE COUNT FOR TYPE AND LIST
TYPLST: db 0 ;FLAG FOR TYPE OR LIST
TABCNT: db 0 ;TAB COUNT FOR TYPE AND LIST
SYSTST: DEFB 0 ;LIST SYSTEM FILES IN DIRECTORY FLAG
;
; General Variables
;
CIBPTR: DEFW CIBUFF ;POINTER TO COMMAND INPUT BUFFER
CIPTR: DEFW CIBUFF ;POINTER TO CURRENT CMD FOR ERROR REPORTING
TMPUSR: DEFB 0 ;TEMPORARY USER NUMBER
TDRIVE: DEFB 0 ;TEMPORARY DRIVE
DFUSR: DEFB DEFUSR ;DEFAULT USER
LDADR: DEFW TPA ;MEMORY LOAD ADDRESS
;
; CPR BUILT-IN COMMAND TABLE
; EACH ENTRY IS COMPOSED OF THE BIT 7 TERMINATED COMMAND AND 2-BYTE ADDRESS
;
CMDTBL:
DC 'DIR'
DEFW DIR
DC 'LIST'
DEFW LIST
DC 'TYPE'
DEFW TYPE
DC 'USER'
DEFW USER
DC 'DFU'
DEFW DFU
DC 'FF' ; was 'PAGE'
DEFW EJECT
DC 'BELL'
DEFW RING
DC 'CLS'
DEFW CLS
DC 'SAK' ; "Strike Any Key"
DEFW SAK
DC 'GO'
DEFW GO
DC 'ERA'
DEFW ERA
DC 'ERAQ'
DEFW ERAQ
DC 'SAVE'
DEFW SAVE
DC 'REN'
DEFW REN
DC 'GET'
DEFW GET
DC 'JUMP'
DEFW JUMP
DC 'PEEK'
DEFW PEEK
DC 'POKE'
DEFW POKE
NCMNDS DEFL 18 ;NUMBER OF COMMANDS
;
IF MULTPL
DC 'SCL'
DEFW SINGLE
NCMNDS DEFL NCMNDS+1
ENDIF
;
IF REBOOT
DC 'BOOT'
DEFW BOOT
NCMNDS DEFL NCMNDS+1
ENDIF
;
;
;**** Section 2 ****
; CPR STARTING POINTS
;
; START CPR AND DON'T PROCESS DEFAULT COMMAND STORED
;
CPR1:
XOR A ;SET NO DEFAULT COMMAND
LD (CBUFF),A
;
; START CPR AND POSSIBLY PROCESS DEFAULT COMMAND
;
CPR:
LD SP,STACK ;MAKE SURE WE HAVE A VALID STACK
LD A,C ;C=USER/DISK NUMBER (SEE LOC 4)
RRA ;EXTRACT USER NUMBER
RRA
RRA
RRA
AND 0FH
LD (TMPUSR),A ;SET USER NUMBER
LD A,C ;GET DISK NUMBER (SEE LOC 4)
AND 0FH ;EXTRACT DEFAULT DISK DRIVE
LD (TDRIVE),A ;SAVE DEFAULT DRIVE
LD C,0DH ;RESET DISK SYSTEM
CALL BDOS
LD (SUBFLG),A ;SAVE SUBMIT FLAG CLUE
DEFB 0F6H ;SET NZ FLAG (OR A,n)
;
; PROMPT USER AND PROCESS INPUT COMMAND
;
RESTRT:
XOR A ;SET ZERO FLAG
LD SP,STACK ;RESET STACK
;
; PROCESS INPUT LINE
;
CALL REDBUF ;CAPITALIZE, NULL TERMINATE, SKIP SPACES
RS3:
CP COMCHR ;COMMENT?
JR Z,RESTRT ;YES, SKIP REST OF LINE
CALL SCANER ;PARSE COMMAND NAME FROM COMMAND LINE
JR NZ,RS4 ;ERROR IF NAME CONTAINS A "?"
CALL CMDSER ;SCAN FOR COMMAND
;
; ENTRY POINT FOR CONTINUED SCAN OF COMMAND LINE
;
CALL UPDATE ;UPDATE BDOS/SYSTEM PARAMETERS
CALL ADVAN ;GET ANY CHARACTER
JR Z,RESTRT ;NONE, END OF LINE
LD (CIPTR),DE ;UPDATE START OF LINE IN CASE ERROR
INC DE ;NOT END OF LINE, MUST BE DELIMITER
LD (CIBPTR),DE ;SAVE POINTER
;
IF MULTPL
LD HL,NEWCMD ;COMMAND?
CP (HL)
RS4:
JP NZ,ERROR ;NO
CALL ADVAN ;STEP OVER DELIMITER
JR RS3
ELSE
RS4:
JP ERROR
ENDIF
;
;
;**** Section 3 ****
; I/O UTILITIES
;
; OUTPUT <CRLF>
;
CRLF:
CALL PRINT ;PRINT STRING
DEFB CR,LF+80H
RET
;
; PRINT STRING POINTED TO BY RET ADR; START WITH <CRLF>
;
PRINTC:
CALL CRLF ;NEW LINE
;
; PRINT STRING POINTED TO BY RET ADR
;
PRINT:
EX (SP),HL ;GET POINTER TO STRING
CALL PRINTS
EX (SP),HL ;RESTORE HL AND RETURN ADDRESS
RET
;
; PRINT STRING POINTED TO BY HL
;
PRINT1:
CALL CONOUT ;PRINT CHARACTER
PRINTS:
LD A,(HL) ;GET NEXT BYTE
INC HL ;POINT TO NEXT BYTE
AND A ;TEST FOR 0 OR BIT 7 SET
RET Z ;DONE
JP P,PRINT1 ;NOT LAST CHARACTER
;
; OUTPUT CHARACTER IN A REG
;
CONOUT:
PUSH BC
PUSH DE
LD C,02H
RES 7,A ;STRIP MSB IN CASE SET FOR EOS
LD E,A
JR BDOSDE
;
; GET CHARACTER FROM CONSOLE AND CHECK FOR ^C
;
BREAK:
PUSH BC
LD C,0BH ;CONSOLE STATUS CHECK
CALL BDOSJP
LD C,01H ;GET CHARACTER FROM CON: WITH ECHO
CALL NZ,BDOSJP ;GET CHARACTER
POP BC
RET Z ;NO CHARACTER
CHKETX:
CP ETX ;^C?
RET NZ ;NO
ABORT:
CALL SUBKIL ;KILL ANY SUBMIT
JR RESTRT ;AND RESTART
;
; BDOS FUNCTIONS
;
READF:
LD DE,FCBDN ;FALL THRU TO READ
READ:
LD C,14H
DEFB 3AH ;SKIP NEXT TWO BYTES
WRITE:
LD C,15H ;FALL THRU TO BDOS CALL
JR BDOSJP
DEFDMA:
LD DE,TBUFF ;TBUFF = DEFAULT ADDRESS
DMASET:
LD C,1AH ;SET DMA ADDRESS
JR BDOSJP
SEARF:
LD DE,FCBDN ;SPECIFY FCB
SEARDE:
LD C,11H ;SEARCH FOR FILE
DEFB 3AH ;SKIP NEXT TWO BYTES
SEARN:
LD C,12H ;SEARN IGNORES DE AND USES THE PREVIOUS
JR BDOSFN ;VALUE FROM THE LAST BDOS CALL
OPENF:
XOR A
LD (FCBCR),A
LD DE,FCBDN ;FALL THRU TO OPEN
OPEN:
LD C,0FH ;OPEN FILE
DEFB 3AH ;SKIP NEXT TWO BYTES
CLOSE:
LD C,10H ;CLOSE FILE
DEFB 3AH ;SKIP NEXT TWO BYTES
CREATE:
LD C,16H ;CREATE FILE
BDOSFN:
CALL BDOSJP
INC A ;SET ERROR RETURN FLAG
RET
SUBKIL:
LD HL,SUBFLG ;ABORT SUBMIT FILE
LD A,(HL) ;SUB FILE IN EXECUTION?
AND A
RET Z ;NO
LD (HL),0 ;KILL SUB FILE EXECUTION FLAG
LD DE,SUBDN ;DELETE $$$.SUB
DELETE:
LD C,13H ;DELETE FILE
JR BDOSJP ;SAVE MORE SPACE
TLOGIN:
LD (TDRIVE),A ;SAVE NEW DEFAULT DRIVE
DLOGIN:
LD A,(TDRIVE) ;LOG IN DEFAULT DRIVE
LD C,0EH ;SELECT DISK
JR BDOSEA ;SAVE SOME CODE SPACE
NEWUSR:
LD (TMPUSR),A ;SET NEW USER NUMBER
RSTUSR:
LD A,(TMPUSR) ;RESET TEMPORARY USER
SETUSR:
LD C,20H ;GET/SET USER NUMBER (GET IF E=FFH)
BDOSEA:
LD E,A ;STUFF PARAMETER INTO REG E
BDOSJP:
PUSH BC
BDOSBC:
PUSH DE ; zcpr does not use any BDOS calls that
BDOSDE:
PUSH HL ; return a value in HL. Those HL calls
CALL BDOS ; are:
POP HL ; get active drive - #24
POP DE ; get allocation vector - #27
POP BC ; get read-only map - #29
AND A ; get disk parameters - #31
RET
;
;
;**** Section 4 ****
; CPR UTILITIES
;
; PRINT PROMPT (DU>)
;
PROMPT:
CALL CRLF ;PRINT PROMPT
LD A,(TDRIVE) ;CURRENT DRIVE IS PART OF PROMPT
ADD A,'A' ;CONVERT TO ASCII A-P
CALL CONOUT
LD A,(TMPUSR) ;GET USER NUMBER
;
IF SUPRES ;IF SUPPRESSING USER # REPORT FOR USER 0
AND A
JR Z,PRPT1 ;ZERO, SUPRESS
ENDIF
;
PRUSRN:
ADD A,0 ;CONVERT HEX TO BCD
DAA
PUSH AF ;SAVE UNITS DIGIT
AND 0F0H
LD A,'1'
CALL NZ,CONOUT ;PRINT IF OVER 10
POP AF
OR '0' ;OUTPUT 1'S DIGIT (CONVERT TO ASCII)
CALL CONOUT
PRPT1:
JP PRINT ;GO PRINT PROMPT CHARACTER
;
; INPUT NEXT COMMAND TO CPR
;
; This routine determines if a SUBMIT file is being processed
; and extracts the command line from it if so or from the user's console.
; This routine also invokes the DU> prompt.
;
REDBUF:
JR NZ,CNVBUF ;PROCESS DEFAULT COMMAND IF ANY
RD0:
CALL DEFDMA ;SELECT TBUFF FOR READ
XOR A ;SELECT USER 0 FOR SUBMIT SEARCH
CALL SETUSR
LD DE,SUBDN ;OPEN $$$.SUB
SUBFLG EQU $+1 ;IN LINE SUBMIT FLAG
LD A,0 ;SUBMIT IN PROGRESS?
AND A
CALL NZ,OPEN ;CALL OPEN IF SUBMIT IN PROGRESS
JR Z,RB2 ;NONE FOUND SO GET COMMAND LINE
LD A,(SUBRC) ;GET VALUE OF LAST RECORD IN FILE
DEC A ;POINT TO NEXT TO LAST RECORD
LD (SUBCR),A ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB
CALL READ ;DE=SUBDN
JR NZ,RB1 ;ABORT $$$.SUB IF ERROR IN READING LAST REC
LD HL,SUBS2 ;POINT TO S2 OF $$$.SUB FCB
LD (HL),A ;SET S2 TO ZERO
INC HL ;POINT TO RECORD COUNT
DEC (HL) ;DECREMENT RECORD COUNT OF $$$.SUB
PUSH AF ;SAVE ZERO FLAG
CALL Z,SUBKIL ;KILL SUBMIT IF ZERO RECORDS LEFT
POP AF ;ELSE
CALL NZ,CLOSE ;JUST CLOSE FILE
CALL PROMPT ;PRINT SUBMIT PROMPT
DEFB SPRMPT+80H
LD HL,TBUFF+1 ;PRINT COMMAND LINE FROM $$$.SUB
CALL PRINTS
LD HL,TBUFF ;MOVE COMMAND LINE TO COMMAND BUFFER
LD DE,CBUFF
LD BC,BUFLEN
LDIR
CALL BREAK ;CHECK FOR ABORT (ANY CHARACTER)
JR Z,CNVBUF ;NONE
;
; INPUT COMMAND LINE FROM USER CONSOLE
;
RB1:
CALL SUBKIL ;ERASE $$$.SUB
RB2:
CALL PROMPT ;PRINT PROMPT
DEFB CPRMPT+80H
LD C,0AH ;READ COMMAND LINE FROM USER
LD DE,MBUFF
CALL BDOS
;
; CAPITALIZE STRING (ENDING IN 0) IN CBUFF AND SET POINTER FOR PARSING
;
CNVBUF:
LD HL,CBUFF ;POINT TO USER'S COMMAND BUFFER
LD A,(HL) ;ANY CHARACTERS IN BUFFER?
AND A
JR Z,RD0 ;NO, FILL BUFFER
INC HL
LD (CIBPTR),HL ;INITIALIZE COMMAND LINE POINTER
LD B,A ;INITIALIZE CHARACTER COUNTER
CB1:
LD A,(HL) ;CAPITALIZE COMMAND CHARACTER
CALL UCASE
LD (HL),A
INC HL ;POINT TO NEXT CHARACTER
DJNZ CB1 ;CONTINUE TO END OF COMMAND LINE
LD (HL),B ;STORE ENDING <NULL>
;
; ADVANCE INPUT POINTER TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK
;
ADVAN:
LD DE,(CIBPTR)
;
; SKIP STRING POINTED TO BY DE (STRING ENDS IN 0) UNTIL END OF STRING
; OR NON-BLANK ENCOUNTERED (BEGINNING OF TOKEN)
;
SBLANK:
LD A,(DE)
OR A
RET Z
CP ' '
RET NZ
INC DE
JR SBLANK
;
; CONVERT CHARACTER IN A TO UPPER CASE
;
UCASE:
CP 61H ;LOWER-CASE A
RET C
CP 7BH ;GREATER THAN LOWER-CASE Z?
RET NC
AND 5FH ;CAPITALIZE
RET
;
; CHECK TO SEE IF DE POINTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET
;
SDELM:
LD A,(DE)
OR A ;0=DELIMITER
RET Z
CP ' ' ;ERROR IF < <SP>
JP C,ERROR
RET Z ;<SP> =DELIMITER
CP '.' ;"." =DELIMITER
RET Z
CP '[' ;"[" =DELIMITER
RET Z
CP ']' ;"]" =DELIMITER
RET Z
CP '>' ;">" =DELIMITER BUT GREATER NOT
RET NC
CP ':' ;":" ";" "<" "=" =DELIMITERS
RET C ;NO DELIMITER FOUND
CP A ;SET ZERO FLAG
RET
;
; ADD A TO HL (HL=HL+A)
;
ADDAH:
ADD A,L
LD L,A
RET NC
INC H
RET
;
; EXTRACT DECIMAL NUMBER FROM COMMAND LINE
; RETURN WITH 8-BIT VALUE IN REG A AND 16-BIT VALUE IN HL
; ALL REGISTERS MAY BE AFFECTED
;
NUMBER:
CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN
LD HL,FCBFN+10 ;POINT TO END OF TOKEN FOR CONVERSION
LD B,11 ;11 CHARACTERS MAX
;
; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER
;
NUMS:
LD A,(HL) ;GET CHARACTERS FROM END, SEARCHING FOR SUFFIX
DEC HL ;BACK UP
CP NUMBASE ;CHECK AGAINST BASE SWITCH FLAG
JR Z,HNUM1
CP ' ' ;SPACE?
JR NZ,NUM1 ;CHECK FOR LAST DIGIT
DJNZ NUMS ;COUNT DOWN
;
; PROCESS DECIMAL NUMBER
;
NUM1:
LD HL,0 ;CLEAR GRAND TOTAL
LD DE,FCBFN ;POINT TO BEGINNING OF TOKEN
NUM2:
LD A,(DE) ;GET CHARACTER
CP ' ' ;DONE IF <SP>
NUM3:
LD A,L ;TOTAL TO A IN CASE DONE
RET Z ;ALL DONE
CALL A2NUM ;CONVERT DIGIT
JR NC,NUM2 ;NO ERROR
JR ERROR
;
; ASCII TO NUMERICAL CONVERSION
; RETURNS WITH CARRY SET IF INVALID OR OVERFLOW
; BASE 10 ASSUMED - MAXIMUM VALUE IS 255
;
A2NUM:
LD A,(DE) ;GET DIGIT
SUB '0' ;CONVERT TO BINARY (ASCII 0-9 TO BINARY)
CP 10 ;ERROR IF >= 10
CCF ;FLIP CARRY
RET C
LD C,A ;DIGIT IN C
LD A,L ;NEW VALUE = OLD VALUE * 10
RLCA ;*2
RET C ;ERROR
RLCA ;*4
RET C ;ERROR
ADD A,L ;*5
RET C ;ERROR
RLCA ;*10
RET C ;ERROR
ADD A,C ;NEW VALUE = OLD VALUE * 10 + DIGIT
RET C ;DON'T INC DE IF ERROR
LD L,A ;SET NEW VALUE
INC DE ;GOOD DIGIT
RET
;
; EXTRACT HEXADECIMAL NUMBER FROM COMMAND LINE
; RETURN WITH 8-BIT VALUE IN REG A AND 16-BIT VALUE IN HL
; ALL REGISTERS MAY BE AFFECTED
;
HEXNUM:
CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN
HNUM1:
LD HL,0 ;HL=ACCUMULATED VALUE
LD DE,FCBFN ;POINT TO TOKEN FOR CONVERSION
HNUM2:
LD A,(DE) ;GET CHARACTER
CP ' ' ;DONE?
JR Z,NUM3 ;RETURN IF SO
CP 'H' ;DONE IF H SUFFIX
JR Z,NUM3
SUB '0' ;CONVERT TO BINARY
CP 10 ;0-9?
JR C,HNUM3
SUB 17 ;A-F?
CP 6 ;ERROR?
JR NC,ERROR
ADD A,10
HNUM3:
INC DE ;POINT TO NEXT CHARACTER
ADD HL,HL ;LEFT SHIFT 4
ADD HL,HL
ADD HL,HL
ADD HL,HL
OR L ;MASK IN NEW LOW
LD L,A ;NEW LOW BYTE IN L
JR HNUM2
;
; GET THE REQUESTED USER NUMBER FROM THE COMMAND LINE AND VALIDATE IT.
;
USRNUM:
CALL NUMBER
LD E,A
CP MAXUSR+1
RET C
;
; INVALID COMMAND -- PRINT IT
;
ERROR:
CALL CRLF ;NEW LINE
LD HL,(CIPTR) ;POINT TO BEGINNING OF COMMAND LINE
ERR1:
LD A,(HL) ;GET CHARACTER
CP ' '+1 ;SIMPLE '?' IF <SP> OR LESS
CALL NC,CONOUT ;PRINT COMMAND CHARACTER OR FALL THRU
INC HL ;POINT TO NEXT
JR NC,ERR1 ;CONTINUE
CALL PRINT ;PRINT '?'
DC '?'
JP ABORT ;RESTART CPR
;
; POINT TO DIRECTORY ENTRY IN TBUFF WHOSE OFFSET IS SPECIFIED BY A AND C
;
DIRPTR:
LD HL,TBUFF ;POINT TO TEMP BUFFER
ADD A,C ;POINT TO 1ST BYTE OF DIR ENTRY
CALL ADDAH ;POINT TO DESIRED BYTE IN DIR ENTRY
LD A,(HL) ;GET DESIRED BYTE
RET
;
; CHECK FOR VALID USER AND LOG IN IF VALID
;
ULOGIN:
LD A,(FCBS1) ;GET USER NUMBER
ALOGIN: