Add read and write PTIMER registers. Doesn't actually do anything as a timer yet. Fix software and hardware interrupts being the wrong way around

This commit is contained in:
starfrost013
2024-12-09 11:57:54 +00:00
parent 2bb1175bc8
commit 4c2477a4cf
5 changed files with 59 additions and 5 deletions

View File

@@ -290,8 +290,12 @@ typedef struct nv3_pextdev_s
typedef struct nv3_ptimer_s
{
uint32_t interrupt_status; // Interrupt status
uint32_t interrupt_enable; // Interrupt enable
uint32_t interrupt_status; // PTIMER Interrupt status
uint32_t interrupt_enable; // PTIMER Interrupt enable
uint32_t clock_numerator; // PTIMER (tick?) numerator
uint32_t clock_denominator; // PTIMER (tick?) denominator
uint64_t time; // time
uint32_t alarm; // The value of time when there should be an alarm
} nv3_ptimer_t;
// Graphics object hashtable

View File

@@ -194,6 +194,11 @@ extern const device_config_t nv3_config[];
#define NV3_PTIMER_START 0x9000 // Programmable Interval Timer
#define NV3_PTIMER_INTR 0x9100
#define NV3_PTIMER_INTR_EN 0x9140
#define NV3_PTIMER_NUMERATOR 0x9200
#define NV3_PTIMER_DENOMINATOR 0x9210
#define NV3_PTIMER_TIME_0_NSEC 0x9400 // nanoseconds [31:5]
#define NV3_PTIMER_TIME_1_NSEC 0x9410 // nanoseconds [28:0]
#define NV3_PTIMER_ALARM_NSEC 0x9420 // nanoseconds [31:5]
#define NV3_PTIMER_END 0x9FFF
#define NV3_VGA_VRAM_START 0xA0000 // VGA Emulation VRAM
#define NV3_VGA_VRAM_END 0xBFFFF

View File

@@ -797,7 +797,7 @@ void* nv3_init(const device_t *info)
nv3_pfifo_init(); // Initialise FIFO for graphics object submission
nv3_pgraph_init(); // Initialise accelerated graphics engine
nv3_ptimer_init(); // Initialise programmable interval timer
nv3_pvideo_init(); // Initialise video overlay engines
nv3_pvideo_init(); // Initialise video overlay engine
return nv3;
}

View File

@@ -137,7 +137,7 @@ uint32_t nv3_pmc_handle_interrupts(bool send_now)
return nv3->pmc.interrupt_status;
}
if (!(nv3->pmc.interrupt_status & 0x7FFFFFFF))
if ((nv3->pmc.interrupt_status & 0x7FFFFFFF))
{
if (nv3->pmc.interrupt_enable & NV3_PMC_INTERRUPT_ENABLE_HARDWARE)
{

View File

@@ -32,6 +32,11 @@
nv_register_t ptimer_registers[] = {
{ NV3_PTIMER_INTR, "PTIMER - Interrupt Status", NULL, NULL},
{ NV3_PTIMER_INTR_EN, "PTIMER - Interrupt Enable", NULL, NULL,},
{ NV3_PTIMER_NUMERATOR, "PTIMER - Numerator", NULL, NULL, },
{ NV3_PTIMER_DENOMINATOR, "PTIMER - Denominator", NULL, NULL, },
{ NV3_PTIMER_TIME_0_NSEC, "PTIMER - Time0", NULL, NULL, },
{ NV3_PTIMER_TIME_1_NSEC, "PTIMER - Time1", NULL, NULL, },
{ NV3_PTIMER_ALARM_NSEC, "PTIMER - Alarm", NULL, NULL, },
{ NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value
};
@@ -75,6 +80,24 @@ uint32_t nv3_ptimer_read(uint32_t address)
return nv3->ptimer.interrupt_status;
case NV3_PTIMER_INTR_EN:
return nv3->ptimer.interrupt_enable;
case NV3_PTIMER_NUMERATOR:
return nv3->ptimer.clock_denominator; // 15:0
break;
case NV3_PTIMER_DENOMINATOR:
return nv3->ptimer.clock_denominator ; //15:0
break;
// 64-bit value
// High part
case NV3_PTIMER_TIME_0_NSEC:
return nv3->ptimer.time & 0xFFFFFFFF; //28:0
break;
// Low part
case NV3_PTIMER_TIME_1_NSEC:
return nv3->ptimer.time >> 32; // 31:5
break;
case NV3_PTIMER_ALARM_NSEC:
return nv3->ptimer.alarm; // 31:5
break;
}
}
}
@@ -112,7 +135,29 @@ void nv3_ptimer_write(uint32_t address, uint32_t value)
nv3_pmc_clear_interrupts();
break;
case NV3_PTIMER_INTR_EN:
nv3->ptimer.interrupt_enable = value & 0x00000001;
nv3->ptimer.interrupt_enable = value & 0x1;
break;
case NV3_PTIMER_NUMERATOR:
nv3->ptimer.clock_denominator = value & 0xFFFF; // 15:0
break;
case NV3_PTIMER_DENOMINATOR:
// prevent Div0
if (!value)
value = 1;
nv3->ptimer.clock_denominator = value & 0xFFFF; //15:0
break;
// 64-bit value
// High part
case NV3_PTIMER_TIME_0_NSEC:
nv3->ptimer.time = (value >> 32) & 0xFFFFFFE0; //28:0
break;
// Low part
case NV3_PTIMER_TIME_1_NSEC:
nv3->ptimer.time = ((value & 0xFFFFFFE0) << 32); // 31:5
break;
case NV3_PTIMER_ALARM_NSEC:
nv3->ptimer.alarm = value & 0xFFFFFFE0; // 31:5
break;
}
}