mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 14:11:48 -06:00
Jörg Linder has disassembled and thoroughly commented a great deal of the BPBIOS binaries. This was an incredible amount of work. I have added all of these to the RomWBW build scripts and will ultimately integrate them more completely.
2358 lines
65 KiB
Z80 Assembly
2358 lines
65 KiB
Z80 Assembly
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."
|
|
;************************************************************************
|