title KAYPRO FORMAT Subprogram for COPY. Copyright (C) 1983 by NLS Inc. ;####################################################### ;## ## ;## Double density diskette format program ## ;## ## ;## By G. Ohnysty ## ;## ## ;## Copyright (C) 1982 By Non-Linear Systems, Inc.## ;## ## ;####################################################### ;## Last Update: 10/26,1983 [01] ## ;####################################################### ; see copy.msg for version # extrn vertrk, bdos, trkcnt, tellbad, prnt, diskon public maktrk, frmtrk, format, single, forma cseg .z80 false equ 0 true equ not false doubl equ true ; true if double sided 48tpi wboot equ 0 ; restart system entry point (Warm boot) cpm equ 5 ; cpm bdos entry point 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 # if doubl lsttrk equ 79 ; last track # else lsttrk equ 39 ; last track # endif 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 rdcmd equ 0E4H ; read track command rstcmd equ 000H ; restore command seekcmd equ 010H ; seek command codeb equ 01H ; select unit B: double density codea equ 02H ; select unit A: double density bitport equ 014H ; drive select port maxsec equ 010 ; maximum number of sectors secp equ 012H ; sector port ; print a message print macro x .xlist ld hl,x call prnt .list endm ; get a char from console, up case input macro .xlist ld c,1 call 5 res 5,a .list endm ; write cnt number of val bytes into memory (hl) bytes macro val, cnt .xlist local loop ld de,cnt loop: ld (hl),val inc hl dec de ld a,d or e jr nz,loop .list endm forma: print newline call dska ; select disk A: jr form0 format: print newline call dskb ; select disk B: form0: call home ; home disk drive ld c,frsttrk ; first track # form1: push bc ; save track number while printing it ld a,c ; "copy"'s copy of track number ld (trkcnt),a print smsg4 ; "Track number:" pop bc call outdec ; display track number call settrk ; move to track given by c call maktrk ; make track image, track # in c call frmtrk ; format the track, verify for error(s) inc c ; up track count ld a,c ; max track+1 reached? cp lsttrk+1 jr nz, form1 ; do another track ld a,0FFH ; format OK flag ret ; done, more formatting to do? single: print smsg1 ; ask for track number call indec ; get integer into reg c cp esc ; want out? ret z push bc print smsg2 ; tell track number to verify with user pop bc push bc call outdec ; print number in reg c print smsg3 ; ask if to continue input pop bc ; recover sector number cp return ret nz ; user wants out ld a,c ; "copy"'s copy of track number ld (trkcnt),a call dskb ; select disk call home ; home disk drive call settrk ; move to track given by c call maktrk ; make track image, track # in c print newline ; new line for error message call frmtrk ; format track ret ; go back to menu frmtrk: push bc ; save bc if not doubl ld a,(trkcnt) ; track #=0? or a jr nz,sid0 in a,(bitport) ; try to erase flip side res 2,a ; select side 1, set 5,a ; select single density out (bitport),a ld hl,(trklen) push hl ld hl,1 ld (trklen),hl ; write track length (controller blank fill) call wrttrk ; wipe track side 1 call busy pop hl ld (trklen),hl in a,(bitport) set 2,a ; select side 0, res 5,a ; select double density out (bitport),a sid0: ; endif ld c,3 ; retry count of write track form2: push bc ; save retry count call wrttrk ; write track image ld a,false ; suppress error reporting call vertrk ; verify image or a jr nz,form4 ; good format ld a,false ; sequential try #1 call vertrk ; verify, report error messages or a jr z,form3 ; fault ld a,false ; sequential try #2 call vertrk ; verify, report error messages or a jr z,form3 ; fault ld a,false ; sequential try #3 call vertrk ; verify, report error messages or a jr nz,form4 ; good format, could read 3 times in a row form3: pop bc ; bad format, retry? dec c ; dec count jr nz,form2 ; retry format call tellbad ; report error pop bc ret ; else exit form4: pop bc ; good format pop bc ret maktrk: ld hl,tran ; sector skew table push hl ; store on stack for use ld hl,track ; 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 if doubl ld a,c ; track number DS srl a ld (hl),a else ld (hl),c ; track number SS endif inc hl bytes 0, 1 ; side number = 00 ex (sp),hl ; pointer to tran table ld a,(hl) ; pick up sector number if doubl bit 0,c ; test side jr z,secdsp add a,10 ; if 1 then sec+10 secdsp: endif 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, track ; 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 cpm 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 dskb: in a,(bitport) and 0fch ; floppy disk mask or codeb ; select format disk b: out (bitport),a ret dska: in a,(bitport) and 0fch or codea ; select format disk A: out (bitport),a ret home: if doubl in a,(bitport) ; on home set to side 0 set 2,a out (bitport),a endif call diskon ld a,rstcmd ; re-zero disk drive out (cmnd),a jr busy ; wait for command done settrk: push bc ; seek track call diskon pop bc push bc ld a,c ; track # if doubl srl a ; get side bit ld b,a ; save track number in a,(bitport) ; set side bit res 2,a jr c,sk0 set 2,a sk0: out (bitport),a ld a,b ; get track number endif out (data),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 diskon pop bc push bc ld hl,(trklen) ; length of track in byte ex de,hl ld c,data ld hl,track ; 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 .xlist include FORMAT.MSG .list defw 0 dseg trklen: defs 2 ; 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: defs 2 ; dma adrs storage area track: defs 8000 ; this is a diskette track image to be formed by the program end