print " *** NEWBIOS .MAX ***" ; ; ********** Erweiterte BIOS-Routinen ********** ; * * ; * Andreas Dobbertin 01.02.1989 * ; * * ; * Spezial-Version f}r PC International * ; * Andreas Dobbertin 13.02.1989 * ; * * ; ********************************************** ; ; ; ------ >>> Neue Warmstart-Routine <<< ------------ ; newwarm ld de,(#0f01) ;Die Ziel-Adresse des ld hl,-860 ; CCP in der TPA add hl,de ; errechnen ex de,hl ;CCP-Zieladresse -> 'DE' ld hl,#0f00 ;Start CCP -> 'HL' ld bc,#2c80 ;44 * 80 Byte kopieren cpyloop push bc ;Z{hler/Blockgr|~e merken call copy_c ;128 Byte kopieren pop bc ;Z{hler -> 'B', #80 -> 'C' djnz cpyloop ;N{chsten Block kopieren ; ld c,#33+3 ;Den 51+3 Byte langen ld hl,#0d80 ; BIOS-Sprungvector hinter call copy_c ; das BDOS kopieren ; di ld bc,#7fc4 ;Die ersten 16K der TPA out (c),c ; ab #4000 einblenden ld a,#c3 ;OP-Code f}r 'JP' -> 'A' ld hl,-51 ;Warmstarteinsprungadresse add hl,de ; errechnen; -> 'HL' ld (#4000),a ld (#4001),hl ld hl,-3632 ;BDOS-Einsprungadresse add hl,de ; errechnen; -> 'HL' ld (#4005),a ld (#4006),hl ld hl,intntry ;Interrupt-Entry -> 'HL' ld (#4038),a ld (#4039),hl ld hl,(#0003) ;IO-Byte & Drive/User ld (#4003),hl ; in die TPA Zero-Page ld c,h ;Drive/User f}r CCP -> 'C' ld hl,-5686 ;CCP-Einsprungadresse add hl,de ; errechnen; -> 'HL' call rom_off ;COMMON-Bank einschalten jp jumpccp ;Den CCP anspringen ; ; ------ >>> 'C' Byte in die TPA kopieren <<< ------ ; copy_c di ld a,d and %11000000 ;Bit 6 & 7 der Ziel-Adr. push af ; maskieren und merken rlca ;Bit 6 & 7 selektieren den rlca ; 16K Block der TPA-Bank or %11000100 ;Banking-Bits dazu ld b,#7f ; und die entsprechende out (c),a ; Bank ab #4000 einblenden res 7,d ;Die Ziel-Adresse in den set 6,d ; Bereich von #4000-#7FFF ld b,#00 ; bringen und 'C' Byte ldir ; verschieben ld bc,#7fc0 ;Die ersten 64K wieder out (c),c ; komplett einschalten pop af ;Bit 6 & 7 der Ziel-Adr. add a,d ; holen und wieder in die sub #40 ; Quell-Adresse einbauen ld d,a ei ret ; ; ------ >>> Interrupt Einsprung <<< --------------- ; new_int call rom_on ;DOS-ROM einschalten rst #38 ;Interrupt ausf}hren jr rom_off ;COMMON-Bank einschalten ; ; ------ >>> BIOS Einsprung <<< -------------------- ; newbios ld (#0003),hl ;I/O-Byte & Drive setzen ld (callsys+1),de call rom_on ;Das DOS-ROM einschalten callsys call $-$ ;Gew. Routine aufrufen ; ; ------ >>> Oberes ROM ausschalten <<< ------------ ; rom_off di exx ;Zweit-Registersatz ein ld bc,(ga_adr) ;Gate-Array Status -> 'BC' set 3,c ;Oberes ROM abschalten out (c),c ;Neuen Status setzen ld (ga_adr),bc ; und merken ld c,#c1 ;Die COMMON-Bank ab out (c),c ; #C000 einschalten ld c,#c2 ret ; ; ------ >>> Oberes ROM einschalten <<< ------------ ; rom_on ld c,#c0 ;Die ersten 64K komplett out (c),c ; einschalten ld bc,(ga_adr) ;Gate-Array Status -> 'BC' res 3,c ;Oberes ROM einschalten out (c),c ;Neuen Status setzen ld (ga_adr),bc ; und merken exx ;Haupt-Registersatz ein ret ; ; ------ >>> Drive w{hlen <<< ---------------------- ; newsdsk push bc push de call #251b ;BIOS SELDSK pop de pop bc ld a,h or l jr nz,gooddrv ; di push bc ld bc,#7fc4 ;Die ersten 16K der TPA out (c),c ; ab #4000 einblenden ld (#4004),a ;Drive A anw{hlen pop bc ret ; gooddrv push bc ld a,e rrca call nc,copydpb pop bc ld a,c ld hl,dph_a or a ret z ld hl,dph_b dec a ret z ld hl,dpb_c dec a ret z ld hl,dph_d ret ; copydpb ld de,#000a add hl,de call ld_hlhl ld a,c ld de,dpb_a or a jr z,movedpb ld de,dpb_b dec a jr z,movedpb ld de,dpb_c dec a jr z,movedpb ld de,dpb_d movedpb di ld bc,#7fc1 out (c),c ld bc,#000f ldir ld bc,#7fc0 out (c),c ei ret ; ; ------ >>> Pufferadresse ausw{hlen <<< ----------- ; newsdma ld a,b rlca rlca and %00000011 or %11000100 ld (dmabnk),a res 7,b set 6,b ld (dmaadr),bc ld bc,dmabuf jp #2524 ;BIOS SETDMA ; ; ------ >>> 128 Byte Record lesen <<< ------------- ; newread call #2527 ;BIOS READ ; ; ------ >>> Record in die TPA kopieren <<< -------- ; copyrec di ld bc,(dmabnk) ;TPA Ziel-Banknr. -> 'C' ld b,#7f out (c),c ;TPA Ziel-Bank einschalten ld de,(dmaadr) ;Ziel-Adresse -> 'DE' ld hl,#807f ;Pr}fen, ob der Record die add hl,de ; Bankgrenze }berschreitet jr c,spec_rd ;Ja, dann Spezial-Routine ld hl,dmabuf ;Quell-Adresse -> 'HL' ld bc,#0080 ;Record-L{nge = 128 Byte ldir ;Record in TPA kopieren ld bc,#7fc0 ;Die ersten 64K wieder out (c),c ; komplett einschalten ret ;That's it ; spec_rd inc hl ;'HL' auf Restl{nge push hl ; erh|hen und merken push bc ;1. Ziel-Banknr. merken ld hl,#8001 ;Byte-Anzahl bis zum sbc hl,de ; Ende der ersten Bank ld b,h ; errechnen ld c,l ;Ergebnis -> 'BC' ld hl,dmabuf ;Quell-Adresse -> 'HL' ldir ;1. Teil in TPA kopieren pop bc ;1. Ziel-Banknr. -> 'C' inc c ;Auf 2. Banknr. erh|hen out (c),c ;2. Ziel-Bank einschalten pop bc ;Record-Restl{nge -> 'BC' ld d,#40 ;#4000 -> 'DE' ldir ;Rest in die TPA kopieren ld bc,#7fc0 ;Die ersten 64K wieder out (c),c ; komplett einschalten ret ;Game over ; ; ------ >>> 128 Byte Record schreiben <<< --------- ; newwrte di push bc ;BDOS Write-Flag merken ld bc,(dmabnk) ;TPA Quell-Banknr. -> 'C' ld b,#7f out (c),c ;Quell-Bank einschalten ld de,(dmaadr) ;Quell-Adresse -> 'DE' ld hl,#807f ;Pr}fen, ob der Record die add hl,de ; Bankgrenze }berschreitet jr c,spec_wr ;Ja, dann Spezial-Routine ex de,hl ;Quell-Adresse -> 'HL' ld de,dmabuf ;Ziel-Adresse -> 'DE' ld bc,#0080 ;Record-L{nge = 128 Byte jr mov2dma ;Record in den DMA-Puffer ; spec_wr inc hl ;'HL' auf Restl{nge push hl ; erh|hen und merken push bc ;1. Quell-Banknr. merken ld hl,#8001 ;Byte-Anzahl bis zum sbc hl,de ; Ende der ersten Bank ld b,h ; errechnen ld c,l ;Ergebnis -> 'BC' ex de,hl ;Quell-Adresse -> 'HL' ld de,dmabuf ;Ziel-Adresse -> 'DE' ldir ;1. Teil in den DMA-Puffer pop bc ;1. Quell-Banknr. -> 'C' inc c ;Auf 2. Banknr. erh|hen out (c),c ;2. Quell-Bank einschalten pop bc ;Record-Restl{nge -> 'BC' ld h,#40 ;#4000 -> 'HL' mov2dma ldir ;Rest in den DMA-Puffer ; ld bc,#7fc0 ;Die ersten 64K wieder out (c),c ; komplett einschalten pop bc ;BDOS Write-Flag -> 'C' jp #252a ;BIOS WRITE ; ; Die folgenden Routinen sind zum Teil identisch mit ; den Original BIOS-Routinen. Sie ersetzen in erster ; Linie die Drucker-Ausgabe, da bei DDOS, X-DDOS, VDOS ; und X-VDOS in der Drucker-Routine unter Umst{nden ; ein Sprung in die ROM-interne Warmstart-Routine ; erfolgen kann. ; ; ; ------ >>> CP/M Interrupt-Entry <<< -------------- ; cpm_int call biosent defw #0038 ; ; ------ >>> CP/M BIOS Entry <<< ------------------- ; ; Diese Routine bringt den Speicher in einen BASIC ; {hnlichen Zustand f}r die Interrupt- und BIOS- ; Routinen im DOS-ROM. ; biosent di ex af,af' exx ex (sp),hl ld (holdsp+1),sp ld sp,#c000 push af push bc push de push iy ld bc,(ga_adr) or a call go_bios di ex af,af' exx ld (ga_adr),bc ld hl,cpm_int ld (#0039),hl pop iy pop de pop bc pop af holdsp ld sp,$-$ pop hl exx ex af,af' ei ret go_bios ld iy,mempool ;Memory-Pool Ptr -> 'IY' ld e,(hl) inc hl ld d,(hl) ;Adresse der Routine push de ; auf den Stapel ld hl,(origint);Original Interrupt-Entry ld (#0039),hl ; hinter den 'JP' bei #38 exx ex af,af' ei ret ; ; ------ >>> IO-Byte Tabelle f}r CONOUT <<< -------- ; con_out defb #01 defw #beb0 ;WRITE_TXA defw sendcrt defw newprou defw #bebc ;WRITE_TXB ; ; ------ >>> IO-Byte Tabelle f}r LIST <<< ---------- ; prt_out defb #03 defw #beb0 ;WRITE_TXA defw sendcrt defw printer defw #bebc ;WRITE_TXB ; ; ------ >>> Druckerausgabe }ber IO-Byte <<< ------- ; newlist ld hl,prt_out jr use_iob ; ; ------ >>> Console schreiben }ber IO-Byte <<< ---- ; newcono ld hl,con_out use_iob call biosent defw useiob1 ; ; ------ >>> Printer Output }ber IO-Byte <<< ------- ; newprou ld hl,prt_out ; ; ------ >>> Sprungadr. }ber IO-Byte ermitteln <<< -- ; ; useiob1 ld b,(hl) ;Bit-Nr. als Z{hler -> 'B' inc hl ld a,(#0003) ;I/O-Byte -> 'A' useiob2 rlca ;I/O-Bits nach Bit 1 & 2 djnz useiob2 ; des Akku bringen ; and %00000110 ;Tabellen-Offset ermitteln ld d,#00 ld e,a add hl,de ;Zu Tabellenstart addieren ld e,(hl) inc hl ld d,(hl) ex de,hl ;Zieladresse -> 'HL' jp (hl) ; ; ------ >>> Zeichen zum Drucker schicken <<< ------ ; printer ld a,c ;Zeichen -> 'A' call #bd2b ;Zeichen zum Drucker ret c ;RET wenn alles OK ; push bc ;Zeichen merken call #bb09 ;Ist eine Taste verf}gbar? pop bc ;Zeichen -> 'C' jr nc,printer ;Nein, dann springe cp #03 ;Ist es CTRL-C ? jr nz,printer ;Nein, dann springe ; ld hl,ctrltxt ;Sonst '...^C' ausgeben prctrlc ld a,(hl) inc hl cp "$" ;Den Text ausgeben und jr z,ctrl_c ; Warmstart ausf}hren push hl call #bb5a ;Zeichen ausgeben pop hl jr prctrlc ; ctrl_c di ld sp,sysstck ld hl,cpm_int ;Den CP/M Interrupt-Entry ld (#0039),hl ; wieder restaurieren und jp newwarm ; den Warmstart ausf}hren ; ctrltxt defm "...^C$" ; ; ------ >>> System-Variablen <<< ------------------ ; ramflg defb #00 ;<> #00 => RAM-Disc aktiv ; dmabnk equ #3f7d ;DMA Banknummer dmaadr equ #3f7e ;DMA Zieladresse ; dmabuf equ #3f80 ;128 Byte DMA Puffer ; intstck equ #bf00 ;Ende+1 Interrupt Stack sysstck equ #bf80 ;Ende+1 System Stack