Saturday, February 14, 2015

NCB85 14. BIOS a FDC linky

Nejako zabúdam na zverejnenie kódu o ktorom tu píšem. Takže to chcem napraviť a ponúkam zopár linkov:

BIOS aktuálne nakonfigurovaný pre 2x360kB je tu
https://github.com/ncb85/NCB85V2-BIOS

Utility program (FDC.COM) na formátovanie diskiet a iné (viď blog o zlých sektoroch) je tu
https://github.com/ncb85/utilis-and-examples
Nachádzajú sa tam aj príklady ku SmallC.

SmallC executable pre Windows je tu
https://drive.google.com/file/d/0B2TmWnRjWCj2alRqZHM1VEgwNFE/view?usp=sharing

Mal som veľké oči a predstavoval si ako budem používať aj 360kB aj 1.2MB diskety a kde nič tu nič. Plexisklo sa nereže najľahšie a ani času moc nie je. Takže stále mám na stole iba 2x360kB. Dobrovoľníci sú vítaní, bolo by fajn keby niekto aktívne používal aj iné formáty diskiet. V súvislosti s chystanou rozširovacou doskou by bolo možné napísať podporu pre RAM disk a pre IDE disk. To by už bol super luxus, 8-bit CPU by si riadilo frčiaci disk s obrovskou kapacitou cca 40MB. Neuveriteľné ;-)

Thursday, February 12, 2015

NCB85 13. Bad sectors

Nedávno som pracoval s jednou disketou a zrazu niekde pri konci mi CP/M zahlásilo chybu pri čítaní sektora. Kedže to bolo na konci tretej stopy od konca diskety, tak to bolo cca 20kB od plnej kapacity. Tá disketa by sa dala používať ako napr.záloha, s tým že by som vždy nechal posledných 20kB prázdnych. Ale štvalo ma to. Prečo by som mal strážiť, aby som disketu nezapĺňal na viac ako 340kB? A čo keby sa zlý sektor vyskytol niekde na začiatku diskety?

Kedže CP/M nemá možnosť označiť zlé bloky je možné len jedno východisko. Vyrobiť file, ktorý bude mať alokované zlé sektory. Našťastie riešenie je naozaj jednoduché. Skúšal som to riešiť cez kombináciu DDT a BDOS volaní ale nedarilo sa mi. Tak som sa uchýlil k programu, ktorý som napísal ešte pri vývoji drivera pre radič disketoviek. Tento program vie okrem iného čítať a zapisovať individuálne sektory na diskete. Okrem toho samozrejme aj formátovať disketu čo bolo úplne prvé na ceste ... to už odbočujem.

Takže v programe FDC.COM som naformátoval disketu a následne spustil kontrolné čítanie všetkých sektorov. Program po chvíli vypísal:
Reading disk (18 sectors per track, 40 tracks)
current track:37
error reading sector(head):
37 11(1)st1 CRC error, alloc unit 170, position 1 of 0..7

Vadný sektor bol na stope č.37, na druhej strane (hlavička 1) a mal číslo 11. Keďže CP/M nealokuje priestor na disku na úrovni sektorov, ale po blokoch, je treba vediet o ktorý alokačný blok sa jedná. Hneď som upravil aj FDC.COM aby vypočítal, v ktorom alokačnom bloku leží vadný sektor. V tomto prípade to bol blok 170 a v rámci bloku išlo o druhý fyzický sektor. Bloky majú 2kB, čiže 16 logických 128-bytových sektorov, alebo 8 fyzických 256-bytových sektorov. Dané hodnoty platia pre mnou zvolený formát a parametre filesystému.

Keď už vieme číslo alokačného bloku, je potrebné ho vyradiť z voľných blokov. Preto som si vyrobil mini file. Napr. príkazom SAVE 1 BAD.CRC. Kedže disk bol po formáte prázdny, file dostal od CP/M hneď druhý alokačný blok s číslom 01. (Prvý alokačný blok zaberá adresár - pre diskety 360kB som zvolil kapacitu 64 súborov, na čo stačí jeden 2kB alokačný blok. 64 x 32-byte je 2kB.) Takže teraz máme v adresári zapísaný novučičký file BAD.CRC, ktorý ideme zneužiť. Tento file je zapísaný v adresári (v tomto prípade v prvom sektore na diskete) v prvých 32 bytoch.

Následne v FDC.COM načítame obsah prvého sektora (256 bytov) na diskete - začiatok adresára. V tej chvíli tam je len jeden file BAD.CRC. Zmenil som v pamäti obsah prvého byte na 0Fh - to je user 15, obsah prvého písmena prípony súboru na 'C'+80h = C3h - to preto aby súbor bol READ ONLY. A nakoniec som zmenil obsah byte 16 na 0AAh - to je tých 170 - číslo alokačného bloku obsahujúceho vadný sektor. Byte 15 určuje dĺžku súboru - v násobkoch 128-byte. Zvolil som 1. Ostatné 00 na druhom riadku sú potencionálne miesto pre ďalšie alokačné bloky. Max veľkosť pre jeden záznam je teda 16 blokov x 2kb - to je 32kB. Kedže na diskete je len jeden zlý sektor, potrebujeme označiť iba jeden alokčný blok ako použitý. Preto len tá jedna AA. A nakoniec som uložil obsah pamäti naspäť do prvého sektora.

0F4241442020202020C3524300000001 .BAD     .RC....
AA000000000000000000000000000000 ................

a takto to potom vyzerá v CP/M. Kapacita diskety je využiteľná až do konca a všetky súbory sa dajú prečítať bez chyby. Súbor je skrytý, vidí ho len používateľ 15 a ani on ho nemôže zmazať.
B>user 15
B>a:
A>b:stat *.*

RECS BYTES EXT ACC
1 2K 1 R/O A:BAD.CRC
BYTES REMAINING ON A: 0K

A>

A>user 0
A>dir
A: PIP COM : ASM COM : STAT COM : ED COM
A: LOAD COM : XM5V2 COM : XM5 COM : DDT COM
A: MBASIC COM : CPM22 ASM : DPB BAS : MLOAD TXT
A: MLOAD ASM : SINUS BAS : NUDE PIC : MLOAD COM
A: MOVCPM COM : FDC COM
A>stat usr:

ACTIVE USER : 0
ACTIVE FILES: 0 15
A>
A>user 15
A>era bad.crc
Bdos Err On A: File R/O