forked from wwarthen/RomWBW
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzcpr.bak
2041 lines (2040 loc) · 50.3 KB
/
zcpr.bak
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
TITLE 'ZCPR Version 1.0'
;
; 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
; FURTHUR 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
;
; 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
;
;
;******** 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 JMP Table into CPR
;
; 1 Buffers
;
; 2 CPR Starting Modules
; CPR1 CPR RESTRT RSTCPR RCPRNL
; PRNNF
;
; 3 Utilities
; CRLF CONOUT CONIN LCOUT LSTOUT
; READF READ BDOSB PRINTC PRINT
; GETDRV DEFDMA DMASET RESET BDOSJP
; LOGIN OPENF OPEN GRBDOS CLOSE
; SEARF SEAR1 SEARN SUBKIL DELETE
; RESETUSR GETUSR SETUSR
;
; 4 CPR Utilities
; SETUD SETU0D UCASE REDBUF CNVBUF
; BREAK USRNUM ERROR SDELM ADVAN
; SBLANK ADDAH NUMBER NUMERR HEXNUM
; DIRPTR SLOGIN DLOGIN COMLOG SCANER
; CMDSER
;
; 5 CPR-Resident Commands and Functions
; 5A DIR DIRPR FILLQ
; 5B ERA
; 5C LIST
; 5D TYPE PAGER
; 5E SAVE
; 5F REN
; 5G USER
; 5H DFU
; 5I JUMP
; 5J GO
; 5K COM CALLPROG ERRLOG ERRJMP
; 5L GET MEMLOAD PRNLE
;
;
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:
;
; REL - TRUE if integration is to be done via MOVCPM
; - FALSE if integration is to be done via DDT and SYSGEN
;
; BASE - Base Address of user's CP/M system (normally 0 for DR version)
; This equate allows easy modification by non-standard CP/M (eg,H89)
;
; CPRLOC - Base Page Address of CPR; this value can be obtained by running
; the BDOSLOC program on your system, or by setting the
; MSIZE and BIOSEX equates to the system memory size in
; K-bytes and the "extra" memory required by your BIOS
; in K-bytes. BIOSEX is zero if your BIOS is normal size,
; and can be negative if your BIOS is in PROM or in
; non-contiguous memory.
;
; RAS - Remote-Access System; setting this equate to TRUE disables
; certain CPR commands that are considered harmful in a Remote-
; Access environment; use under Remote-Access Systems (RBBS) for
; security purposes
;
REL EQU FALSE ;SET TO TRUE FOR MOVCPM INTEGRATION
;
BASE EQU 0 ;BASE OF CP/M SYSTEM (SET FOR STANDARD CP/M)
;
IF REL
CPRLOC EQU 0 ;MOVCPM IMAGE
ELSE
;
; If REL is FALSE, the value of CPRLOC may be set in one
; of two ways. The first way is to set MSIZE and BIOSEX
; as described above using the following three lines:
;
;MSIZE EQU 56 ;SIZE OF MEM IN K-BYTES
;BIOSEX EQU 0 ;EXTRA # K-BYTES IN BIOS
;CPRLOC EQU 3400H+(MSIZE-20-BIOSEX)*1024 ;CPR ORIGIN
;
; The second way is to obtain the origin of your current
; CPR using BDSLOC or its equivalent, then merely set CPRLOC
; to that value as as in the following line:
;
CPRLOC EQU 0BD00H ;FILL IN WITH BDOSLOC SUPPLIED VALUE
;
; Note that you should only use one method or the other.
; Do NOT define CPRLOC twice!
;
; The following gives the required offset to load the CPR into the
; CP/M SYSGEN Image through DDT (the Roffset command); Note that this
; value conforms with the standard value presented in the CP/M reference
; manuals, but it may not necessarily conform with the location of the
; CPR in YOUR CP/M system; several systems (Morrow Designs, P&T, Heath
; Org-0 to name a few) have the CPR located at a non-standard address in
; the SYSGEN Image
;
;CPRR EQU 0980H-CPRLOC ;DDT LOAD OFFSET
CPRR EQU 1100H-CPRLOC ;DDT LOAD OFFSET FOR MORROW DESIGNS
ENDIF
;
RAS EQU FALSE ;SET TO TRUE IF CPR IS FOR A REMOTE-ACCESS SYSTEM
;
; The following is presented as an option, but is not generally user-customiz-
; 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
; logged-in drive, so when the user was logged into B: and he issued a SUBMIT
; command, the $$$.SUB was placed on B: and did not execute because the CCP
; looked for it 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 logged-in 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 files 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
; A:
; DIR
; can be executed, even though the currently logged-in drive is changed
; during execution. If the $$$.SUB file was present on the currently
; logged-in drive, the above series of commands would not work since the
; ZCPR would be looking for $$$.SUB on the logged-in drive, and switching
; logged-in drives without moving the $$$.SUB file as well would cause
; processing to abort.
;
SUBA equ TRUE ; Set to TRUE to have $$$.SUB always on A:
; Set to FALSE to have $$$.SUB on the logged-in drive
;
; The following flag enables extended processing for user-program supplied
; command lines. This is for Command Level 3 of ZCPR. Under the CCPZ Version
; 4.0 philosophy, 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
; Setting CLEVEL3 to TRUE enables extended processing of the third level of
; ZCPR command. All the user program need do is to store the command line and
; set the character count; ZCPR will initialize the pointers properly, store
; the ending zero properly, and capitalize the command line for processing.
; Once the command line is properly stored, the user executes the command line
; by reentering the ZCPR through CPRLOC [NOTE: The C register MUST contain
; a valid User/Disk Flag (see location 4) at this time.]
;
CLEVEL3 equ TRUE ;ENABLE COMMAND LEVEL 3 PROCESSING
;
;
;*** TERMINAL AND 'TYPE' CUSTOMIZATION EQUATES
;
NLINES EQU 24 ;NUMBER OF LINES ON CRT SCREEN
WIDE EQU TRUE ;TRUE IF WIDE DIR DISPLAY
FENCE EQU '|' ;SEP CHAR BETWEEN DIR FILES
;
PGDFLT EQU TRUE ;SET TO FALSE TO DISABLE PAGING BY DEFAULT
PGDFLG EQU 'P' ;FOR TYPE COMMAND: PAGE OR NOT (DEP ON PGDFLT)
; THIS FLAG REVERSES THE DEFAULT EFFECT
;
MAXUSR EQU 15 ;MAXIMUM USER NUMBER ACCESSABLE
;
SYSFLG EQU 'A' ;FOR DIR COMMAND: LIST $SYS AND $DIR
;
SOFLG EQU 'S' ;FOR DIR COMMAND: LIST $SYS FILES ONLY
;
SUPRES EQU TRUE ;SUPRESSES USER # REPORT FOR USER 0
;
DEFUSR EQU 0 ;DEFAULT USER NUMBER FOR COM FILES
;
SPRMPT EQU '$' ;CPR PROMPT INDICATING SUBMIT COMMAND
CPRMPT EQU '>' ;CPR PROMPT INDICATING USER COMMAND
;
NUMBASE EQU 'H' ;CHARACTER USED TO SWITCH FROM DEFAULT
; NUMBER BASE
;
SECTFLG EQU 'S' ;OPTION CHAR FOR SAVE COMMAND TO SAVE SECTORS
;
; END OF CUSTOMIZATION SECTION
;
CR EQU 0DH
LF EQU 0AH
TAB EQU 09H
;
WBOOT EQU BASE+0000H ;CP/M WARM BOOT ADDRESS
UDFLAG EQU BASE+0004H ;USER NUM IN HIGH NYBBLE, DISK IN LOW
BDOS EQU BASE+0005H ;BDOS FUNCTION CALL ENTRY PT
TFCB EQU BASE+005CH ;DEFAULT FCB BUFFER
TBUFF EQU BASE+0080H ;DEFAULT DISK I/O BUFFER
TPA EQU BASE+0100H ;BASE OF TPA
;
;
; MACROS TO PROVIDE Z80 EXTENSIONS
; MACROS INCLUDE:
;
$-MACRO ;FIRST TURN OFF THE EXPANSIONS
;
; JR - JUMP RELATIVE
; JRC - JUMP RELATIVE IF CARRY
; JRNC - JUMP RELATIVE IF NO CARRY
; JRZ - JUMP RELATIVE IF ZERO
; JRNZ - JUMP RELATIVE IF NO ZERO
; DJNZ - DECREMENT B AND JUMP RELATIVE IF NO ZERO
; LDIR - MOV @HL TO @DE FOR COUNT IN BC
; LXXD - LOAD DOUBLE REG DIRECT
; SXXD - STORE DOUBLE REG DIRECT
;
;
;
; @GENDD MACRO USED FOR CHECKING AND GENERATING
; 8-BIT JUMP RELATIVE DISPLACEMENTS
;
@GENDD MACRO ?DD ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS
IF (?DD GT 7FH) AND (?DD LT 0FF80H)
DB 100H ;Displacement Range Error on Jump Relative
ELSE
DB ?DD
ENDIF
ENDM
;
;
; Z80 MACRO EXTENSIONS
;
JR MACRO ?N ;;JUMP RELATIVE
DB 18H
@GENDD ?N-$-1
ENDM
;
JRC MACRO ?N ;;JUMP RELATIVE ON CARRY
DB 38H
@GENDD ?N-$-1
ENDM
;
JRNC MACRO ?N ;;JUMP RELATIVE ON NO CARRY
DB 30H
@GENDD ?N-$-1
ENDM
;
JRZ MACRO ?N ;;JUMP RELATIVE ON ZERO
DB 28H
@GENDD ?N-$-1
ENDM
;
JRNZ MACRO ?N ;;JUMP RELATIVE ON NO ZERO
DB 20H
@GENDD ?N-$-1
ENDM
;
DJNZ MACRO ?N ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
DB 10H
@GENDD ?N-$-1
ENDM
;
LDIR MACRO ;;LDIR
DB 0EDH,0B0H
ENDM
;
LDED MACRO ?N ;;LOAD DE DIRECT
DB 0EDH,05BH
DW ?N
ENDM
;
LBCD MACRO ?N ;;LOAD BC DIRECT
DB 0EDH,4BH
DW ?N
ENDM
;
SDED MACRO ?N ;;STORE DE DIRECT
DB 0EDH,53H
DW ?N
ENDM
;
SBCD MACRO ?N ;;STORE BC DIRECT
DB 0EDH,43H
DW ?N
ENDM
;
; END OF Z80 MACRO EXTENSIONS
;
;
;**** Section 0 ****
;
ORG CPRLOC
;
; ENTRY POINTS INTO ZCPR
; If the ZCPR is entered at location CPRLOC (at the JMP to CPR), then
; the default command in CIBUFF will be processed. If the ZCPR is entered
; at location CPRLOC+3 (at the JMP 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 nybble contains the User Number and the least significant
; nybble 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
; the pointer after the reserved space for the command buffer to point to
; the first byte of the command buffer. Under Version 4.x of ZCPR, this is
; no longer the case. The CIBPTR (Command Input Buffer PoinTeR) is located
; to be compatable with such programs (provided they determine the buffer
; length from the byte at MBUFF [CPRLOC + 6]), but under Version 4.x of ZCPR
; this is no longer necessary. ZCPR Version 4.x automatically initializes
; this buffer pointer in all cases.
;
ENTRY:
JMP CPR ; Process potential default command
JMP 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 command line is terminated by the last character (NOT Carriage
; Return), and a character count of all characters in the command line
; up to and including the last character is placed into location CBUFF
; (immediately before the command line at CIBUFF). The placed command line
; is then parsed, interpreted, and the indicated command is executed.
; If CLEVEL3 is permitted, a terminating zero is placed after the command
; (otherwise the user program has to place this zero) and the CIBPTR is
; properly initialized (otherwise the user program has to init this ptr).
; If the command is placed by a user program, entering at CPRLOC is enough
; to have the command processed. Again, under CCPZ Version 4.0, it is not
; necessary to store the pointer to CIBUFF in CIBPTR; ZCPR will do this for
; the calling program if CLEVEL3 is made TRUE.
; 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 MBUFF (CPRLOC + 6).
;
BUFLEN EQU 80 ;MAXIMUM BUFFER LENGTH
MBUFF:
DB BUFLEN ;MAXIMUM BUFFER LENGTH
CBUFF:
DB 0 ;NUMBER OF VALID CHARS IN COMMAND LINE
CIBUFF:
DB ' ' ;DEFAULT (COLD BOOT) COMMAND
CIBUF:
DB 0 ;COMMAND STRING TERMINATOR
DS BUFLEN-($-CIBUFF)+1 ;TOTAL IS 'BUFLEN' BYTES
;
CIBPTR:
DW CIBUFF ;POINTER TO COMMAND INPUT BUFFER
CIPTR:
DW CIBUF ;CURRENT POINTER
;
DS 26 ;STACK AREA
STACK EQU $ ;TOP OF STACK
;
; FILE TYPE FOR COMMAND
;
COMMSG:
DB 'COM'
;
; SUBMIT FILE CONTROL BLOCK
;
SUBFCB:
IF SUBA ;IF $$$.SUB ON A:
DB 1 ;DISK NAME SET TO DEFAULT TO DRIVE A:
ENDIF
;
IF NOT SUBA ;IF $$$.SUB ON CURRENT DRIVE
DB 0 ;DISK NAME SET TO DEFAULT TO CURRENT DRIVE
ENDIF
;
DB '$$$' ;FILE NAME
DB ' '
DB 'SUB' ;FILE TYPE
DB 0 ;EXTENT NUMBER
DB 0 ;S1
SUBFS2:
DS 1 ;S2
SUBFRC:
DS 1 ;RECORD COUNT
DS 16 ;DISK GROUP MAP
SUBFCR:
DS 1 ;CURRENT RECORD NUMBER
;
; COMMAND FILE CONTROL BLOCK
;
FCBDN:
DS 1 ;DISK NAME
FCBFN:
DS 8 ;FILE NAME
FCBFT:
DS 3 ;FILE TYPE
DS 1 ;EXTENT NUMBER
DS 2 ;S1 AND S2
DS 1 ;RECORD COUNT
FCBDM:
DS 16 ;DISK GROUP MAP
FCBCR:
DS 1 ;CURRENT RECORD NUMBER
;
; OTHER BUFFERS
;
PAGCNT:
DB NLINES-2 ;LINES LEFT ON PAGE
CHRCNT:
DB 0 ;CHAR COUNT FOR TYPE
QMCNT:
DB 0 ;QUESTION MARK COUNT FOR FCB TOKEN SCANNER
;
; CPR BUILT-IN COMMAND TABLE
;
NCHARS EQU 4 ;NUMBER OF CHARS/COMMAND
;
; CPR COMMAND NAME TABLE
; EACH TABLE ENTRY IS COMPOSED OF THE 4-BYTE COMMAND AND 2-BYTE ADDRESS
;
CMDTBL:
DB 'DIR '
DW DIR
DB 'LIST'
DW LIST
DB 'TYPE'
DW TYPE
DB 'USER'
DW USER
DB 'DFU '
DW DFU
;
IF NOT RAS ;FOR NON-RAS
DB 'GO '
DW GO
DB 'ERA '
DW ERA
DB 'SAVE'
DW SAVE
DB 'REN '
DW REN
DB 'GET '
DW GET
DB 'JUMP'
DW JUMP
ENDIF
;
NCMNDS EQU ($-CMDTBL)/(NCHARS+2)
;
;
;**** Section 2 ****
; CPR STARTING POINTS
;
; START CPR AND DON'T PROCESS DEFAULT COMMAND STORED
;
CPR1:
XRA A ;SET NO DEFAULT COMMAND
STA CBUFF
;
; START CPR AND POSSIBLY PROCESS DEFAULT COMMAND
;
; NOTE ON MODIFICATION BY RGF: BDOS RETURNS 0FFH IN
; ACCUMULATOR WHENEVER IT LOGS IN A DIRECTORY, IF ANY
; FILE NAME CONTAINS A '$' IN IT. THIS IS NOW USED AS
; A CLUE TO DETERMINE WHETHER OR NOT TO DO A SEARCH
; FOR SUBMIT FILE, IN ORDER TO ELIMINATE WASTEFUL SEARCHES.
;
CPR:
LXI SP,STACK ;RESET STACK
PUSH B
MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4)
RAR ;EXTRACT USER NUMBER
RAR
RAR
RAR
ANI 0FH
MOV E,A ;SET USER NUMBER
CALL SETUSR
CALL RESET ;RESET DISK SYSTEM
STA RNGSUB ;SAVE SUBMIT CLUE FROM DRIVE A:
POP B
MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4)
ANI 0FH ;EXTRACT DEFAULT DISK DRIVE
STA TDRIVE ;SET IT
JRZ NOLOG ;SKIP IF 0...ALREADY LOGGED
CALL LOGIN ;LOG IN DEFAULT DISK
;
IF NOT SUBA ;IF $$$.SUB IS ON CURRENT DRIVE
STA RNGSUB ;BDOS '$' CLUE
ENDIF
;
NOLOG:
LXI D,SUBFCB ;CHECK FOR $$$.SUB ON CURRENT DISK
RNGSUB EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE RNGSUB FLAG
ORA A ;SET FLAGS ON CLUE
CMA ;PREPARE FOR COMING 'CMA'
CNZ SEAR1
CMA ;0FFH IS RETURNED IF NO $$$.SUB, SO COMPLEMENT
STA RNGSUB ;SET FLAG (0=NO $$$.SUB)
LDA CBUFF ;EXECUTE DEFAULT COMMAND?
ORA A ;0=NO
JRNZ RS1
;
; PROMPT USER AND INPUT COMMAND LINE FROM HIM
;
RESTRT:
LXI SP,STACK ;RESET STACK
;
; PRINT PROMPT (DU>)
;
CALL CRLF ;PRINT PROMPT
CALL GETDRV ;CURRENT DRIVE IS PART OF PROMPT
ADI 'A' ;CONVERT TO ASCII A-P
CALL CONOUT
CALL GETUSR ;GET USER NUMBER
;
IF SUPRES ;IF SUPPRESSING USR # REPORT FOR USR 0
ORA A
JRZ RS000
ENDIF
;
CPI 10 ;USER < 10?
JRC RS00
SUI 10 ;SUBTRACT 10 FROM IT
PUSH PSW ;SAVE IT
MVI A,'1' ;OUTPUT 10'S DIGIT
CALL CONOUT
POP PSW
RS00:
ADI '0' ;OUTPUT 1'S DIGIT (CONVERT TO ASCII)
CALL CONOUT
;
; READ INPUT LINE FROM USER OR $$$.SUB
;
RS000:
CALL REDBUF ;INPUT COMMAND LINE FROM USER (OR $$$.SUB)
;
; PROCESS INPUT LINE
;
RS1:
;
IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED
CALL CNVBUF ;CAPITALIZE COMMAND LINE, PLACE ENDING 0,
; AND SET CIBPTR VALUE
ENDIF
;
CALL DEFDMA ;SET TBUFF TO DMA ADDRESS
CALL GETDRV ;GET DEFAULT DRIVE NUMBER
STA TDRIVE ;SET IT
CALL SCANER ;PARSE COMMAND NAME FROM COMMAND LINE
CNZ ERROR ;ERROR IF COMMAND NAME CONTAINS A '?'
LXI D,RSTCPR ;PUT RETURN ADDRESS OF COMMAND
PUSH D ;ON THE STACK
LDA TEMPDR ;IS COMMAND OF FORM 'D:COMMAND'?
ORA A ;NZ=YES
JNZ COM ; IMMEDIATELY
CALL CMDSER ;SCAN FOR CPR-RESIDENT COMMAND
JNZ COM ;NOT CPR-RESIDENT
MOV A,M ;FOUND IT: GET LOW-ORDER PART
INX H ;GET HIGH-ORDER PART
MOV H,M ;STORE HIGH
MOV L,A ;STORE LOW
PCHL ;EXECUTE CPR ROUTINE
;
; ENTRY POINT FOR RESTARTING CPR AND LOGGING IN DEFAULT DRIVE
;
RSTCPR:
CALL DLOGIN ;LOG IN DEFAULT DRIVE
;
; ENTRY POINT FOR RESTARTING CPR WITHOUT LOGGING IN DEFAULT DRIVE
;
RCPRNL:
CALL SCANER ;EXTRACT NEXT TOKEN FROM COMMAND LINE
LDA FCBFN ;GET FIRST CHAR OF TOKEN
SUI ' ' ;ANY CHAR?
LXI H,TEMPDR
ORA M
JNZ ERROR
JR RESTRT
;
; No File Error Message
;
PRNNF:
CALL PRINTC ;NO FILE MESSAGE
DB 'No Fil','e'+80H
RET
;
;**** Section 3 ****
; I/O UTILITIES
;
; OUTPUT CHAR IN REG A TO CONSOLE AND DON'T CHANGE BC
;
;
; OUTPUT <CRLF>
;
CRLF:
MVI A,CR
CALL CONOUT
MVI A,LF ;FALL THRU TO CONOUT
;
CONOUT:
PUSH B
MVI C,02H
OUTPUT:
MOV E,A
PUSH H
CALL BDOS
POP H
POP B
RET
;
CONIN:
MVI C,01H ;GET CHAR FROM CON: WITH ECHO
CALL BDOSB
JMP UCASE ;CAPITALIZE
;
LCOUT:
PUSH PSW ;OUTPUT CHAR TO CON: OR LST: DEP ON PRFLG
PRFLG EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE PRINT FLAG
ORA A ;0=TYPE
JRZ LC1
POP PSW ;GET CHAR
;
; OUTPUT CHAR IN REG A TO LIST DEVICE
;
LSTOUT:
PUSH B
MVI C,05H
JR OUTPUT
LC1:
POP PSW ;GET CHAR
PUSH PSW
CALL CONOUT ;OUTPUT TO CON:
POP PSW
CPI LF ;CHECK FOR PAGING
JZ PAGER
RET
;
READF:
LXI D,FCBDN ;FALL THRU TO READ
READ:
MVI C,14H ;FALL THRU TO BDOSB
;
; CALL BDOS AND SAVE BC
;
BDOSB:
PUSH B
CALL BDOS
POP B
ORA A
RET
;
; PRINT STRING (ENDING IN 0) PTED TO BY RET ADR;START WITH <CRLF>
;
PRINTC:
PUSH PSW ;SAVE FLAGS
CALL CRLF ;NEW LINE
POP PSW
;
PRINT:
XTHL ;GET PTR TO STRING
PUSH PSW ;SAVE FLAGS
CALL PRIN1 ;PRINT STRING
POP PSW ;GET FLAGS
XTHL ;RESTORE HL AND RET ADR
RET
;
; PRINT STRING (ENDING IN 0) PTED TO BY HL
;
PRIN1:
MOV A,M ;GET NEXT BYTE
CALL CONOUT ;PRINT CHAR
MOV A,M ;GET NEXT BYTE AGAIN FOR TEST
INX H ;PT TO NEXT BYTE
ORA A ;SET FLAGS
RZ ;DONE IF ZERO
RM ;DONE IF MSB SET
JR PRIN1
;
; BDOS FUNCTION ROUTINES
;
;
; RETURN NUMBER OF CURRENT DISK IN A
;
GETDRV:
MVI C,19H
JR BDOSJP
;
; SET 80H AS DMA ADDRESS
;
DEFDMA:
LXI D,TBUFF ;80H=TBUFF
DMASET:
MVI C,1AH
JR BDOSJP
;
RESET:
MVI C,0DH
BDOSJP:
JMP BDOS
;
LOGIN:
MOV E,A
MVI C,0EH
JR BDOSJP ;SAVE SOME CODE SPACE
;
OPENF:
XRA A
STA FCBCR
LXI D,FCBDN ;FALL THRU TO OPEN
;
OPEN:
MVI C,0FH ;FALL THRU TO GRBDOS
;
GRBDOS:
CALL BDOS
INR A ;SET ZERO FLAG FOR ERROR RETURN
RET
;
CLOSE:
MVI C,10H
JR GRBDOS
;
SEARF:
LXI D,FCBDN ;SPECIFY FCB
SEAR1:
MVI C,11H
JR GRBDOS
;
SEARN:
MVI C,12H
JR GRBDOS
;
; CHECK FOR SUBMIT FILE IN EXECUTION AND ABORT IT IF SO
;
SUBKIL:
LXI H,RNGSUB ;CHECK FOR SUBMIT FILE IN EXECUTION
MOV A,M
ORA A ;0=NO
RZ
MVI M,0 ;ABORT SUBMIT FILE
LXI D,SUBFCB ;DELETE $$$.SUB
;
DELETE:
MVI C,13H
JR BDOSJP ;SAVE MORE SPACE
;
; RESET USER NUMBER IF CHANGED
;
RESETUSR:
TMPUSR EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TMPUSR
MOV E,A ;PLACE IN E
JR SETUSR ;THEN GO SET USER
GETUSR:
MVI E,0FFH ;GET CURRENT USER NUMBER
SETUSR:
MVI C,20H ;SET USER NUMBER TO VALUE IN E (GET IF E=FFH)
JR BDOSJP ;MORE SPACE SAVING
;
; END OF BDOS FUNCTIONS
;
;
;**** Section 4 ****
; CPR UTILITIES
;
; SET USER/DISK FLAG TO CURRENT USER AND DEFAULT DISK
;
SETUD:
CALL GETUSR ;GET NUMBER OF CURRENT USER
ADD A ;PLACE IT IN HIGH NYBBLE
ADD A
ADD A
ADD A
LXI H,TDRIVE ;MASK IN DEFAULT DRIVE NUMBER (LOW NYBBLE)
ORA M ;MASK IN
STA UDFLAG ;SET USER/DISK NUMBER
RET
;
; SET USER/DISK FLAG TO USER 0 AND DEFAULT DISK
;
SETU0D:
TDRIVE EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TDRIVE
STA UDFLAG ;SET USER/DISK NUMBER
RET
;
; CONVERT CHAR IN A TO UPPER CASE
;
UCASE:
CPI 61H ;LOWER-CASE A
RC
CPI 7BH ;GREATER THAN LOWER-CASE Z?
RNC
ANI 5FH ;CAPITALIZE
RET
;
; 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
;
REDBUF:
LDA RNGSUB ;SUBMIT FILE CURRENTLY IN EXECUTION?
ORA A ;0=NO
JRZ RB1 ;GET LINE FROM CONSOLE IF NOT
LXI D,SUBFCB ;OPEN $$$.SUB
PUSH D ;SAVE DE
CALL OPEN
POP D ;RESTORE DE
JRZ RB1 ;ERASE $$$.SUB IF END OF FILE AND GET CMND
LDA SUBFRC ;GET VALUE OF LAST RECORD IN FILE
DCR A ;PT TO NEXT TO LAST RECORD
STA SUBFCR ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB
CALL READ ;DE=SUBFCB
JRNZ RB1 ;ABORT $$$.SUB IF ERROR IN READING LAST REC
LXI D,CBUFF ;COPY LAST RECORD (NEXT SUBMIT CMND) TO CBUFF
LXI H,TBUFF ; FROM TBUFF
LXI B,BUFLEN ;NUMBER OF BYTES
LDIR
LXI H,SUBFS2 ;PT TO S2 OF $$$.SUB FCB
MVI M,0 ;SET S2 TO ZERO
INX H ;PT TO RECORD COUNT
DCR M ;DECREMENT RECORD COUNT OF $$$.SUB
LXI D,SUBFCB ;CLOSE $$$.SUB
CALL CLOSE
JRZ RB1 ;ABORT $$$.SUB IF ERROR
MVI A,SPRMPT ;PRINT SUBMIT PROMPT
CALL CONOUT
LXI H,CIBUFF ;PRINT COMMAND LINE FROM $$$.SUB
CALL PRIN1
CALL BREAK ;CHECK FOR ABORT (ANY CHAR)
;
IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED
RZ ;IF <NULL> (NO ABORT), RETURN TO CALLER AND RUN
ENDIF
;
IF NOT CLEVEL3 ;IF THIRD COMMAND LEVEL IS NOT PERMITTED
JRZ CNVBUF ;IF <NULL> (NO ABORT), CAPITALIZE COMMAND
ENDIF
;
CALL SUBKIL ;KILL $$$.SUB IF ABORT
JMP RESTRT ;RESTART CPR
;
; INPUT COMMAND LINE FROM USER CONSOLE
;
RB1:
CALL SUBKIL ;ERASE $$$.SUB IF PRESENT
CALL SETUD ;SET USER AND DISK
MVI A,CPRMPT ;PRINT PROMPT
CALL CONOUT
MVI C,0AH ;READ COMMAND LINE FROM USER
LXI D,MBUFF
CALL BDOS
;
IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED
JMP SETU0D ;SET CURRENT DISK NUMBER IN LOWER PARAMS
ENDIF
;
IF NOT CLEVEL3 ;IF THIRD COMMAND LEVEL IS NOT PERMITTED
CALL SETU0D ;SET CURRENT DISK NUMBER IF LOWER PARAMS
; AND FALL THRU TO CNVBUF
ENDIF
;
; CAPITALIZE STRING (ENDING IN 0) IN CBUFF AND SET PTR FOR PARSING
;
CNVBUF:
LXI H,CBUFF ;PT TO USER'S COMMAND
MOV B,M ;CHAR COUNT IN B
INR B ;ADD 1 IN CASE OF ZERO
CB1:
INX H ;PT TO 1ST VALID CHAR
MOV A,M ;CAPITALIZE COMMAND CHAR
CALL UCASE
MOV M,A
DJNZ CB1 ;CONTINUE TO END OF COMMAND LINE
CB2:
MVI M,0 ;STORE ENDING <NULL>
LXI H,CIBUFF ;SET COMMAND LINE PTR TO 1ST CHAR
SHLD CIBPTR
RET
;
; CHECK FOR ANY CHAR FROM USER CONSOLE;RET W/ZERO SET IF NONE
;
BREAK:
PUSH D ;SAVE DE
MVI C,11 ;CSTS CHECK
CALL BDOSB
CNZ CONIN ;GET INPUT CHAR
BRKBK:
POP D
RET
;
; GET THE REQUESTED USER NUMBER FROM THE COMMAND LINE AND VALIDATE IT.
;
USRNUM:
CALL NUMBER
CPI MAXUSR+1
RC
;
; INVALID COMMAND -- PRINT IT
;
ERROR:
CALL CRLF ;NEW LINE
LHLD CIPTR ;PT TO BEGINNING OF COMMAND LINE
ERR2:
MOV A,M ;GET CHAR
CPI ' '+1 ;SIMPLE '?' IF <SP> OR LESS
JRC ERR1
PUSH H ;SAVE PTR TO ERROR COMMAND CHAR
CALL CONOUT ;PRINT COMMAND CHAR
POP H ;GET PTR
INX H ;PT TO NEXT
JR ERR2 ;CONTINUE
ERR1:
CALL PRINT ;PRINT '?'
DB '?'+80H
CALL SUBKIL ;TERMINATE ACTIVE $$$.SUB IF ANY
JMP RESTRT ;RESTART CPR
;
; CHECK TO SEE IF DE PTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET
;
SDELM:
LDAX D
ORA A ;0=DELIMITER
RZ
CPI ' ' ;ERROR IF < <SP>
JRC ERROR
RZ ;<SP>=DELIMITER
CPI '=' ;'='=DELIMITER
RZ
CPI 5FH ;UNDERSCORE=DELIMITER
RZ
CPI '.' ;'.'=DELIMITER
RZ
CPI ':' ;':'=DELIMITER
RZ
CPI ';' ;';'=DELIMITER
RZ
CPI '<' ;'<'=DELIMITER
RZ
CPI '>' ;'>'=DELIMITER
RET
;
; ADVANCE INPUT PTR TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK
;
ADVAN:
LDED CIBPTR
;
; SKIP STRING PTED TO BY DE (STRING ENDS IN 0) UNTIL END OF STRING
; OR NON-BLANK ENCOUNTERED (BEGINNING OF TOKEN)