.comment % ######################################################### # # # Double density diskette format program # # for the Kaypro 10 (version 1.0) # # (Double Sided Double Density) # # based on FORMAT by Gilbert Ohynsty (and later # # updated by Jim Nickerson and myself) # # # # Begun 24-Mar-83 # # by Matthew Sherman. # # # ######################################################### % .Z80 ; ; track image location is after vfyflp. extrn tbuff, vfyfpy, mmenu public fmtfpy, fmt1tk, thnsd ; vfyfpy is the verify program's entry point ; wboot equ 0 ; restart system entry point (Warm boot) bdos equ 5 ; bdos entry crlf equ 0D0AH ; new line codes cr equ 0DH lf equ 0AH return equ 0DH ; ascii return code esc equ 1BH ; ascii esc frsttrk equ 0 ; first track # lsttrk equ 79 ; last track # nsects equ 10 ; last sector # data equ 013H ; controller data port cmnd equ 010H ; controller command port status equ 010H ; status port for controller wrtcmd equ 0F4H ; write track command, 15 ms delay before execution ; for 1793, write track command, 15 ms delay before ; execution and side select output is made zero ; (used with head select on double sided drives, ; which the Kaypro-II neither has nor supports) rdcmd equ 0E4H ; read track command, 15 ms delay ; same comments as for the write track command rstcmd equ 003H ; restore command seekcmd equ 013H ; seek command bitport equ 20 ; drive select port ; floppy drive equates drvmsk equ 11111110b ; reset drive select bits fpyon equ 00000000b ; select floppy fpyoff equ 00000001b ; deselect floppy sidmsk equ 11111011b ; reset side select bits sid0 equ 00000100b sid1 equ 00000000b denmsk equ 11011111b ; reset density select bits dendbl equ 00000000b ; select double density densgl equ 00100000b ; select single density mtrmsk equ 11101111b ; reset motor bit mask mtron equ 00010000b ; motor on mask mtroff equ 00000000b ; motor off mask maxsec equ 010 ; maximum number of sectors secp equ 012H ; sector port ; print a message print macro x ld c,9 ld de,x call bdos endm ; get a char from console, up case input macro ld c,1 call bdos res 5,a endm ; write cnt number of val bytes into memory (hl) bytes macro val, cnt local loop ld de,cnt loop: ld (hl),val inc hl dec de ld a,d or e jr nz,loop endm ; call bios routine, x=bios jump table #, 0=wboot, 1=const, 2=conin,... bios macro x local retadr ld hl,(1) ld de,x*3 add hl,de ld de,retadr push de jp (hl) retadr: endm fmtfpy: print son1 input cp cr jp nz,mmenu ; not a carriage return, quit, ; else format the disk fmtdsk: print newline call format ; format floppy, call vfyfpy ; verify floppy, jp mmenu ; start over format: call seldsk ; select floppy call home ; home disk drive ld c,frsttrk ; first track # form1: push bc ; save track number while printing it print smsg4 ; "Track number:" pop bc call outdec ; display track number call fmtone inc c ; up track count ld a,c ; max track+1 reached? cp lsttrk+1 jr nz, form1 ; do another track ret ; enter with track number in c fmt1tk: push bc print newline print smsg4 pop bc push bc call outdec ; track number call home ; make sure disk is selected and running, etc. pop bc fmtone: call settrk ; move to track given by c call maktrk ; make track image, track # in c call wrttrk ; format track ret maktrk: ld hl,tran ; sector skew table push hl ; store on stack for use ld hl,tbuff ; hl^ to track image in memory ld b,nsects ; number of sectors to gen bytes 04EH, 80 ; post index gap bytes 0, 12 bytes 0F6H, 3 ; Writes C2 bytes 0FCH, 1 ; index AM bytes 04EH, 16 ; pre ID gap trksec: bytes 0, 8 bytes 0F5H, 3 ; Writes A1 bytes 0FEH, 1 ; ID AM ld a,c srl a ld (hl),a ; track number inc hl bytes 0, 1 ; side number = 00 ex (sp),hl ; pointer to tran table ld a,(hl) ; pick up sector number bit 0,c jr z,mktk2 add a,10 ; add offset for second side mktk2: inc hl ; next table entry ex (sp),hl ; back on stack ld (hl),a ; sector number inc hl bytes 2, 1 ; sector length = 512 bytes 0F7H, 1 ; CRC bytes 04EH, 22 ; post ID gap bytes 0, 12 bytes 0F5H, 3 ; writes A1 bytes 0FBH, 1 ; data AM bytes 0E5H, 512 ; data field bytes 0F7H, 1 ; CRC bytes 04EH, 26 ; post data gap / pre ID gap dec b ; down sector count jp nz,trksec ; another sector to do in image? bytes 04EH, 30 ; pre index gap or a ; clear carry ld de, tbuff ; compute length of track sbc hl,de ld (trklen),hl ex (sp),hl ; tran tbl adr not needed pop hl ret ; exit with hl=len of track tran: ;new translate table defb 0, 8, 3, 6 defb 1, 9, 4, 7 defb 2, 5 ; xlate: push bc push hl ld hl,tran ld c,a ;copy disk logical sector number ld b,0 add hl,bc ld a,(hl) ; translated sector number pop hl pop bc ret indec: ld c,0 ; enter a decimal number into c inlp: push bc ; save deciamal number in c ld c,1 ; get a console character call bdos pop bc cp '0' ret c ; ascii value less than '0' cp '9'+1 ret nc ; ascii value gtr than '9' sub '0' ld b,a ; save decimal digit in b ld a,c add a,a ; times 2 add a,a ; times 4 add a,c ; times 5 add a,a ; times 10 ( a=c*10 ) add a,b ; a=(c*10)+b ld c,a jr inlp ; go get another digit outdec: push bc ; save number in c ld a,c ; decimal print the number in c ld e,'0' ; e hold decimal digit hund: sub 100 ; any hundreds digits? jr c,tens inc e ; bump hundreds digit jr hund tens: add a,100 ; put back 100 push af ; save number ld a,e ; leading zero digit? cp '0' jr z,ten1 ld c,2 call bdos ; write digit ten1: pop af ; recover digit ld e,'0' ; tens digit ten2: sub 10 jr c,ones inc e ; bump tens digit jr ten2 ones: add a,10+'0' push af ; save number, print digit ld c,2 call bdos ; tens digit pop af ld e,a ld c,2 call bdos ; ones digit pop bc ; restore number to c ret ; done seldsk: push bc in a,(bitport) ld c,a and drvmsk ; mask out floppy bits and denmsk ; mask out density bits and mtrmsk or fpyon ; select floppy or dendbl ; select double density or mtron out (bitport),a bit 4,c pop bc ret nz ; motor was on, exit push de ; do delay. push bc ld b,50 call thnsd pop bc ; motor up to speed, pop de ; restore registers ret ; and exit ; delay loop thnsd: ld de,1670 tlp: dec de ld a,d or e jr nz,tlp djnz thnsd ret home: call seldsk ; select drive in a,(bitport) and sidmsk or sid0 ; select side 0, always out (bitport),a ld a,rstcmd ; re-zero disk drive out (cmnd),a jr busy ; wait for command done settrk: push bc ; seek track call seldsk ; make sure that the motor is on call busy ld a,c ; track # srl a out (data),a ld c,sid0 jr nc,setrk2 ld c,sid1 setrk2: in a,(bitport) and sidmsk or c out (bitport),a ld a,seekcmd ; command out (cmnd),a pop bc jr busy busy: call delay ; delay for controller to set busy bit bsy: in a,(status) ; wait for not busy bit 0,a jr nz,bsy ret delay: call dly dly: ex (sp),hl ex (sp),hl ret wrttrk: push bc call seldsk ld hl,(trklen) ; length of track in byte ex de,hl ld c,data ld hl,tbuff ; hl^ to track image, de is length ld a,(66H) ; save byte at nmi push af ld a,0C9H ; store return inst at nmi ld (66H),a ld a,wrtcmd ; track write command out (cmnd),a ; issue command wrtlp: halt ; wait for controller outi ; issue data byte pointed to by hl dec de ; count=count-1 ld a,d ; count zero? or e jp nz,wrtlp ; more bytes pop af ; recover byte at nmi ld (66H),a pop bc ret son1: db cr,lf,lf,'Floppy format program for the Kaypro 10' db cr,lf,lf,'Press a carriage return when ready,' db cr,lf,'Any other key to quit. $' done: defb cr,'DONE ',cr,lf,'$' smsg2: defw crlf smsg4: defb return, 'Formatting track:$' smsg3: defb ' Enter to format, any other key to abort $' secmsg: defb ' Sector ','$' newline:defw crlf defb '$' trklen: defw 0 ; length of track sector: defs 2 ; sector number adrsa: defs 2 ; format data pointer adrsb: defs 2 ; read buffer pointer bytcnt: defs 2 ; byte count dmaadr: defw tbuff ; dma adrs storage area defw 0000h ; for L80 to play with end