fast joystick support in assembler

Page 2/3
1 | | 3

Par NYYRIKKI

Enlighted (5615)

Portrait de NYYRIKKI

01-07-2016, 16:41

Ok, I then add my example as well...

I force all other bits except 7 in PSG register 15 as wrong values in bits 0-3 can incorrectly return that triggers are pressed and wrong values in bits 4-5 can incorrectly return that joystick directions / triggers are not pressed... All of the solution should work with MSX-BIOS though if there is not something very fishy going on.

joyport	equ	0 ;0/1

Readjoystick:

	di
	ld	a, 15	; Lee el puerto de joystick y almacena
	out	($A0), a	; los estados en las variables.
	in	a, ($A2)
	and	128
	or	Joyport*64+15
	out	($A1), a
	ld	a, 14
	out	($A0), a
	ei
	in	a, ($A2) ;read left right up down and button 1 and 2


	; One example (out of many possible) of handling the directions:

	cpl
	ld	hl,Y
	rrca
	call	c,dec_it ;Forward Y
	rrca
	call	c,inc_it ;Back Y
	inc	hl
	rrca
	call	c,dec_it ;Left X
	rrca
	call	c,inc_it ;Right X
	inc	hl
	rrca
	ld	b,a
	sbc	a,a
	ld	(hl),a ; TRG1 (255=Pushed, 0=not)
	ld	a,b
	inc	hl
	rrca
	sbc	a,a
	ld	(hl),a ; TRG2 (255=Pushed, 0=not)
	ret

	; Move between 0 and 255
inc_it	inc (hl)
	ret nc
	dec (hl)
	ret

dec_it	dec (hl)
	ret nc
	inc (hl)
	ret



Y:	DB 0
X:	DB 0
TRG1	DB 0
TRG2	DB 0

Par santiontanon

Paragon (1105)

Portrait de santiontanon

01-07-2016, 20:48

Thanks for all the solutions, they were very helpful!! This is the current solution that I am considering now. The goal is to be able to control the ship with keyboard or joystick at the same time:
- With keyboard: LEFT/RIGHT to turn left/right, UP or 'M' to thrust, and SPACE to fire
- With joystick: LEFT/RIGHT to turn left/right, UP or TRIGGER 2 to thrust, and TRIGGER 1 to fire

It's not the shortest routine ever, but for now it's doing the trick (and I don't like the fact that I need to check two separate rows of the keyboard matrix, but oh well...)

checkInput:
    ld a,#04    ;; get the status of the 4th keyboard row (to get the status of the 'M' key)
    call SNSMAT
    cpl         
    and #04     ;; keep just bit 2: A = #04 if 'M' was pressed, and A = #00 if it was not
    ld b,a      ;; store this in B
    ;; check arrow keys:   
    ld a,#08    ;; get the status of the 8th keyboard row (to get SPACE and arrow keys)
    call SNSMAT 
    cpl
    and #f1     ;; keep only the arrow keys and space
    or b        ;; add 'M' in bit 2
    jp z,Readjoystick   ;; if no key was pressed, then check the joystick
    bit 7,a
    call nz,TurnRight
    bit 4,a
    call nz,TurnLeft
    bit 0,a
    call nz,FireBullet
    and #24     ;; up or 'M' key
    jp nz,Thrust
    ret

Readjoystick:   
    ld  a, 15   ;; read the joystick 1 status:
    out (#A0), a
    in  a, (#A2)
    and #AF
    out (#A1), a
    ld  a, 14
    out (#A0), a
    in  a, (#A2) 
    cpl         ;; invert the bits (so that '1' means direction pressed)
    bit 3,a
    call nz,TurnRight
    bit 2,a
    call nz,TurnLeft
    bit 4,a
    call nz,FireBullet
    and #21     ;; up or second button
    jp nz,Thrust
    ret

Par AxelStone

Prophet (2765)

Portrait de AxelStone

01-07-2016, 21:46

santiontanon wrote:

The goal is to be able to control the ship with keyboard or joystick at the same time

Clearly the best option Wink

Par sd_snatcher

Prophet (3367)

Portrait de sd_snatcher

01-07-2016, 21:57

The best way to read the digital value from the joystick port that is fast and also compliant to the MSX coding guidelines is to use RDPSG, like Konami did.

It isn't worth it to use direct access to the joystick ports, since it doesn't make any sense to read the joystick ports more than once per frame. The few cycles gained per frame wouldn't compensate for the lost compatibility/flexibility.

Par ARTRAG

Enlighted (6455)

Portrait de ARTRAG

01-07-2016, 22:25

direct access is the best way to avoid the crappy encoding of the directions

Par AxelStone

Prophet (2765)

Portrait de AxelStone

01-07-2016, 22:33

I agree with @sd_snatcher, I don't like direct access oriented programming, I prefer to use complaint methods with MSX coding codelines as using BIOS or standard registers. With direct access you can't ensure full compatibility and MSX is a standard, so it should be programmed as standard.

Par ARTRAG

Enlighted (6455)

Portrait de ARTRAG

02-07-2016, 00:09

Another possibility could be like this:

;  (warning draft untested and incomplete code!)
;----------------------------------------------------------
;    8   |  RIGHT DOWN   UP   LEFT   DEL   INS  HOME  SPACE

; PSG I/O port A (r#14) – read-only
; Joy	 |   cas jap/ANSI  TB    TA   RIGHT  LEFT  DOWN  UP


rd_ctrls:
	ld  e,8
	call    checkkbd
[4]	rrca				; sjasm way to say  this instruction is repeated 4 times
	and		00011111B	; SPACE RIGHT DOWN   UP   LEFT
	ld 		h,convertab /256
	ld 		l,a
	ld		a,(hl)
	ld 		l,a
	call	rd_joy
	and		l		; negative logic i.e. 0 <==> pressed
	ret				; A = Key+Joy	 |  TA   RIGHT  LEFT  DOWN  UP

checkkbd:
	in	a,(0aah)
	and 011110000B		; upper 4 bits contain info to preserve
	or	e
	out (0aah),a
	in	a,(0a9h)
	ret
rd_joy:
	ld	a,#0f
	out	(#a0),a
	ld	a,0x8F
	out	(#a1),a		; select port A
	ld	a,#0e
	out	(#a0),a
	in	a,(#a2)
	ret	
	
	 code # 256      ; sjasm way to align to 256 boundaries 
	
convertab:		; encode here all the 32 transitions mapping keyboard to joystick (space + 4 directions)
	db ...
	

You need to map manually the trigger B

Par santiontanon

Paragon (1105)

Portrait de santiontanon

02-07-2016, 06:05

So, what you guys are suggesting is just to replace this part...

    ld  a, 15   ;; read the joystick 1 status:
    out (#A0), a
    in  a, (#A2)
    and #AF
    out (#A1), a
    ld  a, 14
    out (#A0), a
    in  a, (#A2) 

...by this:

    ld  a, 15   ;; read the joystick 1 status:
    call RDPSG
    and #AF
    ld e,a
    ld a,15
    call WRTPSG
    ld  a, 14
    call RDPSG

right? (which is basically a small variation of the code used in the GTSTCK in C-BIOS ( https://sourceforge.net/p/cbios/cbios/ci/master/tree/src/mai... ))

Par sd_snatcher

Prophet (3367)

Portrait de sd_snatcher

02-07-2016, 06:15

@santiontanon

You got the idea! Smile

And you can even do:

    ld  a, 15   ;; read the joystick 1 status:
    call RDPSG
    and #AF
    ld e,a
    ld a,15
    call WRTPSG
    dec a
    jp RDPSG

Par santiontanon

Paragon (1105)

Portrait de santiontanon

02-07-2016, 18:42

ok, I can live with those extra few CPU cycles, I just updated my code and latest release of Transball with these changes Smile

Page 2/3
1 | | 3