TITLE CENTRONICS-Treiber ;********************************************* ;FILE :CEN.MAC ;AUTOR:Lutz Elssner, Robotron-Messelektronik "Otto Schoen" Dresden ;STAND:15.12.89 ;--------------------------------------------- .Z80 .TFCOND ;es werden nur die erfuellten Bedingungen in die ;Druckliste aufgenommen (Aufruf mit /L) ;bei Aufruf mit /L/X wird die komplette Liste erzeugt ;------------------------ INCLUDE TRA.MAC ;Uebersetzung auf 0 oder 0701H festlegen ;------------------------ SEG EQU 0 ;0 Treiber enthaelt keine SEGMENT-Pseudooperationen ;1 Treiber besteht aus CSEG und DSEG ; FUNKT EQU 1 ;0 Treiber ohne Parameter, ohne Eintrag in BIOS-Tab. ;1 zeichenweiser E/A-Treiber ; mit Eintrag in BIOS-Tabelle ;wird vom Treiberrahmen (TRR) ausgewertet (GLOBAL) ; FRES EQU 1 ;0 Meldung, wenn Kommandos mit EXT nachgeladen ;1 automatische Ausfuehrung des CCP-Kommandos RES ;wird vom Treiberrahmen (TRR) ausgewertet (GLOBAL) ; MINADR EQU 0C000H ;kleinste Anfangsadresse fuer residenten Treiber ;Interruptroutinen duerfen nicht unter C000 stehen ;wird vom Treiberrahmen (TRR) ausgewertet (GLOBAL) ; LOWADR EQU 1 ;0 Treiberbeginn wird auf xx00H gelegt ;1 Treiber wird lueckenlos unter TPA gelegt ; SCPV EQU 020FH ;0000H kein Versionstest CGGV EQU 0201H ;sonst Test der Versionsnummer im Treiberrahmen DSEV EQU 020FH ;wird vom Treiberrahmen (TRR) ausgewertet (GLOBAL) ; CGGAD EQU 7F44H ;Adresse der Zeichenkette mit Versionsnummer im ROM DSEAD EQU 4148H ;CGG:Bank 0 / DSE:Bank 1 / Beispiel: '2.01' ;wird vom Treiberrahmen (TRR) ausgewertet (GLOBAL) ; ANZ EQU 1 ;0 alle Bildschirmausgaben vom TRR werden unterdrueckt ;1 Anzeige der Anfangs-, Endadresse und Meldungen ; IF SEG ;nur gueltig, wenn SEG = 1 DATEN EQU 1000H ;hier ist der Wert CODEND oder groesser ;von Hand einzutragen ;stellt Datenanfang zur Laufzeit dar ;CODEND wird vom Kommandofile nach LINK angezeigt ENDIF ; BIORSL EQU 0FD00H ;Anfang der BIOS-Sprungleiste im RAM EOFRAM EQU 0FBB4H ;Adresse, wo Ende des RBASIC-Anwenderspeichers steht SYSANF EQU 0FBB8H ;Adresse, wo Anfang des RBASIC-Betriebssystems steht ;------------------------ INCLUDE TRVOR.MAC ;------------------------ ;Portadressen fuer E/A-Port 1 / Port 2 PIOD EQU 60H ;60H/61H ;Daten PIOC EQU 62H ;62H/63H ;Steuerung ;Interruptadresse fuer E/A-Port 1 / Port 2 INTA EQU 14H ;14H/16H ;wird zum Interruptvektor ;des SIO addiert ;============================================================================ ;Initialisierung ;dieser Programmteil wird nur beim Laden des Treibers abgearbeitet ;und nicht mit resident gemacht (Speicherplatz sparen) RET ;============================================================================ ;residenter Programmteil ;dieser Programmteil bleibt nach dem Laden im Speicher resident ;wird aber beim Laden ebenfalls ab Marke RESBEG abgearbeitet (A=FF) ;ausserdem erfolgt hier der Aufruf des Treibers (A<>FF) ; ;auszufuehrende Funktion steht in Register A ;auszugebendes Zeichen steht in Register C ;wird der Treiber mit gesetztem Carry-Flag verlassen, ;fuehrt das BIOS einen Warmstart aus ;-------------------------------- RESBEG: INC A JR NZ,BEGINN ;A=FF Initialisierung LD A,I ;Interrupttabelle HIGH-Teil LD H,A LD A,2 ;Interrupttabelle LOW-Teil OUT (6BH),A ;aus SIO-Register 2 lesen und ausrechnen IN A,(6BH) AND 11110000B ADD A,INTA LD L,A LD DE,ISR ;Interruptstartadresse in Tabelle LD (HL),E INC HL LD (HL),D ; OUT (PIOC),A ;Interruptvektor in PIO programmieren LD A,0FH ;Mode 0 Ausgabe OUT (PIOC),A LD A,83H ;Interrupt erlauben OUT (PIOC),A ; LD C,9 ;Ausgabe einer Meldung auf Bildschirm LD DE,TEXT CALL 5 ; RET ; TEXT: DB 0DH,0AH,87H,'CENTRONICS-Treiber 1 zugewiesen',84H,0DH,0AH,'$' ;-------------------------------- BEGINN: DEC A JR NZ,F1 ;A=00 Status Eingabe OR A ;CY=0 (kein Fehler) RET ;wird nicht benutzt ; F1: DEC A JR NZ,F2 ;A=01 Zeichen Eingabe OR A ;CY=0 (kein Fehler) RET ;wird nicht benutzt ; F2: DEC A JR NZ,F3 ;A=02 Zeichen Ausgabe PUSH BC ;auszugebendes Zeichen in C retten WART: CALL STATUS ;hier kann eine Abbruchmoeglichkeit programmiert werden JR Z,WART ;warten, bis letztes Zeichen abgeholt POP BC LD HL,MERK ;RAM Interruptmerkzelle LD (HL),0 ;loeschen LD A,C OUT (PIOD),A ;Zeichen ausgeben auf Datenport OR A ;CY=0 RET ; F3: DEC A JR NZ,F4 ;A=03 Ausgabe Status STATUS: LD A,(MERK) ;Interrupt-Merkzelle abfragen OR A RET Z ;A=0 Z=1 CY=0 nicht bereit XOR A DEC A RET ;A=FFH Z=0 CY=0 bereit ; F4: OR A RET ;ungueltiger Code in A uebergeben ;-------------------------------- ;Interruptserviceroutine ISR: LD (SPSV),SP ;Stackpointer retten und eigenen Stack anlegen, LD SP,STACK ;weil Systemstack nur mit einer Stackebene PUSH AF ;belastet werden darf, das ist bereits bei der LD A,1 ;Interruptanmeldung erfolgt LD (MERK),A ;Merkzelle fuer Interrupt mit 1 belegen POP AF LD SP,(SPSV) ;Register AF und SP wieder herstellen EI RETI ;Interrupt beenden ;-------------------------------- ;RAM-Bereich MERK: DS 1,1 ;Interrupt-Merkzelle (Startwert = 1) SPSV: DS 2,0 ;Zwischenspeicher fuer Stackpointer DS 4,0 ;Stack fuer Interrupt STACK: ;-------------------------------- INCLUDE TRNACH.MAC ;-------------------------------- ENDE: END