VOGONS


First post, by furrykef

User metadata
Rank Newbie
Rank
Newbie

I wasn't too sure which forum to put this in, so I'm putting it here. Please move as necessary. (Maybe it should go in one of the DosBox forums, but I'm also interested in how this behaves on a real Tandy...)

I'm writing an NSF player -- y'know, Nintendo music -- for the Tandy 1000 and IBM PCjr. So far this has worked splendidly except for one thing: the SN76489 kinda sucks at being a 2A03. Not only do the squares have no duty cycle and triangles are not possible, the bottom octave is missing. For the NES triangle channel, the bottom two octaves are missing, so many songs have no bass. I find this unacceptable.

So I thought, OK, I'll just set the frequency to zero and toggle the volume to play arbitrary waveforms manually. (This is not unlike the "RealSound" technology used for the PC speaker.) This almost works in DosBox 0.74. I wrote a test program that hooks the 1Ch (or 08h) interrupt and plays a square wave by toggling whenever the timer fires. The problem is, there are gaps in the square wave where the peak or trough is about twice as long as it should be. The result sounds like some kind of really bad arpeggio instead of a solid square wave. I have confirmed that DosBox is running literally nothing aside from my timer routine, so it's not like some other interrupt is interfering. Upon thinking about it further, I think what's happening is that the system clock is slightly out of sync with the SN76489's clock, so sometimes the volume is toggled before the SN's timer fires and sometimes it's toggled after, hence the apparent skips. However, I'm not 100% sure on this yet.

I'm trying to determine if this is a fault in DosBox or if the real hardware behaves this way. I have attached my test program below. (Note that there is no way to kill it, so it will require a reboot.) It would be nice if somebody could tell me how it sounds on a real Tandy. If a real Tandy produces a solid square, then we can work on fixing DosBox to produce the same result.

To assemble with NASM: nasm test.asm -fbin -o test.com

    cpu     8086
org 0x100

section .text

start:
; Set up multiplexer
in al, 0x61
or al, 0x60
out 0x61, al

; Set channel freq to 0 (flat output)
mov al, 0x80
out 0xc0, al
xor al, al
out 0xc0, al

; Silence channel
mov al, 0x9F
out 0xc0, al

; Kill all interrupts for now
; (Note: in a real program, we'd need to restore them upon exit)
mov al, 0xff
out 0x21, al

; Install timer ISR
; NB: In actual program, will have to uninstall ISR afterwards
; Remember DS == CS, so DS:DX == CS:DX
;mov dx, ISR
;mov ah, 0x25 ; DOS service 0x25 = install ISR
;mov al, 0x08 ; 0x08 = system timer interrupt
;int 0x21

; Install timer ISR the hard way
xor ax, ax
mov es, ax
mov ax, ISR
mov [ES:8*4], ax
mov ax, cs
mov [ES:8*4+2], ax


; Set clock
; NB: In actual program, will have to reset clock when done
; (same code, just send 0's to 0x40 instead)
; Then also set DOS to real time clock
mov al, 0b00111010 ; @TODO@ -- which mode (bits 1-3)?
out 0x43, al
mov al, 0x70 ; Low bits
out 0x40, al
mov al, 4
out 0x40, al ; High bits

; Enable just the timer interrupt
mov al, 0xfe
out 0x21, al

; 'Forever' is brought to you by Pinkie Pie
forever:
Show last 32 lines
    jmp     forever


ISR:
cli
push ds
push ax

; Set DS to CS
push cs
pop ds

mov al, [SquareToggle]
not al
mov [SquareToggle], al

and al, 0x0f
or al, 0x90
out 0xc0, al

pop ds

; Tell 8259A interrupt done
mov al, 0x20
out 0x20, al

pop ax
sti
iret


SquareToggle: db 0

Reply 2 of 7, by Great Hierophant

User metadata
Rank l33t
Rank
l33t
ripsaw8080 wrote:

The issue was brought up recently, so it's something of a coincidence to see a second thread on the subject:
Tandy 1000 Non-DAC Digitized PWM Samples

The Tandy used an SN76496 😁

http://nerdlypleasures.blogspot.com/ - Nerdly Pleasures - My Retro Gaming, Computing & Tech Blog

Reply 3 of 7, by furrykef

User metadata
Rank Newbie
Rank
Newbie

For all intents and purposes it's an SN76489, though. They're basically the same chip, and "SN76489" is the better known name.

I hear that the "set frequency to 0" trick doesn't work on SN chips made by TI, so it's quite possible that the test program (the ASM code above) will output nothing on a real Tandy. Only one way to find out for sure, though.

I also realized that not everybody who has a Tandy lying around is going to want to mess around with NASM. So I've attached the test program above as a prebuilt .com file. (Ironically, it's smaller unzipped than zipped, but I had to zip it because the forum doesn't like .com files.) Again, it's a Tandy .com file, so it'll only run on a Tandy.

Attachments

  • Filename
    test.zip
    File size
    201 Bytes
    Downloads
    210 downloads
    File license
    Fair use/fair dealing exception

Reply 4 of 7, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author
furrykef wrote:

I hear that the "set frequency to 0" trick doesn't work on SN chips made by TI

The Wikipedia page for the SN76489 suggests that the Tandy 1000 used an NCR clone, but perhaps not in every machine manufactured:

Another clone is the NCR 7496 or NCR 8496, used in the Tandy 1000 computer. It again has a different white noise pattern but is otherwise functionally identical to the SN76489.

Reply 5 of 7, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie
furrykef wrote:

I'm writing an NSF player -- y'know, Nintendo music -- for the Tandy 1000 and IBM PCjr. So far this has worked splendidly except for one thing: the SN76489 kinda sucks at being a 2A03. Not only do the squares have no duty cycle and triangles are not possible, the bottom octave is missing. For the NES triangle channel, the bottom two octaves are missing, so many songs have no bass. I find this unacceptable.

Tandy's "PSSJ" ASIC, found in the TL/SL and later systems, integrates the SN76496 while adding a number of enhancements. Two that may interest you include an extra bit of frequency division, allowing for frequencies down to 54.62Hz, and a DAC channel that can also function as fourth PSG voice with selectable waveform (Pulse w/variable duty cycle, Ramp, or Triangle).

The systems bearing a PSSJ chip aren't exactly uncommon, so it would be fantastic if your NSF player could utilize these extra features.

Technical and programming information can be found here:

ftp://ftp.oldskool.org/pub/tvdog/tandy1000/do … ents/tltech.zip
ftp://ftp.oldskool.org/pub/tvdog/tandy1000/so … nd/tspak181.zip

Reply 6 of 7, by Great Hierophant

User metadata
Rank l33t
Rank
l33t

My Tandy 1000SX uses an NCR 8496, but the tech reference schematic indicates that a TI SN76496 can be used if a resistor is changed. There is a socket for the chip.

Last edited by Great Hierophant on 2016-09-19, 16:54. Edited 1 time in total.

http://nerdlypleasures.blogspot.com/ - Nerdly Pleasures - My Retro Gaming, Computing & Tech Blog