Many of the things you can plug into the Mega Drive have an "ID", which is a four bit number you can use to identify a peripheral before you use it. Most devices Sega released on Mega Drive and Saturn can be identified this way.
The peripheral ID is a side effect of the protocol used to talk with the device, so not everything has an ID. Peripherals without an ID need to be detected in their own unique way.
How to get the ID
To get the peripheral ID, first configure the I/O control port so that bit 6 is output and the rest are input (in other words, the same way as for setting up a controller). Then read the peripheral twice, once with bit 6 = 0 and once with bit 6 = 1. The values of bits 3-0 are used to determine the ID.
The peripheral ID consists of four bits (where each bit is obtained by ORing two bits read back from the data port). They're as follows:
|Peripheral ID||Write this||Read back from port|
|ID bit 0||bit 1 OR bit 0|
|ID bit 1||bit 3 OR bit 2|
|ID bit 2||bit 1 OR bit 0|
|ID bit 3||bit 3 OR bit 2|
The following routine shows how you could do it (using look-up tables to handle both ORs of each read, since it honestly makes the code simpler):
; Subroutine to get peripheral ID ; Pointer to data port in a0, result in d0 ; d1 and a1 get trashed GetPeripheralId: ; Make sure pin direction is ; set correctly for this move.b #$40, 6(a0) ; Get bits 1-0 of peripheral ID move.b #$00, (a0) nop nop lea @Table1(pc), a1 moveq #$0F, d0 and.b (a0), d0 move.b (a1,d0.w), d0 ; Get bits 3-2 of peripheral ID move.b #$40, (a0) nop nop lea @Table2(pc), a1 moveq #$0F, d1 and.b (a0), d1 or.b (a1,d1.w), d0 ; Result is in d0 rts ; Look-up table to extract ID ; bits from the first read @Table1: dc.b %0000,%0001,%0001,%0001 dc.b %0010,%0011,%0011,%0011 dc.b %0010,%0011,%0011,%0011 dc.b %0010,%0011,%0011,%0011 ; Look-up table to extract ID ; bits from the second read @Table2: dc.b %0000,%0100,%0100,%0100 dc.b %1000,%1100,%1100,%1100 dc.b %1000,%1100,%1100,%1100 dc.b %1000,%1100,%1100,%1100
Beware! Since we messed with the data port the peripheral now may need some time before returning correct data. This is true even for controllers (as this interferes with the 6-button controller sequence). If you retrieved the ID you'll want to save it and wait for the next frame before starting to use the peripheral. You'll know if it got unplugged when you try to use it and it returns incorrect data, anyway.
Known peripheral IDs
The following values are known to match existing peripherals:
|Mega Drive controller|
|Mega Drive controller (see note)|
|Other Saturn peripherals|
The following peripherals can't be detected this way, and you need to try interacting with them directly and see if they return the expected data to tell if they're there:
- Master System controller
- Master System trackball
- Master System paddle
- EA multitap
- Ten Key Pad
- Miracle Piano keyboard
- XBAND keyboard
1100 can happen if the console is reset in the middle
of trying to read a 6-button controller (in which case it may end up
returning the extra buttons and trip the check).