cdddfdefae
This will make it easier to fit BR* in there.
99 lines
2.5 KiB
Forth
99 lines
2.5 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
|
|
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
|
|
|
|
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 FRJMP! ( hdlINT0 )
|
|
PINB DATA SBIC,
|
|
GPIOR0 0 SBI,
|
|
SET,
|
|
RETI,
|
|
|
|
L1 FRJMP! ( 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 )
|
|
|