summaryrefslogtreecommitdiff
path: root/source/monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/monitor.c')
-rw-r--r--source/monitor.c239
1 files changed, 229 insertions, 10 deletions
diff --git a/source/monitor.c b/source/monitor.c
index ad81b28..20c9722 100644
--- a/source/monitor.c
+++ b/source/monitor.c
@@ -27,6 +27,22 @@
#include "keyboard.h"
#include "textmode.h"
#include "framebuffer.h"
+#include "zx81.h"
+
+/* ---------------------------------------- PRIVATE DATA AND TYPES
+*/
+typedef enum
+{
+ DISPLAY_ADDR,
+ DISPLAY_HL,
+ DISPLAY_IX,
+ DISPLAY_SP,
+ DISPLAY_IY,
+ DISPLAY_BC,
+ DISPLAY_DE,
+ DISPLAY_TYPE_COUNT
+} MemDisplayType;
+
/* ---------------------------------------- STATIC INTERFACES
*/
@@ -48,14 +64,17 @@ static void DisplayHelp()
"In single step mode press A",
"to execute next instruction.",
"",
- "Use L/R to alter memory shown",
- "on the memory display.",
+ "Use L/R (+ Y for larger jumps)",
+ "to alter address in mem display.",
+ "",
+ "Press B to cycle between address",
+ "and register memory display.",
"",
"Note that all numbers are in hex",
"and the all keyboard keys are",
"sticky until the monitor exits.",
"",
- "Press A to continue",
+ "Press X to continue",
NULL
};
@@ -68,30 +87,230 @@ static void DisplayHelp()
TM_Put(0,f,help[f]);
}
- while(!(keysUp() & KEY_A))
+ while(!(keysDownRepeat() & KEY_X))
{
swiWaitForVBlank();
}
}
+static void DisplayRunningState(int running)
+{
+ if (running)
+ {
+ TM_Put(0,23,"RUNNING [PRESS X FOR HELP]");
+ }
+ else
+ {
+ TM_Put(0,23,"SINGLE STEP [PRESS X FOR HELP]");
+ }
+}
+
+
+static void DisplayCPU(Z80 *cpu)
+{
+ static const char *flag_char = "SZ5H3PNC";
+ static Z80Word prev_pc[8];
+ Z80Word tmp;
+ int f;
+ char flags[]="--------";
+
+ /* Display disassembly
+ */
+ for(f=0;f<8;f++)
+ {
+ tmp = prev_pc[f];
+
+ /* These may seem a bit convuluted, but there's no point being at home
+ to Mr Undefined Behaviour
+ */
+ TM_printf(1,f,"%4.4x:",tmp);
+ TM_Put(7,f,Z80Disassemble(cpu,&tmp));
+
+ if (f)
+ {
+ prev_pc[f-1] = prev_pc[f];
+ }
+ }
+
+ prev_pc[7] = tmp = cpu->PC;
+
+ TM_printf(0,8,">%4.4x:",tmp);
+ TM_Put(7,8,Z80Disassemble(cpu,&tmp));
+
+ for(f=0;f<8;f++)
+ {
+ TM_printf(1,9+f,"%4.4x:",tmp);
+ TM_Put(7,9+f,Z80Disassemble(cpu,&tmp));
+ }
+
+ /* Display process state
+ */
+ tmp = cpu->AF.b[Z80_LO_WORD];
+
+ for(f=0;f<8;f++)
+ {
+ if (tmp & 1<<(7-f))
+ {
+ flags[f] = flag_char[f];
+ }
+ }
+
+ TM_printf(0,18,"A:%2.2x F:%s IM:%2.2x",
+ cpu->AF.b[Z80_HI_WORD],flags,cpu->IM);
+
+ TM_printf(0,19,"BC:%4.4x DE:%4.4x HL:%4.4x",
+ cpu->BC.w,cpu->DE.w,cpu->HL.w);
+
+ TM_printf(0,20,"IX:%4.4x IY:%4.4x SP:%4.4x",
+ cpu->IX.w,cpu->IY.w,cpu->SP);
+
+ TM_printf(0,21,"PC:%4.4x IF:%d/%d IR:%2.2x%2.2x",
+ cpu->PC,cpu->IFF1,cpu->IFF2,cpu->I,cpu->R);
+}
+
+
+static void DisplayMem(Z80 *cpu, MemDisplayType disp, Z80Word addr)
+{
+ static const char *label[]=
+ {
+ "Address",
+ "HL",
+ "IX",
+ "SP",
+ "IY",
+ "BC",
+ "DE"
+ };
+
+ int x,y;
+
+ switch(disp)
+ {
+ case DISPLAY_HL:
+ addr = cpu->HL.w;
+ break;
+
+ case DISPLAY_IX:
+ addr = cpu->IX.w;
+ break;
+
+ case DISPLAY_SP:
+ addr = cpu->SP;
+ break;
+
+ case DISPLAY_IY:
+ addr = cpu->IY.w;
+ break;
+
+ case DISPLAY_BC:
+ addr = cpu->BC.w;
+ break;
+
+ case DISPLAY_DE:
+ addr = cpu->DE.w;
+ break;
+
+ default:
+ break;
+ }
+
+ TM_printf(0,0,"%s: %4.4x",label[disp],addr);
+
+ for(y=0;y<18;y++)
+ {
+ TM_printf(0,y+2,"%4.4x:",addr);
+
+ for(x=0;x<8;x++)
+ {
+ TM_printf(6+x*3,y+2,"%2.2x",ZX81ReadDisassem(cpu,addr++));
+ }
+ }
+}
+
/* ---------------------------------------- PUBLIC INTERFACES
*/
-void MachineCodeMonitor(void)
+void MachineCodeMonitor(Z80 *cpu)
{
+ static Z80Word display_address = 0x4000;
+ static MemDisplayType mem_display = DISPLAY_ADDR;
int done = FALSE;
+ int running = FALSE;
+ int cpu_display = TRUE;
+ int key;
SK_DisplayKeyboard();
SK_SetDisplayBrightness(TRUE);
- DisplayHelp();
-
- /*
while(!done)
{
- swiWaitForVBlank();
+ TM_Cls();
+ DisplayRunningState(running);
+
+ if (cpu_display)
+ {
+ DisplayCPU(cpu);
+ }
+ else
+ {
+ DisplayMem(cpu,mem_display,display_address);
+ }
+
+ do
+ {
+ swiWaitForVBlank();
+ key = keysDownRepeat();
+ } while (!running && !key);
+
+ if (key & KEY_START)
+ {
+ running = !running;
+ }
+
+ if (key & KEY_X)
+ {
+ DisplayHelp();
+ }
+
+ if (key & KEY_SELECT)
+ {
+ cpu_display = !cpu_display;
+ }
+
+ if (key & KEY_L)
+ {
+ if (keysHeld() & KEY_Y)
+ {
+ display_address -= 512;
+ }
+ else
+ {
+ display_address -= 64;
+ }
+ }
+
+ if (key & KEY_R)
+ {
+ if (keysHeld() & KEY_Y)
+ {
+ display_address += 512;
+ }
+ else
+ {
+ display_address += 64;
+ }
+ }
+
+ if (key & KEY_B)
+ {
+ mem_display = (mem_display+1) % DISPLAY_TYPE_COUNT;
+ }
+
+ if (running || (key & KEY_A))
+ {
+ Z80SingleStep(cpu);
+ }
}
- */
SK_SetDisplayBrightness(FALSE);
TM_Cls();