* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * MULTIFMT.ASM * * * * COPYRIGHT (C) 1984,85,86 AMPRO COMPUTERS, INC. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; Assemble with ASM.COM or equivalent. There is no Z80 code. ;REVISION LOG: ; ; 02/05/86 Version 2.3 ; Changed index pulse detection so works ; better with microfloppies ; ; 06/24/85 Version 2.2 ; Changed floppy restore to use 6ms rate ; ; 02/27/85 Version 2.1 ; Deleted warning message, and added a ; list of the floppy drives available. ; ; 12/12/84 Version 2.0 ; Added warning message for use with ; Bios version 2.1+ ; ; 05/13/84 Version 1.2 ; Added delays after line feeds. ; ; 05/08/84 Unreleased Ver. 1.1X ; Added Pmc, Sanyo and Televideo. ; ; 03/20/84 Release version 1.0. ;MULTIFMT allows formatting several foreign diskettes. It is based ;on the code developed for AMPRODSK and uses most of the algorithms ;in that program. The major differences are: ; ; 1. Added a selection menu at the beginning of the program ; to allow different formats. Jump routines from this ; menu update TABLE near the end of the program for the ; new format. ; ; 2. Removed the "copy" code as it is not needed. ; ; 3. Added routines after formatting and before verify ; to write a "boot loader" on the diskette (required ; by several different formats). The TYPE byte determines ; which formats require a "boot loader". ; wd1770 equates REST EQU 0 ; slow restore RDSEC EQU 88H ; read sector command WRSEC EQU 0A8H ; write sector command WRTRK EQU 0F8H ; write track command STEPI EQU 58H ; step in command RDID EQU 0C8H ; read address command MOT EQU 80H ; motor on status WPR EQU 40H ; write protected status SPU EQU 20H ; disk at speed status (type i) TYP EQU 20H ; record type status (types ii and iii) RNF EQU 10H ; record not found status CRC EQU 8 ; crc error status TK0 EQU 4 ; track zero status (type i) LDT EQU 4 ; lost data status (types ii and iii) IDX EQU 2 ; index status (type i) DRQ EQU 2 ; data request status (types ii and iii) BSY EQU 1 ; controller busy status ERRII EQU WPR+RNF+CRC+LDT ; type ii error status mask ERRIII EQU WPR+LDT ; type iii error status mask CMND EQU 0C0H ; fdc command register WTRK EQU CMND+1 ; write to track register WSEC EQU WTRK+1 ; write to sector register WDAT EQU WSEC+1 ; write to data register STAT EQU WDAT+1 ; fdc status register RTRK EQU STAT+1 ; read from track register RSEC EQU RTRK+1 ; read from sector register RDAT EQU RSEC+1 ; read from data register CONT EQU 0 ; system control port ROMOFF EQU 40H ; turn rom off SID0 EQU 0EFH ; mask side bit off SID1 EQU 10H ; side bit in control register SDEN EQU 20H ; single density bit in control register TRY EQU 3 ; tries TRYHARD EQU 10 ; we try harder MSEC EQU 167 ; constant for 1 ms delay CR EQU 13 ; carriage return LF EQU 10 ; line feed ESC EQU 27 ; escape key UPCASE EQU 5FH ; upper case mask bdos equ 5 ORG 100H ;embed the copyright notice ; START: JMP BEGIN ; leave room for copyright DB ' MULTIFMT Copyright (c) 1984,85,86 AMPRO Computers, Inc. ' DB 13,10,26 ;set up the stack and print signon message ; BEGIN: LXI SP,STACK ; set local stack CALL CLRSC ; clear the screen CALL ILPRT ; print following text DB CR,LF,' Foreign Diskette Format/Verify Utility' DB CR,LF,' Copyright (c) 1984,85,86 AMPRO Computers, Inc.' DB CR,LF,' Version 2.3$' call get$bios$vers mvi a,16 jnz new$sys lhld 1 mvi L,5ch mov a,m jmp plugem new$sys: push psw mvi a,0 lxi h,jplug1 mov m,a inx h mov m,a inx h mov m,a pop psw plugem: adi '@' sta plug1 inr a sta cplug1 jmp doit DISP$FDEV: ; ; [E2.15] ; ; lda lb$vers cpi 20 rm LXI D,D$FDEV$HDR ; Print header mvi c,9 call bdos mvi a,0 ; starting unit # D$NEXT$FDEV: sta unit call lb$get$ldte ; Get address of unit id MOV A,M ; Get unit id CPI 01 ; Floppy? JNZ D$BUMP$PTR ; No -- go to the next device inx h ; Get drive # mov a,m ; . ani 03h ; mask out excess bits MOV l,a ; update floppy device number mvi h,0 ; . dad h ; x2 xchg LXI H,FNAMES ; . dad d ; x2 dad d ; x4 dad d ; x6 lxi d,d$fname ; lxi b,6 ; db 0edh,0b0h ; . (LDIR) lda unit ; adi 'A' ; sta d$current ; LXI D,D$FDEV$LIN ; and output the line mvi c,9 call bdos D$BUMP$PTR: lda unit inr a ; Bump to next unit cpi 16 ; Done yet? jm D$NEXT$FDEV ; No -- go do the next one RET unit: db 0 D$FDEV$HDR: DB CR,LF,LF,'- FLOPPY DISK ASSIGNMENTS -',CR,LF DB ' CP/M drive ' DB 'Floppy disk',CR,LF DB ' ------------------------',CR,LF,'$' D$FDEV$LIN: DB ' ' D$CURRENT: DB 'x ' D$EDISK: DB ' ' D$EBLANK: DB ' ' D$FNAME: DB ' ' DB CR,LF,'$' D$FDEV$HLEN EQU $-D$FDEV$LIN ; Line length FNAMES: DB 'First ' DB 'Second' DB 'Third ' DB 'Fourth' ; end of DISPLAY$FDEV GET$BIOS$VERS: ; Get bios version -- Brings the current BIOS jump tables (starting ; at warm boot) to a local area for ease of utility access. If ; this BIOS is version 2.1 or greater, the secondary jump table ; is brought in as well. ; ; Entry: none ; Exit: Z = bios < 2.1 (old bios) ; NZ = bios 2.1+ (fixed disk bios) ; All registers are modified ; LHLD 1 ; Get start of bios jump table LXI D,LB$BIOS$TBL ; Move bios to local storage LXI B,LB$LEN ; . (length of bios area) DB 0edh,0b0h ; . (move routine) MVI A,0 ; Test CP/M version CALL LB$GETNXT ; Get next jump table STA LB$VERS ; Save bios version INX H ; See if HL is 0FFFFh MOV A,H ; . ORA L ; . RZ ; If so, then old version DCX H ; Fix HL as it has the table addr LXI D,LB$XTBL ; Move extra table to local storage LXI B,LB$XLEN ; . (length of extra table) db 0edh,0b0h ; . (move routine) MVI A,0FFH ; Set NZ to indicate bios ORA A ; ... version 2.1+ RET ; ... and return. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Data area . . . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; Replicated BIOS for ease of use . . . LB$BIOS$TBL: LB$WBOOT DB 0,0,0 ; Warm boot LB$CONST DB 0,0,0 ; Console status LB$CONIN DB 0,0,0 ; Console input LB$CONOUT DB 0,0,0 ; Console output LB$LISTOUT DB 0,0,0 ; List output LB$PUNCH DB 0,0,0 ; Punch output LB$READER DB 0,0,0 ; Reader input LB$HOMDSK DB 0,0,0 ; Home disk (move to track 00) LB$SELDSK DB 0,0,0 ; Select disk drive LB$SETTRK DB 0,0,0 ; Select track number LB$SETSEC DB 0,0,0 ; Select sector number LB$SETDMA DB 0,0,0 ; Set DMA address LB$DSKREAD DB 0,0,0 ; Disk read LB$DSKWRITE DB 0,0,0 ; Disk write LB$LISTST DB 0,0,0 ; List status LB$SECTRN DB 0,0,0 ; Sector translate routine ; AMPRO-specific BIOS calls LB$GETNXT DB 0,0,0 ; Get bios ver & next tbl address LB$GETEDSK DB 0,0,0 ; Get pointer to E-disk storage LB$IOINIT DB 0,0,0 ; Set new I/O parameters LB$SCSIDRV DB 0,0,0 ; SCSI direct driver LB$LEN EQU $-LB$WBOOT ; Length of bios table LB$XTBL: LB$SWAP$DRV DB 0,0,0 ; Swap two logical drives LB$WINDRV DB 0,0,0 ; Set/get win drive parameters LB$PHYTAB DB 0,0,0 ; Set/get phytab access LB$GET$LDTE DB 0,0,0 ; Get physical table entry address LB$RESERVED DB 0,0,0 ; Reserved entry LB$XLEN EQU $-LB$XTBL ; Length of extra table LB$VERS DB 0 doit: ; main program begins here ; ASK1: CALL ILPRT ; print following string DB CR,LF,LF,'FORMAT or VERIFY? (F or V)' DB CR,LF,'Press or <^C> to exit.$' ASK1A: CALL CONIN ; get response CPI ESC JZ EXIT ; exit to operation system CPI 3 JZ EXIT ; ctl c ANI UPCASE ; force upper case CPI 'F' JZ SETF ; if format CPI 'V' JZ SETV ; if verify JMP ASK1A ; otherwise, do this again ; set function code and do it ; SETF: MVI A,1 STA FUNC JMP FORMAT SETV: MVI A,2 STA FUNC JMP VERIFY ;setup the format routine ; FORMAT: CALL CLRSC CALL ILPRT DB 8,32,CR,LF,LF ; overwrite response and make new line DB 'FORMAT prepares a fresh diskette for data or ' DB 'program storage.$' CALL ASK5 ; ask destination JC ASK1 ; restart if bad selection JMP ASK2 FORM0: CALL ASK6 ; give warning JC ASK1 CALL EXEC ; do it JMP ASK1 ; restart at end of format ;setup the verify routine ; VERIFY: CALL CLRSC CALL ILPRT DB 8,32,CR,LF DB CR,LF,'VERIFY checks the reliability of data on a disk.$' CALL ASK5 ; ask for destination disk JC ASK1 JMP ASK2 VERF0: CALL ASK3 ; ask to load disk JC ASK1 CALL EXEC ; do it JMP ASK1 ;get selection and update TABLE ; ASK2: CALL ILPRT ; print following string DB CR,LF,LF,'Formats Available:' DB CR,LF,LF DB ' ' DB '48 TPI FORMATS',CR,LF DB ' (48 tpi Drive Required)',CR,LF,LF DB 'A - H/Z 89 SSDD ' DB 'I - MORROW MD3 DSDD',CR,LF DB 'B - H/Z 89 DSDD ' DB 'J - OSBORNE 2 SSDD',CR,LF DB 'C - H/Z 89 SSXD ' DB 'K - PMC-101 MicroMate DSDD',CR,LF DB 'D - H/Z 89 DSXD ' DB 'L - SANYO MBC 1000/1100 DSDD',CR,LF DB 'E - H/Z 100 SSDD ' DB 'M - TELEVIDEO 802/803 DSDD',CR,LF DB 'F - H/Z 100 DSDD ' DB 'N - TRS80-3 w/MEM MERCH CP/M SSDD',CR,LF DB 'G - KAYPRO II SSDD ' DB 'O - TRS80-4 w/MONTEZUMA CP/M SSDD',CR,LF DB 'H - MORROW MD2 SSDD',CR,LF,LF DB ' ' DB '96 TPI FORMATS',CR,LF DB ' (96 tpi Drive Required)',CR,LF,LF DB 'P - DEC RAINBOW SSDD ' DB 'S - H/Z 89 DSDD ',CR,LF DB 'Q - EAGLE IIE-2 SSDD ' DB 'T - H/Z 89 SSXD',CR,LF DB 'R - H/Z 89 SSDD ' DB 'U - H/Z 89 DSXD' DB CR,LF,LF,'Choose one or to Restart: $' ASKAGN: CALL CONIN ; get the answer CPI 3 ; ^c? JZ EXIT ; exit CPI ESC ; esc? JZ ASK1 ; return ANI UPCASE ; mask upper case sta typeletter CPI 'A' ; a? JZ H1 ; h/z 89 ssdd 48tpi CPI 'B' ; b? JZ H2 ; h/z 89 dsdd 48tpi CPI 'C' ; c? JZ H3 ; h/z 89 ssxd 48tpi CPI 'D' ; d? JZ H4 ; h/z 89 dsxd 48tpi CPI 'E' ; e? JZ H9 ; h/z 100 ssdd CPI 'F' ; f? JZ H10 ; h/z 100 dsdd CPI 'G' ; g? JZ K2 ; kaypro 2 CPI 'H' ; h? JZ MD2 ; morrow md2 CPI 'I' ; i? JZ MD3 ; morrow md3 CPI 'J' ; j? JZ OSB ; osborne 2 CPI 'K' ; k? JZ PMC ; pmc-101 type a CPI 'L' ; l? JZ SAN ; sanyo mbc 1000/1100 CPI 'M' ; m? JZ TEL ; televideo 802/803 CPI 'N' ; n? JZ TR ; trs80-3 w/mem merchant cp/m CPI 'O' ; o? JZ T4 ; trs80-4 CPI 'P' ; p? JZ DEC ; dec rainbow CPI 'Q' ; q? JZ EG ; eagle CPI 'R' ; r? JZ H5 ; h/z 89 ssdd 96tpi CPI 'S' ; s? JZ H6 ; h/z 89 dsdd 96tpi CPI 'T' ; t? JZ H7 ; h/z 89 ssxd 96tpi CPI 'U' ; u? JZ H8 ; h/z 89 dsxd 96tpi JMP ASKAGN ; anything else ask again typeletter: db 'a' ASK2E: STC ; set error flag RET ;update TABLE routines begin here... ; K2: MVI A,2 ; 512 bytes/sectors STA SIZE ; store it MVI A,24 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA TYPE ; no type byte STA SBIAS ; no bias STA TWOSID ; single sided format STA TPI96 ; 0=48tpi, 1=96tpi format LXI D,SEC512 ; point to data CALL MOVDAT ; move to dat0 LXI D,K2SKW ; point to skew table JMP MOVSKW ; move it to skew K2SKW: DB 0,8,3,6,1,9,4,7,2,5,255 EG: MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,79 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA TYPE ; no type byte STA SBIAS ; no bias STA TWOSID ; single sided format INR A ; STA TPI96 ; 0=48tpi, 1=96tpi format LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew T4: MVI A,1 ; 256 bytes/sectors STA SIZE ; store it MVI A,21 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA TYPE ; no type byte STA SBIAS ; no bias STA TWOSID ; single sided format STA TPI96 ; 0=48tpi, 1=96tpi format LXI D,SEC256 ; point to data CALL MOVDAT ; move to dat0 LXI D,T4SKW ; point to skew table JMP MOVSKW ; move it to skew T4SKW: DB 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,255 TR: MVI A,2 ; 512 bytes/sectors STA SIZE ; store it MVI A,24 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA TYPE ; no type byte STA SBIAS ; no bias STA TWOSID ; single sided format STA TPI96 ; 0=48tpi, 1=96tpi format LXI D,SEC512 ; point to data CALL MOVDAT ; move to dat0 LXI D,TRSKW ; point to skew table JMP MOVSKW ; move it to skew TRSKW: DB 1,6,2,7,3,8,4,9,5,10,255 OSB: MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA TYPE ; no type byte STA SBIAS ; no sector bias STA TWOSID ; single sided format STA TPI96 ; 0=48tpi, 1=96tpi format LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew OSBSKW: DB 1,2,3,4,5,255 PMC: MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA TYPE ; no type byte STA SBIAS ; no sector bias STA TPI96 ; 0=48tpi, 1=96tpi format INR A STA TWOSID ; double sided format LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew SAN: MVI A,1 ; 256 bytes/sectors STA SIZE ; store it MVI A,45 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TPI96 ; 0=48tpi, 1=96tpi format STA TYPE ; type byte INR A ; roll up a STA TWOSID ; double sided format LXI D,SEC256 ; point to data CALL MOVDAT ; move to dat0 LXI D,SANSKW ; point to skew table JMP MOVSKW ; move it to skew SANSKW: DB 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,255 TEL: MVI A,1 ; 256 bytes/sectors STA SIZE ; store it MVI A,21 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TPI96 ; 0=48tpi, 1=96tpi format STA TYPE ; type byte INR A ; roll up a STA TWOSID ; double sided format LXI D,SEC256 ; point to data CALL MOVDAT ; move to dat0 LXI D,TELSKW ; point to skew table JMP MOVSKW ; move it to skew TELSKW: DB 1,4,7,10,13,16,2,5,8,11,14,17,3,6,9,12,15,18,255 MD2: MVI A,2 ; STA TYPE ; MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no sector bias STA TWOSID ; single sided format STA TPI96 ; 0=48tpi, 1=96tpi format LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew MD3: MVI A,3 ; STA TYPE ; MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no sector bias STA TPI96 ; 0=48tpi, 1=96tpi format INR A ; STA TWOSID ; double sided format LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew DEC: MVI A,2 ; 512 bytes/sectors STA SIZE ; store it MVI A,24 ; gap3 size STA GAP3 ; MVI A,79 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA TYPE ; no type byte STA SBIAS ; no sector bias STA TWOSID ; single sided format MVI A,1 ; STA TPI96 ; 0=48tpi, 1=96tpi format LXI D,SEC512 ; point to data CALL MOVDAT ; move to dat0 LXI D,DECSKW ; point to skew table JMP MOVSKW ; move it to skew DECSKW: DB 1,2,3,4,5,6,7,8,9,10,255 H1: MVI A,1 ; 256 bytes/sectors STA SIZE ; store it MVI A,45 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TWOSID ; single sided format STA TPI96 ; 0=48tpi, 1=96tpi format MVI A,4 ; STA TYPE ; type byte LXI D,SEC256 ; point to data CALL MOVDAT ; move to dat0 LXI D,H1SKW ; point to skew table JMP MOVSKW ; move it to skew H1SKW: DB 1,12,7,2,13,8,3,14,9,4,15,10,5,16,11,6,255 H2: MVI A,1 ; 256 bytes/sectors STA SIZE ; store it MVI A,45 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TPI96 ; 0=48tpi, 1=96tpi format INR A ; roll up a STA TWOSID ; double sided format MVI A,5 ; STA TYPE ; type byte LXI D,SEC256 ; point to data CALL MOVDAT ; move to dat0 LXI D,H1SKW ; point to skew table JMP MOVSKW ; move it to skew H3: MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TWOSID ; single sided format STA TPI96 ; 0=48tpi, 1=96tpi format MVI A,6 ; STA TYPE ; type byte LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew H4: MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TPI96 ; 0=48tpi, 1=96tpi format INR A ; roll up a STA TWOSID ; double sided format MVI A,7 ; STA TYPE ; type byte LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew H5: MVI A,1 ; 256 bytes/sectors STA SIZE ; store it MVI A,45 ; gap3 size STA GAP3 ; MVI A,79 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TWOSID ; single sided format INR A ; 96 tpi format STA TPI96 ; 0=48tpi, 1=96tpi format MVI A,8 ; STA TYPE ; type byte LXI D,SEC256 ; point to data CALL MOVDAT ; move to dat0 LXI D,H1SKW ; point to skew table JMP MOVSKW ; move it to skew H6: MVI A,1 ; 1024 bytes/sectors STA SIZE ; store it MVI A,45 ; gap3 size STA GAP3 ; MVI A,79 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias INR A ; roll up a STA TPI96 ; 0=48tpi, 1=96tpi format STA TWOSID ; double sided format MVI A,9 ; STA TYPE ; type byte LXI D,SEC256 ; point to data CALL MOVDAT ; move to dat0 LXI D,H1SKW ; point to skew table JMP MOVSKW ; move it to skew H7: MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,79 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TWOSID ; single sided format INR A ; roll up a STA TPI96 ; 0=48tpi, 1=96tpi format MVI A,10 ; STA TYPE ; type byte LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew H8: MVI A,3 ; 1024 bytes/sectors STA SIZE ; store it MVI A,102 ; gap3 size STA GAP3 ; MVI A,79 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias INR A ; roll up a STA TPI96 ; 0=48tpi, 1=96tpi format STA TWOSID ; double sided format MVI A,11 ; STA TYPE ; type byte LXI D,SEC1K ; point to data CALL MOVDAT ; move to dat0 LXI D,OSBSKW ; point to skew table JMP MOVSKW ; move it to skew H9: MVI A,2 ; 512 bytes/sectors STA SIZE ; store it MVI A,121 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TPI96 ; 0=48tpi, 1=96tpi format STA TWOSID ; single sided format MVI A,12 ; STA TYPE ; type byte LXI D,SEC512 ; point to data CALL MOVDAT ; move to dat0 LXI D,H100SKW ; point to skew table JMP MOVSKW ; move it to skew H100SKW: DB 1,2,3,4,5,6,7,8,255 H10: MVI A,2 ; 512 bytes/sectors STA SIZE ; store it MVI A,121 ; gap3 size STA GAP3 ; MVI A,39 ; # of tracks STA MAXTRK ; XRA A ; zero out accum STA SBIAS ; no bias STA TPI96 ; 0=48tpi, 1=96tpi format INR A ; roll up a STA TWOSID ; double sided format MVI A,13 ; STA TYPE ; type byte LXI D,SEC512 ; point to data CALL MOVDAT ; move to dat0 LXI D,H100SKW ; point to skew table JMP MOVSKW ; move it to skew ;move the new data to TABLE ; MOVDAT: MVI B,8 ; # of bytes to move LXI H,DAT0 ; point to data location MOVDT: LDAX D ; move byte to accum MOV M,A ; store it INX D ; roll up reg de INX H ; roll up reg hl DCR B ; count down 1 JNZ MOVDT ; done? RET MOVSKW: LXI H,SKEW ; point to skew MOVSK: LDAX D ; move into accum MOV M,A ; store it CPI 0FFH ; done? JZ RETURN ; INX D ; roll up de INX H ; roll up hl JMP MOVSK ; again RETURN: LDA FUNC ; get function # CPI 1 ; was it a format? JZ FORM0 ; JMP VERF0 ; if not format must be verify SEC128: DB 32,0E5H,32,0E5H,32,0E5H,32,0E5H SEC256: DB 64,0E5H,64,0E5H,64,0E5H,64,0E5H SEC512: DB 128,0E5H,128,0E5H,128,0E5H,128,0E5H SEC1K: DB 0,0E5H,0,0E5H,0,0E5H,0,0E5H ;tell them to put the disk in ; ASK3: lda typeletter call conout CALL ILPRT ; print the following string DB CR,LF,LF,'Place disk in Drive ' ASK30s: db 'a' DB CR,LF,LF,'Press to VERIFY, ' DB ' to quit. $' JMP ASK6E ASK5: call disp$fdev CALL ILPRT DB CR,LF,LF,'Destination drive? (A - ' plug1: db 'D) $' ASK5E: CALL CONIN ; get the answer CPI ESC JZ EXIT CPI 3 JZ EXIT ANI UPCASE ; force upper case CPI 'A' ; first valid drive JC ASK5E cplug1: equ $+1 CPI 'E' ; first invalid drive JNC ASK5E sta ask60d sta ask30s push psw call conout pop psw sui 'A' jplug1: jmp ask50s call lb$get$ldte mov a,m cpi 1 jnz ask5 inx h mov a,m ani 3 ask50s: STA DDRIV CALL SETSEL ; disk select bits ORA A RET ASK6: lda typeletter call conout CALL ILPRT ; print the following string DB CR,LF,LF,'Place destination disk on drive ' ask60d DB 'a' DB CR,LF,LF,'Press to write, ' DB ' to quit. $' ASK6E: CALL CONIN ; get answer CPI CR RZ CPI ESC JZ EXIT JMP ASK6E ;execute it! ; EXEC: CALL ILPRT DB CR,LF,LF,'$' LDA FUNC ; function 1=fmt, 2=vfy CPI 1 JZ FMT CPI 2 JZ VFY ; RET ;format routines... ; FMT: LDA DDRIV CALL SETSEL CALL SETUP XRA A STA TRACK STA HEAD NEXTRK: CALL KEY LXI H,FRMSG CALL PRINT CALL TMRPRT CALL MAKETRK MVI A,TRY STA TRIES NT3: CALL WRITRK JZ NT5 LXI H,TRIES DCR M JNZ NT3 CALL ILPRT DB CR,' ' DB CR,LF,'FORMAT failed.',CR,LF,'$' CALL REPORT RET NT5: LDA TWOSID ORA A LDA TRACK JZ NT0 LDA HEAD ORA A LDA TRACK JZ NT1 NT0: LXI H,MAXTRK CMP M JNZ NT1 CALL ILPRT DB CR,' ' DB CR,LF,'FORMAT complete.',CR,LF,LF,'$' ;check the TYPE byte to see if a boot loader is needed ; LDA TYPE ANI 0FH ; mask off upper nibble CPI 2 ; if morrow md2 JZ MD2GEN ; write boot loader CPI 3 ; if morrow md3 JZ MD3GEN ; write boot loader CPI 4 ; if h/z 89 ssdd JZ H1GEN ; write boot loader CPI 5 ; if h/z 89 dsdd JZ H2GEN ; write boot loader CPI 6 ; if h/z 89 ssxd (48tpi) JZ H3GEN ; write boot loader CPI 7 ; if h/z 89 dsxd (48tpi) JZ H4GEN ; write boot loader CPI 8 ; if h/z 89 ssdd (96tpi) JZ H5GEN ; write boot loader CPI 9 ; if h/z 89 dsdd (96tpi) JZ H6GEN ; write boot loader CPI 10 ; if h/z 89 ssxd (96tpi) JZ H7GEN ; write boot loader CPI 11 ; if h/z 89 dsxd (96tpi) JZ H8GEN ; write boot loader CPI 12 ; if h/z 100 ssdd JZ H9GEN ; write boot loader CPI 13 ; if h/z 100 dsdd JZ H10GEN ; write boot loader JMP VFY ; anything else begin verify NT1: INR A STA TRACK CALL STEPIN JMP NEXTRK ;verify routines begin here ; VFY: MVI A,0 STA HEAD LDA DDRIV CALL SETSEL CALL SETUP MVI A,TRY STA TRIES V1: CALL READID JZ V0 LXI H,TRIES DCR M JNZ V1 CALL ILPRT DB CR,LF,'VERIFY failed. Cannot read source disk.',cr,lf,'$' RET V0: LDA TWOSID CPI 1 MVI A,0 JC VF0 INR A VF0: STA TWOSID XRA A STA TRACK ; start with track 0 VLOOP: CALL KEY LXI H,VFMSG CALL PRINT CALL TMRPRT MVI A,TRY STA TRIES VL1: CALL READTRK JZ VL0 LXI H,TRIES DCR M JNZ VL1 CALL ILPRT DB CR,' ' DB CR,LF,'VERIFY failed. Unrecoverable read error.',CR,LF,'$' CALL REPORT RET VL0: LDA TWOSID ORA A LDA TRACK JZ VF1 LDA HEAD ORA A LDA TRACK JZ VF2 VF1: LXI H,MAXTRK CMP M JNZ VF2 CALL ILPRT DB CR,' ' DB CR,LF,'VERIFY complete.',CR,LF,'$' RET VF2: INR A STA TRACK CALL STEPIN JMP VLOOP ;boot loader routine begin here ; ;gen as in sysgen! ; GEN: LDA DDRIV ; CALL SETSEL ; CALL SETUP ; setup write XRA A ; zero out acc STA TRACK ; track 0 STA HEAD ; LXI H,TKBUF ; get point SHLD DMAADR ; save buffer pointer LXI H,SKEW1 ; point to new skew CALL WTLOOP ; write data JMP VFY MD2GEN: CALL MDGEN ; LXI D,DAT4 ; point to next data MVI B,25 ; CALL MOVDT ; JMP MD1GEN ; MD3GEN: CALL MDGEN ; LXI D,DAT5 ; point to next data MVI B,25 ; move double sided dpb CALL MOVDT ; JMP MD1GEN ; MDGEN: MVI A,1 ; STA SKEW1 ; INR A ; STA SKEW1+1 ; MVI A,255 ; STA SKEW1+2 ; LXI D,DAT3 ; point to morrow data MVI B,60 ; # of bytes to move LXI H,TKBUF ; point to buffer area CALL MOVDT ; move data MVI E,0 ; fill data MVI D,68 ; # of bytes to move CALL LOAD ; move them RET MD1GEN: MVI E,0 ; MVI D,103 ; CALL LOAD ; CALL MOVE5 ; CALL LOAD ; CALL MOVE5 ; CALL LOAD ; CALL MOVE5 ; CALL LOAD ; LXI D,DAT3 ; MVI B,60 ; CALL MOVDT ; MVI D,68 ; MVI E,0 ; CALL LOAD ; CALL MOVE5 CALL LOAD CALL MOVE5 CALL LOAD CALL MOVE5 CALL LOAD CALL MOVE5 CALL LOAD JMP GEN ; MOVE5: MVI E,0E5H ; MVI D,0 ; RET H1GEN: CALL HGEN ; load skew1 LXI D,H1DAT ; point to h1 data JMP HGEN1 ; store data H2GEN: CALL HGEN ; load skew1 LXI D,H2DAT ; point to h2 data JMP HGEN1 ; store the data H3GEN: CALL HGEN LXI D,H3DAT JMP HGEN2 H4GEN: CALL HGEN LXI D,H4DAT JMP HGEN2 H5GEN: CALL HGEN LXI D,H5DAT JMP HGEN1 H6GEN: CALL HGEN LXI D,H6DAT JMP HGEN1 H7GEN: CALL HGEN LXI D,H7DAT JMP HGEN2 H8GEN: CALL HGEN LXI D,H8DAT JMP HGEN2 H9GEN: CALL HGEN LXI D,H9DAT JMP HGEN2 H10GEN: CALL HGEN LXI D,H10DAT JMP HGEN2 HGEN: MVI A,1 ; load STA SKEW1 ; skew MVI A,255 ; table STA SKEW1+1 ; RET HGEN1: ;use this routine for 256 byte sector h/z formats MVI B,29 ; # of bytes to move LXI H,TKBUF ; point to buffer area CALL MOVDT ; move data MVI E,0E5H ; fill data MVI D,227 ; # of bytes to move CALL LOAD ; move them JMP GEN HGEN2: ;use this routine for 512/1024 byte sector h/z formats MVI B,29 ; # of bytes to move LXI H,TKBUF ; point to buffer area CALL MOVDT ; move data MVI E,0E5H ; fill data MVI D,227 ; # of bytes to move CALL LOAD ; move them CALL MOVE5 CALL LOAD CALL MOVE5 CALL LOAD CALL MOVE5 CALL LOAD JMP GEN ;step in the drive ; STEPIN: LDA TWOSID ORA A JZ STI ; single sided LDA HEAD ORA A MVI A,1 JZ STI0 MVI A,0 STI0: STA HEAD JZ STI1 STI: LDA SELBYT ANI SID0 ; mask side bit off OUT CONT ; select side 0 STA SELBYT CALL WAIT MVI A,STEPI CALL OUTCMD STILP: IN STAT RAR JC STILP RET STI1: LDA SELBYT ORI SID1 OUT CONT ; select side 1 STA SELBYT LXI H,TRACK DCR M JMP WAIT ;write a track ; WRITRK: IN STAT RAR JC WRITRK LXI H,TKBUF MVI A,WRTRK ; write track command CALL OUTCMD CALL WR MOV A,B STA STATUS ANI ERRIII RET WR: IN STAT ; get fdc status MOV B,A ; save status RAR ; check busy RNC ; end of command, return to caller RAR ; check for drq JNC WR ; if not MOV A,M ; get a byte from buffer OUT WDAT ; to fdc INX H ; bump hl JMP WR ; again ;make a track in memory ; MAKETRK: LXI H,TKBUF ; create track image in memory MVI B,60 MVI A,4EH MTLP: MOV M,A ; write gap4a INX H DCR B JNZ MTLP SHLD DMAADR ; sector 1 starts here LDA HEAD STA SIDE LXI H,SKEW ;load skew table pointer LOOP: MOV C,M INX H INR C JZ ENDTRK ; if c was 0ffh DCR C LDA SBIAS ADD C STA SECTOR PUSH H ; save skew pointer on stack CALL MAKTRK POP H JMP LOOP ENDTRK: LHLD DMAADR LXI B,1000 ETLP: MVI M,4EH ;end track fill data INX H DCX B MOV A,B ORA C JNZ ETLP SHLD DMAADR RET MAKTRK: LHLD DMAADR ; track image PUSH H ; save it LXI H,TABLE ; track format table MAKT1: MOV D,M ; get count INX H ; bump pointer MOV E,M ; get data INX H ; bump pointer MOV A,E ; check for end of table (0ffh) INR A ; 0ffh + 1 = 0 JZ MAKT2 ; if end of table XTHL ; point to track buffer CALL LOAD ; fill track buffer XTHL ; point to format table JMP MAKT1 ; again MAKT2: POP H ; get track buffer address from stack SHLD DMAADR ; save pointer to track buffer RET ; to caller ;write current track from read buffer ; WRITETRK: LXI H,RDBUF SHLD DMAADR LXI H,SKEW ; point to skew table WTLOOP: MOV C,M INX H ; bump pointer INR C RZ ; finished, end of table is 0ffh DCR C LDA SBIAS ADD C OUT WSEC ; to fdc PUSH H ; save skew pointer CALL WRITESEC POP H JMP WTLOOP ;write a sector from DMA buffer ; WRITESEC: IN STAT ; clear status IN RDAT ; clear any trash LHLD DMAADR MVI A,WRSEC ; write sector command CALL OUTCMD ; to fdc CALL WR ; write the data SHLD DMAADR ; save pointer MOV A,B ; get status STA STATUS ANI ERRII RZ ; return to this caller POP H ; adjust stack from writetrk POP H RET ; return to previous caller ;read current track into read buffer ; READTRK: LXI H,RDBUF SHLD DMAADR LXI H,SKEW ; point to skew table RTLOOP: MOV C,M ; get sector number from table INX H ; bump pointer INR C RZ ; finished, end of table is 0ffh DCR C LDA SBIAS ADD C STA SECTOR OUT WSEC ; to fdc PUSH H ; save skew pointer CALL READSEC ; read the sector RT0: POP H JMP RTLOOP READSEC: IN STAT ; clear status IN RDAT ; clear any trash LHLD DMAADR ; pointer to read buffer MVI A,RDSEC ; read sector command CALL OUTCMD ; to fdc CALL RD ; read the data SHLD DMAADR ; save pointer MOV A,B STA STATUS ANI ERRII RZ POP H ; adjust stack from readtrk POP H RET ; to previous caller RD: IN STAT ; get fdc status byte MOV B,A ; save status RAR ; rotate busy bit to carry RNC ; end of command, return to caller RAR ; rotate data request to carry JNC RD ; wait for data request RD0: IN RDAT ; get data from fdc MOV M,A ; put it into buffer INX H ; bump hl JMP RD ; again READID: IN STAT IN RDAT LXI H,IDSV MVI A,RDID CALL OUTCMD CALL RD MOV A,B ; get status STA STATUS ANI ERRIII RET ;allow FDC to setup properly ; WAIT: LXI B,50 * MSEC WT0: DCX B MOV A,B ORA C JNZ WT0 RET WAIT10: LXI B,10 * MSEC JMP WT0 LOAD: MOV M,E ; (e) to track buffer INX H ; increment pointer DCR D ; decrement count JNZ LOAD ; again RET CLRSC: MVI D,24 ; print 24 line feed chars to clear screen CLS: MVI A,LF CALL CONOUT ; out to console CALL WAIT10 ; wait 10 ms after line feed DCR D ; decrement count JNZ CLS ; again RET PRINT: MOV A,M ; hl points to text string INX H ; bump hl CPI '$' ; check for terminator RZ ; return to caller CALL CONOUT ; send byte to console JMP PRINT ; again pCONOUT: PUSH B ; save PUSH D ; the PUSH H ; registers MOV E,A ; text to be printed MVI C,2 ; console output function CALL 5 ; bdos POP H ; restore POP D ; the POP B ; registers RET ;prints next byte pointed to by top of stack ;until delimiter $ is found ; ILPRT: XTHL ; return address to hl points to text ILP: MOV A,M ; get next byte INX H ; bump pointer CPI '$' ; check for string terminator JZ ILPE ; if end of string CALL pCONOUT ; send byte to console JMP ILP ; again ILPE: XTHL ; put updated pointer on stack RET CONOUT: PUSH B ; save PUSH D ; the PUSH H ; registers MOV E,A ; text to be printed MVI C,6 ; console output function CALL 5 ; bdos POP H ; restore POP D ; the POP B ; registers RET CONIN: MVI A,9 ; bios call avoids echo to console BIOS: LHLD 1 MOV L,A PCHL CONINB: PUSH B PUSH D ; save PUSH H ; registers MVI C,1 ; console input function CALL 5 ; bdos POP H ; restore POP D ; registers POP B RET ; ;restore the disk and wait for status ; ; The current setup routine does a restore with the 1772 ; motor on flag enabled. It exits as soon as the BUSY ; status bit goes away, or after a 4 second timeout. SETUP: LDA SELBYT ; get selected drive OUT CONT ; select the drive MVI A,REST ; restore command CALL OUTCMD ; output the command LXI H,4000 ; 4000 ms timeout setup DEL0: MVI C,0 DEL1: DCR C JNZ DEL1 IN STAT RAR JNC READY ; go on if 1772 done DCX H MOV A,H ORA L JNZ DEL1 MVI A,0D0H ; timed out -- force interrupt, CALL OUTCMD ; then report failure JMP FAILED ; The current ready function checks to see if a diskette ; is inserted in a drive. A read address command with ; the motor on flag enabled is used. If the command ; hangs up, the 1772 is not receiving index pulses, ; indicating the lack of a spinning diskette. READY: MVI A,0C0H ; read address command CALL OUTCMD LXI H,4000 ; 4000 mS timeout setup MVI C,0 RDY1: DCR C JNZ RDY1 IN STAT RAR RNC ; finished, if 1772 done DCX H MOV A,H ORA L JNZ RDY1 ; loop till timeout MVI A,0D0H ; timeout -- force interrupt, CALL OUTCMD ; then report failure FAILED: LDA SELBYT ANI 0FH MVI C,0 FLD1: INR C RAR JNC FLD1 MOV A,C adi 30H ; add ascii bias STA DRI CALL ILPRT ; print following string DB CR,LF,'Drive ' DRI: DB 'A Not Ready, Insert disk, close door, and try again.',CR,LF,'$' POP B ; adjust stack RET ;send a command to the FDC ; OUTCMD: OUT CMND MVI A,10 OC0: DCR A JNZ OC0 ; wait 35 us. for fdc to set-up RET KEY: push b push d mvi c,6 mvi e,0ffh call 5 pop d pop b rz CPI 3 JZ EXIT PUSH PSW CALL ILPRT DB CR,' ',CR,'$' ; clear the line POP PSW CPI ESC RNZ POP H RET EXIT: JMP 0 ; warm boot TMRPRT: LDA TRACK LXI D,TKMSG0 CALL BINASC LDA HEAD LXI D,SDMSG0 CALL BINASC LXI H,TKMSG JMP PRINT ; print returns to caller REPORT: LXI D,DR ; point to error message LDA SELBYT ANI 0FH ; mask upper nybble MVI C,0 ; clear counter R1: INR C ; bump it RAR ; rotate selbit into carry JNC R1 ; again? MOV A,C ADI 30H ; add ascii bias STAX D ; store it in message STA WPRMSG0 LDA STATUS ANI WPR ; is disk protected? JZ R2 LXI H,WPRMSG ; write protected message CALL PRINT POP H ; adjust the stack CALL CONIN ; get response CPI CR ; carriage return? JZ EXEC ; if so RET ; get out of here R2: LXI D,TK ; in error message LDA TRACK CALL BINASC LXI D,HD LDA SIDE ORA A ; set flags JZ RPRT1 MVI A,1 RPRT1: CALL BINASC LXI D,SC LDA SECTOR CALL BINASC LXI D,ST LDA STATUS ANI RNF JNZ SRNF LXI H,CRCER CALL MOV3 JMP RPRT2 SDNR: LXI H,DNRER CALL MOV3 JMP RPRT2 SRNF: LXI H,RNFER CALL MOV3 RPRT2: LXI H,ERRMSG RPRT3: JMP PRINT ; print returns to caller MOV3: MVI B,3 MOVL: MOV A,M STAX D INX H INX D DCR B JNZ MOVL RET BINASC: PUSH PSW ; save value PUSH D ; save string ptr MVI A,'0' ; ascii zero STAX D LXI B,2 ; b=0, c=2 XRA A ; a=0 B0: INX D ; bump ptr STAX D ; zero to str DCR C JNZ B0 ; again please POP D ; restore de LXI H,TBL ; conversion table B1: MVI C,0 ; clear count MOV A,M ; table value INR A JZ BEND ; end of table, conv done POP PSW ; restore value B3: SUB M ; begin division JC B2 INR C ; keep count JMP B3 B2: ADD M ; restore acc PUSH PSW ; save it MOV A,C ; count CPI 0 JNZ STSTR ; set ascii value in string MOV A,B CPI 0 ; 1st time? JNZ STSTR B4: INX H ; bump tbl ptr JMP B1 ; next STSTR: MVI B,1 ; flag 1st time MOV A,C ; count to c ADI 30H ; ascii bias STAX D ; write it into string INX D ; bump str ptr JMP B4 BEND: POP PSW ; adjust stack RET ; return to caller TBL: DB 100 DB 10 DB 1 DB 255 ; end of table ;setup the selbyt ; SETSEL: inr a MOV C,A XRA A STC STSL: RAL DCR C JNZ STSL ORI ROMOFF STA SELBYT RET ;error messages... ERRMSG: DB CR,LF,' Error: Drive ' DR: DB 0,': Track ' TK: DB 0,0,0,' Head ' HD: DB 0,0,0,' Sector ' SC: DB 0,0,0,' Status ' ST: DB 0,0,0,CR,LF,'$' TKMSG: DB 'Track ' TKMSG0: DB 0,0,0,' Side ' SDMSG0: DB 0,0,0,CR,'$' VFMSG: DB 'Verify $' FRMSG: DB 'Format $' WPRMSG: DB CR,' ' DB CR,LF,'Remove write protect tab from ' DB 'destination diskette.' DB CR,LF,'Place diskette in drive ' WPRMSG0:DB 'A, then press . $' DNRER: DB 'DNR' RNFER: DB 'RNF' CRCER: DB 'CRC' ;the main data table.. ; TABLE: DB 12,0 ; defines sector format (#bytes,data) DB 3,0F5H ; write 0a1h DB 1,0FEH ; id address mark DB 1 TRACK: DB 0 DB 1 SIDE: DB 0 DB 1 SECTOR: DB 1 DB 1 SIZE: DB 3 ; always 512 bytes DB 1,0F7H ; write crc (2 bytes) GAP2: DB 22,4EH ; gap 2 length, data PREAM: DB 12,0 ; preamble DB 3,0F5H ; write 0a1h DB 1,0FBH ; data address mark DAT0: DB 0,0E5H ; bytes of data fill DB 0,0E5H ; bytes of data fill DB 0,0E5H ; bytes of data fill DB 0,0E5H ; bytes of data fill DB 1,0F7H ; write crc (2 bytes) GAP3: DB 0,4EH ; gap 3 length, data DW -1 ; end of table (0ffffh) SKEW: DS 40 DAT3: DB 0,0,0,3EH,0C9H,32H,255,253,0CDH,255,253,21H,254,255,39H,5EH DB 23H,56H,21H,17H,0,19H,0EBH,31H,0,255,0D3H,0F6H,0CDH,3,0,0C3H DB 18H,0,CR,LF,'Not a SYSTEM Diskette',CR,LF DAT4: DB 0,0,0,0,0,0,0,0,0 DB 40,0,4,15,1,5EH,0,7FH,0,0C0H,0,32,0,2,0,0E1H DAT5: DB 0,4,0,0,0,0,0,0,0 DB 40,0,4,15,1,0C2H,0,0BFH,0,0E0H,0,30H,0,2,0,89H H1DAT: DB 0E5H,0E5H,0E5H,0E5H,0,62H,0E5H,2,8,0E5H,0E5H,0,0E5H DB 20H,0,3,7,0,97H,0,7FH,0,0F0H,0,20H,0,2,0,0ADH H2DAT: DB 0E5H,0E5H,0E5H,0E5H,0,63H,0E5H,2,16,0E5H,0E5H,0,0E5H DB 20H,0,4,15,0,9BH,0,255,0,0F0H,0,40H,0,2,0,0F7H H3DAT: DB 0E5H,0E5H,0E5H,0E5H,0,66H,0E5H,8,8,0E5H,0E5H,0,0E5H DB 28H,0,3,7,0,0BDH,0,7FH,0,0F0H,0,20H,0,2,0,75H H4DAT: DB 0E5H,0E5H,0E5H,0E5H,0,67H,0E5H,8,16,0E5H,0E5H,0,0E5H DB 28H,0,4,15,0,0C2H,0,255,0,0F0H,0,40H,0,2,0,0BEH H5DAT: DB 0E5H,0E5H,0E5H,0E5H,0,6AH,0E5H,2,16,0E5H,0E5H,1,0E5H DB 20H,0,4,15,1,9BH,0,7FH,0,0C0H,0,20H,0,2,0,0BEH H6DAT: DB 0E5H,0E5H,0E5H,0E5H,0,6BH,0E5H,2,16,0E5H,0E5H,1,0E5H DB 20H,0,4,15,0,3BH,1,255,0,0F0H,0,40H,0,2,0,4DH H7DAT: DB 0E5H,0E5H,0E5H,0E5H,0,6EH,0E5H,8,16,0E5H,0E5H,1,0E5H DB 28H,0,4,15,1,0C2H,0,7FH,0,0C0H,0,20H,0,2,0,85H H8DAT: DB 0E5H,0E5H,0E5H,0E5H,0,6FH,0E5H,8,16,0E5H,0E5H,1,0E5H DB 28H,0,4,15,0,8AH,1,255,0,0F0H,0,40H,0,2,0,0ECH H9DAT: DB 0E5H,0E5H,0E5H,0E5H,0,22H,1,4,8,27H,80H,0,11H DB 20H,0,3,7,0,97H,0,127,0,0F0H,0,20H,0,2,0,0C6H H10DAT: DB 0E5H,0E5H,0E5H,0E5H,0,23H,1,4,16,27H,80H,0,11H DB 20H,0,4,15,1,9BH,0,255,0,0F0H,0,40H,0,2,0,15 SKEW1: DS 4 ; TYPE: DB 0 ; 2=morrow ss, 3=morrow ds etc. FUNC: DS 1 ; function 1=format, 2=verify, MAXTRK: DB 39 ; maximum track TWOSID: DB 0 ; 0=ss , 1=ds HEAD: DB 0 ; SDRIV: DS 1 ; source drive DDRIV: DS 1 ; destination drive SELBYT: DS 1 ; SBIAS: DB 0 ; sector bias 0=ss, 10h=ds, 30h=ds96 TPI96: DB 1 ; 0=48tpi , 1=96tpi DMAADR: DS 2 ; STATUS: DS 1 ; TRIES: DS 1 ; DS 64 ; space for 32 level stack STACK: DS 2 ; space for ccp stack pointer IDSV: DS 6 ; id save area RDBUF: DS 10 * 512 ; read buffer TKBUF: END START ; end of program