mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4446 lines
82 KiB
4446 lines
82 KiB
; 03/01/85 Richard Conn: Replaced fixed in EDPLOT that was somehow lost
|
|
; (see lines suffixed by <RLC-3/1/85>
|
|
;
|
|
; 01/18/85 Modified by Jay Sage to incorporate a set of permanent
|
|
; macros. These macros can be invoked by the command tail
|
|
; when DU is invoked. They are copied from a space of 128
|
|
; bytes near the beginning of the code. The area is
|
|
; identified by a string of text to facilitate patching.
|
|
; The macros are listed one after another, separated by
|
|
; carriage return characters. Macros that are not to be
|
|
; defined must be present as carriage returns alone or the
|
|
; program will fail.
|
|
;
|
|
; PROGRAM: DU3
|
|
; AUTHOR: RICHARD CONN
|
|
; DERIVATION: DUTIL is derived from DU Version 7.5
|
|
; DU2 is derived from DUTIL Version 1.1
|
|
; DU3 is derived from DU2 Version 1.1
|
|
; VERSION: 1.0
|
|
; DATE: 20 June 84
|
|
; PREVIOUS VERSIONS: None
|
|
; NOTE: DU3 must be assembled using M80 (or equiv)
|
|
;
|
|
VERS EQU 13
|
|
Z3ENV EQU 0F400H
|
|
|
|
;
|
|
; DU3 is derived from --
|
|
; DU.ASM V7.5 Revised 1/23/81
|
|
; DISK UTILITY - By Ward Christensen
|
|
;
|
|
; Principal Authors of DU V7.5 are --
|
|
; WLC KBP RGF BRR
|
|
;
|
|
; Key comments from DU V7.5 and DU3 follow --
|
|
;
|
|
;This version of DU is compatible with CP/M 2.x
|
|
;and does not require alteration for various hardware
|
|
;configurations. It adjusts itself automatically to
|
|
;the correct number of sectors, tracks, directory size,
|
|
;etc. It has been tested on 5-1/4" and 8" floppy, and
|
|
;10 megabyte hard disk systems.
|
|
;
|
|
;Because of the automatic adaption feature, no conditional
|
|
;assembly options are included.
|
|
;
|
|
;*************************************************
|
|
;* *
|
|
;* This program has been heavily modified *
|
|
;* to allow it to work without modification *
|
|
;* on all versions of CP/M 2.x. *
|
|
;* One known possible problem involves the *
|
|
;* system tracks on some systems, and results *
|
|
;* from the system sectors being skewed. There *
|
|
;* is NO way for a program executing under CP/M *
|
|
;* to know about this. This program assumes the *
|
|
;* standard convention of no skew being used on *
|
|
;: the system tracks. This usually isn't a prob- *
|
|
;* lem because the SYSGEN program can be used to *
|
|
;* get the system from the disk so that it can *
|
|
;* be modified. *
|
|
;* *
|
|
;* Ron Fowler *
|
|
;* *
|
|
;*************************************************
|
|
;
|
|
|
|
;
|
|
; SYSLIB and Z3LIB References
|
|
;
|
|
ext z3vinit,envptr,cls,at,tinit,dinit,stndout,stndend,gotoxy
|
|
ext getspeed,getcrt,getmdisk,getmuser
|
|
ext codend
|
|
|
|
;
|
|
;System equates
|
|
;
|
|
BASE EQU 0 ;SET TO 4200H FOR HEATH OR TRS-80 ALTCPM
|
|
;
|
|
;CP/M Key Areas
|
|
;
|
|
FCB EQU BASE+5CH ;CP/M FCB
|
|
BDOS EQU BASE+5 ;CP/M BDOS ENTRY POINT
|
|
TBUFF EQU BASE+80H ;CP/M TEMPORARY DISK I/O BUFFER
|
|
TPA EQU BASE+100H ;CP/M TRANSCIENT PROGRAM AREA
|
|
;
|
|
; Some Key Variables in DU3
|
|
;
|
|
EOLCH equ ',' ;Marks logical end of line
|
|
SEPCH equ ' ' ;Argument Separator
|
|
MULCH equ '*' ;Multiplication Command
|
|
DIM equ 1 ;Enter DIM Mode for ILPRT
|
|
BRIGHT equ 2 ;Enter BRIGHT Mode for ILPRT
|
|
|
|
;
|
|
;CP/M BDOS Function Codes
|
|
;
|
|
PRINT EQU 9
|
|
GVERS EQU 12
|
|
RESETDK EQU 13 ;RESET SYSTEM
|
|
SELDK EQU 14 ;SELECT DISK
|
|
CLOSEF EQU 16 ;CLOSE FILE
|
|
SRCHF EQU 17 ;SEARCH FIRST
|
|
SRCHN EQU 18 ;SEARCH NEXT
|
|
DELF EQU 19 ;DELETE FILE
|
|
WRITEF EQU 21 ;WRITE BLOCK TO FILE
|
|
MAKEF EQU 22 ;CREATE FILE
|
|
SUSER EQU 32 ;SELECT USER
|
|
GETDSK EQU 25
|
|
GETDPB EQU 31
|
|
;
|
|
;CP/M 1.4 Offsets and Some Key Values
|
|
;
|
|
TRNOFF EQU 15 ;CP/M 1.4 OFFSET FROM BASE
|
|
;OF BDOS TO SECTRAN ROUTINE
|
|
SKWOFF EQU 1AH ;CP/M 1.4 OFFSET TO SKEW TABLE
|
|
S2OFF EQU 14 ;OFFSET INTO FCB FOR S2 BYTE
|
|
DPBOFF EQU 3AH ;CP/M 1.4 OFFSET TO DPB WITHIN BDOS
|
|
S2MASK EQU 0FH ;MASK FOR EXTENDED RC BITS OF S2
|
|
DPBLEN EQU 15 ;SIZE OF CP/M 2.x DISK PARM BLOCK
|
|
;
|
|
;Define ASCII characters
|
|
;
|
|
CR EQU 0DH ;CARRIAGE RETURN
|
|
LF EQU 0AH ;LINE FEED
|
|
TAB EQU 09H ;TAB
|
|
BS EQU 08H ;BACKSPACE
|
|
|
|
;
|
|
; MACROS INCLUDE:
|
|
;
|
|
; DJNZ - DECREMENT B AND JUMP RELATIVE IF NO ZERO
|
|
;
|
|
DJNZ MACRO ?N ;;DECREMENT B AND JUMP ON NO ZERO
|
|
DCR B
|
|
JNZ ?N
|
|
ENDM
|
|
;
|
|
; END OF MACROS
|
|
;
|
|
|
|
|
|
;
|
|
;Beginning of Program
|
|
;
|
|
;
|
|
; Environment Definition
|
|
;
|
|
if z3env ne 0
|
|
;
|
|
; External ZCPR3 Environment Descriptor
|
|
;
|
|
jmp start
|
|
db 'Z3ENV' ;This is a ZCPR3 Utility
|
|
db 1 ;External Environment Descriptor
|
|
z3eadr:
|
|
dw z3env
|
|
|
|
;
|
|
; Space Added for Initial Macro Definitions -- block added by <JPS>
|
|
;
|
|
;label to help locate when patching
|
|
|
|
db 'INITIAL MACROS:'
|
|
|
|
imac0: db 'G0,D',cr ;macro 0
|
|
db '-D',cr ;macro 1
|
|
db '+D',cr ;macro 2
|
|
db cr ;macro 3
|
|
db cr ;macro 4
|
|
db cr ;macro 5
|
|
db cr ;macro 6
|
|
db cr ;macro 7
|
|
db cr ;macro 8
|
|
db cr ;macro 9
|
|
|
|
;fill rest of 128 bytes with nulls
|
|
|
|
if imac0 + 128 - $ gt 0
|
|
rept imac0 + 128 - $
|
|
db 0
|
|
endm
|
|
endif
|
|
|
|
; End of Block Added by <JPS>
|
|
|
|
start:
|
|
lhld z3eadr ;pt to ZCPR3 environment
|
|
;
|
|
else
|
|
;
|
|
; Internal ZCPR3 Environment Descriptor
|
|
;
|
|
MACLIB Z3BASE.LIB
|
|
MACLIB SYSENV.LIB
|
|
z3eadr:
|
|
jmp start
|
|
SYSENV
|
|
start:
|
|
lxi h,z3eadr ;pt to ZCPR3 environment
|
|
endif
|
|
|
|
;
|
|
; Start of Program -- Initialize ZCPR3 Environment
|
|
;
|
|
call z3vinit ;initialize the ZCPR3 Env and the VLIB Env
|
|
call tinit ;init terminal
|
|
LXI H,0 ;GET PTR TO CP/M STACK
|
|
DAD SP ;HL=SP
|
|
SHLD DUTSTK ;SAVE IT
|
|
;
|
|
call codend ;get free space
|
|
lxi d,100h ;open area
|
|
dad d ;large stack area
|
|
shld savbuf
|
|
dad d ;100H for SAVBUF
|
|
push h ;save ptr
|
|
mvi m,126 ;allow 126-char input line
|
|
inx h
|
|
inx h ;ptr to INBUF
|
|
shld inbuf
|
|
pop h ;pt to beginning
|
|
lxi d,400h ;large area for expansion
|
|
dad d
|
|
shld pinbuf ;ptr to PINBUF
|
|
dad d
|
|
shld ctemp ;ptr to CTEMP
|
|
dad d
|
|
shld ctempx ;ptr to CTEMPX
|
|
shld mtabl ;ptr to MACRO TABLE
|
|
lxi d,100h*10 ;10 macros
|
|
dad d
|
|
shld gbuff ;group save buffer
|
|
shld direct ;directory load buffer
|
|
;
|
|
lhld savbuf ;top of stack
|
|
sphl ; SET STACK
|
|
;
|
|
call getspeed
|
|
sta clock ;set clock speed
|
|
call getcrt ;get CRT data
|
|
inx h ;pt to screen size
|
|
mov a,m ;get it
|
|
sta pagsiz ;set page size
|
|
call getmdisk ;get max disk
|
|
sta mdisk ;and set it
|
|
call getmuser ;get max user
|
|
sta muser ;and set it
|
|
;
|
|
;Set up local jumps to BIOS
|
|
;
|
|
START1:
|
|
LHLD BASE+1 ;WARM BOOT POINTER
|
|
LXI D,3 ;READY FOR ADD
|
|
DAD D
|
|
SHLD VCONST+1 ;CON: Status
|
|
DAD D
|
|
SHLD VCONIN+1 ;CON: Input
|
|
DAD D
|
|
SHLD VCONOT+1 ;CON: Output
|
|
DAD D
|
|
SHLD VLIST+1 ;LST: Output
|
|
DAD D ;Skip PUNCH
|
|
DAD D ;Skip RDR
|
|
DAD D
|
|
SHLD VHOME+1 ;Home Disk
|
|
DAD D
|
|
SHLD VSELDK+1 ;Select Disk
|
|
DAD D
|
|
SHLD VSETRK+1 ;Set Track
|
|
DAD D
|
|
SHLD VSTSEC+1 ;Set Sector
|
|
DAD D
|
|
SHLD SETDMA+1 ;Set DMA Address
|
|
DAD D
|
|
SHLD VREAD+1 ;Read Block From Disk
|
|
DAD D
|
|
SHLD VWRITE+1 ;Write Block To Disk
|
|
DAD D ;Skip LISTST
|
|
DAD D
|
|
SHLD VSCTRN+1 ;CP/M 2.x Sector Translation Table
|
|
; JMP HELLO
|
|
;
|
|
;Initialization Complete -- Print Signon Message and Begin Command Processing
|
|
;
|
|
HELLO:
|
|
CALL GETSTP ;SET UP CP/M PARAMETERS
|
|
CALL INITP ;INITIALIZE BUFFER PARAMETERS
|
|
CALL ILPRT
|
|
DB 'DU3 - Disk Utility III, Version '
|
|
DB VERS/10+'0','.',(VERS MOD 10)+'0'
|
|
DB CR,LF,CR,LF
|
|
DB DIM,'Type ? for Help',BRIGHT
|
|
DB CR,LF,0
|
|
;
|
|
;Clear Editor Reference
|
|
;
|
|
XRA A
|
|
STA EDRUN ;EDITOR NOT RUNNING
|
|
;
|
|
;Save initial command line in INBUF
|
|
;
|
|
LXI H,TBUFF ;PT TO COMMAND LINE BUFFER
|
|
MOV A,M ;GET CHAR COUNTER
|
|
ora a ;check for no tail <JPS>
|
|
jnz ctail ;if not, no need to increment <JPS>
|
|
inr a ;allow for blank otherwise present <JPS>
|
|
ctail: ; <JPS>
|
|
INX H ;PT TO FIRST CHAR
|
|
ADD L ;COMPUTE LOCATION OF AFTER LAST CHAR
|
|
MOV L,A
|
|
MOV A,H
|
|
ACI 0
|
|
MOV H,A
|
|
MVI M,CR ;SET ENDING CR
|
|
LHLD INBUF ;PT TO BUFFER
|
|
XCHG ;... IN DE
|
|
LXI H,TBUFF+2 ;PT TO INPUT LINE (1 changed to 2 <JPS>)
|
|
MVI B,128 ;COPY BUFFER
|
|
CALL MOVE
|
|
;
|
|
;Establish Initial Position
|
|
;
|
|
LXI D,0 ;GROUP 0
|
|
CALL DEGROUP ;POSITION TO GROUP
|
|
CALL INQSUB ;PRINT POSITION
|
|
;
|
|
;Check for initial command
|
|
;
|
|
LHLD INBUF ;INPUT BUFFER
|
|
MOV A,M
|
|
CPI CR
|
|
JZ PRMPTR ;NO INITIAL COMMAND FROM COMMAND LINE
|
|
INX H ;PT TO FIRST CHAR
|
|
;
|
|
;Got initial command, set it up
|
|
;
|
|
MOV A,M ;GET FIRST CHAR
|
|
CPI '/' ;IF SLASH, PRINT INITIAL HELP (TOOLSET CONVENTION)
|
|
JZ IHELP ;PRINT INITIAL HELP INFO
|
|
XRA A
|
|
STA IHFLG ;SET NO INITIAL HELP
|
|
; line replaced <JPS>
|
|
; JMP PRMPTI ;PROCESS AS THOUGH COMMAND LINE WAS TYPED <JPS>
|
|
jmp prmpts ;allow processing of macros in command line <JPS>
|
|
;
|
|
;Input Command Line From User at Console
|
|
;
|
|
PRMPTR:
|
|
XRA A ;A=0
|
|
STA IHFLG ;Set No Initial Help
|
|
LDA EDRUN ;Check for Editor Running
|
|
ORA A
|
|
JNZ EDIT0 ;Reenter Editor
|
|
CALL SINBUF ;Save old INBUF into PINBUF
|
|
PRMPTE:
|
|
CALL RDBUF ;Read Input Line
|
|
PRMPTS: ;Entry when Command Line has Input <JPS>
|
|
CALL EXMAC ;Expand Macros
|
|
;
|
|
;Begin Processing Command Line in INBUF
|
|
; At this point, HL points to next character to process
|
|
;
|
|
PRMPTI:
|
|
MVI A,0FFH ;SET INFINITE LOOP COUNT
|
|
STA TOGO ;LOOP COUNT FOR MULTIPLE LOOPS
|
|
STA TOGO+1
|
|
;
|
|
;Minor Command Loop; This is the entry point for each individual command in
|
|
; a Command Line; Commands may be separated by semicolons in this manner
|
|
;
|
|
PROMPT EQU $
|
|
SETSTK:
|
|
SHLD STKSAV ;SAVE HL FOR STACK LOAD
|
|
LHLD SAVBUF ;RESET STACK
|
|
SPHL
|
|
LHLD STKSAV ;RESTORE HL
|
|
XRA A ;ZERO 2-UP PRINT FOR DUAL-COLUMN PRINT
|
|
STA TWOUP ;..SWITCH
|
|
MVI A,1
|
|
STA FTSW ;TELL SEARCH NOT TO INCR
|
|
PUSH H
|
|
LXI H,TBUFF ;SET NO-READ INPUT BUFFER ADDRESS
|
|
SHLD BUFAD ;FOR RDBYTE
|
|
POP H
|
|
CALL CTLCS ;ABORT?
|
|
JZ PRMPTR ;..YES, READ BUFFER
|
|
;
|
|
;Do we have to position in directory after find?
|
|
;
|
|
LDA FINDFL
|
|
ORA A
|
|
JNZ POSDIR ;POSITION IN DIRECTORY
|
|
;
|
|
;Begin Command Evaluation -- Check for EOL and Capitalize
|
|
;
|
|
MOV A,M ;GET NEXT CHAR IN COMMAND LINE
|
|
INX H ;POINT TO FOLLOWING CHAR
|
|
CPI CR ;END OF LINE PHYSICALLY?
|
|
JZ PRMPTR ;INPUT NEW COMMAND LINE IF SO
|
|
CPI EOLCH ;END OF LINE LOGICALLY?
|
|
JZ PROMPT ;PROCESS NEXT ELEMENT IF SO
|
|
CALL UPCASE ;CAPITALIZE COMMAND
|
|
STA DUMTYP ;TYPE OF DUMP (A,D,H)
|
|
LXI D,CMDTBL ;PT TO COMMAND TABLE
|
|
CALL CMD ;PROCESS
|
|
JMP WHAT ;ERROR RETURN
|
|
;
|
|
;Command dispatcher
|
|
; If command not found, abort with error message
|
|
; If command file, process command with HL pting to next command char and
|
|
; A containing command letter
|
|
;
|
|
CMD:
|
|
PUSH H ;SAVE HL
|
|
MOV B,A ;COMMAND IN B
|
|
XCHG ;HL PTS TO COMMAND TABLE
|
|
CMDLP:
|
|
MOV A,M ;GET COMMAND
|
|
ORA A ;0=END OF TABLE
|
|
JZ CMDER
|
|
CMP B ;COMPARE COMMAND
|
|
JZ CMDGO
|
|
INX H ;PT TO ADR
|
|
INX H
|
|
INX H ;PT TO NEXT CMND
|
|
JMP CMDLP
|
|
CMDGO:
|
|
INX H ;PT TO ADDRESS LOW
|
|
MOV E,M
|
|
INX H ;PT TO ADDRESS HIGH
|
|
MOV D,M
|
|
POP H ;RESTORE HL
|
|
POP PSW ;CLEAR RETURN ADDRESS
|
|
MOV A,B ;COMMAND BACK INTO A
|
|
PUSH D ;PLACE ADDRESS ON STACK
|
|
RET ;"RUN COMMAND"
|
|
CMDER:
|
|
POP H ;RESTORE HL
|
|
MOV A,B ;RESTORE COMMAND CHAR IN CASE CMD RUN
|
|
RET ;... IMMEDIATELY AGAIN ON A NEW TABLE
|
|
;
|
|
;Macro Expansion Routine -- Expand Macros
|
|
;
|
|
EXMAC:
|
|
LHLD CTEMP ;BUILD INTO TEMPORARY BUFFER
|
|
XCHG
|
|
LHLD INBUF ;PT TO INPUT LINE
|
|
EXMAC1:
|
|
MOV A,M ;GET CHAR
|
|
CPI '0' ;SKIP IF LESS THAN '0'
|
|
JC EXMAC2
|
|
CPI '9'+1 ;CHECK FOR RANGE
|
|
JNC EXMAC2
|
|
INX H ;PT TO NEXT CHAR
|
|
PUSH H ;SAVE PTR TO NEXT CHAR IN LINE
|
|
SUI '0' ;CONVERT TO BINARY (0-9)
|
|
MOV B,A ;RESULT IN B
|
|
MVI C,0
|
|
LHLD MTABL ;PT TO BASE OF MACROS
|
|
DAD B ;PT TO MACRO
|
|
CALL COPYM ;COPY MACRO INTO LINE
|
|
DCX D ;BACK UP OVER <CR>
|
|
POP H ;GET PTR TO NEXT CHAR IN COMMAND LINE
|
|
EXMAC2:
|
|
MOV A,M ;GET CHAR
|
|
STAX D ;PUT CHAR
|
|
INX H ;PT TO NEXT
|
|
INX D
|
|
CALL MTEST ;TEST FOR END OF BUFFER
|
|
CPI CR ;DONE?
|
|
JZ EXMAC3
|
|
CPI EOLCH ;LOGICAL EOL?
|
|
JNZ EXMAC2
|
|
JMP EXMAC1 ;PROCESS NEXT COMMAND
|
|
EXMAC3:
|
|
LHLD CTEMP ;COPY COMMAND LINE BACK
|
|
XCHG
|
|
LHLD INBUF ;INTO INBUF
|
|
XCHG
|
|
CALL COPYCR ;COPY TO <CR>
|
|
LHLD INBUF ;PT TO INBUF
|
|
RET ;EXPANSION COMPLETE
|
|
;
|
|
;Copy Macro Into Command Line Buffer
|
|
;
|
|
COPYM:
|
|
MOV A,M ;GET CHAR
|
|
STAX D ;PUT CHAR
|
|
INX H ;PT TO NEXT
|
|
INX D
|
|
CALL MTEST ;CHECK FOR LIMIT
|
|
CPI CR ;END OF MACRO?
|
|
JNZ COPYM
|
|
RET
|
|
;
|
|
;Test for Buffer Full
|
|
;
|
|
MTEST:
|
|
PUSH H ;SAVE HL
|
|
PUSH PSW ;SAVE A
|
|
LHLD CTEMPX ;CHECK FOR END OF BUFFER
|
|
MOV A,H ;GET PAGE
|
|
CMP D ;CHECK PAGE
|
|
JZ MACERR
|
|
POP PSW ;GET A
|
|
POP H ;GET HL
|
|
RET
|
|
;
|
|
;Macro Command Expansion Error
|
|
;
|
|
MACERR:
|
|
CALL ILPRT
|
|
DB CR,LF,'Error -- Macro Expanded Command Line too Long',0
|
|
JMP PRMPTR ;NEW COMMAND
|
|
;
|
|
;Save INBUF into PINBUF for later processing by '@' command
|
|
;
|
|
SINBUF:
|
|
LHLD PINBUF ;PT TO PINBUF (PREVIOUS INBUF)
|
|
XCHG
|
|
LHLD INBUF ;PT TO INBUF
|
|
;
|
|
;Copy (HL) to (DE) until <CR> Encountered
|
|
;
|
|
COPYCR:
|
|
MOV A,M ;GET CHAR
|
|
STAX D ;PUT CHAR
|
|
INX H ;PT TO NEXT
|
|
INX D
|
|
CPI CR ;DONE?
|
|
JNZ COPYCR
|
|
RET
|
|
|
|
;
|
|
;Command Not Found Error
|
|
;
|
|
WHAT:
|
|
POP H ; RESTORE HL
|
|
CALL ILPRT
|
|
DB DIM,'Invalid Command at or after ',BRIGHT,0
|
|
MOV A,B ;GET COMMAND LETTER
|
|
CALL TYPE ;PRINT IT
|
|
JMP PRMPTR
|
|
;
|
|
;Memory full error
|
|
;
|
|
MEMFUL:
|
|
CALL ILPRT
|
|
DB '+++ Out of memory +++'
|
|
DB CR,LF,0
|
|
JMP PRMPTR
|
|
;
|
|
;COMMAND: E
|
|
;Edit Current Block
|
|
;
|
|
EROW EQU 6 ;FIRST ROW OF EDITOR DISPLAY
|
|
ECOL EQU 4 ;FIRST COL OF EDITOR DISPLAY
|
|
ECOLC EQU ECOL+16*3+2 ;FIRST COL OF EDITOR CHAR DISPLAY
|
|
ECURS EQU '>' ;EDITOR CURSOR
|
|
;
|
|
EDIT:
|
|
CALL SINBUF ;SAVE COMMAND LINE AS PREVIOUS
|
|
MVI A,0FFH
|
|
STA EDRUN ;EDITOR IS RUNNING
|
|
;
|
|
; SET UP ARROW KEYS
|
|
;
|
|
LHLD ENVPTR ;PT TO ENVIRONMENT DESCRIPTOR
|
|
LXI D,80H+10H ;PT TO ARROW KEY INFO
|
|
DAD D
|
|
LXI D,EDCURT ;PT TO CURSOR TABLE
|
|
MVI B,4 ;4 ARROW KEYS
|
|
EDITA:
|
|
MOV A,M ;GET CHAR
|
|
STAX D ;STORE CHAR
|
|
INX H ;PT TO NEXT
|
|
INX D ;PT TO NEXT ENTRY
|
|
INX D
|
|
INX D
|
|
DJNZ EDITA ;COUNT DOWN
|
|
;
|
|
; REENTER EDIT WITH PTRS RESET
|
|
; REFRESH EDIT SCREEN
|
|
;
|
|
EDIT0:
|
|
CALL CLS ;NEW SCREEN
|
|
CALL AT
|
|
DB 2,32 ;ROW 2, COL 32
|
|
CALL ILPRT ;BANNER
|
|
DB 'DU3 Block Editor',0
|
|
MVI H,EROW+9 ;POSITION FOR COMMAND DISPLAY
|
|
MVI L,1
|
|
CALL GOTOXY ;POSITION CURSOR
|
|
CALL ILPRT ;PRINT COMMAND SUMMARY
|
|
DB ' -- Movement --'
|
|
DB ' -------------- Operation ---------------',CR,LF
|
|
DB ' ^E '
|
|
DB DIM,'Enter: ',BRIGHT,'A',DIM,' ASCII Chars',BRIGHT
|
|
DB ' +',DIM,' Next Sector',BRIGHT,CR,LF
|
|
DB ' ^ '
|
|
DB DIM,' ',BRIGHT,'H',DIM,' Hex Numbers',BRIGHT
|
|
DB ' -',DIM,' Last Sector',BRIGHT,CR,LF
|
|
DB ' ^S <-+-> ^D '
|
|
DB ' '
|
|
DB ' ^C',DIM,' Exit DU3 ',BRIGHT
|
|
DB CR,LF
|
|
DB ' v '
|
|
DB 'C',DIM,' DU3 Command Line ',BRIGHT
|
|
DB ' ^R',DIM,' Rescreen ',BRIGHT,CR,LF
|
|
DB ' ^X '
|
|
DB 'X',DIM,' Exit Editor to DU3',BRIGHT
|
|
DB ' ^W',DIM,' Write Block',BRIGHT
|
|
DB 0
|
|
CALL AT
|
|
DB 2,65
|
|
CALL ILPRT
|
|
DB DIM,'Position:',BRIGHT,0
|
|
; JMP EDITCMD
|
|
;
|
|
; REFRESH SCREEN DISPLAY DATA ONLY
|
|
;
|
|
EDITR:
|
|
XRA A ;A=0
|
|
STA EINDEX ;SET INDEX TO 0 (FIRST ELEMENT)
|
|
STA EDERR ;SET NO PREVIOUS ERROR
|
|
CALL AT ;POSITION CURSOR
|
|
DB EROW-2,ECOL
|
|
CALL INQSUB ;PRINT POSITION DATA
|
|
CALL EDPLOT ;PLOT BUFFER DATA
|
|
;
|
|
; INPUT EDITOR COMMAND
|
|
;
|
|
EDITCMD:
|
|
CALL EDERCL ;CLEAR EDITOR INVALID COMMAND MESSAGE
|
|
EDITCMD1:
|
|
CALL AT ;POSITION FOR COMMAND LINE
|
|
DB 22,10
|
|
CALL ILPRT
|
|
DB DIM,'Edit Command? ',BRIGHT,BS,0
|
|
CALL CONIN ;GET CHAR
|
|
CALL UPCASE ;CAPITALIZE
|
|
MOV B,A ;COMMAND IN B
|
|
LXI D,EDCURT ;PROCESS CURSOR COMMANDS FIRST
|
|
CALL CMD ;PROCESS COMMAND
|
|
LXI D,ECMDTBL ;EDITOR COMMAND TABLE
|
|
CALL CMD ;PROCESS COMMAND
|
|
MVI A,0FFH ;SET ERROR FLAG
|
|
STA EDERR
|
|
CALL AT ;CLEAR ERROR MESSAGE
|
|
DB 23,15
|
|
CALL ILPRT
|
|
DB 'Invalid Command',0
|
|
JMP EDITCMD1
|
|
;
|
|
;Clear Editor Invalid Command Message
|
|
;
|
|
EDERCL:
|
|
LDA EDERR ;PREVIOUS ERROR?
|
|
ORA A ;0=NO
|
|
RZ
|
|
XRA A ;CLEAR FLAG
|
|
STA EDERR
|
|
CALL AT ;CLEAR ERROR MESSAGE
|
|
DB 23,15
|
|
CALL ILPRT
|
|
DB ' ',0
|
|
RET
|
|
;
|
|
;PLOT BUFFER DATA
|
|
;
|
|
EDPLOT:
|
|
MVI H,EROW ;SET ROW
|
|
MVI L,ECOL-1 ;SET COLUMN <RLC-3/1/85>
|
|
CALL GOTOXY ;POSITION CURSOR
|
|
XCHG ;POSITION IN DE
|
|
LXI H,TBUFF ;PT TO DATA
|
|
MVI B,8 ;8 LINES
|
|
EDIT00:
|
|
MVI C,16 ;16 ELEMENTS
|
|
CALL SPACE ;PRINT LEADING SPACE <RLC-3/1/85>
|
|
EDIT01:
|
|
MOV A,M ;GET BYTE
|
|
CALL HEX ;PRINT AS HEX
|
|
CALL SPACE ;PRINT 1 SPACE
|
|
INX H ;PT TO NEXT
|
|
DCR C ;COUNT DOWN
|
|
JNZ EDIT01
|
|
XCHG ;POSITION AGAIN
|
|
INR H ;NEXT ROW
|
|
CALL GOTOXY
|
|
XCHG
|
|
DCR B ;COUNT DOWN
|
|
JNZ EDIT00
|
|
MVI H,EROW ;RESET ROW
|
|
MVI L,ECOLC ;RESET COL
|
|
CALL GOTOXY ;POSITION CURSOR
|
|
XCHG ;POSITION IN DE
|
|
LXI H,TBUFF ;PT TO DATA
|
|
MVI B,8 ;8 LINES
|
|
EDIT02:
|
|
CALL ASTER ;PRINT BAR
|
|
MVI C,16 ;16 ELEMENTS
|
|
EDIT03:
|
|
MOV A,M ;GET BYTE
|
|
ANI 7FH ;MASK MSB
|
|
CPI 7FH ;7FH IS DOT
|
|
JZ EDIT7F
|
|
CPI ' ' ;SPACE OR MORE?
|
|
JNC EDIT04
|
|
EDIT7F:
|
|
MVI A,'.' ;PRINT DOT
|
|
EDIT04:
|
|
CALL TYPE ;PRINT BYTE
|
|
INX H ;PT TO NEXT
|
|
DCR C ;COUNT DOWN
|
|
JNZ EDIT03
|
|
CALL ASTER ;PRINT ENDING BAR
|
|
XCHG ;POSITION AGAIN
|
|
INR H ;NEXT ROW
|
|
CALL GOTOXY
|
|
XCHG
|
|
DCR B ;COUNT DOWN
|
|
JNZ EDIT02
|
|
CALL EDCUR ;POSITION CURSOR
|
|
RET
|
|
;
|
|
;EDITOR COMMAND TABLE
|
|
;
|
|
ECMDTBL:
|
|
DB CR ;NOP
|
|
DW EDITCMD
|
|
DB 'C'-'@' ;^C = EXIT DU3
|
|
DW EDCC
|
|
DB 'R'-'@' ;^R = REFRESH
|
|
DW EDIT0
|
|
DB 'E'-'@' ;^E=UP
|
|
DW EDUP
|
|
DB 'X'-'@' ;^X=DOWN
|
|
DW EDDOWN
|
|
DB 'D'-'@' ;^D=RIGHT
|
|
DW EDRIGHT
|
|
DB 'S'-'@' ;^S=LEFT
|
|
DW EDLEFT
|
|
DB 'W'-'@' ;WRITE BLOCK
|
|
DW EDITWR
|
|
DB ' ' ;NOP
|
|
DW EDITCMD
|
|
DB '+' ;ADVANCE
|
|
DW EDITPLUS
|
|
DB '-' ;BACKUP
|
|
DW EDITMINUS
|
|
DB 'A' ;CHANGE ALPHA
|
|
DW EDITALP
|
|
DB 'C' ;COMMAND LINE
|
|
DW EDITCL
|
|
DB 'H' ;CHANGE HEX
|
|
DW EDITHEX
|
|
DB 'X' ;EXIT
|
|
DW EDITX
|
|
DB 0 ;END OF TABLE
|
|
;
|
|
; ARROW KEY DEFINITONS FROM TCAP
|
|
;
|
|
EDCURT:
|
|
DB 0 ;0 INDICATES NO ARROW KEYS
|
|
DW EDUP
|
|
DB 0
|
|
DW EDDOWN
|
|
DB 0
|
|
DW EDRIGHT
|
|
DB 0
|
|
DW EDLEFT
|
|
DB 0 ;END OF TABLE
|
|
;
|
|
;EDITOR BUFFERS
|
|
;
|
|
EINDEX:
|
|
DS 1 ;INDEX ENTRY
|
|
EDERR:
|
|
DS 1 ;ERROR FLAG
|
|
EDRUN:
|
|
DS 1 ;FLAG SAYING THAT EDITOR IS RUNNING
|
|
;
|
|
;Write Block to Disk
|
|
;
|
|
EDITWR:
|
|
CALL EDERCL ;CLEAR ERROR LINE
|
|
CALL WRITE ;WRITE BLOCK
|
|
CALL AT
|
|
DB 23,15 ;MESSAGE
|
|
CALL ILPRT
|
|
DB 'Block Written',0
|
|
MVI A,0FFH ;SET ERROR
|
|
STA EDERR
|
|
JMP EDITCMD1
|
|
;
|
|
;Enter ASCII Chars
|
|
;
|
|
EDITALP:
|
|
CALL EDERCL ;CLEAR ERROR LINE
|
|
CALL AT
|
|
DB 22,35
|
|
CALL ILPRT
|
|
DB DIM,'Enter Text (<hh> for Hex)',BRIGHT
|
|
DB CR,LF,' --> ',0
|
|
CALL RDBUF1 ;INPUT TEXT WITHOUT PROMPT
|
|
CALL EDPRCL ;CLEAR PROMPT LINE
|
|
LDA EINDEX ;PT TO POSITION
|
|
LXI D,TBUFF ;COMPUTE OFFSET
|
|
ADD E
|
|
MOV E,A
|
|
MOV A,D
|
|
ACI 0
|
|
MOV D,A ;DE PTS TO BYTE, HL PTS TO TEXT
|
|
EDITA1:
|
|
MOV A,M ;GET CHAR
|
|
CPI CR ;EOL?
|
|
JZ EDITA2 ;REFRESH SCREEN
|
|
CALL GETVAL ;GET ASCII OR <HEX> VALUE
|
|
STAX D ;UPDATE BYTE
|
|
INX H ;PT TO NEXT INPUT CHAR
|
|
INR E ;PT TO NEXT BUFFER BYTE
|
|
JNZ EDITA1
|
|
EDITA2:
|
|
CALL EDPLOT ;REPLOT
|
|
JMP EDITCMD1 ;DONE-REFRESH SCREEN
|
|
;
|
|
;Enter Numbers
|
|
;
|
|
EDITHEX:
|
|
CALL EDERCL ;CLEAR ERROR LINE
|
|
CALL AT
|
|
DB 22,35
|
|
CALL ILPRT
|
|
DB DIM,'Enter Hex Numbers (#nn for Dec)'
|
|
DB BRIGHT
|
|
DB CR,LF,' --> ',0
|
|
CALL RDBUF1 ;INPUT TEXT WITHOUT PROMPT
|
|
CALL EDPRCL ;CLEAR PROMPT LINE
|
|
LDA EINDEX ;PT TO POSITION
|
|
LXI D,TBUFF ;COMPUTE OFFSET
|
|
ADD E
|
|
MOV E,A
|
|
MOV A,D
|
|
ACI 0
|
|
MOV D,A ;DE PTS TO BYTE, HL PTS TO TEXT
|
|
EDITH1:
|
|
MOV A,M ;GET HEX DIGIT
|
|
CPI CR ;EOL?
|
|
JZ EDITA2 ;REFRESH SCREEN
|
|
CPI ' ' ;SKIP SPACES
|
|
JNZ EDITH2
|
|
INX H ;SKIP SPACE
|
|
JMP EDITH1
|
|
EDITH2:
|
|
PUSH D ;SAVE PTR
|
|
CALL HEXIN ;GET VALUE AND POSITION HL
|
|
MOV A,E ;... IN A
|
|
POP D ;GET PTR
|
|
STAX D ;PUT BYTE
|
|
INR E ;ADVANCE TO NEXT BYTE
|
|
JNZ EDITH1
|
|
JMP EDITA2 ;DONE-REFRESH
|
|
;
|
|
;CLEAR PROMPT LINE
|
|
;
|
|
EDPRCL:
|
|
CALL AT ;PROMPT LINE
|
|
DB 22,35
|
|
MVI B,40 ;40 POSITIONS
|
|
CALL EDPCL
|
|
CALL AT ;USER INPUT
|
|
DB 23,1
|
|
MVI B,79 ;79 POSITIONS
|
|
EDPCL:
|
|
CALL SPACE ;CLEAR PROMPT LINE WITH SPACES
|
|
DCR B
|
|
JNZ EDPCL
|
|
RET
|
|
;
|
|
;Enter Command Line from Editor
|
|
;
|
|
EDITCL:
|
|
CALL EDERCL ;CLEAR ERROR LINE
|
|
CALL CRLF ;NEW LINE
|
|
JMP PRMPTE ;GET COMMAND LINE FROM USER
|
|
;
|
|
;Advance to Next Block
|
|
;
|
|
EDITPLUS:
|
|
CALL NXTSEC ;ADVANCE SECTORS
|
|
EDITP1:
|
|
PUSH H
|
|
LHLD CURSEC
|
|
XCHG
|
|
CALL SETSEC ;SET SECTOR
|
|
LHLD CURTRK
|
|
XCHG
|
|
CALL SETTRK ;SET TRACK
|
|
POP H
|
|
CALL READ ;READ IN BLOCK
|
|
CALL CLCSUB ;CALCULATE GROUP DATA
|
|
JMP EDITR ;REFRESH DATA
|
|
;
|
|
;Backup to Last Block
|
|
;
|
|
EDITMINUS:
|
|
CALL LSTSEC ;BACKUP BLOCK
|
|
JMP EDITP1
|
|
;
|
|
;Exit EDIT Mode
|
|
;
|
|
EDITX:
|
|
XRA A
|
|
STA EDRUN ;EDITOR IS NOT RUNNING NOW
|
|
CALL EDERCL ;CLEAR ERROR LINE
|
|
JMP PRMPTR
|
|
;
|
|
;Exit DU3
|
|
;
|
|
EDCC:
|
|
CALL EDERCL ;CLEAR ERROR LINE
|
|
JMP EXIT
|
|
;
|
|
;EDIT MOVE: UP
|
|
;
|
|
EDUP:
|
|
CALL EDCCUR ;CLEAR CURSOR
|
|
LDA EINDEX ;BACKUP INDEX BY 16
|
|
SUI 16
|
|
;
|
|
;Common EDIT MOVE Routine - on input, A=new index
|
|
;
|
|
EDMOVE:
|
|
ANI 7FH ;MOD 128
|
|
STA EINDEX
|
|
CALL EDCUR ;SET CURSOR
|
|
JMP EDITCMD
|
|
;
|
|
;EDIT MOVE: DOWN
|
|
;
|
|
EDDOWN:
|
|
CALL EDCCUR ;CLEAR CURSOR
|
|
LDA EINDEX ;INCREMENT INDEX BY 16
|
|
ADI 16
|
|
JMP EDMOVE ;COMMON ROUTINE
|
|
;
|
|
;EDIT MOVE: RIGHT
|
|
;
|
|
EDRIGHT:
|
|
CALL EDCCUR ;CLEAR CURSOR
|
|
LDA EINDEX ;INCREMENT INDEX BY 1
|
|
INR A
|
|
JMP EDMOVE ;COMMON ROUTINE
|
|
;
|
|
;EDIT MOVE: LEFT
|
|
;
|
|
EDLEFT:
|
|
CALL EDCCUR ;CLEAR CURSOR
|
|
LDA EINDEX ;DECREMENT INDEX BY 1
|
|
DCR A
|
|
JMP EDMOVE ;COMMON ROUTINE
|
|
;
|
|
;EDIT SUBROUTINE: EDCUR
|
|
; Position Editor Cursor at EINDEX
|
|
;EDIT SUBROUTINE: EDCCUR
|
|
; Clear Editor Cursor at EINDEX
|
|
;
|
|
EDCUR:
|
|
PUSH H ;SAVE HL
|
|
MVI C,ECURS ;CURSOR CHAR
|
|
CALL EDSETCUR
|
|
CALL AT ;UPDATE DATA
|
|
DB 2,75
|
|
LDA EINDEX ;PT TO BYTE AT CURSOR
|
|
LXI H,TBUFF
|
|
ADD L
|
|
MOV L,A
|
|
MOV A,H
|
|
ACI 0
|
|
MOV H,A ;HL PTS TO BYTE AT CURSOR
|
|
MOV A,M ;GET BYTE
|
|
CALL HEX ;PRINT AS HEX
|
|
CALL SPACE
|
|
MOV A,M ;GET BYTE
|
|
POP H ;RESTORE HL
|
|
ANI 7FH ;MASK
|
|
CPI 7FH ;7FH IS DOT
|
|
JZ EDC7F
|
|
CPI ' ' ;OUTPUT CHAR OR DOT
|
|
JNC TYPE
|
|
EDC7F:
|
|
MVI A,'.' ;DOT
|
|
JMP TYPE
|
|
EDCCUR:
|
|
MVI C,' ' ;CLEAR CURSOR
|
|
EDSETCUR:
|
|
CALL EDROW ;COMPUTE ROW
|
|
ANI 0FH ;COMPUTE COL MOD 16
|
|
MOV B,A ;RESULT IN B
|
|
ADD A ;*2
|
|
ADD B ;*3
|
|
ADI ECOL ;ADD IN COL
|
|
DCR A ;SUBTRACT 1
|
|
MOV L,A ;COL POSITION SET
|
|
CALL GOTOXY ;POSITION CURSOR
|
|
MOV A,C ;OUTPUT CHAR
|
|
JMP TYPE
|
|
;
|
|
;Compute Row from EINDEX
|
|
;
|
|
EDROW:
|
|
LDA EINDEX ;GET INDEX
|
|
MOV B,A ;SAVE IN B
|
|
RRC ;DIVIDE BY 16
|
|
RRC
|
|
RRC
|
|
RRC
|
|
ANI 0FH ;MASK FOR LSB ONLY
|
|
ADI EROW ;COMPUTE ROW
|
|
MOV H,A ;ROW SET
|
|
MOV A,B ;GET INDEX
|
|
RET
|
|
;
|
|
;COMMAND: @
|
|
;Repeat Previous Command Line
|
|
;
|
|
PCMD:
|
|
MOV A,M ;GET NEXT CHAR
|
|
CPI CR ;SHOULD BE <CR>
|
|
JZ PCMD1
|
|
CALL ILPRT
|
|
DB CR,LF,'Warning: Remainder of Command Line after "@" Deleted',0
|
|
PCMD1:
|
|
CALL ILPRT
|
|
DB CR,LF,DIM,'Command --',BRIGHT,CR,LF,0
|
|
LHLD INBUF ;COPY INTO INBUF
|
|
XCHG
|
|
LHLD PINBUF ;GET PREVIOUS COMMAND
|
|
PCMD2:
|
|
MOV A,M ;GET CHAR
|
|
STAX D ;PUT CHAR
|
|
INX H ;PT TO NEXT
|
|
INX D
|
|
CPI CR ;END OF LINE?
|
|
PUSH PSW ;SAVE FLAG
|
|
CALL TYPE ;PRINT CHAR
|
|
POP PSW ;GET FLAG
|
|
JNZ PCMD2
|
|
MVI A,LF ;<LF>
|
|
CALL TYPE
|
|
LHLD INBUF ;RESTART COMMAND PROCESSING
|
|
JMP PRMPTI ;INCLUDE LOOP CAPABILITY
|
|
;
|
|
;COMMAND: :
|
|
;Define or Print Macro
|
|
;:n<text> Defines Macro n, 0<=n<=9; ::n Prints Macro n, 0<=n<=9
|
|
;
|
|
MAC:
|
|
MOV A,M ;GET NEXT CHAR
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI 'P' ;PRINT MACRO?
|
|
JNZ MACROD ;IF NOT, DEFINE MACRO
|
|
INX H ;PT TO MACRO NUMBER
|
|
MOV A,M ;GET IT
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI '@' ;PRINT PREVIOUS COMMAND?
|
|
JZ PCPR
|
|
PUSH PSW ;SAVE A
|
|
call cls
|
|
cz crlf
|
|
CALL ILPRT
|
|
DB DIM,'Macro Definitions --',BRIGHT,0
|
|
POP PSW ;GET A
|
|
CPI 'A' ;PRINT ALL MACROS?
|
|
JZ AMACPR
|
|
CALL MNUM ;CHECK FOR VALID NUMBER AND RETURN # IN D
|
|
INX H ;PT TO CHAR AFTER MACRO NUMBER
|
|
CALL MACPR ;PRINT MACRO WHOSE NUMBER IS IN D
|
|
JMP PROMPT
|
|
;
|
|
;Print Previous Command
|
|
;
|
|
PCPR:
|
|
INX H ;PT TO CHAR AFTER '@'
|
|
LXI D,PROMPT ;SET UP RET ADR
|
|
PUSH D ;RETURN ADR ON STACK
|
|
PUSH H ;SAVE PTR
|
|
CALL ILPRT
|
|
DB DIM,'Previous Command Line Definition --',BRIGHT
|
|
DB CR,LF,'@: ',0
|
|
LHLD PINBUF ;PT TO PREVIOUS COMMAND
|
|
JMP MPRINT ;USE MACRO PRINT FACILITY
|
|
;
|
|
;Print All Macros
|
|
;
|
|
AMACPR:
|
|
INX H ;PT TO CHAR AFTER 'A'
|
|
MVI D,0 ;SET FOR FIRST MACRO
|
|
AMPRL:
|
|
CALL MACPR ;PRINT MACRO WHOSE NUMBER IS IN D
|
|
INR D ;INCREMENT MACRO NUMBER
|
|
MOV A,D ;GET VALUE
|
|
CPI 10 ;DONE?
|
|
JNZ AMPRL
|
|
JMP PROMPT ;CONTINUE PROCESSING
|
|
;
|
|
;Print Macro Whose Number (0-9) is in D
|
|
;
|
|
MACPR:
|
|
PUSH H ;SAVE PTR
|
|
CALL ILPRT ;PRINT HEADER
|
|
DB CR,LF,DIM,0
|
|
MOV A,D ;GET NUMBER
|
|
ADI '0' ;CONVERT TO ASCII
|
|
CALL TYPE ;PRINT
|
|
CALL ILPRT
|
|
DB ': ',BRIGHT,0
|
|
LHLD MTABL ;PT TO TABLE OF MACROS
|
|
MVI E,0 ;PAGE OFFSET OF ZERO; MACRO NUMBER ALREADY IN D
|
|
DAD D ;PT TO MACRO
|
|
MPRINT:
|
|
MOV A,M ;GET CHAR
|
|
INX H ;PT TO NEXT
|
|
CPI CR ;END OF MACRO?
|
|
PUSH PSW ;SAVE FLAG
|
|
CALL TYPE ;PRINT CHAR
|
|
POP PSW ;GET FLAG
|
|
JNZ MPRINT
|
|
MVI A,LF ;<LF>
|
|
CALL TYPE
|
|
POP H ;GET PTR TO NEXT CHAR
|
|
RET
|
|
;
|
|
;Check char in A for valid Macro Number (0-9), print error message if
|
|
; not, return number in D if so
|
|
;
|
|
MNUM:
|
|
SUI '0' ;CONVERT TO 0-9
|
|
JC MNERR ;ERROR IF LESS
|
|
CPI 10 ;RANGE?
|
|
JNC MNERR
|
|
MOV D,A ;RESULT IN D
|
|
RET
|
|
MNERR:
|
|
CALL ILPRT
|
|
DB CR,LF,'Invalid Macro Number Specified in Command',0
|
|
JMP PRMPTR ;NEW COMMAND
|
|
;
|
|
;Define Macro
|
|
;
|
|
MACROD:
|
|
CALL MNUM ;CHECK NUMBER AND RETURN IN D
|
|
INX H ;PT TO CHAR AFTER MACRO NUMBER
|
|
PUSH H ;SAVE PTR
|
|
LHLD MTABL ;PT TO MACRO TABLE
|
|
MVI E,0 ;SET EVEN PAGE
|
|
DAD D ;PT TO MACRO ENTRY IN HL
|
|
XCHG ;... IN DE
|
|
POP H ;PT TO MACRO TEXT
|
|
CALL COPYCR ;COPY TO <CR>
|
|
JMP PRMPTR ;NEW COMMAND
|
|
;
|
|
;COMMAND: !
|
|
;Delay for user input
|
|
;
|
|
UWAIT:
|
|
CALL WAIT ; USE WAIT ROUTINE
|
|
JMP PROMPT
|
|
;
|
|
;COMMAND: #
|
|
;Print disk statistics
|
|
;
|
|
STATS:
|
|
PUSH H ;SAVE POINTER TO NEXT COMMAND
|
|
call cls
|
|
cz crlf
|
|
CALL ILPRT
|
|
DB DIM
|
|
DB ' -- Queue Information --',BRIGHT,CR,LF
|
|
DB CR,LF
|
|
DB 0
|
|
CALL QSTATS ;PRINT STATUS INFO
|
|
CALL ILPRT
|
|
DB CR,LF
|
|
DB DIM
|
|
DB ' -- Disk Information --',BRIGHT,CR,LF
|
|
DB CR,LF
|
|
DB DIM,'Disk Drive: ',BRIGHT,0
|
|
LDA DRIVE
|
|
ADI 'A' ;CONVERT TO ASCII
|
|
CALL TYPE ;PRINT DRIVE LETTER
|
|
CALL ILPRT
|
|
DB CR,LF,DIM,'Tracks: ',BRIGHT,0
|
|
LHLD MAXTRK ;PRINT NUMBER OF TRACKS
|
|
INX H
|
|
CALL DEC
|
|
CALL ILPRT
|
|
DB CR,LF,DIM,'Sectors/Track: ',BRIGHT,0
|
|
LHLD SPT ;PRINT NUMBER OF SECTORS/TRACK
|
|
CALL DEC
|
|
CALL ILPRT
|
|
DB CR,LF,DIM,'Group Size: ',BRIGHT,0
|
|
LDA BLM ;PRINT SIZE OF A GROUP
|
|
INR A
|
|
MOV L,A
|
|
MVI H,0
|
|
CALL DEC
|
|
CALL ILPRT
|
|
DB DIM,' Blocks/Group',BRIGHT
|
|
DB CR,LF,DIM,'Total Groups: ',BRIGHT,0
|
|
LHLD DSM ;PRINT TOTAL NUMBER OF GROUPS ON A DISK
|
|
CALL DEC
|
|
CALL ILPRT
|
|
DB CR,LF,DIM,'Directory Entries: ',BRIGHT,0
|
|
LHLD DRM ;PRINT NUMBER OF DIRECTORY ENTRIES
|
|
INX H
|
|
CALL DEC
|
|
CALL ILPRT
|
|
DB CR,LF,DIM,'System Tracks: ',BRIGHT,0
|
|
LHLD SYSTRK ;PRINT NUMBER OF SYSTEM TRACKS
|
|
CALL DEC
|
|
CALL SWAIT
|
|
POP H ;RESTORE POINTER TO NEXT COMMAND
|
|
JMP PROMPT
|
|
;
|
|
;COMMAND: N
|
|
;The following command resets the disk
|
|
;system thru CP/M, and may be usable for
|
|
;changing the disk density or format.
|
|
;This can only be done if your BIOS resets
|
|
;the auto-density select parameters at
|
|
;every track-zero access.
|
|
;
|
|
NEWDSK:
|
|
PUSH H ;SAVE POINTER TO NEXT LETTER
|
|
MVI C,RESETDK ;BDOS RESET DISK FUNCTION
|
|
CALL BDOS
|
|
LDA DRIVE ;RESELECT CURRENT DRIVE
|
|
MOV C,A
|
|
POP H
|
|
CALL SELECT
|
|
JMP PROMPT
|
|
;
|
|
;COMMAND: Q
|
|
;Queue Control
|
|
;
|
|
QUEUER:
|
|
MOV A,M ;GET 2ND ARGUMENT
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI EOLCH ;END OF LINE?
|
|
JZ QSTAT ;STATUS REPORT
|
|
CPI CR ;END OF LINE?
|
|
JZ QSTAT
|
|
INX H ;PT TO AFTER KEY CHAR
|
|
PUSH H ;SAVE PTR
|
|
CPI 'Z' ;ZERO QUEUE?
|
|
JZ QZERO
|
|
CPI 'S' ;SAVE QUEUE?
|
|
JZ QFSAVE
|
|
POP H ;GET PTR
|
|
CALL ILPRT
|
|
DB 'Invalid Queue Command',CR,LF,0
|
|
JMP PRMPTR ;ABORT LINE ON ERROR
|
|
;
|
|
; Zero the Queue
|
|
;
|
|
QZERO:
|
|
LHLD DIRECT ;ZERO QUEUE
|
|
SHLD QNXT ;SET NEXT
|
|
SHLD QLST ;SET LAST
|
|
LXI H,0 ;ZERO COUNT
|
|
SHLD QCNT
|
|
POP H ;GET PTR AND FALL THRU TO QSTAT
|
|
;
|
|
; Print Status of Queue
|
|
;
|
|
QSTAT:
|
|
PUSH H ;SAVE PTR TO NEXT CHAR
|
|
call cls
|
|
cz crlf
|
|
CALL ILPRT
|
|
DB DIM
|
|
DB '** Queue Status Summary **'
|
|
DB BRIGHT
|
|
DB CR,LF,0
|
|
CALL QSTATS ;PRINT STATUS
|
|
POP H ;RESTORE PTR
|
|
JMP PROMPT
|
|
QSTATS:
|
|
LHLD QCNT ;GET SIZE OF QUEUE
|
|
CALL PRQCNT ;PRINT DATA
|
|
CALL PRQSPAC ;PRINT SPACE AVAILABLE INFO
|
|
CALL ILPRT
|
|
DB CR,LF
|
|
DB DIM,'Group Save Buffer Address: ',BRIGHT,0
|
|
PUSH H
|
|
LHLD GBUFF ;BC=ADDRESS
|
|
MOV B,H
|
|
MOV C,L
|
|
POP H
|
|
CALL HEXB1 ;PRINT AS HEX
|
|
CALL ILPRT
|
|
DB ' Hex',CR,LF
|
|
DB 0
|
|
CALL ILPRT
|
|
DB DIM,'Address of Head of Queue: ',BRIGHT,0
|
|
LHLD QNXT ;PRINT ADDRESS OF HEAD OF QUEUE
|
|
MOV B,H ;... ADDRESS IN BC
|
|
MOV C,L
|
|
CALL HEXB1 ;PRINT IN HEX
|
|
CALL ILPRT
|
|
DB ' Hex',CR,LF
|
|
DB DIM,'Address of Tail of Queue: ',BRIGHT,0
|
|
LHLD QLST ;PRINT ADDRESS OF TAIL OF QUEUE
|
|
MOV B,H
|
|
MOV C,L
|
|
CALL HEXB1
|
|
CALL ILPRT
|
|
DB ' Hex',CR,LF,0
|
|
RET
|
|
;
|
|
; Print Amount of Space Left in Queue
|
|
;
|
|
PRQSPAC:
|
|
LXI B,-1 ;SET COUNT
|
|
LHLD QLST ;GET PTR TO QUEUE TAIL
|
|
QSTAT1:
|
|
INX B ;INCREMENT COUNT
|
|
LXI D,80H ;PT TO NEXT QUEUE ELEMENT
|
|
DAD D
|
|
XCHG ;WRAP AROUND
|
|
CALL QWRAP
|
|
LHLD QNXT ;GET PTR TO FIRST ELEMENT
|
|
XCHG
|
|
MOV A,H ;COMPARE
|
|
CMP D
|
|
JNZ QSTAT1
|
|
MOV A,L
|
|
CMP E
|
|
JNZ QSTAT1
|
|
MOV H,B ;HL=BLOCK COUNT
|
|
MOV L,C
|
|
CALL DEC ;PRINT AS DECIMAL
|
|
CALL ILPRT
|
|
DB DIM,' Blocks Left in Queue',BRIGHT,CR,LF,0
|
|
RET
|
|
;
|
|
; Save Queue as a File
|
|
;
|
|
QFSAVE:
|
|
MOV A,M ;GET FIRST CHAR OF FILE NAME
|
|
CPI EOLCH ;EOL?
|
|
JZ WHAT
|
|
CPI CR ;EOL?
|
|
JZ WHAT
|
|
LXI D,FCB ;START TO FILL FCB
|
|
XRA A ;A=0
|
|
STAX D ;SELECT DEFAULT DRIVE
|
|
INX D ;PT TO FILE NAME
|
|
MVI B,8 ;SAVE FILE NAME
|
|
CALL MVNAME
|
|
MVI B,3 ;SAVE FILE TYPE
|
|
CALL MVNAME
|
|
PUSH H ;SAVE PTR TO NEXT CHAR
|
|
LHLD QCNT ;ANY ELEMENTS IN QUEUE?
|
|
MOV A,H
|
|
ORA L
|
|
JZ QEMPTY
|
|
PUSH H ;SAVE QUEUE COUNT
|
|
CALL NORITE ;CAN'T WRITE NOW
|
|
LXI D,FCB ;PT TO FCB
|
|
CALL FCBINIT ;INIT FCB
|
|
MVI C,DELF ;DELETE FILE
|
|
PUSH D ;SAVE DE
|
|
CALL BDOS
|
|
POP D
|
|
CALL FCBINIT ;INIT FCB AGAIN
|
|
MVI C,MAKEF ;CREATE FILE
|
|
CALL BDOS
|
|
POP B ;GET QUEUE COUNT IN BC
|
|
LHLD QNXT ;PT TO NEXT BLOCK IN QUEUE
|
|
QFS1:
|
|
PUSH B ;SAVE COUNT
|
|
LXI D,TBUFF ;COPY INTO TBUFF
|
|
MVI B,128 ;128 BYTES
|
|
CALL MOVE
|
|
XCHG ;PT TO NEXT QUEUE BLOCK IN DE
|
|
CALL QWRAP ;WRAP AROUND
|
|
PUSH D ;SAVE PTRS
|
|
LXI D,FCB ;PT TO FCB
|
|
MVI C,WRITEF ;WRITE BLOCK TO FILE
|
|
CALL BDOS
|
|
POP H ;GET PTR TO NEXT BLOCK
|
|
POP B ;GET COUNT
|
|
DCX B ;COUNT DOWN
|
|
MOV A,B ;DONE?
|
|
ORA C
|
|
JNZ QFS1
|
|
LXI D,FCB ;CLOSE FILE
|
|
MVI C,CLOSEF
|
|
CALL BDOS
|
|
CALL ILPRT
|
|
DB 'Queue Saved in File',CR,LF,0
|
|
POP H ;PT TO NEXT CHAR
|
|
JMP PROMPT
|
|
FCBINIT:
|
|
PUSH D ;SAVE PTR
|
|
LXI H,12 ;SKIP TO EX FIELD
|
|
DAD D
|
|
MVI B,24 ;ZERO 36 BYTES
|
|
XRA A ;A=0
|
|
FCBIN1:
|
|
MOV M,A ;STORE ZEROES
|
|
INX H
|
|
DJNZ FCBIN1
|
|
POP D ;RESTORE PTR
|
|
RET
|
|
;
|
|
;COMMAND: *
|
|
;Repeat buffer contents
|
|
;
|
|
REPEAT:
|
|
CALL DECIN ;NN SPECIFIED?
|
|
MOV A,D
|
|
ORA E
|
|
JZ NNN ;NO -- SET FOR INFINITE LOOP OR SIMPLE REPEAT
|
|
LHLD TOGO ;LOAD LOOP FLAG
|
|
INX H ;TEST FOR FIRST TIME
|
|
MOV A,H
|
|
ORA L ;WAS IT 0FFFFH?; IF SO, WE HAVE NEW VALUE
|
|
JNZ NNN ;NO: COUNTING
|
|
XCHG ;GET COUNT
|
|
SHLD TOGO ;SET COUNT
|
|
;
|
|
NNN:
|
|
LHLD TOGO ;GET CURRENT COUNT
|
|
XCHG ;DE=CURRENT COUNT, HL=COUNT LIMIT
|
|
LHLD INBUF ;PT TO FIRST CHAR FOR REPEAT
|
|
INX D ;TEST FOR 0FFFFH
|
|
MOV A,D ;IF 0FFFFH, INX D MADE DE=0
|
|
ORA E
|
|
JZ PROMPT ;CONTINOUS LOOP IF 0FFFFH
|
|
DCX D ;COUNT DOWN
|
|
DCX D ;MAKE UP FOR PREV INX D
|
|
XCHG
|
|
SHLD TOGO ;SET NEW COUNT (1 LESS THAN BEFORE)
|
|
MOV A,H ;ALL DONE?
|
|
ORA L
|
|
XCHG ;GET BACK INBUF PTR IN HL
|
|
JNZ PROMPT ;KEEP GOING IF NOT YET ZERO
|
|
JMP PRMPTR ;ALL DONE
|
|
;
|
|
;COMMAND: U
|
|
;Set CP/M 2.x user number
|
|
;
|
|
USER:
|
|
CALL DECIN ;GET REQUESTED USER NO.
|
|
LDA MUSER ;GET MAX USER
|
|
MOV B,A ;... IN B
|
|
MOV A,E
|
|
CMP B ;VALID?
|
|
JNC USRERR
|
|
MOV A,D ;HIGH-ORDER BYTE MUST BE ZERO FOR VALID NUMBER
|
|
ORA A
|
|
JNZ USRERR
|
|
MOV A,E ;SAVE USER NUMBER
|
|
STA UNUM
|
|
MVI C,SUSER ;SET USER NUMBER
|
|
PUSH H ;SAVE CHAR POINTER
|
|
CALL BDOS ;SET USER NO.
|
|
POP H
|
|
JMP PROMPT
|
|
USRERR:
|
|
CALL ILPRT
|
|
DB 'User Number Out of Range',CR,LF,0
|
|
JMP PRMPTR
|
|
;
|
|
;COMMAND: P
|
|
;Toggle print flag
|
|
;
|
|
PRNTFF:
|
|
LDA PFLAG ;TOGGLE PRINT FLAG
|
|
XRI 1
|
|
STA PFLAG
|
|
JMP PROMPT
|
|
;
|
|
;COMMAND: Z
|
|
;Sleep routine, in seconds
|
|
;
|
|
SLEEP:
|
|
CALL DECIN ;GET COUNT IF ANY
|
|
MOV A,E ;ANY?
|
|
ORA A
|
|
JNZ SLEPLP
|
|
MVI E,1 ; 1 SEC DEFAULT
|
|
;
|
|
SLEPLP:
|
|
LDA CLOCK ; GET CLOCK SPEED
|
|
MOV D,A
|
|
;
|
|
SLEEP1:
|
|
LXI B,41700 ; APPROX 1 SEC @ 1MHz
|
|
;
|
|
SLEEP2:
|
|
DCX B ;COUNT DOWN FOR 1 MHz [5 CYCLES]
|
|
MOV A,B ;[5 CYCLES] <-- TOTAL TIME: 24 CYCLES
|
|
ORA C ;[4 CYCLES] <-- (24 MU-SECS AT 1MHz)
|
|
JNZ SLEEP2 ;[10 CYCLES]
|
|
PUSH D
|
|
CALL CTLCS ;ABORT?
|
|
POP D
|
|
JZ PRMPTR
|
|
DCR D ;COUNT DOWN FOR CLOCK SPEED
|
|
JNZ SLEEP1
|
|
DCR E ;COUNT DOWN NUMBER OF REQUESTED SECONDS
|
|
JNZ SLEPLP
|
|
JMP PROMPT
|
|
;
|
|
;Check for control-C or S
|
|
;
|
|
CTLCS:
|
|
CALL CONST ;CHAR AVAILABLE?
|
|
ORA A
|
|
JNZ GETC
|
|
ORI 1 ;NO CHAR, RETURN NZ
|
|
RET
|
|
;
|
|
GETC: CALL CONIN ;INPUT CHAR
|
|
ANI 1FH ;ALLOW ASCII
|
|
CPI 'S'-40H ;WAIT FOR NEXT CHAR IF ^S OR S OR s
|
|
CZ CONIN
|
|
CPI 'C'-40H ;CHECK FOR ^C OR C OR c
|
|
RET ;0 SET IF CTL-C
|
|
;
|
|
;Initialize Memory Buffers
|
|
;
|
|
INITP:
|
|
XRA A ;A=0
|
|
STA HEXAD ;CLEAR ADDRESS
|
|
STA HEXAD+1
|
|
STA PFLAG ;SET NO PRINT
|
|
STA SAVEFL ;SET NO SAVE DONE
|
|
STA WRFLG ;MAY NOT WRITE
|
|
STA DIRPOS ;SET NO DIRECTORY POSITION
|
|
STA FINDFL ;SET NO POSITION
|
|
INR A ;A=1
|
|
STA FTSW ;SET SEARCH WITHOUT INCREMENT
|
|
STA NOTPOS ;NOT POSITIONED
|
|
LXI H,0 ;HL=0
|
|
SHLD QCNT ;SET NO ELEMENTS IN QUEUE
|
|
SHLD MFPTR ;SET NO MULTI FILE PTR
|
|
SHLD CURTRK ;SET TRACK 0
|
|
INX H ;HL=1
|
|
SHLD CURSEC ;SET LOGICAL SECTOR 1
|
|
SHLD PHYSEC ;SET PHYSICAL SECTOR 1
|
|
LHLD PINBUF ;SET PREVIOUS COMMAND TO NIL
|
|
MVI M,CR ;CLEAR PREVIOUS COMMAND
|
|
LHLD DIRECT ;SET FIRST AND LAST QUEUE ELEMENT PTRS
|
|
SHLD QNXT
|
|
SHLD QLST
|
|
|
|
; Initialize Default Macros -- new block by <JPS>
|
|
|
|
LHLD MTABL ;CLEAR MACRO TABLE
|
|
MVI B,10 ;10 ENTRIES
|
|
lxi d,imac0 ;point to beginning of default macro table
|
|
|
|
initp1: push h ;save pointer to start of each macro
|
|
|
|
initp2: ldax d ;get next initial macro character
|
|
mov m,a ;store it in macro table
|
|
inx d
|
|
inx h
|
|
cpi cr ;end of macro?
|
|
jnz initp2
|
|
|
|
pop h ;retrieve pointer to start of this macro
|
|
dcr b ;see if we've done all macros
|
|
rz ;if so, return
|
|
inr h ;point to next macro
|
|
jmp initp1
|
|
|
|
;INITP1:
|
|
; MVI M,CR ;STORE <CR>
|
|
; INR H ;PT TO NEXT PAGE
|
|
; DJNZ INITP1
|
|
; RET
|
|
|
|
; End of Block Changed by <JPS>
|
|
|
|
;
|
|
;Set up flags, etc, at initialization
|
|
;Find our way at initialization
|
|
;
|
|
GETSTP:
|
|
PUSH H
|
|
LHLD INBUF ;PT TO INPUT BUFFER
|
|
MVI M,CR ;INITIALIZE INPUT BUFFER
|
|
POP H
|
|
MVI C,SUSER ;GET USER NUMBER
|
|
MVI E,0FFH ;GET USER
|
|
CALL BDOS
|
|
STA UNUM ;SET USER NUMBER
|
|
MVI C,GETDSK
|
|
CALL BDOS ;GET CURRENT DISK
|
|
MOV C,A ;WE HAVE TO SELECT
|
|
JMP SELECT ;TO GET THE DPH
|
|
;
|
|
;COMMAND: L
|
|
;Log in the selected disk
|
|
;
|
|
LOGIN:
|
|
CALL DOLOG
|
|
JMP PROMPT
|
|
;
|
|
DOLOG:
|
|
MOV A,M ;DISK REQUESTED?
|
|
LXI D,0
|
|
CPI CR ;NO REQUEST OF PHYSICAL EOL
|
|
JZ LGNODK
|
|
CPI EOLCH ;NO REQUEST IF LOGICAL EOL
|
|
JZ LGNODK
|
|
CALL UPCASE ;CAPITALIZE
|
|
INX H ;POINT TO NEXT CHAR
|
|
SUI 'A' ;CONVERT TO 0-15
|
|
MOV C,A ;DISK NUMBER IN C
|
|
LDA MDISK ;GET MAX DISK
|
|
MOV B,A ;... IN B
|
|
MOV A,C
|
|
CMP B
|
|
JC SELECT
|
|
CALL ILPRT
|
|
DB 'Disk Letter Out of Range',CR,LF,0
|
|
JMP PRMPTR
|
|
;
|
|
;Select Disk Whose Number is in C (A=0, B=1, etc)
|
|
;
|
|
SELECT:
|
|
PUSH H ;SAVE PTR TO NEXT COMMAND LETTER
|
|
MOV A,C
|
|
STA DRIVE ;REMEMBER LATER WHERE WE ARE
|
|
;
|
|
VSELDK: CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
MOV A,H
|
|
ORA L
|
|
JZ WHAT ;SELECT ERROR
|
|
MOV E,M ;GET THE SECTOR TABLE PNTR
|
|
INX H
|
|
MOV D,M
|
|
INX H
|
|
XCHG
|
|
SHLD SECTBL ;SET THE SECTOR TABLE PTR
|
|
LXI H,8 ;OFFSET TO DPBPTR
|
|
DAD D
|
|
MOV A,M ;PICK UP DPB POINTER
|
|
INX H ; TO USE
|
|
MOV H,M ; AS PARAMETER
|
|
MOV L,A ; TO LOGIT
|
|
CALL LOGIT
|
|
LHLD SYSTRK ;RESET TRACK AND SECTOR
|
|
XCHG ; TO DIRECTORY
|
|
CALL SETTRK ; ON EVERY
|
|
LXI D,1 ; LOGIN
|
|
CALL SETSEC ; CHANGE
|
|
LHLD PHYSEC ;THIS LOGIC WILL TELL
|
|
MOV A,H ; IF FIRST SEC
|
|
ORA L ; IS PHYSICAL 0
|
|
STA FIRST0
|
|
CALL CLCSUB ;CALCULATE WHAT GROUP/GRPDISP WE ARE IN
|
|
POP H ;GET PTR TO NEXT LETTER
|
|
;
|
|
LGNODK:
|
|
CALL NORITE ;SET NO DISK I/O DONE (NO POSITION)
|
|
RET
|
|
;
|
|
;Read in the disk directory
|
|
;
|
|
REDDIR:
|
|
PUSH H ;SAVE PTR TO NEXT LETTER
|
|
CALL NORITE ;POSITIONING LOST
|
|
LHLD SYSTRK ;SAVE CURRENT TRACK
|
|
SHLD CURTRK
|
|
LXI H,1 ;SET SECTOR 1
|
|
SHLD CURSEC
|
|
LHLD DRM ;GET DIR SIZE FROM DPB
|
|
INX H ;MAKE 1-RELATIVE
|
|
CALL ROTRHL
|
|
CALL ROTRHL ;DIVIDE BY 4 (4 NAMES/SECTOR)
|
|
MOV B,H ;BC=NUMBER OF BLOCKS TO READ
|
|
MOV C,L
|
|
XCHG
|
|
LHLD DIRECT ;DMA ADDR
|
|
XCHG ;... IN DE
|
|
;
|
|
;Read Disk Directory Loop
|
|
;
|
|
RDIRLP:
|
|
PUSH B ;SAVE REGS
|
|
PUSH D
|
|
MOV B,D ;BC=DMA ADDRESS
|
|
MOV C,E
|
|
LDA BDOS+2 ;CHECK MEM AVAIL
|
|
DCR A ;ARE WE RNNING INTO BDOS?
|
|
CMP D
|
|
JC MEMFUL ;MEMORY FULL ERROR IF SO
|
|
CALL SETDMA ;SET DMA ADDRESS TO THAT IN BC
|
|
LHLD CURTRK ;SET TRACK
|
|
XCHG
|
|
CALL SETTRK
|
|
LHLD CURSEC ;SET SECTOR
|
|
XCHG
|
|
CALL SETSEC
|
|
CALL READ ;READ DIRECTORY BLOCK
|
|
CALL NXTSEC ;INCREMENT TO NEXT SECTOR
|
|
POP D
|
|
POP B
|
|
LXI H,80H ;ADVANCE TO NEXT DMA ADDRESS
|
|
DAD D
|
|
XCHG ;DE=NEXT DMA ADDRESS
|
|
DCX B ;COUNT DOWN DIRECTORY BLOCKS
|
|
MOV A,B
|
|
ORA C
|
|
JNZ RDIRLP
|
|
LXI B,TBUFF ;RESET DMA ADDRESS TO TBUFF
|
|
CALL SETDMA
|
|
POP H ;GET PTR TO NEXT CHAR
|
|
RET
|
|
;
|
|
;COMMAND: M
|
|
;Map the directory
|
|
;
|
|
MAP:
|
|
PUSH H ;SAVE PTR
|
|
LHLD QCNT ;GET COUNT
|
|
MOV A,H
|
|
ORA L
|
|
POP H
|
|
JZ MAP1 ;PROCEED IF QUEUE EMPTY
|
|
CALL ILPRT ;PRINT ABORT MESSAGE
|
|
DB CR,LF,'MAP not permitted -- Block Queue would be overlaid',0
|
|
JMP PRMPTR
|
|
MAP1:
|
|
CALL PAGSET ;SET PAGING COUNTER
|
|
XRA A
|
|
STA ONLY1 ;SET FLAG FOR ALL GROUPS (NOT ONLY 1)
|
|
CALL REDDIR ;READ IN DIRECTORY
|
|
MVI C,0 ;INIT START GRP #
|
|
LDA AL0 ;READ DIR GRP BITS
|
|
CALL COLECT ;COLLECT COUNT OF DIR GRPS..
|
|
LDA AL1 ;..IN REGISTER C
|
|
CALL COLECT
|
|
MVI B,0 ;BC NOW HAS A DEFAULT START GRP #
|
|
CALL HEXIN ;GET SPECIFIED GROUP IF ANY
|
|
PUSH H ;SAVE INBUF PTR
|
|
MOV A,E ;GET START
|
|
ORA D ;NOTHING?
|
|
JZ MAPDF ;..YES, DFLT
|
|
MVI A,0FFH ;SET FLAG FOR ONLY 1 GROUP
|
|
STA ONLY1
|
|
MOV B,D ;GET VALUE IN BC
|
|
MOV C,E
|
|
;
|
|
MAPDF:
|
|
CALL HEXB ;PRINT FIRST GROUP NUMBER
|
|
MVI A,'-' ;PRINT SEPARATOR
|
|
CALL TYPE
|
|
MVI A,' ' ;SET NO DUPLICATES
|
|
STA DUPFLG
|
|
CALL GETGRP ;GET GRP(C) TO HL
|
|
;
|
|
MAPCNT:
|
|
INX B ;NEXT GRP #
|
|
PUSH H
|
|
LHLD DSM ;GET HIGHEST GRP #
|
|
INX H ;PLUS 1 FOR COMPARISON
|
|
MOV A,L ;WHEN BC REACHES DSM+1..
|
|
CMP C ;..THEN WE HAVE EXCEEDED..
|
|
JNZ MAPC1 ;..THE DISK CAPACITY..
|
|
MOV A,H
|
|
CMP B
|
|
;
|
|
MAPC1:
|
|
POP H
|
|
JZ MAPEND ;..AND WE ARE DONE
|
|
PUSH H
|
|
CALL GETGRP ;GET ANOTHER
|
|
POP D ;SEE IF SAME
|
|
CALL CTLCS ;ABORT?
|
|
JZ MAPND2
|
|
MOV A,D
|
|
CMP H
|
|
JNZ MAPDIF
|
|
MOV A,E
|
|
CMP L
|
|
JZ MAPCNT ;SAME, CONTINUE
|
|
;
|
|
;Different file encountered
|
|
;
|
|
MAPDIF:
|
|
DCX B
|
|
CALL HEXB ;PRINT ENDING GROUP NUMBER
|
|
INX B
|
|
XCHG
|
|
CALL MAPNAM ;PRINT FILE NAME
|
|
LDA ONLY1 ;ONLY 1 NAME TO BE PRINTED?
|
|
ORA A ;0=NO
|
|
JNZ MAPND1
|
|
JMP MAPDF
|
|
;
|
|
;End of map
|
|
;
|
|
MAPEND:
|
|
DCX B ;GET LAST
|
|
CALL HEXB ;PRINT LAST GROUP NUMBER
|
|
CALL MAPNAM ;PRINT FILE NAME
|
|
CALL WAIT ;DELAY FOR USER
|
|
MAPND1:
|
|
POP H
|
|
CALL CRLF ;NEW LINE
|
|
;
|
|
;End of map - reposition to previous group
|
|
;
|
|
MAPND2:
|
|
PUSH H
|
|
LHLD GROUP ;POINT TO GROUP IN DE
|
|
XCHG
|
|
JMP POSGP2
|
|
;
|
|
;Print file name pointed to by HL
|
|
;
|
|
MAPNAM:
|
|
CALL SPACE ;LEADING SPACE
|
|
MOV A,H
|
|
ORA L ;NONE?
|
|
JZ NONAME
|
|
MOV A,M ;SEE IF ALLOC
|
|
CPI 0E5H ;FREE?
|
|
MVI A,' ' ;MARK ALLOCATED
|
|
JNZ MPNSP1
|
|
MVI A,'(' ;MARK NOT ALLOCATED (ERASED FILE)
|
|
;
|
|
MPNSP1:
|
|
CALL TYPE ;PRINT ALLOCATION INDICATOR (SPACE OR '(')
|
|
PUSH H ;SAVE POINTER
|
|
MOV A,M
|
|
CALL HEX ;SHOW USER NUMBER
|
|
CALL SPACE
|
|
INX H ;SKIP USER BYTE
|
|
PUSH B
|
|
MVI B,8 ;PRINT FILE NAME
|
|
CALL MAPN2
|
|
MVI A,'.' ;PRINT DECIMAL SEPARATOR
|
|
CALL TYPE
|
|
MVI B,3 ;PRINT FILE TYPE
|
|
CALL MAPN2
|
|
LDA DUPFLG ;DUPLICATE?
|
|
CALL TYPE ;SPACE OR STAR
|
|
POP B
|
|
MOV A,M ;GET EXT
|
|
CALL HEX ;PRINT EXTENT NUMBER
|
|
POP H
|
|
MOV A,M
|
|
CPI 0E5H ;DELETED ENTRY?
|
|
MVI A,' ' ;PRINT ENDING SPACE
|
|
JNZ MPNSP2
|
|
MVI A,')' ;PRINT ALLOCATION FLAG
|
|
;
|
|
MPNSP2:
|
|
CALL TYPE ;")" IF ERASED FILE OR SPACE IF NOT
|
|
JMP FLIP
|
|
;
|
|
NONAME:
|
|
CALL ILPRT
|
|
DB DIM,' ++ Free ++ ',BRIGHT,0
|
|
;
|
|
FLIP:
|
|
LDA TWOUP ;FLIP FLAG FOR TWO ENTRIES PER LINE
|
|
XRI 1
|
|
STA TWOUP
|
|
JZ PAGER ;NEW LINE WITH PAGING IF REQUIRED
|
|
;
|
|
DELIM:
|
|
MVI A,':' ;PRINT DELIMITER BETWEEN ADJACENT ENTRIES ON LINE
|
|
CALL TYPE
|
|
JMP SPACE
|
|
;
|
|
;Print name pted to by HL, length in B
|
|
;
|
|
MAPN2:
|
|
MOV A,M
|
|
ANI 7FH ;STRIP POSSIBLE 2.x ATTRIBUTE BIT
|
|
INX H
|
|
CPI ' ' ;PRINTABLE?
|
|
JC MAPN2H ;..NO, IN HEX
|
|
CPI 7EH ;7E IS LEADIN ON SOME CRTS
|
|
JC MAPN2A
|
|
;
|
|
MAPN2H:
|
|
CALL BHEX ;PRINT A AS HEX CHARS
|
|
JMP MAPN2Z
|
|
;
|
|
MAPN2A:
|
|
CALL TYPE ;PRINT AS CHAR
|
|
;
|
|
MAPN2Z:
|
|
DJNZ MAPN2
|
|
RET
|
|
;
|
|
;Find which file group (BC) belongs to
|
|
;
|
|
GETGRP:
|
|
LHLD DRM ;MAX DIR ENTRY #
|
|
INX H ;MAKE 1-RELATIVE
|
|
SHLD FILECT
|
|
LXI H,0
|
|
SHLD MFPTR ;SET MULTI-FILE (MORE THAN ONE USER) PTR
|
|
LHLD DIRECT ;PT TO DIRECTORY
|
|
;
|
|
GETGLP:
|
|
PUSH H ;SAVE POINTER TO NAME
|
|
MOV A,M ;PICK UP DN BYTE
|
|
CPI 0E5H ;ERASED?
|
|
JZ GETGNF
|
|
LXI D,14 ;NOW GET RECORD COUNT
|
|
DAD D ; S2 PORTION ..
|
|
MOV A,M ; IS 0 IN CP/M 1.4
|
|
ANI 0FH
|
|
MOV E,A
|
|
INX H
|
|
MOV A,M
|
|
ORA E
|
|
JZ GETGNF
|
|
MVI E,16 ;FIRST SET FOR 8-BIT GRPS
|
|
LDA DSM+1
|
|
ORA A
|
|
JZ SMALGP
|
|
MVI E,8 ;NOPE, BIG GROUPS
|
|
;
|
|
SMALGP:
|
|
MOV D,A ;SAVE GRP SIZE INDICATOR
|
|
;
|
|
GETGL2:
|
|
INX H ;POINTING INTO DM FIELD
|
|
CALL GRPCMP ;COMPARE BC GP # AGAINST 1 DM FLD
|
|
JNZ NOTGOT ;JUMP IF NOT FOUND
|
|
;
|
|
;Found the file
|
|
;
|
|
PUSH H ;SAVE GROUP PTR
|
|
LHLD MFPTR
|
|
MOV A,H ;ANY ENTRIES?
|
|
ORA L
|
|
POP H ;GET PTR
|
|
XTHL ;SAVE ENTRY START AND SAVE PTR
|
|
JZ MPFRST ;IF ZERO, THEN FIRST ENTRY
|
|
MVI A,'*' ;SET MULTI FLAG
|
|
STA DUPFLG
|
|
MPFRST:
|
|
SHLD MFPTR ;SAVE POINTER
|
|
XTHL ;RESTORE ENTRY START AND GET PTR
|
|
NOTGOT:
|
|
DCR E ;COUNT DOWN
|
|
JNZ GETGL2 ;GO TEST SOME MORE
|
|
;
|
|
GETGNF:
|
|
POP H ;NOT THIS ONE
|
|
LXI D,32 ;SO GO TO NEXT
|
|
DAD D
|
|
XCHG
|
|
LHLD FILECT ;THERE IS LIMIT TO EVERYTHING
|
|
DCX H
|
|
SHLD FILECT
|
|
MOV A,H
|
|
ORA L
|
|
XCHG ;RE-ALIGN
|
|
JNZ GETGLP
|
|
;
|
|
;Set the allocation address, if any
|
|
;
|
|
LHLD MFPTR ;GET ADDRESS
|
|
RET
|
|
;
|
|
;COMMAND: <
|
|
;Save the current sector
|
|
; Special Form of <S saves current block onto queue
|
|
; Special Form of <G saves indicated group onto queue
|
|
;
|
|
SAVE:
|
|
LDA WRFLG ;READ DONE?
|
|
ORA A
|
|
JZ BADW ;NONE TO SAVE
|
|
MOV A,M ;CHECK FOR 'S'
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI 'B' ;BLOCK SAVE
|
|
JZ QSAV ;SAVE ON STACK
|
|
CPI 'G' ;GROUP SAVE
|
|
JZ SAVEG
|
|
PUSH H
|
|
LHLD SAVBUF ;PT TO SAVBUF
|
|
XCHG ;COPY INTO SAVBUF
|
|
LXI H,TBUFF ;FROM TBUFF
|
|
MVI B,128 ;128 BYTES
|
|
CALL MOVE
|
|
MVI A,1 ;..SHOW
|
|
STA SAVEFL ;..SAVED EXISTS
|
|
POP H ;GET PTR TO NEXT CHAR
|
|
JMP PROMPT
|
|
;
|
|
; Save Block on Queue
|
|
;
|
|
QSAV:
|
|
INX H ;SKIP OVER 2ND <
|
|
PUSH H ;SAVE PTR TO NEXT CHAR
|
|
LHLD QLST ;SEE IF ANOTHER SAVE WILL FILL QUEUE
|
|
LXI D,128 ;SET HL TO PT TO END OF NEXT SECTOR IN QUEUE
|
|
DAD D
|
|
XCHG ;DE PTS TO END OF NEXT BLOCK
|
|
QSAV0:
|
|
LHLD QNXT ;SEE IF QUEUE IS FULL NOW
|
|
MOV A,H ;MAY BE SAME
|
|
CMP D
|
|
JNZ QSAV1
|
|
MOV A,L ;MAY NOT BE SAME
|
|
CMP E
|
|
JZ QSAV2 ;QUEUE IS FULL, SO ABORT
|
|
QSAV1:
|
|
LHLD QLST ;GET PTR TO LAST QUEUE ELEMENT
|
|
XCHG ;... IN DE
|
|
LXI H,TBUFF ;COPY FROM TBUFF
|
|
MVI B,128 ;128 BYTES
|
|
CALL MOVE
|
|
CALL QWRAP ;CHECK FOR WRAP AROUND
|
|
XCHG ;HL PTS TO NEW LAST QUEUE POSITION
|
|
SHLD QLST ;SAVE HL
|
|
LHLD QCNT ;INCREMENT SECTOR COUNT
|
|
INX H
|
|
SHLD QCNT
|
|
CALL PRQCNT ;PRINT QUEUE COUNT
|
|
POP H ;PT TO NEXT CHAR
|
|
JMP PROMPT
|
|
QSAV2:
|
|
CALL ILPRT
|
|
DB 'Block Queue is Full -- Block Not Saved',CR,LF,0
|
|
LHLD QCNT ;GET COUNT
|
|
CALL PRQCNT ;PRINT COUNT
|
|
POP H ;PT TO NEXT CHAR
|
|
JMP PRMPTR
|
|
;
|
|
; PRINT NUMBER OF ELEMENTS IN QUEUE
|
|
;
|
|
PRQCNT:
|
|
CALL DEC ;PRINT AS DECIMAL
|
|
CALL ILPRT
|
|
DB DIM,' Blocks in Queue',BRIGHT,CR,LF,0
|
|
RET
|
|
;
|
|
; CHECK TO SEE IF QUEUE ELEMENT PTED TO BY DE SHOULD BE WRAPPED AROUND
|
|
; ON EXIT, DE PTS TO QUEUE ELEMENT WITH WRAP AROUND
|
|
;
|
|
QWRAP:
|
|
LHLD BDOS+1 ;CHECK FOR WRAP AROUND
|
|
MOV A,H
|
|
SUI 10 ;BELOW CCP
|
|
CMP D ;WRAP AROUND IF EQUAL
|
|
RNZ
|
|
XCHG
|
|
LHLD DIRECT ;NEXT ELEMENT IS HERE
|
|
XCHG ;... IN DE
|
|
RET
|
|
;
|
|
;This routine is common to Save Group (RG) and Write Group (WG); it is used
|
|
; to extract the group number, check it, and position DU3 to it
|
|
; On exit, GROUP = Group Number, GRPDIS = 0, and DU3 is positioned
|
|
;
|
|
COMG:
|
|
INX H ;PT TO CHAR AFTER 'G' OF '<G' COMMAND
|
|
PUSH H ;SAVE PTR TO NEXT CHAR
|
|
MOV A,M ;GET CHAR AFTER 'G'
|
|
LHLD GROUP ;GET CURRENT GROUP
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI EOLCH ;CURRENT IF LOGICAL EOL
|
|
JZ COMG1
|
|
CPI CR ;CURRENT IF PHYSICAL EOL
|
|
JZ COMG1
|
|
CALL HEXIN ;GET GROUP NUMBER IN HEX
|
|
LHLD DSM ;CHECK FOR BOUNDS ERROR
|
|
CALL SUBDE ;SUBTRACT GROUP NUMBER FROM DSM
|
|
POP H ;RESTORE PTR
|
|
JC OUTLIM ;LIMIT ERROR IF CARRY
|
|
PUSH H ;SAVE PTR AGAIN
|
|
XCHG ;SAVE GROUP NUMBER
|
|
SHLD GROUP
|
|
COMG1:
|
|
SHLD TGRP ;TEMPORARY GROUP NUMBER
|
|
XCHG ;GROUP NUMBER IN DE
|
|
XRA A ;A=0
|
|
STA GRPDIS ;SET GROUP DISPLACEMENT
|
|
CALL GTKSEC ;CONVERT GROUP NUMBER TO TRACK AND SECTOR
|
|
CALL SETTRK ;SET TRACK
|
|
XCHG
|
|
CALL SETSEC ;SET SECTOR
|
|
POP H ;GET PTR TO NEXT CHAR
|
|
RET
|
|
;
|
|
;This is the Save Group Routine; it copies the indicated group into the save
|
|
; buffer.
|
|
;
|
|
SAVEG:
|
|
CALL COMG ;EXTRACT COMMON GROUP INFO -- GROUP NUMBER AND POS
|
|
PUSH H
|
|
CALL ILPRT
|
|
DB 'Reading from Group ',0
|
|
LHLD GROUP ;GET CURRENT GROUP
|
|
MOV B,H ;VALUE IN BC
|
|
MOV C,L
|
|
CALL HEXB ;PRINT AS HEX
|
|
CALL ILPRT
|
|
DB CR,LF,0
|
|
LHLD QLST ;LAST PTR USED FOR READ
|
|
SHLD QPTR
|
|
POP H
|
|
MVI A,0 ;SET COPY FUNCTION TO SAVE
|
|
STA CPYFCT ;0=READ, 0FFH=WRITE
|
|
;
|
|
;Group Copy Routine -- if CPYFCT = 0, Read Group; if CPYFCT = 0FFH, Write Group
|
|
;
|
|
COPYG:
|
|
PUSH H ;SAVE PTR TO NEXT CHAR IN COMMAND LINE
|
|
CALL NORITE ;POSITIONING LOST
|
|
XCHG ;SAVE HL
|
|
LHLD QPTR ;PT TO NEXT QUEUE POSITION
|
|
XCHG ;... IN DE
|
|
LDA BLM ;GET NUMBER OF BLOCKS/GROUP
|
|
INR A ; ADD 1 TO BLM FOR CORRECT COUNT
|
|
MOV B,A ;COUNT IN B
|
|
;
|
|
COPYGL:
|
|
PUSH B ;SAVE COUNT
|
|
PUSH D ;SAVE PTR TO NEXT BLOCK TO LOAD
|
|
MOV B,D ;SET BC=DE FOR SET DMA
|
|
MOV C,E
|
|
CALL SETDMA ;SET ADDRESS TO LOAD
|
|
LDA CPYFCT ;READ OR WRITE?
|
|
ORA A ;0=READ
|
|
JNZ COPYGLW
|
|
CALL READ ;READ BLOCK
|
|
LHLD QCNT ;INCREMENT QUEUE ELEMENT COUNT
|
|
INX H
|
|
SHLD QCNT
|
|
JMP COPYGL0
|
|
COPYGLW:
|
|
LHLD QCNT ;QUEUE EMPTY?
|
|
MOV A,H
|
|
ORA L
|
|
JZ QEMPTY
|
|
CALL PWRITE ;WRITE BLOCK (NO CHECK)
|
|
LHLD QCNT ;DECREMENT QUEUE ELEMENT COUNT
|
|
DCX H
|
|
SHLD QCNT
|
|
COPYGL0:
|
|
CALL NXTSEC ;COMPUTE NEXT SECTOR ADDRESS
|
|
LHLD CURTRK ;GET NEXT TRACK ADDRESS
|
|
XCHG ;... IN DE
|
|
CALL SETTRK ;SET IT
|
|
LHLD CURSEC ;GET NEXT SECTOR ADDRESS
|
|
XCHG ;... IN DE
|
|
CALL SETSEC ;SET IT
|
|
POP D ;GET PTR TO NEXT BLOCK
|
|
POP B ;GET COUNTER
|
|
LXI H,80H ;OFFSET TO NEXT BLOCK
|
|
DAD D
|
|
SHLD QPTR
|
|
XCHG ;DE PTS TO NEXT BLOCK
|
|
CALL QWRAP ;ALLOW WRAP AROUND IN QUEUE
|
|
LDA CPYFCT ;0=READ
|
|
ORA A ;NO QUEUE OVERFLOW CHECK IF WRITE
|
|
JNZ COPYGL1
|
|
LHLD QNXT ;CHECK FOR QUEUE OVERFLOW
|
|
MOV A,H ;MUST NOT BE EQUAL
|
|
CMP D
|
|
JNZ COPYGL1
|
|
MOV A,L
|
|
CMP E
|
|
JZ QSAV2
|
|
COPYGL1:
|
|
DJNZ COPYGL ;LOOP UNTIL FINISHED
|
|
LHLD QCNT ;PRINT COUNT
|
|
CALL PRQCNT
|
|
LHLD QPTR ;GET QUEUE PTR
|
|
LDA CPYFCT ;RESET PROPER QUEUE PTR
|
|
ORA A ;0=READ
|
|
JZ COPYGL2
|
|
SHLD QNXT ;NEXT PTR USED FOR WRITE
|
|
JMP COPYGL3
|
|
COPYGL2:
|
|
SHLD QLST ;LAST PTR USED FOR READ
|
|
COPYGL3:
|
|
LXI B,TBUFF ;RESET DMA ADDRESS
|
|
CALL SETDMA
|
|
XRA A ;A=0
|
|
STA WRFLG ;SET NO READ DONE
|
|
LHLD TGRP ;GET GROUP NUMBER
|
|
XCHG ;... IN DE
|
|
POP H ;GET PTR TO NEXT CHAR
|
|
JMP POSGRP ;POSITION TO GROUP IN DE AND CONTINUE PROCESSING
|
|
;
|
|
;COMMAND: >
|
|
;Restore the current sector
|
|
; Special Form >S gets next block from queue
|
|
; Special Form >G gets next group from queue
|
|
;
|
|
RESTOR:
|
|
MOV A,M ;CHECK FOR SPECIAL FORM
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI 'B' ;BLOCK SAVE?
|
|
JZ QRESTOR
|
|
CPI 'G' ;GROUP SAVE?
|
|
JZ RESTRG
|
|
LDA SAVEFL ;SAVE DONE PREVIOUSLY?
|
|
ORA A
|
|
JZ NOSAVE ;NONE TO SAVE
|
|
PUSH H
|
|
LHLD SAVBUF ;COPY FROM SAVBUF
|
|
LXI D,TBUFF ;INTO TBUFF
|
|
MVI B,128 ;128 BYTES
|
|
CALL MOVE
|
|
POP H ;GET PTR TO NEXT CHAR
|
|
JMP PROMPT
|
|
;
|
|
; Restore Sector from Queue
|
|
;
|
|
QRESTOR:
|
|
INX H ;PT TO NEXT CHAR
|
|
PUSH H ;SAVE PTR ON STACK
|
|
LHLD QCNT ;GET ELEMENT COUNT
|
|
MOV A,H ;EMPTY?
|
|
ORA L
|
|
JZ QEMPTY ;ABORT IF EMPTY
|
|
DCX H ;COUNT DOWN
|
|
SHLD QCNT
|
|
CALL PRQCNT ;PRINT COUNT
|
|
LHLD QNXT ;PT TO NEXT ELEMENT IN QUEUE
|
|
LXI D,TBUFF ;COPY INTO TBUFF
|
|
MVI B,128 ;128 BYTES
|
|
CALL MOVE
|
|
XCHG ;DE=PTR TO NEXT ELEMENT IN QUEUE
|
|
CALL QWRAP ;CHECK FOR WRAP AROUND
|
|
XCHG ;HL PTS TO NEXT ELEMENT IN QUEUE
|
|
SHLD QNXT ;SAVE PTR
|
|
POP H ;RESTORE PTR
|
|
JMP PROMPT
|
|
QEMPTY:
|
|
CALL ILPRT
|
|
DB 'Error -- Queue Empty',CR,LF,0
|
|
POP H ;RESTORE NEXT CHAR PTR
|
|
JMP PRMPTR
|
|
;
|
|
;Write Group Loaded in GBUFF to Disk
|
|
;
|
|
RESTRG:
|
|
CALL COMG ;GET GROUP NUMBER FROM COMMAND LINE AND POS
|
|
PUSH H
|
|
CALL ILPRT
|
|
DB 'Writing to Group ',0
|
|
LHLD GROUP ;GET GROUP NUMBER
|
|
MOV B,H ;VALUE IN BC
|
|
MOV C,L
|
|
CALL HEXB ;PRINT IN HEX
|
|
CALL ILPRT
|
|
DB CR,LF,0
|
|
LHLD QNXT ;NEXT PTR USED FOR WRITE
|
|
SHLD QPTR
|
|
POP H
|
|
MVI A,0FFH ;WRITE FUNCTION
|
|
STA CPYFCT ;COPY FUNCTION FOR GROUP COPY ROUTINE
|
|
JMP COPYG ;GROUP COPY ROUTINE
|
|
;
|
|
NOSAVE:
|
|
CALL ILPRT
|
|
DB '++ No "<" Save Command Issued ++'
|
|
DB CR,LF,0
|
|
JMP PRMPTR
|
|
;
|
|
;Move (HL) to (DE) length in B
|
|
;
|
|
MOVE:
|
|
MOV A,M
|
|
STAX D
|
|
INX H
|
|
INX D
|
|
DJNZ MOVE
|
|
RET
|
|
;
|
|
NORITE:
|
|
XRA A ;GET 0
|
|
STA WRFLG ;CAN'T WRITE NOW
|
|
RET
|
|
;
|
|
;No match in search, try next char
|
|
;
|
|
SRNOMT:
|
|
POP H
|
|
CALL CTLCS ;ABORT?
|
|
JNZ SEARCH ;..YES
|
|
LHLD INBUF
|
|
MVI M,CR
|
|
JMP CLCGRP ;SHOW WHERE STOPPED
|
|
;
|
|
;COMMAND: =
|
|
;Search for character string
|
|
;
|
|
SEARCH:
|
|
PUSH H ;SAVE STRING POINTER
|
|
;
|
|
SRCHL:
|
|
CALL RDBYTE ;GET A BYTE
|
|
MOV B,A ;SAVE IT
|
|
MOV A,M ;CHECK NEXT MATCH CHAR.
|
|
CPI '<' ;WILL IT BE HEX?
|
|
MOV A,B ;RESTORE DISK CHAR
|
|
JZ SRCHL1
|
|
ANI 7FH ;NEXT CHAR IS ASCII...STRIP BIT 7
|
|
;
|
|
SRCHL1:
|
|
PUSH PSW
|
|
CALL GETVAL ;GET SEARCH VALUE
|
|
MOV B,A
|
|
POP PSW
|
|
CMP B ;MATCH?
|
|
JNZ SRNOMT ;NO MATCH
|
|
INX H
|
|
MOV A,M ;DONE?
|
|
CPI CR ;END OF LINE?
|
|
JZ SREQU
|
|
CPI EOLCH ;LOGICAL EOL?
|
|
JNZ SRCHL
|
|
;
|
|
;Got match
|
|
;
|
|
SREQU:
|
|
CALL ILPRT
|
|
DB '= at ',0
|
|
LDA BUFAD
|
|
ANI 7FH
|
|
CALL HEX
|
|
CALL CRLF
|
|
JMP CLCGRP
|
|
;
|
|
;Get value from input buffer
|
|
;
|
|
GETVAL:
|
|
MOV A,M ;GET NEXT CHAR
|
|
CPI '<' ;HEX ESCAPE?
|
|
RNZ ;NO, RETURN
|
|
;"<<" means one "<"
|
|
INX H
|
|
MOV A,M
|
|
CPI '<'
|
|
RZ
|
|
;Got hex
|
|
PUSH D
|
|
CALL HEXIN ;GET VALUE
|
|
CPI '>' ;PROPER DELIM?
|
|
MOV A,E ;GET VALUE
|
|
POP D
|
|
JNZ WHAT ;ERROR
|
|
RET
|
|
;
|
|
;Read a byte at a time from disk
|
|
;
|
|
RDBYTE:
|
|
PUSH H
|
|
LDA FTSW ;FIRST READ?
|
|
ORA A
|
|
JNZ READ1
|
|
LHLD BUFAD
|
|
MOV A,L
|
|
ORA A ;IN BUFFER?
|
|
JM NORD ;YES, SKIP READ
|
|
;
|
|
;Have to read
|
|
;
|
|
CALL NXTSEC ;ADVANCE TO NEXT BLOCK
|
|
;
|
|
READ1:
|
|
XRA A
|
|
STA FTSW ;NOT FIRST READ
|
|
LHLD CURSEC
|
|
XCHG
|
|
CALL SETSEC
|
|
LHLD CURTRK
|
|
XCHG
|
|
CALL SETTRK
|
|
CALL READ
|
|
CALL CLCSUB
|
|
LXI H,TBUFF
|
|
;
|
|
NORD:
|
|
MOV A,M
|
|
INX H
|
|
SHLD BUFAD
|
|
POP H
|
|
RET
|
|
;
|
|
;COMMAND: V
|
|
;View the file in ASCII starting at
|
|
;current sector, stepping thru the disk
|
|
;
|
|
VIEW:
|
|
LDA WRFLG
|
|
ORA A
|
|
JZ BADDMP
|
|
CALL DECIN ;GET DISPL IF ANY
|
|
PUSH H
|
|
MOV A,E
|
|
ORA A
|
|
JNZ VIEWLP
|
|
INR E ;DFLT=1
|
|
;
|
|
VIEWLP:
|
|
LXI H,TBUFF ;TO DATA
|
|
;
|
|
VEWCHR:
|
|
CALL CTLCS ;ABORT?
|
|
JZ VEWEND
|
|
MOV A,M ;GET NEXT CHAR
|
|
CPI 1AH ;EOF?
|
|
JZ VEWEOF
|
|
ANI 7FH ;MASK
|
|
CPI 7EH ;ESC CHAR FOR H1500
|
|
JNC VIEWHX ;SHOW RUBOUT AND TILDE AS HEX
|
|
CPI ' '
|
|
JNC VIEWPR
|
|
CPI CR ;CR PASS
|
|
JZ VIEWPR
|
|
CPI LF ;LF PASS
|
|
JZ VIEWPR
|
|
CPI TAB ;TAB PASS
|
|
JZ VIEWPR
|
|
;
|
|
VIEWHX:
|
|
MOV A,M ;NOT ASCII...PRINT AS <NN>
|
|
CALL BHEX
|
|
JMP VIEWNP
|
|
;
|
|
VIEWPR:
|
|
CALL TYPE
|
|
;
|
|
VIEWNP:
|
|
INR L
|
|
JNZ VEWCHR
|
|
DCR E
|
|
JZ VEWEND
|
|
PUSH D ;SAVE COUNT
|
|
CALL NXTSEC
|
|
LHLD CURSEC
|
|
XCHG
|
|
CALL SETSEC
|
|
LHLD CURTRK
|
|
XCHG
|
|
CALL SETTRK
|
|
CALL READ
|
|
POP D ;RESTORE COUNT
|
|
JMP VIEWLP
|
|
;
|
|
VEWEOF:
|
|
CALL ILPRT
|
|
DB CR,LF,DIM,' ++ EOF ++',BRIGHT,CR,LF,0
|
|
;
|
|
VEWEND:
|
|
POP H
|
|
CALL CRLF
|
|
JMP CLCGRP
|
|
;
|
|
;COMMAND: A or D
|
|
;Dump in hex or ASCII
|
|
;
|
|
DUMP:
|
|
LDA WRFLG
|
|
ORA A
|
|
JNZ DUMPOK
|
|
;
|
|
BADDMP:
|
|
CALL ILPRT
|
|
DB '++ Can''t dump, no sector read ++',CR,LF,0
|
|
;
|
|
EXPL:
|
|
CALL ILPRT
|
|
DB 'Use G command following F,',CR,LF
|
|
DB 'or R or S following T',CR,LF,0
|
|
JMP PRMPTR
|
|
;
|
|
DUMPOK:
|
|
MOV A,M ;GET NEXT CHAR
|
|
CPI EOLCH ;LOGICAL EOL?
|
|
JZ DUMPDF ;DFLT
|
|
CPI CR ;PHYSICAL EOL?
|
|
JNZ DMPNDF
|
|
;
|
|
;Use default
|
|
;
|
|
DUMPDF:
|
|
LXI B,TBUFF
|
|
LXI D,0FFH
|
|
JMP DUMP1
|
|
;
|
|
DMPNDF:
|
|
CALL DISP
|
|
MOV B,D
|
|
MOV C,E
|
|
CPI CR
|
|
JZ DUMP1
|
|
CPI EOLCH
|
|
JZ DUMP1
|
|
INX H ;SKIP SEPCH
|
|
CALL DISP
|
|
;
|
|
;BC = start, DE = end
|
|
;
|
|
DUMP1:
|
|
PUSH H ;SAVE COMMAND POINTER
|
|
MOV H,B
|
|
MOV L,C
|
|
;
|
|
DUMPLP:
|
|
CALL DUMPHL ;PERFORM DUMP OF DIR ENTRY AT HL
|
|
POP H ;RESTORE HL
|
|
JMP PROMPT
|
|
;
|
|
; PERFORM DUMP AT HL
|
|
;
|
|
DUMPHL:
|
|
CALL STNDOUT ;DIM
|
|
MOV A,L
|
|
ANI 7FH
|
|
CALL HEX ;PRINT HEX VALUE
|
|
CALL STNDEND ;BRIGHT
|
|
CALL SPACE
|
|
CALL SPACE
|
|
LDA DUMTYP
|
|
CPI 'A'
|
|
JZ DUMPAS
|
|
PUSH H ;SAVE START
|
|
;
|
|
; DUMP 16 BYTES STARTING AT HL (CHECK FOR DE TERMINATION)
|
|
;
|
|
DHEX:
|
|
MOV A,M
|
|
CALL HEX ;PRINT HEX VALUE PTED TO BY HL
|
|
MOV A,L
|
|
ANI 3
|
|
CPI 3 ;EXTRA SPACE EVERY 4
|
|
CZ SPACE
|
|
MOV A,L
|
|
ANI 7
|
|
CPI 7 ;TWO EXTRA SPACES EVERY 8
|
|
CZ SPACE
|
|
MOV A,E ;CHECK FOR END OF BYTES TO DUMP
|
|
CMP L
|
|
JZ DPOP
|
|
INX H
|
|
MOV A,L ;CHECK FOR END OF 16 BYTES
|
|
ANI 0FH
|
|
JNZ DHEX
|
|
;
|
|
DPOP:
|
|
CALL CTLCS ;ABORT?
|
|
JZ PRMPTR
|
|
LDA DUMTYP ;CHECK FOR ASCII ALSO
|
|
CPI 'H'
|
|
JZ DNOAS ;HEX ONLY
|
|
POP H ;GET START ADDR
|
|
;
|
|
; DUMP ASCII CHARS - HL PTS TO FIRST BYTE
|
|
;
|
|
DUMPAS:
|
|
CALL ASTER ;PRINT FIRST ASTERISK TO SEPARATE TEXT
|
|
;
|
|
DCHR:
|
|
MOV A,M ;GET CHAR
|
|
ANI 7FH
|
|
CPI ' '
|
|
JC DPER
|
|
CPI 7FH ;TRAP DEL
|
|
JC DOK
|
|
;
|
|
DPER:
|
|
MVI A,'.' ;PRINT PRINTING CHAR
|
|
;
|
|
DOK:
|
|
CALL TYPE ;PRINT CHAR
|
|
MOV A,E ;CHECK FOR END OF DUMP
|
|
CMP L
|
|
JZ DEND
|
|
INX H
|
|
MOV A,L ;CHECK FOR END OF 16 BYTES
|
|
ANI 0FH
|
|
JNZ DCHR
|
|
;
|
|
; END OF ASCII DUMP
|
|
;
|
|
DEND:
|
|
CALL ASTER ;PRINT ENDING ASTERISK
|
|
CALL CRLF ;NEW LINE
|
|
PUSH D
|
|
CALL CTLCS ;ABORT?
|
|
POP D
|
|
JZ PRMPTR
|
|
MOV A,E ;DONE WITH DUMP?
|
|
CMP L
|
|
JNZ DUMPHL
|
|
RET
|
|
;
|
|
; NO ASCII DUMP
|
|
;
|
|
DNOAS:
|
|
POP B ;CLEAR STACK (START ADDRESS OF DUMP)
|
|
CALL CRLF ;NEW LINE
|
|
MOV A,E ;DONE WITH DUMP?
|
|
CMP L
|
|
JNZ DUMPHL
|
|
RET
|
|
;
|
|
;COMMAND: G
|
|
;Position
|
|
;
|
|
POS:
|
|
PUSH PSW
|
|
MOV A,M
|
|
CPI EOLCH ;LOGICAL EOL?
|
|
JZ POSINQ
|
|
CPI CR ;PHYSICAL EOL?
|
|
JNZ POSOK
|
|
;
|
|
POSINQ:
|
|
POP PSW
|
|
JMP INQ
|
|
;
|
|
POSOK:
|
|
POP PSW
|
|
CPI 'T' ;TRACK?
|
|
JZ POSTKD
|
|
CPI 'S' ;SECTOR?
|
|
JZ POSSCD
|
|
CPI 'G' ;GROUP?
|
|
JZ POSGPH
|
|
JMP WHAT ;ERROR OTHERWISE
|
|
;
|
|
;Position to Track
|
|
;
|
|
POSTKD:
|
|
CALL DECIN ;GET NUMBER IN DECIMAL
|
|
;
|
|
POSTRK:
|
|
PUSH H
|
|
LHLD MAXTRK ;CHECK FOR BEYOND END OF DISK
|
|
CALL SUBDE
|
|
POP H
|
|
JC OUTLIM
|
|
CALL SETTRK ;SET TRACK
|
|
CALL NORITE ;TRACK DOESN'T READ
|
|
MVI A,1
|
|
STA NOTPOS ;SHOW NOT POSITIONED
|
|
JMP CLCGRP
|
|
;
|
|
;Position to Sector
|
|
;
|
|
POSSCD:
|
|
CALL DECIN ;GET NUMBER IN DECIMAL
|
|
MOV A,D
|
|
ORA E
|
|
JZ WHAT ;DON'T ALLOW SECTOR 0
|
|
;
|
|
POSSEC:
|
|
PUSH H
|
|
LHLD SPT ;CHECK FOR WITHIN RANGE
|
|
CALL SUBDE
|
|
POP H
|
|
JC WHAT
|
|
CALL SETSEC ;SET SECTOR
|
|
CALL READ ;READ
|
|
XRA A
|
|
STA NOTPOS ;POSITIONED OK
|
|
;
|
|
;Calculate Group Number/Group Displacement and Print
|
|
;
|
|
CLCGRP:
|
|
CALL CLCSUB
|
|
JMP INQ
|
|
;
|
|
;Calculate group from track and sector
|
|
; On exit, GROUP = Group Number and GRPDIS = Displacement within Group
|
|
;
|
|
CLCSUB:
|
|
PUSH H
|
|
LHLD SYSTRK
|
|
XCHG
|
|
LHLD CURTRK
|
|
CALL SUBDE ;COMPUTE RELATIVE TRACK NUMBER (SKIP SYSTEM TRACKS)
|
|
XCHG
|
|
LHLD SPT ;MULTIPLY BY NUMBER OF SECTORS/TRACK
|
|
CALL MULT
|
|
XCHG ;DE=TOTAL NUMBER OF SECTORS IN TRACKS
|
|
LHLD CURSEC ;GET SECTOR OFFSET FROM BEGINNING OF TRACK
|
|
DCX H
|
|
DAD D ;HL=TOTAL NUMBER OF SECTORS WITH OFFSET
|
|
LDA BLM
|
|
MOV B,A
|
|
MOV A,L
|
|
ANA B
|
|
STA GRPDIS ;DISPLACEMENT WITHIN GROUP
|
|
LDA BSH
|
|
MOV B,A
|
|
;
|
|
CLCLOP:
|
|
CALL ROTRHL
|
|
DJNZ CLCLOP
|
|
SHLD GROUP ;GROUP NUMBER
|
|
POP H
|
|
RET
|
|
;
|
|
;Position in the directory after a find
|
|
;(Does not work in CP/M-2.x)
|
|
;
|
|
POSDIR:
|
|
PUSH H ;SAVE INBUF
|
|
LHLD BSH
|
|
XRA A
|
|
STA FINDFL ;CANCEL POS REQ
|
|
LDA DIRPOS ;GET POSITION
|
|
RAR
|
|
RAR
|
|
PUSH PSW
|
|
ANA H
|
|
STA GRPDIS
|
|
POP PSW
|
|
;
|
|
POSDLP:
|
|
RAR
|
|
DCR L
|
|
JNZ POSDLP
|
|
ANI 1 ;GET GROUP
|
|
MOV L,A ;SETUP FOR POSGP2
|
|
MVI H,0
|
|
SHLD GROUP
|
|
XCHG
|
|
;
|
|
POSGP2:
|
|
CALL GTKSEC ;CONVERT GROUP TO SECTOR/TRACK
|
|
CALL SETTRK ;SET TRACK
|
|
XCHG
|
|
CALL SETSEC ;SET SECTOR
|
|
CALL READ ;READ BLOCK
|
|
XRA A
|
|
STA NOTPOS ;NOW POSITIONED
|
|
POP H
|
|
JMP INQ
|
|
;
|
|
;Position to Group
|
|
;
|
|
POSGPH:
|
|
CALL HEXIN ;GET PARAMETER
|
|
;
|
|
;Position to Group Numbered in DE and Print Position
|
|
;
|
|
POSGRP:
|
|
CALL DEGROUP ;GOTO GROUP
|
|
JC OUTLIM
|
|
JMP INQ ;PRINT POSITION
|
|
;
|
|
;Position to Group Numbered in DE
|
|
; Return with Carry Set if Out of Limits
|
|
;
|
|
DEGROUP:
|
|
PUSH H
|
|
LHLD DSM ;CHECK FOR WITHIN BOUNDS
|
|
CALL SUBDE
|
|
POP H
|
|
RC
|
|
PUSH H ;SAVE HL
|
|
XCHG
|
|
SHLD GROUP ;SET GROUP NUMBER
|
|
XCHG
|
|
XRA A
|
|
STA GRPDIS ;SET ZERO DISPLACEMENT
|
|
CALL GTKSEC ;CONVERT GROUP TO SECTOR/TRACK
|
|
CALL SETTRK ;SET TRACK
|
|
XCHG
|
|
CALL SETSEC ;SET SECTOR
|
|
CALL READ ;READ BLOCK
|
|
XRA A ;SET NC AND FLAG
|
|
STA NOTPOS ;NOW POSITIONED
|
|
POP H
|
|
RET
|
|
;
|
|
;Convert Group Number in DE to Sector and Track; also, GRPDIS = Offset in Grp
|
|
; On exit, DE = Track Number, HL = Sector Number
|
|
;
|
|
GTKSEC:
|
|
MOV H,D ;HL=GROUP NUMBER
|
|
MOV L,E
|
|
LDA BSH ;GET NUMBER OF SECTORS IN GROUP
|
|
;
|
|
GLOOP:
|
|
DAD H
|
|
DCR A
|
|
JNZ GLOOP
|
|
LDA GRPDIS ;ADD IN DISPLACEMENT WITHIN GROUP
|
|
ADD L ;CAN'T CARRY
|
|
MOV L,A
|
|
;
|
|
;Divide by number of sectors, quotient=track, remainder=sector
|
|
;
|
|
XCHG ;DE=TOTAL NUMBER OF SECTORS
|
|
LHLD SPT ;GET NUMBER OF SECTORS/TRACK
|
|
CALL NEG ;HL = -SECTORS/TRACK
|
|
XCHG
|
|
LXI B,0 ;SET TRACK COUNTER TO ZERO
|
|
;
|
|
DIVLP:
|
|
INX B ;INCREMENT TRACK COUNT
|
|
DAD D ;SUBTRACT SECTORS/TRACK FROM SECTORS TOTAL
|
|
JC DIVLP
|
|
DCX B ;ADJUST TRACK COUNT
|
|
XCHG
|
|
LHLD SPT ;ADD SECTORS/TRACK BACK IN TO ADJUST
|
|
DAD D ;HL=NUMBER OF SECTORS ON LAST TRACK OF GROUP
|
|
PUSH H
|
|
LHLD SYSTRK ;ADD IN NUMBER OF SYSTEM TRACKS
|
|
DAD B
|
|
XCHG ;DE=TRACK NUMBER
|
|
POP H
|
|
INX H ;HL=SECTOR NUMBER
|
|
RET
|
|
;
|
|
;COMMAND: F
|
|
;Find Directory Entry for specified file
|
|
;
|
|
POSFIL:
|
|
CALL NORITE
|
|
MVI A,1
|
|
STA FINDFL ;SO WE POSITION LATER
|
|
LXI D,FCB
|
|
XRA A ;LOGGED IN DISK
|
|
STAX D
|
|
INX D
|
|
MVI B,8
|
|
CALL MVNAME
|
|
MVI B,3
|
|
CALL MVNAME
|
|
MVI A,'?'
|
|
STAX D ;LOOK IN ALL EXTENTS
|
|
MVI A,'D' ;SET TYPE OF DUMP TO FULL
|
|
STA DUMTYP
|
|
PUSH H ;SAVE PTR TO NEXT CHAR
|
|
LXI D,FCB
|
|
MVI C,SRCHF
|
|
CALL BDOS
|
|
INR A
|
|
JNZ FLOK
|
|
STA DIRPOS ;GRP 0 IF NOT FOUND
|
|
CALL ILPRT
|
|
DB '++ File Not Found ++',CR,LF,0
|
|
POP H ;RESTORE PTR TO NEXT CHAR
|
|
JMP PROMPT
|
|
;
|
|
FLOK:
|
|
DCR A
|
|
STA DIRPOS ;SAVE POS. IN DIR
|
|
ANI 3
|
|
MOV L,A
|
|
MVI H,0
|
|
DAD H ;X32 BYTES/ENTRY
|
|
DAD H
|
|
DAD H
|
|
DAD H
|
|
DAD H
|
|
LXI D,TBUFF
|
|
DAD D ;HL POINTS TO ENTRY
|
|
LXI D,32
|
|
XCHG
|
|
DAD D
|
|
XCHG
|
|
CALL DUMPHL ;PRINT DIR ENTRY
|
|
LXI D,FCB ;LOOK FOR NEXT EXTENT
|
|
MVI C,SRCHN
|
|
CALL BDOS
|
|
INR A
|
|
JNZ FLOK
|
|
POP H ;RESTORE PTR TO NEXT CHAR
|
|
JMP PROMPT
|
|
;
|
|
MVNAME:
|
|
MOV A,M ;GET NEXT CHAR OF FILE NAME/TYPE
|
|
CPI '.' ;END OF FILE NAME?
|
|
JZ MVIPAD ;PAD OUT IF SO
|
|
CPI CR ;END OF ENTRY?
|
|
JZ PAD ;PAD OUT IF SO
|
|
CPI EOLCH ;END OF ENTRY?
|
|
JZ PAD ;PAD OUT IF SO
|
|
CALL UPCASE ;CAPITALIZE
|
|
STAX D ;STORE
|
|
INX H ;PT TO NEXT
|
|
INX D
|
|
DJNZ MVNAME
|
|
MOV A,M ;CHECK FOR ERROR
|
|
CPI CR ;OK IF EOL
|
|
RZ
|
|
CPI EOLCH ;OK IF LOGICAL EOL
|
|
RZ
|
|
INX H
|
|
CPI '.' ;OK IF DECIMAL
|
|
RZ
|
|
JMP WHAT
|
|
;
|
|
MVIPAD:
|
|
INX H
|
|
;
|
|
PAD:
|
|
MVI A,' ' ;PRINT PADDING SPACES
|
|
STAX D
|
|
INX D
|
|
DJNZ PAD
|
|
RET
|
|
;
|
|
;COMMAND: +
|
|
;Advance to Next Logical Sector
|
|
;
|
|
PLUS:
|
|
LXI D,1 ;DFLT TO 1 SECT
|
|
MOV A,M ;GET NEXT CHAR
|
|
CPI CR ;CR?
|
|
JZ PLUSGO ;..YES, DFLT TO 1
|
|
CPI EOLCH
|
|
JZ PLUSGO
|
|
CALL DECIN ;GET #
|
|
MOV A,D
|
|
ORA E
|
|
JNZ PLUSGO
|
|
LXI D,1 ;SET 1 IF VALUE OF ZERO
|
|
;
|
|
PLUSGO:
|
|
CALL NXTSEC ;ADVANCE TO NEXT LOGICAL SECTOR
|
|
DCX D ;MORE TO GO?
|
|
MOV A,D
|
|
ORA E
|
|
JNZ PLUSGO ;..YES
|
|
;
|
|
;Ok, incremented to sector. Setup and read
|
|
;
|
|
PLUSMI:
|
|
PUSH H
|
|
LHLD CURSEC
|
|
XCHG
|
|
CALL SETSEC ;SET SECTOR
|
|
LHLD CURTRK
|
|
XCHG
|
|
CALL SETTRK ;SET TRACK
|
|
POP H
|
|
CALL READ ;READ IT
|
|
JMP CLCGRP ;CALCULATE GROUP AND DISPLAY
|
|
;
|
|
;COMMAND: -
|
|
;Back up to previous sector
|
|
;
|
|
MINUS:
|
|
LXI D,1 ;SET DFLT
|
|
MOV A,M ;GET CHAR
|
|
CPI CR ;CR?
|
|
JZ MINGO ;..YES, DFLT=1
|
|
CPI EOLCH
|
|
JZ MINGO
|
|
CALL DECIN ;..NO, GET ##
|
|
MOV A,D
|
|
ORA E
|
|
JNZ MINGO
|
|
LXI D,1 ;ASSUME 1
|
|
;
|
|
MINGO:
|
|
CALL LSTSEC ;BACK UP ONE SECTOR
|
|
DCX D ;COUNT DOWN ON NUMBER OF TIMES TO BACKUP
|
|
MOV A,D
|
|
ORA E
|
|
JNZ MINGO
|
|
JMP PLUSMI ;READ BLOCK
|
|
;
|
|
;Go to last sector
|
|
; Wrap around to last sector of previous track or last sector of
|
|
; last track, as necessary
|
|
;
|
|
LSTSEC:
|
|
PUSH H
|
|
LHLD CURSEC ;BACK UP SECTOR
|
|
DCX H
|
|
MOV A,H
|
|
ORA L
|
|
JNZ LSEC1
|
|
LHLD CURTRK ;BEYOND SECTOR ZERO, SO BACK UP TRACK
|
|
MOV A,H
|
|
ORA L
|
|
JNZ LSEC0
|
|
LHLD MAXTRK ;WRAP TO END OF DISK
|
|
SHLD CURTRK
|
|
LHLD MAXSEC
|
|
JMP LSEC1
|
|
;
|
|
LSEC0:
|
|
DCX H
|
|
SHLD CURTRK
|
|
LHLD SPT ;GET NUMBER OF SECTORS/TRACK
|
|
;
|
|
LSEC1:
|
|
SHLD CURSEC ;SET NEW CURRENT SECTOR
|
|
POP H
|
|
RET
|
|
;
|
|
;Go to next sector
|
|
; On exit, CURSEC = Current Sector and CURTRK = Current Track
|
|
;
|
|
NXTSEC:
|
|
PUSH H
|
|
PUSH D
|
|
LHLD CURSEC ;INCREMENT CURRENT SECTOR
|
|
INX H
|
|
XCHG
|
|
LHLD SPT ;CHECK TO SEE IF BEYOND END OF TRACK
|
|
CALL SUBDE
|
|
XCHG
|
|
JNC NEXTOK
|
|
LHLD CURTRK ;BEYOND END OF TRACK, SO INCR CURRENT TRACK
|
|
INX H
|
|
XCHG
|
|
LHLD MAXTRK ;SEE IF BEYOND END OF DISK
|
|
CALL SUBDE
|
|
JNC TRASK
|
|
LXI D,0 ;WRAP TO START OF DISK
|
|
;
|
|
TRASK:
|
|
XCHG
|
|
SHLD CURTRK ;SET NEW CURRENT TRACK
|
|
LXI H,1 ;SET SECTOR 1
|
|
;
|
|
NEXTOK:
|
|
SHLD CURSEC ;SET NEW CURRENT SECTOR
|
|
POP D
|
|
POP H
|
|
RET
|
|
;
|
|
;Tell what group, displacement, track, sector, physical sector
|
|
;
|
|
INQ:
|
|
CALL INQSUB
|
|
JMP PROMPT
|
|
;
|
|
;Position inquiry subroutine
|
|
;Executed via: G S or T (with no operands)
|
|
;
|
|
INQSUB:
|
|
PUSH H
|
|
LHLD SYSTRK ;CHECK IF IN SYSTEM TRACKS
|
|
XCHG
|
|
LHLD CURTRK
|
|
CALL SUBDE
|
|
JC NOGRP
|
|
CALL ILPRT ;PRINT GROUP NUMBER IF NOT IN SYSTEM TRACKS
|
|
DB DIM,'Group = ',BRIGHT,0
|
|
LHLD GROUP
|
|
MOV B,H
|
|
MOV C,L
|
|
CALL HEXB ;PRINT GROUP NUMBER IN BC
|
|
MVI A,':'
|
|
CALL TYPE
|
|
LDA GRPDIS
|
|
CALL HEX ;PRINT GROUP DISPLACEMENT IN A
|
|
MVI A,','
|
|
CALL TYPE
|
|
;
|
|
NOGRP:
|
|
CALL ILPRT ;PRINT TRACK NUMBER
|
|
DB DIM,' Track = ',BRIGHT,0
|
|
LHLD CURTRK
|
|
CALL DEC ;TRACK NUMBER IN DECIMAL
|
|
CALL ILPRT ;PRINT SECTOR NUMBER
|
|
DB DIM,', Sector = ',BRIGHT,0
|
|
LHLD CURSEC
|
|
CALL DEC ;SECTOR NUMBER IN DECIMAL
|
|
CALL ILPRT ;PRINT PHYSCIAL SECTOR NUMBER
|
|
DB DIM,', Physical Sector = ',BRIGHT,0
|
|
LHLD PHYSEC
|
|
CALL DEC ;PHYSICAL SECTOR NUMBER IN DECIMAL
|
|
CALL CRLF
|
|
POP H
|
|
RET
|
|
;
|
|
;COMMAND: C
|
|
;Change Contents of Current Block
|
|
;
|
|
CHG:
|
|
MOV A,M ;GET TYPE (HEX, ASCII)
|
|
CALL UPCASE
|
|
PUSH PSW ;SAVE "H" OR "A"
|
|
INX H
|
|
CALL HEXIN ;GET DISP IN HEX
|
|
CALL DISP1 ;VALIDATE DISP TO DE
|
|
INX H
|
|
LXI B,0 ;SHOW NO 'THRU' ADDR
|
|
CPI '-' ;TEST DELIM FR. DISP
|
|
JNZ CHGNTH ;NO THRU
|
|
PUSH D ;SAVE FROM
|
|
CALL HEXIN
|
|
CALL DISP1 ;GET THRU
|
|
INX H ;SKIP END DELIM
|
|
MOV B,D
|
|
MOV C,E ;BC = THRU
|
|
POP D ;GET FROM
|
|
JMP CHGAH
|
|
;
|
|
CHGNTH:
|
|
CPI SEPCH
|
|
JNZ WHAT
|
|
;
|
|
CHGAH:
|
|
POP PSW
|
|
CPI 'H' ;HEX?
|
|
JZ CHGHEX
|
|
CPI 'A' ;ASCII?
|
|
JNZ WHAT
|
|
;
|
|
;Change ASCII
|
|
;
|
|
CHGALP:
|
|
MOV A,M ;GET CHAR
|
|
CPI CR
|
|
JZ PROMPT
|
|
CPI EOLCH
|
|
JZ PROMPT
|
|
;
|
|
;The following print of the deleted byte is commented out; if leading
|
|
; semicolons are removed, deleted bytes will be printed
|
|
;
|
|
; LDAX D ;GET BYTE THAT IS REPLACED
|
|
; CPI ' '
|
|
; JC CHGAHX
|
|
; CPI 7EH ;DON'T PRINT ESC CHAR FOR H1500
|
|
; JNC CHGAHX
|
|
; JMP CHGA2
|
|
;
|
|
;CHGAHX:
|
|
; CALL BHEX
|
|
; JMP CHGA3
|
|
;
|
|
;CHGA2:
|
|
; CALL TYPE
|
|
;
|
|
;End of print of delete bytes
|
|
;
|
|
CHGA3:
|
|
SHLD BACK ;IN CASE "THRU"
|
|
CALL GETVAL ;GET ASCII OR <HEX> VALUE
|
|
STAX D ;UPDATE BYTE
|
|
INX H ;PT TO NEXT INPUT CHAR
|
|
;
|
|
;See if 'THRU' requested
|
|
;
|
|
MOV A,C
|
|
ORA A
|
|
JZ CHANTH
|
|
CMP E ;DONE?..
|
|
JZ PROMPT ;..YES
|
|
LHLD BACK
|
|
;
|
|
CHANTH:
|
|
INR E
|
|
JNZ CHGALP
|
|
MOV A,M
|
|
CPI CR
|
|
JZ PROMPT
|
|
CPI EOLCH
|
|
JZ PROMPT
|
|
JMP WHAT
|
|
;
|
|
;Change hex
|
|
;
|
|
CHGHCM:
|
|
INX H
|
|
;
|
|
CHGHEX:
|
|
MOV A,M ;GET HEX DIGIT
|
|
CPI CR
|
|
JZ PROMPT
|
|
CPI EOLCH
|
|
JZ PROMPT
|
|
CPI SEPCH ;DELIM?
|
|
JZ CHGHCM
|
|
PUSH D
|
|
SHLD HEXAD ;IN CASE 'THRU'
|
|
CALL HEXIN ;POSITIONS TO DELIM
|
|
MOV A,E ;GET VALUE
|
|
POP D ;..ADDR
|
|
;
|
|
;The following comments out the echo of the deleted byte; removing the
|
|
; leading semicolons restores the echo
|
|
;
|
|
; PUSH PSW ;SAVE VALUE
|
|
; LDAX D ;GET OLD
|
|
; CALL HEX ;ECHO IN HEX
|
|
; POP PSW ;GET NEW
|
|
;
|
|
;End of echo of bytes
|
|
;
|
|
STAX D ;SAVE NEW BYTE
|
|
MOV A,C ;SEE IF 'THRU'
|
|
ORA A
|
|
JZ CHHNTH ;..NO.
|
|
CMP E ;..YES, DONE?
|
|
JZ PROMPT
|
|
LHLD HEXAD ;..NO: MORE
|
|
;
|
|
CHHNTH:
|
|
INR E
|
|
JNZ CHGHEX
|
|
MOV A,M
|
|
CPI CR
|
|
JZ PROMPT
|
|
CPI EOLCH
|
|
JZ PROMPT
|
|
JMP WHAT
|
|
;
|
|
;COMMAND: R
|
|
;Read Current Block into TBUFF
|
|
;COMMAND: RG
|
|
;Read Specified Group into GBUFF
|
|
;
|
|
DOREAD:
|
|
LDA NOTPOS ;POSITIONED?
|
|
ORA A
|
|
JNZ CANTRD
|
|
CALL READ ;READ BLOCK
|
|
JMP PROMPT
|
|
;
|
|
CANTRD:
|
|
CALL ILPRT
|
|
DB '++ Can''t read - not positioned ++',CR,LF
|
|
DB 'Position by:',CR,LF
|
|
DB ' Track then Sector, or',CR,LF
|
|
DB ' Group',CR,LF,0
|
|
JMP PROMPT
|
|
;
|
|
;COMMAND: W
|
|
;Write Current Block to Disk
|
|
;COMMAND: WG
|
|
;Write Specified Group from GBUFF
|
|
;
|
|
DORITE:
|
|
CALL WRITE ;DO WRITE
|
|
JMP PROMPT
|
|
;
|
|
;Print Byte in A as Hex Digits
|
|
;
|
|
BHEX:
|
|
PUSH PSW
|
|
MVI A,'<'
|
|
CALL TYPE
|
|
POP PSW
|
|
CALL HEX
|
|
MVI A,'>'
|
|
CALL TYPE
|
|
RET
|
|
;
|
|
;Print Number in BC as Hex Digits
|
|
; HEXB does not print MS Byte if DSM shows small disk size
|
|
; HEXB1 prints BC regardless
|
|
;
|
|
HEXB:
|
|
LDA DSM+1
|
|
ORA A
|
|
JZ HEXX
|
|
HEXB1:
|
|
MOV A,B
|
|
CALL HEX
|
|
;
|
|
HEXX:
|
|
MOV A,C
|
|
;
|
|
;Print Byte in A as 2 Hex Digits
|
|
;
|
|
HEX:
|
|
PUSH PSW
|
|
RAR ;GET HIGH NYBBLE
|
|
RAR
|
|
RAR
|
|
RAR
|
|
CALL NIBBL ;PRINT IT
|
|
POP PSW ;GET LOW NYBBLE
|
|
;
|
|
NIBBL:
|
|
ANI 0FH ;MASK LOW NYBBLE
|
|
CPI 10 ;0-9?
|
|
JC HEXNU
|
|
ADI 7 ;CONVERT TO A-F
|
|
;
|
|
HEXNU:
|
|
ADI '0' ;CONVERT TO ASCII
|
|
JMP TYPE ;PRINT IT
|
|
;
|
|
;Decimal output routine
|
|
; Print Number in HL as decimal digits
|
|
;
|
|
DEC:
|
|
PUSH B
|
|
PUSH D
|
|
PUSH H
|
|
XRA A ;SET NO LEADING DIGIT
|
|
STA DDIG
|
|
LXI B,10000
|
|
CALL DPRT
|
|
DAD B
|
|
LXI B,1000
|
|
CALL DPRT
|
|
DAD B
|
|
LXI B,100
|
|
CALL DPRT
|
|
DAD B
|
|
LXI B,10
|
|
CALL DPRT
|
|
DAD B
|
|
MOV A,L ;ALWAYS PRINT LSD
|
|
ADI '0' ;ASCII
|
|
CALL TYPE
|
|
POP H
|
|
POP D
|
|
POP B
|
|
RET
|
|
DPRT:
|
|
PUSH B ;SAVE BC
|
|
MVI D,0FFH ;SET -1
|
|
DPRTL:
|
|
INR D ;ADD 1 TO OUTPUT DIGIT
|
|
MOV A,L ;L-C
|
|
SUB C
|
|
MOV L,A
|
|
MOV A,H ;H-B
|
|
SBB B
|
|
MOV H,A
|
|
JNC DPRTL
|
|
POP B ;RESTORE BC
|
|
LDA DDIG ;GET LEADING DIGIT FLAG
|
|
ORA D ;CHECK FOR ZERO STILL
|
|
STA DDIG ;SET FLAG
|
|
MOV A,D ;GET DIGIT TO PRINT
|
|
RZ ;ABORT IF BOTH ZERO
|
|
ADI '0' ;ASCII
|
|
JMP TYPE
|
|
DDIG: DS 1 ;TEMP FOR DEC USE ONLY
|
|
;
|
|
;Print <SP>
|
|
;
|
|
SPACE:
|
|
MVI A,' '
|
|
JMP TYPE
|
|
;
|
|
;Print a dim '|'
|
|
;
|
|
ASTER:
|
|
CALL STNDOUT ;DIM
|
|
MVI A,'|'
|
|
CALL TYPE
|
|
JMP STNDEND ;BRIGHT
|
|
;
|
|
;Inline print routine
|
|
; Print Chars ending in 0 pted to by Return Address; return to byte after
|
|
;
|
|
ILPRT:
|
|
XTHL ;PT TO STRING
|
|
ILPLP:
|
|
CALL CTLCS ;ABORT?
|
|
JZ PRMPTR
|
|
MOV A,M ;GET CHAR
|
|
; CPI 1 ;PAUSE? -- ^A
|
|
; JNZ ILPOK
|
|
; CALL CONIN ;WAIT FOR ANY CHAR
|
|
; CPI 3 ;ABORT?
|
|
; JZ PRMPTR
|
|
; JMP ILPNX
|
|
;
|
|
;ILPOK:
|
|
CPI DIM ;GOTO DIM?
|
|
JZ ILPDIM
|
|
CPI BRIGHT ;GOTO BRIGHT?
|
|
JZ ILPBRI
|
|
CALL TYPE ;PRINT CHAR
|
|
JMP ILPNX
|
|
ILPDIM:
|
|
CALL STNDOUT ;ENTER STANDOUT MODE
|
|
JMP ILPNX
|
|
ILPBRI:
|
|
CALL STNDEND ;EXIT STANDOUT MODE
|
|
;
|
|
ILPNX:
|
|
INX H ;PT TO NEXT
|
|
MOV A,M ;GET IT
|
|
ORA A ;DONE?
|
|
JNZ ILPLP
|
|
INX H ;PT TO BYTE AFTER ENDING 0
|
|
XTHL ;RESTORE HL AND RET ADR
|
|
RET
|
|
;
|
|
;DISP calls DECIN, and validates a sector
|
|
;displacement, then converts it to an address
|
|
;
|
|
DISP:
|
|
CALL DECIN
|
|
DISP1:
|
|
PUSH PSW ;SAVE DELIMITER
|
|
MOV A,D
|
|
ORA A
|
|
JNZ BADISP
|
|
MOV A,E
|
|
ORA A
|
|
JM BADISP
|
|
ADI 80H ;TO POINT TO BUFFER AT BASE+80H
|
|
MOV E,A
|
|
MVI D,BASE/256
|
|
POP PSW ;GET DELIM
|
|
RET
|
|
;
|
|
BADISP:
|
|
CALL ILPRT
|
|
DB '++ Bad Displacement (Not 0-7FH) ++'
|
|
DB CR,LF,0
|
|
JMP PRMPTR
|
|
;
|
|
;Input Number from Command Line -- Assume it to be Hex
|
|
; Number returned in DE
|
|
;
|
|
HEXIN:
|
|
LXI D,0 ;INIT VALUE
|
|
MOV A,M
|
|
CPI '#' ;DECIMAL?
|
|
JZ HDIN ;MAKE DECIMAL
|
|
;
|
|
HINLP:
|
|
MOV A,M ;GET CHAR
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI CR ;EOL?
|
|
RZ
|
|
CPI EOLCH ;EOL?
|
|
RZ
|
|
CPI SEPCH
|
|
RZ
|
|
CPI ' ' ;SPACE?
|
|
RZ
|
|
CPI '-' ;'THRU'?
|
|
RZ
|
|
CPI '>'
|
|
RZ
|
|
INX H ;PT TO NEXT CHAR
|
|
CPI '0' ;RANGE?
|
|
JC WHAT
|
|
CPI '9'+1 ;RANGE?
|
|
JC HINNUM
|
|
CPI 'A' ;RANGE?
|
|
JC WHAT
|
|
CPI 'F'+1 ;RANGE?
|
|
JNC WHAT
|
|
SUI 7 ;ADJUST FROM A-F TO 10-15
|
|
;
|
|
HINNUM:
|
|
SUI '0' ;CONVERT FROM ASCII TO BINARY
|
|
XCHG
|
|
DAD H ;MULT PREVIOUS VALUE BY 16
|
|
DAD H
|
|
DAD H
|
|
DAD H
|
|
ADD L ;ADD IN NEW DIGIT
|
|
MOV L,A
|
|
XCHG
|
|
JMP HINLP
|
|
;
|
|
HDIN:
|
|
INX H ;SKIP '#'
|
|
;
|
|
;Input Number in Command Line as Decimal
|
|
; Number is returned in DE
|
|
;
|
|
DECIN:
|
|
LXI D,0
|
|
MOV A,M ; GET 1ST CHAR
|
|
CPI '#' ; HEX?
|
|
JNZ DINLP
|
|
INX H ; PT TO DIGIT
|
|
JMP HINLP ; DO HEX PROCESSING
|
|
;
|
|
DINLP:
|
|
MOV A,M ;GET DIGIT
|
|
CALL UPCASE ;CAPITALIZE
|
|
CPI '0' ;RANGE?
|
|
RC
|
|
CPI '9'+1 ;RANGE?
|
|
RNC
|
|
SUI '0' ;CONVERT TO BINARY
|
|
INX H ;PT TO NEXT
|
|
PUSH H
|
|
MOV H,D
|
|
MOV L,E
|
|
DAD H ;X2
|
|
DAD H ;X4
|
|
DAD D ;X5
|
|
DAD H ;X10
|
|
ADD L ;ADD IN DIGIT
|
|
MOV L,A
|
|
MOV A,H
|
|
ACI 0
|
|
MOV H,A
|
|
XCHG ;RESULT IN DE
|
|
POP H
|
|
JMP DINLP
|
|
;
|
|
;Read in a console buffer
|
|
;
|
|
RDBUF:
|
|
CALL ILPRT ;PRINT PROMPT
|
|
DB CR,LF,'DU3 ',0
|
|
LDA DRIVE ;GET DRIVE NUMBER
|
|
ADI 'A' ;CONVERT TO ASCII
|
|
CALL TYPE
|
|
LDA UNUM ;DISPLAY USER NUMBER
|
|
MOV L,A ;VALUE IN HL
|
|
MVI H,0
|
|
CALL DEC ;PRINT IN DECIMAL
|
|
CALL ILPRT ;PRINT PROMPT
|
|
DB '? ',0
|
|
;
|
|
;ENTRY POINT TO READ BUFFER WITHOUT PROMPT
|
|
;
|
|
RDBUF1:
|
|
LHLD INBUF ;USE CP/M READLN
|
|
DCX H
|
|
DCX H
|
|
XCHG
|
|
MVI C,10
|
|
PUSH D
|
|
CALL BDOS
|
|
POP D
|
|
INX D ;PT TO CHAR COUNT
|
|
LDAX D ;GET CHAR COUNT
|
|
MOV B,A ;CHAR COUNT IN B
|
|
INX D ;PT TO INPUT LINE
|
|
XCHG ;... IN HL
|
|
ADD L ;ADD CHAR COUNT TO HL
|
|
MOV L,A
|
|
MOV A,H
|
|
ACI 0
|
|
MOV H,A
|
|
MVI A,CR ;STORE ENDING CR
|
|
MOV M,A ;SET CR
|
|
CALL TYPE ;ECHO IT
|
|
MVI A,LF ;ECHO..
|
|
CALL TYPE ;..LF
|
|
LHLD INBUF ;SET PTR TO FIRST CHAR IN LINE
|
|
RET
|
|
;
|
|
;Set paging flag for page routine
|
|
;
|
|
PAGSET:
|
|
LDA PAGSIZ ;GET SIZE OF PAGE
|
|
STA PAGFLG ;SET FLAG
|
|
RET
|
|
;
|
|
;Page output
|
|
;
|
|
PAGER:
|
|
LDA PAGFLG ;GET FLAG
|
|
CPI 2 ;2 LINES LEFT?
|
|
JZ WAIT ;SAME AS USER DELAY
|
|
DCR A ;COUNT DOWN
|
|
STA PAGFLG
|
|
JMP CRLF
|
|
;
|
|
;Delay Routine
|
|
;
|
|
SWAIT:
|
|
CALL AT
|
|
DB 23,5 ;POSITION CURSOR
|
|
JMP WAIT0
|
|
WAIT:
|
|
CALL CRLF ;NEW LINE
|
|
WAIT0:
|
|
PUSH H
|
|
CALL ILPRT
|
|
DB DIM,'Type Any Character to Continue or ^C to Abort - ',BRIGHT,0
|
|
POP H
|
|
CALL CONIN ;GET RESPONSE
|
|
CPI 'C'-40H ;^C?
|
|
JZ WAIT1
|
|
CALL CRLF ;NEW LINE
|
|
CALL PAGSET ;RESET PAGE COUNT
|
|
RET
|
|
WAIT1:
|
|
LDA IHFLG ;INITIAL HELP?
|
|
ORA A ;0=NO
|
|
JZ PRMPTR ;ABORT TO COMMAND PROMPT
|
|
JMP EXIT1 ;ABORT TO CP/M
|
|
;
|
|
;CRLF Routine
|
|
;
|
|
CRLF:
|
|
MVI A,CR
|
|
CALL TYPE
|
|
MVI A,LF
|
|
JMP TYPE
|
|
;
|
|
;Convert to Upper Case
|
|
;
|
|
UPCASE:
|
|
ANI 7FH ;MASK OUT MSB
|
|
CPI 60H ;LESS THAN SMALL A?
|
|
RC ;RETURN IF SO
|
|
ANI 5FH ;MAKE UPPER CASE
|
|
RET
|
|
;
|
|
;CON: Status Routine
|
|
;
|
|
CONST:
|
|
PUSH B
|
|
PUSH D
|
|
PUSH H
|
|
VCONST:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
POP H
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
;CON: Input Routine
|
|
;
|
|
CONIN:
|
|
PUSH B
|
|
PUSH D
|
|
PUSH H
|
|
VCONIN:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
POP H
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
;Console out with TAB expansion
|
|
; Char in A
|
|
;
|
|
TYPE:
|
|
PUSH B ;SAVE REGS
|
|
PUSH D
|
|
PUSH H
|
|
MOV C,A ;FOR OUTPUT ROUTINE
|
|
CPI TAB
|
|
JNZ TYPE2
|
|
;Tabulate
|
|
TYPTAB:
|
|
MVI A,' ' ;PRINT SPACE
|
|
CALL TYPE
|
|
LDA TABCOL ;GET COL COUNT
|
|
ANI 7 ;DONE?
|
|
JNZ TYPTAB
|
|
JMP TYPRET
|
|
;
|
|
;Filter out control characters to
|
|
;prevent garbage during view of file
|
|
;
|
|
TYPE2:
|
|
CPI ' '
|
|
JNC TYPEQ
|
|
CPI CR
|
|
JZ TYPEQ
|
|
CPI LF
|
|
JNZ TYPNCR
|
|
;
|
|
TYPEQ:
|
|
;
|
|
;CON: Output Routine
|
|
;
|
|
VCONOT: CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
;
|
|
;Update column used in tab expansion
|
|
;
|
|
MOV A,C ;GET CHAR
|
|
CPI CR
|
|
JNZ TYPNCR
|
|
MVI A,0 ;RESET TAB COLUMN IF <CR>
|
|
STA TABCOL
|
|
JMP TYPLST
|
|
;
|
|
TYPNCR:
|
|
CPI ' ' ;CTL CHAR?
|
|
JC TYPLST ;..NO CHANGE IN COL
|
|
LDA TABCOL ;INCR TAB COUNT
|
|
INR A
|
|
STA TABCOL
|
|
;
|
|
TYPLST:
|
|
LDA PFLAG ;CHECK FOR PRINTER OUTPUT
|
|
ANI 1
|
|
CNZ LIST ;FROM C REG
|
|
;
|
|
TYPRET:
|
|
POP H ;RESTORE REGS
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
;LST: Output Routine
|
|
; Char in C
|
|
;
|
|
LIST:
|
|
PUSH B ;SAVED REGS
|
|
PUSH D
|
|
PUSH H
|
|
VLIST:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
POP H
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
;Home Disk Routine
|
|
;
|
|
HOME:
|
|
PUSH H
|
|
VHOME:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
POP H
|
|
RET
|
|
;
|
|
;Set track # in DE
|
|
;
|
|
SETTRK:
|
|
PUSH H
|
|
LHLD MAXTRK ;CHECK FOR WITHIN BOUNDS
|
|
CALL SUBDE ;IF TRACK # IN DE > MAX, THEN ERROR
|
|
POP H
|
|
JC OUTLIM
|
|
XCHG ;RESET CURRENT TRACK
|
|
SHLD CURTRK
|
|
XCHG
|
|
MOV B,D ;BC=TRACK NUMBER
|
|
MOV C,E
|
|
PUSH H
|
|
;
|
|
VSETRK:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
POP H
|
|
RET
|
|
;
|
|
;Set Sector Number in DE
|
|
;
|
|
SETSEC:
|
|
PUSH H
|
|
PUSH D
|
|
LHLD SYSTRK ;GET NUMBER OF SYSTEM TRACKS
|
|
XCHG
|
|
SHLD CURSEC ;SET CURRENT SECTOR
|
|
LHLD CURTRK ;GET CURRENT TRACK
|
|
CALL SUBDE ;SEE IF WE ARE IN THE SYSTEM TRACKS
|
|
POP B ;BC=SECTOR NUMBER
|
|
MOV H,B ;HL=SECTOR NUMBER
|
|
MOV L,C
|
|
JNC NOTSYS ;IF NO CARRY FOR SUBDE, WE ARE NOT IN SYSTEM TRACKS
|
|
LDA FIRST0 ;SEE IF FIRST SEC 0
|
|
ORA A
|
|
JNZ GSTSEC ;NO, JUMP AWAY
|
|
DCX H ;YES, SO DECREMENT
|
|
JMP GSTSEC ;REQUESTED, THEN GO
|
|
;
|
|
;Not in System Tracks, so Skew Factor is effective
|
|
;
|
|
NOTSYS:
|
|
LHLD SECTBL ;GET PTR TO SECTOR TABLE
|
|
XCHG ;... IN DE
|
|
DCX B ;DECREMENT SECTOR NUMBER BY 1
|
|
;
|
|
VSCTRN:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
LDA SPT+1 ;IF SPT<256 (HI-ORD = 0)
|
|
ORA A ; THEN FORCE 8-BIT TRANSLATION
|
|
JNZ GSTSEC ; ELSE KEEP ALL 16 BITS
|
|
MOV H,A
|
|
GSTSEC:
|
|
SHLD PHYSEC
|
|
MOV B,H
|
|
MOV C,L
|
|
;
|
|
VSTSEC:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
POP H ;RESTORE PTR TO NEXT CHAR
|
|
RET
|
|
;
|
|
;Out of Disk Track Limit
|
|
;
|
|
OUTLIM:
|
|
CALL ILPRT
|
|
DB '++ Not Within Tracks 0-',0
|
|
PUSH H
|
|
LHLD MAXTRK ;PRINT MAX TRACK NUMBER
|
|
CALL DEC
|
|
POP H
|
|
CALL ILPRT
|
|
DB ' ++',CR,LF,0
|
|
CALL NORITE ;NOT POSITIONED
|
|
JMP PRMPTR
|
|
;
|
|
;Set DMA Address
|
|
;
|
|
SETDMA:
|
|
JMP $-$ ;ADDR FILLED IN BY 'INIT'
|
|
;
|
|
;Read Next Block into DMA Address
|
|
;
|
|
READ:
|
|
MVI A,1 ;SET FLAG
|
|
STA WRFLG
|
|
PUSH H ;SAVE PTR TO NEXT CHAR
|
|
;
|
|
VREAD:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
ORA A ;ERROR?
|
|
JZ READOK
|
|
CALL ILPRT
|
|
DB '++ READ Failed, Sector may be Invalid ++'
|
|
DB CR,LF,0
|
|
;
|
|
READOK:
|
|
POP H ;GET PTR TO NEXT CHAR
|
|
RET
|
|
;
|
|
;Write Block in DMA Address to Disk
|
|
;
|
|
WRITE:
|
|
LDA WRFLG ;READ ALREADY PERFORMED?
|
|
ORA A ;ERROR IF NOT
|
|
JNZ PWRITE
|
|
;
|
|
BADW:
|
|
CALL ILPRT
|
|
DB '++ Cannot Write Unless Read Issued ++'
|
|
DB CR,LF,0
|
|
JMP EXPL
|
|
;
|
|
;Do Write
|
|
;
|
|
PWRITE:
|
|
PUSH H ;SAVE PTR TO NEXT CHAR
|
|
MVI C,1 ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED
|
|
;
|
|
VWRITE:
|
|
CALL $-$ ;ADDR FILLED IN BY 'INIT'
|
|
ORA A ;ERROR?
|
|
JZ WRITOK
|
|
CALL ILPRT
|
|
DB '++ WRITE Failed ++',CR,LF,0
|
|
;
|
|
WRITOK:
|
|
POP H
|
|
RET
|
|
;
|
|
;Help; HELP is entry point for HELP (?) command, HELP1 is entry point for
|
|
; Initial Help Command, and IHELP is entry point for HELP (/) from command
|
|
; line
|
|
;
|
|
IHELP:
|
|
call cls
|
|
cz crlf
|
|
call helpban
|
|
CALL ILPRT
|
|
DB DIM,'Introductory HELP on DU3 (Disk Utility)',BRIGHT,CR,LF
|
|
DB ' The DU3 program is designed to provide the user with'
|
|
DB CR,LF
|
|
DB 'the ability to manipulate information on the disk as easily'
|
|
DB CR,LF
|
|
DB 'as the DDT and SID utilities allow the user to manipulate'
|
|
DB CR,LF
|
|
DB 'information in memory.',CR,LF
|
|
DB ' The following is a summary of the commands available to'
|
|
DB CR,LF
|
|
DB 'the DU3 user. This same list is invoked internally by the'
|
|
DB CR,LF
|
|
DB '? Command of DU3. For additional information on disk'
|
|
DB CR,LF
|
|
DB 'structures and how to use DU3 in general, refer to the'
|
|
DB CR,LF
|
|
DB 'file DU3.HLP.',CR,LF,0
|
|
MVI A,0FFH ;A=0FFH
|
|
STA IHFLG ;SET INITIAL HELP
|
|
CALL SWAIT
|
|
JMP HELP1 ;PROCESS NORMALLY
|
|
HELP:
|
|
XRA A ;A=0
|
|
STA IHFLG ;SET NO INITIAL HELP
|
|
HELP1:
|
|
call cls
|
|
cz crlf
|
|
call helpban ;print help banner
|
|
CALL ILPRT
|
|
DB 'Operands in brackets [...] are optional'
|
|
DB CR,LF,CR,LF
|
|
DB ' @ ',DIM,'Repeat Previous Non-@ Command Line'
|
|
DB BRIGHT,CR,LF
|
|
DB ' +[nn] ',DIM,'Step In [nn (decimal)] Sectors'
|
|
DB BRIGHT,CR,LF
|
|
DB ' -[nn] ',DIM,'Step Out [nn (decimal)] Sectors'
|
|
DB BRIGHT,CR,LF
|
|
DB DIM
|
|
DB ' Note: + or - need not be followed by a "," to '
|
|
DB 'delimit commands.'
|
|
DB BRIGHT
|
|
DB CR,LF
|
|
DB ' # ',DIM,'Print Disk Parameters for Current Drive'
|
|
DB BRIGHT
|
|
DB CR,LF
|
|
DB ' =xxx ',DIM
|
|
DB 'Search for ASCII xxx from Current Sector'
|
|
DB BRIGHT
|
|
DB CR,LF
|
|
DB DIM
|
|
DB ' Note: upper/lower case matters. Use <xx> for hex:'
|
|
DB BRIGHT
|
|
DB CR,LF
|
|
DB DIM
|
|
DB ' To find "IN 0" use: =<db><0> or'
|
|
DB BRIGHT
|
|
DB CR,LF
|
|
DB DIM
|
|
DB ' "(tab)H,0(CR)(LF)" use: =<9>H,0<D><A>'
|
|
DB BRIGHT
|
|
DB CR,LF
|
|
DB ' *[nn] ',DIM,'Repeat [nn (decimal) times]'
|
|
DB BRIGHT,CR,LF
|
|
DB ' ! ',DIM,'Pause for User',BRIGHT,CR,LF
|
|
DB ' :ntext ',DIM,'Define ''text'' to be Macro n'
|
|
DB BRIGHT,CR,LF
|
|
DB ' n ',DIM,'Perform Macro n, 0<=n<=9',BRIGHT,CR,LF
|
|
DB ' :Pn ',DIM,'Print Macro n, 0<=n<=9',BRIGHT
|
|
DB CR,LF
|
|
DB ' :Px ',DIM
|
|
DB 'Print All Macros if x=A or Print Prev Line if x=@'
|
|
DB BRIGHT
|
|
DB 0
|
|
CALL SWAIT
|
|
call cls
|
|
cz crlf
|
|
call helpban
|
|
CALL ILPRT
|
|
DB ' A[ff,tt] ',DIM,'ASCII Dump',BRIGHT
|
|
DB CR,LF
|
|
DB ' C ',DIM,'Change:',BRIGHT
|
|
DB CR,LF
|
|
DB ' CHaddr byte byte... (hex)'
|
|
DB CR,LF
|
|
DB ' ',DIM,'or',BRIGHT
|
|
DB ' CAaddr data... (Ascii)'
|
|
DB CR,LF
|
|
DB DIM
|
|
DB ' <xx> Allowed for imbedded hex.'
|
|
DB BRIGHT
|
|
DB CR,LF
|
|
DB ' ',DIM,'or',BRIGHT
|
|
DB ' CHfrom-thru byte e.g. ch0-7f e5'
|
|
DB CR,LF
|
|
DB ' ',DIM,'or',BRIGHT,' CAfrom-thru byte'
|
|
DB CR,LF
|
|
DB ' D[ff,tt] ',DIM,'Dump (Hex and ASCII)',BRIGHT
|
|
DB CR,LF
|
|
DB ' E ',DIM,'DU3 Editor',BRIGHT,CR,LF
|
|
DB ' ',DIM,' Note: Rest of Command Line '
|
|
DB 'is Flushed',BRIGHT,CR,LF
|
|
DB ' Ffn.ft ',DIM,'Find File',BRIGHT
|
|
DB CR,LF
|
|
DB ' Gnn ',DIM,'CP/M Allocation Group nn (hex)'
|
|
DB BRIGHT,CR,LF
|
|
DB ' H[ff,tt] ',DIM,'Hex Dump',BRIGHT
|
|
DB CR,LF
|
|
DB ' L[d] ',DIM,'Log in Current Drive or Drive d'
|
|
DB BRIGHT,CR,LF
|
|
DB ' M[nn] ',DIM,'Map [from group nn (hex)]'
|
|
DB BRIGHT
|
|
DB 0
|
|
CALL SWAIT
|
|
call cls
|
|
cz crlf
|
|
call helpban
|
|
CALL ILPRT
|
|
DB ' N ',DIM,'Load New Disk',BRIGHT,CR,LF
|
|
DB ' P ',DIM,'Toggle Printer Switch',BRIGHT,CR,LF
|
|
DB ' Q ',DIM,'Queue Status;',BRIGHT,CR,LF
|
|
DB ' QZ ',DIM,'Zero (Empty) Queue',BRIGHT,CR,LF
|
|
DB ' QSfn.ft ',DIM,'Save Queue as a File on Disk',BRIGHT
|
|
DB CR,LF
|
|
DB ' < ',DIM,'Save Current Block into Temp',BRIGHT
|
|
DB CR,LF
|
|
DB ' > ',DIM,'Restore Temp Block',BRIGHT,CR,LF
|
|
DB ' <B ',DIM,'Save Block into Queue',BRIGHT,CR,LF
|
|
DB ' >B ',DIM,'Restore Queue Block',BRIGHT,CR,LF
|
|
DB ' <G[n] ',DIM,'Save Group into Queue',BRIGHT,CR,LF
|
|
DB ' >G[n] ',DIM,'Restore Queue Group',BRIGHT,CR,LF
|
|
DB ' Snn ',DIM,'Sector nn (decimal)',BRIGHT,CR,LF
|
|
DB ' Tnn ',DIM,'Track nn (decimal)',BRIGHT,CR,LF
|
|
DB ' Unn ',DIM,'Set User nn (decimal) for Find command'
|
|
DB BRIGHT,CR,LF
|
|
DB ' V[nn] ',DIM,'View [nn (decimal)] ASCII Blocks',BRIGHT
|
|
DB CR,LF
|
|
DB ' R ',DIM,'Read Current Block',BRIGHT,CR,LF
|
|
DB ' W ',DIM,'Write Current Block',BRIGHT,CR,LF
|
|
DB ' X ',DIM,'Exit Program',BRIGHT,CR,LF
|
|
DB ' Z[nn] ',DIM,'Sleep [nn (decimal) seconds]',BRIGHT
|
|
DB 0
|
|
CALL SWAIT
|
|
call cls
|
|
cz crlf
|
|
call helpban
|
|
CALL ILPRT
|
|
DB DIM,'Command Line is of the form: ',BRIGHT,'DU3 du?',CR,LF
|
|
DB ' ',DIM,'"d" is Logged-In Disk, "u" is Current User'
|
|
DB BRIGHT,CR,LF
|
|
DB CR,LF
|
|
DB 'Ctrl-C ',DIM,'Cancel a function',BRIGHT,CR,LF
|
|
DB 'Ctrl-S ',DIM,'Suspend output',BRIGHT,CR,LF
|
|
DB '"," ',DIM,'Separate commands',BRIGHT,CR,LF
|
|
DB CR,LF
|
|
DB DIM,'Examples:',BRIGHT,' g0 ',DIM,'and',BRIGHT
|
|
DB ' +,d,z2,*'
|
|
DB CR,LF
|
|
DB DIM,'Causes:',BRIGHT,CR,LF
|
|
DB ' 1. Position to group 0',CR,LF
|
|
DB ' 2. Loops on step in, dump, sleep 2 sec',CR,LF
|
|
DB ' until control-c is typed',CR,LF,CR,LF
|
|
DB '"nn" usage varies with command as follows:',CR,LF
|
|
DB ' +, -, *, T, S, U, V, Z ',DIM,'nn in Decimal'
|
|
DB BRIGHT,CR,LF
|
|
DB ' ',DIM,'(use #nn for Hex)'
|
|
DB BRIGHT,CR,LF
|
|
DB ' G, M ',DIM,'nn in Hexadecimal'
|
|
DB BRIGHT,CR,LF
|
|
DB ' ',DIM,'(use #nn for Decimal)'
|
|
DB BRIGHT,CR,LF
|
|
DB CR,LF
|
|
DB '"ff" and "tt" are in Hexadecimal (use #ff or #tt for Decimal)'
|
|
DB 0
|
|
CALL SWAIT
|
|
LDA IHFLG ;INITIAL HELP?
|
|
ORA A ;0=NO
|
|
JNZ EXIT1 ;RETURN TO CP/M IF SO
|
|
JMP PRMPTR ;NEW LINE INPUT IF NOT
|
|
helpban:
|
|
call ilprt
|
|
DB ' ',DIM,'-- DU3 Command Summary --',BRIGHT
|
|
DB CR,LF,CR,LF,0
|
|
ret
|
|
;
|
|
;COMMAND: X
|
|
;Exit to CP/M
|
|
;
|
|
EXIT:
|
|
call dinit ;deinit terminal
|
|
JMP BASE ;WARM BOOT
|
|
;
|
|
;Quick Exit to CP/M
|
|
;
|
|
EXIT1:
|
|
LHLD DUTSTK ;GET CP/M STACK PTR
|
|
SPHL ;SET SP
|
|
RET
|
|
|
|
;
|
|
;********************************
|
|
;* *
|
|
;* Utility Subroutines *
|
|
;* *
|
|
;********************************
|
|
;
|
|
GRPCMP:
|
|
MOV A,C
|
|
INR D
|
|
DCR D
|
|
JZ CMP8
|
|
CMP M
|
|
INX H
|
|
RNZ
|
|
MOV A,B
|
|
;
|
|
CMP8:
|
|
CMP M
|
|
RET
|
|
;
|
|
;2's complement HL ==> HL
|
|
;
|
|
NEG:
|
|
MOV A,L
|
|
CMA
|
|
MOV L,A
|
|
MOV A,H
|
|
CMA
|
|
MOV H,A
|
|
INX H
|
|
RET
|
|
;
|
|
;HL/2 ==> HL
|
|
;
|
|
ROTRHL:
|
|
ORA A
|
|
MOV A,H
|
|
RAR
|
|
MOV H,A
|
|
MOV A,L
|
|
RAR
|
|
MOV L,A
|
|
RET
|
|
;
|
|
;Collect the number of '1' bits
|
|
;in A as a count in C
|
|
;
|
|
COLECT:
|
|
MVI B,8 ;NUMBER OF BITS
|
|
;
|
|
COLOP:
|
|
RAL
|
|
JNC COSKIP
|
|
INR C
|
|
;
|
|
COSKIP:
|
|
DCR B
|
|
JNZ COLOP
|
|
RET
|
|
;
|
|
;HL-DE ==> HL
|
|
; Carry Flag is Significant
|
|
;
|
|
SUBDE:
|
|
MOV A,L
|
|
SUB E
|
|
MOV L,A
|
|
MOV A,H
|
|
SBB D
|
|
MOV H,A
|
|
RET
|
|
;
|
|
;Quick Kludge multiply
|
|
;HL*DE ==> HL
|
|
;
|
|
MULT:
|
|
PUSH B
|
|
PUSH D
|
|
XCHG
|
|
MOV B,D
|
|
MOV C,E
|
|
MOV A,B
|
|
ORA C
|
|
JNZ MULCON
|
|
LXI H,0 ;FILTER SPECIAL CASE
|
|
JMP MLDONE ; OF MULTIPLY BY 0
|
|
;
|
|
MULCON:
|
|
DCX B
|
|
MOV D,H
|
|
MOV E,L
|
|
;
|
|
MULTLP:
|
|
MOV A,B
|
|
ORA C
|
|
JZ MLDONE
|
|
DAD D
|
|
DCX B
|
|
JMP MULTLP
|
|
;
|
|
MLDONE:
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
;Routine to fill in disk params
|
|
;with every drive change
|
|
;
|
|
LOGIT:
|
|
LXI D,DPB ; THEN MOVE TO LOCAL
|
|
MVI B,DPBLEN ; WORKSPACE
|
|
CALL MOVE
|
|
LXI H,GRPDIS
|
|
MOV A,M
|
|
PUSH PSW
|
|
LDA BLM
|
|
MOV M,A
|
|
PUSH H
|
|
LHLD DSM
|
|
XCHG
|
|
CALL GTKSEC
|
|
SHLD MAXSEC
|
|
XCHG
|
|
SHLD MAXTRK
|
|
POP H
|
|
POP PSW
|
|
MOV M,A
|
|
RET
|
|
|
|
;***********************************
|
|
;
|
|
; DU3 Command Table
|
|
;
|
|
;***********************************
|
|
CMDTBL:
|
|
DB ' ' ;null command
|
|
DW PROMPT
|
|
;
|
|
DB ':'
|
|
DW MAC
|
|
;
|
|
DB '@'
|
|
DW PCMD
|
|
;
|
|
DB '+'
|
|
DW PLUS
|
|
;
|
|
DB '-'
|
|
DW MINUS
|
|
;
|
|
DB '='
|
|
DW SEARCH
|
|
;
|
|
DB '<'
|
|
DW SAVE
|
|
;
|
|
DB '>'
|
|
DW RESTOR
|
|
;
|
|
DB '#'
|
|
DW STATS
|
|
;
|
|
DB '?'
|
|
DW HELP
|
|
;
|
|
DB MULCH
|
|
DW REPEAT
|
|
;
|
|
DB '!'
|
|
DW UWAIT
|
|
;
|
|
DB 'A'
|
|
DW DUMP
|
|
;
|
|
DB 'C'
|
|
DW CHG
|
|
;
|
|
DB 'D'
|
|
DW DUMP
|
|
;
|
|
DB 'E'
|
|
DW EDIT
|
|
;
|
|
DB 'F'
|
|
DW POSFIL
|
|
;
|
|
DB 'G'
|
|
DW POS
|
|
;
|
|
DB 'H'
|
|
DW DUMP
|
|
;
|
|
DB 'L'
|
|
DW LOGIN
|
|
;
|
|
DB 'M'
|
|
DW MAP
|
|
;
|
|
DB 'N'
|
|
DW NEWDSK
|
|
;
|
|
DB 'P'
|
|
DW PRNTFF
|
|
;
|
|
DB 'Q'
|
|
DW QUEUER
|
|
;
|
|
DB 'R'
|
|
DW DOREAD
|
|
;
|
|
DB 'S'
|
|
DW POS
|
|
;
|
|
DB 'T'
|
|
DW POS
|
|
;
|
|
DB 'U'
|
|
DW USER
|
|
;
|
|
DB 'V'
|
|
DW VIEW
|
|
;
|
|
DB 'W'
|
|
DW DORITE
|
|
;
|
|
DB 'X'
|
|
DW EXIT
|
|
;
|
|
DB 'Z'
|
|
DW SLEEP
|
|
;
|
|
DB 0 ; End of Table
|
|
;*************************************
|
|
|
|
;
|
|
;Temporary storage area
|
|
;
|
|
clock:
|
|
ds 1 ;clock speed
|
|
pagsiz:
|
|
ds 1 ;page size
|
|
muser:
|
|
ds 1 ;max user
|
|
mdisk:
|
|
ds 1 ;max disk
|
|
STKSAV:
|
|
DS 2 ;SAVE HL VALUE
|
|
DUTSTK:
|
|
DS 2 ;OLD CP/M STACK POINTER; TOP OF DU3 STACK
|
|
BUFAD:
|
|
DS 2 ;FORCES INITIAL READ
|
|
QCNT:
|
|
DS 2 ;NUMBER OF SECTORS IN QUEUE
|
|
QNXT:
|
|
DS 2 ;PTR TO NEXT SECTOR IN QUEUE
|
|
QLST:
|
|
DS 2 ;PTR TO LAST SECTOR IN QUEUE
|
|
QPTR:
|
|
DS 2 ;G-P QUEUE PTR
|
|
HEXAD:
|
|
DS 2 ;TO RE-FETCH A VALUE
|
|
TOGO:
|
|
DS 2 ;REPEAT COUNT (FFFF=CONT)
|
|
TWOUP:
|
|
DS 1
|
|
UNUM:
|
|
DS 1 ;NUMBER OF CURRENT USER
|
|
ONLY1:
|
|
DS 1 ;FLAG TO PRINT ONLY 1 MAP ENTRY (0=NO)
|
|
MFPTR:
|
|
DS 2 ;MULTI FILE PTR FOR GETGRP
|
|
PAGFLG:
|
|
DS 1 ;LINE COUNTER FOR PAGING
|
|
PFLAG:
|
|
DS 1 ;1=PRINT
|
|
GROUP:
|
|
DS 2 ;GROUP NUMBER
|
|
GRPDIS:
|
|
DS 1 ;DISPLACEMENT INTO GROUP
|
|
SAVEFL:
|
|
DS 1 ;SAVE FLAG
|
|
CURTRK:
|
|
DS 2 ;CURRENT TRACK NUMBER
|
|
CURSEC:
|
|
DS 2 ;CURRENT SECTOR NUMBER
|
|
PHYSEC:
|
|
DS 2 ;CURRENT PHYSICAL SECTOR NUMBER
|
|
TABCOL:
|
|
DS 1 ;TAB COLUMN
|
|
CPYFCT:
|
|
DS 1 ;GROUP COPY FUNCTION; 0=READ, 0FFH=WRITE
|
|
FILECT:
|
|
DS 2 ;FILE COUNT
|
|
DIRPOS:
|
|
DS 1 ;POSITION IN DIRECTORY
|
|
FINDFL:
|
|
DS 1 ;1=MUST POSITION AFTER FIND
|
|
FTSW:
|
|
DS 1 ;SEARCH W/O INCREMENT
|
|
NOTPOS:
|
|
DS 1 ;INITIALLY NOT POSITIONED
|
|
WRFLG:
|
|
DS 1 ;MAY NOT WRITE UNTIL '+', '-',
|
|
; OR 'G' COMMAND
|
|
TGRP:
|
|
DS 2 ;TEMPORARY GROUP FLAG
|
|
FIRST0:
|
|
DS 1 ;SETS TO 0 IF FIRST SEC # IS 0
|
|
DRIVE:
|
|
DS 1 ;DRIVE NUMBER
|
|
MAXTRK:
|
|
DS 2 ;MAX TRACK NUMBER
|
|
MAXSEC:
|
|
DS 2 ;MAX SECTOR NUMBER
|
|
SECTBL:
|
|
DS 2 ;POINTER TO SECTOR SKEW TABLE
|
|
;
|
|
IHFLG:
|
|
DS 1 ;0=NOT AT INITIAL HELP, 0FFH=AT INITIAL HELP
|
|
DUPFLG:
|
|
DS 1 ;SPACE OR STAR TO INDICATE MULTIPLE USERS
|
|
BACK:
|
|
DS 2 ;TO BACK UP IN "CA0-7F,X"
|
|
DUMTYP:
|
|
DS 1
|
|
;
|
|
;The disk parameter block
|
|
;is moved here from CP/M
|
|
;
|
|
DPB EQU $ ;DISK PARAMETER BLOCK (COPY)
|
|
SPT:
|
|
DS 2
|
|
BSH:
|
|
DS 1
|
|
BLM:
|
|
DS 1
|
|
EXM:
|
|
DS 1
|
|
DSM:
|
|
DS 2
|
|
DRM:
|
|
DS 2
|
|
AL0:
|
|
DS 1
|
|
AL1:
|
|
DS 1
|
|
CKS:
|
|
DS 2
|
|
SYSTRK:
|
|
DS 2
|
|
;
|
|
;End of disk parameter block
|
|
;
|
|
SAVBUF:
|
|
DS 2
|
|
INBUF:
|
|
DS 2 ;INPUT LINE BUFFER
|
|
PINBUF:
|
|
DS 2 ;PREVIOUS CONTENTS OF INPUT BUFFER
|
|
CTEMP:
|
|
DS 2 ;BUILD NEW COMMAND LINE BUFFER
|
|
CTEMPX:
|
|
DS 2 ;END OF CTEMP
|
|
MTABL:
|
|
DS 2 ;10 PAGES FOR 10 MACROS
|
|
GBUFF:
|
|
DS 2
|
|
DIRECT:
|
|
DS 2
|
|
;
|
|
END
|
|
|