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.
 
 
 
 
 
 

752 lines
21 KiB

TITLE "HASHINI Drive Utility"
;************************************************************************
;* H A S H I N I *
;* Set Drive Volume Name and Init for File Stamps *
;* by Harold F. Bower and Cameron W. Cotrill *
;*----------------------------------------------------------------------*
;* Disassembly: jxl Mar 2025 *
;* public release 1.0 Apr 2025 *
;* see remarks at the end *
;*----------------------------------------------------------------------*
;* LINK with Version 4 libraries: Z3LIB, SYSLIB *
;* *
;* A>Z80ASM HASHINI/RS *
;* A>SLRNK HASHINI/N,/A:100,/D:09E5,HASHINI,Z3LIBS/S,SYSLIBS/S,/E *
;************************************************************************
VER EQU 02
REV EQU ' '
DATE MACRO
DEFB '12 Sep 93'
ENDM
CTRLC EQU 03H ; Control-C character
BEL EQU 07H ; Bell character
BS EQU 08H ; Backspace character
TAB EQU 09H ; Tab character
LF EQU 0AH ; Line Feed character
CR EQU 0DH ; Carriage Return character
ESC EQU 1BH ; Escape character
CPMBIOS EQU 0 ; CP/M BIOS warm boot (JP)
CPMBDOS EQU 5 ; CP/M BDOS entry point (JP)
CPMFCB EQU 5CH ; CP/M standard FCB #1 (+1 filename, +9 filetype)
CPMFCB2 EQU 6CH ; CP/M standard FCB #2
CPMDMA EQU 80H ; CP/M standard DMA buffer
; From Z3LIB Get..
EXTRN GETNAME, PRTNAME, GETQUIET, Z3INIT
; From SYSLIB Get..
EXTRN BLINE, EPRINT, CRLF, CAPIN, COUT, CODEND
;::::: PROGRAM START
ORG 100H
CSEG
HASHINI: JP START ; bypass header
DEFB 'Z3ENV' ; this is a ZCPR3 utility
DEFB 1 ; show external environment
DEFB 1
ENVADR: DEFW 0 ; addr of Z3 environment
DEFB 1
DEFB 'HASHINI '
DEFB 0
; config area (for ZNCFG.COM)
CFGAREA: DEFB 0 ; default value for program quiet flag
DEFB 0FFH
START: LD (STACK),SP ; save stack
LD SP,STACK
CALL Z3INIT ; init ENVPTR for Z3LIB routines
CALL GETNAME ; get ptr to program name
CALL GETQUIET ; check ENV quiet flag
LD HL,CFGAREA ; ptr to config area
OR (HL) ; merge flags (ENV + program)
LD (PRGQFLG),A ; store program quiet flag
CALL EPRINT
DEFB CR,LF,'Initialize Volume Label and File Stamps Ver '
DEFB VER/10+'0','.',VER MOD 10 + '0',REV,' '
DATE
DEFB CR,LF
DEFB 0
LD C,25 ; get current disk (BDOS fn #25)
CALL CPMBDOS
LD (OLDDRV),A ; remember drive #
CALL EVALCMD ; evaluate command line
JR INITWSPC
;::::: MAIN LOOP
START0: LD SP,STACK ; reset stack pointer
CALL EPRINT
DEFB CR,LF,LF,'Initialize another Disk? (Y/[N]) : '
DEFB 0
CALL CINPUT ; get user input
CP 'Y' ; is it 'Y' ?
JP NZ,EXIT ; ..if not, jump to exit
CALL SELODRV ; restore previously logged drive
CALL CRLF
OR 0FFH ; from now on run interactively
; init workspace (ram storage)
INITWSPC: LD (RUNMODE),A ; store mode
LD HL,WSPC ; clear workspace data area
LD B,(STACK-WSPC)-3
CALL FILLZ
;::::: DISK DRIVE
GETDISK: LD A,(RUNMODE) ; get mode
OR A ; running in cmdline mode ?
JR Z,GETVOLN ; ..if so, drive is known, jump to continue
; interactive mode - ask for disk to initialize
IMDISK: CALL EPRINT
DEFB CR,LF,LF,'Initialize which Disk for '
DEFB 0
LD A,(STMPTYP) ; stamp format indicator
OR A ; is it P2Dos ?
JR NZ,IMDISK1 ; ..if not, jump to continue
CALL EPRINT ; display chosen format
DEFB 'P2DOS'
DEFB 0
JR IMDISK2 ; skip over
IMDISK1: CALL EPRINT
DEFB 'NZTIME'
DEFB 0
IMDISK2: CALL EPRINT
DEFB ' Date/Time Stamps? : '
DEFB 0
CALL CINPUT ; get user input
CP 'A' ; disk drive letter must be
JR C,IMDISK3 ; between 'A' and 'P'
CP 'P'+1
JR C,IMDISK4
IMDISK3: CALL EPRINT ; else, notify user and loop
DEFB BEL,BS,' ',BS
DEFB 0
JR IMDISK
IMDISK4: LD (CURRDSK),A ; store disk drive letter
;::::: VOLUME NAME
GETVOLN: LD A,(VOLNAME)
OR A
JR NZ,IMVOLN3
; interactive mode - ask for volume name
IMVOLN: CALL EPRINT
DEFB CR,LF,'Enter Volume Name [1-11 chars] : '
DEFB 0
LD HL,CPMDMA ; set ptr to standard buffer
LD (HL),11 ; prepare char count (max. 11 chars)
XOR A ; clear A
LD (CPMDMA+1),A ; prepare end-of-string
DEC A ; let capitalize (A= non-zero)
CALL BLINE ; get user input
LD A,(HL) ; check char count
OR A ; is it empty string (nothing entered) ?
JR Z,IMVOLN ; ..if so, loop
LD DE,VOLNAME ; point to volname buffer
IMVOLN1: LD A,(HL) ; get char
LDI ; ..and copy over
OR A ; end of string ?
JR NZ,IMVOLN1 ; ..if not, loop
IMVOLN3: LD A,(PRGQFLG) ; get program quiet flag
OR A ; running in quiet mode ?
JR Z,DSKPROC ; ..if so, skip over
CALL EPRINT
DEFB CR,LF,' Confirm Initialize Drive '
DEFB 0
LD A,(CURRDSK)
CALL COUT
CALL EPRINT
DEFB ': (Y/[N]) '
DEFB 0
CALL CINPUT ; get user input
CP 'Y'
JP NZ,FINISH
;::::: PROCESS DISK
DSKPROC: LD A,(CURRDSK) ; get current disk drive letter
SUB 'A' ; make numeric
PUSH AF ; save regs
LD E,A ; drive # in E
CALL BDSELD ; select disk drive (BDOS call)
CALL EPRINT ; display warning
DEFB BEL,CR,LF,'+++ Existing Files will be ERASED! +++'
DEFB CR,LF,' --- Proceed anyway (Y/[N]) : '
DEFB 0
CALL CINPUT ; get user input
CP 'Y' ; is it 'Y' ?
JP NZ,FINISH ; ..if not, jump to finish processing
POP AF ; restore regs
LD C,A ; drive # in C
CALL BIOSELD ; select disk drive (BIOS call)
LD A,H ; check if DPH addr is valid
OR L
JP Z,E$DRVILL ; ..if not, jump display error msg and exit
; get parameters of current disk drive
LD E,(HL) ; get addr of skew table in DE
INC HL
LD D,(HL)
LD (SKEWTBL),DE ; and store value
LD DE,9
ADD HL,DE ; move ptr fwd (to DPH+10)
LD E,(HL) ; addr of DPB in DE
INC HL
LD D,(HL)
PUSH DE ; move addr to IX
POP IX
; ??? ##### CODEND not used
CALL CODEND ; get first free memory page addr in HL
LD D,(IX+8) ; get DirMax in DE
LD E,(IX+7) ; (max. dir entries -1)
INC DE ; +1
LD (DIRMAX),DE ; store value
SRL D ; /2
RR E
SRL D ; /4
RR E
LD (STMPMAX),DE ; store value
; (1 stamp dir entry for 4 file dir entries)
LD BC,0
LD HL,CPMDMA ; set to standard buffer
PUSH DE ; save regs
PUSH BC
LD DE,VOLNAME ; ptr to volume name
LD A,(DE) ; get char
OR A ; is it zero ? (<NUL> means empty string)
LD B,3*32 ; prepare counter for 3 stamp entries
JR Z,MKSTMP ; ..if no volume name, jump to continue
; make a volume name entry
; HL= ptr to standard buffer, DE= ptr to VOLNAME
; B= char count, C= char
LD (HL),020H ; set first byte of dir entry (user area)
; to 0x20 - indicates time stamp
INC HL ; move ptr fwd
LD B,11 ; number of chars
MKVOLN: LD A,(DE) ; get VOLNAME char in A
LD C,' ' ; prepare for <NUL> byte
OR A ; end of string ?
JR Z,MKVOLN1 ; ..if so, skip over
LD C,A ; else, get char in C
INC DE ; move VOLNAME ptr forward
MKVOLN1: LD (HL),C ; copy char to buffer
INC HL ; move ptr fwd
DJNZ MKVOLN ; loop till done
LD B,32-12 ; clear remaining bytes of stamp entry
CALL FILLZ
LD B,2*32 ; fill next 2 stamp entries
; make a stamp entry and write to dir
MKSTMP: LD A,0E5H ; CP/M default byte for free dir entries
CALL FILLA ; fill stamp entries
LD A,(STMPTYP) ; get chosen stamp format (0x00 = P2Dos, 0xFF = NZTime)
OR A ; ..and check
LD A,021H ; prepare for P2Dos
JR Z,MKSTMP1 ; ..if so, skip over
LD A,0A1H ; else, prepare for NZTime
MKSTMP1: LD (HL),A ; store byte
INC HL ; move ptr fwd
LD B,32-1 ; ..and clear remaining bytes of stamp entry
CALL FILLZ
POP BC ; restore regs
POP DE
CALL PVBOSE ; if verbose mode, display msg
DEFB CR,LF,'...Writing Initialized Directory...'
DEFB 0
LD DE,0 ; initial start #
LD (STMPCUR),DE ; set # of current stamp entry
CALL WRSTMP ; ..and write stamp to directory
LD HL,CPMDMA ; reset ptr to begin of standard buffer
LD A,0E5H ; clear first part of stamp entry
LD B,32
CALL FILLA
MKSTMP2: CALL WRSTMP ; ..and write next stamp entry
LD HL,(STMPCUR) ; get current #
LD DE,(STMPMAX) ; get max. #
OR A ; clear flags
SBC HL,DE ; check if all entries were written
ADD HL,DE
JR NZ,MKSTMP2 ; ..if not, loop
LD BC,1 ; set C= 1 to indicate Directory Write (forced)
CALL BIOWRIT ; ..and perform through BIOS
JP DSKDONE
; display help and exit
HLPEXIT: XOR A ; clear A
LD (RUNMODE),A ; ..and store mode (cmdline)
JR HELP
E$DRVILL: CALL EPRINT ; display error msg and fall through
DEFB CR,LF,LF,BEL,'Illegal drive name'
DEFB 0
;::::: HELP
HELP: CALL EPRINT
DEFB CR,LF,'Usage: Set Drive Volume Name & '
DEFB 'Initialize for P2Dos/NzTime file stamps',CR,LF,LF
DEFB 'Syntax:',CR,LF,TAB
DEFB 0
CALL PPRGNAM
CALL EPRINT
DEFB ' [d:][volname] [/][P | Z | Q]',CR,LF
DEFB 'Examples:',CR,LF,TAB
DEFB 0
CALL PPRGNAM
CALL EPRINT
DEFB TAB,'- Enter Interactive Mode',CR,LF,TAB
DEFB 0
CALL PPRGNAM
CALL EPRINT
DEFB ' /P',TAB,'- Init Drive interactively w/P2D stamps',CR,LF,TAB
DEFB 0
CALL PPRGNAM
CALL EPRINT
DEFB ' d:',TAB,'- Initialize drive "d" w/default Stamp',CR,LF,TAB
DEFB 0
CALL PPRGNAM
CALL EPRINT
DEFB ' d:name',TAB,'- Init drive "d" adding Vol ID "name"',CR,LF,TAB
DEFB TAB,TAB,' file with default Stamps',CR,LF,TAB
DEFB 0
CALL PPRGNAM
CALL EPRINT
DEFB ' d: ZQ',TAB,'- Init drive "d" for NZTime Stamps',CR,LF,TAB
DEFB TAB,TAB,' suppressing unneeded messages',CR,LF,TAB
DEFB 0
CALL PPRGNAM
CALL EPRINT
DEFB ' //',TAB,'- Display this message',CR,LF,LF
DEFB 'Note: ZCNFG may be used to configure a flag to suppress',CR,LF
DEFB ' drive confirmation prompt and status messages',CR,LF
DEFB 0
JP FINISH
; print program name on CON: device
; (either the actual name, or fallback to default)
; only used by HELP
PPRGNAM: LD A,(ENVADR) ; get high byte of ENV ptr
OR A ; check if valid (<> zero)
JP NZ,PRTNAME ; ..if so, display actual name
; and let return from there
CALL EPRINT ; else, display default name
DEFB 'HASHINI'
DEFB 0
RET
; write a stamp entry to directory
; in: IX= ptr DPB
; STMPCUR= # of current stamp entry
WRSTMP: PUSH BC ; save regs
PUSH DE
PUSH HL
LD HL,0
LD BC,(STMPCUR) ; get # of current stamp entry
LD D,(IX+1) ; get sectors per track (DPB+0)
LD E,(IX+0)
LD A,17 ; set counter
; determine track # (in BC) and sector # (in HL)
WRSTMP1: OR A ; clear flags
SBC HL,DE ; divide by subtraction
CCF ; inverse C-flag
JR C,WRSTMP2
ADD HL,DE ; compensate overflow
OR A ; clear flags
WRSTMP2: RL C ; divide BC by 2 (track #)
RL B
DEC A ; decrease counter
JR Z,WRSTMP3 ; ..if zero, exit loop
RL L ; else, also divide HL by 2 (sector #)
RL H
JR WRSTMP1 ; and continue
WRSTMP3: PUSH HL ; save (log.) sector #
LD H,(IX+14) ; get track offset (# sys tracks)
LD L,(IX+13)
ADD HL,BC ; add to calculated track #
LD B,H
LD C,L
CALL BIOSTTR ; set track
POP BC ; restore (log.) sector #
LD DE,(SKEWTBL) ; get addr of skew table
CALL BIOSTRN ; translate logical to physical sector
LD B,H
LD C,L
CALL BIOSTSE ; set (phys.) sector
LD BC,CPMDMA ; set buffer addr
CALL BIOSTDM
LD BC,0 ; set C= 0 to indicate Unallocated Write
CALL BIOWRIT ; ..and perform through BIOS
OR A ; check for error
JR Z,WRSTMPX ; ..if not, jump to exit subroutine
CALL EPRINT ; else, display msg
DEFB CR,LF,BEL,'Directory write error'
DEFB 0
JR FINISH
WRSTMPX: LD BC,(STMPCUR) ; get current stamp #
INC BC ; increase
LD (STMPCUR),BC ; ..and save again
POP HL ; restore regs
POP DE
POP BC
RET
; select disk drive that was logged at start of program
; using BIOS fn first, then BDOS fn
SELODRV: LD A,(OLDDRV) ; get # of old logged disk drive
LD C,A ; in C
LD B,0
PUSH BC ; save it
LD DE,1 ; ??? ##### not necessary
CALL BIOSELD ; select disk drive (through BIOS)
POP DE ; restore drive # in E
; ..and fall through
; call BDOS fn #14 SELDSK
; in: E= drive #
BDSELD: LD C,14
JP CPMBDOS ; jump BDOS and let return from there
;::::: FINISH PROCESSING DISK
FINISH: CALL SELODRV ; restore previously logged drive
; ..and fall through
DSKDONE: LD A,(CURRDSK)
SUB 40H ; make numeric
LD B,A ; use value as counter
SCF ; set C-flag
LD HL,0 ; start with all bits cleared
DSKDN0: ADC HL,HL ; shift Carry bit into position
DJNZ DSKDN0 ; loop till done
EX DE,HL ; bit mask in DE (selected disk drive)
LD C,37 ; BDOS fn #37 RESDSK reset disk system
CALL CPMBDOS
LD A,(RUNMODE) ; get mode
OR A ; running in cmdline mode ?
JP NZ,START0 ; ..if not, loop for next drive
; else, fall through and exit
;::::: EXIT PROGRAM
EXIT: LD SP,(STACK) ; restore stack
RET ; ..and return to system
;::::: SUPPORT FUNCTIONS
; EVALCMD Evaluate command line
; based on tokens provided by CP/M parser in FCB #1/#2
; in: A= # of current drive
; out: A= 0x00 cmdline mode, 0xFF interactive mode
; Syntax: [d:][volname] [/][P | Z | Q]
EVALCMD: XOR A ; clear A
LD (CURRDSK),A ; ..and variables
LD (RUNMODE),A
LD HL,CPMFCB ; set ptr to standard FCB #1
LD A,(HL) ; get drive #
OR A ; check if zero
JR Z,ECMD1 ; ..if so, skip over
ADD A,40H ; else, make ascii
CP 'P'+1 ; check if valid
JR NC,ECMD1 ; ..if not, skip over
LD (CURRDSK),A ; else, save disk drive letter
ECMD1
INC HL ; move ptr fwd
LD A,(HL) ; get char
LD DE,VOLNAME ; ptr to buffer for volume name
LD B,11 ; max. 11 chars
CP ' ' ; is it <SP> ?
JR Z,ECMD2 ; ..if so, jump to continue
CP '/' ; is it option or help request ?
JR NZ,ECMD1V ; ..if not, jump to copy volume name
INC HL ; else, move ptr fwd
CP (HL) ; and check next char
JP Z,HLPEXIT ; ..if also '/', jump to display help
JR ECMD3OPT ; else, this char indicates an option
; volume name found, copy it
ECMD1V0: LD A,(HL) ; get char
ECMD1V: CP ' ' ; is it <SP> ?
JR Z,ECMD2 ; ..if so, jump to continue
LD (DE),A ; save char in VOLNAME buffer
INC DE ; move both ptr's forward
INC HL
DJNZ ECMD1V0 ; loop till done
; eval 2nd cmdline token (FCB #2)
ECMD2: XOR A ; clear A
LD (DE),A ; store in VOLNAME to indicate no name
LD HL,CPMFCB2+1 ; set ptr to standard FCB #2, after drive letter
LD A,(HL) ; get char
CP '/' ; is it option or help request ?
JR NZ,ECMD3OPT ; ..if not, letter must be an option, so skip over
INC HL ; else, move ptr fwd
CP (HL) ; and check next char
JP Z,HLPEXIT ; ..if also '/', jump to display help
; eval option and done
ECMD3OPT: CALL EVLOPT ; eval option
RET NZ ; if error, switch to interactive mode and return
; else, continue final check
LD HL,CPMFCB ; set ptr to standard FCB #1
LD A,(HL) ; get byte
OR A ; is it zero ?
JR Z,ECMDIM ; ..if so, jump done (interactive mode)
INC HL ; move ptr fwd
LD A,(HL) ; get char
CP ' ' ; is it <SP> ?
JR NZ,ECMDCM ; ..if not, jump done (cmdline mode)
LD A,(CPMFCB2+1) ; get char of 2nd token
CP ' ' ; is it <SP> ?
JR NZ,ECMDCM ; ..if not, jump done (cmdline mode)
; else, fall through (interactive mode)
ECMDIM: OR 0FFH ; set status (interactive mode)
RET
ECMDCM: XOR A ; set status (cmdline mode)
RET
; evaluate _one_ option on cmdline
; in: HL= ptr to char (already behind a leading '/')
; out: A= 0x00 cmdline mode, 0xFF interactive mode
; Z-flag reset (NZ) in case of error, i.e. interactive mode
; possible flags are /Q (quiet), /P (P2Dos stamps), /Z (NZTime stamps)
EVLOPT: LD B,7 ; max. 7 chars
EVLOPTQ: LD A,(HL) ; get char
CP 'Q' ; option /Q - quiet ?
JR NZ,EVLOPTP ; ..if not, jump to check next option
LD A,(PRGQFLG) ; get program quiet flag
XOR 0FFH ; toggle
LD (PRGQFLG),A ; ..and save back
JR EVLONXT ; jump to continue
EVLOPTP: CP 'P' ; option /P - P2Dos stamps ?
JR NZ,EVLOPTZ ; ..if not, jump to check next option
XOR A ; clear A
LD (STMPTYP),A ; ..and store stamp type
JR EVLONXT ; jump to continue
EVLOPTZ: CP 'Z' ; option /Z - NZTime stamps ?
JR NZ,EVLONX1 ; ..if not, jump to check for whitespace
OR 0FFH ; set A= 0xFF
LD (STMPTYP),A ; store stamp type
; ..and fall through to read next char
EVLONXT: INC HL ; move ptr fwd
LD A,(HL) ; get char
; options are separated by whitespace
EVLONX1: CP ' ' ; is it <SP> ?
JR Z,EVLOXIT ; ..if so, jump to exit loop
CP TAB ; is it <TAB> ?
JR Z,EVLOXIT ; ..if so, jump to exit loop
JR NZ,EVLOERR ; else, invalid option char found
DJNZ EVLOPTQ ; loop till done
EVLOXIT: XOR A ; set return code 0x00 (clear A and flags)
RET
EVLOERR: LD A,(PRGQFLG) ; get program quiet flag
OR A ; running in verbose mode ?
LD A,BEL
CALL Z,COUT ; ..if so, notify user
CALL EPRINT
DEFB CR,LF,'+++ Unrecognized Option "'
DEFB 0
LD A,(HL)
CALL COUT
CALL EPRINT
DEFB '" ... Setting Interactive'
DEFB 0
OR 0FFH ; set return code 0xFF
RET
; get console input
; and check for abort request
CINPUT: CALL CAPIN ; get char and capitalize
CP CTRLC ; is it <Ctrl-C> ?
JP Z,EXIT
CP ESC ; is it <ESC> ?
JP Z,EXIT
CP 'a' ; below 'a' ? (not possible, CAPIN capitalizes)
RET C
CP 'z'+1 ; between lowercase 'a' and lowercase 'z' ?
RET NC
AND 01011111b ; remove bit 5 to capitalize
RET
; ##### unreferenced code (not used)
; copy 32 (0x20) bytes from (HL) to (DE)
LD B,32
UNUSED1: LD A,(HL)
LD (DE),A
INC HL
INC DE
DJNZ UNUSED1
RET
; #####
; fill memory with zero, or byte
; in: A= byte
; B= # of bytes
; HL= target addr
FILLZ: XOR A ; clear A
FILLA: LD (HL),A ; store byte
INC HL ; move ptr fwd
DJNZ FILLA ; loop
RET
; verbose print - print string to CON: if quiet flag is off
; in: (Stack) contains start addr of nul-terminated string
PVBOSE: LD A,(PRGQFLG) ; get program quiet flag
OR A ; running in verbose mode ?
JP Z,EPRINT ; ..if so, jump to print and let return from there
EX (SP),HL ; else, swap HL and top-of-stack
PVBOSE0: LD A,(HL) ; get char
INC HL ; move ptr fwd
OR A ; is byte = zero ?
JR NZ,PVBOSE0 ; ..if not, loop
EX (SP),HL ; else, swap back
RET
; entry points for indirect BIOS calls
; BC is loaded with absolute offset from WBOOT (fn #1)
; to respective jump instruction, i.e. 3 bytes per fn
BIOSELD: PUSH BC
LD BC,3*8 ; fn #9 SELDSK select disk
JR BIOSFN
BIOSTTR: PUSH BC
LD BC,3*9 ; fn #10 SETTRK set track
JR BIOSFN
BIOSTSE: PUSH BC
LD BC,3*10 ; fn #11 SETSEC set sector
JR BIOSFN
BIOSTDM: PUSH BC
LD BC,3*11 ; fn #12 SETDMA set buffer addr
JR BIOSFN
BIOREAD: PUSH BC
LD BC,3*12 ; fn #13 READ read one sector (not used)
JR BIOSFN
BIOWRIT: PUSH BC
LD BC,3*13 ; fn #14 WRITE write one sector
JR BIOSFN
BIOSTRN: PUSH BC
LD BC,3*15 ; fn #16 SECTRN sector translation
JR BIOSFN
; call BIOS fn indirectly
; in: BC= offset to fn in Bios jump table
BIOSFN: EX (SP),HL ; swap HL and top-of-stack (= prev. BC)
PUSH HL ; save HL (prev. BC)
LD HL,(CPMBIOS+1) ; Bios base addr
ADD HL,BC ; add offset to fn #
POP BC ; restore BC
EX (SP),HL ; swap HL and top-of-stack again
RET ; "call" by returning to Bios fn
UNUSED2:
DEFB 0,0,0,0,0,0 ; ##### unreferenced chunk of data
DEFB '!!!TIME&DAT' ; obviously not used
DEFB 0,0,0,0,0,0,0,0
DEFB 0,0,0,0,0,0,0,0
DEFB 0,0,0,0,0,0,0,0
;:::::::::::::::::::::::::::::::::::::::::::::::::::::
; Z3LIB - 0x08a7
; SYSLIB - 0x091a
; end addr 0x09e5 (begin DSEG)
;:::::::::::::::::::::::::::::::::::::::::::::::::::::
DSEG
STMPTYP: DEFB 0 ; stamp type flag, 0x00 = P2Dos, 0xFF = NZTime
PRGQFLG: DEFB 0 ; program quiet flag, 0x00 = verbose
VOLNAME: DEFS 12 ; buffer for volume name, 11 bytes + <NUL> terminator
RUNMODE: DEFB 0 ; indicator, 0x00 = cmdline mode / 0xFF = interactive mode
OLDDRV: DEFB 0 ; logged drive at program start
CURRDSK: DEFB 0 ; current disk drive letter
WSPC: ; workspace starts here
DIRMAX: DEFW 0 ; max. # of dir entries (from DPH +1)
STMPMAX: DEFW 0 ; max. # of stamp entries (= DIRMAX / 4)
STMPCUR: DEFW 0 ; current # of stamp entry (used as counter)
SKEWTBL: DEFW 0 ; addr of skew table (from DPH)
DEFS 070H ; room for stack
STACK: DEFW 0 ; stack storage location
END
;************************************************************************
; Remarks jxl:
; HASHINI.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 SHOWHD.COM, i.e. no changes to the source were made. Possible
; optimisations detected during disassembly are marked with "#####" in the
; comment. It is fair to say that the program seems to be in an early
; stage; as the version number indicates. Apparently, provisions were made
; to test exitence, or even generate a DateStamper !!!TIME&.DAT file
; (which is not the case right now.)
; The program supports an interactive and a command line mode. Labels
; start with "IM" to indicate code specifically for interactive mode.
;************************************************************************