/****************************************************************************
OS/A65 Version 1.3.3
Multitasking Operating System for 6502 Computers
Copyright (C) 1989-1998 Andre Fachat
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************/
/*
* WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
*
* This device is still in the old 1.3 source format.
* It also lacks the BRKKEY feature of the 1.4 kernel
*
* To use it, you have to convert it to 1.4 source format and
* implement the brkkey feature!
*/
/*
* This is a ACIA 6551 serial line driver for CS/A65. It uses the
* hardware installed in my personal C64. The 6551 is at address $d600.
*
* The ACIA 6551 has a real bad 'feature'. The RTS/CTS lines are not
* independent from the transmitter and receiver. Instead, making
* RTS high automatically disables receiver _and_ transmitter!
* Also an incoming CTS high immediately disables the transmitter.
* That's why I use the DSR input for the CTS modem line. This line
* can be checked independently.
*/
#ifdef ACIABASE
#define ACIA ACIABASE
#else
#define ACIA $d600
#endif
#print ACIA
#define Anzdev 1
.(
.word devend2
jmp prg1
.asc "ser", sernr ,0
-sernr += 1
/*
* status: Bit 0 = 1= handshake enabled
* 1 : 1= no ACIA found
* 5 : 1= set RTS hi
* 6 : 1= we are transmitting
* 7 : 1= we are receiving
*
*/
dev =sysmem
div =sysmem+1
status =sysmem+2
instr =sysmem+Anzdev*1+2
outstr =sysmem+Anzdev*2+2
-sysmem +=Anzdev*3+2
prg1 ldx #0
stx dev
cmp #DC_RES
beq devini
pha
lda status,x
and #2
beq prgok
pla
lda #E_NOTIMP
sec
rts
prgok pla
cmp #DC_IRQ
beq devirq
jmp others
devini lda #0
sta status,x
sta instr,x
sta outstr,x
STA ACIA+ACIA_SR ; programmed reset
LDA #%00011000 ; 1200 BAUD, 1 stop bit, 8 data bits
STA ACIA+ACIA_CTRL
cmp ACIA+ACIA_CTRL
bne devx
LDA #%00000101 ; no parity, normal receiver mode,
; RTS low, Tx interrupt enabled
STA ACIA+ACIA_CMD
cmp ACIA+ACIA_CMD
bne devx
LDA ACIA+ACIA_SR ; clear interrupt
clc
rts
devx lda status,x
ora #2
sta status,x
lda #E_NOTIMP
sec
rts
devirq
.(
lda ACIA+ACIA_SR
bpl irqend ; not this ACIA
tay
bit status ; check if receiving
bpl tx ; no -> tx
and #%00001000 ; Rx data register full?
beq nobyt ; no -> nobyt
ldx outstr
lda ACIA
jsr PUTC
bcs test
nobyt ldx outstr
lda #SC_STAT
jsr STRCMD
test bcc tx
cmp #E_NUL
bne tstwater
jsr rxoff
jmp tx
tstwater cmp #E_SEMPTY
beq wl
tax
lda status
and #1
bne wh
txa
cmp #E_SFULL
beq wh
cmp #E_SHWM
bne twl
wh ldx #0
jsr rtshi
jmp tx ; unbedingt
twl cmp #E_SLWM
bne tx
wl ldx #0
jsr rtslo
tx bit status
bvc irqhs
tya
and #%00010000 ; transmit data register empty?
beq irqhs ; no then -> irqhs
lda #32
bit status
bne endsend ; do not send any more to make RTS high.
tya
and #%01000000 ; DSR high?
bne irqhs ; -> irqhs
ldx instr ; send new data byte
jsr GETC
bcs test2
sta ACIA
bcc irqhs
test2 cmp #E_EOF
bne irqhs
jsr txoff
irqhs lda ACIA+ACIA_SR
lda #E_OK ; irq source removed
rts
irqend lda #E_NOIRQ ; no irq source found
rts
endsend
lda ACIA+ACIA_CMD
and #%11110011
sta ACIA+ACIA_CMD
jmp irqhs
.)
rtshi
lda status,x
ora #%00100000
sta status,x
rts
rtslo
lda ACIA+ACIA_CMD
ora #%00000100
sta ACIA+ACIA_CMD
lda status,x
and #%11011111
sta status,x
rts
others cmp #DC_GS
bne o1
lda status,x
and #DC_SW_TX
bne devonx
tya
sta instr,x
jmp ok
devonx jmp devon
o1 cmp #DC_PS
bne o2
lda status,x
and #DC_SW_RX
bne devonx
tya
sta outstr,x
okx jmp ok
o2 cmp #DC_RX_ON
bne o3
jsr rtslo
lda #DC_SW_RX
bne o2a
o3 cmp #DC_TX_ON
bne o4
lda #DC_SW_TX
o2a ora status,x
sta status,x
bne okx
o4 cmp #DC_RX_OFF
bne o5
rxoff ldx dev
lda status,x
and #DC_SW_RX
beq devoffx
lda outstr,x
tax
lda #SC_EOF
jsr STRCMD
ldx dev
lda status,x
and #255-DC_SW_RX
sta status,x
rx1off ;jsr rts1hi
;bcc okx
jmp okx
devoffx jmp devoff
o5 cmp #DC_TX_OFF
bne o6
txoff ldx dev
lda status,x
and #DC_SW_TX
beq devoffx
lda instr,x
tax
lda #SC_NUL
jsr STRCMD
ldx dev
lda status,x
and #255-DC_SW_TX
sta status,x
jmp ok
o6 cmp #DC_HS
bne o6a
lda status,x
and #255-1
sta status,x
tya
and #1
ora status,x
sta status,x
jmp ok
o6a cmp #DC_SPD
bne o7
tya
and #%00001111
sta div
lda ACIA+ACIA_CTRL
and #%11110000
ora div
sta ACIA+ACIA_CTRL
jmp ok
o7 cmp #DC_ST
beq ok
cmp #DC_EXIT
bne onotimp
jsr rxoff
jsr txoff
ldx dev
lda status,x
ora #2
sta status,x
sta ACIA+ACIA_SR ; programmed reset
bne ok
ok lda #E_OK
.byt $2c
devon lda #E_DON
.byt $2c
devoff lda #E_DOFF
.byt $2c
onotimp lda #E_NOTIMP
cmp #1
rts
devend2 .)