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