mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-06 00:50:55 +11:00
6a55a04f22
next step: implement ST.
136 lines
3.6 KiB
Forth
136 lines
3.6 KiB
Forth
( Receives keystrokes from PS/2 keyboard and send them to the
|
|
'164. On the PS/2 side, it works the same way as the controller
|
|
in the rc2014/ps2 recipe. However, in this case, what we have
|
|
on the other side isn't a z80 bus, it's the one of the two
|
|
controller ports of the SMS through a DB9 connector.
|
|
|
|
The PS/2 related code is copied from rc2014/ps2 without much
|
|
change. The only differences are that it pushes its data to a
|
|
'164 instead of a '595 and that it synchronizes with the SMS
|
|
with a SR latch, so we don't need PCINT. We can also afford to
|
|
run at 1MHz instead of 8.
|
|
|
|
*** Register Usage ***
|
|
|
|
GPIOR0 flags:
|
|
0 - when set, indicates that the DATA pin was high when we
|
|
received a bit through INT0. When we receive a bit, we set
|
|
flag T to indicate it.
|
|
|
|
R16: tmp stuff
|
|
R17: recv buffer. Whenever we receive a bit, we push it in
|
|
there.
|
|
R18: recv step:
|
|
- 0: idle
|
|
- 1: receiving data
|
|
- 2: awaiting parity bit
|
|
- 3: awaiting stop bit
|
|
R19: Register used for parity computations and tmp value in
|
|
some other places
|
|
R20: data being sent to the '164
|
|
Y: pointer to the memory location where the next scan code from
|
|
ps/2 will be written.
|
|
Z: pointer to the next scan code to push to the 595 )
|
|
|
|
0x0060 CONSTANT SRAM_START
|
|
0x015f CONSTANT RAMEND
|
|
0x3d CONSTANT SPL
|
|
0x3e CONSTANT SPH
|
|
0x11 CONSTANT GPIOR0
|
|
0x35 CONSTANT MCUCR
|
|
0x33 CONSTANT TCCR0B
|
|
0x3b CONSTANT GIMSK
|
|
0x38 CONSTANT TIFR
|
|
0x16 CONSTANT PINB
|
|
0x17 CONSTANT DDRB
|
|
0x18 CONSTANT PORTB
|
|
2 CONSTANT CLK
|
|
1 CONSTANT DATA
|
|
3 CONSTANT CP
|
|
0 CONSTANT LQ
|
|
4 CONSTANT LR
|
|
0x100-100 CONSTANT TIMER_INITVAL
|
|
( We need a lot of labels in this program... )
|
|
VARIABLE L5 VARIABLE L6 VARIABLE L7 VARIABLE L8
|
|
|
|
H@ ORG !
|
|
L1 FLBL, ( main )
|
|
L2 FLBL, ( hdlINT0 )
|
|
|
|
( Read DATA and set GPIOR0/0 if high. Then, set flag T.
|
|
no SREG fiddling because no SREG-modifying instruction )
|
|
L2 ' RJMP FLBL! ( hdlINT0 )
|
|
PINB DATA SBIC,
|
|
GPIOR0 0 SBI,
|
|
SET,
|
|
RETI,
|
|
|
|
L1 ' RJMP FLBL! ( main )
|
|
16 RAMEND 0xff AND LDI,
|
|
SPL 16 OUT,
|
|
16 RAMEND 8 RSHIFT LDI,
|
|
SPH 16 OUT,
|
|
( init variables )
|
|
18 CLR,
|
|
GPIOR0 18 OUT,
|
|
( Setup int0
|
|
INT0, falling edge )
|
|
16 0x02 ( ISC01 ) LDI,
|
|
MCUCR 16 OUT,
|
|
( Enable INT0 )
|
|
16 0x40 ( INT0 ) LDI,
|
|
GIMSK 16 OUT,
|
|
( Setup buffer )
|
|
29 ( YH ) CLR,
|
|
28 ( YL ) SRAM_START 0xff AND LDI,
|
|
31 ( ZH ) CLR,
|
|
30 ( ZL ) SRAM_START 0xff AND LDI,
|
|
( Setup timer. We use the timer to clear up "processbit"
|
|
registers after 100us without a clock. This allows us to start
|
|
the next frame in a fresh state. at 1MHZ, no prescaling is
|
|
necessary. Each TCNT0 tick is already 1us long. )
|
|
16 0x01 ( CS00 ) LDI, ( no prescaler )
|
|
TCCR0B 16 OUT,
|
|
( init DDRB )
|
|
DDRB CP SBI,
|
|
PORTB LR CBI,
|
|
DDRB LR SBI,
|
|
SEI,
|
|
|
|
L1 LBL! ( loop )
|
|
L2 FLBL, ( BRTS processbit. flag T set? we have a bit to
|
|
process )
|
|
28 ( YL ) 30 ( ZL ) CP, ( if YL == ZL, buf is empty )
|
|
L3 FLBL, ( BRNE sendTo164. YL != ZL? buf has data )
|
|
( nothing to do. Before looping, let's check if our
|
|
communication timer overflowed. )
|
|
16 TIFR IN,
|
|
16 1 ( TOV0 ) SBRC,
|
|
L4 FLBL, ( RJMP processbitReset, timer0 overflow? reset )
|
|
( Nothing to do for real. )
|
|
L1 ' RJMP LBL, ( loop )
|
|
|
|
( Process the data bit received in INT0 handler. )
|
|
L2 ' BRTS FLBL! ( processbit )
|
|
19 GPIOR0 IN, ( backup GPIOR0 before we reset T )
|
|
19 0x1 ANDI, ( only keep the first flag )
|
|
GPIOR0 0 CBI,
|
|
CLT, ( ready to receive another bit )
|
|
|
|
( We've received a bit. reset timer )
|
|
L2 FLBL, ( RCALL resetTimer )
|
|
|
|
( Which step are we at? )
|
|
18 TST,
|
|
L5 FLBL, ( BREQ processbits0 )
|
|
18 1 CPI,
|
|
L6 FLBL, ( BREQ processbits1 )
|
|
18 2 CPI,
|
|
L7 FLBL, ( BREQ processbits2 )
|
|
( step 3: stop bit )
|
|
18 CLR, ( happens in all cases )
|
|
( DATA has to be set )
|
|
19 TST, ( was DATA set? )
|
|
L1 ' BREQ FLBL! ( loop, not set? error, don't push to buf )
|
|
( push r17 to the buffer )
|