TITLE 'FORMAT - CP/M-86 FORMAT UTILITY 08 JUN 83' ;*** ; ; THIS IS THE ZDS CP/M-86 FORMAT UTILITY ; ; COPYRIGHT (C) 1983, ZENITH DATA SYSTEMS CORP. ; ; MODULE GENERATION ; GENCMD FORMAT ; ; ; RESTRICTED RIGHTS LEGEND ; ------------------------ ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; FALSE EQU 0 TRUE EQU NOT FALSE REVSN EQU 0 DSEG INCLUDE CPM86SYS.LIB INCLUDE CIOTABLE.LIB BIOSFLG EQU FALSE INCLUDE BIOSDEF.LIB INCLUDE SBCDEF.LIB INCLUDE Z207DEF.LIB INCLUDE Z217DEF.LIB INCLUDE ZDPEDEF.LIB INCLUDE LABDEF.LIB INCLUDE ASCII.LIB EJECT DSEG ORG 0100H CSEG ORG 0000H MOV AX,DS ;SET UP STACK MOV SS,AX LEA SP,STACK MOV CL,PRCONB ;PRINT SIGNON MESSAGE LEA DX,SIGNON INT BDOSE CALL FGBT ;GET ADDRESS OF BIOS TABLES MOV OSDS,ES CMP ES:BIOSREL[BX],BREL ;Q. CORRECT RELEASE OF BIOS JE FMT0 ; BR IF YES MOV CL,PRCONB LEA DX,BADBIOS INT BDOSE JMP FMT6 FMT0: MOV CL,GMREG ;REQ MEMORY FOR BUFFER LEA DX,MCB INT BDOSE CMP AL,0 JE FMT0A ; BR IF REQ HONORED MOV CL,PRCONB LEA DX,NOMEM INT BDOSE JMP FMT6 FMT0A: CMP TBUFF,0 ;Q. COMMAND LINE PRESENT JE FMT1 ; BR IF NOT CALL CLINT ;INTERPRET COMMAND LINE ; JC FMT6 ; BR IF ERROR JNC $+5 JMP FMT6 FMT1: CMP NOQFLG,0 ;Q. ASK IF THIS IS WHAT USER WANTS JNE FMT2 ; BR IF DON'T ASK MOV CL,PRCONB ;ASK USER LEA DX,SIGNON1 INT BDOSE MOV CL,RDCON INT BDOSE CALL TOUPPER CMP AL,'Y' ;Q. YES REPLY ; JNE FMT6 ; BR IF NOT JE $+5 JMP FMT6 ; GET DRIVE TO FORMAT FMT2: MOV AL,DRIVID ;GET DRIVE (ASSUME COMMAND LINE) CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE FMT2A ; BR IF YES MOV CL,PRCONB ;ASK FOR DRIVE LEA DX,WHICH INT BDOSE MOV CL,RDCON INT BDOSE CMP AL,CTLC ;Q. CTL-C JE FMT5 ; BR IF YES -- ABORT FMT2A: CALL TOUPPER MOV DRIVID,AL MOV DRMSGA,AL MOV PROMPTA,AL CALL WKIND ;DETERMINE DRIVE TYPE JNC FMT2B ; BR IF NO ERROR MOV CL,PRCONB LEA DX,DRMSG INT BDOSE JMPS FMT4 FMT2B: CMP DRIVID,'A' ;Q. SYSTEM DRIVE INVOLVED JNE FMT3 ; BR IF NOT MOV SYSDSK,1 ; OTHERWISE REMEMBER ; FMT3: CALL DISPATCH ;FORMAT DISK JC FMT9 ; BR IF ERROR FMT4: CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE FMT5 ; BR IF YES MOV CL,PRCONB ;ASK IF ANY MORE FORMATTING TO BE DONE LEA DX,AMWMSG INT BDOSE MOV CL,RDCON INT BDOSE CALL TOUPPER CMP AL,'Y' JE FMT2 ;BR IF YES FMT5: CMP SYSDSK,0 ;Q. SYSTEM DISK INVOLVED JE FMT6 ; BR IF NOT MOV CL,PRCONB ;WAIT FOR SYSTEM TO DISK TO BE LEA DX,LVEMSG ; REINSERTED INT BDOSE MOV CL,RDCON INT BDOSE FMT6: MOV CL,RDS ;RESET DISK SUBSYSTEM INT BDOSE MOV CL,RESET ;WARM BOOT XOR DL,DL INT BDOSE ; ERROR DURING FORMATTING FMT9: CALL FWPC ;Q. DISK WRITE PROTECTED LEA DX,WPEMSG CMP AL,0 JNE FMT9A ; BR IF YES LEA DX,BMSG FMT9A: MOV CL,PRCONB ;PRINT ERROR MESSAGE INT BDOSE JMPS FMT4 EJECT ;** FORMAT Z207. ; F207: MOV AL,'D' ;5 1/4" DRIVE USE DOUBLE DENSITY TEST AIOUNI,CONDS8 JZ F2072 ;BR IF 5 1/4" DRIVE F2071: MOV AL,CLIDENS ;GET DENSITY (ASSUME COMMAND LINE) CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE F2072 ; BR IF YES MOV CL,PRCONB ;ASK FOR DENSITY LEA DX,WDSDMSG INT BDOSE MOV CL,RDCON INT BDOSE F2072: CALL TOUPPER MOV AH,0 ;ASSUME SINGLE DENSITY CMP AL,'S' ;Q. SINGLE DENSITY JE F2073 ; BR IF YES MOV AH,DPEDD ;DOUBLE DENSITY CMP AL,'D' ;Q. DOUBLE DENSITY JE F2073 ; BR IF YES MOV CL,PRCONB LEA DX,ERRMSG INT BDOSE CMP COMLIN,0 JE F2071 JMP F20749 F2073: MOV DENSITY,AH ;SAVE DENSITY MOV AL,'2' ;ASSUME DOUBLE SIDED TEST AIOUNI,CONDS8 ;Q. 8" DRIVE JNZ F2075 ; BR IF YES F2074: MOV AL,CLISIDS ;GET SIDES (ASSUME COMMAND LINE) CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE F2075 ; BR IF YES MOV CL,PRCONB ;ASK FOR # SIDES LEA DX,WSMSG INT BDOSE MOV CL,RDCON INT BDOSE F2075: MOV AH,0 ;ASSUME SINGLE SIDED CMP AL,'1' ;Q. SINGLE SIDED JE F2076 ; BR IF YES MOV AH,DPE2S ;ASSUME DOUBLE SIDED CMP AL,'2' ;Q. DOUBLE SIDED JE F2076 ; BR IF YES MOV CL,PRCONB LEA DX,ERRMSG INT BDOSE CMP COMLIN,0 JE F2074 JMP F20749 F2076: MOV SIDES,AH ;SAVE # SIDES CMP NOQFLG,0 ;Q. NO QUERY SWITCH SET JNE F2077 ; BR IF YES MOV CL,PRCONB ;ASK TO INSERT DISK LEA DX,PROMPT INT BDOSE MOV CL,PRCONB ;ASK IF READY LEA DX,PROMPT1 INT BDOSE MOV CL,RDCON INT BDOSE CMP AL,CR ;Q. ; JNE F20748 ; BR IF NOT JE $+5 JMP F20748 F2077: CALL F20770 ;FILL IN DPE & DPB MOV TRACK,0 ;CLEAR WORK VALUES MOV AX,NTRK837 ;DETERMINE # CP/M TRACKS TEST AIOUNI,CONDS8 JNZ F2078 MOV AX,NTRKS37 TEST DRTYPE,DPE96T JZ F2078 MOV AX,NTRKD37 F2078: CMP SIDES,DPE2S JNE F2079 SHL AX,1 F2079: MOV DSKTKS,AX LES BX,DWORD PTR DPEPTR ;FORCE RESTORE BY SETTING TRACK POINTER MOV ES:DPETRK[BX],DPEUNK ; TO UNKOWN ; IF 8" DRIVE AND TRACK 0 / SIDE 0 IS SINGLE DENSITY ; THEN FORMAT TRACK 0 / SIDE 0 TEST AIOUNI,CONDS8 ;Q. 8" DRIVE JZ F20740 ; BR IF NOT TEST DRTYPE,DPET0SD ;Q. CP/M TRACK 0 SINGLE DENSITY JZ F20740 ; BR IF NOT LEA SI,F207STBL ;BUILD TRACK IMAGE CALL F20780 CALL F20750 ;FORMAT TRACK CMP AL,0 ;Q. ERROR JNE F20749 ; BR IF ERROR ; FORMAT SURFACE(S) F20740: LEA SI,F207D2TB ;DETERMINE WHICH TABLE TO USE TEST AIOUNI,CONDS8 ; TO BUILD TRACK IMAGE JZ F20741 LEA SI,F207STBL CMP DENSITY,DPEDD JNE F20741 LEA SI,F207DTBL F20741: CALL F20780 ;BUILD TRACK IMAGE F20742: CALL F20750 ;FORMAT TRACK CMP AL,0 ;Q. ERROR JE F20743 ; BR IF NOT CMP AL,FDSNRD ;IF NOT READY ERROR ON 8" DRIVE AND JNE F20749 ; TRYING TO FORMAT DOUBLE SIDED, THEN TEST AIOUNI,CONDS8 ; SWITCH TO SINGLE SIDED AND JZ F20749 ; TRY AGAIN CMP TRACK,1 JNE F20749 CMP SIDES,DPE2S JNE F20749 MOV SIDES,0 JMP F2077 ; F20743: MOV AX,TRACK ;Q. ALL TRACKS DONE CMP AX,DSKTKS JNE F20742 ; BR IF NOT ; FORM LABEL AND WRITE IT TO TRACK 0 / SECTOR 1 / SIDE 0 CALL WRLAB JC F20749 ;BR IF ERROR ; ALL DONE F20748: CLC ;INDICATE NO ERROR RET ; ERROR F20749: STC ;INDICATE ERROR RET ;* FORMAT TRACK F20750: CALL F20790 ;SET TRACK/SIDE/SECTOR VALUES IN TRACK IMAGE MOV CX,TRACK ;SET DESIRED CP/M TRACK # CALL FSETTRK MOV CX,0 ;SET DMA OFFSET CALL FSETDMA MOV CX,BUFFER ;SET DMA SEGMENT CALL FSETDMAS MOV CL,1 ;ASSUME VERIFY CMP FAST,0 ;Q. FAST JE F20751 ; BR IF NOT MOV CL,0 ; NO VERIFY F20751: CALL FFORMAT ;FORMAT TRACK CMP AL,0 ;Q. ERROR JNE F20752 ; BR YES INC TRACK ;BUMP TRACK COUNTER F20752: RET ;* FILL DPE & DPB F20770: MOV AL,0 ;DETERMINE WHICH TABLE TO USE TEST AIOUNI,CONDS8 JNZ F20771 TEST DRTYPE,DPE96T JZ F20772 MOV AL,2 JMPS F20772 F20771: MOV AL,4 CMP DENSITY,DPEDD JNE F20772 MOV AL,6 F20772: CMP SIDES,DPE2S JNE F20773 INC AL F20773: MOV AH,F207TBLL MUL AH ADD AX,OFFSET F207TBL MOV SI,AX ;(SI)=TABLE ADDRESS LES BX,DWORD PTR DPEPTR ;GET ADDRESS OF DPE CLD LODSB ;DPE FLAG BYTE 1 AND ES:DPEFLAG[BX],NOT (DPE48RO+DPEDD+DPE2S) OR ES:DPEFLAG[BX],AL TEST AIOUNI,CONDS8 ; Q. 8" DRIVE JZ F20774 ; BR IF NOT AND ES:DPEFLAG[BX],NOT DPET0SD AND DRTYPE,NOT DPET0SD CMP DENSITY,DPEDD ; Q. DOUBLE DENSITY REQUESTED JNE F20774 ; BR IF NOT CMP CLID0,0 ; Q. FORMAT TRACK 0 DOUBLE DENSITY JNE F20774 ; BR IF YES OR ES:DPEFLAG[BX],DPET0SD ; SET FLAG FOR TRACK 0 SINGLE DENSITY OR DRTYPE,DPET0SD F20774: LODSB ;CP/M RECORDS PER SECTOR MOV ES:DPERPS[BX],AL LODSB ;CP/M RECORDS PER ALLOCATION BLOCK MOV ES:DPERPAB[BX],AL LODSB ;MEDIA TPI AND ES:DPEFLG2[BX],NOT DPE96TM OR ES:DPEFLG2[BX],AL LES DI,DWORD PTR DPBPTR ;FILL IN DPB MOV CX,DPBL CLD REP MOVSB RET ;* BUILD TRACK IMAGE F20780: CLD LODSB ;SPT MOV DSKSPT,AL MOV DI,0 ;START OF TRACK IMAGE MOV ES,BUFFER F20781: LODSB ;FILL IN FRONT END GAP CMP AL,0 ;Q. END OF FRONT END GAP INFO JE F20782 ; BR IF YES XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20781 F20782: MOV F207B,DI MOV F207C,0 MOV F207D,0 MOV DL,DSKSPT ;GET SECTORS PER TRACK MOV BX,SI ;REMEMBER START OF SECTOR DESCRIPTORS F20783: MOV SI,BX ;FILL IN FOR A SECTOR F20784: LODSB CMP AL,0 JNE F20784A ; BR IF NOT TRACK # MARKER CMP F207C,0 ; Q. TRACK OFFSET DETERMINED JNE F20784B ; BR IF YES MOV F207C,DI ; OTHERWISE SAVE TRACK OFFSET JMPS F20784B F20784A: XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20784 F20784B: LODSB CMP AL,0 JNE F20784C ; BR IF NOT END OF SECTOR MARKER CMP F207D,0 ; Q. LENGTH OF SECTOR DETERMINED JNE F20785 ; BR IF YES MOV AX,DI ; OTHERWISE CALC LENGTH SUB AX,F207B MOV F207D,AX JMPS F20785 F20784C: XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20784B F20785: DEC DL ;Q. ALL SECTORS DONE JNZ F20783 ; BR IF NOT F20786: LODSB ;FILL REQUIRED GAP IV AMOUNT XOR CH,CH MOV CL,AL LODSB REP STOSB F20787: LODSB ;FILL OPTIONAL GAP IV AMOUNT CMP AL,0 JE F20788 XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20787 F20788: RET ;* FILL IN TRACK/SIDE/SECTOR VALUES FOR THIS ITERATION IN TRACK IMAGE F20790: MOV DX,TRACK ;CALCULATE PHYSICAL TRACK/SIDE VALUES XOR DH,DH CMP SIDES,DPE2S JNE F20791 SHR DL,1 JNC F20791 MOV DH,1 F20791: MOV DI,F207C MOV ES,BUFFER CLD XOR CH,CH MOV CL,DSKSPT MOV BL,1 F20792: MOV SI,DI MOV AX,DX STOSW MOV AL,BL STOSB INC BL MOV DI,SI ADD DI,F207D LOOP F20792 F20793: RET ;* DSEG $ F207B RW 1 ;ADDR OF 1ST SECTOR IN BUFFER F207C RW 1 ;OFFSET INTO 1ST SECTOR OF TRACK # F207D RW 1 ;SIZE OF SECTOR F207STBL RB 0 ;8" SINGLE DENSITY TRACK FORMAT TABLE DB 26 ; SECTORS PER TRACK DB 40,0FFH ; TRACK HEADER GAP DB 6,0 DB 1,0FCH DB 26,0FFH DB 0 DB 6,0 ; SECTOR AREA (REPEAT FOR SPT) DB 1,0FEH DB 0 ; TRACK # OFFSET MARKER DB 4,0 DB 1,0F7H DB 11,0FFH DB 6,0 DB 1,0FBH DB 128,0E5H DB 1,0F7H DB 27,0FFH DB 0 DB 24,0FFH ; REQUIRED GAP IV AMOUNT DB 255,0FFH ; OPTIONAL GAP IV AMOUNT DB 124,0FFH DB 0 F207DTBL RB 0 ;8" DOUBLE DENSITY 26X256 TRACK FORMAT DB 26 DB 80,04EH DB 12,0 DB 3,0F6H DB 1,0FCH DB 50,04EH DB 0 DB 12,0 DB 3,0F5H DB 1,0FEH DB 0 DB 3,0 DB 1,1 DB 1,0F7H DB 22,04EH DB 12,0 DB 3,0F5H DB 1,0FBH DB 128,0E5H DB 128,0E5H DB 1,0F7H DB 54,04EH DB 0 DB 24,04EH DB 255,04EH DB 255,04EH DB 255,04EH DB 121,04EH DB 0 F207D2TB RB 0 ;5 1/4" FORMAT TABLE DB 8 DB 80,04EH DB 12,0 DB 3,0F6H DB 1,0FCH DB 50,04EH DB 0 DB 12,0 DB 3,0F5H DB 1,0FEH DB 0 DB 3,0 DB 1,2 DB 1,0F7H DB 22,04EH DB 12,0 DB 3,0F5H DB 1,0FBH DB 128,0E5H DB 128,0E5H DB 128,0E5H DB 128,0E5H DB 1,0F7H DB 80,04EH DB 0 DB 24,04EH DB 255,04EH DB 255,04EH DB 255,04EH DB 255,04EH DB 15,04EH DB 0 ; Z207 DISK DESCRIPTORS FOR LABEL ; ; DB DENSITY/SIDES FLAGS ; DB CP/M RECORDS PER SECTOR ; DB CP/M RECORDS PER ALLOCATION BLOCK ; DB MEDIA TPI FLAG ; DW SECTORS PER TRACK ; DB BLOCK SHIFT FACTOR ; DB BLOCK MASK ; DB EXTENT MASK ; DW # OF BLOCKS - 1 ; DW # OF DIRECTORY ENTRIES - 1 ; DW AL1*256+AL0 ; DW LENGTH OF CHECKSUM VECTOR ; DW # OF SYSTEM TRACKS ; F207TBL RB 0 ;5 1/4" DOUBLE DENSITY (8X512)/SINGLE SIDED/48 TPI DB DPEDD,4,8,0 DW 32 DB 3,7,0 DW 151,127,00F0H,32,2 F207TBLL EQU OFFSET $ - OFFSET F207TBL ;5 1/4" DOUBLE DENSITY (8X512)/DOUBLE SIDED/48 TPI DB DPEDD+DPE2S,4,16,0 DW 32 DB 4,15,1 DW 155,255,00F0H,64,2 ;5 1/4" DOUBLE DENSITY (8X512)/SINGLE SIDED/96 TPI DB DPEDD,4,16,DPE96TM DW 32 DB 4,15,1 DW 155,127,00C0H,32,2 ;5 1/4" DOUBLE DENSITY (8X512)/DOUBLE SIDED/96 TPI DB DPEDD+DPE2S,4,16,DPE96TM DW 32 DB 4,15,0 DW 315,255,00F0H,64,2 ;8" SINGLE DENSITY / SINGLE SIDED DB 0,1,8,0 DW 26 DB 3,7,0 DW 242,63 DB 0C0H,0 DW 16,2 ;8" SINGLE DENSITY / DOUBLE SIDED DB DPE2S,1,16,0 DW 26 DB 4,15,1 DW 246,127 DB 0C0H,0 DW 32,2 ;8" DOUBLE DENSITY / SINGLE SIDED DB DPEDD,2,16,0 DW 52 DB 4,15,1 DW 242,127 DB 0C0H,0 DW 32,2 ;8" DOUBLE DENSITY / DOUBLE SIDED DB DPEDD+DPE2S,2,16,0 DW 52 DB 4,15,0 DW 493,255 DB 0F0H,0 DW 64,2 EJECT CSEG $ ;** F217 - FORMAT 217 ; ; FORMATTING A Z217 PARTITION CONSISTS OF WRITING 0E5H BYTES THROUGH OUT ; THE SYSTEM TRACK(S) AND THE DIRECTORY. ; F217: MOV CL,SGUSR ;GET CURRENT USER CODE MOV DL,0FFH INT BDOSE MOV F217UC,AL MOV CL,SGUSR ;RESET USER CODE TO 31 MOV DL,15 ; TO HIDE FILE 'BADBLOCK.SYS' INT BDOSE TEST DRTYPE,DPEASGN ;Q. PARTITION ASSIGNED ; JZ F21799 ; BR IF NOT JNZ $+5 JMP F21799 MOV AL,DRIVID ;INFORM USER MOV FPARTD,AL MOV CL,PRCONB LEA DX,FMTPART INT BDOSE CMP NOQFLG,0 ;Q. SHOULD I AS IF READY JNE F2171 ; BR IF NO MOV CL,PRCONB ;ASK IF READY LEA DX,PROMPT1 INT BDOSE MOV CL,RDCON INT BDOSE CMP AL,CR ;Q. ; JNE F21798 ; ABORT IF NOT JE $+5 JMP F21798 F2171: CALL FCBD ;CLEAR BIOS BUFFERS FOR DRIVE CALL F21780 ;FILL IN DPB & CALC VALUES ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 ;* COMPUTE # CP/M RECORDS TO CLEAR. ; (# CP/M RECORDS) = (# DIRECTORY ALLOCATION BLOCKS) SHL (BSH) + ; (# RECORDS FOR SYSTEM TRACK(S)) LES BX,DWORD PTR DPBPTR ;GET # ALLOCATION BLOCKS FOR DIRECTORY MOV AX,0 MOV DH,ES: DPBAL0[BX] MOV DL,ES: DPBAL1[BX] F2172: SHL DX,1 JNC F2172A INC AX JMPS F2172 F2172A: MOV F217DAB,AX ;SAVE # ALLOCATION BLOCKS MOV CL,ES: DPBBSH[BX] ;GET BLOCK SHIFT FACTOR SHL AX,CL ;(DIRECTORY AB'S) SHL (BSH) ADD AX,WINST*WIRPT ;ADD # CP/M RECORDS FOR SYSTEM TRACK(S) MOV F217C1,AX ;* WRITE 0E5H TO ALL SECTORS TO BE CLEARED MOV CX,128 ;FILL SECTOR BUFFER WITH 0E5H MOV DI,0 MOV ES,BUFFER MOV AL,0E5H CLD REP STOSB MOV CX,0 ;SET DMA OFFSET CALL FSETDMA MOV CX,BUFFER ;SET DMA SEGMENT CALL FSETDMAS MOV F217TRK,0 ;INIT TRACK # MOV F217SEC,1 ;INIT SECTOR # F21710: MOV CX,F217TRK ;SET TRACK # CALL FSETTRK MOV CX,F217SEC ;SET SECTOR # CALL FSETSEC MOV CL,BWRNOR ;WRITE SECTOR CALL FWRITE CMP AL,0 ;Q. ERROR ; JNE F21799 ; BR IF ERROR JE $+5 JMP F21799 CMP F217SEC,WIRPT ;Q. JUST WROTE LAST SECTOR OF TRACK JNE F21712 ; BR IF NO MOV F217SEC,0 ;RESET SECTOR # INC F217TRK ;INCREMENT TRACK # F21712: INC F217SEC ;BUMP SECTOR # DEC F217C1 ;LOOP JNZ F21710 ;* WRITE LABEL TO 1ST SECTOR OF DISK CALL WRLAB ; JC F21799 ;BR IF ERROR JNC $+5 JMP F21799 ;* BUILD A FILE WITH THE BAD SECTORS OF THIS PARTITION ALLOCATED ; TO THIS FILE SO THEY CAN'T BE USED. MOV AL,DRIVID ;GET DRIVE SUB AL,'A'-1 ;CONVERT TO 1-N MOV F217FCB+OFFSET FCBDN,AL ;PLACE IN FCB CALL F217RDB ;READ IN BAD SECTOR TABLE ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 MOV F217LAB,0 ;INIT LAST ALLOCATION BLOCK MARKED BAD MOV F217C2,0 ;INIT ALLOCATION BLOCK COUNTER F2175A: CALL F21750 ;GET NEXT ENTRY IN TABLE JZ F2175C ; BR IF NO MORE ENTRIES SUB AX,F217LB ;Q. SECTOR # BEFORE START OF PARTITION JC F2175A ; BR IF YES SUB AX,WINSYS ;Q. SECTOR # WITHIN SYSTEM TRACK(S) ; JC F21799 ; BR IF YES JNC $+5 JMP F21799 LES BX,DWORD PTR DPBPTR ;CALCULATE ALLOCATION BLOCK # XOR CH,CH ; AB = (AX) SHR (BSH-2) MOV CL,ES:DPBBSH[BX] SUB CL,2 SHR AX,CL IF WICSZ NE 512 %: SECTOR SIZE NE 512 ENDIF CMP AX,F217DAB ;Q. BAD SECTOR WITHIN DIRECTORY ; JB F21799 ; BR IF YES JNB $+5 JMP F21799 CMP AX,ES:DPBDSM[BX] ;Q. CHECK AGAINST MAX BLOCK # JA F2175A ; BR IF PAST END OF PARTITION CMP AX,F217LAB ;Q. SAME AS LAST BAD BLOCK # JE F2175A ; BR IF YES MOV F217LAB,AX ;UPDATE 'F217LAB' ; ADD BAD BLOCK # TO DISK MAP FOR THE CURRENT DIRECTORY ENTRY. CMP F217C2,16 ;Q. MAP FULL JNE F2175B ; BR IF NOT PUSH AX ;SAVE ALLOCATION BLOCK # CALL F21760 ;WRITE DIRECTORY ENTRY TO DISK POP AX ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 MOV F217C2,0 ;ZERO MAP COUNTER F2175B: MOV BX,F217C2 ;PLACE BAD BLOCK # INTO MAP MOV WORD PTR F217MAP[BX],AX INC F217C2 ;BUMP MAP COUNTER LES BX,DWORD PTR DPBPTR ;CHECK DSM TO SEE IF SINGLE OR CMP ES: BYTE PTR DPBDSM+1[BX],0 ; DOUBLE BYTE MAP VALUES JE F2175A ; BR IF SINGLE (DSM <= 255) INC F217C2 JMPS F2175A ; DONE BUILDING DIRECTORY ENTRIES BAD SECTORS. F2175C: CALL F21760 ;WRITE DIRECTORY ENTRY ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 OR F217FCB+OFFSET FCBRO,FCBROF ;SET ATTRIBUTES TO R/O & SYS OR F217FCB+OFFSET FCBSYS,FCBSYSF MOV CL,SFA LEA DX,F217FCB INT BDOSE ;* JMP F21798 ;* GET NEXT ENTRY FOR BAD SECTOR TABLE. ; ; ENTRY: (F217BSE)=TABLE POINTER ; EXIT: 'Z' 0=ENTRY PRESENT , 1=NO MORE ENTRIES ; (AX)=BAD SECTOR # ; USES: ALL ; F21750: MOV BX,F217BSE ;GET TABLE POINTER TO NEXT ENTRY MOV ES,BUFFER MOV AX,ES:[BX] ;GET LOW ORDER 16 BITS ADD F217BSE,3 ;UPDATE TABLE POINTER CMP AX,0 ;UPDATE ZERO FLAG RET ;* WRITE DIRECTORY ENTRY TO DISK. ; ; ENTRY: (F217C2)=MAP COUNTER ; (F217FCB)=DIRECTORY ENTRY ; EXIT: (F217C2)=MAP COUNTER ZEROED ; (F217FCB)=DIRECTORY ENTRY UPDATED FOR NEXT EXTENT ; 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; F21760: CMP F217C2,0 ;Q. MAP COUNTER = 0 JE F21763 ; BR IF YES -- DIR ENTRY IS EMPTY MOV CL,RDS ;RESET DISK SYSTEM INT BDOSE MOV CL,CREATE ;MAKE FILE FOR THIS ENTRY LEA DX,F217FCB INT BDOSE CMP AL,0FFH JE F21764 ; BR IF ERROR MOV CX,16 ;MOVE MAP TO FCB LEA SI,F217MAP LEA DI,F217FCB+OFFSET FCBDM F21761: MOV AL,[SI] MOV BYTE PTR [SI],0 MOV [DI],AL INC SI INC DI LOOP F21761 LES BX,DWORD PTR DPBPTR ;SET EXTENT NUMBER BYTE MOV AL,F217FCB+OFFSET FCBEX ADD AL,ES:DPBEXM[BX] CMP AL,32 ;EXTENT NUMBER > MAX JB F21762 ; BR IF NOT SUB AL,32 ; MAKE EXTENT # MODULUS 32 INC F217FCB+OFFSET FCBRWF ; INC MODULE NUMBER F21762: MOV F217FCB+OFFSET FCBEX,AL MOV F217FCB+OFFSET FCBRC,128 ;SET RECORD COUNT TO FULL AND F217FCB+OFFSET FCBRWF,07FH ;CLEAR 'FILE WRITE FLAG' MOV CL,CLOSE ;CLOSE FILE LEA DX,F217FCB INT BDOSE CMP AL,0FFH JE F21764 ; BR IF ERROR INC F217FCB+OFFSET FCBEX ;SET EXTENT NUMBER FOR NEXT TIME MOV F217C2,0 ;CLEAR MAP COUNTER F21763: CLC ;INDICATE NO ERROR RET F21764: STC ;INDICATE ERROR RET ;* CALCULATE DPE HEATH EXTENSIONS AND DISK PARAMETER BLOCK VALUES F21780: ; CALCULATE # SECTORS WITHIN PARTITION. LES BX,DWORD PTR DPEPTR ;GET LAST SECTOR # + 1 MOV AX,ES: WORD PTR DPEUPB[BX] INC AX MOV DX,ES: WORD PTR DPETRK[BX] ;GET BEGINNING SECTOR # MOV F217LB,DX SUB AX,DX ;# SECTORS WITHIN PARTITION CMP AX,WIMIN ;Q. >= MINIMUM ALLOWABLE JAE F21781 ; BR IF YES MOV CL,PRCONB LEA DX,MINMSG INT BDOSE STC JMP F21789 F21781: CMP AX,WIMAX ;Q. <= MAXIMUM USEABLE JBE F21782 ; BR IF YES MOV CL,PRCONB ;ISSUE WARNING MESSAGE LEA DX,MAXMSG INT BDOSE MOV AX,WIMAX ;ONLY ALLOW MAXIMUM USABLE F21782: MOV F217NS,AX ;SAVE # SECTORS WITHIN PARTITION ; SEARCH PARAMETER TABLE TO FIND ENTRY THAT THE PARTITION'S # USEABLE ; SECTORS >= TABLE ENTRY'S # SECTORS. LEA BX,F217TBL ;GET TABLE POINTER F21783: CMP AX,F217TNS[BX] ;Q. COMPARE JAE F21784 ; BR IF >= ADD BX,F217TBLL ;BUMP TO NEXT TABLE ENTRY JMPS F21783 ; PLACE INFO INTO THE HEATH EXTENSION AREA OF THE DRIVES'S ; DISK PARAMETER ENTRIES TABLE. F21784: LES DI,DWORD PTR DPEPTR ;GET DPE POINTER MOV AL,F217TRA[BX] ;CP/M RECORDS PER ALLOCATION BLOCK MOV ES:DPERPAB[DI],AL ; PLACE INFO INTO THE DRIVE'S DISK PARAMETER BLOCK. LES DI,DWORD PTR DPBPTR ;GET DPB POINTER MOV ES:DPBSPT[DI],WIRPT ;CP/M RECORDS PER TRACK MOV AL,F217TBS[BX] ;BLOCK SHIFT FACTOR MOV ES:DPBBSH[DI],AL MOV AL,F217TBM[BX] ;BLOCK MASK MOV ES:DPBBLM[DI],AL MOV AL,F217TEX[BX] ;EXTENT MASK MOV ES:DPBEXM[DI],AL MOV AX,F217TDE[BX] ;# DIRECTORY ENTRIES - 1 MOV ES:DPBDRM[DI],AX MOV AL,F217TA0[BX] ;AL0 MOV ES:DPBAL0[DI],AL MOV AL,F217TA1[BX] ;AL1 MOV ES:DPBAL1[DI],AL MOV ES:DPBCKS[DI],0 ;CHECKSUM VECTOR LENGTH MOV ES:DPBOFF[DI],WINST ;# OF SYSTEM TRACKS ; CALCULATE DISK PARAMETER BLOCK 'DSM' VALUE. ; DSM = ( [# USEABLE SECTORS] - [# SYSTEM SECTORS] ) / ; [# SECTORS PER ALLOCATION BLOCK] - 1 MOV AX,F217NS SUB AX,WINSYS LES BX,DWORD PTR DPBPTR MOV CL,ES:DPBBSH[BX] SUB CL,2 SHR AX,CL IF WICSZ NE 512 %: CELL SIZE IS NOT 512 ENDIF DEC AX MOV ES:DPBDSM[BX],AX ; CLC ;INDICATE NO ERROR F21789: RET ;* NO ERROR F21798: CLC JMPS F217100 ;* ERROR F21799: STC ;* DONE FORMATTING Z217 PARTITION F217100: PUSHF MOV CL,SGUSR ;RESTORE USER CODE MOV DL,F217UC INT BDOSE CALL FCBD ;CLEAR BIOS BUFFERS POPF RET ;* READ IN BAD SECTOR TABLE F217RDB: CALL FCBD ;CLEAR BUFFERS LES BX,DWORD PTR DPEPTR ;INDICATE DO LOGICAL I/O OR ES:DPEFLAG[BX],DPELSIO MOV F217BSE,0 ;READ SBC MOV F217SEC,1 MOV F217C2,WIRPS F217RDB1: MOV CX,0 ;READ NEXT SECTOR OF SBC MOV DX,F217SEC MOV DI,F217BSE MOV ES,BUFFER CALL F217RD ; JC F217RDB9 ; BR IF ERROR JNC $+5 JMP F217RDB9 ADD F217BSE,128 INC F217SEC DEC F217C2 JNZ F217RDB1 MOV BX,0 ;CHECK CHECKSUM MOV ES,BUFFER MOV CX,WICSZ MOV DX,0 XCHG DX,ES:SBCCRC CALL F217CS STC ; JNE F217RDB9 ; BR IF NOT CORRECT JE $+5 JMP F217RDB9 MOV ES,BUFFER ;LOGICAL SECTOR # OF BAD SECTOR TABLE MOV AX,ES: WORD PTR SBCBSA ; COPY A MOV F217BSA,AX MOV AX,ES: SBCCBA ;BAD SECTOR TABLE COPY A CHECKSUM MOV F217CBA,AX MOV AX,ES: WORD PTR SBCBSB ;LOGICAL SECTOR # OF BAD SECTOR TABLE MOV F217BSB,AX ; COPY B MOV AX,ES: SBCCBB ;BAD SECTOR TABLE COPY B CHECKSUM MOV F217CBB,AX MOV F217CB,0 ;CLEAR USE COPY B FLAG F217RDB2: MOV AX,F217BSA ;GET LOG SEC # OF BAD SECTOR TABLE XOR DX,DX ;COMPUTE TRACK # MOV CX,WINSPT DIV CX MOV F217TRK,AX MOV AL,WIRPS ;COMPUTE CP/M SECTOR # = PHYSICAL MUL DL ; SECTOR # * CP/M RECORDS PER INC AX ; PHYSICAL SECTOR + 1 MOV F217SEC,AX MOV F217BSE,0 ;SET BUFFER ADDRESS MOV F217C2,WIRPS*2 ;ASSUME TABLE FIT IN 2 PHYSICAL SECTORS F217RDB3: MOV CX,F217TRK ;GET TRACK # MOV DX,F217SEC ;GET SECTOR # MOV DI,F217BSE ;GET BUFFER FWA MOV ES,BUFFER CALL F217RD ;READ 128 BYTES JC F217RDB5 ; BR IF ERROR CMP F217SEC,WIRPT ;Q. END OF TRACK JNE F217RDB4 ; BR IF NOT INC F217TRK ;BUMP TRACK # MOV F217SEC,0 F217RDB4: INC F217SEC ;BUMP SECTOR # ADD F217BSE,128 ;BUMP BUFFER ADDRESS DEC F217C2 ;LOOP AND READ JNZ F217RDB3 MOV BX,0 ;CHECK CHECKSUM MOV ES,BUFFER MOV CX,WIRPS*2 MOV DX,F217CBA CALL F217CS JE F217RDB6 F217RDB5: CMP F217CB,0 ;Q. ALREADY TRYING FOR COPY B STC JNE F217RDB9 ; BR IF YES MOV F217CB,1 ;SET UP TO TRY FOR COPY B MOV AX,F217BSB MOV F217BSA,AX MOV AX,F217CBB MOV F217CBA,AX JMP F217RDB2 F217RDB6: MOV F217BSE,0 ;INIT BAD SECTOR TABLE ENTRY POINTER CLC ;INDICATE NO ERROR F217RDB9: PUSHF ;SAVE CARRY FLAG (ERROR INDICATOR) LES BX,DWORD PTR DPEPTR ;TURN OFF DOING LOGICAL SECTOR I/O AND ES:DPEFLAG[BX],NOT DPELSIO CALL FCBD ;CLEAR BIOS BUFFERS POPF ;RETRIEVE ERROR INDICATOR RET ;* CALCULATE CHECK SUM AND CHECK IT ; ; ENTRY: (BX),(ES)=RECORD ; (CX)=SIZE ; (DX)=CHECKSUM ; EXIT: PSW/Z 0=ERROR , 1=OK ; USES: AX,BX,CX ; F217CS: MOV AX,0 F217CS1: ADD AL,ES:[BX] ADC AH,0 INC BX LOOP F217CS1 NOT AX CMP AX,DX RET ;* READ CP/M SECTOR FROM DISK ; ; ENTRY: (CX)=TRACK # ; (DX)=CP/M SECTOR # (1 TO SPT) ; (DI)=BUFFER FWA OFFSET ; (ES)=BUFFER FWA SEGMENT ; EXIT: 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; F217RD: PUSH ES PUSH DI PUSH DX CALL FSETTRK ;SET TRACK POP CX CALL FSETSEC ;SET SECTOR POP CX ;SET DMA OFFSET CALL FSETDMA POP CX ;SET DMA SEGMENT CALL FSETDMAS CALL FREAD ;READ SECTOR CMP AL,0 ;Q. ERROR JE F217RD1 ; BR IF NOT STC ;INDICATE ERROR F217RD1: RET EJECT DSEG $ ;* PARAMETER TABLE CONTAINING ; 1) HEATH EXTENSION VALUES ; 2) DISK PARAMETER BLOCK VALUES ; ; FORMAT OF TABLE: ; BYTE # DESCRIPTION ; ------ ---------------------------------------------------- ; 0-1 # SECTORS -- THIS ENTRY IS USED IF PARTITION'S ; # USEABLE SECTORS >= ; 2 CP/M RECORDS PER ALLOCATION BLOCK ; 3 BLOCK SHIFT FACTOR ; 4 BLOCK MASK ; 5 EXTENT MASK ; 6-7 # OF DIRECTORY ENTRIES - 1 ; 8 AL0 ; 9 AL1 ; F217TBL RB 0 F217TNS EQU 0 F217TRA EQU 2 F217TBS EQU 3 F217TBM EQU 4 F217TEX EQU 5 F217TDE EQU 6 F217TA0 EQU 8 F217TA1 EQU 9 DW 1024/WICSZ*4*1024+WINSYS+1 ;4 MEG < X <= 8 MEG DB 32,5,31,1 DW 1023 DB 0FFH,000H F217TBLL EQU OFFSET $ - OFFSET F217TBL ;TABLE ENTRY LENGTH DW 1024/WICSZ*1*1024+WINSYS+1 ;1 MEG < X <= 4 MEG DB 16,4,15,0 DW 511 DB 0FFH,000H DW 1024/WICSZ*512+WINSYS+1 ;512K < X <= 1 MEG DB 16,4,15,0 DW 255 DB 0F0H,000H DW 1024/WICSZ*256+WINSYS+1 ;256K < X <= 512K DB 16,4,15,1 DW 127 DB 0C0H,000H DW WIMIN ;MINIMUM <= X <= 256K DB 8,3,7,0 DW 63 DB 0C0H,000H FMTPART DB CR,LF,CR,LF,'Will format partition assigned to drive ' FPARTD DB '?:',CR,LF,CPMEOM MINMSG DB CR,LF,BELL,'PARTION IS SMALLER THAN MINIMUM ALLOWABLE ' DB 'SIZE',CR,LF,CPMEOM MAXMSG DB CR,LF,BELL,'PARTITION IS LARGER THAN CP/M MAXIMUM SIZE' DB ' -- ONLY 8 MEG USEABLE',CR,LF,CPMEOM F217NS RW 1 ;# USEABLE SECTORS F217TRK RW 1 ;TRACK # F217SEC RW 1 ;SECTOR # F217DAB RW 1 ;# DIRECTORY ALLOCATION BLOCKS F217C1 RW 1 ;LOOP COUNTER F217C2 RW 1 ;COUNTER F217BSE RW 1 ;BAD SECTOR TABLE POINTER F217LAB RW 1 ;LAST ALLOCATION BLOCK MARKED BAD F217LB RW 1 ;PARTITION LOWER BOUND F217UC RB 1 ;USER CODE F217BSA RW 1 ;LOG SEC # BAD SECTOR TABLE COPY A F217CBA RW 1 ;BAD SECTOR TABLE COPY A CHECKSUM F217BSB RW 1 ;LOG SEC # BAD SECTOR TABLE COPY B F217CBB RW 1 ;BAD SECTOR TABLE COPY B CHECKSUM F217CB RB 1 ;USE COPY B FLAG F217FCB DB 0,'BADBLOCKSYS',0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 F217MAP DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 EJECT CSEG $ ;** WKIND -- DETERMINES DRIVE TYPE AND SELECTS DRIVE ; ; ENTRY: (AL)=DRIVE NAME ; EXIT: 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; WKIND: SUB AL,'A' ;CONVERT TO CP/M DRIVE # MOV CL,AL CALL FSETDSK ;ATTEMPT TO SELECT DRIVE CMP BX,0 ;Q. SELECT ERROR JE WKIND9 ; BR IF ERROR MOV DPEPTR,BX ;SAVE POINTER TO DPE MOV ES,OSDS MOV DPEPTR+2,ES MOV AX,ES:DPEDPB[BX] ;DPB MOV DPBPTR,AX MOV DPBPTR+2,ES MOV AL,ES:DPEFLAG[BX] ;FLAG MOV DRTYPE,AL MOV AL,ES:DPEUNIT[BX] ;UNIT SELECT MOV AIOUNI,AL MOV AL,ES:DPEFLG2[BX] ;FLAG2 MOV FLAG2,AL CLC ;INDICATE NO ERROR RET WKIND9: STC ;INDICATE ERROR RET ;** FSETDSK - GETS DISK TABLE POINTER IN (BX)/(ES) ; ; ENTRY: (CL)=CP/M DRIVE # ; EXIT: (BX)=ADDRESS OFFSET (0=ERROR) ; USES: ALL ; FSETDSK: MOV DBIOSF,SETDSK MOV DL,1 JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETTRK - SET CP/M TRACK # ; ; ENTRY: (CX)=TRACK # ; EXIT: NONE ; USES: ALL ; FSETTRK: MOV DBIOSF,SETTRK JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETSEC - SET CP/M SECTOR # ; ; ENTRY: (CX)=SECTOR # ; EXIT: NONE ; USES: ALL ; FSETSEC: MOV DBIOSF,SETSEC JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETDMA - SET CP/M DMA OFFSET ; ; ENTRY: (CX)=DMA OFFSET ; EXIT: NONE ; USES: ALL ; FSETDMA: MOV DBIOSF,SDMA JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETDMAS - SET CP/M DMA SEGMENT ; ; ENTRY: (CX)=DMA SEGMENT ; EXIT: NONE ; USES: ALL ; FSETDMAS: MOV DBIOSF,SETDMAB JMPS DOBIOS ;RETURN THRU DOBIOS ;** FREAD - READ CP/M SECTOR ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FREAD: MOV DBIOSF,BREAD JMPS DOBIOS ;RETURN THRU DOBIOS ;** FWRITE - WRITE CP/M SECTOR ; ; ENTRY: (CL)=WRITE MODE ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FWRITE: MOV DBIOSF,BWRITE JMPS DOBIOS ;RETURN THRU DOBIOS ;** FFORMAT - FORMAT DISK ; ; ENTRY: (CL)=VERIFY FLAG ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FFORMAT: MOV DBIOSF,BFMT JMPS DOBIOS ;RETURN THRU DOBIOS ;** FWRTRK - WRITE TRACK ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FWRTRK: MOV DBIOSF,BWRTRK JMPS DOBIOS ;RETURN THRU DOBIOS ;** FWPC - WRITE PROTECT CHECK ; ; ENTRY: NONE ; EXIT: (AL)=WRITE PROTECT STATUS (0=NO , 1=YES) ; USES: ALL ; FWPC: MOV DBIOSF,BWPC JMPS DOBIOS ;RETURN THRU DOBIOS ;** FCBD - CLEAR BUFFER FOR DRIVE ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; FCBD: MOV DBIOSF,BCBD JMPS DOBIOS ;RETURN THRU DOBIOS ;** FGBT - GET ADDRESS OF BIOS TABLES ; ; ENTRY: NONE ; EXIT: (BX)=ADDRESS OFFSET ; (ES)=ADDRESS SEGMENT ; USES: ALL ; FGBT: MOV DBIOSF,BGBT ;** DOBIOS - DIRECT BIOS CALL ; ; ENTRY: (CX) & (DX) ; EXIT: WHATEVER IS RETURNED BY BIOS ; USES: ALL ; DOBIOS: MOV DBIOSCX,CX MOV DBIOSDX,DX MOV CL,DBIOS LEA DX,DBIOST INT BDOSE RET EJECT ;** DISPATCH - CALL APPROPRIATE FORMATTING ROUTINE ; DISPATCH: XOR BH,BH MOV BL,DRTYPE MOV CL,5 SHR BX,CL SHL BX,1 CMP FMTRTN[BX],0 JE DISPATCH1 JMP FMTRTN[BX] DISPATCH1: RET ;** TOUPPER - CONVERT TO UPPER CASE ; ; ENTRY: (AL)=VALUE ; EXIT: (AL)=VALUE CONVERTED TO UPPERCASE ; USES: AL ; TOUPPER: CMP AL,'a' JB TOUPPER1 CMP AL,'z' JA TOUPPER1 SUB AL,'a'-'A' TOUPPER1: RET ;** WRLAB - FORM LABEL AND WRITE IT TO 1ST SECTOR OF DISK ; ; ENTRY: NONE ; EXIT: 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; WRLAB: MOV CX,128 ;CLEAR 128 BYTES OF BUFFER TO 0E5H MOV DI,0 MOV ES,BUFFER CLD MOV AL,0E5H REP STOSB MOV ES: BYTE PTR .LABTYP,LABVER ;INSERT CURRENT FORM # ; MOVE HEATH EXTENSIONS TO LABEL PUSH DS MOV DI,LABHTH LDS SI,DWORD PTR DPEPTR ADD SI,OFFSET DPEHTH MOV CX,DPEHL REP MOVSB POP DS ; MOVE DPB TO LABEL PUSH DS MOV DI,LABDPB LDS SI,DWORD PTR DPBPTR MOV CX,DPBL REP MOVSB POP DS ; CALCULATE CHECKSUM FOR LABEL XOR AL,AL MOV BX,LABEL MOV CX,LABLEN-1 WRLAB1: ADD AL,ES:[BX] INC BX LOOP WRLAB1 NOT AL MOV ES:[BX],AL ; WRITE LABEL TO DISK MOV CX,0 CALL FSETTRK MOV CX,1 CALL FSETSEC MOV CX,0 CALL FSETDMA MOV CX,BUFFER CALL FSETDMAS MOV CL,BWRDIR CALL FWRITE OR AL,AL ;Q. ERROR JZ WRLAB2 ; BR IF NOT STC ;INDICATE ERROR ; WRLAB2: RET EJECT ;** CLINT - COMMAND LINE INTERPRETER ; ; ENTRY: (TBUFF)=COUNT ; TBUFF+1=ADDRESS OF COMMAND LINE ; EXIT: VALUES ; 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; CLINT: MOV COMLIN,1 ;INDICATE COMMAND LINE PRESENT MOV CL,TBUFF ;COUNT LEA SI,TBUFF+1 ;ADDR OF START OF STRING CALL CSCAN ;FIND DRIVE NAME CMP AL,TNAME ;Q. DRIVE NAME JNE RDOPT9 ; BR IF NOT CMP CH,2 ;Q. TOKEN LENGTH = 2 JNE RDOPT9 ; BR IF NOT CMP BYTE PTR 1[DI],':' ;Q. 2ND CHARACTER = ':' JNE RDOPT9 ; BR IF YES MOV AL,[DI] ;SAVE DRIVE NAME MOV DRIVID,AL ;* RDOPT - READ OPTIONS ; ; ENTRY: (CL)=COMMAND LINE COUNT ; (SI)=COMMAND LINE POINTER ; EXIT: VALUES ; 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; CALL CSCAN ;GET NEXT TOKEN CMP AL,TEOL ;Q. EOL JE RDOPT90 ; BR IF YES CMP AL,TLBR ;Q. '[' JNE RDOPT9 ; BR IF NOT ; MAIN LOOP RDOPT0: CALL CSCAN ;GET OPTION CMP AL,TNAME ;Q. VALID JNE RDOPT9 ; BR IF NOT ; DECODE SECTION RDOPT1: CMP CH,1 ;Q. TOKEN SIZE = 1 JNE RDOPT2 ; BR IF NOT MOV AL,[DI] ;GET TOKEN CMP AL,'F' ;Q. FAST JNE RDOPT1A ; BR IF NOT MOV FAST,1 ;SET FAST FLAG JMPS RDOPT6 RDOPT1A: CMP AL,'N' ;Q. NO QUERY JNE RDOPT10 ; BR IF NOT MOV NOQFLG,1 ;SET FLAG JMPS RDOPT6 RDOPT2: CMP CH,2 ;Q. TOKEN SIZE = 2 JNE RDOPT10 ; BR IF NOT MOV AX,[DI] ;GET TOKEN XCHG AL,AH CMP AX,'DD' ;Q. DOUBLE DENSITY JE RDOPT2B ; BR IF YES CMP AX,'SD' ;Q. SINGLE DENSITY JNE RDOPT2C ; BR IF NOT RDOPT2B: MOV CLIDENS,AH JMPS RDOPT6 RDOPT2C: CMP AX,'1S' ;Q. SINGLE SIDED JE RDOPT2D ; BR IF YES CMP AX,'2S' ;Q. DOUBLE SIDED JNE RDOPT2E ; BR IF NOT RDOPT2D: MOV CLISIDS,AH JMPS RDOPT6 RDOPT2E: CMP AX,'D0' ;Q. TRACK 0 DOUBLE DENSITY JNE RDOPT10 ; BR IF NOT MOV CLID0,1 ;SET FLAG ; END OF OPTION DECODE, GET NEXT OPTION RDOPT6: CALL CSCAN ;LOOK FOR MORE OPTIONS CMP AL,TRBR ;Q. ']' JE RDOPT90 ; BR IF YES CMP AL,TCOMMA ;Q; ',' JE RDOPT0 ; BR IF YES ; SYNTAX ERROR RDOPT9: MOV CL,PRCONB LEA DX,SYNMSG INT BDOSE STC JMPS RDOPT90 ; ILLEGAL OPTION RDOPT10: MOV CL,PRCONB LEA DX,OPTMSG INT BDOSE STC ; RDOPT90: RET ;* CSCAN - SCANNER FOR CP/M COMMAND LINES ; ; CSCAN IS CALLED TO GET THE NEXT TOKEN FROM A CP/M ; COMMAND LINE. ; ; ENTRY: (CL)=COUNT ; (SI)=COMMAND LINE POINTER ; EXIT: (CL)=UPDATED COUNT ; (SI)=UPDATED COMMAND LINE POINTER ; (AL)=TOKEN TYPE ; (DI)=ADDRESS OF TOKEN ; (CH)=LENGTH OF TOKEN ; USES: ALL ; CSCAN: MOV DH,0 ;STATE = 0 MOV CH,0 ;TOKEN SIZE = 0 ; MAIN LOOP CSC00: MOV DL,0 ;ASSUME CLASS 0 CMP CL,0 ;Q. BYTES LEFT JE CSC02 ; BR IF NOT ; COMPUTE CHARACTER CLASS MOV AL,[SI] ;GET BYTE FROM STRING AND AL,07FH ;STRIP MS BIT CALL TOUPPER ;UPC XLATE MOV [SI],AL LEA BX,CSCCLT ;TABLE LOOKUP FOR CLASS XLAT AL MOV DL,AL ;SAVE CLASS ; COMPUTE INDEX FOR SCAN TABLE ENTRY GIVEN STATE & CLASS ; = 2*(STATE*NCLASS+CLASS) CSC02: MOV AL,CSCNCL MUL DH ADD AL,DL ADC AH,0 SHL AX,1 MOV BX,AX ; DECODE AND PERFORM ACTION TEST CSCSNT[BX],CSCACS ;Q. SET TOKEN START JZ CSC04 ; BR IF NOT MOV DI,SI CSC04: TEST CSCSNT[BX],CSCACA ;Q. INC TOKEN SIZE JZ CSC05 ; BR IF NOT INC CH CSC05: TEST CSCSNT[BX],CSCACI ;Q. INC STRING POINTER JZ CSC06 ; BR IF NOT INC SI DEC CL CSC06: TEST CSCSNT[BX],CSCACR ;Q. RETURN TRANSITION JNZ CSC07 ; BR IF YES ; GO TO NEXT STATE TRANSITION MOV DH,CSCSNT+1[BX] ;GET NEXT STATE JMPS CSC00 ; RETURN ACTION CSC07: MOV AL,CSCSNT+1[BX] ;GET TOKEN TYPE RET DSEG $ COMLIN DB 0 ;COMMAND LINE FLAG NOQFLG DB 0 ;NO QUERY FLAG DRIVID DB ' ' ;COMMAND LINE DIRVE ID CLID0 DB 0 ;TRACK 0 DOUBLE DENSITY FLAG CLIDENS DB 'D' ;COMMAND STRING DENSITY RESULT CLISIDS DB '2' ;COMMAND STRING SIDES RESULT FAST DB 0 ;FAST FLAG SYNMSG DB CR,LF,BELL,'Illegal Command Syntax',CR,LF,CPMEOM OPTMSG DB CR,LF,BELL,'Illegal Format Option',CR,LF,CPMEOM ; DEFINE CONSTANTS AND TABLES TNAME EQU 1 ; Name token TEQUAL EQU 2 ; Equal sign token TLBR EQU 3 ; Left brace token TRBR EQU 4 ; Right brace token TCOMMA EQU 5 ; Comma token TEOL EQU 6 ; End-of-line token TILG EQU 7 ; Illegal type token CSCACR EQU 08H ; "RETURN" action CSCACG EQU 00H ; "GOTO" action CSCACS EQU 01H ; Set token start action CSCACA EQU 02H ; Increase token size action CSCACI EQU 04H ; Increase string ptr action CSCAMK EQU 01H ; Action mask CSCNST EQU 2 ; Number of states CSCNCL EQU 8 ; Number of character classes ; THE CHARACTER CLASSES AND THE CHARACTER CLASS TABLE CSCEOL EQU 0 ; End of line class CSCILG EQU 1 ; Illegal character class CSCEQU EQU 2 ; Equal sign class CSCLBR EQU 3 ; Left brace class CSCRBR EQU 4 ; Right brace class CSCBNK EQU 5 ; Blank/tab class CSCCOM EQU 6 ; Comma class CSCNAM EQU 7 ; Name class ; FOR EACH OF THE 128 CHARACTERS, DEFINE WHICH CLASS IN WHICH IT BELONGS CSCCLT DB CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 00-07 DB CSCILG,CSCBNK,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 08-15 DB CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 16-23 DB CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 24-31 DB CSCBNK,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 32-39 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCCOM,CSCNAM,CSCNAM,CSCNAM ; 40-47 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 48-55 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCEQU,CSCNAM,CSCNAM ; 56-63 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 64-71 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 72-79 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 80-87 DB CSCNAM,CSCNAM,CSCNAM,CSCLBR,CSCNAM,CSCRBR,CSCNAM,CSCNAM ; 88-95 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 96-03 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 04-11 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 12-19 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 20-27 ; THE SCANNER STATE TABLE CSCSNT DB CSCACS+CSCACA+CSCACI+CSCACR,TEOL ; CSCEOL DB CSCACS+CSCACA+CSCACI+CSCACR,TILG ; CSCILG DB CSCACS+CSCACA+CSCACI+CSCACR,TEQUAL ; CSCEQU DB CSCACS+CSCACA+CSCACI+CSCACR,TLBR ; CSCLBR DB CSCACS+CSCACA+CSCACI+CSCACR,TRBR ; CSCRBR DB CSCACI+CSCACG,0 ; CSCBNK DB CSCACS+CSCACA+CSCACI+CSCACR,TCOMMA ; CSCCOM DB CSCACS+CSCACA+CSCACI+CSCACG,1 ; CSCNAM DB CSCACR,TNAME ; CSCEOL DB CSCACR,TNAME ; CSCILG DB CSCACR,TNAME ; CSCEQU DB CSCACR,TNAME ; CSCLBR DB CSCACR,TNAME ; CSCRBR DB CSCACR,TNAME ; CSCBNK DB CSCACR,TNAME ; CSCCOM DB CSCACA+CSCACI+CSCACG,1 ; CSCNAM EJECT SIGNON DB CR,LF,'CP/M-86 Format Version ' IF (BREL/10) NE 0 DB BREL/10+'0' ENDIF DB (BREL MOD 10)+'0','.' DB REVSN/10+'0',(REVSN MOD 10)+'0',CR,LF DB 'Copyright (c) 1983, Zenith Data Systems Corp.' DB CR,LF,CPMEOM SIGNON1 DB CR,LF,'This program is used to initialize a disk.',CR,LF DB 'All information currently on the disk will be destroyed.' DB CR,LF,'Is that what you want? (Y/N): ',CPMEOM BADBIOS DB 'Incorrect version of the BIOS',CR,LF,CPMEOM NOMEM DB 'Not enough memory',CR,LF,CPMEOM WHICH DB CR,LF,CR,LF DB 'Which drive do you wish to use for this operation?' DB ': ',CPMEOM ERRMSG DB CR,LF,BELL,'Option not available',CR,LF,CPMEOM WDSDMSG DB CR,LF,CR,LF DB 'Which density? (S=single, D=double): ',CPMEOM WSMSG DB CR,LF,CR,LF DB 'Number of sides? (1=single, 2=double): ',CPMEOM DRMSG DB CR,LF,BELL,'Drive ' DRMSGA DB '? not available in current configuration.',CR,LF,CPMEOM PROMPT DB CR,LF,CR,LF DB 'Put the disk you wish to be formatted in drive ' PROMPTA DB '?.',CPMEOM PROMPT1 DB CR,LF DB 'Press RETURN to begin, anything else to abort.',CR,LF,CPMEOM AMWMSG DB CR,LF DB 'Do you have more disks to format? (Y/N): ',CPMEOM LVEMSG DB CR,LF DB 'Place a bootable disk in drive A: and press any ' DB 'character:',CPMEOM WPEMSG DB CR,LF DB 'Disk is write protected' BMSG DB CR,LF,BELL DB 'Unable to format this disk.',CR,LF,CPMEOM FMTRTN RW 0 DW 0 DW OFFSET F207 DW OFFSET F217 DW 0 DW 0 DW 0 DW 0 DW 0 SYSDSK DB 0 ;SYSTEM DISK INVOLVED MCB RB 0 ;MEMORY REQUEST CONTROL BLOCK BUFFER RW 1 DW 1024/16*12 RB 1 DENSITY RB 1 ;DENSITY TO BE USED SIDES RB 1 ;# SIDES DRTYPE RB 1 ;FLAG BYTE #1 AIOUNI RB 1 ;UNIT SELECT FLAG2 RB 1 ;FLAG BYTE #2 TRACK RW 1 ;TRACK COUNTER DSKTKS RW 1 ;NUMBER OF TRACKS DSKSPT RB 1 ;NUMBER OF PHYSICAL SECTORS PER TRACK OSDS RW 1 ;OS (DS) VALUE DPEPTR RW 2 ;DISK PARAMETER ENTRIES POINTER DPBPTR RW 2 ;DISK PARAMETER BLOCK POINTER DBIOST RB 0 ;DIRECT BIOS CALL PARAMETER LIST DBIOSF RB 1 DBIOSCX RW 1 DBIOSDX RW 1 RB 256 ;STACK STACK RB 0 EJECT ;* PATCH AREA FOR CODE SEGMENT CSEG $ PATCOD RB 127 DB 0 ;* PATCH AREA FOR DATA SEGMENT DSEG $ PATDAT RB 63 DB 0 END