.z80 ;================================================================ ;CP/M 2.2 f}r vortex-Speichererweiterung - gebankter Bios-Teil ;Datei OSC4BANK.MAC Version 29-Jan-89 ;Includes: OSC4CONS.MAC OSC4TERM.MAC OSC4TIME.MAC OSC4CHAR.MAC ;Urversion erzeugt mit Hilfe von DISZ80.COM aus $OSC.SYS ; + arbeitet unabh{ngig vom CP/M-ROM ; + Indirections f}r zwei Zusatz-Ein/Ausgabeger{te ; + Schnellere Bankumschaltung ; + Warmstart mit BDOS-Kopie im RAM ; + statt Spooler wahlweise gr|~ere RamDisk ; + Spooler repariert ; + schnellere Interruptroutine ; + schnellere Bankumschaltung ; + bei Spooler-Umschaltung gehen keine Daten verloren ; + 8. Druckerbit ; + wahlweise blinkender Cursor ; + SHIFT-CTRL-ESC f}hrt zu Breakpoint bzw. Warmstart ; + $$$.SUB ohne Diskzugriff von RamDisk gelesen ; + wahlweise Auto-Start beim ersten/allen Warmstart ; + auf Wunsch Uhrzeit auf dem Bildschirm ; + VT52-Simulation (nur die wichtigsten Routinen, fuer WS 3.0 + Turbo) ; + schnelle Bildschirmausgabe + zus{tzliche Video-Attribute ; + von A200h bis B0FFh zusammenh{ngend freier Speicher ; + Initial Comand Buffer ; + vertraegt sich mit Dobbertin-Speichererweiterung public chargr,charus,cwrite,matrix ;aus OSC4CHAR.MAC public esctst,clrelp,lfp,newlf ;aus OSC4TERM.MAC public paper,pen,turn,setvid public shtime,stclck,gotime ;aus OSC4TIME.MAC public kbreak,klevnt,ibreak,xbreak ;neue KM_BREAK-Routine public nkmw,nkmr,kmread public printw ;Wartezeit bis Printer-Timeout auftritt public bankst,banken public ccpanf,quelle,spdis,ccpcom public motevn,motswt,LBE44,LBE46 public CurBlk,ConTic,CurSpd,mcsend,mcwait,UhrCnt,UhrEvt,UhrTic,UhrAtt public L8142 ;0FFh -> Spooler ein bei Boot public L815A ;Spooler-Tickerroutine public L81CB ;Controlblock Spooler-Ticker public RamIni ;Ram-Konfiguration feststellen, RamDisk initialisieren public L856C ;enth{lt 1 Bit f}r jede Speicherbank public autobuf,autoclr public FrmGate extrn dosanf,dosend extrn X_Move,X_Retn,X_Firm,X_Halt,X_Cons,X_Time,X_Buff .XLIST include OSC4CONS.MAC .LIST bankst: .PHASE Sys_BnkBios jp bankswitch jp reset ;BOOT hat jetzt die Funktionsnummer 1 ! L8052: jp ConISt L8055: jp ConInp jp ConOut LOut: jp LstOut jp AuxOut AInp: jp AuxInp RS1IST: jp NULIST RS1INP: jp NULINP RS1OST: jp NULOST RS1OUT: jp NULOUT RS2IST: jp NULIST RS2INP: jp NULINP RS2OST: jp NULOST LSta: jp LstOSt RS2OUT: jp NULOUT JP DD_ON_MOTOR JP DD_TIMEOFF_MOTO JP RAMDISK_RW JP DD_OFF_MOTOR JP Automatic_Keys JP Reload_Bdos JP DISP_MESSAGE_JN JP DISP_MESSAGE JP SPOOL_LIST JP SPOOL_LISTST JP SPOOL_SWITCH JP Console_Input ;DISP_VERSION JP FIRMWARE_CALL JP Reader_Input ;WAIT_SYSTEMDISK JP RAMDISK_FORMAT bankswitch: LD (L85C8),SP ;Eingabe: Routinenadresse in DE LD SP,Sys_FirmStack;Parameter: in AF', BC', DE', HL' call ExecJ ;Gate-Array: in BC DI EX AF,AF' ;Ergebnis nach '-Register EXX ;(jetzt Hi-ROM bereits ausgeschaltet) ld (FrmGate),bc ;Gate-Array-Zustand merken ld c,0E0h ;Ram-Expansion einblenden in 8000-FFFF LD SP,(L85C8) JP X_Retn ExecJ: PUSH de ;als RET-Adresse auf Stapel ld bc,(FrmGate) ;Gate-Array-Zustand restaurieren OR A ;kein pending Interrupt EX AF,AF' ;Eingabeparameter restaurieren EXX EI ;Fortsetzung ohne Probleme RET ;****** Zeichenorientierte Ein/Ausgaberoutinen ConISt: ld a,(Cpm_Devices) and 03h cp 1 jp z,KBDIST cp 0 jp z,RS1IST cp 3 jp z,RS2IST ld a,(Cpm_Devices) ;Batch-Eingabestatus (AuxISt) and 0Ch cp 0 jp z,RS1IST cp 8 jp z,RS2IST cp 0Ch jp z,KBDIST NULIST: NULOST: ld a,0FFH ret ConInp: ld a,(Cpm_Devices) and 03h cp 1 jp z,KBDINP cp 0 jp z,RS1INP cp 3 jp z,RS2INP AuxInp: ld a,(Cpm_Devices) and 0Ch cp 0 jp z,RS1INP cp 8 jp z,RS2INP cp 0Ch jp z,KBDINP NULINP: ld a,1Ah ret ConOut: ld a,(Cpm_Devices) and 03h cp 1 jp z,CRTOUT cp 0 jp z,RS1OUT cp 3 jp z,RS2OUT LstOut: ld a,(Cpm_Devices) and 0C0h cp 80h jp z,LPTOUT cp 0 jp z,RS1OUT cp 0C0h jp z,RS2OUT jp CRTOUT AuxOut: ld a,(Cpm_Devices) and 30h cp 0 jp z,RS1OUT cp 20h jp z,RS2OUT cp 30h jp z,CRTOUT NULOUT: ret LstOst: ld a,(Cpm_Devices) and 0C0h cp 80h jp z,LPTOST cp 0 jp z,RS1OST cp 0C0h jp z,RS2OST jp CRTOST ;****** Druckerausgabe LPTOST: call MC_BUSY_PRINTER ld a,0FFh ret nc xor a ret LPTOUT: ld a,c call MC_PRINT_CHAR jr nc,LPTOUT ret ;****** Bildschirmausgabe CRTOST: ld a,0FFh ret CRTOUT: xor a ld (NoCurs),a ;Cursor sperren ld hl,Blink ld a,(hl) and a ;FFh -> Cursor war eingeschaltet call nz,TXT_CUR_OFF ;Cursor wird unbedingt ausgeschaltet ld (hl),0 ;Cursor jetzt ausgeschaltet ld a,c call TXT_OUTPUT ld a,2 ld (NoCurs),a ;Cursor ver|gert einschalten ret ;****** Konsoleneingabe KBDIST: ld a,(autoclr) and a jr z,KbdSt ;Tastatur hat Vorrang ld a,(autobuf) and a ld a,0 ret nz ;solange Zeichen im Puffer keine R}ckmeldung KbdSt: ld hl,LastK ld a,0FFh cp (hl) ;255 -> es ist noch kein Zeichen gespeichert ret nz ;Zeichen war schon da call KM_READ_CHAR jr c,Charda ;aber jetzt ein Zeichen gefunden (Cur On jetzt zu sp{t) xor a ;bisher noch kein Zeichen ret charda: ld (hl),a ;LD (LastK),A gelesenes Zeichen merken ld a,0FFh ret KBDINP: ld a,(autobuf) and a jr z,KbdIn ld a,(autoclr) and a jr z,auto1 naclr: ld hl,autobuf dec (hl) ld hl,(autopos) ld a,(hl) inc hl ld (autopos),hl ret auto1: call KbdSt and a jr z,naclr xor a ld (autobuf),a KbdIn: ld hl,LastK ld a,(hl) ;potentielles letztes Zeichen ld (hl),0FFh ;jetzt Puffer leer cp (hl) ;war Puffer schon vorher leer? ret nz ;nein -> Zeichen schon da call KM_READ_CHAR ret c ;Zeichen schon im Puffer xor a ld (NoCurs),a ;Cursor sperren ld hl,Blink ld a,(hl) and a ;FFh -> Cursor war eingeschaltet call z,TXT_CUR_ON ;Cursor wird unbedingt eingeschaltet ld (hl),0FFh ;Cursor jetzt eingeschaltet ld a,(CurSpd) ld (NoCurs),a ;Blink-Z{hler setzen jp KM_WAIT_CHAR ;KM_READ_CHAR mit Schleife READER_INPUT: ld a,0FFh ld (X_Cons),a ;Konsole-Interrupt verhindern call AInp ;Reader-Eingabe jr AIst CONSOLE_INPUT: ld a,0FFh ld (X_Cons),a ;Console-Interrupt verhindern call L8055 ;Consoleneingabe AIst: push af call L8052 ;Konsolenstatus ld (X_Cons),a ;Console-Interrupt zulassen pop af ret ;****** Console-Status + Cursor Frame Fly Interrupt ConTic: call KL_L_ROM_DISABL push af ;laut Priority-Byte Routine im zentralen RAM!!! ld a,(X_Cons) ;alter Console-Input Status inc a jr z,CurTic ;Zeichen war schon da ld hl,ConAsc ;nur 25 mal pro Sekunde abfragen ld a,(hl) cpl ld (hl),a and a jr z,CurTic call L8052 ld (X_Cons),a CurTic: pop af call KL_ROM_RESTORE ld hl,NoCurs ;Cursor-Status ld a,(hl) and a ret z ;Cursor blinkt nicht dec (hl) ;Timer abgelaufen? ret nz ld a,(CurSpd) ld (hl),a ;Reload Timer ld hl,Blink ld a,(hl) cpl ld (hl),a ;Cursor-Zustand invertieren and a jp z,TXT_CUR_OFF;Cursor jetzt auszuschalten jp TXT_CUR_ON ;****** Uhrzeit aktualisieren UhrCnt: call KL_L_ROM_DISABL push af ld hl,X_Time+5 ld b,60h call UhrBcd call z,UhrBcd ld b,24h call z,UhrBcd jr nz,NoUhr ld hl,(X_Time) inc hl ld (X_Time),a NoUhr: call gotime ;Uhrzeit anzeigen pop af jp KL_ROM_RESTORE UhrBcd: dec hl ld a,(hl) add a,1 daa ld (hl),a xor b ret nz ld (hl),a ret ;****** CP/M - Keyboard - Buffer initialisieren Automatic_Keys: ld (autoclr),a push hl ld hl,autobuf ld (hl),0 inc hl ld (autopos),hl call SaveDma pop hl ld de,X_Buff call HiCopy ld hl,X_Buff+Drive_RecordLen-1 ld de,autobuf+Drive_RecordLen-1 ld bc,Drive_RecordLen lddr jp RestDma ;****** BDOS nachladen in TPA-Bank. DE := CCP-Anfang Reload_Bdos: call SaveDma ld hl,fboot ld a,(hl) ;erster Warmstart? ld (hl),0 and a jr nz,firstw ld a,(ccpcom) ;jedes Mal Auto-Kommando? and a jr nz,firstw ld (quelle+7),a ;ab 2. Warmstart Auto-Kommando loeschen firstw: ld a,0+(dosend-dosanf)/Drive_RecordLen ;Recordanzahl CCP und BDOS ld hl,quelle ;Quelladresse CCP (Sysbank) ccpanf: ld de,$-$ ;Zieladresse CCP (Runtime) push de loader: push de ;Zieladresse CCP ld de,X_Buff push de ld bc,Drive_RecordLen ldir pop de ;Puffer ex (sp),hl ;POP Zieladresse CCP, PUSH Quelladresse CCP ex de,hl call HiCopy pop hl ;Quelladresse CCP dec a jr nz,loader call RestDma pop de ;CCP-Anfangsadresse ld bc,(FrmGate) ret SaveDma:ld de,L85CA ld hl,X_Buff ld bc,Drive_RecordLen ldir ret RestDma:ld de,X_Buff ld hl,L85CA ld bc,Drive_RecordLen ldir ret SPOOL_SWITCH: LD HL,L83E4 ld (hl),95h ;Spooler aus ld a,(spdis) inc a jr z,nospl ;nicht einschaltbar, wenn gesperrt LD A,(L8142) OR A LD (HL),94H ;Spooler an ld a,0FFh jr z,L80B9 ;anschalten, wenn vorher aus ld bc,(L8140) ld a,b or c jr nz,nospl ;nicht-leerer Spooler nicht abschaltbar ld (hl),95h ;Spooler aus L80B9: LD (L8142),A nospl: LD A,18H CALL DISP_MESSAGE RET ;****** System neu booten (Kaltstart) reset: ld hl,runboot ;System in Urzustand versetzen ld c,0FFh jp MC_START_PROGRA runboot:call KL_ROM_WALK ;alle ROMs einbinden ld hl,CpmName basic: call KL_FIND_COMMAND jp c,KL_FAR_PCHL ;RSX-Befehl CP/M suchen und starten ld hl,failed ;CP/M nicht gefunden jp MC_BOOT_PROGRAM ;Programm laden mit }bergebener Routine failed: and a ;Dummy-Laderoutine ret ;CY := 'Laden fehlgeschlagen' CpmName:db 'CP','M'+80h ;CpmName:defm 'CPM' ;M80 -> auch hier Bit 7 gesetzt??? FIRMWARE_CALL: DI EXX LD HL,(X_Firm) DEC HL DEC HL DEC HL PUSH HL EXX EI RET SPOOL_LIST: LD A,(L8142) OR A JR Z,L812C ld (L84AB),a ;Spooler-Interrupt kurz sperren call L80FD ;Zeichen ausgeben ld a,0 ld (L84AB),a ;Interrupt freigeben ret L80FD: LD HL,(L8140) ;Testen, ob Platz im Spooler BIT 7,H JR Z,L8104 ld a,(X_Cons) ;warten, da~ Spooler frei OR A ; -> ^C ist Abbruch JR Z,L80FD push de CALL CONSOLE_INPUT pop de CP 3 RET Z jr L80FD L8104: ld a,h ;war Spooler leer? (z -> TRUE) or l ;-> dann Interrupt einh{ngen INC HL LD (L8140),HL LD A,C DI EXX PUSH BC SET 5,C OUT (C),C LD HL,(L8143) LD (HL),A INC HL RES 7,H LD (L8143),HL POP BC OUT (C),C EXX ei scf ret nz ;Interrupt ist schon aktiv LD HL,L81C5 LD DE,1 LD BC,1 CALL KL_ADD_TICKER SCF RET L812C: ld a,c CALL MC_PRINT_CHAR RET C call KL_TIME_PLEASE ex de,hl rwait: ld a,c CALL MC_PRINT_CHAR RET C ld a,(X_Cons) ;warten, da~ Drucker bereit OR A ; -> ^C ist Abbruch JR Z,nopbrk push de push bc CALL CONSOLE_INPUT pop bc pop de CP 3 RET Z nopbrk: push bc push de call KL_TIME_PLEASE pop de and a sbc hl,de ld bc,(printw) ;einige Sekunden warten sbc hl,bc pop bc jr c,rwait LD A,0EH CALL DISP_MESSAGE_JN JR NZ,L812C OR A RET SPOOL_LISTST: LD A,(L8142) OR A JP Z,L8154 LD A,(L8140+1) RLCA JR L8157 L8154: CALL MC_BUSY_PRINTER L8157: CCF SBC A,A RET ;Spooler-Ticker-Routine L815A: LD A,(L84AB) ;FFh -> Spooler kurz gesperrt OR A RET NZ CALL MC_BUSY_PRINTER RET C LD HL,(L8140) DEC HL LD (L8140),HL push hl DI EXX PUSH BC SET 5,C SET 2,C OUT (C),C LD HL,(L8145) LD A,(HL) INC HL RES 7,H LD (L8145),HL POP BC OUT (C),C EXX EI call MC_SEND_PRINTER pop hl LD A,H OR L ret nz ;Spooler wurde nicht leer LD HL,L81C5 JP KL_DELETE_TICKE ;****** Diskettenmotoren einschalten mit Wartezeit DD_ON_MOTOR: CALL L81BF ld a,(motflg) and a JR NZ,L81B1 LD BC,Port_Motor LD A,1 OUT (C),A PUSH HL LD DE,(LBE44) CALL L81B6 POP HL L81AD: ld a,(motflg) and a JR Z,L81AD L81B1: RET ;****** Motore abschalten mit Nachlaufen DD_TIMEOFF_MOTO: LD DE,(LBE46) L81B6: LD HL,LBE67 LD BC,0 JP KL_ADD_TICKER L81BF: LD HL,LBE67 JP KL_DELETE_TICKE ;****** Motor Ticker-Routine MotSwt: ld hl,motflg ld a,(hl) and a ;war Motor eingeschalten? jr nz,DD_OFF_MOTOR ld (hl),255 ;Motor jetzt eingeschalten motend: ld hl,lbe67 ;Ticker Block jp KL_DELETE_TICKE ;****** Motor sofort abschalten DD_OFF_MOTOR: call motend xor a ld (motflg),a push bc ld bc,Port_Motor out (c),a pop bc ret L81D2: CALL DISP_MESSAGE L81D8: CALL CONSOLE_INPUT CALL L828F CP 'J' ;4AH JR Z,L81ED CP 'N' ;4EH JR Z,L81EE LD A,7 ld c,a CALL CRTOUT JR L81D8 L81ED: OR A L81EE: jp L8259 DISP_MESSAGE_JN: CALL DISP_MESSAGE LD A,0FH CALL L81D2 LD A,1 JR NZ,L81FF LD A,2 L81FF: CALL DISP_MESSAGE L8202: LD A,0 DISP_MESSAGE: PUSH HL PUSH BC PUSH AF LD HL,L82B7 AND 7FH LD B,A INC B JR L8215 L8210: LD A,(HL) INC HL INC A JR NZ,L8210 L8215: DJNZ L8210 L8217: LD A,(HL) INC HL INC A JP Z,L8229 DEC A PUSH HL PUSH BC PUSH DE CALL L822D POP DE POP BC POP HL JR L8217 L8229: POP AF POP BC POP HL RET L822D: CP 0C1H JR NZ,L8252 LD B,' ' ;20H EX DE,HL LD DE,100 CALL L8243 LD DE,10 CALL L8243 LD A,L JR L824D L8243: XOR A L8244: SBC HL,DE INC A JR NC,L8244 ADD HL,DE DEC A JR Z,L824F L824D: LD B,'0' ;30H L824F: ADD A,B JR L8259 L8252: CP 0C2H JR NZ,L825C LD A,C ADD A,'A' ;41H L8259: JP L8289 L825C: BIT 7,A JR NZ,DISP_MESSAGE PUSH AF CP ' ' ;20H JR NZ,L827C PUSH HL PUSH DE CALL TXT_GET_WINDOW CALL TXT_GET_CURSOR LD A,D SUB 4 CCF JR NC,L8274 CP H L8274: POP DE POP HL JR NC,L827C POP AF JP L8202 L827C: POP AF L8289: push af push bc push hl ld c,a call CRTOUT pop hl pop bc pop af ret L828F: CP 61H RET C CP 7BH RET NC SUB ' ' ;20H RET L82B7: DEFB 0DH,0AH,0FFH ;00 defb 8BH,91H,0FFH ;01 defb 8BH,92H,0FFH ;02 defb 'fehler',0FFH ;03 defb 0C1H,'K',0FFH ;04 defb 90H,'Schreib',83H,0FFH ;05 defb 90H,'Lese',83H,0FFH ;06 defb 8AH,'fehlt',0FFH ;07 defb 8AH,'hat Schreibschutz',0FFH ;08 DEFb 0FFH ;09 defb 90H,93H,0FFH ;0A defb 80H,'Operation wird ',0FFH ;0B DEFB 0FFH ;0C defb 90H,'Formatier',83H,0FFH ;0D defb 80H,'Drucker nicht bereit',0FFH ;0E DEFb ' - Wiederholen J/N ? ',0FFH ;0F defb 80H,'Laufwerk ',0C2H,': ',0FFH ;10 DEFb 'wiederholt',80H,0FFH ;11 DEFb 'abgebrochen',80H,0FFH ;12 DEFb 'Diskette ',0FFH ;13 DEFb 'an ',0FFH ;14 DEFb 'aus ',0FFH ;15 defb 0FFH ;16 DEFb 'nicht ',0FFH ;17 DEFb '- Spooler ' L83E4: DEFB 0,' -',80H,0FFH ;18 ;****** Speicherbank im Register A selektieren L83E9: PUSH AF SET 5,A OUT (C),A POP AF RET ;****** RamDisk schreiben/lesen ;A:= Bit1=1 ->lesen, DE:=DMA-Adr B:=Sektor C:=Track (zu je 4KB) RAMDISK_RW: LD (L84AC),A LD A,0FFH LD (L84AB),A ;Spooler kurz sperren LD (L84AD),DE LD DE,0 ;E:= 0 PUSH BC LD A,C LD B,A ;B:= Cinput RRCA RRCA RRCA RRCA LD C,A ;C:= Cinput SHR 4 AND 80H LD D,A ;DE:= (Cinput AND 08h) SHL 12 LD A,C AND 0FH ;A:= (Cinput AND F0h) SHR 4 CALL L84B1 ;Exp-RAM Nr. REG A selektieren LD A,B AND 7 RLCA RLCA RLCA RLCA LD H,A LD L,0 ;HL:= (Cinput AND 07h) SHL 12 ADD HL,DE ;HL:= (Cinput AND 0Fh) SHL 12 POP AF SRL A LD D,A LD E,0 ;DE:= Binput SHL 7 RR E ADD HL,DE LD (L84AF),HL ;RamDisk-Sektor-Position merken LD HL,L84AC ;Read-Write Flag BIT 3,B ;(Cinput AND 08h) # 0 JR NZ,L847F BIT 1,(HL) ;Disk-Adr in 0000h..7FFFh JR NZ,L843B ;128 Bytes aus Sys-RAM in selektierter Exp-Bank schreiben (HL->Flag) CALL L8463 ;aus Sys-RAM in Puffer CALL L8443 ;aus Puffer nach Exp-Bank JR L84A3 ;sel TPA/Spooler-Bank + Spooler frei ;128 Bytes aus selektierter Exp-Bank in Sys-RAM lesen (HL->RWflag L843B: CALL L8443 ;aus Exp-Bank nach Puffer CALL L8463 ;aus Puffer nach Sys-RAM JR L84A3 ;sel TPA/Spooler-Bank + Spooler frei ;128 Bytes zwischen Puffer und Exp-Bank transportieren L8443: LD A,(HL) ;Bit1,A=1 -> lesen sonst schreiben aus Exp-RAM di EXX PUSH BC SET 5,C ;Exp RAM einschalten OUT (C),C LD HL,(L84AF) ;RamDisk-Position LD DE,L85CA ;Puffer LD BC,128 ;Sektorl{nge BIT 1,A JR NZ,L845C EX DE,HL ;aus Puffer nach RamDisk L845C: LDIR POP BC OUT (C),C EXX ei RET ;128 Bytes zwischen Puffer und Sys-Bank transportieren L8463: LD A,(HL) ;Bit1,A=1 -> lesen aus Puffer, sonst schreiben PUSH HL LD HL,L85CA ;Puffer LD DE,X_BUFF ;Default-DMA BIT 0,A ;wenn Ziel (teilweise) > 8000h JR NZ,L8473 LD DE,(L84AD) ;sonst richtige DMA L8473: LD BC,128 ;Sektorl{nge BIT 1,A ;lesen/schreiben JR NZ,L847B EX DE,HL ;schreiben -> Puffer ist Ziel L847B: LDIR POP HL RET ;RamDisk-Adresse >8000h. HL:=RWflag, (84AF)=RamdiskPos, (84AD)=DMA L847F: LD A,(HL) LD HL,(L84AF) ;Quelle := RamdiskPos LD DE,X_BUFF ;Ziel := Default-DMA BIT 0,A JR NZ,L848E ;wenn DMA < 8000h LD DE,(L84AD) ;Ziel := CP/M-DMA L848E: BIT 1,A JR NZ,L8496 EX DE,HL ;Schreiben -> Ziel:=RamDisk, Quelle:=DMA L8496: call HiCopy ;(fehlendes EXX schadete im Original nicht,weil SlowModus L84A3: CALL L84CF ;Exp-RAM mit Spooler/TPA selektieren XOR A LD (L84AB),A ;Spooler wieder freigeben RET ;***** RAM-Bank Nr. Reg-A selektieren, abh{ngig vom Konfig-Byte L84B1: PUSH BC ;(von hinten her suchen) LD C,A INC C LD B,8 LD A,(L856C) L84B9: RLCA JR NC,L84BF ;diese Bank nicht vorhanden DEC C ;gew}nschte Bank erreicht? JR Z,L84C4 ;dann gefunden -> Cy=1 und selektieren L84BF: DJNZ L84B9 ;solange suchen, wie noch Banks da L84C1: OR A ;CY=0 -> nicht gen}gend Banks gefunden POP BC RET L84C4: LD A,B ;Bank gefunden -> selektieren DEC A L84C6: LD BC,Port_Memory ;Bank in Register A selektieren CALL L83E9 SCF POP BC RET ;****** erste vorhandene Speicherbank suchen NC -> nicht vorhanden L84CF: PUSH BC ;(von vorne her suchen) LD A,(L856C) LD B,8 L84D5: RRCA JR C,L84DC DJNZ L84D5 JR L84C1 ;kein Vortex-Speicher da -> NC L84DC: LD A,8 SUB B JR L84C6 ;erste vorhandene Bank selektieren, CY=1 ;****** Speicherbanks suchen + RamDisk initialisieren ;(wird nur 1 mal beim laden von $OSC.SYS aufgerufen) RamIni: LD A,' ' ;20H ;Speicherkarte aktivieren LD BC,Port_Memory OUT (C),A DI EXX PUSH BC ;Gate-Array: SystemRAM selektiert SET 5,C ;Expansion-RAM einblenden ; RES 6,C ;von 0000-7FFF SET 2,C ;LOW-ROM ausschalten OUT (C),C LD IX,L856E ;Zwischenspeicher, 8 Bytes LD BC,Port_Memory ;Speicher-Port LD HL,0 ;Testadresse LD A,7 ;maximale Bankzahl L84FF: CALL L83E9 ;Speicherbank im Register A selektieren LD E,(HL) ;Byte aus Testadresse LD (IX+00),E ;retten INC IX DEC A CP 0FFH JR NZ,L84FF ;in allen Banks LD A,7 ;maximale Bankzahl L850F: CALL L83E9 ;Bank selektieren add a,0A0h ;Pr}fbyte modifizieren LD (HL),A ;Banknummer in Testadresse schreiben sub 0A1h CP 0FFH JR NZ,L850F ;f}r alle Banks XOR A ;mit Bank 0 anfangen LD D,A ;Konfigurationsflag L851A: CALL L83E9 ;Bank selektieren LD E,(HL) ;Testbyte holen add a,0A0h ;Pr}fbyte modifizieren CP E ;und mit Banknummer vergleichen JR NZ,L8523 SET 0,D ;wenn gleich, dann Bank vorhanden L8523: RRC D ;Bit in Konfigurationsbyte setzen sub 9Fh ;Banknummer zur}ckholen CP 8 JR NZ,L851A ;f}r alle Banks LD A,D ;Konfigurationsbyte LD (L856C),A ;merken XOR A ;mit Bank 0 anfangen L852F: CALL L83E9 ;Bank selektieren DEC IX LD E,(IX+00) ;alter Inhalt des Testbytes LD (HL),E ;in Testadresse schreiben INC A CP 8 JR NZ,L852F ;f}r alle Banks POP BC OUT (C),C ;System-RAM selektieren EXX EI JP L84CF ;erste Speicherbank selektieren ;****** 128 Bytes Daten zwischen Low-SysRAM und High-ExpRAM kopieren HiCopy: ld bc,Drive_RecordLen di push af exx push bc ld a,0C0h ;High RAM abschalten, wenn fertig ld bc,Port_Gate or 0E0h ;High RAM einschalten zum kopieren call X_Move pop bc exx pop af ei ret ;****** RamDisk formatieren RAMDISK_FORMAT: XOR A ;letzte Bank (=Track 0) selektieren CALL L84B1 DI EXX PUSH BC ; RES 6,C ;in Bereich 0000-7FFF einblenden SET 5,C OUT (C),C LD HL,0 LD BC,8000h L855C: LD (HL),0E5H ;32 KB mit E5 loeschen INC HL DEC BC LD A,B OR C JR NZ,L855C POP BC OUT (C),C EXX EI JP L84CF ;Bios-Bank selektieren ;****** CAPS LOCK auch f}r deutsche Umlaute nkmw: call nkmr jr nc,nkmw ret nkmr: call kmread captst: ret nc ;keine Taste -> keine [nderung cp '{' ret c cp '~' ccf ret c push hl statep: call KM_GET_STATE bit 7,h ;CAPS Lock? jr z,nocap and 0DFh ;in Gro~buchstaben wandeln nocap: pop hl scf ;Taste gefunden ret ;****** neue KM_TEST_BREAK Routine (ROM-Abh{ngig! => patchen) kbreak: ld hl,$-$ ;aus Originaler ROM-Routine }bernehmen! bit 2,(hl) ret z ;kein ESC ld a,c xor 0A0h ret nz ;kein SHIFT-CTRL push bc inc hl ld b,0Ah kbr2: adc a,(hl) dec hl djnz kbr2 pop bc cp 0A4h ret nz ;nicht ausschlie~lich SHIFT_CTRL_ESC push bc ld hl,ibreak ;Async Event einh{ngen weil Interrupt-Vorspann aktiv klevnt: call $-$ ;KL_EVENT Rom-Adresse einsetzen pop bc ret ;****** im Asynchronen Event d}rfen auch Ints eingesetzt werden xbreak: call KM_READ_CHAR jr c,xbreak ;Tastaturpuffer leeren ld a,'X' and 1Fh;^X in Tastaturpuffer (damit derzeit laufendes call KM_CHAR_RETURN ;KM_WAIT_CHAR gestoppt) di exx ld e,c set 2,c ;Low ROM abschalten out (c),c exx ld a,0C0h ;High RAM abschalten, wenn fertig ld bc,Port_Gate or 0E0h ;High RAM einschalten zur STack-Manipulation call X_Halt exx ld c,e out (c),c ;Low ROM wieder einschalten exx ei ret ;Interrupt wie gew|hnlich beenden ;****** 8. Druckerbit: PIO Port C Bit 5 (CAS-Daten) (Pin 12) ;auch auf Drucker-Stecker abzweigen (Pin 9) mcwait: ld bc,0032h mc2: push bc ld c,a ld b,0F5h in a,(c) rla rla ld a,c pop bc jr nc,mcsend djnz mc2 dec c jr nz,mc2 or a ret mcsend: push bc ld c,a ;Datenbyte mit 8 Bit add a,a ld a,5 adc a,a ;Bit 5,Port C setzen wie Datenbyte, Bit 7 ld b,0F7h out (c),a ;PIO-Control ld a,c ld b,0EFh ;Druckerport and 7Fh out (c),a ;Daten anlegen or 80h di ;Strobe m|glichst kurz out (c),a ;Strobe Date and 7Fh ei out (c),a ;Strobe zur}cknehmen ld a,c ;8. Bit restaurieren pop bc scf ;]bertragung erfolgreich ret include OSC4TERM.MAC include OSC4TIME.MAC include OSC4CHAR.MAC L8140: DEFW 0 ;Spooler Zustandsinformationen L8143: DEFW 0 L8145: DEFW 0 lock: dw 0 ;aus OSC4TIME.MAC: kein Uhrausgabe-Interruptkonflikt L84AB: DEFB 0 ;0FF -> Spooler wegen RamdiskZugriff gesperrt locbuf: db 0 ;aus OSC4TERM.MAC vidatt: db 0 ; " ConAsc: db 0 ;Frequenzteiler - KonsolenStatusabfrage NoCurs: DEFb 0 ;0, wenn Cursor eingeschaltet, sonst Delay-Z{h|er Blink: DEFb 0 ;0FFh wenn Cursor gerade sichtbar MotFlg: DEFb 0 ;0FFH wenn Motor eingeschaltet autopos:defw autobuf+1 LastK: DEFb 0FFh ;zuletzt gelesenes Zeichen von Tastatur fboot: defb 0FFh ;FFh -> allererster Warmstart nbuff: db 0FFh,0FFh,0FFh ;OSC4TIME.MAC:Ergebnis des Uhrlesens ablegen ibreak: DEFS 7 ;KM_TEST_BREAK Event-Block CurBlk: DEFS 2 ;Frame-Fly-Header DEFS 7 ;Cursor/ConInSt Frame-Fly Event-Block L81C5: DEFS 6 ;Spooler Ticker Header L81CB: DEFS 7 ;Spooler Event Block LBE67: DEFS 6 ;Motor Ticker-Header MotEvn: DEFS 7 ;Motor Event-Block UhrTic: DEFS 6 ;Uhrzeit Ticker-Header UhrEvt: DEFS 7 ;Uhrzeit Event-Block L856C: DEFS 1 ;Konfigurationsbyte der RAM-Karte (0) L8142: DEFs 1 ;FF -> Spooler eingeschalten L84AC: DEFS 1 ;Bit1=1 bei lesen aus RamDisk, 0-> schreiben CurSpd: DEFS 1 ;Blinkgeschwindigkeit Cursor Uhratt: defs 1 ;Bildschirmattribut der Uhranzeige spdis: defs 1 ;FF -> Spooler deaktiviert (-> + 32KB RamDisk) ccpcom: defs 1 ;FF -> Auto-Kommando bei jedem Warmstart autoclr:defs 1 ;Auto-Keys Control FrmGate:defs 2 ;Firmware-Gate-Array-Zustand L85C8: DEFS 2 ;Speicher f}r ResBios-Stapel printw: defs 2 ;Wartezeit, bis Drucker Timeout meldet L84AD: DEFS 2 ;DMA-Adresse f}r Ramdisk Sektor-RW L84AF: DEFS 2 ;Ramdisk-Adresse f}r Sektor RW LBE44: DEFS 2 ;Motor an Verz|gerung LBE46: DEFS 2 ;Motor aus Verz|gerung matrix: defs 72 ;Zeichen-Matrizen f}r deutsche Sonderzeichen tbuffer: ;8 Bytes Puffer f}r OSC4CHAR.MAC (bei Ram-Test nicht benutzt) L856E: DEFS 8 ;Zwischenspeicher f}r Ram-Test L85CA: DEFS 0080H ;Sektorpuffer autobuf:defs 128 kmread: defs 3 ;Firmware-Vektor KM_READ_CHAR DEFS -$ AND 0FFH quelle: ;Hierher kommt CCP/BDOS .DEPHASE Banken: ;================================================================ END