Files

479 lines
14 KiB
C

// ____________________________
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀
// 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);
}