; ; F D G B : FLOPPY DISK GAME BIOS ; ; knihovna pro prÁci s disky OS L.E.C. CP/M bez pÒÉtomnosti BDOSu ; a BIOSu v RAM. ; ; ÃÉslo verze : 3.51a ; ; historie vzniku ; ; programoval : Svatopluk óvec , 1- 5.8.1991 , Praha. ; doprogramoval : Svatopluk óvec , 17-18.6.1993 , Praha. ; zÁvÅreÃnÁ modifikace : Svatopluk óvec , 1-12.9.1993 , Praha. ; post scriptum [1] Svatopluk óvec , 6-9.12.1993 , Praha. ; ; .z80 aseg org 100h RAM equ 0100h ; adresa,kde se bude modul disk nachÁzet VO512 equ ending ; 200h mÉsto ve hÒe,kter× nenÉ obsazeno{pro directory} .phase RAM ;::::::::::::::::::: minibios :::::::::::::::::::::::::::::::::::::::: jp readfile ; naÃtenÉ souboru podle _A rychle jp openfile ; otevÒenÉ souboru = naÃtenÉ a seÒazenÉ AB's jp rbyte ; naÃte jeden byte jakoby z mgf jp wbyte ; uloÚÉ jeden byte jakoby na mgf jp rsektor ; naÃte jeden 512 sektor pÒÉmo na danou adresu. jp wsektor ; zapÉÓe jeden 512b sektor jp closefile ; zavÒenÉ souboru = vypnutÉ motoru jp init ; nastavenÉ sama sebe pro aktuÁlnÉ disk,ze kter×ho ; jsem spouÓtÅn db "END:" dw ending ; readfile: ; naÃte rychle soubor,sektor po sektoru... push hl push de xor a call openfile pop bc pop hl ; bc / 512 + zbytek ld a,0FEh and b ; bc / 512 srl a ; >> 1 push af ld a,1 and b ld b,a pop af push bc or a jr z,wodron woody: push af push hl call rsektor pop hl ld bc,512 add hl,bc pop af dec a jr nz,woody wodron: pop bc ld a,b or c jr z,rfileuon bereg: ; dodÅlÁnÉ zbytku poslednÉho sektoru push hl push bc call rbyte pop bc pop hl ld (hl),a inc hl dec bc ld a,b or c jr nz,bereg rfileuon: call closefile scf ret ; ; !!!! init se volÁ jeÓtÅ za Úivota biosu !!!! db " DISK LOADER V 3.51a , (W) 09-12-93 SVATOPLUK SVEC" ;------------------------------------------------------------------- ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; :::::: diskove parametry ::::::::::::::::::::::::::::::::::::::: is40t: db 0 ; je 40 track floppy v device ? popbw: dw 0 ; obsazenost bufferu pro write isrd: db 0 ; je rd pÒÉtomen ? gord: db 0 ; pracuji teÄ na rd ? motison: db 0 ; bÅÚÉ uÚ motor u mechaniky ? PAB: db 8 ; poÃet AB v jedn× poloÚce numdriv: db 0 ; ÃÉslo aktuÁlnÉho drivu pro roztoÃenÉ motoru adrv: db 0 ; aktuÁlnÉ parametry mechaniky xro "gofd" drva: db 0 ; aktuÁlnÉ mechanika : { a,b,c,d } jejÉ parametry favmot: db 0 ; kterÁ to je ta favoritnÉ maxdriv: db 0 ; max. drive favdriv: db 0 ; favoritnÉ drv,mot,bere se jako prvnÉ,poprv× = A: drv0: db 0 ; mechanika a: drv1: db 0 ; mechanika b: drv2: db 0 ; mechanika c: drv3: db 0 ; mechanika d: jejich parametry mottm: dw 300 ; rozbeh motoru 500 ms settl: db 20 ; ustaleni hlavy 20 ms steptm: db 12 ; doba kroku 12 ms timoff: db 0 ; casovani motoru FD : pro obÅ mechaniky actstrn: ; pro ramdisk : aktuÁlnÉ strÁnka acttrk: db 0 ; aktualni stopa actsec: db 0 ; aktualni sektor actDMA: dw 0,0 ; aktualni DMA adresa actpoz: db 0,0 ; aktualni pozice v miste urceni - tab64 actoff: db 0,0 ; aktualni pozice v AB_adresari tab83: db 4,0,4,16,4,32,5,12,5,28,6,8,6,24,7,4,7,20 ; tabulka pro prepocet trak: db 0 ; cislo pro pocitani trk povtab64: dw 0FFFEh ; aktualni pozice v tabulce stopa-sektor,init = 0 popb: dw 0 ; aktualni pocet prectenych bytu : <= 512 pops: db 3,0 ; pocet zatim prectenych sektoru z 2 kB AB actss: db 0,0 ; aktualni stopa-sektor tab64: dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; tabulka pro aktualni AB_loky OVRN: db "SIMCITY" OVRN1: db "0BBS" ; maska pro hledani overlayu v adresari LOG: db "SIMCITY" LOG1: db " SAV" ;::::::::::::::::::::::::::::: wsektor: ;:: zapÉÓe 512b sektor ld a,0 ld bc,6cfh out (c),a ld (actDMA),hl ld hl,wrisec ld (METALLICA+1),hl ld (METALLI02+1),hl ld hl,(actDMA) call rsektor ; najede,ale pak je to writesektor ld hl,readsec ld (METALLICA+1),hl ld (METALLI02+1),hl ret c ; o.k. ld bc,6cfh ld a,15 out (c),a ret wrisec: ld hl,(acttrk) ld a,l or h jr nz,dalezkouska ld bc,6cfh wrisec001: ld a,0 out (c),a inc a ld (wrisec001+1),a ld a,9 out (0d0h),a nop in a,(0D1h) inc a jr z,wrisec001 dalezkouska: call wds99 ret ; nc = chyba wds99: ld a,(gord) ; jdu z rd ? or a jr z,wdse30 ; ne, teÄ z fd ld a,(isrd) or a jp nz,rdwrite ; ano,jdu ret ; ret s nc = chyba... device not ready.... wdse30: ld hl,VO512 call wrsec ret ; rdread: call nezread rdout: scf ; Cy = o.k. ret ; rdwrite: call nezwrite jr rdout ; zalsel: ; select u zÁlohovan×ho ramdisku ld bc,(actstrn) ld a,c out (0E9h),a call offset ld b,h ld a,l out (0EBh),a ld hl,(actDMA) ld b,0 ret zalread: ; rutina pro readsec ze zÁlohovan×ho ramdisku call zalsel ld c,0EAh ; byl chybus ! inir inir ; 2*256 = 512 ret zalwrite: ; a pro zÁpis call zalsel ld c,0EAh ; byl chybus ! otir otir ret ; nezread: ld a,2 ld (nezmod+1),a jr nezdal nezwrite: ld a,0 ld (nezmod+1),a ; to sam× pro nezÁlohovanÙ ramdisk nezdal: exx push bc exx ld bc,(actstrn) MODI09: ld a,0E8h MODI46: sla c sla c add a,c cp 0F0h jr c,nezr01 sub 8 nezr01: ld c,a ; z t×to strÁnky se bude brÁt call offset ; offset do hl ld de,(actDMA) exx ;1 ld bc,512 nezr03: exx ;0 ld b,l in b,(c) ld b,h ; select nezmod: jr nezre ; 0=write,2=read jr nezwi nezre: in a,(c) ld (de),a jr nezpos nezwi: ld a,(de) out (c),a nezpos: inc hl inc de exx ;1 dec bc ld a,c or b jr nz,nezr03 pop bc exx ;0 ret ; offset: ;::::::::::: spoÃte offset v ramdisku :::::::: ld hl,-512 ld de,512 inc b ; min 0->1 ,max 127->128 nezr02: add hl,de djnz nezr02 ; offset v rÁmci strÁnky ret ; wrsec: ;::: zapÉÓe jeden 512b sektor nebo ne,ale vrÁtÉ se ::::: ; ld hl,(actss) ld a,l or h ret z ; 0,0 nebudu zapisovat.. ld a,(gord) or a jp nz,rdwrite call select ld b,5 wrse01: push bc call seek jr nc,badseek call brkct ; break radice in a,(0D8H) ; status bit 6,a ; je tam wr-protect ? jr z,badwr ; je ! call d1ms ; cekat 1 ms call side ; vypoÃti stranu xor 5DH ; pro 97 zde 57h out (0D8H),a ; povel WRITE SECTOR call busy ; poÃkej,aÚ nebude busy call outsec ; a teÄ poÓli data ld a,3 ; male cekani call waita ld hl,(actDMA) ; test, je-li 512 bytu or a ex de,hl sbc hl,de ; vrÓek - spodek ld de,513 or a sbc hl,de ; = 512+1 => pÒenos byl 512 bytÊ jr nz,badseek ; ne ! in a,(0D8H) ; status inc a ; musi byt 0 !!! scf ; (pro 97 ^ and D9h ) pop bc ret z ; dobrÙ zÁpis ! push bc badseek: call errcl badwr: pop bc djnz wrse01 or a ret outsec: ; :: zapise na disk jeden 512 B sektor ::: ld c,0DBH ; registr dat ld de,(actDMA) ; (jako buffer) ld hl,outs01 outs01: ld a,(de) ; 1 byte z bufferu inc de cpl ; upravy pro tvar,ve ld b,a ; kterem to chce radic outs02: in a,(0D8H) ; uz je sektor plny ? rra ret c ; ano : navrat rra jr c,outs02 ; neni pripraven out (c),b ; zapis(1 bytu na disk jp (hl) ; smycka ; ; ;:::::::: init: ; inicializace == automodify == pÒizpÊsobenÉ ; platÉ pro : ramdisk , a: , b: , ld hl,0EA36h ; tabulka diskÊ ld de,maxdriv ldi ldi ; a favdriv = A: dec hl ld bc,4 ; fav = a: poprv× ldir ; pÒesun fd parametrÊ ld hl,0EA3Bh ld de,mottm ld bc,4 ldir ; pÒesun ÃasÊ fl.disku init01: ; upravÉ ovlÁdÁnÉ na ramdisk ld a,(0EA3Fh) ; poÃet size ramdisku or a ret z ; nenÉ ramdisk... ld (isrd),a ; je ... ld a,(0F31Fh) ; zde se rozeznÁ zal od nez cp 43h ; zal ? jr nz,init10 ; ano,je to zÁlohovanÙ ramdisk.. ld a,(0EA3Fh) ; velikost.. cp 8 ; 128 kB : u toho by to nechodilo.. jr z,init87 ; 0 : E8 , 1 : + EB = EC.. xor a ld hl,0 ld (MODI46),hl ; ne sla... ld (MODI46+2),hl init87: ld a,(0F9A3h) ld (MODI09+1),a ; E8 v. EC ld hl,nezread ; ne,je to nezÁlohovanÙ rd pod L.E.C. ld de,nezwrite jr init04 init10: ; pÒesmÅruj ÃtecÉ rutiny na ramdisk zÁlohovanÙ ld hl,zalread ; je to zÁlohovanÙ pod L.E.C. ld de,zalwrite init04: ld (rdread+1),hl ; pÒesmÅruj call writesec ld (rdwrite+1),de ret ; ; ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::; rsektor: ;:: naÃte pÒÉmo jeden 512 sektor na DMA ^hl :::; ;::: jde u programÊ,kter× pÒi naÃÉtÁnÉ nic nedÅlajÉ :::::::::::; ld (actDMA),hl ld a,(gord) ; jdu teÄ po ramdisku ? or a jr z,rsek02 ; ne,jdu na floppy ld a,18h ; ramdisk.. ld (MODI14),a ; mÁ sektory na stopÅ zarovnan×.. ld a,3Eh ld (MODI12),a jr rsek01 rsek02: ld a,20h ; jr nz,... ld (MODI14),a ld a,10h ld (MODI12),a rsek01: ld a,(pops) inc a ; prvni jsem precetl pri najizdeni na AB cp 4 ; uz jsem vycerpal 4 512-tky v AB ? jr z,rsekt5 ; ano ld (pops),a ; dalsi 512 uz jsem jako precetl ld de,(acttrk) ; tady jsem byl predtim ld b,4 ; 4 128-cky v 1 512-ctce rsekt8: inc d ; dalsi sektor ld a,d cp 36 ; jsem na 36.sektoru,tzn za rohem ? MODI14: jr nz,rsekt7 ; jeste ne inc e ; dalsi stopa ld d,0 ; setup na 0 pro rbyte7 rsekt7: MODI12: djnz rsekt8 ; 1 . 512 = 4 . 128 ld (acttrk),de ; min:sector o 4,max:stopa o 1,sektor o 3 ; zde wbyte : wsect !!! METALLICA: call readsec ; nacti dalsi 512 B sektor ret ; jako by se nic nestalo rsekt5: ; ::::: najizdim na dalsi AB na disku ::::::::::::::::::::::::::: ld a,0 ld (pops),a ; od nuly sektoru ld hl,(povtab64) ; uz musim nacist-najet na dalsi zacatek AB inc hl inc hl ; dalsi sektor ld (povtab64),hl ; setup offsetu v tab64 ld de,tab64 ; ukazatel na zacatek tabulky add hl,de ; hl ukazuje na trk,sec_actual ld c,(hl) ; stopa inc hl ld b,(hl) ; sektor Š ld (acttrk),bc ; ulozit ld (actss),bc ; a do mezi.. METALLI02: call readsec ; precist ten sektor ret ; jako by se nic nestalo... ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: rbyte: ; ::::: simuluje funkci "readbyte" :::::::::::::::::::::::::::::: ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: rbyte99: ld hl,(popb) ; jeste zbyva...0 ld a,h cp 2 ; kolik ? jr z,rbyte1 ; uz nic,musim nacist dalsi sektor inc hl ; zatim aspon jeden ld (popb),hl ; pristi bude.. dec hl ; ted je ale.. ld de,VO512 ; start bufferu add hl,de ld a,(hl) ; ted jsem prave precetl jeden byte ret rbyte1: ; :::::: nactu dalsi sektor ::::: ld hl,0 ld (popb),hl ; setup poctu vzatÙch z bufferu ld hl,VO512 call rsektor ; naÃti sektoz do vyrbuferu jr rbyte99 ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: wbyte: ; ::::: simuluje funkci "writebyte" ::::::::::::::::::::::::::: ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: push af wbyte99: ld hl,(popbw) ; jeste zbyva...0 ld a,h cp 2 ; kolik ? jr z,wbyte1 ; uz nic,musim uloÚit dalsi sektor inc hl ; zatim aspon jeden ld (popbw),hl ; pristi bude.. dec hl ; ted je ale.. ld de,VO512 ; start bufferu add hl,de pop af ld (hl),a ; ted jsem prave precetl jeden byte ret wbyte1: ; :::::: poÓlu dalÓÉ sektor ::::: ld hl,0 ld (popbw),hl ; setup poctu vzatÙch z bufferu ld hl,VO512 call wsektor ; naÃti sektor do vyrbuferu jr wbyte99 ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: openfile: ; :::: prebere funkci "readheader" , do tabulky AB_tab ::::::::| ;:::::prepocte a ulozi cisla AB daneho overlayoveho souboru pro readbyte :| ;:::::::::::::::: v _A pÒijde ÃÉslo overlaye { 0..X } :::::::::::::::::::| add a,"0" ld hl,OVRN1 ld (hl),a openfule: di ld hl,tab64 ld de,tab64+1 ld bc,63 ld (hl),0 ldir ; clear tab ld hl,512 ld (popb),hl ; nastav read - je plnÙ,potÒebuje naÃÉst ld hl,0 ld (popbw),hl ; a write - je prÁzdnÙ a potÒebuje naÃÉst ld hl,VO512 ; adresa voln× pamÅti 512 Bytu ld (actDMA),hl ; set DMA opfi78: ; bad smyÃka... ld a,(isrd) or a jr z,opfi80 ld (gord),a ld a,1 ld (is40t),a ; teÄ je to 40track call opfi99 ret c ; byl zjiÓtÅn na rd... o.k. opfi80: ; nenÉ rd nebo na rd nebyl zjiÓtÅn.. zkus to na Ãtyrech fd ! xor a ld (gord),a ld a,(favmot) ld (numdriv),a ld a,(favdriv) ld (adrv),a bit 0,a ; 80t ? ld hl,is40t jr nz,opfif65 ; ano,je to 80t ld a,1 ; floppy je 40 t jr opfif67 opfif65: xor a ; floppy je 80t opfif67: ld (hl),a ld a,e bit 2,a ; je to - single step ? jr z,opfif62 ; ano,single step ld hl,doubi ; ne - double step.. ld de,doubo jr opfif63 opfif62: ld hl,stepi ld de,stepo opfif63: ld (mistep+1),hl ; nastav step in ld (mostep+1),de ; a step out call opfi99 ret c ; nalezeno hned na favoritnÉm ! xor a dec a ; first : -1 -> 0 ld (numdriv),a ; zaÃneme hledat tedy dÁle opfi61: ld a,(numdriv) cp 3 ; uÚ jsem minule zkusil d: ? jr z,opfi76 ; ano, oznam not found... inc a ld (numdriv),a ld hl,numdriv ld a,(maxdriv) cp (hl) ; numdriv > maxdriv ?? jr c,opfi61 ; tahle nenÉ fyzicky pÒÉtomna.. ld a,(numdriv) ld hl,drv0 ld e,a ld d,0 add hl,de ld a,(hl) ld e,a ld (adrv),a ; co kdyby to vyÓlo,rutiny sem ÓahajÉ bit 0,a ; 80t ? ld hl,is40t jr nz,opfi65 ; ano,je to 80t ld a,1 ; floppy je 40 t jr opfi67 opfi65: xor a ; floppy je 80t opfi67: ld (hl),a ld a,e bit 2,a ; je to - single step ? jr z,opfi62 ; ano,single step ld hl,doubi ; ne - double step.. ld de,doubo jr opfi63 opfi62: ld hl,stepi ld de,stepo opfi63: ld (mistep+1),hl ; nastav step in ld (mostep+1),de ; a step out call opfi99 ; teÄ to zkus jeÓtÅ z floppy... jr nc,kokrhal01 ld a,(numdriv) ld (favmot),a ld e,a ld d,0 ld hl,drv0 add hl,de ld a,(hl) ld (favdriv),a ; nalezenÙ bude pÒÉÓtÍ favoritnÉ scf ret ; o.k.,teÄ to vyÓlo na tomhle floppy kokrhal01: xor a ld (motison),a out (0DCh),a jr opfi61 opfi76: ld a,0 ld hl,01000 opfi77: ld bc,6cfh out (c),a inc a jr nz,opfi77 dec hl jr nz,opfi77 xor a out (c),a jp opfi78 ; zkus to jeÓtÅ jednou opfi99: ld hl,4 ld a,(gord) ; zkouÓÉm najÉt file na rd or a jr z,opfi01 ld l,0 ; ano,tam start dir na 0,0 opfi01: ld (acttrk),hl ; set track & sector ld hl,0 ld (actpoz),hl ld (actoff),hl ; setup pozic pro novÙ file ld a,(is40t) ; je to na 40t mechanice ? or a jr z,opfi02 ; ne,na 80t ld a,16 ld (PAB),a ; poÃet AB v jedn× poloÚce directory ld a,0 ld (MODI03),a ld a,57h ld (MODI02),a ld a,0FEh ld (MODI01+1),a ld a,1 ld (MODI10+1),a ld a,(gord) or a jr z,opfi48 ; nejedu na rd ! ld a,2 ; set na rd !!! opfi48: ld (MODI07+1),a jr opfi03 opfi02: ld a,8 ld (PAB),a ; poÃet AB v jedn× poloÚce directory ld a,23h ; inc hl ld (MODI03),a ld a,56h ld (MODI02),a ; ld d,(hl) ld a,0FFh ld (MODI01+1),a ; celÁ maska... ld a,4 ld (MODI10+1),a ; offset 512b ld a,0 ld (MODI07+1),a opfi03: ld bc,8 ; 2 AB = 4 kB = 8 * 0.5 kB = 8 * 512 B ; openw: ; ::::: nacte cely adresar a pro dany soubor.ovr prepocte AB -> sec push bc ; |1| : dir = 4.512 call readsec ; nacti jeden ze ctyr sektoru adresare pop bc ret nc ; {nc}= chyba uÚ pÒi ÃtenÉ push bc ld hl,(acttrk) MODI10: ld b,4 ; preskok 512 B mezeru = 4*128 ld c,0 add hl,bc ld (acttrk),hl ; 1,2,3 sektor 128B uz jsem nacetl... ld bc,16 ; pocet souboru v jednom sektoru adresare ld hl,(actDMA) ; setup hl na zacatek sektoru open1: push bc ; |2| vnitrni smycka - jeden sektor adres. push hl ; |3| hl ukazuje na VO512 + 32*b ve smycce ld a,(hl) cp 0E5h ; je polozka prazdna ? jp z,open2 ; ano,je ld bc,11 ; pocet porovnani ld de,OVRN ; to,co se bude porovnavat inc hl ; preskoc usera open3: ld a,(de) inc de ; inc hl provede cpi sam cpi ; zero = stejnota jp nz,open2 ; neni to ta polozka - rovnou ven ld a,c or b ; jsem na konci ? jr nz,open3 ; jeste ne ld a,1 ld (mamho),a ; Òekni, Úe jsem ho naÓel... ; :::::::::: ano,vse se rovna - o.k. :::::::::::::::::::::::::::::::::::::: ; :::: prepocita AB na stopa-sektor a ulozi do tab64 podle f_ext :::::::: ld a,(hl) ; hl / uz predtim / ukazuje na f_ext [0,1,2,3-max] MODI01: and 11111111b ;pro rd a 360 ,pro 728 = ffh rlc a ; *2 rlc a ; *4 rlc a ; *8 rlc a ; *16 ld hl,tab64 ld d,0 ld e,a add hl,de ; hl = prvnÉ poloÚka pro tento ext ld (actpoz),hl ; uloz to ,kam se bude ukladat stopa,sec pop hl ; |2| push hl ; |3| ld de,16 add hl,de ; hl ukazuje na cisla AB ld (actoff),hl ; setup toho,odkud budeme brat ld a,(PAB) ; pocet AB v jedne polozce - pro 360kB : 16 ld b,a open5: ; ::::: prima smycka pro prepocet AB -> trk,sec ::::::::::::::::: push bc ; |4| - treti vnoreni call spoctits ; spocte z cisla AB (hl) sektor a stopu urceni ; a ulozi - rd presmeruje na sebe pop bc ; |3| djnz open5 ; dokud je nejaky AB open2: ; ::::: jede na dalsi polozku v adresari :::::::::::::::::::: ld de,32 ; adresarovy offset pop hl ; |2| add hl,de ; dalsi polozka pop bc ; |1| dec bc ld a,b or c jp nz,open1 ; mensi smycka - 16 polozek pop bc ; |0| dec bc ld a,b or c jp nz,openw ; vetsi smycka - 8 sektoru ld hl,0FFFEh ld (povtab64),hl ld a,3 ; setup popsu - on se totiz zvetsuje a pak... ld (pops),a ld a,(mamho) rrca ; non cy = o.k. ld a,0 ld (mamho),a ; a zpÅt vynulovat ret ; vse ulozeno... mamho: db 0 ; naÓel jsem ten soubor... ; spoctits: ; ::: spocte a ulozi z AB -> trk,sec :: -> actoff | -> actpoz ::: xor a ld (trak),a ld hl,(actoff) ; v hl : 01 , 1B / pr. / ld e,(hl) ; nizsi inc hl MODI02: ld d,(hl) ; vyssi nebo 0 ex de,hl ; hl=000A MODI07: jr spoc34 ; rd : 2 , fd : 0 spoc34: jr spoc2 ; pro AMF sprd01: ; z AA -> trk,sec , ale pro ramdisk ; do bc: stopa,"sektor" - ale rovnou 512b push hl ld b,5 sprd02: srl l rr h djnz sprd02 ; AB / 32 = stopa ld b,l pop hl ld a,l and 00011111b ; MOD 32 sla a sla a ; * 4 ld c,a jr spoc54 spoc2: ; ::::: jede dolu , vnoreni dava do (trak) :::::::::::::::::::::: ld a,h or a ; uz na nizsi ? jr nz,spoc6 ; jeste ne ld a,l ; a uz je mozna mensi,nez 9 ??? cp 9 ; uz jsem v nejnizsi oktade ??? jr c,spoc1 ; ano spoc6: ld bc,9 ; jeste ne sbc hl,bc ; o dalsich 9 dolu ld a,(trak) inc a ld (trak),a ; dalsi trak jr spoc2 ; === loop === : kvuli poctu 4-stop(v (trak) spoc1: ; ::::: prepocet :::::::: , v a je offset v tabulce ::::::::::::: ld hl,tab83 ; start tabulky pro prepocty Ab -> trk,sec ld b,0 rlc a ; a * 2,v a je real offset / bylo l / ld c,a add hl,bc ; v (hl) je first trak,abs_sector(/ 4 / ld a,(trak) ; toto se musi * 4 rlc a ; *2 rlc a ; *4 - v a je offset add a,(hl) ; v a je ted absolutni stopa ld b,a ; meziulozeni inc hl ld c,(hl) ; v c je absolutni sektor spoc54: ld hl,(actpoz) ; sem to davame --- ulozeni ld (hl),b inc hl ld (hl),c inc hl ld (actpoz),hl ; setup pro dalsi ld hl,(actoff) inc hl MODI03: inc hl ; pro 360 kb : nop ld (actoff),hl ; dalsi polozka ret ;:::::::::::::::::::::::::::::::::::::::::::::::::::: closefile: ; :::: vypne motor fyzicky, logicky :::::: ;:::::::::::::::::::::::::::::::::::::::::::::::::::: push af xor a out (0DCh),a ld (motison),a pop af ret ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: readsec: ; ::::: Precte fyzicky 512 B sektor , Carry = uspech . ::::::::: ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: call rds99 ret ; nc = chyba rds99: ld a,(gord) ; jdu z rd ? or a jr z,rdse30 ; ne, teÄ z fd ld a,(isrd) or a jp nz,rdread ; ano,jdu ret ; ret s nc = chyba... device not ready.... rdse30: di call select ; zde jen motor on,najede na mÉsto. ld b,10 ; 10 opakovani pri chybe rdsec1: ; smycka pri neuspechu push bc call seek ; pokusi se najet hlavou nad sektor jr nc,rdsec2 ; nepovedlo se call side ; doda bit se stranou xor 7DH ; naxoruji ,pro 97 zde 7FH out (0D8h),a ; vybere stranu call busy ; ceka na busy call insec ; ** bere data do RAM ** jr nc,rdsec2 ; zase se nedari.. call nobusy ; o.k. : ceka na not busy in a,(0D8H) ; bere status cpl and 0BFH ; pro 97 zde 99h or a ; operace probehla o.k. /?/ jr z,wrrder ; bude cary rdsec2: call errcl ; zase nic,popojede a seek znova pop bc djnz rdsec1 ; opakuje 10x push bc ; chce Abort scf ; aby bylo nc = chyba wrrder: ; navrat z cteni a zapisu sektoru ccf pop bc outwrd: ; to same,ale bez popiku ret ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: insec: ;:: precte z posuvneho registru jeden fyzicky 512 B sektor ::::: ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ld bc,0002H ; C = 2 /krat :56/ ld d,b ; ld e,b ; mam FFFF pokusu ld hl,(actDMA) ; aktualni DMA insec1: dec de ld a,d or e ret z ; navrat s non Cy = error insec2: in a,(0D8H) ; status and 02H ; nasel ? jr nz,insec1 ; ne in a,(0DBH) ; ano : data cpl ; ld (hl),a ; do RAM inc hl ; dalsi.. djnz insec2 ; prectu 512 bytu,coz je jeden dec c ; fyzicky sformatovany sektor: jr nz,insec2 ; , dodrzuje se format IBM. scf ; set o.k. ret ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: side: ; :::::: vypocita stranu FD mechaniky ::::::::: di sidex: or a ; Cy = 0 ld hl,adrv ; bezici disk bit 1,(hl) ; neni jednostranna ? ret z ; ano,nemusim nic pocitat ld a,(acttrk) ; cislo bezici stopy rla ; ted vypocitam rla ; stranu : stopa x 8 rla ; and 08H ; a maskuji ; pro WD2797 jen _A x 2 : rla , and 02H scf ret ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * select: ; :::::: provede select stopy,zapne motor ::::::::::::::: * ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * ld a,(motison) or a ret nz ; ano,motor uÚ bÅÚÉ.. inc a ld (motison),a ; ne,ale bude bÅÚet ld a,(numdriv) ; ÃÉslo drivu or 84H ; maska "motor on" di ; ted ne... out (0DCH),a ; motor-on & select ld hl,(mottm) ; cas rozbehu motoru selek1: djnz selek1 ; mensi cekacka dec hl ld a,h or l jr nz,selek1 ; vetsi cekacka - pockam,nez se motor rozbehne... ; uz muzes ret ; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: seek: ; :::::: dojede na sektor podle (actsec) ::::::::::::::::::: ; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ld a,(actsec) ; bezici logicky sektor - 128 bytovy srl a ; 128 bytovy srl a ; /4 - 512 bytovy je preci 4x vetsi inc a cpl out (0DAH),a ; nastad sektor FD_ call sidex ; side bez ovladani int ld a,(acttrk) ; ted side jen pro flag jr c,seek1 ; je oboustranna add a,a ; je jednostranna seek1: out (0DDH),a ; nastav stranu FD_ srl a ; ld h,a ; in a,(0D9H) ; cpl ; sub h ; vypocet zbyvajiciho poctu kroku ccf ; ret z ; je na te stope => nejedem ld l,a ; zbyva kroku jr nc,seek4 ; je vetsi,jedem dovnitr seek2: mostep: call stepo ; je mensi,jedem ven : meni se pri ; double step na CD FD B2 dec l ; L krat jr nz,seek2 jr seek5 ; ted uz jsem tam take seek4: mistep: call stepi ; jede dovnitr inc l jr nz,seek4 seek5: in a,(0D9H) ; stopa xor h ; je opravdu stejna ? add a,1 ; do CY kdyz OK setwt: ; :: necha ustalit hlavy FD mechaniky ::: ld a,(settl) ; settling time waita: ; :::: cekacka podle a :::::: push bc ld b,00H waitaw: djnz waitaw dec a jr nz,waitaw pop bc ret ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::: errcl: ;::: osetri chyby tak,ze se pokusi popojizdet :::: ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::: ld a,0FFH ; tady je to jinak ld (timoff),a ; ld h,74H ; errcl1: in a,(0D8H) ; cti status rra ; jr c,errcl2 ; dec hl ; ld a,h ; or l ; jr nz,errcl1 ; jr brkct ; errcl2: in a,(0D9H) ; cti reg. stopy rra ; o.k. ? call c,stepi ; ne,dovnitr call nc,stepo ; ne,ven call setwt ; cekej na ustaleni di ld a,3FH ; ridici slovo out (0D8H),a ; go! call busy ; cekej na busy call rdadr ; precti znacku jr nc,recal ; chyba,jdi na zacatek call nobusy ; cekej na nobusy in a,(0D8H) ; cti status cpl ; and 0BFH ; je to dobre ? jr nz,recal ; ne ,jdi az ná zacatek ld a,c ; beru data z rdadr zpet out (0D9H),a ; a davam zpatky ret ;::::::::::::::::::::::::::::::::::::::::::::::::::: rdadr: ; :: cte znacku sektoru aby zjistil,kde je :: ;::::::::::::::::::::::::::::::::::::::::::::::::::: ld l,2 ; priznak znacky ld d,15 ; 15 * 256 pok}su rdadr1: dec de ; ld a,d ; or e ; ret z ; uz padej s chybou in a,(0D8H) ; cti status and l ; je to ono ? jr nz,rdadr1 ; nee ! in a,(0DBH) ; ano,ctu registr dat ld c,a ; do C ld b,5 ;(5 polozek ? rdadr2: in a,(0D8H) ; ctu status and l ; je to ono ? jr nz,rdadr2 ; dokud ne,tak skakej in a,(0DBH) ; uz jo djnz rdadr2 ; takze dalsi polozka scf ; Cy = 1 = o.k. ret ; padej s C naplnenym recal: ; ::::: dojede na nultou stopu a vypadne :: ld l,80 ; 80 stop.. recall: ; ......# total ! #...... call stepo ; ven ! /vlastne dovnitr !/ dec l ; jr z,setwt ; uÚ je konec - vypadni in a,(0D8H) ; cti status bit 2,a ; 2.bit == 1 ? jr nz,recall ; jeste ne/jsem tam/ ld a,0FFH ; uz tam jsem : cpl ( 0 ) = FF out (0D9H),a ; nulta stopa nastavena jr setwt ; ted uz opravdu koncime.. stepi: ; ::: udela jeden krok dovnitr mechanikou FD: ld a,0A7H ; ridici slovo STEP_IN jr stepw ; preskok stepo: ; ::: udela jeden krok ven mechanikou FD :::: ld a,87H ; ridici slovo STEP_OUT stepw: out (0D8H),a ; go ! ld a,(steptm) ; doba kroku call waita ; presne tolik cekej brkct: ;: zastavi radicem prave vykonavanou praci a pocka na nobusy ::: ld a,2FH ; ridici slovo out (0D8H),a ; do ridiciho reg. nobusy: ; :::: vrati se pri "no busy" :::::: call d1ms ; cekej nobusw: in a,(0D8H) ; cti status rra ; je 1.bit "1" ? jr c,d1ms ; ano,sam se sejmi djnz nobusw ; zatim ne jr brkct ; zkus to jeste Šbusy: ; :::: vrati se pri "busy" ::::::::: call d1ms ; pockej chvilku busyw: in a,(0D8H); cti prikazovy registr and 81H ; je tento stav : xor 80H ; "1......0" ? ret z ; ano,not busy djnz busyw ; ne,porad je busy ret d1ms: ; ::::: pocka jednu milisekundu ::::::::::: ld b,18H ; d1msw: djnz d1msw ; ret dint: ; :::: zakaze preruseni :::: di ret eint: ;:: odblokuje INT :::::::::::::: ret ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: doubi: ;:::::: dÅlÁ dvojitÙ krok dovnitÒ :::::::: - FD86 - :::::::::: call stepi ; jedem dovnitÒ jako obvykle ld a,(adrv) ; v a priznak drivu bit 2,a ; nechce nahodou dvojkrok na SD ? ret z ; ano,chce,to nechapu... in a,(0D9H); ne,chce to na DD,o.k. push af ; uschovam stopu call stepi ; jedem dovnitÒ jeste jednou.. pop af ; beru stopu zpet out (0D9H),a ; zase ji ulozim ret doubo: ;:::::: dÅlÁ dvojitÙ krok ven :::::::::::: - FDB2 - :::::::::: call stepo ; jedem ven jako obvykle ld a,(adrv) ; v a priznak drivu bit 2,a ; nechce nahodou dvojkrok na SD ? ret z ; ano,chce,to nechapu... in a,(0D9H); ne,chce to na DD,o.k. push af ; uschovam stopu call stepo ; jedem ven jeste jednou.. pop af ; beru stopu zpet out (0D9H),a ; zase ji ulozim ret ; ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ending: db "END FDGBIOS " .dephase end