; ; DISK UTILITY - DU.ASM ; (revised 8/12/80) ; ;DU.ASM 8/6/78 BY WARD CHRISTENSEN ;11/12/78 ADD LOGIN COMMAND ;11/26/78 ADD DISK # TO LOGIN COMMAND ;02/25/79 PUT SECTOR READ INTO "S" COMMAND ;03/15/79 ADD CHANGES FOR CP/M ON MICROPOLIS ; FIX WRAP-AROUND FROM TRACK 0 TO TRACK 76 ; ON MINUS COMMAND. ; (BY KEITH PETERSEN, W8SDZ) ;03/18/79 ADD CHANGES TO CALCGRP ROUTINE TO ALLOW ; FOR CONDITIONAL ASSEMBLY FOR CP/M ON ; MICROPOLIS. (KBP) ;09/04/79 ADD REGISTER SAVES TO DIRECT VECTOR ; CALLS. REMOVE UNUSED MACRO. DELETED ; SEVERAL UNUSED ROUTINES. (KBP) ;11/27/79 ADD CHANGES FOR DIGITAL MICROSYSTEMS ; DOUBLE DENSITY USING THE FDC3 CONTROLLER ; BOARD, AND NORTHSTAR DOUBLE DENSITY (KBP) ;12/04/79 CORRECT ERROR IN GROUP NUMBER DISPLAY FOR ; NORTHSTAR DOUBLE DENSITY. (KBP) ; ;02/16/80 CORRECT VERSION 2.0 INCOMPATIBILITY IN 'F' COMMAND ; CHANGE DISPLAY TO SHOW BOTH RELATIVE AND PHYSICAL SECTOR ; (BRUCE RATOFF, ACGNJ) ; ;07/01/80 ADD CHANGES FOR THINKER TOYS DJ2D CONTROLLER AND ; 1024 BYTE DOUBLE DENSITY SECTORS ; (Jeff Hammersley) ; ;08/12/80 ADD CHANGES FOR MICROMATION SINGLE-SIDED DBL DENSITY ; FORMAT - NOTE - FOR TRACKS 2-76 ONLY (TRACKS 0 & 1 ; ARE SINGLE DENSITY) (CHARLES STROM) ; ; STDCPM EQU 0 ;TRUE IF STANDARD CP/M MICROP EQU 0 ;TRUE IF MICROPOLIS CP/M DIGDBL EQU 0 ;TRUE IF DIGITAL MICROSYSTEMS DBL DENS NSDBL EQU 0 ;TRUE IF NORTHSTAR DBL DENSITY CP/M TTDBL1 EQU 0 ;TRUE IF THINKER TOYS DBL DENSITY ; 1024 byte sectors MMDBL EQU 1 ;TRUE IF MICROMATION DBL DENSITY ; CR EQU 0DH LF EQU 0AH ; ;Functions supported: ; ; Tnn Seek to track nn (no read) ; Snn Position to sector nn, and read ; Gnn Position to group nn and read. ; Fname print directory for file "name" ; N-O-T-E this is not a direct disk ; read, so the W command MAY NOT be ; executed after 'F'. (must do G, + ; or - command first) ; ; L Logs in the disk (used if a disk other ; than the one DU resides on, is placed ; in the system) ; ; Ln Logs in disk 'n', such as: LA ; ; D Dump sector, hex + ASCII ; A Dump sector, ASCII only ; H Dump sector, hex only ; ;note all dump commands (D, A, H) may be optionally ; followed by a starting and ending address: ; D0,7F is the same as just D ; D3,5 ; A20,3F ; ; CHaddr,val,val,val... change hex in sector ; CAaddr,char string... change ASCII in sector ; (must W to have changes written to disk) ;Note that the C command echoes the overlaid data for ; verification ; ; + advance 1 sector (if below track 2, ; this advances to next numerical, if ; 2 or >, advances based on CP/M's normal ; sector scrambling algorithm, i.e. so + ; will get the next logical sector of the file ; - backs up 1 logical sector ; ; note + and - may take an amount: ; for example, +F steps in 15 sectors ; ; ? Says what sector, track, and group ; are current ; R Reads the sector currently positioned to ; into memory. Note R (Read) is implicit in ; the G, +, and - commands, but N-O-T in the ; S and T commands (I did it because I was ; tired of disk reading after T command before ; I had a chance to issue the S command) ; W Write back the current sector (N-O-T-E may ; not be used after an F command, as CP/M was ; used to find the file in the directory ; X Exit back to CP/M (Must press return). Ctl-c ; was too easy to hit over modem lines, so I ; decided on 2-byte (X, CR) to exit. ; ; ORG 100H ; LXI SP,STACK ;SET UP LOCAL JMPS TO BIOS LHLD 1 LXI D,3 DAD D SHLD VCONST+1 DAD D SHLD VCONIN+1 DAD D SHLD VCONOUT+1 DAD D ;LIST DAD D ;PUNCH DAD D ;RDR DAD D ;HOME DAD D ;SEL DISK DAD D SHLD VSETTRK+1 DAD D SHLD VSETSEC+1 DAD D ;SETDMA DAD D SHLD VREAD+1 DAD D SHLD VWRITE+1 CALL ILPRT DB 'DISK UTIL 7/01/80',CR,LF IF STDCPM DB 'Standard CP/M Version' ENDIF IF MICROP DB 'Micropolis Version' ENDIF IF DIGDBL DB 'DD Digital Microsystems Version' ENDIF IF NSDBL DB 'DD Northstar Version' ENDIF IF TTDBL1 DB 'Thinker Toys DBL Density (1024 byte sectors)' ENDIF IF MMDBL DB 'Micromation DBL Density (Tracks 2-76 ONLY!)' ENDIF DB CR,LF,0 PROMPT LXI SP,STACK CALL RDBUF LXI H,INBUF MOV A,M INX H CPI 'T' JZ POS CPI 'S' JZ POS CPI 'G' JZ POS CPI 'F' JZ POSFIL CPI 'L' JZ LOGIN CPI 'D' JZ DUMP CPI 'A' JZ DUMP CPI 'H' JZ DUMP CPI 'C' JZ CHG CPI '+' JZ PLUS CPI '-' JZ MINUS CPI '?' JZ INQ CPI 'R' JZ DOREAD CPI 'W' JZ DOWRITE CPI 'X' JZ 0 WHAT CALL ILPRT DB '?',0 JMP PROMPT ; LOGIN MVI C,RESETDK CALL BDOS LDA INBUF+1 ;DISK REQ? LXI D,0 CPI CR JZ LGNODK SUI 'A' MOV E,A LGNODK MVI C,SELDK CALL BDOS CALL NOWRITE JMP PROMPT ; NOWRITE XRA A ;GET 0 STA WRFLG ;CAN'T WRITE NOW RET ; DUMP LDA WRFLG ORA A JNZ DUMPOK CALL ILPRT DB '++CAN''T DUMP, NO SECTOR READ.',CR,LF,0 EXPL CALL ILPRT DB 'USE G COMMAND FOLLOWING F,',CR,LF DB 'OR R FOLLOWING S OR T',CR,LF,0 JMP PROMPT ; DUMPOK MOV A,M CPI CR JNZ DUMPNDF ;USE DEFAULT LXI B,0 LXI D,7FH JMP DUMP1 ; DUMPNDF CALL HEXIN MOV B,D MOV C,E CPI CR JZ DUMP1 INX H ;SKIP ',' CALL HEXIN ; ;BC = START, DE = END ; DUMP1 MOV A,B ORA D JNZ WHAT MOV A,C ORA E JM WHAT ;>7FH MOV H,B MOV A,C ORI 80H MOV L,A MOV A,E ORI 80H MOV E,A DUMPLP MOV A,L ANI 7FH CALL HEX CALL SPACE CALL SPACE LDA INBUF CPI 'A' JZ DUMPAS PUSH H ;SAVE START DHEX MOV A,M CALL HEX MOV A,L ANI 3 CPI 3 CZ SPACE MOV A,L ANI 7 CPI 7 CZ SPACE MOV A,E CMP L JZ DPOP INX H MOV A,L ANI 0FH JNZ DHEX DPOP LDA INBUF CPI 'H' JZ DNOAS ;HEX ONLY POP H ;GET START ADDR DUMPAS CALL ASTER DCHR MOV A,M CPI ' ' JC DPER CPI 7FH JC DOK DPER MVI A,'.' DOK CALL TYPE MOV A,E CMP L JZ DEND INX H MOV A,L ANI 0FH JNZ DCHR DEND CALL ASTER CALL CRLF CALL CONST ORA A JNZ PROMPT MOV A,E CMP L JZ PROMPT JMP DUMPLP ; DNOAS POP B CALL CRLF MOV A,E CMP L JZ PROMPT JMP DUMPLP ; ;POSITION ; POS PUSH PSW CALL NOWRITE MOV A,M CPI CR JZ WHAT CALL HEXIN POP PSW CPI 'T' JZ POSTRK CPI 'S' JZ POSSEC CPI 'G' JZ POSGRP JMP WHAT ; POSTRK MOV A,E CALL SETTRK JMP CALCGRP ; POSSEC MOV A,E ORA A JZ WHAT ; IF STDCPM CPI 27 ENDIF ; IF MICROP CPI 33 ENDIF ; IF DIGDBL CPI 59 ENDIF ; IF NSDBL CPI 41 ENDIF ; IF TTDBL1 CPI 65 ENDIF ; IF MMDBL CPI 53 ENDIF ; JNC WHAT CALL SETSEC CALL READ ; CALCGRP LDA CURTRK SUI 2 ;GRP 0 IS TRK 2 MOV L,A MVI H,0 MOV D,H MOV E,L DAD H ;X2 ; IF STDCPM DAD D ;X3 DAD H ;X6 DAD H ;X12 DAD D ;X13 DAD H ;X26 ENDIF ; IF MICROP DAD H ;X4 DAD H ;X8 DAD H ;X16 DAD H ;X32 ENDIF ; IF DIGDBL DAD D ;X3 DAD H ;X6 DAD D ;X7 DAD H ;X14 DAD H ;X28 DAD D ;X29 DAD H ;X58 ENDIF ; IF NSDBL DAD H ;X4 DAD H ;X8 DAD D ;X9 DAD D ;X10 DAD H ;X20 DAD H ;X40 ENDIF ; IF TTDBL1 DAD H ;X4 DAD H ;X8 DAD H ;X16 DAD H ;X32 DAD H ;X64 ENDIF ; IF MMDBL DAD D ;X3 DAD H ;X6 DAD H ;X12 DAD D ;X13 DAD H ;X26 DAD H ;X52 ENDIF ; LDA CURSEC DCR A ADD L MOV L,A MOV A,H ACI 0 MOV H,A MOV A,L ; IF STDCPM OR NSDBL ANI 07H ENDIF ; IF MICROP OR DIGDBL OR TTDBL1 OR MMDBL ANI 0FH ENDIF ; STA DISP DAD H DAD H DAD H DAD H ; IF STDCPM OR NSDBL DAD H ENDIF ; MOV A,H STA GROUP JMP INQ ; POSGRP MOV A,E STA GROUP XRA A STA DISP MOV L,E ;MULTIPLY MVI H,0 ;BY 8 DAD H DAD H DAD H ; IF MICROP OR DIGDBL OR TTDBL1 OR MMDBL DAD H ;MULTIPLY BY 16 INSTEAD OF 8 ENDIF ; IF STDCPM ;DIVIDE BY 26, QUOTIENT = TRK, REMAINDER = SECTOR LXI D,-26 ENDIF ; IF MICROP ;DIVIDE BY 32, QUOTIENT = TRK, REMAINDER = SECTOR LXI D,-32 ENDIF ; IF DIGDBL ;DIVIDE BY 58, QUOTIENT = TRK, REMAINDER = SECTOR LXI D,-58 ENDIF ; IF NSDBL ;DIVIDE BY 40, QUOTIENT = TRK, REMAINDER = SECTOR LXI D,-40 ENDIF ; IF TTDBL1 ;DIVIDE BY 64, QUOTIENT = TRK, REMAINDER = SECTOR LXI D,-64 ENDIF ; IF MMDBL ;DIVIDE BY 52, QUOTIENT = TRK, REMAINDER = SECTOR LXI D,-52 ENDIF ; MVI B,0 ;TRK DIVLP INR B DAD D JC DIVLP DCR B ; IF STDCPM LXI D,26 ENDIF ; IF MICROP LXI D,32 ENDIF ; IF DIGDBL LXI D,58 ENDIF ; IF NSDBL LXI D,40 ENDIF ; IF TTDBL1 LXI D,64 ENDIF ; IF MMDBL LXI D,52 ENDIF ; DAD D MOV A,B ADI 2 ;GROUP 0 IS TRK 2 CALL SETTRK MOV A,L INR A CALL SETSEC CALL READ JMP INQ ; POSFIL CALL NOWRITE LXI D,FCB XRA A STAX D INX D MVI B,8 CALL MVNAME MVI B,3 CALL MVNAME LXI D,FCB MVI C,SEARCHF ;USED TO BE OPEN - DIDN'T WORK IN 2.0 CALL BDOS INR A JNZ FLOK CALL ILPRT DB '++FILE NOT FOUND',0 JMP PROMPT ; FLOK DCR A ANI 3 MOV L,A MVI H,0 DAD H DAD H DAD H DAD H DAD H LXI D,80H DAD D LXI D,32 XCHG DAD D XCHG MVI A,'I' STA INBUF+1 JMP DUMPLP ; MVNAME MOV A,M CPI '.' JZ MVIPAD CPI CR JZ PAD STAX D INX H INX D DCR B JNZ MVNAME MOV A,M CPI CR RZ INX H CPI '.' RZ JMP WHAT ; MVIPAD INX H PAD MVI A,' ' STAX D INX D DCR B JNZ PAD RET ; PLUS LXI D,1 MOV A,M CPI CR JZ PLUSGO CALL HEXIN PLUSGO LDA CURSEC INR A ; IF STDCPM CPI 27 ENDIF ; IF MICROP CPI 33 ENDIF ; IF DIGDBL CPI 59 ENDIF ; IF NSDBL CPI 41 ENDIF ; IF TTDBL1 CPI 65 ENDIF ; IF MMDBL CPI 53 ENDIF ; JNZ PLUSOK LDA CURTRK INR A STA CURTRK MVI A,1 PLUSOK STA CURSEC DCR E JNZ PLUSGO PLUSMI LDA CURSEC CALL SETSEC LDA CURTRK CALL SETTRK CALL READ JMP CALCGRP ; MINUS LXI D,1 MOV A,M CPI CR JZ MINGO CALL HEXIN MINGO LDA CURSEC DCR A JNZ MINOK LDA CURTRK DCR A STA CURTRK ; IF STDCPM MVI A,26 ENDIF ; IF MICROP MVI A,32 ENDIF ; IF DIGDBL MVI A,58 ENDIF ; IF NSDBL MVI A,40 ENDIF ; IF TTDBL1 MVI A,64 ENDIF ; IF MMDBL MVI A,52 ENDIF ; MINOK STA CURSEC DCR E JNZ MINGO JMP PLUSMI ; INQ LDA CURTRK CPI 2 JC NOGRP CALL ILPRT DB 'G=',0 LDA GROUP CALL HEX MVI A,':' CALL TYPE LDA DISP ; IF STDCPM OR NSDBL ORI '0' CALL TYPE ENDIF ; IF MICROP OR DIGDBL OR TTDBL1 OR MMDBL CALL HEX ENDIF ; MVI A,',' CALL TYPE NOGRP CALL ILPRT DB ' T=',0 LDA CURTRK CALL HEX CALL ILPRT DB ', RS=',0 ;DISPLAY RELATIVE SECTOR # LDA CURSEC CALL HEX CALL ILPRT ;DISPLAY PHYSICAL (MAPPED) SECTOR # DB ', PS=',0 LDA MAPSEC CALL HEX JMP PROMPT ; CHG MOV A,M ;GET TYPE (HEX, ASCII) PUSH PSW INX H CALL HEXIN INX H CPI ',' JNZ WHAT MOV A,D ORA A JNZ WHAT MOV A,E ORA A JM WHAT ORI 80H MOV E,A ;POINT TO BUFFER POP PSW CPI 'H' JZ CHGHEX CPI 'A' JNZ WHAT ;CHANGE ASCII CHGALP MOV A,M CPI CR JZ PROMPT LDAX D CPI ' ' JC CHGAHX CPI 7FH JNC CHGAHX JMP CHGA2 CHGAHX MVI A,'(' CALL TYPE LDAX D CALL HEX MVI A,')' CHGA2 CALL TYPE MOV A,M STAX D INX H INR E JNZ CHGALP MOV A,M CPI CR JZ PROMPT JMP WHAT ; ;CHANGE HEX CHGHEX MOV A,M CPI CR JZ PROMPT PUSH D CALL HEXIN MOV A,E POP D PUSH PSW LDAX D CALL HEX POP PSW STAX D MOV A,M CPI CR JZ PROMPT CPI ',' INX H INR E JNZ CHGHEX MOV A,M CPI CR JZ PROMPT JMP WHAT ; DOREAD CALL READ JMP PROMPT ; DOWRITE CALL WRITE JMP PROMPT ; HEX PUSH PSW RAR RAR RAR RAR CALL NIBBL POP PSW NIBBL ANI 0FH CPI 10 JC HEXNU ADI 7 HEXNU ADI '0' JMP TYPE ; SPACE MVI A,' ' JMP TYPE ; ASTER MVI A,'*' JMP TYPE ; ILPRT XTHL ILPLP MOV A,M CALL TYPE INX H MOV A,M ORA A JNZ ILPLP INX H XTHL RET ; HEXIN LXI D,0 HINLP MOV A,M CPI CR RZ CPI ',' RZ CPI '0' JC WHAT CPI '9'+1 JC HINNUM CPI 'A' JC WHAT CPI 'F'+1 JNC WHAT SUI 7 HINNUM SUI '0' XCHG DAD H DAD H DAD H DAD H ADD L MOV L,A XCHG INX H JMP HINLP ; RDBUF CALL ILPRT DB CR,LF,':',0 LXI H,INBUF MVI B,0 RDBLP CALL CONIN CPI 'U'-40H JZ RDCTLU CPI CR JZ RDCR CPI 8 JZ RDBS CPI 7FH JZ RDBS CPI 'R'-40H JZ RDCTLR MOV M,A INX H INR B CALL TYPE JMP RDBLP ; RDCR MOV M,A CALL TYPE MVI A,LF CALL TYPE RET ; RDBS XRA A ORA B JZ RDCTLU DCX H DCR B MOV A,M CALL TYPE JMP RDBLP ; RDCTLR MVI M,CR CALL CRLF LXI H,INBUF MVI B,0 RDCRL MOV A,M CPI CR JZ RDBLP CALL TYPE INR B INX H JMP RDCRL ; RDCTLU MVI A,'^' CALL TYPE MVI A,'U' CALL TYPE JMP RDBUF ; CRLF MVI A,CR CALL TYPE MVI A,LF JMP TYPE ; CONST: PUSH B PUSH D PUSH H VCONST CALL $-$ ;MODIFIED BY INIT POP H POP D POP B RET ; CONIN: PUSH B PUSH D PUSH H VCONIN CALL $-$ ;MODIFIED BY INIT POP H POP D POP B RET ; TYPE: PUSH B PUSH D PUSH H MOV C,A ;FOR CONOUT VCONOUT CALL $-$ ;MODIFIED BY INIT POP H POP D POP B RET ; SETTRK EQU $ IF STDCPM OR MICROP OR DIGDBL OR TTDBL1 OR MMDBL CPI 77 ;TRAP OUT MORE THAN 77 ENDIF ; IF NSDBL CPI 35 ;TRAP OUT MORE THAN 34 ENDIF ; JC SETTRK2 ; IF STDCPM OR MICROP OR DIGDBL OR TTDBL1 OR MMDBL MVI A,76 ;77TH TRACK IS 76 ENDIF ; IF NSDBL MVI A,34 ;35TH TRACK IS 34 ENDIF ; SETTRK2 STA CURTRK PUSH B PUSH D PUSH H MOV C,A VSETTRK CALL $-$ ;MODIFIED BY INIT POP H POP D POP B RET ; SETSEC PUSH B PUSH D PUSH H STA CURSEC MOV C,A LDA CURTRK CPI 2 JC XSETSEC ;DON'T SCRAMBLE TRK'S 0-1 LXI H,SECTBL-1 MOV A,C ADD L MOV L,A MOV A,H ACI 0 MOV H,A MOV C,M XSETSEC MOV A,C ;REMEMBER MAPPED SECTOR # FOR INQ STA MAPSEC VSETSEC CALL $-$ ;MODIFIED BY INIT POP H POP D POP B RET ; READ: PUSH B PUSH D PUSH H MVI A,1 STA WRFLG VREAD CALL $-$ ;MODIFIED BY INIT POP H POP D POP B RET ; WRITE: LDA WRFLG ORA A JNZ WRITE2 CALL ILPRT DB '++CANNOT WRITE UNLESS READ ISSUED' DB CR,LF,0 JMP EXPL ; WRITE2 PUSH B PUSH D PUSH H VWRITE CALL $-$ ;MODIFIED BY INIT POP H POP D POP B RET ; IF STDCPM SECTBL DB 1,7,13,19,25,5,11,17,23,3,09,15,21 DB 2,8,14,20,26,6,12,18,24,4,10,16,22 ENDIF ; IF MICROP SECTBL DB 1,2,11,12,21,22,31,32,9,10,19,20,29,30,7,8 DB 17,18,27,28,5,6,15,16,25,26,3,4,13,14,23,24 ENDIF ; IF DIGDBL SECTBL DB 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 DB 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33 DB 34,35,36,37,38,39,40,41,42,43,44,45,46,47,48 DB 49,50,51,52,53,54,55,56,57,58 ENDIF ; IF NSDBL SECTBL DB 1,2,3,4,21,22,23,24,5,6,7,8,25,26,27,28 DB 9,10,11,12,29,30,31,32,13,14,15,16 DB 33,34,35,36,17,18,19,20,37,38,39,40 ENDIF ; IF TTDBL1 SECTBL DB 1,2,3,4,5,6,7,8 DB 25,26,27,28,29,30,31,32 DB 49,50,51,52,53,54,55,56 DB 9,10,11,12,13,14,15,16 DB 33,34,35,36,37,38,39,40 DB 57,58,59,60,61,62,63,64 DB 17,18,19,20,21,22,23,24 DB 41,42,43,44,45,46,47,48 ENDIF ; IF MMDBL SECTBL DB 1,14,27,40,10,23,36,49,6,19,32,45,2,15,28,41 DB 11,24,37,50,7,20,33,46,3,16,29,42,12,25,38,51 DB 8,21,34,47,4,17,30,43,13,26,39,52,9,22,35,48 DB 5,18,31,44 ENDIF ; GROUP DB 0 DISP DB 0 CURTRK DB 0 CURSEC DB 1 MAPSEC DB 1 WRFLG DB 0 ;MAY NOT WRITE UNTIL '+', '-', ; OR 'G' COMMAND DS 60 ;ROOM FOR STACK STACK: EQU $ INBUF DS 128 ; FCB EQU 5CH BDOS EQU 5 RESETDK EQU 13 SELDK EQU 14 SEARCHF EQU 17 ; END 100H YG !7wÍ$2w>)Í…(Í7Y*}wå!cw Í->2ew2dw:wþáÊÏ=åÍ/%Íh%W !Ww Í$͇?áÚ™=Í‘(ÃÕ=Ô«:lw·Êè=:cw·õÌñ;ñÄ÷;*ew"gwÍÇ>Í‘5! {Íh;Í->Ò>