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

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:

  1. Toggle bit 5 of data port
  2. Wait until bit 4 becomes same value
  3. 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.

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:

Sega multitap header
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:

List of peripheral types
ValuePeripheral
00003-button controller
00016-button controller
0010Mouse
1111Nothing

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.

Format for the 3-button controller
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.

Format for the 6-button controller
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.

Format for the mouse data
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

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.