; DISKPRAM.ASM
;
;
; DISKPRAM intended use is to determine the the values of the DISK
; PARAMETER BLOCK and the SKEW TRANSLATION TABLE of a system alien
; to Ampro MULTIDSK program. After the host system parameters are
; are determined ESET may be used to set up the E: drive on the
; AMPRO system
;
; DISKPRAM displays the disk parameter block and the skew translation
; table maintained in the target cp/m 2.2 bios in any selected system
;
; DISKPRAM is the conbination of DPB.ASM and SKEW.ASM by
; Robert C. Kuhman, Sysop of the Cro's Nest RCP/M.
;
;****************************************************************
; Revisions:
; V1.00 as of 27/10/84 Fred Willink
;****************************************************************
;
BOOT EQU 0 ;
BDOS EQU 05H ;
FCB1 EQU 5CH ;
;
; other equates
;
ACROSS EQU 8
;
; ampro bios disk id save area
;
; ascii equates
;
BELL EQU 07H ; bell
TAB EQU 09H ; horz tab
LF EQU 0AH ; line feed
CR EQU 0DH ; carriage return
SPC EQU 20H ; space
;
ORG 100H
;
START: LXI H,0
DAD SP ; hl=ccp stack pointer
LXI SP,STACK ; set up local stack
PUSH H ; save the ccp pointer for return
TEST: LDA FCB1+1
CPI '/'
JZ HELP ; help
CPI '?'
JZ HELP
CALL DPB
CALL SKEW
JMP EXIT
;
HELP: LXI H,HLPMSG ; point to help message
CALL COSTR ; display help
;
; exit no warm boot
;
EXIT: POP H ; recover ccp"s stack ptr
SPHL
RET
;
DPB: LDA FCB1 ; drive code given ?
DCR A ; convert a=1 to 0
JP DPB2
CALL FCN25
DPB2: MOV E,A ; save for select
ADI 'A' ; make drive code printable
STA DRIVE
CALL FCN14
CALL FCN31
PUSH H ; save it for dump
;
LXI D,SPT ; make dph values printable
CALL CVT2
LXI D,BSH
CALL CVT1
LXI D,BLM
CALL CVT1
LXI D,EXM
CALL CVT1
LXI D,DSM
CALL CVT2
LXI D,DRM
CALL CVT2
LXI D,ALV0
CALL CVT1
LXI D,ALV1
CALL CVT1
LXI D,CKS
CALL CVT2
LXI D,OFF
CALL CVT2
;
LXI H,DSPLAY ; dph table
CALL COSTR ; print it all
POP H
MVI B,15
CALL HEXDMP ; print hexdump of dpb
CALL COCRLF
CALL COCRLF
RET
;
SKEW: MVI A,ACROSS ; number of records to display across screen
STA NPRINT ; save
LDA FCB1 ; see if drive was specified
DCR A ; test ff=no
JP REC2 ; yes, select drive
CALL FCN25 ; no, get current drive
REC2: MOV E,A
MOV C,A
CALL FCN14 ; select drive
CALL FCN31 ; get address of dph
MOV E,M
INX H
MOV D,M
XCHG
SHLD NRECS ; save dph address for records per track
MVI A,24 ; offset for seldsk:
CALL BIOS ; hl=dph, de=xlate table
MOV E,M
INX H
MOV D,M ; de=dph
PUSH H
PUSH D
PUSH B
XCHG ; dph in hl
SHLD DPHADR ; and save
CALL HEXADR ; display dph address
LXI H,DPH ; trailer message for address
CALL COSTR ; display
POP B
POP D
POP H
MOV A,E ; get low byte
ORA D ; or with high
JNZ REC3 ; if zero no translate done
LXI H,NXLATE ; no translate message
CALL COSTR
RET
;
REC3: LXI B,0 ; clear record number
XRA A ; clear a
STA POSIT ; initialize counter
;
RECLOP: MVI A,45 ; offset to sectran
CALL BIOS ; hl=xlate (bc)
CALL PRINT ; display results
LHLD NRECS ;
DCX H
MOV A,L
ORA H
JZ SHOWD
SHLD NRECS
INX B
JMP RECLOP ; till through
;
SHOWD: LXI H,TBLMSG ; for skew table
CALL COSTR ; display
MVI A,20 ; number of entries
STA POSIT ; set counter
LHLD DPHADR ; get dph address
SHLD LAST ; save it
JMP ENTRY
;
MORE: LHLD LAST ; get last position
INX H ; update and
SHLD LAST ; save it
ENTRY: MOV E,M ; get byte
MVI D,0 ; zero d
MOV A,E ; value in a
CPI 27 ; largest value
JNC ZERFIL ;
CPI 1 ; start of table
JZ WHERE ; what position
CPI 0 ;
JNZ NOPE ; none of those
WHERE: LDA POSIT ; see where in table
CPI 20 ; first position of 20
JNZ ZERFIL ; see if need zeros
NOPE: XCHG ; hl has value
CALL DECOUT ; print decimal value
LDA POSIT ; get count
CPI 0 ; see if done
RZ ; yes, return
MVI A,',' ; insert comma
CALL COUT
CALL COSPAC ; insert space
LDA POSIT ; see if done
CPI 0
JZ ZERFIL ; fill remainder
NOTDON: DCR A ; count down
STA POSIT ; and save
JMP MORE
;
ZERFIL: LDA POSIT ; how many zero's
CPI 0
RZ ; done if zero
DCR A ; count down
STA POSIT ; and save
MVI A,'0'
CALL COUT ; print '0'
LDA POSIT
CPI 0 ; see if through now
RZ
MVI A,','
CALL COUT ; print ','
CALL COSPAC ; print space
JMP ZERFIL
;
; convert binary in hl to ascii decimal
;
DECOUT: MVI B,0 ; leading zero fill
LXI D,-100
CALL SUBTR ; hundreds
LXI D,-10
CALL SUBTR ; tens
MOV A,L
ADI '0' ; ascii bias
JMP COUT ; print and return to caller
;
; subtract powers of 10
;
SUBTR: MVI C,'0'-1 ; ascii count
SUBT2: INR C
DAD D ; add neg number
JC SUBT2
;
; one to many add one back
;
MOV A,D ; complement
CMA ; de
MOV D,A
MOV A,E
CMA
MOV E,A
INX D
DAD D
MOV A,C ; get count
;
; check for zero
;
CPI '1' ; less than 1?
JNC NZERO ; no
MOV A,B ; check 0 flag
ORA A
MOV A,C ; restore
RZ ; skip leading zero
JMP COUT ; print character
;
; set flag for non-zero character
;
NZERO: MVI B,0FFH ; set to zero
JMP COUT ; print
RET
;
; print record entry
;
PRINT: CALL HEXADR ; print hl as hex words
CALL COSPAC ; insert space
LDA NPRINT ; see if end of line
DCR A
STA NPRINT ; update
RNZ
MVI A,ACROSS ; how many lines across
STA NPRINT ; save
CALL COCRLF ; start new line
RET
;
; select disk, 'e' has drive number
;
FCN14: PUSH B
PUSH D
PUSH H
MVI C,14
CALL BDOS
POP H
POP D
POP B
RET
;
; get current disk number, returns current disk in 'a'
;
FCN25: PUSH B
PUSH D
PUSH H
MVI C,25 ; no drive given, get current disk
CALL BDOS
POP H
POP D
POP B
RET
;
; get disk parameters, returns 'hl'=dpb address
;
FCN31: PUSH B
PUSH D
MVI C,31 ; hl = dpb for current disk
CALL BDOS
POP D
POP B
RET
;
CVT2: PUSH H ; display 16 bit integer
INX H
CALL CVT1
XTHL
CALL CVT1
POP H
RET
;
CVT1: MOV A,M ; display byte at 'hl'
INX H
CVT1A: CALL HEXBYT ; a,c=ascii display
STAX D
INX D
MOV A,C
STAX D
INX D
RET
;
; Subroutine to do an addressed dump of one line. HL point to data,
; 'B' has length
;
HEXDMP: CALL HEXADR ; display hl contents in hex
MVI A,':'
CALL COUT
CALL COSPAC
;
HEXLIN: PUSH B
PUSH H
HEXL2: MOV A,M
CALL COHEX ; display hl in hex
CALL COSPAC ; space
INX H
DCR B
JNZ HEXL2
POP H
POP B
RET
;
; Subroutine to print hl as an address in hex
;
HEXADR MOV A,H
CALL COHEX
MOV A,L
CALL COHEX
RET
;
; print the hex byte in 'a'
;
COHEX: PUSH PSW ; save byte
CALL HEXLFT ; get left half
CALL COUT ; and print
POP PSW ; restore byte
CALL HEXRHT ; right half and
CALL COUT ; print
RET
;
HEXLFT: RAR ; make left nibble
RAR
RAR
RAR
;
HEXRHT: ANI 0FH ; make right nibble
CPI 0AH
JC HEXLR
ADI 'A'-3AH
;
HEXLR: ADI '0'
RET
;
; suboutrine to return the hex value of 'a',
; least significant half in 'c', most significant in 'a'.
; used when ascii-hex is to be stored.
;
HEXBYT: PUSH PSW ; save
CALL HEXRHT ; get right nibble
MOV C,A ; save in c
POP PSW ; restore and get
CALL HEXLFT ; left nibble
RET
;
; subroutine to write 'a' to console
;
COUT: PUSH B
PUSH D
PUSH H
ANI 7FH ; strip bit 7
MOV E,A
MVI C,2 ; cp/m fcn 2
CALL BDOS ;
POP H
POP D
POP B
RET
;
; print cr,lf to the console
;
COCRLF: PUSH PSW
MVI A,CR ; carriage return
CALL COUT ; print it
MVI A,LF ; line feed
CALL COUT ; and print it
POP A
RET
;
; subroutine to write a space to the console
;
COSPAC: PUSH PSW
MVI A,SPC ; space
CALL COUT ; and print it
POP PSW
RET
;
; subroutine to write bytes addressed by hl, terminated by last byte with
; 80 bit set.
;
COSTR MOV A,M ; get byte
CALL COUT ; print
MOV A,M ; again and test
RLC ; for bit 7 set
RC ; yes, return
INX H ; next byte
JMP COSTR ; and continue
;
; bios service, offset in 'a'
;
BIOS: PUSH B
PUSH D
LHLD BOOT+1 ; get warm boot address
ADD L ; add offset to wboot
MOV L,A ; to address of service
PUSH H ; save it
LXI H,BIORET ; return address
XTHL
PCHL
;
BIORET: POP D
POP B
RET
;
; message strings
;
DSPLAY:
DB 'DPB table for drive '
DRIVE: DS 1
DB ':',CR,LF
DB 'SPT: '
SPT: DS 4
DB 'H',TAB,'Sectors per track.',cr,lf
DB 'BSH: '
BSH: DS 2
DB 'H',TAB,'Block shift.',cr,lf
DB 'BLM: '
BLM: DS 2
DB 'H',TAB,'Block mask.',cr,lf
DB 'EXM: '
EXM: DS 2
DB 'H',TAB,'Extent mask.',cr,lf
DB 'DSM: '
DSM: DS 4
DB 'H',TAB,'Disk size-1.',cr,lf
DB 'DRM: '
DRM: DS 4
DB 'H',TAB,'Directory entries-1.',cr,lf
DB 'ASV0: '
ALV0: DS 2
DB 'H',TAB,'Directory group allocation 0.',cr,lf
DB 'ALV1: '
ALV1: DS 2
DB 'H',TAB,'Directory group allocation 1.',cr,lf
DB 'CKS: '
CKS: DS 4
DB 'H',TAB,'Check size.',cr,lf
DB 'OFF: '
OFF: DS 4
DB 'H',TAB,'Offset (number of reserve tracks).',cr,lf,lf
;
DMPMSG: DB '"DPB address and hex dump of table."'
DB CR,LF+80H
;
NXLATE: DB BELL,'Diskette needs no translation.',cr,lf+80h
;
TBLMSG: DB 'Skew table decimal values.',cr,lf+80h
;
DPH: DB ': (DPH address)',CR,LF+80H
; User help
;
HLPMSG: DB 'DISKPRAM.COM - <H E L P>',CR,LF,LF
DB 'Syntax:',CR,LF
DB 'A0>DISKPRAM <cr> - DPB and SKEW table for defalt drive',CR,LF
DB 'A0>DISKPRAM d: - Tables for selected drive',CR,LF
DB 'A0>DISKPRAM ? or / - Displays this message',CR,LF
;
DB CR,LF,'This program is designed to provide the user with a tool'
DB CR,LF,'that is able to display the DPB and SKEW table of a CP/M'
DB CR,LF,'2.2 system. This information can be used as the decimal'
DB CR,LF,'input for a program such as ESET.COM written for the AMPRO'
DB CR,LF,'system. With ESET the AMPRO''s E: drive may be used to read'
DB CR,LF,'and write alien 5" diskette formats',CR,LF,LF+80H
;
NRECS: DS 2
NPRINT: DS 1
DPHADR: DS 2
POSIT: DS 1
LAST: DS 2
;
DS 30
STACK: EQU $
;
END