mirror of https://github.com/n64decomp/mk64.git
parent
727ceadfb4
commit
de5c688e42
3
Makefile
3
Makefile
|
@ -25,7 +25,8 @@ TARGET_N64 ?= 1
|
|||
COMPILER ?= ido
|
||||
$(eval $(call validate-option,COMPILER,ido gcc))
|
||||
|
||||
# options for debuging. Set this to 1 and modify the macros in include/debug.h
|
||||
# Add debug tools with 'make DEBUG=1' and modify the macros in include/debug.h
|
||||
# Run make clean first. Add '#define CRASH_SCREEN_ENHANCEMENT' to the top of main.c
|
||||
DEBUG ?= 0
|
||||
|
||||
# VERSION - selects the version of the game to build
|
||||
|
|
4
mk64.ld
4
mk64.ld
|
@ -116,6 +116,7 @@ SECTIONS
|
|||
BUILD_DIR/src/audio/external.o(.text);
|
||||
BUILD_DIR/src/audio/port_eu.o(.text);
|
||||
#if DEBUG
|
||||
BUILD_DIR/src/debug/crash_screen_enhancement.o(.text);
|
||||
BUILD_DIR/src/debug/debug.o(.text);
|
||||
BUILD_DIR/src/os/sprintf.o(.text);
|
||||
#endif
|
||||
|
@ -266,6 +267,7 @@ SECTIONS
|
|||
BUILD_DIR/src/audio/playback.o(.data);
|
||||
BUILD_DIR/src/audio/effects.o(.data);
|
||||
#if DEBUG
|
||||
BUILD_DIR/src/debug/crash_screen_enhancement.o(.data);
|
||||
BUILD_DIR/src/debug/debug.o(.data);
|
||||
BUILD_DIR/src/os/sprintf.o(.data);
|
||||
#endif
|
||||
|
@ -311,6 +313,7 @@ SECTIONS
|
|||
BUILD_DIR/src/audio/external.o(.rodata);
|
||||
BUILD_DIR/src/audio/port_eu.o(.rodata);
|
||||
#if DEBUG
|
||||
BUILD_DIR/src/debug/crash_screen_enhancement.o(.rodata);
|
||||
BUILD_DIR/src/debug/debug.o(.rodata);
|
||||
BUILD_DIR/src/os/sprintf.o(.rodata);
|
||||
#endif
|
||||
|
@ -346,6 +349,7 @@ SECTIONS
|
|||
BUILD_DIR/src/code_800AF9B0.o(.bss);
|
||||
BUILD_DIR/src/menus.o(.bss);
|
||||
#if DEBUG
|
||||
BUILD_DIR/src/debug/crash_screen_enhancement.o(.bss);
|
||||
BUILD_DIR/src/debug/debug.o(.bss);
|
||||
BUILD_DIR/src/os/sprintf.o(.bss);
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
#include <ultra64.h>
|
||||
#include <macros.h>
|
||||
#include "types.h"
|
||||
#include <types.h>
|
||||
#include <config.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "crash_screen.h"
|
||||
|
||||
#ifdef CRASH_SCREEN_ENHANCEMENT
|
||||
#include "debug/crash_screen_enhancement.h"
|
||||
#endif
|
||||
|
||||
OSThread D_80162790;
|
||||
ALIGNED8 u8 gDebugThreadStack[0x400];
|
||||
OSMesgQueue D_80162D40;
|
||||
OSMesg D_80162D58;
|
||||
uintptr_t *pFramebuffer;
|
||||
u16 *pFramebuffer;
|
||||
s32 sButtonSequenceIndex;
|
||||
|
||||
#define DRAW_CODE 0xFFFF
|
||||
|
@ -212,17 +220,17 @@ void thread9_crash_screen(UNUSED void *arg0)
|
|||
osSetEventMesg(10, &D_80162D40, (OSMesg) 16);
|
||||
sButtonSequenceIndex = 0;
|
||||
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
osRecvMesg(&D_80162D40, &mesg, 1);
|
||||
thread = get_faulted_thread();
|
||||
|
||||
if (thread) {
|
||||
// Run only on the first iteration.
|
||||
if (sCounter == 0) {
|
||||
crash_screen_draw_square((u16 *)pFramebuffer);
|
||||
//#define SKIP_DRAW_SQUARE
|
||||
#ifndef SKIP_DRAW_SQUARE
|
||||
while(1)
|
||||
crash_screen_draw_square(pFramebuffer);
|
||||
//#define SKIP_DRAW_SQUARE
|
||||
#ifndef SKIP_DRAW_SQUARE
|
||||
while(TRUE)
|
||||
{
|
||||
read_controllers();
|
||||
|
||||
|
@ -239,8 +247,12 @@ void thread9_crash_screen(UNUSED void *arg0)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
crash_screen_draw_info((u16 *) pFramebuffer, thread);
|
||||
#endif
|
||||
#ifdef CRASH_SCREEN_ENHANCEMENT
|
||||
crash_screen_draw(thread);
|
||||
#else
|
||||
crash_screen_draw_info(pFramebuffer, thread);
|
||||
#endif
|
||||
|
||||
}
|
||||
if (sCounter < 5) {
|
||||
|
@ -250,7 +262,7 @@ void thread9_crash_screen(UNUSED void *arg0)
|
|||
}
|
||||
}
|
||||
|
||||
void crash_screen_set_framebuffer(uintptr_t *framebuffer) {
|
||||
void crash_screen_set_framebuffer(u16 *framebuffer) {
|
||||
pFramebuffer = framebuffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#include <ultra64.h>
|
||||
#include <macros.h>
|
||||
|
||||
extern u16 *pFramebuffer;
|
||||
|
||||
void crash_screen_set_framebuffer(u16*);
|
|
@ -0,0 +1,221 @@
|
|||
#include <ultra64.h>
|
||||
#include <macros.h>
|
||||
#include <types.h>
|
||||
#include <config.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "../crash_screen.h"
|
||||
#include "crash_screen_enhancement.h"
|
||||
|
||||
s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args);
|
||||
|
||||
u32 crashScreenFont2[7 * 9 + 1] = {
|
||||
0x70871c30,0x8988a250,0x88808290,0x88831c90,0x888402f8,0x88882210,0x71cf9c10,0xf9cf9c70,0x8228a288,0xf200a288,0x0bc11c78,0x0a222208,0x8a222288,0x71c21c70,0x23c738f8,0x5228a480,0x8a282280,0x8bc822f0,0xfa282280,0x8a28a480,0x8bc738f8,0xf9c89c08,0x82288808,0x82088808,0xf2ef8808,0x82288888,0x82288888,0x81c89c70,0x8a08a270,0x920da288,0xa20ab288,0xc20aaa88,0xa208a688,0x9208a288,0x8be8a270,0xf1cf1cf8,0x8a28a220,0x8a28a020,0xf22f1c20,0x82aa0220,0x82492220,0x81a89c20,0x8a28a288,0x8a28a288,0x8a289488,0x8a2a8850,0x894a9420,0x894aa220,0x70852220,0xf8011000,0x08020800,0x10840400,0x20040470,0x40840400,0x80020800,0xf8011000,0x70800000,0x88822200,0x08820400,0x108f8800,0x20821000,0x00022200,0x20800020
|
||||
};
|
||||
|
||||
extern u64 osClockRate;
|
||||
|
||||
u8 gCrashScreenCharToGlyph[128] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, 43, -1, -1, 37, 38, -1, 42,
|
||||
-1, 39, 44, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 36, -1, -1, -1, -1, 40, -1, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
|
||||
};
|
||||
|
||||
char *gCauseDesc[18] = {
|
||||
"Interrupt",
|
||||
"TLB modification",
|
||||
"TLB exception on load",
|
||||
"TLB exception on store",
|
||||
"Address error on load",
|
||||
"Address error on store",
|
||||
"Bus error on inst.",
|
||||
"Bus error on data",
|
||||
"System call exception",
|
||||
"Breakpoint exception",
|
||||
"Reserved instruction",
|
||||
"Coprocessor unusable",
|
||||
"Arithmetic overflow",
|
||||
"Trap exception",
|
||||
"Virtual coherency on inst.",
|
||||
"Floating point exception",
|
||||
"Watchpoint exception",
|
||||
"Virtual coherency on data",
|
||||
};
|
||||
|
||||
char *gFpcsrDesc[6] = {
|
||||
"Unimplemented operation", "Invalid operation", "Division by zero", "Overflow", "Underflow",
|
||||
"Inexact operation",
|
||||
};
|
||||
|
||||
void crash_screen_draw_glyph_enhancement(s32 x, s32 y, s32 glyph) {
|
||||
const u32 *data;
|
||||
u16 *ptr;
|
||||
u32 bit;
|
||||
u32 rowMask;
|
||||
s32 i, j;
|
||||
|
||||
data = &crashScreenFont2[glyph / 5 * 7];
|
||||
ptr = pFramebuffer + SCREEN_WIDTH * y + x;
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
bit = 0x80000000U >> ((glyph % 5) * 6);
|
||||
rowMask = *data++;
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
*ptr++ = (bit & rowMask) ? 0xffff : 1;
|
||||
bit >>= 1;
|
||||
}
|
||||
ptr += SCREEN_WIDTH - 6;
|
||||
}
|
||||
}
|
||||
|
||||
void crash_screen_draw_rect(s32 x, s32 y, s32 w, s32 h) {
|
||||
u16 *ptr;
|
||||
s32 i, j;
|
||||
|
||||
ptr = pFramebuffer + SCREEN_WIDTH * y + x;
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
// 0xe738 = 0b1110011100111000
|
||||
*ptr = ((*ptr & 0xe738) >> 2) | 1;
|
||||
ptr++;
|
||||
}
|
||||
ptr += SCREEN_WIDTH - w;
|
||||
}
|
||||
}
|
||||
|
||||
static char *write_to_buf(char *buffer, const char *data, size_t size) {
|
||||
return (char *) memcpy(buffer, data, size) + size;
|
||||
}
|
||||
|
||||
void crash_screen_print(s32 x, s32 y, const char *fmt, ...) {
|
||||
char *ptr;
|
||||
u32 glyph;
|
||||
s32 size;
|
||||
char buf[0x100];
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
size = _Printf(write_to_buf, buf, fmt, args);
|
||||
|
||||
if (size > 0) {
|
||||
ptr = buf;
|
||||
|
||||
|
||||
while (size > 0) {
|
||||
|
||||
|
||||
glyph = gCrashScreenCharToGlyph[*ptr & 0x7f];
|
||||
|
||||
if (glyph != 0xff) {
|
||||
crash_screen_draw_glyph_enhancement(x, y, glyph);
|
||||
}
|
||||
|
||||
size--;
|
||||
|
||||
ptr++;
|
||||
x += 6;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void crash_screen_sleep(s32 ms) {
|
||||
u64 cycles = ms * 1000LL * osClockRate / 1000000ULL;
|
||||
osSetTime(0);
|
||||
while (osGetTime() < cycles) {
|
||||
}
|
||||
}
|
||||
|
||||
void crash_screen_print_float_reg(s32 x, s32 y, s32 regNum, void *addr) {
|
||||
u32 bits;
|
||||
s32 exponent;
|
||||
|
||||
bits = *(u32 *) addr;
|
||||
exponent = ((bits & 0x7f800000U) >> 0x17) - 0x7f;
|
||||
if ((exponent >= -0x7e && exponent <= 0x7f) || bits == 0) {
|
||||
crash_screen_print(x, y, "F%02d:%.3e", regNum, *(f32 *) addr);
|
||||
} else {
|
||||
crash_screen_print(x, y, "F%02d:---------", regNum);
|
||||
}
|
||||
}
|
||||
|
||||
void crash_screen_print_fpcsr(u32 fpcsr) {
|
||||
s32 i;
|
||||
u32 bit;
|
||||
|
||||
bit = 1 << 17;
|
||||
crash_screen_print(30, 155, "FPCSR:%08XH", fpcsr);
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (fpcsr & bit) {
|
||||
crash_screen_print(132, 155, "(%s)", gFpcsrDesc[i]);
|
||||
return;
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void crash_screen_draw(OSThread* thread) {
|
||||
s16 cause;
|
||||
__OSThreadContext *tc = &thread->context;
|
||||
|
||||
cause = (tc->cause >> 2) & 0x1f;
|
||||
if (cause == 23) { // EXC_WATCH
|
||||
cause = 16;
|
||||
}
|
||||
if (cause == 31) { // EXC_VCED
|
||||
cause = 17;
|
||||
}
|
||||
|
||||
osWritebackDCacheAll();
|
||||
|
||||
crash_screen_draw_rect(25, 20, 270, 25);
|
||||
crash_screen_print(30, 25, "THREAD:%d (%s)", thread->id, gCauseDesc[cause]);
|
||||
crash_screen_print(30, 35, "PC:%08XH SR:%08XH VA:%08XH", tc->pc, tc->sr, tc->badvaddr);
|
||||
crash_screen_sleep(2000);
|
||||
crash_screen_draw_rect(25, 45, 270, 185);
|
||||
crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0,
|
||||
(u32) tc->v1);
|
||||
crash_screen_print(30, 60, "A0:%08XH A1:%08XH A2:%08XH", (u32) tc->a0, (u32) tc->a1,
|
||||
(u32) tc->a2);
|
||||
crash_screen_print(30, 70, "A3:%08XH T0:%08XH T1:%08XH", (u32) tc->a3, (u32) tc->t0,
|
||||
(u32) tc->t1);
|
||||
crash_screen_print(30, 80, "T2:%08XH T3:%08XH T4:%08XH", (u32) tc->t2, (u32) tc->t3,
|
||||
(u32) tc->t4);
|
||||
crash_screen_print(30, 90, "T5:%08XH T6:%08XH T7:%08XH", (u32) tc->t5, (u32) tc->t6,
|
||||
(u32) tc->t7);
|
||||
crash_screen_print(30, 100, "S0:%08XH S1:%08XH S2:%08XH", (u32) tc->s0, (u32) tc->s1,
|
||||
(u32) tc->s2);
|
||||
crash_screen_print(30, 110, "S3:%08XH S4:%08XH S5:%08XH", (u32) tc->s3, (u32) tc->s4,
|
||||
(u32) tc->s5);
|
||||
crash_screen_print(30, 120, "S6:%08XH S7:%08XH T8:%08XH", (u32) tc->s6, (u32) tc->s7,
|
||||
(u32) tc->t8);
|
||||
crash_screen_print(30, 130, "T9:%08XH GP:%08XH SP:%08XH", (u32) tc->t9, (u32) tc->gp,
|
||||
(u32) tc->sp);
|
||||
crash_screen_print(30, 140, "S8:%08XH RA:%08XH", (u32) tc->s8, (u32) tc->ra);
|
||||
crash_screen_print_fpcsr(tc->fpcsr);
|
||||
crash_screen_print_float_reg(30, 170, 0, &tc->fp0.f.f_even);
|
||||
crash_screen_print_float_reg(120, 170, 2, &tc->fp2.f.f_even);
|
||||
crash_screen_print_float_reg(210, 170, 4, &tc->fp4.f.f_even);
|
||||
crash_screen_print_float_reg(30, 180, 6, &tc->fp6.f.f_even);
|
||||
crash_screen_print_float_reg(120, 180, 8, &tc->fp8.f.f_even);
|
||||
crash_screen_print_float_reg(210, 180, 10, &tc->fp10.f.f_even);
|
||||
crash_screen_print_float_reg(30, 190, 12, &tc->fp12.f.f_even);
|
||||
crash_screen_print_float_reg(120, 190, 14, &tc->fp14.f.f_even);
|
||||
crash_screen_print_float_reg(210, 190, 16, &tc->fp16.f.f_even);
|
||||
crash_screen_print_float_reg(30, 200, 18, &tc->fp18.f.f_even);
|
||||
crash_screen_print_float_reg(120, 200, 20, &tc->fp20.f.f_even);
|
||||
crash_screen_print_float_reg(210, 200, 22, &tc->fp22.f.f_even);
|
||||
crash_screen_print_float_reg(30, 210, 24, &tc->fp24.f.f_even);
|
||||
crash_screen_print_float_reg(120, 210, 26, &tc->fp26.f.f_even);
|
||||
crash_screen_print_float_reg(210, 210, 28, &tc->fp28.f.f_even);
|
||||
crash_screen_print_float_reg(30, 220, 30, &tc->fp30.f.f_even);
|
||||
osViBlack(FALSE);
|
||||
osViSwapBuffer(pFramebuffer);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#include <ultra64.h>
|
||||
#include <macros.h>
|
||||
|
||||
void crash_screen_draw(OSThread* thread);
|
||||
|
||||
// Add this to the top of main.c or crash_screen.c
|
||||
//#define CRASH_SCREEN_ENHANCEMENT
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Example of how to force crash screen to run.
|
||||
* Make sure to include the header crash_screen_enhancement.h in main.h
|
||||
*/
|
||||
|
||||
// void display_and_vsync(void) {
|
||||
// profiler_log_thread5_time(BEFORE_DISPLAY_LISTS);
|
||||
// osRecvMesg(&gGfxVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
|
||||
// exec_display_list(&gGfxPool->spTask);
|
||||
// profiler_log_thread5_time(AFTER_DISPLAY_LISTS);
|
||||
// osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
|
||||
// osViSwapBuffer((void *) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[sRenderedFramebuffer]));
|
||||
// profiler_log_thread5_time(THREAD5_END);
|
||||
// osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
|
||||
// crash_screen_set_framebuffer((uintptr_t *) gPhysicalFramebuffers[sRenderedFramebuffer]);
|
||||
|
||||
// crash_screen_draw((u16 *) gPhysicalFramebuffers[sRenderedFramebuffer], &gGameLoopThread);
|
||||
// Add this line ^
|
||||
|
||||
// if (++sRenderedFramebuffer == 3) {
|
||||
// sRenderedFramebuffer = 0;
|
||||
// }
|
||||
// if (++sRenderingFramebuffer == 3) {
|
||||
// sRenderingFramebuffer = 0;
|
||||
// }
|
||||
// gGlobalTimer++;
|
||||
// }
|
15
src/main.c
15
src/main.c
|
@ -33,6 +33,7 @@
|
|||
#include "actors.h"
|
||||
#include "staff_ghosts.h"
|
||||
#include <debug.h>
|
||||
#include "crash_screen.h"
|
||||
|
||||
// Declarations (not in this file)
|
||||
void func_80091B78(void);
|
||||
|
@ -133,7 +134,7 @@ Gfx *gDisplayListHead;
|
|||
struct SPTask *gGfxSPTask;
|
||||
s32 D_801502A0;
|
||||
s32 D_801502A4;
|
||||
u32 gPhysicalFramebuffers[3];
|
||||
u16 *gPhysicalFramebuffers[3];
|
||||
u32 D_801502B4;
|
||||
UNUSED u32 D_801502B8;
|
||||
UNUSED u32 D_801502BC;
|
||||
|
@ -435,7 +436,6 @@ void config_gfx_pool(void) {
|
|||
* Yields to the VI framerate twice, locking the game at 30 FPS.
|
||||
* Selects the next framebuffer to be rendered and displayed.
|
||||
*/
|
||||
void crash_screen_set_framebuffer(uintptr_t*);
|
||||
void display_and_vsync(void) {
|
||||
profiler_log_thread5_time(BEFORE_DISPLAY_LISTS);
|
||||
osRecvMesg(&gGfxVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
|
||||
|
@ -445,7 +445,8 @@ void display_and_vsync(void) {
|
|||
osViSwapBuffer((void *) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[sRenderedFramebuffer]));
|
||||
profiler_log_thread5_time(THREAD5_END);
|
||||
osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
|
||||
crash_screen_set_framebuffer((uintptr_t *) gPhysicalFramebuffers[sRenderedFramebuffer]);
|
||||
crash_screen_set_framebuffer(gPhysicalFramebuffers[sRenderedFramebuffer]);
|
||||
|
||||
if (++sRenderedFramebuffer == 3) {
|
||||
sRenderedFramebuffer = 0;
|
||||
}
|
||||
|
@ -1032,16 +1033,15 @@ void thread3_video(UNUSED void *arg0) {
|
|||
OSMesg msg;
|
||||
UNUSED s32 pad[4];
|
||||
|
||||
gPhysicalFramebuffers[0] = (u32) &gFramebuffer0;
|
||||
gPhysicalFramebuffers[1] = (u32) &gFramebuffer1;
|
||||
gPhysicalFramebuffers[2] = (u32) &gFramebuffer2;
|
||||
gPhysicalFramebuffers[0] = (u16 *) &gFramebuffer0;
|
||||
gPhysicalFramebuffers[1] = (u16 *) &gFramebuffer1;
|
||||
gPhysicalFramebuffers[2] = (u16 *) &gFramebuffer2;
|
||||
|
||||
// Clear framebuffer.
|
||||
framebuffer1 = (u64 *) &gFramebuffer1;
|
||||
for (i = 0; i < 19200; i++) {
|
||||
framebuffer1[i] = 0;
|
||||
}
|
||||
|
||||
setup_mesg_queues();
|
||||
setup_game_memory();
|
||||
|
||||
|
@ -1144,6 +1144,7 @@ void thread5_game_loop(UNUSED void *arg) {
|
|||
if (!wasSoftReset) {
|
||||
clear_nmi_buffer();
|
||||
}
|
||||
|
||||
set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) OS_EVENT_SW2);
|
||||
// These variables track stats such as player wins.
|
||||
// In the event of a console reset, it remembers them.
|
||||
|
|
|
@ -73,7 +73,7 @@ extern s32 D_800DC56C[];
|
|||
|
||||
extern u16 D_80152308;
|
||||
|
||||
extern u32 gPhysicalFramebuffers[];
|
||||
extern u16 *gPhysicalFramebuffers[];
|
||||
extern OSIoMesg gDmaIoMesg;
|
||||
extern OSMesg gMainReceivedMesg;
|
||||
extern OSMesgQueue gDmaMesgQueue;
|
||||
|
|
Loading…
Reference in New Issue