aisetfreq OK, some libultra improvements (#416)

* aisetfreq OK

* Add a lot of HW_REG and some other macros to libultra

* Format

* Remove extra volatile

* Review

* De-C guNormalize

* Correct typo in crc.c
This commit is contained in:
EllipticEllipsis 2021-11-18 18:15:09 +00:00 committed by GitHub
parent 89b9d90826
commit dfc146663f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 107 additions and 46 deletions

View File

@ -11,6 +11,7 @@
#include "ultra64/sptask.h"
#include "ultra64/thread.h"
#include "ultra64/rcp.h"
#include "ultra64/rdp.h"
#include "ultra64/rsp.h"
#include "ultra64/vi.h"

View File

@ -96,6 +96,7 @@
#define SI_STATUS_INTERRUPT (1 << 12)
#define PIF_RAM_START 0x1FC007C0
#define PIF_RAM_SIZE 0x40
#define MI_INIT_MODE_REG 0x04300000
#define MI_MODE_REG MI_INIT_MODE_REG

45
include/ultra64/rdp.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef ULTRA64_RDP_H
#define ULTRA64_RDP_H
/* DP Command Registers */
#define DPC_START_REG 0x04100000
#define DPC_END_REG 0x04100004
#define DPC_CURRENT_REG 0x04100008
#define DPC_STATUS_REG 0x0410000C
#define DPC_CLOCK_REG 0x04100010
#define DPC_BUFBUSY_REG 0x04100014
#define DPC_PIPEBUSY_REG 0x04100018
#define DPC_TMEM_REG 0x0410001C
/* DP Span Registers */
#define DPS_TBIST_REG 0x04200000
#define DPS_TEST_MODE_REG 0x04200004
#define DPS_BUFTEST_ADDR_REG 0x04200008
#define DPS_BUFTEST_DATA_REG 0x0420000C
/* DP Status Read Flags */
#define DPC_STATUS_XBUS_DMEM_DMA (1 << 0)
#define DPC_STATUS_FREEZE (1 << 1)
#define DPC_STATUS_FLUSH (1 << 2)
#define DPC_STATUS_START_GCLK (1 << 3)
#define DPC_STATUS_TMEM_BUSY (1 << 4)
#define DPC_STATUS_PIPE_BUSY (1 << 5)
#define DPC_STATUS_CMD_BUSY (1 << 6)
#define DPC_STATUS_CBUF_READY (1 << 7)
#define DPC_STATUS_DMA_BUSY (1 << 8)
#define DPC_STATUS_END_VALID (1 << 9)
#define DPC_STATUS_START_VALID (1 << 10)
/* DP Status Write Flags */
#define DPC_CLR_XBUS_DMEM_DMA (1 << 0)
#define DPC_SET_XBUS_DMEM_DMA (1 << 1)
#define DPC_CLR_FREEZE (1 << 2)
#define DPC_SET_FREEZE (1 << 3)
#define DPC_CLR_FLUSH (1 << 4)
#define DPC_SET_FLUSH (1 << 5)
#define DPC_CLR_TMEM_CTR (1 << 6)
#define DPC_CLR_PIPE_CTR (1 << 7)
#define DPC_CLR_CMD_CTR (1 << 8)
#define DPC_CLR_CLOCK_CTR (1 << 9)
#endif

View File

@ -8,7 +8,7 @@
// pre-boot variables
extern u32 osTvType;
extern u32 osRomType;
extern u32 osRomBase;
extern uintptr_t osRomBase;
extern u32 osResetType;
extern u32 osCicId;
extern u32 osVersion;

2
spec
View File

@ -170,7 +170,7 @@ beginseg
include "build/src/libultra/voice/voicecontwrite20.o"
include "build/src/libultra/io/crc.o"
include "build/src/libultra/os/getactivequeue.o"
include "build/src/libultra/gu/normalize.o"
include "build/asm/boot/normalize.text.o"
include "build/asm/boot/setcompare.text.o"
include "build/asm/boot/getcompare.text.o"
include "build/src/libultra/io/dpgetstat.o"

View File

@ -1,3 +0,0 @@
#include "global.h"
#pragma GLOBAL_ASM("asm/non_matchings/boot/normalize/guNormalize.s")

View File

@ -1,5 +1,5 @@
#include "global.h"
u32 osAiGetLength(void) {
return *(u32*)0xA4500004;
return HW_REG(AI_LEN_REG, u32);
}

View File

@ -1,3 +1,20 @@
#include "global.h"
#pragma GLOBAL_ASM("asm/non_matchings/boot/aisetfreq/osAiSetFrequency.s")
s32 osAiSetFrequency(u32 frequency) {
u8 bitrate;
f32 dacRateF = ((f32)osViClock / frequency) + 0.5f;
u32 dacRate = dacRateF;
if (dacRate < 132) {
return -1;
}
bitrate = (dacRate / 66);
if (bitrate > 16) {
bitrate = 16;
}
HW_REG(AI_DACRATE_REG, u32) = dacRate - 1;
HW_REG(AI_BITRATE_REG, u32) = bitrate - 1;
return osViClock / (s32)dacRate;
}

View File

@ -34,7 +34,7 @@
* \f[ m(X) X^n = Q(X) p(X) + R(X) \f]
* (\f$ R(X) \f$ is the *remainder after dividing by \f$ p(X) \f$*).
* - Therefore, \f$ m(X) X^n - R(X) \f$ is divisible by the generator polynomial. This means that if we append the
* binary number corresponding to \f$ R(X) \f$ to the message and rerun the algorithm, we will get 0 if now errors have
* binary number corresponding to \f$ R(X) \f$ to the message and rerun the algorithm, we will get 0 if no errors have
* been introduced.
*
*

View File

@ -1,5 +1,5 @@
#include "global.h"
u32 osDpGetStatus(void) {
return *(u32*)0xA410000C;
return HW_REG(DPC_STATUS_REG, u32);
}

View File

@ -1,5 +1,5 @@
#include "global.h"
void osDpSetStatus(u32 data) {
*(u32*)0xA410000C = data;
HW_REG(DPC_STATUS_REG, u32) = data;
}

View File

@ -1,23 +1,22 @@
#include "global.h"
s32 __osPiRawStartDma(s32 direction, u32 devAddr, void* dramAddr, size_t size) {
register int stat;
s32 __osPiRawStartDma(s32 direction, uintptr_t devAddr, void* dramAddr, size_t size) {
register int status = HW_REG(PI_STATUS_REG, u32);
stat = *(vu32*)0xA4600010;
while (stat & (2 | 1)) {
stat = *(vu32*)0xA4600010;
while (status & (PI_STATUS_IOBUSY | PI_STATUS_BUSY)) {
status = HW_REG(PI_STATUS_REG, u32);
}
*(u32*)0xA4600000 = osVirtualToPhysical(dramAddr);
HW_REG(PI_DRAM_ADDR_REG, u32) = osVirtualToPhysical(dramAddr);
*(u32*)0xA4600004 = ((osRomBase | devAddr) & 0x1fffffff);
HW_REG(PI_CART_ADDR_REG, u32) = ((osRomBase | devAddr) & 0x1FFFFFFF);
switch (direction) {
case 0:
*(u32*)0xA460000C = size - 1;
case OS_READ:
HW_REG(PI_WR_LEN_REG, u32) = size - 1;
break;
case 1:
*(u32*)0xA4600008 = size - 1;
case OS_WRITE:
HW_REG(PI_RD_LEN_REG, u32) = size - 1;
break;
default:
return -1;

View File

@ -1,11 +1,11 @@
#include "global.h"
int __osSiDeviceBusy() {
register u32 status;
status = *(u32*)0xA4800018;
if (status & 3) {
return 1;
s32 __osSiDeviceBusy() {
register u32 status = HW_REG(SI_STATUS_REG, u32);
if (status & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) {
return true;
} else {
return 0;
return false;
}
}

View File

@ -1,24 +1,24 @@
#include "global.h"
s32 __osSiRawStartDma(s32 direction, void* dramAddr) {
if ((*(u32*)0xA4800018 & 0x3) != 0) {
if (HW_REG(SI_STATUS_REG, u32) & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) {
return -1;
}
if (direction == 1) {
osWritebackDCache(dramAddr, 64);
if (direction == OS_WRITE) {
osWritebackDCache(dramAddr, PIF_RAM_SIZE);
}
*(u32*)0xA4800000 = osVirtualToPhysical(dramAddr);
HW_REG(SI_DRAM_ADDR_REG, u32) = osVirtualToPhysical(dramAddr);
if (direction == 0) {
*(u32*)0xA4800004 = 0x1FC007C0;
if (direction == OS_READ) {
HW_REG(SI_PIF_ADDR_RD64B_REG, void*) = (void*)PIF_RAM_START;
} else {
*(u32*)0xA4800010 = 0x1FC007C0;
HW_REG(SI_PIF_ADDR_WR64B_REG, void*) = (void*)PIF_RAM_START;
}
if (direction == 0) {
osInvalDCache(dramAddr, 64);
if (direction == OS_READ) {
osInvalDCache(dramAddr, PIF_RAM_SIZE);
}
return 0;
}

View File

@ -5,6 +5,7 @@ s32 __osSpDeviceBusy(void) {
if (status & (SP_STATUS_DMA_BUSY | SP_STATUS_DMA_FULL | SP_STATUS_IO_FULL)) {
return true;
} else {
return false;
}
return false;
}

View File

@ -1,5 +1,5 @@
#include "global.h"
u32 __osSpGetStatus() {
return *(vu32*)0xA4040010;
return HW_REG(SP_STATUS_REG, u32);
}

View File

@ -1,17 +1,17 @@
#include "global.h"
s32 __osSpRawStartDma(s32 direction, void* devAddr, void* dramAddr, size_t size) {
if (__osSpDeviceBusy() != 0) {
if (__osSpDeviceBusy()) {
return -1;
}
*(vu32*)0xA4040000 = devAddr;
*(vu32*)0xA4040004 = osVirtualToPhysical(dramAddr);
HW_REG(SP_MEM_ADDR_REG, u32) = devAddr;
HW_REG(SP_DRAM_ADDR_REG, u32) = osVirtualToPhysical(dramAddr);
if (direction == 0) {
*(vu32*)0xA404000C = size - 1;
if (direction == OS_READ) {
HW_REG(SP_WR_LEN_REG, u32) = size - 1;
} else {
*(vu32*)0xA4040008 = size - 1;
HW_REG(SP_RD_LEN_REG, u32) = size - 1;
}
return 0;

View File

@ -1,5 +1,5 @@
#include "global.h"
void __osSpSetStatus(u32 data) {
*(vu32*)0xA4040010 = data;
HW_REG(SP_STATUS_REG, u32) = data;
}

View File

@ -17,7 +17,7 @@ void __osViInit(void) {
__osViNext->modep = &osViModePalLan1;
} else if (osTvType == OS_TV_MPAL) {
__osViNext->modep = &osViModeMpalLan1;
} else {
} else { // OS_TV_NTSC or OS_TV_UNK28
__osViNext->modep = &osViModeNtscLan1;
}