Files
mazegame/projects/samples/s_mapper.c
T

191 lines
6.4 KiB
C

// ____________________________
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀
// ROM mapper sample
//─────────────────────────────────────────────────────────────────────────────
#include "msxgl.h"
//=============================================================================
// DEFINES
//=============================================================================
// Library's logo
#define MSX_GL "\x01\x02\x03\x04\x05\x06"
#define SEG_PANEL_X 25
extern const c8* Seg4Data1;
extern const c8* Seg4Data2;
extern const u16 Seg5AsmData;
void Seg4Func1(u8 id) __banked;
//=============================================================================
// READ-ONLY DATA
//=============================================================================
// Fonts
#include "font/font_mgl_sample6.h"
// Animation characters
const u8 g_ChrAnim[] = { '|', '\\', '-', '/' };
//
const c8 g_SampleText[] = "Sample text";
__at(0x0F8000) const c8 g_SampleText15[] = "Seg 15 text";
// __at(0xFFA000) const c8 g_SampleText255[] = "Seg 255 text";
//=============================================================================
// MEMORY DATA
//=============================================================================
// Screen mode setting index
u8 g_VBlank = 0;
u8 g_Frame = 0;
u8 g_Phase = 0;
u8 g_Temp;
//=============================================================================
// FUNCTIONS
//=============================================================================
//-----------------------------------------------------------------------------
// H_TIMI interrupt hook
void VBlankHook()
{
g_VBlank = 1;
g_Frame++;
u8 sb3 = GET_BANK_SEGMENT(3);
SET_BANK_SEGMENT(3, g_Frame); // Make segment #1 visible through bank #3
g_Temp = GET_BANK_SEGMENT(3);
SET_BANK_SEGMENT(3, sb3); // Restore segment in bank #2
}
//-----------------------------------------------------------------------------
// Wait for V-Blank period
void WaitVBlank()
{
while (g_VBlank == 0) {}
g_VBlank = 0;
}
//-----------------------------------------------------------------------------
//
void DrawSegments(u8 y, const c8* txt)
{
Print_DrawTextAt(0, y, txt);
Print_DrawIntAt(SEG_PANEL_X, y, GET_BANK_SEGMENT(0));
Print_DrawIntAt(SEG_PANEL_X + 4, y, GET_BANK_SEGMENT(1));
Print_DrawIntAt(SEG_PANEL_X + 8, y, GET_BANK_SEGMENT(2));
Print_DrawIntAt(SEG_PANEL_X + 12, y, GET_BANK_SEGMENT(3));
}
//-----------------------------------------------------------------------------
// Program entry point
void main()
{
// Initial bank setting (initialized into crt0 code):
// Bank 0 => Segment 0
// Bank 1 => Segment 1
// Bank 2 => Segment 2
// Bank 3 => Segment 3
VDP_SetMode(VDP_MODE_SCREEN0); // Initialize screen mode 0 (text)
VDP_ClearVRAM();
Print_SetTextFont(g_Font_MGL_Sample6, 1); // Initialize font
Print_DrawText(MSX_GL " MAPPER SAMPLE"); // Display title
Print_DrawLineH(0, 1, 40);
Print_SetPosition(SEG_PANEL_X, 3);
Print_DrawText("B#0 B#1 B#2 B#3");
// INIT
// Bank 0 => Segment 0
// Bank 1 => Segment 1
// Bank 2 => Segment 2
// Bank 3 => Segment 3
DrawSegments(5, "Initial segments");
// SIMPLE SWITCH
// Bank 0 => Segment 0
// Bank 1 => Segment 1
// Bank 2 => Segment 2
// Bank 3 => Segment 5 (content of s_mapper_s5_b3.asm)
SET_BANK_SEGMENT(3, 5); // Make segment #5 visible through bank #3
DrawSegments(7, "Switch bank 3 to seg 5");
Print_SetPosition(0, 8);
Print_DrawFormat("Data: [%s]", &Seg5AsmData);
// BANKED CALL
// Bank 0 => Segment 0
// Bank 1 => Segment 1
// Bank 2 => Segment 2 (before/after calling) | 4 (content of s_mapper_s4_b2.c during banked call)
// Bank 3 => Segment 5 (content of s_mapper_s5_b3.asm)
Print_DrawTextAt(0, 10, "Call banked functions");
Seg4Func1(11); // Bank 2 => Segment 4 (content of s_mapper_s4_b2.c)
Seg4Func1(12); // Bank 2 => Segment 4 (content of s_mapper_s4_b2.c)
DrawSegments(13, "After banked call");
// MIRRORING
// Bank 0 => Segment 0
// Bank 1 => Segment 1
// Bank 2 => Segment 0
// Bank 3 => Segment 1
u8 sb2 = GET_BANK_SEGMENT(2);
SET_BANK_SEGMENT(2, 0); // Make segment #0 visible through bank #2
u8 sb3 = GET_BANK_SEGMENT(3);
SET_BANK_SEGMENT(3, 1); // Make segment #1 visible through bank #3
DrawSegments(15, "Set mirroring");
Print_SetPosition(0, 16);
Print_DrawFormat("At %4xh: [%s]", g_SampleText, g_SampleText);
Print_SetPosition(0, 17);
Print_DrawFormat("At %4xh: [%s]", g_SampleText + 0x4000, g_SampleText + 0x4000);
// RESTORE
// Bank 0 => Segment 0
// Bank 1 => Segment 1
// Bank 2 => Segment 2
// Bank 3 => Segment 5 (content of s_mapper_s5_b3.asm)
SET_BANK_SEGMENT(2, sb2); // Make previous segment visible through bank #2
SET_BANK_SEGMENT(3, sb3); // Make previous segment visible through bank #3
DrawSegments(19, "Restore segments");
// OUT OF BOUNDS
// Bank 0 => Segment 0
// Bank 1 => Segment 1
// Bank 2 => Segment 15 (last segment)
// Bank 3 => Segment 255
SET_BANK_SEGMENT(2, 15); // Make segment #15 visible through bank #2
SET_BANK_SEGMENT(3, 255); // Make segment #255 visible through bank #3
DrawSegments(19, "Out of bounds seg");
Print_SetPosition(0, 20);
Print_DrawFormat("Bank 2: [%s]", g_SampleText15);
Print_SetPosition(0, 21);
Print_DrawFormat("Bank 3: [%s]", 0xA000);
VDP_EnableVBlank(TRUE);
BIOS_SetHookCallback(H_TIMI, VBlankHook);
u8 frameCount = 0;
u8 errorCount = 0;
while (!Keyboard_IsKeyPressed(KEY_ESC))
{
// WaitVBlank();
SET_BANK_SEGMENT(3, frameCount);
if (GET_BANK_SEGMENT(3) != frameCount)
errorCount++;
Print_DrawIntAt(0, 23, errorCount);
Print_DrawCharAt(39, 0, g_ChrAnim[frameCount++ & 0x03]);
}
BIOS_ClearHook(H_TIMI);
BIOS_Exit(0);
}