Files

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);
}