home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-09-19 | 101.4 KB | 5,003 lines |
- .xlist ;Moved here to keep .PRN file short for Z8E
- .Z80
- TITLE SPZ - CP/M DISK UTILITY
- ;------------------------------------------------------------------------------
- ;
- ; SUPERZAP - A screen-oriented disk editor for CP/M-80
- ;
- ; Versions prior to 3.x by Davidson and Sheldrake
- ;
- ; Upgraded to CP/M+ operation by:
- ; John Hastwell-Batten,
- ; SYSOP, Tesseract RCPM+,
- ; P.O. Box 242,
- ; Dural, NSW 2158,
- ; AUSTRALIA.
- ;
- ; Hopefully, what we have now is a "universal" version that will run
- ; without change under CP/M 2.2 and CP/M 3.1 but since I do not have
- ; a CP/M 2.2 system there is the chance that I have screwed it up.
- ;
- ; All of Willie Davidson's code is in upper case. My changes are easy
- ; to identify because they are in lower case. JHB.
- ; (.. I changed MOST OF THEM TO UPPER -- TO DISTINGUISH
- ; RECENT ONES I MADE...... PGM.
- ;------------------------------------------------------------------------------
- ;
- ; Update list (most recent first)
- ;
- ; 3.5 15 Sep 86 John T. Coburn
- ;
- ; Fixed 2 bugs in the cursor addressing routines when using ANSI
- ; terminal addressing. Insured that Row1st byte is a zero or one.
- ; Setup source to default to ANSI terminal cursor addressing. Set
- ; Peter's additions to the default case. Setup to be assembled by
- ; most assemblers - the ENTRY pseudoop is conditionalized.
- ;
- ;
- ; 3.4 11-24 Jul 86 Peter G. Martin
- ;
- ; Added hex & ascii searches in Edit mode,
- ; random sector/page/line access in Type mode,(rough)
- ; Alternative line-end interpretation for Type
- ; for word-processed ('document') files
- ;
- ;
- ; 3.3 20 Mar 86 Willie Davidson (mods done by John Hastwell-Batten)
- ;
- ; - Incorporated Willie Davidson's updates to the CP/M 2.2 version into
- ; this universal version.
- ;
- ; 3.2 24 Feb 86 John Hastwell-Batten
- ;
- ; - Removed CP/M 3 configuration/implementation dependencies.
- ; SUPERZAP should now run on any CP/M 3 or 2.2 system with a Z80.
- ;
- ; 3.1 11 Jan 86 John Hastwell-Batten
- ;
- ; - Added ability to select user number (very crude).
- ; - Changed default track number to directory track
- ; - Made terminal functions more general and object-patchable.
- ;
- ; 3.0 9 Jan 86 John Hastwell-Batten
- ;
- ; - ASEG and ORG directives added, .LIST and .XLIST directives moved
- ; to simplify use with Z8E debugger.
- ; - Upgraded to be compatible with CP/M 3.1
- ; - Introduced inverse video display of characters with high bit set
- ; to make display of directory sectors more readable
- ;
- ; 2.1 Willie Davidson and H Sheldrake
- ;
- ; Original (as distributed by SIG/M)
- ;
- ;------------------------------------------------------------------------------
-
- ASEG ;For Z8E debugger symbol table alignment
- ORG 100H ;(Just makes it a little easier)
-
- ;---------------- Entry point to program -----------------
-
- JP INIT ;Now we have to do this ourselves
-
- $VER DEFL '3' ;VERSION NUMBER
- $MOD DEFL '5' ;MODIFICATION LEVEL
-
- DB ' SUPERZAP 3 ' ;DELETED A FEW "BLANK" LINES.
- DB ' for CP/M 2.2 ' ;SCREEN CONTROLS NOW AT 150H
- DB ' and CP/M 3.1 ' ;INSTEAD OF 180H -- JHB
- DB ' W.M.Davidson '
- DB ' H.J.Sheldrake '
- ; DB '18 DEAN PARK CR.'
- ; DB ' EDINBURGH '
- ; DB ' EH4 1PH '
- ; DB ' SCOTLAND '
-
- ; CURSOR CHARACTER EQUATES (MUST BE 01H TO 01FH)
-
- $LEFT EQU 013H ;CURSOR LEFT IS ^S
- $RIGHT EQU 004H ;CURSOR RIGHT IS ^D
- $UP EQU 005H ;CURSOR UP IS ^E
- $DOWN EQU 018H ;CURSOR DOWN IS ^X
- $TAB EQU 009H ;CURSOR TAB IS ^I
- $ESC EQU 01BH ;ESCAPE IS ESC
- $INSRT EQU 'V'-040H ;INSERT IS ^V
- $DELETE EQU 'G'-040H ;DELETE IS ^G
- $QUIT EQU 'Q'-040H ;QUIT EDIT IS ^Q
- $END EQU 'K'-040H ;END EDIT IS ^K
-
- ; SCREEN CONTROL (for ANSI terminals)
-
- CLSSTR: DB 6,1bh,5Bh,48h,1Bh,5Bh,4Ah,0,0 ;CLEAR SCREEN
- CLLSTR: DB 3,1Bh,5Bh,4BH,0,0,0,0,0 ;CLEAR LINE
- vInv: db 4,1Bh,5Bh,37h,6Dh,0,0,0 ;Inverse video
- vNorm: db 3,1Bh,5Bh,6Dh,0,0,0,0 ;Normal video
- cpPref: DB 2,1Bh,5Bh,0,0,0,0,0 ;CURSOR POSITION PREFIX
- cpMid: db 1,3Bh,0,0,0,0,0,0 ;Cursor position infix
- cpEnd: db 1,48h,0,0,0,0,0,0 ;Cursor position suffix
- row1st: db 1 ;1=row first, 0=column first
- rowOff: db 1 ;Offset for row
- colOff: db 1 ;Offset for column
- cpBin: db 0 ;0 for decimal cursor coordinates,
- ;Non-0 for binary.
- maxASC: db 7Eh ;set to 7dh for stupid hazeltines
-
- ; --- WARNING WARNING WARNING WARNING ---
- ; the value of row1st is set to 0 or 1 ( Odd numbers are 1 )
-
- FLAGCH: DB ' ' ;FLAG CHARACTER IN LIST MODE
-
- ; NEW: word processor newline characters for typing of files
- ; Standard which should be harmless is to have all 'line end' chars
- ; set to 0DH, which is normally handled by the 'hard-wired' code...
- ; This means, you may insert UP TO 2 'soft' codes for those line-ends
- ; used by your word-processor files which ARE NOT NORMALLY FOLLOWED BY
- ; a LF and 2 'hard' codes for CRs normally followed by LFs such as
- ; Wordstar's 8D 0A combination.
- ; PGM 24 July 86
- ; DEFAULT FOR ALL FOUR ENTRIES IS 0DH -- SELECT FOR WORD-PROCESSOR YOU USE
- ; OR LEAVE HARMLESS AS 0DH
-
- soft1: db 0dh ; CHANGE AS YOU WOULD OR LEAVE AS 0DH
- soft2: db 0dh ; for the default - No Action case
- hard1: db 0dh ;
- hard2: db 0dh ;
-
- SLR_Z80 equ 1 ; Ignore the ENTRY pseudo op
-
- ;---------------- MACRO DEFINITIONS
- ; NB: macro variables prefix of '#' are preferred for Z80MR macro assembler
- ; --- PGM.
-
- ; $RTN - STANDARD ROUTINE ENTRY
-
- $RTN MACRO $RTNN
- IfNDef SLR_Z80 ; Z80ASM doesn't allow in Absolute Mode
- ENTRY $RTNN
- EndIf
- $RTNN: DS 0
- ENDM
-
- ; $PANEL - LOAD HL AND DISPLAY PANEL
-
- $PANEL MACRO $PNLNM
- LD HL,$PNLNM ;POINT TO PANEL
- CALL DPNL ;DISPLAY IT
- ENDM
-
- ; $FLD - LOAD HL AND DISPLAY FIELD
-
- $FLD MACRO $FLDNM
- LD HL,$FLDNM
- CALL DFLD
- ENDM
-
- ; $NPANEL - CLEAR SCREEN AND DISPLAY PANEL
-
- $NPANEL MACRO $PNLNM
- CALL DHDR
- $PANEL $PNLNM
- ENDM
-
- ; $STRO - PRINT STRING AT (HL)
-
- $STRO MACRO $STRNM
- LD HL,$STRNM
- CALL STRO
- ENDM
-
- ; $STRL - PRINT STRING AT (HL) WHERE FIRST BYTE IS LENGTH
-
- $STRL MACRO $STRNM
- LD HL,$STRNM
- CALL STRL
- ENDM
-
- ; $IFLD - LOAD HL, DISPLAY FIELD, GET AND FOLD INPUT
-
- $IFLD MACRO $FLDNM
- LD HL,$FLDNM ;POINT TO FIELD
- CALL DFLD ;DISPLAY IT
- CALL CHRF ;GET INPUT
- ENDM
-
- ; $MTCH - CALL BYTE MATCHER
-
- $MTCH MACRO $LST
- LD HL,$LST
- CALL MTCH
- ENDM
-
- ; $EXVA - EXECUTE VECTORED ACTION
-
- $EXVA MACRO $LST
- LD DE,$LST
- CALL EXVA
- ENDM
-
- ; $HEXW - DISPLAY HEX WORD
-
- $HEXW MACRO $WORD
- LD HL,($WORD)
- CALL HEXW
- ENDM
-
- ;---------------- GLOBAL EQUATES ----------------
-
- CR EQU 0DH
- LF EQU 0AH
- FALSE EQU 000H
- TRUE EQU 0FFH
- CMD EQU 80H
-
- FBUFF EQU 80H
-
- ;Note: The CP/M2.2-specific version of this program used the default
- ; file I/O buffer at 80H for all disk operations, i.e. for file-
- ; oriented AND physical I/O. Under CP/M 3.1 this is not tenable
- ; because the BIOS deals with physical sectors rather than 128-
- ; byte "logical" sectors and physical sectors can be much larger
- ; than 128 bytes.
- ;
- ; Physical disk I/O for CP/M 3.x now uses an area set aside at
- ; the end of this program, before the scratchpad. 2048 bytes has
- ; been reserved. That should be enough; I don't know of any
- ; system which supports physical sectors longer than 1024 bytes
- ; but the notes on the WD1797 FDC suggest that 2048 is possible.
- ;
- ; JHB January 1986
- ;
- ;---------------- CPM SYSTEM CALL CODES
-
- CPM EQU 05H ;CPM CALL ADDRESS
- CONIO EQU 06H ;DIRECT CONSOLE I/O
- GETVSN EQU 0Ch ;Get CP/M version number
- RESET EQU 0DH ;RESET DISK SYSTEM
- SETDEF EQU 0EH ;SET DEFAULT DRIVE
- OPEN EQU 0FH ;OPEN FILE
- CLOSE EQU 10H ;CLOSE FILE
- FNDFST EQU 11H ;FIND FIRST DIRECTORY MATCH
- FNDNXT EQU 12H ;FIND NEXT DIRECTORY MATCH
- GETDEF EQU 19H ;GET CURRENT DRIVE ID
- SDMA EQU 1Ah ;Set DMA address (Req'd for CP/M 3.1)
- USERNO EQU 20h ;GET/SET USER NUMBER
- READRN EQU 21H ;READ RANDOM RECORD
- WRITRN EQU 22H ;WRITE RANDOM RECORD
- FILESZ EQU 23H ;COMPUTE FILE SIZE
- SETRN EQU 24H ;SET RANDOM RECORD
-
- ;---------------- DEFAULT FCB IMAGE
-
- WRKFCB EQU 5CH ;DEFAULT FCB ADDRESS
- WRKDR EQU WRKFCB+0 ;DRIVE
- WRKFN EQU WRKDR+1 ;FILE NAME BODY
- WRKFT EQU WRKFN+8 ;FILE NAME EXTENSION
- WRKEX EQU WRKFT+3 ;EXTENT NUMBER
- WRKS1 EQU WRKEX+1 ;CPM RESERVED
- WRKS2 EQU WRKS1+1 ;CPM RESERVED
- WRKRC EQU WRKS2+1 ;RECORD COUNT THIS EXTENT
- WRKMP EQU WRKRC+1 ;ALLOCATION MAP FOR EXTENT
- WRKNR EQU WRKMP+16 ;NEXT SEQUENTIAL RECORD
- WRKRR EQU WRKNR+1 ;2 BYTE RANDOM RECORD NUMBER
- WRKOV EQU WRKRR+2 ;RANDOM OVERFLOW FLAG
-
- FREESP: DW ENDCDE ;ALLOW USER CODE INSERTION
-
-
- ;---------------- MESSAGES
-
- HLAREA EQU 0109H ;HELP IN LINES 01-10 (01 FOR 09)
- DRAREA EQU 0E08H ;DIRECTORY LINES 14-21 (14 FOR 08)
-
- HDRMSG: DB 0,21,'SUPERZAP version ',$VER,'.',$MOD,0
-
- ;---------------- GLOBAL WORK AREAS
-
- MEMRY: DS 2 ;FREE MEMORY SPACE
- CPM3: DS 1 ;CP/M 3 flag
- READST: DB 0FFH ;RETURN CODE FROM READ OPERATIONS
- INCH: DB 0 ;INPUT CHARACTER
- TYCURC: DB 0 ;CURRENT CHARACTER FOR TYPE
- RELREC: DW 0 ;CURRENT RECORD NUMBER
- BUFPOS: DS 1
- linesc: ds 2 ; line count for type display
- BASEAD: DS 3
- SAVREC: DW 0 ;SAVE RECORD DURING SET
- SAVFSC: DW 0 ;RECORD TO BE READ
- RO: DB 0 ;READ ONLY FILE FILE
- NEWDE@: DS 2 ;ADDRESS OF ENTRY JUST FOUND
- NXTDE@: DS 2 ;NEXT POSITION IN TABLE
- TOPDE@: DW 0 ;TOP OF DIRECTORY TABLE
- FSTDE@: DW 0 ;BOTTOM OF DIRECTORY TABLE
- DECNT: DB 0 ;NUMBER OF ENTRIES READ
- PRTCNT: DB 0 ;NUMBER OF ENTRIES DISPLAYED
- PRTENT: DB 0 ;ENTRY NUMBER TO BE PRINTED
- SELDE: DS 1 ;SELECTED DIRECTORY ENTRY
- DIROFF: DB 0 ;DIRECTORY DISPLAY OFFSET
- DEFDRV: DS 1 ;CURRENT DRIVE ID
- REQDRV: DS 1 ;REQUIRED DRIVE ID
- CURAN: DS 1 ;CURRENT ABSOLUTE DRIVE NUMBER
- ERRFLD: DW 0 ;ERROR FIELD ON SCREEN
- DB 0 ;END OF FIELD MARK
- ERRTXT: DW 0 ;ADDRESS EOF ERROR TEXT
- PRVERR: DW 0 ;ADDRESS OF PREVIOUS TEXT
- WTG: DB 0 ;NEXT PROCESS MODE
- AFNSTR: DB '???????????'
- DSKCMD: DB 'DSK:'
- PGEPTR: DS 2 ;ADDRESS OF PAGE POINTER LIST
- CURPG@: DS 2 ;ADDRESS OF CURRENT PAGE ENTRY
- MAXPG@: DS 2 ;ADDRESS OF LAST PAGE ENTRY
- RPANEL: DS 1 ;DISPLAY PANEL REQUEST
-
- ; SCRATCHPAD DATA
-
- SPADDR: DS 2 ;SCRATCHPAD BUFFER ADDRESS
- SPTYPE: DS 1 ;NONE/PHYSICAL/RELATIVE
- SPSECT: DS 2 ;SECTOR NUMBER
- SPDRIV: DS 1 ;ABSOLUTE DRIVE NUMBER
- SPNAME: DS 12 ;UFN OR TRACK NUMBER
- DB 0 ;END OF FIELD MARK
- SPDMSG: DB 'Drive ',0
- SPTMSG: DB ' Track ',0
- SPSMSG: DB ' Sector ',0
- SPEMTY: DB 'Empty',0
-
- ;---------------- LIST MODE FCB
-
- LMDFCB EQU $
-
- LMDDR: DB 0 ;DRIVE
- LMDFN: DS 8 ;FILE NAME
- LMDFT: DS 3 ;FILE TYPE
- LMDEX: DB 0 ;EXTENT NUMBER
- LMDS1: DB 0
- LMDS2: DB 0
- LMDRC: DB 0 ;RECORD COUNT
- LMDD0: DS 16 ;CLUSTER ALLOC MAP
- LMDCR: DB 0 ;CURRENT RECORD
-
- ; LOCAL BIOS COPY - USED TO SIMPLIFY DIRECT BIOS CALLS
-
- LBIOS EQU $ ;START OF LOCAL BIOS
-
- WBOOT: CALL BIOS3 ;For CP/M3 we make all of these
- CONST: CALL BIOS3 ;branch to the same place. From
- CONIN: CALL BIOS3 ;there we will do a "Come From"
- CONOUT: CALL BIOS3 ;statement to figure out which
- LIST: CALL BIOS3 ;routine was called.
- PUNCH: CALL BIOS3
- READER: CALL BIOS3 ;For CP/M 2.2 these CALLs will
- HOME: CALL BIOS3 ;be overlaid with a copy of the
- SELDSK: CALL BIOS3 ;JP table at the beginning of
- SETTRK: CALL BIOS3 ;the BIOS.
- SETSEC: CALL BIOS3
- SETDMA: CALL BIOS3 ;JHB - January 1986
- READ: CALL BIOS3
- WRITE: CALL BIOS3
- LISTST: CALL BIOS3
- SECTRN: CALL BIOS3
-
- ; Note that the entire CP/M 3.x BIOS table is not represented here.
-
- ELBIOS EQU $ ;END OF LOCAL BIOS
-
- ; INIT - SPZ INITIALISATION
-
- $RTN INIT
- LD HL,(6)
- LD L,0 ;Don't interfere with any RSXs
- LD SP,HL ;SET STACK TO BASE OF BDOS
-
- ld a,(row1st) ; Insure that Row1st
- and 1 ; is a 1 or 0
- ld (row1st),a
-
- LD C,GETVSN ;Test CP/M version. Set
- CALL CPM ;'cpm3' to zero if 2.x
- LD A,2FH ;or to 1 if 3.x
- SUB L
- LD A,H ;Pull in MP/M flag too
- JR NC,NOTPLUS
- INC A
- NOTPLUS:
- LD (CPM3),A ;Zero if CP/M 2.x, Non-zero if MP/M or CP/M 3.x
- OR A ;Only copy BIOS vector if CP/M 2.x
- JR NZ,NOLOCAL
- LD HL,(1) ;LOAD BIOS VECTOR ADDRESS
- LD DE,LBIOS
- LD BC,ELBIOS-LBIOS
- LDIR ;SET UP LOCAL BIOS VECTOR
- NOLOCAL:
- LD HL,AFNSTR
- CALL LSEL ;SET LIST SELECTION TO ALL
- LD HL,(FREESP) ;FIND TOP OF PROG
- LD (SPADDR),HL ;SET SCRATCHPAD ADDRESS
- LD DE,080H
- ADD HL,DE
- LD (MEMRY),HL ;PUT WORK AREA ABOVE SCRATCHPAD
- XOR A
- LD (SPTYPE),A ;SET SCRATCHPAD EMPTY
- LD HL,0
- LD (ERRTXT),HL ;CLEAR ERROR MESSAGE FIELD
- LD (PRVERR),HL ;AND PREVIOUS ERROR
- LD C,GETDEF
- CALL CPM ;GET DEFAULT DRIVE NUMBER
- LD (DEFDRV),A ;SAVE IT
- LD (CURAN),A ;SET CURRENT ABSOLUTE DISK NUMBER
- LD A,(WRKDR)
- OR A
- JR Z,INIT01 ;IF DRIVE ID IN COMMAND
- DEC A
- LD (CURAN),A ;USE THAT AS CURRENT
- INIT01 EQU $ ;ENDIF
- LD HL,CMD ;POINT TO COMMAND AREA
- INIT02 EQU $ ;LOOP
- INC HL
- LD A,(HL)
- OR A
- JR Z,INIT05 ;QUIT IF END OF COMMAND
- CP ' '
- JR Z,INIT02 ;IGNORE SPACES
- INC HL
- LD A,(HL)
- CP ':'
- JR NZ,INIT03 ;IF CMD IS DRIVE ID
- INC HL ;SKIP PAST IT
- JR INIT04
- INIT03 EQU $ ;ELSE
- DEC HL ;POINT TO FIRST CHARACTER
- INIT04 EQU $ ;ENDIF
- LD DE,DSKCMD
- LD BC,4
- CALL CPST
- JR NZ,INIT05 ;IF DISK OPTION
- CALL SETP ;SET DISK MODE
- JR INIT06
- INIT05 EQU $ ;ELSE
- CALL SETD ;ASSUME DIRECTORY MODE
- LD HL,WRKFN
- LD A,(HL)
- CP ' '
- JR Z,INIT08 ;IF NOT NULL OPTION
- LD B,11
- INIT09 EQU $ ;LOOP
- LD A,(HL)
- CP '?'
- JR Z,INIT10 ;EXIT IF AFN INDICATED
- INC HL
- DJNZ INIT09 ;TILL FN AND FT SCANNED
- CALL SETF ;MUST BE UFN
- JR INIT12
- INIT10 EQU $ ;ON '?' FOUND
- LD HL,WRKFN
- CALL LSEL ;SET LIST SELECTION TO AFN GIVEN
- INIT12 EQU $ ;ENDIF
- INIT08 EQU $ ;ENDIF
- INIT06 EQU $ ;ENDIF
- LD A,(CURAN)
- CALL CHDR ;INITIALISE DISK CONTROL BLOCKS
- JR NZ,INIT13 ;IF ILLEGAL DISK
- LD A,(DEFDRV)
- CALL CHDR ;USE DEFAULT DISK
- LD HL,ILDMSG
- LD (ERRTXT),HL ;SET ERROR MESSAGE
- INIT13 EQU $
-
- ; MAIN - SPZ MAINLINE
-
- $RTN MAIN
- MAIN01 EQU $ ;LOOP
- LD A,(WTG)
- $MTCH MAINLS ;TEST CODE
- JR NZ,MAIN02 ;IF INVALID ACTION EXIT
- $EXVA MAINVC ;EXEC ACTION
- JR MAIN01
- MAIN02 EQU $ ;ENDLOOP
- CALL CLRS
- LD A,(DEFDRV)
- LD E,A
- LD C,SETDEF
- CALL CPM ;RESTORE ORIGINAL DEFAULT
- LD C,RESET ;Reset disk system
- CALL CPM
- JP 0 ;EXIT TO SYSTEM
-
- ILDMSG: DB '** Invalid Disk Specified',0
-
- ; MAINLINE ACTION VECTOR
-
- MAINLS: DB 4,'XFDP'
- MAINVC EQU $
- DW ENDR ;END RUN
- DW FDMD ;FILE DISPLAY MODE
- DW DRMD ;DIRECTORY MODE
- DW PSMD ;PHYSICAL SECTOR MODE
-
-
- ; ENDR - END SPZ RUN
-
- $RTN ENDR
- XOR A
- LD (WTG),A
- RET
-
-
- ; FDMD - FILE DISPLAY MODE
-
- $RTN FDMD
- LD HL,(FDMDER)
- LD (ERRFLD),HL ;SET ERROR FIELD POINTER
- LD A,0FFH
- LD (FDMDSI),A ;REQUEST SI DISPLAY
- LD (RPANEL),A ;REQUEST PANEL DISPLAY
- CALL TFLE
- LD A,(FLERR)
- OR A
- JR Z,FDMD03 ;IF FILE ERROR
- CALL SETD ;SET DIRECTORY MODE
- JP FDMD04
- FDMD03 EQU $ ;ELSE
- FDMD05 EQU $ ;LOOP
- LD A,(RPANEL)
- OR A
- JR Z,FDMD11 ;IF PANEL REQUIRED
- XOR A
- LD (RPANEL),A ;RESET REQUEST
- $NPANEL FDMDPN ;DISPLAY FILE MODE PANEL
- LD HL,FILEMS ;POINT TO FILE MESSAGE
- LD A,(COMFLG)
- OR A
- JR Z,FDMD09 ;IF .COM FILE
- LD HL,LOADMS ;POINT TO LOAD MESSAGE
- FDMD09 EQU $ ;ENDIF
- CALL DFLD
- $FLD FSPMSG
- CALL DSPI ;DISPLAY SCRATCHPAD INFO
- ld a,8 ; new display clear -- pgm
- call CLRL ; " "
- FDMD11 EQU $ ;ENDIF
- CALL ERRP ;PROCESS ERRORS
- LD A,(FDMDSI)
- OR A
- JR Z,FDMD10 ;IF SI DISPLAY REQUIRED
- CALL DFSI ;DISPLAY FILE SECTOR INFO
- LD HL,FBUFF
- CALL WRBF ;DISPLAY BUFFER CONTENTS
- XOR A
- LD (FDMDSI),A ;RESET REQUEST
- FDMD10 EQU $ ;ENDIF
- FDMD07 EQU $ ;LOOP
- $IFLD SELMSG ;PROMPT SELMSG AND GET COMMAND
- $MTCH FDMDLS
- JR Z,FDMD06 ;EXITIF VALID
- CALL ALRM ;SOUND THE ALARM
- JR FDMD07
- FDMD06 EQU $ ;ENDLOOP
- $EXVA FDMDVC
- LD A,(WTG)
- CP 'F'
- JR NZ,FDMD08 ;EXIT IF MODE NO LONGER F
- JP FDMD05
- FDMD08 EQU $ ;ENDLOOP
- LD C,CLOSE
- LD DE,WRKFCB
- CALL CPM
- FDMD04 EQU $ ;ENDIF
- RET
-
- COMSTR: DB 'COM' ;.COM FILE TYPE
-
-
- ; FILE DISPLAY MODE MESSAGES, PANEL AND ACTION VECTOR
- ; -- under mod 4, july 86, new options added... PGM.
-
- SELMSG: DB 9,10,'Select Function ===> ',00
- SETMSG: DB 11,36,'Enter Hex Sector',0 ;OVERLAID BY CURMSG
- FDMDER: DB 7,0 ;ERROR POSITION
- FILEMS: DB 11,53,'File Offset ',0
- LOADMS: DB 11,53,'Load Address',0
-
- FDMDPN: db 16 ;field count
- DB 02,00,'N Next sector',0
- DB 03,00,'P Previous sector',0
- DB 02,22,'T Top of file',0
- DB 03,22,'E Last sector of file',0
- DB 02,54,'Z Exit from Superzap',0
- DB 03,54,'L Exit to file list',0
- DB 04,00,'C Change Sector',0
- DB 04,22,'S Select Sector',0
- DB 04,54,'X Scratchpad operations',0
- db 05,00,'A Find ASCII string',0 ; new one
- db 05,22,'H Find HEX sequence',0 ; new one
- DB 11,04,'File-Name',0
- DB 11,16,'Access',0
- CURMSG: DB 11,36,'Current-Sector ',0 ;OVERLAID BY SETMSG
- FILE: DB 12,00
- DRIVNM: DB 'd:'
- FILENM: DB 'filename.typ',0
- DB 12,17,'R/'
- FDMDRS: DB 's ',0 ;ACCESS INDICATOR
- FSPMSG: DB 06,00,'Scratchpad :- ',0
-
-
- fndpmt: db 08,00,'Find :',$TAB,0 ; new
- strpos: db 08,08 ; new
- notfnd: db 08,00,'NOT FOUND - HIT <T> FOR START ',0 ; new
- fndcon: db 13,64,'NEXT (Y/N) ? ',0 ; new
-
- ; FILE STATISTICS FIELDS
-
- WRSNFL: DB 12,41,0
- WRFOFL: DB 12,55,0
- SFSNIP: DB 12,45,0
-
- FDMDLS: db 11,'NPTEZLCSXAH' ; new extra options added ...PGM.
- FDMDVC EQU $
- dw NXFS ;NEXT FILE SECTOR
- dw PRFS ;PREVIOUS FILE SECTOR
- dw FRFS ;POSITION TO FIRST FILE SECTOR
- dw LSFS ;POSITION TO LAST FILE SECTOR
- dw SETX ;SET EXIT MODE
- dw SETD ;SELECT DIRECTORY MODE
- dw FSCH ;FILE SECTOR CHANGE
- dw SFSN ;SET FILE SECTOR NUMBER
- dw FSPM ;SCRATCHPAD MANAGER
- dw fasc ; find ascii string ; new
- dw fhex ; find hex sequence ; new
-
- FDMDSI: DS 1 ;SI REQUEST FLAG
-
- ; NXFS - READ NEXT FILE SECTOR
-
- ; Maybe it's just my caution or lack of complete comprehension
- ; of all of the code, but I DO think we could do with a deal
- ; more of register-preservation in many routines....pgm.
-
- $RTN NXFS
- push de ; new -- save some registers
- LD HL,(RELREC)
- INC HL
- LD (RELREC),HL ;INCREMENT RECORD NUMBER
- CALL RDFS ;ATTEMPT TO READ RECORD
- push af ; <= save file status (new)
- JR NZ,NXFS02 ;IF GOOD READ
- LD A,TRUE
- LD (FDMDSI),A ;REQUEST SI DISPLAY
- JR NXFS01
- NXFS02 EQU $ ;ELSE
- CALL ALRM ;SOUND ALARM
- NXFS01 EQU $ ;ENDIF
- pop af ; new -- return file status in A
- pop de ; new
- RET
-
-
- ; PRFS - READ PREVIOUS FILE SECTOR
-
- $RTN PRFS
- LD HL,(RELREC)
- LD A,H
- OR L
- JR NZ,PRFS01 ;IF RECORD ZERO
- CALL ALRM ;SOUND ALARM
- JR PRFS02
- PRFS01 EQU $
- DEC HL
- LD (RELREC),HL ;DECREMENT RECORD POINTER
- CALL RDFS ;ATTEMPT TO READ IT
- JR NZ,PRFS03 ;IF GOOD READ
- LD A,TRUE
- LD (FDMDSI),A ;REQUEST SI DISPLAY
- JP PRFS04
- PRFS03 EQU $ ;ELSE
- CALL ALRM ;SOUND ALARM
- PRFS04 EQU $ ;ENDIF
- PRFS02 EQU $ ;ENDIF
- RET
-
-
- ; FSCH - FILE SECTOR CHANGE
-
- $RTN FSCH
- LD A,(RO)
- OR A
- JR Z,FSCH01 ;IF READ ONLY FILE
- CALL ALRM ;SOUND THE ALARM
- JR FSCH02
- FSCH01 EQU $ ;ELSE
- CALL SCCH ;GO INTO SECTOR CHANGE MODE
- LD A,(SCCHWR)
- OR A
- JR Z,FSCH03 ;IF WRITE REQUIRED
- CALL WRFS ;WRITE OUT SECTOR
- JR FSCH04
- FSCH03 EQU $ ;ELSE
- CALL RDFS ;READ SECTOR
- FSCH04 EQU $ ;ENDIF
- LD A,TRUE
- LD (RPANEL),A ;REDISPLAY FILE MODE PANEL
- LD (FDMDSI),A ;REQUEST SI DISPLAY
- FSCH02 EQU $ ;ENDIF
- RET
-
- ; FRFS - POSITION TO FIRST FILE SECTOR
-
- $RTN FRFS
- LD HL,0
- LD (RELREC),HL
- CALL RDFS ;READ THE SECTOR
- LD A,TRUE
- LD (FDMDSI),A ;REQUEST SI DISPLAY
- RET
-
- ; LSFS - POSITION TO LAST FILE SECTOR
-
- $RTN LSFS
- LD DE,WRKFCB
- LD C,FILESZ ;COMPUTE FILE SIZE
- CALL CPM
- LD HL,(WRKRR)
- DEC HL
- LD (RELREC),HL ;SET UP RECORD TO READ
- CALL RDFS ;READ THE RECORD
- LD A,TRUE
- LD (FDMDSI),A ;REQUEST SI DISPLAY
- RET
-
- ; SFSN - SET FILE SECTOR NUMBER
-
- $RTN SFSN
- LD HL,SELMSG
- CALL CFLD ;CLEAR FUNCTION PROMPT
- LD HL,(RELREC)
- LD (SAVREC),HL ;SAVE RECORD NUMBER
- $FLD SETMSG ;DISPLAY SET MESSAGE
- LD HL,0
- LD (RELREC),HL ;ZERO RECORD NUMBER
- SFSN01 EQU $
- CALL DFSI ;DISPLAY FILE SECTOR INFO
- $IFLD SFSNIP ;POSITION AND GET INPUT
- $MTCH HEXCHR
- JR NZ,SFSN02 ;IF VALID
- EX DE,HL ;DIGIT TO DE
- LD HL,(RELREC)
- CALL H16D ;HL=HL*16+DIGIT
- LD (RELREC),HL ;SAVE NEW RECORD NUMBER
- JR SFSN03
- SFSN02 EQU $
- CP $ESC
- JR NZ,SFSN04 ;ELSE IF ESC
- LD HL,(SAVREC)
- LD (RELREC),HL ;RESTORE SECTOR NUMBER
- JR SFSN03
- SFSN04 EQU $
- CP $LEFT
- JR NZ,SFSN06 ;ELSE IF BACKSPACE
- LD HL,RELREC+1
- XOR A
- RRD
- DEC HL
- RRD ;RELREC=RELREC/16
- JR SFSN03
- SFSN06 EQU $
- CP CR
- JR NZ,SFSN07 ;ELSE IF C/R
- CALL RDFS ;READ SECTOR
- JR Z,SFSN08 ;IF BAD READ
- CALL ALRM ;SOUND THE ALARM
- XOR A
- LD (INCH),A ;DONT EXIT
- SFSN08 EQU $ ;ENDIF
- JR SFSN03
- SFSN07 EQU $ ;ELSE
- CALL ALRM ;ERROR
- SFSN03 EQU $
- LD A,(INCH)
- CP CR
- JR Z,SFSN99 ;EXITIF C/R
- CP $ESC
- JR Z,SFSN99 ;OR ESC
- JP SFSN01
- SFSN99 EQU $ ;ENDLOOP
- $FLD CURMSG ;REDISPLAY CURRENT SECTOR MESSAGE
- LD A,TRUE
- LD (FDMDSI),A ;REQUEST DISPLAY
- RET
-
- ; FSPM - FILE SCRATCHPAD MODE
-
- $RTN FSPM
- $NPANEL PSPMPN ;DISPLAY PANEL
- $FLD PSPCUR ;POSITION FOR CURRENT INFO
- LD A,(CURAN)
- ADD A,41H
- CALL CHRO ;DISPLAY DRIVE
- LD A,':'
- CALL CHRO
- $STRO FILENM
- $STRO SPSMSG
- $HEXW RELREC ;SECTOR
- $FLD PSPSPD ;POSITION FOR S/P DATA
- CALL DSPD ;DISPLAY SCRATCHPAD DATA
- CALL SPCI ;GET COMMAND
- $EXVA FSPMV ;PROCESS COMMAND
- LD A,0FFH
- LD (RPANEL),A ;REQUEST PANEL
- LD (FDMDSI),A ;REQUEST SECTOR INFO
- RET
-
- FSPMV: DW FSPX
- DW FLSP
- DW FXSP
-
- $RTN FSPX
- RET
-
- ; SPCI - GET SCRATCHPAD COMMAND
-
- $RTN SPCI
- SPCI01 EQU $ ;LOOP
- $IFLD SELMSG ;GET COMMAND
- $MTCH PSPML
- JR Z,SPCI02 ;EXIT IF VALID
- CALL ALRM ;SOUND ALARM
- JR SPCI01
- SPCI02 EQU $ ;ENDLOOP
- RET
-
- ; DSPI - DISPLAY S/P INFO
-
- $RTN DSPI
- LD A,(SPTYPE)
- OR A
- JR NZ,DSPI01 ;IF EMPTY
- $STRO SPEMTY
- JR DSPI02
- DSPI01 EQU $
- DEC A
- JR NZ,DSPI03 ;ELSE IF PHYSICAL
- $STRO SPDMSG
- LD A,(SPDRIV)
- ADD A,41H
- CALL CHRO ;DISPLAY DRIVE
- $STRO SPTMSG
- $HEXW SPNAME ;TRACK
- $STRO SPSMSG
- $HEXW SPSECT ;SECTOR
- JR DSPI02
- DSPI03 EQU $ ;ELSE FILE RELATIVE
- LD A,(SPDRIV)
- ADD A,041H
- CALL CHRO
- LD A,':'
- CALL CHRO
- $STRO SPNAME ;DISPLAY FILE NAME
- $STRO SPSMSG
- $HEXW SPSECT ;AND SECTOR
- DSPI02 EQU $ ;ENDIF
- RET
-
-
- ; FXSP - EXCHANGE WITH SCRATCHPAD
-
- $RTN FXSP
- LD A,(SPTYPE)
- OR A
- JR NZ,FXSP01 ;IF PAD EMPTY
- CALL ALRM ;RING BELL
- JR FXSP02
- FXSP01 EQU $ ;ELSE
- LD A,(RO)
- OR A
- JR Z,FXSP03 ;IF READ ONLY
- CALL ALRM ;ERROR
- JR FXSP04 ;ELSE
- FXSP03 EQU $
- LD BC,(SPADDR)
- CALL DMASET ;SET CPM BUFFER
- CALL WRFS ;WRITE BUFFER
- LD BC,FBUFF
- CALL DMASET ;RESTORE DMA
- CALL FLSP ;COPY OLD BUFFER
- CALL RDFS ;RE READ SECTOR
- FXSP04 EQU $ ;ENDIF
- FXSP02 EQU $ ;ENDIF
- RET
-
- ; FLSP - LOAD SCRATCHPAD (LOGICAL)
-
- $RTN FLSP
- LD HL,FBUFF
- LD DE,(SPADDR)
- LD BC,128
- LDIR ;COPY THE BUFFER
- LD A,(CURAN)
- LD (SPDRIV),A ;SET DRIV
- LD HL,FILENM
- LD DE,SPNAME
- LD BC,12
- LDIR ;COPY FILE NAME
- LD HL,(RELREC)
- LD (SPSECT),HL
- LD A,2
- LD (SPTYPE),A ;SET THE TYPE
- RET
-
- ; DFSI - DISPLAY FILE SECTOR INFORMATION
-
- $RTN DFSI
- $FLD WRSNFL ;POSITION FOR SECTOR NUMBER
- $HEXW RELREC ;DISPLAY RECORD NUMBER
- $FLD WRFOFL ;POSITION FOR FILE OFFSET
- LD HL,(RELREC) ;GET REC NO
- XOR A
- SRL H
- RR L
- RRA
- LD (BASEAD+2),A
- LD A,(COMFLG)
- OR A
- JR Z,DFSI01 ;IF .COM FLAG
- INC HL
- DFSI01 EQU $ ;ENDIF
- LD (BASEAD),HL ;SAVE REC/2
- CALL PRTADR ;PRINT 3 BYTE ADDRESS
- RET
-
- COMFLG: DS 1
-
- ; New Section
- ;
- pattrn: ds 21 ; 20 bytes ought to be enough ?
- lasthl: ds 2 ; pointers for last 'lead' byte found
- lastbc: ds 2 ;
- prevhl: ds 2 ; pointers to find in earlier sector
- prevbc: ds 2 ;
- oerlap: db 0 ; pattrn overlaps buffers flag
- curch: ds 1 ; byte storage
- lsflg: ds 1
- curct: ds 1
- cuhx: ds 1
- nib: ds 1
- fndmk: db 2,'->'
-
- ; FASC -- GET ASCII PATTERN FOR SEARCH, FIND AND DISPLAY IT.
-
- $RTN fasc
- ld a,0ffh
- ld (ascii),a
- call asin ; < = prompt, get and check ascii pattrn
- ; and leave it in pattrn, null terminated.
- call find ; go find it, display it etc.
- ret
-
- ; FIND -- search for and display with pointers all instances of hex
- ; or ascii patterns in object file. Prompts for continuation, and
- ; continues if requested to end of file. Ends on display of end of
- ; file, last sector accessed, or top of file
-
-
- $RTN find
- ld a,(afncnt)
- or a
- jp z,cpout
- top equ $
- xor a ; clear indicator of sector overlap
- ld (oerlap),a
- ld hl,fbuff
- ld bc,0080h
- ld (lasthl),hl
- ld (lastbc),bc
- ld (prevhl),hl ; storage for when we cross
- ld (prevhl),bc ; sector boundaries
- topres equ $
- ld a,0ffh ; signal not lone last byte
- ld (lsflg),a
- ld hl,(lasthl)
- ld bc,(lastbc)
- topccp equ $
- ld a,(afncnt)
- ld (curct),a
- ld de,pattrn ; get and look for 1st byte
- ld a,(de)
- cpir
- jp po,cplast ; if not overrun
- ld (lasthl),hl ; save pointers
- ld (lastbc),bc
-
- cprest equ $ ; check tail
- call DCCT ; next byte -- end of search pattern ?
- jr z,cpfnd ; yes -- go display find.
- dec c ; else are we at buffer end
- jp m,nbbitf ; yes
- cp (hl) ; no -- continue checking pattrn
- jr nz,topres ; failed -- restart search
- inc hl ; otherwise -- next buffer byte
- jr cprest ; and loop
-
- cplast equ $ ; was it a find on last byte
- jr z,cplfnd ; if not found on last byte
- call nxfs ; get another sector
- jp nz,cp99 ; aborting if none available
- jp top ; or looping if one is
-
- cplfnd equ $ ; else
- ld (lasthl),hl ; save these for screen
- ld (lastbc),bc
- call DCCT ; reached end ?
- jp nz,nbbitf ; if only byte in pattern
- ld a,c ; and it's at end of buffer
- ld (lsflg),a ; signal with c=0=lsflg and show it
- jp cpfnd ; endif
-
- nbbitf equ $ ; We found a bit, but reached end of sector
- ld (curch),a ; save current byte
- ld a,c ; use BC value as flag to show
- ld (lsflg),a ; whether found pattrn at very end
- ld hl,(lasthl)
- ld (prevhl),hl
- ld bc,(lastbc)
- ld (prevbc),bc ; save pointers for progress point
- ld a,0ffh
- ld (oerlap),a ; flagging that we have overlapped
- nbbit0 equ $
- call nxfs ; get/check next sector
- jp nz,cp99 ; reached eof -- exit
- ld hl,fbuff ; point to start of next sector
- ld bc,80h
- ld a,(curch) ; restore byte
- nbbit1 equ $
- cp (hl)
- jr nz,nbunf ; if found,
- call DCCT ; keep checking
- jr z,cpfnd
- inc hl
- jr nbbit1
-
- nbunf equ $ ; tried the overlap, but no match..
- ld a,(lsflg) ; was it on last byte anyway ?
- or a ; if so, loop
- jp z,top ; if not last byte
- call prfs ; go back a sector
- xor a ; establish we're back
- ld (oerlap),a
- ld hl,(prevhl) ; restore the sector's pointers
- ld bc,(prevbc)
- jp topccp ; and continue search on 1st sector
-
- cpfnd equ $ ; we found something
- ld bc,(lastbc) ; well get a pointer anyway
- ld a,(lsflg)
- or a
- jr nz,cpfnd0 ; if last char
- ld hl,fbuff ; reinitialise ptrs for new buffer
- ld (lasthl),hl
- ld bc,80h
- ld (lastbc),bc ; endif
-
- cpfnd0 equ $
- ld a,(oerlap) ; was find in overlap?
- or a
- jr z,cpfnd2 ; if overlap
- ld bc,(prevbc) ; replace ptr with earlier one
- cpfnd1 equ $
- call prfs ; and go back to start of find
- xor a ; remembering to flag that's done
- ld (oerlap),a
- cpfnd2 equ $
- push bc ; are registers saved ? save bc anyway
- call DFSI ; show things
- ld hl,FBUFF
- call WRBF
- pop bc ; get back byte ptr
- ld hl,80h ; calculate equivalent
- or a ; of bufpos for display
- sbc hl,bc
- ld a,l
- or a
- jr nz,cpfnd3 ; if zero, it's last byte
- ld a,80h ; so set up to char in front
- cpfnd3 equ $
- dec a
- ld (bufpos),a ; use that
- call slcp ; to update cursor and
- ld hl,(lpos) ; then fiddle
- dec h ; to go back a bit more
- dec h ; to allow room for visual ptr
- ld (lpos),hl
- call udcp ; point to that position
- call vmInv
- ld hl,fndmk ; and point to the find
- call strl
- call vmNorm
- $fld fndcon ; ask if we want next
- call chrf ; get answer to next query
- cp 'Y'
- push af ; save response
- call slcp ; reposition on display
- ld hl,(lpos)
- dec h ; back again
- dec h
- ld (lpos),hl
- call udcp ; for cursor update and
- call spco ; clear fndmk
- call spco
- pop af ; now check query answer
- jp nz,cpout ; if next wanted, do it
- jr nz,cp99
- ld a,(lsflg) ; but check first
- or a ; if on last byte in buffer
- jp nz,topres ; not ? then loop
- call nxfs ; last byte? get new sector
- jp z,topres ; if its there, loop
- ; else
- cp99 equ $ ; clear pattrn input line
- ld hl,fndcon
- call cfld
- ld a,8
- call CLRL
- $fld notfnd ; say eof and not found
- call chrf ; wait, displaying, for any input
- cp 'T'
- jr nz,cpout
- call frfs
- cpout equ $
- ld a,0ffh
- ld (rpanel),a
- cpout1 equ $
- ld (fdmdsi),a
- ret
-
- ; DDCT - GET NEXT PATTERN BYTE AND CHECK COUNT OF BYTES
-
- $RTN DCCT ; get next byte
- inc de
- ld a,(de)
- push hl ; and decrement count
- ld hl,curct
- dec (hl) ; did we get to end ?
- pop hl
- ret
-
-
- ; ASIN -- GETTING ASCII PATTERN INPUT FOR SEARCH
-
- $RTN asin
- call sstr
- asin01 equ $
- call afnc ; position cursor
- call chri ; get a char (unfolded)
- cp CR
- JR Z,asin99
- cp $ESC
- jr NZ,asin02
- xor a
- ld (pattrn),a
- jp asin99
-
- asin02 equ $
- $MTCH asincd ; if scrn char control key
- jr nz,asin03
- $EXVA asinvc ; do action required
- JR asin01 ; endif
-
- asin03 equ $
- cp $TAB
- jr z,asin04
- cp 20h ; else if not other ctrl key
- jr nc,asin04
- call alrm
- jr asin01
-
- asin04 equ $
- call pastr ; output progress
- ld a,(afnmax)
- ld hl,afncnt
- inc (hl)
- cp (hl)
- jp nz,asin01
- call alrm
-
- asin99 equ $
- ret
-
- asincd: db 3,$LEFT,$RIGHT,$DELETE
-
- asinvc: dw afnl
- dw afnr
- dw afnd
-
-
- ; PASTR -- STORING BYTES OF PATTERN FOR SEARCH
-
- $RTN pastr
- push af
- ld hl,(afnchp)
- ld a,(afncnt)
- call aahl
- pop af
- ld (hl),a
- push af
- ld a,(ascii)
- or a
- jr z,pastr1
- pop af
- call chro
- jr pastr2
- pastr1 equ $
- pop af
- call hexo
- pastr2 equ $
- ret
-
- ; FHEX -- INPUT HEX SEQUENCE AND SEARCH FOR IT.
- $RTN fhex
- xor a
- ld (ascii),a
- call hxin
- call find
- ret
- ;
-
- ; SSTR -- INITIALISING PATTERN FOR SEARCH AND PROMPTING
-
- $RTN sstr ; initialise variables
- xor a ; and prompt for find input
- ld (afncnt),a
- ld (pattrn),a
- $fld fndpmt
- ld hl,(strpos)
- ld (afncur),hl
- ld a,20
- ld (afnmax),a
- ld hl,pattrn
- ld (afnchp),hl
- ret
-
- ; HXIN -- GETTING INPUT OF HEX BYTE SEQUENCE FOR SEARCH
-
-
- $RTN hxin
- call sstr ; initialise
- hxnib1 equ $
- xor a ; clear temporary byte hold
- ld (cuhx),a
- call hxsc ; position on screen
- $strl cllstr ; clear line beyond that
- call hxsc ; reposition
- call chrf ; get a nibble in
- $MTCH HEXCHR
- jr nz,hxino1
- ld a,(cuhx)
- call hxad
- ld (cuhx),a
- call pastr ; now save byte and display
- ld hl,afncnt ; incrementing byte count
- inc (hl)
-
- hxnib2 equ $
- call chrf
- $MTCH HEXCHR
- jr nz,hxino2
- ld a,(cuhx)
- call hxad
- ld (cuhx),a
- ld hl,afncnt ; going back in byte count
- dec (hl)
- call hxsc ; to ensure save and screen right
- call pastr
- ld a,(afnmax) ; IF after 2 nibbles in,
- ld hl,afncnt ; we are at maximum byte count
- cp (hl) ; exit
- jp z,hxin99 ; ENDIF
- inc (hl) ; IF NOT
- jp hxnib1 ; loop for another byte
- ; ENDIF
- hxino1 equ $ ; IF NON-HEX CHARS ON 1st nibble,
- ld a,(inch) ; SWITCH CASE
- cp CR ; CASE cr input,
- jr z,hxin99 ; we're done
- cp $ESC ; CASE esc
- jp z,hxinX ; exit signalling no valid input
- cp $LEFT ; CASE left
- jr nz,hxinw1
- ld a,(afncnt) ; IF still the 1st byte of input
- or a ; just restart //ENDIF
- jp z,hxnib1 ; ENDIF
- dec a ; IF not 1st byte,decrement count
- ld (afncnt),a ; and restart
- jp hxnib1 ; ENDIF
-
- hxinw1 equ $ ; DEFAULT:
- call alrm ; ring bell
- jp hxnib1 ; and try agin
-
-
- hxino2 equ $ ; NON-HEX INPUT 2nd nibble
- ld a,(inch)
- cp CR
- jr nz,hxino3
- ld hl,afncnt ; decrement count
- dec (hl) ; before exit, but ...
- jr nz,hxin99 ; IF it's single 1st nibble
- inc (hl) ; don't signal no input
- jr hxin99 ; ENDIF
- hxino3 equ $
- cp $ESC
- jr z,hxinX
- cp $LEFT
- jr nz,hxinw2
- xor a
- ld hl,cuhx ; rotate byte back
- rrd
- ld a,(hl)
- or a ; IF still known relevant data
- jp nz,hxnib2 ; loop for 2nd nibble
- ld hl,afncnt ; ELSE reposition
- dec (hl) ; and loop for whole new byte
- jp hxnib1 ; ENDIF
-
- hxinw2 equ $ ; wrong input
- call alrm ; ring and loop
- jp hxnib2
-
- hxinX equ $ ; exit -- cancel search
- xor a
- ld (afncnt),a
- hxin99 equ $ ; just exit
- ret
-
-
- ; HXSC -- POSITION CURSOR FOR HEX SCREEN INPUT -- EACH BYTE
- ; SEPARATED WITH SPACES
-
-
- $RTN hxsc
- push bc
- push af
- ld hl,(afncur)
- ld a,(afncnt)
- ld b,a
- add a,a
- add a,b
- add a,h
- ld h,a
- call curs
- pop af
- pop bc
- ret
-
- ; HXAD
-
- $RTN hxad
- ex de,hl ; move value into de
- ld l,a ; and current byte into L
- ld h,0 ; rotating and adding
- call h16d
- ld a,l ; and getting result in af
- ret
-
- ; End of New Section v.3 mod 4 pgm
-
- ; DRMD - DIRECTORY MODE
-
- $RTN DRMD
- LD HL,(DRMDEF)
- LD (ERRFLD),HL ;SET PANEL ERROR FIELD
- LD A,TRUE
- LD (DRMDLD),A ;REQUEST LIST
- DRMD01 EQU $ ;LOOP
- LD A,(DRMDLD)
- OR A
- JR Z,DRMD02 ;IF LIST REQUIRED
- $NPANEL DRMDPN ;DISPLAY DIRECTORY LIST PANEL
- CALL DLST ;DO DIRECTORY LIST
- XOR A
- LD (DRMDLD),A ;RESET LIST REQUEST
- DRMD02 EQU $ ;ENDIF
- DRMD06 EQU $ ;LOOP
- CALL ERRP ;PROCESS ERRORS
- LD A,(SELDE)
- CALL DIRPOS ;POSITION OVER CURRENT ENTRY
- CALL CHRF
- $MTCH DRMDLS
- JR Z,DRMD05 ;EXITIF VALID
- CALL ALRM ;SOUND ALARM
- JR DRMD06
- DRMD05 EQU $ ;ENDLOOP
- $EXVA DRMDVC ;PERFORM ACTION
- LD A,(WTG)
- CP 'D'
- JR NZ,DRMD07 ;EXIT IF MODE NO LONGER D
- JP DRMD01
- DRMD07 EQU $ ;ENDLOOP
- RET
-
-
- ; DIRECTORY MODE PANEL AND VECTOR
- ;
- ; Updated Jan 86 by JHB to include user number selection
-
- DRMDPN: DB 13 ;(Was 12)
- DB 02,00,'^',$LEFT+040H,' Cursor left',0
- DB 03,00,'^',$RIGHT+040H,' Cursor right',0
- DB 04,00,'^',$UP+040H,' Cursor up',0
- DB 05,00,'^',$DOWN+040H,' Cursor down',0
- DB 02,22,'P Previous directory page',0
- DB 03,22,'N Next directory page',0
- db 04,22,'U Change user number',0
- DB 02,54,'Z Exit from Superzap',0
- DB 03,54,'C Change disk',0
- DB 04,54,'S Select track/sector',0
- DB 05,54,'M Set directory selection',0
-
- DB 07,00,'E Edit file',0
- DB 07,22,'T Type file',0
-
- DRMDLS: DB 15,$LEFT,$RIGHT,$UP,$DOWN,CR,'EZCSMPNTU',$TAB
-
- DRMDVC: DW FBS
- DW FFS
- DW FUP
- DW FDN
- DW FNL
- DW STFL
- DW SETX
- DW CHDD
- DW SETP
- DW SAFN
- DW DIRP
- DW DIRN
- DW TYPE
- DW CHUN
- DW FFS
-
- DRMDEF: DB 9,0
- NRFMSG: DB '** No records in file',0
- FNFMSG: DB '** File not found',0
-
- DRMDLD: DS 1 ;LIST DIRECTORY REQUEST FLAG
-
-
- ; DIRP - PAGE UP DIRECTORY
-
- $RTN DIRP
- LD A,(DIROFF)
- OR A
- JR Z,DIRP01 ;IF NOT PAGE 0
- SUB 32
- LD (DIROFF),A ;SET PREV PAGE
- XOR A
- LD (SELDE),A ;FIRST ENTRY ON PAGE
- CALL ERRP
- LD HL,DRAREA
- CALL CLRA ;CLEAR AREA
- CALL DLST ;DISPLAY PAGE
- JR DIRP02
- DIRP01 EQU $ ;ELSE
- CALL ALRM ;RING BELL
- DIRP02 EQU $ ;ENDIF
- RET
-
- ; DIRN - PAGE DOWN DIRECTORY
-
- $RTN DIRN
- LD A,(DIROFF)
- ADD A,32 ;POINT TO NEXT PAGE
- LD HL,DECNT
- CP (HL)
- JR NC,DIRN01 ;IF AVAILABLE
- LD (DIROFF),A ;SAVE NEW POINTER
- XOR A
- LD (SELDE),A ;SET FIRST ENTRY ON PAGE
- CALL ERRP
- LD HL,DRAREA
- CALL CLRA ;CLEAR DIRECTORY AREA
- CALL DLST ;DISPLAY DIRECTORY
- JR DIRN02
- DIRN01 EQU $ ;ELSE
- CALL ALRM ;ALARM
- DIRN02 EQU $ ;ENDIF
- RET
-
-
- ; FBS - BACKSPACE IN DIRECTORY
-
- $RTN FBS
- LD A,(DIROFF)
- LD B,A
- LD HL,DECNT
- FBS01 EQU $ ;REPEAT
- LD A,(SELDE)
- DEC A
- AND 31
- LD (SELDE),A ;SELECT PREVIOUS
- JR Z,FBS02 ;EXIT IF FIRST POSN
- ADD A,B
- CP (HL)
- JR NC,FBS01 ;UNTIL NEW<=MAX
- FBS02 EQU $
- RET
-
- ; FUP - CURSOR UP IN DIRECTORY
-
- $RTN FUP
- LD A,(DIROFF)
- LD B,A
- LD HL,DECNT
- FUP01 EQU $ ;REPEAT
- LD A,(SELDE)
- SUB 4
- AND 31
- LD (SELDE),A ;1 LINE UP
- JR Z,FUP02 ;EXIT IF FIRST POSN
- ADD A,B
- CP (HL)
- JR NC,FUP01 ;UNTIL NEW<=MAX
- FUP02 EQU $
- RET
-
- ; FDN - CURSOR DOWN IN DIRECTORY
-
- $RTN FDN
- LD A,(DIROFF)
- LD B,A
- LD HL,DECNT
- FDN01 EQU $ ;REPEAT
- LD A,(SELDE)
- ADD A,4
- AND 31
- LD (SELDE),A ;1 LINE DOWN
- JR Z,FDN02
- ADD A,B
- CP (HL)
- JR NC,FDN01 ;UNTIL NEW<=MAX
- FDN02 EQU $
- RET
-
- ; FNL - C/R IN DIRECTORY
-
- $RTN FNL
- LD A,(DIROFF)
- LD B,A
- LD HL,DECNT
- FNL01 EQU $ ;REPEAT
- LD A,(SELDE) ;PICK UP CURRENT
- ADD A,4 ;MOVE TO NEXT LINE
- AND 01CH
- LD (SELDE),A ;START OF NEXT LINE
- JR Z,FNL02
- ADD A,B
- LD HL,DECNT
- CP (HL)
- JR NC,FNL01 ;UNTIL NEW<=MAX
- FNL02 EQU $
- RET
-
- ; FFS - CURSOR FORWARD IN DIRECTORY
-
- $RTN FFS
- LD A,(DIROFF)
- LD B,A ;GET START OF DISPLAY
- LD HL,DECNT
- FFS01 EQU $ ;REPEAT
- LD A,(SELDE)
- INC A
- AND 31
- LD (SELDE),A ;NEXT ENTRY
- JR Z,FFS02
- ADD A,B
- CP (HL)
- JR NC,FFS01 ;UNTIL NEW<=MAX
- FFS02 EQU $
- RET
-
- ; DIRPOS - POSITION TO PRINT DIRECTORY ENTRY
-
- DIRPOS EQU $
- LD (DIRNUM),A ;SAVE ENTRY POSITION
- LD HL,LPTAB
- RRCA
- RRCA ;DIVIDE COUNT BY 4
- AND 0FH ;MAKE IT LINE COUNT
- CALL AAHL
- LD B,(HL) ;PICK UP LINE POSN
- LD HL,DCTAB
- LD A,(DIRNUM) ;PICK UP ENTRY AGAIN
- AND 03 ;MAKE COUNT INTO COLUM NUMBER
- CALL AAHL
- LD H,(HL) ;GET COLUMN POSITION
- LD L,B ;AND LINE NUMBER
- CALL CURS ;POSITION CURSOR
- RET
- DIRNUM: DS 1
-
-
- ; STFL - SELECT FILE
-
- $RTN STFL
- CALL CFCB ;COPY FCB FROM DIR LIST
- CALL SETF ;SET FILE MODE
- RET
-
- ; CFCB - COPY FCB FROM DIRECTORY LIST
-
- $RTN CFCB
- LD A,(DECNT)
- OR A
- JR NZ,CFCB01 ;IF NO FILES
- CALL ALRM ;SOUND ALARM
- LD HL,FNFMSG
- LD (ERRTXT),HL ;SET FILE NOT FOUND ERROR
- JR CFCB02
- CFCB01 EQU $ ;ELSE
- LD A,(SELDE) ;GET SELECTED ENTRY NUMBER
- LD B,A
- LD A,(DIROFF)
- ADD A,B ;ADD DISPLAY START
- LD H,0
- LD L,A
- LD DE,(MEMRY) ;BASE OF TABLE
- CALL H16D ;HL=HL*16+DE
- LD DE,WRKFN ;START OF FILE NAME
- LD BC,11
- LDIR ;MOVE DE OVER TO FCB
- XOR A
- LD (WRKEX),A
- CFCB02 EQU $ ;ENDIF
- RET
-
- ; Second new section --main routine has bits and pieces added...PGM.
- ; TYPE - TYPE SELECTED FILE
-
- $RTN TYPE
- CALL CFCB ;SET UP FCB
- CALL TFLE ;TEST FILE
- LD A,(FLERR)
- OR A
- JP NZ,TYPE01 ;IF FILE FOUND
- XOR A
- LD (BUFPOS),A ;BUFFER OFFSET 0
- LD (BASEAD+1),A
- ld (tqued),a ; New -- reset already queued flag
- ld (linesc+1),a ; and line count
- ld (tsect),a ; and specific sector flag
- ld (tline),a ; and specific line flag
- INC A
- LD (BASEAD),A ;INITIALISE PAGE NUMBER 1
- ld (linesc),a ; new -- line number 1
- CALL TGET ;PRIME FIRST CHARACTER
- LD HL,(PGEPTR)
- LD (CURPG@),HL ;SET CURRENT PAGE ENTRY TO FIRST
- LD (MAXPG@),HL ;AND LAST
- LD A,0FFH
- LD (TYPEX),A ;SET NO EXIT
- LD (TYDSP),A ;REQUEST DISPLAY
- TYPE03 EQU $ ;LOOP
- LD A,(TYDSP)
- OR A
- JR Z,TYPE09 ;IF DISPLAY REQUIRED
- XOR A
- LD (TYDSP),A ;RESET REQUEST
- $NPANEL TYPEPN ;DISPLAY PANEL
- $FLD TYPEFN
- $STRO DRIVNM ; new filename display
- $fld mxsnum ; and data on max sector
- $hexw maxrec
- $FLD PGENUM
- $HEXW BASEAD ;DISPLAY PAGE NUMBER
- $FLD RECNUM
- $HEXW RELREC ;DISPLAY RECORD NUMBER
- $fld linnum ; new line number display
- $hexw linesc
- CALL TYPG ;DISPLAY PAGE
- ld a,(tqued) ; new -- is data queued?
- or a ; (this probably should go elsewhere)
- call z,TYPQ ; if not, queue it
- xor a ; reinitialise flags
- ld (tsect),a
- ld (tline),a
- $fld recnm2 ; and then end of ranges
- $hexw relrec ; display range
- $fld linnm2
- $hexw lastln
- TYPE09 EQU $ ;ENDIF
- TYPE06 EQU $ ;LOOP
- $IFLD TYPIP ;GET COMMAND
- $MTCH TYPLST
- JR Z,TYPE05 ;EXITIF VALID
- CALL ALRM ;SOUND ALARM
- JR TYPE06
- TYPE05 EQU $ ;ENDLOOP
- $EXVA TYPVEC ;EXEC COMMAND
- LD A,(TYPEX)
- OR A
- JR Z,TYPE04 ;EXITIF FLAG SET
- JP TYPE03 ; not relative any more
- TYPE04 EQU $ ;ENDLOOP
- TYPE01 EQU $ ;ENDIF
- LD A,TRUE
- LD (DRMDLD),A ;REQUEST DIRECTORY LIST
- RET
-
- TYPEPN: DB 11 ; new display and extra options
- DB 01,00,'N Next page',0
- DB 01,22,'R Return after Paging',0
- DB 01,50,'L Exit to file list',0
- DB 02,00,'P Previous page',0
- DB 02,22,'T Top of file',0
- DB 02,50,'Z Exit from Superzap',0
- db 03,00,'S Sector to type',0
- db 03,22,'G Goto Page No.',0
- db 03,50,'W Select line',0
- db 04,00,'Enter Selection ==>',0
-
- mxsnum: db 05,50,'Max. Sector ',0
- mxout: db 05,62,0 ; posn for max sector
- PGENUM: DB 6,0,'Page ',0 ; moved down & across
- RECNUM: DB 6,32,'Sectors ',0
- recnm2: db 6,44,'-',0
- tyfofl: db 6,44,0 ; input position for 1st sector
- linnum: db 6,60,'Lines ',0
- linnm2: db 6,71,'-',0
- loadin: db 4,22,'** LOADING FILE DATA **',0
- TYPEFN: DB 5,22,'File : ',0 ; on diff line
- TYPIP: DB 4,19,0 ;new input position
- TYPFL: DB 8,0,0 ;FIRST CHR POSITION
- tcsend: db 6,44,' ',0
- tclend db 6,71,' ',0
-
- decs db 10,'0123456789' ; new data for decimal input
-
- TYPLST: db 9,'NRLPTZSGW'
- TYPVEC: DW TYPF
- DW TYPR
- DW TYPL
- DW TYPB
- DW TYPT
- DW TYPZ
- dw typs ; new options
- dw typp
- dw tpln
-
- TYPEX: DS 1 ;EXIT FLAG
- TYDSP: DS 1 ;DISPLAY REQUEST
- TYPEOP: DS 1 ;END OF PAGE
- target: DS 2 ; sector requested
- tqued: ds 1 ; queued flag
- tsect: ds 1 ; flag showing typs called
- tline: ds 1 ; flag showing tpln called
- maxrec: ds 2 ; last sector read
- savba: ds 2 ; temp storage, basead
- lastln: ds 2
-
- ; TYPF - FORWARD PAGE
-
- $RTN TYPF
- LD A,(READST)
- OR A
- JR Z,TYPF01 ;IF EOF
- CALL ALRM
- JR TYPF02
- TYPF01 EQU $ ;ELSE
- LD HL,(CURPG@)
- LD DE,8
- ADD HL,DE
- LD (CURPG@),HL ;UPDATE CURRENT POINTER
- LD A,0FFH
- LD (TYDSP),A ;REQUEST DISPLAY
- TYPF02 EQU $
- RET
-
- ; TYPR - RETURN AFTER PAGING
-
- $RTN TYPR
- LD HL,(CURPG@)
- LD DE,(MAXPG@)
- XOR A
- SBC HL,DE
- JR Z,TYPR01 ;IF NOT END OF FILE
- EX DE,HL ;RESTORE TOP OF QUEUE
- LD DE,8
- XOR A
- SBC HL,DE
- CALL LPGE ;LOAD LAST PAGE
- LD A,0FFH
- LD (TYDSP),A ;REQUEST DISPLAY
- TYPR01 EQU $ ;ENDIF
- RET
-
- ; TYPL - EXIT TYPE TO DIR LIST
-
- $RTN TYPL
- XOR A
- LD (TYPEX),A ;REQUEST EXIT
- RET
-
- ; TYPB - PAGE BACKWARD
-
- $RTN TYPB
- LD DE,(CURPG@)
- LD HL,(PGEPTR)
- XOR A
- SBC HL,DE
- JR Z,TYPB01 ;IF NOT TOP OF FILE
- EX DE,HL
- LD DE,8
- XOR A
- SBC HL,DE
- CALL LPGE ;LOAD PAGE DATA
- LD A,0FFH
- LD (TYDSP),A ;REQUEST DISPLAY
- TYPB01 EQU $ ;ENDIF
- RET
-
- ; TYPT - PAGE TO TOP OF FILE
-
- $RTN TYPT
- LD HL,(PGEPTR)
- CALL LPGE ;LOAD FIRST PAGE
- LD A,0FFH
- LD (TYDSP),A ;REQUEST DISPLAY
- RET
-
- ; TYPZ - EXIT TYPE TO CP/M
-
- $RTN TYPZ
- CALL SETX ;EXIT SUPERZAP
- XOR A
- LD (TYPEX),A ;REQUEST EXIT
- RET
-
- ; TYPG - TYPE PAGE
- ; alterations include renumbering of labels -- pgm.
- $RTN typg
- CALL QPGE ;PUT PAGE ON QUEUE
- $FLD TYPFL ;POSITION FOR FIRST CHAR
- ; $STRO TYNPRF ;LEFT MARGIN -- omitted
- XOR A
- LD (TYPEOP),A ;RESET END OF PAGE
- LD (PGECOL),A
- LD (PGELNE),A ;LINE 0 COL 0
- typg01 EQU $ ;LOOP
- LD A,(TYPEOP)
- OR A
- jp NZ,typg99 ; exit if eop (non-rel jump)
- LD A,(COMFLG)
- OR A
- LD A,(TYCURC)
- JR Z,typg02 ;IF COM FILE
- push af
- xor a
- ld (tsect),a ; not whole sector
- pop af
- CALL TPUT ;OUTPUT CHARACTER
- LD A,(READST)
- OR A
- jp NZ,typg99 ; exit if end of file (non-rel now)
- LD A,(TYPEOP)
- OR A
- jp NZ,typg99 ; or end of page
- CALL TGET ;GET NEXT CHARACTER
- jp typg12
- typg02 EQU $ ;ELSE (NOT A COM FILE)
- push af
- ld a,(tsect)
- or a
- jr z,typg03
- ld hl,(WRKRR)
- call tinv
- jr typg04
- typg03 EQU $
- ld hl,(LINESC)
- ld a,(tline)
- or a
- call nz,tinv
- typg04 EQU $
- pop af
- CP 009H
- JR NZ,typg06 ;IF TAB
- typg05 EQU $ ;REPEAT
- LD A,' '
- CALL TPUT ;PUT SPACE
- LD A,(PGECOL)
- AND 7
- JR NZ,typg05 ;UNTIL TAB STOP
- jp typg11
- typg06 EQU $
- CP CR ; ELSE IF C/R
- JR Z,typg07 ; GO CHECK FOR TRAILING L/F
- ld hl,HARD1
- cp (hl) ; do same for 'hard's
- jr z,typg07
- ld hl,HARD2
- cp (hl)
- jr z,typg07 ; (just do newline)
- ld hl,SOFT1 ; now process 'softs'
- cp (hl)
- jr z,typg09
- ld hl,SOFT2
- cp (hl)
- jr z,typg09
- jr typg10
- typg07 EQU $
- LD A,(READST)
- OR A
- JR NZ,typg08 ;IF EOF
- LD A,(BUFPOS)
- LD HL,FBUFF
- CALL AAHL
- LD A,(HL)
- CP 00AH
- push AF ; save result
- call TYNL ; but do newline anyway
- pop AF
- call z,TGET ; and swallow char if L/F there
- JR typg11
- typg08 EQU $ ; eof cr only
- LD A,CR
- CALL TPUT ;PUT CHAR
- JR typg11
- typg09 EQU $ ;ELSE
- CALL TYNL ; newline for softs
- JR typg11 ;ENDIF
- typg10 EQU $ ;ELSE
- CALL TPUT ; just do a NORMAL char output
- typg11 EQU $ ;ENDIF
- LD A,(READST)
- OR A
- JR NZ,typg99 ;EXIT IF EOF
- CALL TGET ;GET NEXT CHR
- typg12 EQU $
- jp typg01 ; non-relative jmp, now
- typg99 EQU $ ;ENDLOOP
- call vmNorm ; ensure enhancement off eof
- LD HL,(BASEAD)
- call BCDU ; do bcd incrementing
- LD (BASEAD),HL ;INC PAGE NUMBER
- RET ;ENDIF
-
- PGECOL: DS 1
- PGELNE: DS 1
- TUNPUT: db 0 ; flag for dummy paging ops
- ; TYNPRF: DB ' ',0 ; <= omitted left margin
-
- ; QPGE - PUT PAGE DATA ON QUEUE
-
- $RTN QPGE
- LD HL,(MAXPG@)
- LD DE,(CURPG@)
- XOR A
- SBC HL,DE
- JR NZ,QPGE01 ;IF AT END OF Q
- LD HL,TYCURC
- LD DE,(MAXPG@)
- LD BC,8
- LDIR ;COPY PAGE DATA
- LD (MAXPG@),DE ;UPDATE MAX PTR
- QPGE01 EQU $ ;ENDIF
- RET
-
-
- ; LPGE - LOAD PAGE DATA FROM QUEUE AT (HL)
-
- $RTN LPGE
- LD (CURPG@),HL ;SET CURRENT POINTER
- LD DE,TYCURC
- LD BC,8
- LDIR ;COPY PAGE DATA
- CALL RDFS ;READ FIRST SECTOR OF PAGE
- RET
-
-
- ; TGET - GET CHARACTER FOR TYPE
-
- $RTN TGET
- LD A,(READST)
- OR A
- JR NZ,TGET02 ;IF NOT EOF
- LD HL,BUFPOS
- LD A,(HL) ;GET CURRENT OFFSET
- INC (HL) ;INC FOR NEXT GET
- LD HL,FBUFF
- CALL AAHL ;POINT TO CURRENT CHARACTER
- LD A,(HL)
- LD (TYCURC),A ;GET CHARACTER
- LD A,(BUFPOS)
- CP 080H
- JR NZ,TGET01 ;IF BUFPOS=80
- LD HL,(RELREC)
- ld a,(tqued) ; new -- check if queued
- or a
- jr nz,tget04 ; if not queued
- ld (maxrec),hl ; save last sector
- tget04 equ $ ; endif
- call tinv ; switch for enhanced display on/off
- INC HL
- LD (RELREC),HL ;SET NEXT SECTOR
- call tinv ; switch again
- XOR A
- tget03 equ $
- LD (BUFPOS),A ;BUFFER OFFSET=0
- CALL RDFS ;READ SECTOR
- TGET01 EQU $ ;ENDIF
- TGET02 EQU $ ;ENDIF
- LD A,(TYCURC) ;RETURN CHARACTER
- RET
-
-
- ; TINV -- ENHANCE SECTOR switch routine -- checks if needed.
-
- $RTN tinv
- ld a,(tsect)
- or a
- jr nz,tinv1
- ld a,(tline)
- or a
- jr z,tinv4
- tinv1 equ $
- push hl
- push de ; preserve -- in case
- ld de,(TARGET)
- sbc hl,de
- jr NZ,tinv2
- call vmInv
- jr tinv3
- tinv2 equ $
- call vmNorm
- tinv3 equ $
- pop de ; and restore
- pop hl
- tinv4 equ $
- ret
-
-
- ; TPUT - TYPE A CHARACTER
-
- $RTN TPUT
- LD B,A
- LD A,(PGECOL)
- CP 79 ; changed for 80 cols -- no left margin
- JR NZ,TPUT01 ; if COL=79
- CALL TYNL ; TAKE NEW LINE
- TPUT01 EQU $ ; endif
- LD A,(TYPEOP)
- OR A
- JR NZ,TPUT02 ;IF NOT EOP
- ld a,(TUNPUT) ; if unput flagged
- or a ; then skip screen output
- jr nz,TPUT03 ; and just count lines
- LD A,B ; else
- CALL ASCO ;OUTPUT CHARACTER
- TPUT03 EQU $ ; endif
- LD HL,PGECOL
- INC (HL) ;INC COL COUNT
- TPUT02 EQU $ ;ENDIF
- RET
-
-
- ; TYNL - TYPE NEW LINE
-
- $RTN TYNL
- XOR A
- LD (PGECOL),A ;SET COL 0
- ld hl,(LINESC) ; get file line count
- ld (LASTLN),hl
- call BCDU ; incremented
- ld (LINESC),hl
- call tinv ; switch if we've got to specified line
- LD HL,PGELNE
- INC (HL) ;NOW PAGE LINE COUNT UP
- LD A,16
- CP (HL)
- JR NZ,TYNL01 ;if page line = 16
- ld a,(tsect) ; check if page specified and done
- or a
- call nz,vmNorm ; switch enhanced off if it is
- LD A,0FFH
- LD (TYPEOP),A ;SET END OF PAGE
- JR TYNL02
- TYNL01 EQU $ ;ELSE
- ld a,(TUNPUT) ; check if just counting lines
- or a
- jr nz,TYNL02
- LD A,00DH ; if not, output newline
- CALL CHRO
- LD A,00AH
- CALL CHRO ;OUTPUT CRLF
- ; $STRO TYNPRF ; <= omitted left margin again
- TYNL02 EQU $ ;ENDIF
- RET
-
- ; all new option
- ; TYPS -- selecting sector for typing
-
- $RTN typs
- ld a,0ffh
- ld (tsect),a ; flag specific sector function
- ld hl,(RELREC) ; save current
- ld (SAVFSC),hl
- ld hl,0 ; set to start
- ld (RELREC),hl
- typs00 equ $
- $fld tcsend ; clear end of range bit
- $fld recnum ; redisplay sector
- $hexw relrec
- call CHRF ; get folded input
- $MTCH HEXCHR
- jr nz,typs01
- ex de,hl
- ld hl,(RELREC)
- call H16D
- ld (RELREC),hl
- jr typs05
- typs01 equ $
- cp $ESC
- jr nz,typs02
- ld hl,(SAVFSC)
- ld (RELREC),hl
- jr typs05
- typs02 equ $
- cp $LEFT
- jr nz,typs03
- ld hl,RELREC+1
- xor a
- rrd
- dec hl
- rrd
- jr typs05
- typs03 equ $
- cp CR
- jr nz,typs04
- ld hl,(RELREC) ; get sector target
- ld (TARGET),hl ; and save it for later
- ld hl,(PGEPTR)
- ld de,1 ; offset to 1st relrec instance
- call tloc ; look for and load data
- jr z,typs99 ; if actual read error
- xor a
- ld (INCH),a ; fall thru to alrm
- typs04 equ $
- call ALRM ; endif
- typs05 equ $
- ld a,(INCH)
- cp CR
- jr z,typs99
- cp $ESC
- jr NZ,typs00 ; loop bottom
-
- typs99 equ $
- ld a,0ffh
- ld (TYDSP),a
- ret
-
- ; New
- ; TYPQ -- COMPILE QUEUE OF DATA FOR WHOLE FILE
- typq equ $
- ld a,0ffh
- ld (TUNPUT),a ; set unput flag
- ld hl,(SAVFSC) ; go back to where we were
- ld (RELREC),hl
- call TYPT ; start at top,
- typq01 equ $
- call vmInv
- $FLD LOADIN
- call vmNorm
- call TYPG ; using dummy paging process
- $fld mxout
- $hexw maxrec
- call TYPF ; getting next page
- ld hl,loadin ; and flashing signal
- call cfld
- ld a,(READST)
- or a
- jr z,typq01 ; until eof
- ld hl,(CURPG@) ; insert null terminators
- ld de,8
- add hl,de
- xor a
- ld b,e
- typq02 equ $
- ld (hl),a
- inc hl
- djnz typq02
- typq03 equ $
- ld (tunput),a ; reset dummy run flag
- dec a ; set queued-already flag,
- ld (tqued),a
- call TYPT ; and call redisplay of 1st sector
- ret
-
- ; new option
- ; TYPP -- Select and find screen page within file to display
-
- $RTN typp ; select page number to type
- ld hl,(RELREC)
- ld (SAVFSC),hl
- ld hl,(BASEAD)
- ld (SAVBA),hl
- ld hl,0
- ld (BASEAD),hl
- typp00 equ $
- $fld PGENUM
- $hexw BASEAD
- call CHRF
- $MTCH DECS
- jr nz,typp01
- ld a,l
- ld hl,(BASEAD)
- add hl,hl
- add hl,hl
- add hl,hl
- add hl,hl
- add a,l
- daa
- ld l,a
- ld a,h
- ld h,0
- adc a,h
- daa
- ld h,a
- ld (BASEAD),hl
- jr typp00
-
- typp01 equ $
- cp $ESC
- jr nz,typp02
- ld hl,(SAVFSC)
- ld (RELREC),hl
- ld hl,(SAVBA)
- ld (BASEAD),hl
- jp typp06
-
- typp02 equ $
- cp $LEFT
- jr nz,typp03
- ld hl,BASEAD+1
- xor a
- rrd
- dec hl
- rrd
- jr typp06
-
- typp03 equ $
- cp CR
- jr nz,typp05
- ld hl,(BASEAD)
- ld a,l
- or h
- jr nz,typp04 ; if zero page
- inc a ; make it page 1
- ld (BASEAD),a ; endif
- typp04 equ $
- ld hl,(BASEAD)
- ld (TARGET),hl
- ld hl,(PGEPTR)
- ld de,6 ; offset to basead posn
- call tloc ; call routine to find target
- ; and test it for range
- jr z,typp99 ; if read error
- xor a ; signal
- ld (INCH),a ; and fall thru alarm
-
- typp05 equ $
- call ALRM
- ; endif
- typp06 equ $
- ld a,(INCH)
- cp CR
- jr z,typp99
- cp $ESC
- jp nz,typp00 ; loop
- xor a
- ld (TYDSP),a
-
- typp99 equ $
- ld a,0ffh
- ld (TYDSP),a
- ret
-
- ; 3rd new option under TYPE
-
- ; TPNL -- Select and display specified line within file
-
-
- $RTN tpln
- ld a,0ffh
- ld (tline),a
- ld hl,(RELREC)
- ld (SAVFSC),hl
- ld hl,(LINESC)
- ld (SAVBA),hl
- ld hl,0
- ld (LINESC),hl
- tpln00 equ $
- $fld tclend
- $fld linnum
- $hexw linesc
- call CHRF
- $MTCH DECS
- jr nz,tpln01
- ld a,l
- ld hl,(LINESC)
- add hl,hl
- add hl,hl
- add hl,hl
- add hl,hl
- add a,l
- daa
- ld l,a
- ld a,h
- ld h,0
- adc a,h
- daa
- ld h,a
- ld (LINESC),hl
- jr tpln00
-
- tpln01 equ $
- cp $ESC
- jr nz,tpln02
- ld hl,(SAVFSC)
- ld (RELREC),hl
- ld hl,(SAVBA)
- ld (LINESC),hl
- jp tpln06
-
- tpln02 equ $
- cp $LEFT
- jr nz,tpln03
- ld hl,LINESC+1
- xor a
- rrd
- dec hl
- rrd
- jp tpln06
-
- tpln03 equ $
- cp CR
- jr nz,tpln05
- ld hl,(LINESC)
- ld a,l ; minimum line is 0001
- or h
- jr nz,tpln04
- inc a
- ld (LINESC),a
- tpln04 equ $
- ld hl,(LINESC)
- ld (TARGET),hl
- ld hl,(PGEPTR)
- ld de,4 ; offset to linesc posn
- call tloc ; call routine to find target
- ; and test it for range
- jr z,tpln99 ; if read error
- xor a ; signal
- ld (INCH),a ; and fall thru alarm
- ; to loop for other input
- tpln05 equ $
- call ALRM
- ; endif
- tpln06 equ $
- ld a,(INCH)
- cp CR
- jr z,tpln99
- cp $ESC
- jp nz,tpln00
-
- tpln99 equ $
- ld a,0ffh
- ld (TYDSP),A
- ret
-
- ; Routine to support new options -- sequential search thru queued data
-
- ; TLOC -- find place in queue for match
- ; This REALLY should be a binary search, based on the assumption we
- ; save the address of the last queued entry, while pgeptr already should
- ; hold address of first.
-
-
- $RTN tloc ; sequential search in queue
- push de ; preserve offset to tycurc posn
- add hl,de ; point to field we want
- ld bc,8 ; sizeof the queue structure
- tloc00 equ $
- ld de,(TARGET) ; get in what we're looking for
- push hl ; record where we're at
- call LDHL ; get the current field
- xor a
- sbc hl,de ; check against 'target'
- jr nc,tloc02 ; if not found yet
- pop hl ; get back where we're at
- pop de ; and offset to tycurc
- push de ; --- saving it again
- add hl,bc ; move to next queue item
- push hl ; save its address
- or a
- sbc hl,de
- ld de,06 ; now check its BASEAD value
- add hl,de ; (we're really hacking here )
- call LDHL ; (binary srch WOULD be better)
- ld a,l ; ANYWAY... BECAUSE THIS IS AN UNTIL,
- or h ; zero BASEAD means endofq
- pop hl ; fall thru
- jr nz,tloc00 ; or loop if more
-
- tloc01 equ $ ; search failed
- pop de
- push af ; preserve z flag set
- call typr ; set up end of file parameters
- call alrm ; say it didn't really work
- pop af
- jr tloc99 ; but signal z set -- ok
-
- tloc02 equ $
- pop hl
- jr z,tloc03 ; if past it,
- or a ; go back one
- sbc hl,bc ; endif
- tloc03 equ $
- pop de
- or a
- sbc hl,de ; restore offset to top of entry
- call LPGE ; signals nz on bad read, z if found
- tloc99 equ $ ; endif
- ret
-
-
- ; routine separated -- increments packed BCD data in HL by one
-
- $RTN BCDU
- LD A,1
- ADD A,L
- DAA
- LD L,A
- LD A,0
- ADC A,H
- DAA
- LD H,A
- ret
-
- ; End of second new section v3 mod 4 -PGM.
-
- ; CHUN - CHANGE USER NUMBER (CODE MOSTLY COPIED FROM CHDD)
-
- $RTN CHUN
- LD HL,UNMSG
- CALL CFLD
- LD A,TRUE
- LD (DRMDLD),A
- $IFLD UNMSG
- CP $ESC
- RET Z
- SUB 30H ;Make user number 0-9
- JR C,CHUN04 ;If illegal user number
- CP 10 ;Check for A..F
- JR C,CHUN05
- SUB 7
- CHUN02: CP 16
- JR C,CHUN05
- CHUN04: CALL ALRM
- RET
- CHUN05: LD E,A
- LD C,USERNO
- CALL CPM
- LD C,GETDEF
- CALL CPM
- CALL CHDR
- XOR A
- LD (SELDE),A
- RET
-
- UNMSG: DEFB 12,20,'Enter user number or press ESC ===>',0
-
- ; CHDD - CHANGE DIRECTORY DRIVE
-
- $RTN CHDD
- LD HL,DSKMSG
- CALL CFLD ;CLEAR PROMPT FIELD
- LD A,TRUE
- LD (DRMDLD),A ;REQUEST LIST ON RETURN
- $IFLD DSKMSG ;PROMPT FOR DRIVE
- CP $ESC
- JR Z,CHDD03 ;IF NOT ESC
- SUB 041H ;MAKE DRIVE ID
- CALL CHDR ;CHANGE DISK
- JR NZ,CHDD04 ;IF ILLEGAL DISK
- CALL ALRM ;SOUND ALARM
- JR CHDD05
- CHDD04 EQU $ ;ELSE
- XOR A
- LD (SELDE),A ;SELECT FIRST ENTRY
- CHDD05 EQU $ ;ENDIF
- CHDD03 EQU $ ;ENDIF
- RET
-
- DSKMSG: DB 12,20,'Enter Drive Name or press ESC ===>',0
- NFDMSG: DB '** No Files on Drive',0
-
-
- ; SAFN - SET DIRECTORY LIST AFN
-
- $RTN SAFN
- $NPANEL AFNPNL ;DISPLAY SET AFN PANEL
- LD A,TRUE
- LD (DRMDLD),A ;REQUEST DIRECTORY LIST
- LD HL,LMDFCB+1
- LD DE,CPYAFN
- LD BC,11
- LDIR ;TAKE LOCAL COPY OF DIR SEARCH NAME
- CALL DAFN ;DISPLAY CURRENT MASK
- XOR A
- LD (IMODE),A ;RESET INSERT MODE
- LD (NMODE),A ;SET FOR NAME PART
- LD (AFNCNT),A ;SET COUNT=0
- LD HL,(AFNPNM)
- LD (AFNCUR),HL ;SET START ADDRESS ON SCREEN
- LD A,8
- LD (AFNMAX),A ;SET LENGTH OF FIELD
- LD HL,CPYAFN
- LD (AFNCHP),HL ;SAVE START ADDRESS IN MEMORY
- SAFN01 EQU $ ;LOOP
- CALL AFNC ;POSITION CURSOR
- CALL CHRF ;GET A CHARACTER
- CP CR
- JR Z,SAFN02 ;EXITIF C/R
- CP $ESC
- JR Z,SAFN02 ;OR ESCAPE
- $MTCH AFNACD
- JR NZ,SAFN03 ;IF VALID CONTROL
- $EXVA AFNAVC ;PERFORM ACTION
- JR SAFN04
- SAFN03 EQU $ ;ELSE
- $MTCH AFNINV
- JR Z,SAFN05 ;IF NOT IN ILLEGAL CHARACTER SET
- CP 020H
- JP C,SAFN05 ;AND NOT CONTROL CHARACTER
- CALL PAFN ;PUT CHARACTER IN STRING
- JR SAFN06
- SAFN05 EQU $ ;ELSE
- CALL ALRM ;RING BELL
- SAFN06 EQU $ ;ENDIF
- SAFN04 EQU $ ;ENDIF
- JR SAFN01
- SAFN02 EQU $ ;ENDLOOP
- CP $ESC
- JR Z,SAFN99 ;IF EXIT BY C/R
- LD HL,CPYAFN
- CALL LSEL ;COPY NEW NAME TO FCB
- CALL RDIR ;READ DIRECTORY
- XOR A
- LD (SELDE),A ;RESET CURRENT SELECTION
- SAFN99 EQU $ ;ENDIF
- RET
-
- AFNINV: DB 7,07FH,':;<>[]' ;INVALID FILENAME CHARACTERS
- IMODE: DS 1 ;INSERT ON/OFF
- NMODE: DS 1 ;IN NAME/EXT PART
- AFNCNT: DS 1 ;CURENT POSITION IN NAME
- AFNCUR: DS 2 ;CURSOR POSITION OF CURRENT FIELD
- AFNCHP: DS 2 ;ADDRESS OF CURRENT FIELD
- AFNMAX: DS 1 ;LENGTH OF CURRENT PART
- CPYAFN: DS 11
-
- AFNPNL EQU $
- DB 10 ;FIELD COUNT
- DB 02,00,'^',$LEFT+040H,' Cursor Left',0
- DB 02,27,'^',$RIGHT+040H,' Cursor Right',0
- DB 03,00,'^',$DELETE+040H,' Delete Character',0
- DB 03,27,'^',$INSRT+040H,' Insert On/Off',0
- DB 02,54,'^',$TAB+040H,' Edit Name/Type',0
- DB 03,54,'ESC Use Current Selection',0
- AFNMSG: DB 7,08,'Edit File Name ===>',0
- DB 7,37,'<=',0 ;FILENAME END MARKER
- DB 9,13,'File Type ===>',0
- DB 9,32,'<=',0 ;FILE TYPE END MARKER
- AFNPNM: DB 7,28,0 ;POSITION OF FILE NAME
- AFNPEX: DB 9,28,0 ;POSITION OF FILE TYPE
-
- INSMSG: DB 05,29,'Insert',0
-
- AFNACD: DB 8,$LEFT,$RIGHT,$DELETE,$INSRT,$TAB,' .*'
-
- AFNAVC: DW AFNL ;CURSOR LEFT
- DW AFNR ;CURSOR RIGHT
- DW AFND ;DELETE CHAR
- DW AFNI ;TOGGLE INSERT MODE
- DW AFNT ;TOGGLE NAME MODE
- DW AFNS ;SPACE FILL FIELD
- DW AFNP ;PERIOD
- DW AFNQ ; "?" FILL (USED BY "*")
-
- ; AFNP - PERIOD IN AFN
-
- $RTN AFNP
- LD A,(NMODE)
- OR A
- JR NZ,AFNP01 ;IF IN NAME
- CALL AFNS ;SPACE FILL
- AFNP01 EQU $ ;ENDIF
- RET
-
- ; AFND - DELETE CHARACTER IN AFN
-
- $RTN AFND
- LD HL,(AFNCHP) ;ADDRESS OF CURRENT FIELD
- LD A,(AFNCNT)
- LD C,A ;SAVE COUNT
- CALL AAHL ;ADDRESS OF CURRENT CHARACTER
- LD D,H
- LD E,L ;DEST IN DE
- INC HL ;SOURCE IN HL
- LD A,(AFNMAX) ;LENGTH OF FIELD
- SUB C ;LENGTH REMAINING
- DEC A ;LENGTH TO MOVE
- JR Z,AFND01 ;IF SOMETHING TO MOVE
- LD B,0
- LD C,A ;SET UP COUNT
- LDIR ;MOVE FIELD LEFT
- AFND01 EQU $ ;ENDIF
- LD A,' '
- LD (DE),A ;BLANK LAST CHARACTER
- CALL DAFN ;DISPLAY NEW AFN
- RET
-
- ; AFNS - SPACE FILL AFN
-
- $RTN AFNS
- LD A,' '
- LD (FILLCH),A
- CALL AFNF
- RET
-
- ; AFNQ - "?" FILL AFN
-
- $RTN AFNQ
- LD A,'?'
- LD (FILLCH),A
- CALL AFNF
- RET
-
- FILLCH: DS 1 ;CHARACTER TO FILL AFN
-
-
- ; AFNF - FILL AFN FIELD
-
- $RTN AFNF
- LD HL,(AFNCHP)
- LD A,(AFNCNT)
- LD B,A ;SAVE COUNT
- CALL AAHL ;POSITION IN FIELD
- LD A,(AFNMAX)
- SUB B
- LD B,A ;SAVE COUNT
- LD A,(FILLCH)
- AFNF01 EQU $ ;REPEAT
- LD (HL),A ;INSERT SPACE
- INC HL ;POINT NEXT CHARACTER
- DJNZ AFNF01 ;UNTIL END OF FIELD
- CALL DAFN ;DISPLAY FIELD
- CALL AFNT ;POSITION IN OTHER HALF
- RET
-
-
- ; DAFN - DISPLAY DIRECTORY SEARCH NAME
-
- $RTN DAFN
- $FLD AFNPNM ;POSITION FOR NAME
- LD B,8
- LD HL,CPYAFN
- DAFN01 EQU $ ;LOOP
- LD A,(HL)
- CALL CHRO ;PRINT A CHARCTER
- INC HL ;POINT TO NEXT
- DJNZ DAFN01 ;UNTIL END OF FIELD
- $FLD AFNPEX ;POSITION FOR TYPE
- LD HL,CPYAFN+8
- LD B,3
- DAFN02 EQU $ ;REPEAT
- LD A,(HL)
- CALL CHRO ;PRINT CHAR
- INC HL ;POINT TO NEXT
- DJNZ DAFN02 ;UNTIL END OF FIELD
- RET
-
-
- ; PAFN - PUT CHARACTER IN STRING
-
- $RTN PAFN
- PUSH AF ;SAVE CHARACTER
- LD A,(IMODE)
- OR A
- JR Z,PAFN01 ;IF INSERT ON
- CALL AFNM ;MAKE SPACE
- PAFN01 EQU $ ;ENDIF
- LD HL,(AFNCHP) ;GET CHARACTER POSITION
- LD A,(AFNCNT)
- CALL AAHL ;ADD COUNT TO HL
- POP AF ;RESTORE CHARACTER
- LD (HL),A ;PUT IT IN STRING
- CALL CHRO ;DISPLAY CHARACTER
- LD A,(IMODE)
- OR A
- JR Z,PAFN02 ;IF INSERT ON
- CALL DAFN ;DISPLAY FULL NAME
- PAFN02 EQU $ ;ENDIF
- CALL AFNR ;MOVE CURSOR
- RET
-
- ; AFNM - MAKE SPACE FOR INSERT
-
- $RTN AFNM
- LD HL,(AFNCHP) ;ADDRESS OF CURRENT FIELD
- LD A,(AFNMAX)
- DEC A ;ADJUST COUNT TO OFFSET
- CALL AAHL ;ADDRESS OF LAST CHARACTER
- LD D,H
- LD E,L ;DEST IN DE
- DEC HL ;SOURCE IN HL
- LD A,(AFNCNT) ;CURRENT OFFSET
- LD C,A
- LD A,(AFNMAX)
- SUB C ;LENGTH REMAINING
- DEC A ;LENGTH TO MOVE
- JR Z,AFNM01 ;IF SOMETHING TO MOVE
- LD B,0
- LD C,A ;SET UP COUNT
- LDDR ;MOVE FIELD RIGHT
- AFNM01 EQU $ ;ENDIF
- RET
-
- ; AFNL - CURSOR LEFT IN AFN
-
- $RTN AFNL
- LD A,(AFNCNT)
- OR A
- JR Z,AFNL01 ;IF NOT START OF FIELD
- DEC A ;POSITION TO PREVIOUS
- JR AFNL02
- AFNL01 EQU $ ;ELSE
- CALL AFNT ;TOGGLE MODE
- LD A,(AFNMAX) ;GET END OF FIELD COUNT
- DEC A ;POINT TO LAST CHAR IN FIELD
- LD B,A ;SET COUNT
- DEC A ;POINT TO PREVIOUS
- LD HL,(AFNCHP)
- CALL AAHL
- LD A,' '
- AFNL03 EQU $ ;REPEAT
- CP (HL)
- JR NZ,AFNL04 ;EXITIF PREVIOUS NOT SPACE
- DEC HL
- DJNZ AFNL03 ;UNTIL END OF FIELD
- AFNL04 EQU $ ;ENDLOOP
- LD A,B ;RESTORE COUNT
- AFNL02 EQU $ ;ENDIF
- LD (AFNCNT),A ;BACKSPACE POSITION
- RET
-
-
- ; AFNR - CURSOR RIGHT IN AFN
-
- $RTN AFNR
- LD HL,(AFNCHP)
- LD A,(AFNCNT)
- CALL AAHL ;POINT TO CURRENT CHARACTER
- LD A,(HL)
- CP ' '
- JR NZ,AFNR02 ;IF SPACE
- CALL AFNT ;CHANGE MODE
- JR AFNR03
- AFNR02 EQU $ ;ELSE
- LD A,(AFNMAX) ;GET FIELD MAX
- LD HL,AFNCNT
- INC (HL) ;INC POSITION
- CP (HL)
- JP NZ,AFNR01 ;IF OUT OF RANGE
- CALL AFNT ;TOGGLE MODE
- AFNR01 EQU $ ;ENDIF
- AFNR03 EQU $ ;ENDIF
- RET
-
- ; AFNI - TOGGLE AFN INSERT MODE
-
- $RTN AFNI
- LD A,(IMODE)
- CPL
- LD (IMODE),A ;TOGGLE MODE FLAG
- LD HL,INSMSG ;POINT TO INSERT MESSAGE
- OR A
- JR Z,AFNI01 ;IF NOW INSERT MODE
- CALL DFLD ;DISPLAY IT
- JR AFNI02
- AFNI01 EQU $ ;ELSE
- CALL CFLD ;CLEAR IT
- AFNI02 EQU $ ;ENDIF
- RET
-
-
- ; AFNT - TOGGLE AFN MODE
-
- $RTN AFNT
- XOR A
- LD (AFNCNT),A ;RESET COUNT
- LD A,(NMODE)
- CPL
- LD (NMODE),A ;TOGLE MODE FLAG
- OR A
- JR NZ,AFNT01 ;IF NOW NAME MODE
- LD A,8 ;GET MAX LENGTH
- LD HL,(AFNPNM) ;GET START POSITION
- LD DE,CPYAFN
- JR AFNT02
- AFNT01 EQU $ ;ELSE
- LD A,3 ;GET MAX FOR EXTENSION
- LD HL,(AFNPEX) ;GET POSITION FOR EXTENSION
- LD DE,CPYAFN+8
- AFNT02 EQU $ ;ENDIF
- LD (AFNMAX),A ;SET MAX
- LD (AFNCUR),HL ;SET START POSITION
- LD (AFNCHP),DE ;SET START ADDRESS
- RET
-
-
- ; AFNC - POSITION CURSOR IN AFN
-
- $RTN AFNC
- LD HL,(AFNCUR) ;GET START OF FIELD
- LD A,(AFNCNT) ;GET OFFSET
- ADD A,H
- LD H,A ;OFFSET CURSOR
- CALL CURS ;POSITION CURSOR
- RET
-
-
- ; TFLE - TEST FILE
-
- $RTN TFLE
- XOR A
- LD (FLERR),A ;RESET ERROR FLAG
- LD DE,WRKFCB ;POINT TO WORK FCB
- LD C,OPEN
- CALL CPM ;ATTEMPT TO OPEN FILE
- INC A
- JR NZ,TFLE01 ;IF OPEN ERROR
- LD HL,FNFMSG
- LD (ERRTXT),HL ;SET FILE NOT FOUND ERROR
- LD A,0FFH
- LD (FLERR),A ;SET ERROR FLAG
- JP TFLE02
- TFLE01 EQU $ ;ELSE
- LD HL,0
- LD (RELREC),HL ;INITIALISE RECORD COUNTER
- LD (SAVFSC),HL
- LD DE,WRKFN
- CALL FMTN
- LD A,(WRKDR)
- ADD A,040H
- LD (DRIVNM),A ;FORMAT NAME AND DRIVE
- CALL RDFS ;READ SECTOR
- JR Z,TFLE03 ;IF READ BAD
- LD HL,NRFMSG
- LD (ERRTXT),HL ;SET NO RECORDS ON FILE ERROR
- LD A,0FFH
- LD (FLERR),A ;SET ERROR FLAG
- TFLE03 EQU $ ;ENDIF
- TFLE02 EQU $ ;ENDIF
- RET
- FLERR: DS 1
-
-
- ; PSMD - PHYSICAL SECTOR MODE
-
- $RTN PSMD
- LD HL,(PSMDER)
- LD (ERRFLD),HL ;SET ERROR FIELD POINTER
- LD A,0FFH
- LD (PMNEWD),A ;FLAG NEW DISK
- LD (RPANEL),A ;REQUEST PANEL
- PSMD05 EQU $ ;LOOP
- CALL ZBSA ;CLEAR ADDRESS COUNTER
- LD A,(PMNEWD)
- OR A
- JP Z,PSMD01 ;IF NEW DISK
- XOR A
- LD (PMNEWD),A ;RESET FLAG
- LD A,(CURAN)
- LD C,A
- CALL SELDSK ;SELECT PHYSICAL DISK
- CALL HOME ;HOME THE DISK
- LD HL,0
- LD (PSMDSC),HL ;SET SECTOR TO 0
- ; LD (PSMDTR),HL ;SET TRACK TO 0
- ; The above used to set the track to 0 but I found that is not very useful so
- ; I changed it to point to the beginning of the directory (JHB)
- LD HL,(DPBOFF)
- LD (PSMDTR),HL
- PSMD01 EQU $ ;ENDIF
- LD A,(RPANEL)
- OR A
- JR Z,PSMD06 ;IF PANEL REQUIRED
- XOR A
- LD (RPANEL),A ;RESET FLAG
- $NPANEL PSMDPN ;DISPLAY PHYSICAL MODE PANEL
- $FLD PSPMSG
- CALL DSPI ;DISPLAY SCRATCHPAD DATA
- PSMD06 EQU $
- CALL PRDD ;READ AND DISPLAY SECTOR
- CALL ERRP ;PROCESS ERROR MESSAGES
- PSMD03 EQU $ ;LOOP
- $IFLD SELMSG ;ISSUE SELMSG, GET COMMAND
- $MTCH PSMDLS
- JR Z,PSMD02 ;EXITIF VALID
- CALL ALRM ;SOUND THE ALARM
- JR PSMD03
- PSMD02 EQU $ ;ENDLOOP
- $EXVA PSMDVC ;EXEC ACTION
- LD A,(WTG)
- CP 'P'
- JR NZ,PSMD04 ;EXIT IF NEXT MODE <> P
- JP PSMD05
- PSMD04 EQU $ ;ENDLOOP
- RET
- PMNEWD: DS 1 ;NEW DISK FLAG
-
- BIOS3: ;General BIOS entry for CP/M 3.1
- LD (HLVAL),HL ;Save caller's register values
- LD (DEVAL),DE ; in BIOS parameter block
- LD (BCVAL),BC ;
- LD (AVAL),A ;
- POP HL ;Get return address for figuring which
- ; routine was called. (Also leaves proper
- ; return address on stack!)
- LD DE,LBIOS-3 ;Base of jump table
- XOR A ;Clear carry flag
- SBC HL,DE ;(BIOS function) * 3 now in HL
- LD B,A
- LD A,L
- FNCALC:
- SUB 3 ;Figure out which BIOS function was called
- JR Z,GOTFN
- INC B
- JR FNCALC
- GOTFN:
- LD A,B ;Stash it in the BIOS parameter block
- LD DE,BIOSFN
- LD (DE),A
- LD C,50 ;CP/M Plus direct BIOS call
- CALL CPM
- RET
-
- BIOSFN: DEFS 1 ;CP/M Plus BIOS parameter block
- AVAL: DEFS 1
- BCVAL: DEFS 2
- DEVAL: DEFS 2
- HLVAL: DEFS 2
-
- ; LOCAL DISK PARAMETER HEADER
- ;
- ; It seems that the DPH layouts for CP/M 2.x and CP/M 3.x are different.
- ; In particular, there are 10 bytes between DPHXLT and DPHDPB instead
- ; of the 8 shown here. We will correct for this when we are making a
- ; local copy of the DPB.
- ;
- ; Note that the labels DPHDIR, DPHCSV and DPHALV are not used anywhere.
- ; --- (JHB)
- DPHLCL EQU $
- DPHXLT: DS 2
- DS 6 ;FILLER
- DPHDIR: DS 2
- DPHDPB: DS 2
- DPHCSV: DS 2
- DPHALV: DS 2
-
- DPHDP3 EQU DPHDPB+2 ;Equivalence for CP/M 3.x
-
- ; LOCAL DISK PARAMETER BLOCK
-
- DPBLCL EQU $
- DPBSPT: DS 2 ;CP/M LOGICAL SECTORS PER TRACK
- DPBBSH: DS 1
- DPBBLM: DS 1 ;LOGICAL SECTORS PER BLOCK - 1
- DPBEXM: DS 1
- DPBDSM: DS 2 ;FILE BLOCKS PER DISK
- DPBDRM: DS 2
- DPBAL0: DS 1
- DPBAL1: DS 1
- DPBCKS: DS 2
- DPBOFF: DS 2
- DPBPSH: DS 1 ;CP/M 3 only
- DPBPSM: DS 1 ;CP/M 3 only
-
- ; LOCAL DISK PARAMETER EXTENSIONS
-
- DPETPD: DS 2 ;TRACKS PER DISK
- DPESPB: DS 2 ;SECTORS PER BLOCK
- DPERSC: DS 2 ;RESERVED SECTORS
-
-
- PSMDTR: DS 2
- PSMDSC: DS 2
- PSMDBL: DS 2
-
- PHYSEC: DS 2
-
- ; PHYSICAL DISK MODE MESSAGES, PANEL AND ACTION VECTOR
-
- TRKMSG: DB 11,04,'Enter Hex Track',0 ;OVERLAID BY CTRMSG
- SECMSG: DB 11,23,'Enter Hex Sector',0 ;OVERLAID BY CSCMSG
- BLKMSG: DB 11,42,'Enter Hex Block',0 ;OVERLAID BY CBLMSG
- DIDMSG: DB 11,61,'Enter Drive ID',0 ;OVERLAID BY CDKMSG
-
- PSMDPN: DB 16 ;FIELD COUNT
- DB 02,00,'N Next sector',0
- DB 03,00,'P Previous sector',0
- DB 04,00,'I Next track',0
- DB 05,00,'O Previous track',0
- DB 02,27,'T Select track',0
- DB 03,27,'S Select sector',0
- DB 04,27,'B Select block',0
- DB 05,27,'D Select drive',0
- DB 02,54,'Z Exit from Superzap',0
- DB 03,54,'L Exit to file list',0
- DB 04,54,'X Scratchpad operations',0
- DB 05,54,'C Change sector',0
-
- CTRMSG: DB 11,04,'Current-Track ',0 ;OVERLAID BY TRKMSG
- CSCMSG: DB 11,23,'Current-Sector ',0 ;OVERLAID BY SECMSG
- CBLMSG: DB 11,42,'Current-Block ',0 ;OVERLAID BY BLKMSG
- CDKMSG: DB 11,61,'Current-Drive ',0 ;OVERLAID BY DIDMSG
-
- PSMDER: DB 8,0 ;ERROR FIELD
- PSPMSG: DB 07,00,'Scratchpad :- ',0
-
- ; FILE STATISTICS FIELDS
-
- PSTRFL: DB 12,11,0
- PSTRIP: DB 12,15,0
- PSSCFL: DB 12,28,0
- PSSCIP: DB 12,32,0
- PSBLFL: DB 12,47,0
- PSBLIP: DB 12,51,0
- PSDKFL: DB 12,67,0
-
- PSMDLS: DB 12,'NCPSITOZLBDX'
- PSMDVC EQU $
- DW NXPS ;NEXT PHYSICAL SECTOR
- DW PSCH ;PHYSICAL SECTOR CHANGE MODE
- DW PRPS ;PREVIOUS PHYSICAL SECTOR
- DW SPSN ;SET PHYSICAL SECTOR
- DW FRTR ;FORWARD TRACK
- DW SPTN ;SET PHYSICAL TRACK
- DW BWTR ;BACKWARD TRACK
- DW SETX ;SET EXIT MODE
- DW PTOD ;CHANGE TO DIRECTORY MODE
- DW SPBL ;SET PHYSICAL BLOCK
- DW CHPD ;CHANGE PHYSICAL DISK
- DW PSPM ;PHYSICAL S/P MANAGER
-
- ; PTOD - CHANGE TO DIRECTORY
-
- $RTN PTOD
- LD A,(CURAN)
- CALL CHDR ;RESET DISKS
- CALL SETD ;SET D MODE
- RET
-
- ; CHPD - CHANGE PHYSICAL DISK
-
- $RTN CHPD
- $FLD DIDMSG ;DISPLAY PROMP
- CHPD01 EQU $ ;LOOP
- $FLD PSDKFL ;POSITION FOR DISK ID
- LD A,(CURAN) ;GET ABSOLUTE DRIVE NUMBER
- ADD A,041H ;MAKE IT ALPHA
- CALL CHRO ;DISPLAY DRIVE ID
- CALL CHRF
- CP $ESC
- JR Z,CHPD02 ;EXIT IF ESCAPE
- CP CR
- JR Z,CHPD02 ;OR CR
- SUB 041H ;MAKE IT DISK NUMBER
- CALL CHDR ;CHANGE DRIVE
- JR NZ,CHPD02 ;EXITIF NON ZERO DPH
- CALL ALRM ;RING BELL
- JR CHPD01
- CHPD02 EQU $ ;ENDLOOP
- CP $ESC
- JR Z,CHPD03 ;IF NOT ESC
- LD A,0FFH
- LD (PMNEWD),A ;FLAG NEW DISK
- CHPD03 EQU $
- $FLD CDKMSG ;REDISPLAY CURRENT
- RET
-
-
- ; PRDD - READ AND DISPLAY PHYSICAL SECTOR
-
- $RTN PRDD
- CALL PSRD ;READ PHYSICAL SECTOR
- LD HL,FBUFF
- CALL WRBF ;DISPLAY BUFFER CONTENTS
- CALL UBLK ;UPDATE BLOCK
- CALL DPSI ;DISPLAY PHYSICAL SECTOR INFO
- RET
-
- ; DPSI - DISPLAY SECTOR INFORMATION
-
- $RTN DPSI
- $FLD PSTRFL ;POSITION CURSOR FOR TRACK NUMBER
- $HEXW PSMDTR ;DISPLAY TRACK
- $FLD PSSCFL ;POSITION FOR SECTOR NUMBER
- $HEXW PSMDSC ;DISPLAY SECTOR
- $FLD PSBLFL ;POSITION FOR BLOCK NUMBER
- $HEXW PSMDBL ;DISPLAY BLOCK
- $FLD PSDKFL ;POSITION FOR DISK ID
- LD A,(CURAN) ;GET ABSOLUTE DRIVE NUMBER
- ADD A,041H ;MAKE IT ALPHA
- CALL CHRO ;DISPLAY DRIVE ID
- RET
-
-
- ; UBLK - UPDATE BLOCK NUMBER
-
- $RTN UBLK
- LD DE,(PSMDTR)
- LD BC,(DPBSPT)
- CALL MULT
- LD DE,(PSMDSC)
- ADD HL,DE ;CALCULATE ABSOLUTE SECTOR
- LD DE,(DPERSC)
- OR A
- SBC HL,DE
- JR NC,UBLK01 ;IF WITHIN SYSTEM AREA
- LD DE,0 ;SET BLOCK ZERO
- JR UBLK02
- UBLK01 EQU $ ;ELSE
- EX DE,HL
- LD BC,(DPESPB)
- CALL DIVD ;CALCULATE BLOCK NUMBER
- LD HL,(DPBDSM)
- OR A
- SBC HL,DE
- JR NC,UBLK04 ;IF BLOCK NOT IN RANGE
- LD DE,0 ;SET BLOCK ZERO
- UBLK04 EQU $ ;ENDIF
- UBLK02 EQU $ ;ENDIF
- LD (PSMDBL),DE ;SET NEW BLOCK NUMBER
- RET
-
-
- ; NXPS - NEXT PHYSICAL SECTOR
-
- $RTN NXPS
- LD HL,(PSMDSC)
- INC HL
- LD (PSMDSC),HL ;INCREMENT PHYSICAL SECTOR
- LD DE,(DPBSPT)
- OR A
- SBC HL,DE
- JR C,NXPS01 ;IF TRACK OVERFLOW
- LD HL,0
- LD (PSMDSC),HL ;SET TO FIRST SECTOR
- CALL FRTR ;ADVANCE TRACK
- NXPS01 EQU $ ;ENDIF
- RET
-
-
- ; PRPS - PREVIOUS PHSICAL SECTOR
-
- $RTN PRPS
- LD HL,(PSMDSC)
- LD A,H
- OR L
- JR NZ,PRPS01 ;IF SECTOR IS ZERO
- CALL BWTR ;GO BACK A TRACK
- LD HL,(DPBSPT) ;SET UP FOR DECREMENT
- PRPS01 EQU $ ;ENDIF
- DEC HL
- LD (PSMDSC),HL ;DECREMENT TO PREVIOUS SECTOR
- RET
-
-
- ; SPSN - SET PHYSICAL SECTOR NUMBER
-
- $RTN SPSN
- LD HL,SELMSG
- CALL CFLD
- LD HL,(PSMDSC)
- LD (SAVPSC),HL ;SAVE RECORD NUMBER
- $FLD SECMSG ;DISPLAY SET SECTOR
- LD HL,0
- LD (PSMDSC),HL ;ZERO RECORD NUMBER
- SPSN01 EQU $
- CALL UBLK
- CALL DPSI ;DISPLAY PHYSICAL SECTOR INFO
- $IFLD PSSCIP ;POSITION AND GET INPUT
- $MTCH HEXCHR
- JR NZ,SPSN02 ;IF VALID HEX
- EX DE,HL
- LD HL,(PSMDSC)
- CALL H16D ;HL=HL*16+DIGIT
- LD (PSMDSC),HL ;SAVE NEW SECTOR NUMBER
- JR SPSN03
- SPSN02 EQU $
- CP $ESC
- JR NZ,SPSN04 ;ELSEIF ESCAPE
- LD HL,(SAVPSC)
- LD (PSMDSC),HL ;RESTORE SECTOR NUMBER
- JR SPSN03
- SPSN04 EQU $
- CP $LEFT
- JR NZ,SPSN05 ;ELSEIF BACKSPACE
- LD HL,PSMDSC+1
- XOR A
- RRD
- DEC HL
- RRD ;SECTOR=SECTOR/16
- JR SPSN03
- SPSN05 EQU $
- CP CR
- JR NZ,SPSN06 ;ELSEIF CR
- OR A
- LD HL,(PSMDSC)
- LD DE,(DPBSPT)
- SBC HL,DE
- JR C,SPSN07 ;IF SECTOR OUT OF RANGE
- CALL ALRM ;SIGNAL ERROR
- LD HL,(SAVPSC)
- LD (PSMDSC),HL ;RESTORE TO ORIGINAL
- XOR A
- LD (INCH),A ;DONT EXIT
- SPSN07 EQU $
- JR SPSN03
- SPSN06 EQU $ ;ELSE
- CALL ALRM ;ERROR
- SPSN03 EQU $ ;ENDIF
- LD A,(INCH)
- CP CR
- JR Z,SPSN08 ;EXIT IF CR
- CP $ESC
- JR Z,SPSN08 ;EXIT IF ESC
- JP SPSN01
- SPSN08 EQU $ ;ENDLOOP
- $FLD CSCMSG ;DISPLAY CURRENT SECTOR MESSAGE
- RET
-
- SAVPSC: DS 2
-
-
- ; FRTR - FORWARD TRACK
-
- $RTN FRTR
- LD HL,(PSMDTR)
- INC HL
- LD (PSMDTR),HL
- LD DE,(DPETPD)
- OR A
- SBC HL,DE
- JR C,FRTR01 ;IF DISK OVERFLOW
- LD HL,0
- LD (PSMDTR),HL ;SET TO FIRST TRACK
- FRTR01 EQU $
- RET
-
-
- ; SPTN - SET PHYSICAL TRACK NUMBER
-
- $RTN SPTN
- LD HL,SELMSG
- CALL CFLD
- LD HL,(PSMDTR)
- LD (SAVPTR),HL ;SAVE TRACK NUMBER
- $FLD TRKMSG ;DISPLAY TRKMSG
- LD HL,0
- LD (PSMDTR),HL ;ZERO TRACK NUMBER
- SPTN01 EQU $
- CALL UBLK
- CALL DPSI ;DISPLAY PHYSICAL SECTOR INFO
- $IFLD PSTRIP ;POSITION AND GET INPUT
- $MTCH HEXCHR
- JR NZ,SPTN02 ;IF VALID HEX
- EX DE,HL
- LD HL,(PSMDTR)
- CALL H16D ;HL=HL*16+DIGIT
- LD (PSMDTR),HL ;SAVE NEW TRACK NUMBER
- JR SPTN03
- SPTN02 EQU $
- CP $ESC
- JR NZ,SPTN04 ;ELSEIF ESCAPE
- LD HL,(SAVPTR)
- LD (PSMDTR),HL ;RESTORE TRACK NUMBER
- JR SPTN03
- SPTN04 EQU $
- CP $LEFT
- JR NZ,SPTN05 ;ELSEIF BACKSPACE
- LD HL,PSMDTR+1
- XOR A
- RRD
- DEC HL
- RRD ;TRACK=TRACK/16
- JR SPTN03
- SPTN05 EQU $
- CP CR
- JR NZ,SPTN06 ;ELSEIF CR
- OR A
- LD HL,(PSMDTR)
- LD DE,(DPETPD)
- SBC HL,DE
- JR C,SPTN07 ;IF TRACK OUT OF RANGE
- CALL ALRM ;SIGNAL ERROR
- LD HL,(SAVPTR)
- LD (PSMDTR),HL ;RESTORE TO ORIGINAL
- XOR A
- LD (INCH),A ;DONT EXIT
- SPTN07 EQU $ ;ENDIF
- JR SPTN03
- SPTN06 EQU $ ;ELSE
- CALL ALRM ;ERROR
- SPTN03 EQU $ ;ENDIF
- LD A,(INCH)
- CP CR
- JR Z,SPTN08 ;EXIT IF CR
- CP $ESC
- JR Z,SPTN08 ;EXIT IF ESC
- JP SPTN01
- SPTN08 EQU $ ;ENDLOOP
- $FLD CTRMSG ;REDISPLY TRACK MESSAGE
- RET
-
- SAVPTR: DS 2
-
-
- ; BWTR - BACKWARD TRACK
-
- $RTN BWTR
- LD HL,(PSMDTR)
- LD A,H
- OR L
- JR NZ,BWTR01 ;IF TRACK IS ZERO
- LD HL,(DPETPD) ;SET UP FOR DECREMENT
- BWTR01 EQU $ ;ENDIF
- DEC HL
- LD (PSMDTR),HL ;DECREMENT TO PREVIOUS TRACK
- RET
-
-
- ; SPBL - SET PHYSICAL BLOCK
-
- $RTN SPBL
- LD HL,SELMSG
- CALL CFLD
- LD HL,(PSMDBL)
- LD (SAVPBL),HL ;SAVE BLOCK NUMBER
- $FLD BLKMSG ;DISPLAY BLKMSG
- LD HL,0
- LD (PSMDBL),HL ;ZERO BLOCK NUMBER
- SPBL01 EQU $
- CALL DPSI ;DISPLAY PHYSICAL SECTOR INFO
- $IFLD PSBLIP ;POSITION AND GET INPUT
- $MTCH HEXCHR
- JR NZ,SPBL02 ;IF VALID HEX
- EX DE,HL
- LD HL,(PSMDBL)
- CALL H16D ;BLOCK=BLOCK*16+DIGIT
- LD (PSMDBL),HL ;SAVE NEW BLOCK NUMBER
- JR SPBL03
- SPBL02 EQU $
- CP $ESC
- JR NZ,SPBL04 ;ELSEIF ESCAPE
- LD HL,(SAVPBL)
- LD (PSMDBL),HL ;RESTORE BLOCK NUMBER
- JR SPBL03
- SPBL04 EQU $
- CP $LEFT
- JR NZ,SPBL05 ;ELSEIF BACKSPACE
- LD HL,PSMDBL+1
- XOR A
- RRD
- DEC HL
- RRD ;BLOCK=BLOCK/16
- JR SPBL03
- SPBL05 EQU $
- CP CR
- JR NZ,SPBL06 ;ELSEIF CR
- OR A
- LD DE,(PSMDBL)
- LD HL,(DPBDSM)
- SBC HL,DE
- JP P,SPBL07 ;IF BLOCK OUT OF RANGE
- CALL ALRM ;SIGNAL ERROR
- LD HL,(SAVPBL)
- LD (PSMDBL),HL ;RESTORE TO ORIGINAL
- XOR A
- LD (INCH),A ;DONT EXIT
- JR SPBL08
- SPBL07 EQU $ ;ELSE
- LD DE,(PSMDBL)
- LD BC,(DPESPB)
- CALL MULT
- LD DE,(DPERSC)
- ADD HL,DE ;CALCULATE ABSOLUTE SECTOR
- EX DE,HL
- LD BC,(DPBSPT)
- CALL DIVD
- LD (PSMDTR),DE ;SET TRACK
- LD (PSMDSC),HL ;SET SECTOR
- SPBL08 EQU $ ;ENDIF
- JR SPBL03
- SPBL06 EQU $ ;ELSE
- CALL ALRM ;ERROR
- SPBL03 EQU $ ;ENDIF
- LD A,(INCH)
- CP CR
- JR Z,SPBL09 ;EXIT IF CR
- CP $ESC
- JR Z,SPBL09 ;EXIT IF ESC
- JP SPBL01
- SPBL09 EQU $ ;ENDLOOP
- $FLD CBLMSG ;REDISPLAY CURRENT BLOCK MESSAGE
- RET
-
- SAVPBL: DS 2
-
-
- ; PSPM - PHYSICAL SCRATCHPAD MODE
-
- $RTN PSPM
- $NPANEL PSPMPN ;DISPLAY PANEL
- $FLD PSPCUR ;POSITION FOR CURRENT INFO
- $STRO SPDMSG
- LD A,(CURAN)
- ADD A,41H
- CALL CHRO ;DISPLAY DRIVE
- $STRO SPTMSG
- $HEXW PSMDTR ;TRACK
- $STRO SPSMSG
- $HEXW PSMDSC ;SECTOR
- $FLD PSPSPD ;POSITION FOR S/P DATA
- CALL DSPD
- CALL SPCI ;GET COMMAND
- $EXVA PSPMV ;PROCESS COMMAND
- LD A,0FFH
- LD (RPANEL),A ;REQUEST PANEL
- RET
-
- PSPMPN: DB 3
- DB 2,0,'ESC Return to sector display',0
- DB 3,0,'C Copy current sector to scratchpad',0
- DB 4,0,'E Exchange current sector with scratchpad',0
-
- PSPCUR: DB 11,0,'Current :- ',0
- PSPSPD: DB 12,0,'Scratchpad :- ',0
-
- PSPML: DB 3,$ESC,'CE'
- PSPMV: DW PSPX
- DW PLSP
- DW PXSP
-
- $RTN PSPX
- RET
-
-
- ; PXSP - EXCHANGE WITH SCRATCHPAD
-
- $RTN PXSP
- LD A,(SPTYPE)
- OR A
- JR NZ,PXSP01 ;IF PAD EMPTY
- CALL ALRM ;RING BELL
- JR PXSP02
- PXSP01 EQU $ ;ELSE
- LD BC,(SPADDR)
- CALL dmaSet ;SET CPM BUFFER
- CALL PSWR ;WRITE BUFFER
- LD BC,FBUFF
- CALL DMASET ;RESTORE DMA
- CALL PLSP ;COPY OLD BUFFER
- PXSP02 EQU $ ;ENDIF
- RET
-
- ; PLSP - LOAD SCRATCHPAD (PHYSICAL)
-
- $RTN PLSP
- LD HL,FBUFF
- LD DE,(SPADDR)
- LD BC,128
- LDIR ;COPY THE BUFFER
- LD A,(CURAN)
- LD (SPDRIV),A ;SET DRIV
- LD HL,(PSMDTR)
- LD (SPNAME),HL ;SET TRACK
- LD HL,(PSMDSC)
- LD (SPSECT),HL ;SET SECTOR
- LD A,1
- LD (SPTYPE),A ;SET THE TYPE
- RET
-
-
- ; DSPD DISPLAY S/P DATA
-
- $RTN DSPD
- CALL DSPI ;DISPLAY SP INFO
- LD A,(SPTYPE)
- OR A
- JR Z,DSPD01 ;IF SP NOT EMPTY
- CALL ZBSA ;CLEAR ADDRESS COUNTER
- LD HL,(SPADDR)
- CALL WRBF ;DISPLAY IT
- DSPD01 EQU $ ;ENDIF
- RET
-
-
- ; LSEL - LIST FILE SELECTION STUB MASK POINTED TO BY HL
-
- $RTN LSEL
- LD DE,LMDFN
- LD BC,11
- LDIR
- RET
-
- ; PSCH - PHYSICAL SECTOR CHANGE
-
- $RTN PSCH
- CALL SCCH ;GO INTO SECTOR CHANGE MODE
- LD A,(SCCHWR)
- OR A
- JR Z,PSCH03 ;IF WRITE REQUIRED
- CALL PSWR ;WRITE OUT SECTOR
- PSCH03 EQU $ ;ENDIF
- LD A,0FFH
- LD (RPANEL),A ;REQUEST PANEL
- RET
-
-
- ; SCCH - SECTOR CHANGE MODE
-
- $RTN SCCH
- LD HL,HLAREA
- CALL CLRA ;CLEAR THE HELP AREA
- $PANEL SCCHPN ;DISPLAY SECTOR CHANGE PANEL
- LD A,FALSE
- LD (SCCHWR),A ;WRITE FLAG FALSE
- LD (ASCII),A ;ASCII FALSE
- LD (SCCHEX),A ;EXIT FALSE
- LD (LOORD),A ;START WITH HO HEX DIGIT
- XOR A
- LD (BUFPOS),A ;BUFFER POSITION 0
- SCCH03 EQU $ ;LOOP
- CALL SLCP
- CALL UDCP ;POSITION CURSOR
- CALL CHRI
- CP 020H
- JP NC,SCCH04 ;IF CONTROL CODE
- $MTCH SCCHLS
- JR Z,SCCH05 ;IF NOT VALID
- CALL ALRM ;SOUND THE ALARM
- JR SCCH06
- SCCH05 EQU $ ;ELSE
- $EXVA SCCHVC ;ACTION CONTROL CODE
- SCCH06 EQU $ ;ENDIF
- JR SCCH08
- SCCH04 EQU $ ;ELSE
- LD A,(ASCII)
- OR A
- JR Z,SCCH09 ;IF ASCII MODE
- CALL MACH ;MAKE ASCII CHANGE
- JR SCCH10
- SCCH09 EQU $ ;ELSE
- CALL MHCH ;MAKE HEX CHANGE
- SCCH10 EQU $ ;ENDIF
- SCCH08 EQU $ ;ENDIF
- LD A,(SCCHEX)
- OR A
- JR NZ,SCCH11 ;EXIT IF END OF UPDATES
- JR SCCH03
- SCCH11 EQU $ ;ENDLOOP
- RET
-
- SCCHEX: DB 0
- SCCHWR: DB 0
-
-
- ; SECTOR CHANGE MODE PANEL AND ACTION VECTOR
-
- SCCHPN: DB 8
- DB 2,0,'^',$LEFT+040H,' Cursor left',0
- DB 2,40,'^',$RIGHT+040H,' Cursor right',0
- DB 3,0,'^',$UP+040H,' Cursor up',0
- DB 3,40,'^',$DOWN+040H,' Cursor down',0
- DB 4,0,'^',$TAB+040H,' Change Side',0
- DB 4,40,'CR New Line',0
- DB 5,0,'^',$QUIT+040H,' Cancel changes',0
- DB 5,40,'^',$END+040H,' Save Changes',0
-
- SCCHLS: DB 8,$LEFT,$TAB,$DOWN,$UP,$RIGHT,CR,$END,$QUIT
-
- SCCHVC EQU $
- DW LEFT
- DW TOGL
- DW DOWN
- DW UPWD
- DW RGHT
- DW NWLN
- DW CHND
- DW QUIT
-
-
- ; LEFT - MOVE CURSOR LEFT
-
- $RTN LEFT
- LD A,(LOORD)
- OR A
- JR NZ,LEFT01 ;IF HIGH OR ASCII
- LD A,(BUFPOS)
- DEC A
- AND 07FH
- LD (BUFPOS),A ;DECREMENT POSITION
- LEFT01 EQU $
- LD A,(ASCII)
- OR A
- JR NZ,LEFT02 ;IF HEX MODE
- LD A,(LOORD)
- CPL
- LD (LOORD),A ;TOGGLE DIGIT
- LEFT02 EQU $
- RET
-
-
- ; TOGL - TOGGLE BETWEEN HEX AND ASCII
-
- $RTN TOGL
- LD A,(ASCII)
- CPL
- LD (ASCII),A ;TOGGLE MODE FLAG
- LD A,FALSE
- LD (LOORD),A ;INDICATE HO DIGIT
- RET
-
-
- ; DOWN - MOVE CURSOR DOWN ONE LINE
-
- $RTN DOWN
- LD A,(BUFPOS)
- ADD A,16
- AND 07FH
- LD (BUFPOS),A
- RET
-
-
- ; UPWD - MOVE CURSOR UP ONE LINE
-
- $RTN UPWD
- LD A,(BUFPOS)
- SUB 16
- AND 07FH ;MODULO 128
- LD (BUFPOS),A
- RET
-
-
- ; RGHT - MOVE CURSOR RIGHT
-
- $RTN RGHT
- LD A,(ASCII)
- OR A
- JR NZ,RGHT01 ;IF HEX MODE
- LD A,(LOORD)
- CPL ;TOGGLE HEX DIGIT
- LD (LOORD),A
- RGHT01 EQU $ ;ENDIF
- LD A,(LOORD)
- OR A
- JR NZ,RIGH02 ;IF HIGH ORD OR ASCII
- LD A,(BUFPOS)
- INC A
- AND 07FH
- LD (BUFPOS),A ;INCREMENT POSITION
- RIGH02 EQU $ ;ENDIF
- RET
-
-
- ; NWLN - MOV CURSOR TO START OF NEW LINE
-
- $RTN NWLN
- LD A,FALSE
- LD (LOORD),A ;INDICATE HO HEX DIGIT
- LD A,(BUFPOS)
- ADD A,16
- AND 070H
- LD (BUFPOS),A ;NEW BUFFER ADDR
- RET
-
-
- ; CHND - CHANGE END AND WRITE
-
- $RTN CHND
- LD A,TRUE
- LD (SCCHEX),A ;SIGNAL EXIT
- LD (SCCHWR),A ;SIGNAL WRITE
- RET
-
-
- ; QUIT - END WITHOUT SAVING UPDATES
-
- $RTN QUIT
- LD A,TRUE
- LD (SCCHEX),A ;SIGNAL EXIT
- RET
-
-
- ; WRBF - DISPLAY FILE DATA IN SECTOR BUFFER
-
- $RTN WRBF
- EX DE,HL
- XOR A
- LD (BUFPOS),A ;SET OFFSET TO 0
- WRBF01 EQU $ ;LOOP (HEX AND ASCII LINE)
- PUSH DE ;SAVE BUFFER POINTER
- PUSH DE ;AND FOR ASCII
- XOR A
- LD (CPOS),A ;POSITION 1
- CALL STLP ;SET LINE CURSOR POSITION
- CALL UDCP ;UPDATE CURSOR
- CALL PRTADR ;DISPLAY ADDRESS
- LD A,(BASEAD+2)
- ADD A,010H
- LD (BASEAD+2),A ;INC ADDR FOR NEXT LINE
- CALL SHCP ;SET UP CURSOR POSN IN HEX AREA
- CALL UDCP ;UPDATE CURSOR
- POP DE ;GET CURRENT ADDRESS
- WRBF03 EQU $ ;LOOP (BYTES IN HEX)
- LD A,(DE) ;GET CHARACTER THERE
- INC DE ;INCREMENT BUFF POINTER
- CALL HEXO ;PRINT BYTE
- CALL SPCO ;PRINT SPACE
- LD HL,BUFPOS
- INC (HL) ;INC TO NEXT COL
- LD A,3
- AND (HL)
- JR NZ,WRBF04 ;IF END OF GROUP
- CALL SPCO ;PRINT SPACE
- WRBF04 EQU $ ;ENDIF
- LD A,0FH
- AND (HL)
- JR NZ,WRBF03 ;UNTIL 16 BYTES DISPLAYED
-
- LD A,(HL)
- SUB 16
- LD (HL),A ;RESET BUFFER OFFSET
- CALL SACP ;POSITION FOR ASCII
- LD HL,CPOS
- DEC (HL) ;BACK OFF 1 FOR MARGIN
- CALL UDCP ;POSITION CURSOR
- LD A,'|'
- CALL CHRO ;PRINT MARGIN
- POP DE ;RESTORE CHAR POINTER
- WRBF02 EQU $ ;LOOP (BYTES IN ASCII)
- LD A,(DE) ;GET CURRENT CHARACTER
- INC DE ;INCREMENT POINTER
- CALL ASCO ;PRINT CHAR
- LD HL,BUFPOS
- INC (HL) ;INCREMENT BUFFER OFFSET
- LD A,0FH
- AND (HL)
- JR NZ,WRBF02 ;UNTIL 16 BYTES DISPLAYED
- LD A,'|'
- CALL CHRO ;PRINT MARGIN
-
- LD A,(HL)
- AND 07FH
- JP NZ,WRBF01 ;UNTIL 128 BYTES DISPLAYED
- RET
-
-
- ; CURSOR POSITON TABLES FOR HEX AND ASCII DISPLAY
-
- LPTAB: DB 14,15,16,17,18,19,20,21
-
- HCTAB: DB 9,12,15,18,22,25,28,31,35,38,41,44,48,51,54,57
- ACTAB: DB 63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78
-
- DCTAB: DB 00,20,40,60
-
-
- ; ZBSA - ZERO BASE ADDRESS
-
- $RTN ZBSA
- XOR A
- LD (BASEAD),A
- LD (BASEAD+1),A
- LD (BASEAD+2),A
- RET
-
-
- ; PRTADR - PRINT FILE ADDRESS
-
- $RTN PRTADR
- $HEXW BASEAD ;DISPLAY 2 BYTES
- LD A,(BASEAD+2)
- CALL HEXO
- RET
-
-
- ; SLCP - SET CURSOR TO CURRENT LINE AND COLUMN POSITION IN BUFFER
-
- $RTN SLCP
- CALL STLP
- CALL STCP
- RET
-
-
- ; STLP - SET UP LINE POSITION
-
- $RTN STLP
- LD HL,LPTAB ;GET BASE OF LINE TABLE
- LD A,(BUFPOS)
- RRA
- RRA
- RRA
- RRA
- AND 0FH ;MOV TO LOW ORDER
- CALL AAHL
- LD A,(HL) ;GET VALUE
- LD (LPOS),A ;SET UP FOR UDCP
- RET
-
- ; STCP - SET UP COLUMN POSITION IN BUFFER
-
- $RTN STCP
- LD A,(ASCII)
- OR A
- JR Z,STCP01 ;IF IN ASCII DISPLAY MODE
- CALL SACP ;SET UP ASCII DISPLAY
- JR STCP02
- STCP01 EQU $ ;ELSE
- CALL SHCP ;SET UP FOR HEX DISPLAY
- LD A,(LOORD)
- OR A
- JR Z,STCP03 ;IF LOW ORDER DIGIT
- LD HL,CPOS
- INC (HL) ;INCREMENT COLUMN POS
- STCP03 EQU $ ;ENDIF
- STCP02 EQU $ ;ENDIF
- RET
-
- ASCII: DB 0
- LOORD: DB 0
-
-
- ; SHCP - SET CURSOR ADDRESS FOR HEX DISPLAY
-
- $RTN SHCP
- LD HL,HCTAB
- LD A,(BUFPOS)
- AND 0FH
- CALL AAHL
- LD A,(HL) ;PICK UP VALUE
- LD (CPOS),A ;SET POSITION
- RET
-
-
- ; SACP - SET CURSOR ADDRESS FOR ASCII DISPLAY
-
- $RTN SACP
- LD HL,ACTAB
- LD A,(BUFPOS)
- AND 0FH
- CALL AAHL
- LD A,(HL)
- LD (CPOS),A
- RET
-
-
- ; MACH - UPDATE BUFFER IN ASCII FORMAT
-
- $RTN MACH
- LD A,(INCH)
- CP 020H
- JR C,MACH01
- CP 080H
- JR C,MACH02 ;IF CHARACTER OUT OF RANGE
- MACH01 EQU $
- CALL ALRM ;SOUND THE ALARM
- JR MACH03
- MACH02 EQU $ ;ELSE
- PUSH AF
- PUSH AF ;SAVE CHAR
- LD A,(BUFPOS) ;GET BUFFER OFFSET
- LD HL,FBUFF
- CALL AAHL ;POINT TO CHARACTER
- POP AF ;RESTORE CHAR
- LD (HL),A ;CHARACTER TO BUFFER
- CALL ASCO ;ECHO IT
- CALL SHCP
- CALL UDCP ;POSITION IN HEX AREA
- POP AF ;RESTORE CHAR
- CALL HEXO
- CALL RGHT ;MOVE CURSOR FOR NEXT
- MACH03 EQU $ ;ENDIF
- RET
-
-
- ; MHCH - UPDATE BUFFER CONTENTS IN HEX
-
- $RTN MHCH
- LD A,(INCH) ;GET INPUT CHARACTER
- CALL FOLD
- LD (INCH),A ;SAVE FOLDED VERSION
- $MTCH HEXCHR
- JR Z,MHCH02 ;IF NOT VALID HEX
- CALL ALRM ;SOUND THE ALARM
- JR MHCH03
- MHCH02 EQU $
- LD C,L ;SET HEX VALUE OF NIBBLE IN C
- LD A,(INCH)
- CALL ASCO ;ECHO IT
- LD A,(BUFPOS) ;GET OFFSET
- LD HL,FBUFF ;BASE OF BUFFET
- CALL AAHL ;HL=A(CURRENT CHAR)
- LD B,(HL) ;B = CURRENT CHARACTER
- LD A,(LOORD)
- OR A
- JR Z,MHCH04 ;IF LO ORDER NIBBLE
- LD A,0F0H ;SET MASK
- JR MHCH05
- MHCH04 EQU $ ;ELSE
- LD A,C ;CHAR TO A REG
- RLCA
- RLCA
- RLCA
- RLCA ;HEX=HEX*16
- AND 0F0H ;CLEAR ANY MINCE LEFT
- LD C,A ;BACK TO C REG
- LD A,00FH ;SET MASK
- MHCH05 EQU $ ;ENDIF
- AND B ;MASK NIBBLE
- OR C ;INSERT NEW VALUE
- LD (HL),A ;REPLACE IN BUFFER
- PUSH AF ;SAVE IT FOR ASCII
- CALL SACP
- CALL UDCP ;TOGGLE TO ASCII DISP
- POP AF ;PICK UP NEW CHAR
- CALL ASCO ;DISPLAY IT
- CALL RGHT ;ADVANCE CURSOR
- MHCH03 EQU $ ;ENDIF
- RET
-
- HEXCHR: DB 16,'0123456789ABCDEF' ;VALID HEX CHARACTERS
-
-
- ; CHDR - CHANGE TO DRIVE IN A
-
- $RTN CHDR
- LD (SAVDRV),A ;SAVE REQUESTED DRIVE
- LD C,A
- CALL SELDSK ;LOCATE DPH
- LD A,H
- OR L
- JR NZ,CHDR01 ;IF INVALID DISK
- LD A,(CURAN) ;GET CURRENT ID
- LD C,A
- CALL SELDSK ;RE-SELECT IT
- XOR A
- JP CHDR02
- CHDR01 EQU $ ;ELSE
- PUSH HL ;SAVE DPH
- LD C,RESET
- CALL CPM ;RESET DISKS
- LD HL,-1 ;Clear prvTrk and prvSec to force
- LD (PRVTRK),HL ; physical I/O on next access
- LD (PRVSEC),HL
-
- ; <<< INITIALISE PHYSICAL CONTROL BLOCKS >>>
- ; If CP/M 3.1 then the DPH is not necessarily in the same memory bank as
- ; this program but the banked BDOS does us the favour of making a local
- ; copy in common memory.
-
- POP HL ;RESTORE DPH
- LD DE,DPHLCL
- LD BC,16
- LDIR ;TAKE LOCAL COPY OF DPH
- LD HL,(DPHDPB) ;DPB pointer for CP/M 2.x
- LD A,(CPM3) ;Check which version of CP/M so we get
- OR A ; the DPB pointer right
- JR Z,COPYDPB ;Skip reload if 2.2
- LD HL,(DPHDP3) ;Get CP/M 3 DPB pointer
- COPYDPB:
- LD DE,DPBLCL
- LD BC,17 ;Increased from 15 for CP/M+
- LDIR ;TAKE LOCAL COPY OF DPB
- LD DE,(DPBSPT)
- LD BC,(DPBOFF)
- CALL MULT ;HL RETURNS NUMBER OF SYSTEM SECTORS
- PUSH HL
- LD (DPERSC),HL ;SAVE RESERVED SECTORS
- LD A,(DPBBLM)
- LD D,0
- LD E,A
- INC DE
- LD (DPESPB),DE ;SAVE SECTORS PER BLOCK
- LD BC,(DPBDSM)
- CALL MULT ;HL RETURNS NUMBER OF FILE SECTORS
- POP DE
- ADD HL,DE ;HL CONTAINS SECTORS PER DISK
- LD DE,(DPBSPT)
- DEC DE
- ADD HL,DE ;READY TO ROUND UP
- EX DE,HL
- LD BC,(DPBSPT)
- CALL DIVD ;DE RETURNS TRACKS PER DISK
- LD (DPETPD),DE ;SAVE TRACKS PER DISK
- ;INITIALISE FILE CONTROL BLOCKS
- LD A,(SAVDRV) ;RESTORE REQUESTED DRIVE
- LD (CURAN),A ;SAVE AS ABSOLUTE DISK NUMBER
- INC A
- LD (WRKDR),A ;PUT IT IN WORK FCB
- LD (LMDDR),A ;AND DIRECTORY FCB
- CALL RDIR ;READ DIRECTORY
- LD A,0FFH
- OR A ;SET NON-ZERO FLAGS
- CHDR02 EQU $ ;ENDIF
- RET
-
- SAVDRV: DS 1
-
-
- ; DLST - DIRECTORY LISTING
-
- $RTN DLST
- $FLD DDLMSG
- LD A,(CURAN) ;GET DISK ID
- ADD A,41H ;CONVERT TO ASCII LETTER
- LD (DRIVNM),A ;PUT DRIVE NAME IN MESSAGE
- LD DE,LMDFN
- CALL FMTN
- $STRO DRIVNM
- LD DE,(FSTDE@)
- LD A,(DIROFF) ;GET STARTING ENTRY
- LD H,0
- LD L,A
- CALL H16D ;HL=COUNT*LENGTH+FIRST
- LD (NXTDE@),HL ;POINT TO FIRST DISPLAY
- XOR A
- LD (PRTCNT),A
- DLST02 EQU $ ;LOOP
- LD A,(DIROFF)
- LD B,A
- LD A,(DECNT)
- SUB B
- LD HL,PRTCNT
- CP (HL)
- JR Z,DLST03 ;EXIT IF ALL ENTRIES PROCESSED
- LD A,(HL) ;GET DISPLAY COUNTER
- CALL DIRPOS ;POSITION TO DISPLAY
- LD A,(FLAGCH) ;LOAD FLAG CHARACTER
- CALL CHRO ;PRINT IT
- CALL SPCO ;AND SPACE
- LD DE,(NXTDE@) ;POINT ENTRY TO PRINT
- CALL FMTN ;FORMAT FILE NAME
- $STRO FILENM ;PRINT NAME
- LD HL,(NXTDE@)
- LD DE,16
- ADD HL,DE
- LD (NXTDE@),HL ;UPDATE TABLE POINTER
- LD HL,PRTCNT
- INC (HL) ;INCREMENT DISPLAY COUNTER
- LD A,32
- CP (HL)
- JR Z,DLST03 ;EXIT DISPLAY FULL
- JR DLST02
- DLST03 EQU $ ;ENDLOOP
- RET
-
- DDLMSG: DB 12,20,'Directory list - ',0
-
-
- ; RDIR - READ DIRECTORY
-
- $RTN RDIR
- XOR A
- LD (DECNT),A ;NO ENTRIES IN TABLE
- LD (SELDE),A ;SELECT LIST ENTRY 0
- LD (DIROFF),A ;DISPLAY STARTS AT 0
- LD HL,(MEMRY)
- LD (NXTDE@),HL ;WHERE TO INSERT POINTER
- LD (FSTDE@),HL ;START OF TABLE POINTER
- DEC HL
- LD (TOPDE@),HL ;TOP OF TABLE
- LD DE,LMDFCB
- LD C,FNDFST
- CALL CPM ;GET FIRST DIRECTORY ENTRY
- CP 0FFH
- JR Z,RDIR01 ;QUIT IF NO FILE MATCHED
- RRCA
- RRCA
- RRCA ;MULTIPY BY 32
- LD HL,FBUFF ;POINT TO RECORD
- CALL AAHL ;ADDRESS OF CURRENT ENTRY
- LD (NEWDE@),HL ;SAVE IT
- CALL INSRT ;PUT MATCHED ENTRY IN TABLE
- LD HL,(TOPDE@)
- LD DE,16
- ADD HL,DE
- LD (TOPDE@),HL ;MARK TOP OF TABLE
- RDIR02 EQU $ ;LOOP
- LD DE,LMDFCB
- LD C,FNDNXT
- CALL CPM ;FIND NEXT MATCH
- CP 0FFH
- JR Z,RDIR03 ;EXITIF NO MORE
- RRCA
- RRCA
- RRCA ;MULTIPLY DIR CODE BY 32
- LD HL,FBUFF ;POINT TO RECORD
- CALL AAHL
- LD (NEWDE@),HL ;SAVE IT
- CALL ORDER ;FIND OUT WHERE TO PUT IT
- CALL INSRT ;PUT ENTRY IN TABLE
- JR RDIR02
- RDIR03 EQU $ ;ENDLOOP
- RDIR01 EQU $ ;ENDIF
- LD HL,(TOPDE@)
- INC HL
- LD (PGEPTR),HL ;MARK START OF PAGING POINTERS
- RET
-
- ; INSRT - PUT DIRECTORY ENTRY IN TABLE
-
- INSRT EQU $
- LD DE,(NXTDE@) ;GET TABLE POINTER
- LD HL,(NEWDE@) ;GET ADDRESS OF NEW ENTRY
- INC HL ;DONT COPY DRIVE BYTE
- LD BC,16 ;LENGTH OF ENTRY
- LDIR ;SAVE ENTRY
- LD HL,DECNT
- INC (HL) ;ADD ONE TO ENTRY COUNT
- RET
-
- ; ORDER - UPDATE THE DIRECTORY TABLE
-
- ORDER EQU $
- LD HL,(FSTDE@)
- ORDER1 EQU $ ;LOOP
- LD DE,(TOPDE@)
- EX DE,HL
- OR A
- SBC HL,DE
- JP M,ORDER2 ;EXIT IF END OF TABLE
- PUSH DE ;SAVE CURRENT POINTER
- LD HL,(NEWDE@) ;POINT TO NEW ENTRY
- INC HL ;IGNORE DRIVE ID FIELD
- LD BC,11 ;LENGTH OF FILE NAME
- CALL CPST ;COMPARE FILENAME
- POP DE ;RESTORE CURRENT POINTER
- JP M,ORDER2 ;EXIT IF CURRENT>NEW
- LD HL,16
- ADD HL,DE ;POINT TO NEXT ENTRY
- JP ORDER1
- ORDER2 EQU $ ;ENDLOOP
- LD (NXTDE@),DE ;SAVE INSERT ADDRESS
- LD HL,(TOPDE@)
- INC HL
- OR A
- SBC HL,DE
- LD B,H
- LD C,L ;LENGTH TO MOVE
- LD HL,(TOPDE@) ;CURRENT TOP OF TABLE
- PUSH HL ;SAVE CURRENT TOP
- LD DE,16
- ADD HL,DE ;NEW TOP OF TABLE
- LD (TOPDE@),HL ;SAVE NEW TOP
- POP DE ;RESTORE OLD TOP
- LD A,B
- OR C
- JP Z,ORDER3 ;QUIT IF NOTHING TO MOVE
- EX DE,HL ;DEST=NEW,SRC=OLD TOP ADDRESS
- LDDR ;MOVE TABLE UP 16 BYTES
- ORDER3 EQU $ ;ENDIF
- RET
-
-
- ; CPST - COMPARE STRING (HL)0:6 WITH (DE)0:6 LENGTH (BC)
-
- $RTN CPST
- XOR A
- LD (CPSTCN),A ;COMPARE CONDITION IS =
- CPST01 EQU $ ;LOOP
- LD A,C
- OR B
- JR Z,CPST02 ;EXITIF DONE
- PUSH BC ;SAVE COUNTER
- LD A,(DE) ;GET 2ND STR CHAR
- AND 07FH ;IGNORE HIGH BIT
- LD B,A ;SAVE IT
- LD A,(HL) ;GET 1ST STR CHAR
- AND 07FH ;IGNORE HI BIT
- SUB B ;COMPARE CURRENT CHARS
- LD (CPSTCN),A ;SAVE RESULT
- POP BC ;RETRIEVE COUNTER
- JR NZ,CPST02 ;EXITIF NOT EQUAL
- INC HL
- INC DE
- DEC BC ;POINT TO NEXT CHARS
- JR CPST01
- CPST02 EQU $ ;ENDLOOP
- LD A,(CPSTCN) ;PICK UP CONDITIONS
- OR A ;SET CPU FLAGS
- RET
-
- CPSTCN: DS 1 ;COMPARE CONDITION
-
- ; CLRA - CLEAR AREA FROM LINE H FOR L
-
- $RTN CLRA
- LD A,H
- LD B,L
- CLRA01 EQU $
- CALL CLRL
- INC A
- DJNZ CLRA01
- LD HL,0
- LD (PRVERR),HL ;NO ERROR NOW DISPLAYED
- RET
-
- ; FMTN - FORMAT FILE NAME FROM FCB POINTED TO BY DE INTO FILENM
-
- $RTN FMTN
- LD HL,FILENM
- LD B,8 ;LENGTH 8
- FMTN01 EQU $ ;LOOP
- LD A,(DE)
- AND 07FH ;STRIP OFF HIGH BIT
- LD (HL),A ;COPY CHARACTER
- INC HL
- INC DE
- DJNZ FMTN01 ;UNTIL NAME DONE
- LD (HL),'.' ;INSERT SEPERATOR
- INC HL
- LD A,(DE)
- AND 80H
- LD (RO),A ;SET RO FLAG
- LD B,3 ;LENGTH 3
- FMTN02 EQU $ ;REPEAT
- LD A,(DE)
- AND 07FH ;STRIP OFF HIGH BIT
- LD (HL),A ;COPY CHARACTER
- INC HL
- INC DE ;POINT TO NEXT
- DJNZ FMTN02 ;UNTIL TYPE DONE
- LD A,(RO)
- OR A ;TEST RO FLAG
- LD A,'W' ;ASSUME R/W MODE
- JR Z,FMTN03 ;IF READ ONLY
- LD A,'O' ;SELECT R/O MODE
- FMTN03 EQU $ ;ELSE
- LD (FDMDRS),A ;SET MODE
- XOR A
- LD (COMFLG),A ;CLEAR .COM FLAG
- LD HL,COMSTR
- LD DE,FILENM+9 ;POINT TO TYPE
- LD BC,3
- CALL CPST
- JR NZ,FMTN04 ;IF .COM FILE
- LD A,0FFH
- LD (COMFLG),A ;SET FLAG
- FMTN04 EQU $ ;ENDIF
- RET
-
-
- ; UDCP - UPDATE CURSOR POSITION TO LPOS/CPOS
-
- UDCP EQU $
- PUSH HL
- PUSH AF
- LD A,(LPOS) ;GET LINE NUMBER
- LD L,A
- LD A,(CPOS) ;GET COLUM POSITION
- LD H,A
- CALL CURS ;PUT CURSOR THERE
- POP AF
- POP HL
- RET
-
- LPOS: DB 0
- CPOS: DB 0
-
- ;---------------
- ; FILE I/O ROUTINES
- ;---------------
-
- ; IOADDR - Set the data transfer address for disk operations
-
- $RTN IOADDR
- LD DE,(DMA)
- LD C,SDMA
- CALL CPM ;Could just JP CPM but this is
- RET ;easier when using Z8E debugger
-
- ; DMASET - Record the data transfer address for disk operations
-
- $RTN DMASET
- LD (DMA),BC
- RET
-
- DMA: DEFW 80h ;(Default at entry to this program)
-
- ; RDFS - READ FILE RELATIVE SECTOR
-
- $RTN RDFS
- push bc
- XOR A
- LD (WRKOV),A
- LD HL,(WRKRR)
- LD (SAVFSC),HL ;SAVE CURRENT RECORD
- LD HL,(RELREC)
- LD (WRKRR),HL ;SET RECORD NUMBER
- CALL IOADDR ;Set data pointer
- LD DE,WRKFCB ;POINT TOFCB
- LD C,READRN
- CALL CPM ;READ THE RECORD
- LD (READST),A ;SAVE STATUS
- OR A
- JR Z,RDFS01 ;IF BAD READ
- LD HL,(SAVFSC)
- LD (RELREC),HL ;RESTORE RECORD NUMBER
- LD (WRKRR),HL
- RDFS01 EQU $
- pop bc
- RET
-
- ; WRFS - WRITE FILE RELATIVE SECTOR BACK TO DISK
-
-
- $RTN WRFS
- CALL IOADDR ;Set data pointer
- LD DE,WRKFCB ;POINT TO FCB
- LD C,WRITRN ;RANDOM WRITE
- CALL CPM ;GO DO IT
- RET
-
- ; PHYS3 - Test if CP/M Plus and if so then change sector number to
- ; conform to physical sector size.
-
- $RTN PHYS3
- LD A,(CPM3)
- OR A
- PUSH AF ;Save result for caller
- JR Z,PEXIT ;No transformation needed for 2.x
- LD A,(DPBPSH) ;Pick up physical sector size from DPH
- INC A ;Pre-increment for shift loop
- PSHIFT:
- DEC A ;Count down the number of shifts
- JR Z,PEXIT ;Exit when done
- SRL B ;BC := BC/2
- SRA C
- JR PSHIFT ;Around again
- PEXIT:
- POP AF
- RET
-
- ; SECPNT Build address of 128-byte "logical" sector within psBuff
- ; On exit, HL holds required address and BC contains the
- ; value 128 (ready for an LDIR instruction)
-
- $RTN SECPNT
- LD HL,(PSMDSC) ;Get sector number
- LD A,(DPBPSM) ;Get physical sector mask
- AND L ;Calculate which 128-byte chunk
- LD HL,PSBUFF
- LD BC,128 ;Chunk size
- POFF: RET Z ;Exit now if address calculated
- ADD HL,BC ;Otherwise increment pointer
- DEC A
- JR POFF
-
- ; PSRD - READ PHYSICAL SECTOR
-
- $RTN PSRD
- CALL IOADDR ;We'll override this later if CP/M 3.x
- LD BC,(PSMDTR)
- CALL SETTRK ;SELECT TRACK
- LD BC,(PSMDSC)
- CALL PHYS3 ;If CP/M 3.x then change to physical
- PUSH BC ;Save sector number during tests
- JR Z,PREAD ;If CP/M 2.x then do the read
- LD HL,(PRVSEC) ;See if same physical sector as last time
- SBC HL,BC ;(Carry flag is already clear)
- JR NZ,PREAD ;Do read if different
- LD BC,(PRVTRK) ;Check track
- LD HL,(PSMDTR)
- SBC HL,BC
- JR NZ,PREAD ;Do read if different
-
- ;If we get here then we are running under CP/M+ and we already have the
- ;correct physical sector in memory. All we have to do is deliver the
- ;appropriate logical sector to the rest of the program.
-
- POP BC ;Align stack
- CALL SECPNT ;Build pointer into psBuff
- LD DE,(DMA) ;Where to put the data
- LDIR ;Move 128 bytes
- RET
- PREAD:
- POP BC
- LD (PRVSEC),BC ;Record sector ..
- LD HL,(PSMDTR)
- LD (PRVTRK),HL ;.. and track
- ; LD DE,(DPBOFF)
- ; OR A
- ; SBC HL,DE
- ; JR C,STSA01 ;IF NOT SYSTEM TRACK
- LD DE,(DPHXLT)
- CALL SECTRN ;DO SECTOR TRANSLATION
- LD B,H
- LD C,L
- STSA01 EQU $
- CALL SETSEC
- LD A,(CPM3) ;If CP/M 3 then ..
- OR A
- JR Z,DOREAD
- LD BC,PSBUFF ;.. use physical sector buffer
- CALL SETDMA
- DOREAD: CALL READ ;READ SECTOR
- PUSH AF ;Preserve result
- LD A,(CPM3)
- OR A
- JR Z,PSRDX ;Exit if CP/M 2.2
- CALL IOADDR ;Restore DMA
- CALL SECPNT ;Calculate address in psBuff
- LD DE,(DMA) ;Where to put the data
- LDIR ;Copy it
- PSRDX: POP AF
- RET
-
-
- ; PSWR - WRITE PHYSICAL SECTOR
-
- $RTN PSWR
- LD A,(CPM3) ;Decide which method to use
- OR A
- JR Z,PSWR2
- CALL SECPNT ;Calculate address within psBuff
- EX DE,HL ;Put destination address into DE
- LD HL,(DMA) ;Where to put the data
- LDIR ;Move the data
- LD BC,PSBUFF ;Set address for data transfer
- CALL SETDMA
- PSWR2:
- LD C,WRDIR ;USE WRITE DIRECTORY TO FORCE WRITE
- CALL WRITE ;WRITE SECTOR
- PUSH AF ;Save result
- CALL IOADDR ;Restore data address
- POP AF
- RET
-
- WRDIR EQU 1 ;BIOS DIRECTORY WRITE CODE
-
- PRVSEC: DEFW -1
- PRVTRK: DEFW -1
-
- ;----------------
- ; UTILITY ROUTINES
- ;----------------
-
- ; H16D - HL * 16 + DE
-
- $RTN H16D
- ADD HL,HL
- ADD HL,HL
- ADD HL,HL
- ADD HL,HL ;HL=HL*16
- ADD HL,DE ; + DE
- RET
-
- ; ERRP - PROCESS ERROR DISPLAYS
-
- $RTN ERRP
- LD HL,(PRVERR)
- LD A,H
- OR L
- JR Z,ERRP01 ;IF PREVIOS ERROR
- PUSH HL ;SAVE TEXT ADDRESS
- $FLD ERRFLD ;POSITION CURSOR
- POP HL
- CALL CSTR ;CLEAR STRING
- LD HL,0
- LD (PRVERR),HL ;CLEAR POINTER
- ERRP01 EQU $ ;ENDIF
- LD HL,(ERRTXT)
- LD A,H
- OR L
- JR Z,ERRP02 ;IF ERROR SET
- PUSH HL ;SAVE TEXT POINTER
- $FLD ERRFLD ;POSITION CURSOR
- POP HL
- LD (PRVERR),HL ;SAVE TEXT ADDRESS
- CALL STRO ;OUTPUT TEXT
- CALL ALRM ;SOUND ALARM
- LD HL,0
- LD (ERRTXT),HL ;CLEAR TEXT POINTER
- ERRP02 EQU $ ;ENDIF
- RET
-
- ; MTCH - BYTE LIST MATCHER
-
- $RTN MTCH
- PUSH BC ;SAVE BC
- LD B,0
- LD C,(HL) ;BC=LENGTH
- INC HL ;POINT TO START OF LIST
- PUSH BC ;SAVE LENGTH
- CPIR ;SCAN LIST
- POP HL ;RESTORE LENGTH TO HL
- JR NZ,MTCH01 ;IF FOUND
- OR A
- SBC HL,BC ;SUBTRACT RESIDUE TO GIVE OFFSET+1
- DEC HL ;HL IS OFFSET
- CP A ;SET Z FLAG
- MTCH01 EQU $
- POP BC ;RESTORE BC
- RET
-
-
- ; EXVA - JUMP TO ROUTINE AT OFFSET 2*HL FROM DE
-
- $RTN EXVA
- ADD HL,HL
- ADD HL,DE ;DERIVE ACTION ADDR
- CALL LDHL
- JP (HL)
-
-
- ; LDHL - LOAD HL WITH (HL)
-
- $RTN LDHL
- PUSH AF
- LD A,(HL)
- INC HL
- LD H,(HL)
- LD L,A ;HL = (HL)
- POP AF
- RET
-
-
- ; AAHL - ADD A TO HL
-
- $RTN AAHL
- PUSH DE ;SAVE DE
- LD E,A
- LD D,0
- ADD HL,DE
- POP DE ;RESTORE DE
- RET
-
- ; MULT - MULTIPLY DE BY BC TO GIVE RESULT IN HL AND OVERFLOW IN DE
-
- $RTN MULT
- LD A,16 ;SET A TO LOOP COUNT
- LD HL,0 ;ZERO RESULT
- OR A ;CLEAR CARRY
- MULT01 EQU $ ;LOOP
- EX DE,HL
- ADC HL,HL ;SHIFT DE LEFT 1 (AND INTO CARRY)
- EX DE,HL
- JP NC,MULT02 ;IF BIT SHIFTED OUT OF DE IS SET
- ADD HL,BC ;ADD MULTIPLICAND TO RESULT
- JP NC,MULT03 ;IF RESULT OVERFLOWED
- INC DE ;PROPAGATE INTO DE
- MULT03 EQU $ ;ENDIF
- MULT02 EQU $ ;ENDIF
- DEC A ;DECREMENT LOOP COUNT
- JP Z,MULT04 ;IF LOOP COUNT IS ZERO EXIT
- ADD HL,HL ;SHIFT LEFT 1 (OVERFLOW ADDED BY ADC)
- JP MULT01
- MULT04 EQU $ ;ENDLOOP
- RET
-
- ; DIVD - DIVIDE DE BY BC TO GIVE REMAINDER IN HL AND QUOTIENT IN DE
-
- $RTN DIVD
- LD A,16 ;SET A TO LOOP COUNT
- LD HL,0 ;ZERO REMAINDER
- DIVD01 EQU $ ;LOOP
- ADD HL,HL ;SHIFT REMAINDER LEFT 1
- EX DE,HL
- ADD HL,HL ;SHIFT DIVISOR LEFT 1
- EX DE,HL
- JP NC,DIVD02 ;IF CARRY SET
- INC HL ;INCREMENT RESULT
- DIVD02 EQU $ ;ENDIF
- OR A ;RESET CARRY FLAG
- SBC HL,BC ;SUBTRACT DIVISOR
- INC DE ;INCREMENT QUOTIENT
- JP P,DIVD03 ;IF RESULT IS NEGATIVE
- ADD HL,BC ;BACK OFF SUBTRACT
- DEC DE ;DECREMENT QUOTIENT
- DIVD03 EQU $ ;ENDIF
- DEC A ;DECREMENT LOOP COUNT
- JP Z,DIVD04 ;IF LOOP COUNT ZERO EXIT
- JP DIVD01
- DIVD04 EQU $ ;ENDLOOP
- RET
-
-
- ; SETD - SET DIRECTORY MODE
-
- $RTN SETD
- LD A,'D'
- LD (WTG),A ;NEXT MODE IS DIRECTORY
- RET
-
-
- ; SETF - SET FILE MODE
-
- $RTN SETF
- LD A,'F'
- LD (WTG),A ;NEXT MODE IS FILE
- RET
-
-
- ; SETP - SET PHYSICAL SECTOR MODE
-
- $RTN SETP
- LD A,'P'
- LD (WTG),A ;NEXT MODE IS PHYSICAL SECTOR
- RET
-
-
- ; SETX - SET EXIT MODE
-
- $RTN SETX
- LD A,'X'
- LD (WTG),A ;NEXT MODE IS EXIT
- RET
-
- ;----------------
- ; SCREEN I/O ROUTINES
- ;----------------
-
- ; CHRI - INPUT CHARACTER
- ; USE BIOS CALL TO SUPPORT SYSTEMS WITH SOFTWARE CURSOR
-
- $RTN CHRI
- PUSH HL
- PUSH DE
- PUSH BC
- CALL CONIN
- LD (INCH),A
- POP BC
- POP DE
- POP HL
- RET
-
-
- ; FOLD - FOLD CHARACTER IN A TO UPPER CASE IF REQUIRED
-
- $RTN FOLD
- CP 'a'
- JR C,FOLD01
- CP 'z'+1
- JR NC,FOLD01 ;IF NOT UPPER CASE
- AND 05FH ;FOLD CHARACTER
- FOLD01 EQU $ ;ENDIF
- RET
-
-
- ; CHRF - GET FOLDED CHARACTER
-
- $RTN CHRF
- CALL CHRI
- CALL FOLD
- RET
-
- ; CHRO - OUTPUT CHARACTER IN A
-
- $RTN CHRO
- PUSH BC
- PUSH DE
- PUSH HL
- PUSH AF
- LD E,A ;INPUT TO PARM REG
- LD C,CONIO ;DIRECT OUTPUT
- CALL CPM ;CALL CPM
- POP AF
- POP HL
- POP DE
- POP BC
- RET
-
-
- ; ALRM - SOUND THE CONSOLE BELL
-
- $RTN ALRM
- PUSH AF
- LD A,07H
- CALL CHRO
- POP AF
- RET
-
-
- ; SPCO - OUTPUT SPACE TO SCREEN
-
- $RTN SPCO
- PUSH AF
- LD A,' '
- CALL CHRO
- POP AF
- RET
-
-
- ; CLRS - CLEAR SCREEN AND HOME CURSOR
-
- $RTN CLRS
- PUSH AF
- PUSH HL
- $STRL CLSSTR ;PRINT CLEAR SCREEN STRING
- LD HL,0
- LD (PRVERR),HL ;CLEAR PREV ERROR
- POP HL
- POP AF
- RET
-
-
- ; DHDR - CLEAR SCREEN AND DISPLAY HEADER
-
- $RTN DHDR
- CALL CLRS
- $FLD HDRMSG
- RET
-
- ; CLRL - CLEAR LINE CONTAINED IN A
-
- $RTN CLRL
- PUSH AF
- PUSH HL
- LD H,0 ;COLUMN ZERO
- LD L,A ;LINE (A)
- CALL CURS ;POSITION TO LINE
- $STRL CLLSTR ;PRINT CLEAR LINE STRING
- POP HL
- POP AF
- RET
-
-
- ; CURS - SET CURSOR POSITION TO LINE L COLUMN H
-
- $RTN CURS
- PUSH AF
- PUSH HL
- $STRL CPPREF ;OUTPUT CURSOR POSITION PREFIX
- POP HL
- PUSH HL
- LD A,(ROW1ST) ;Row or column?
- OR A
- PUSH AF ;Save row/column flag
- CALL COORD
- $STRL CPMID ;Output cursor position infix
- POP AF ;Recover row/column flag
- DEC A ;Toggle it for 2nd coordinate
- POP HL
- CALL COORD
- $STRL CPEND
- POP AF
- RET
-
- ; COORD - outputs a cursor-position coordinate.
- ; H contains horizontal position
- ; L contains line number
- ; Z flag is set if H coord required, reset if L
-
- $RTN COORD
- JR Z,DOHOR
- LD A,(ROWOFF)
- ADD A,L
- JR EITHER
- DOHOR: LD A,(COLOFF)
- ADD A,H
- EITHER: LD E,A
- ld d,0 ; JTC be sure no extra values in D
- LD A,(CPBIN)
- OR A
- JR NZ,COBIN
- CALL DECOUT
- RET
- COBIN: LD A,E
- CALL CHRO
- RET
-
- ; DECOUT - Convert 16-bit number in DE to decimal and output to the screen
- ; Leading zeros are suppressed. Number is treated as unsigned.
-
- $RTN DECOUT
- PUSH HL
- PUSH DE
- PUSH BC
- EX DE,HL
- LD BC,-10 ;Radix
- LD DE,-1 ;Initialise quotient
- DVLP: ADD HL,BC ;Subtract radix
- INC DE ;Increment quotient
- JR C,DVLP ;(Slow way to divide)
- SBC HL,BC ;Correct for extra subtract
- ;JTC EX DE,HL
- ld a,d ; JTC
- or e ;Test for zero
- CALL NZ,DECOUT ;Recursive call
- LD A,'0' ;Convert digit for display
- add a,l ; JTC
- CALL CHRO ;Write to screen
- POP BC ;Restore stack
- POP DE
- POP HL
- RET
-
- ; DPNL - DISPLAY PANEL
-
- $RTN DPNL
- LD B,(HL)
- INC HL
- DPNL01 EQU $
- PUSH BC
- CALL DFLD ;DISPLAY FIELD
- POP BC
- DJNZ DPNL01
- RET
-
-
- ; DFLD - DISPLAY FIELD
-
- $RTN DFLD
- PUSH HL
- CALL LDHL
- CALL CURS ;SET CURSOR POSITION
- POP HL
- INC HL
- INC HL
- CALL STRO ;OUPUT STRING
- RET
-
- ; CFLD - CLEAR FIELD
-
- $RTN CFLD
- PUSH HL
- CALL LDHL
- CALL CURS ;SET CURSOR POSITION
- POP HL
- INC HL
- INC HL
- CALL CSTR ;CLEAR STRING
- RET
-
- ; CSTR - CLEAR STRING POINTED TO BY HL
-
- $RTN CSTR
- CSTR01 EQU $ ;LOOP
- LD A,(HL) ;PICK UP FIELD CHARACTER
- OR A
- JR Z,CSTR02 ;EXIT IF NULL
- CALL SPCO ;OUTPUT BLANK
- INC HL ;POINT TO NEXT CHARACTER
- JR CSTR01
- CSTR02 EQU $ ;ENDLOOP
- INC HL
- RET
-
- ; STRO - OUTPUT STRING POINTED TO BY HL AND DELIMITED BY A NULL
-
- $RTN STRO
- STRO01 EQU $
- LD A,(HL)
- OR A
- JR Z,STRO02
- CALL CHRO
- INC HL
- JR STRO01
- STRO02 EQU $
- INC HL
- RET
-
- ; STRL - Output length-prefixed string pointed to by HL
-
- $RTN STRL
- PUSH BC
- LD B,(HL)
- INC B
- STRLLP: INC HL
- DEC B
- JR Z,STRLXT
- LD A,(HL)
- PUSH HL
- CALL CHRO
- POP HL
- JR STRLLP
- STRLXT: POP BC
- RET
-
- ; ASCO - OUTPUT ASCII CHARACTER OR '.' TO SCREEN
- ;
- ; Modified Jan 86 by JHB to display ASCII chars with high bit
- ; set in reverse video. The idea is to make displays of file
- ; names in directory sectors more readable.
-
- $RTN ASCO
- PUSH HL
- PUSH AF
- BIT 7,A ;Check high bit
- PUSH AF ;Save high bit flag
- PUSH AF ;Save character during video mode change
- CALL NZ,VMINV ;Turn on highlight
- POP AF ;Recover character for display
- AND 7FH ;Mask off high bit
- LD HL,MAXASC ;Check for graphic
- CP (HL)
- JR NC,ASCO01
- CP 20H
- JR NC,ASCO02
- ASCO01 EQU $
- LD A,'.'
- ASCO02 EQU $
- CALL CHRO
- POP AF ;Did we highlight?
- CALL NZ,VMNORM ;If so then return to normal video
- POP AF
- POP HL
- RET
-
-
- ; HEXO - OUTPUT BYTE IN A IN HEX TO SCREEN
-
- $RTN HEXO
- PUSH AF
- RRA
- RRA
- RRA
- RRA ;REVERSE NIBBLES
- CALL HEXC ;PRINT HO NIBBLE
- POP AF
- CALL HEXC ;PRINT LO NIBBLE
- RET
-
- ;
- ; HEXW - OUTPUT WORD IN HL TO SCREEN
- ;
- $RTN HEXW
- PUSH AF
- LD A,H
- CALL HEXO
- LD A,L
- CALL HEXO
- POP AF
- RET
-
-
- ; HEXC - OUTPUT LO NIBBLE IN A IN HEX TO SCREEN
-
- $RTN HEXC
- AND 0FH ;LOSE HO NIBBLE
- ADD A,90H
- DAA
- ADC A,40H
- DAA
- CALL CHRO ;OUTPUT HEX CHARACTER
- RET
-
- ; VIDEO FUNCTIONS
-
- $RTN VMINV ;Inverse video
- LD HL,VINV
- JR VMSET
-
- $RTN VMNORM ;Normal video
- LD HL,VNORM
- VMSET: CALL STRL
- RET
-
- ; END OF CODE
-
- PSBUFF EQU $ ;Physical sector I/O buffer
- ENDCDE EQU $+2048
- .list
- ; Enable symbols for Z8E
- END INIT
- D 7FH ;Mask off high bit
- LD HL,MAXASC ;Check for grap