Z80 DAC Sound Problem

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
walker7
Interested
Posts: 45
Joined: Tue Jul 24, 2012 6:27 am

Z80 DAC Sound Problem

Post by walker7 » Mon Apr 18, 2016 2:35 am

I wrote a simple piece of Z80 code to play a small DAC sample. I've got it running properly. However, when I play it on various emulators, most of the time I don't hear anything, and I double-checked to make sure that the sound was on. I only hear the sample when I play it on Exodus. What's the problem?
When programming, you can do it if you put your mind to it.

Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Z80 DAC Sound Problem

Post by Sik » Mon Apr 18, 2016 3:52 am

Hard to tell without more info (although that it runs on Exodus does mean that it's indeed trying to send sound to the DAC). Do you know if it works on real hardware?

I would dare to guess that the most likely culprit is not initializing the Z80 properly (more especifically, the reset and bus request stuff).
Sik is pronounced as "seek", not as "sick".

walker7
Interested
Posts: 45
Joined: Tue Jul 24, 2012 6:27 am

Re: Z80 DAC Sound Problem

Post by walker7 » Mon Apr 18, 2016 4:19 am

Here's the code I used to initialize the Z80:

Code: Select all

	moveq	#$000,d0			; Load constant $0000 (bit 8 clear).
	move.w	#$100,d7			; Load constant $0100 (bit 8 set).
	lea	$A11100,a1			; POINT TO: Z80 Start/Stop Switch.
	lea	$A11200,a2			; POINT TO: Z80 Reset Switch.
	lea	Z80_Program(pc),a5		; POINT TO: Z80 Program.
	lea	$A00000,a0			; POINT TO: Z80.

	move.w	#$100,(a1)			; Stop the Z80.
	move.w	#$100,(a2)			; Reset the Z80.
.2:	btst	d0,(a1)				; Test bit 0 of $A11000 (Z80 busy bit) for clear.
	bne.b	.2				; If it's set, loop (spin).

	move.w	#Z80Program_Length-1,d2		; Initialize Loop Counter.
.1:	move.b	(a5)+,(a0)+			; Write a byte of Z80 code.
	dbra	d2,.1				; Loop for next byte.
	
	move.w	d0,(a2)				; Reset the Z80.
	move.w	d0,(a1)				; Unlock the Z80.


And here's the code I originally used to play back my DAC sample:

Code: Select all

di		; disable interrupts
xor	a		; set a to 0
ld	hl, 6000H	; bank switcher

; use 32k bank 1 ($008000-$00FFFF)
ld 	(hl),1	; bit 15 = 1
ld 	(hl),a	; bit 16 = 0
ld 	(hl),a	; bit 17 = 0
ld 	(hl),a	; bit 18 = 0
ld 	(hl),a	; bit 19 = 0
ld 	(hl),a	; bit 20 = 0
ld 	(hl),a	; bit 21 = 0
ld 	(hl),a	; bit 22 = 0
ld 	(hl),a	; bit 23 = 0

ld	de,0831h	; length of sample

ld	hl,4000h	; fm register port
ld	(hl),B4h	; select register $B4 (stereo control)

ld	hl,4001h	; fm data port
ld	(hl),C0h	; enable stereo on both speakers

ld	hl,4000h	; fm register port
ld	(hl),2Bh	; select register $2B (DAC enable)

inc	hl		; hl points to $4001 (fm data port)
ld	(hl),80h	; write $80 to enable DAC

ld	ix,8000h	; point to beginning of sample
loop1:
ld	iy,4000h	; fm register port

ld	(iy),2Bh	; select register $2B (this just might be where the error occurs...maybe it should be $2A)
ld	a,(ix)	; load byte from sample
ld	iy,4001h	; fm data port
ld	(iy),a	; write byte from sample (note that it's writing to register $2B)

inc	ix		; move to next byte
dec	de		; decrement length

ld	b,15		; sample speed
loop2:
djnz	loop2		; this loop controls the pitch of the sample

ld	a,d		; load a with d
or	e		; or a with e

jr	nz,loop1	; if there are sample bytes left, loop for next byte
jr	FEh		; loop forever

EDIT: I just tested it with the erroneous $2B changed to $2A listed above, and it worked.
When programming, you can do it if you put your mind to it.

Post Reply