1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-12-24 14:28:06 +11:00

recipes/sms/kbd: use Collapse OS' AVR assembler

This commit is contained in:
Virgil Dupras 2020-02-26 23:10:43 -05:00
parent 64a54c72f8
commit 97dcad9b15
7 changed files with 83 additions and 51 deletions

View File

@ -628,19 +628,19 @@ _parseArgs:
_readBit:
ld a, 7
jr _readExpr
jp _readExpr
_readA6:
ld a, 0x3f
jr _readExpr
jp _readExpr
_readA5:
ld a, 0x1f
jr _readExpr
jp _readExpr
_readK8:
ld a, 0xff
jr _readExpr
jp _readExpr
_readDouble:
push de
@ -707,6 +707,12 @@ _readR5:
push de
ld a, (hl)
call upcase
cp 'X'
jr z, .rdXYZ
cp 'Y'
jr z, .rdXYZ
cp 'Z'
jr z, .rdXYZ
cp 'R'
jr nz, .end ; not a register
inc hl
@ -717,6 +723,34 @@ _readR5:
.end:
pop de
ret
.rdXYZ:
; First, let's get a base value, that is, (A-'X'+26)*2, because XL, our
; lowest register, is equivalent to r26.
sub 'X'
rla ; no carry from sub
add a, 26
ld d, a ; store that
inc hl
ld a, (hl)
call upcase
cp 'H'
jr nz, .skip1
; second char is 'H'? our value is +1
inc d
jr .skip2
.skip1:
cp 'L'
jr nz, .end ; not L either? then it's not good
.skip2:
; Good, we have our final value in D and we're almost sure it's a valid
; register. Our only check left is that the 3rd char is a null.
inc hl
ld a, (hl)
or a
jr nz, .end
; we're good
ld a, d
jr .end
; Put DE's LSB into A and, additionally, ensure that the new value is <=
; than what was previously in A.

View File

@ -1,12 +1,5 @@
; *** CPU registers aliases ***
.equ XH 27
.equ XL 26
.equ YH 29
.equ YL 28
.equ ZH 31
.equ ZL 30
.equ SREG_C 0 ; Carry Flag
.equ SREG_Z 1 ; Zero Flag
.equ SREG_N 2 ; Negative Flag

View File

@ -1,11 +1,13 @@
PROGNAME = ps2ctl
AVRDUDEMCU ?= t45
AVRDUDEARGS ?= -c usbtiny -P usb
TARGETS = $(PROGNAME).hex os.sms
TARGETS = $(PROGNAME).bin os.sms
BASEDIR = ../../..
ZASM = $(BASEDIR)/emul/zasm/zasm
KERNEL = $(BASEDIR)/kernel
APPS = $(BASEDIR)/apps
AVRA = $(BASEDIR)/emul/zasm/avra
AVRINC = $(BASEDIR)/avr
# Rules
@ -14,14 +16,14 @@ APPS = $(BASEDIR)/apps
all: $(TARGETS)
@echo Done!
send: $(PROGNAME).hex
avrdude $(AVRDUDEARGS) -p $(AVRDUDEMCU) -U flash:w:$(PROGNAME).hex
send: $(PROGNAME).bin
avrdude $(AVRDUDEARGS) -p $(AVRDUDEMCU) -U flash:w:$(PROGNAME).bin
$(PROGNAME).hex: $(PROGNAME).asm
avra -o $@ $(PROGNAME).asm
$(PROGNAME).bin: $(PROGNAME).asm
$(AVRA) $(AVRINC) < $(PROGNAME).asm > $@
os.sms: glue.asm
$(ZASM) $(KERNEL) $(APPS) < glue.asm > $@
clean:
rm -f $(TARGETS) *.eep.hex *.obj os.bin
rm -f $(TARGETS)

View File

@ -55,7 +55,6 @@ either the low or high bits.
* 74xx157 (multiplexer)
* A NOR SR-latch. I used a 4043.
* Proto board, wires, IC sockets, etc.
* [AVRA][avra]
## Historical note
@ -114,4 +113,3 @@ Just hook it on. I've tried it, it works.
Did you get there? Feels pretty cool huh?
[rc2014-ps2]: ../../rc2014/ps2
[avra]: https://github.com/hsoft/avra

View File

@ -1,5 +1,3 @@
.include "tn45def.inc"
; 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
@ -30,17 +28,22 @@
; written.
; Z: pointer to the next scan code to push to the 595
;
.inc "avr.h"
.inc "tn254585.h"
.inc "tn45.h"
; *** Constants ***
.equ CLK = PINB2
.equ DATA = PINB1
.equ CP = PINB3
.equ CLK 2 ; Port B
.equ DATA 1 ; Port B
.equ CP 3 ; Port B
; SR-Latch's Q pin
.equ LQ = PINB0
.equ LQ 0 ; Port B
; SR-Latch's R pin
.equ LR = PINB4
.equ LR 4 ; Port B
; init value for TCNT0 so that overflow occurs in 100us
.equ TIMER_INITVAL = 0x100-100
.equ TIMER_INITVAL 0x100-100
; *** Code ***
@ -56,9 +59,9 @@ hdlINT0:
reti
main:
ldi r16, low(RAMEND)
ldi r16, RAMEND&0xff
out SPL, r16
ldi r16, high(RAMEND)
ldi r16, RAMEND}8
out SPH, r16
; init variables
@ -67,23 +70,23 @@ main:
; Setup int0
; INT0, falling edge
ldi r16, (1<<ISC01)
ldi r16, 0x02 ; ISC01
out MCUCR, r16
; Enable INT0
ldi r16, (1<<INT0)
ldi r16, 0x40 ; INT0
out GIMSK, r16
; Setup buffer
clr YH
ldi YL, low(SRAM_START)
ldi YL, SRAM_START&0xff
clr ZH
ldi ZL, low(SRAM_START)
ldi ZL, SRAM_START&0xff
; 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.
ldi r16, (1<<CS00) ; no prescaler
ldi r16, 0x01 ; CS00 - no prescaler
out TCCR0B, r16
; init DDRB
@ -101,7 +104,7 @@ loop:
; nothing to do. Before looping, let's check if our communication timer
; overflowed.
in r16, TIFR
sbrc r16, TOV0
sbrc r16, 1 ; TOV0
rjmp processbitReset ; Timer0 overflow? reset processbit
; Nothing to do for real.
@ -220,7 +223,7 @@ sendTo164Loop:
resetTimer:
ldi r16, TIMER_INITVAL
out TCNT0, r16
ldi r16, (1<<TOV0)
ldi r16, 0x02 ; TOV0
out TIFR, r16
ret
@ -237,8 +240,8 @@ sendToPS2:
; Wait until the timer overflows
in r16, TIFR
sbrs r16, TOV0
rjmp PC-2
sbrs r16, 1 ; TOV0
rjmp $-4
; Good, 100us passed.
; Pull Data low, that's our start bit.
@ -258,7 +261,7 @@ sendToPS2:
sendToPS2Loop:
; Wait for CLK to go low
sbic PINB, CLK
rjmp PC-1
rjmp $-2
; set up DATA
cbi PORTB, DATA
@ -268,7 +271,7 @@ sendToPS2Loop:
; Wait for CLK to go high
sbis PINB, CLK
rjmp PC-1
rjmp $-2
dec r16
brne sendToPS2Loop ; not zero? loop
@ -279,7 +282,7 @@ sendToPS2Loop:
; Wait for CLK to go low
sbic PINB, CLK
rjmp PC-1
rjmp $-2
; set parity bit
cbi PORTB, DATA
@ -288,22 +291,22 @@ sendToPS2Loop:
; Wait for CLK to go high
sbis PINB, CLK
rjmp PC-1
rjmp $-2
; Wait for CLK to go low
sbic PINB, CLK
rjmp PC-1
rjmp $-2
; We can now release the DATA line
cbi DDRB, DATA
; Wait for DATA to go low. That's our ACK
sbic PINB, DATA
rjmp PC-1
rjmp $-2
; Wait for CLK to go low
sbic PINB, CLK
rjmp PC-1
rjmp $-2
; We're finished! Enable INT0, reset timer, everything back to normal!
rcall resetTimer
@ -314,21 +317,21 @@ sendToPS2Loop:
; Check that Y is within bounds, reset to SRAM_START if not.
checkBoundsY:
tst YL
breq PC+2
breq $+4
ret ; not zero, nothing to do
; YL is zero. Reset Y
clr YH
ldi YL, low(SRAM_START)
ldi YL, SRAM_START&0xff
ret
; Check that Z is within bounds, reset to SRAM_START if not.
checkBoundsZ:
tst ZL
breq PC+2
breq $+4
ret ; not zero, nothing to do
; ZL is zero. Reset Z
clr ZH
ldi ZL, low(SRAM_START)
ldi ZL, SRAM_START&0xff
ret
; Counts the number of 1s in r19 and set r16 to 1 if there's an even number of
@ -336,10 +339,10 @@ checkBoundsZ:
checkParity:
ldi r16, 1
lsr r19
brcc PC+2 ; Carry unset? skip next
brcc $+4 ; Carry unset? skip next
inc r16 ; Carry set? We had a 1
tst r19 ; is r19 zero yet?
brne checkParity+1 ; no? loop and skip first LDI
brne checkParity+2 ; no? loop and skip first LDI
andi r16, 0x1 ; Sets Z accordingly
ret

View File

@ -24,3 +24,5 @@ jmp bar
mov r6, r30
lsl r3
tst r12
clr YH
clr r29

Binary file not shown.