Sega multitap
Sega's official multitap (called Team Player or Sega Tap depending on the region). It uses up only one port (so you can plug two of them) and supports both controllers and mouse, but it's also harder to work with (compared to the EA multitap). Most 4P games support this multitap.
To enable the multitap features you must set the multitap to MULTI mode.
Setting up the Sega multitap
To detect the multitap probably it's best to check the peripheral ID. Sega multitap has an ID of 7
(%0111
). Once detected, you should set both the control
and data ports to $60
(see I/O ports
page for the addresses):
; If multitap is in e.g. 1P port
move.b #$60, (IoCtrl1)
move.b #$60, (IoData1)
Reading the Sega multitap
We need to start with this (assuming we left $60
in the
data port):
- Read from data port
- Write
$20
to data port - Read from data port again
Bits 3-0 must be %0011
in the first read and %1111
in the second. If they aren't, quit now!
; 1st multitap check
moveq #$0F, d0
and.b (a0), d0
cmp.b #$03, d0
bne @Error
; 2nd multitap check
move.b #$20, (a0)
nop
nop
nop
moveq #$0F, d0
and.b (a0), d0
cmp.b #$0F, d0
bne @Error
Now comes the most important part. The Sega multitap returns a packet which consists of several nibbles (how many nibbles you need to read depends on what's plugged in!). The procedure to read a nibble is as follows:
- Toggle bit 5 of data port
- Wait until bit 4 becomes same value
- Read bits 3-0 to get a nibble
; Read a nibble from the Sega multitap
; in a0.l = pointer to IoData1/2
; in d0.b = nibble (-1 on error)
ReadSegaNibble:
; Flip bit 5
bchg #5, (a0)
; 68000 trick: BCHG will set the
; zero flag to the new value of
; the bit (0 if clear, 1 if set)
; so we use SEQ which sets d0 to
; either 0 (if Z=0) or $FF (if Z=1)
; then AND to leave only bit 4
seq.b d0
and.b #1<<4, d0
; Now wait until bit 4 gets set
; to the same value we want
; If it takes too long we return
; an error (unplugged?)
moveq #$7F, d7
@Wait:
moveq #1<<4, d1
and.b (a0), d1
cmp.b d0, d1
beq.s @GotNibble
dbf d7, @Wait
bra @Error
@GotNibble:
; Get the nibble in d0
moveq #$0F, d0
and.b (a0), d0
rts
@Error:
; Whoops
moveq #-1, d0
rts
Make sure to add a timeout while waiting for bit 4 to change! If the multitap gets unplugged in the middle of waiting, your game will get stuck. If it takes too long, stop trying to read the multitap and assume something went wrong.
First comes the header (which tells you what's
plugged in), then after that come nibbles for everything that's plugged
in. Once you're done, write $60
to the data port to leave
the multitap alone.
Header
The first six nibbles from the Sega multitap are the "header", which indicates what's connected in each of the multitap's ports (as well as helping make sure it's indeed the multitap). It looks like this:
Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
---|---|---|---|---|
1st nibble | 0
| 0
| 0
| 0
|
2nd nibble | 0
| 0
| 0
| 0
|
3rd nibble | 1P ID3
| 1P ID2
| 1P ID1
| 1P ID0
|
4th nibble | 2P ID3
| 2P ID2
| 2P ID1
| 2P ID0
|
5th nibble | 3P ID3
| 3P ID2
| 3P ID1
| 3P ID0
|
6th nibble | 4P ID3
| 4P ID2
| 4P ID1
| 4P ID0
|
The first two nibbles must be zero. Otherwise, throw away the whole thing.
The following four nibbles indicate what's plugged into each port:
Value | Peripheral |
---|---|
0000 | 3-button controller |
0001 | 6-button controller |
0010 | Mouse |
1111 | Nothing |
After the header, there are more nibbles to read depending on what's plugged into each port (except for those with nothing, of course). Because of this, it's important to handle all three supported peripherals (even if your game simply throws away the stuff it doesn't want).
3-button controller
Players with the 3-button controller (type 0000
) include
two additional nibbles. Every bit represents a button and, just like with
the controller, 0 means pressed while 1 means released.
Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
---|---|---|---|---|
1st nibble | Right
| Left
| Down
| Up
|
2nd nibble | Start
| A
| C
| B
|
6-button controller
6-button controllers (type 0001
) are similar to the 3-button
ones, except they have a third nibble for the extra buttons.
Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
---|---|---|---|---|
1st nibble | Right
| Left
| Down
| Up
|
2nd nibble | Start
| A
| C
| B
|
3rd nibble | Mode
| X
| Y
| Z
|
Mouse
The last device supported by the multitap is the mouse (type
0010
) and it adds a total of six nibbles. The
format of these bits is the same as their mouse protocol counterpart,
so refer to the mouse page for details.
Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
---|---|---|---|---|
1st nibble | Yo
| Xo
| Ys
| Xs
|
2nd nibble | C
| M
| R
| L
|
3rd nibble | X7
| X6
| X5
| X4
|
4th nibble | X3
| X2
| X1
| X0
|
5th nibble | Y7
| Y6
| Y5
| Y4
|
6th nibble | Y3
| Y2
| Y1
| Y0
|
Peripheral ID in ROM header
Multitap support in the ROM header is specified by adding "4
"
in the devices field (the one at
$000190
). Since it doesn't specify which multitap
is supported, it's a good idea to consider supporting the EA multitap as
well.
Support for the extra buttons in the 6-button controller ("6
")
and the mouse ("M
") should also be specified when the
relevant features are supported. On the other hand, if the game simply
ignores them, you shouldn't add them.