Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
cpm:write_a_bios:teil_2 [2018/10/05 06:49] – [Variante 2] volkerp | cpm:write_a_bios:teil_2 [2025/04/19 15:36] (aktuell) – volkerp | ||
---|---|---|---|
Zeile 3: | Zeile 3: | ||
weiter geht es mit dem **DPB** | weiter geht es mit dem **DPB** | ||
- | das folgende Beispiel stammt aus einer [[cpm: | + | Das BIOS erhält die Information, |
+ | * SETDSK (Laufwerk, 0..15), | ||
+ | * SETTRK (Track, Spur 0...x, berechnet aus Blocknummer + Systempuren), | ||
+ | * SECTRAN (Transformation der aktuellen log. Record-Nummer 0..BSM, Sektorversatz, | ||
+ | * und SETSEC (Sector, transformierte Record-Nummer). | ||
+ | |||
+ | Das BDOS ruft diese genannten BIOS-Funktionen immer vor Aufruf von READ oder WRITE in dieser Reihenfolge auf. Ein BIOS speichert daher die Werte für Laufwerk, Spur, Sektor zwischen und greift bei Lese- und Schreiboperationen darauf zu. Pro Format/ | ||
+ | |||
+ | Das folgende Beispiel stammt aus einer [[cpm: | ||
Bei CP/A erfolgt die Sektorzählung ab 1, deshalb steht in sectran ein inc hl. | Bei CP/A erfolgt die Sektorzählung ab 1, deshalb steht in sectran ein inc hl. | ||
- | Die Zählung ab 1 muss bei den direkten Zugriffen beachtet werden! | + | Die Zählung ab 1 muss bei den direkten Zugriffen |
< | < | ||
Zeile 29: | Zeile 37: | ||
- Ausgabe A17..A16 auf Port " | - Ausgabe A17..A16 auf Port " | ||
- Ausgabe A15..A8 auf Port " | - Ausgabe A15..A8 auf Port " | ||
- | - Einblenden in den Hauptspeicher (auf Adresse " | + | - Einblenden |
- Zugriff auf " | - Zugriff auf " | ||
- | Für die Nutzung im CP/M soll außerdem eine Kopie von CCP+BDOS (5 KByte) auf der RAM-Disk gehalten werden, sinnvollerweise in Systemspuren. | + | Für die Nutzung im CP/M soll außerdem eine Kopie von CCP+BDOS (5 KByte) auf der |
+ | RAM-Disk gehalten werden, sinnvollerweise in Systemspuren. | ||
- | Eine RAM-Floppy hat keine physischen Spuren, deshalb kann man die Aufteilung in virtuelle Spuren und Sektoren nach eigenen Ideen vornehmen. | + | Eine RAM-Floppy hat keine physischen Spuren, deshalb kann man die Aufteilung in |
+ | virtuelle Spuren und Sektoren nach eigenen Ideen vornehmen. | ||
Die Ansteuerung als Übersicht: | Die Ansteuerung als Übersicht: | ||
< | < | ||
- | | + | |
- | :17 16 15 14 13 12 11 10 9 8: 7 6 5 4 3 2 1 0 : | + | :17 16 15 14 13 12 11 10 9 8: 7 6 5 4 3 2 1 0 : |
- | : : | + | : : |
- | +--+--+--+-+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ | + | +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ |
- | | | + | | Bank | | |
- | +--+--+--+-+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ | + | |B0 B1 b0 b1 x x x x | |
- | : | + | +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ |
- | : 9 8: 7 6 5 4 3 2 1 0: : 0: : | + | : : |
- | Variante 1 | + | Variante 1 |
- | | + | |
+ | :------------------------------TRACK--------------: | ||
+ | | ||
+ | Variante 2 | ||
+ | : 6 5 4 3 2 1 0: 3 2 1 0: : | ||
+ | : | ||
- | : : | ||
- | : 7 6: | ||
- | Variante 2 : | ||
</ | </ | ||
==== Variante 1 ==== | ==== Variante 1 ==== | ||
- | Die Fenstergröße von 256 Byte bietet es an, die Spurgröße als 256 Byte zu wählen. Hi-Byte und Lo-Byte der Tracknummer sind dann direkt " | + | Die Fenstergröße von 256 Byte bietet es an, die Spurgröße als 256 Byte zu |
+ | wählen. Hi-Byte und Lo-Byte der Tracknummer sind dann direkt " | ||
+ | Das macht die Ansteuerung besonders einfach. | ||
also: | also: | ||
Zeile 88: | Zeile 102: | ||
</ | </ | ||
- | Die BIOS-Routinen zum Blocklesen und -schreiben verweisen auf folgende Routinen. Wegen der Spurgröße von 256 Byte = 2 Records muss ein Blocking/ | + | Die BIOS-Routinen zum Blocklesen und -schreiben verweisen auf folgende Routinen. |
+ | Wegen der Spurgröße von 256 Byte = 2 Records muss ein Blocking/ | ||
+ | erfolgen. Glücklicherweise ist das bei einer RAM-Disk nicht weiter schwierig | ||
+ | umzusetzen, da innerhalb des Zugriffsfensters nur der angesprochene Bereich von | ||
+ | 128 Byte gelesen bzw. verändert wird. | ||
< | < | ||
Zeile 110: | Zeile 128: | ||
LD HL, | LD HL, | ||
OUT (LDAH), | OUT (LDAH), | ||
- | OUT (LDBB), | + | ld a,h |
+ | rrca | ||
+ | rrca | ||
+ | OUT (LDBB), | ||
LD HL, WINDOW ; das ist eine xx00h-Adr. | LD HL, WINDOW ; das ist eine xx00h-Adr. | ||
LD a, (SECTOR) ; 1 oder 2 (in CP/A wg. SECTRAN) | LD a, (SECTOR) ; 1 oder 2 (in CP/A wg. SECTRAN) | ||
Zeile 119: | Zeile 140: | ||
LD BC,128 | LD BC,128 | ||
RET | RET | ||
+ | |||
+ | |||
</ | </ | ||
==== Variante 2 ==== | ==== Variante 2 ==== | ||
- | Um eine kleinere Blockgröße nutzen zu können, muss die Anzahl der Spuren | + | (System EPOS, EPOSRF2.MAC) |
- | Da geht z.B. mit einer Spurgröße | + | |
+ | Um eine kleinere Blockgröße nutzen zu können, muss die Anzahl der Spuren | ||
+ | Da geht z.B. mit einer Blockgröße | ||
1 Track = 2048 Byte\\ | 1 Track = 2048 Byte\\ | ||
- | d.h. 16 Records/ | + | d.h. 16 Records/ |
- | wir brauchen | + | wir brauchen 1600h/2048 = 3 Tracks f. Systemspur |
- | insg. 128 Tracks-> DSM = 128-3\\ | + | wie wählen kleinste Blockgröße BLS 1k, 8 bit-Blocknummern ( DSM < 256)\\ |
- | kleinste Blockgröße 1k\\ | + | insg. 256 Tracks-> DSM = (256-3*2)/1-1 = 249, (epos 253)\\ |
und z.B. 64 Dir-Einträge (d.h. 2 Dir-Blöcke) | und z.B. 64 Dir-Einträge (d.h. 2 Dir-Blöcke) | ||
+ | |||
+ | DSM = (DISKSIZE-OFF*SPURSIZE)/ | ||
Diese Aufteilung ist aufgrund der kleineren Blockgröße günstiger, wenn viele kleine Dateien auf | Diese Aufteilung ist aufgrund der kleineren Blockgröße günstiger, wenn viele kleine Dateien auf | ||
Zeile 137: | Zeile 164: | ||
< | < | ||
- | ;DISKDEF 1, | + | dpbm: dw 16 ;spt |
- | dpb01: dw 16 ;SPT sectors per track | + | db 3 ;bsh |
- | db 3 ;BSF block shift factor | + | db 7 ;blm |
- | db 7 ;BLM block mask | + | db 0 ;exm |
- | db 0 ;EXM null mask | + | dw 253 ;dsm |
- | dw 124 ;DSM disk size-1 | + | dw 63 ;dpm |
- | dw 63 ;DRM directory max | + | db 0c0h ;al0 |
- | db C0H ;AL0 alloc 0 | + | db 00 ;al1 |
- | db 0 ;Al1 alloc 1 | + | dw 0 ;cks |
- | dw 0 ;CKS check size | + | dw 1 ;off |
- | dw 3 ;OFS track offset | + | db 80h ; |
+ | ds 12,0 | ||
; | ; | ||
- | alv01: ds 0010h ;allocation vector | + | allm: ds 33 ;alloc-map |
- | csv01: | + | |
- | </ | + | |
- | + | ||
- | Read und Write sind wie oben implementiert, | + | |
- | + | ||
- | < | + | |
- | ADRE: | + | |
- | OUT (READEN), | + | |
; | ; | ||
- | ;Adr. Fenster = (track*16+sector)/ | + | rfrwoper: |
- | LD HL,(TRACK) | + | ld hl,(sektrk) ;und lesen |
- | ADD HL,HL | + | add hl,hl |
- | ADD HL,HL | + | add hl,hl |
- | ADD HL,HL | + | add hl,hl ; trk << 3 |
- | ADD HL,HL ; HL = Track * 10h (SPT) | + | ld a,(seksec) |
- | LD DE,(SECTOR) | + | and 1fh |
- | DEC DE ; wg. CP/A | + | srl a ; sec >> 1 |
- | ADD HL,DE ; HL := HL + Sector | + | push af |
- | XOR A ; A = 0, Cy = 0 | + | add a,l |
- | RR H | + | di |
- | RR L ; HL := HL/2 ( da 2 Sektoren/ | + | out (ioa+5),a |
- | RR A ; L Bit0 nach A Bit7 ( A = 0 oder 80h) | + | out (ioa+7),a |
- | OUT (LDAH), L ; hi-adr. | + | out (ioa), |
- | OUT (LDBB), H ; Bank | + | ld a,03h |
- | LD H, Hi(WINDOW) | + | and h ;Bit0+1 |
- | LD L,A | + | rrca |
- | LD DE,(DMA) | + | rrca :-> |
- | LD BC,128 | + | out (ioa+2),a ;bank |
- | RET | + | ; |
+ | pop af ;cy=off im fenster | ||
+ | ld hl,wind | ||
+ | jr nc, | ||
+ | ld hl, | ||
+ | rf01: | ||
+ | ld a,b | ||
+ | or a ;rd/wr | ||
+ | jr z,rf02 | ||
+ | ex de,hl | ||
+ | rf02: ld bc,128 | ||
+ | ldir | ||
+ | ; | ||
+ | xor a | ||
+ | out (ioa+4),a | ||
+ | ei | ||
+ | ret | ||
</ | </ | ||
Zeile 208: | Zeile 244: | ||
</ | </ | ||
- | CP/M zählt die logischen Recordnummern pro Spur von 0..39. SECTRAN übersetzt diese Recordnummern in 1..40 (CP/ | + | CP/M zählt die logischen Recordnummern pro Spur von 0..39. SECTRAN übersetzt |
+ | diese Recordnummern in 1..40 (CP/ | ||
+ | Recordnummer mit SETSEC ans BIOS. | ||
CP/M ermittelt anhand DSM, ob 16Bit- oder 8-Bit-Blocknummern genutzt werden: DSM > 255 -> 16Bit-Blocknummern. | CP/M ermittelt anhand DSM, ob 16Bit- oder 8-Bit-Blocknummern genutzt werden: DSM > 255 -> 16Bit-Blocknummern. | ||
- | Die max. Spurnummer berechnet sich als DSM*BLS/ | + | Die max. Spurnummer berechnet sich als DSM*BLS/ |
CP/M arbeitet aber intern nicht mit einer maximalen Spurnummer, sondern testet auf Überschreiten von DSM. | CP/M arbeitet aber intern nicht mit einer maximalen Spurnummer, sondern testet auf Überschreiten von DSM. | ||
Der DPB wird vom CP/M wie folgt angezeigt: | Der DPB wird vom CP/M wie folgt angezeigt: | ||
+ | |||
< | < | ||
A>stat dsk: | A>stat dsk: | ||
Zeile 243: | Zeile 282: | ||
</ | </ | ||
- | Bislang wurde noch nicht darauf eingegangen, | + | Bislang wurde noch nicht darauf eingegangen, |
+ | hat. Die Adressierung von Diskettenseite/ | ||
+ | Blocking/ | ||
+ | |||
+ | TODO |