All pastes #833968 Raw Edit

Unnamed

public text v1 · immutable
#833968 ·published 2007-12-27 20:17 UTC
rendered paste body
##################################################################################################################################
#                                                                                                                    Hacked ;-)  #
#                                                                                                                                #
#                           ---- Anaconda04 - Viperfree Cobra04 DVD-R boot core recode in pure assembly ----                     #
#                                                                                                                                #
#                                      Copylefted 2K5 by Freefall , Wildlight , ttl and xor37h                                   #
#                                                                                                                                #
# Attention :                                                                                                                    #
# This code is *NOT* based on the actual Cobra04 code, only the databytes in "DriveCode" are 'borrowed' from the original        #
# Cobra04 file ! This code is provided 'as is' and is ofcourse for educational use only !                                        #
#                                                                                                                                #
# - Wildlight , 21.02.2005                                                                                                       #
#                                                                                                                                #
##################################################################################################################################

# set up the registernames
.set r0,0;   .set sp,1;   .set rtoc,2; .set r3,3;   .set r4,4
.set r5,5;   .set r6,6;   .set r7,7;   .set r8,8;   .set r9,9
.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
.set r30,30; .set r31,31

# use test sectioen for our code
.text
# declare program entrypoint
.global _start

# --> entrypoint 
_start:
	# Perform drive reset
	lis		r4 , 0xcc00							# setup reset register (high)
	ori		r4 , r4 , 0x3024						# setup reset register (low)
	lwz		r5 , 0(r4)							# read reset register
	rlwinm	r5 , r5 , 0 , 30 , 28					# clear bit 2
	ori		r5 , r5 , 1							# set bit 0
	stw		r5 , 0(r4)							# write back to reset register
	lwz		r5 , 0(r4)							# read reset register
	ori		r5 , r5 , 4							# set bit 2
	ori		r5 , r5 , 1							# set bit 0
	stw		r5 , 0(r4)							# write back to reset register -> reset DVD drive

	# Wait some time (~ 8 secs)
	li		r3 , 8000								# ~ 8 seconds
	bl		Delay								# ... delay

	# Unlock the drives' debug commands
	bl		UnlockDrive							# unlock debugmode in drive (see function for info)

	# Send the neccessary code to the drive
	bl		SendDriveCode							# copy cobra04 patchcode into drices' memory (see function for info)

	# Wait some time (~ 2 secs)
	li		r3 , 2000								# ~ 2 seconds
	bl		Delay								# ... delay

	# Read Disc ID (now from DVD-R)
	bl		ReadDiscID							# initialize disc with A8000040 command

	# Enable audio streaming if neccesary
	bl		EnableAudioStreaming					# send E400xx00xx command

	# Load and parse the apploader & start the application
	bl		LoadApploader							# read the apploader from the disc, load the application into memory and start

	# ... end of communication ...

# ------------------------------------------------------------------------------------------------------------------------------------

Delay:
	lis		r4 , 0x0003							# 0x30000 for the inner delay loop

DelayLoopInner:
	subi		r4 , r4 , 1							# decrement within inner loop
	cmpwi	r4 , 0								# zero reached ?
	bne		DelayLoopInner							# => no, back to inner loop
	subi		r3 , r3 , 1							# decrement given delay time
	cmpwi	r3 , 0								# zero reached ?
	bne		Delay								# => no, back to outer loop
	blr											# delay performed, back to caller

UnlockDrive:
	lis		r3 , 0xcc00							# setup DVD base register (high)
	ori		r3 , r3 , 0x6000						# setup DVD base register (low)
	lwz		r4 , 0(r3)							# read DVD status 1
	ori		r4 , r4 , 0x14							# set bit 2 and 4
	stw		r4 , 0(r3)							# write back to DVD status 1
	li		r4 , 0								# zero to ...
	stw		r4 , 4(r3)							# ... DVD status 2
	lis		r4 , 0xff01							# create first unlock command : ff 01 'M 'A 'T 'S 'H 'I 'T 'A 02 00
	ori		r4 , r4 , 0x4d41						# -"-
	stw		r4 , 8(r3)							# -"-
	lis		r4 , 0x5453							# -"-
	ori		r4 , r4 , 0x4849						# -"-
	stw		r4 , 12(r3)							# -"-
	lis		r4 , 0x5441							# -"-
	ori		r4 , r4 , 0x0200						# -"-
	stw		r4 , 16(r3)							# and send to drive in DVD command 1 / command 2 / command 3 registers
	li		r4 , 1								# immediate mode (1)
	stw		r4 , 28(r3)							# startup command

UnlockDrive_Loop1:
	lwz		r4 , 0(r3)							# read DVD status 1 register
	andi.	r4 , r4 , 0x14							# mask bit 2 and 4 (error and finish)
	cmpwi	r4 , 0								# none set ?
	beq		UnlockDrive_Loop1						# => yeah, so check again

	lwz		r4 , 0(r3)							# read DVD status 1
	ori		r4 , r4 , 0x14							# set bit 2 and 4
	stw		r4 , 0(r3)							# write back to DVD status 1
	li		r4 , 0								# zero to ...
	stw		r4 , 4(r3)							# ... DVD status 2
	lis		r4 , 0xff00							# create second unlock command : ff 00 'D 'V 'D '- 'G 'A 'M 'E 03 00
	ori		r4 , r4 , 0x4456						# -"-
	stw		r4 , 8(r3)							# -"-
	lis		r4 , 0x442d							# -"-
	ori		r4 , r4 , 0x4741						# -"-
	stw		r4 , 12(r3)							# -"-
	lis		r4 , 0x4d45							# -"-
	ori		r4 , r4 , 0x0300						# -"-
	stw		r4 , 16(r3)							# and send to drive in DVD command 1 / command 2 / command 3 registers
	li		r4 , 1								# immediate mode (1)
	stw		r4 , 28(r3)							# startup command

UnlockDrive_Loop2:
	lwz		r4 , 0(r3)							# read DVD status 1 register
	andi.	r4 , r4 , 0x14							# mask bit 2 and 4 (error and finish)
	cmpwi	r4 , 0								# none set ?
	beq		UnlockDrive_Loop2						# => yeah, so check again

	blr											# return to caller

SendDriveCode:
	mflr		r11									# backup link register
	lis		r3 , DriveCode@h						# setup register r3 to point to Cobra04 drivecode table (high)
	ori		r3 , r3 , DriveCode@l					# setup register r3 to point to Cobra04 drivecode table (low)
	
	lis		r8 , 0								# prepare some registers for the drive memoryaddress calculation
	lis		r9 , 0								# -"-

SendDriveCode_Loop1:
	lbz		r4 , 0(r3)							# get a byte from the drivecode (command)
	addi		r3 , r3 , 1							# increment drivecode tablepointer
	
	cmpwi	r4 , 0								# command == 0 (address setup) ?
	beq		SendDriveCode_AddrSet					# => yes, call address setup

	cmpwi	r4 , 99								# command = 99 (end of table) ?
	beq		SendDriveCode_End						# => stop table parsing

	bl		SendDriveCode_DriveCmd					# any other commandvalue is the length of data to send to the drive (max 12 bytes)
	add		r3 , r3 , r4							# add the given length (in command) to the drivecode tablepointer for the next round
	b		SendDriveCode_Loop1						# and do the next round !

SendDriveCode_AddrSet:
	lis		r7 , 0								# zero register r7
	lbz		r6 , 0(r3)							# load next drivecode byte (16bit address (high) ) ...
	slwi		r7 , r6 , 8							# ... and shift left by 8
	lbz		r6 , 1(r3)							# load next drivecode byte (16bit address (low) ) ...
	or		r7 , r7 , r6							# ... and or to previous high value
	or		r9 , r8 , r7							# or to offset in register r8 and store result in register r9
	addi		r3 , r3 , 2							# increment drivecode tablepointer by 2
	b		SendDriveCode_Loop1						# and do next round !
	
SendDriveCode_End:
	mtlr		r11									# restore link register
	blr											# return to caller

SendDriveCode_DriveCmd:
	lis		r6 , CmdBuffer2@h						# setup temporary commandbuffer (high) [2]
	ori		r6 , r6 , CmdBuffer2@l					# setup temporary commandbuffer (low) [2]
	mtctr	r4									# number of bytes to send (r4) to counter register
	mr		r5 , r3								# actual drivecode tablepointer (r3) to register r5

SendDriveCode_DriveCmd_Loop1:
	lbz		r7 , 0(r5)							# copy from actual drivecode tablepointer to temporary commandbuffer
	stb		r7 , 0(r6)							# (r4 x bytes)
	addi		r5 , r5 , 1							# -"-
	addi		r6 , r6 , 1							# -"-
	bdnz		SendDriveCode_DriveCmd_Loop1				# -"-

	lis		r13 , 0xcc00							# setup DVD base register (high)
	ori		r13 , r13 , 0x6000						# setup DVD base register (low)

	lis		r12 , CmdBuffer1@h						# setup another temporary commandbuffer (high) [1]
	ori		r12 , r12 , CmdBuffer1@l					# setup another temporary commandbuffer (low) [1]

	stw		r9 ,	4(r12)							# store calculated drive memory address to DVD command 2 register
	add		r9 , r9 , r4							# and increment drive memory address by length of data
	mr		r14 , r4								# get length of data ...
	slwi		r14 , r14 , 16							# ... shift into high 16bit ...
	stw		r14 , 8(r12)							# ... and store into DVD command 3 register

	lwz		r14 , 0(r13)							# read DVD status 1
	ori		r14 , r14 , 0x14						# set bit 2 and 4
	stw		r14 , 0(r13)							# write back to DVD status 1
	li		r14 , 0								# zero to ...
	stw		r14 , 4(r13)							# ... DVD status 2
	lwz		r14 , 0(r12)							# create drive memory write command : ff 01 01 00 <memoffset> <datalength>
	stw		r14 , 8(r13)							# -"-
	lwz		r14 , 4(r12)							# -"-
	stw		r14 , 12(r13)							# -"-
	lwz		r14 , 8(r12)							# -"-
	stw		r14 , 16(r13)							# and send to drive in DVD command 1 / command 2 / command 3 registers
	li		r14 , 3								# special : normally DMA mode , here : tell the drive another command with data follows !
	stw		r14 , 28(r13)							# startup command

SendDriveCode_DriveCmd_Loop2:
	lwz		r14 , 0(r13)							# read DVD status 1 register
	andi.	r14 , r14 , 0x14						# mask bit 2 and 4 (error and finish)
	cmpwi	r14 , 0								# none set ?
	beq		SendDriveCode_DriveCmd_Loop2				# => yeah, so check again

	lis		r12 , CmdBuffer2@h						# get temporary commandbuffer (high) [2]
	ori		r12 , r12 , CmdBuffer2@l					# get temporary commandbuffer (low) [2]

	lwz		r14 , 0(r13)							# read DVD status 1
	ori		r14 , r14 , 0x14						# set bit 2 and 4
	stw		r14 , 0(r13)							# write back to DVD status 1
	li		r14 , 0								# zero to ...
	stw		r14 , 4(r13)							# ... DVD status 2
	lwz		r14 , 0(r12)							# create write drive memory command : <data>
	stw		r14 , 8(r13)							# -"-
	lwz		r14 , 4(r12)							# -"-
	stw		r14 , 12(r13)							# -"-
	lwz		r14 , 8(r12)							# -"-
	stw		r14 , 16(r13)							# and send to drive in DVD command 1 / command 2 / command 3 registers
	li		r14 , 1								# immediate mode (1)
	stw		r14 , 28(r13)							# startup command

SendDriveCode_DriveCmd_Loop3:
	lwz		r14 , 0(r13)							# read DVD status 1 register
	andi.	r14 , r14 , 0x14						# mask bit 2 and 4 (error and finish)
	cmpwi	r14 , 0								# none set ?
	beq		SendDriveCode_DriveCmd_Loop3				# => yeah, so check again

	blr											# return to caller

ReadDiscID:
	lis		r3 , 0xcc00							# setup DVD base register (high)
	ori		r3 , r3 , 0x6000						# setup DVD base register (low)
	lwz		r4 , 0(r3)							# read DVD status 1
	ori		r4 , r4 , 0x14							# set bit 2 and 4
	stw		r4 , 0(r3)							# write back to DVD status 1
	li		r4 , 0								# zero to ...
	stw		r4 , 4(r3)							# ... DVD status 2
	lis		r4 , 0xa800							# setup ReadDiscID command (A8000040)
	ori		r4 , r4 , 0x0040						# -"-
	stw		r4 , 8(r3)							# write to DVD command 1
	lis		r4 , 0								# zero to ...
	stw		r4 , 12(r3)							# ... DVD command 2
	li		r4 , 0x20								# 32 bytes (Disc ID length) to ...
	stw		r4 , 16(r3)							# ... DVD command 3
	stw		r4 , 24(r3)							# ... and to DVD DMA length register
	lis		r4 , 0x8000							# Gamecube memory address 0x80000000 for the buffer
	stw		r4 , 20(r3)							# write to DVD DMA address register
	li		r4 , 3								# DMA mode (3)
	stw		r4 , 28(r3)							# startup command

ReadDiscID_Loop1:
	lwz		r4 , 0(r3)							# read DVD status 1 register
	andi.	r4 , r4 , 0x14							# mask bit 2 and 4 (error and finish)
	cmpwi	r4 , 0								# none set ?
	beq		ReadDiscID_Loop1						# => yeah, so check again

	mflr		r10									# backup link register
	lis		r3 , 0x8000							# invalidate cache (32 bytes) at 0x80000000
	li		r4 , 32								# -"-
	bl		InvalidateCache						# -"-
	mtlr		r10									# restore link register

	blr											# return to caller

EnableAudioStreaming:
	mflr		r11									# backup link register
	
	lis		r9 , 0x8000							# setup audio streaming byte tests at 0x8000000x
	lis		r5 , 0xe400							# setup audio streaming drive command (0xe4000000)
	lbz		r3 , 8(r9)							# get byte at 0x80000008
	cmpwi	r3 , 0								# byte is zero ?
	beq		EnableAudioStreaming_Setup				# => yeah, skip further tests
	oris		r5 , r5 , 0x0001						# => no, expand audio streaming drive command to 0x4e010000
	lbz		r3 , 9(r9)							# get byte at 0x80000009
	cmpwi	r3 , 0								# byte is zero ?
	bne		EnableAudioStreaming_Setup				# => no, skip further setup
	ori		r5 , r5 , 0x000a						# => yes, expand audio streaming drive command to 0xe401000a
	
EnableAudioStreaming_Setup:
	lis		r3 , 0xcc00							# setup DVD base register (high)
	ori		r3 , r3 , 0x6000						# setup DVD base register (low)
	lwz		r4 , 0(r3)							# read DVD status 1
	ori		r4 , r4 , 0x14							# set bit 2 and 4
	stw		r4 , 0(r3)							# write back to DVD status 1
	li		r4 , 0								# zero to ...
	stw		r4 , 4(r3)							# ... DVD status 2
	stw		r5 , 8(r3)							# write audio streaming drive command to DVD command 1
	li		r4 , 0								# zero to ...
	stw		r4 , 12(r3)							# ... DVD command 2
	stw		r4 , 16(r3)							# ... and DVD command 3
	li		r4 , 1								# immediate mode (1)
	stw		r4 , 28(r3)							# startup command

	mr		r10 , r3								# backup DVD base register
	li		r3 , 100								# wait ~100 ms
	bl		Delay								# -"-
	mr		r3 , r10								# restore DVD base register
	
EnableAudioStreamingSetup_Loop2:
	lwz		r4 , 0(r3)							# read DVD status 1 register
	andi.	r4 , r4 , 0x14							# mask bit 2 and 4 (error and finish)
	cmpwi	r4 , 0								# none set ?
	beq		EnableAudioStreamingSetup_Loop2			# => yeah, so check again

	mtlr		r11									# restore link register
	blr											# return to caller

LoadApploader:
	lis		r9 , 0x8010							# read 32 bytes (apploader header) from DVD offset 0x2440 to GC memory 0x80100000
	mr		r3 , r9								# -"-
	li		r4 , 0x2440							# -"-
	li		r5 , 32								# -"-
	bl		DVDReadSector							# -"-

	lis		r3 , 0x8120							# read apploader from DVD offset 0x2460 to 0x81200000 with length given in header at position 20
	li		r4 , 0x2460							# -"-
	lwz		r5 , 20(r9)							# -"-
	addi		r5 , r5 , 32							# -"-
	bl		DVDReadSector							# -"-

	lis		r12 , ApploaderData1@h					# jump to entryfunction of apploader given in header at postion 16
	ori		r12 , r12 , ApploaderData1@l				# (and receive three functionpointers for 'init' , 'main' and 'final' calling of apploader)
	mr		r3 , r12								# -"-
	addi		r12 , r12 , 4							# -"-
	mr		r4 , r12								# -"-
	addi		r12 , r12 , 4							# -"-
	mr		r5 , r12								# -"-
	lwz		r8 , 16(r9)							# -"-
	mtctr	r8									# -"-
	bctrl										# -"-

LoadApploader_Loop1:
	lis		r12 , ApploaderData1@h					# read out DVD offset , length and GC memory position for each chunk to load
	ori		r12 , r12 , ApploaderData1@l				# (using the 'main' function call in the apploader)
	lis		r15 , ApploaderData2@h					# -"-
	ori		r15 , r15 , ApploaderData2@l				# -"-
	mr		r3 , r15								# -"-
	addi		r15 , r15 , 4							# -"-
	mr		r4 , r15								# -"-
	addi		r15 , r15 , 4							# -"-
	mr		r5 , r15								# -"-
	lwz		r8 , 4(r12)							# -"-
	mtctr	r8									# -"-
	bctrl										# -"-

	cmpwi	r3 , 0								# 'main' function returned zero (= no more chunks to load) ?
	beq		LoadApploader_End						# => yes, finish chunk loading

	lis		r15 , ApploaderData2@h					# use DVD offset , length and GC memory position to read a chunk from the DVD
	ori		r15 , r15 , ApploaderData2@l				# -"-
	lwz		r3 , 0(r15)							# -"-
	lwz		r4 , 8(r15)							# -"-
	lwz		r5 , 4(r15)							# -"-
	bl		DVDReadSector							# -"-

	b		LoadApploader_Loop1						# loop for next chunk to read

LoadApploader_End:
	lis		r12 , ApploaderData1@h					# use 'final' function call in the apploader to receive final application entrypoint
	ori		r12 , r12 , ApploaderData1@l				# -"-
	lwz		r8 , 8(r12)							# -"-
	mtctr	r8									# -"-
	bctrl
	
	mtlr		r3									# write final application entrypoint into link register
	blr											# and jump ... !

DVDReadSector:
	lis		r13 , 0xcc00							# setup DVD base register (high)
	ori		r13 , r13 , 0x6000						# setup DVD base register (low)
	lwz		r14 , 0(r13)							# read DVD status 1
	ori		r14 , r14 , 0x14						# set bit 2 and 4
	stw		r14 , 0(r13)							# write back to DVD status 1
	li		r14 , 0								# zero to ...
	stw		r14 , 4(r13)							# ... DVD status 2
	lis		r14 , 0xa800							# setup ReadSector command (A8000000)
	stw		r14 , 8(r13)							# write to DVD command 1
	srawi	r4 , r4 , 2							# correct DVD offset value ( >> 2 )
	stw		r4 , 12(r13)							# write to DVD command 2
	stw		r5 , 16(r13)							# write datalength of chunk to DVD command 3 ...
	stw		r5 , 24(r13)							# ... and to DVD DMA length register
	stw		r3 , 20(r13)							# write GC memoryaddress of chunk to DVD DMA address register
	li		r14 , 3								# DMA mode (3)
	stw		r14 , 28(r13)							# startup command

DVDReadSector_Loop1:
	lwz		r14 , 24(r13)							# read DVD DMA length register
	cmpwi	r14 , 0								# is zero ?
	bne		DVDReadSector_Loop1						# => no, check again

	mflr		r11									# backup link register
	mr		r4 , r5								# Invalidate cache of the memory chunk
	bl		InvalidateCache						# -"-
	mtlr		r11									# restore link register
	blr											# return to caller

# ------------------------------------------------------------------------------------------------------------------------------------

InvalidateCache:
	srawi	r4 , r4 , 5							# correct given size of range
	mtctr	r4									# write to counter register

InvalidateCache_Loop1:	
	dcbf		r0 , r3								# invalidate instruction cache (32 byte block)
	icbi		r0 , r3								# invalidate data cache (32 byte block)
	addi		r3 , r3 , 32							# increment range by 32
	bdnz		InvalidateCache_Loop1					# counter reached zero ? => no, do another round
	blr											# return to caller

# ------------------------------------------------------------------------------------------------------------------------------------

.align 4
ApploaderData1:
	.long	0 , 0 , 0								# 'init' , 'main' , 'final' apploader function call pointer
ApploaderData2:
	.long	0 , 0 , 0								# 'memory destination' , 'length' , 'DVD offset' of each chunk to load from the apploader

.align 4
CmdBuffer1:
	.long	0xfe010100 , 0 , 0						# DVD write memory command ( 0xfe010100 <offset> <length> )
CmdBuffer2:
	.long	0 , 0 , 0								# temporary buffer for the drivecode table data

.align 4
DriveCode:										# **** Cobra 04 'borrowed' drive memory code ****

/*
	00008502 EA00        	??          	BRA	$00008504
	
	00008504 FCB400      	???         	JMP	$000085BB
	
	00008507 F3FEC0DAFC00	???????     	TBZ	($00FCDA)0,$00008510
	0000850E EA15        	??          	BRA	$00008525
	
	00008510 C80EFC      	???         	MOV	($FC0E),D0
	00008513 D854        	?T          	CMP	$54,D0			;'T'
	00008515 E903        	??          	BNE	$0000851A
	00008517 FD8600      	???         	JSR	$000085A0
	0000851A C80EFC      	???         	MOV	($FC0E),D0
	0000851D F474770A08  	?tw??       	MOV	$080A77,A0
	00008522 F000        	??          	JMP	(A0)
	
	00008524 FE          	?           	RTS	
	---------------------------
	
	00008525 F5D8DAFC    	????        	BCLR	($FCDA)0
	00008529 F5D844FC    	??D?        	BCLR	($FC44)0
	0000852D F27C        	?|          	MOV	A3,A0
	0000852F D004        	??          	ADD	$04,A0
	00008531 CC5B80      	?[?         	MOVBU	($805B),D0
	00008534 D801        	??          	CMP	$01,D0			;'?'
	00008536 E902        	??          	BNE	$0000853A
	00008538 7C04        	|?          	MOV	($04,A3),A0
	0000853A F475428500  	?uB??       	MOV	$008542,A1
	0000853F 5120        	Q           	MOV	A1,($20,A0)
	00008541 FE          	?           	RTS	
	---------------------------
	
	00008542 F55E00      	?^?         	MOVX	D2,($00,A3)
	00008545 F55F04      	?_?         	MOVX	D3,($04,A3)
	00008548 5D08        	]?          	MOV	A1,($08,A3)
	0000854A 5E0C        	^?          	MOV	A2,($0C,A3)
	0000854C 82          	?           	MOV	D0,D2
	0000854D F2F3        	??          	MOV	A0,D3
	0000854F F23E        	?>          	MOV	D3,A2
	00008551 D202        	??          	ADD	$02,A2
	00008553 F475240040  	?u$?@       	MOV	$400024,A1
	00008558 31          	1           	MOVBU	(A0),D1
	00008559 D900        	??          	CMP	$00,D1			;'?'
	0000855B E902        	??          	BNE	$0000855F
	0000855D 8A08        	??          	MOV	$08,D2			;'?'
	0000855F F710FFF7    	????        	AND	$F7FF,PSW
	00008563 21          	!           	MOV	(A0),D1
	00008564 F47900F000  	?y???       	CMP	$00F000,D1
	00008569 E90A        	??          	BNE	$00008575
	0000856B 8000        	??          	MOV	$00,D0			;'?'
	0000856D F51009      	???         	MOVB	D0,($09,A0)
	00008570 8000        	??          	MOV	$00,D0			;'?'
	00008572 C02082      	? ?         	MOV	D0,($8220)
	00008575 21          	!           	MOV	(A0),D1
	00008576 D906        	??          	CMP	$06,D1			;'?'
	00008578 E906        	??          	BNE	$00008580
	0000857A 6106        	a?          	MOV	($06,A0),D1
	0000857C D506        	??          	ADD	$06,D1			;'?'
	0000857E 4106        	A?          	MOV	D1,($06,A0)
	00008580 F47450B108  	?tP??       	MOV	$08B150,A0
	00008585 F4C8BA8500  	?????       	MOVBU	($0085BA),D0
	0000858A D829        	?)          	CMP	$29,D0			;')'
	0000858C E905        	??          	BNE	$00008593
	0000858E F47433AE08  	?t3??       	MOV	$08AE33,A0
	00008593 F7488400    	?H??        	CMP	$0084,D0
	00008597 E905        	??          	BNE	$0000859E
	00008599 F47480AE08  	?t???       	MOV	$08AE80,A0
	0000859E F000        	??          	JMP	(A0)
	
	000085A0 C82082      	? ?         	MOV	($8220),D0
	000085A3 D401        	??          	ADD	$01,D0			;'?'
	000085A5 C02082      	? ?         	MOV	D0,($8220)
	000085A8 F7480006    	?H??        	CMP	$0600,D0
	000085AC E90B        	??          	BNE	$000085B9
	000085AE 8000        	??          	MOV	$00,D0			;'?'
	000085B0 C02082      	? ?         	MOV	D0,($8220)
	000085B3 F80502      	???         	MOV	$0205,D0
	000085B6 C04480      	?D?         	MOV	D0,($8044)
	000085B9 FE          	?           	RTS	
	---------------------------
	
	000085BA 00          	?           	MOV	D0,(A0)
	000085BB D3FC        	??          	ADD	-$04,A3
	000085BD 0E          	?           	MOV	D2,(A3)
	000085BE F4C8030A08  	?????       	MOVBU	($080A03),D0
	000085C3 F444BA8500  	?D???       	MOVB	D0,($0085BA)
	000085C8 F474078500  	?t???       	MOV	$008507,A0
	000085CD F7204C80    	? L?        	MOV	A0,($804C)
	000085D1 F4C016EB40  	????@       	MOV	($40EB16),D0
	000085D6 F700FFEF    	????        	AND	$EFFF,D0
	000085DA FDD000      	???         	JSR	$000086AD
	000085DD F80D7F      	???         	MOV	$7F0D,D0
	000085E0 FD9700      	???         	JSR	$0000867A
	000085E3 F80E7F      	???         	MOV	$7F0E,D0
	000085E6 FD9100      	???         	JSR	$0000867A
	000085E9 F80B7F      	???         	MOV	$7F0B,D0
	000085EC FD8B00      	???         	JSR	$0000867A
	000085EF F80001      	???         	MOV	$0100,D0
	000085F2 FD7300      	?s?         	JSR	$00008668
	000085F5 F80B7F      	???         	MOV	$7F0B,D0
	000085F8 FD7F00      	???         	JSR	$0000867A
	000085FB F80A7F      	???         	MOV	$7F0A,D0
	000085FE FD7900      	?y?         	JSR	$0000867A
	00008601 F80D7F      	???         	MOV	$7F0D,D0
	00008604 FD7300      	?s?         	JSR	$0000867A
	00008607 F88000      	???         	MOV	$0080,D0
	0000860A FD5B00      	?[?         	JSR	$00008668
	0000860D F4C016EB40  	????@       	MOV	($40EB16),D0
	00008612 F7400010    	?@??        	OR	$1000,D0
	00008616 FD9400      	???         	JSR	$000086AD
	00008619 800C        	??          	MOV	$0C,D0			;'?'
	0000861B F4CABA8500  	?????       	MOVBU	($0085BA),D2
	00008620 DC8E81      	???         	MOV	$818E,A0
	00008623 DA29        	?)          	CMP	$29,D2			;')'
	00008625 E903        	??          	BNE	$0000862A
	00008627 DC9A81      	???         	MOV	$819A,A0
	0000862A F74A8400    	?J??        	CMP	$0084,D2
	0000862E E903        	??          	BNE	$00008633
	00008630 DC9681      	???         	MOV	$8196,A0
	00008633 10          	?           	MOVB	D0,(A0)
	00008634 F47030B100  	?p0??       	MOV	$00B130,D0
	00008639 F4CABA8500  	?????       	MOVBU	($0085BA),D2
	0000863E DA29        	?)          	CMP	$29,D2			;')'
	00008640 E905        	??          	BNE	$00008647
	00008642 F47013AE00  	?p???       	MOV	$00AE13,D0
	00008647 F74A8400    	?J??        	CMP	$0084,D2
	0000864B E905        	??          	BNE	$00008652
	0000864D F47060AE00  	?p`??       	MOV	$00AE60,D0
	00008652 C0D2FC      	???         	MOV	D0,($FCD2)
	00008655 8008        	??          	MOV	$08,D0			;'?'
	00008657 C0D4FC      	???         	MOV	D0,($FCD4)
	0000865A 800C        	??          	MOV	$0C,D0			;'?'
	0000865C C4DAFC      	???         	MOVB	D0,($FCDA)
	0000865F 8000        	??          	MOV	$00,D0			;'?'
	00008661 C02082      	? ?         	MOV	D0,($8220)
	00008664 2E          	.           	MOV	(A3),D2
	00008665 D304        	??          	ADD	$04,A3
	00008667 FE          	?           	RTS	
	---------------------------
	
	00008668 F471FFFFFF  	?q???       	MOV	$FFFFFF,D1
	0000866D F71D0100    	????        	SUB	$0001,D1
	00008671 E9FA        	??          	BNE	$0000866D
	00008673 F71C0100    	????        	SUB	$0001,D0
	00008677 E9EF        	??          	BNE	$00008668
	00008679 FE          	?           	RTS	
	---------------------------
	
	0000867A D3FC        	??          	ADD	-$04,A3
	0000867C F90010      	???         	MOV	$1000,D1
	0000867F 0D          	?           	MOV	D1,(A3)
	00008680 4C02        	L?          	MOV	D0,($02,A3)
	00008682 F27C        	?|          	MOV	A3,A0
	00008684 8002        	??          	MOV	$02,D0			;'?'
	00008686 F4CABA8500  	?????       	MOVBU	($0085BA),D2
	0000868B F74AC900    	?J??        	CMP	$00C9,D2
	0000868F E905        	??          	BNE	$00008696
	00008691 F4E1902A08  	???*?       	JSR	$0008B126
	00008696 DA29        	?)          	CMP	$29,D2			;')'
	00008698 E905        	??          	BNE	$0000869F
	0000869A F4E16A2708  	??j'?       	JSR	$0008AE09
	0000869F F74A8400    	?J??        	CMP	$0084,D2
	000086A3 E905        	??          	BNE	$000086AA
	000086A5 F4E1AC2708  	???'?       	JSR	$0008AE56
	000086AA D304        	??          	ADD	$04,A3
	000086AC FE          	?           	RTS	
	---------------------------
	
	000086AD F44016EB40  	?@??@       	MOV	D0,($40EB16)
	000086B2 A5          	?           	SUB	D1,D1
	000086B3 F4CABA8500  	?????       	MOVBU	($0085BA),D2
	000086B8 F74AC900    	?J??        	CMP	$00C9,D2
	000086BC E905        	??          	BNE	$000086C3
	000086BE F4E10D4908  	???I?       	JSR	$0008CFD0
	000086C3 DA29        	?)          	CMP	$29,D2			;')'
	000086C5 E905        	??          	BNE	$000086CC
	000086C7 F4E17E4908  	??~I?       	JSR	$0008D04A
	000086CC F74A8400    	?J??        	CMP	$0084,D2
	000086D0 E905        	??          	BNE	$000086D7
	000086D2 F4E16E4908  	??nI?       	JSR	$0008D045
	000086D7 FE          	?           	RTS	
	---------------------------
*/

	# Address 0x8502
	.byte	00,	0x85,0x02
	.byte	12,	0xea,0x00,0xfc,0xb4,0x00,0xf3,0xfe,0xc0,0xda,0xfc,0x00,0x02
	.byte	12,	0xea,0x15,0xc8,0x0e,0xfc,0xd8,0x54,0xe9,0x03,0xfd,0x86,0x00
	.byte	12,	0xc8,0x0e,0xfc,0xf4,0x74,0x77,0x0a,0x08,0xf0,0x00,0xfe,0xf5
	.byte	12,	0xd8,0xda,0xfc,0xf5,0xd8,0x44,0xfc,0xf2,0x7c,0xd0,0x04,0xcc
	.byte	12,	0x5b,0x80,0xd8,0x01,0xe9,0x02,0x7c,0x04,0xf4,0x75,0x42,0x85
	.byte	12,	0x00,0x51,0x20,0xfe,0xf5,0x5e,0x00,0xf5,0x5f,0x04,0x5d,0x08
	.byte	12,	0x5e,0x0c,0x82,0xf2,0xf3,0xf2,0x3e,0xd2,0x02,0xf4,0x75,0x24
	.byte	12,	0x00,0x40,0x31,0xd9,0x00,0xe9,0x02,0x8a,0x08,0xf7,0x10,0xff
	.byte	12,	0xf7,0x21,0xf4,0x79,0x00,0xf0,0x00,0xe9,0x0a,0x80,0x00,0xf5
	.byte	12,	0x10,0x09,0x80,0x00,0xc0,0x20,0x82,0x21,0xd9,0x06,0xe9,0x06
	.byte	12,	0x61,0x06,0xd5,0x06,0x41,0x06,0xf4,0x74,0x50,0xb1,0x08,0xf4
	.byte	12,	0xc8,0xba,0x85,0x00,0xd8,0x29,0xe9,0x05,0xf4,0x74,0x33,0xae
	.byte	12,	0x08,0xf7,0x48,0x84,0x00,0xe9,0x05,0xf4,0x74,0x80,0xae,0x08
	.byte	12,	0xf0,0x00,0xc8,0x20,0x82,0xd4,0x01,0xc0,0x20,0x82,0xf7,0x48
	.byte	12,	0x00,0x06,0xe9,0x0b,0x80,0x00,0xc0,0x20,0x82,0xf8,0x05,0x02
	.byte	12,	0xc0,0x44,0x80,0xfe,0x00,0xd3,0xfc,0x0e,0xf4,0xc8,0x03,0x0a
	.byte	12,	0x08,0xf4,0x44,0xba,0x85,0x00,0xf4,0x74,0x07,0x85,0x00,0xf7
	.byte	12,	0x20,0x4c,0x80,0xf4,0xc0,0x16,0xeb,0x40,0xf7,0x00,0xff,0xef
	.byte	12,	0xfd,0xd0,0x00,0xf8,0x0d,0x7f,0xfd,0x97,0x00,0xf8,0x0e,0x7f
	.byte	12,	0xfd,0x91,0x00,0xf8,0x0b,0x7f,0xfd,0x8b,0x00,0xf8,0x00,0x01
	.byte	12,	0xfd,0x73,0x00,0xf8,0x0b,0x7f,0xfd,0x7f,0x00,0xf8,0x0a,0x7f
	.byte	12,	0xfd,0x79,0x00,0xf8,0x0d,0x7f,0xfd,0x73,0x00,0xf8,0x80,0x00
	.byte	12,	0xfd,0x5b,0x00,0xf4,0xc0,0x16,0xeb,0x40,0xf7,0x40,0x00,0x10
	.byte	12,	0xfd,0x94,0x00,0x80,0x0c,0xf4,0xca,0xba,0x85,0x00,0xdc,0x8e
	.byte	12,	0x81,0xda,0x29,0xe9,0x03,0xdc,0x9a,0x81,0xf7,0x4a,0x84,0x00
	.byte	12,	0xe9,0x03,0xdc,0x96,0x81,0x10,0xf4,0x70,0x30,0xb1,0x00,0xf4
	.byte	12,	0xca,0xba,0x85,0x00,0xda,0x29,0xe9,0x05,0xf4,0x70,0x13,0xae
	.byte	12,	0x00,0xf7,0x4a,0x84,0x00,0xe9,0x05,0xf4,0x70,0x60,0xae,0x00
	.byte	12,	0xc0,0xd2,0xfc,0x80,0x08,0xc0,0xd4,0xfc,0x80,0x0c,0xc4,0xda
	.byte	12,	0xfc,0x80,0x00,0xc0,0x20,0x82,0x2e,0xd3,0x04,0xfe,0xf4,0x71
	.byte	12,	0xff,0xff,0xff,0xf7,0x1d,0x01,0x00,0xe9,0xfa,0xf7,0x1c,0x01
	.byte	12,	0x00,0xe9,0xef,0xfe,0xd3,0xfc,0xf9,0x00,0x10,0x0d,0x4c,0x02
	.byte	12,	0xf2,0x7c,0x80,0x02,0xf4,0xca,0xba,0x85,0x00,0xf7,0x4a,0xc9
	.byte	12,	0x00,0xe9,0x05,0xf4,0xe1,0x90,0x2a,0x08,0xda,0x29,0xe9,0x05
	.byte	12,	0xf4,0xe1,0x6a,0x27,0x08,0xf7,0x4a,0x84,0x00,0xe9,0x05,0xf4
	.byte	12,	0xe1,0xac,0x27,0x08,0xd3,0x04,0xfe,0xf4,0x40,0x16,0xeb,0x40
	.byte	12,	0xa5,0xf4,0xca,0xba,0x85,0x00,0xf7,0x4a,0xc9,0x00,0xe9,0x05
	.byte	12,	0xf4,0xe1,0x0d,0x49,0x08,0xda,0x29,0xe9,0x05,0xf4,0xe1,0x7e
	.byte	12,	0x49,0x08,0xf7,0x4a,0x84,0x00,0xe9,0x05,0xf4,0xe1,0x6e,0x49
	.byte	06,	0x08,0xfe,0xfe,0x74,0x08,0x06
	
	# Address 0x804c
	.byte	00,	0x80,0x4c
	.byte	03,	0x02,0x85,0x00
 
	# end
	.byte	99
	
.end