// ____________________________ // ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄ // ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███ // █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄ // ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀ // Real-time clock module sample //───────────────────────────────────────────────────────────────────────────── //============================================================================= // INCLUDES //============================================================================= #include "msxgl.h" #include "tool/mem_op.h" //============================================================================= // DEFINES //============================================================================= // Graph base position #define GRAPH_X 16 #define GRAPH_Y 48 #define GRAPH_U 4 // Random sample count #define RAND_SAMPLE 0x8000 // 16384 #define CURVE_STEP 64 // enum CURVE_FORMAT { CURVE_8B_SIGNED = 0, CURVE_8B_UNSIGNED, CURVE_16B_SIGNED, CURVE_16B_UNSIGNED, }; // struct CurveEntry { const c8* Name; const void* Data; const c8* Min; const c8* Max; u16 Count; u16 Offset; u8 ZeroX; u8 ZeroY; u8 Format; }; //============================================================================= // READ-ONLY DATA //============================================================================= // Fonts #include "font/font_mgl_sample6.h" // Sinus & cosinus table #include "mathtable/mt_trigo_64.inc" #include "mathtable/mt_trigo_ext_64.inc" #include "mathtable/mt_sq_256.inc" #include "mathtable/mt_sqrt_256.inc" // Character animation const u8 chrAnim[] = { '|', '\\', '-', '/' }; const struct CurveEntry g_Curves[] = { { "Sine", g_Sinus64, "0", "Pi*2", 64, 6, 0, 106, CURVE_16B_SIGNED }, { "Cosine", g_Cosinus64, "0", "Pi*2", 64, 6, 0, 106, CURVE_16B_SIGNED }, { "Tangent", g_Tangent64, "-Pi/2", "Pi*2", 64, 3, 128, 106, CURVE_16B_SIGNED }, { "Arcsine", g_ArcSinus64, "-1", "1", 64, 2, 128, 106, CURVE_16B_SIGNED }, { "Arccosine", g_ArcCosinus64, "-1", "1", 64, 2, 128, 180, CURVE_16B_SIGNED }, { "Arctangent", g_ArcTangent64, "0", "?", 64, 2, 0, 170, CURVE_16B_SIGNED }, { "Square", g_Square256, "0", "1", 256, 5, 0, 170, CURVE_16B_UNSIGNED }, { "Square Root", g_SquareRoot256, "0", "?", 256, 1, 0, 170, CURVE_8B_UNSIGNED }, }; //============================================================================= // MEMORY DATA //============================================================================= // Screen mode setting index u8 g_VBlank = 0; u16 g_Frame = 0; i8 g_CurveIdx = 0; //============================================================================= // HELPER FUNCTIONS //============================================================================= //----------------------------------------------------------------------------- // H_TIMI interrupt hook void VBlankHook() { g_VBlank = 1; g_Frame++; } //----------------------------------------------------------------------------- // Wait for V-Blank period void WaitVBlank() { while (g_VBlank == 0) {} g_VBlank = 0; } //----------------------------------------------------------------------------- // Diplay page header void DisplayHeader(const c8* title) { // Setup screen VDP_SetMode(VDP_MODE_SCREEN5); VDP_SetColor(COLOR_DARK_BLUE); VDP_CommandHMMV(0, 0, 256, 1024, COLOR_MERGE2(COLOR_DARK_BLUE)); // Clear VRAM VDP_CommandWait(); // Setup print Print_SetBitmapFont(g_Font_MGL_Sample6); Print_SetColor(COLOR_WHITE, COLOR_DARK_BLUE); Print_Clear(); Print_SetPosition(0, 2); Print_DrawText("\x1\x2\x3\x4\x5\x6 MATH SAMPLE - "); Print_DrawText(title); Draw_LineH(0, 255, 12, COLOR_WHITE, 0); } //----------------------------------------------------------------------------- // Diplay page footer void DisplayFooter() { Draw_LineH(0, 255, 199, COLOR_WHITE, 0); Print_SetColor(COLOR_WHITE, COLOR_DARK_BLUE); Print_SetPosition(0, 203); Print_DrawText("F1:Rnd8 F2:Rnd16 F3:Curve F4:Func F5:Tab"); } //----------------------------------------------------------------------------- // Diplay page footer void DisplayRandom16() { DisplayHeader("Random 16b"); Print_SetPosition(0, 20); Print_DrawText("Method: "); Print_DrawText(RANDOM_16_NAME); Draw_Box(GRAPH_X - 1, GRAPH_Y, (u8)(GRAPH_X + 128), (u8)(GRAPH_Y + 128 + 1), COLOR_WHITE, 0); Print_SetColor(COLOR_LIGHT_BLUE, COLOR_DARK_BLUE); Print_SetPosition(158, GRAPH_Y); Print_DrawText("0 hit"); Print_SetPosition(158, GRAPH_Y + 8 * 5); Print_DrawText("5+ hits"); VDP_CommandHMMV(150, GRAPH_Y + 8 * 1, 4, 8, COLOR_MERGE2(COLOR_LIGHT_BLUE)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 2, 4, 8, COLOR_MERGE2(COLOR_CYAN)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 3, 4, 8, COLOR_MERGE2(COLOR_LIGHT_GREEN)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 4, 4, 8, COLOR_MERGE2(COLOR_LIGHT_YELLOW)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 5, 4, 8, COLOR_MERGE2(COLOR_LIGHT_RED)); u16 startFrame = g_Frame; for (u16 i = 0; i < RAND_SAMPLE; ++i) { u16 rand = Math_GetRandom16(); u16 x = GRAPH_X + ((rand % 0x00FF) / 2); u16 y = GRAPH_Y + 128 - ((rand >> 8) / 2); switch (VDP_CommandPOINT(x, y)) { case COLOR_DARK_BLUE: VDP_CommandPSET(x, y, COLOR_LIGHT_BLUE, 0); break; case COLOR_LIGHT_BLUE: VDP_CommandPSET(x, y, COLOR_CYAN, 0); break; case COLOR_CYAN: VDP_CommandPSET(x, y, COLOR_LIGHT_GREEN, 0); break; case COLOR_LIGHT_GREEN: VDP_CommandPSET(x, y, COLOR_LIGHT_YELLOW, 0); break; default: VDP_CommandPSET(x, y, COLOR_LIGHT_RED, 0); break; }; } Print_SetPosition(0, 184); Print_DrawText("t="); Print_DrawInt(g_Frame - startFrame); DisplayFooter(); } //----------------------------------------------------------------------------- // Diplay page footer void DisplayRandom8() { DisplayHeader("Random 8b"); Print_SetPosition(0, 20); Print_DrawText("Method: "); Print_DrawText(RANDOM_8_NAME); Draw_Box(GRAPH_X - 1, GRAPH_Y, (u8)(GRAPH_X + 128), (u8)(GRAPH_Y + 128 + 1), COLOR_WHITE, 0); Print_SetColor(COLOR_LIGHT_BLUE, COLOR_DARK_BLUE); Print_SetPosition(158, GRAPH_Y); Print_DrawText("0 hit"); Print_SetPosition(158, GRAPH_Y + 8 * 5); Print_DrawText("5+ hits"); VDP_CommandHMMV(150, GRAPH_Y + 8 * 1, 4, 8, COLOR_MERGE2(COLOR_LIGHT_BLUE)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 2, 4, 8, COLOR_MERGE2(COLOR_CYAN)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 3, 4, 8, COLOR_MERGE2(COLOR_LIGHT_GREEN)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 4, 4, 8, COLOR_MERGE2(COLOR_LIGHT_YELLOW)); VDP_CommandHMMV(150, GRAPH_Y + 8 * 5, 4, 8, COLOR_MERGE2(COLOR_LIGHT_RED)); u16 startFrame = g_Frame; for (u16 i = 0; i < RAND_SAMPLE; ++i) { #if (MSX_VERSION != MSX_TR) && ((RANDOM_8_METHOD == RANDOM_8_REGISTER) || (RANDOM_8_METHOD == RANDOM_8_RACC)) // 7-bits RNG u16 x = GRAPH_X + Math_GetRandom8(); u16 y = GRAPH_Y + 128 - Math_GetRandom8(); #else // 8-bits RNG u16 x = GRAPH_X + (Math_GetRandom8() / 2); u16 y = GRAPH_Y + 128 - (Math_GetRandom8() / 2); #endif switch (VDP_CommandPOINT(x, y)) { case COLOR_DARK_BLUE: VDP_CommandPSET(x, y, COLOR_LIGHT_BLUE, 0); break; case COLOR_LIGHT_BLUE: VDP_CommandPSET(x, y, COLOR_CYAN, 0); break; case COLOR_CYAN: VDP_CommandPSET(x, y, COLOR_LIGHT_GREEN, 0); break; case COLOR_LIGHT_GREEN: VDP_CommandPSET(x, y, COLOR_LIGHT_YELLOW, 0); break; default: VDP_CommandPSET(x, y, COLOR_LIGHT_RED, 0); break; }; } Print_SetPosition(0, 184); Print_DrawText("t="); Print_DrawInt(g_Frame - startFrame); DisplayFooter(); } //----------------------------------------------------------------------------- // Diplay void DisplayFunc() { DisplayHeader("Function"); // 8-bits Print_SetPosition(0, 20); i8 rnd8, val8; rnd8 = (i16)Math_GetRandom8(); Print_DrawFormat("A=Random8(): %i [%8b]\n", rnd8, rnd8); val8 = Math_Div10(rnd8); Print_DrawFormat("Div10(A): %i\n", val8); val8 = Math_Mod10(rnd8); Print_DrawFormat("Mod10(A): %i\n", val8); val8 = Math_Flip(rnd8); Print_DrawFormat("Flip(A): %i [%8b]\n", val8, val8); val8 = Math_Negative(rnd8); Print_DrawFormat("Negative(A): %i\n", val8); val8 = Math_SignedDiv2(rnd8); Print_DrawFormat("Div2(A): %i\n", val8); val8 = Math_SignedDiv4(rnd8); Print_DrawFormat("Div4(A): %i\n", val8); val8 = Math_SignedDiv8(rnd8); Print_DrawFormat("Div8(A): %i\n", val8); val8 = Math_SignedDiv16(rnd8); Print_DrawFormat("Div16(A): %i\n", val8); val8 = Math_SignedDiv32(rnd8); Print_DrawFormat("Div32(A): %i\n", val8); // 16-bits Print_Return(); i16 rnd16, val16; rnd16 = Math_GetRandom16(); Print_DrawFormat("B=Random16(): %i [%b]\n", rnd16, rnd16); val16 = Math_Div10_16b(rnd16); Print_DrawFormat("Div10_16b(B): %i\n", val16); val16 = Math_Mod10_16b(rnd16); Print_DrawFormat("Mod10_16b(B): %i\n", val16); val16 = Math_Flip_16b(rnd16); Print_DrawFormat("Flip_16b(B): %i [%b]\n", val16, val16); val16 = Math_Negative16(rnd16); Print_DrawFormat("Negative16(B):%i\n", val16); val16 = Math_Swap(rnd16); Print_DrawFormat("Swap(B): %i [%b]\n", val16, val16); DisplayFooter(); } u8 g_Tab[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; //----------------------------------------------------------------------------- // Diplay tab operation void DisplayTab() { DisplayHeader("Tab Operation"); Print_SetPosition(0, 20); Print_DrawFormat("Source: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_Inc(g_Tab, 8); Print_DrawFormat("Increment: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_RShift(g_Tab, 8); Print_DrawFormat("Right-Shift: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_Inc(g_Tab, 8); Print_DrawFormat("Increment: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_RShift(g_Tab, 8); Print_DrawFormat("Right-Shift: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_Dec(g_Tab, 8); Print_DrawFormat("Decrement: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_LShift(g_Tab, 8); Print_DrawFormat("Left-Shift: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_Dec(g_Tab, 8); Print_DrawFormat("Decrement: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); Mem_LShift(g_Tab, 8); Print_DrawFormat("Left-Shift: [%i,%i,%i,%i,%i,%i,%i,%i]\n\n", g_Tab[0], g_Tab[1], g_Tab[2], g_Tab[3], g_Tab[4], g_Tab[5], g_Tab[6], g_Tab[7]); DisplayFooter(); } //----------------------------------------------------------------------------- // Diplay curves void DisplayCurve() { DisplayHeader("Curve"); const struct CurveEntry* curve = &g_Curves[g_CurveIdx]; Print_SetPosition(0, 20); Print_DrawText("Table: "); Print_DrawText(curve->Name); Draw_LineH(0, 255, curve->ZeroY, COLOR_LIGHT_BLUE, 0); Draw_LineV(curve->ZeroX, 32, 196, COLOR_LIGHT_BLUE, 0); Print_SetColor(COLOR_LIGHT_BLUE, COLOR_DARK_BLUE); Print_SetPosition(2, curve->ZeroY + 2); Print_DrawText(curve->Min); Print_SetPosition(255 - 2 - String_Length(curve->Max) * 6, curve->ZeroY + 2); Print_DrawText(curve->Max); u8 prevX = 0, prevY = 0; for (u16 i = 0; i < CURVE_STEP; ++i) { u8 idx = i * (u8)((u16)curve->Count / CURVE_STEP); u8 x = i * (u8)((u16)256 / CURVE_STEP); u8 y = curve->ZeroY; switch (curve->Format) { case CURVE_8B_SIGNED: { const i8* ptr = (const i8*)curve->Data; y -= ptr[idx] >> curve->Offset; break; } case CURVE_8B_UNSIGNED: { const u8* ptr = (const u8*)curve->Data; y -= ptr[idx] >> curve->Offset; break; } case CURVE_16B_SIGNED: { const i16* ptr = (const i16*)curve->Data; y -= ptr[idx] >> curve->Offset; break; } case CURVE_16B_UNSIGNED: { const u16* ptr = (const u16*)curve->Data; y -= ptr[idx] >> curve->Offset; break; } }; #if (0) VDP_CommandPSET(x, y, COLOR_WHITE, 0); #else if (i > 0) Draw_Line(prevX, prevY, x, y, COLOR_WHITE, 0); #endif prevX = x; prevY = y; } DisplayFooter(); } //============================================================================= // MAIN LOOP //============================================================================= //----------------------------------------------------------------------------- // Program entry point void main() { #if (MSX_VERSION == MSX_TR) BIOS_SetCPUMode(CPU_MODE_R800_ROM + CPU_TURBO_LED); #endif BIOS_SetHookCallback(H_TIMI, VBlankHook); DisplayCurve(); bool bContinue = TRUE; while (bContinue) { WaitVBlank(); Print_SetPosition(248, 2); Print_DrawChar(chrAnim[g_Frame & 0x03]); u8 row6 = Keyboard_Read(6); if (IS_KEY_PRESSED(row6, KEY_F1)) DisplayRandom8(); else if (IS_KEY_PRESSED(row6, KEY_F2)) DisplayRandom16(); else if (IS_KEY_PRESSED(row6, KEY_F3)) DisplayCurve(); u8 row7 = Keyboard_Read(7); if (IS_KEY_PRESSED(row7, KEY_F4)) DisplayFunc(); if (IS_KEY_PRESSED(row7, KEY_F5)) DisplayTab(); u8 row8 = Keyboard_Read(8); if (IS_KEY_PRESSED(row8, KEY_UP) || IS_KEY_PRESSED(row8, KEY_LEFT)) { g_CurveIdx--; if (g_CurveIdx < 0) g_CurveIdx = numberof(g_Curves) - 1; DisplayCurve(); } else if (IS_KEY_PRESSED(row8, KEY_DOWN) || IS_KEY_PRESSED(row8, KEY_RIGHT)) { g_CurveIdx++; if (g_CurveIdx >= numberof(g_Curves)) g_CurveIdx = 0; DisplayCurve(); } if (Keyboard_IsKeyPressed(KEY_ESC)) bContinue = FALSE; } BIOS_ClearHook(H_TIMI); BIOS_Exit(0); }