TITLE Interrrupts fuer SHARD ; INCLUDE HD64180.LIB ; .LIST ; ;**************************************************************** ; ; Interruptmodul fuer EUMEL SHARD ; ; Timer Handling, SCC Interrupts, 6502 Interrupts ; Buffer Manager ; ; Version 0.9 vom 10.01.87 (Transmittinterrupts) ; Version 1.0, getestet (Ringpuffer korrigiert, ; 20.01.87 - keine Interrupthaenger an Kanal 1/5 mehr) ; 1.1 (27.05.87) Verlorener Timerinterrupt im Info/Vortest ; durch Korrektur von CHKINT (weniger oft aufgerufen) ; 1.2 (26.06.87) Wieder rausgebaut, da bei mehr als 16 Zeichen im ; Eingabepuffer die Puffer-Auslesegeschwindigkeit stark ; sinkt. ; ; Copyright (C) 1985 by R. Ellerbrake ; 86/87, M. Staubermann ; ;**************************************************************** ; ; Globale Adressen ; GLOBAL BAUSCC, BITSCC, SCCINIT, CLRCBUF GLOBAL ESTOP, EGO, AFLOW GLOBAL I6502, TIMER, CENTR GLOBAL SCCKA, SCCKB, SCCAER, SCCBER, SCCATX, SCCBTX GLOBAL PUTBUF, FREEBUF, DRUCK, SCCATAB, SCCBTAB ; ;---------------------------------------------------------------- ; ; Externe Adressen ; EXTERNAL TIMEAD, IINTAD, SHUTUPAD EXTERNAL IKANTAB, BLINKP, SWICUR, MEMDMA, FLWTYP EXTERNAL AFLOW5, RD6502 ; ; ;---------------------------------------------------------------- ; CSEG ; ; Konstanten ; CMN1T0 EQU 51H ;Common Area 1 auf 6502 Adr. 0 CMN1T1 EQU 52H ;Common Area 1 auf 6502 Adr. $1000 ; XON EQU 11H ; CTRL-Q XOFF EQU 13H ; CTRL-S ; Bereich fuer Transmitbuffer im 6502-Speicher DBUF EQU 0A000H SABUF EQU DBUF+1000H SBBUF EQU SABUF+0800H ; SABUF+SBBUF zusammen max. 4k in einem Window ; Offsets auf Kanal-Buffer-Tabellen SIZE EQU 0 ; aktuelle Groesse (Belegung) des Puffers BEG EQU 2 ; Pufferanfang (fest) READ EQU 3 ; Adresse des naechsten Out-Buffer-Zeichens WRITE EQU 5 ; Adresse des naechsten In-Buffer-Zeichens ENDE EQU 7 ; excl. Pufferende (fest) CPORT EQU 8 ; Controlport mit Statusregister XFLAG EQU 9 ; Bit 7 = 1: Transmitter stoppen ; Bit 6 = 1: XON/XOFF ausgabeseitig INCLUDE PORTS.MAC ;---------------------------------------------------------------- ; ; 6502-Adressen ; BASE EQU 0F000H ;Anfangsadresse 6502 Bereich IFLG EQU BASE+09EH ; Start/Stop Flag fuer 6502 INTPAR1 EQU BASE+0EAH ;Interrupt Parameter 1 (Kanal) INTPAR2 EQU INTPAR1+1 ;Interrupt Parameter 2 (Eingabezeichen) INTPAR3 EQU INTPAR2+1 ;Interrupt Parameter 3 (Fehlerbits) ;----------------------------------------------------------------- ; ; P H Y S L O G ; Umrechnung der physischen Kanalnummer in eine logische ; ; Eingang: A = phys. Kanalnummer ; Ausgang: A = log. Kanalnummer ; keine anderen Register veraendert ; PHYSLOG: PUSH HL ADD A,IKANTAB ; Kanal phys. --> log. Umrechnen LD L,A LD H,0 LD A,(HL) POP HL RET ;................................................................ ; ; Timer Interrupt Handler ; ; wird durch CIO Timer 2 Interrupt aufgerufen ; TIMER: PUSH AF ; LD A,50 ;50 ms pro Timerinterrupt CALL TIMEAD ;EUMEL timerinterrupt ; DI LD A,(CCOUNT) ;Cursor invertieren ? DEC A JR NZ,TIMER1 ; IN0 A,(CIOAD) ; Cursor invertieren, wenn Zugriff erlaubt BIT 0,A JR Z,TIMER2 PUSH HL PUSH DE PUSH BC CALL SWICUR ; Cursor invertieren POP BC POP DE POP HL TIMER2: LD A,(BLINKP) TIMER1: LD (CCOUNT),A LD A,0BH OUT0 (CIOCTL),A ;Counter/Timer 2 Command LD A,00100100B ;Clear IP & IUS OUT0 (CIOCTL),A PUSH IX LD IX,DRUCK CALL TXHANDLER ; Testen, ob Drucker haengt POP IX EINT: POP AF EINT1: EI RETI ; ;................................................................ ; ; I 6 5 0 2 ; ; 6502 Interrupt Handler ; I6502: PUSH AF PUSH BC CALL INT6502 POP BC JR EINT INT6502: PUSH DE LD A,0B0H ; Reset Interrupt FF (Keine IRQ's mehr) OUT0 (CIOCD),A IN0 A,(CBR) ;Common Area 1 retten PUSH AF LD A,CMN1T0 OUT0 (CBR),A ; LD BC,(INTPAR1) ; C = Kanalnummer, B = Eingabezeichen LD DE,(INTPAR3) ; E = Fehlerbits XOR A ; Interrupt quitieren LD (INTPAR1),A POP AF OUT0 (CBR),A ;Common Area 1 zurueckschalten LD A,C AND A ;kein Auftrag -> JR Z,RET6502I CP 40H JR NC,BREAK ; Sonderbehandlung LD C,E ; Fehlerbits PUSH AF CALL PHYSLOG CALL IINTAD ; EUMEL Inputinterrupt DI POP BC ; Kanal in B CP 1 JR NZ,RET6502I ; noch Platz im Puffer LD A,B CALL ESTOP ; Eingabestop, reagiert sofort RET6502I: POP DE RET6502J: LD C,0B4H ; Reseteingang des 6502-IRQ-FF wieder auf High OUT0 (CIOCD),C RET BREAK: POP DE CALL RET6502J CP 'S' ; Shutup ? (53H) RET NZ CALL EINT1 ; Interrupts freigeben JP SHUTUPAD ;------------------------------------------------------------------- ; ; E F L W 5 ; Kanal 5 Interrupt an 64180 stoppen/starten ; Reagiert sofort ; ; Eingang: Bit 7(HL) = 1: Stop, = 0: Start ; Ausgang: BC veraendert ; EFLW5: LD BC,7F80H ; B = AND-resetmaske, C = OR-setmaske JR EFLW15 ; Bit 7 ist Flag ;------------------------------------------------------------------- ; ; E F L W 1 ; Kanal 1 Interrupt an 64180 stoppen/starten ; Reagiert sofort ; ; Eingang: Bit 7(HL) = 1: Stop, = 0: Start ; Ausgang: BC veraendert ; EFLW1: LD BC,0BF40H ; Bit 6 ist Flag EFLW15: PUSH AF LD A,I DI IN0 A,(CBR) PUSH AF LD A,51H OUT0 (CBR),A LD A,(IFLG) AND B ; "weiter" BIT 7,(HL) JR Z,EFLWA OR C ; "stop" setzen EFLWA: LD (IFLG),A ; Stop/Weiter an 6502 weitergeben POP AF OUT0 (CBR),A JP PO,EFLWB EI EFLWB: POP AF RET ;******************************************************************** ; ; Ringpuffer - Verwaltung ; ;---------------------------------------------------------------- ; ; F R E E B U F ; freien Platz im Puffer berechnen ; (dies ist nicht immer die Anzahl der uebernehmbaren Zeichen!) ; ; Eingang: IX = Zeiger auf Kanal-Puffer-Tabelle ; Ausgang: BC = Anzahl Bytes, die noch in den Puffer passen ; Carry gesetzt: Puffer leer, sonst Puffer gefuellt ; A veraendert ; FREEBUF: PUSH HL LD A,(IX+ENDE) ; Konstante SUB (IX+BEG) LD H,A LD L,0 DI LD B,(IX+SIZE+1) LD C,(IX+SIZE) EI LD A,B OR C SCF ; Set carry, Puffer leer JR Z,FREEBUF1 AND A SBC HL,BC ; Carry is cleared FREEBUF1: LD B,H LD C,L POP HL RET ;---------------------------------------------------------------- ; ; P U T B U F ; Zeichenkette in Ausgabepuffer schreiben ; ; Eingang: HL = Anfangsadresse der Zeichenkette ; BC = Laenge der Zeichenkette ; IX = Zeiger auf Kanal-Puffer-Tabelle ; Ausgang: BC = Anzahl der uebernommenen Zeichen ; Carry set, alles uebernommen ; HL, A veraendert ; PUTBUF: PUSH BC CALL FREEBUF DI LD A,B OR C JR NZ,PUTBUF1 PUSH AF CALL TXHANDLER POP AF EI INC SP ; POP BC, nichts uebernommen, Clear carry INC SP RET PUTBUF1: POP BC PUSH DE PUSH HL ; Stringanfang im Hauptspeicher in HL LD H,(IX+READ+1) ; Lesezeiger in HL LD L,(IX+READ) LD D,(IX+WRITE+1) ; Schreibzeiger in DE LD E,(IX+WRITE) LD A,(IX+SIZE) ; Puffer leer ? OR (IX+SIZE+1) JR NZ,PUTBUF3 LD D,(IX+BEG) LD E,0 ; Beide Zeiger auf Pufferstart LD (IX+READ+1),D LD (IX+READ),E LD (IX+WRITE+1),D LD (IX+WRITE),E ; Weiter, ohne zu splitten LD L,E ; L := 0 LD H,(IX+ENDE) PUTBUF3: ; DE, erste Position fuer String ; HL, letzte Position (excl.) fuer String AND A ; falls nicht HL = Pufferende SBC HL,DE JR C,PUTBUF2 ; C, wenn Read < Write: String splitten ; Z kann nicht auftreten, da Puffer nicht voll PUTBUF9: ; BC := min (BC, HL) LD A,L ; HL enthaelt max. uebernehmbare Size SUB C ; BC enthaelt Eingangs-Stringlaenge LD A,H SBC B JR NC,PUTBUF4 ; NC, alles uebernommen LD B,H ; C --> nur Puffersize uebernommen LD C,L PUTBUF4: CCF ; Carry fuer EUMEL umdrehen POP HL ; Stringanfang in HL PUSH AF CALL PUTBUFA CALL TXHANDLER ; Ein Zeichen ausgeben, IP wird gesetzt EI POP AF POP DE RET PUTBUF2: ; String muss ggf. gesplittet werden LD H,(IX+ENDE) XOR A LD L,A SBC HL,DE ; HL enthaelt Size (immer > 0) JR PUTBUF9 ;---------------------------------------------------------------------- ; ; Teilstring in Puffer schreiben ; Eingang: Interrupts disabled ; HL = Teilstringanfang ; DE = Schreibzeiger ; BC = Stringlaenge, die uebernommen werden soll ; (BC muss ok sein!) ; Ausgang: Nur BC ok ; (DE = Schreibzeiger (korrigiert)) ; (HL = Teilstring + uebernommene Stringlaenge) ; BC unveraendert ; PUTBUFA: PUSH HL EX DE,HL ; DE = Hauptspeicher, HL = 6502-Speicher PUSH BC ; merken fuer Ausgang PUSH HL ; Stringanfang in DE, Schreibzeiger in HL LD A,1 ; Von DE (log.) nach HL(6502) kopieren CALL MEMDMA POP HL ; Schreibzeiger POP BC ; uebernommene Stringlaenge ADD HL,BC ; Stringlaenge addieren LD A,H CP (IX+ENDE) JR NZ,PUTBUFA2 LD H,(IX+BEG) ; Schreibzeiger auf Pufferanfang setzen ; L war schon 0 PUTBUFA2: LD (IX+WRITE+1),H LD (IX+WRITE),L ; Schreibzeiger neu setzen ; EX DE,HL ; Schreibzeiger in DE LD L,(IX+SIZE) LD H,(IX+SIZE+1) ADD HL,BC ; Stringlaenge addieren LD (IX+SIZE+1),H ; eintragen LD (IX+SIZE),L POP HL ; Stringanfang RET ;................................................................ ; ; SCCA Output Interrupt ; SCCATX: PUSH IX LD IX,SCCATAB JR TXCHAR ;................................................................ ; ; SCCB Output Interrupt ; SCCBTX: PUSH IX LD IX,SCCBTAB TXCHAR: PUSH AF CALL TXHANDLER LD A,00111000B ; Reset highest IUS OUT0 (SCCBC),A JR EOFTX ;................................................................ ; ; Centronics Output Interrupt ; CENTR: PUSH IX LD IX,DRUCK PUSH AF CALL TXHANDLER LD A,9 ; Statusregister OUT0 (CIOCTL),A LD A,00100000B ; Reset IP & IUS OUT0 (CIOCTL),A EOFTX: POP AF POP IX EI RETI ; ;------------------------------------------------------------------------ ; Output Interrupt Handler ; fuer Centronics und SCC ; ; Eingang: IX = Zeiger auf Descriptortabelle des Kanals ; Interrupts disabled ; Ausgang: Nur AF veraendert ; TXHANDLER: PUSH HL PUSH DE PUSH BC IN0 A,(CIOAD) ; Zugriff auf Puffer erlaubt ? BIT 0,A JP Z,REGRET PUSH IX POP HL LD A,L CP LOW DRUCK JR Z,CENTRIRQ LD B,0 BIT 7,(IX+XFLAG) ; Transmitter gestoppt ? JR NZ,REGRET ; Keine Interruptbehandlung LD E,(IX+SIZE) LD D,(IX+SIZE+1) LD L,(IX+READ) LD H,(IX+READ+1) TX1: LD C,(IX+CPORT) LD A,D OR E JR Z,TX5 ; Puffer ist leer TSTIO 0100B JR Z,TX4 ; Output-Buffer voll IN0 A,(CBR) PUSH AF LD A,51H+(SABUF/1000H); MMU-Wert fuer Pufferwindow (max. 4k) OUT0 (CBR),A PUSH HL LD A,H AND 0FH OR 0F0H ; Ins Window F000H... LD H,A LD A,(HL) ; Zeichen ausgeben INC C ; Aus Controlport wird Datenport INC C OUT (C),A ; B bleibt 0! POP HL INC HL POP AF OUT0 (CBR),A ; MMU zurueckschalten LD A,H CP (IX+ENDE) JR NZ,TX2 ; Carry set: Lesezeiger < Pufferende, ok LD H,(IX+BEG) ; L war schon 0 TX2: DEC DE ; Puffergroesse DECR 1 JR TX1 ; Falls moeglich naechstes Zeichen ausgeben TX5: LD A,00101000B ; Reset TxIP (B ist 0!) OUT (C),A TX4: LD (IX+SIZE),E LD (IX+SIZE+1),D LD (IX+READ),L LD (IX+READ+1),H REGRET: POP BC POP DE POP HL RET CENTRIRQ: LD C,CIOCTL LD DE,(DRUCK+SIZE) LD HL,(DRUCK+READ) CENTR3: LD A,D OR E JR Z,TX4 ; Puffer ist leer LD A,9 ; Statusregister OUT0 (CIOCTL),A ; Statusregister TSTIO 1000B JR Z,TX4 ; Output-Buffer voll IN0 B,(CBR) LD A,51H+(DBUF/1000H) ; MMU-Wert fuer Pufferwindow (max. 4k) OUT0 (CBR),A PUSH HL LD A,H AND 0FH OR 0F0H ; Ins Window F000H... LD H,A LD A,(HL) ; Byte aus Puffer lesen OUT0 (CIOBD),A ; und ausgeben OUT0 (CBR),B ; MMU zurueckschalten POP HL INC HL LD A,H ; Pufferende ? CP (IX+ENDE) JR NZ,CENTR2 LD H,(IX+BEG) ; L war schon 0 CENTR2: DEC DE ; Puffergroesse DECR 1 JR CENTR3 ; Falls moeglich naechstes Zeichen ausgeben ;************************************************************************* ; ; CLRCBUF ; ; 64180-Centronics Buffer loeschen ; Ausgang: HL veraendert, Flags unveraendert ; CLRCBUF: LD HL,DBUF LD (DRUCK+READ),HL LD (DRUCK+WRITE),HL LD HL,0 LD (DRUCK+SIZE),HL RET ;................................................................ ; ; SCC Input Interrupt Handler ;-------------------------------------------------------------------- ; Zeichen mit Fehler empfangen SCCAER: ; von SCC-Kanal A PUSH BC LD C,SCCAC JR SCCERR SCCBER: ; von SCC-Kanal B PUSH BC LD C,SCCBC SCCERR: PUSH AF LD B,0 LD A,00010000B ; Reset EXT/Status Interrupts OUT (C),A LD A,00110000B ; Error Reset OUT (C),A LD A,1 OUT (C),A ; Read-Register 1 IN B,(C) BIT 5,B ; Overrun Error ? JR Z,SCCER1 SET 0,A SCCER1: BIT 4,B ; Parity Error ? JR Z,SCCER2 SET 2,A SCCER2: BIT 6,B ; Framing Error (mit 0 = Break) JR Z,SCCER3 SET 1,A SCCER3: JR SCC1 ;----------------------------------------------------------------------- ; Zeichen ohne Fehler empfangen SCCKA: PUSH BC LD C,SCCAC JR SCCOK SCCKB: PUSH BC LD C,SCCBC SCCOK: PUSH AF XOR A ; Keine Fehler ; Interrupt weiterleiten und Flusskontrolle auswerten ; Eingang: A = Fehlerbits ; C = Contollportadresse des Kanals SCC1: LD (ERRBIT),A LD A,C SUB A,3EH LD (KANAL),A LD B,0 PUSH BC TSTIO 1 ; Statusregister JR Z,IRET ; Receive Character available ? INC C ; Aus Controlport wird Datenport INC C IN B,(C) ; Zeichen einlesen LD A,11111101B ; Maske zur XON/XOFF Erkennung AND B ; mit Eingabezeichen verknuepfen CP 00010001B ; = XON oder XOFF ? JR NZ,SCC2 ; Nein, normaler Inputinterrupt PUSH HL LD HL,XFLGB LD A,(KANAL) CP 2 JR Z,SCC3 LD HL,XFLGA SCC3: BIT 6,(HL) ; Bit 6: Ausgabeseitig XON/XOFF JR Z,SCC5 ; 0: An Inputinterrupt weiterleiten BIT 1,B ; XOFF : Bit 1 = 1, XON: Bit 1 = 0 JR Z,SCC4 SET 7,(HL) ; Transmitter stoppen POP HL JR IRET SCC4: RES 7,(HL) ; Transmitter starten POP HL POP BC CP 2 ; Flag setzen CALL NZ,SCCATX ; Flags werden nicht veraendert! CALL Z,SCCBTX ; enthaelt u.a. EI und RETI ; und Reset highest IUS POP AF POP BC RET SCC5: POP HL SCC2: LD A,(ERRBIT) ; Fehlerbits LD C,A LD A,(KANAL) ; Kanalnummer CALL PHYSLOG ; phys. Kanalnummer --> log. Kanalnummer CALL IINTAD CP 3 ; Weniger als 3 Zeichen Platz ? JR NC,IRET LD A,(KANAL) CALL ESTOP ; Eingabestop fuer Kanal 2 oder 3 IRET: POP BC LD A,00111000B ; Reset highest IUS OUT (C),A ; POP AF POP BC EI RETI ;................................................................ ; ; SCC Initialisierung ; HL, BC veraendert ; SCCINIT: LD HL,SCCAINI ;SCC Kanal A initialisieren LD BC,(SCCALG+1)*100H+SCCAC+1 INILP1: DEC C OTIM JR NZ,INILP1 ; ; SCC Kanal B initialisieren LD BC,(SCCBLG+1)*100H+SCCBC+1 INILP2: DEC C OTIM JR NZ,INILP2 ; RET ; ;................................................................. ; ; B A U S C C ; Baudrateneinstellung fuer SCC-Kanaele ; ; Eingang: A - Kanalnummer (2 oder 3) ; HL - Schluessel (s. Tabelle) (1..16) ; Es werden korrekte Parameter vorrausgesetzt ; ; Ausgang: Register duerfen nicht veraendert werden ; BAUSCC: PUSH AF PUSH HL LD BC,BDSCCA+1 CP 3 ;Kanal A ? JR Z,CHABD ;Ja -> ; LD BC,BDSCCB+1 ;Tab. fuer Kanal B ; CHABD: PUSH BC LD BC,BDTAB-2 ;Tabelle mit Baudratenteilfaktoren ADD HL,HL ;Tab.-Offset ADD HL,BC POP BC ;Baudrate eintragen LD A,(HL) LD (BC),A ;LSB eintragen INC HL INC BC INC BC LD A,(HL) ;MSB eintragen LD (BC),A INISCC: CALL SCCINIT POP HL POP AF RET ; ;................................................................. ; ; B I T S C C ; Stopbits, Parity, Datenbits fuer SCC-Kanaele einstellen ; ; Eingang: A = Kanal (2 oder 3) ; L = Schluessel : ; Bit 0..2 : Datenbits - 1 (Nur 7 oder 8 erlaubt) ; Bit 3..4 : 00 = No Parity, 01 = Odd , 10 = Even ; Bit 5..6 : 00 = 1 Stop, 01 = 1.5 Stop, 10 = 2 Stop ; ; Es werden korrekte Parameter vorausgesetzt ; ; Ausgang: Register unveraendert ; BITSCC: PUSH AF PUSH HL LD BC,BTSCCA+1 CP 3 ;Kanal A ? JR Z,CHABT ;Ja -> ; LD BC,BTSCCB+1 ;Tab. fuer Kanal B ; CHABT: LD A,L RRA RRA RRA ; Paritybits (0, 1), Stopbits (2, 3) AND 0FH ADD 4 ; Stopbits korrigieren BIT 1,A ; Wenn even Parity noch Bit 0 setzen JR Z,NOEVN ; 00 = No Parity, 01 = Odd, 11 = Even SET 0,A NOEVN: OR 01000000B ; Clock x16 Mode LD (BC),A ; eintragen INC BC ; Zeigt auf Register 3 INC BC LD A,L AND 7 CP 7-1 LD A,01000001B ; Receiver Enable, 7 Datenbits JR Z,CHABT1 LD A,11000001B ; dgl., 8 Datenbits CHABT1: LD (BC),A ; Eintragen INC BC ; Zeigt auf Register 5 INC BC LD A,10101010B ; Enable Transmitter, 7 Datenbits JR Z,CHABT2 ; Compare-Flag noch nicht veraendert! LD A,11101010B ; dgl. 8 Datenbits CHABT2: LD (BC),A ; eintragen JR INISCC ;.................................................................. ; ; X F L W 2 3 ; XON/XOFF - Eingabeflusskontrolle auf SCC-Kanaelen ; ; Eingang: A = Kanal (2, 3) ; BIT 7 (HL), Stop/Weiter ; ; Ausgang: alle Register unveraendert ; XFLW23: PUSH AF PUSH BC LD B,0 ADD A,3EH ; Kanal --> Controlport LD C,A ; Transmitinterrupt kann nicht durchkommen XFLW23B: TSTIO 0100B ; Transmitbuffer empty ? JR Z,XFLW23B LD A,XON BIT 7,(HL) JR Z,XFLW23A LD A,XOFF XFLW23A: INC C ; Controlport --> Datenport INC C OUT (C),A POP BC POP AF RET ;................................................................. ; ; C F L O W 2 3 ; CTS - Ausgabeflusskontrolle auf SCC-Kanaelen ; ; Eingang: A = Kanal (2, 3) ; BIT 1(HL), BIT 2(HL) beide 1 : Mit CTS-Flusskontrolle ; sonst ohne Flusskontrolle ; Ausgang: Nur HL darf veraendert werden ; CFLOW23: PUSH AF PUSH BC LD B,0 ADD A,3EH ; Controlport LD C,A CP 40H ; SCCA ? LD A,(HL) ; Bit 1 und 2 relevant LD HL,CTSA+1 JR Z,CFLOW2 LD HL,CTSB+1 CFLOW2: RES 5,(HL) ; erstmal keine Auto-Enables AND 0110B ; Bit 1 und 2 ausblenden CP 0110B JR NZ,CFLOW3 SET 5,(HL) ; Auto-Enables einschalten CFLOW3: LD A,3 OUT (C),A ; Write-Register 3 LD A,(HL) OUT (C),A POP BC POP AF RET ;...................................................................... ; ; R F L W 2 3 ; RTS/DTR - Eingabeflusskontrolle auf SCC-Kanaelen ; ; Eingang: A = Kanal (2, 3) ; Bit 7 (HL), Stop/Weiter ; ; Ausgang: Nur Register HL darf veraendert werden ; RFLW23: PUSH AF PUSH BC LD B,0 ADD A,3EH ; Controlport LD C,A CP 40H ; SCCA ? LD A,(RTSA+1) JR Z,RFLW2 LD A,(RTSB+1) RFLW2: AND 01111101B ; RTS und DTR ausblenden BIT 7,(HL) JR NZ,RFLW3 ; Stop: RTS = 0 und DTR = 0 OR 10000010B ; Go : RTS = 1 und DTR = 1 RFLW3: PUSH AF LD A,5 OUT (C),A ; Write-Register 5 POP AF OUT (C),A POP BC POP AF RET ;........................................................................ ; ; X F L O W 2 3 ; XON/XOFF - Ausgabeflusskontrolle fuer SCC-Kanaele ; ; Eingang: A = Kanal (2, 3) ; Bit 0, 2 (HL) = 1 : XON/XOFF gewuenscht sonst nicht ; Ausgang: Nur HL veraendert ; XFLOW23: PUSH AF LD A,(HL) AND 0101B CP 0101B ; einstellen, wenn 0101 LD L,0 JR NZ,XFLOW2 SET 6,L ; Bit 6 = 1 : mit Flusskontrolle XFLOW2: POP AF PUSH AF CP 2 ; Kanal 2 = SCCB LD A,L JR Z,XFLOW1 LD (XFLGA),A POP AF RET XFLOW1: LD (XFLGB),A POP AF RET ;........................................................................ ; ; A F L O W ; Ausgabeflusskontrolle einstellen ; ; Eingang: A = phys. Kanalnummer ; Bit 0, 1, 2(HL) = Flusskontrolmodus ; ; Ausgang: Nur HL darf veraendert werden ; AFLOW: CP 5 JP Z,AFLOW5 ; Kanal 5: Ausgabeseitig ist immer CTS ; Flusskontrolle eingestellt, Software- ; Flusskontrolle mit XON/XOFF ist einschalt- ; bar, zusaetzlich einstellbar DSR-Flussk. CP 2 RET C ; Kanal 1 hat keine Ausgabeflusskontrolle CP 4 RET NC ; > 3 : --> PUSH HL CALL XFLOW23 ; XON/XOFF-Flusskontrolle einstellen POP HL JP CFLOW23 ; Auto-Enables on, wenn Bit 1(HL)=1 und 2(HL)=1 ;.................................................................. ; ; Eingabestop ; ; Eingang: A = phys. Kanalnummer (2, 3, 5) ; ESTOP: CP 7 RET NC ; Nicht existenter Kanal PUSH HL CALL FLWTYP ; Zeiger auf Flowmode - Tabelle berechnen BIT 3,(HL) JR Z,POPRET ; Keine Eingabeflusskontrolle erwuenscht BIT 7,(HL) ; War der Kanal schon gestoppt ? JR NZ,POPRET SET 7,(HL) ; Stopflag setzen ESTPGO: ; Ab hier Stop/Go identisch CP 2 JR Z,ESTOP23 CP 3 JR Z,ESTOP23 PUSH BC CP 5 CALL Z,EFLW5 ; AF wird nicht veraendert CP 1 CALL Z,EFLW1 POP BC POPRET: POP HL RET ESTOP23: BIT 0,(HL) ; XOFF senden ? CALL NZ,XFLW23 ; Bit 7 unterscheidet XON/XOFF BIT 1,(HL) ; DTR/RTS low setzen? CALL NZ,RFLW23 ; Bit 7 unterscheidet JR POPRET ;.................................................................. ; ; Eingabe Weiter ; ; Eingang: A = Kanalnummer (2, 3, 5) ; EGO: CP 7 RET NC ; Nicht existenter Kanal PUSH HL PUSH AF AND 1011B ; Kanal 1 oder 5 CP 1 CALL Z,CHKINT POP AF CALL FLWTYP ; Zeiger auf Flowmode - Tabelle berechnen BIT 3,(HL) JR Z,POPRET ; Keine Eingabeflusskontrolle erwuenscht BIT 7,(HL) ; War der Kanal gestoppt ? JR Z,POPRET ; Nein, return RES 7,(HL) ; Goflag setzen JR ESTPGO ; Wie Stop weiter ;----------------------------------------------------------------- ; ; C H K I N T ; ggf. Inputinterrupt aufrufen, falls 6502-IRQ nicht quittiert ; ; HL, A veraendert ; CHKINT: ; LD HL,DCOUNT ; Nicht immer CHKINT ; DEC (HL) ; Korr. 1.1 ; RET NZ ; LD (HL),100 PUSH BC LD HL,LOW INTPAR1 CALL RD6502 ; Byte aus Zeropage lesen AND A CALL NZ,INT6502 POP BC RET ;---------------------------------------------------------------- ; ; SCC Kanal A Initialisierung ; SCCAINI: DEFB 9,0C0H ; Force Hardware Reset (beide Kanaele) ; Master Interrupts disabled DEFB 2,20H ; Interrupt Vektor (beide Kanaele) DEFB 11,01010110B ; use Baudrategenerator Output BDSCCA: DEFB 12,18 ; Baud Rate Low, Default 9600 Baud DEFB 13,0 ; Baud Rate High DEFB 14,00000010B ; Baud Rate Gen. Source = PCLK BTSCCA: DEFB 4,01001100B ; No Parity, 2 Stopbits CTSA: DEFB 3,11000001B ; Enable Receiver, Datenbits RTSA: DEFB 5,11101010B ; Enable Transmitter, Datenbits ; DEFB 14,00000011B ; Enable Baudrategenerator DEFB 17,00010110B ; Receive/Transmit Interrupts Enable ; Reset Ext./STatus-Interrupts SCCALG EQU $-SCCAINI ; ; SCC Kanal B Initialisierung ; SCCBINI: DEFB 11,01010110B ; use Baudrategenerator Output BDSCCB: DEFB 12,18 ; Baud Rate Low, Default 9600 Baud DEFB 13,0 ; Baud Rate High DEFB 14,00000010B ; Baud Rate Gen. Source = PCLK BTSCCB: DEFB 4,01001100B ; No Parity, 2 Stopbits CTSB: DEFB 3,11000001B ; Enable Receiver, Datenbits RTSB: DEFB 5,11101010B ; Enable Transmitter, Datenbits ; DEFB 14,00000011B ; Enable Baudrategenerator DEFB 17,00010110B ; Receive/Transmit Interrupts Enable ; Reset Ext./Status-Interrupts DEFB 9,00001001B ; Master Interrupt Enable ; SCCBLG EQU $-SCCBINI ; ; Baudratentabelle fuer beide SCC-Kanaele ; BDTAB: DEFW 3838 ;50 Baud DEFW 2558 ;75 Baud DEFW 1743 ;110 Baud DEFW 1426 ;134.5 Baud DEFW 1278 ;150 Baud DEFW 638 ;300 Baud DEFW 318 ;600 Baud DEFW 158 ;1200 Baud DEFW 105 ;1800 Baud DEFW 78 ;2400 Baud DEFW 51 ;3600 Baud DEFW 38 ;4800 Baud DEFW 25 ;7200 Baud DEFW 18 ;9600 Baud DEFW 8 ;19200 Baud DEFW 3 ;38400 Baud ; ; Datenbereich ; ERRBIT: DEFB 0 ; Fehlerbits KANAL: DEFB 0 ; Kanal mit Eingabezeichen CCOUNT: DEFB 8 ; Cursorinvertier Zaehler ;DCOUNT: DEFB 0 ; CHKINT - Weiter Zaehler DRUCK: DEFW 0 ; aktuelle Groesse des Puffers DEFB HIGH DBUF ; Drucker-Pufferanfang DEFW DBUF ; Lesezeiger DEFW DBUF ; Schreibzeiger DEFB HIGH (DBUF+1000H); Druckerpufferende (excl.) SCCATAB: DEFW 0 ; Aktuelle Groesse des Puffers DEFB HIGH SABUF ; SCCA-Transmitbuffer Anfang im Basisspeicher DEFW SABUF ; Lesezeiger DEFW SABUF ; Schreibzeiger DEFB HIGH (SABUF+0800H); SCCA-Transmitbufferende (excl.) DEFB SCCAC ; Controlport XFLGA: DEFB 0 ; XON/XOFF auf SCCA ausgabeseitig ? SCCBTAB: DEFW 0 ; aktuelle Groesse des Puffers DEFB HIGH SBBUF ; SCCB-Transmitbuffer Anfang im Basispeicher DEFW SBBUF ; Lesezeiger DEFW SBBUF ; Schreibzeiger DEFB HIGH (SBBUF+0800H); SCCB-Transmitbufferende (excl.) DEFB SCCBC ; Controlport XFLGB: DEFB 0 ; XON/XOFF auf SCCB ausgabeseitig ? ;**************************************************************** END