Skip to content

Commit

Permalink
HALT and BREAK instructions
Browse files Browse the repository at this point in the history
Two special opcodes have been implemeted - 0x15 (AKA HALT) and 0x113E (aka BREAK).
The BREAK opcode is supported by lwasm while the HALT opcode is an unused 6x09
single byte instruction.  When enabled Vcc will halt (pause) the CPU when one of
these codes is encountered. The ability to enable/disable these opcodes has been
added to the CPU config screen and these settings are preserved in the Vcc ini file.
  • Loading branch information
ejaquay committed Mar 30, 2024
1 parent a74a7a1 commit a9239d0
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 14 deletions.
41 changes: 41 additions & 0 deletions Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,47 @@ namespace VCC { namespace Debugger
MemWrite8(memWrite.value, memWrite.addr);
}

// Check of halt instruction is enabled
bool Debugger::Halt_Enabled(int Hinstr)
{
switch (Hinstr) {
case 0x15:
return Halt_0x15_TF;
case 0x113E:
return Halt_0x113E_TF;
default:
return false;
}
}

// DoHalt halts emulation and returns the number of opcodes
// used or zero if a breakpoint. A breakpoint will restore
// the original instruction which will execute next. The PC
// will be used as the key to the breakpoints list
int Debugger::DoHalt(int Hinstr,unsigned short /*PC*/) {
Debugger::Halt();
switch (Hinstr) {
case 0x15: //Vcc HALT
return 1;
case 0x113E: //Vcc BREAK
return 2;
default:
return 1;
}
}

// Enable / Disable halt instruction
void Debugger::EnableHalt(int Hinstr, bool enable)
{
switch (Hinstr) {
case 0x15:
Halt_0x15_TF = enable;
break;
case 0x113E:
Halt_0x113E_TF = enable;
break;
}
}

} }

Expand Down
18 changes: 18 additions & 0 deletions Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ namespace VCC { namespace Debugger

void Update();

// VCC halt instuction status and enable. Halt_0x113E is a "BREAK"
// instruction that can be compiled into code for debugging purposes.
// Halt_0x15 is a "HALT" instruction. VCC could use "HALT" as a breakpoint
// mechanism. A breakpoint would be established by replacing an opcode by
// HALT and saving the replaced opcode in a table indexed by the program
// counter. When the halt is encountered the original opcode is restored
// and will execute next. If the breakpoint is to be persistant the HALT
// will need to be replaced after the original instruction executes. NOTE:
// The current Debugger Breakpoints screen does not use this mechanism. It
// searches for a program counter match in a table before executing each
// instruction, which slows execution. A future TODO is to use this new
// mechanism instead for that screen.
bool Halt_Enabled(int);
void EnableHalt(int,bool);
int DoHalt(int,unsigned short);

protected:

enum class ExecutionMode
Expand Down Expand Up @@ -156,5 +172,7 @@ namespace VCC { namespace Debugger
bool TraceTriggerChanged_ = false;
tracebuffer_type TraceCaptured_;
std::map<int, long> TraceMarks_;
bool Halt_0x113E_TF = false;
bool Halt_0x15_TF = false;
};
} }
4 changes: 2 additions & 2 deletions OpCodeTables.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ namespace VCC { namespace Debugger
0x12, "NOP", Inherent, 2, 1, 1, 1, false, Fixed,
0x13, "SYNC", Inherent, 4, 3, 1, 1, false, WaitForSYNCAdjust,
0x14, "SEXW", Inherent, 4, 4, 1, 1, true, Fixed, // Illegal on 6809
0x15, "-", Illegal, 0, 0, 0, 1, false, None,
0x15, "HALT", Inherent, 2, 1, 1, 1, false, Fixed,
0x16, "LBRA", LongRelative, 5, 4, 3, 1, false, LongBranchAdjust,
0x17, "LBSR", LongRelative, 9, 7, 3, 1, false, LongBranchAdjust,
0x18, "-", Illegal, 0, 0, 0, 1, false, None,
Expand Down Expand Up @@ -697,7 +697,7 @@ namespace VCC { namespace Debugger
0x3B, "TFM", Immediate, 6, 6, 3, 2, true, TFMAdjust, // Illegal on 6809
0x3C, "BITMD", Immediate, 4, 4, 3, 2, true, Fixed, // Illegal on 6809
0x3D, "LDMD", Immediate, 5, 5, 3, 2, true, Fixed, // Illegal on 6809
0x3E, "-", Illegal, 0, 0, 0, 2, false, None,
0x3E, "BREAK", Inherent, 4, 2, 2, 2, false, Fixed,
0x3F, "SWI3", Inherent, 20, 22, 2, 2, false, Fixed,

0x40, "-", Illegal, 0, 0, 0, 2, false, None,
Expand Down
13 changes: 8 additions & 5 deletions Vcc.rc
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,21 @@ IDD_CPU DIALOGEX 0, 0, 268, 217
STYLE DS_SETFONT | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
GROUPBOX "Memory Size",IDC_STATIC,17,60,60,54,BS_CENTER
CONTROL "Slider1",IDC_CLOCKSPEED,"msctls_trackbar32",TBS_TOP | TBS_NOTICKS | WS_TABSTOP,17,30,176,15,WS_EX_CLIENTEDGE
EDITTEXT IDC_CLOCKDISPLAY,199,30,45,15,ES_AUTOHSCROLL | ES_READONLY
GROUPBOX "Over-Clocking",IDC_STATIC,15,19,234,34,BS_CENTER
ICON "",IDC_CPUICON,143,140,21,20
RADIOBUTTON "Motorola MC6809 CPU",IDC_6809,27,139,89,10
RADIOBUTTON "Hitachi HD6309 CPU",IDC_6309,27,152,87,10,WS_TABSTOP
GROUPBOX "Memory Size",IDC_STATIC,17,60,60,54,BS_CENTER
RADIOBUTTON "128 K",IDC_128K,27,71,35,10
RADIOBUTTON "512 K",IDC_512K,27,81,35,10
RADIOBUTTON "2048 K",IDC_2M,27,92,39,10
RADIOBUTTON "8192 K",IDC_8M,27,103,39,10
GROUPBOX "CPU",IDC_STATIC,17,123,156,44,BS_CENTER
GROUPBOX "CPU",IDC_STATIC,17,123,154,43,BS_CENTER
RADIOBUTTON "Motorola MC6809 CPU",IDC_6809,27,137,89,10
RADIOBUTTON "Hitachi HD6309 CPU",IDC_6309,27,150,87,10,WS_TABSTOP
ICON "",IDC_CPUICON,140,138,21,20
GROUPBOX "VCC Debug Opcodes",IDC_STATIC,17,174,120,43,BS_CENTER
CONTROL "HALT ($15)",IDC_ENABLE_HALT, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,188,70,10
CONTROL "BREAK ($113E)",IDC_ENABLE_BREAK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,200,70,10
END

IDD_AUDIO DIALOGEX 0, 0, 269, 160
Expand Down
35 changes: 31 additions & 4 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ unsigned char WriteIniFile(void)
WritePrivateProfileInt("CPU","Throttle",CurrentConfig.SpeedThrottle,IniFilePath);
WritePrivateProfileInt("CPU","CpuType",CurrentConfig.CpuType,IniFilePath);
WritePrivateProfileInt("CPU", "MaxOverClock", CurrentConfig.MaxOverclock, IniFilePath);
WritePrivateProfileInt("CPU","HaltEnabled",CurrentConfig.HaltOpcEnabled,IniFilePath);
WritePrivateProfileInt("CPU","BreakEnabled",CurrentConfig.BreakOpcEnabled,IniFilePath);

WritePrivateProfileString("Audio","SndCard",CurrentConfig.SoundCardName,IniFilePath);
WritePrivateProfileInt("Audio","Rate",CurrentConfig.AudioRate,IniFilePath);
Expand Down Expand Up @@ -299,7 +301,9 @@ unsigned char ReadIniFile(void)
CurrentConfig.FrameSkip = GetPrivateProfileInt("CPU","FrameSkip",1,IniFilePath);
CurrentConfig.SpeedThrottle = GetPrivateProfileInt("CPU","Throttle",1,IniFilePath);
CurrentConfig.CpuType = GetPrivateProfileInt("CPU","CpuType",0,IniFilePath);
CurrentConfig.MaxOverclock = GetPrivateProfileInt("CPU", "MaxOverClock",100, IniFilePath);
CurrentConfig.MaxOverclock = GetPrivateProfileInt("CPU","MaxOverClock",100,IniFilePath);
CurrentConfig.HaltOpcEnabled = GetPrivateProfileInt("CPU","HaltEnabled",0,IniFilePath);
CurrentConfig.BreakOpcEnabled = GetPrivateProfileInt("CPU","BreakEnabled",0,IniFilePath);

CurrentConfig.AudioRate = GetPrivateProfileInt("Audio","Rate",3,IniFilePath);
GetPrivateProfileString("Audio","SndCard","",CurrentConfig.SoundCardName,63,IniFilePath);
Expand Down Expand Up @@ -547,6 +551,18 @@ void UpdateConfig (void)
SetCPUMultiplyer(CurrentConfig.CPUMultiplyer);
SetRamSize(CurrentConfig.RamSize);
SetCpuType(CurrentConfig.CpuType);

if (CurrentConfig.HaltOpcEnabled) {
EmuState.Debugger.EnableHalt(0x15,true);
} else {
EmuState.Debugger.EnableHalt(0x15,false);
}
if (CurrentConfig.BreakOpcEnabled) {
EmuState.Debugger.EnableHalt(0x113E,true);
} else {
EmuState.Debugger.EnableHalt(0x113E,false);
}

SetMonitorType(CurrentConfig.MonitorType);
SetCartAutoStart(CurrentConfig.CartAutoStart);
if (CurrentConfig.RebootNow)
Expand Down Expand Up @@ -622,6 +638,8 @@ LRESULT CALLBACK CpuConfig(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
for (temp=0;temp<=1;temp++)
SendDlgItemMessage(hDlg,Cpuchoice[temp],BM_SETCHECK,(temp==TempConfig.CpuType),0);
SendDlgItemMessage(hDlg,IDC_CPUICON,STM_SETIMAGE ,(WPARAM)IMAGE_ICON,(LPARAM)CpuIcons[TempConfig.CpuType]);
SendDlgItemMessage(hDlg,IDC_ENABLE_HALT,BM_SETCHECK,TempConfig.HaltOpcEnabled,0);
SendDlgItemMessage(hDlg,IDC_ENABLE_BREAK,BM_SETCHECK,TempConfig.BreakOpcEnabled,0);
break;

case WM_HSCROLL:
Expand Down Expand Up @@ -659,6 +677,15 @@ LRESULT CALLBACK CpuConfig(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
SendDlgItemMessage(hDlg,IDC_CPUICON,STM_SETIMAGE ,(WPARAM)IMAGE_ICON,(LPARAM)CpuIcons[TempConfig.CpuType]);
}
break;
case IDC_ENABLE_HALT:
TempConfig.HaltOpcEnabled = (unsigned char)
SendDlgItemMessage(hDlg,IDC_ENABLE_HALT,BM_GETCHECK,0,0);
break;
case IDC_ENABLE_BREAK:
TempConfig.BreakOpcEnabled = (unsigned char)
SendDlgItemMessage(hDlg,IDC_ENABLE_BREAK,BM_GETCHECK,0,0);
break;

} //End switch LOWORD(wParam)
break; //Break WM_COMMAND
} //END switch (message)
Expand Down Expand Up @@ -707,9 +734,9 @@ LRESULT CALLBACK TapeConfig(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPara
SendDlgItemMessage(hDlg,IDC_TAPEFILE,WM_SETTEXT,strlen(TapeFileName),(LPARAM)(LPCSTR)TapeFileName);
// hCounter=GetDlgItem(hDlg,IDC_TCOUNT);
// SendMessage (hCounter, EM_SETBKGNDCOLOR, 0, (LPARAM)RGB(0,0,0));
SendDlgItemMessage(hDlg,IDC_TCOUNT,EM_SETBKGNDCOLOR ,0,(LPARAM)RGB(0,0,0));
SendDlgItemMessage(hDlg,IDC_TCOUNT,EM_SETBKGNDCOLOR ,0,(LPARAM)RGB(0,0,0));
SendDlgItemMessage(hDlg,IDC_TCOUNT,EM_SETCHARFORMAT ,SCF_ALL,(LPARAM)&CounterText);
SendDlgItemMessage(hDlg,IDC_MODE,EM_SETBKGNDCOLOR ,0,(LPARAM)RGB(0,0,0));
SendDlgItemMessage(hDlg,IDC_MODE,EM_SETBKGNDCOLOR ,0,(LPARAM)RGB(0,0,0));
SendDlgItemMessage(hDlg,IDC_MODE,EM_SETCHARFORMAT ,SCF_ALL,(LPARAM)&CounterText);
// SendDlgItemMessage(hDlg,IDC_MODE,EM_SETCHARFORMAT ,SCF_ALL,(LPARAM)&ModeText);
hDlgTape=hDlg;
Expand Down Expand Up @@ -767,7 +794,7 @@ LRESULT CALLBACK AudioConfig(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
SendDlgItemMessage(hDlg,IDC_PROGRESSRIGHT,PBM_SETRANGE32,0,0x7F);
SendDlgItemMessage(hDlg,IDC_PROGRESSLEFT,PBM_SETPOS,0,0);
SendDlgItemMessage(hDlg,IDC_PROGRESSLEFT,PBM_SETBARCOLOR,0,0xFFFF); //bgr
SendDlgItemMessage(hDlg,IDC_PROGRESSRIGHT,PBM_SETBARCOLOR,0,0xFFFF);
SendDlgItemMessage(hDlg,IDC_PROGRESSRIGHT,PBM_SETBARCOLOR,0,0xFFFF);
SendDlgItemMessage(hDlg,IDC_PROGRESSLEFT,PBM_SETBKCOLOR,0,0);
SendDlgItemMessage(hDlg,IDC_PROGRESSRIGHT,PBM_SETBKCOLOR,0,0);
for (Index=0;Index<NumberOfSoundCards;Index++)
Expand Down
2 changes: 2 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ typedef struct {
unsigned char FrameSkip;
unsigned char SpeedThrottle;
unsigned char CpuType;
unsigned char HaltOpcEnabled; // 0x15 halt enabled
unsigned char BreakOpcEnabled; // 0x113E halt enabled
// unsigned char AudioMute;
unsigned char MonitorType;
unsigned char PaletteType;
Expand Down
24 changes: 22 additions & 2 deletions hd6309.c
Original file line number Diff line number Diff line change
Expand Up @@ -6205,6 +6205,26 @@ void Stu_E(void)
CycleCounter+=NatEmuCycles65;
}

void Halt_15(void)
{ //15
if (EmuState.Debugger.Halt_Enabled(0x15)) {
PC_REG += EmuState.Debugger.DoHalt(0x15,PC_REG);
} else {
PC_REG+=1;
CycleCounter+=NatEmuCycles21;
}
}

void Halt_113E(void)
{ //113E
if (EmuState.Debugger.Halt_Enabled(0x113E)) {
PC_REG += EmuState.Debugger.DoHalt(0x113E,PC_REG);
} else {
PC_REG+=2;
CycleCounter+=NatEmuCycles21;
}
}

void(*JmpVec1[256])(void) = {
Neg_D, // 00
Oim_D, // 01
Expand All @@ -6227,7 +6247,7 @@ void(*JmpVec1[256])(void) = {
Nop_I, // 12
Sync_I, // 13
Sexw_I, // 14
InvalidInsHandler, // 15
Halt_15, // 15
Lbra_R, // 16
Lbsr_R, // 17
InvalidInsHandler, // 18
Expand Down Expand Up @@ -6786,7 +6806,7 @@ void(*JmpVec3[256])(void) = {
Tfm4, // 3B
Bitmd_M, // 3C
Ldmd_M, // 3D
InvalidInsHandler, // 3E
Halt_113E, // 3E
Swi3_I, // 3F
InvalidInsHandler, // 40
InvalidInsHandler, // 41
Expand Down
2 changes: 2 additions & 0 deletions hd6309defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ This file is part of VCC (Virtual Color Computer).
#define NOP_I 0x12
#define SYNC_I 0x13
#define SEXW_I 0x14 //6309
#define HALT 0x15 //Vcc Halt_0x15
#define LBRA_R 0x16
#define LBSR_R 0x17
#define DAA_I 0x19
Expand Down Expand Up @@ -438,6 +439,7 @@ This file is part of VCC (Virtual Color Computer).
#define TFM4 0x3B //6309
#define BITMD_M 0x3C //6309
#define LDMD_M 0x3D //6309
#define BREAK 0x3E //VCC Halt_0x113e
#define SWI3_I 0x3F
#define COME_I 0x43 //6309
#define DECE_I 0x4A //6309
Expand Down
20 changes: 20 additions & 0 deletions mc6809.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,16 @@ case Page3:

switch (MemRead8(pc.Reg++))
{
case BREAK: //113E
if (EmuState.Debugger.Halt_Enabled(0x15)) {
if (EmuState.Debugger.DoHalt(0x15,PC_REG) == 0) {
pc.Reg = pc.Reg - 2;
}
} else {
CycleCounter+=4;
}
break;

case SWI3_I: //113F
cc[E]=1;
MemWrite8( pc.B.lsb,--s.Reg);
Expand Down Expand Up @@ -865,6 +875,16 @@ case SYNC_I: //13
SyncWaiting=1;
break;

case HALT: //15
if (EmuState.Debugger.Halt_Enabled(0x15)) {
if (EmuState.Debugger.DoHalt(0x15,PC_REG) == 0) {
pc.Reg = pc.Reg - 1;
}
} else {
CycleCounter+=4;
}
break;

case LBRA_R: //16
*spostword=MemRead16(pc.Reg);
pc.Reg+=2;
Expand Down
2 changes: 2 additions & 0 deletions mc6809defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ This file is part of VCC (Virtual Color Computer).
#define Page3 0x11
#define NOP_I 0x12
#define SYNC_I 0x13
#define HALT 0x15 // Vcc Halt_15
#define LBRA_R 0x16
#define LBSR_R 0x17
#define DAA_I 0x19
Expand Down Expand Up @@ -320,6 +321,7 @@ This file is part of VCC (Virtual Color Computer).
#define STS_E 0xFF

//*******************Page 3 Codes*********************************
#define BREAK 0x3E // Vcc Halt_113E
#define SWI3_I 0x3F
#define CMPU_M 0x83
#define CMPS_M 0x8C
Expand Down
4 changes: 3 additions & 1 deletion resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@
#define IDC_EDIT_BLOCK 2138
#define IDC_ADRTXT 2139
#define IDC_BTN_OS9 2140
#define IDC_ENABLE_HALT 2141
#define IDC_ENABLE_BREAK 2142

#define IDM_USER_WIKI 40001
#define ID_FILE_EXIT 40002
Expand Down Expand Up @@ -432,7 +434,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 176
#define _APS_NEXT_COMMAND_VALUE 40047
#define _APS_NEXT_CONTROL_VALUE 2142
#define _APS_NEXT_CONTROL_VALUE 2145
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

0 comments on commit a9239d0

Please sign in to comment.