Ninja Tap Assembly driver
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