; ; FORMAT81.MAC -- Version 1.1 ; ; This is an interim program to format a disk in the Commodore 1581 ; disk drive for use under CP/M 3.0 on the C-128. Disks formatted ; with this program are NOT likely to be compatible with the ; official BIOS upgrade, when it is finally delivered by Commodore ; Business Machines. ; ; USAGE: ; ; FORMAT81 {d:} ; ; Formats the disk in the given drive. If a drive specification is ; not supplied in the command tail, then the currently logged disk ; is assumed. Only drives A, B, C, and D will be accepted; all ; others result in an 'invalid drive' message. Permissible drives ; may be further restricted in the drive list (DrvLst:) below. ; ; Version 1.0 (9/10/87) -- successfully formatted disks in 1581 drive ; using Epson QX-10 format options. ; ; Version 1.1 (9/12/87) -- added command line drive selection, drive ; list, error checking, and drive reset. ; ; Gene Pizzetta ; 481 Revere Street ; Revere, MA 02151 ; Voice (617) 284-0891 ; CompuServe 72060,505 ; Quantum-Link GeneP ; ; This utility was developed with SLRMAC, but should be fully compatible ; with MAC. Z80.LIB is required for assembly. ; WBoot equ 0000h Bdos equ 0005h FcbDrv equ 005ch ; drive number in default FCB lf equ 0ah cr equ 0dh esc equ 1bh ; ; BDOS functions ; ConIn equ 1 ; console input PrtStr equ 9 ; print string CurDsk equ 25 ; get current (default) drive ResetDr equ 37 ; reset drive ConMode equ 109 ; set console mode SetDlmt equ 110 ; set string delimiter ; ; BIOS user vectors ; DrvStr equ 0fe00h ; string to send drive VicDrv equ 0fd02h ; drive number vector VicData equ 0fd06h ; drive error flags Fast equ 0fd08h ; fast drive flag BiosUser equ 30 ; BIOS user function DiskFunc equ 4 ; reg A for user disk function FormatFunc equ 8 ; reg L for user format disk subfunction QueryFunc equ 5 ; reg L for user inquire disk subfunction ; MACLIB Z80 ; org 100h ; jmp Main ; ; valid drives in system (A: through D:), where DrvLst: db 0,0,0,0 ; 00h = valid drive, 0ffh = not valid ; ; string to send drive: ; byte 1 = number of characters in string ; byte 2 = format flag ; byte 3 = sector size (512K) ; byte 4 = last track (79) ; byte 5 = sectors per track (10) ; byte 6 = starting track (0) ; byte 7 = fill byte (0E5h) ; byte 8 = starting sector (1) FmtStr: db 07h,86h,02h,4fh,0ah,00h,0e5h,01h VicByt: db 0 ; VicDrv byte storage SignOn: db 1ah,lf,esc,'G4 C-128 1581 CP/M FORMAT PROGRAM v1.1 ' db esc,'G0',cr,lf,0 AskMsg: db lf,lf,lf,'Press ''$'' to format disk in drive ' Drive: db 0,': ',0 InvMsg: db cr,lf,lf,' ',07h,'Invalid drive',cr,lf,0 WrkMsg: db cr,lf,lf,' Formatting ...',cr,lf,lf,0 ErrMsg: db ' ',07h,'Formatting error',cr,lf,0 FinMsg: db cr,lf,lf,lf,lf,' Format another disk? ',0 ExMsg: db cr,lf,lf,' < Returning to CP/M >',lf,0 ; Main: mvi c,SetDlmt ; set string delimiter to nul lxi d,0 call Bdos mvi c,ConMode ; don't allow ^C to abort lxi d,08h call Bdos lda FcbDrv ; was a drive given? cpi 0 jrnz SaveDr ; (yes) mvi c,CurDsk ; no, find out what the default is call Bdos inr a ; increment to match FCB (A=1, ...) SaveDr: push psw ; save it on the stack adi 40h ; make it ASCII sta Drive ; ..and store it in drive message pop psw ; get back the original push psw ; ..and save it again ; ; check drive list for invalid drive ; lxi h,DrvLst-1 ; point HL to drive list - 1 mvi b,00h ; zero b mov c,a ; move drive number (1-4) to c dad b ; add drive number to HL pointer mvi a,00h ; ..and check it cmp m ; valid drive? jnz Invalid ; (no, abort) ; ; now set up VicByt to be sent to VicDrv vector ; pop psw ; recover drive number cpi 1 ; drive A? jrz DrvA cpi 2 ; drive B? jrz DrvB cpi 3 ; drive C? jrz DrvC cpi 4 ; drive D? jrz drvD jmp Invalid ; ; set vicbyt byte for selected drive ; DrvA: mvi a,1 sta VicByt jr Hello ; DrvB: mvi a,2 sta VicByt jr Hello ; DrvC: mvi a,4 sta VicByt jr Hello ; DrvD: mvi a,8 sta VicByt jr Hello ; Hello: mvi c,PrtStr ; print sign on lxi d,SignOn call Bdos mvi c,PrtStr ; now ask user lxi d,AskMsg call Bdos mvi c,ConIn ; ..and get a response call Bdos cpi '$' ; was it yes? jrz Cont ; (yes, continue) cpi '4' jnz Fini ; (no, abort) Cont: mvi c,PrtStr ; tell 'em we're working lxi d,WrkMsg call Bdos ; ; Format: lxi h,FmtStr ; move format string to lxi d,DrvStr ; ..drive string buffer lxi b,08h ldir ; lda VicByt ; get stored drive byte sta VicDrv ; ..put it in drive vector sta Fast ; ..and in fast flag ; ; call user function to format disk ; mvi a,DiskFunc mvi l,FormatFunc call UserFunc ; ; check for error (we don't care what the error is) ; lda VicData ani 11110001b ; mask unimportant bits cpi 0 jrz DrvLog ; (no error) mvi c,PrtStr ; report error lxi d,ErrMsg call Bdos jr Fini ; ; call user function to log in disk ; DrvLog: mvi a,DiskFunc mvi l,QueryFunc call UserFunc jr Fini ; Invalid: mvi c,PrtStr ; report invalid drive lxi d,InvMsg call Bdos jr Exit ; Fini: mvi c,PrtStr ; we're done ... do it again? lxi d,FinMsg call Bdos mvi c,ConIn call Bdos cpi 'y' jz Hello ; (yes, start over) cpi 'Y' jz hello ; ; call Bdos to reset drive ; lda VicByt mvi c,ResetDr mvi d,00h mov e,a call Bdos ; Exit mvi c,PrtStr ; sign off lxi d,ExMsg call Bdos jmp WBoot ; ; subroutine UserFunc -- calculates address and calls user function ; UserFunc: push h ; save HL lhld WBoot+1 ; address vector for warm boot mvi l,BiosUser*3 ; get offset xthl ; exchange HL with stack ret ; end