mirror of
https://github.com/ksherlock/itty-bitty-vtty.git
synced 2024-06-14 06:29:29 +00:00
1cc501e72a
this also adds a hexdump in the CDA for the outgoing buffer in local mode, "incoming" data is read from the outgoing buffer. Currently data is (potentially) sent on each run of the main loop. I thought about using the TX empty interrupt but it still needs to be kicked off at some point (unlike incoming data)
363 lines
4.6 KiB
ArmAsm
363 lines
4.6 KiB
ArmAsm
|
|
lst off
|
|
rel
|
|
xc
|
|
xc
|
|
|
|
mx %11
|
|
cas se
|
|
use vt.equ
|
|
use debug
|
|
|
|
SCCBREG equ $c038
|
|
SCCAREG equ $c039
|
|
SCCBDATA equ $c03a
|
|
SCCADATA equ $c03b
|
|
|
|
|
|
SerFlag equ $e10104 ;
|
|
|
|
*
|
|
* scc speed:
|
|
*
|
|
* time constant = ( clock / (2 * clock mode * baud rate)) - 2
|
|
* baud rate = clock / ( 2 * clock mode * (time constant + 2))
|
|
*
|
|
* clock mode = 1x, 16x, 32x, or 64x (selected via write register 4 bits 6/7)
|
|
* clock = 3.6864 MHz crystal (scc runs at 14.31818 / 4 = ~ 3.58 Mhz)
|
|
* time constant = write register 12 (low) + 13 (high)
|
|
*
|
|
*
|
|
* see IIgs TN #18 - Do-It-Yourself SCC Access
|
|
|
|
init_modem ent
|
|
* sep #$30
|
|
|
|
php
|
|
sei
|
|
|
|
stz read_q_head
|
|
stz read_q_tail
|
|
stz write_q_head
|
|
stz write_q_tail
|
|
|
|
|
|
* zero out the buffer [for CDA debugger]
|
|
ldx #0
|
|
]loop stz read_buffer,x
|
|
inx
|
|
bne ]loop
|
|
|
|
|
|
lda SCCBREG ; sync access
|
|
ldx #0
|
|
|
|
]loop
|
|
lda :table,x
|
|
bmi :done
|
|
sta SCCBREG
|
|
inx
|
|
lda :table,x
|
|
sta SCCBREG
|
|
inx
|
|
bra ]loop
|
|
:done
|
|
|
|
* adjust SerFlag so serial IRQs will be handled.
|
|
lda >SerFlag
|
|
ora #%00_000_111 ; channel B interrupts.
|
|
sta >SerFlag
|
|
|
|
plp
|
|
rts
|
|
|
|
:table ; register, value
|
|
* db 9,%01_0_1_0_0_0_1 ; reset channel B (modem port) - handled @ startup.
|
|
db 4,%01_00_01_0_0 ; x16 clock, 1 stop bit, no parity
|
|
db 3,%11_0_0_0_0_0_0 ; 8 bits, rx disabled
|
|
db 5,%0_11_0_0_0_1_0 ; 8 bits, RTS
|
|
db 11,%0_10_10_0_00 ; modem port, rcv/tx clock = br
|
|
db 12,10 ; 9600 baud (low)
|
|
db 13,0 ; 9600 baud (high)
|
|
db 14,0 ; disable baud rate generator
|
|
db 14,%000_0_0_0_0_1 ; enable baud rate generator
|
|
db 3,%11_0_0_0_0_0_1 ; 8 bits, rx enabled
|
|
db 5,%0_11_0_1_0_1_0 ; 8 bits, tx enabled, RTS
|
|
db 15,0 ; disable external interrupts
|
|
db 0,%00_010_0_00 ; reset ext/status interrupts
|
|
db 1,%0_0_0_10_0_0_0 ; interrupts on rx or special condition
|
|
db 9,%00_0_0_1_0_1_0 ; master interrupts enabled.
|
|
db -1,-1
|
|
|
|
write_modem_sync ent
|
|
mx %11
|
|
* a: byte to send
|
|
tay ; save
|
|
* ldx #0
|
|
php
|
|
|
|
|
|
:mask = %0010_0100 ; tx buffer empty, clear to send
|
|
:wait
|
|
cli ; guard scc register access.
|
|
sei
|
|
stz SCCBREG
|
|
lda SCCBREG
|
|
and #:mask
|
|
cmp #:mask
|
|
bne :wait
|
|
|
|
sty SCCBDATA
|
|
plp
|
|
rts
|
|
|
|
|
|
read_modem_sync ent
|
|
* c set if data read
|
|
* v set if overrun
|
|
mx %11
|
|
* ldx #0
|
|
rep #$41 ; clear C + V
|
|
stz SCCBREG
|
|
lda SCCBREG
|
|
and #%0001
|
|
beq :rts
|
|
|
|
* read reg 1 for overrun
|
|
lda #1
|
|
sta SCCBREG
|
|
lda SCCBREG
|
|
and #%0010_0000
|
|
beq :ok
|
|
|
|
* clear the overrun
|
|
lda #$30 ; reg0, error reset.
|
|
sta SCCBREG
|
|
stz SCCBREG
|
|
sep #$40 ; V
|
|
:ok
|
|
* lda #8
|
|
* sta SCCBREG
|
|
* lda SCCBREG
|
|
lda SCCBDATA
|
|
|
|
* debugging...
|
|
|
|
|
|
sec
|
|
:rts rts
|
|
|
|
|
|
write_buffer equ $1d00
|
|
read_buffer equ $1e00
|
|
|
|
modem_vector ent
|
|
jml modem_int
|
|
modem_int
|
|
*
|
|
* called in 8-bit native mode, interrupts disabled.
|
|
* d = unknown
|
|
* a/x/y don't need to be preserved.
|
|
* return carry clear if handled, carry set if not.
|
|
|
|
* doesn't access direct page.
|
|
|
|
* check/clear overrun?
|
|
mx %11
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
stz SCCBREG
|
|
lda SCCBREG
|
|
and #%0000_0001 ; rx ready.
|
|
beq :nope
|
|
|
|
:read
|
|
lda SCCBDATA
|
|
ldx DPAGE+read_q_tail
|
|
sta read_buffer,x
|
|
inc DPAGE+read_q_tail
|
|
|
|
* more?
|
|
stz SCCBREG
|
|
lda SCCBREG
|
|
and #%0000_0001 ; rx ready.
|
|
bne :read
|
|
clc
|
|
bra :finish
|
|
|
|
:nope
|
|
|
|
sec
|
|
:finish
|
|
* reset errors.
|
|
lda #%00_110_000
|
|
stz SCCBREG
|
|
sta SCCBREG
|
|
|
|
* reset highest ius
|
|
lda #%00_111_000
|
|
stz SCCBREG
|
|
sta SCCBREG
|
|
|
|
plb
|
|
rtl
|
|
|
|
|
|
|
|
modem_io ent
|
|
debug modem_io
|
|
|
|
mx %11
|
|
php
|
|
sei
|
|
bit LOCAL
|
|
bmi :local
|
|
|
|
:write
|
|
* send any outbound data...
|
|
|
|
:mask = %0010_0100 ; tx buffer empty, clear to send
|
|
ldx write_q_tail
|
|
cpx write_q_head
|
|
beq :read
|
|
|
|
lda SCCBREG ; sync
|
|
stz SCCBREG
|
|
lda SCCBREG
|
|
and #:mask
|
|
cmp #:mask
|
|
bne :read
|
|
|
|
* ldx write_q_tail
|
|
lda write_buffer,x
|
|
sta SCCBDATA
|
|
inc write_q_tail
|
|
:read
|
|
ldx read_q_tail
|
|
cpx read_q_head
|
|
beq :nope
|
|
lda read_buffer,x
|
|
inc read_q_tail
|
|
plp
|
|
sec
|
|
rts
|
|
|
|
:nope
|
|
plp
|
|
clc
|
|
rts
|
|
|
|
|
|
:local
|
|
ldx write_q_tail
|
|
cpx write_q_head
|
|
beq :nope
|
|
lda write_buffer,x
|
|
inc write_q_tail
|
|
plp
|
|
sec
|
|
rts
|
|
|
|
|
|
|
|
write_modem ent
|
|
write_modem_async ent
|
|
|
|
mx %11
|
|
php
|
|
sei
|
|
|
|
* bit LOCAL
|
|
* bmi :local
|
|
|
|
ldx write_q_head
|
|
sta write_buffer,x
|
|
inc write_q_head
|
|
plp
|
|
rts
|
|
*:local
|
|
* ldx read_q_head
|
|
* sta read_buffer,x
|
|
* inc read_q_head
|
|
* plp
|
|
* rts
|
|
|
|
|
|
write_modem_str ent
|
|
|
|
; y = address of string (0-terminated)
|
|
; inc write_q_head vs inx
|
|
; because it wraps at $ff
|
|
|
|
mx %10
|
|
php
|
|
sei
|
|
* bit LOCAL
|
|
* bmi :local
|
|
|
|
:loop lda |$0000,y
|
|
beq :fini
|
|
ldx write_q_head
|
|
sta write_buffer,x
|
|
inc write_q_head
|
|
iny
|
|
bra :loop
|
|
|
|
*:local lda |$0000,y
|
|
* beq :fini
|
|
* ldx read_q_head
|
|
* sta read_buffer,x
|
|
* inc read_q_head
|
|
* iny
|
|
* bra :local
|
|
|
|
|
|
:fini
|
|
plp
|
|
rts
|
|
|
|
|
|
|
|
|
|
read_modem ent
|
|
read_modem_async ent
|
|
|
|
mx %11
|
|
|
|
php
|
|
sei
|
|
ldx read_q_head
|
|
cpx read_q_tail
|
|
beq :nope
|
|
|
|
lda read_buffer,x
|
|
inc read_q_head
|
|
plp
|
|
sec
|
|
rts
|
|
|
|
:nope
|
|
plp
|
|
clc
|
|
rts
|
|
|
|
reset_modem_buffer ent
|
|
mx %11
|
|
php
|
|
sei
|
|
|
|
stz read_q_head
|
|
stz read_q_tail
|
|
stz write_q_head
|
|
stz write_q_tail
|
|
|
|
plp
|
|
rts
|
|
|
|
*buffer ds 256
|
|
|
|
sav vt100.modem.L
|