Page 1 of 1

How to properly send commands to the CD controller (low-level)

Posted: February 16th, 2019, 4:33 pm
by LameGuy64
I've been trying to figure this one out in awhile but was unable to figure it out. I'm working on some low level CD routines that allow me to send any command to the CD controller but it would often miss commands when I send a string of them to the controller judging by observing the CD-ROM command log in no$psx.

Here's the assembly code of my CD command function written in GNU assembler syntax:

Code: Select all

.set IOBASE,		0x1f80

.set CD_REG0,			0x1800
.set CD_REG1,			0x1801
.set CD_REG2,			0x1802
.set CD_REG3,			0x1803

StupidCdControl:
	
	# a0 - Command value
	# a1 - Arguments
	# a2 - Pointer to result buffer
	
	lui		$v1, IOBASE
	
	li		$v0, 1					# Clear parameter FIFO
	sb		$v0, CD_REG0($v1)
	li		$v0, 0x40
	sb		$v0, CD_REG3($v1)
	
.cmd_wait:							# Wait for CD to become ready to take commands
	lbu		$v0, CD_REG0($a1)
	nop
	andi	$v0, 0x80
	bnez	$v0, .cmd_wait
	nop
	
	la		$v0, _cd_busy			# Set internal values
	sw		$a0, 0($v0)
	la		$v0, _cd_result_dest
	sw		$a2, 0($v0)
	
	beqz	$a1, .no_params
	nop
	beq		$a0, 0x02, .setLoc_param
	nop
	beq		$a0, 0x03, .play_param
	nop
	beq		$a0, 0x0e, .setMode_param
	nop
	beq		$a0, 0x14, .getTD_param
	nop
	b		.no_params
	nop
.setLoc_param:
	b		.do_params
	li		$a3, 0x03
.play_param:
	b		.do_params
	li		$a3, 0x01
.setMode_param:
	b		.do_params
	li		$a3, 0x02
.getTD_param:
	li		$a3, 0x01
	sb		$0 , CD_REG0($v1)
.do_params:
	lbu		$v0, 0($a1)
	addi	$a3, -1
	sb		$v0, CD_REG1($v1)
	bgtz	$a3, .do_params
	addiu	$a1, 1
.no_params:

	sb		$0 , CD_REG0($v1)
	sb		$a0, CD_REG1($v1)
	
.param_wait:
	lbu		$v0, CD_REG0($v1)
	nop
	and		$v0, 0x8
	beqz	$v0, .param_wait
	nop
	
	jr		$ra
	nop
	
# Related to IRQ handler but that isn't really relevant to this issue
.comm _cd_busy,4,4
.comm _cd_result_dest,4,4
It'll successfully send a command to the CD controller at first but any further commands won't register. I think I'm missing something that I haven't figured out yet.

Re: How to properly send commands to the CD controller (low-level)

Posted: April 1st, 2019, 2:05 pm
by TriMesh
You always have to wait for the int before sending another command or it just gets dropped on the floor. If the last int hasn't been cleared, the HC05 just throws the command away.