Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
429 lines
12 KiB
C
429 lines
12 KiB
C
// ____________________________
|
|
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄
|
|
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███
|
|
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄
|
|
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀
|
|
// by Guillaume 'Aoineko' Blanchard under CC BY-SA license
|
|
//─────────────────────────────────────────────────────────────────────────────
|
|
#include "msxgl.h"
|
|
|
|
//=============================================================================
|
|
// DEFINES
|
|
//=============================================================================
|
|
|
|
// Library's logo
|
|
#define MSX_GL "\x01\x02\x03\x04\x05\x06"
|
|
|
|
// Mapper page
|
|
#define BANK_ADDR 0x8000
|
|
#define MAPPER_Y 10
|
|
#define MAPPER_NUM 8
|
|
#define MAPPER_ADDR_X 20
|
|
#define CHAR_ASCII 20
|
|
#define CHAR_HEXA 7
|
|
#define QUICK_JUMP 16
|
|
|
|
#if (MAPPER_NUM > ROM_SEGMENTS)
|
|
#undef MAPPER_NUM
|
|
#define MAPPER_NUM ROM_SEGMENTS
|
|
#endif
|
|
|
|
#if ((TARGET_TYPE == TYPE_ROM) && (ROM_MAPPER == ROM_NEO8))
|
|
// void PrintSegment500Data(u8 x, u8 y) __banked;
|
|
// #define BANKED_BANK 1
|
|
// #define BANKED_SEG 500
|
|
// #define BANKED_CALL(x, y) PrintSegment500Data(x, y)
|
|
#define TEST_BANK 4
|
|
#define ROM_MAPPER_STR "Segment in bank 4"
|
|
#elif ((TARGET_TYPE == TYPE_ROM) && (ROM_MAPPER == ROM_NEO16))
|
|
// void PrintSegment500Data(u8 x, u8 y) __banked;
|
|
// #define BANKED_BANK 1
|
|
// #define BANKED_SEG 500
|
|
// #define BANKED_CALL(x, y) PrintSegment500Data(x, y)
|
|
#define TEST_BANK 2
|
|
#define ROM_MAPPER_STR "Segment in bank 2"
|
|
#elif ((TARGET_TYPE == TYPE_ROM) && (ROM_MAPPER >= ROM_MAPPER_16K))
|
|
// void PrintSegment2Data(u8 x, u8 y) __banked;
|
|
// #define BANKED_BANK 1
|
|
// #define BANKED_SEG 2
|
|
// #define BANKED_CALL(x, y) PrintSegment2Data(x, y)
|
|
#define TEST_BANK 1
|
|
#define ROM_MAPPER_STR "Segment in bank 1"
|
|
#elif ((TARGET_TYPE == TYPE_ROM) && (ROM_MAPPER > ROM_PLAIN))
|
|
// void PrintSegment4Data(u8 x, u8 y) __banked;
|
|
// #define BANKED_BANK 2
|
|
// #define BANKED_SEG 4
|
|
// #define BANKED_CALL(x, y) PrintSegment4Data(x, y)
|
|
#define TEST_BANK 2
|
|
#define ROM_MAPPER_STR "Segment in bank 2"
|
|
#else
|
|
// void PrintSegment4Data(u8 x, u8 y) __banked;
|
|
// #define BANKED_BANK 2
|
|
// #define BANKED_SEG 4
|
|
// #define BANKED_CALL(x, y) PrintSegment4Data(x, y)
|
|
#define TEST_BANK 0
|
|
#define ROM_MAPPER_STR ""
|
|
#endif
|
|
|
|
// Function prototypes
|
|
void main();
|
|
|
|
//=============================================================================
|
|
// READ-ONLY DATA
|
|
//=============================================================================
|
|
|
|
// Fonts data
|
|
#include "font/font_mgl_sample6.h"
|
|
|
|
// // Data in bank 2 & 3
|
|
// #if (ROM_MAPPER == ROM_ASCII16)
|
|
// __at(0x8000) const c8 g_DataBank1[] = "Segment #1 (default in Bank #1)";
|
|
// #elif ((ROM_MAPPER == ROM_ASCII8) || (ROM_MAPPER == ROM_KONAMI) || (ROM_MAPPER == ROM_KONAMI_SCC))
|
|
// __at(0x8000) const c8 g_DataBank2[] = "Segment #2 (default in Bank #2)";
|
|
// __at(0xA000) const c8 g_DataBank3[] = "Segment #3 (default in Bank #3)";
|
|
// #endif
|
|
|
|
// Character animation data
|
|
const c8 g_ChrAnim[] = { '|', '\\', '-', '/' };
|
|
|
|
|
|
//=============================================================================
|
|
// MEMORY DATA
|
|
//=============================================================================
|
|
u8 g_Buffer[128];
|
|
#if ((TARGET_TYPE == TYPE_ROM) || (ROM_MAPPER != ROM_PLAIN))
|
|
u8 g_DisplayASCII = 0;
|
|
i16 g_Segment = 0;
|
|
u16 g_Address = BANK_ADDR;
|
|
#endif
|
|
|
|
//=============================================================================
|
|
// HELPER FUNCTIONS
|
|
//=============================================================================
|
|
|
|
#if ((TARGET_TYPE == TYPE_ROM) || (TARGET == TARGET_DOS0))
|
|
//-----------------------------------------------------------------------------
|
|
/// ISR for 48/64K ROM
|
|
void VDP_InterruptHandler()
|
|
{
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
void Print_Slot(u8 slot)
|
|
{
|
|
Print_DrawInt(Sys_SlotGetPrimary(slot));
|
|
if (Sys_SlotIsExpended(slot))
|
|
{
|
|
Print_DrawChar('-');
|
|
Print_DrawInt(Sys_SlotGetSecondary(slot));
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
const c8* GetTargetType(u8 target)
|
|
{
|
|
switch (target)
|
|
{
|
|
case TYPE_BIN: return "BASIC";
|
|
case TYPE_ROM: return "ROM";
|
|
case TYPE_DOS: return "DOS";
|
|
};
|
|
return "Unknow";
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
const c8* GetROMMapper(u8 mapper)
|
|
{
|
|
switch (mapper)
|
|
{
|
|
case ROM_PLAIN: return "Plain";
|
|
case ROM_ASCII8: return "ASCII-8";
|
|
case ROM_ASCII16: return "ASCII-16";
|
|
case ROM_KONAMI: return "Konami";
|
|
case ROM_KONAMI_SCC: return "Konami SCC";
|
|
case ROM_NEO8: return "NEO-8";
|
|
case ROM_NEO16: return "NEO-16";
|
|
case ROM_YAMANOOTO: return "Yamanooto";
|
|
case ROM_ASCII16X: return "ASCII16-X";
|
|
};
|
|
return "Unknow";
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
const c8* GetROMFrame(u8 size)
|
|
{
|
|
switch (size)
|
|
{
|
|
case ROM_8K: return "8K";
|
|
case ROM_16K: return "16K";
|
|
case ROM_24K: return "24K";
|
|
case ROM_32K: return "32K";
|
|
case ROM_48K: return "48K";
|
|
case ROM_64K: return "64K";
|
|
};
|
|
return "Unknow";
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
void DisplayHeader()
|
|
{
|
|
// Print_Clear();
|
|
VDP_FillVRAM(' ' - g_PrintData.CharFirst + g_PrintData.PatternOffset, g_ScreenLayoutLow, g_ScreenLayoutHigh, 40 * 24);
|
|
Print_SetPosition(0, 0);
|
|
Print_DrawText(MSX_GL " TARGET SAMPLE");
|
|
Print_DrawLineH(0, 1, 40);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
void DisplayFooter()
|
|
{
|
|
Print_DrawLineH(0, 22, 40);
|
|
Print_SetPosition(0, 23);
|
|
#if ((TARGET_TYPE == TYPE_ROM) || (ROM_MAPPER != ROM_PLAIN))
|
|
if (g_DisplayASCII)
|
|
Print_DrawText("F1:Hexa ");
|
|
else
|
|
Print_DrawText("F1:ASCII ");
|
|
Print_DrawText("\x81\x80:Addr \x82:Seg");
|
|
#endif
|
|
}
|
|
|
|
#if ((TARGET_TYPE == TYPE_ROM) && (ROM_MAPPER != ROM_PLAIN))
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
void UpdateMapper()
|
|
{
|
|
Print_SetPosition(MAPPER_ADDR_X, MAPPER_Y);
|
|
Print_DrawText("\x81 ");
|
|
Print_DrawHex16(g_Address);
|
|
Print_DrawText(" \x80\n");
|
|
|
|
Print_SetPosition(1, MAPPER_Y + 2);
|
|
Print_DrawChar((g_Segment == 0) ? ' ' : '\x8E');
|
|
Print_SetPosition(1, MAPPER_Y + 1 + MAPPER_NUM);
|
|
Print_DrawChar((g_Segment == ROM_SEGMENTS - MAPPER_NUM) ? ' ' : '\x8F');
|
|
|
|
for (u8 i = 0; i < MAPPER_NUM; i++)
|
|
{
|
|
u16 index = g_Segment + i;
|
|
Print_SetPosition(2, MAPPER_Y + 2 + i);
|
|
Print_DrawInt(index);
|
|
if (index < 100)
|
|
Print_DrawChar(' ');
|
|
if (index < 1000)
|
|
Print_DrawChar(' ');
|
|
|
|
Print_SetPosition(7, MAPPER_Y + 2 + i);
|
|
SET_BANK_SEGMENT(TEST_BANK, index);
|
|
u8 max = g_DisplayASCII ? CHAR_ASCII : CHAR_HEXA;
|
|
for (u8 j = 0; j < max; j++)
|
|
{
|
|
u8 chr = ((const u8*)(g_Address))[j];
|
|
if (g_DisplayASCII)
|
|
Print_DrawChar(chr);
|
|
else
|
|
{
|
|
Print_DrawHex8(chr);
|
|
if (j < max - 1)
|
|
Print_DrawChar(' ');
|
|
}
|
|
}
|
|
Print_Return();
|
|
}
|
|
|
|
for (u8 i = 0; i < MAPPER_BANKS; i++)
|
|
{
|
|
u16 seg = 0;
|
|
switch (i)
|
|
{
|
|
case 0: seg = GET_BANK_SEGMENT(0); break;
|
|
case 1: seg = GET_BANK_SEGMENT(1); break;
|
|
case 2: seg = GET_BANK_SEGMENT(2); break;
|
|
case 3: seg = GET_BANK_SEGMENT(3); break;
|
|
case 4: seg = GET_BANK_SEGMENT(4); break;
|
|
case 5: seg = GET_BANK_SEGMENT(5); break;
|
|
};
|
|
Print_SetPosition(30, MAPPER_Y + 4 + i);
|
|
Print_DrawFormat("%c%i", (i == TEST_BANK) ? 0x80 : ' ', i);
|
|
Print_SetPosition(35, MAPPER_Y + 4 + i);
|
|
Print_DrawFormat("%i ", seg);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Display media target information
|
|
void DiplayInfo()
|
|
{
|
|
DisplayHeader();
|
|
|
|
Print_SetPosition(0, 2);
|
|
Print_DrawText(TARGET_NAME);
|
|
Print_DrawFormat("\n\nType: %s", GetTargetType(TARGET_TYPE));
|
|
#if (TARGET_TYPE == TYPE_ROM)
|
|
Print_DrawFormat("\nMapper: %s", GetROMMapper(ROM_MAPPER));
|
|
|
|
Print_DrawFormat("\nSize: %iKB", ROM_SIZE);
|
|
#if (ROM_MAPPER != ROM_PLAIN)
|
|
Print_DrawFormat(" (%i)", (i16)ROM_SEGMENTS);
|
|
#endif
|
|
#endif
|
|
Print_DrawFormat("\nAddr: %4x~%4x", Sys_GetFirstAddr(), Sys_GetLastAddr());
|
|
Print_DrawFormat("\nISR: %c", TARGET_ISR ? 0x0C : 0x0B);
|
|
|
|
Print_SetPosition(29, 4);
|
|
Print_DrawText("Page Slot");
|
|
|
|
Print_SetPosition(29, 5);
|
|
Print_DrawText("\x18\x17\x17\x17\x12\x17\x17\x17\x17\x17\x19");
|
|
u8 mainPage = (u16)main >> 14;
|
|
for (u8 i = 0; i < 4; i++)
|
|
{
|
|
Print_SetPosition(29, 6 + i);
|
|
Print_DrawChar('\x16');
|
|
g_PrintData.CursorX = 33;
|
|
Print_DrawChar('\x16');
|
|
g_PrintData.CursorX = 39;
|
|
Print_DrawChar('\x16');
|
|
|
|
u8 slotId = Sys_GetPageSlot(i);
|
|
Print_SetPosition(30, 6 + i);
|
|
Print_DrawFormat("%c%i", (i == mainPage) ? 0x80 : ' ', i);
|
|
Print_SetPosition(35, 6 + i);
|
|
Print_Slot(slotId);
|
|
}
|
|
Print_SetPosition(29, 6 + 4);
|
|
Print_DrawText("\x1A\x17\x17\x17\x11\x17\x17\x17\x17\x17\x1B");
|
|
|
|
#if ((TARGET_TYPE == TYPE_ROM) && (ROM_MAPPER != ROM_PLAIN))
|
|
|
|
Print_SetPosition(0, MAPPER_Y);
|
|
Print_DrawText(ROM_MAPPER_STR);
|
|
|
|
Print_SetPosition(0, MAPPER_Y + 1);
|
|
Print_DrawText("\x18\x17\x17\x17\x17\x17\x12");
|
|
Print_DrawCharX('\x17', 20);
|
|
Print_DrawChar('\x19');
|
|
for (u8 i = 0; i < MAPPER_NUM; i++)
|
|
{
|
|
Print_SetPosition(0, MAPPER_Y + 2 + i);
|
|
Print_DrawChar('\x16');
|
|
g_PrintData.CursorX = 6;
|
|
Print_DrawChar('\x16');
|
|
g_PrintData.CursorX = 27;
|
|
Print_DrawChar('\x16');
|
|
}
|
|
Print_SetPosition(0, MAPPER_Y + 2 + MAPPER_NUM);
|
|
Print_DrawText("\x1A\x17\x17\x17\x17\x17\x11");
|
|
Print_DrawCharX('\x17', 20);
|
|
Print_DrawChar('\x1B');
|
|
|
|
Print_SetPosition(29, MAPPER_Y + 2);
|
|
Print_DrawText("Bank Seg");
|
|
|
|
Print_SetPosition(29, MAPPER_Y + 3);
|
|
Print_DrawText("\x18\x17\x17\x17\x12\x17\x17\x17\x17\x17\x19");
|
|
for (u8 i = 0; i < MAPPER_BANKS; i++)
|
|
{
|
|
Print_SetPosition(29, MAPPER_Y + 4 + i);
|
|
Print_DrawChar('\x16');
|
|
g_PrintData.CursorX = 33;
|
|
Print_DrawChar('\x16');
|
|
g_PrintData.CursorX = 39;
|
|
Print_DrawChar('\x16');
|
|
}
|
|
Print_SetPosition(29, MAPPER_Y + 4 + MAPPER_BANKS);
|
|
Print_DrawText("\x1A\x17\x17\x17\x11\x17\x17\x17\x17\x17\x1B");
|
|
|
|
UpdateMapper();
|
|
|
|
// Print_SetPosition(0, MAPPER_Y + 4 + MAPPER_NUM);
|
|
// Print_DrawText("Banked call:");
|
|
// BANKED_CALL(1, MAPPER_Y + 5 + MAPPER_NUM);
|
|
|
|
#endif
|
|
|
|
DisplayFooter();
|
|
}
|
|
|
|
//=============================================================================
|
|
// MAIN LOOP
|
|
//=============================================================================
|
|
//-----------------------------------------------------------------------------
|
|
// Program entry point
|
|
void main()
|
|
{
|
|
// Initialize
|
|
VDP_SetMode(VDP_MODE_SCREEN0);
|
|
VDP_EnableVBlank(TRUE);
|
|
Print_SetTextFont(g_Font_MGL_Sample6, 1);
|
|
|
|
DiplayInfo();
|
|
|
|
u8 count = 0;
|
|
while (!Keyboard_IsKeyPressed(KEY_ESC))
|
|
{
|
|
Halt();
|
|
|
|
Print_SetPosition(39, 0);
|
|
Print_DrawChar(g_ChrAnim[count++ & 0x03]);
|
|
|
|
// Handle user input
|
|
u8 row6 = Keyboard_Read(6);
|
|
u8 row8 = Keyboard_Read(8);
|
|
|
|
#if ((TARGET_TYPE == TYPE_ROM) && (ROM_MAPPER != ROM_PLAIN))
|
|
if (IS_KEY_PRESSED(row6, KEY_F1))
|
|
{
|
|
g_DisplayASCII = 1 - g_DisplayASCII;
|
|
UpdateMapper();
|
|
}
|
|
if (IS_KEY_PRESSED(row8, KEY_RIGHT))
|
|
{
|
|
g_Address++;
|
|
UpdateMapper();
|
|
}
|
|
if (IS_KEY_PRESSED(row8, KEY_LEFT))
|
|
{
|
|
if (g_Address > BANK_ADDR)
|
|
g_Address--;
|
|
UpdateMapper();
|
|
}
|
|
if (IS_KEY_PRESSED(row8, KEY_DOWN))
|
|
{
|
|
if (IS_KEY_PRESSED(row6, KEY_CTRL))
|
|
g_Segment += QUICK_JUMP;
|
|
else
|
|
g_Segment++;
|
|
if (g_Segment > ROM_SEGMENTS - MAPPER_NUM)
|
|
g_Segment = ROM_SEGMENTS - MAPPER_NUM;
|
|
UpdateMapper();
|
|
}
|
|
if (IS_KEY_PRESSED(row8, KEY_UP))
|
|
{
|
|
if (IS_KEY_PRESSED(row6, KEY_CTRL))
|
|
g_Segment -= QUICK_JUMP;
|
|
else
|
|
g_Segment--;
|
|
if (g_Segment < 0)
|
|
g_Segment = 0;
|
|
UpdateMapper();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if ((TARGET_TYPE == TYPE_ROM) && (TARGET & ROM_ISR))
|
|
// BIOS not present in page 0
|
|
Sys_SetPage0Slot(g_EXPTBL[0]);
|
|
#endif
|
|
BIOS_Exit(0);
|
|
} |