Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
cpm:write_a_bios [2012/03/07 10:51] – angelegt volkerpcpm:write_a_bios [2014/05/08 10:19] (aktuell) volkerp
Zeile 1: Zeile 1:
-====== howto write a bios  ======+====== BIOS schreiben  ======
  
 **howto write a bios for cp/m 2.2\\ **howto write a bios for cp/m 2.2\\
 V. Pohlers, 2012** V. Pohlers, 2012**
  
-Zu CP/M 2.2 gibt es eine Datei cbios.asm mitdie als Ausgang für ein BIOS dienen kann. +Ich will versuchen, die Grundlagen zum Schreiben eines eigenen kleinen BIOS für CP/M 2.2 praxisgerecht darzustellenGrundlagenwissen sollte man schon habenz.B. was ein BIOS ist und welche Funktionen drin sind, wie eine Diskette aufgebaut ist u.a.m.\\ 
-Diesen Code habe ich hier genutzt, an Z80 angepasst und ggfweiter vereinfacht.+Detailwissen liefert [[cpm:systemdoku]].
  
-Das BIOS folgt unmittelbar auf CCP und BDOS. Am Anfang des BIOS steht ein  
-Sprungverteiler zu den 17 BIOS-Funktionen. 
  
-Die BIOS-Funktionen müssen keine Register retten.+  * [[cpm:write_a_bios:teil_1|]] Warmstart, Zeichen-I/O, Diskettenfunktion 
 +  * [[cpm:write_a_bios:teil_2|]] Ansteuerung einer RAM-Disk
  
-===== Kalt- und Warmstart ===== 
- 
-<code> 
- .Z80 
-; Skeletal CBIOS for first level of CP/M 2.0 alteration 
-; 
-CCP EQU xx00H ;base of ccp 
-BDOS EQU CCP+806H ;base of bdos 
-BIOS EQU CCP+1600H ;base of bios 
- 
-CDISK EQU 0004H ;current disk number 0=A,...,15=P 
-IOBYTE EQU 0003H ;intel i/o byte 
-; 
- ORG BIOS ;origin of this program 
- 
-; jump vector for individual subroutines 
- JP BOOT ;cold start 
-WBOOTE: JP WBOOT ;warm start 
- JP CONST ;console status 
- JP CONIN ;console character in 
- JP CONOUT ;console character out 
- JP LIST ;list character out 
- JP PUNCH ;punch character out 
- JP READER ;reader character out 
- JP HOME ;move head to home position 
- JP SELDSK ;select disk 
- JP SETTRK ;set track number 
- JP SETSEC ;set sector number 
- JP SETDMA ;set dma address 
- JP READ ;read disk 
- JP WRITE ;write disk 
- JP LISTST ;return list status 
- JP SECTRAN ;sector translate 
-</code> 
- 
-**BOOT** ist der Eintrittspunkt, der nach dem BOOT-Vorgang einmalig angesprungen  
-werden sollte. Vom CP/M aus wird niemals BOOT aufgerufen. Im einfachsten Fall  
-kann BOOT im BIOS-Bereich komplett leer bleiben, wenn die Systeminitialisierung  
-im BOOT-Loader erfolgt. 
- 
-Der Kaltstart wird nur nach dem erstmaligen Laden des Betriebsystems benötigt.  
-Der Aufruf an den Kaltstart erfolgt meist von einem speziellen Ladeprogramm, das  
-nach dem Einschalten des Rechners das BIOS von der Systemdiskette geladen hat. 
- 
-Aufgabe des Kaltstart ist es, die einzelnen Systemkomponenten zu initialisieren  
-und eine Meldung über den erfolgten Systemstart auf der Console auszugeben. 
- 
-Normalerweise wird nach einem Kaltstart ein Warmstart ausgeführt, der den CCP  
-und das BDOS von der Diskette lädt und die Sprungbefehle einsetzt. Dann braucht  
-nur die zuerst anzuwählende Disk- und Usernummer in die Speicheradresse  
-0004h eingetragen zu werden. 
- 
-**WBOOT** wird beim Warmstart (z.b. ^C oder JP 0000) aufgerufen. Die BDOS- 
-Funktion 0 geht direkt zur BIOS-Funktion WBOOT weiter. 
- 
-WBOOT muss CCP und BDOS im Speicher restaurieren. Für ein erstes BIOS kann dies  
-übergangen werden, solange keine Programe gestartet werden, die das CCP oder  
-sogar CCP und BDOS überschreiben. Zum Neuladen von CCP und BDOS sind folgende Verfahren üblich: 
- 
-  * Laden aus Systemspuren der BOOT-Diskette (meist A:) 
-  * Laden aus einer Kopie im Speicher (z.B. bei Vorhandensein von Schattenspeicher) 
-  * Erstellen einer Kopie während des BOOT-Vorgangs in eine RAM-Disk und Laden von dieser (üblicherweise auch hier aus Systemspuren) 
-  * Laden aus einer @OS-Datei von der Diskette. Dazu muss aber ein Mini-BDOS verfügbar sein, was das logische Lesen von Diskette unterstützt. Die Records dieser @OS-Datei könnten ja beliebig auf der Diskette verstreut liegen. 
- 
-Nach dem Neuladen von CCP und BDOS werden die Systemsprünge für JP 0000 und CALL 5 eingerichtet, 
-das aktuelle Laufwerk wieder selektiert und die Steuerung ans CCP übergeben. 
- 
-<code> 
-; 
-BOOT: ;simplest case is to just perform parameter initialization 
- XOR A ;zero in the accum 
- LD (IOBYTE),A ;clear the iobyte 
- LD (CDISK),A ;select disk zero 
- JP GOCPM ;initialize and go to cp/m 
-; 
-WBOOT: ;simplest case is to read the disk until all sectors loaded 
- LD SP,80H ;use space below buffer for stack 
- ;... 
- ..reread ccp+bdos into memory 
- ;... 
-;        
-; end of load operation, set parameters and go to cp/m 
-GOCPM: 
- LD A,0C3H ;c3 is a jmp instruction 
- LD (0),A ;for jmp to wboot 
- LD HL,WBOOTE ;wboot entry point 
- LD (1),HL ;set address field for jmp at 0 
-; 
- LD (5),A ;for jmp to bdos 
- LD HL,BDOS ;bdos entry point 
- LD (6),HL ;address field of jump at 5 to bdos 
-; 
- LD BC,80H ;default dma address is 80h 
- CALL SETDMA 
-; 
- EI ;enable the interrupt system 
- LD A,(CDISK) ;get current disk number 
- LD C,A ;send to the ccp 
- JP CCP ;go to cp/m for further processing 
- 
-</code> 
- 
-===== Zeichen-I/O ===== 
- 
-Im BIOS sind die grundlegenden I/O-Funktionen zur zeichenweisen Ein- und Ausgabe  
-für Konsole, Drucker, Reader, Punch enthalten.  
- 
-Ein einfaches BIOS braucht nur Ein- und Ausgabe für Konsole, die restl.  
-Funktionen sind Leerfunktionen.  
- 
-Das **I/O-Byte** wird von CP/M selbst nicht genutzt. Die BDOS-Funktionen Nr. 7 und 8  
-lesen bzw. beschreiben direkt die Speicherzelle IOBYTE. Das Systemprogramm STAT  
-nutzt wiederum nur diese BDOS-Funktionen.  
- 
-Ein I/O-Byte-Unterstützung muss deshalb vollständig im BIOS erfolgen. Man kann  
-problemlos darauf verzichten; wenn man nicht verschiedene Geräte für die 4 I/O- 
-Kanäle Konsole, Drucker, Reader, Punch unterstützen muss/will. 
- 
-Die BIOS-Funktion **CONIN** darf das eingetippte Zeichen nicht auf dem Bildschirm  
-ausgeben. 
- 
-<code> 
-; 
-; 
-; simple i/o handlers (must be filled in by user) 
-; in each case, the entry point is provided, with space reserved 
-; to insert your own code 
-; 
-CONST: ;console status, return 0ffh if character ready, 00h if not 
- ..status subroutine 
- LD A,00H 
- RET 
-; 
-CONIN: ;console character into register a 
- ..input routine 
- AND 7FH ;strip parity bit 
- RET 
-; 
-CONOUT: ;console character output from register c 
- LD A,C ;get to accumulator 
- ..output routine 
- RET 
-; 
-LIST: ;list character from register c 
- LD A,C ;character to register a 
- RET ;null subroutine 
-; 
-LISTST: ;return list status (0 if not ready, 1 if ready) 
- XOR A ;0 is always ok to return 
- RET 
-; 
-PUNCH: ;punch character from register c 
- LD A,C ;character to register a 
- RET ;null subroutine 
-; 
-; 
-READER: ;read character into register a from reader device 
- LD A,1AH ;enter end of file for now (replace later) 
- AND 7FH ;remember to strip parity bit 
- RET 
-</code> 
- 
-===== Diskettenfunktionen ===== 
- 
-Der größte Teil des BIOS besteht in Funktionen zur Diskettenarbeit. 
- 
-Eine Diskette besteht physikalisch aus **Spuren (Tracks)**. Diese sind in  
-**physische Sektoren** unterteilt. Das BDOS greift immer über Track- und  
-logische Sektornummer auf Laufwerke zu. Ein **logischer Sektor (sector, auch  
-record)** ist immer 128 Byte lang. 
- 
-Eine Spur kann Werte von 0..FFFFh annehmen, ein logischer Sektor von 0..FFFFh. 
-Üblich sind bei Disketten aber Werte von 0..80 für die Spur und 0..255 für den logischen Sektor. 
-Viele BIOSe arbeiten deshalb auch nur mit 8-Bit-Registern für diese Werte. Damit sind immerhin  
-256 Tracks * 256 logische Sektoren * 128 Byte = 8 MByte adressierbar. 
- 
-Es ist Aufgabe des BIOS, die beiden Werte (Tracks und logischer Sektor) in 
- 
-  * Diskettenseite 
-  * Spur 
-  * und physische Sektornummer 
- 
-umzusetzen. Wie das erfolgt, ist dem BIOS-Schreiber überlassen (und hängt von der Hardware ab). 
-Beispiele folgen später. 
- 
-Die physischen Sektoren sind beispielsweise 1 KByte groß. Das BIOS muss einen  
-Puffer bereitstellen, um einen kompletten physischen Sektor einzulesen und  
-diesen in logische Sektoren aufzuteilen. Dieser Mechanismuss heiß  
-Blocking/Deblocking. Das dies nicht trivial ist, gibt es zu CP/M 2.2 eine Datei  
-deblock.asm als Vorlage. 
- 
-Die Routinen SETDMA, SETTRK, SETSEC speichern einfach die übergebenen Werte.  
-Wenn die Laufwerke nur mit max 256 Spuren zu max. 256 log. Sektoren arbeiten,  
-kann man TRACK und SECTOR als Byte belassen und nur Register C übernehmen. Das  
-BDOS übergibt nur gültige Werte, so dass Register B in diesem Fall immer 0 ist  
-und nicht beachtet werden muss. 
- 
-HOME selektiert Spur 0. Ein phys. Zugriff aufs Laufwerk ist nicht erforderlich. 
-Mam spart auch CALL SETTRK und RET, wenn HOME direkt vor SETTRK steht. 
-Diese Funktion war bei älteren Laufwerken zur exakten 
-Positionierung des Schreib/Lesekopfes gedacht. 
-Da das BDOS vor jedem Diskzugriff die Spurnummer über SETTRK 
-anwählt, ist HOME bei neueren Laufwerken überflüssig. 
- 
-SETTRK bezieht sich auf die im Registerpaar BC übergebene Spur. Diese Spurnummer  
-errechnet sich immer aus der BDOS-internen (logischen) Spurnummer plus dem OFF- 
-Wert im DPB. Wie auch beim SELDSK-Aufruf ist ein tatsächlicher Diskzugriff nicht  
-garantiert. 
- 
-SETSEC bezieht sich auf den im Registerpaar 
-BC übergebenen Sektor. Die so gesetzte Sektornummer ist immer 
-das Ergebnis der SECTRAN-Funktion (s.u.). Auch hier ist ein 
-tatsächlicher Diskzugriff auf diesen Sektor nicht garantiert. 
- 
-SETDMA: Alle nachfolgenden Diskzugriffe müssen die DMA-Adresse als 
-Quell- (bei Schreibzugriffen) bzw. Zieladresse (bei Lesezugriffen) 
-benutzen. Die DMA-Adresse zeigt immer auf einen 128-Byte großen Buffer, 
-weshalb Diskzugriffe immer in Recordgröße erfolgen.  
- 
-<code> 
-; 
-; i/o drivers for the disk  
-; 
-HOME: ;move to the track 00 position of current drive 
- LD BC,0 ;select track 0 
- ;CALL SETTRK  
- ;RET 
-; 
-SETTRK ;set track given by register bc 
- LD (TRACK),BC 
- RET 
-; 
-SETSEC ;set sector given by register bc 
- LD (SECTOR),BC 
- RET 
- 
-SETDMA ;set dma address given by registers b and c 
- LD (DMAAD),BC 
- RET 
- 
-; 
-</code> 
- 
-**SECTRAN** übernahm ursprünglich eine Sektornummertransformation bei  
-hardsektorierten Disketten (8") anhand einer Sektorverschränkungstabelle (X- 
-lation table XLT). Dies ist bei moderneren Laufwerken nicht mehr üblich bzw.  
-wegen größerer physischer Sektorlänge als 128 Byte auch nicht möglich. Eine  
-Sektorverschränkung physischer Sektoren erfolgt deshalb meist im phys.  
-Diskettentreiber (s. unten).  
- 
-Im allgemeinen genügt es, einfach die im Registerpaar BC 
-übergebene Sektornummer ins Registerpaar HL zu kopieren. 
- 
-im CP/A wird einfach der übergebene Wert genommen und um 1 erhöht (die Sektoren  
-zählen in CP/A bzw. auf Diskette ab 1). Nutzt man eine allgemeine SECTRAN- 
-Routine für alle Laufwerke, muss dies bei den phys. Treibern beachtet werden. 
- 
-<code> 
-SECTRAN: (allg) 
-;translate the sector given by BC using the 
-;translate table given by DE 
- EX DE,HL ;HL=.trans 
- ADD HL,BC ;HL=.trans(sector) 
- LD L,(HL) ;L = trans(sector) 
- LD H,0 ;HL= trans(sector) 
- RET ;with value in HL 
-; 
-SECTRAN: (CP/A) 
-;translate the sector given by BC without translate table 
- LD L,C ;L = trans(sector) 
- LD H,B ;HL= trans(sector) 
- inc HL 
- RET ;with value in HL 
-; 
-</code> 
- 
-**SELDSK**: Das BIOS muß die im C-Register übergebene Laufwerksnummer 
-überprüfen und, falls ein Laufwerk mit dieser Nummer existiert, 
-in HL die Adresse des zugehörigen disk parameter header DPH zurückgeben, 
-Im CP/M ist nicht garantiert, daß nach einem SELDSK-Aufruf 
-auch tatsächlich auf dieses Laufwerk zugegriffen wird. 
-Vielmehr hat der SELDSK-Aufruf nur eine 'Anmeldefunktion', 
-damit sich das BDOS auf das Laufwerk einstellen kann. 
-Das BIOS muß die Laufwerksnummer aber intern speichern, da 
-sich nachfolgende Diskzugriffe immer auf das zuletzt selektierte 
-Laufwerk beziehen. 
- 
-In einem aufwendigen BIOS kann bei SELDSK eine Analyse der Diskette erfolgen, um  
-das konkrete **Diskettenformat automatisch zu ermitteln**. Im CP/A-BIOS gibt es eine Liste von  
-Formaten, die hier getestet werden (z.B. 624k, 780k, 800k). Als Resultat dieser  
-Analyse wird ein passender DPB ausgewählt (oder dynamisch zusammengestellt)  
-und im DPH eingetragen. 
- 
-Die Laufwerke müssen nicht in alphabetischer Reihenfolge und durchlaufend angelegt sein. 
-Man kann die Laufwerksbuchstaben A..P willkürlich den Laufwerken zuordnen. SELDSK muss  
-für ein existierenes Laufwerk den passenden DPH und andernfalls 0000 zurückgeben. 
- 
-Für jeden Laufwerksbuchstabe, der vom BIOS angesprochen werden kann, muss es  
-einen eigenen disk parameter header DPH geben. 
- 
-Ein disk parameter header DPH ist 16 Byte lang und muss im RAM stehen. BDOS  
-beschreibt die freien Felder des DPH mit eigenen Werten. 
- 
-Ein DPH umfasst 8 Einträge zu je 16 Bit und hat folgende Struktur:  
-<ditaa> 
-    +-----------------------------------------------------+ 
-    | XLT | NHDE | CLTK | FSCT | DIRBUF | DPB | CSV | ALV | 
-    +-----------------------------------------------------+ 
-Byte  0/1   2/   4/5    6/7    8/9      A/B   C/  E/F 
-</ditaa> 
- 
-XLT (s.o.), NHDE, CLTK, FSCT sind mit 0 vorbelegt, DIRBUF ist ein 128 Byte  
-großer Puffer (für alle Laufwerke derselbe), DPB ist die Adresse des Disk  
-Parameter Blocks, CSV die Adresse des Prüfsummenvektors (Check Sum Vector) und  
-ALV die Adresse des Belegungsvektors (Allocation Vector). 
- 
-Der DPB enthält die Laufwerkseigenschaften und wird weiter unten beschrieben.  
-Ein DPB kann für mehrere DPH genommen werden, wenn die Laufwerkseigenschaften  
-gleich sind (z.B. für 2 gleiche Diskettenlaufwerke). 
- 
-CSV und ALV sind Speicherbereiche im RAM,  
-deren Größe von den Laufwerkseigenschaften abhängen (s. DPB). 
- 
-<code> 
-; fixed data tables for four drives 
- 
-DPBASE: 
-; disk parameter header for disk 00 
-DPH0: DW 0000H,0000H 
- DW 0000H,0000H 
- DW DIRBF,DPB0 
- DW CHK00,ALL00 
-; disk parameter header for disk 01 
-DPH1: DW 0000H,0000H 
- DW 0000H,0000H 
- DW DIRBF,DPB1 
- DW CHK01,ALL01 
-; disk parameter header for disk 02 
-DPH2: DW 0000H,0000H 
- DW 0000H,0000H 
- DW DIRBF,DPB2 
- DW CHK02,ALL02 
-; disk parameter header for disk 03 
-DPH3: DW 0000H,0000H 
- DW 0000H,0000H 
- DW DIRBF,DPB3 
- DW CHK03,ALL03 
-; 
- 
-; werden die Laufwerksbuchstaben durchgehend vergeben (A:..D:) und  
-; folgen die DPH direkt aufeinander, kann der DPH durch DPBASE + 16*DISKNO berechnet werden 
-SELDSK: ;select disk given by register C 
- LD HL,0000H ;error return code 
- LD A,C 
- LD (DISKNO),A 
- CP 4 ;must be between 0 and 3 
- RET NC ;no carry if 4,5,... 
-; compute proper disk parameter header address 
- LD A,(DISKNO) 
- LD L,A ;L=disk number 0,1,2,3 
- LD H,0 ;high order zero 
- ADD HL,HL ;*2 
- ADD HL,HL ;*4 
- ADD HL,HL ;*8 
- ADD HL,HL ;*16 (size of each header) 
- LD DE,DPBASE 
- ADD HL,DE ;HL=.dpbase(diskno*16) 
- RET 
- 
-; Alternativ: sind die Laufwerksbuchstaben nicht durchgehend vergeben, kann die Ermittlung auch direkt  
-; erfolgen, hier Laufwerke A:, B:, F:, P: 
-SELDSK: ;select disk given by register C 
- LD A,C 
- LD (DISKNO),A 
-  
- LD HL, DPH0 
- CP 'A'-'A' ; Laufwerk A 
- RET Z 
- LD HL, DPH1 
- CP 'B'-'A' ; Laufwerk B 
- RET Z 
- LD HL, DPH2 
- CP 'F'-'A' ; Laufwerk F 
- RET Z 
- LD HL, DPH3 
- CP 'P'-'A' ; Laufwerk P 
- RET Z 
- ; 
- LD HL,0000H ;error return code 
- RET 
-</code> 
- 
- 
-Die **READ**-Funktion liest einen (logischen) Sektor von der Diskette in den  
-DMA-Buffer. Die Disknummer, Spurnummer und Sektornummer sind jeweils durch die  
-letzten SELDSK-, SETTRK- und SETSEC-Aufrufe festgelegt.  
- 
-Bei physikalischen Sektorlängen vom mehr als 128 Bytes muß das BIOS einen  
-Sektorbuffer entsprechender Große selbst bereitstellen und aus diesem Buffer 128  
-Bytes zum zuletzt definierten DMA-Buffer kopieren. Falls ein Lesefehler  
-auftritt, sollte das BIOS den Diskzugriff ein paar Mal wiederholen und, falls  
-der Fehler bestehen bleibt, den Fehlercode 1 im A-Register zurückgeben. 
- 
-Die **WRITE**-Funktion schreibt einen (logischen) Sektor vom DMA-Buffer auf die  
-Diskette. Die Disknummer, Spurnummer und Sektornummer sind jeweils durch die  
-letzten SELDSK-, SETTRK- und SETSEC-Aufrufe festgelegt. 
- 
-Bei physikalischen Sektorlängen von mehr als 128 Bytes kann das Record-Flag zur  
-Realisierung eines 'Blocking'-Algorithmus verwendet werden. Bei einem normalen  
-Schreibzugriff reicht es, den logischen Sektor nur in den BIOS-internen  
-Sektorbuffer zu übernehmen. Dies hat den Vorteil, daß nachfolgende  
-Schreibzugriffe auf den selben physikalischen Sektor keinen Diskettenzugriff  
-verlangen. Erst wenn der neue logische Sektor in einem anderen physikalsichen  
-Sektor liegt, muß der Sektorbuffer auf die Diskette geschrieben werden.  
-Directory-Schreibzugriffe sollten immer direkt auf die Diskette geleitet werden. 
- 
-Je nach Laufwerkstyp (Diskette, RAM-Floppy etc.) können Read und Write völlig unterschiedlich 
-implementiert sein. Die BIOS-Routinen READ und WRITE müssen in diesem Fall je nach Laufwerk DISKNO 
-auf spezielle Routinen READx und WRITEx verzweigen. 
- 
-Ganz einfache Routinen: 
-<code> 
-; 
-READ: CALL calcadr 
- read log. Sektor nach (DMAAD) 
- ld a,0 ; keine Fehler 
- ret 
-; 
-WRITE: CALL calcadr 
- schreibe log. Sektor von (DMAAD) 
- ld a,0 ; keine Fehler 
- ret 
-; 
-calcadr: ..aus log. Track TRACK und log. Sektor SECTOR  
-   die physikalische Position berechnen 
- ret 
-</code> 
- 
-Es verbleiben die RAM-Speicherbereiche, die nicht vorbelegt sind und deshalb am  
-Ende des BIOS stehen sollten, damit das BIOS in den Systemspuren nicht zu groß wird. 
- 
-<code> 
-; the remainder of the CBIOS is reserved uninitialized 
-; data area, and does not need to be a part of the 
-; system memory image (the space must be available, 
-; however, between "begdat" and "enddat"). 
-; 
-TRACK: DS 2 ;two bytes for expansion 
-SECTOR: DS 2 ;two bytes for expansion 
-DMAAD: DS 2 ;direct memory address 
-DISKNO: DS 1 ;disk number 0-15 
-; 
-; scratch ram area for BDOS use 
-DIRBF: DS 128 ;scratch directory area 
-ALL00: DS xx ;allocation vector 0 
-ALL01: DS xx ;allocation vector 1 
-ALL02: DS xx ;allocation vector 2 
-ALL03: DS xx ;allocation vector 3 
-CHK00: DS xx ;check vector 0 
-CHK01: DS xx ;check vector 1 
-CHK02: DS xx ;check vector 2 
-CHK03: DS xx ;check vector 3 
- 
-BUFFER: DS xxK ;Puffer für physischen Sektor 
-; 
- END 
-</code> 
- 
- 
-===== Der Disk Parameter Block ===== 
- 
- 
-Ein DPB umfasst 15 Bytes in folgender Aufteilung:  
-<ditaa> 
-+----------------------------------------------------------+ 
-| SPT | BSH | BLM | EXM | DSM | DRM| AL0 | AL1 | CKS | OFF | 
-+----------------------------------------------------------+ 
-  0/1               5/  7/   9       B/  D/E   
-   16                16    16    8        16    16 
-</ditaa> 
- 
-Beschreibung s.a. [[:intern:systemdoku#der_disk_parameter_block]] 
- 
-Zur Erstellung eines DPB brauch man folgende Angaben: 
- 
-  - Gesamtkapazität der Diskette in KByte 
-  - physischer Aufbau der Diskette 
-   - Anzahl der Spuren (Tracks) 
-   - Anzahl physischer Sektoren pro Spur 
-   - anzahl sd 
-     
-... 
- 
-; 
-DPBLK: ;disk parameter block, common to all disks 
- DW 26 ;sectors per track 
- DB 3 ;block shift factor 
- DB 7 ;block mask 
- DB 0 ;null mask 
- DW 242 ;disk size-1 
- DW 63 ;directory max 
- DB 192 ;alloc 0 
- DB 0 ;alloc 1 
- DW 16 ;check size 
- DW 2 ;track offset 
-; 
-; end of fixed tables 
  
  • cpm/write_a_bios.1331117503.txt.gz
  • Zuletzt geändert: 2012/03/07 10:51
  • von volkerp