<span class="section">I/O</span><br><br>
Registers<br><br>
<table cellpadding="4">
<tbody><tr><th>Address</th><th>Description</th></tr>
<tr><td>$A10001</td><td>Version</td></tr>
<tr><td>$A10003</td><td>Port A data</td></tr>

<tr><td>$A10005</td><td>Port B data</td></tr>
<tr><td>$A10007</td><td>Port C data</td></tr>
<tr><td>$A10009</td><td>Port A control</td></tr>
<tr><td>$A1000B</td><td>Port B control</td></tr>
<tr><td>$A1000D</td><td>Port C control</td></tr>
<tr><td>$A1000F</td><td>Port A TxData</td></tr>

<tr><td>$A10011</td><td>Port A RxData</td></tr>
<tr><td>$A10013</td><td>Port A serial control</td></tr>
<tr><td>$A10015</td><td>Port B TxData</td></tr>
<tr><td>$A10017</td><td>Port B RxData</td></tr>
<tr><td>$A10019</td><td>Port B serial control</td></tr>
<tr><td>$A1001B</td><td>Port C TxData</td></tr>

<tr><td>$A1001D</td><td>Port C RxData</td></tr>
<tr><td>$A1001F</td><td>Port C serial control</td></tr>
</tbody></table><br><br>
Reading even addresses returns the same as odd ones so you can use both $A10000 and $A10001.<br><br><br>
<span class="section">$a10001 - version register</span><br><br>
Reading version register returns a byte:<br><br>
<span class="offset">Bit 7</span> - Export bit. 1 if export (USA, Europe, etc.), 0 if domestic (Japan)<br>

<span class="offset">Bit 6</span> - Video type. 1 if PAL, 0 if NTSC<br>
<span class="offset">Bit 5</span> - 0 if Sega CD connected, 1 if not connected<br>
<span class="offset">Bit 4</span> - Unused (always 0)<br>
<span class="offset">Bits 3-0</span> - 0 - MegaDrive 1 / Genesis 1, 1 - newer. Newer have additional security hardware.<br><br><br>

<span class="section">$a10003-7 - data registers</span><br><br>
Reading a data register returns the state of all pins:<br><br>
<span class="offset">Bit 7</span> - Unused<br>
<span class="offset">Bit 6</span> - TH pin<br>
<span class="offset">Bit 5</span> - TR pin<br>
<span class="offset">Bit 4</span> - TL pin<br>

<span class="offset">Bit 3</span> - Data 3 pin<br>
<span class="offset">Bit 2</span> - Data 2 pin<br>
<span class="offset">Bit 1</span> - Data 1 pin<br>
<span class="offset">Bit 0</span> - Data 0 pin<br><br><br>
<span class="section">Reading joypads</span><br><br>

Here's the code:<br><br>
<pre class="68k">pads_read:

		lea     ($FFFFFFF0).w,a0	;where the joypad states will be written
		lea     ($A10003).l,a1	;first joypad data port
		bsr.s   joypad_read	;do the first joypad
		addq.w  #2,a1		;do the second joypad
joypad_read:
		move.b  #0,(a1)		;set the first part
		nop     			;let the hardware parts act
		nop     
		move.b  (a1),d0		;move the lower byte to d0
		lsl.b   #2,d0		;shift some stuff
		andi.b  #$C0,d0		;exclude some dirty stuff
		move.b  #$40,(a1)		;set the second part
		nop     			;the delay
		nop     
		move.b  (a1),d1		;move the upper byte to d1
		andi.b  #$3F,d1		;exclude some dirty stuff
		or.b    d1,d0		;or d0 with d1
		not.b   d0		;not d0
		move.b  (a0),d1		;move the previous joypad state
		eor.b   d0,d1		;eor previous state with current state
					;(we get holded joypad state in d1)
		move.b  d0,(a0)+		;move the pressed state to ram
		and.b   d0,d1		;and stuff
		move.b  d1,(a0)+		;move the holded state to ram
		rts     
</pre><br><br>
After executing that code you will have:<br><br>
<span class="offset">$FFFFF0</span> - Current pressed state of joypad 1<br>
<span class="offset">$FFFFF1</span> - Current holded state of joypad 1<br>
<span class="offset">$FFFFF2</span> - Current pressed state of joypad 2<br>

<span class="offset">$FFFFF3</span> - Current holded state of joypad 2<br><br>
The joypad output format:<br><br>
<span class="offset">Bit 7</span> - Start<br>
<span class="offset">Bit 6</span> - A button<br>
<span class="offset">Bit 5</span> - C button<br>

<span class="offset">Bit 4</span> - B button<br>
<span class="offset">Bit 3</span> - Right<br>
<span class="offset">Bit 2</span> - Left<br>
<span class="offset">Bit 1</span> - Down<br>
<span class="offset">Bit 0</span> - Up<br><br>