sms/pad: new module to manage Megadrive controller in SMS
This commit is contained in:
parent
ca5bc07a75
commit
9eb80d5eac
49
kernel/sms/pad.asm
Normal file
49
kernel/sms/pad.asm
Normal file
@ -0,0 +1,49 @@
|
||||
; pad - read input from MD controller
|
||||
;
|
||||
; Conveniently expose an API to read the status of a MD pad. Moreover,
|
||||
; implement a mechanism to input arbitrary characters from it. It goes as
|
||||
; follow:
|
||||
;
|
||||
; * Direction pad select characters. Up/Down move by one, Left/Right move by 5\
|
||||
; * Start acts like Return
|
||||
; * A acts like Backspace
|
||||
; * B changes "character class": lowercase, uppercase, numbers, special chars.
|
||||
; The space character is the first among special chars.
|
||||
; * C confirms letter selection
|
||||
;
|
||||
; *** Consts ***
|
||||
;
|
||||
.equ PAD_CTLPORT 0x3f
|
||||
.equ PAD_D1PORT 0xdc
|
||||
|
||||
; *** Variables ***
|
||||
;
|
||||
; *** Code ***
|
||||
|
||||
; Put status for port A in register A. Bits, from MSB to LSB:
|
||||
; Start - A - C - B - Right - Left - Down - Up
|
||||
; Each bit is high when button is unpressed and low if button is pressed. For
|
||||
; example, when no button is pressed, 0xff is returned.
|
||||
padStatusA:
|
||||
; This logic below is for the Genesis controller, which is modal. TH is
|
||||
; an output pin that swiches the meaning of TL and TR. When TH is high
|
||||
; (unselected), TL = Button B and TR = Button C. When TH is low
|
||||
; (selected), TL = Button A and TR = Start.
|
||||
push bc
|
||||
ld a, 0b11111101 ; TH output, unselected
|
||||
out (PAD_CTLPORT), a
|
||||
in a, (PAD_D1PORT)
|
||||
and 0x3f ; low 6 bits are good
|
||||
ld b, a ; let's store them
|
||||
; Start and A are returned when TH is selected, in bits 5 and 4. Well
|
||||
; get them, left-shift them and integrate them to B.
|
||||
ld a, 0b11011101 ; TH output, selected
|
||||
out (PAD_CTLPORT), a
|
||||
in a, (PAD_D1PORT)
|
||||
and 0b00110000
|
||||
sla a
|
||||
sla a
|
||||
or b
|
||||
; we're good now!
|
||||
pop bc
|
||||
ret
|
@ -1,11 +1,14 @@
|
||||
di
|
||||
im 1
|
||||
jp main
|
||||
|
||||
.fill 0x66-$
|
||||
retn
|
||||
|
||||
#include "sms/pad.asm"
|
||||
|
||||
main:
|
||||
di
|
||||
im 1
|
||||
|
||||
ld sp, 0xdff0
|
||||
|
||||
ld hl, VdpData
|
||||
@ -60,45 +63,30 @@ mainloop:
|
||||
; What we do here is simple. We go though all bits of port A controller
|
||||
; increasing B each time. As soon as we get a hit, we display that
|
||||
; letter. Pressed buttons go low.
|
||||
; This logic below is for the Genesis controller, which is modal. TH is
|
||||
; an output pin that swiches the meaning of TL and TR. When TH is high
|
||||
; (unselected), TL = Button B and TR = Button C. When TH is low
|
||||
; (selected), TL = Button A and TR = Start.
|
||||
ld a, 0b11111101 ; TH output, unselected
|
||||
out (0x3f), a
|
||||
call padStatusA
|
||||
ld b, 0x41 ; a
|
||||
in a, (0xdc) ; I/O port
|
||||
and 0b00100000 ; Port A Button C pressed
|
||||
bit 5, a ; Port A Button C pressed
|
||||
jr z, updateLetter
|
||||
inc b ; b
|
||||
in a, (0xdc)
|
||||
and 0b00010000 ; Port A Button B pressed
|
||||
bit 4, a ; Port A Button B pressed
|
||||
jr z, updateLetter
|
||||
inc b ; c
|
||||
in a, (0xdc)
|
||||
and 0b00001000 ; Port A Right pressed
|
||||
bit 3, a ; Port A Right pressed
|
||||
jr z, updateLetter
|
||||
inc b ; d
|
||||
in a, (0xdc)
|
||||
and 0b00000100 ; Port A Left pressed
|
||||
bit 2, a ; Port A Left pressed
|
||||
jr z, updateLetter
|
||||
inc b ; e
|
||||
in a, (0xdc)
|
||||
and 0b00000010 ; Port A Down pressed
|
||||
bit 1, a ; Port A Down pressed
|
||||
jr z, updateLetter
|
||||
inc b ; f
|
||||
in a, (0xdc)
|
||||
and 0b00000001 ; Port A Up pressed
|
||||
bit 0, a ; Port A Up pressed
|
||||
jr z, updateLetter
|
||||
ld a, 0b11011101 ; TH output, unselected
|
||||
out (0x3f), a
|
||||
inc b ; g
|
||||
in a, (0xdc)
|
||||
and 0b00010000 ; Port A Button A pressed
|
||||
bit 6, a ; Port A Button A pressed
|
||||
jr z, updateLetter
|
||||
inc b ; h
|
||||
in a, (0xdc)
|
||||
and 0b00100000 ; Port A Start pressed
|
||||
bit 7, a ; Port A Start pressed
|
||||
jr z, allLetters ; when start is pressed, print all letters
|
||||
; no button pressed on port A, continue to updateLetter
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user