VOGONS


First post, by riplin

User metadata
Rank Newbie
Rank
Newbie

Hi folks,

I'm doing some GUS programming and I'm having trouble getting the on board timers to function. I've confirmed that my interrupt handler is hooked up properly by hooking it up to int 8 instead and then it functions correctly. But when I try to hook it up to the IRQ of the GUS, and start the timers, nothing happens. This is what I'm doing:

My card reset function sets the global interrupt enable flag in the reset register (along with the two other bits):
- Write 0x4c (reset) to index register at port BaseAddress + 0x103 (0x3X3)
- Write 0x07 (master enable, dma enable, interrupt enable) to data high register at port BaseAddress + 0x105 (0x3x5)

Then when I configure the timer, I do the following:

Set up the timer start count:
- Write 0x46(timer 1 count) to index register at port BaseAddress + 0x103 (0x3X3)
- Write 0x05 (comes to 50Hz) to data high register at port BaseAddress + 0x105 (0x3x5)

Enable timer in timer control register:
- Write 0x45(timer control) to index register at port BaseAddress + 0x103(0x3x3)
- Write 0x04 (enable timer 1) to data high register at port BaseAddress + 0x105(0x3x5)

Start timer:
- Write 0x04 (Select timer control) to port BaseAddress + 0x008 (0x2x8)
- Write 0x01 (Start timer 1) to port BaseAddress + 0x009 (0x2x9)

From what I understand, this should kick off the timer, but nothing happens. I'm testing in DosBox-X and on real hardware using a PicoGUS. Both behave the same way thankfully (not working though). So it's obviously my fault, but I can't figure out why it won't work.

I've also confirmed that I'm actually talking to the card by detecting that the GUS is present (writing to GUS memory and checking the values).

What am I missing?

Any help is greatly appreciated!

Last edited by riplin on 2025-07-17, 08:51. Edited 1 time in total.

Reply 1 of 8, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie
riplin wrote on 2025-07-17, 08:20:

Set up the timer start count:
- Write 0x43(timer 1 count) to index register at port BaseAddress + 0x103 (0x3X3)

Where are you getting this from? That doesn't look like it's the timer 1 count register.

Reply 2 of 8, by riplin

User metadata
Rank Newbie
Rank
Newbie
jmarsh wrote on 2025-07-17, 08:30:
riplin wrote on 2025-07-17, 08:20:

Set up the timer start count:
- Write 0x43(timer 1 count) to index register at port BaseAddress + 0x103 (0x3X3)

Where are you getting this from? That doesn't look like it's the timer 1 count register.

Sorry, that's a typo in my post. That should be 0x46, not 0x43.

Reply 3 of 8, by riplin

User metadata
Rank Newbie
Rank
Newbie

One thing I'm wondering is that If I do a full reset of the card by setting the reset (0x4c) to 0x00, does that also wipe out the interrupt and dma configuration in register 0x2XB? I can imagine interrupts not working if there is no interrupt configured on the card...

Edit: Well that wasn't it. I set up the dma and interrupt registers at 0x2XB, same as the SDK code and still no interrupts.

Edit2: So there's a pair of system interrupt mask registers (port 0x21 and port 0xa1). I should probably unmask the interrupts there as well. Let's see if that helps.

Reply 4 of 8, by pan069

User metadata
Rank Oldbie
Rank
Oldbie

Are you enabling the timer interrupt in the IRQ status enable register? This seems to be a missing step based on your description.

You must explicitly enable the timer interrupt in the IRQ Status Enable Register at index 0x4C. It is not enough to just set the "interrupt enable" bit in the reset register that just enables the overall IRQ system.

Try this:

; Enable timer 1 interrupt in IRQ Status Enable Register
mov dx, BaseAddress + 0x103 ; Index register
mov al, 0x4C ; IRQ Status Enable Register
out dx, al

mov dx, BaseAddress + 0x105 ; Data High register
mov al, 0x01 ; Bit 0 = Timer 1 IRQ enable
out dx, al

This is critical because without enabling the specific source (timer IRQ), the GUS will never raise an IRQ even if timers are running.

Reply 5 of 8, by riplin

User metadata
Rank Newbie
Rank
Newbie
pan069 wrote on 2025-07-17, 10:38:
Are you enabling the timer interrupt in the IRQ status enable register? This seems to be a missing step based on your descriptio […]
Show full quote

Are you enabling the timer interrupt in the IRQ status enable register? This seems to be a missing step based on your description.

You must explicitly enable the timer interrupt in the IRQ Status Enable Register at index 0x4C. It is not enough to just set the "interrupt enable" bit in the reset register that just enables the overall IRQ system.

Try this:

; Enable timer 1 interrupt in IRQ Status Enable Register
mov dx, BaseAddress + 0x103 ; Index register
mov al, 0x4C ; IRQ Status Enable Register
out dx, al

mov dx, BaseAddress + 0x105 ; Data High register
mov al, 0x01 ; Bit 0 = Timer 1 IRQ enable
out dx, al

This is critical because without enabling the specific source (timer IRQ), the GUS will never raise an IRQ even if timers are running.

Hi, yes, I do that in me reset function:

riplin wrote on 2025-07-17, 08:20:
... My card reset function sets the global interrupt enable flag in the reset register (along with the two other bits): - Write […]
Show full quote

...
My card reset function sets the global interrupt enable flag in the reset register (along with the two other bits):
- Write 0x4c (reset) to index register at port BaseAddress + 0x103 (0x3X3)
- Write 0x07 (master enable, dma enable, interrupt enable) to data high register at port BaseAddress + 0x105 (0x3x5)
...

Reply 6 of 8, by riplin

User metadata
Rank Newbie
Rank
Newbie
riplin wrote on 2025-07-17, 08:55:

One thing I'm wondering is that If I do a full reset of the card by setting the reset (0x4c) to 0x00, does that also wipe out the interrupt and dma configuration in register 0x2XB? I can imagine interrupts not working if there is no interrupt configured on the card...

Edit: Well that wasn't it. I set up the dma and interrupt registers at 0x2XB, same as the SDK code and still no interrupts.

Edit2: So there's a pair of system interrupt mask registers (port 0x21 and port 0xa1). I should probably unmask the interrupts there as well. Let's see if that helps.

That didn't help. 🙁 Good that it's now there, but still no running timers.

Reply 8 of 8, by riplin

User metadata
Rank Newbie
Rank
Newbie
pan069 wrote on 2025-07-17, 10:38:
Are you enabling the timer interrupt in the IRQ status enable register? This seems to be a missing step based on your descriptio […]
Show full quote

Are you enabling the timer interrupt in the IRQ status enable register? This seems to be a missing step based on your description.

You must explicitly enable the timer interrupt in the IRQ Status Enable Register at index 0x4C. It is not enough to just set the "interrupt enable" bit in the reset register that just enables the overall IRQ system.

Try this:

; Enable timer 1 interrupt in IRQ Status Enable Register
mov dx, BaseAddress + 0x103 ; Index register
mov al, 0x4C ; IRQ Status Enable Register
out dx, al

mov dx, BaseAddress + 0x105 ; Data High register
mov al, 0x01 ; Bit 0 = Timer 1 IRQ enable
out dx, al

This is critical because without enabling the specific source (timer IRQ), the GUS will never raise an IRQ even if timers are running.

So, coming back to this, poking around the PicoGUS/DOSBox code, I found the following comment:

/* Behavior observed on real GUS hardware: Master IRQ enable bit 2 of the reset register affects only voice/wave
* IRQ signals from the GF1. It does not affect the DMA terminal count interrupt nor does it affect the Adlib timers.
* This is how "Juice" by Psychic Link is able to play music by GUS timer even though the demo never enables the
* Master IRQ Enable bit. */

Still not anywhere closer to get the blasted thing to generate an IRQ though. ugh.

So this flag doesn't affect the timer interrupts.