; 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 - ',CR,LF,LF DB 'Syntax:',CR,LF DB 'A0>DISKPRAM - 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