print " *** BOOTSEC .MAX ***" ; ; *********** CP/M 2.2 Boot-Sector ************ ; * * ; * modifiziert f}r 8 Bit Druckerschnittstelle * ; * Andreas Dobbertin 23.01.1987 * ; * * ; * modifiziert f}r DOBBERTIN RAM-Erweiterung * ; * Andreas Dobbertin 01.02.1989 * ; * * ; * Spezial-Version f}r PC International * ; * Andreas Dobbertin 13.02.1989 * ; * * ; ********************************************** ; ; ; ------ >>> BIOS-Jumpblock ins RAM kopieren <<< --- ; bootsec push bc ;Zeiger auf original BIOS pop hl ; Sprungvector -> 'HL' ld de,#2500 ;Den original BIOS-Sprung- ld bc,#0033 ; Vector nach #2500-#2532 ldir ; kopieren ; ; ------ >>> Track #00 & Track #01 lesen <<< ------- ; ; Die beiden Systemspuren Track #00 & #01 werden ein- ; gelesen. Der Speicher soll folgenderma~en belegt ; werden; ; ; #0100 - #02FF Bootsector ( Loader ) ; #0300 - #04FF Configuration Sector ; #0500 - #07FF Speicher Initialisierung ; #0800 - #0A7F FAST-Routinen (wird -> #4800 kopiert) ; #0A80 - #0D7F Neue BIOS-Routinen ; #0D80 - #0EFF Initialisierungswerte f}r COMMON BANK ; #0F00 - #16F1 CCP ; #1700 - #24EE BDOS ; #2500 - #2532 original BIOS Sprungvector ; #2533 - #3EFF *** ungenutzt *** ; #3F00 - #3F3B 60 Byte System-Stack ; #3F3C - #3F77 60 Byte Interrupt-Stack ; #3F78 - #3F7C *** ungenutzt *** ; #3F7D BIOS DMA-Banknummer ; #3F7E - #3F7F BIOS DMA-Adresse ; #3F80 - #3FFF DMA-Puffer ; #4000 - #47FF RAM Zeichensatz f}r FAST-Routinen ; #4800 - #4A7F FAST-Routinen f}r Mode 0, 1 und 2 ; ; Die COMMON-BANK belegt den Bereich von #FD00 - #FFFF ; in der TPA Bank und ist folgenderma~en belegt; ; ; #FD00 - #FD35 neuer (erweiterter) BIOS Sprungvector ; #FD36 - #FD8C Bankumschaltender BIOS Sprungvector ; #FD8D - #FDFF Banking Routinen ; #FE00 - #FE0F DPH Drive A ; #FE10 - #FE1F DPH Drive B ; #FE20 - #FE2F DPH Drive C ( reserviert ) ; #FE30 - #FE3F DPH Drive D ( reserviert ) ; #FE40 - #FE4E DPB Drive A ; #FE4F *** ungenutzt *** ; #FE50 - #FE5E DPB Drive B ; #FE5F *** ungenutzt *** ; #FE60 - #FE6E DPB Drive C ( reserviert ) ; #FE6F *** ungenutzt *** ; #FE70 - #FE7E DPB Drive D ( reserviert ) ; #FE7F *** ungenutzt *** ; #FE80 - #FE9F ALV Drive A ; #FEA0 - #FEBF ALV Drive B ; #FEC0 - #FEDF ALV Drive C ( reserviert ) ; #FEE0 - #FEFF ALV Drive D ( reserviert ) ; #FF00 - #FF1F CSV Drive A ; #FF20 - #FF3F CSV Drive B ; #FF40 - #FF5F CSV Drive C ( reserviert ) ; #FF60 - #FF7F CSV Drive D ( reserviert ) ; #FF80 - #FF9F 128 Byte Record Buffer ; ld a,15 ;Das 15. Byte des DPB's call readdpb ; ( Sectoroffset ) -> 'A' and %01000000 ;#00 oder #40 -> 'A' or %00000010 ;Sector #02 oder #42 ld c,a ;Sector-Nr. -> 'C' ; ld de,#0000 ;Track 0, Drive A ld hl,#0300 ;Puffer-Adr. = #0300 ; ld b,17 ;17 Sectoren einlesen nextsec call #be89 ;Sector einlesen jr nc,readerr ;Springe bei Readerror ld a,c ;Sector-Nr. -> 'A' and %00111111 ;Absolute Sectornr. -> 'A' cp #09 ;Trackende erreicht ? jr c,sametrk ;Nein, dann springe ld a,c ;Sectornr. -> 'A' and %01000000 ;#00 oder #40 -> 'A' ld c,a ;#00 oder #40 -> 'C' inc d ;Tracknr. erh|hen sametrk inc c ;Sectornr. erh|hen inc h ;Pufferadresse um inc h ; 512 erh|hen djnz nextsec ; call raminit ;RAM initialisieren call fast_on ;Fast-Routine aktivieren call patchpr ;8. Drucker-Bit aktivieren newboot call config ;Configuration auswerten jp newwarm ;Warmstart ausf}hren ; ; ------ >>> Fehlermeldung ausgeben <<< ------------ ; readerr call prtext ;Fehlermeldung ausgeben ; defb #0a,#0d defm "Failed to lo" defm "ad CP/M$" ; jr $ ;Jump forever ; ; ------ >>> Patchroutine nach #BE22 - #BE3F <<< --- ; patchpr ld hl,prpatch ld de,#be22 ld bc,30 ldir ; ; ------ >>> Rechnerabh{ngige Adressen {ndern <<< -- ; ld a,(#bd32) ;CPC 464 'JP #0808' inc a ;CPC 664 'JP #0835' ld (#be3e),a ;CPC 6128 'JP #0845' ; ld a,(#bd2f) ;CPC 464 'CALL #081B' ld (#be26),a ;CPC 664 'CALL #0848' ; CPC 6128 'CALL #0858' ; ; ------ >>> Vektor und Indirection patchen <<< ---- ; ld hl,#be22 ld (#bdf2),hl ld hl,#be31 ld (#bd32),hl ld a,#ef ;= RST 5 ld (#bd31),a ret ; ; ------ >>> Druckerpatch f}r 8. Bit <<< ----------- ; prpatch ld bc,#0032 pr_wait call #081b ;Adr. wird evtl. gepatched jr nc,sendchr djnz pr_wait dec c jr nz,pr_wait or a ;Carry-Flag l|schen ret ; sendchr push bc ld bc,#f600 ;PIO Port-C bit 7,a ;8. Bit gesetzt ? jr z,resbit8 ;Nein, dann springe ld c,%00100000 resbit8 out (c),c ;8. Bit setzen/r}cksetzen jp #0808 ;Adr. wird evtl. gepatched ; ; ------ >>> Parametersector auswerten <<< --------- ; config call prtext ;Mode 2 einschalten ; defb #04,#02,"$" ; ; ------ >>> Configuration Sector }berpr}fen <<< --- ; ld a,(#0301) ;Ist das zweite Byte des cp #12 ; Config.-Sectors #12 ? jr z,goodsec ; ; ------ >>> Falscher Configuration Sector <<< ----- ; call prtext ; defb #0d,#0a defm "Illegal conf" defm "iguration se" defm "ctor" defb #0d,#0a,#0a,"$" ; ret ; ; ------ >>> Zeichensatz ausw{hlen <<< ------------- ; goodsec ld a,(#0317) ;Zeichensatz-Flag holen ld c,a ;Zeichensatz-Flag -> 'C' call setchar ;Zeichensatz ausw{hlen ; ; ------ >>> Drive-Parameter setzen <<< ------------ ; ld hl,(#0302) ;'MOTOR_ON'-Delay holen ld (drvetab),hl ld hl,(#0304) ;'MOTOR_OFF'-Delay ld (drvetab+2),hl ld a,(#0306) ;'STEP_RATE' ld (drvetab+6),a ld hl,drvetab ;'HL' zeigt auf Tabelle call #be83 ;= DOS-Befehl '82' ; ; ------ >>> CP/M IO-Byte setzen <<< --------------- ; ld a,(#0307) ;IO-Byte holen und in ld (#0003),a ; #0003 ablegen ; ; ------ >>> Error-Message ON/OFF setzen <<< ------- ; ld a,(#0308) ;ON/OFF (#00/#FF) holen call #be80 ;= DOS-Befehl '81' ; ; ------ >>> Ser. Interface initialisieren <<< ----- ; ld hl,#030a ;'HL' zeigt auf SIO-Table call #bea1 ;Z80-SIO initialisieren ; ; ------ >>> Einschaltstring ausgeben <<< ---------- ; ld hl,#0364 ;'HL' zeigt auf Text call prtext2 ;Einschalttext ausgeben call prtext ; defm #0a,#0d defm "v 1.2, " defm "63K TPA" defm #0a,#0d,"$" ; ; ------ >>> Drucker String senden <<< ------------- ; ld a,(hl) ;L{nge des Printerstrings inc hl ; holen. Ist ein Printer- or a ; string vorhanden ? jr z,noprter ;Nein, dann }berspringen ; ld b,a ;'B' ist Schleifenz{hler sendprt ld c,(hl) ;Ein Zeichen holen inc hl ;Zeiger erh|hen push hl push bc call #250f ;Zeichen zum Drucker pop bc pop hl djnz sendprt ;Weiter bis alle Zeichen ; gesendet sind ; ; ------ >>> Tastatur umdefinieren <<< ------------- ; noprter ex de,hl ;Zeiger -> 'DE' ld hl,#bb27 ;Adresse 'KM_SET_NORMAL' call defkeys ;Eventuell neu definieren ld hl,#bb2d ;Adresse 'KM_SET_SHIFT' call defkeys ;Eventuell neu definieren ld hl,#bb33 ;Adresse 'KM_SET_CONTROL' call defkeys ;Eventuell neu definieren ex de,hl ;Zeiger -> 'HL' ; ; ------ >>> Expansionsstrings setzen <<< ---------- ; ld a,(hl) ;Anzahl holen inc hl ;Zeiger erh|hen or a ;Anzahl = 0 ? jr z,no_exp ;Ja, dann springe ; ld d,a set_exp ld b,(hl) ;Expansions Token -> 'B' inc hl ;Zeiger erh|hen. ld c,(hl) ;L{nge des Strings -> 'C' inc hl ;Zeiger erh|hen push hl push de push bc call #bb0f ;KM_SET_EXPANSION string pop bc pop de pop hl jr c,noexper ;Springe wenn fehlerfrei ; ; ------ >>> Fehlermeldung ausgeben <<< ------------ ; call prtext ; defb #0d,#0a defm "Expansion bu" defm "ffer full or" defm " illegal tok" defm "en specified" defb #0d,#0a,#0a,"$" ; ret ; ; ------ >>> SET_EXPANSION Fortsetzung <<< --------- ; noexper ld b,#00 ;Zeiger um die L{nge des add hl,bc ; letzten Strings erh|hen dec d ;War's der letzte String ? jr nz,set_exp ;Nein, dann noch einen ; ; ------ >>> Initial Command ausf}hren <<< --------- ; no_exp ld a,(#0316) jp #bea4 ; ; ------ >>> Tabelle der Laufwerksparameter <<< ---- ; drvetab defw #0000 ;F}r 'MOTOR_ON' -Delay defw #0000 ;F}r 'MOTOR_OFF'-Delay defb #af ;Wartezeit bei Format defw #001e ;F}r 'STEP_RATE' defb #01 ;'HEAD_LOAD' -Time defb #03 ;'HEAD_UNLOAD'-Time ; ; ------ >>> Tastatur definieren Unterprgr. <<< ---- ; defkeys ld a,(de) ;Anzahl der neu zu defi- ld c,a ; nierenden Tasten nach inc de ; 'C' bringen or a ;Anzahl = 0 ? ret z ;Ja, dann zur}ck ; set_key ld a,(de) ;Neuen Tastenwert holen ld b,a ; und nach 'B' bringen inc de ;Zeiger erh|hen ld a,(de) ;Tastennummer nach 'A' inc de ;Zeiger erh|hen push hl ;Sprungadresse merken call jp_tohl ;Taste neu definieren pop hl ;Sprungadresse holen dec c ;War's die letzte Taste ? jr nz,set_key ;Nein, dann noch eine ret ; ; ------ >>> Text ( ab RET-Adr. ) ausgeben <<< ----- ; prtext ex (sp),hl ;RET-Adresse -> 'HL' call prtext2 ;Text ausgeben ex (sp),hl ret ; ; ------ >>> Text ( ab 'HL' ) ausgeben <<< --------- ; prtext2 ld a,(hl) ;Ein Zeichen holen inc hl ;Zeiger erh|hen cp "$" ;End of Text ? ret z ;Ja, dann zur}ck ld c,a ;Sonst Zeichen -> 'C' push hl call #250c ;Zeichen ausgeben pop hl jr prtext2 ; ; ------ >>> Springe zu 'HL' <<< ------------------- ; jp_tohl jp (hl) ; ; ------ >>> Lade 'HL' aus 'HL' und 'HL'+1 <<< ----- ; ld_hlhl ld a,(hl) ;LD HL,(HL) inc hl ld h,(hl) ld l,a ret ; ; ------ >>> 'A'-ter Eintrag des DPB -> 'A' <<< ---- ; readdpb ld hl,(#be40) ;Adr. DPH Drive A -> 'HL' ld de,#000a ;Offset f}r Drive A add hl,de ;Offset addieren ld e,a ;DPB-Offset -> 'DE' call ld_hlhl ;Start DPB -> 'HL' add hl,de ;DPB-Offset addieren ld a,(hl) ;Gew}nschtes Byte -> 'A' ret