1 /*	Copyright 2012 Theo Berkau <cwx@cyberwarriorx.com>
2 
3 	This file is part of Yabause.
4 
5 	Yabause is free software; you can redistribute it and/or modify
6 	it under the terms of the GNU General Public License as published by
7 	the Free Software Foundation; either version 2 of the License, or
8 	(at your option) any later version.
9 
10 	Yabause is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU General Public License for more details.
14 
15 	You should have received a copy of the GNU General Public License
16 	along with Yabause; if not, write to the Free Software
17 	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
18 */
19 
20 #include "UIDebugM68K.h"
21 #include "../CommonDialogs.h"
22 #include "UIYabause.h"
23 
M68KDis(void * context,u32 addr,char * string)24 int M68KDis(void *context, u32 addr, char *string)
25 {
26    return (int)(M68KDisasm(addr, string) - addr);
27 }
28 
M68KBreakpointHandler(u32 addr)29 void M68KBreakpointHandler (u32 addr)
30 {
31    UIYabause* ui = QtYabause::mainWindow( false );
32 
33    emit ui->breakpointHandlerM68K();
34 }
35 
UIDebugM68K(YabauseThread * mYabauseThread,QWidget * p)36 UIDebugM68K::UIDebugM68K( YabauseThread *mYabauseThread, QWidget* p )
37    : UIDebugCPU(PROC_M68K, mYabauseThread, p )
38 {
39    this->setWindowTitle(QtYabause::translate("Debug M68K"));
40    gbRegisters->setTitle(QtYabause::translate("M68K Registers"));
41 	gbMemoryBreakpoints->setVisible( false );
42 
43    updateRegList();
44    if (SoundRam)
45    {
46       m68kregs_struct m68kregs;
47       const m68kcodebreakpoint_struct *cbp;
48       int i;
49 
50       cbp = M68KGetBreakpointList();
51 
52       for (i = 0; i < MAX_BREAKPOINTS; i++)
53       {
54          QString text;
55          if (cbp[i].addr != 0xFFFFFFFF)
56          {
57             text.sprintf("%08X", (int)cbp[i].addr);
58             lwCodeBreakpoints->addItem(text);
59          }
60       }
61 
62       lwDisassembledCode->setDisassembleFunction(M68KDis);
63       lwDisassembledCode->setEndAddress(0x100000);
64       lwDisassembledCode->setMinimumInstructionSize(2);
65       M68KGetRegisters(&m68kregs);
66       updateCodeList(m68kregs.PC);
67 
68       M68KSetBreakpointCallBack(M68KBreakpointHandler);
69    }
70 }
71 
updateRegList()72 void UIDebugM68K::updateRegList()
73 {
74    int i;
75    m68kregs_struct regs;
76    QString str;
77 
78    if (SoundRam == NULL)
79       return;
80 
81    memset(&regs, 0, sizeof(regs));
82    M68KGetRegisters(&regs);
83    lwRegisters->clear();
84 
85    // Data registers
86    for (i = 0; i < 8; i++)
87    {
88       str.sprintf("D%d =   %08X", i, (int)regs.D[i]);
89       lwRegisters->addItem(str);
90    }
91 
92    // Address registers
93    for (i = 0; i < 8; i++)
94    {
95       str.sprintf("A%d =   %08X", i, (int)regs.A[i]);
96       lwRegisters->addItem(str);
97    }
98 
99    // SR
100    str.sprintf("SR =   %08X", (int)regs.SR);
101    lwRegisters->addItem(str);
102 
103    // PC
104    str.sprintf("PC =   %08X", (int)regs.PC);
105    lwRegisters->addItem(str);
106 }
107 
updateCodeList(u32 addr)108 void UIDebugM68K::updateCodeList(u32 addr)
109 {
110    lwDisassembledCode->goToAddress(addr);
111    lwDisassembledCode->setPC(addr);
112 }
113 
getRegister(int index,int * size)114 u32 UIDebugM68K::getRegister(int index, int *size)
115 {
116    m68kregs_struct m68kregs;
117    u32 value;
118 
119    M68KGetRegisters(&m68kregs);
120 
121    switch (index)
122    {
123       case 0:
124       case 1:
125       case 2:
126       case 3:
127       case 4:
128       case 5:
129       case 6:
130       case 7:
131          value = m68kregs.D[index];
132          break;
133       case 8:
134       case 9:
135       case 10:
136       case 11:
137       case 12:
138       case 13:
139       case 14:
140       case 15:
141          value = m68kregs.A[index - 8];
142          break;
143       case 16:
144          value = m68kregs.SR;
145          break;
146       case 17:
147          value = m68kregs.PC;
148          break;
149       default:
150 			value = 0;
151 			break;
152    }
153 
154    *size = 4;
155    return value;
156 }
157 
setRegister(int index,u32 value)158 void UIDebugM68K::setRegister(int index, u32 value)
159 {
160    m68kregs_struct m68kregs;
161 
162 	memset(&m68kregs, 0, sizeof(m68kregs));
163 	M68KGetRegisters(&m68kregs);
164 
165    switch (index)
166    {
167       case 0:
168       case 1:
169       case 2:
170       case 3:
171       case 4:
172       case 5:
173       case 6:
174       case 7:
175          m68kregs.D[index] = value;
176          break;
177       case 8:
178       case 9:
179       case 10:
180       case 11:
181       case 12:
182       case 13:
183       case 14:
184       case 15:
185          m68kregs.A[index - 8] = value;
186          break;
187       case 16:
188          m68kregs.SR = value;
189          break;
190       case 17:
191          m68kregs.PC = value;
192          updateCodeList(m68kregs.PC);
193          break;
194       default: break;
195    }
196 
197    M68KSetRegisters(&m68kregs);
198 }
199 
addCodeBreakpoint(u32 addr)200 bool UIDebugM68K::addCodeBreakpoint(u32 addr)
201 {
202 	if (!SoundRam)
203 		return false;
204    return M68KAddCodeBreakpoint(addr) == 0;
205 }
206 
delCodeBreakpoint(u32 addr)207 bool UIDebugM68K::delCodeBreakpoint(u32 addr)
208 {
209     return M68KDelCodeBreakpoint(addr) == 0;
210 }
211 
stepInto()212 void UIDebugM68K::stepInto()
213 {
214    if (M68K)
215       M68KStep();
216 }
217