Page 1 of 1
Kempston support
Posted: Tue Apr 09, 2024 8:14 pm
by sludge
How do you go about supporting Kempston joystick in games?
I think its IN 31 but I haven't a clue about the up/down/left/right/fire bits.
This is the routine I use for Sinclair (I think it will make sense), how would you adapt it for Kempston?
Code: Select all
Sinclair
ld a,239
ld (js1+1),a
ld (downx+4),a
ld (upx+4),a
ld (leftx+4),a
ld (js2+1),a
ld a,2
ld (stickup+1),a
ld a,4
ld (stickdown+1),a
ld a,16
ld (stickleft+1),a
ld a,8
ld (stickright+1),a
ld a,$01
ld (js3+1),a
ret
Re: Kempston support
Posted: Tue Apr 09, 2024 8:27 pm
by PROSM
For the Kempston, you read from port 31. The received byte is as follows:
Code: Select all
000FUDLR
(F - fire, U - up, D - down, L - left, R - right)
The Kempston joystick input is active-high, meaning that if the button/direction is activated, the relevant bit will be 1. This is in contrast to the keyboard, which is active-low, where a pressed key will result in the relevant bit being 0.
Bear in mind that the three most significant bits might not necessarily be zero on every hardware setup, so it's best to mask away those bits like you would with the keyboard.
I'm afraid I don't know what's going on with the routine you've posted - there's no IN instructions to actually read the keyboard data, so presumably it's only part of a larger routine.
Re: Kempston support
Posted: Tue Apr 09, 2024 8:29 pm
by TomD
Easiest way to implement is:
then check which bit is set in a
fire is bit 4
up is bit 3
down is bit 2
left is bit 1
right is bit 0
Some joysticks can have a second and even third fire button but they are rare.
TomD
Re: Kempston support
Posted: Tue Apr 09, 2024 8:38 pm
by sludge
Tried this but it wont work, character just keeps moving right.
Code: Select all
kempston
ld a,31
ld (js1+1),a
ld (downx+4),a
ld (upx+4),a
ld (leftx+4),a
ld (js2+1),a
ld a,3
ld (stickup+1),a
ld a,2
ld (stickdown+1),a
ld a,1
ld (stickleft+1),a
ld a,0
ld (stickright+1),a
ld a,4
ld (js3+1),a
ret
Re: Kempston support
Posted: Tue Apr 09, 2024 8:40 pm
by sludge
Theres also this part:
Perhaps the 254 needs to change?
Re: Kempston support
Posted: Tue Apr 09, 2024 9:08 pm
by sludge
Ah right, I realised why I never bothered with Kempston, if no Kempston is present IN31 automatically reads it as fire being pressed.
That means the game starts automatically with Kempston controls even though no Kempston is connected.
Re: Kempston support
Posted: Tue Apr 09, 2024 9:17 pm
by TomD
sludge wrote: ↑Tue Apr 09, 2024 9:08 pm
Ah right, I realised why I never bothered with Kempston, if no Kempston is present IN31 automatically reads it as fire being pressed.
That means the game starts automatically with Kempston controls even though no Kempston is connected.
Following code from JetSet Willy checks if Kempston is connected
Code: Select all
xor a
ld (kempston),a ; reset kempston present flag
ld bc,0x001f
di
xor a
loop:
in e,(c)
or e
djnz loop ; check for all b's
and %00100000 ; checks if bit 5 set, will be zero if kempston present
jr nz,end
ld a,0x01
ld (kempston),a ; set kempston present
end:
Re: Kempston support
Posted: Tue Apr 09, 2024 9:33 pm
by sludge
Cheers Tom, I'll have a play around with that routine.
Re: Kempston support
Posted: Tue Apr 09, 2024 10:36 pm
by ketmar
that's how i detect kempston joystick in my code. HL is 0 if no kemprson joystick present, 1 otherwise.
Code: Select all
ld hl, # 0
;; zero flag
xor a
;; wait for the interrupt to avoid floating bus issue
halt
in a, () $1F
;; $FF? nothing's here
inc a
\ jr z, # .done
ret z
;; test for some invalid values
dec a
ld e, a
and # $E0
\ jr nz, # .done
ret nz
ld a, e
and # $03
cp # $03
\ jr z, # .done ;; left & right pressed simultaneously. ???
ret z
ld a, e
and # $0C
cp # $0C
\ jr z, # .done ;; up & down pressed simultaneously. ???
ret z
inc l ;; change the flag
ret
do not forget "HALT" instruction, it is important to not read some ULA garbage here.
Re: Kempston support
Posted: Wed Apr 10, 2024 1:48 am
by sludge
I'm still a bit flummoxed with the bits not working - perhaps the 254 part has something to do with it?
This is what I use on the title screen to load Kempston values into the game code:
Code: Select all
kempston
ld a,31
ld (js1+1),a
ld (downx+4),a
ld (upx+4),a
ld (leftx+4),a
ld (js2+1),a
ld a,3
ld (stickup+1),a
ld a,2
ld (stickdown+1),a
ld a,1
ld (stickleft+1),a
ld a,0
ld (stickright+1),a
ld a,4
ld (js3+1),a
ret
This is part of the game code which is set up for Sinclair joystick:
Code: Select all
js2 ld a,239
in a, (254)
js3 and 1
call z,fire
js1 ld a,239
in a, (254)
stickdown
and 4
jr nz,downx
Re: Kempston support
Posted: Wed Apr 10, 2024 1:56 am
by ParadigmShifter
You're just loading the same value into several addresses?
Code: Select all
ld a,31
ld (js1+1),a
ld (downx+4),a
ld (upx+4),a
ld (leftx+4),a
ld (js2+1),a
are you thinking each bit is in fact a byte or something? I dunno. Your code is weird sorry!
Re: Kempston support
Posted: Wed Apr 10, 2024 2:05 am
by ParadigmShifter
Right I see you are trying to self modify the code to change IN 254 to IN 31. EDIT: Also reading from the same input port more than once a frame seems a bit pointless really... read it once per frame.
Well that's a bad plan tbh. Just have 2 routines. Remember the logic for keyboard and kempston (pressed = 0 for kbd, pressed = 1 for kempston) is opposite as well.
Only self modify code if it makes it faster or smaller. Your code looks like neither? You'd be better off with a function pointer to jump to a routine to handle keyboard or joystick as appropriate.
Re: Kempston support
Posted: Wed Apr 10, 2024 6:06 am
by sludge
Excuse my coding, it was written over thirty year ago on graph paper in a maths lesson.
I've never got round to modifying that bit of the code although the rest of the game code isnt much better either.
My coding skills are quite shocking, I doubt I know how to use any more than twenty Z80 commands properly.
Re: Kempston support
Posted: Wed Apr 10, 2024 6:11 am
by ketmar
sludge wrote: ↑Wed Apr 10, 2024 6:06 am
My coding skills are quite shocking, I doubt I know how to use any more than twenty Z80 commands properly.
more than enough! "LD" alone occupies about 1/3 of the whole non-prefixed instruction set! ;-)
Re: Kempston support
Posted: Wed Apr 10, 2024 6:32 am
by sludge
ketmar wrote: ↑Wed Apr 10, 2024 6:11 am
more than enough! "LD" alone occupies about 1/3 of the whole non-prefixed instruction set!
True.
Re: Kempston support
Posted: Wed Apr 10, 2024 7:12 am
by R-Tape
sludge wrote: ↑Wed Apr 10, 2024 1:48 am
This is what I use on the title screen to load Kempston values into the game code:
It might be less confusing to have 3 separate routines rather than all that code poking. So e.g. on the intro page you have a byte that says what control option has been selected, the game code could look something like this:
Code: Select all
....main game loop
call playercontrol
....
playercontrol:
ld a,(controlbyte)
cp 0
jr z,keys
cp 1
jr z,sinclair
cp 2
jr z,kempston
Re: Kempston support
Posted: Thu Apr 11, 2024 1:38 am
by ParadigmShifter
For more than a few cases of an IF statement like that I prefer function pointers e.g.
Code: Select all
ld hl, (controlmethod)
jp (hl)
DoneInput:
where controlmethod points to a routine that handles the specific input and ends with a jp DoneInput. jp (hl) is the fastest jump of all (4T!). Of course jp (hl) is a terrible name for the opcode it should be JP HL...
You can call a routine instead by doing this instead
Code: Select all
ld hl, (controlmethod)
call jphl
; will return to here
; elsewhere
jphl: jp (hl)
but that isn't as efficient (not that input matters really since it's a lot faster than drawing graphics etc.). You can even search through the ROM or your own data to find a byte that is same as jp (hl) (#E9 hex) so you don't need to waste a byte in your code