Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
cpm:write_a_bios:teil_2 [2012/03/08 15:49] – Page name changed from cpm:write_a_bios:dbp to cpm:write_a_bios:teil_2 volkerpcpm:write_a_bios:teil_2 [2021/09/28 08:23] (aktuell) volkerp
Zeile 2: Zeile 2:
  
 weiter geht es mit dem **DPB** weiter geht es mit dem **DPB**
 +
 +das folgende Beispiel stammt aus einer [[cpm:cpa|]]-Implementation.
 +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!
 +
 +<code>
 +;-----------------------------------------------------------------------------
 +; Uebersetzung Sektornummer in CP/A
 +;-----------------------------------------------------------------------------
 +sectran: ld h, b
 + ld l, c
 + inc hl ;Sektoren zaehlen in CP/A ab 1
 + ret
 +</code>
  
 ===== Beispiel 2 ===== ===== Beispiel 2 =====
  
 Wir wollen ein RAM-Floppy ansteuern.  Wir wollen ein RAM-Floppy ansteuern. 
-Die RAM-Floppy (NANOS) hat folgende Eigenschaften:+Die [[:z1013:module:raf#nanos|RAM-Floppy (NANOS)]] hat folgende Eigenschaften:
  
   * 256 K Gesamtkapazität   * 256 K Gesamtkapazität
Zeile 18: Zeile 32:
   - Zugriff auf "Window"+A7..A0   - Zugriff auf "Window"+A7..A0
  
-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: 
 + 
 +<code> 
 +                    :-----  Vollständige 18 bit RAM-Adresse (RAF 256K)  ------: 
 +                    :17 16   15 14 13 12 11 10  9  8:  7  6  5  4  3  2  1  0 : 
 +                    :                               :                         : 
 +  +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ 
 +  |           Bank        | |       Hi-Adr.         | |       Window          | 
 +  |B0 B1 b0 b1 x  x  x  x | 
 +  +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ 
 +                          : :                       : :  :                    : 
 +Variante 1 
 +  : 9  8                      7  6  5  4  3  2  1  0: : 0:                    : 
 +  :------------------------------TRACK--------------: :--:-------RECORD-------: 
 +                                                 SECTOR ^ 
 + 
 +Variante 2 
 +  : 6  5                      4  3  2  1  0: 3  2  1    0:                    : 
 +  :------------------------------TRACK---- :-SECTOR------:-------RECORD-------: 
 + 
 +</code>
  
 ==== 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 "Bank" und "HiAdr". Das macht die Ansteuerung besonders einfach.+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 "Bank" und "HiAdr". 
 +Das macht die Ansteuerung besonders einfach.
  
 also: also:
  
 1 Track = 256 Byte (Fenstergröße)\\ 1 Track = 256 Byte (Fenstergröße)\\
-d.h. 2 Records/track\\+d.h. 2 Records/track 1..2\\
 wir brauchen damit 1600h/256 = 22 Tracks f. Systemspur\\ wir brauchen damit 1600h/256 = 22 Tracks f. Systemspur\\
-insg. 1024 tracks -> DSM = 1023-22\\ +insg. 1024 tracks -> DSM = 1024-22 = 1012\\ 
-wir wählen die kleinstmögliche Blockgröße 2k (1k gehen nicht wg. EXM, da wir mehr als 256 Spuren haben)\\+wir wählen die kleinstmögliche Blockgröße 2k (1k gehen nicht wg. EXM, da DSM > 255)\\
 und z.B. 128 Dir-Einträge (d.h. 2 Dir-Blöcke)\\ und z.B. 128 Dir-Einträge (d.h. 2 Dir-Blöcke)\\
  
Zeile 39: Zeile 79:
 <code> <code>
  ;DISKDEF 0,1,2,,2048,1012,128,0,22  ;DISKDEF 0,1,2,,2048,1012,128,0,22
-dpb00: dw 2 ;sec per track +dpb00: dw 2 ;SPT sectors per track 
- db 4 ;block shift + db 4 ;BSF block shift factor 
- db 15 ;block mask + db 15 ;BLM block mask 
- db 0 ;extnt mask + db 0 ;EXM null mask 
- dw 1011 ;disk size-1 + dw 1011 ;DSM disk size-1 
- dw 127 ;directory max + dw 127 ;DRM directory max 
- db C0h ;alloc0 + db C0h ;AL0 alloc 0 
- db 0 ;alloc1 + db 0 ;Al1 alloc 1 
- dw 0 ;check size + dw 0 ;CKS check size 
- dw 22 ;offset+ dw 22 ;OFS track offset
 ; ;
-alv00: ds 007Fh +alv00: ds 007Fh   ;allocation vector 
-csv00: ds 0000+csv00: ds 0000         ;check vector
 </code> </code>
  
-Die BIOS-Routinen zum Blocklesen und -schreiben verweisen auf folgende Routinen:+Die BIOS-Routinen zum Blocklesen und -schreiben verweisen auf folgende Routinen
 +Wegen der Spurgröße von 256 Byte = 2 Records muss ein Blocking/Deblocking 
 +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.
  
 <code> <code>
Zeile 76: Zeile 120:
  LD HL,(TRACK)  LD HL,(TRACK)
  OUT (LDAH), L ; hi-adr.  OUT (LDAH), L ; hi-adr.
- OUT (LDBB), H ; Bank+ ld a,h 
 + rrca 
 + rrca 
 + OUT (LDBB), A ; Bank
  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)
  CP 2  CP 2
  jr nz, ADRE0a  jr nz, ADRE0a
- LD H,80h+ LD L,80h
 ADREa: LD DE,(DMAAD) ADREa: LD DE,(DMAAD)
  LD BC,128  LD BC,128
  RET  RET
 +
 +
 </code> </code>
  
 ==== Variante 2 ==== ==== Variante 2 ====
  
-Um eine kleinere Blockgröße nutzen zu können, muss die Anzahl der Spuren ≤ 256 werden. +(System EPOS, EPOSRF2.MAC) 
-Da geht z.B. mit einer Spurgröße von 2 KByte.+ 
 +Um eine kleinere Blockgröße nutzen zu können, muss die Anzahl der Spuren <= 256 werden. 
 +Da geht z.B. mit einer Blockgröße von 1 KByte. Als phys. Spurgröße wählen wir 2 KByte.
  
 1 Track = 2048 Byte\\  1 Track = 2048 Byte\\ 
-d.h. 16 Records/Track\\ +d.h. 16 Records/Track 0..15 (CPA 1..16)\\ 
-wir brauchen damit 1600h/2048 = 3 Tracks f. Systemspur\\ +wir brauchen 1600h/2048 = 3 Tracks f. Systemspur OFF, Epos 1 Systemspur\\ 
-insg. 256 Tracks-> DSM = 255-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)
  
-Diese Aufteilung ist wg. der kleineren Blockgröße günstiger, wenn viele kleine Dateien auf  +DSM = (DISKSIZE-OFF*SPURSIZE)/BLS-1 
-der RAM-Disk gehalten werden sollen. Auch wird weniger Platz für den Allocation Vektor ALVxx benötigt. Aber die Umrechnung logischer Track-Sektor -> Adr. f. RAM-Disk ist aufwendiger!+ 
 +Diese Aufteilung ist aufgrund der kleineren Blockgröße günstiger, wenn viele kleine Dateien auf  
 +der RAM-Disk gehalten werden sollen. Auch wird weniger Platz für den Allocation Vektor ALVxx benötigt. Aber die Umrechnung logischer Track und Sektor -> Adr. f. RAM-Disk ist aufwendiger!
  
 <code> <code>
-      ;DISKDEF 1,1,16,,1024,252,64,0,+dpbm: dw 16 ;spt 
-dpb01: dw 16 ;sec per track + db 3 ;bsh 
- db 3 ;block shift + db 7 ;blm 
- db 7 ;block mask + db 0 ;exm 
- db 0 ;extnt mask + dw 253 ;dsm 
- dw 251 ;disk size-1 + dw 63 ;dpm 
- dw 63 ;directory max + db 0c0h ;al0 
- db C0H ;alloc0 + db 00 ;al1 
- db 0 ;alloc1 + dw 0 ;cks 
- dw 0 ;check size + dw 1 ;off 
- dw 3 ;offset + db 80h ;dev 
-alv01: ds 0020h + ds 12,0 
-csv01: ds 0000h+
 +allm: ds 33 ;alloc-map  
 +
 +rfrwoper: ;physisches schreiben 
 + ld hl,(sektrk) ;und lesen 
 + add hl,hl 
 + add hl,hl 
 + add hl,hl ; trk << 3 
 + ld a,(seksec) 
 + and 1fh 
 + srl a ; sec >> 1  
 + push af 
 + add a,l 
 + di 
 + out (ioa+5),
 + out (ioa+7),
 + out (ioa),a ;Hi-Adr. im ramfl 
 + ld a,03h  
 + and h ;Bit0+1 
 + rrca 
 + rrca :->Bit6+7 
 + out (ioa+2),a ;bank 
 +
 + pop af ;cy=off im fenster 
 + ld hl,wind 
 + jr nc,rf01 
 + ld hl,wind+128 
 +rf01: ld de,(dmaad) 
 + ld a,b 
 + or a ;rd/wr 
 + jr z,rf02 
 + ex de,hl 
 +rf02: ld bc,128 
 + ldir 
 +
 + xor a 
 + out (ioa+4),
 + ei 
 + ret
 </code> </code>
  
-Read und Write sind wie oben implementiert, die Adressierung ist jetzt umfangreicher:+===== Beispiel 3 ===== 
 + 
 +Ein Floppy-Laufwerk800K, 2 Seiten, 1K phys. Sektorgröße, 5 phys. Sektoren pro Spur und Seite 
 + 
 +log. Sektoren pro Spur 1..40\\ 
 +Blockgröße BLS = 2048\\ 
 +Diskgröße = 800K/BLS = 400\\ 
 +192 Directory-Einträge\\ 
 +keine Systemspuren
  
 <code> <code>
-ADRE: OUT (RAMEN)+ ;DISKDEF 0,1,40,,2048,400,192,192, 
- OUT (READEN)+dpba: dw 40 ;SPT sectors per track 
-+ db 4 ;BSF block shift factor 
- ;Adr. Fenster = (track*16+sector)/+ db 15 ;BLM block mask 
- LD HL,(TRACK) + db 0 ;EXM null mask 
- ADD HL,HL + dw 399 ;DSM disk size-1 
- ADD HL,HL + dw 191 ;DRM directory max 
- ADD HL,HL + db 0E0H ;AL0 alloc 
- ADD HL,HL HL = Track * 10h (SPT+ db 0 ;Al1 alloc 1 
- LD DE,(SECTOR) + dw 48 ;CKS check size 
- DEC DE wg. CP/A + dw 0 ;OFS track offset 
- ADD HL,DE HL := HL + Sector +alva: ds 0032h    
- XOR A A = 0, Cy = 0  +csva: ds 0030h    
- RR H  +
- RR L HL := HL/2 ( da 2 Sektoren/Fenster ) +
- RR A L Lo-Bit in A Hi-Bit ( A = oder 80h) +
- OUT (LDAH), L hi-adr. +
- OUT (LDBB), H Bank +
- LD H, Hi(WINDOW) +
- LD L,A +
- LD DE,(DMA) +
- LD BC,128 +
- RET+
 </code> </code>
  
-Die Ansteuerung als Übersicht:+CP/M zählt die logischen Recordnummern pro Spur von 0..39. SECTRAN übersetzt 
 +diese Recordnummern in 1..40 (CP/A-Umrechnung) und übergibt diese berechnete 
 +Recordnummer mit SETSEC ans BIOS. 
 + 
 +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/SPT/128-OFS. 
 +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:
  
 <code> <code>
-                :-----  Vollständige 18 bit RAM-Adresse (RAF 256K)  ------+A>stat dsk: 
-                :17 16   15 14 13 12 11 10  9  8:   6  5  4  3  2  1  0 : +    ADrive Characteristics 
-                :                               :                         : + 6400128 Byte Record Capacity 
-  +--+--+--+-+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +  800Kilobyte Drive  Capacity 
-  |        Bank       | |       Hi-Adr.         | |       Window          | +  19232  Byte Directory Entries 
-  +--+--+--+-+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +  192: Checked  Directory Entries 
-                :                               : :  :                    +  128Records/ Extent 
-                9  8    7  6  5  4  3  2  1  0: :  :                    : +   16Records/ Block 
-Variante 1      :------------TRACK--------------: :--:-------RECORD-------: +   40Sectors/ Track 
-                                                 SECTOR +    0: Reserved Tracks 
 +</code>
  
 +POWER gibt ein paar mehr Informationen aus:
  
-                :                          :         :                    : +<code> 
-                : 7  6    5  4     0 : 3  1 0                   +        POWER 3.03 on CP/M 2.22 1/2 
-Variante 2      :------------TRACK---------:-SECTOR--:-------RECORD-------:+A=disk 
 +disk capacity   800K 
 +tracks          160    0 system 
 +sectors/track    40   40 last 
 +sectors/system    0   48 dir 
 +dir entries     192    6K 
 +sectors/group:     16    2K 18FH groups 
 +kbytes/extent    16K
 </code> </code>
 +
 +Bislang wurde noch nicht darauf eingegangen, dass eine phys. Diskette 2 Seiten
 +hat. Die Adressierung von Diskettenseite/Spur/phys.Sektor incl.
 +Blocking/Deblocking ist Aufgabe des BIOS.
  
  • cpm/write_a_bios/teil_2.1331221759.txt.gz
  • Zuletzt geändert: 2012/03/08 15:49
  • von volkerp