diff options
| author | Jack Walker <7463599+Jack-Walker@users.noreply.github.com> | 2020-03-17 00:31:30 -0400 |
|---|---|---|
| committer | Jack Walker <7463599+Jack-Walker@users.noreply.github.com> | 2020-03-17 00:31:30 -0400 |
| commit | 087f561f7786a812c815b9198f24e6acd0477497 (patch) | |
| tree | 8e8b1efeb798ff0b341d39de024d7b8554013c4a /src/libultra_boot_O2 | |
| parent | be78236d36a5eb4ef80acef6188751f6b5d176ae (diff) | |
First proper commit.
Diffstat (limited to 'src/libultra_boot_O2')
35 files changed, 1671 insertions, 0 deletions
diff --git a/src/libultra_boot_O2/_Ldtob.c b/src/libultra_boot_O2/_Ldtob.c new file mode 100644 index 000000000..4a72dfd33 --- /dev/null +++ b/src/libultra_boot_O2/_Ldtob.c @@ -0,0 +1,286 @@ +#include <global.h> +#include <stdlib.h> +#include <string.h> +#include <ultra64/printf.h> + +#define BUFF_LEN 0x20 + +s16 _Ldunscale(s16 *, _Pft *); +void _Genld(_Pft *, u8, u8 *, s16, s16); + +const double D_800122E0[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L }; + +/* float properties */ +#define _D0 0 +#define _DBIAS 0x3ff +#define _DLONG 1 +#define _DOFF 4 +#define _FBIAS 0x7e +#define _FOFF 7 +#define _FRND 1 +#define _LBIAS 0x3ffe +#define _LOFF 15 +/* integer properties */ +#define _C2 1 +#define _CSIGN 1 +#define _ILONG 0 +#define _MBMAX 8 +#define NAN 2 +#define INF 1 +#define FINITE -1 +#define _DFRAC ((1 << _DOFF) - 1) +#define _DMASK (0x7fff & ~_DFRAC) +#define _DMAX ((1 << (15 - _DOFF)) - 1) +#define _DNAN (0x8000 | _DMAX << _DOFF | 1 << (_DOFF - 1)) +#define _DSIGN 0x8000 +#if _D0 == 3 +#define _D1 2 /* little-endian order */ +#define _D2 1 +#define _D3 0 +#else +#define _D1 1 /* big-endian order */ +#define _D2 2 +#define _D3 3 +#endif + +void _Ldtob(_Pft *args, u8 type) { + u8 buff[BUFF_LEN]; + u8 *ptr; + u32 sp70; + f64 val; + /* maybe struct? */ + s16 err; + s16 nsig; + s16 exp; + + s32 i; + s32 n; + f64 factor; + s32 gen; + s32 j; + s32 lo; + ldiv_t qr; + u8 drop; + s32 n2; + + ptr = buff; + val = args->v.ld; + if (args->prec < 0) { + args->prec = 6; + } else { + if (args->prec == 0 && (type == 'g' || type == 'G')) { + args->prec = 1; + } + } + err = _Ldunscale(&exp, (_Pft*)args); + if (err > 0) { + memcpy(args->s, err == 2 ? "NaN" : "Inf", args->n1 = 3); + return; + } + if (err == 0) { + nsig = 0; + exp = 0; + } else { + if (val < 0) { + val = -val; + } + exp = exp * 30103 / 0x000186A0 - 4; + if (exp < 0) { + n = (3 - exp) & ~3; + exp = -n; + for (i = 0; n > 0; n >>= 1, i++) { + if ((n & 1) != 0) { + val *= D_800122E0[i]; + } + } + } else { + if (exp > 0) { + factor = 1; + exp &= ~3; + + for (n = exp, i = 0; n > 0; n >>= 1, i++) { + if ((n & 1) != 0) { + factor *= D_800122E0[i]; + } + } + val /= factor; + } + } + gen = ((type == 'f') ? exp + 10 : 6) + args->prec; + if (gen > 0x13) { + gen = 0x13; + } + *ptr++ = '0'; + while (gen > 0 && 0 < val) { + lo = val; + if ((gen -= 8) > 0) { + val = (val - lo) * 1.0e8; + } + ptr = ptr + 8; + for (j = 8; lo > 0 && --j >= 0;) { + qr = ldiv(lo, 10); + *--ptr = qr.rem + '0'; + lo = qr.quot; + } + while (--j >= 0) { + ptr--; + *ptr = '0'; + } + ptr += 8; + } + + gen = ptr - &buff[1]; + for (ptr = &buff[1], exp += 7; *ptr == '0'; ptr++) { + --gen, --exp; + } + + nsig = ((type == 'f') ? exp + 1 : ((type == 'e' || type == 'E') ? 1 : 0)) + args->prec; + if (gen < nsig) { + nsig = gen; + } + if (nsig > 0) { + if (nsig < gen && ptr[nsig] > '4') { + drop = '9'; + } else { + drop = '0'; + } + + for (n2 = nsig; ptr[--n2] == drop;) { + nsig--; + } + if (drop == '9') { + ptr[n2]++; + } + if (n2 < 0) { + --ptr, ++nsig, ++exp; + } + } + } + _Genld((_Pft*)args, type, ptr, nsig, exp); +} + +s16 _Ldunscale(s16 *pex, _Pft *px) { + + unsigned short *ps = (unsigned short *) px; + short xchar = (ps[_D0] & _DMASK) >> _DOFF; + if (xchar == _DMAX) { /* NaN or INF */ + *pex = 0; + return (s16)(ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF); + } else if (0 < xchar) { + ps[_D0] = (ps[_D0] & ~_DMASK) | (_DBIAS << _DOFF); + *pex = xchar - (_DBIAS - 1); + return (FINITE); + } + if (0 > xchar) { + return NAN; + } else { + *pex = 0; + return (0); + } +} + +void _Genld(_Pft *px, u8 code, u8 *p, s16 nsig, s16 xexp) { + u8 point = '.'; + if (nsig <= 0) { + nsig = 1, + + p = (u8 *) "0"; + } + + if (code == 'f' + || ((code == 'g' || code == 'G') && (-4 <= xexp) && (xexp < px->prec))) { /* 'f' format */ + ++xexp; /* change to leading digit count */ + if (code != 'f') { /* fixup for 'g' */ + if (!(px->flags & FLAGS_HASH) && nsig < px->prec) { + px->prec = nsig; + } + if ((px->prec -= xexp) < 0) { + px->prec = 0; + } + } + if (xexp <= 0) { /* digits only to right of point */ + px->s[px->n1++] = '0'; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1++] = point; + } + if (px->prec < -xexp) { + xexp = -px->prec; + } + px->nz1 = -xexp; + px->prec += xexp; + if (px->prec < nsig) { + nsig = px->prec; + } + memcpy(&px->s[px->n1], p, px->n2 = nsig); + px->nz2 = px->prec - nsig; + } else if (nsig < xexp) { /* zeros before point */ + memcpy(&px->s[px->n1], p, nsig); + px->n1 += nsig; + px->nz1 = xexp - nsig; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1] = point, ++px->n2; + } + px->nz2 = px->prec; + } else { /* enough digits before point */ + memcpy(&px->s[px->n1], p, xexp); + px->n1 += xexp; + nsig -= xexp; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1++] = point; + } + if (px->prec < nsig) { + nsig = px->prec; + } + memcpy(&px->s[px->n1], p + xexp, nsig); + px->n1 += nsig; + px->nz1 = px->prec - nsig; + } + } else { /* 'e' format */ + if (code == 'g' || code == 'G') { /* fixup for 'g' */ + if (nsig < px->prec) { + px->prec = nsig; + } + if (--px->prec < 0) { + px->prec = 0; + } + code = code == 'g' ? 'e' : 'E'; + } + px->s[px->n1++] = *p++; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1++] = point; + } + if (0 < px->prec) { /* put fraction digits */ + if (px->prec < --nsig) { + nsig = px->prec; + } + memcpy(&px->s[px->n1], p, nsig); + px->n1 += nsig; + px->nz1 = px->prec - nsig; + } + p = (u8 *) &px->s[px->n1]; /* put exponent */ + *p++ = code; + if (0 <= xexp) { + *p++ = '+'; + } else { /* negative exponent */ + *p++ = '-'; + xexp = -xexp; + } + if (100 <= xexp) { /* put oversize exponent */ + if (1000 <= xexp) { + *p++ = xexp / 1000 + '0', xexp %= 1000; + } + *p++ = xexp / 100 + '0', xexp %= 100; + } + *p++ = xexp / 10 + '0', xexp %= 10; + *p++ = xexp + '0'; + px->n2 = p - (u8 *) &px->s[px->n1]; + } + if ((px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { /* pad with leading zeros */ + int n = + px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2; + + if (n < px->width) { + px->nz0 = px->width - n; + } + } +} diff --git a/src/libultra_boot_O2/_Litob.c b/src/libultra_boot_O2/_Litob.c new file mode 100644 index 000000000..15206217c --- /dev/null +++ b/src/libultra_boot_O2/_Litob.c @@ -0,0 +1,54 @@ +#include <global.h> +#include <stdlib.h> +#include <string.h> +#include <ultra64/printf.h> + +#define BUFF_LEN 0x18 + +u8 D_8000AF70[] = "0123456789abcdef"; +u8 D_8000AF84[] = "0123456789ABCDEF"; + +void _Litob(_Pft *args, u8 type) { + u8 buff[BUFF_LEN]; + const u8 *num_map; + s32 base; + s32 buff_ind; + u64 num; + lldiv_t quotrem; + + if (type == 'X') + num_map = D_8000AF84; + else + num_map = D_8000AF70; + + base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); + buff_ind = BUFF_LEN; + num = args->v.ll; + + if ((type == 'd' || type == 'i') && args->v.ll < 0) + num = -num; + + if (num != 0 || args->prec != 0) + buff[--buff_ind] = num_map[num % base]; + + args->v.ll = num / base; + + while (args->v.ll > 0 && buff_ind > 0) { + quotrem = lldiv(args->v.ll, base); + args->v.ll = quotrem.quot; + buff[--buff_ind] = num_map[quotrem.rem]; + } + + args->n1 = BUFF_LEN - buff_ind; + + memcpy(args->s, buff + buff_ind, args->n1); + + if (args->n1 < args->prec) + args->nz0 = args->prec - args->n1; + + if (args->prec < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { + buff_ind = args->width - args->n0 - args->nz0 - args->n1; + if (buff_ind > 0) + args->nz0 += buff_ind; + } +} diff --git a/src/libultra_boot_O2/_Printf.c b/src/libultra_boot_O2/_Printf.c new file mode 100644 index 000000000..cbb803bbd --- /dev/null +++ b/src/libultra_boot_O2/_Printf.c @@ -0,0 +1,230 @@ +#include <ultra64.h> +#include <ultra64/printf.h> +#include <stdarg.h> +#include <string.h> + +#define ATOI(i, a) \ + for (i = 0; *a >= '0' && *a <= '9'; a++) \ + if (i < 999) \ + i = *a + i * 10 - '0'; +#define _PROUT(fmt, _size) \ + if (_size > 0) { \ + arg = (void*)pfn(arg, fmt, _size); \ + if (arg != 0) \ + x.nchar += _size; \ + else \ + return x.nchar; \ + } +#define _PAD(m, src, extracond) \ + if (extracond && m > 0) { \ + int i; \ + int j; \ + for (j = m; j > 0; j -= i) { \ + if ((u32) j > 32) \ + i = 32; \ + else \ + i = j; \ + _PROUT(src, i); \ + } \ + } + +char spaces[] = " "; +char zeroes[] = "00000000000000000000000000000000"; + +void _Putfld(_Pft *, va_list *, u8, u8 *); + +s32 _Printf(char *(*pfn)(char *, const char *, size_t), char *arg, const char *fmt, va_list ap) +{ + _Pft x; + x.nchar = 0; + while (1) { + const u8* s; + u8 c; + u8* t; + + static const u8 fchar[] = " +-#0"; + static const u32 fbit[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 }; + + u8 ac[0x20]; + + s = (u8 *)fmt; + while ((c = *s) != 0 && c != '%') { + s++; + } + _PROUT(fmt, s - (u8 *)fmt); + if (c == 0) { + return x.nchar; + } + fmt = (char *) ++s; + x.flags = 0; + for (; (t = strchr(fchar, *s)) != NULL; s++) { + x.flags |= fbit[t - fchar]; + } + if (*s == '*') { + x.width = va_arg(ap, s32); + if (x.width < 0) { + x.width = -x.width; + x.flags |= FLAGS_MINUS; + } + s++; + } else { + ATOI(x.width, s); + } + if (*s != '.') { + x.prec = -1; + } else { + s++; + if (*s == '*') { + x.prec = va_arg(ap, s32); + s++; + } else { + ATOI(x.prec, s); + } + } + if (strchr("hlL", *s) != NULL) { + x.qual = *s++; + } else { + x.qual = 0; + } + + if (x.qual == 'l' && *s == 'l') { + x.qual = 'L'; + s++; + } + _Putfld(&x, &ap, *s, ac); + x.width -= x.n0 + x.nz0 + x.n1 + x.nz1 + + x.n2 + x.nz2; + _PAD(x.width, spaces, !(x.flags & FLAGS_MINUS)); + _PROUT((char *) ac, x.n0); + _PAD(x.nz0, zeroes, 1); + _PROUT(x.s, x.n1); + _PAD(x.nz1, zeroes, 1); + _PROUT((char *) (&x.s[x.n1]), x.n2) + _PAD(x.nz2, zeroes, 1); + _PAD(x.width, spaces, x.flags & FLAGS_MINUS); + fmt = (char *) s + 1; + } +} + +void _Putfld(_Pft* px, va_list* pap, u8 code, u8* ac) { + px->n0 = px->nz0 = px->n1 = px->nz1 = px->n2 = + px->nz2 = 0; + + switch (code) { + + case 'c': + ac[px->n0++] = va_arg(*pap, u32); + break; + + case 'd': + case 'i': + if (px->qual == 'l') { + px->v.ll = va_arg(*pap, s32); + } else if (px->qual == 'L') { + px->v.ll = va_arg(*pap, s64); + } else { + px->v.ll = va_arg(*pap, s32); + } + + if (px->qual == 'h') { + px->v.ll = (s16) px->v.ll; + } + + if (px->v.ll < 0) { + ac[px->n0++] = '-'; + } else if (px->flags & FLAGS_PLUS) { + ac[px->n0++] = '+'; + } else if (px->flags & FLAGS_SPACE) { + ac[px->n0++] = ' '; + } + + px->s = (char *) &ac[px->n0]; + + _Litob(px, code); + break; + + case 'x': + case 'X': + case 'u': + case 'o': + if (px->qual == 'l') { + px->v.ll = va_arg(*pap, s32); + } else if (px->qual == 'L') { + px->v.ll = va_arg(*pap, s64); + } else { + px->v.ll = va_arg(*pap, s32); + } + + if (px->qual == 'h') { + px->v.ll = (u16) px->v.ll; + } else if (px->qual == 0) { + px->v.ll = (u32) px->v.ll; + } + + if (px->flags & FLAGS_HASH) { + ac[px->n0++] = '0'; + if (code == 'x' || code == 'X') { + + ac[px->n0++] = code; + } + } + px->s = (char *) &ac[px->n0]; + _Litob(px, code); + break; + + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + px->v.ld = px->qual == 'L' ? va_arg(*pap, f64) : va_arg(*pap, f64); + + if (*(u16*)&px->v.ll & 0x8000) { + ac[px->n0++] = '-'; + } else { + if (px->flags & FLAGS_PLUS) { + ac[px->n0++] = '+'; + } else if (px->flags & FLAGS_SPACE) { + ac[px->n0++] = ' '; + } + } + + px->s = (char *) &ac[px->n0]; + _Ldtob(px, code); + break; + + case 'n': + if (px->qual == 'h') { + *(va_arg(*pap, u16 *)) = px->nchar; + } else if (px->qual == 'l') { + *va_arg(*pap, u32 *) = px->nchar; + } else if (px->qual == 'L') { + *va_arg(*pap, u64 *) = px->nchar; + } else { + *va_arg(*pap, u32 *) = px->nchar; + } + break; + + case 'p': + px->v.ll = (long) va_arg(*pap, void *); + px->s = (char *) &ac[px->n0]; + _Litob(px, 'x'); + break; + + case 's': + px->s = va_arg(*pap, char *); + px->n1 = strlen(px->s); + if (px->prec >= 0 && px->n1 > px->prec) { + px->n1 = px->prec; + } + break; + + case '%': + ac[px->n0++] = '%'; + break; + + default: + ac[px->n0++] = code; + break; + } +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/__osDevMgrMain.c b/src/libultra_boot_O2/__osDevMgrMain.c new file mode 100644 index 000000000..b3d8cd971 --- /dev/null +++ b/src/libultra_boot_O2/__osDevMgrMain.c @@ -0,0 +1,102 @@ +#include <global.h> +#include <ultra64/hardware.h> + +void __osDevMgrMain(void* arg) +{ + OSIoMesg* ioMesg; + OSMesg sp70; + OSMesg sp6C; + OSMgrArgs* arg0; + __OSTranxInfo* transfer; + __OSBlockInfo* block; + s32 phi_s2; + s32 phi_s0; + u32 sp54; + + arg0 = (OSMgrArgs*)arg; + ioMesg = NULL; + + while (true) + { + osRecvMesg(arg0->cmdQueue, (OSMesg)&ioMesg, OS_MESG_BLOCK); + if ((ioMesg->piHandle != NULL) && (ioMesg->piHandle->type == DEVICE_TYPE_64DD) && + ((ioMesg->piHandle->transferInfo.cmdType == 0) || (ioMesg->piHandle->transferInfo.cmdType == 1))) + { + transfer = &ioMesg->piHandle->transferInfo; + block = &transfer->block[transfer->blockNum]; + transfer->sectorNum = -1; + if (transfer->transferMode != 3) + block->dramAddr = (void*)((u32)block->dramAddr - block->sectorSize); + + phi_s2 = ((transfer->transferMode == 2) && (ioMesg->piHandle->transferInfo.cmdType == 0)) ? 1 : 0; + + osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK); + __osResetGlobalIntMask(0x00100401); + __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x80000000); + + while (true) + { + osRecvMesg(arg0->eventQueue, &sp70, OS_MESG_BLOCK); + transfer = &ioMesg->piHandle->transferInfo; + block = &transfer->block[transfer->blockNum]; + if (block->errStatus == 0x1D) + { + __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x10000000); + __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow); + __osEPiRawReadIo(ioMesg->piHandle, 0x05000508, &sp54); + if (sp54 & 0x02000000) + __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x1000000); + block->errStatus = 4; + HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLEAR_INTR; + __osSetGlobalIntMask(0x00100C01); + } + osSendMesg(ioMesg->hdr.retQueue, ioMesg, OS_MESG_NOBLOCK); + + if ((phi_s2 != 1) || (ioMesg->piHandle->transferInfo.block[0].errStatus != 0)) + break; + + phi_s2 = 0; + } + + osSendMesg(arg0->acccessQueue, 0, OS_MESG_NOBLOCK); + if (ioMesg->piHandle->transferInfo.blockNum == 1) + osYieldThread(); + } + else + { + switch (ioMesg->hdr.type) + { + case 11: + osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK); + phi_s0 = arg0->piDmaCallback(OS_READ, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size); + break; + case 12: + osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK); + phi_s0 = arg0->piDmaCallback(OS_WRITE, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size); + break; + case 15: + osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK); + phi_s0 = arg0->epiDmaCallback(ioMesg->piHandle, OS_READ, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size); + break; + case 16: + osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK); + phi_s0 = arg0->epiDmaCallback(ioMesg->piHandle, OS_WRITE, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size); + break; + case 10: + osSendMesg(ioMesg->hdr.retQueue, ioMesg, OS_MESG_NOBLOCK); + phi_s0 = -1; + break; + default: + phi_s0 = -1; + break; + } + + if (phi_s0 == 0) + { + osRecvMesg(arg0->eventQueue, &sp70, OS_MESG_BLOCK); + osSendMesg(ioMesg->hdr.retQueue, ioMesg, OS_MESG_NOBLOCK); + osSendMesg(arg0->acccessQueue, NULL, OS_MESG_NOBLOCK); + } + } + } +} diff --git a/src/libultra_boot_O2/__osEPiRawReadIo.c b/src/libultra_boot_O2/__osEPiRawReadIo.c new file mode 100644 index 000000000..d44881015 --- /dev/null +++ b/src/libultra_boot_O2/__osEPiRawReadIo.c @@ -0,0 +1,54 @@ +#include <global.h> +#include <ultra64/hardware.h> + +s32 __osEPiRawReadIo(OSPiHandle* handle, u32 devAddr, u32* data) +{ + s32 status; + OSPiHandle* curHandle; + + while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY | PI_STATUS_ERROR)) + ; + + if (__osCurrentHandle[handle->domain]->type != handle->type) + { + curHandle = __osCurrentHandle[handle->domain]; + + if (handle->domain == 0) + { + if (curHandle->latency != handle->latency) + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency; + + if (curHandle->pageSize != handle->pageSize) + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize; + + if (curHandle->relDuration != handle->relDuration) + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration; + + if (curHandle->pulse != handle->pulse) + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse; + } + else + { + if (curHandle->latency != handle->latency) + HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency; + + if (curHandle->pageSize != handle->pageSize) + HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize; + + if (curHandle->relDuration != handle->relDuration) + HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration; + + if (curHandle->pulse != handle->pulse) + HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse; + } + + curHandle->type = handle->type; + curHandle->latency = handle->latency; + curHandle->pageSize = handle->pageSize; + curHandle->relDuration = handle->relDuration; + curHandle->pulse = handle->pulse; + } + + *data = HW_REG(handle->baseAddress | devAddr | 0, u32); + return 0; +} diff --git a/src/libultra_boot_O2/__osEPiRawStartDma.c b/src/libultra_boot_O2/__osEPiRawStartDma.c new file mode 100644 index 000000000..dcd5f44d9 --- /dev/null +++ b/src/libultra_boot_O2/__osEPiRawStartDma.c @@ -0,0 +1,69 @@ +#include <global.h> +#include <ultra64/hardware.h> + +s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dramAddr, size_t size) +{ + s32 status; + OSPiHandle* curHandle; + + while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY | PI_STATUS_ERROR)) + ; + + if (__osCurrentHandle[handle->domain]->type != handle->type) + { + curHandle = __osCurrentHandle[handle->domain]; + + if (handle->domain == 0) + { + if (curHandle->latency != handle->latency) + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency; + + if (curHandle->pageSize != handle->pageSize) + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize; + + if (curHandle->relDuration != handle->relDuration) + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration; + + if (curHandle->pulse != handle->pulse) + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse; + } + else + { + if (curHandle->latency != handle->latency) + HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency; + + if (curHandle->pageSize != handle->pageSize) + HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize; + + if (curHandle->relDuration != handle->relDuration) + HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration; + + if (curHandle->pulse != handle->pulse) + HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse; + } + + curHandle->type = handle->type; + curHandle->latency = handle->latency; + curHandle->pageSize = handle->pageSize; + curHandle->relDuration = handle->relDuration; + curHandle->pulse = handle->pulse; + } + + HW_REG(PI_DRAM_ADDR_REG, void*) = (void*)osVirtualToPhysical(dramAddr); + HW_REG(PI_CART_ADDR_REG, void*) = (void*)((handle->baseAddress | cartAddr) & 0x1fffffff); + + switch (direction) + { + case OS_READ: + HW_REG(PI_WR_LEN_REG, u32) = size - 1; + break; + case OS_WRITE: + HW_REG(PI_RD_LEN_REG, u32) = size - 1; + break; + default: + return -1; + break; + } + + return 0; +} diff --git a/src/libultra_boot_O2/__osEPiRawWriteIo.c b/src/libultra_boot_O2/__osEPiRawWriteIo.c new file mode 100644 index 000000000..517c7397a --- /dev/null +++ b/src/libultra_boot_O2/__osEPiRawWriteIo.c @@ -0,0 +1,54 @@ +#include <global.h> +#include <ultra64/hardware.h> + +s32 __osEPiRawWriteIo(OSPiHandle* handle, u32 devAddr, u32 data) +{ + s32 status; + OSPiHandle* curHandle; + + while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY | PI_STATUS_ERROR)) + ; + + if (__osCurrentHandle[handle->domain]->type != handle->type) + { + curHandle = __osCurrentHandle[handle->domain]; + + if (handle->domain == 0) + { + if (curHandle->latency != handle->latency) + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency; + + if (curHandle->pageSize != handle->pageSize) + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize; + + if (curHandle->relDuration != handle->relDuration) + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration; + + if (curHandle->pulse != handle->pulse) + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse; + } + else + { + if (curHandle->latency != handle->latency) + HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency; + + if (curHandle->pageSize != handle->pageSize) + HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize; + + if (curHandle->relDuration != handle->relDuration) + HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration; + + if (curHandle->pulse != handle->pulse) + HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse; + } + + curHandle->type = handle->type; + curHandle->latency = handle->latency; + curHandle->pageSize = handle->pageSize; + curHandle->relDuration = handle->relDuration; + curHandle->pulse = handle->pulse; + } + + HW_REG(handle->baseAddress | devAddr, u32) = data; + return 0; +} diff --git a/src/libultra_boot_O2/__osPiRawStartDma.c b/src/libultra_boot_O2/__osPiRawStartDma.c new file mode 100644 index 000000000..0957a0ebc --- /dev/null +++ b/src/libultra_boot_O2/__osPiRawStartDma.c @@ -0,0 +1,30 @@ +#include <global.h> +#include <ultra64/hardware.h> + +s32 __osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size) +{ + register int status; + status = HW_REG(PI_STATUS_REG, u32); + while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY | PI_STATUS_ERROR)) + { + status = HW_REG(PI_STATUS_REG, u32); + } + + HW_REG(PI_DRAM_ADDR_REG, void *) = (void *)osVirtualToPhysical(dram_addr); + + HW_REG(PI_CART_ADDR_REG, void *) = (void *)((osRomBase | cart_addr) & 0x1fffffff); + + switch (dir) + { + case OS_READ: + HW_REG(PI_WR_LEN_REG, u32) = size - 1; + break; + case OS_WRITE: + HW_REG(PI_RD_LEN_REG, u32) = size - 1; + break; + default: + return -1; + break; + } + return 0; +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/__osSiDeviceBusy.c b/src/libultra_boot_O2/__osSiDeviceBusy.c new file mode 100644 index 000000000..983bd071d --- /dev/null +++ b/src/libultra_boot_O2/__osSiDeviceBusy.c @@ -0,0 +1,12 @@ +#include <global.h> +#include <ultra64/hardware.h> + +u32 __osSiDeviceBusy() +{ + register u32 status; + status = HW_REG(SI_STATUS_REG, u32); + if (status & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) + return true; + else + return false; +} diff --git a/src/libultra_boot_O2/__osSiRawReadIo.c b/src/libultra_boot_O2/__osSiRawReadIo.c new file mode 100644 index 000000000..c3bb394f0 --- /dev/null +++ b/src/libultra_boot_O2/__osSiRawReadIo.c @@ -0,0 +1,10 @@ +#include <global.h> +#include <ultra64/hardware.h> + +s32 __osSiRawReadIo(void *a0, u32 *a1) +{ + if (__osSiDeviceBusy()) + return -1; + *a1 = HW_REG((u32)a0, u32); + return 0; +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/__osSiRawWriteIo.c b/src/libultra_boot_O2/__osSiRawWriteIo.c new file mode 100644 index 000000000..c7ff8eab7 --- /dev/null +++ b/src/libultra_boot_O2/__osSiRawWriteIo.c @@ -0,0 +1,10 @@ +#include <global.h> +#include <ultra64/hardware.h> + +s32 __osSiRawWriteIo(void *a0, u32 a1) +{ + if (__osSiDeviceBusy()) + return -1; + HW_REG((u32)a0, u32) = a1; + return 0; +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/__osViGetCurrentContext.c b/src/libultra_boot_O2/__osViGetCurrentContext.c new file mode 100644 index 000000000..b629c77f7 --- /dev/null +++ b/src/libultra_boot_O2/__osViGetCurrentContext.c @@ -0,0 +1,6 @@ +#include <global.h> + +OSViContext* __osViGetCurrentContext() +{ + return __osViCurr; +} diff --git a/src/libultra_boot_O2/__osViInit.c b/src/libultra_boot_O2/__osViInit.c new file mode 100644 index 000000000..a660a1de2 --- /dev/null +++ b/src/libultra_boot_O2/__osViInit.c @@ -0,0 +1,34 @@ +#include <global.h> +#include <ultra64/hardware.h> + +OSViContext vi[2] = {0}; +OSViContext* __osViCurr = &vi[0]; +OSViContext* __osViNext = &vi[1]; + +void __osViInit() +{ + bzero(vi, sizeof(vi)); + __osViCurr = &vi[0]; + __osViNext = &vi[1]; + + __osViNext->retraceCount = 1; + __osViCurr->retraceCount = 1; + __osViNext->buffer = (void*)0x80000000; + __osViCurr->buffer = (void*)0x80000000; + + if (osTvType == 0) + __osViNext->modep = &osViModePalLan1; + else if (osTvType == 2) + __osViNext->modep = &osViModeMpalLan1; + else + __osViNext->modep = &osViModeNtscLan1; + + __osViNext->state = 0x20; + __osViNext->features = __osViNext->modep->comRegs.ctrl; + + while (HW_REG(VI_CURRENT_REG, u32) > 10) + ; + + HW_REG(VI_CONTROL_REG, u32) = 0; + __osViSwapContext(); +} diff --git a/src/libultra_boot_O2/__osViSwapContext.c b/src/libultra_boot_O2/__osViSwapContext.c new file mode 100644 index 000000000..93f8ede35 --- /dev/null +++ b/src/libultra_boot_O2/__osViSwapContext.c @@ -0,0 +1,64 @@ +#include <global.h> +#include <ultra64/hardware.h> + +void __osViSwapContext() +{ + register OSViMode *s0; + register OSViContext *s1; + u32 origin; + u32 hStart; + u32 vstart; + u32 sp34; + u32 field; + register u32 s2; + + field = 0; + s1 = __osViNext; + s0 = s1->modep; + field = HW_REG(VI_V_CURRENT_LINE_REG, u32) & 1; + s2 = osVirtualToPhysical(s1->buffer); + origin = (s0->fldRegs[field].origin) + s2; + if (s1->state & 2) { + s1->x.scale |= s0->comRegs.xScale & ~0xfff; + } else { + s1->x.scale = s0->comRegs.xScale; + } + if (s1->state & 4) { + sp34 = (u32)(s0->fldRegs[field].yScale & 0xfff); + s1->y.scale = s1->y.factor * sp34; + s1->y.scale |= s0->fldRegs[field].yScale & ~0xfff; + } else { + s1->y.scale = s0->fldRegs[field].yScale; + } + + vstart = (s0->fldRegs[field].vStart - (__additional_scanline << 0x10)) + __additional_scanline; + hStart = s0->comRegs.hStart; + + if (s1->state & 0x20) { + hStart = 0; + } + if (s1->state & 0x40) { + s1->y.scale = 0; + origin = osVirtualToPhysical(s1->buffer); + } + if (s1->state & 0x80) { + s1->y.scale = (s1->y.offset << 0x10) & 0x3ff0000; + origin = osVirtualToPhysical(s1->buffer); + } + HW_REG(VI_ORIGIN_REG, u32) = origin; + HW_REG(VI_WIDTH_REG, u32) = s0->comRegs.width; + HW_REG(VI_BURST_REG, u32) = s0->comRegs.burst; + HW_REG(VI_V_SYNC_REG, u32) = s0->comRegs.vSync; + HW_REG(VI_H_SYNC_REG, u32) = s0->comRegs.hSync; + HW_REG(VI_LEAP_REG, u32) = s0->comRegs.leap; + HW_REG(VI_H_START_REG, u32) = hStart; + HW_REG(VI_V_START_REG, u32) = vstart; + HW_REG(VI_V_BURST_REG, u32) = s0->fldRegs[field].vBurst; + HW_REG(VI_INTR_REG, u32) = s0->fldRegs[field].vIntr; + HW_REG(VI_X_SCALE_REG, u32) = s1->x.scale; + HW_REG(VI_Y_SCALE_REG, u32) = s1->y.scale; + HW_REG(VI_CONTROL_REG, u32) = s1->features; + __osViNext = __osViCurr; + __osViCurr = s1; + *__osViNext = *__osViCurr; +} diff --git a/src/libultra_boot_O2/ldiv.c b/src/libultra_boot_O2/ldiv.c new file mode 100644 index 000000000..391fe79c4 --- /dev/null +++ b/src/libultra_boot_O2/ldiv.c @@ -0,0 +1,28 @@ +#include <global.h> +#include <stdlib.h> + +ldiv_t ldiv(long num, long denom) { + ldiv_t ret; + + ret.quot = num / denom; + ret.rem = num - denom * ret.quot; + if (ret.quot < 0 && ret.rem > 0) { + ret.quot++; + ret.rem -= denom; + } + + return ret; +} + +lldiv_t lldiv(long long num, long long denom) { + lldiv_t ret; + + ret.quot = num / denom; + ret.rem = num - denom * ret.quot; + if (ret.quot < 0 && ret.rem > 0) { + ret.quot++; + ret.rem -= denom; + } + + return ret; +} diff --git a/src/libultra_boot_O2/osCartRomInit.c b/src/libultra_boot_O2/osCartRomInit.c new file mode 100644 index 000000000..5492a61f5 --- /dev/null +++ b/src/libultra_boot_O2/osCartRomInit.c @@ -0,0 +1,64 @@ +#include <global.h> +#include <ultra64/hardware.h> + +OSPiHandle __CartRomHandle; + +OSPiHandle* osCartRomInit() +{ + register u32 a; + register s32 status; + register u32 prevInt; + register u32 lastLatency; + register u32 lastPageSize; + register u32 lastRelDuration; + register u32 lastPulse; + + static u32 D_8000AF10 = 1; + + __osPiGetAccess(); + + if (!D_8000AF10) + { + __osPiRelAccess(); + return &__CartRomHandle; + } + + D_8000AF10 = 0; + __CartRomHandle.type = DEVICE_TYPE_CART; + __CartRomHandle.baseAddress = 0xb0000000; + __CartRomHandle.domain = 0; + __CartRomHandle.speed = 0; + bzero(&__CartRomHandle.transferInfo, sizeof(__OSTranxInfo)); + + while (status = HW_REG(PI_STATUS_REG, u32), status & PI_STATUS_ERROR) + ; + + lastLatency = HW_REG(PI_BSD_DOM1_LAT_REG, u32); + lastPageSize = HW_REG(PI_BSD_DOM1_PGS_REG, u32); + lastRelDuration = HW_REG(PI_BSD_DOM1_RLS_REG, u32); + lastPulse = HW_REG(PI_BSD_DOM1_PWD_REG, u32); + + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = 0xff; + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = 0; + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = 3; + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = 0xff; + + a = HW_REG(__CartRomHandle.baseAddress, u32); + __CartRomHandle.latency = a & 0xFF; + __CartRomHandle.pageSize = (a >> 0x10) & 0xF; + __CartRomHandle.relDuration = (a >> 0x14) & 0xF; + __CartRomHandle.pulse = (a >> 8) & 0xFF; + + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = lastLatency; + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = lastPageSize; + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = lastRelDuration; + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = lastPulse; + + prevInt = __osDisableInt(); + __CartRomHandle.next = __osPiTable; + __osPiTable = &__CartRomHandle; + __osRestoreInt(prevInt); + __osPiRelAccess(); + + return &__CartRomHandle; +} diff --git a/src/libultra_boot_O2/osDriveRomInit.c b/src/libultra_boot_O2/osDriveRomInit.c new file mode 100644 index 000000000..2428161e8 --- /dev/null +++ b/src/libultra_boot_O2/osDriveRomInit.c @@ -0,0 +1,60 @@ +#include <global.h> +#include <ultra64/hardware.h> + +OSPiHandle __DriveRomHandle; + +OSPiHandle* osDriveRomInit() +{ + register s32 status; + register u32 a; + register s32 prevInt; + static u32 D_8000AC70 = 1; + + __osPiGetAccess(); + + if (!D_8000AC70) + { + __osPiRelAccess(); + return &__DriveRomHandle; + } + + D_8000AC70 = 0; + __DriveRomHandle.type = DEVICE_TYPE_BULK; + __DriveRomHandle.baseAddress = 0xa6000000; + __DriveRomHandle.domain = 0; + __DriveRomHandle.speed = 0; + bzero(&__DriveRomHandle.transferInfo, sizeof(__OSTranxInfo)); + + while (status = HW_REG(PI_STATUS_REG, u32), status & PI_STATUS_ERROR) + ; + + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = 0xff; + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = 0; + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = 3; + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = 0xff; + + a = HW_REG(__DriveRomHandle.baseAddress, u32); + __DriveRomHandle.latency = a & 0xFF; + __DriveRomHandle.pulse = (a >> 8) & 0xFF; + __DriveRomHandle.pageSize = (a >> 0x10) & 0xF; + __DriveRomHandle.relDuration = (a >> 0x14) & 0xF; + + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = (u8)a; + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = __DriveRomHandle.pageSize; + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = __DriveRomHandle.relDuration; + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = __DriveRomHandle.pulse; + + __osCurrentHandle[__DriveRomHandle.domain]->type = __DriveRomHandle.type; + __osCurrentHandle[__DriveRomHandle.domain]->latency = __DriveRomHandle.latency; + __osCurrentHandle[__DriveRomHandle.domain]->pageSize = __DriveRomHandle.pageSize; + __osCurrentHandle[__DriveRomHandle.domain]->relDuration = __DriveRomHandle.relDuration; + __osCurrentHandle[__DriveRomHandle.domain]->pulse = __DriveRomHandle.pulse; + + prevInt = __osDisableInt(); + __DriveRomHandle.next = __osPiTable; + __osPiTable = &__DriveRomHandle; + __osRestoreInt(prevInt); + __osPiRelAccess(); + + return &__DriveRomHandle; +} diff --git a/src/libultra_boot_O2/osEPiReadIo.c b/src/libultra_boot_O2/osEPiReadIo.c new file mode 100644 index 000000000..9953c8529 --- /dev/null +++ b/src/libultra_boot_O2/osEPiReadIo.c @@ -0,0 +1,12 @@ +#include <global.h> + +s32 osEPiReadIo(OSPiHandle* handle, u32 devAddr, u32* data) +{ + register s32 ret; + + __osPiGetAccess(); + ret = __osEPiRawReadIo(handle, devAddr, data); + __osPiRelAccess(); + + return ret; +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/osEPiStartDma.c b/src/libultra_boot_O2/osEPiStartDma.c new file mode 100644 index 000000000..a2c2b8d5a --- /dev/null +++ b/src/libultra_boot_O2/osEPiStartDma.c @@ -0,0 +1,21 @@ +#include <global.h> + +s32 osEPiStartDma(OSPiHandle* handle, OSIoMesg* mb, s32 direction) +{ + s32 ret; + if (!__osPiDevMgr.initialized) + return -1; + + mb->piHandle = handle; + if (direction == OS_READ) + mb->hdr.type = 0xf; + else + mb->hdr.type = 0x10; + + if (mb->hdr.pri == 1) + ret = osJamMesg(osPiGetCmdQueue(), (OSMesg)mb, 0); + else + ret = osSendMesg(osPiGetCmdQueue(), (OSMesg)mb, 0); + + return ret; +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/osEPiWriteIo.c b/src/libultra_boot_O2/osEPiWriteIo.c new file mode 100644 index 000000000..ef1cc385f --- /dev/null +++ b/src/libultra_boot_O2/osEPiWriteIo.c @@ -0,0 +1,12 @@ +#include <global.h> + +s32 osEPiWriteIo(OSPiHandle* handle, u32 devAddr, u32 data) +{ + register s32 ret; + + __osPiGetAccess(); + ret = __osEPiRawWriteIo(handle, devAddr, data); + __osPiRelAccess(); + + return ret; +} diff --git a/src/libultra_boot_O2/osPiGetCmdQueue.c b/src/libultra_boot_O2/osPiGetCmdQueue.c new file mode 100644 index 000000000..159c42378 --- /dev/null +++ b/src/libultra_boot_O2/osPiGetCmdQueue.c @@ -0,0 +1,9 @@ +#include <global.h> + +OSMesgQueue* osPiGetCmdQueue() +{ + if (!__osPiDevMgr.initialized) + return NULL; + + return __osPiDevMgr.cmdQueue; +} diff --git a/src/libultra_boot_O2/osViBlack.c b/src/libultra_boot_O2/osViBlack.c new file mode 100644 index 000000000..4a122496c --- /dev/null +++ b/src/libultra_boot_O2/osViBlack.c @@ -0,0 +1,13 @@ +#include <global.h> + +// TODO: name magic constants +void osViBlack(u8 active) +{ + register u32 int_disabled = __osDisableInt(); + if (active) { + __osViNext->state |= 0x20; + } else { + __osViNext->state &= ~0x20; + } + __osRestoreInt(int_disabled); +} diff --git a/src/libultra_boot_O2/osViGetNextFramebuffer.c b/src/libultra_boot_O2/osViGetNextFramebuffer.c new file mode 100644 index 000000000..83eaa2705 --- /dev/null +++ b/src/libultra_boot_O2/osViGetNextFramebuffer.c @@ -0,0 +1,9 @@ +#include <global.h> + +void* osViGetNextFramebuffer() +{ + s32 prevInt = __osDisableInt(); + void* buff = __osViNext->buffer; + __osRestoreInt(prevInt); + return buff; +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/osViModeFpalLan1.c b/src/libultra_boot_O2/osViModeFpalLan1.c new file mode 100644 index 000000000..c620ad53d --- /dev/null +++ b/src/libultra_boot_O2/osViModeFpalLan1.c @@ -0,0 +1,33 @@ +#include <global.h> + +OSViMode osViModeFpalLan1 = +{ + 0x2C, //type + { //comRegs + 0x311E, //ctrl + 0x140, //width + 0x4541E3A, //burst + 0x271, //vSync + 0x170C69, //hSync + 0xC6F0C6D, //leap + 0x800300, //hStart + 0x200, //xScale + 0 //vCurrent + }, + { //fldRegs + { + 0x280, //origin + 0x400, //yScale + 0x2F0269, //vStart + 0x9026B, //vBurst + 2, //vIntr + }, + { + 0x280, //origin + 0x400, //yScale + 0x2F0269, //vStart + 0x9026B, //vBurst + 2 //vIntr + } + } +}; diff --git a/src/libultra_boot_O2/osViModeMpalLan1.c b/src/libultra_boot_O2/osViModeMpalLan1.c new file mode 100644 index 000000000..805cd450b --- /dev/null +++ b/src/libultra_boot_O2/osViModeMpalLan1.c @@ -0,0 +1,33 @@ +#include <global.h> + +OSViMode osViModeMpalLan1 = +{ + 0x1E, //type + { //comRegs + 0x311E, //ctrl + 0x140, //width + 0x4651E39, //burst + 0x20D, //vSync + 0x40C11, //hSync + 0xC190C1A, //leap + 0x6C02EC, //hStart + 0x200, //xScale + 0, //vCurrent + }, + { //fldRegs + { //[0] + 0x280, //origin + 0x400, //yScale + 0x2501FF, //vStart + 0xE0204, //vBurst + 2, //vIntr + }, + { //[1] + 0x280, //origin + 0x400, //yScale + 0x2501FF, //vStart + 0xE0204, //vBurst + 2, //vIntr + } + } +}; diff --git a/src/libultra_boot_O2/osViModeNtscLan1.c b/src/libultra_boot_O2/osViModeNtscLan1.c new file mode 100644 index 000000000..99573758e --- /dev/null +++ b/src/libultra_boot_O2/osViModeNtscLan1.c @@ -0,0 +1,33 @@ +#include <global.h> + +OSViMode osViModeNtscLan1 = +{ + 2, //type + { //comRegs + 0x311E, //ctrl + 0x140, //width + 0x3E52239, //burst + 0x20D, //vSync + 0xC15, //hSync + 0xC150C15, //leap + 0x6C02EC, //hStart + 0x200, //xScale + 0, //vCurrent + }, + { //fldRegs + { //[0] + 0x280, //origin + 0x400, //yScale + 0x2501FF, //vStart + 0xE0204, //vBurst + 2, //vIntr + }, + { //[1] + 0x280, //origin + 0x400, //yScale + 0x2501FF, //vStart + 0xE0204, //vBurst + 2, //vIntr + } + } +}; diff --git a/src/libultra_boot_O2/osViSetMode.c b/src/libultra_boot_O2/osViSetMode.c new file mode 100644 index 000000000..5d29da826 --- /dev/null +++ b/src/libultra_boot_O2/osViSetMode.c @@ -0,0 +1,10 @@ +#include <global.h> + +void osViSetMode(OSViMode *mode) +{ + register u32 int_disabled = __osDisableInt(); + __osViNext->modep = mode; + __osViNext->state = 1; + __osViNext->features = __osViNext->modep->comRegs.ctrl; + __osRestoreInt(int_disabled); +} diff --git a/src/libultra_boot_O2/osViSetSpecialFeatures.c b/src/libultra_boot_O2/osViSetSpecialFeatures.c new file mode 100644 index 000000000..06d040a51 --- /dev/null +++ b/src/libultra_boot_O2/osViSetSpecialFeatures.c @@ -0,0 +1,37 @@ +#include <global.h> + +void osViSetSpecialFeatures(u32 func) +{ + register u32 int_disabled = __osDisableInt(); + if (func & OS_VI_GAMMA_ON) { + __osViNext->features |= OS_VI_GAMMA; + } + if (func & OS_VI_GAMMA_OFF) { + __osViNext->features &= ~OS_VI_GAMMA; + } + if (func & OS_VI_GAMMA_DITHER_ON) { + __osViNext->features |= OS_VI_GAMMA_DITHER; + } + if (func & OS_VI_GAMMA_DITHER_OFF) { + + __osViNext->features &= ~OS_VI_GAMMA_DITHER; + } + if (func & OS_VI_DIVOT_ON) { + + __osViNext->features |= OS_VI_DIVOT; + } + if (func & OS_VI_DIVOT_OFF) { + + __osViNext->features &= ~OS_VI_DIVOT; + } + if (func & OS_VI_DITHER_FILTER_ON) { + __osViNext->features |= OS_VI_DITHER_FILTER; + __osViNext->features &= ~(OS_VI_UNK200 | OS_VI_UNK100); + } + if (func & OS_VI_DITHER_FILTER_OFF) { + __osViNext->features &= ~OS_VI_DITHER_FILTER; + __osViNext->features |= __osViNext->modep->comRegs.ctrl & (OS_VI_UNK200 | OS_VI_UNK100); + } + __osViNext->state |= 8; + __osRestoreInt(int_disabled); +} diff --git a/src/libultra_boot_O2/osViSetXScale.c b/src/libultra_boot_O2/osViSetXScale.c new file mode 100644 index 000000000..128b64c99 --- /dev/null +++ b/src/libultra_boot_O2/osViSetXScale.c @@ -0,0 +1,18 @@ +#include <global.h> + +void osViSetXScale(f32 value) +{ + register u32 nomValue; + register u32 saveMask; + + saveMask = __osDisableInt(); + + __osViNext->x.factor = value; + + __osViNext->state |= 0x2; + + nomValue = __osViNext->modep->comRegs.xScale & 0xfff; + __osViNext->x.scale = (u32)(__osViNext->x.factor * nomValue) & 0xFFF; + + __osRestoreInt(saveMask); +} diff --git a/src/libultra_boot_O2/osViSetYScale.c b/src/libultra_boot_O2/osViSetYScale.c new file mode 100644 index 000000000..bf34f28e1 --- /dev/null +++ b/src/libultra_boot_O2/osViSetYScale.c @@ -0,0 +1,11 @@ +#include <global.h> + +void osViSetYScale(float scale) +{ + register s32 prevInt; + + prevInt = __osDisableInt(); + __osViNext->y.factor = scale; + __osViNext->state |= 4; + __osRestoreInt(prevInt); +} diff --git a/src/libultra_boot_O2/osViSwapBuffer.c b/src/libultra_boot_O2/osViSwapBuffer.c new file mode 100644 index 000000000..eb6b05d31 --- /dev/null +++ b/src/libultra_boot_O2/osViSwapBuffer.c @@ -0,0 +1,9 @@ +#include <global.h> + +void osViSwapBuffer(void *vaddr) +{ + u32 int_disabled = __osDisableInt(); + __osViNext->buffer = vaddr; + __osViNext->state |= 0x10; // TODO: figure out what this flag means + __osRestoreInt(int_disabled); +} diff --git a/src/libultra_boot_O2/pimgr.c b/src/libultra_boot_O2/pimgr.c new file mode 100644 index 000000000..c15d7b919 --- /dev/null +++ b/src/libultra_boot_O2/pimgr.c @@ -0,0 +1,60 @@ +#include <global.h> + +OSMgrArgs __osPiDevMgr = {0}; + +OSPiHandle __Dom1SpeedParam; +OSPiHandle __Dom2SpeedParam; +OSThread piThread; +u8 piStackThread[0x1000]; +OSMesgQueue piEventQueue; +OSMesg piEventBuf[2]; +OSThread __osThreadSave; + +OSPiHandle* __osPiTable = NULL; +OSPiHandle* __osCurrentHandle[] = +{ + &__Dom1SpeedParam, + &__Dom2SpeedParam, +}; + + +void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt) +{ + u32 int_disabled; + OSPri newPri; + OSPri currentPri; + + if (!__osPiDevMgr.initialized) + { + osCreateMesgQueue(cmdQ, cmdBuf, cmdMsgCnt); + osCreateMesgQueue(&piEventQueue, piEventBuf, 1); + if (!__osPiAccessQueueEnabled) + __osPiCreateAccessQueue(); + + osSetEventMesg(OS_EVENT_PI, &piEventQueue, (OSMesg)0x22222222); + newPri = -1; + currentPri = osGetThreadPri(NULL); + if (currentPri < pri) + { + newPri = currentPri; + osSetThreadPri(NULL, pri); + } + int_disabled = __osDisableInt(); + + __osPiDevMgr.initialized = true; + __osPiDevMgr.cmdQueue = cmdQ; + __osPiDevMgr.mgrThread = &piThread; + __osPiDevMgr.eventQueue = &piEventQueue; + __osPiDevMgr.acccessQueue = &__osPiAccessQueue; + __osPiDevMgr.piDmaCallback = __osPiRawStartDma; + __osPiDevMgr.epiDmaCallback = __osEPiRawStartDma; + + osCreateThread(&piThread, 0, __osDevMgrMain, (void *)&__osPiDevMgr, piStackThread + sizeof(piStackThread), pri); + osStartThread(&piThread); + + __osRestoreInt(int_disabled); + + if (newPri != -1) + osSetThreadPri(NULL, newPri); + } +} diff --git a/src/libultra_boot_O2/sprintf.c b/src/libultra_boot_O2/sprintf.c new file mode 100644 index 000000000..58510a35c --- /dev/null +++ b/src/libultra_boot_O2/sprintf.c @@ -0,0 +1,26 @@ +#include <global.h> + +char* proutSprintf(char* dst, const char *fmt, size_t size) +{ + return (char*)memcpy(dst, fmt, size) + size; +} + +s32 vsprintf(char* dst, const char* fmt, va_list args) +{ + s32 ret = _Printf(&proutSprintf, dst, fmt, args); + if (ret > -1) + dst[ret] = 0; + return ret; +} + +s32 sprintf(char* dst, const char* fmt, ...) +{ + s32 ret; + va_list args; + va_start(args, fmt); + + ret = _Printf(&proutSprintf, dst, fmt, args); + if (ret > -1) + dst[ret] = 0; + return ret; +} diff --git a/src/libultra_boot_O2/string.c b/src/libultra_boot_O2/string.c new file mode 100644 index 000000000..771caf1a3 --- /dev/null +++ b/src/libultra_boot_O2/string.c @@ -0,0 +1,33 @@ +#include <global.h> + +const u8 *strchr(const u8 *str, s32 ch) +{ + u8 c = ch; + while (*str != c) + { + if (*str == 0) + return NULL; + str++; + } + return str; +} + +size_t strlen(const u8 *str) +{ + const u8 *ptr = str; + while (*ptr) + ptr++; + return ptr - str; +} + +void *memcpy(void *dst, const void *src, size_t size) +{ + u8 *_dst = dst; + const u8 *_src = src; + while (size > 0) + { + *_dst++ = *_src++; + size--; + } + return dst; +}
\ No newline at end of file diff --git a/src/libultra_boot_O2/vimgr.c b/src/libultra_boot_O2/vimgr.c new file mode 100644 index 000000000..de54494f9 --- /dev/null +++ b/src/libultra_boot_O2/vimgr.c @@ -0,0 +1,125 @@ +#include <global.h> + +typedef struct +{ + u16 unk00; + u8 unk02; + u32 unk04; + u8 pad[0xc]; + u16 unk14; + u16 unk16; +} viMesgStruct; + +OSThread viThread; +u8 viThreadStack[0x1000]; +OSMesgQueue viEventQueue; +OSMesg viEventBuf[6]; +viMesgStruct viRetraceMsg; +viMesgStruct viCounterMsg; +OSMgrArgs __osViDevMgr = {0}; +u32 __additional_scanline = 0; + +void viMgrMain(void*); + +void osCreateViManager(OSPri pri) +{ + u32 int_disabled; + OSPri newPri; + OSPri currentPri; + if (!__osViDevMgr.initialized) + { + __osTimerServicesInit(); + __additional_scanline = 0; + osCreateMesgQueue(&viEventQueue, viEventBuf, 5); + viRetraceMsg.unk00 = 13; + viRetraceMsg.unk02 = 0; + viRetraceMsg.unk04 = 0; + viCounterMsg.unk00 = 14; + viCounterMsg.unk02 = 0; + viCounterMsg.unk04 = 0; + osSetEventMesg(OS_EVENT_VI, &viEventQueue, &viRetraceMsg); + osSetEventMesg(OS_EVENT_COUNTER, &viEventQueue, &viCounterMsg); + newPri = -1; + currentPri = osGetThreadPri(NULL); + if (currentPri < pri) + { + newPri = currentPri; + osSetThreadPri(NULL, pri); + } + + int_disabled = __osDisableInt(); + __osViDevMgr.initialized = true; + __osViDevMgr.mgrThread = &viThread; + __osViDevMgr.cmdQueue = &viEventQueue; + __osViDevMgr.eventQueue = &viEventQueue; + __osViDevMgr.acccessQueue = NULL; + __osViDevMgr.piDmaCallback = NULL; + __osViDevMgr.epiDmaCallback = NULL; + + osCreateThread(&viThread, 0, &viMgrMain, &__osViDevMgr, viThreadStack+sizeof(viThreadStack), pri); + __osViInit(); + osStartThread(&viThread); + __osRestoreInt(int_disabled); + if (newPri != -1) + { + osSetThreadPri(NULL, newPri); + } + } +} + +void viMgrMain(void* vargs) +{ + OSMgrArgs* args; + static u16 viRetrace; + u32 addTime; + viMesgStruct* mesg; + u32 temp; // always 0 + + temp = 0; + mesg = NULL; + viRetrace = __osViGetCurrentContext()->retraceCount; + if (viRetrace == 0) + viRetrace = 1; + + args = (OSMgrArgs*)vargs; + + while (1) + { + osRecvMesg(args->eventQueue, (OSMesg)&mesg, OS_MESG_BLOCK); + switch (mesg->unk00) + { + case 13: + __osViSwapContext(); + viRetrace--; + if (!viRetrace) + { + OSViContext* ctx = __osViGetCurrentContext(); + if (ctx->mq) + osSendMesg(ctx->mq, ctx->msg, OS_MESG_NOBLOCK); + viRetrace = ctx->retraceCount; + } + + __osViIntrCount++; + + // block optimized out since temp is always 0, + // but it changes register allocation and ordering for __osCurrentTime + if (temp != 0) + { + addTime = osGetCount(); + __osCurrentTime = addTime; + temp = 0; + } + + addTime = __osBaseCounter; + __osBaseCounter = osGetCount(); + addTime = __osBaseCounter - addTime; + __osCurrentTime = __osCurrentTime + addTime; + + break; + + case 14: + __osTimerInterrupt(); + break; + } + } +} |
