mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2357 lines
65 KiB
2357 lines
65 KiB
TITLE "B/P Bios Build System Image"
|
|
;************************************************************************
|
|
;* B P B U I L D *
|
|
;* Create a system image file containing B/P Bios *
|
|
;* by Harold F. Bower and Cameron W. Cotrill *
|
|
;*----------------------------------------------------------------------*
|
|
;* Disassembly: jxl Jan 2025 *
|
|
;* public release 1.0 Apr 2025 *
|
|
;* see remarks at the end *
|
|
;*----------------------------------------------------------------------*
|
|
;* LINK with Version 4 libraries: VLIB, Z3LIB, SYSLIB *
|
|
;* and SLINK0.REL module (as included in ZSDOS v1 GNU public release) *
|
|
;* *
|
|
;* A>Z80ASM BPBUILD/RS *
|
|
;* A>SLRNK BPBUILD/N,/A:100,/D:23E0,BPBUILD,SLINK0,VLIBS/S,Z3LIBS/S,SYSLIBS/S,/E *
|
|
;************************************************************************
|
|
|
|
VER EQU 10
|
|
REV EQU ' '
|
|
|
|
DATE MACRO
|
|
DEFB '31 Aug 92'
|
|
ENDM
|
|
|
|
|
|
CTRLC EQU 03H ; Control-C character
|
|
BEL EQU 07H ; Bell character
|
|
TAB EQU 09H ; Tab character
|
|
LF EQU 0AH ; Line Feed character
|
|
CR EQU 0DH ; Carriage Return character
|
|
ESC EQU 1BH ; Escape character
|
|
|
|
CPMBDOS EQU 5 ; CP/M BDOS entry point (JP)
|
|
CPMFCB EQU 5CH ; CP/M standard FCB #1 (+1 filename, +9 filetype)
|
|
CPMDMA EQU 80H ; CP/M standard DMA buffer
|
|
|
|
|
|
; SLINK0 M-Rel linker module
|
|
EXTRN LINK ; get
|
|
PUBLIC @GBYTE ; make visible
|
|
|
|
; From VLIB Get..
|
|
EXTRN Z3VINIT, GXYMSG, VPRINT, EREOL, TINIT, DINIT, CLS, GOTOXY
|
|
|
|
; From Z3LIB Get..
|
|
EXTRN GETNAME, PRTNAME, ZFNAME, GZMTOP, WHRENV
|
|
|
|
; From SYSLIB Get..
|
|
EXTRN PUTUD, RETUD, SETDMA, INITFCB, BLINE, CRLF, CAPINE, CAPIN, PFN1, PFN3
|
|
EXTRN F$EXIST, F$MOPEN, F$CLOSE, F$DELETE, F$OPEN, F$READ, F$RENAME, F$WRITE
|
|
EXTRN PADC, PHLFDC, PHL4HC, COUT, EVAL10, EVAL16, ISALNUM, CODEND
|
|
|
|
|
|
;::::: PROGRAM START
|
|
|
|
ORG 100H
|
|
CSEG
|
|
|
|
|
|
BPBUILD: JP START ; bypass header
|
|
DEFB 'Z3ENV' ; this is a ZCPR3 utility
|
|
DEFB 1 ; show external environment
|
|
|
|
ENVADR: DEFW 0 ; addr of Z3 environment
|
|
|
|
START: LD HL,(CPMBDOS) ; ##### BUG: should rather be CPMBDOS+1
|
|
CALL WHRENV ; find Z3 Environment Descriptor
|
|
LD (ENVADR),HL ; store ENV ptr locally
|
|
CALL Z3VINIT ; ..and init for VLIB/Z3LIB routines
|
|
CALL TINIT ; init terminal characteristics
|
|
CALL GETNAME ; get actual program name
|
|
CALL GETQFLG ; get quiet flag
|
|
AND A ; check if verbose mode
|
|
JR NZ,START0 ; ..if not, skip over (= quiet)
|
|
|
|
CALL VPRINT
|
|
DEFB 1,'B/P System Build',2,' V',VER/10+'0','.',VER MOD 10 + '0',REV,' '
|
|
DATE
|
|
DEFB ' ',CR,LF
|
|
DEFB 0
|
|
|
|
START0: CALL GZMTOP ; get top of memory (first byte _not_ to be used)
|
|
DEC HL ; -1
|
|
EX DE,HL ; save temporarily
|
|
CALL CODEND ; get available page after code end (WSPC area)
|
|
EX DE,HL ; swap regs back
|
|
XOR A ; reset C-Flag
|
|
SBC HL,DE ; calc remaining TPA size
|
|
EX DE,HL ; use DE as counter
|
|
|
|
CLRTPA: LD (HL),0 ; clear TPA memory
|
|
INC HL ; ..from end of program to top of memory
|
|
DEC DE
|
|
LD A,E
|
|
OR D ; counter = zero ?
|
|
JR NZ,CLRTPA ; ..loop till done
|
|
|
|
LD (STACK),SP ; set local stackpointer
|
|
LD SP,STACK
|
|
CALL RETUD ; get current drive (B) and user (C)
|
|
LD (OLDDU),BC ; ..and store
|
|
|
|
; evaluate command line
|
|
LD A,(CPMFCB+1) ; get first char of command line (in FCB #1)
|
|
CP '/' ; is this a help request ?
|
|
JP Z,HELP ; ..if so, jump display help and exit
|
|
CP ' ' ; is file name blank ?
|
|
JR Z,INITRAM ; ..if so, jump to ask for manual input
|
|
|
|
; a file name was specified (= image file), attempt to read header
|
|
LD HL,CPMFCB+9 ; check file type
|
|
LD A,(HL)
|
|
CP ' ' ; is first char <SP> ?
|
|
JR NZ,RDFILE ; ..if not, skip over
|
|
EX DE,HL ; else, swap regs
|
|
LD HL,FTYPES+3 ; ptr to standard file type 'IMG'
|
|
LD BC,3 ; ..and copy 3 chars
|
|
LDIR
|
|
RDFILE: LD HL,CPMFCB+1 ; ptr to file name in standard FCB #1
|
|
LD DE,IMGFN_I ; ptr to default file name for system image
|
|
LD BC,11 ; copy 11 chars from FCB to IMG Header area
|
|
LDIR
|
|
CALL CODEND ; get addr WSPC
|
|
CALL RDHDR ; read first page of IMG file
|
|
OR A ; check if successful
|
|
JR NZ,RDFILE0 ; ..if not, jump to display msg
|
|
CALL CODEND ; get addr WSPC
|
|
LD DE,IMGHD_I ; point to area for IMG file header
|
|
JR RDFILE1 ; ..and jump to continue
|
|
RDFILE0: CALL VPRINT
|
|
DEFB CR,LF,"+++ Can't Read...any key to continue w/defaults +++"
|
|
DEFB 0
|
|
CALL CAPINE ; get input (any key)
|
|
CALL CODEND ; get addr WSPC
|
|
EX DE,HL ; swap regs
|
|
LD HL,IMGHD_I ; point to area for IMG file hdr
|
|
|
|
RDFILE1: LD BC,0100H ; bytes to copy (1 page)
|
|
LDIR ; ..from hdr to WSPC (no file, or read error)
|
|
; or from WSPC to hdr (file read successfully)
|
|
|
|
; initialize ram storage
|
|
INITRAM: LD HL,CCPFCB
|
|
XOR A ; nullify A
|
|
LD B,IMGFCB+36-CCPFCB ; B= 179
|
|
INITRM0: LD (HL),A ; clear variables
|
|
INC HL ; with <NUL> (180 bytes)
|
|
DJNZ INITRM0
|
|
LD BC,11 ; bytes to copy
|
|
PUSH BC
|
|
LD HL,CFNAM_I ; copy ZCPR file name
|
|
LD DE,CCPFCB+1
|
|
LDIR
|
|
POP BC ; restore # bytes
|
|
PUSH BC
|
|
LD HL,DFNAM_I ; copy ZSDOS file name
|
|
LD DE,DOSFCB+1
|
|
LDIR
|
|
POP BC ; restore # bytes
|
|
PUSH BC
|
|
LD HL,BFNAM_I ; copy B/P Bios file name
|
|
LD DE,BIOSFCB+1
|
|
LDIR
|
|
POP BC ; restore # bytes
|
|
LD HL,IMGFN_I ; copy IMG file name
|
|
LD DE,IMGFCB+1
|
|
LDIR
|
|
|
|
|
|
;::::: MAIN MENU
|
|
|
|
M0MAIN: CALL M0SHOW ; display menu
|
|
CALL MSELECT ; get user for input
|
|
CP ' ' ; is it <SP> ?
|
|
JP Z,MKSYS ; ..build new system
|
|
CP CR ; <CR> ?
|
|
JP Z,MKSYS ; ..build new system
|
|
CP ESC ; <ESC> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
CP CTRLC ; <Ctrl-C> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
CP '1' ; '1' ?
|
|
JR Z,M0GOM1 ; ..go to Files menu
|
|
CP '2' ; '2' ?
|
|
JP Z,M0GOM2 ; ..go to Bios config menu
|
|
CP '3' ; '3' ?
|
|
JP Z,M0GOM3 ; ..go to Environment menu
|
|
JR M0MAIN
|
|
|
|
M0GOM1: CALL M1FILE
|
|
JR M0MAIN
|
|
|
|
M0GOM2: CALL M2BIOS
|
|
JR M0MAIN
|
|
|
|
M0GOM3: CALL M3ENV
|
|
JR M0MAIN
|
|
|
|
|
|
;::::: MAKE (build) NEW SYSTEM
|
|
|
|
MKSYS: CALL CLS
|
|
CALL VPRINT
|
|
DEFB CR,LF,'..building system..',CR,LF,LF
|
|
DEFB 0
|
|
|
|
|
|
;----- Pre-run to determine addr/size of linked system segments
|
|
|
|
; determine CPR size/addr
|
|
LD HL,0
|
|
LD (COMTB6),HL ; clear org B2RAM Common
|
|
LD (COMTB5),HL ; clear org BANK2 Common
|
|
LD DE,CCPFCB
|
|
LD HL,COMTBL
|
|
CALL LNKDSZ ; determine CCP segment sizes
|
|
LD (CCNBSZ),HL ; store CCP CSEG Non-banked size
|
|
ADD HL,BC ; add DSEG size
|
|
CALL ALIGN ; ..align to next sector boundary
|
|
LD (CNBSZ_I),HL ; ..and store CCP Non-banked total size
|
|
LD HL,(COMTB6) ; get B2RAM Common
|
|
LD (CDBKSZ),HL ; ..and store CCP DSEG Banked size
|
|
EX DE,HL
|
|
LD HL,(COMTB5) ; get BANK2 Common
|
|
LD (CCBKSZ),HL ; ..and store CCP CSEG Banked size
|
|
ADD HL,DE ; add values
|
|
CALL ALIGN ; ..align to next sector boundary
|
|
LD (CBKSZ_I),HL ; ..and store as CCP Banked total size
|
|
CALL PB2ADR ; display addr's
|
|
|
|
; determine DOS size/addr
|
|
LD DE,DOSFCB
|
|
LD HL,COMTBL
|
|
CALL LNKDSZ ; determine DOS segment sizes
|
|
LD (DCNBSZ),HL ; store DOS CSEG Non-banked size
|
|
ADD HL,BC ; add DSEG size
|
|
CALL ALIGN ; ..align to next sector boundary
|
|
LD (DNBSZ_I),HL ; ..and store DOS Non-banked total size
|
|
LD HL,(COMTB6) ; get B2RAM Common
|
|
LD (DDBKSZ),HL ; ..and store DOS DSEG Banked size
|
|
EX DE,HL
|
|
LD HL,(COMTB5) ; get BANK2 Common
|
|
LD (DCBKSZ),HL ; ..and store DOS CSEG Banked size
|
|
ADD HL,DE ; add values
|
|
CALL ALIGN ; ..align to next sector boundary
|
|
LD (DBKSZ_I),HL ; ..and store as DOS Banked total size
|
|
CALL PB2ADR ; display addr's
|
|
|
|
; determine B/P BIOS size/addr
|
|
LD DE,BIOSFCB
|
|
LD HL,COMTBL
|
|
CALL LNKDSZ ; determine BIOS segment sizes
|
|
LD (BCNBSZ),HL ; store BIOS CSEG Non-banked size
|
|
ADD HL,BC ; add DSEG size
|
|
CALL ALIGN ; ..align to next sector boundary
|
|
LD (BNBSZ_I),HL ; ..and store BIOS Non-banked total size
|
|
LD HL,(COMTB6) ; get B2RAM Common
|
|
LD (BDBKSZ),HL ; ..and store BIOS DSEG Banked size
|
|
EX DE,HL
|
|
LD HL,(COMTB5) ; get BANK2 Common
|
|
LD (BCBKSZ),HL ; ..and store BIOS CSEG Banked size
|
|
ADD HL,DE ; add values
|
|
LD (BBKSZ_I),HL ; ..and store as BIOS Banked total size
|
|
CALL PB2ADR ; display addr's
|
|
LD HL,(COMTB7) ; get org RESVD Common
|
|
LD (BRSVDO),HL ; ..and store it
|
|
|
|
|
|
;----- Auto-size system segments
|
|
|
|
AUTOSZ: LD HL,(Z3ENV_I+63) ; get start addr CCP from ENV
|
|
LD (CNBADR),HL
|
|
LD HL,(Z3ENV_I+66) ; " DOS from ENV
|
|
LD (DNBADR),HL
|
|
LD HL,(Z3ENV_I+69) ; " BIOS from ENV
|
|
LD (BNBADR),HL
|
|
|
|
CALL VPRINT
|
|
DEFB CR,LF,'Auto-size system ([Y]/N)? : '
|
|
DEFB 0
|
|
CALL CAPIN ; get user input (capitalized)
|
|
CALL EXITRQ ; quit program ?
|
|
CALL YESNO ; get (Y)es/no input
|
|
CP 'N' ; entered 'N' ?
|
|
LD A,0FFH ; prepare indicator byte for 'Yes'
|
|
JR NZ,PRELINK ; ..if not 'N', skip over
|
|
XOR A ; else, clear A (indicator byte for 'No')
|
|
|
|
|
|
;----- Prelink BIOS
|
|
|
|
PRELINK: LD (AUTOSIZ),A ; ..and store indicator
|
|
CALL VPRINT
|
|
DEFB CR,LF,'-- Pre-linking Bios for Info --'
|
|
DEFB 0
|
|
LD HL,(Z3ENV_I+27) ; get addr Env Descriptor
|
|
LD (COMTB1),HL ; ..and store in org _ENV_ Common
|
|
LD HL,0
|
|
LD (COMTB0),HL ; set org _BIOS_ Common to zero
|
|
LD HL,(COMTB5) ; get BIOS BANK2 Common (= Banked CSEG size)
|
|
LD DE,(DBKSZ_I) ; DOS Banked size
|
|
ADD HL,DE ; add values
|
|
LD (COMTB5),HL ; ..and store as org BANK2 Common
|
|
; (BIOS Banked CSEG addr)
|
|
LD DE,(BCBKSZ) ; BIOS Banked CSEG size
|
|
ADD HL,DE ; add values
|
|
LD (COMTB6),HL ; ..and store as org B2RAM Common
|
|
; (BIOS Banked DSEG addr)
|
|
|
|
; prepare alt. registers for linking
|
|
; BC'= offset to add to CSEG, DE'= offset to add to DSEG
|
|
; ( HL'= dest. addr bitmap -- not used )
|
|
EXX
|
|
LD BC,(BNBAD_I) ; BIOS Non-banked addr
|
|
LD HL,(BCNBSZ) ; BIOS Non-banked CSEG size
|
|
ADD HL,BC ; calc Non-banked DSEG start
|
|
EX DE,HL ; ..keep in DE
|
|
EXX
|
|
|
|
CALL CODEND ; get addr WSPC
|
|
LD DE,0100H ; move beyond header (1 page)
|
|
ADD HL,DE
|
|
LD B,H
|
|
LD C,L ; ..store addr in BC
|
|
LD (LPHYADR),HL ; ..and in local var for link module
|
|
LD HL,(BNBSZ_I) ; get BIOS Non-banked size
|
|
ADD HL,BC ; calc BIOS phys. load location CSEG
|
|
LD (COMTB5+2),HL ; (in BANK2 Common)
|
|
LD DE,(BCBKSZ) ; get BIOS Banked CSEG addr
|
|
ADD HL,DE ; calc BIOS phys. load location DSEG
|
|
LD (COMTB6+2),HL ; (in B2RAM Common)
|
|
LD HL,(BCNBSZ) ; get BIOS Non-Banked CSEG size
|
|
ADD HL,BC ; add to dest. addr
|
|
LD DE,BIOSFCB ; ptr to BIOS FCB
|
|
|
|
; link file with BC= phys. addr CSEG, HL= phys. addr DSEG, DE= addr FCB
|
|
CALL LNKFILE
|
|
|
|
LD HL,(LPHYADR) ; get dest. addr (start of linked file)
|
|
LD DE,128 ; offset to OPTF1 (option flag)
|
|
ADD HL,DE ; in B/P Bios config area
|
|
LD A,(HL) ; get byte
|
|
LD (OPTF1),A ; store it
|
|
AND 00001000B ; mask bit 3 (ALV/CSV in TPA, or in bank)
|
|
LD (BNKDSYS),A ; store indicator
|
|
JR NZ,PRELNK0 ; ..if bit 3= 1 (in bank), skip over
|
|
CALL VPRINT ; else, display 'Non-Banked'
|
|
DEFB '(Non-Banked)'
|
|
DEFB 0
|
|
JR CALCSIZ
|
|
|
|
PRELNK0: CALL VPRINT
|
|
DEFB '(Banked)'
|
|
DEFB 0
|
|
|
|
|
|
;----- Calculate addr/size of System Segments
|
|
|
|
CALCSIZ: LD HL,(BNBSZ_I) ; get BIOS Non-banked size
|
|
LD DE,(BBKSZ_I) ; ..and Banked size
|
|
ADD HL,DE ; calc total size
|
|
LD C,L ; move in BC
|
|
LD B,H
|
|
LD HL,(LPHYADR) ; dest. addr
|
|
LD E,L ; in DE
|
|
LD D,H
|
|
INC DE ; move ptr fwd
|
|
LD (HL),0 ; ..and clear memory
|
|
LDIR
|
|
LD A,(AUTOSIZ) ; get indicator for auto-sizing
|
|
OR A ; check if zero (= no)
|
|
PUSH AF
|
|
CALL NZ,CALCASZ ; ..if auto-sizing, calc base addr's
|
|
; of Non-banked system segments
|
|
|
|
POP AF
|
|
JR Z,STNDSZ ; ..if no auto-sizing, jump to continue
|
|
LD HL,(CNBADR) ; CCP Non-banked start addr
|
|
LD (Z3ENV_I+63),HL ; write to ENV
|
|
EX DE,HL
|
|
LD HL,(DNBADR) ; start addr DOS
|
|
LD (Z3ENV_I+66),HL ; write to ENV
|
|
XOR A
|
|
SBC HL,DE ; calc CCP size (in bytes)
|
|
ADD HL,HL ; and convert to 128-byte records
|
|
LD A,H
|
|
LD (Z3ENV_I+65),A ; write # records to ENV
|
|
LD HL,(BNBADR) ; BIOS Non-banked start addr
|
|
LD (Z3ENV_I+69),HL ; write to ENV
|
|
LD DE,(Z3ENV_I+66) ; get start addr DOS
|
|
XOR A
|
|
SBC HL,DE ; calc DOS size (in bytes)
|
|
ADD HL,HL ; and convert to 128-byte records
|
|
LD A,H
|
|
LD (Z3ENV_I+68),A ; write # records to ENV
|
|
JR SIZDONE ; then, jump to continue
|
|
|
|
|
|
; Use Standard Sizes ?
|
|
STNDSZ: CALL VPRINT
|
|
DEFB CR,LF,'Set to "Standard" if possible? (Y/[N]) : '
|
|
DEFB 0
|
|
CALL CAPIN ; get user input
|
|
CALL EXITRQ ; quit program ?
|
|
CALL NOYES ; get yes/(N)o input
|
|
CP 'Y' ; is it 'Y' ?
|
|
CALL Z,CALCSSZ ; ..if so, set standard sizes for segments
|
|
|
|
|
|
;----- Sizing done - addr/size of Non-banked System Segments determined
|
|
|
|
SIZDONE: CALL PSYSNB ; display base addr's of system (Non-banked)
|
|
|
|
; transfer base addr's from ENV to IMG hdr
|
|
LD DE,(Z3ENV_I+69) ; base addr BIOS from ENV
|
|
LD (BNBAD_I),DE ; to IMG hdr
|
|
LD DE,(Z3ENV_I+66) ; base addr DOS from ENV
|
|
LD (DNBAD_I),DE
|
|
LD DE,(Z3ENV_I+63) ; base addr CCP from ENV
|
|
LD (CNBAD_I),DE
|
|
LD A,(OPTF1) ; get OPTF1 flag from linked BIOS
|
|
AND 00000001B ; mask bit 0 (0= unbanked, 1= banked Bios)
|
|
JR Z,ENV2COM
|
|
BIT 7,D ; check CCP base addr >32k
|
|
JP NZ,ENV2COM ; start addr of CCP in banked system must be above 32k
|
|
CALL VPRINT
|
|
DEFB CR,LF,BEL,'+++ CPR Starting Addr Too Low (<8000H) +++',CR,LF
|
|
DEFB 0
|
|
JP AUTOSZ ; loop, ask for auto-sizing
|
|
|
|
|
|
; Transfer addr's from Z3ENV to COMMON table (logical 'ORG')
|
|
ENV2COM: LD HL,(Z3ENV_I+27) ; addr Z3ENV (env. descriptor)
|
|
LD (COMTB1),HL ; org _ENV_ Common
|
|
LD HL,(Z3ENV_I+69) ; addr BIOS (start NZBIO)
|
|
LD (COMTB0),HL ; org _BIOS_ Common
|
|
LD HL,(Z3ENV_I+34) ; addr Z3MSG (msg buffer)
|
|
LD (COMTB2),HL ; org _MSG_ Common
|
|
LD HL,(Z3ENV_I+36) ; addr EXTFCB (external FCB)
|
|
LD (COMTB3),HL ; org _FCB_ Common
|
|
LD HL,(Z3ENV_I+24) ; addr Z3CL (cmd line buffer)
|
|
LD (COMTB4),HL ; org _MCL_ Common
|
|
LD HL,(Z3ENV_I+30) ; addr SHSTK (shell stack)
|
|
LD (COMTB8),HL ; org _SSTK_ Common
|
|
LD HL,(Z3ENV_I+38) ; addr EXTSTK (external stack)
|
|
LD (COMTB9),HL ; org _XSTK_ Common
|
|
|
|
; ##### CHECK: top of mem not used (HL immediately overwritten)
|
|
CALL GZMTOP
|
|
|
|
; init phys. load location addr's in COMMON table
|
|
LD HL,0080H
|
|
LD (COMTB0+2),HL
|
|
LD (COMTB1+2),HL
|
|
LD (COMTB2+2),HL
|
|
LD (COMTB3+2),HL
|
|
LD (COMTB4+2),HL
|
|
LD (COMTB7+2),HL
|
|
LD (COMTB8+2),HL
|
|
LD (COMTB9+2),HL
|
|
|
|
|
|
;----- Link files
|
|
|
|
; link CCP
|
|
LD HL,(CNBSZ_I) ; CCP Non-banked total size
|
|
; (make room for Non-banked CCP to..
|
|
; ..copy from SYS Bank to TPA Bank)
|
|
INC H ; +100H
|
|
LD (COMTB5),HL ; store as CCP Banked CSEG start (org BANK2 Common)
|
|
LD (CBKAD_I),HL ; ..and as CCP Banked base addr
|
|
EX DE,HL
|
|
LD HL,(CCBKSZ) ; CCP Banked CSEG addr
|
|
ADD HL,DE ; add to Banked base addr
|
|
LD (COMTB6),HL ; ..store as CCP Banked DSEG start (org B2RAM Common)
|
|
|
|
; ##### CHECK: obsolete? contents of HL and DE overwritten after EXX/EXX anyway
|
|
LD HL,(CBKSZ_I) ; CCP Banked total size
|
|
ADD HL,DE
|
|
|
|
; prepare alt. registers for linking
|
|
; BC'= offset to add to CSEG, DE'= offset to add to DSEG
|
|
; ( HL'= dest. addr bitmap -- not used )
|
|
EXX
|
|
LD BC,(CNBAD_I) ; CCP Non-banked base addr
|
|
LD HL,(CCNBSZ) ; CCP Non-banked CSEG size
|
|
ADD HL,BC ; add (= DSEG start)
|
|
EX DE,HL ; swap into DE
|
|
EXX
|
|
|
|
CALL CODEND ; get addr WSPC
|
|
LD DE,0100H ; move beyond header (1 page)
|
|
ADD HL,DE ; add (= destination)
|
|
LD C,L
|
|
LD B,H ; copy addr in BC
|
|
LD (LPHYADR),HL ; ..and store in var for link module
|
|
LD HL,(CNBSZ_I) ; CCP Non-banked total size
|
|
ADD HL,BC ; add to dest location
|
|
LD (COMTB5+2),HL ; ..set CCP Banked CSEG phys. load location
|
|
; (in BANK2 Common)
|
|
LD DE,(CCBKSZ) ; CCP Banked CSEG addr
|
|
ADD HL,DE ; add to dest
|
|
LD (COMTB6+2),HL ; ..set CCP Banked DSEG phys. load location
|
|
; (in B2RAM Common)
|
|
LD HL,COMTBL ; addr of COMMON's table
|
|
LD (LTBLADR),HL ; store in var for linker
|
|
LD HL,(CCNBSZ) ; CSEG size CCP unbanked
|
|
ADD HL,BC ; add (= dest DSEG)
|
|
LD DE,CCPFCB
|
|
|
|
; link file with BC= phys. addr CSEG, HL= phys. addr DSEG, DE= addr FCB
|
|
CALL LNKFILE
|
|
|
|
; link DOS
|
|
LD HL,(COMTB5) ; get org BANK2 Common (= CCP Banked base addr)
|
|
LD DE,(CBKSZ_I) ; CCP Banked total size
|
|
ADD HL,DE ; add
|
|
LD (COMTB5),HL ; ..store as DOS Banked CSEG addr (org BANK2 Common)
|
|
LD (DBKAD_I),HL ; ..and as DOS Banked base addr
|
|
LD DE,(DCBKSZ) ; DOS Banked CSEG size
|
|
ADD HL,DE ; add to base addr
|
|
LD (COMTB6),HL ; ..store as DOS Banked DSEG addr (org B2RAM Common)
|
|
|
|
; prepare alt. registers for linking
|
|
EXX
|
|
LD BC,(DNBAD_I) ; DOS Non-banked base addr
|
|
LD HL,(DCNBSZ) ; DOS Non-banked CSEG size
|
|
ADD HL,BC ; add (= DSEG start)
|
|
EX DE,HL ; swap into DE
|
|
EXX
|
|
|
|
LD BC,(LPHYADR) ; destination addr (WSPC + 0x100)
|
|
LD HL,(CNBSZ_I) ; CCP Non-banked total size
|
|
ADD HL,BC
|
|
LD DE,(CBKSZ_I) ; CCP Banked total size
|
|
ADD HL,DE
|
|
LD C,L
|
|
LD B,H ; new dest. addr in BC
|
|
LD (LPHYADR),HL ; ..and update var for link module
|
|
|
|
; ##### CHECK: already done when linking CCP - obsolete ?
|
|
LD HL,COMTBL ; addr of COMMON's table
|
|
LD (LTBLADR),HL ; store in var for linker
|
|
; ######
|
|
|
|
LD HL,(DNBSZ_I) ; DOS Non-banked total size
|
|
ADD HL,BC ; add to dest location
|
|
LD (COMTB5+2),HL ; ..set DOS Banked CSEG phys. load location
|
|
; (in BANK2 Common)
|
|
LD DE,(DCBKSZ) ; DOS Banked CSEG size
|
|
ADD HL,DE ; add to dest
|
|
LD (COMTB6+2),HL ; ..set DOS Banked DSEG phys. load location
|
|
; (in B2RAM Common)
|
|
LD HL,(DCNBSZ) ; DOS Non-banked CSEG size
|
|
ADD HL,BC ; add (= dest DSEG)
|
|
LD DE,DOSFCB
|
|
|
|
; link file with BC= phys. addr CSEG, HL= phys. addr DSEG, DE= addr FCB
|
|
CALL LNKFILE
|
|
|
|
; link BIOS
|
|
LD HL,(COMTB5) ; get org BANK2 Common (= DOS Banked base addr)
|
|
LD DE,(DBKSZ_I) ; DOS Banked total size
|
|
ADD HL,DE ; add
|
|
LD (COMTB5),HL ; ..store as BIOS Banked CSEG addr (org BANK2 Common)
|
|
LD (BBKAD_I),HL ; ..and as BIOS Banked base addr
|
|
LD DE,(BCBKSZ) ; BIOS Banked CSEG size
|
|
ADD HL,DE ; add to base addr
|
|
LD (COMTB6),HL ; ..store as BIOS Banked DSEG addr (org B2RAM Common)
|
|
|
|
; prepare alt. registers for linking
|
|
EXX
|
|
LD BC,(BNBAD_I) ; BIOS Non-banked base addr
|
|
LD HL,(BCNBSZ) ; BIOS Non-banked CSEG size
|
|
ADD HL,BC ; add (= DSEG start)
|
|
EX DE,HL ; swap into DE
|
|
EXX
|
|
|
|
LD BC,(LPHYADR) ; destination addr (begin DOS)
|
|
LD HL,(DNBSZ_I) ; DOS Non-banked total size
|
|
ADD HL,BC
|
|
LD DE,(DBKSZ_I) ; DOS Banked total size
|
|
ADD HL,DE
|
|
LD C,L
|
|
LD B,H ; new dest. addr in BC
|
|
LD (LPHYADR),HL ; ..and update var for link module
|
|
LD HL,(BNBSZ_I) ; BIOS Non-banked total size
|
|
ADD HL,BC ; add to dest location
|
|
LD (COMTB5+2),HL ; ..set BIOS Banked CSEG phys. load location
|
|
; (in BANK2 Common)
|
|
LD DE,(BCBKSZ) ; BIOS Banked CSEG size
|
|
ADD HL,DE ; add to dest
|
|
LD (COMTB6+2),HL ; ..set BIOS Banked DSEG phys. load location
|
|
; (in B2RAM Common)
|
|
LD DE,(BDBKSZ) ; BIOS Banked DSEG size
|
|
ADD HL,DE ; add (= end addr in WSPC)
|
|
LD (SYSEADR),HL ; ..and store in var
|
|
LD HL,(BCNBSZ) ; BIOS Non-Banked CSEG size
|
|
ADD HL,BC ; add (= dest DSEG)
|
|
LD DE,BIOSFCB
|
|
|
|
; link file with BC= phys. addr CSEG, HL= phys. addr DSEG, DE= addr FCB
|
|
CALL LNKFILE
|
|
|
|
;----- Link finished
|
|
|
|
LD DE,(SYSEADR) ; end addr of linked system in WSPC
|
|
CALL CODEND ; addr start of WSPC
|
|
EX DE,HL
|
|
XOR A
|
|
SBC HL,DE ; calc length in bytes
|
|
CALL ALIGN ; ..and align to next sector boundary
|
|
|
|
; divide by 8 (dump lower bits 6..0)
|
|
LD A,L ; move low byte to A
|
|
LD L,H ; move high byte to L
|
|
LD H,0 ; and dump high byte
|
|
RLC A ; rotate MSB to C-Flag
|
|
ADC HL,HL ; double HL plus C-Flag
|
|
LD (SYSBLKS),HL ; ..store system length (in blocks) in var
|
|
PUSH HL
|
|
CALL UPDINFO ; update 'k Bios' info
|
|
POP HL
|
|
|
|
CALL VPRINT
|
|
DEFB CR,LF,' Total '
|
|
DEFB 0
|
|
LD DE,IMGFCB+1 ; ptr to IMG file name
|
|
CALL PFN3 ; ..display it
|
|
CALL VPRINT
|
|
DEFB ' size = '
|
|
DEFB 0
|
|
CALL PHL4HC
|
|
CALL VPRINT
|
|
DEFB 'H sectors',CR,LF
|
|
DEFB 0
|
|
|
|
|
|
;----- Update Z3ENV <---> B/P Bios (vice versa)
|
|
|
|
LD DE,(LPHYADR) ; get last dest. addr (BIOS)
|
|
LD HL,152 ; offset to Env. Descriptor (CONFIG+26)
|
|
ADD HL,DE ; move ptr fwd
|
|
LD BC,(Z3ENV_I+27) ; addr Z3ENV (env. descriptor)
|
|
LD (HL),C ; ..store actual addr Z3ENV
|
|
INC HL
|
|
LD (HL),B
|
|
LD BC,4
|
|
ADD HL,BC ; move ptr to CPU Clock Rate (CONFIG+31)
|
|
LD A,(HL) ; get value
|
|
LD (Z3ENV_I+43),A ; ..and store in ENV
|
|
LD HL,67 ; offset to BIOS fn #22 (get addr DRVTBL)
|
|
ADD HL,DE ; move ptr forward
|
|
LD A,(HL)
|
|
INC HL
|
|
LD H,(HL) ; get addr of fn call in HL
|
|
LD L,A
|
|
LD BC,(BNBAD_I) ; BIOS Non-banked base addr in BC
|
|
OR A
|
|
SBC HL,BC ; ..calc difference
|
|
ADD HL,DE ; ..set ptr to start of fn in WSPC memory
|
|
INC HL ; move ptr beyond opcode 0x21 (LD HL,nnnn)
|
|
LD A,(HL)
|
|
INC HL
|
|
LD H,(HL) ; addr of drive table in HL
|
|
LD L,A
|
|
OR A
|
|
SBC HL,BC ; calc diff to BIOS base addr
|
|
ADD HL,DE ; ..and set ptr to location in WSPC memory
|
|
LD B,16 ; counter (16 drives, A..P)
|
|
LD DE,0
|
|
DEC HL ; prior to loop, set ptr back
|
|
|
|
; create bit mask for drive vector
|
|
MKDRVEC: INC HL
|
|
LD A,(HL) ; check if high byte
|
|
INC HL
|
|
OR (HL) ; .and low byte are zero
|
|
JR Z,MKDRVE0 ; ..if so, skip drive
|
|
SCF ; else, set C-Flag for existing byte
|
|
MKDRVE0: RR D ; and rotate bit into position
|
|
RR E
|
|
DJNZ MKDRVEC ; loop till done
|
|
LD (Z3ENV_I+52),DE ; set DRVEC (drive vector)
|
|
LD HL,(UNBAD_I)
|
|
LD (Z3ENV_I+60),HL ; set USRSP addr (resident user space)
|
|
LD A,(UNBSZ_I)
|
|
LD (Z3ENV_I+59),A ; set remaining user space
|
|
LD (Z3ENV_I+62),A ; ..and size of user space
|
|
|
|
|
|
;----- Write IMG file to disk
|
|
|
|
; copy IMG header to workspace (0x100 bytes before linked new system)
|
|
CALL CODEND ; get addr WSPC
|
|
EX DE,HL ; dest in DE
|
|
LD HL,IMGHD_I ; src addr (IMG hdr) in HL
|
|
LD BC,0100H ; bytes to copy
|
|
LDIR
|
|
|
|
; save file
|
|
LD BC,(SYSBLKS) ; # of sectors to write
|
|
CALL CODEND ; addr WSPC
|
|
CALL WRFILE ; write IMG file
|
|
JP NC,EXIT ; ..if ok, jump and exit program
|
|
CALL VPRINT
|
|
DEFB CR,LF,'..Error Writing output file..',BEL,CR,LF
|
|
DEFB 0
|
|
JP EXIT
|
|
|
|
|
|
;::::: SUPPORT FUNCTIONS
|
|
|
|
; check if user requested to abort program (<ESC> or <Ctrl-C> entered)
|
|
; in: A= char
|
|
EXITRQ: CP ESC ; is it <ESC> ?
|
|
JR Z,EXITRQ0 ; ..if so, jump forward and abort
|
|
CP CTRLC ; <Ctrl-C> ?
|
|
RET NZ ; ..if not, return
|
|
; else, fall through and abort
|
|
EXITRQ0: CALL CRLF
|
|
|
|
M$ABORT: CALL VPRINT
|
|
DEFB ' ...aborting...',CR,LF
|
|
DEFB 0
|
|
JP EXIT
|
|
|
|
|
|
;::::: HELP SCREEN
|
|
|
|
HELP: CALL VPRINT
|
|
DEFB CR,LF,1
|
|
DEFB 0
|
|
CALL PRGNAME
|
|
CALL VPRINT
|
|
DEFB 2,' builds banked and non-banked parts of a B/P Bios.',CR,LF
|
|
DEFB ' It operates with layered Menus and supports tailoring of defaults.',CR,LF
|
|
DEFB ' Starting locations of BIOS, DOS and CPR may be automatically computed',CR,LF
|
|
DEFB ' or Specified. If ZSDOS2 is the selected Dos, Bit Allocation buffers',CR,LF
|
|
DEFB ' for Hard Drives are located in the System Bank.',CR,LF,LF
|
|
DEFB 'Syntax:',CR,LF,' '
|
|
DEFB 0
|
|
CALL PRGNAME
|
|
CALL VPRINT
|
|
DEFB ' - Generate system w/defaults',CR,LF,' '
|
|
DEFB 0
|
|
CALL PRGNAME
|
|
CALL VPRINT
|
|
DEFB ' fn[.ft] - Make/Modify a specific system',CR,LF
|
|
DEFB ' (Default type is .IMG)',CR,LF
|
|
DEFB ' '
|
|
DEFB 0
|
|
CALL PRGNAME
|
|
CALL VPRINT
|
|
DEFB ' // - Display this Message',CR,LF
|
|
DEFB 0
|
|
|
|
|
|
;::::: EXIT PROGRAM
|
|
|
|
EXIT: LD SP,(STACK) ; restore stackpointer
|
|
CALL DINIT ; de-init terminal characteristics
|
|
LD BC,(OLDDU)
|
|
CALL PUTUD ; log initial Drive/User
|
|
RET
|
|
|
|
|
|
; display main menu
|
|
M0SHOW: CALL CLS
|
|
CALL VPRINT
|
|
DEFB CR,LF,1,' Main ',2,CR,LF,CR,LF,LF
|
|
DEFB TAB,1,' 1 ',2,' File Names',CR,LF,LF
|
|
DEFB TAB,1,' 2 ',2,' BIOS Configuration',CR,LF,LF
|
|
DEFB TAB,1,' 3 ',2,' Environment'
|
|
DEFB 0
|
|
RET
|
|
|
|
|
|
;::::: MENU 1 - FILES
|
|
|
|
M1FILE: CALL CLS
|
|
CALL VPRINT
|
|
DEFB CR,LF,1,' Files (1.1) ',2,CR,LF,CR,LF,LF
|
|
DEFB TAB,1,' 1 ',2,' Command Processor File : '
|
|
DEFB 0
|
|
LD DE,CCPFCB+1 ; ptr file name in CCP FCB
|
|
CALL PFN1 ; ..display file name + type
|
|
CALL VPRINT
|
|
DEFB CR,LF,LF,TAB,1,' 2 ',2,' Operating System File : '
|
|
DEFB 0
|
|
LD DE,DOSFCB+1 ; ptr file name in DOS FCB
|
|
CALL PFN1
|
|
CALL VPRINT
|
|
DEFB CR,LF,LF,TAB,1,' 3 ',2,' B/P Bios Source File : '
|
|
DEFB 0
|
|
LD DE,BIOSFCB+1 ; ptr file name in BIOS FCB
|
|
CALL PFN1
|
|
CALL VPRINT
|
|
DEFB CR,LF,LF,TAB,1,' 4 ',2,' B/P Executable Image : '
|
|
DEFB 0
|
|
LD DE,IMGFCB+1 ; ptr file name in IMG FCB
|
|
CALL PFN1
|
|
|
|
CALL MSELECT ; get user input
|
|
CP ' ' ; is it <SP> ?
|
|
RET Z ; ..return
|
|
CP CR ; <CR> ?
|
|
RET Z ; ..return
|
|
CP ESC ; <ESC> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
CP CTRLC ; <Ctrl-C> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
CP '4'+1 ; is it above '4' ?
|
|
JP NC,M1FILE ; ..if so, display Files menu again
|
|
; else, fall through
|
|
LD DE,CCPFCB
|
|
LD HL,CFNAM_I ; ZCPR FCB+name ptr's
|
|
CP '1' ; option '1' ?
|
|
JR Z,M1FNAME ; ..if so, jump to continue
|
|
LD DE,DOSFCB
|
|
LD HL,DFNAM_I ; ZSDOS FCB+name ptr's
|
|
CP '2' ; option '2' ?
|
|
JR Z,M1FNAME ; ..if so, jump to continue
|
|
LD DE,BIOSFCB
|
|
LD HL,BFNAM_I ; B/P Bios FCB+name ptr's
|
|
CP '3' ; option '3' ?
|
|
JR Z,M1FNAME ; ..if so, jump to continue
|
|
LD DE,IMGFCB ; else, set IMG FCB+name ptr's
|
|
LD HL,IMGFN_I ; ..and fall through
|
|
|
|
; enter file name
|
|
M1FNAME: LD (MSELOPT),A ; store selected option
|
|
PUSH HL ; save HL regs
|
|
CALL VPRINT
|
|
DEFB CR,LF,TAB,TAB,' FileName[.Typ] : '
|
|
DEFB 0
|
|
CALL CINPUTL ; get user input (line editor)
|
|
PUSH DE
|
|
LD DE,CPMFCB ; ptr to standard FCB #1
|
|
CALL INITFCB ; init FCB
|
|
CALL ZFNAME ; ..and parse user input as fn/ft into FCB
|
|
POP DE ; restore regs
|
|
POP HL
|
|
OR A ; check if file name is unambiguous
|
|
JR Z,M1FCB ; ..if so, jump to continue
|
|
|
|
; error, file name invalid
|
|
M1FNERR: LD A,BEL ; else, send <BEL> to CON:
|
|
CALL COUT
|
|
JP M1FILE ; ..and loop, ask for new input
|
|
|
|
; file name ok, init FCB
|
|
M1FCB: LD A,(CPMFCB+1) ; check first char of file name
|
|
CP ' ' ; is it <SP> ?
|
|
JR Z,M1FNERR ; ..if so, file name is invalid
|
|
; jump, alert and ask for new input
|
|
PUSH HL ; save regs
|
|
LD A,(CPMFCB+9) ; get first char of file type
|
|
CP ' ' ; is it <SP> ?
|
|
JR NZ,M1FCB1 ; ..if not, jump to continue
|
|
LD A,(MSELOPT) ; get selected menu option (to set file type)
|
|
PUSH DE
|
|
LD DE,CPMFCB+9
|
|
LD BC,3 ; bytes to copy
|
|
LD HL,FTYPES+3 ; prepare ptr for .IMG file type
|
|
CP '4' ; was option '4' (image file) selected ?
|
|
JR Z,M1FCB0 ; ..if so, jump to continue
|
|
LD HL,FTYPES+6 ; prepare ptr for .REL file type
|
|
CP '3' ; was option '3' (B/P Bios file) selected ?
|
|
JR Z,M1FCB0 ; ..if so, jump to continue
|
|
LD HL,FTYPES+9 ; else, set ptr to .ZRL file type
|
|
|
|
M1FCB0: LDIR ; ..and copy
|
|
POP DE ; DE= ptr to respective FCB in temp area
|
|
; (Stack)= ptr to file name in IMG file header area
|
|
M1FCB1: LD HL,CPMFCB ; ptr to standard FCB #1
|
|
LD BC,15 ; copy 15 bytes to FCB in temp area
|
|
LDIR
|
|
POP DE
|
|
LD HL,CPMFCB+1 ; ptr to file name in standard FCB #1
|
|
LD BC,11 ; copy 11 bytes (fn.ft) to IMG file hdr
|
|
LDIR
|
|
JP M1FILE ; ..and loop
|
|
|
|
|
|
;::::: MENU 2 - BIOS CONFIG
|
|
|
|
M2BIOS: CALL CLS
|
|
CALL VPRINT
|
|
DEFB 1,' Environment (2.1) ',2
|
|
DEFB 0
|
|
CALL GXYMSG ; display w/ positioning
|
|
DEFB 3,3,'COMMON (Bank 0) MEMORY BANK 2 MEMORY'
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 4,2,'---------------------- ------------------------'
|
|
DEFB 0
|
|
CALL GXYMSG ; col 2 (on the left)
|
|
DEFB 5,2,1,' A ',2,' Common BIOS - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 6,2,' Size - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 7,2,1,' B ',2,' Common BDOS - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 8,2,' Size - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 9,2,1,' C ',2,' Command Proc - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 10,2,' Size - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 11,2,1,' D ',2,' User Space - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 12,2,' Size - '
|
|
DEFB 0
|
|
CALL GXYMSG ; col 34 (on the right)
|
|
DEFB 5,34,1,' E ',2,' Banked BIOS - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 6,34,' Size - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 7,34,1,' F ',2,' Banked BDOS - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 8,34,' Size - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 9,34,1,' G ',2,' Command Proc - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 10,34,' Size - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 11,34,1,' H ',2,' User Space - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 12,34,' Size - '
|
|
DEFB 0
|
|
|
|
; display BIOS addr and size
|
|
LD HL,0516H ; row 5 / col 22
|
|
CALL GOTOXY ; position cursor
|
|
LD HL,(Z3ENV_I+69) ; ptr to start addr BIOS in ENV
|
|
CALL PHLXH ; display as hex + 'H'
|
|
EX DE,HL ; keep value
|
|
LD HL,0616H ; row 6 / col 22
|
|
CALL GOTOXY
|
|
PUSH DE
|
|
CALL ENVLOW ; lowest addr of ENV component in HL
|
|
POP DE
|
|
LD BC,(UNBAD_I) ; get addr User Space in IMG hdr
|
|
LD A,B ; check if invalid (= zero)
|
|
OR C
|
|
CALL NZ,MINHLBC ; ..if not, get the lower of both addr's in HL
|
|
OR A
|
|
SBC HL,DE ; calc size [lowest ENV] - [start addr BIOS]
|
|
ADD HL,HL ; *2
|
|
LD A,L ; check for page boundary
|
|
OR A ; (low byte = zero)
|
|
JR Z,M2ADRSZ ; ..if so, skip over
|
|
INC H ; else, increase before displaying
|
|
|
|
; display addr and size of other system segments
|
|
M2ADRSZ: LD A,H
|
|
CALL PSPCAD ; display <SP> + value as dec (size high byte)
|
|
LD HL,0716H ; row 7 / col 22
|
|
LD DE,Z3ENV_I+66 ; ptr start addr DOS in Z3ENV
|
|
CALL PSEGXY ; print Segment addr/size at coordinates
|
|
LD HL,0916H ; row 9 / col 22
|
|
LD DE,Z3ENV_I+63 ; ..start addr ZCPR in Z3ENV
|
|
CALL PSEGXY
|
|
LD HL,0B16H ; row 11 / col 22
|
|
LD DE,UNBAD_I ; ..addr User Space in IMG hdr
|
|
CALL PSEGXY
|
|
LD HL,0536H ; row 5 / col 54
|
|
LD DE,BBKAD_I ; ..base addr BIOS Banked in IMG hdr
|
|
CALL PSEGXY
|
|
LD HL,0736H ; row 7 / col 54
|
|
LD DE,DBKAD_I ; ..base addr DOS Banked in IMG hdr
|
|
CALL PSEGXY
|
|
LD HL,0936H ; row 9 / col 54
|
|
LD DE,CBKAD_I ; ..base addr ZCPR Banked in IMG hdr
|
|
CALL PSEGXY
|
|
LD HL,0B36H ; row 11 / col 54
|
|
LD DE,UBKAD_I ; ..addr User Space Banked (RESVD ??) in IMG hdr
|
|
CALL PSEGXY
|
|
|
|
; select option from Menu 2 Bios Config
|
|
M2SELCT: CALL MSELECT ; get user input
|
|
CP ' ' ; is it <SP> ?
|
|
RET Z ; ..return
|
|
CP CR ; <CR> ?
|
|
RET Z ; ..return
|
|
CP ESC ; <ESC> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
CP CTRLC ; <Ctrl-C> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
|
|
LD HL,Z3ENV_I+69
|
|
CP 'A' ; 'A' (Common Bios) ?
|
|
JR Z,M2EXEC
|
|
LD HL,Z3ENV_I+66
|
|
CP 'B' ; 'B' (Common BDOS) ?
|
|
JR Z,M2EXEC
|
|
LD HL,Z3ENV_I+63
|
|
CP 'C' ; 'C' (Common ZCPR) ?
|
|
JR Z,M2EXEC
|
|
LD HL,UNBAD_I
|
|
CP 'D' ; 'D' (Common User Space) ?
|
|
JR Z,M2EXEC
|
|
LD HL,BBKAD_I
|
|
CP 'E' ; 'E' (Banked Bios) ?
|
|
JR Z,M2EXEC
|
|
LD HL,DBKAD_I
|
|
CP 'F' ; 'F' (Banked BDOS) ?
|
|
JR Z,M2EXEC
|
|
LD HL,CBKAD_I
|
|
CP 'G' ; 'G' (Banked ZCPR) ?
|
|
JR Z,M2EXEC
|
|
LD HL,UBKAD_I
|
|
CP 'H' ; 'H' (Banked User Space) ?
|
|
|
|
JR NZ,M2SELCT
|
|
|
|
M2EXEC: CALL PHLXSIZ ; execute selected option (display addr and size,
|
|
; ask for new values, convert)
|
|
JP M2BIOS ; ..then loop, display again
|
|
|
|
|
|
;::::: SUPPORT FUNCTIONS (Menu 2 - Bios Config)
|
|
|
|
; return the lower of HL and BC ("min" function)
|
|
; in: BC, HL = values to compare
|
|
; out: HL= the lower of both values
|
|
MINHLBC: LD A,H ; test high byte first
|
|
SUB B
|
|
RET C ; if borrowed from C-Flag, return (HL < BC)
|
|
JR NZ,MINHLB0 ; if delta <> zero, jump (HL > BC)
|
|
LD A,L ; ..else, test low byte too
|
|
SUB C
|
|
RET C ; if borrowed from C-Flag, return (BC > HL)
|
|
MINHLB0: LD L,C ; ..else, copy contents of BC into HL
|
|
LD H,B
|
|
RET
|
|
|
|
|
|
;::::: MENU 3 - ENVIRONMENT
|
|
|
|
M3ENV: CALL CLS
|
|
CALL VPRINT
|
|
DEFB 1,' Environment (3.1) ',2
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 3,2,1,' A ',2,' - Environment - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 4,2,' Size (# recs)- '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 5,2,1,' B ',2,' - Flow Ctrl Pkg - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 6,2,' Size (# recs)- '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 7,2,1,' C ',2,' - I/O Package - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 8,2,' Size (# recs)- '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 9,2,1,' D ',2,' - Res Cmd Proc - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 10,2,' Size (# recs)- '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 11,2,1,' E ',2,' - Command Line - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 12,2,' Size (bytes) - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 3,34,1,' F ',2,' - Named Dirs - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 4,34,' # of Entries - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 5,34,1,' G ',2,' - External Path - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 6,34,' # of Entries - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 7,34,1,' H ',2,' - Shell Stack - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 8,34,' # of Entries - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 9,34,' Entry Size - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 10,34,1,' I ',2,' - Msg Buffer - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 11,34,1,' J ',2,' - Ext. FCB - '
|
|
DEFB 0
|
|
CALL GXYMSG
|
|
DEFB 12,34,1,' K ',2,' - Ext. Stack - '
|
|
DEFB 0
|
|
|
|
; display addr and size of ENV components
|
|
; stored as <addr> (16-bit) <size/count> (8-bit)
|
|
LD HL,0318H ; row 3 / col 24
|
|
LD DE,Z3ENV_I+27 ; ptr addr Z3ENV (ZCPR3 Environment Descriptor)
|
|
CALL PSEGXY ; print Segement addr/size at coordinates
|
|
LD HL,0518H ; row 5 / col 24
|
|
LD DE,Z3ENV_I+18 ; ptr addr FCP (Flow Cmd Pkg)
|
|
CALL PSEGXY
|
|
LD HL,0718H ; row 7 / col 24
|
|
LD DE,Z3ENV_I+15 ; ptr addr IOP (I/O Pkg)
|
|
CALL PSEGXY
|
|
LD HL,0918H ; row 9 / col 24
|
|
LD DE,Z3ENV_I+12 ; ptr addr RCP (Resident Cmd Pkg)
|
|
CALL PSEGXY
|
|
LD HL,0B18H ; row 11 / col 24
|
|
LD DE,Z3ENV_I+24 ; ptr addr Z3CL (ZCPR3 cmd line buffer)
|
|
CALL PSEGXY
|
|
LD HL,0339H ; row 3 / col 57
|
|
LD DE,Z3ENV_I+21 ; ptr addr Z3NDIR (named dir buffer)
|
|
CALL PSEGXY
|
|
LD HL,0539H ; row 5 / col 57
|
|
LD DE,Z3ENV_I+9 ; ptr addr EXPATH (external path)
|
|
CALL PSEGXY
|
|
LD HL,0739H ; row 7 / col 57
|
|
LD DE,Z3ENV_I+30 ; ptr addr SHSTK (shell stack)
|
|
CALL PSEGXY
|
|
|
|
; single value entries (8-bit or 16-bit)
|
|
LD HL,0939H ; row 9 / col 57
|
|
CALL GOTOXY
|
|
LD A,(Z3ENV_I+33) ; SHSIZE (size of a shell stack entry)
|
|
CALL PSPCAD ; display <SP> + value as dec
|
|
LD HL,0A39H ; row 10 / col 57
|
|
CALL GOTOXY
|
|
LD HL,(Z3ENV_I+34) ; addr Z3MSG (ZCPR3 message buffer)
|
|
CALL PHLXH ; display as hex + 'H'
|
|
LD HL,0B39H ; row 11 / col 57
|
|
CALL GOTOXY
|
|
LD HL,(Z3ENV_I+36) ; addr EXTFCB (external File Control Block)
|
|
CALL PHLXH
|
|
LD HL,0C39H ; row 12 / col 57
|
|
CALL GOTOXY
|
|
LD HL,(Z3ENV_I+38) ; addr EXTSTK (external stack)
|
|
CALL PHLXH
|
|
|
|
M3SELCT: CALL MSELECT
|
|
CP ' ' ; is it <SP> ?
|
|
RET Z ; ..return
|
|
CP CR ; <CR> ?
|
|
RET Z ; ..return
|
|
CP ESC ; <ESC> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
CP CTRLC ; <Ctrl-C> ?
|
|
JP Z,M$ABORT ; ..quit program
|
|
CP 'A' ; 'A' (ENV) ?
|
|
JR C,M3SELCT ; ..if below ascii 'A', loop ask for new input
|
|
|
|
LD HL,Z3ENV_I+27 ; ptr to addr of ZCPR3 Env Descriptor
|
|
JR Z,M3EXEC1
|
|
LD HL,Z3ENV_I+18 ; ..of FCP
|
|
CP 'B'
|
|
JR Z,M3EXEC1
|
|
LD HL,Z3ENV_I+15 ; ..of IOP
|
|
CP 'C'
|
|
JR Z,M3EXEC1
|
|
LD HL,Z3ENV_I+12 ; ..of RCP
|
|
CP 'D'
|
|
JR Z,M3EXEC1
|
|
LD HL,Z3ENV_I+24 ; ..of Z3CL (cmd line buffer)
|
|
CP 'E'
|
|
JR Z,M3EXEC1
|
|
LD HL,Z3ENV_I+21 ; ..of Z3NDIR (named dir buffer)
|
|
CP 'F'
|
|
JR Z,M3EXEC2
|
|
LD HL,Z3ENV_I+9 ; ..of EXPATH (external path)
|
|
CP 'G'
|
|
JR Z,M3EXEC2
|
|
LD HL,Z3ENV_I+30 ; ..of SHSTK
|
|
CP 'H'
|
|
JR Z,M3EXEC4
|
|
LD HL,Z3ENV_I+34 ; ..of Z3MSG (msg buffer)
|
|
CP 'I'
|
|
JR Z,M3EXEC3
|
|
LD HL,Z3ENV_I+36 ; ..of EXTFCB
|
|
CP 'J'
|
|
JR Z,M3EXEC3
|
|
LD HL,Z3ENV_I+38 ; ..of EXTSTK
|
|
CP 'K'
|
|
JR Z,M3EXEC3
|
|
|
|
JP M3ENV
|
|
|
|
|
|
; ##### CHECK: redundant JR C loop in case of error,
|
|
; because called routines handle errors
|
|
M3EXEC1: CALL PHLXSIZ ; print addr and size + get input (converted)
|
|
JR C,M3EXEC1
|
|
M3EXEC: JP M3ENV ; ..and loop
|
|
|
|
M3EXEC2: CALL PHLXENT ; print addr and # entries + get input (converted)
|
|
JR C,M3EXEC2
|
|
JR M3EXEC
|
|
|
|
M3EXEC3: CALL PHLXCIN ; print (only) addr + get input (converted)
|
|
JR C,M3EXEC3
|
|
JR M3EXEC
|
|
|
|
M3EXEC4: CALL PADENSZ ; print addr, # entries, and size + get input (converted)
|
|
JR C,M3EXEC4
|
|
JR M3EXEC
|
|
|
|
|
|
;::::: SUPPORT FUNCTIONS (all Menus)
|
|
|
|
; select an option from menu (validate user input)
|
|
MSELECT: CALL VPRINT
|
|
DEFB CR,LF,LF
|
|
DEFB 0
|
|
MSELCT0: CALL VPRINT
|
|
DEFB CR,TAB,TAB,'Selection : '
|
|
DEFB 0
|
|
CALL EREOL ; clear end of line
|
|
CALL CAPIN ; get input and capitalize it
|
|
CP ' ' ; is it <SP> ?
|
|
RET Z ; ..return
|
|
CP CR ; <CR> ?
|
|
RET Z ; ..return
|
|
CP ESC ; <ESC> ?
|
|
RET Z ; ..return
|
|
CP CTRLC ; <Ctrl-C> ?
|
|
RET Z ; ..return
|
|
CP '0' ; is it a control char (below ascii '0') ?
|
|
JR C,MSELCT0 ; ..then loop and ask for new input
|
|
CP '9'+1 ; is it an ascii number ?
|
|
JR C,MSELCT1 ; ..if so, jump to display
|
|
CP 'A' ; is it below ascii 'A' ?
|
|
JR C,MSELCT0 ; ..then loop and ask for new input
|
|
CP 'Z'+1 ; is it above ascii 'Z' ?
|
|
JR NC,MSELCT0 ; ..then loop and ask for new input
|
|
MSELCT1: JP COUT ; display on CON: and let return from there
|
|
|
|
|
|
; validate input for (Y)/N query, and echo
|
|
; Yes is default
|
|
; in: A= char (capitalized)
|
|
YESNO: CP 'N' ; is it 'N' ?
|
|
JR Z,YESNO0 ; ..if so, skip over
|
|
LD A,'Y' ; else, set 'Y' for any other char
|
|
YESNO0: JP COUT ; print on CON: and let return from there
|
|
|
|
; validate input for Y/(N) query, and echo
|
|
; No is default
|
|
; in: A= char (capitalized)
|
|
NOYES: CP 'Y' ; is it 'Y' ?
|
|
JR Z,YESNO0 ; ..if so, jump to display
|
|
LD A,'N' ; else, set 'N' for any other char
|
|
JR YESNO0 ; and jump to display
|
|
|
|
|
|
; determine CSEG and DSEG sizes of linked file
|
|
; (SLINK0 linker module provides a dedicated sizing function)
|
|
; in: DE= ptr FCB
|
|
; HL= addr COMTBL
|
|
; out: BC= DSEG size
|
|
; HL= CSEG size
|
|
LNKDSZ: LD (LFCBADR),DE ; store addr of FCB
|
|
LD (LTBLADR),HL ; store addr of COMMON table
|
|
PUSH DE
|
|
INC DE
|
|
CALL PFN1 ; display file name
|
|
POP DE
|
|
CALL INITFCB ; init FCB
|
|
CALL F$EXIST ; check if file exists
|
|
OR A
|
|
JP Z,E$NFND ; ..if not, jump and let return from there
|
|
CALL INITFCB ; init FCB
|
|
CALL F$OPEN ; open file
|
|
OR A
|
|
JP NZ,E$OPEN ; ..if error, jump and let return from there
|
|
LD A,128
|
|
LD (LBYTPOS),A ; set byte pos for @GBYTE function (= initiate load)
|
|
XOR A ; clear A (= just sizing info)
|
|
LD HL,(LTBLADR) ; set ptr COMMON table
|
|
|
|
CALL LINK
|
|
|
|
OR A ; check error status
|
|
JP NZ,E$LINK ; ..if not ok, jump
|
|
PUSH BC ; save DSEG size
|
|
PUSH DE ; save CSEG size
|
|
PUSH BC
|
|
PUSH DE
|
|
LD DE,(LFCBADR) ; get FCB addr
|
|
CALL F$CLOSE ; close file
|
|
CALL VPRINT
|
|
DEFB ' - CSEG='
|
|
DEFB 0
|
|
POP HL ; restore CSEG size
|
|
CALL PHL4HC ; ..and display as hex
|
|
CALL VPRINT
|
|
DEFB 'H, DSEG='
|
|
DEFB 0
|
|
POP HL ; restore DSEG size
|
|
CALL PHL4HC ; ..and display as hex
|
|
CALL VPRINT
|
|
DEFB 'H',CR,LF
|
|
DEFB 0
|
|
POP HL ; restore CSEG size in HL
|
|
POP BC ; restore DSEG size in BC
|
|
RET
|
|
|
|
|
|
; print addr's of BANK2 and B2RAM Common
|
|
PB2ADR: LD HL,(COMTB6) ; get org B2RAM Common
|
|
LD A,H ; check if zero
|
|
OR L
|
|
LD HL,(COMTB5) ; prepare, and get org BANK2 Common
|
|
JR NZ,PB2ADR0 ; ..if addr <> zero, jump to continue
|
|
LD A,H ; else, check org BANK2 Common
|
|
OR L ; if also zero
|
|
RET Z ; ..if so, return
|
|
; else, fall through and print
|
|
PB2ADR0: CALL VPRINT
|
|
DEFB ' Bank2='
|
|
DEFB 0
|
|
LD HL,(COMTB5) ; get org BANK2 Common
|
|
CALL PHL4HC
|
|
CALL VPRINT
|
|
DEFB 'H B2Ram='
|
|
DEFB 0
|
|
LD HL,(COMTB6) ; get org B2RAM Common
|
|
CALL PHL4HC
|
|
CALL VPRINT
|
|
DEFB 'H',CR,LF
|
|
DEFB 0
|
|
RET
|
|
|
|
|
|
; Standard sizes - calculate base addr's of system segments Non-banked
|
|
; in: -
|
|
; out: - (addr's in ram storage locations)
|
|
CALCSSZ: LD DE,(CNBSZ_I) ; compare CCP Non-banked size
|
|
LD HL,0800H ; with CP/M standard 2.0 kB
|
|
OR A
|
|
SBC HL,DE
|
|
JR C,E$LARGE ; ..if too large, jump error
|
|
LD DE,(DNBSZ_I) ; compare DOS Non-banked size
|
|
LD HL,0E00H ; with CP/M standard 3.5 kB
|
|
SBC HL,DE
|
|
JR C,E$LARGE ; ..if too large, jump error
|
|
CALL ENVLOW ; addr of lowest ENV component in HL
|
|
CALL USPCSZ ; size of User Space in DE
|
|
JR NZ,CALCSS0 ; ..if User Space size <> zero, skip over
|
|
LD HL,0 ; else, nullify HL before calc
|
|
CALCSS0: OR A ; reset C-Flag
|
|
SBC HL,DE ; calc User Space base addr
|
|
LD (UNBAD_I),HL ; ..and store it
|
|
LD HL,(Z3ENV_I+69) ; start addr BIOS (from ENV)
|
|
LD (BNBADR),HL ; ..and store in var (BIOS Non-banked addr)
|
|
LD DE,0E00H ; DOS standard size
|
|
SBC HL,DE ; calc base addr
|
|
LD (Z3ENV_I+66),HL ; store in ENV
|
|
LD (DNBADR),HL ; ..and in var (DOS Non-banked addr)
|
|
LD A,1CH ; DOS standard size in 128-byte recs
|
|
LD (Z3ENV_I+68),A ; ..store in ENV
|
|
LD DE,0800H ; CCP standard size
|
|
SBC HL,DE ; calc base addr
|
|
LD (Z3ENV_I+63),HL ; store in ENV
|
|
LD (CNBADR),HL ; ..and in var (CCP Non-banked addr)
|
|
LD A,10H ; CCP standard size in 128-byte recs
|
|
LD (Z3ENV_I+65),A ; store in ENV
|
|
RET
|
|
|
|
; too large
|
|
E$LARGE: CALL VPRINT
|
|
DEFB CR,LF,BEL,TAB,TAB,'+++ CPR or DOS too Large +++',CR,LF
|
|
DEFB 0
|
|
JP AUTOSZ ; loop, ask for auto-sizing
|
|
|
|
|
|
; link file (using SLINK0 LINK routine)
|
|
; in: DE= ptr FCB, BC= phys. addr CSEG, HL= phys. addr DSEG
|
|
; alt. registers set, addr of COMMON table in var
|
|
; out: BC= size DSEG, DE= size CSEG
|
|
LNKFILE: PUSH BC
|
|
PUSH HL
|
|
LD (LFCBADR),DE ; store addr of FCB
|
|
CALL INITFCB ; init FCB
|
|
CALL F$EXIST ; check if file exists
|
|
OR A
|
|
JR Z,E$NFND0 ; ..if not, jump and let return from there
|
|
CALL INITFCB ; init FCB
|
|
CALL F$OPEN ; open file
|
|
OR A
|
|
JR NZ,E$OPEN0 ; ..if error, jump and let return from there
|
|
LD A,128
|
|
LD (LBYTPOS),A ; set ptr for @GBYTE function (= initiate load)
|
|
LD A,00000001B ; set flag to link (bit 0= 1), no bitmap (bit 1= 0)
|
|
LD HL,(LTBLADR) ; set addr COMMON table
|
|
POP DE ; restore DSEG addr
|
|
POP BC ; restore CSEG addr
|
|
CALL LINK ; ..and link
|
|
OR A
|
|
JR NZ,E$LINK ; ..if error, jump error and exit
|
|
RET
|
|
|
|
|
|
; error messages
|
|
|
|
E$NFND0: POP HL ; clear stack
|
|
POP HL ; ..then fall through
|
|
E$NFND: CALL VPRINT
|
|
DEFB '..not found..'
|
|
DEFB 0
|
|
JP CRLF
|
|
|
|
E$OPEN0: POP HL
|
|
POP HL
|
|
E$OPEN CALL VPRINT
|
|
DEFB '..Open Error..'
|
|
DEFB 0
|
|
LD DE,(LFCBADR) ; addr of FCB
|
|
CALL F$CLOSE ; close file
|
|
JP CRLF
|
|
|
|
E$LINK: PUSH AF
|
|
CALL VPRINT
|
|
DEFB CR,LF,BEL,'..Link Error..'
|
|
DEFB 0
|
|
POP AF
|
|
CP 'A'
|
|
JR NC,E$INFIL
|
|
CALL PADC
|
|
LD A,' '
|
|
|
|
E$INFIL: CALL COUT
|
|
CALL VPRINT
|
|
DEFB ' in '
|
|
DEFB 0
|
|
LD DE,(LFCBADR) ; addr of FCB
|
|
INC DE ; move ptr to file name
|
|
CALL PFN3
|
|
DEC DE
|
|
CALL F$CLOSE ; close file
|
|
JP EXIT
|
|
|
|
|
|
;::::: SLINK0 MODULE SUPPORT FUNCTION AND COMMONs TABLE
|
|
|
|
; get one byte from input file
|
|
; used by SLINK0 linker module
|
|
; (saves all registers)
|
|
@GBYTE: PUSH BC ; save regs
|
|
PUSH DE
|
|
PUSH HL
|
|
LD A,(LBYTPOS) ; check pos for file read
|
|
CP 128
|
|
JR C,GBYTE0 ; while below 128, bypass reading a sector
|
|
LD HL,CPMDMA ; input buffer starts here
|
|
CALL SETDMA ; set file DMA buffer
|
|
LD DE,(LFCBADR) ; addr of FCB
|
|
CALL F$READ ; ..read one sector (sequential)
|
|
OR A
|
|
SCF ; set C-Flag in case of error
|
|
JR NZ,GBYTE1 ; jump w/ error code C-Flag set
|
|
|
|
; valid data is in sector buffer, get a byte and move ptr fwd
|
|
GBYTE0: LD E,A ; set ptr for offset
|
|
LD D,0 ; high byte is zero
|
|
LD HL,CPMDMA ; start from base
|
|
ADD HL,DE
|
|
INC A ; move ptr fwd
|
|
LD (LBYTPOS),A ; ..and save
|
|
LD A,(HL) ; get a byte
|
|
OR A ; set return status OK (NC)
|
|
GBYTE1: POP HL ; restore regs
|
|
POP DE
|
|
POP BC
|
|
RET
|
|
|
|
|
|
; table of Named COMMONs
|
|
; for the various system segments
|
|
; used by SLINK0 linker module
|
|
; (12 bytes per entry)
|
|
COMTBL: DEFB '_BIOS_',80H,0 ; name (1-7 char, 80H terminated) - 8 byte field
|
|
COMTB0: DEFW 0 ; logical load location ('ORG') of segment
|
|
DEFW 0 ; phys. load location of segment
|
|
DEFB '_ENV_',80H,0,0
|
|
COMTB1: DEFW 0FE00H
|
|
DEFW 0
|
|
DEFB '_MSG_',80H,0,0
|
|
COMTB2: DEFW 0
|
|
DEFW 0
|
|
DEFB '_FCB_',80H,0,0
|
|
COMTB3: DEFW 0
|
|
DEFW 0
|
|
DEFB '_MCL_',80H,0,0
|
|
COMTB4: DEFW 0
|
|
DEFW 0
|
|
DEFB 'BANK2',80H,0,0
|
|
COMTB5: DEFW 0
|
|
DEFW 0
|
|
DEFB 'B2RAM',80H,0,0
|
|
COMTB6: DEFW 0
|
|
DEFW 0
|
|
DEFB 'RESVD',80H,0,0
|
|
COMTB7: DEFW 0
|
|
DEFW 0
|
|
DEFB '_SSTK_',80H,0
|
|
COMTB8: DEFW 0
|
|
DEFW 0
|
|
DEFB '_XSTK_',80H,0
|
|
COMTB9: DEFW 0
|
|
DEFW 0
|
|
DEFB 80H ; end-of-table mark
|
|
|
|
|
|
|
|
; update info string w/ size information "k Bios"
|
|
; in linked BIOS
|
|
UPDINFO: LD DE,(LPHYADR) ; last destination addr (BIOS) in WSPC
|
|
LD HL,(SYSEADR) ; end addr of linked system in WSPC
|
|
XOR A
|
|
SBC HL,DE ; calc length in bytes
|
|
LD C,L ; and move to BC
|
|
LD B,H ; (# of bytes to scan)
|
|
EX DE,HL
|
|
|
|
; find string 'k Bios' in linked Bios
|
|
; (similar to Z3LIB's CHKENV routine)
|
|
UPDFND: LD DE,S$KBIOS ; point to string to search for ('k Bios')
|
|
LD A,(DE) ; do a quick scan for first char in string
|
|
CPIR
|
|
RET PO ; ..if not found, return
|
|
PUSH BC ; save count and addr
|
|
PUSH HL
|
|
CALL UPDFND0 ; and check remaining chars in string
|
|
POP HL
|
|
POP BC
|
|
JR NZ,UPDFND ; ..if no match, loop
|
|
|
|
; string is stored as "60.00k Bios"
|
|
LD DE,-6 ; move 6 bytes back to first digit char
|
|
ADD HL,DE
|
|
EX DE,HL ; swap regs (ptr in DE)
|
|
LD A,(BNBAD_I+1) ; get high byte base addr BIOS Non-banked
|
|
ADD A,6 ; ??? # recs User Space ???
|
|
PUSH AF
|
|
RRA ; divide by 4
|
|
RRA ; (1.024 = 256 *4 = 0x100 *4)
|
|
AND 00111111B ; mask off upper bits
|
|
|
|
; divide by subtraction
|
|
LD BC,10 ; B= 0, C= 10
|
|
UPDDIV: SUB C ; A= A-10
|
|
JR C,UPDPAT ; ..if negative, exit loop and write to memory
|
|
INC B ; B= B+1
|
|
JR UPDDIV ; continue division
|
|
|
|
; patch new info string
|
|
UPDPAT: ADD A,10 ; compensate underflow
|
|
LD C,A ; B contains 10's, C contains 1's
|
|
LD HL,3030H ; HL= ascii '0' '0'
|
|
ADD HL,BC ; convert digits to ascii (add '0')
|
|
EX DE,HL ; swap digits/ptr
|
|
LD (HL),D ; store 1st digit char
|
|
INC HL
|
|
LD (HL),E ; store 2nd digit char
|
|
INC HL ; move ptr to decimal places
|
|
INC HL
|
|
EX DE,HL ; and swap regs again
|
|
POP AF ; restore AF
|
|
AND 00000011B ; mask bits 1 and 0
|
|
LD HL,S$KDECPL ; ptr to list of strings for decimal places
|
|
ADD A,A ; strings of 2 bytes each (pos *2)
|
|
CALL ADDHLA ; move ptr forward
|
|
LDI ; ..and copy 2 bytes
|
|
LDI
|
|
RET
|
|
|
|
; string 'k Bios'
|
|
S$KBIOS: DEFB 'k Bios'
|
|
|
|
; check remaining chars in string
|
|
UPDFND0: LD BC,5 ; chars remaining in string
|
|
LD DE,S$KBIOS+1 ; find this string
|
|
UPDFND1: LD A,(DE)
|
|
CPI
|
|
RET NZ ; ..if no match, return
|
|
INC DE ; move source ptr fwd
|
|
JP PE,UPDFND1 ; ..if not yet done, continue checking
|
|
RET
|
|
|
|
; strings for decimal places
|
|
S$KDECPL: DEFB '00','25','50','75'
|
|
|
|
|
|
; read IMG file header
|
|
; in: file name in standard FCB #1
|
|
RDHDR: LD DE,CPMFCB
|
|
CALL F$OPEN ; attempt to open file
|
|
OR A ; check if successful
|
|
JR NZ,RDHDR0 ; ..if not, jump
|
|
CALL CODEND ; get addr WSPC
|
|
CALL SETDMA ; ..and set as buffer addr
|
|
LD DE,CPMFCB
|
|
CALL F$READ ; read file sequentially
|
|
JR NZ,RDHDR0 ; ..if error, jump
|
|
LD DE,128 ; else, move forward
|
|
ADD HL,DE ; by 1 sector
|
|
CALL SETDMA ; set file buffer addr
|
|
LD DE,CPMFCB
|
|
CALL F$READ ; read another sector
|
|
RET Z ; ..if successful, return
|
|
; else, fall through
|
|
RDHDR0: OR 0FFH ; set Z-Flag
|
|
SCF ; and C-Flag (error status)
|
|
RET
|
|
|
|
|
|
; write IMG file to disk
|
|
; in: HL= addr IMG in memory
|
|
; BC= # sectors to write
|
|
; out: C-Flag reset (NC) if successful (will not return from error, anyway)
|
|
WRFILE: PUSH BC
|
|
PUSH HL
|
|
LD DE,IMGFCB
|
|
CALL INITFCB ; init FCB
|
|
CALL F$EXIST ; check if file exists
|
|
JR Z,WRFIL0 ; ..if not, jump to continue
|
|
LD HL,IMGFCB ; else, try to rename existing file
|
|
LD DE,CPMFCB
|
|
LD BC,9 ; bytes to copy
|
|
LDIR
|
|
LD HL,FTYPES ; ptr to standard file type 'BAK'
|
|
LD BC,3 ; bytes to copy
|
|
LDIR
|
|
LD DE,CPMFCB
|
|
CALL INITFCB ; init FCB
|
|
CALL F$DELETE ; delete an existing .BAK file
|
|
EX DE,HL ; HL= ptr to FCB (old file name)
|
|
LD DE,IMGFCB ; ptr to FCB (new file name)
|
|
CALL F$RENAME ; try to rename
|
|
JR Z,E$IMGREN ; ..if error, jump error and exit
|
|
|
|
WRFIL0: LD DE,IMGFCB
|
|
CALL INITFCB ; init FCB
|
|
CALL F$MOPEN ; open file (create if not exists)
|
|
POP HL ; clear stack and fall through
|
|
POP BC
|
|
WRFIL1: PUSH BC ; save regs
|
|
PUSH HL
|
|
CALL SETDMA ; set file buffer addr
|
|
CALL F$WRITE ; write one 128-byte sector
|
|
POP HL ; restore regs
|
|
POP BC
|
|
OR A ; check error status
|
|
JR NZ,E$IMGWRI ; ..if error, jump error and exit
|
|
PUSH DE
|
|
LD DE,128 ; move forward by 1 sector
|
|
ADD HL,DE
|
|
POP DE
|
|
DEC BC ; reduce counter
|
|
LD A,B
|
|
OR C ; counter = zero ?
|
|
JR NZ,WRFIL1 ; ..if not, loop
|
|
CALL F$CLOSE ; close file
|
|
OR A ; set C-Flag (status = ok)
|
|
RET
|
|
|
|
|
|
; error messages
|
|
|
|
E$IMGREN: CALL VPRINT
|
|
DEFB CR,LF,BEL,' +++ ..Error Renaming: '
|
|
DEFB 0
|
|
|
|
E$IMGFIL: LD DE,IMGFCB+1 ; ptr to file name in IMG FCB
|
|
CALL PFN1 ; display it
|
|
CALL CRLF
|
|
JP EXIT
|
|
|
|
E$IMGWRI: CALL VPRINT
|
|
DEFB CR,LF,BEL,' +++ ..Error Writing to: '
|
|
DEFB 0
|
|
JR E$IMGFIL
|
|
|
|
|
|
; ##### unreferenced code (not used)
|
|
JUMPHL JP (HL)
|
|
; #####
|
|
|
|
|
|
; get Quiet Flag from Z3 Environment
|
|
; in: -
|
|
; out: A= Quiet Flag, defaults to A= 0 (not quiet)
|
|
GETQFLG: LD HL,(ENVADR) ; get local ENVPTR
|
|
LD A,H ; check if invalid (= zero)
|
|
OR L
|
|
RET Z ; ..if so, return
|
|
LD A,40 ; else, move ptr forward to Quiet Flag
|
|
CALL ADDHLA
|
|
LD A,(HL) ; get value
|
|
RET
|
|
|
|
|
|
; print program name on CON: device
|
|
; (either the actual name, or fallback to default)
|
|
; only used by HELP
|
|
PRGNAME: LD A,(ENVADR+1) ; get high byte of local ENVPTR
|
|
OR A ; check if valid (<> zero)
|
|
JP NZ,PRTNAME ; ..if so, display actual name
|
|
; ..and let return from there
|
|
CALL VPRINT ; else, display default
|
|
DEFB 'BPBUILD'
|
|
DEFB 0
|
|
RET
|
|
|
|
|
|
; ##### unreferenced code (not used)
|
|
LD B,8
|
|
UNUSED1
|
|
INC HL
|
|
LD A,(HL)
|
|
AND 01111111B
|
|
CP ' '
|
|
CALL NZ,COUT
|
|
DJNZ UNUSED1
|
|
RET
|
|
; #####
|
|
|
|
|
|
; add A to HL (result in HL)
|
|
ADDHLA: ADD A,L ; add L
|
|
LD L,A ; store result in L
|
|
RET NC ; ..if no overflow, return
|
|
INC H ; else, increment H
|
|
RET
|
|
|
|
|
|
; align addr to next 128-byte boundary
|
|
; in: HL= addr
|
|
; out: HL= aligned addr
|
|
ALIGN: LD DE,7FH ; add offset for partial 128-byte block
|
|
ADD HL,DE
|
|
LD A,L ; get low byte
|
|
AND 80H ; sector alignment
|
|
LD L,A
|
|
RET
|
|
|
|
|
|
; Auto-sizing - calculate base addr's of system segments Non-banked
|
|
; in: -
|
|
; out: - (addr's in ram storage locations)
|
|
CALCASZ: CALL ENVLOW ; addr of lowest ENV component in HL
|
|
CALL VPRINT
|
|
DEFB CR,LF,'Sizing from lowest ENV element = '
|
|
DEFB 0
|
|
CALL PHL4HC
|
|
CALL USPCSZ ; User Space size (USPCS) in bytes
|
|
OR A
|
|
SBC HL,DE ; calc User Space start addr
|
|
LD (UNBAD_I),HL ; ..and store in IMG hdr
|
|
LD A,(BNKDSYS) ; get banking indicator (0= Non-banked)
|
|
OR A
|
|
JR NZ,CALCAS0 ; ..if Non-banked, skip over
|
|
LD DE,(BRSVDO) ; get org RESVD Common
|
|
XOR A ; reset flags
|
|
SBC HL,DE ; ..and calc base addr
|
|
CALCAS0: LD DE,(BNBSZ_I) ; BIOS Non-banked total size
|
|
XOR A ; reset flags
|
|
SBC HL,DE ; ..and calc BIOS Non-banked base addr
|
|
LD L,0 ; align to page boundary
|
|
LD (BNBADR),HL ; store it
|
|
LD DE,(DNBSZ_I) ; DOS Non-banked total size
|
|
SBC HL,DE ; ..calc base addr
|
|
LD (DNBADR),HL
|
|
LD DE,(CNBSZ_I) ; CCP Non-banked total size
|
|
SBC HL,DE ; ..calc base addr
|
|
LD (CNBADR),HL
|
|
RET
|
|
|
|
|
|
; print base addr's of System (Non-banked Segments) on CON:
|
|
; in: -
|
|
PSYSNB: LD HL,(UNBAD_I) ; base addr User Space (from IMG hdr)
|
|
LD A,H
|
|
OR L ; check if zero
|
|
JR NZ,PSYSNB0 ; ..and branch accordingly
|
|
CALL VPRINT
|
|
DEFB CR,LF,' <No Resident User Space>'
|
|
DEFB 0
|
|
JR PSYSNB1
|
|
PSYSNB0: CALL VPRINT
|
|
DEFB CR,LF,' Base of Usr Sp = '
|
|
DEFB 0
|
|
CALL PHL4HC ; display HL as hex
|
|
PSYSNB1: CALL VPRINT
|
|
DEFB CR,LF,' Base of Bios = '
|
|
DEFB 0
|
|
LD HL,(BNBADR) ; BIOS Non-banked base addr (from var)
|
|
CALL PHL4HC ; ..display as hex
|
|
CALL VPRINT
|
|
DEFB CR,LF,' Base of Dos = '
|
|
DEFB 0
|
|
LD HL,(DNBADR) ; DOS Non-banked base addr (from var)
|
|
CALL PHL4HC
|
|
CALL VPRINT
|
|
DEFB CR,LF,' Base of Cpr = '
|
|
DEFB 0
|
|
LD HL,(CNBADR) ; CCP Non-banked base addr (from var)
|
|
JP PHL4HC ; ..display and let return from there
|
|
|
|
|
|
; size of User Space in bytes
|
|
; in: -
|
|
; out: DE= size, Z-Flag set if size = 0
|
|
USPCSZ: LD DE,UNBSZ_I ; User Space # records in IMG hdr
|
|
LD A,(DE)
|
|
LD D,A ; convert to 16-bit word
|
|
LD E,0 ; ..and multiply by 256
|
|
SRL D ; /2 (blocks * 128 = size in bytes)
|
|
RR E
|
|
OR A ; if User Space size = zero, set Z-Flag
|
|
RET
|
|
|
|
|
|
; get lowest addr in Z3ENV
|
|
; ( from offs. +9 EXPAT to +30 SHSTK = 8x 16-/8-bit value combo
|
|
; from offs. +34 Z3MSG to +38 EXTSTK = 3x 16-bit value )
|
|
; in: -
|
|
; out: HL= lowest addr of Z3ENV components
|
|
ENVLOW: LD HL,Z3ENV_I ; ptr to Z3ENV base
|
|
LD DE,9 ; start w/ offset to addr EXPATH (ext. path)
|
|
ADD HL,DE
|
|
LD C,(HL) ; get addr in BC
|
|
INC HL
|
|
LD B,(HL)
|
|
DEC HL ; move ptr back prior to loop
|
|
LD A,8 ; 8 entries (from EXPATH to SHSTK)
|
|
ENVLOW0: PUSH AF
|
|
CALL ADRLOWC ; find the lower of two addresses
|
|
INC HL ; skip byte following the addr
|
|
POP AF
|
|
DEC A ; decrease counter
|
|
JR NZ,ENVLOW0 ; ..loop till done
|
|
LD A,3 ; 3 entries (from Z3MSG to EXTSTK)
|
|
ENVLOW1: PUSH AF
|
|
CALL ADRLOWS ; find the lower of two addresses
|
|
POP AF
|
|
DEC A ; decrement counter
|
|
JR NZ,ENVLOW1 ; ..loop till done
|
|
INC HL ; skip Quiet flag
|
|
CALL ADRLOWS ; check also Z3WHL addr
|
|
LD L,C ; finally, copy lowest addr to HL
|
|
LD H,B
|
|
RET
|
|
|
|
|
|
; returns lowest addr of Z3ENV components w/ 16-/8-bit value combo (e.g. RCP, IOP)
|
|
; in: HL= ptr to current addr
|
|
; BC= lowest addr so far
|
|
; out: BC= lowest addr
|
|
ADRLOWC: LD E,(HL) ; get low byte
|
|
INC HL
|
|
LD D,(HL) ; ..and high byte
|
|
INC HL
|
|
LD A,D
|
|
OR E ; check if high = low = zero
|
|
RET Z ; ..if so, return
|
|
LD A,(HL) ; get high byte again
|
|
OR A ; check if zero
|
|
RET Z ; ..if so, return
|
|
LD A,E ; get low byte again
|
|
SUB C
|
|
LD A,D ; get high byte again
|
|
SBC A,B ; ..and check against lowest addr so far
|
|
RET NC ; ..no C-Flag means, old addr is lower
|
|
LD C,E ; else, copy current addr
|
|
LD B,D
|
|
RET
|
|
|
|
|
|
; returns lowest addr of Z3ENV components w/ 16-bit value (e.g. Z3MSG)
|
|
; in: HL= ptr to byte ahead of current addr
|
|
; BC= lowest addr so far
|
|
; out: BC= lowest addr
|
|
ADRLOWS: INC HL ; move ptr fwd to addr
|
|
LD A,(HL) ; get low byte
|
|
INC HL
|
|
OR (HL) ; check if high = low = zero
|
|
RET Z ; ..if so, return
|
|
DEC HL ; move ptr back
|
|
LD A,(HL) ; get low byte again
|
|
INC HL
|
|
SUB C
|
|
LD A,(HL) ; get high byte again
|
|
SBC A,B ; ..and check against lowest addr so far
|
|
RET NC ; ..no C-Flag means, old addr is lower
|
|
LD B,(HL) ; else, copy current addr
|
|
DEC HL
|
|
LD C,(HL)
|
|
INC HL
|
|
RET
|
|
|
|
|
|
; print HL as four-digit hex + closing bracket
|
|
; then get user input and convert to number
|
|
; in: HL= 16-bit value
|
|
; A= 0 no conversion, <> 0 convert to number
|
|
; out: DE= converted number
|
|
PHLXCNV: PUSH HL ; save regs
|
|
CALL PHL4HC ; display as hex
|
|
LD A,'H' ; display additional 'H'
|
|
CALL COUT
|
|
POP DE ; prepare for no input (restore value in DE)
|
|
CALL PRBRCIN ; display closing bracket and get user input
|
|
RET Z ; ..if input empty, return
|
|
JP EVAL16 ; else, convert as hexadecimal
|
|
; ..and let return from there
|
|
|
|
|
|
|
|
; print HL as decimal + closing bracket
|
|
; then get user input and convert to number
|
|
; in: HL= 16-bit value
|
|
; A= 0 no conversion, <> 0 convert to number
|
|
; out: DE= converted number
|
|
PHLDCNV: PUSH HL ; save regs
|
|
CALL PHLFDC ; display as dec
|
|
POP DE ; prepare for no input (restore value in DE)
|
|
CALL PRBRCIN ; display closing bracket and get user input
|
|
RET Z ; ..if input empty, return
|
|
JP EVAL10 ; else, convert as decimal number
|
|
; ..and let return from there
|
|
|
|
|
|
; print right (closing) bracket, then fall through to get user input
|
|
PRBRCIN: CALL VPRINT
|
|
DEFB ']',TAB,': '
|
|
DEFB 0
|
|
|
|
|
|
; get console input (based based on line editor)
|
|
; in: -
|
|
; out: HL= ptr to first char of nul-terminated input string
|
|
; ##### CHECK: buffer location could interfere with STACK
|
|
CINPUTL: LD HL,CINBUF ; set ptr to buffer
|
|
LD (HL),30 ; set buffer size
|
|
INC HL
|
|
LD (HL),0 ; init char count (filled by BLINE)
|
|
INC HL
|
|
LD (HL),0 ; init first char (filled by BLINE)
|
|
DEC HL ; move ptr back to start of buffer
|
|
DEC HL
|
|
OR 0FFH ; set flag to capitalize
|
|
JP BLINE ; get line input, and let return from there
|
|
|
|
|
|
; ##### unreferenced code (not used)
|
|
UNUSED2
|
|
CALL BASEROW
|
|
LD L,10
|
|
CALL GOTOXY
|
|
CALL VPRINT
|
|
DEFB 'Selection (ESC/Ctrl-C Aborts) : '
|
|
DEFB 0
|
|
CALL CAPINE
|
|
CP ESC
|
|
RET Z
|
|
CP CTRLC
|
|
RET Z
|
|
CALL ISALNUM
|
|
JR NZ,UNUSED2
|
|
RET
|
|
; #####
|
|
|
|
|
|
; print segment information - addr, # entries, and size
|
|
; ask for new values and convert, replacing old values at orig. location
|
|
; in: HL= ptr to 16-bit value (addr),
|
|
; followed by 8-bit values (entries, size)
|
|
PADENSZ: CALL PHLXENT ; print addr and # entries, get input (converted)
|
|
PUSH HL ; save ptr
|
|
CALL BASEROW
|
|
INC HL ; row 4 from bottom
|
|
JR PHLXSZ1 ; ..jump to continue displaying size
|
|
|
|
|
|
; print string "Address" and 16-bit value as hex on CON:
|
|
; ask for new value, convert it, and store at original addr
|
|
; then print "Size" and following byte, ask for new value,
|
|
; convert it, and store at original addr
|
|
; in: HL= ptr to 16-bit value (addr), followed by 8-bit value (entries)
|
|
PHLXSIZ: CALL PHLXCIN ; print addr, get input and convert
|
|
PHLXSZ0: PUSH HL ; save ptr
|
|
CALL BASEROW ; row 5 from bottom
|
|
PHLXSZ1: INC H ; 2* row down
|
|
INC H
|
|
LD L,16 ; col 16
|
|
CALL GOTOXY ; position cursor
|
|
CALL VPRINT
|
|
DEFB 'Size',TAB,' ['
|
|
DEFB 0
|
|
POP HL ; restore ptr
|
|
LD A,(HL) ; get byte
|
|
PUSH HL
|
|
LD L,A ; copy byte to L
|
|
LD H,0 ; set high byte to zero
|
|
CALL PHLDCNV ; ..display as dec and get user input (converted)
|
|
POP HL ; restore ptr
|
|
JR NC,PHLXSZ2 ; ..if conversion successful, skip over
|
|
LD A,BEL ; else, send <BEL> to CON:
|
|
CALL COUT
|
|
JR PHLXSZ0 ; ..and loop
|
|
|
|
PHLXSZ2: LD A,E ; copy converted number to A
|
|
LD (HL),A ; ..and store at orig. location
|
|
RET
|
|
|
|
|
|
; print string "Address" and 16-bit value as hex on CON:
|
|
; ask for new value, convert it, and store at original addr
|
|
; then print "Entries" and following byte, ask for new value,
|
|
; convert it, and store at original addr
|
|
; in: HL= ptr to 16-bit value (addr), followed by 8-bit value (entries)
|
|
PHLXENT: CALL PHLXCIN ; print addr, get input and convert
|
|
PHLXEN0: PUSH HL ; save ptr
|
|
CALL BASEROW ; row 5 from bottom
|
|
INC H ; 2* row down
|
|
INC H
|
|
LD L,16 ; col 16
|
|
CALL GOTOXY ; position cursor
|
|
CALL VPRINT
|
|
DEFB '# Entries ['
|
|
DEFB 0
|
|
POP HL ; restore ptr
|
|
LD A,(HL) ; get byte
|
|
PUSH HL
|
|
LD L,A ; copy byte to L
|
|
LD H,0 ; set high byte to zero
|
|
CALL PHLDCNV ; ..display as dec and get user input (converted)
|
|
POP HL ; restore ptr
|
|
JR NC,PHLXSZ2 ; ..if conversion successful, jump to continue
|
|
LD A,BEL ; else, send <BEL> to CON:
|
|
CALL COUT
|
|
JR PHLXEN0 ; ..and loop
|
|
|
|
|
|
; print string "Address" and 16-bit value as hex on CON:
|
|
; in row 4 from bottom, col 15
|
|
; then ask for new value, convert it, and store at original addr
|
|
; in: HL= ptr to 16-bit value
|
|
PHLXCIN: PUSH HL
|
|
CALL BASEROW ; row 5 from bottom
|
|
INC H ; row down
|
|
LD L,15 ; col 15
|
|
CALL GOTOXY ; position cursor
|
|
CALL VPRINT ; ..and display
|
|
DEFB 'Address',TAB,'['
|
|
DEFB 0
|
|
POP HL ; restore ptr in HL
|
|
LD E,(HL) ; get 16-bit value in DE
|
|
INC HL
|
|
LD D,(HL)
|
|
DEC HL
|
|
PUSH HL ; save ptr again
|
|
EX DE,HL ; swap regs
|
|
CALL PHLXCNV ; display hex value and get user input (converted)
|
|
POP HL ; restore ptr
|
|
JR NC,PHLXCI0 ; check for overflow in number conversion
|
|
; ..if not, jump
|
|
; else, fall through
|
|
LD A,BEL ; alert user (send <BEL> to CON:)
|
|
CALL COUT
|
|
JR PHLXCIN ; ..and loop
|
|
|
|
PHLXCI0: LD (HL),E ; store converted number in DE
|
|
INC HL ; at orig. location
|
|
LD (HL),D
|
|
INC HL
|
|
RET
|
|
|
|
|
|
; print addr and value of segment to CON: at xy coordinates
|
|
; in: HL= row/col
|
|
; DE= ptr to addr (value byte follows)
|
|
PSEGXY: CALL GOTOXY ; position cursor
|
|
PUSH HL ; save coordinates
|
|
LD A,(DE) ; get low byte
|
|
INC DE ; move ptr fwd
|
|
LD L,A
|
|
LD A,(DE) ; get high byte
|
|
INC DE ; ptr fwd
|
|
LD H,A
|
|
CALL PHLXH ; display 16-bit value as hex and 'H'
|
|
POP HL ; restore coordinates
|
|
INC H ; row +1
|
|
CALL GOTOXY ; position cursor
|
|
LD A,(DE) ; get byte
|
|
JR PSPCAD ; display <SP> + value as dec, return from there
|
|
|
|
|
|
; print addr in HL as four-digit hex and append 'H'
|
|
; in: HL= addr
|
|
PHLXH: CALL PHL4HC ; display as 4-digit hex
|
|
LD A,'H' ; append 'H'
|
|
JP COUT ; ..and let return from there
|
|
|
|
|
|
; ###### unreferenced code (not used)
|
|
UNUSED3: CALL ALIGN ; align to next sector boundary
|
|
ADD HL,HL
|
|
LD A,H
|
|
; #####
|
|
|
|
; print <SP> and A as decimal
|
|
PSPCAD: PUSH AF ; save regs
|
|
LD A,' ' ; send <SP> to CON:
|
|
CALL COUT
|
|
POP AF ; restore A
|
|
JP PADC ; display as decimal, let return from there
|
|
|
|
|
|
; returns row # of 5 lines above bottom of screen
|
|
; in: -
|
|
; out: H= row (max. row -5)
|
|
BASEROW: PUSH DE ; save regs
|
|
LD HL,(ENVADR) ; get ptr to ENV
|
|
LD DE,50 ; offset to number of rows (CRT)
|
|
ADD HL,DE ; move ptr
|
|
LD H,(HL) ; get value
|
|
DEC H ; -5
|
|
DEC H
|
|
DEC H
|
|
DEC H
|
|
DEC H
|
|
POP DE ; restore regs
|
|
RET
|
|
|
|
|
|
;::::: Standard file types
|
|
|
|
FTYPES: DEFB 'BAK','IMG','REL','ZRL'
|
|
DEFS 23
|
|
|
|
|
|
;::::: HEADER OF IMAGE FILE (all labels end with "_I")
|
|
|
|
; area for building the IMG file header
|
|
; if an image file was specified on the command line, the header is read
|
|
; and copied here, else default values are used and updated accordingly
|
|
IMGHD_I: JP 0
|
|
|
|
UNBAD_I: DEFW 0E900H ; addr User Space Non-banked
|
|
UNBSZ_I: DEFB 6 ; # recs
|
|
UBKAD_I: DEFW 0 ; addr User Space Banked
|
|
DEFS 8
|
|
|
|
CFNAM_I: DEFB 'ZCPR33 REL' ; default name ZCPR file
|
|
CNBAD_I: DEFW 0 ; Non-banked base addr
|
|
CNBSZ_I: DEFW 0 ; " size
|
|
CBKAD_I: DEFW 0 ; Banked base addr
|
|
CBKSZ_I: DEFW 0 ; " size
|
|
DEFS 13
|
|
|
|
DFNAM_I: DEFB 'ZSDOS ZRL' ; default name ZSDOS file
|
|
DNBAD_I: DEFW 0
|
|
DNBSZ_I: DEFW 0
|
|
DBKAD_I: DEFW 0
|
|
DBKSZ_I: DEFW 0
|
|
DEFS 13
|
|
|
|
BFNAM_I: DEFB 'B/P-18 REL' ; default name B/P Bios file
|
|
BNBAD_I: DEFW 0
|
|
BNBSZ_I: DEFW 0
|
|
BBKAD_I: DEFW 0
|
|
BBKSZ_I: DEFW 0
|
|
DEFS 13
|
|
|
|
IMGFN_I: DEFB 'BPSYS IMG' ; default name system image file
|
|
DEFS 5
|
|
|
|
|
|
;::::: Z3ENV DESCRIPTOR (in IMG header)
|
|
|
|
Z3ENV_I: JP 0 ; Leading jump (address is CBIOS when NZCOM)
|
|
DEFB 'Z3ENV' ; Environment ID
|
|
DEFB 81H ; Env type (=>80H means extended)
|
|
; ##### should rather be 90H for B/P Bios
|
|
|
|
; offset
|
|
; (dec / hex)
|
|
DEFW 0FDF4H ; EXPATH 9 / 09
|
|
DEFB 05H
|
|
DEFW 0F200H ; RCP 12 / 0C
|
|
DEFB 10H
|
|
DEFW 0EC00H ; IOP 15 / 0F
|
|
DEFB 0CH
|
|
DEFW 0FA00H ; FCP 18 / 12
|
|
DEFB 04H
|
|
DEFW 0FC00H ; Z3NDIR 21 / 15
|
|
DEFB 0EH
|
|
DEFW 0FF00H ; Z3CL 24 / 18
|
|
DEFB 0CBH
|
|
DEFW 0FE00H ; Z3ENV 27 / 1B
|
|
DEFB 02H
|
|
DEFW 0FD00H ; SHSTK 30 / 1E
|
|
DEFB 04H
|
|
DEFB 20H
|
|
DEFW 0FD80H ; Z3MSG 34 / 22
|
|
DEFW 0FDD0H ; EXTFCB 36 / 24
|
|
DEFW 0FFD0H ; EXTSTK 38 / 26
|
|
DEFB 00H ; Quiet Flag 40 / 28
|
|
DEFW 0FDFFH ; Z3WHL 41 / 29
|
|
DEFB 4 ; Proc. Speed (MHz) 43 / 2B
|
|
|
|
DEFB 'P'-'@' ; Max Disk Letter
|
|
DEFB 31 ; Max User Number
|
|
DEFB 1 ; DU flag
|
|
DEFB 0 ; CRT Selection
|
|
DEFB 0 ; Printer Selection
|
|
DEFB 80 ; CRT 0: Width (# Columns)
|
|
DEFB 24 ; # of Lines
|
|
DEFB 22 ; # of Text Lines
|
|
|
|
DEFW 0001000011111111B ; DRVEC (valid drives) 52 / 34
|
|
DEFB 0 ; <Reserved>
|
|
|
|
DEFB 80 ; PRT 0: Width (# Columns)
|
|
DEFB 66 ; # of Lines
|
|
DEFB 58 ; # of Text Lines
|
|
DEFB 1 ; FF Flag
|
|
|
|
; storage for Resident User Space Vectors (replaces PRT1 definitions)
|
|
DEFB 06H ; remaining free recs 59 / 3B
|
|
DEFW 0E900H ; base addr (xx00H/xx80H) 60 / 3C
|
|
DEFB 06H ; size in 128-byte recs 62 / 3E
|
|
|
|
DEFW 0BE00H ; CPR 63 / 3F
|
|
DEFB 10H
|
|
DEFW 0C600H ; DOS 66 / 42
|
|
DEFB 1CH
|
|
DEFW 0D400H ; BIOS 69 / 45
|
|
|
|
DEFB 'SH ' ; Shell variable filename
|
|
DEFB 'VAR' ; Shell variable filetype
|
|
DEFB ' ' ; File 1
|
|
DEFB ' ' ;
|
|
DEFB ' ' ; File 2
|
|
DEFB ' ' ;
|
|
DEFB ' ' ; File 3
|
|
DEFB ' ' ;
|
|
DEFB ' ' ; File 4
|
|
DEFB ' ' ;
|
|
DEFB 0 ; Public Drive Area (ZRDOS +)
|
|
DEFB 0 ; Public User Area (ZRDOS +)
|
|
|
|
; *** end of Z3ENV descriptor and IMG header ***
|
|
|
|
|
|
;:::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
; LINK - 0x1980
|
|
; VLIB - 0x1bfb
|
|
; Z3LIB - 0x1e3a
|
|
; SYSLIB - 0x20f4
|
|
; end addr 0x23e0 (begin DSEG)
|
|
;:::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
|
|
|
|
;::::: RAM STORAGE
|
|
|
|
DSEG
|
|
|
|
MSELOPT: DEFB 0 ; selected Menu option
|
|
|
|
; room for FCB's of system segments
|
|
CCPFCB: DEFS 36 ; CCP (ZCPR)
|
|
DOSFCB: DEFS 36 ; (ZS)DOS
|
|
BIOSFCB: DEFS 36 ; (B/P) BIOS
|
|
|
|
CCNBSZ: DEFW 0 ; CCP CSEG Non-banked Size (in TPA bank)
|
|
DCNBSZ: DEFW 0 ; DOS CSEG Non-banked Size
|
|
BCNBSZ: DEFW 0 ; BIOS CSEG Non-banked Size
|
|
BCBKSZ: DEFW 0 ; BIOS CSEG Banked Size (org 'BANK2', in System bank)
|
|
BDBKSZ: DEFW 0 ; BIOS DSEG Banked Size (org 'B2RAM')
|
|
DCBKSZ: DEFW 0 ; DOS CSEG Banked Size ('BANK2')
|
|
DDBKSZ: DEFW 0 ; DOS DSEG Banked Size ('B2RAM')
|
|
CCBKSZ: DEFW 0 ; CCP CSEG Banked Size ('BANK2')
|
|
CDBKSZ: DEFW 0 ; CCP DSEG Banked Size ('B2RAM')
|
|
|
|
SYSBLKS: DEFW 0 ; Size of new system in 128-byte blocks (# sectors)
|
|
AUTOSIZ: DEFB 0 ; Auto-sizing flag (0= no, 0xFF= yes)
|
|
BNKDSYS: DEFB 0 ; Banked system flag (bit 3 of OPTF1 = indicator ALV/CSV in bank)
|
|
OPTF1: DEFB 0 ; OPTF1 option flag of linked BIOS
|
|
BRSVDO: DEFW 0 ; BIOS org RESVD common
|
|
BNBADR: DEFW 0 ; BIOS Non-banked base addr
|
|
DNBADR: DEFW 0 ; DOS Non-banked base addr
|
|
CNBADR: DEFW 0 ; CCP Non-banked base addr
|
|
|
|
LPHYADR: DEFW 0 ; phys. destination addr when linking system segment (from WSPC onwards)
|
|
SYSEADR: DEFW 0 ; end addr of new system in WSPC (total of all segments)
|
|
|
|
IMGFCB: DEFS 36 ; room for FCB of image file
|
|
|
|
; used by linker related fn's
|
|
LBYTPOS: DEFB 0 ; byte ptr @GBYTE function
|
|
LFCBADR: DEFW 0 ; addr current FCB
|
|
LTBLADR: DEFW 0 ; addr COMTBL
|
|
|
|
CINBUF: ; console input buffer
|
|
DEFS 60H ; room for stack
|
|
STACK: DEFW 0 ; stack storage location
|
|
OLDDU: DEFW 0 ; logged Drive/User at program start
|
|
|
|
END
|
|
|
|
|
|
;************************************************************************
|
|
; Remarks jxl:
|
|
; BPBUILD.COM, included in available B/P Bios package(s), was dis-
|
|
; assembled and extensively commented. Labels are up to seven chars long
|
|
; to comply with M-REL standards. However, it is recommended to use SLR
|
|
; tools that support labels up to sixteen chars.
|
|
; In its current state, the compiled/linked file matches exactly the
|
|
; original ZSCFG2.COM, i.e. no changes to the source were made. Possible
|
|
; optimisations detected during disassembly are marked with "#####" in the
|
|
; comment.
|
|
;
|
|
; The program makes use of linker module which was included in the
|
|
; distributed package of ZSDOS v1 sources (SLINK0.Z80/.REL), to generate
|
|
; its output from M-REL files - an interesting piece of software!
|
|
; The embedded Image header and Z3 Environment descriptor could be
|
|
; externalised in .LIB files. However, this was not done (yet) to provide
|
|
; the complete source code "as is."
|
|
;************************************************************************
|
|
|