Ninja Tap Assembly driver
This page was last modified 01:14, 25 March 2023 by Gdx. Based on work by Aoineko.

Original Ninja Tap assembler driver version 2.0:

;	PCCM Ninja-Tap Driver v2.0  for MSX	(Primary & C-lib routine)
;	Copyright 1994 1995 Knight's Chamber, all rights reserved.
;	Written by Firm Knight.
;=======================================================================
 
;	Please switch to Z80 when accessing Ninja Tap.
;	This routine is free software.
;	Feel free to incorporate and use it for any purpose.
;=======================================================================
 
;	It can be used in assembler or as a C library (common files).
;=======================================================================
 
;	Labels
;=======================================================================
 
IO_PSG_ADRS	equ	0a0h
IO_PSG_WRITE	equ	0a1h
IO_PSG_READ	equ	0a2h
 
	public	gtntap		; Routine to receive data from Ninja Tap
	public	ckntap		; Routine to check Ninja Tap connections
 
;	Macro
;=======================================================================
 
latch	macro	adrs			; Address latch
	ld	 a,adrs
	out	(IO_PSG_ADRS),a
	endm
 
rd_psg	macro				; Input
	in	 a,(IO_PSG_READ)
	endm
 
wr_psg	macro				; Output
	out	(IO_PSG_WRITE),a
	endm
 
;	Data area
;=======================================================================
 
Result:		db	0	; Ninja Tap connection flag
MaxPlayer:	db	0	; Maximum number of players
Port1ID:	db	0	; Ninja Tap AP standard ID (Port 1)
Port2ID:	db	0	; Ninja Tap AP standard ID (Port 2)
 
;	Ninja Tap driver
;
;	[E]	hl : Pointer to Ninja Tap table
;	[R]	none
;	[M]	af,bc,de,hl
;
;	Structure of Ninja Tap Table
;
;	 Data up to the maximum number of players returned by ckntap is valid.
;	The state of the button is in negative logic.
;
;	offset +0  Player1  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;	       +1  Player2  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;	       +2  Player3  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;	       +3  Player4  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;	       +4  Player5  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;	       +5  Player6  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;	       +6  Player7  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;	       +7  Player8  MSB (A)(B)(  )(  )(↑)(↓)(←)(→) LSB
;=======================================================================
 
gtntap:
	di
 
	ld	 a,(Result)
	rrca				; Processing port 1
	ld	de,0af20h
	call	nc,GetJoyStick
	ld	de,0ba3ah
	call	 c,GetNinjaTap
	rrca				; Processing port 2
	ld	de,09f50h
	call	nc,GetJoyStick
	ld	de,0fa7ah
	call	 c,GetNinjaTap
 
	ei
 
	ret
 
;	Standard joystick access
;=======================================================================
 
GetJoystick:
	push	af
 
	latch	15
	rd_psg
	and	 d
	or	 e
	wr_psg				; Port selection
 
	latch	14
	rd_psg
 
	ld	 e,0ffh
 
	bit	 5,a
	jr	nz,@Trg2Off
	res	 2,e			; Processing trigger 2
@Trg2Off:
	bit	 4,a
	jr	nz,@Trg1Off
	res	 3,e			; Processing trigger 1
@Trg1Off:
	rra
	rl	 e
	rra
	rl	 e
	rra
	rl	 e
	rra
	rl	 e			; Processing stick
 
	ld	(hl),e
	inc	hl
 
	pop	af
 
	ret
 
;	Ninja Tap access
;=======================================================================
 
GetNinjaTap:
	push	af
	push	hl
 
	latch	15
	rd_psg
	and	 d
	or	 e
	wr_psg			; pin 8=H, pin 6=L, Switching connection port
	or	005h
	wr_psg			; pin 6=H	4021 data load
	and	0fah
	wr_psg			; pin 6=L	4021 switch to serial transfer mode
 
	ld	 b,8
@Ninja_Loop:
	latch	15
	rd_psg
	or	030h
	wr_psg			; pin 8=H
	and	0cfh
	wr_psg			; pin 8=L	Request for data transmission
 
	latch	14
	rd_psg			; Data read
 
				; Distribute data
	rra
	rl	 h		; Joystick 1
	rra
	rl	 e		; Joystick 2
	rra
	rl	 d		; Joystick 3
	rra
	rl	 c		; Joystick 4
 
	djnz	@Ninja_Loop
 
	ld	 a,h
 
	pop	hl		; Stores results
 
	ld	(hl),a		; Joystick 1
	inc	hl
	ld	(hl),e		; Joystick 2
	inc	hl
	ld	(hl),d		; Joystick 3
	inc	hl
	ld	(hl),c		; Joystick 4
	inc	hl
 
	latch	15
	rd_psg
	or	03fh
	wr_psg			; Retore to initial state
 
	pop	af
 
	ret
 
;	Check Ninja Tap connections
;
;	[E]	none
;	[R]	hl reg = Pointer to Ninja Tap information table
;	[M]	af,bc,de,hl,ix
;
;	Structure of Ninja Tap information table
;
;	offset +0  Number of joysticks that can be connected to the system (for Ninja Tap)
;	       +1  AP standard ID (port 1). ID is 0-15
;	       +1  AP standard ID (port 2). 255 if not AP standard
;=======================================================================
 
ckntap:
	di
 
	ld	ix,Result
	ld	bc,0		; b = Number of joystick that can be connected
				; c = Internal use flag
	ld	de,0bf00h
	call	check		; Check port 1
	ld	 c,a
 
	ld	 e,040h
	call	check		; Check port 2
	rlca
	or	 c
	ld	(ix+0),a	; Result storage (for internal use)
	ld	(ix+1),b	; Results saved (maximum number of people who can play)
 
	ld	 h,0ffh
	rrca
	ld	de,0ba3ah
	call	 c,GetAP_ID	; Investigation of port 1 ID
	ld	(ix+2),h
	ld	 h,0ffh
	rrca
	ld	de,0fa7ah
	call	 c,GetAP_ID	; Investigation of port 2 ID
	ld	(ix+3),h
 
	ei
 
	ld	hl,MaxPlayer
 
	ret
 
;	Check Ninja Tap connections
;=============================================================================
 
check:
	call	PortSel		; Port selection
 
	inc	 b
 
	and	0c0h
	wr_psg			; pin 6, 7, 8=L
 
	ex	af,af'
 
	latch	14
	rd_psg
 
	bit	 5,a		; pin 7=H?
	jr	nz,check_1
 
	xor	 a		; Ninja Tap not connected
	ret
 
check_1:
	latch	15
	ex	af,af'
	or	030h
	wr_psg			; pin 8=H
 
	latch	14
	rd_psg
 
	bit	 5,a		; pin 7=L?
	ld	 a,0
	ret	 nz		; Ninja Tap not connected
 
	inc	 a		; Ninja Tap is connected
	inc	 b
	inc	 b
	inc	 b
 
	ret
 
;	Obtain ID for Ninja Tap AP standard
;=============================================================================
 
GetAP_ID:
	push	af
 
	call	PortSel		; pin 6=H, pin 8=H, Port selection  
 
	or	005h
	wr_psg			; pin 6=H	4021 data load
	and	0fah
	wr_psg			; pin 6=L	4021 switch to serial transfer mode
 
	ld	 b,9
@ID_Get_Loop:
	latch	15
	rd_psg
	or	030h
	wr_psg			; pin 8=H
	and	0cfh
	wr_psg			; pin 8=L	Request for data transmission
 
	latch	14
	rd_psg			; Data read
 
	djnz	@ID_Get_Loop
 
	and	0fh
	ld	 h,a
 
	latch	15
	rd_psg
	or	03fh
	wr_psg			; Retore to initial state
 
	pop	af
 
	ret
 
;	Solution to reduce routine size (^^;;
;=======================================================================
 
PortSel:
	latch	15
	rd_psg
	and	 d
	or	 e
	wr_psg			; Switching connection port
 
	ret
 
;=============================================================================
;	Reference	Routine size: 323 bytes
;
;	 We measured the execution speed of this routine with the system timer of MSXturboR.
;	We obtained the following results. There may be a slight margin of error.
;
;	 CPU:Z80	Routine: gtntap
;
;		No Ninja Tap	191.639 μS
;		1 Ninja Tap	594.472 μS
;		2 Ninja Tap	997.305 μS
;=============================================================================
 
	end