Files
mazegame/projects/samples/s_sys.c
T

607 lines
17 KiB
C

// ____________________________
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀
// System module sample
//─────────────────────────────────────────────────────────────────────────────
//=============================================================================
// INCLUDES
//=============================================================================
#include "msxgl.h"
//=============================================================================
// DEFINES
//=============================================================================
#define SLOT_Y 3
// Library's logo
#define MSX_GL "\x01\x02\x03\x04\x05\x06"
//=============================================================================
// READ-ONLY DATA
//=============================================================================
// Fonts data
#include "font/font_mgl_sample6.h"
// Character animation data
const c8 g_ChrAnim[] = { '|', '\\', '-', '/' };
// Slot box
const c8* g_SlotTop = "\x18\x17\x17\x17\x17\x17\x17\x17\x19";
const c8* g_SlotMid = "\x16\x20\x20\x20\x20\x20\x20\x20\x16";
const c8* g_SlotBot = "\x1A\x17\x17\x17\x17\x17\x17\x17\x1B";
// Selected slot
const c8* g_SlotTopSel = "\x98\x97\x97\x97\x97\x97\x97\x97\x99";
const c8* g_SlotMidSel = "\x96\x20\x20\x20\x20\x20\x20\x20\x96";
const c8* g_SlotBotSel = "\x9A\x97\x97\x97\x97\x97\x97\x97\x9B";
// Expended slot box
const c8* g_SlotExTop = "\x18\x17\x12\x17\x12\x17\x12\x17\x19";
const c8* g_SlotExMid = "\x16\x20\x16\x20\x16\x20\x16\x20\x16";
const c8* g_SlotExBot = "\x1A\x17\x11\x17\x11\x17\x11\x17\x1B";
// Selected slot
const c8* g_SlotExTopSel = "\x98\x97\x99";
const c8* g_SlotExMidSel = "\x96\x20\x96";
const c8* g_SlotExBotSel = "\x9A\x97\x9B";
//=============================================================================
// MEMORY DATA
//=============================================================================
u8 g_VDP;
//=============================================================================
// HELPER FUNCTIONS
//=============================================================================
//-----------------------------------------------------------------------------
//
void Print_DrawSlot(u8 slot)
{
Print_DrawInt(Sys_SlotGetPrimary(slot));
if (Sys_SlotIsExpended(slot))
{
Print_DrawChar('-');
Print_DrawInt(Sys_SlotGetSecondary(slot));
}
}
//-----------------------------------------------------------------------------
//
void Print_DrawVersion(u16 ver)
{
Print_DrawInt(ver >> 12);
Print_DrawChar('.');
Print_DrawInt((ver >> 6) & 0x3F);
Print_DrawChar('.');
Print_DrawInt(ver & 0x3F);
}
//-----------------------------------------------------------------------------
//
void InterSlotWritePage3(u8 slot, u16 addr, u8 value) __NAKED __SDCCCALL0
{
slot; // IX+4
addr; // IX+6 IX+5
value; // IX+7
__asm
di
push ix
ld ix, #0
add ix, sp
ld d, 4(ix) // D=[E.|..|SS|PP] Get slot ID
ld l, 5(ix)
ld h, 6(ix) // HL=Write address
ld a, 7(ix)
ld i, a // I=Write value
// Backup primary slot
in a, (P_PPI_A) // A=[P3|P2|P1|P0]
ld b, a // B=[P3|P2|P1|P0] Save current primary slot in B
// Switch primary slot
ld a, d // A=[E.|..|SS|PP]
rrca
rrca // A=[PP|E.|..|SS]
and #0b11000000 // A=[PP|00|00|00]
ld e, a // E=[PP|00|00|00]
ld a, b // A=[P3|P2|P1|P0]
and #0b00111111 // A=[00|P2|P1|P0]
or e // A=[PP|P2|P1|P0] remplace ?? par le slot primaire (00,01,10 ou 11)
out (P_PPI_A), a // write new primary slot
// Backup secondary slot (of the new primary slot)
ld a, (M_SLTSL) // A=[~3|~2|~1|~0]
cpl // A=[S3|S2|S1|S0]
ld c, a // C=[S3|S2|S1|S0] Save current secondary slot in C
// Switch secondary slot
ld a, d // A=[E.|..|SS|PP]
rlca
rlca // A=[..|SS|PP|E.]
rlca
rlca // A=[SS|PP|E.|..]
and #0b11000000 // A=[SS|00|00|00]
ld e, a // E=[SS|00|00|00]
ld a, c // A=[S3|S2|S1|S0]
and #0b00111111 // A=[00|S2|S1|S0]
or e // A=[SS|S2|S1|S0] remplace ?? par le slot secondaire (00,01,10 ou 11)
ld (M_SLTSL), a // write new seconday slot
// Write
ld a, i
ld (hl), a
// Restore
ld a, c // C=[S3|S2|S1|S0]
ld (M_SLTSL), a
ld a, b // B=[P3|P2|P1|P0]
out (P_PPI_A), a
pop ix
ei
ret
__endasm;
}
//-----------------------------------------------------------------------------
//
u8 InterSlotReadPage3(u8 slot, u16 addr) __NAKED
{
slot; // A -> D
addr; // DE -> HL
__asm
di
ld d, a // D=[E.|..|SS|PP] Get slot ID
ld l, d
ld h, e // HL=Read address
// Backup primary slot
in a, (P_PPI_A) // A=[P3|P2|P1|P0]
ld b, a // B=[P3|P2|P1|P0] Save current primary slot in B
// Switch primary slot
ld a, d // A=[E.|..|SS|PP]
rrca
rrca // A=[PP|E.|..|SS]
and #0b11000000 // A=[PP|00|00|00]
ld e, a // E=[PP|00|00|00]
ld a, b // A=[P3|P2|P1|P0]
and #0b00111111 // A=[00|P2|P1|P0]
or e // A=[PP|P2|P1|P0] Remplace ?? par le slot primaire (00,01,10 ou 11)
out (P_PPI_A), a
// Backup secondary slot (of the new primary slot)
ld a, (M_SLTSL) // A=[~3|~2|~1|~0]
cpl // A=[S3|S2|S1|S0]
ld c, a // C=[S3|S2|S1|S0] Save current secondary slot in C
// Switch secondary slot
ld a, d // A=[E.|..|SS|PP]
rlca
rlca // A=[..|SS|PP|E.]
rlca
rlca // A=[SS|PP|E.|..]
and #0b11000000 // A=[SS|00|00|00]
ld e, a // E=[SS|00|00|00]
ld a, c // A=[S3|S2|S1|S0]
and #0b00111111 // A=[S3|00|00|00]
or e // A=[SS|S2|S1|S0] Remplace ?? par le slot secondaire (00,01,10 ou 11)
ld (M_SLTSL), a
// Read
ld a, (hl)
ld l, a // L=Return value
// Restore
ld a, c
ld (M_SLTSL), a
ld a, b
out (P_PPI_A), a
ei
ret
__endasm;
}
//-----------------------------------------------------------------------------
//
u8 IsSlotPageRAM(u8 slotId, u8 page)
{
u16 addr = page * 0x4000;
if (page < 3)
{
u8 data = BIOS_InterSlotRead(slotId, addr);
BIOS_InterSlotWrite(slotId, addr, ~data);
if (BIOS_InterSlotRead(slotId, addr) == data)
return 0;
BIOS_InterSlotWrite(slotId, addr, data);
}
else
{
u8 data = InterSlotReadPage3(slotId, addr);
InterSlotWritePage3(slotId, addr, ~data);
if (InterSlotReadPage3(slotId, addr) == data)
return 0;
InterSlotWritePage3(slotId, addr, data);
}
return 1;
}
//-----------------------------------------------------------------------------
//
const c8* GetSlotName(u8 slotId, u8 page)
{
if ((slotId == g_EXPTBL[0]) && (page == 0))
return "M-R";
if ((slotId == g_EXPTBL[0]) && (page == 1))
return "BAS";
if ((slotId == g_EXBRSA) && (page == 0))
return "SUB";
if ((slotId == g_MASTER) && (page == 1))
return "DSK";
if (IsSlotPageRAM(slotId, page))
return "RAM";
if (page < 3)
{
u16 addr = page * 0x4000;
if (BIOS_InterSlotRead(slotId, addr) == 'A')
if (BIOS_InterSlotRead(slotId, ++addr) == 'B')
return "ROM";
}
u8 prim = slotId & 0x03;
u8 sec = (slotId >> 2) & 0x03;
u16 addr = M_SLTATR + 16 * prim + 4 * sec + page;
u8 app = *((u8*)addr);
if (app & 0x80)
return " B ";
if (app & 0x40)
return " D ";
if (app & 0x20)
return " S ";
return " ? ";
}
//-----------------------------------------------------------------------------
//
void DisplayHeader()
{
Print_Clear();
Print_SetPosition(0, 0);
Print_DrawText(MSX_GL " SYSTEM INFORMATION");
Print_DrawLineH(0, 1, 40);
}
//-----------------------------------------------------------------------------
//
void DisplayFooter()
{
Print_SetPosition(0, 23);
Print_DrawText("F1:Info F2:Slot F3:Mem ESC:Exit");
}
//-----------------------------------------------------------------------------
//
void DisplayInfo()
{
DisplayHeader();
Print_DrawLineV(19, 2, 20);
//-------------------------------------------------------------------------
Print_SetPosition(0, 3);
Print_DrawText("System");
// MSX version
Print_DrawText("\n- Version: ");
switch (Sys_GetMSXVersion())
{
case MSXVER_1: Print_DrawText("MSX1"); break;
case MSXVER_2: Print_DrawText("MSX2"); break;
case MSXVER_2P: Print_DrawText("MSX2+"); break;
case MSXVER_TR: Print_DrawText("TurboR"); break;
default: Print_DrawText("Unknow"); break;
}
Print_DrawText("\n- Font: ");
switch (g_ROMVersion.CharacterSet)
{
case 0: Print_DrawText("Jap"); break;
case 1: Print_DrawText("Int"); break;
case 2: Print_DrawText("Rus"); break;
default: Print_DrawText("Unknow"); break;
}
Print_DrawText("\n- Keyb: ");
switch (g_ROMVersion.KeyboardType)
{
case 0: Print_DrawText("Jap"); break;
case 1: Print_DrawText("Int"); break;
case 2: Print_DrawText("Fra"); break;
case 3: Print_DrawText("UK"); break;
case 4: Print_DrawText("Ger"); break;
case 5: Print_DrawText("USSR"); break;
case 6: Print_DrawText("Spain"); break;
default: Print_DrawText("Unknow"); break;
}
//-------------------------------------------------------------------------
// VDP version
Print_DrawText("\n\nVideo");
Print_DrawText("\n- VDP: ");
switch (g_VDP)
{
case 0: Print_DrawText("TMS9918A"); break;
case 1: Print_DrawText("V9938"); break;
case 2: Print_DrawText("V9958"); break;
default: Print_DrawText("Unknow"); break;
}
// VDP frequency
Print_DrawText("\n- Freq: ");
switch (g_ROMVersion.VSF)
{
case 0: Print_DrawText("60 Hz"); break;
case 1: Print_DrawText("50 Hz"); break;
}
// VRAM size
Print_DrawText("\n- VRAM: ");
switch (GET_VRAM_SIZE())
{
case 0: Print_DrawText("16 KB"); break;
case 1: Print_DrawText("64 KB"); break;
case 2: Print_DrawText("128 KB"); break;
case 3: Print_DrawText("192 KB"); break;
}
// VRAM size
Print_DrawText("\n- IO R/W: ");
Print_DrawHex8(g_VDP_DR);
Print_DrawChar('/');
Print_DrawHex8(g_VDP_DW);
//-------------------------------------------------------------------------
// Memory
Print_DrawText("\n\nMemory");
Print_DrawText("\n- Heap: ");
Print_DrawHex16(Mem_GetHeapAddress());
Print_DrawText("\n- Stack: ");
Print_DrawHex16(Mem_GetStackAddress());
Print_DrawText("\n- Free: ");
Print_DrawInt(Mem_GetHeapSize());
Print_DrawText(" B");
//-------------------------------------------------------------------------
// Slots
u8 X = 21;
u8 Y = 3;
Print_DrawTextAt(X, Y++, "Current Slots");
Print_DrawTextAt(X, Y++, "- Page #0: ");
Print_DrawSlot(Sys_GetPageSlot(0));
Print_DrawTextAt(X, Y++, "- Page #1: ");
Print_DrawSlot(Sys_GetPageSlot(1));
Print_DrawTextAt(X, Y++, "- Page #2: ");
Print_DrawSlot(Sys_GetPageSlot(2));
Print_DrawTextAt(X, Y++, "- Page #3: ");
Print_DrawSlot(Sys_GetPageSlot(3));
//-------------------------------------------------------------------------
// ROMs
Y++;
Print_DrawTextAt(X, Y++, "ROM");
Print_DrawTextAt(X, Y++, "- Main: ");
Print_DrawSlot(g_MNROM);
Print_DrawTextAt(X, Y++, "- Sub: ");
Print_DrawSlot(g_EXBRSA);
Print_DrawTextAt(X, Y++, "- Disk: ");
Print_DrawSlot(g_MASTER);
//-------------------------------------------------------------------------
// Lib
Y++;
Print_DrawTextAt(X, Y++, "Lib");
Print_DrawTextAt(X, Y++, "- "MSX_GL": ");
Print_DrawVersion(MSXGL_VERSION);
Print_DrawTextAt(X, Y++, "- SDCC: ");
Print_DrawVersion(SDCC_VERSION);
#if (MSX_VERSION & MSX_1)
Print_DrawTextAt(X, Y++, "- Target: MSX1");
#elif (MSX_VERSION & MSX_2)
Print_DrawTextAt(X, Y++, "- Target: MSX2");
#elif (MSX_VERSION & MSX_2P)
Print_DrawTextAt(X, Y++, "- Target: MSX2+");
#elif (MSX_VERSION & MSX_TR)
Print_DrawTextAt(X, Y++, "- Target: MSX TR");
#endif
DisplayFooter();
}
//-----------------------------------------------------------------------------
//
void DisplaySlots()
{
DisplayHeader();
// Draw frames
Print_DrawTextAt(0, SLOT_Y + 2, "FFFF\n\n\nC000\nBFFF\n\n\n8000\n7FFF\n\n\n4000\n3FFF\n\n\n0000");
for (u8 slot = 0; slot < 4; ++slot)
{
Print_DrawTextAt((slot * 9) + 6, SLOT_Y, "Slot");
Print_DrawInt(slot);
if (Sys_IsSlotExpanded(slot))
{
for (u8 sub = 0; sub < 4; ++sub)
{
Print_SetPosition((slot * 9) + 5 + (sub * 2), SLOT_Y + 1);
Print_DrawInt(sub);
}
for (u8 page = 0; page < 4; ++page)
{
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 2, g_SlotExTop);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 3, g_SlotExMid);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 4, g_SlotExMid);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 5, g_SlotExBot);
}
}
else
{
for (u8 page = 0; page < 4; ++page)
{
u8 pageSlot = Sys_GetPageSlot(3 - page);
if (pageSlot == SLOT(slot))
{
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 2, g_SlotTopSel);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 3, g_SlotMidSel);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 4, g_SlotMidSel);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 5, g_SlotBotSel);
}
else
{
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 2, g_SlotTop);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 3, g_SlotMid);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 4, g_SlotMid);
Print_DrawTextAt((slot * 9) + 4, (page * 4) + SLOT_Y + 5, g_SlotBot);
}
}
}
}
// Find slot type
for (u8 page = 0; page < 4; ++page)
{
u8 pageSlot = Sys_GetPageSlot(3 - page);
for (u8 slot = 0; slot < 4; ++slot)
{
if (Sys_IsSlotExpanded(slot))
{
for (u8 sub = 0; sub < 4; ++sub)
{
if (pageSlot == SLOTEX(slot, sub))
{
Print_SetPosition((slot * 9) + 4 + (sub * 2), (page * 4) + SLOT_Y + 2);
Print_DrawText(g_SlotExTopSel);
Print_SetPosition((slot * 9) + 4 + (sub * 2), (page * 4) + SLOT_Y + 3);
Print_DrawText(g_SlotExMidSel);
Print_SetPosition((slot * 9) + 4 + (sub * 2), (page * 4) + SLOT_Y + 4);
Print_DrawText(g_SlotExMidSel);
Print_SetPosition((slot * 9) + 4 + (sub * 2), (page * 4) + SLOT_Y + 5);
Print_DrawText(g_SlotExBotSel);
}
Print_SetPosition((slot * 9) + 4 + (sub * 2), (page * 4) + SLOT_Y + 3 + (sub & 0x1));
Print_DrawText(GetSlotName(SLOTEX(slot, sub), 3 - page));
}
}
else
{
Print_SetPosition((slot * 9) + 7, (page * 4) + SLOT_Y + 3);
Print_DrawText(GetSlotName(SLOT(slot), 3 - page));
}
}
}
DisplayFooter();
}
//-----------------------------------------------------------------------------
//
void DisplayMem()
{
DisplayHeader();
Print_SetPosition(0, 3);
// Memory
Print_DrawText("Memory\n");
Print_DrawFormat("- Heap: %x\n", Mem_GetHeapAddress());
Print_DrawFormat("- Stack: %x\n", Mem_GetStackAddress());
Print_DrawFormat("- Free: %i bytes\n", Mem_GetHeapSize());
// Static allocator
Print_DrawText("\nDynamic allocator\n");
Mem_DynamicInitializeHeap(1024);
Print_DrawFormat("- Init 1024 bytes from heap\n");
void* p1 = Mem_DynamicAlloc(100);
Print_DrawFormat("- Alloc 100 bytes: p1=%x (%i)\n", p1, p1 ? Mem_GetDynamicSize(p1) : 0);
void* p2 = Mem_DynamicAlloc(500);
Print_DrawFormat("- Alloc 500 bytes: p2=%x (%i)\n", p2, p2 ? Mem_GetDynamicSize(p2) : 0);
Mem_DynamicFree(p1);
Print_DrawFormat("- Free p1\n");
void* p3 = Mem_DynamicAlloc(101);
Print_DrawFormat("- Alloc 101 bytes: p3=%x (%i)\n", p3, p3 ? Mem_GetDynamicSize(p3) : 0);
void* p4 = Mem_DynamicAlloc(100);
Print_DrawFormat("- Alloc 100 bytes: p4=%x (%i)\n", p4, p4 ? Mem_GetDynamicSize(p4) : 0);
void* p5 = Mem_DynamicAlloc(500);
Print_DrawFormat("- Alloc 500 bytes: p5=%x (%i)\n", p5, p5 ? Mem_GetDynamicSize(p5) : 0);
Mem_HeapFree(1024); // Release dynamic allocator heap allocation
DisplayFooter();
}
//=============================================================================
// MAIN LOOP
//=============================================================================
//-----------------------------------------------------------------------------
// Program entry point
void main()
{
g_VDP = VDP_GetVersion();
VDP_SetMode(VDP_MODE_SCREEN0);
VDP_FillVRAM_16K(0, 0x0000, 0x4000); // Clear VRAM
Print_SetTextFont(g_Font_MGL_Sample6, 1);
Print_SetColor(0xF, 0x0);
callback cb = DisplayInfo;
cb();
u8 count = 0;
while (!Keyboard_IsKeyPressed(KEY_ESC))
{
Halt();
Print_SetPosition(39, 0);
Print_DrawChar(g_ChrAnim[count++ & 0x03]);
u8 row = Keyboard_Read(KEY_ROW(KEY_F1));
if (IS_KEY_PRESSED(row, KEY_F1))
{
cb = DisplayInfo;
cb();
}
else if (IS_KEY_PRESSED(row, KEY_F2))
{
cb = DisplaySlots;
cb();
}
else if (IS_KEY_PRESSED(row, KEY_F3))
{
cb = DisplayMem;
cb();
}
}
BIOS_Exit(0);
}