Kempston support

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Kempston support

Post 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
User avatar
PROSM
Manic Miner
Posts: 476
Joined: Fri Nov 17, 2017 7:18 pm
Location: Sunderland, England
Contact:

Re: Kempston support

Post 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.
All software to-date
Working on something, as always.
User avatar
TomD
Manic Miner
Posts: 379
Joined: Tue Nov 13, 2018 9:47 am
Location: Leeds UK
Contact:

Re: Kempston support

Post by TomD »

Easiest way to implement is:

Code: Select all

ld bc,0x001f
in a,(c)
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

Code: Select all

bit 4,a
jr nz,_thefireroutine
Some joysticks can have a second and even third fire button but they are rare.

TomD
Retro enthusiast and author of Flynn's Adventure in Bombland, The Order of Mazes & Maze Death Rally-X. Check them out at http://tomdalby.com
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Kempston support

Post 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

User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Kempston support

Post by sludge »

Theres also this part:

Code: Select all

js1		ld a,239
		in a, (254)
Perhaps the 254 needs to change?
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Kempston support

Post 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.
User avatar
TomD
Manic Miner
Posts: 379
Joined: Tue Nov 13, 2018 9:47 am
Location: Leeds UK
Contact:

Re: Kempston support

Post 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:
Retro enthusiast and author of Flynn's Adventure in Bombland, The Order of Mazes & Maze Death Rally-X. Check them out at http://tomdalby.com
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Kempston support

Post by sludge »

Cheers Tom, I'll have a play around with that routine.
User avatar
ketmar
Manic Miner
Posts: 716
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Kempston support

Post 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.
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Kempston support

Post 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
User avatar
ParadigmShifter
Manic Miner
Posts: 673
Joined: Sat Sep 09, 2023 4:55 am

Re: Kempston support

Post 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!
User avatar
ParadigmShifter
Manic Miner
Posts: 673
Joined: Sat Sep 09, 2023 4:55 am

Re: Kempston support

Post 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.
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Kempston support

Post 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.
User avatar
ketmar
Manic Miner
Posts: 716
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Kempston support

Post 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! ;-)
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Kempston support

Post 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.
User avatar
R-Tape
Site Admin
Posts: 6415
Joined: Thu Nov 09, 2017 11:46 am

Re: Kempston support

Post 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
	
	
User avatar
ParadigmShifter
Manic Miner
Posts: 673
Joined: Sat Sep 09, 2023 4:55 am

Re: Kempston support

Post 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 :)
Post Reply