Refactor the build directory structure and rewrite the makefile to bring it more in-line with modern standards.
ghedger
4 years ago
0 | # Installation | |
1 | # Build modernization by Greg Hedger, November 2017 | |
2 | # Ubuntu 16.04 | |
3 | ||
4 | make | |
5 | cd bin | |
6 | ./linapple | |
7 | ||
8 | # Prerequisites | |
9 | sudo apt-get install libzip-dev libzip4 libcurl3 libcurl-ocaml-dev | |
10 | ||
11 | ||
12 | # Historical INSTALL | |
13 | Linapple - crossplatfom emulator of Apple][ (Apple2, Apple 2) series computer for Linux or other OSes with SDL support. | |
14 | ||
15 | ||
16 | [INSTALL] | |
17 | ||
18 | You need SDL, cURL, zlib and libzip: | |
19 | ||
20 | For Debian/Ubuntu their names are: | |
21 | ||
22 | libsdl1.2-dev - Simple Direct Media crossplatform library for video,audio, events etc. | |
23 | libcurl4 - openssl-dev - cURL net functions | |
24 | zlib1g-dev - access .gz files | |
25 | libzip-dev - access .zip files | |
26 | ||
27 | All these libraries are available for free around the world. | |
28 | ||
29 | For example for Debian/Ubuntu to install: | |
30 | ||
31 | $sudo apt-get install libsdl1.2-dev libcurl4-openssl-dev zlib1g-dev libzip-dev | |
32 | ||
33 | ||
34 | After being SDL, zlib, cURL and libzip installed you will be able to compile linapple from sources: | |
35 | ||
36 | Untar the package (in .bz2 format): | |
37 | ||
38 | $ tar xjf linapple-src_2a.tar.bz2 | |
39 | ||
40 | ||
41 | Then go to src directory and compile. | |
42 | ||
43 | $ make | |
44 | ||
45 | If there was no errors, you may install it if you wish: | |
46 | ||
47 | $ cd bin | |
48 | $ ./linapple | |
49 | ||
50 | It will be install in /usr/local/linapple folder, whre you can find linapple.conf file for changing some linapple settings, | |
51 | and empty `images` and `ftp` folders, where Apple 2 images files and downloaded through FTP images are meant to be in. | |
52 | ||
53 | But of course you are free to choose any directories of your choice. | |
54 | Note: you should read/write permissions of these folders, or linapple could not work properly. | |
55 | ||
56 | For linaaple ability to unpack .zip and .gz files on the fly (either from local disks or from FTP) you also need read/write access for linapple working | |
57 | folder (which by default is /usr/local/linapple), for linapple unpacks these files as drive0.dsk and drive1.dsk for drive 1 and 2 respectively. | |
58 | ||
59 | ||
60 | OK. | |
61 | If you installed it, you are able to run emulator from any place, just run it like this: | |
62 | ||
63 | $ linapple | |
64 | ||
65 | ||
66 | If you have chosen not to install it, go to the upper directory then and run the beast: | |
67 | ||
68 | $ cd .. | |
69 | ||
70 | $ ./linapple | |
71 | ||
72 | ||
73 | If all files are on their places, you should see an X-Window with splash screen. | |
74 | Press F2 (or F3 before to choose some disk image in drive 1), and go to work. | |
75 | ||
76 | Note: linapple needs some files in its current working directory for proper working. | |
77 | ||
78 | These files are: | |
79 | ||
80 | splash.bmp - splash screen | |
81 | charset40.bmp - charset for Apple][ (Apple 2e, etc.) text modes. | |
82 | font.bmp - font for Help screen and Disk Select screens. | |
83 | icon.bmp - nice icon, logo of Apple][ computer. | |
84 | linapple.conf - configuration file. | |
85 | Master.dsk - disk image with Applesoft(tm) DOS 3.3 inside. See Apple license (on apple.com) for details. | |
86 | ||
87 | Essentials are font.bmp and charset40.bmp, others can be omitted peacefully. | |
88 | ||
89 | P.S. You may play with some options in Makefile in src directory, if you know what you are to do. :) | |
90 | ||
91 | Note: See README file for more detailed instructions on using linapple. | |
92 | ||
93 | ||
94 | [UNINSTALL] | |
95 | ||
96 | To uninstall previously installed linapple (by `sudo make install` command) you may write this: | |
97 | ||
98 | $ sudo make uninstall | |
99 | ||
100 | This will remove by default entire `/usr/local/linapple` folder and `/usr/local/bin/linapple` script. | |
101 | ||
102 | ||
103 | Also there is possible command for cleaning compiled binaries in src directory: | |
104 | ||
105 | $ make clean | |
106 | ||
107 | Note: `linapple` executable in upper directory will remain intact. | |
108 | ||
109 | ||
110 | ||
111 | [CONTACT] | |
112 | ||
113 | I will be glad to see your comments, suggestions and so on on my email: beotiger@gmail.com | |
114 | ||
115 | Sincerely Yours, | |
116 | Krez beom beotiger, December 2007 AD - March 2012 AD | |
117 | ||
118 | beotiger@mail.ru | |
119 | beotiger@gmail.com | |
120 | ||
121 | Let Apple 2 live forever! | |
122 |
0 | #Compiler and Linker | |
1 | CC := g++ | |
2 | ||
3 | #The Target Binary Program | |
4 | TARGET := linapple | |
5 | ||
6 | #The Directories, Source, Includes, Objects, Binary and Resources | |
7 | SRCDIR := src | |
8 | INCDIR := inc | |
9 | BUILDDIR := obj | |
10 | TARGETDIR := bin | |
11 | RESDIR := res | |
12 | SRCEXT := cpp | |
13 | DEPEXT := d | |
14 | OBJEXT := o | |
15 | ||
16 | #Flags, Libraries and Includes | |
17 | ||
18 | SDL_CONFIG ?= sdl-config | |
19 | SDL_CFLAGS = $(shell $(SDL_CONFIG) --cflags) | |
20 | SDL_LIBS = $(shell $(SDL_CONFIG) --libs) | |
21 | ||
22 | CURL_CONFIG ?= curl-config | |
23 | CURL_CFLAGS = $(shell $(CURL_CONFIG) --cflags) | |
24 | CURL_LIBS = $(shell $(CURL_CONFIG) --libs) | |
25 | ||
26 | CFLAGS := -Wall -O3 -c | |
27 | CFLAGS += $(SDL_CFLAGS) | |
28 | CFLAGS += $(CURL_CFLAGS) | |
29 | ||
30 | LIB := $(SDL_LIBS) $(CURL_LIBS) -lz -lzip | |
31 | INC := -I$(INCDIR) -I/usr/local/include | |
32 | INCDEP := -I$(INCDIR) | |
33 | ||
34 | #--------------------------------------------------------------------------------- | |
35 | #DO NOT EDIT BELOW THIS LINE | |
36 | #--------------------------------------------------------------------------------- | |
37 | SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT)) | |
38 | OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT))) | |
39 | ||
40 | #Defauilt Make | |
41 | all: resources $(TARGET) | |
42 | ||
43 | #Remake | |
44 | remake: cleaner all | |
45 | ||
46 | #Copy Resources from Resources Directory to Target Directory | |
47 | resources: directories | |
48 | @cp $(RESDIR)/* $(TARGETDIR)/ | |
49 | ||
50 | #Make the Directories | |
51 | directories: | |
52 | @mkdir -p $(TARGETDIR) | |
53 | @mkdir -p $(BUILDDIR) | |
54 | ||
55 | #Clean only Objecst | |
56 | clean: | |
57 | @$(RM) -rf $(BUILDDIR) | |
58 | @$(RM) -rf $(TARGETDIR) | |
59 | ||
60 | #Full Clean, Objects and Binaries | |
61 | cleaner: clean | |
62 | @$(RM) -rf $(TARGETDIR) | |
63 | ||
64 | #Pull in dependency info for *existing* .o files | |
65 | -include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT)) | |
66 | ||
67 | #Link | |
68 | ||
69 | $(TARGET): $(OBJECTS) | |
70 | $(CC) -o $(TARGETDIR)/$(TARGET) $^ $(LIB) | |
71 | ||
72 | #Compile | |
73 | $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) | |
74 | @mkdir -p $(dir $@) | |
75 | $(CC) $(CFLAGS) $(INC) -c -o $@ $< | |
76 | @$(CC) $(CFLAGS) $(INCDEP) -MM $(SRCDIR)/$*.$(SRCEXT) > $(BUILDDIR)/$*.$(DEPEXT) | |
77 | @cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp | |
78 | @sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT) | |
79 | @sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT) | |
80 | @rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp | |
81 | ||
82 | #Non-File Targets | |
83 | .PHONY: all remake clean cleaner resources | |
84 |
21 | 21 | |
22 | 22 | [INSTALL] |
23 | 23 | |
24 | make | |
25 | cd bin | |
26 | ./linapple | |
27 | ||
28 | ||
24 | 29 | I will show brief instructions for compiling and installing linapple here. |
25 | 30 | |
26 | 31 | Please, see INSTALL file for comprehensive installing tips. |
27 | 32 | |
28 | 33 | After SDL1.2, zlib, libcurl and libzip are installed in your system, you can build sources. |
29 | 34 | |
30 | Unpack downloaded linapple archive and go to src directory: | |
31 | ||
32 | $ cd src | |
33 | ||
34 | Then run: | |
35 | ||
36 | $ make | |
37 | ||
38 | or | |
39 | ||
40 | $ sudo make install | |
41 | ||
42 | If there is no errors, run: | |
43 | ||
44 | $ linapple | |
45 | ||
46 | or without being installed: | |
47 | ||
48 | $ cd .. | |
49 | $ ./linapple | |
50 | ||
51 | If all files are on their places, you should see an X-Window with splash screen. | |
35 | If all files are on their places, you should see an X-Window with splash screen. | |
52 | 36 | |
53 | 37 | Press F2 (or F3 or Alt+F3) before to choose some disk image in drive 1), and go to work. |
54 | ||
55 | It works as well as AppleWin, although it needs testing and supporting. | |
56 | Where to install? Anywhere you feel fit, just let linapple be with some files it needs for comprehenceive working. | |
57 | ||
58 | These files are: | |
59 | 38 | |
60 | 39 | splash.bmp - splash screen |
61 | 40 | charset40.bmp - charset for Apple][ (Apple 2e, etc.) text modes. |
0 | /* | |
1 | AppleWin : An Apple //e emulator for Windows | |
2 | ||
3 | Copyright (C) 1994-1996, Michael O'Brien | |
4 | Copyright (C) 1999-2001, Oliver Schmidt | |
5 | Copyright (C) 2002-2005, Tom Charlesworth | |
6 | Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski | |
7 | ||
8 | AppleWin is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | AppleWin is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with AppleWin; if not, write to the Free Software | |
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | */ | |
22 | ||
23 | /* Description: main | |
24 | * | |
25 | * Author: Various | |
26 | */ | |
27 | ||
28 | /* Adaptation for SDL and POSIX (l) by beom beotiger, Nov-Dec 2007, krez beotiger March 2012 AD */ | |
29 | ||
30 | #include "stdafx.h" | |
31 | //#pragma hdrstop | |
32 | #include "MouseInterface.h" | |
33 | ||
34 | // for time logging | |
35 | #include <time.h> | |
36 | #include <sys/time.h> | |
37 | ||
38 | #include <curl/curl.h> | |
39 | ||
40 | #include <stdlib.h> | |
41 | ||
42 | #include <iostream> | |
43 | #include <sys/types.h> | |
44 | #include <sys/stat.h> | |
45 | #include <fcntl.h> | |
46 | ||
47 | //char VERSIONSTRING[] = "xx.yy.zz.ww"; | |
48 | ||
49 | TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED; | |
50 | ||
51 | eApple2Type g_Apple2Type = A2TYPE_APPLE2EEHANCED; | |
52 | ||
53 | BOOL behind = 0; // Redundant | |
54 | DWORD cumulativecycles = 0; // Wraps after ~1hr 9mins | |
55 | DWORD cyclenum = 0; // Used by SpkrToggle() for non-wave sound | |
56 | DWORD emulmsec = 0; | |
57 | static DWORD emulmsec_frac = 0; | |
58 | bool g_bFullSpeed = false; | |
59 | bool hddenabled = false; | |
60 | static bool g_uMouseInSlot4 = false; // not any mouse in slot4??--bb | |
61 | // Win32 | |
62 | //HINSTANCE g_hInstance = (HINSTANCE)0; | |
63 | ||
64 | AppMode_e g_nAppMode = MODE_LOGO; | |
65 | ||
66 | // Default screen sizes | |
67 | // SCREEN_WIDTH & SCREEN_HEIGHT defined in Frame.h | |
68 | UINT g_ScreenWidth = SCREEN_WIDTH; | |
69 | UINT g_ScreenHeight = SCREEN_HEIGHT; | |
70 | ||
71 | //static int lastmode = MODE_LOGO; -- not used??? | |
72 | DWORD needsprecision = 0; // Redundant | |
73 | //TCHAR g_sProgramDir[MAX_PATH] = TEXT(""); | |
74 | TCHAR g_sCurrentDir[MAX_PATH] = TEXT(""); // Also Starting Dir for Slot6 disk images?? --bb | |
75 | TCHAR g_sHDDDir[MAX_PATH] = TEXT(""); // starting dir for HDV (Apple][ HDD) images?? --bb | |
76 | TCHAR g_sSaveStateDir[MAX_PATH] = TEXT(""); // starting dir for states --bb | |
77 | TCHAR g_sParallelPrinterFile[MAX_PATH] = TEXT("Printer.txt"); // default file name for Parallel printer | |
78 | ||
79 | // FTP Variables | |
80 | TCHAR g_sFTPLocalDir[MAX_PATH] = TEXT(""); // FTP Local Dir, see linapple.conf for details | |
81 | TCHAR g_sFTPServer[MAX_PATH] = TEXT(""); // full path to default FTP server | |
82 | TCHAR g_sFTPServerHDD[MAX_PATH] = TEXT(""); // full path to default FTP server | |
83 | ||
84 | //TCHAR g_sFTPUser[256] = TEXT("anonymous"); // user name | |
85 | //TCHAR g_sFTPPass[256] = TEXT("mymail@hotmail.com"); // password | |
86 | TCHAR g_sFTPUserPass[512] = TEXT("anonymous:mymail@hotmail.com"); // full login line | |
87 | ||
88 | bool g_bResetTiming = false; // Redundant | |
89 | BOOL restart = 0; | |
90 | ||
91 | // several parameters affecting the speed of emulated CPU | |
92 | DWORD g_dwSpeed = SPEED_NORMAL; // Affected by Config dialog's speed slider bar | |
93 | double g_fCurrentCLK6502 = CLK_6502; // Affected by Config dialog's speed slider bar | |
94 | static double g_fMHz = 1.0; // Affected by Config dialog's speed slider bar | |
95 | ||
96 | int g_nCpuCyclesFeedback = 0; | |
97 | DWORD g_dwCyclesThisFrame = 0; | |
98 | ||
99 | FILE* g_fh = NULL; // file for logging, let's use stderr instead? | |
100 | bool g_bDisableDirectSound = false; // direct sound, use SDL Sound, or SDL_mixer??? | |
101 | ||
102 | CSuperSerialCard sg_SSC; | |
103 | CMouseInterface sg_Mouse; | |
104 | ||
105 | UINT g_Slot4 = CT_Mockingboard; // CT_Mockingboard or CT_MouseInterface | |
106 | ||
107 | CURL *g_curl = NULL; // global easy curl resourse | |
108 | //=========================================================================== | |
109 | ||
110 | // ???? what is DBG_CALC_FREQ??? O_O --bb | |
111 | #define DBG_CALC_FREQ 0 | |
112 | #if DBG_CALC_FREQ | |
113 | const UINT MAX_CNT = 256; | |
114 | double g_fDbg[MAX_CNT]; | |
115 | UINT g_nIdx = 0; | |
116 | double g_fMeanPeriod,g_fMeanFreq; | |
117 | ULONG g_nPerfFreq = 0; | |
118 | #endif | |
119 | ||
120 | ||
121 | ||
122 | //--------------------------------------------------------------------------- | |
123 | ||
124 | void ContinueExecution() | |
125 | { | |
126 | static BOOL pageflipping = 0; //? | |
127 | ||
128 | const double fUsecPerSec = 1.e6; | |
129 | ||
130 | const UINT nExecutionPeriodUsec = 1000; // 1.0ms | |
131 | const double fExecutionPeriodClks = g_fCurrentCLK6502 * ((double)nExecutionPeriodUsec / fUsecPerSec); | |
132 | ||
133 | bool bScrollLock_FullSpeed = g_bScrollLock_FullSpeed; //g_uScrollLockToggle; | |
134 | ||
135 | g_bFullSpeed = ( (g_dwSpeed == SPEED_MAX) || | |
136 | bScrollLock_FullSpeed || | |
137 | (DiskIsSpinning() && enhancedisk && !Spkr_IsActive() && !MB_IsActive()) ); | |
138 | ||
139 | if(g_bFullSpeed) | |
140 | { | |
141 | // Don't call Spkr_Mute() - will get speaker clicks | |
142 | MB_Mute(); | |
143 | SysClk_StopTimer(); | |
144 | g_nCpuCyclesFeedback = 0; // For the case when this is a big -ve number | |
145 | // SetPriorityNormal(); | |
146 | } | |
147 | else | |
148 | { | |
149 | // Don't call Spkr_Demute() | |
150 | MB_Demute(); | |
151 | SysClk_StartTimerUsec(nExecutionPeriodUsec); | |
152 | // Switch to higher priority, eg. for audio (BUG #015394) | |
153 | // SetPriorityAboveNormal(); | |
154 | } | |
155 | ||
156 | // | |
157 | ||
158 | int nCyclesToExecute = (int) fExecutionPeriodClks + g_nCpuCyclesFeedback; | |
159 | if(nCyclesToExecute < 0) | |
160 | nCyclesToExecute = 0; | |
161 | ||
162 | DWORD dwExecutedCycles = CpuExecute(nCyclesToExecute); | |
163 | g_dwCyclesThisFrame += dwExecutedCycles; | |
164 | ||
165 | // | |
166 | ||
167 | cyclenum = dwExecutedCycles; | |
168 | ||
169 | DiskUpdatePosition(dwExecutedCycles); | |
170 | JoyUpdatePosition(); | |
171 | // the next call does not present in current Applewin as on March 2012?? | |
172 | VideoUpdateVbl(g_dwCyclesThisFrame); | |
173 | ||
174 | SpkrUpdate(cyclenum); | |
175 | sg_SSC.CommUpdate(cyclenum); | |
176 | PrintUpdate(cyclenum); | |
177 | ||
178 | // | |
179 | ||
180 | const DWORD CLKS_PER_MS = (DWORD)g_fCurrentCLK6502 / 1000; | |
181 | ||
182 | emulmsec_frac += dwExecutedCycles; | |
183 | if(emulmsec_frac > CLKS_PER_MS) | |
184 | { | |
185 | emulmsec += emulmsec_frac / CLKS_PER_MS; | |
186 | emulmsec_frac %= CLKS_PER_MS; | |
187 | } | |
188 | ||
189 | // | |
190 | // DETERMINE WHETHER THE SCREEN WAS UPDATED, THE DISK WAS SPINNING, | |
191 | // OR THE KEYBOARD I/O PORTS WERE BEING EXCESSIVELY QUERIED THIS CLOCKTICK | |
192 | VideoCheckPage(0); | |
193 | BOOL screenupdated = VideoHasRefreshed(); | |
194 | BOOL systemidle = 0; //(KeybGetNumQueries() > (clockgran << 2)); // && (!ranfinegrain); // TO DO | |
195 | ||
196 | if(screenupdated) | |
197 | pageflipping = 3; | |
198 | ||
199 | // | |
200 | ||
201 | if(g_dwCyclesThisFrame >= dwClksPerFrame) | |
202 | { | |
203 | g_dwCyclesThisFrame -= dwClksPerFrame; | |
204 | ||
205 | if(g_nAppMode != MODE_LOGO) | |
206 | { | |
207 | VideoUpdateFlash(); | |
208 | ||
209 | static BOOL anyupdates = 0; | |
210 | static DWORD lastcycles = 0; | |
211 | static BOOL lastupdates[2] = {0,0}; | |
212 | ||
213 | anyupdates |= screenupdated; | |
214 | ||
215 | // | |
216 | ||
217 | lastcycles = cumulativecycles; | |
218 | if ((!anyupdates) && (!lastupdates[0]) && (!lastupdates[1]) && VideoApparentlyDirty()) | |
219 | { | |
220 | VideoCheckPage(1); | |
221 | static DWORD lasttime = 0; | |
222 | DWORD currtime = GetTickCount(); | |
223 | if ((!g_bFullSpeed) || | |
224 | (currtime-lasttime >= (DWORD)((graphicsmode || !systemidle) ? 100 : 25))) | |
225 | { | |
226 | VideoRefreshScreen(); | |
227 | lasttime = currtime; | |
228 | } | |
229 | screenupdated = 1; | |
230 | } | |
231 | ||
232 | lastupdates[1] = lastupdates[0]; | |
233 | lastupdates[0] = anyupdates; | |
234 | anyupdates = 0; | |
235 | ||
236 | if (pageflipping) | |
237 | pageflipping--; | |
238 | } | |
239 | ||
240 | MB_EndOfVideoFrame(); | |
241 | } | |
242 | ||
243 | // | |
244 | ||
245 | if(!g_bFullSpeed) | |
246 | { | |
247 | SysClk_WaitTimer(); | |
248 | ||
249 | #if DBG_CALC_FREQ | |
250 | if(g_nPerfFreq) | |
251 | { | |
252 | //QueryPerformanceCounter((LARGE_INTEGER*)&nTime1); QueryPerformanceFrequency | |
253 | LONG nTime1 = GetTickCount();//no QueryPerformanceCounter and alike | |
254 | LONG nTimeDiff = nTime1 - nTime0; | |
255 | double fTime = (double)nTimeDiff / (double)(LONG)g_nPerfFreq; | |
256 | ||
257 | g_fDbg[g_nIdx] = fTime; | |
258 | g_nIdx = (g_nIdx+1) & (MAX_CNT-1); | |
259 | g_fMeanPeriod = 0.0; | |
260 | for(UINT n=0; n<MAX_CNT; n++) | |
261 | g_fMeanPeriod += g_fDbg[n]; | |
262 | g_fMeanPeriod /= (double)MAX_CNT; | |
263 | g_fMeanFreq = 1.0 / g_fMeanPeriod; | |
264 | } | |
265 | #endif | |
266 | } | |
267 | } | |
268 | ||
269 | //=========================================================================== | |
270 | ||
271 | void SetCurrentCLK6502() | |
272 | { | |
273 | static DWORD dwPrevSpeed = (DWORD) -1; | |
274 | ||
275 | if(dwPrevSpeed == g_dwSpeed) | |
276 | return; | |
277 | ||
278 | dwPrevSpeed = g_dwSpeed; | |
279 | ||
280 | // SPEED_MIN = 0 = 0.50 MHz | |
281 | // SPEED_NORMAL = 10 = 1.00 MHz | |
282 | // 20 = 2.00 MHz | |
283 | // SPEED_MAX-1 = 39 = 3.90 MHz | |
284 | // SPEED_MAX = 40 = ???? MHz (run full-speed, /g_fCurrentCLK6502/ is ignored) | |
285 | ||
286 | ||
287 | if(g_dwSpeed < SPEED_NORMAL) | |
288 | g_fMHz = 0.5 + (double)g_dwSpeed * 0.05; | |
289 | else | |
290 | g_fMHz = (double)g_dwSpeed / 10.0; | |
291 | ||
292 | g_fCurrentCLK6502 = CLK_6502 * g_fMHz; | |
293 | ||
294 | // | |
295 | // Now re-init modules that are dependent on /g_fCurrentCLK6502/ | |
296 | // | |
297 | ||
298 | SpkrReinitialize(); | |
299 | MB_Reinitialize(); | |
300 | } | |
301 | ||
302 | //=========================================================================== | |
303 | void EnterMessageLoop () | |
304 | { | |
305 | // MSG message; | |
306 | SDL_Event event; | |
307 | ||
308 | // PeekMessage(&message, NULL, 0, 0, PM_NOREMOVE); | |
309 | while(true) | |
310 | ||
311 | // while (message.message!=WM_QUIT) | |
312 | { | |
313 | if(SDL_PollEvent(&event)) | |
314 | { | |
315 | if(event.type == SDL_QUIT && event.key.keysym.sym != SDLK_F4) return; | |
316 | FrameDispatchMessage(&event); | |
317 | ||
318 | ||
319 | ||
320 | // if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) | |
321 | // { | |
322 | // TranslateMessage(&message); | |
323 | // DispatchMessage(&message); | |
324 | ||
325 | while ((g_nAppMode == MODE_RUNNING) || (g_nAppMode == MODE_STEPPING)) | |
326 | { | |
327 | if(SDL_PollEvent(&event)) { | |
328 | if(event.type == SDL_QUIT && event.key.keysym.sym != SDLK_F4) return; | |
329 | FrameDispatchMessage(&event); | |
330 | } | |
331 | else if (g_nAppMode == MODE_STEPPING) | |
332 | { | |
333 | DebugContinueStepping(); | |
334 | } | |
335 | else | |
336 | { | |
337 | ContinueExecution(); | |
338 | if (g_nAppMode != MODE_DEBUG) | |
339 | { | |
340 | if (g_bFullSpeed) | |
341 | ContinueExecution(); | |
342 | } | |
343 | } | |
344 | } | |
345 | } | |
346 | else | |
347 | { | |
348 | if (g_nAppMode == MODE_DEBUG) | |
349 | DebuggerUpdate(); | |
350 | else if (g_nAppMode == MODE_LOGO || g_nAppMode == MODE_PAUSED) | |
351 | SDL_Delay(100); // Stop process hogging CPU | |
352 | } | |
353 | } | |
354 | } | |
355 | ||
356 | //=========================================================================== | |
357 | // void GetProgramDirectory () { | |
358 | // GetModuleFileName((HINSTANCE)0,g_sProgramDir,MAX_PATH); | |
359 | // g_sProgramDir[MAX_PATH-1] = 0; | |
360 | // int loop = _tcslen(g_sProgramDir); | |
361 | // while (loop--) | |
362 | // if ((g_sProgramDir[loop] == TEXT('\\')) || | |
363 | // (g_sProgramDir[loop] == TEXT(':'))) { | |
364 | // g_sProgramDir[loop+1] = 0; | |
365 | // break; | |
366 | // } | |
367 | // } | |
368 | ||
369 | ||
370 | //--------------------------------------------------------------------------- | |
371 | ||
372 | int DoDiskInsert(int nDrive, LPSTR szFileName) | |
373 | { | |
374 | // DWORD dwAttributes = GetFileAttributes(szFileName); | |
375 | // | |
376 | // | |
377 | // if(dwAttributes == INVALID_FILE_ATTRIBUTES) | |
378 | // { | |
379 | // return -1; | |
380 | // } | |
381 | // | |
382 | // BOOL bWriteProtected = (dwAttributes & FILE_ATTRIBUTE_READONLY) ? TRUE : FALSE; | |
383 | ||
384 | return DiskInsert(nDrive, szFileName, 0, 0); | |
385 | } | |
386 | ||
387 | bool ValidateDirectory(char *dir) | |
388 | { | |
389 | bool ret = false; | |
390 | if (dir && *dir) { | |
391 | struct stat st; | |
392 | if(stat("/tmp",&st) == 0) | |
393 | if(st.st_mode & S_IFDIR != 0) | |
394 | ret = true; | |
395 | } | |
396 | printf("%s is dir? %d\n", dir, ret); | |
397 | return ret; | |
398 | } | |
399 | ||
400 | void SetDiskImageDirectory( char *regKey, int driveNumber) | |
401 | { | |
402 | char *szHDFilename = NULL; | |
403 | if(RegLoadString(TEXT("Configuration"), TEXT(regKey), 1, &szHDFilename, MAX_PATH)) | |
404 | { | |
405 | if(!ValidateDirectory(szHDFilename)) { | |
406 | RegSaveString(TEXT("Configuration"), TEXT(regKey), 1, "/"); | |
407 | RegLoadString(TEXT("Configuration"), TEXT(regKey), 1, &szHDFilename, MAX_PATH); | |
408 | } | |
409 | ||
410 | DoDiskInsert(driveNumber, szHDFilename); | |
411 | free(szHDFilename); | |
412 | } | |
413 | } | |
414 | ||
415 | //=========================================================================== | |
416 | // Let us load main configuration from config file. Y_Y --bb | |
417 | void LoadConfiguration () | |
418 | { | |
419 | DWORD dwComputerType; | |
420 | ||
421 | /* if (LOAD(TEXT(REGVALUE_APPLE2_TYPE),&dwComputerType)) | |
422 | { | |
423 | if (dwComputerType >= A2TYPE_MAX) | |
424 | dwComputerType = A2TYPE_APPLE2EEHANCED; | |
425 | g_Apple2Type = (eApple2Type) dwComputerType; | |
426 | } | |
427 | else | |
428 | {*/ | |
429 | LOAD(TEXT("Computer Emulation"),&dwComputerType); | |
430 | switch (dwComputerType) | |
431 | { | |
432 | // NB. No A2TYPE_APPLE2E | |
433 | ||
434 | case 0: g_Apple2Type = A2TYPE_APPLE2;break; | |
435 | case 1: g_Apple2Type = A2TYPE_APPLE2PLUS;break; | |
436 | case 2: g_Apple2Type = A2TYPE_APPLE2EEHANCED;break; | |
437 | default: g_Apple2Type = A2TYPE_APPLE2EEHANCED;break; | |
438 | } | |
439 | // } | |
440 | // determine Apple type and set appropriate caption -- should be in (F9)switching modes? | |
441 | switch (g_Apple2Type) | |
442 | { | |
443 | case A2TYPE_APPLE2: g_pAppTitle = TITLE_APPLE_2; break; | |
444 | case A2TYPE_APPLE2PLUS: g_pAppTitle = TITLE_APPLE_2_PLUS; break; | |
445 | case A2TYPE_APPLE2E: g_pAppTitle = TITLE_APPLE_2E; break; | |
446 | case A2TYPE_APPLE2EEHANCED: g_pAppTitle = TITLE_APPLE_2E_ENHANCED; break; | |
447 | } | |
448 | ||
449 | LOAD(TEXT("Joystick 0"),&joytype[0]); | |
450 | LOAD(TEXT("Joystick 1"),&joytype[1]); | |
451 | LOAD(TEXT("Sound Emulation") ,&soundtype); | |
452 | ||
453 | DWORD dwSerialPort; | |
454 | LOAD(TEXT("Serial Port") ,&dwSerialPort); | |
455 | sg_SSC.SetSerialPort(dwSerialPort); // ----------- why it is here???? | |
456 | ||
457 | LOAD(TEXT("Emulation Speed") ,&g_dwSpeed); | |
458 | ||
459 | LOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);// | |
460 | LOAD(TEXT("Video Emulation") ,&g_videotype); | |
461 | // printf("Video Emulation = %d\n", videotype); | |
462 | ||
463 | DWORD dwTmp = 0; // temp var | |
464 | ||
465 | LOAD(TEXT("Fullscreen") ,&dwTmp); // load fullscreen flag | |
466 | fullscreen = (BOOL) dwTmp; | |
467 | dwTmp = 1; | |
468 | LOAD(TEXT(REGVALUE_SHOW_LEDS) ,&dwTmp); // load Show Leds flag | |
469 | g_ShowLeds = (BOOL) dwTmp; | |
470 | ||
471 | //printf("Fullscreen = %d\n", fullscreen); | |
472 | // LOAD(TEXT("Uthernet Active") ,(DWORD *)&tfe_enabled); | |
473 | ||
474 | SetCurrentCLK6502(); // set up real speed | |
475 | ||
476 | // | |
477 | if(LOAD(TEXT(REGVALUE_MOUSE_IN_SLOT4), &dwTmp)) | |
478 | g_uMouseInSlot4 = dwTmp; | |
479 | g_Slot4 = g_uMouseInSlot4 ? CT_MouseInterface : CT_Mockingboard; | |
480 | ||
481 | // if(LOAD(TEXT(REGVALUE_SPKR_VOLUME), &dwTmp)) | |
482 | // SpkrSetVolume(dwTmp, 100); // volume by default? | |
483 | // | |
484 | // if(LOAD(TEXT(REGVALUE_MB_VOLUME), &dwTmp)) | |
485 | // MB_SetVolume(dwTmp, 100); // volume by default?? --bb | |
486 | ||
487 | if(LOAD(TEXT(REGVALUE_SOUNDCARD_TYPE), &dwTmp)) | |
488 | MB_SetSoundcardType((eSOUNDCARDTYPE)dwTmp); | |
489 | ||
490 | if(LOAD(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), &dwTmp)) | |
491 | g_bSaveStateOnExit = dwTmp ? true : false; | |
492 | ||
493 | if(LOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp)) hddenabled = (bool) dwTmp;// after MemInitialize | |
494 | // HD_SetEnabled(dwTmp ? true : false); | |
495 | // printf("g_bHD_Enabled = %d\n", g_bHD_Enabled); | |
496 | ||
497 | char *szHDFilename = NULL; | |
498 | ||
499 | if(RegLoadString(TEXT("Configuration"), TEXT("Monochrome Color"), 1, &szHDFilename, 10)) | |
500 | { | |
501 | if (!sscanf(szHDFilename, "#%X", &monochrome)) monochrome = 0xC0C0C0; | |
502 | free(szHDFilename); | |
503 | szHDFilename = NULL; | |
504 | } | |
505 | ||
506 | dwTmp = 0; | |
507 | LOAD(TEXT("Boot at Startup") ,&dwTmp); // | |
508 | if(dwTmp) { | |
509 | // autostart | |
510 | SDL_Event user_ev; | |
511 | user_ev.type = SDL_USEREVENT; | |
512 | user_ev.user.code = 1; //restart? | |
513 | SDL_PushEvent(&user_ev); | |
514 | } | |
515 | ||
516 | dwTmp = 0; | |
517 | LOAD(TEXT("Slot 6 Autoload") ,&dwTmp); // load autoinsert for Slot 6 flag | |
518 | if(dwTmp) { | |
519 | // Load floppy disk images and insert it automatically in slot 6 drive 1 and 2 | |
520 | SetDiskImageDirectory(REGVALUE_DISK_IMAGE1, 0); | |
521 | SetDiskImageDirectory(REGVALUE_DISK_IMAGE1, 1); | |
522 | } | |
523 | else { | |
524 | #define MASTER_DISK "Master.dsk" | |
525 | DoDiskInsert(0, MASTER_DISK); | |
526 | } | |
527 | ||
528 | // Load hard disk images and insert it automatically in slot 7 | |
529 | if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_HDD_IMAGE1), 1, &szHDFilename, MAX_PATH)) | |
530 | { | |
531 | // printf("LoadConfiguration: returned string is: %s\n", szHDFilename); | |
532 | HD_InsertDisk2(0, szHDFilename); | |
533 | free(szHDFilename); | |
534 | szHDFilename = NULL; | |
535 | } | |
536 | if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_HDD_IMAGE2), 1, &szHDFilename, MAX_PATH)) | |
537 | { | |
538 | // printf("LoadConfiguration: returned string is: %s\n", szHDFilename); | |
539 | HD_InsertDisk2(1, szHDFilename); | |
540 | free(szHDFilename); | |
541 | szHDFilename = NULL; | |
542 | } | |
543 | ||
544 | // file name for Parallel Printer | |
545 | if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_PPRINTER_FILENAME), 1, &szHDFilename, MAX_PATH)) | |
546 | { | |
547 | if(strlen(szHDFilename) > 1) strncpy(g_sParallelPrinterFile, szHDFilename, MAX_PATH); | |
548 | free(szHDFilename); | |
549 | szHDFilename = NULL; | |
550 | } | |
551 | ||
552 | ||
553 | // for joysticks use default Y-,X-trims | |
554 | // if(LOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp)) | |
555 | // JoySetTrim((short)dwTmp, true); | |
556 | // if(LOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp)) | |
557 | // JoySetTrim((short)dwTmp, false); | |
558 | // we do not use this, scroll lock ever toggling full-speed??? | |
559 | // if(LOAD(TEXT(REGVALUE_SCROLLLOCK_TOGGLE), &dwTmp)) | |
560 | // g_uScrollLockToggle = dwTmp; | |
561 | ||
562 | // | |
563 | ||
564 | char *szFilename = NULL; | |
565 | double scrFactor = 0.0; | |
566 | // Define screen sizes | |
567 | if (RegLoadString(TEXT("Configuration"),TEXT("Screen factor"),1, &szFilename,16)) { | |
568 | scrFactor = atof(szFilename); | |
569 | if(scrFactor > 0.1) { | |
570 | g_ScreenWidth = UINT(g_ScreenWidth * scrFactor); | |
571 | g_ScreenHeight = UINT(g_ScreenHeight * scrFactor); | |
572 | } | |
573 | free(szFilename); | |
574 | szFilename = NULL; | |
575 | } | |
576 | else { // Try to set Screen Width & Height directly | |
577 | dwTmp = 0; | |
578 | LOAD(TEXT("Screen Width") ,&dwTmp); | |
579 | if(dwTmp > 0) g_ScreenWidth = dwTmp; | |
580 | dwTmp = 0; | |
581 | LOAD(TEXT("Screen Height") ,&dwTmp); | |
582 | if(dwTmp > 0) g_ScreenHeight = dwTmp; | |
583 | } | |
584 | ||
585 | if (RegLoadString(TEXT("Configuration"),TEXT(REGVALUE_SAVESTATE_FILENAME),1, &szFilename,MAX_PATH)) { | |
586 | Snapshot_SetFilename(szFilename); // If not in Registry than default will be used | |
587 | free(szFilename); | |
588 | szFilename = NULL; | |
589 | } | |
590 | ||
591 | // Current/Starting Dir is the "root" of where the user keeps his disk images | |
592 | RegLoadString(TEXT("Preferences"), REGVALUE_PREF_START_DIR, 1, &szFilename, MAX_PATH); | |
593 | if (szFilename) { | |
594 | strcpy(g_sCurrentDir, szFilename); | |
595 | free(szFilename); | |
596 | szFilename = NULL; | |
597 | } | |
598 | // SetCurrentDirectory(g_sCurrentDir); | |
599 | if(strlen(g_sCurrentDir) == 0 || g_sCurrentDir[0] != '/') //something is wrong in dir name? | |
600 | {// | |
601 | char *tmp = getenv("HOME"); /* we don't have HOME? ^_^ 0_0 $_$ */ | |
602 | if(tmp == NULL) strcpy(g_sCurrentDir, "/"); //begin from the root, then | |
603 | else strcpy(g_sCurrentDir, tmp); | |
604 | } | |
605 | // Load starting directory for HDV (Apple][ HDD) images | |
606 | RegLoadString(TEXT("Preferences"), REGVALUE_PREF_HDD_START_DIR, 1, &szFilename, MAX_PATH); | |
607 | if (szFilename) { | |
608 | strcpy(g_sHDDDir, szFilename); | |
609 | free(szFilename); | |
610 | szFilename = NULL; | |
611 | } | |
612 | // SetCurrentDirectory(g_sCurrentDir); | |
613 | if(strlen(g_sHDDDir) == 0 || g_sHDDDir[0] != '/') //something is wrong in dir name? | |
614 | { | |
615 | char *tmp = getenv("HOME"); /* we don't have HOME? ^_^ 0_0 $_$ */ | |
616 | if(tmp == NULL) strcpy(g_sHDDDir, "/"); //begin from the root, then | |
617 | else strcpy(g_sHDDDir, tmp); | |
618 | } | |
619 | ||
620 | ||
621 | // Load starting directory for saving current states | |
622 | RegLoadString(TEXT("Preferences"), REGVALUE_PREF_SAVESTATE_DIR, 1, &szFilename, MAX_PATH); | |
623 | if (szFilename) { | |
624 | strcpy(g_sSaveStateDir, szFilename); | |
625 | free(szFilename); | |
626 | szFilename = NULL; | |
627 | } | |
628 | if(strlen(g_sSaveStateDir) == 0 || g_sSaveStateDir[0] != '/') //something is wrong in dir name? | |
629 | { | |
630 | char *tmp = getenv("HOME"); /* we don't have HOME? ^_^ 0_0 $_$ */ | |
631 | if(tmp == NULL) strcpy(g_sSaveStateDir, "/"); //begin from the root, then | |
632 | else strcpy(g_sSaveStateDir, tmp); | |
633 | } | |
634 | ||
635 | // Read and fill FTP variables - server, local dir, user name and password | |
636 | RegLoadString(TEXT("Preferences"), REGVALUE_FTP_DIR, 1, &szFilename, MAX_PATH); | |
637 | if (szFilename) { | |
638 | strcpy(g_sFTPServer, szFilename); | |
639 | free(szFilename); | |
640 | szFilename = NULL; | |
641 | } | |
642 | RegLoadString(TEXT("Preferences"), REGVALUE_FTP_HDD_DIR, 1, &szFilename, MAX_PATH); | |
643 | if (szFilename) { | |
644 | strcpy(g_sFTPServerHDD, szFilename); | |
645 | free(szFilename); | |
646 | szFilename = NULL; | |
647 | } | |
648 | ||
649 | RegLoadString(TEXT("Preferences"), REGVALUE_FTP_LOCAL_DIR, 1, &szFilename, MAX_PATH); | |
650 | if (szFilename) { | |
651 | strcpy(g_sFTPLocalDir, szFilename); | |
652 | free(szFilename); | |
653 | szFilename = NULL; | |
654 | } | |
655 | RegLoadString(TEXT("Preferences"), REGVALUE_FTP_USERPASS, 1, &szFilename, 512); | |
656 | if (szFilename) { | |
657 | strcpy(g_sFTPUserPass, szFilename); | |
658 | free(szFilename); | |
659 | szFilename = NULL; | |
660 | } | |
661 | // Print some debug strings | |
662 | printf("Ready login = %s\n",g_sFTPUserPass); | |
663 | ||
664 | // | |
665 | // ****By now we deal without Uthernet interface! --bb**** | |
666 | // char szUthernetInt[MAX_PATH] = {0}; | |
667 | // RegLoadString(TEXT("Configuration"),TEXT("Uthernet Interface"),1,szUthernetInt,MAX_PATH); | |
668 | // update_tfe_interface(szUthernetInt,NULL); | |
669 | ||
670 | } | |
671 | ||
672 | //=========================================================================== | |
673 | void RegisterExtensions () | |
674 | { // TO DO: register extensions for KDE or GNOME desktops?? Do not know, if it is sane idea. He-he. --bb | |
675 | ||
676 | ||
677 | // TCHAR szCommandTmp[MAX_PATH]; | |
678 | // GetModuleFileName((HMODULE)0,szCommandTmp,MAX_PATH); | |
679 | // | |
680 | // TCHAR command[MAX_PATH]; | |
681 | // wsprintf(command, "\"%s\"", szCommandTmp); // Wrap path & filename in quotes & null terminate | |
682 | // | |
683 | // TCHAR icon[MAX_PATH]; | |
684 | // wsprintf(icon,TEXT("%s,1"),(LPCTSTR)command); | |
685 | // | |
686 | // _tcscat(command,TEXT(" \"%1\"")); // Append "%1" | |
687 | // | |
688 | // RegSetValue(HKEY_CLASSES_ROOT,".bin",REG_SZ,"DiskImage",10); | |
689 | // RegSetValue(HKEY_CLASSES_ROOT,".do" ,REG_SZ,"DiskImage",10); | |
690 | // RegSetValue(HKEY_CLASSES_ROOT,".dsk",REG_SZ,"DiskImage",10); | |
691 | // RegSetValue(HKEY_CLASSES_ROOT,".nib",REG_SZ,"DiskImage",10); | |
692 | // RegSetValue(HKEY_CLASSES_ROOT,".po" ,REG_SZ,"DiskImage",10); | |
693 | // // RegSetValue(HKEY_CLASSES_ROOT,".aws",REG_SZ,"DiskImage",10); // TO DO | |
694 | // // RegSetValue(HKEY_CLASSES_ROOT,".hdv",REG_SZ,"DiskImage",10); // TO DO | |
695 | // | |
696 | // RegSetValue(HKEY_CLASSES_ROOT, | |
697 | // "DiskImage", | |
698 | // REG_SZ,"Disk Image",21); | |
699 | // | |
700 | // RegSetValue(HKEY_CLASSES_ROOT, | |
701 | // "DiskImage\\DefaultIcon", | |
702 | // REG_SZ,icon,_tcslen(icon)+1); | |
703 | // | |
704 | // RegSetValue(HKEY_CLASSES_ROOT, | |
705 | // "DiskImage\\shell\\open\\command", | |
706 | // REG_SZ,command,_tcslen(command)+1); | |
707 | // | |
708 | // RegSetValue(HKEY_CLASSES_ROOT, | |
709 | // "DiskImage\\shell\\open\\ddeexec", | |
710 | // REG_SZ,"%1",3); | |
711 | // | |
712 | // RegSetValue(HKEY_CLASSES_ROOT, | |
713 | // "DiskImage\\shell\\open\\ddeexec\\application", | |
714 | // REG_SZ,"applewin",9); | |
715 | // | |
716 | // RegSetValue(HKEY_CLASSES_ROOT, | |
717 | // "DiskImage\\shell\\open\\ddeexec\\topic", | |
718 | // REG_SZ,"system",7); | |
719 | } | |
720 | ||
721 | //=========================================================================== | |
722 | ||
723 | //LPSTR GetNextArg(LPSTR lpCmdLine) | |
724 | //{ | |
725 | // Sane idea: use getoptlong as command-line parameter preprocessor. Use it at your health. Ha. --bb | |
726 | ||
727 | /* | |
728 | int bInQuotes = 0; | |
729 | ||
730 | while(*lpCmdLine) | |
731 | { | |
732 | if(*lpCmdLine == '\"') | |
733 | { | |
734 | bInQuotes ^= 1; | |
735 | if(!bInQuotes) | |
736 | { | |
737 | *lpCmdLine++ = 0x00; // Assume end-quote is end of this arg | |
738 | continue; | |
739 | } | |
740 | } | |
741 | ||
742 | if((*lpCmdLine == ' ') && !bInQuotes) | |
743 | { | |
744 | *lpCmdLine++ = 0x00; | |
745 | break; | |
746 | } | |
747 | ||
748 | lpCmdLine++; | |
749 | } | |
750 | ||
751 | return lpCmdLine; | |
752 | */ | |
753 | //} | |
754 | ||
755 | //FILE *spMono, *spStereo; | |
756 | ||
757 | //--------------------------------------------------------------------------- | |
758 | ||
759 | int main(int argc, char * lpCmdLine[]) | |
760 | { | |
761 | // reading FullScreen and Boot from conf file? | |
762 | // bool bSetFullScreen = false; | |
763 | // bool bBoot = false; | |
764 | ||
765 | registry = fopen(REGISTRY, "a+t"); // open conf file (linapple.conf by default) | |
766 | // spMono = fopen("speakersmono.pcm","wb"); | |
767 | // spStereo = fopen("speakersstereo.pcm","wb"); | |
768 | ||
769 | // LPSTR szImageName_drive1 = NULL; // file names for images of drive1 and drive2 | |
770 | // LPSTR szImageName_drive2 = NULL; | |
771 | ||
772 | ||
773 | bool bBenchMark = (argc > 1 && | |
774 | !strcmp(lpCmdLine[1],"-b")); // if we should start benchmark (-b in command line string) | |
775 | ||
776 | // I will remake this using getopt and getoptlong! | |
777 | /* | |
778 | while(*lpCmdLine) | |
779 | { | |
780 | LPSTR lpNextArg = GetNextArg(lpCmdLine); | |
781 | ||
782 | if(strcmp(lpCmdLine, "-d1") == 0) | |
783 | { | |
784 | lpCmdLine = lpNextArg; | |
785 | lpNextArg = GetNextArg(lpCmdLine); | |
786 | szImageName_drive1 = lpCmdLine; | |
787 | if(*szImageName_drive1 == '\"') | |
788 | szImageName_drive1++; | |
789 | } | |
790 | else if(strcmp(lpCmdLine, "-d2") == 0) | |
791 | { | |
792 | lpCmdLine = lpNextArg; | |
793 | lpNextArg = GetNextArg(lpCmdLine); | |
794 | szImageName_drive2 = lpCmdLine; | |
795 | if(*szImageName_drive2 == '\"') | |
796 | szImageName_drive2++; | |
797 | } | |
798 | else if(strcmp(lpCmdLine, "-f") == 0) | |
799 | { | |
800 | bSetFullScreen = true; | |
801 | } | |
802 | else if((strcmp(lpCmdLine, "-l") == 0) && (g_fh == NULL)) | |
803 | { | |
804 | g_fh = fopen("AppleWin.log", "a+t"); // Open log file (append & text g_nAppMode) | |
805 | // Start of Unix(tm) specific code | |
806 | struct timeval tv; | |
807 | struct tm * ptm; | |
808 | char time_str[40]; | |
809 | gettimeofday(&tv, NULL); | |
810 | ptm = localtime(&tv.tvsec); | |
811 | strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", ptm); | |
812 | // end of Unix(tm) specific code | |
813 | fprintf(g_fh,"*** Logging started: %s\n",time_str); | |
814 | } | |
815 | else if(strcmp(lpCmdLine, "-m") == 0) | |
816 | { | |
817 | g_bDisableDirectSound = true; // without direct sound? U-u-u-u-uuuuuuuhhhhhhhhh --bb | |
818 | } | |
819 | #ifdef RAMWORKS | |
820 | else if(strcmp(lpCmdLine, "-r") == 0) // RamWorks size [1..127] | |
821 | { | |
822 | lpCmdLine = lpNextArg; | |
823 | lpNextArg = GetNextArg(lpCmdLine); | |
824 | g_uMaxExPages = atoi(lpCmdLine); | |
825 | if (g_uMaxExPages > 127) | |
826 | g_uMaxExPages = 128; | |
827 | else if (g_uMaxExPages < 1) | |
828 | g_uMaxExPages = 1; | |
829 | } | |
830 | #endif | |
831 | ||
832 | lpCmdLine = lpNextArg; | |
833 | } | |
834 | */ | |
835 | ||
836 | ||
837 | // What is it???? RIFF support for sound saving during emulation in RIFF format. | |
838 | // Currently not used? | |
839 | #if 0 | |
840 | #ifdef RIFF_SPKR | |
841 | RiffInitWriteFile("Spkr.wav", SPKR_SAMPLE_RATE, 1); | |
842 | #endif | |
843 | #ifdef RIFF_MB | |
844 | RiffInitWriteFile("Mockingboard.wav", 44100, 2); | |
845 | #endif | |
846 | #endif | |
847 | ||
848 | //----- | |
849 | ||
850 | // char szPath[_MAX_PATH]; | |
851 | // | |
852 | // if(0 == GetModuleFileName(NULL, szPath, sizeof(szPath))) | |
853 | // { | |
854 | // strcpy(szPath, __argv[0]); | |
855 | // } | |
856 | ||
857 | // Extract application version and store in a global variable | |
858 | // DWORD dwHandle, dwVerInfoSize; | |
859 | // | |
860 | // dwVerInfoSize = GetFileVersionInfoSize(szPath, &dwHandle); | |
861 | // | |
862 | // if(dwVerInfoSize > 0) | |
863 | // { | |
864 | // char* pVerInfoBlock = new char[dwVerInfoSize]; | |
865 | // | |
866 | // if(GetFileVersionInfo(szPath, NULL, dwVerInfoSize, pVerInfoBlock)) | |
867 | // { | |
868 | // VS_FIXEDFILEINFO* pFixedFileInfo; | |
869 | // UINT pFixedFileInfoLen; | |
870 | // | |
871 | // VerQueryValue(pVerInfoBlock, TEXT("\\"), (LPVOID*) &pFixedFileInfo, (PUINT) &pFixedFileInfoLen); | |
872 | // | |
873 | // // Construct version string from fixed file info block | |
874 | // | |
875 | // unsigned long major = pFixedFileInfo->dwFileVersionMS >> 16; | |
876 | // unsigned long minor = pFixedFileInfo->dwFileVersionMS & 0xffff; | |
877 | // unsigned long fix = pFixedFileInfo->dwFileVersionLS >> 16; | |
878 | // unsigned long fix_minor = pFixedFileInfo->dwFileVersionLS & 0xffff; | |
879 | // | |
880 | // sprintf(VERSIONSTRING, "%d.%d.%d.%d", major, minor, fix, fix_minor); | |
881 | // } | |
882 | // } | |
883 | ||
884 | #if DBG_CALC_FREQ | |
885 | //QueryPerformanceFrequency((LARGE_INTEGER*)&g_nPerfFreq); | |
886 | g_nPerfFreq = 1000;//milliseconds? | |
887 | if(g_fh) fprintf(g_fh, "Performance frequency = %d\n",g_nPerfFreq); | |
888 | #endif | |
889 | ||
890 | //----- | |
891 | ||
892 | // Initialize COM | |
893 | // . NB. DSInit() is done when g_hFrameWindow is created (WM_CREATE) | |
894 | ||
895 | if(InitSDL()) return 1; // init SDL subsystems, set icon | |
896 | // CoInitialize( NULL ); ------- what is it initializing?---------------------------------------- | |
897 | ||
898 | // CURL routines | |
899 | curl_global_init(CURL_GLOBAL_DEFAULT); | |
900 | g_curl = curl_easy_init(); | |
901 | if(!g_curl) { | |
902 | printf("Could not initialize CURL easy interface"); | |
903 | return 1; | |
904 | } | |
905 | /* Set user name and password to access FTP server */ | |
906 | curl_easy_setopt(g_curl, CURLOPT_USERPWD, g_sFTPUserPass); | |
907 | // | |
908 | // just do not see why we need this timer??? | |
909 | /*bool bSysClkOK =*/ SysClk_InitTimer(); | |
910 | ||
911 | // DO ONE-TIME INITIALIZATION | |
912 | // g_hInstance = passinstance; | |
913 | MemPreInitialize(); // Call before any of the slot devices are initialized | |
914 | // GdiSetBatchLimit(512); | |
915 | // GetProgramDirectory(); | |
916 | // RegisterExtensions(); | |
917 | // FrameRegisterClass(); | |
918 | ImageInitialize(); | |
919 | DiskInitialize(); | |
920 | CreateColorMixMap(); // For tv emulation g_nAppMode | |
921 | ||
922 | // int nError = 0; | |
923 | // if(szImageName_drive1) | |
924 | // { | |
925 | // nError = DoDiskInsert(0, szImageName_drive1); | |
926 | // bBoot = true; | |
927 | // } | |
928 | // if(szImageName_drive2) | |
929 | // { | |
930 | // nError |= DoDiskInsert(1, szImageName_drive2); | |
931 | // } | |
932 | ||
933 | // | |
934 | ||
935 | do | |
936 | { | |
937 | // DO INITIALIZATION THAT MUST BE REPEATED FOR A RESTART | |
938 | restart = 0; | |
939 | g_nAppMode = MODE_LOGO; | |
940 | fullscreen = false; | |
941 | ||
942 | LoadConfiguration(); | |
943 | FrameCreateWindow(); | |
944 | ||
945 | if (!DSInit()) soundtype = SOUND_NONE; // Direct Sound and Stuff | |
946 | ||
947 | MB_Initialize(); // Mocking board | |
948 | SpkrInitialize(); // Speakers - of Apple][ ...grrrrrrrrrrr, I love them!--bb | |
949 | DebugInitialize(); | |
950 | JoyInitialize(); | |
951 | MemInitialize(); | |
952 | HD_SetEnabled(hddenabled ? true : false); | |
953 | //printf("g_bHD_Enabled = %d\n", g_bHD_Enabled); | |
954 | ||
955 | VideoInitialize(); | |
956 | ||
957 | ||
958 | // if (!bSysClkOK) | |
959 | // { | |
960 | // MessageBox(g_hFrameWindow, "DirectX failed to create SystemClock instance", TEXT("AppleWin Error"), MB_OK); | |
961 | // PostMessage(g_hFrameWindow, WM_DESTROY, 0, 0); // Close everything down | |
962 | // } | |
963 | ||
964 | // tfe_init(); | |
965 | Snapshot_Startup(); // Do this after everything has been init'ed | |
966 | ||
967 | ||
968 | /* ------Will be fullscreened and booted later. I promise. --bb */ | |
969 | // if(bSetFullScreen) | |
970 | // { | |
971 | // PostMessage(g_hFrameWindow, WM_KEYDOWN, VK_F1+BTN_FULLSCR, 0); | |
972 | // PostMessage(g_hFrameWindow, WM_KEYUP, VK_F1+BTN_FULLSCR, 0); | |
973 | // bSetFullScreen = false; | |
974 | // } | |
975 | // | |
976 | // if(bBoot) | |
977 | // { | |
978 | // PostMessage(g_hFrameWindow, WM_KEYDOWN, VK_F1+BTN_RUN, 0); | |
979 | // PostMessage(g_hFrameWindow, WM_KEYUP, VK_F1+BTN_RUN, 0); | |
980 | // bBoot = false; | |
981 | // } | |
982 | ||
983 | JoyReset(); | |
984 | SetUsingCursor(0); | |
985 | ||
986 | // trying fullscreen | |
987 | if (!fullscreen) SetNormalMode(); | |
988 | else SetFullScreenMode(); | |
989 | ||
990 | DrawFrameWindow(); // we do not have WM_PAINT? | |
991 | ||
992 | ||
993 | // ENTER THE MAIN MESSAGE LOOP | |
994 | if(bBenchMark) VideoBenchmark(); // start VideoBenchmark and exit | |
995 | else EnterMessageLoop(); // else we just start game | |
996 | // on WM_DESTROY event: | |
997 | ||
998 | ||
999 | Snapshot_Shutdown(); | |
1000 | DebugDestroy(); | |
1001 | // printf("Quitting. Snapshot_Shutdown-ed!\n"); | |
1002 | if (!restart) { | |
1003 | DiskDestroy(); | |
1004 | ImageDestroy(); | |
1005 | HD_Cleanup(); | |
1006 | } | |
1007 | // printf("Quitting. DiskDestroy, ImageDestroy and HD_Cleanup!\n"); | |
1008 | PrintDestroy(); | |
1009 | sg_SSC.CommDestroy(); | |
1010 | CpuDestroy(); | |
1011 | MemDestroy(); | |
1012 | // printf("Quitting. PrintDestroy, sg_SSC.CommDestroy, CPU-MEMDestroy!\n"); | |
1013 | SpkrDestroy(); | |
1014 | // printf("Quitting. SpkrDestroy!!\n"); | |
1015 | ||
1016 | VideoDestroy(); | |
1017 | // printf("Quitting. VideoDestroy!!\n"); | |
1018 | MB_Destroy(); | |
1019 | // printf("Quitting. MB_Destroy!\n"); | |
1020 | // end of WM_DESTROY event | |
1021 | MB_Reset(); | |
1022 | // printf("Quitting. MB_Reset!\n"); | |
1023 | sg_Mouse.Uninitialize(); // Maybe restarting due to switching slot-4 card from mouse to MB | |
1024 | // printf("Quitting. Mouse.Uninitialize!!!\n"); | |
1025 | JoyShutDown(); // close opened (if any) joysticks | |
1026 | } | |
1027 | while (restart); | |
1028 | ||
1029 | // Release COM | |
1030 | DSUninit(); | |
1031 | SysClk_UninitTimer(); | |
1032 | // CoUninitialize();------------------------------- what is it uninitializing?-------------------------- | |
1033 | ||
1034 | // tfe_shutdown(); | |
1035 | ||
1036 | if(g_fh) | |
1037 | { | |
1038 | fprintf(g_fh,"*** Logging ended\n\n"); | |
1039 | fclose(g_fh); | |
1040 | } | |
1041 | ||
1042 | RiffFinishWriteFile(); | |
1043 | fclose(registry); //close conf file (linapple.conf by default) | |
1044 | // fclose(spMono); | |
1045 | // fclose(spStereo); | |
1046 | ||
1047 | SDL_Quit(); | |
1048 | // CURL routines | |
1049 | curl_easy_cleanup(g_curl); | |
1050 | curl_global_cleanup(); | |
1051 | // | |
1052 | printf("Linapple: successfully exited!\n"); | |
1053 | return 0; | |
1054 | } |
0 | #include "stdafx.h" | |
1 | //#pragma hdrstop | |
2 | ||
3 | // MemoryTextFile _________________________________________________________________________________ | |
4 | ||
5 | const int EOL_NULL = 0; | |
6 | ||
7 | //=========================================================================== | |
8 | bool MemoryTextFile_t::Read( char *pFileName ) | |
9 | { | |
10 | bool bStatus = false; | |
11 | FILE *hFile = fopen( pFileName, "rt" ); | |
12 | ||
13 | if (hFile) | |
14 | { | |
15 | fseek( hFile, 0, SEEK_END ); | |
16 | long nSize = ftell( hFile ); | |
17 | fseek( hFile, 0, SEEK_SET ); | |
18 | ||
19 | m_vBuffer.reserve( nSize + 1 ); | |
20 | m_vBuffer.insert( m_vBuffer.begin(), nSize+1, 0 ); | |
21 | ||
22 | char *pBuffer = & m_vBuffer.at(0); | |
23 | fread( (void*)pBuffer, nSize, 1, hFile ); | |
24 | ||
25 | m_vBuffer.push_back( EOL_NULL ); | |
26 | ||
27 | fclose(hFile); | |
28 | ||
29 | m_bDirty = true; | |
30 | GetLinePointers(); | |
31 | ||
32 | bStatus = true; | |
33 | } | |
34 | ||
35 | return bStatus; | |
36 | } | |
37 | ||
38 | ||
39 | //=========================================================================== | |
40 | void MemoryTextFile_t::GetLine( const int iLine, char *pLine, const int nMaxLineChars ) | |
41 | { | |
42 | if (m_bDirty) | |
43 | { | |
44 | GetLinePointers(); | |
45 | } | |
46 | ||
47 | ZeroMemory( pLine, nMaxLineChars ); | |
48 | strncpy( pLine, m_vLines[ iLine ], nMaxLineChars-1 ); | |
49 | } | |
50 | ||
51 | ||
52 | // cr/new lines are converted into null, string terminators | |
53 | //=========================================================================== | |
54 | void MemoryTextFile_t::GetLinePointers() | |
55 | { | |
56 | if (! m_bDirty) | |
57 | return; | |
58 | ||
59 | m_vLines.erase( m_vLines.begin(), m_vLines.end() ); | |
60 | char *pBegin = & m_vBuffer.at( 0 ); | |
61 | char *pLast = & m_vBuffer[ m_vBuffer.size() ]; | |
62 | ||
63 | char *pEnd = NULL; | |
64 | char *pStartNextLine; | |
65 | ||
66 | while (pBegin < pLast) | |
67 | { | |
68 | m_vLines.push_back( pBegin ); | |
69 | ||
70 | pEnd = const_cast<char*>( SkipUntilEOL( pBegin )); | |
71 | ||
72 | if (*pEnd == EOL_NULL) | |
73 | { | |
74 | // Found EOL via null | |
75 | pStartNextLine = pEnd + 1; | |
76 | } | |
77 | else | |
78 | { | |
79 | pStartNextLine = const_cast<char*>( EatEOL( pEnd )); | |
80 | ||
81 | // DOS/Win "Text" mode converts LF CR (0D 0A) to CR (0D) | |
82 | // but just in case, the file is read in binary. | |
83 | int nEOL = pStartNextLine - pEnd; | |
84 | while (nEOL-- > 1) | |
85 | { | |
86 | *pEnd++ = ' '; | |
87 | } | |
88 | ||
89 | // assert( pEnd != NULL ); | |
90 | *pEnd = EOL_NULL; | |
91 | } | |
92 | pBegin = pStartNextLine; | |
93 | } | |
94 | ||
95 | m_bDirty = false; | |
96 | } | |
97 | ||
98 | ||
99 | //=========================================================================== | |
100 | void MemoryTextFile_t::PushLine( char *pLine ) | |
101 | { | |
102 | char *pSrc = pLine; | |
103 | while (pSrc && *pSrc) | |
104 | { | |
105 | if (*pSrc == CHAR_CR) | |
106 | m_vBuffer.push_back( EOL_NULL ); | |
107 | else | |
108 | if (*pSrc == CHAR_LF) | |
109 | m_vBuffer.push_back( EOL_NULL ); | |
110 | else | |
111 | m_vBuffer.push_back( *pSrc ); | |
112 | ||
113 | pSrc++; | |
114 | } | |
115 | m_vBuffer.push_back( EOL_NULL ); | |
116 | ||
117 | m_bDirty = true; | |
118 | } | |
119 | ||
120 |
0 | // Motorola MC6821 PIA | |
1 | ||
2 | typedef void (*mem_write_handler) (void* objFrom, void* objTo, int nAddr, BYTE byData); | |
3 | ||
4 | typedef struct _STWriteHandler | |
5 | { | |
6 | void* objTo; | |
7 | mem_write_handler func; | |
8 | } STWriteHandler; | |
9 | ||
10 | // | |
11 | ||
12 | #define PIA_DDRA 0 | |
13 | #define PIA_CTLA 1 | |
14 | #define PIA_DDRB 2 | |
15 | #define PIA_CTLB 3 | |
16 | ||
17 | class C6821 | |
18 | { | |
19 | public: | |
20 | C6821(); | |
21 | virtual ~C6821(); | |
22 | ||
23 | BYTE GetPB(); | |
24 | BYTE GetPA(); | |
25 | void SetPB(BYTE byData); | |
26 | void SetPA(BYTE byData); | |
27 | void SetCA1( BYTE byData ); | |
28 | void SetCA2( BYTE byData ); | |
29 | void SetCB1( BYTE byData ); | |
30 | void SetCB2( BYTE byData ); | |
31 | void Reset(); | |
32 | BYTE Read( BYTE byRS ); | |
33 | void Write( BYTE byRS, BYTE byData ); | |
34 | ||
35 | void UpdateInterrupts(); | |
36 | ||
37 | void SetListenerA( void *objTo, mem_write_handler func ); | |
38 | void SetListenerB( void *objTo, mem_write_handler func ); | |
39 | void SetListenerCA2( void *objTo, mem_write_handler func ); | |
40 | void SetListenerCB2( void *objTo, mem_write_handler func ); | |
41 | ||
42 | protected: | |
43 | BYTE m_byIA; | |
44 | BYTE m_byCA1; | |
45 | BYTE m_byICA2; | |
46 | BYTE m_byOA; | |
47 | BYTE m_byOCA2; | |
48 | BYTE m_byDDRA; | |
49 | BYTE m_byCTLA; | |
50 | BYTE m_byIRQAState; | |
51 | ||
52 | BYTE m_byIB; | |
53 | BYTE m_byCB1; | |
54 | BYTE m_byICB2; | |
55 | BYTE m_byOB; | |
56 | BYTE m_byOCB2; | |
57 | BYTE m_byDDRB; | |
58 | BYTE m_byCTLB; | |
59 | BYTE m_byIRQBState; | |
60 | ||
61 | STWriteHandler m_stOutA; | |
62 | STWriteHandler m_stOutB; | |
63 | STWriteHandler m_stOutCA2; | |
64 | STWriteHandler m_stOutCB2; | |
65 | STWriteHandler m_stOutIRQA; | |
66 | STWriteHandler m_stOutIRQB; | |
67 | }; |
0 | #ifndef AY8910_H | |
1 | #define AY8910_H | |
2 | ||
3 | #define MAX_8910 4 | |
4 | ||
5 | void _AYWriteReg(int n, int r, int v); | |
6 | void AY8910_write_ym(int chip, int addr, int data); | |
7 | void AY8910_reset(int chip); | |
8 | void AY8910Update(int chip,INT16 **buffer,int length); | |
9 | ||
10 | void AY8910_InitAll(int nClock, int nSampleRate); | |
11 | void AY8910_InitClock(int nClock); | |
12 | BYTE* AY8910_GetRegsPtr(UINT nAyNum); | |
13 | ||
14 | #endif |
0 | #pragma once | |
1 | ||
2 | #ifdef _WIN32 | |
3 | #define FILE_SEPARATOR TEXT('\\') | |
4 | #else | |
5 | #define FILE_SEPARATOR TEXT('/') | |
6 | #endif | |
7 | ||
8 | #define FTP_SEPARATOR TEXT('/') | |
9 | ||
10 | // let it be our second version! | |
11 | #define LINAPPLE_VERSION 2 | |
12 | ||
13 | #include <curl/curl.h> | |
14 | ||
15 | extern FILE * spMono,*spStereo; | |
16 | ||
17 | extern char VERSIONSTRING[]; // Contructed in WinMain() | |
18 | ||
19 | extern TCHAR *g_pAppTitle; | |
20 | ||
21 | extern eApple2Type g_Apple2Type; | |
22 | ||
23 | extern BOOL behind; | |
24 | extern DWORD cumulativecycles; | |
25 | extern DWORD cyclenum; | |
26 | extern DWORD emulmsec; | |
27 | extern bool g_bFullSpeed; | |
28 | ||
29 | // Win32 | |
30 | //extern HINSTANCE g_hInstance; | |
31 | ||
32 | ||
33 | extern AppMode_e g_nAppMode; | |
34 | ||
35 | extern UINT g_ScreenWidth; | |
36 | extern UINT g_ScreenHeight; | |
37 | ||
38 | extern DWORD needsprecision; | |
39 | //extern TCHAR g_sProgramDir[MAX_PATH]; | |
40 | extern TCHAR g_sCurrentDir[MAX_PATH]; | |
41 | extern TCHAR g_sHDDDir[MAX_PATH]; | |
42 | extern TCHAR g_sSaveStateDir[MAX_PATH]; | |
43 | extern TCHAR g_sParallelPrinterFile[MAX_PATH]; | |
44 | // FTP vars | |
45 | extern TCHAR g_sFTPLocalDir[MAX_PATH]; // FTP Local Dir, see linapple.conf for details | |
46 | extern TCHAR g_sFTPServer[MAX_PATH]; // full path to default FTP server | |
47 | extern TCHAR g_sFTPServerHDD[MAX_PATH]; // full path to default FTP server | |
48 | ||
49 | //extern TCHAR g_sFTPUser[256]; // user name | |
50 | //extern TCHAR g_sFTPPass[256]; // password | |
51 | extern TCHAR g_sFTPUserPass[512]; // full login line | |
52 | ||
53 | extern CURL * g_curl; | |
54 | ||
55 | ||
56 | extern bool g_bResetTiming; | |
57 | extern BOOL restart; | |
58 | ||
59 | extern DWORD g_dwSpeed; | |
60 | extern double g_fCurrentCLK6502; | |
61 | ||
62 | extern int g_nCpuCyclesFeedback; | |
63 | extern DWORD g_dwCyclesThisFrame; | |
64 | ||
65 | extern FILE* g_fh; // Filehandle for log file | |
66 | extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so no MB support) | |
67 | ||
68 | extern UINT g_Slot4; // Mockingboard or Mouse in slot4 | |
69 | ||
70 | void SetCurrentCLK6502(); |
0 | #pragma once | |
1 | ||
2 | typedef struct _regsrec { | |
3 | BYTE a; // accumulator | |
4 | BYTE x; // index X | |
5 | BYTE y; // index Y | |
6 | BYTE ps; // processor status | |
7 | WORD pc; // program counter | |
8 | WORD sp; // stack pointer | |
9 | BYTE bJammed; // CPU has crashed (NMOS 6502 only) | |
10 | } regsrec, *regsptr; | |
11 | ||
12 | extern regsrec regs; | |
13 | extern unsigned __int64 g_nCumulativeCycles; | |
14 | ||
15 | void CpuDestroy (); | |
16 | void CpuCalcCycles(ULONG nExecutedCycles); | |
17 | DWORD CpuExecute (DWORD); | |
18 | ULONG CpuGetCyclesThisFrame(ULONG nExecutedCycles); | |
19 | void CpuInitialize (); | |
20 | void CpuSetupBenchmark (); | |
21 | void CpuIrqReset(); | |
22 | void CpuIrqAssert(eIRQSRC Device); | |
23 | void CpuIrqDeassert(eIRQSRC Device); | |
24 | void CpuNmiReset(); | |
25 | void CpuNmiAssert(eIRQSRC Device); | |
26 | void CpuNmiDeassert(eIRQSRC Device); | |
27 | void CpuReset (); | |
28 | DWORD CpuGetSnapshot(SS_CPU6502* pSS); | |
29 | DWORD CpuSetSnapshot(SS_CPU6502* pSS); |
0 | #pragma once | |
1 | ||
2 | #define USE_SPEECH_API | |
3 | ||
4 | const double _M14 = (157500000.0 / 11.0); // 14.3181818... * 10^6 | |
5 | const double CLK_6502 = ((_M14 * 65.0) / 912.0); // 65 cycles per 912 14M clocks | |
6 | //const double CLK_6502 = 23 * 44100; // 1014300 | |
7 | ||
8 | // The effective Z-80 clock rate is 2.041MHz | |
9 | // See: http://www.apple2info.net/hardware/softcard/SC-SWHW_a2in.pdf | |
10 | const double CLK_Z80 = (CLK_6502 * 2); | |
11 | ||
12 | const UINT uCyclesPerLine = 65; // 25 cycles of HBL & 40 cycles of HBL' | |
13 | const UINT uVisibleLinesPerFrame = 64*3; // 192 | |
14 | const UINT uLinesPerFrame = 262; // 64 in each third of the screen & 70 in VBL | |
15 | const DWORD dwClksPerFrame = uCyclesPerLine * uLinesPerFrame; // 17030 | |
16 | ||
17 | #define NUM_SLOTS 8 | |
18 | ||
19 | #define MAX(a,b) (((a) > (b)) ? (a) : (b)) | |
20 | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | |
21 | ||
22 | #define RAMWORKS // 8MB RamWorks III support | |
23 | ||
24 | #define MOCKINGBOARD // Mockingboard support | |
25 | ||
26 | // Use a base freq so that DirectX (or sound h/w) doesn't have to up/down-sample | |
27 | // Assume base freqs are 44.1KHz & 48KHz | |
28 | const DWORD SPKR_SAMPLE_RATE = 44100; // that is for Apple][ speakers | |
29 | const DWORD SAMPLE_RATE = 44100; // that is for Phasor/Mockingboard? | |
30 | ||
31 | enum AppMode_e | |
32 | { | |
33 | MODE_LOGO = 0 | |
34 | , MODE_PAUSED | |
35 | , MODE_RUNNING // 6502 is running at normal speed (Debugger breakpoints may or may not be active) | |
36 | , MODE_DEBUG // 6502 is paused | |
37 | , MODE_STEPPING // 6502 is running at full speed (Debugger breakpoints always active) | |
38 | }; | |
39 | ||
40 | #define SPEED_MIN 0 | |
41 | #define SPEED_NORMAL 10 | |
42 | #define SPEED_MAX 40 | |
43 | ||
44 | #define DRAW_BACKGROUND 1 | |
45 | #define DRAW_LEDS 2 | |
46 | #define DRAW_TITLE 4 | |
47 | #define DRAW_BUTTON_DRIVES 8 | |
48 | ||
49 | // Function Keys F1..F12 | |
50 | #define BTN_HELP 0 | |
51 | #define BTN_RUN 1 | |
52 | #define BTN_DRIVE1 2 | |
53 | #define BTN_DRIVE2 3 | |
54 | #define BTN_DRIVESWAP 4 | |
55 | #define BTN_FULLSCR 5 | |
56 | #define BTN_DEBUG 6 | |
57 | #define BTN_SETUP 7 | |
58 | #define BTN_CYCLE 8 | |
59 | #define BTN_QUIT 11 | |
60 | #define BTN_SAVEST 10 | |
61 | #define BTN_LOADST 9 | |
62 | ||
63 | //#define MAXIMAGES 16 | |
64 | ||
65 | // TODO: Move to StringTable.h | |
66 | #define TITLE_APPLE_2 TEXT("Apple ][ Emulator") | |
67 | #define TITLE_APPLE_2_PLUS TEXT("Apple ][+ Emulator") | |
68 | #define TITLE_APPLE_2E TEXT("Apple //e Emulator") | |
69 | #define TITLE_APPLE_2E_ENHANCED TEXT("Enhanced Apple //e Emulator") | |
70 | ||
71 | #define TITLE_PAUSED TEXT(" Paused ") | |
72 | #define TITLE_STEPPING TEXT("Stepping") | |
73 | ||
74 | #define LOAD(a,b) RegLoadValue(TEXT("Configuration"),a,1,b) | |
75 | #define SAVE(a,b) RegSaveValue(TEXT("Configuration"),a,1,b) | |
76 | ||
77 | // Configuration | |
78 | #define REGVALUE_APPLE2_TYPE "Apple2 Type" | |
79 | #define REGVALUE_SPKR_VOLUME "Speaker Volume" | |
80 | #define REGVALUE_MB_VOLUME "Mockingboard Volume" | |
81 | #define REGVALUE_SOUNDCARD_TYPE "Soundcard Type" | |
82 | #define REGVALUE_KEYB_BUFFER_ENABLE "Keyboard Buffer Enable" | |
83 | #define REGVALUE_SAVESTATE_FILENAME "Save State Filename" | |
84 | #define REGVALUE_SAVE_STATE_ON_EXIT "Save State On Exit" | |
85 | #define REGVALUE_HDD_ENABLED "Harddisk Enable" | |
86 | #define REGVALUE_HDD_IMAGE1 "Harddisk Image 1" | |
87 | #define REGVALUE_HDD_IMAGE2 "Harddisk Image 2" | |
88 | #define REGVALUE_DISK_IMAGE1 "Disk Image 1" | |
89 | #define REGVALUE_DISK_IMAGE2 "Disk Image 2" | |
90 | ||
91 | #define REGVALUE_PPRINTER_FILENAME "Parallel Printer Filename" | |
92 | ||
93 | #define REGVALUE_PDL_XTRIM "PDL X-Trim" | |
94 | #define REGVALUE_PDL_YTRIM "PDL Y-Trim" | |
95 | #define REGVALUE_SCROLLLOCK_TOGGLE "ScrollLock Toggle" | |
96 | #define REGVALUE_MOUSE_IN_SLOT4 "Mouse in slot 4" | |
97 | ||
98 | // Preferences | |
99 | #define REGVALUE_PREF_START_DIR TEXT("Slot 6 Directory") | |
100 | #define REGVALUE_PREF_HDD_START_DIR TEXT("HDV Starting Directory") | |
101 | #define REGVALUE_PREF_SAVESTATE_DIR TEXT("Save State Directory") | |
102 | ||
103 | #define REGVALUE_SHOW_LEDS TEXT("Show Leds") | |
104 | ||
105 | // For FTP access | |
106 | #define REGVALUE_FTP_DIR TEXT("FTP Server") | |
107 | #define REGVALUE_FTP_HDD_DIR TEXT("FTP ServerHDD") | |
108 | ||
109 | #define REGVALUE_FTP_LOCAL_DIR TEXT("FTP Local Dir") | |
110 | #define REGVALUE_FTP_USERPASS TEXT("FTP UserPass") | |
111 | //#define REGVALUE_FTP_USER TEXT("FTP User") | |
112 | //#define REGVALUE_FTP_PASS TEXT("FTP Pass") | |
113 | ||
114 | #define WM_USER_BENCHMARK WM_USER+1 | |
115 | #define WM_USER_RESTART WM_USER+2 | |
116 | #define WM_USER_SAVESTATE WM_USER+3 | |
117 | #define WM_USER_LOADSTATE WM_USER+4 | |
118 | ||
119 | enum eSOUNDCARDTYPE {SC_UNINIT=0, SC_NONE, SC_MOCKINGBOARD, SC_PHASOR}; // Apple soundcard type | |
120 | ||
121 | typedef BYTE (*iofunction)(WORD nPC, WORD nAddr, BYTE nWriteFlag, BYTE nWriteValue, ULONG nCyclesLeft); | |
122 | ||
123 | typedef struct _IMAGE__ { int unused; } *HIMAGE; | |
124 | ||
125 | enum eIRQSRC {IS_6522=0, IS_SPEECH, IS_SSC, IS_MOUSE}; | |
126 | ||
127 | // | |
128 | ||
129 | #define APPLE2E_MASK 0x10 | |
130 | #define APPLE2C_MASK 0x20 | |
131 | ||
132 | #define IS_APPLE2 ((g_Apple2Type & (APPLE2E_MASK|APPLE2C_MASK)) == 0) | |
133 | #define IS_APPLE2E (g_Apple2Type & APPLE2E_MASK) | |
134 | #define IS_APPLE2C (g_Apple2Type & APPLE2C_MASK) | |
135 | ||
136 | // NB. These get persisted to the Registry, so don't change the values for these enums! | |
137 | enum eApple2Type { | |
138 | A2TYPE_APPLE2=0, | |
139 | A2TYPE_APPLE2PLUS, | |
140 | A2TYPE_APPLE2E=APPLE2E_MASK, | |
141 | A2TYPE_APPLE2EEHANCED, | |
142 | // A2TYPE_APPLE2C=APPLE2C_MASK, // Placeholder | |
143 | A2TYPE_MAX | |
144 | }; | |
145 | ||
146 | enum eBUTTON {BUTTON0=0, BUTTON1}; | |
147 | enum eBUTTONSTATE {BUTTON_UP=0, BUTTON_DOWN}; | |
148 | ||
149 | // sizes of status panel | |
150 | #define STATUS_PANEL_W 100 | |
151 | #define STATUS_PANEL_H 48 |
0 | #pragma once | |
1 | ||
2 | #include <vector> | |
3 | #include <algorithm> // sort | |
4 | #include <map> | |
5 | #include <string> | |
6 | using namespace std; | |
7 | ||
8 | #include "Debugger_Types.h" | |
9 | // #include "Debugger_Parser.h" | |
10 | // #include "Debugger_Console.h" | |
11 | // #include "Debugger_Assembler.h" | |
12 | // #include "Debugger_Help.h" | |
13 | // #include "Debugger_Display.h" | |
14 | // #include "Util_MemoryTextFile.h" | |
15 | ||
16 | // Globals __________________________________________________________________ | |
17 | ||
18 | // Benchmarking | |
19 | extern DWORD extbench; | |
20 | ||
21 | // Bookmarks | |
22 | extern int g_nBookmarks; | |
23 | extern Bookmark_t g_aBookmarks[ MAX_BOOKMARKS ]; | |
24 | // extern vector<int> g_aBookmarks; | |
25 | ||
26 | // Breakpoints | |
27 | extern int g_nBreakpoints; | |
28 | extern Breakpoint_t g_aBreakpoints[ MAX_BREAKPOINTS ]; | |
29 | ||
30 | extern const char *g_aBreakpointSource [ NUM_BREAKPOINT_SOURCES ]; | |
31 | extern const TCHAR *g_aBreakpointSymbols[ NUM_BREAKPOINT_OPERATORS ]; | |
32 | ||
33 | // Full-Speed debugging | |
34 | extern int g_nDebugOnBreakInvalid; | |
35 | extern int g_iDebugOnOpcode ; | |
36 | extern bool g_bDebugDelayBreakCheck; | |
37 | ||
38 | // Commands | |
39 | extern const int NUM_COMMANDS_WITH_ALIASES; // = sizeof(g_aCommands) / sizeof (Command_t); // Determined at compile-time ;-) | |
40 | extern int g_iCommand; // last command | |
41 | ||
42 | extern Command_t g_aCommands[]; | |
43 | extern Command_t g_aParameters[]; | |
44 | ||
45 | // Config - FileName | |
46 | extern char g_sFileNameConfig[]; | |
47 | ||
48 | // Cursor | |
49 | extern WORD g_nDisasmTopAddress ; | |
50 | extern WORD g_nDisasmBotAddress ; | |
51 | extern WORD g_nDisasmCurAddress ; | |
52 | ||
53 | extern bool g_bDisasmCurBad ; | |
54 | extern int g_nDisasmCurLine ; // Aligned to Top or Center | |
55 | extern int g_iDisasmCurState ; | |
56 | ||
57 | extern int g_nDisasmWinHeight; | |
58 | ||
59 | extern const int WINDOW_DATA_BYTES_PER_LINE; | |
60 | ||
61 | // Config - Disassembly | |
62 | extern bool g_bConfigDisasmAddressColon ; | |
63 | extern bool g_bConfigDisasmOpcodesView ; | |
64 | extern bool g_bConfigDisasmOpcodeSpaces ; | |
65 | extern int g_iConfigDisasmTargets ; | |
66 | extern int g_iConfigDisasmBranchType ; | |
67 | extern int g_bConfigDisasmImmediateChar; | |
68 | // Config - Info | |
69 | extern bool g_bConfigInfoTargetPointer ; | |
70 | ||
71 | // Disassembly | |
72 | // extern int g_aDisasmTargets[ MAX_DISPLAY_LINES ]; | |
73 | ||
74 | // Display | |
75 | extern bool g_bDebuggerViewingAppleOutput; | |
76 | ||
77 | // Font | |
78 | extern int g_nFontHeight; | |
79 | extern int g_iFontSpacing; | |
80 | ||
81 | // Memory | |
82 | extern MemoryDump_t g_aMemDump[ NUM_MEM_DUMPS ]; | |
83 | ||
84 | // extern MemorySearchArray_t g_vMemSearchMatches; | |
85 | extern vector<int> g_vMemorySearchResults; | |
86 | ||
87 | // Source Level Debugging | |
88 | extern TCHAR g_aSourceFileName[ MAX_PATH ]; | |
89 | // extern MemoryTextFile_t g_AssemblerSourceBuffer; | |
90 | ||
91 | extern int g_iSourceDisplayStart ; | |
92 | extern int g_nSourceAssembleBytes ; | |
93 | extern int g_nSourceAssemblySymbols; | |
94 | ||
95 | // Version | |
96 | extern const int DEBUGGER_VERSION; | |
97 | ||
98 | // Watches | |
99 | extern int g_nWatches; | |
100 | extern Watches_t g_aWatches[ MAX_WATCHES ]; | |
101 | ||
102 | // Window | |
103 | extern int g_iWindowLast; | |
104 | extern int g_iWindowThis; | |
105 | extern WindowSplit_t g_aWindowConfig[ NUM_WINDOWS ]; | |
106 | ||
107 | // Zero Page | |
108 | extern int g_nZeroPagePointers; | |
109 | extern ZeroPagePointers_t g_aZeroPagePointers[ MAX_ZEROPAGE_POINTERS ]; // TODO: use vector<> ? | |
110 | ||
111 | // Prototypes _______________________________________________________________ | |
112 | ||
113 | // Bookmarks | |
114 | bool Bookmark_Find( const WORD nAddress ); | |
115 | ||
116 | // Breakpoints | |
117 | bool GetBreakpointInfo ( WORD nOffset, bool & bBreakpointActive_, bool & bBreakpointEnable_ ); | |
118 | ||
119 | // 0 = Brk, 1 = Invalid1, .. 3 = Invalid 3 | |
120 | inline bool IsDebugBreakOnInvalid( int iOpcodeType ) | |
121 | { | |
122 | bool bActive = (g_nDebugOnBreakInvalid >> iOpcodeType) & 1; | |
123 | return bActive; | |
124 | } | |
125 | ||
126 | inline void SetDebugBreakOnInvalid( int iOpcodeType, int nValue ) | |
127 | { | |
128 | if (iOpcodeType <= AM_3) | |
129 | { | |
130 | g_nDebugOnBreakInvalid &= ~ ( 1 << iOpcodeType); | |
131 | g_nDebugOnBreakInvalid |= ((nValue & 1) << iOpcodeType); | |
132 | } | |
133 | } | |
134 | ||
135 | // Color | |
136 | inline COLORREF DebuggerGetColor( int iColor ); | |
137 | ||
138 | // Source Level Debugging | |
139 | int FindSourceLine( WORD nAddress ); | |
140 | LPCTSTR FormatAddress( WORD nAddress, int nBytes ); | |
141 | ||
142 | // Symbol Table / Memory | |
143 | bool FindAddressFromSymbol( LPCSTR pSymbol, WORD * pAddress_ = NULL, int * iTable_ = NULL ); | |
144 | WORD GetAddressFromSymbol (LPCTSTR symbol); // HACK: returns 0 if symbol not found | |
145 | void SymbolUpdate( Symbols_e eSymbolTable, char *pSymbolName, WORD nAddrss, bool bRemoveSymbol, bool bUpdateSymbol ); | |
146 | ||
147 | LPCTSTR FindSymbolFromAddress (WORD nAdress, int * iTable_ = NULL ); | |
148 | LPCTSTR GetSymbol (WORD nAddress, int nBytes); | |
149 | ||
150 | Update_t DebuggerProcessCommand( const bool bEchoConsoleInput ); | |
151 | ||
152 | // Prototypes _______________________________________________________________ | |
153 | ||
154 | enum | |
155 | { | |
156 | DEBUG_EXIT_KEY = 0x1B, // Escape | |
157 | DEBUG_TOGGLE_KEY = SDLK_F1 + BTN_DEBUG | |
158 | }; | |
159 | ||
160 | void DebugBegin (); | |
161 | void DebugContinueStepping (); | |
162 | void DebugDestroy (); | |
163 | void DebugDisplay (BOOL); | |
164 | void DebugEnd (); | |
165 | void DebugInitialize (); | |
166 | // void DebugProcessChar (TCHAR); | |
167 | void DebuggerInputConsoleChar( TCHAR ch ); | |
168 | // void DebugProcessCommand (int); | |
169 | void DebuggerProcessKey( int keycode ); | |
170 | ||
171 | void DebuggerUpdate(); | |
172 | void DebuggerCursorNext(); | |
173 | ||
174 | void DebuggerMouseClick( int x, int y ); |
0 | #pragma once | |
1 | ||
2 | ||
3 | // Addressing _____________________________________________________________________________________ | |
4 | ||
5 | enum | |
6 | { | |
7 | // MAX_ADDRESSING_MODE_LEN = 12 | |
8 | ||
9 | MAX_OPMODE_FORMAT = 12, | |
10 | MAX_OPMODE_NAME = 32 | |
11 | ||
12 | , NO_6502_TARGET = -1 | |
13 | , _6502_NUM_FLAGS = 8 | |
14 | }; | |
15 | ||
16 | enum RangeType_t | |
17 | { | |
18 | RANGE_MISSING_ARG_2 = 0, // error | |
19 | RANGE_HAS_LEN , // valid case 1 | |
20 | RANGE_HAS_END , // valid case 2 | |
21 | }; | |
22 | ||
23 | struct AddressingMode_t | |
24 | { | |
25 | char m_sFormat[ MAX_OPMODE_FORMAT ]; | |
26 | int m_nBytes; | |
27 | char m_sName [ MAX_OPMODE_NAME ]; | |
28 | }; | |
29 | ||
30 | /* | |
31 | +---------------------+--------------------------+ | |
32 | | Opmode e | assembler format | | |
33 | +=====================+==========================+ | |
34 | | Immediate | #aa | | |
35 | | Absolute | aaaa | | |
36 | | Zero Page | aa | Note: | |
37 | | Implied | | | |
38 | | Indirect Absolute | (aaaa) | aa = 2 hex digits | |
39 | | Absolute Indexed,X | aaaa,X | as $FF | |
40 | | Absolute Indexed,Y | aaaa,Y | | |
41 | | Zero Page Indexed,X | aa,X | aaaa = 4 hex | |
42 | | Zero Page Indexed,Y | aa,Y | digits as | |
43 | | Indexed Indirect | (aa,X) | $FFFF | |
44 | | Indirect Indexed | (aa),Y | | |
45 | | Relative | aaaa | Can also be | |
46 | | Accumulator | A | assembler labels | |
47 | +---------------------+--------------------------+ | |
48 | (Table 2-3. _6502 Software Design_, Scanlon, 1980) | |
49 | ||
50 | Opcode: opc aaa od | |
51 | opc...od = Mnemonic / Opcode | |
52 | ...aaa.. = Addressing g_nAppMode | |
53 | od = 00 | |
54 | 000 #Immediate | |
55 | 001 Zero page | |
56 | 011 Absolute | |
57 | 101 Zero page,X | |
58 | 111 Absolute,X | |
59 | od = 01 | |
60 | 000 (Zero page,X) | |
61 | 001 Zero page | |
62 | 010 #Immediate | |
63 | 011 Absolute | |
64 | 100 (Zero page),Y | |
65 | 101 Zero page,X | |
66 | 110 Absolute,Y | |
67 | 111 Absolute,X | |
68 | od = 10 | |
69 | 000 #Immediate | |
70 | 001 Zero page | |
71 | 010 Accumulator | |
72 | 011 Absolute | |
73 | 101 Zero page,X | |
74 | 111 Absolute,X | |
75 | */ | |
76 | /* | |
77 | Legend: | |
78 | A = Absolute (fortunately Accumulator is implicit, leaving us to use 'A') | |
79 | I = Indexed ( would of been X, but need reg X) | |
80 | M = iMmediate | |
81 | N = iNdirect | |
82 | R = Relative | |
83 | X = Offset X Register | |
84 | Y = Offset Y Register | |
85 | Z = Zeropage | |
86 | */ | |
87 | enum AddressingMode_e // ADDRESSING_MODES_e | |
88 | { | |
89 | AM_IMPLIED // Note: SetDebugBreakOnInvalid() assumes this order of first 4 entries | |
90 | , AM_1 // Invalid 1 Byte | |
91 | , AM_2 // Invalid 2 Bytes | |
92 | , AM_3 // Invalid 3 Bytes | |
93 | , AM_M // 4 #Immediate | |
94 | , AM_A // 5 $Absolute | |
95 | , AM_Z // 6 Zeropage | |
96 | , AM_AX // 7 Absolute, X | |
97 | , AM_AY // 8 Absolute, Y | |
98 | , AM_ZX // 9 Zeropage, X | |
99 | , AM_ZY // 10 Zeropage, Y | |
100 | , AM_R // 11 Relative | |
101 | , AM_IZX // 12 Indexed (Zeropage Indirect, X) | |
102 | , AM_IAX // 13 Indexed (Absolute Indirect, X) | |
103 | , AM_NZY // 14 Indirect (Zeropage) Indexed, Y | |
104 | , AM_NZ // 15 Indirect (Zeropage) | |
105 | , AM_NA // 16 Indirect (Absolute) i.e. JMP | |
106 | ||
107 | , NUM_ADDRESSING_MODES | |
108 | , NUM_OPMODES = NUM_ADDRESSING_MODES | |
109 | , AM_I = NUM_ADDRESSING_MODES, // for assemler | |
110 | ||
111 | // Deprecated | |
112 | /* | |
113 | ADDR_INVALID1 = 1, | |
114 | ADDR_INVALID2 = 2, | |
115 | ADDR_INVALID3 = 3, | |
116 | ADDR_IMM = 4, // Immediate | |
117 | ADDR_ABS = 5, // Absolute | |
118 | ADDR_ZP = 6, // Zeropage | |
119 | ADDR_ABSX = 7, // Absolute + X | |
120 | ADDR_ABSY = 8, // Absolute + Y | |
121 | ADDR_ZP_X = 9, // Zeropage + X | |
122 | ADDR_ZP_Y = 10, // Zeropage + Y | |
123 | ADDR_REL = 11, // Relative | |
124 | ADDR_INDX = 12, // Indexed (Zeropage) Indirect | |
125 | ADDR_ABSIINDX = 13, // Indexed (Absolute) Indirect | |
126 | ADDR_INDY = 14, // Indirect (Zeropage) Indexed | |
127 | ADDR_IZPG = 15, // Indirect (Zeropage) | |
128 | ADDR_IABS = 16, // Indirect Absolute (i.e. JMP) | |
129 | */ | |
130 | }; | |
131 | ||
132 | ||
133 | // Assembler ______________________________________________________________________________________ | |
134 | ||
135 | enum Prompt_e | |
136 | { | |
137 | PROMPT_COMMAND, | |
138 | PROMPT_ASSEMBLER, | |
139 | NUM_PROMPTS | |
140 | }; | |
141 | ||
142 | ||
143 | // Bookmarks ______________________________________________________________________________________ | |
144 | ||
145 | enum | |
146 | { | |
147 | MAX_BOOKMARKS = 10 | |
148 | }; | |
149 | ||
150 | // Breakpoints ____________________________________________________________________________________ | |
151 | ||
152 | enum | |
153 | { | |
154 | MAX_BREAKPOINTS = 16 | |
155 | }; | |
156 | ||
157 | /* | |
158 | Breakpoints are now in a tri-state. | |
159 | This allows one to set a bunch of breakpoints, and re-enable the ones you want | |
160 | without having to remember which addresses you previously added. :-) | |
161 | ||
162 | The difference between Set and Enabled breakpoints: | |
163 | ||
164 | Set Enabled Break? | |
165 | x x yes, listed as full brightness | |
166 | x - no, listed as dimmed | |
167 | - ? no, not listed | |
168 | */ | |
169 | // NOTE: Order must match _PARAM_REGS_* | |
170 | // NOTE: Order must match Breakpoint_Source_t | |
171 | // NOTE: Order must match g_aBreakpointSource | |
172 | enum BreakpointSource_t | |
173 | { | |
174 | BP_SRC_REG_A , | |
175 | BP_SRC_REG_X , | |
176 | BP_SRC_REG_Y , | |
177 | ||
178 | BP_SRC_REG_PC, // Program Counter | |
179 | BP_SRC_REG_S , // Stack Counter | |
180 | ||
181 | BP_SRC_REG_P , // Processor Status | |
182 | BP_SRC_FLAG_C, // Carry | |
183 | BP_SRC_FLAG_Z, // Zero | |
184 | BP_SRC_FLAG_I, // Interrupt | |
185 | BP_SRC_FLAG_D, // Decimal | |
186 | BP_SRC_FLAG_B, // Break | |
187 | BP_SRC_FLAG_R, // Reserved | |
188 | BP_SRC_FLAG_V, // Overflow | |
189 | BP_SRC_FLAG_N, // Sign | |
190 | ||
191 | BP_SRC_OPCODE, | |
192 | BP_SRC_MEM_1 , | |
193 | ||
194 | NUM_BREAKPOINT_SOURCES | |
195 | }; | |
196 | ||
197 | // Note: Order must match Breakpoint_Operator_t | |
198 | // Note: Order must much _PARAM_BREAKPOINT_* | |
199 | // Note: Order must match g_aBreakpointSymbols | |
200 | enum BreakpointOperator_t | |
201 | { | |
202 | BP_OP_LESS_EQUAL , // <= REG | |
203 | BP_OP_LESS_THAN , // < REG | |
204 | BP_OP_EQUAL , // = REG | |
205 | BP_OP_NOT_EQUAL , // != REG | |
206 | // BP_OP_NOT_EQUAL_1 , // ! REG | |
207 | BP_OP_GREATER_THAN , // > REG | |
208 | BP_OP_GREATER_EQUAL, // >= REG | |
209 | BP_OP_READ , // @ MEM @ ? * | |
210 | BP_OP_WRITE , // * MEM @ ? * | |
211 | BP_OP_READ_WRITE , // ? MEM @ ? * | |
212 | NUM_BREAKPOINT_OPERATORS | |
213 | }; | |
214 | ||
215 | struct Breakpoint_t | |
216 | { | |
217 | WORD nAddress; // for registers, functions as nValue | |
218 | WORD nLength ; | |
219 | BreakpointSource_t eSource; | |
220 | BreakpointOperator_t eOperator; | |
221 | bool bSet ; // used to be called enabled pre 2.0 | |
222 | bool bEnabled; | |
223 | }; | |
224 | ||
225 | typedef Breakpoint_t Bookmark_t; | |
226 | typedef Breakpoint_t Watches_t; | |
227 | typedef Breakpoint_t ZeroPagePointers_t; | |
228 | ||
229 | ||
230 | // Colors ___________________________________________________________________ | |
231 | ||
232 | enum Color_Schemes_e | |
233 | { | |
234 | SCHEME_COLOR, // NOTE: MUST match order in CMD_WINDOW_COLOR | |
235 | SCHEME_MONO , // NOTE: MUST match order in CMD_WINDOW_MONOCHROME | |
236 | SCHEME_BW , // NOTE: MUST match order in CMD_WINDOW_BW | |
237 | // SCHEME_CUSTOM | |
238 | NUM_COLOR_SCHEMES | |
239 | }; | |
240 | ||
241 | // Named, since they are easier to remember. | |
242 | // Ok, maybe RGB + CYMK is a little "too" cute. But what the hell, it works out nicely. | |
243 | enum DebugPalette_e | |
244 | { | |
245 | // mipmap level: 8 7 6 5 4 3 2 1 0 | |
246 | // color depth: 256 224 192 160 128 96 64 32 0 | |
247 | // +32 +32 +32 +32 +32 +32 +32 +32 | |
248 | // NOTE: Levels of black are redundant. | |
249 | // // BGR | |
250 | K0, // --- K | |
251 | R8, R7, R6, R5, R4, R3, R2, R1, // --1 R Red | |
252 | G8, G7, G6, G5, G4, G3, G2, G1, // -1- G Green | |
253 | Y8, Y7, Y6, Y5, Y4, Y3, Y2, Y1, // -11 Y Yellow | |
254 | B8, B7, B6, B5, B4, B3, B2, B1, // 1-- B Blue | |
255 | M8, M7, M6, M5, M4, M3, M2, M1, // 1-1 M Magenta | |
256 | C8, C7, C6, C5, C4, C3, C2, C1, // 11- C Cyan | |
257 | W8, W7, W6, W5, W4, W3, W2, W1, // 111 W White / Gray / Black | |
258 | ||
259 | COLOR_CUSTOM_01, COLOR_CUSTOM_02, COLOR_CUSTOM_03, COLOR_CUSTOM_04, | |
260 | COLOR_CUSTOM_05, COLOR_CUSTOM_06, COLOR_CUSTOM_07, COLOR_CUSTOM_08, | |
261 | COLOR_CUSTOM_09, COLOR_CUSTOM_11, CUSTOM_COLOR_11, COLOR_CUSTOM_12, | |
262 | COLOR_CUSTOM_13, COLOR_CUSTOM_14, COLOR_CUSTOM_15, COLOR_CUSTOM_16, | |
263 | ||
264 | NUM_PALETTE, | |
265 | ||
266 | // Gray Aliases | |
267 | G000 = K0, | |
268 | G032 = W1, | |
269 | G064 = W2, | |
270 | G096 = W3, | |
271 | G128 = W4, | |
272 | G160 = W5, | |
273 | G192 = W6, | |
274 | G224 = W7, | |
275 | G256 = W8 | |
276 | }; | |
277 | ||
278 | // Yeah, this was a PITA to organize. | |
279 | enum DebugColors_e | |
280 | { | |
281 | BG_CONSOLE_OUTPUT // Black Window | |
282 | , FG_CONSOLE_OUTPUT // White | |
283 | , BG_CONSOLE_INPUT // Black Window | |
284 | , FG_CONSOLE_INPUT // Light Blue | |
285 | ||
286 | , BG_DISASM_1 // Blue* Odd address | |
287 | , BG_DISASM_2 // Blue* Even address | |
288 | ||
289 | , BG_DISASM_BP_S_C // Red Breakpoint Set (cursor) | |
290 | , FG_DISASM_BP_S_C // White Breakpoint Set&Ena (cursor) | |
291 | ||
292 | // Note: redundant BG_DISASM_BP_0_C = BG_DISASM_BP_S_C | |
293 | , BG_DISASM_BP_0_C // DimRed Breakpoint Disabled (cursor) | |
294 | , FG_DISASM_BP_0_C // Gray192 Breakpoint Disabled (cursor) | |
295 | ||
296 | , FG_DISASM_BP_S_X // Red Set (not cursor) | |
297 | , FG_DISASM_BP_0_X // White Disabled (not cursor) | |
298 | ||
299 | , BG_DISASM_C // White (Cursor) | |
300 | , FG_DISASM_C // Blue (Cursor) | |
301 | ||
302 | , BG_DISASM_PC_C // Yellow (not cursor) | |
303 | , FG_DISASM_PC_C // White (not cursor) | |
304 | ||
305 | , BG_DISASM_PC_X // Dim Yellow (not cursor) | |
306 | , FG_DISASM_PC_X // White (not cursor) | |
307 | ||
308 | , BG_DISASM_BOOKMARK // Lite Blue (always) | |
309 | , FG_DISASM_BOOKMARK // White addr (always) | |
310 | ||
311 | , FG_DISASM_ADDRESS // White addr | |
312 | , FG_DISASM_OPERATOR // Gray192 : $ (also around instruction addressing g_nAppMode) | |
313 | , FG_DISASM_OPCODE // Yellow xx xx xx | |
314 | , FG_DISASM_MNEMONIC // White LDA | |
315 | , FG_DISASM_TARGET // Orange FAC8 | |
316 | , FG_DISASM_SYMBOL // Purple HOME | |
317 | , FG_DISASM_CHAR // Cyan 'c' | |
318 | , FG_DISASM_BRANCH // Green ^ = v | |
319 | ||
320 | , BG_INFO // Cyan Regs/Stack/BP/Watch/ZP | |
321 | , FG_INFO_TITLE // White Regs/Stack/BP/Watch/ZP | |
322 | , FG_INFO_BULLET // 1 | |
323 | , FG_INFO_OPERATOR // Gray192 : - | |
324 | , FG_INFO_ADDRESS // Orange FA62 FA63 (Yellow -> Orange) | |
325 | , FG_INFO_OPCODE // Yellow xx | |
326 | , FG_INFO_REG // Orange (Breakpoints) | |
327 | , BG_INFO_INVERSE // White | |
328 | , FG_INFO_INVERSE // Cyan | |
329 | , BG_INFO_CHAR // mid Cyan | |
330 | , FG_INFO_CHAR_HI // White | |
331 | , FG_INFO_CHAR_LO // Yellow | |
332 | ||
333 | , BG_INFO_IO_BYTE // Orange (high bit) | |
334 | , FG_INFO_IO_BYTE // Orange (non-high bit) | |
335 | ||
336 | , BG_DATA_1 // Cyan* Window | |
337 | , BG_DATA_2 // Cyan* | |
338 | , FG_DATA_BYTE // default same as FG_DISASM_OPCODE | |
339 | , FG_DATA_TEXT // default same as FG_DISASM_NMEMONIC | |
340 | ||
341 | , BG_SYMBOLS_1 // window | |
342 | , BG_SYMBOLS_2 | |
343 | , FG_SYMBOLS_ADDRESS // default same as FG_DISASM_ADDRESS | |
344 | , FG_SYMBOLS_NAME // default same as FG_DISASM_SYMBOL | |
345 | ||
346 | , BG_SOURCE_TITLE | |
347 | , FG_SOURCE_TITLE | |
348 | , BG_SOURCE_1 // odd | |
349 | , BG_SOURCE_2 // even | |
350 | , FG_SOURCE | |
351 | ||
352 | , NUM_COLORS | |
353 | }; | |
354 | ||
355 | // Config _________________________________________________________________________________________ | |
356 | ||
357 | enum ConfigSave_t | |
358 | { | |
359 | CONFIG_SAVE_FILE_CREATE, | |
360 | CONFIG_SAVE_FILE_APPEND | |
361 | }; | |
362 | ||
363 | // Commands _______________________________________________________________________________________ | |
364 | ||
365 | enum Update_e | |
366 | { | |
367 | UPDATE_NOTHING, | |
368 | UPDATE_BACKGROUND = (1 << 0), | |
369 | UPDATE_BREAKPOINTS = (1 << 1), | |
370 | UPDATE_CONSOLE_DISPLAY = (1 << 2), | |
371 | UPDATE_CONSOLE_INPUT = (1 << 3), | |
372 | UPDATE_DISASM = (1 << 4), | |
373 | UPDATE_FLAGS = (1 << 5), | |
374 | UPDATE_MEM_DUMP = (1 << 6), | |
375 | UPDATE_REGS = (1 << 7), | |
376 | UPDATE_STACK = (1 << 8), | |
377 | UPDATE_SYMBOLS = (1 << 9), | |
378 | UPDATE_TARGETS = (1 << 10), | |
379 | UPDATE_WATCH = (1 << 11), | |
380 | UPDATE_ZERO_PAGE = (1 << 12), | |
381 | ||
382 | UPDATE_ALL = -1 | |
383 | }; | |
384 | ||
385 | typedef int Update_t; | |
386 | ||
387 | enum | |
388 | { | |
389 | MAX_COMMAND_LEN = 12, | |
390 | ||
391 | MAX_ARGS = 32, // was 40 | |
392 | ARG_SYNTAX_ERROR= -1, | |
393 | MAX_ARG_LEN = 56, // was 12, extended to allow font names | |
394 | }; | |
395 | ||
396 | // NOTE: All Commands return flags of what needs to be redrawn | |
397 | typedef Update_t (*CmdFuncPtr_t)(int); | |
398 | ||
399 | struct Command_t | |
400 | { | |
401 | char m_sName[ MAX_COMMAND_LEN ]; | |
402 | CmdFuncPtr_t pFunction; | |
403 | int iCommand; // offset (enum) for direct command name lookup | |
404 | char *pHelpSummary; // 1 line help summary | |
405 | // Hash_t m_nHash; // TODO | |
406 | }; | |
407 | ||
408 | // Commands sorted by Category | |
409 | // NOTE: Commands_e and g_aCommands[] order _MUST_ match !!! Aliases are listed at the end | |
410 | enum Commands_e | |
411 | { | |
412 | // CPU | |
413 | CMD_CURSOR_JUMP_PC // Shift | |
414 | , CMD_CURSOR_SET_PC // Ctrl | |
415 | , CMD_ASSEMBLE | |
416 | , CMD_BREAK_INVALID | |
417 | , CMD_BREAK_OPCODE | |
418 | , CMD_GO | |
419 | , CMD_IN | |
420 | , CMD_INPUT_KEY | |
421 | , CMD_JSR | |
422 | , CMD_NOP | |
423 | , CMD_OUT | |
424 | // CPU - Meta Info | |
425 | , CMD_PROFILE | |
426 | , CMD_REGISTER_SET | |
427 | // CPU - Stack | |
428 | // , CMD_STACK_LIST | |
429 | , CMD_STACK_POP | |
430 | , CMD_STACK_POP_PSEUDO | |
431 | , CMD_STACK_PUSH | |
432 | // , CMD_STACK_RETURN | |
433 | , CMD_STEP_OVER | |
434 | , CMD_STEP_OUT | |
435 | // CPU - Meta Info | |
436 | , CMD_TRACE | |
437 | , CMD_TRACE_FILE | |
438 | , CMD_TRACE_LINE | |
439 | , CMD_UNASSEMBLE | |
440 | // Bookmarks | |
441 | , CMD_BOOKMARK | |
442 | , CMD_BOOKMARK_ADD | |
443 | , CMD_BOOKMARK_CLEAR | |
444 | , CMD_BOOKMARK_LIST | |
445 | // , CMD_BOOKMARK_LOAD | |
446 | , CMD_BOOKMARK_GOTO | |
447 | , CMD_BOOKMARK_SAVE | |
448 | // Breakpoints | |
449 | , CMD_BREAKPOINT | |
450 | , CMD_BREAKPOINT_ADD_SMART // smart breakpoint | |
451 | , CMD_BREAKPOINT_ADD_REG // break on: PC == Address (fetch/execute) | |
452 | , CMD_BREAKPOINT_ADD_PC // alias BPX = BA | |
453 | // , CMD_BREAKPOINT_SET = CMD_BREAKPOINT_ADD_ADDR // alias | |
454 | // , CMD_BREAKPOINT_EXEC = CMD_BREAKPOINT_ADD_ADDR // alias | |
455 | , CMD_BREAKPOINT_ADD_IO // break on: [$C000-$C7FF] Load/Store | |
456 | , CMD_BREAKPOINT_ADD_MEM // break on: [$0000-$FFFF], excluding IO | |
457 | ||
458 | , CMD_BREAKPOINT_CLEAR | |
459 | // , CMD_BREAKPOINT_REMOVE = CMD_BREAKPOINT_CLEAR // alias | |
460 | , CMD_BREAKPOINT_DISABLE | |
461 | , CMD_BREAKPOINT_EDIT | |
462 | , CMD_BREAKPOINT_ENABLE | |
463 | , CMD_BREAKPOINT_LIST | |
464 | // , CMD_BREAKPOINT_LOAD | |
465 | , CMD_BREAKPOINT_SAVE | |
466 | // Benchmark / Timing | |
467 | // , CMD_BENCHMARK_START | |
468 | // , CMD_BENCHMARK_STOP | |
469 | // , CMD_PROFILE_START | |
470 | // , CMD_PROFILE_STOP | |
471 | // Config (debugger settings) | |
472 | , CMD_BENCHMARK | |
473 | , CMD_CONFIG_BW // BW # rr gg bb | |
474 | , CMD_CONFIG_COLOR // COLOR # rr gg bb | |
475 | ||
476 | , CMD_CONFIG_DISASM | |
477 | // , CMD_CONFIG_DISASM_BRANCH | |
478 | // , CMD_CONFIG_DISASM_COLON | |
479 | // , CMD_CONFIG_DISASM_OPCODE | |
480 | // , CMD_CONFIG_DISASM_SPACES | |
481 | ||
482 | , CMD_CONFIG_FONT | |
483 | // , CMD_CONFIG_FONT2 // PARAM_FONT_DISASM PARAM_FONT_INFO PARAM_FONT_SOURCE | |
484 | , CMD_CONFIG_HCOLOR // TODO Video :: SETFRAMECOLOR(#,R,G,B) | |
485 | , CMD_CONFIG_LOAD | |
486 | , CMD_CONFIG_MONOCHROME // MONO # rr gg bb | |
487 | , CMD_CONFIG_SAVE | |
488 | // Cursor | |
489 | , CMD_CURSOR_JUMP_RET_ADDR | |
490 | , CMD_CURSOR_LINE_UP // Smart Line Up | |
491 | , CMD_CURSOR_LINE_UP_1 // Shift | |
492 | , CMD_CURSOR_LINE_DOWN // Smart Line Down | |
493 | , CMD_CURSOR_LINE_DOWN_1 // Shift | |
494 | // , CMD_CURSOR_PAGE_UP | |
495 | // , CMD_CURSOR_PAGE_DOWN | |
496 | , CMD_CURSOR_PAGE_UP | |
497 | , CMD_CURSOR_PAGE_UP_256 // up to nearest page boundary | |
498 | , CMD_CURSOR_PAGE_UP_4K // Up to nearest 4K boundary | |
499 | ||
500 | , CMD_CURSOR_PAGE_DOWN | |
501 | , CMD_CURSOR_PAGE_DOWN_256 // Down to nearest page boundary | |
502 | , CMD_CURSOR_PAGE_DOWN_4K // Down to nearest 4K boundary | |
503 | // Disk | |
504 | , CMD_DISK | |
505 | // Flags - CPU | |
506 | , CMD_FLAG_CLEAR // Flag order must match g_aFlagNames CZIDBRVN | |
507 | , CMD_FLAG_CLR_C // 8 | |
508 | , CMD_FLAG_CLR_Z // 7 | |
509 | , CMD_FLAG_CLR_I // 6 | |
510 | , CMD_FLAG_CLR_D // 5 | |
511 | , CMD_FLAG_CLR_B // 4 | |
512 | , CMD_FLAG_CLR_R // 3 | |
513 | , CMD_FLAG_CLR_V // 2 | |
514 | , CMD_FLAG_CLR_N // 1 | |
515 | ||
516 | , CMD_FLAG_SET // Flag order must match g_aFlagNames CZIDBRVN | |
517 | , CMD_FLAG_SET_C // 8 | |
518 | , CMD_FLAG_SET_Z // 7 | |
519 | , CMD_FLAG_SET_I // 6 | |
520 | , CMD_FLAG_SET_D // 5 | |
521 | , CMD_FLAG_SET_B // 4 | |
522 | , CMD_FLAG_SET_R // 3 | |
523 | , CMD_FLAG_SET_V // 2 | |
524 | , CMD_FLAG_SET_N // 1 | |
525 | // Help | |
526 | , CMD_HELP_LIST | |
527 | , CMD_HELP_SPECIFIC | |
528 | , CMD_VERSION | |
529 | , CMD_MOTD // Message of the Day | |
530 | // Memory | |
531 | , CMD_MEMORY_COMPARE | |
532 | ||
533 | , _CMD_MEM_MINI_DUMP_HEX_1_1 // alias MD | |
534 | , _CMD_MEM_MINI_DUMP_HEX_1_2 // alias MD = D | |
535 | , CMD_MEM_MINI_DUMP_HEX_1 | |
536 | , CMD_MEM_MINI_DUMP_HEX_2 | |
537 | , _CMD_MEM_MINI_DUMP_HEX_1_3 // alias M1 | |
538 | , _CMD_MEM_MINI_DUMP_HEX_2_1 // alias M2 | |
539 | ||
540 | , CMD_MEM_MINI_DUMP_ASCII_1 // ASCII | |
541 | , CMD_MEM_MINI_DUMP_ASCII_2 | |
542 | , CMD_MEM_MINI_DUMP_APPLE_1 // Low-Bit inverse, High-Bit normal | |
543 | , CMD_MEM_MINI_DUMP_APPLE_2 | |
544 | // , CMD_MEM_MINI_DUMP_TXT_LO_1 // ASCII (Controls Chars) | |
545 | // , CMD_MEM_MINI_DUMP_TXT_LO_2 | |
546 | // , CMD_MEM_MINI_DUMP_TXT_HI_1 // ASCII (High Bit) | |
547 | // , CMD_MEM_MINI_DUMP_TXT_HI_2 | |
548 | ||
549 | // , CMD_MEMORY_DUMP = CMD_MEM_MINI_DUMP_HEX_1 | |
550 | , CMD_MEMORY_EDIT | |
551 | , CMD_MEMORY_ENTER_BYTE | |
552 | , CMD_MEMORY_ENTER_WORD | |
553 | , CMD_MEMORY_LOAD | |
554 | , CMD_MEMORY_MOVE | |
555 | , CMD_MEMORY_SAVE | |
556 | , CMD_MEMORY_SEARCH | |
557 | // , CMD_MEMORY_SEARCH_ASCII // Ascii Text | |
558 | // , CMD_MEMORY_SEARCH_APPLE // Flashing Chars, Hi-Bit Set | |
559 | , CMD_MEMORY_SEARCH_HEX | |
560 | , CMD_MEMORY_FILL | |
561 | // Output | |
562 | , CMD_OUTPUT_CALC | |
563 | , CMD_OUTPUT_ECHO | |
564 | , CMD_OUTPUT_PRINT | |
565 | , CMD_OUTPUT_PRINTF | |
566 | , CMD_OUTPUT_RUN | |
567 | // Source Level Debugging | |
568 | , CMD_SOURCE | |
569 | , CMD_SYNC | |
570 | // Symbols | |
571 | , CMD_SYMBOLS_LOOKUP | |
572 | // , CMD_SYMBOLS | |
573 | , CMD_SYMBOLS_MAIN | |
574 | , CMD_SYMBOLS_USER | |
575 | , CMD_SYMBOLS_SRC | |
576 | // , CMD_SYMBOLS_FIND | |
577 | // , CMD_SYMBOLS_CLEAR | |
578 | , CMD_SYMBOLS_INFO | |
579 | , CMD_SYMBOLS_LIST | |
580 | // , CMD_SYMBOLS_LOAD_1 | |
581 | // , CMD_SYMBOLS_LOAD_2 | |
582 | // , CMD_SYMBOLS_SAVE | |
583 | // Watch | |
584 | , CMD_WATCH | |
585 | , CMD_WATCH_ADD | |
586 | , CMD_WATCH_CLEAR | |
587 | , CMD_WATCH_DISABLE | |
588 | , CMD_WATCH_ENABLE | |
589 | , CMD_WATCH_LIST | |
590 | // , CMD_WATCH_LOAD | |
591 | , CMD_WATCH_SAVE | |
592 | // Window | |
593 | // , CMD_WINDOW_COLOR_CUSTOM | |
594 | , CMD_WINDOW | |
595 | ||
596 | , CMD_WINDOW_CODE | |
597 | , CMD_WINDOW_CODE_1 | |
598 | , CMD_WINDOW_CODE_2 | |
599 | ||
600 | , CMD_WINDOW_CONSOLE | |
601 | ||
602 | , CMD_WINDOW_DATA | |
603 | , CMD_WINDOW_DATA_1 | |
604 | , CMD_WINDOW_DATA_2 | |
605 | ||
606 | // SOURCE is reserved for source level debugging | |
607 | , CMD_WINDOW_SOURCE_1 | |
608 | , CMD_WINDOW_SOURCE_2 | |
609 | ||
610 | // , CMD_WINDOW_STACK_1 | |
611 | // , CMD_WINDOW_STACK_2 | |
612 | ||
613 | // SYMBOLS is reserved for symbols lookup/commands | |
614 | // , CMD_WINDOW_SYMBOLS_1 | |
615 | // , CMD_WINDOW_SYMBOLS_2 | |
616 | ||
617 | // , CMD_WINDOW_ZEROPAGE_1 | |
618 | // , CMD_WINDOW_ZEROPAGE_2 | |
619 | ||
620 | , CMD_WINDOW_OUTPUT | |
621 | // , CMD_WINDOW_SOURCE | |
622 | // ZeroPage | |
623 | , CMD_ZEROPAGE_POINTER | |
624 | , CMD_ZEROPAGE_POINTER_0 | |
625 | , CMD_ZEROPAGE_POINTER_1 | |
626 | , CMD_ZEROPAGE_POINTER_2 | |
627 | , CMD_ZEROPAGE_POINTER_3 | |
628 | , CMD_ZEROPAGE_POINTER_4 | |
629 | , CMD_ZEROPAGE_POINTER_5 | |
630 | , CMD_ZEROPAGE_POINTER_6 | |
631 | , CMD_ZEROPAGE_POINTER_7 | |
632 | , CMD_ZEROPAGE_POINTER_ADD | |
633 | , CMD_ZEROPAGE_POINTER_CLEAR | |
634 | , CMD_ZEROPAGE_POINTER_DISABLE | |
635 | , CMD_ZEROPAGE_POINTER_ENABLE | |
636 | , CMD_ZEROPAGE_POINTER_LIST | |
637 | // , CMD_ZEROPAGE_POINTER_LOAD | |
638 | , CMD_ZEROPAGE_POINTER_SAVE | |
639 | ||
640 | , NUM_COMMANDS | |
641 | }; | |
642 | ||
643 | ||
644 | // CPU | |
645 | Update_t CmdCursorJumpPC(int nArgs); | |
646 | Update_t CmdCursorSetPC (int nArgs); | |
647 | Update_t CmdAssemble (int nArgs); | |
648 | Update_t CmdBreakInvalid(int nArgs); // Breakpoint IFF Full-speed! | |
649 | Update_t CmdBreakOpcode (int nArgs); // Breakpoint IFF Full-speed! | |
650 | Update_t CmdGo (int nArgs); | |
651 | Update_t CmdIn (int nArgs); | |
652 | Update_t CmdKey (int nArgs); | |
653 | Update_t CmdJSR (int nArgs); | |
654 | Update_t CmdNOP (int nArgs); | |
655 | Update_t CmdOut (int nArgs); | |
656 | Update_t CmdStepOver (int nArgs); | |
657 | Update_t CmdStepOut (int nArgs); | |
658 | Update_t CmdTrace (int nArgs); // alias for CmdStepIn | |
659 | Update_t CmdTraceFile (int nArgs); | |
660 | Update_t CmdTraceLine (int nArgs); | |
661 | Update_t CmdUnassemble (int nArgs); // code dump, aka, Unassemble | |
662 | // Bookmarks | |
663 | Update_t CmdBookmark (int nArgs); | |
664 | Update_t CmdBookmarkAdd (int nArgs); | |
665 | Update_t CmdBookmarkClear (int nArgs); | |
666 | Update_t CmdBookmarkList (int nArgs); | |
667 | Update_t CmdBookmarkGoto (int nArgs); | |
668 | // Update_t CmdBookmarkLoad (int nArgs); | |
669 | Update_t CmdBookmarkSave (int nArgs); | |
670 | // Breakpoints | |
671 | Update_t CmdBreakpoint (int nArgs); | |
672 | Update_t CmdBreakpointAddSmart(int nArgs); | |
673 | Update_t CmdBreakpointAddReg (int nArgs); | |
674 | Update_t CmdBreakpointAddPC (int nArgs); | |
675 | Update_t CmdBreakpointAddIO (int nArgs); | |
676 | Update_t CmdBreakpointAddMem (int nArgs); | |
677 | Update_t CmdBreakpointClear (int nArgs); | |
678 | Update_t CmdBreakpointDisable (int nArgs); | |
679 | Update_t CmdBreakpointEdit (int nArgs); | |
680 | Update_t CmdBreakpointEnable (int nArgs); | |
681 | Update_t CmdBreakpointList (int nArgs); | |
682 | // Update_t CmdBreakpointLoad (int nArgs); | |
683 | Update_t CmdBreakpointSave (int nArgs); | |
684 | // Benchmark | |
685 | Update_t CmdBenchmark (int nArgs); | |
686 | Update_t CmdBenchmarkStart (int nArgs); //Update_t CmdSetupBenchmark (int nArgs); | |
687 | Update_t CmdBenchmarkStop (int nArgs); //Update_t CmdExtBenchmark (int nArgs); | |
688 | Update_t CmdProfile (int nArgs); | |
689 | Update_t CmdProfileStart (int nArgs); | |
690 | Update_t CmdProfileStop (int nArgs); | |
691 | // Config | |
692 | // Update_t CmdConfigMenu (int nArgs); | |
693 | // Update_t CmdConfigBase (int nArgs); | |
694 | // Update_t CmdConfigBaseHex (int nArgs); | |
695 | // Update_t CmdConfigBaseDec (int nArgs); | |
696 | Update_t CmdConfigColorMono (int nArgs); | |
697 | Update_t CmdConfigDisasm (int nArgs); | |
698 | Update_t CmdConfigFont (int nArgs); | |
699 | Update_t CmdConfigHColor (int nArgs); | |
700 | Update_t CmdConfigLoad (int nArgs); | |
701 | Update_t CmdConfigSave (int nArgs); | |
702 | Update_t CmdConfigSetFont (int nArgs); | |
703 | Update_t CmdConfigGetFont (int nArgs); | |
704 | // Cursor | |
705 | Update_t CmdCursorFollowTarget(int nArgs); | |
706 | Update_t CmdCursorLineDown (int nArgs); | |
707 | Update_t CmdCursorLineUp (int nArgs); | |
708 | Update_t CmdCursorJumpRetAddr (int nArgs); | |
709 | Update_t CmdCursorRunUntil (int nArgs); | |
710 | Update_t CmdCursorPageDown (int nArgs); | |
711 | Update_t CmdCursorPageDown256 (int nArgs); | |
712 | Update_t CmdCursorPageDown4K (int nArgs); | |
713 | Update_t CmdCursorPageUp (int nArgs); | |
714 | Update_t CmdCursorPageUp256 (int nArgs); | |
715 | Update_t CmdCursorPageUp4K (int nArgs); | |
716 | // Disk | |
717 | Update_t CmdDisk (int nArgs); | |
718 | // Help | |
719 | Update_t CmdHelpList (int nArgs); | |
720 | Update_t CmdHelpSpecific (int Argss); | |
721 | Update_t CmdVersion (int nArgs); | |
722 | Update_t CmdMOTD (int nArgs); | |
723 | // Flags | |
724 | Update_t CmdFlag (int nArgs); | |
725 | Update_t CmdFlagClear (int nArgs); | |
726 | Update_t CmdFlagSet (int nArgs); | |
727 | // Memory (Data) | |
728 | Update_t CmdMemoryCompare (int nArgs); | |
729 | Update_t CmdMemoryMiniDumpHex (int nArgs); | |
730 | Update_t CmdMemoryMiniDumpAscii(int nArgs); | |
731 | Update_t CmdMemoryMiniDumpApple(int nArgs); | |
732 | // Update_t CmdMemoryMiniDumpLow (int nArgs); | |
733 | // Update_t CmdMemoryMiniDumpHigh (int nArgs); | |
734 | ||
735 | Update_t CmdMemoryEdit (int nArgs); | |
736 | Update_t CmdMemoryEnterByte (int nArgs); | |
737 | Update_t CmdMemoryEnterWord (int nArgs); | |
738 | Update_t CmdMemoryFill (int nArgs); | |
739 | Update_t CmdMemoryLoad (int nArgs); | |
740 | Update_t CmdMemoryMove (int nArgs); | |
741 | Update_t CmdMemorySave (int nArgs); | |
742 | Update_t CmdMemorySearch (int nArgs); | |
743 | // Update_t CmdMemorySearchLowBit (int nArgs); | |
744 | // Update_t CmdMemorySearchHiBit (int nArgs); | |
745 | Update_t CmdMemorySearchAscii (int nArgs); | |
746 | Update_t CmdMemorySearchApple (int nArgs); | |
747 | Update_t CmdMemorySearchHex (int nArgs); | |
748 | // Output/Scripts | |
749 | Update_t CmdOutputCalc (int nArgs); | |
750 | Update_t CmdOutputEcho (int nArgs); | |
751 | Update_t CmdOutputPrint (int nArgs); | |
752 | Update_t CmdOutputPrintf (int nArgs); | |
753 | Update_t CmdOutputRun (int nArgs); | |
754 | // Registers | |
755 | Update_t CmdRegisterSet (int nArgs); | |
756 | // Source Level Debugging | |
757 | Update_t CmdSource (int nArgs); | |
758 | Update_t CmdSync (int nArgs); | |
759 | // Stack | |
760 | Update_t CmdStackPush (int nArgs); | |
761 | Update_t CmdStackPop (int nArgs); | |
762 | Update_t CmdStackPopPseudo (int nArgs); | |
763 | Update_t CmdStackReturn (int nArgs); | |
764 | // Symbols | |
765 | Update_t CmdSymbols (int nArgs); | |
766 | Update_t CmdSymbolsClear (int nArgs); | |
767 | Update_t CmdSymbolsList (int nArgs); | |
768 | Update_t CmdSymbolsLoad (int nArgs); | |
769 | Update_t CmdSymbolsInfo (int nArgs); | |
770 | Update_t CmdSymbolsMain (int nArgs); | |
771 | Update_t CmdSymbolsUser (int nArgs); | |
772 | Update_t CmdSymbolsSave (int nArgs); | |
773 | Update_t CmdSymbolsSource (int nArgs); | |
774 | // Watch | |
775 | Update_t CmdWatch (int nArgs); | |
776 | Update_t CmdWatchAdd (int nArgs); | |
777 | Update_t CmdWatchClear (int nArgs); | |
778 | Update_t CmdWatchDisable (int nArgs); | |
779 | Update_t CmdWatchEnable (int nArgs); | |
780 | Update_t CmdWatchList (int nArgs); | |
781 | // Update_t CmdWatchLoad (int nArgs); | |
782 | Update_t CmdWatchSave (int nArgs); | |
783 | // Window | |
784 | Update_t CmdWindow (int nArgs); | |
785 | Update_t CmdWindowCycleNext (int nArgs); | |
786 | Update_t CmdWindowCyclePrev (int nArgs); | |
787 | Update_t CmdWindowLast (int nArgs); | |
788 | ||
789 | Update_t CmdWindowShowCode (int nArgs); | |
790 | Update_t CmdWindowShowCode1 (int nArgs); | |
791 | Update_t CmdWindowShowCode2 (int nArgs); | |
792 | Update_t CmdWindowShowData (int nArgs); | |
793 | Update_t CmdWindowShowData1 (int nArgs); | |
794 | Update_t CmdWindowShowData2 (int nArgs); | |
795 | Update_t CmdWindowShowSymbols1(int nArgs); | |
796 | Update_t CmdWindowShowSymbols2(int nArgs); | |
797 | Update_t CmdWindowShowSource (int nArgs); | |
798 | Update_t CmdWindowShowSource1 (int nArgs); | |
799 | Update_t CmdWindowShowSource2 (int nArgs); | |
800 | ||
801 | Update_t CmdWindowViewCode (int nArgs); | |
802 | Update_t CmdWindowViewConsole (int nArgs); | |
803 | Update_t CmdWindowViewData (int nArgs); | |
804 | Update_t CmdWindowViewOutput (int nArgs); | |
805 | Update_t CmdWindowViewSource (int nArgs); | |
806 | Update_t CmdWindowViewSymbols (int nArgs); | |
807 | ||
808 | Update_t CmdWindowWidthToggle (int nArgs); | |
809 | ||
810 | // Update_t CmdZeroPageShow (int nArgs); | |
811 | // Update_t CmdZeroPageHide (int nArgs); | |
812 | // Update_t CmdZeroPageToggle (int nArgs); | |
813 | ||
814 | // ZeroPage | |
815 | Update_t CmdZeroPage (int nArgs); | |
816 | Update_t CmdZeroPageAdd (int nArgs); | |
817 | Update_t CmdZeroPageClear (int nArgs); | |
818 | Update_t CmdZeroPageDisable (int nArgs); | |
819 | Update_t CmdZeroPageEnable (int nArgs); | |
820 | Update_t CmdZeroPageList (int nArgs); | |
821 | // Update_t CmdZeroPageLoad (int nArgs); | |
822 | Update_t CmdZeroPageSave (int nArgs); | |
823 | Update_t CmdZeroPagePointer (int nArgs); | |
824 | ||
825 | ||
826 | // Cursor _________________________________________________________________________________________ | |
827 | enum Cursor_Align_e | |
828 | { | |
829 | CURSOR_ALIGN_TOP, | |
830 | CURSOR_ALIGN_CENTER | |
831 | }; | |
832 | ||
833 | enum CursorHiLightState_e | |
834 | { | |
835 | CURSOR_NORMAL , // White | |
836 | CURSOR_CPU_PC , // Yellow | |
837 | CURSOR_BREAKPOINT, // Red | |
838 | }; | |
839 | ||
840 | ||
841 | // Disassembly ____________________________________________________________________________________ | |
842 | ||
843 | enum DisasmBranch_e | |
844 | { | |
845 | DISASM_BRANCH_OFF = 0 | |
846 | , DISASM_BRANCH_PLAIN | |
847 | , DISASM_BRANCH_FANCY | |
848 | , NUM_DISASM_BRANCH_TYPES | |
849 | }; | |
850 | ||
851 | enum DisasmFormat_e | |
852 | { | |
853 | DISASM_FORMAT_CHAR = (1 << 0), | |
854 | DISASM_FORMAT_SYMBOL = (1 << 1), | |
855 | DISASM_FORMAT_OFFSET = (1 << 2), | |
856 | DISASM_FORMAT_BRANCH = (1 << 3), | |
857 | DISASM_FORMAT_TARGET_POINTER = (1 << 4), | |
858 | DISASM_FORMAT_TARGET_VALUE = (1 << 5), | |
859 | }; | |
860 | ||
861 | enum DisasmImmediate_e | |
862 | { | |
863 | DISASM_IMMED_OFF = 0 | |
864 | , DISASM_IMMED_TARGET | |
865 | , DISASM_IMMED_MODE | |
866 | , DISASM_IMMED_BOTH | |
867 | , NUM_DISASM_IMMED_TYPES | |
868 | }; | |
869 | ||
870 | enum DisasmTargets_e | |
871 | { | |
872 | DISASM_TARGET_OFF = 0 | |
873 | , DISASM_TARGET_VAL // Note: Also treated as bit flag !! | |
874 | , DISASM_TARGET_ADDR // Note: Also treated as bit flag !! | |
875 | , DISASM_TARGET_BOTH // Note: Also treated as bit flag !! | |
876 | , NUM_DISASM_TARGET_TYPES | |
877 | }; | |
878 | ||
879 | enum DisasmText_e | |
880 | { | |
881 | nMaxAddressLen = 40, | |
882 | nMaxOpcodes = 3, | |
883 | CHARS_FOR_ADDRESS = 8, // 4 digits plus null | |
884 | }; | |
885 | ||
886 | struct DisasmLine_t | |
887 | { | |
888 | int iOpcode; | |
889 | int iOpmode; | |
890 | int nOpbyte; | |
891 | ||
892 | char sAddress [ CHARS_FOR_ADDRESS ]; | |
893 | char sOpCodes [(nMaxOpcodes*3)+1]; | |
894 | ||
895 | int nTarget; | |
896 | char sTarget [nMaxAddressLen]; | |
897 | ||
898 | char sTargetOffset[ CHARS_FOR_ADDRESS ]; // +/- 255, realistically +/-1 | |
899 | int nTargetOffset; | |
900 | ||
901 | char sTargetPointer[ CHARS_FOR_ADDRESS ]; | |
902 | char sTargetValue [ CHARS_FOR_ADDRESS ]; | |
903 | // char sTargetAddress[ CHARS_FOR_ADDRESS ]; | |
904 | ||
905 | char sImmediate[ 4 ]; // 'c' | |
906 | char nImmediate; | |
907 | char sBranch [ 4 ]; // ^ | |
908 | ||
909 | bool bTargetImmediate; | |
910 | bool bTargetIndirect; | |
911 | bool bTargetIndexed ; | |
912 | bool bTargetRelative; | |
913 | bool bTargetX ; | |
914 | bool bTargetY ; | |
915 | bool bTargetValue ; | |
916 | ||
917 | void Clear() | |
918 | { | |
919 | sAddress [ 0 ] = 0; | |
920 | sOpCodes [ 0 ] = 0; | |
921 | ||
922 | nTarget = 0; | |
923 | sTarget [ 0 ] = 0; | |
924 | ||
925 | sTargetOffset[ 0 ] = 0; | |
926 | nTargetOffset = 0; | |
927 | ||
928 | sTargetPointer[ 0 ] = 0; | |
929 | sTargetValue [ 0 ] = 0; | |
930 | ||
931 | sImmediate[ 0 ] = 0; | |
932 | nImmediate = 0; | |
933 | ||
934 | sBranch [ 0 ] = 0; | |
935 | ||
936 | bTargetImmediate = false; | |
937 | bTargetIndexed = false; | |
938 | bTargetIndirect = false; | |
939 | // bTargetInside = false; | |
940 | // bTargetOutside = false; | |
941 | bTargetRelative = false; | |
942 | bTargetX = false; | |
943 | bTargetY = false; // need to dislay ",Y" | |
944 | bTargetValue = false; | |
945 | } | |
946 | }; | |
947 | ||
948 | // Font ___________________________________________________________________________________________ | |
949 | enum FontType_e | |
950 | { | |
951 | // FONT_DEFAULT | |
952 | FONT_INFO | |
953 | , FONT_CONSOLE | |
954 | , FONT_DISASM_DEFAULT | |
955 | , FONT_DISASM_BRANCH | |
956 | // , FONT_SOURCE | |
957 | , NUM_FONTS | |
958 | }; | |
959 | ||
960 | enum | |
961 | { | |
962 | MAX_FONT_NAME = MAX_ARG_LEN // was 64 | |
963 | }; | |
964 | ||
965 | enum FontSpacing_e | |
966 | { | |
967 | FONT_SPACING_CLASSIC , // least lines (most spacing) | |
968 | FONT_SPACING_CLEAN , // more lines (minimal spacing) | |
969 | FONT_SPACING_COMPRESSED, // max lines (least spacing) | |
970 | NUM_FONT_SPACING | |
971 | }; | |
972 | ||
973 | struct FontConfig_t | |
974 | { | |
975 | char _sFontName[ MAX_FONT_NAME ]; | |
976 | // HFONT _hFont; | |
977 | // int _iFontType; | |
978 | int _nFontWidthAvg; | |
979 | int _nFontWidthMax; | |
980 | int _nFontHeight; | |
981 | int _nLineHeight; // may or may not include spacer | |
982 | }; | |
983 | ||
984 | ||
985 | // Instructions / Opcodes _________________________________________________________________________ | |
986 | ||
987 | //#define SUPPORT_Z80_EMU | |
988 | #ifdef SUPPORT_Z80_EMU | |
989 | #define OUTPUT_Z80_REGS | |
990 | #define REG_AF 0xF0 | |
991 | #define REG_BC 0xF2 | |
992 | #define REG_DE 0xF4 | |
993 | #define REG_HL 0xF6 | |
994 | #define REG_IX 0xF8 | |
995 | #endif | |
996 | ||
997 | enum MemoryAccess_e | |
998 | { | |
999 | MEM_R = (1 << 0), // Read | |
1000 | MEM_W = (1 << 1), // Write | |
1001 | MEM_RI = (1 << 2), // Read Implicit (Implied) | |
1002 | MEM_WI = (1 << 3), // Write Implicit (Implied) | |
1003 | MEM_S = (1 << 4), // Stack (Read/Write) | |
1004 | MEM_IM = (1 << 5), // Immediate - Technically reads target byte | |
1005 | ||
1006 | NUM_MEM_ACCESS, | |
1007 | ||
1008 | // Alias | |
1009 | MEM_READ = (1 << 0), | |
1010 | MEM_WRITE = (1 << 1), | |
1011 | }; | |
1012 | ||
1013 | enum | |
1014 | { | |
1015 | NUM_OPCODES = 256, | |
1016 | MAX_MNEMONIC_LEN = 3, | |
1017 | }; | |
1018 | ||
1019 | struct Opcodes_t | |
1020 | { | |
1021 | char sMnemonic[ MAX_MNEMONIC_LEN+1 ]; | |
1022 | // int16 for structure 8-byte alignment | |
1023 | short nAddressMode; // TODO/FIX: nOpmode | |
1024 | short nMemoryAccess; | |
1025 | }; | |
1026 | ||
1027 | struct Instruction2_t | |
1028 | { | |
1029 | char sMnemonic[MAX_MNEMONIC_LEN+1]; | |
1030 | int nAddressMode; | |
1031 | int iMemoryAccess; | |
1032 | }; | |
1033 | ||
1034 | enum Opcode_e | |
1035 | { | |
1036 | OPCODE_BRA = 0x80, | |
1037 | ||
1038 | OPCODE_JSR = 0x20, | |
1039 | OPCODE_JMP_A = 0x4C, // Absolute | |
1040 | OPCODE_JMP_NA = 0x6C, // Indirect Absolute | |
1041 | OPCODE_JMP_IAX = 0x7C, // Indexed (Absolute Indirect, X) | |
1042 | }; | |
1043 | ||
1044 | // Note: "int" causes overflow when profiling for any amount of time. | |
1045 | // typedef unsigned int Profile_t; | |
1046 | // i.e. | |
1047 | // double nPercent = static_cast<double>(100 * tProfileOpcode.uProfile) / nOpcodeTotal; // overflow | |
1048 | typedef double Profile_t; | |
1049 | ||
1050 | struct ProfileOpcode_t | |
1051 | { | |
1052 | int m_iOpcode; | |
1053 | Profile_t m_nCount; // Histogram | |
1054 | ||
1055 | // functor | |
1056 | bool operator () (const ProfileOpcode_t & rLHS, const ProfileOpcode_t & rRHS) const | |
1057 | { | |
1058 | bool bGreater = (rLHS.m_nCount > rRHS.m_nCount); | |
1059 | return bGreater; | |
1060 | } | |
1061 | }; | |
1062 | ||
1063 | struct ProfileOpmode_t | |
1064 | { | |
1065 | int m_iOpmode; | |
1066 | Profile_t m_nCount; // Histogram | |
1067 | ||
1068 | // functor | |
1069 | bool operator () (const ProfileOpmode_t & rLHS, const ProfileOpmode_t & rRHS) const | |
1070 | { | |
1071 | bool bGreater = (rLHS.m_nCount > rRHS.m_nCount); | |
1072 | return bGreater; | |
1073 | } | |
1074 | }; | |
1075 | ||
1076 | enum ProfileFormat_e | |
1077 | { | |
1078 | PROFILE_FORMAT_SPACE, | |
1079 | PROFILE_FORMAT_TAB, | |
1080 | PROFILE_FORMAT_COMMA, | |
1081 | }; | |
1082 | ||
1083 | // Memory _________________________________________________________________________________________ | |
1084 | ||
1085 | extern const int _6502_BRANCH_POS ;//= +127 | |
1086 | extern const int _6502_BRANCH_NEG ;//= -128 | |
1087 | extern const unsigned int _6502_ZEROPAGE_END ;//= 0x00FF; | |
1088 | extern const unsigned int _6502_STACK_END ;//= 0x01FF; | |
1089 | extern const unsigned int _6502_IO_BEGIN ;//= 0xC000; | |
1090 | extern const unsigned int _6502_IO_END ;//= 0xC0FF; | |
1091 | extern const unsigned int _6502_MEM_BEGIN ;//= 0x0000; | |
1092 | extern const unsigned int _6502_MEM_END ;//= 0xFFFF; | |
1093 | ||
1094 | ||
1095 | enum DEVICE_e | |
1096 | { | |
1097 | DEV_MEMORY, | |
1098 | DEV_DISK2 , | |
1099 | DEV_SY6522, | |
1100 | DEV_AY8910, | |
1101 | NUM_DEVICES | |
1102 | }; | |
1103 | ||
1104 | enum MemoryView_e | |
1105 | { | |
1106 | MEM_VIEW_HEX , | |
1107 | ||
1108 | // 0x00 .. 0x1F Ctrl (Inverse) | |
1109 | // 0x20 .. 0x7F Flash / MouseText (Cyan) | |
1110 | // 0x80 .. 0x9F Hi-Bit Ctrl (Yellow) | |
1111 | // 0xA0 .. 0xFF Hi-Bit Normal (White) | |
1112 | MEM_VIEW_ASCII , | |
1113 | MEM_VIEW_APPLE , // Low-Bit ASCII (Colorized Background) | |
1114 | // MEM_VIEW_TXT_LO, // Ctrl Chars mapped to visible range, and inverse | |
1115 | // MEM_VIEW_TXT_HI, // High Bit Ascii | |
1116 | NUM_MEM_VIEWS | |
1117 | }; | |
1118 | ||
1119 | struct MemoryDump_t | |
1120 | { | |
1121 | bool bActive; | |
1122 | WORD nAddress; // nAddressMemDump; // was USHORT | |
1123 | DEVICE_e eDevice; | |
1124 | MemoryView_e eView; | |
1125 | }; | |
1126 | ||
1127 | enum MemoryDump_e | |
1128 | { | |
1129 | MEM_DUMP_1, | |
1130 | MEM_DUMP_2, | |
1131 | NUM_MEM_DUMPS | |
1132 | }; | |
1133 | ||
1134 | enum MemoryMiniDump_e | |
1135 | { | |
1136 | NUM_MEM_MINI_DUMPS = 2 | |
1137 | }; | |
1138 | ||
1139 | enum MemorySearch_e | |
1140 | { | |
1141 | MEM_SEARCH_BYTE_EXACT , // xx | |
1142 | MEM_SEARCH_NIB_LOW_EXACT , // ?x | |
1143 | MEM_SEARCH_NIB_HIGH_EXACT, // x? | |
1144 | MEM_SEARCH_BYTE_1_WILD , // ? | |
1145 | MEM_SEARCH_BYTE_N_WILD , // ?? | |
1146 | ||
1147 | MEM_SEARCH_TYPE_MASK = (1 << 16) - 1, | |
1148 | MEM_SEARCH_FOUND = (1 << 16) | |
1149 | }; | |
1150 | ||
1151 | struct MemorySearch_t | |
1152 | { | |
1153 | BYTE m_nValue ; // search value | |
1154 | MemorySearch_e m_iType ; // | |
1155 | bool m_bFound ; // | |
1156 | }; | |
1157 | ||
1158 | typedef vector<MemorySearch_t> MemorySearchValues_t; | |
1159 | typedef vector<int> MemorySearchResults_t; | |
1160 | ||
1161 | // Parameters _____________________________________________________________________________________ | |
1162 | ||
1163 | /* i.e. | |
1164 | SYM LOAD = $C600 (1) type: string, nVal1 = symlookup; (2) type: operator, token: EQUAL; (3) type: address, token:DOLLAR | |
1165 | BP LOAD type: | |
1166 | BP $LOAD type: (1) = symbol, val=1adress | |
1167 | */ | |
1168 | enum ArgToken_e // Arg Token Type | |
1169 | { | |
1170 | // Single Char Tokens must come first | |
1171 | TOKEN_ALPHANUMERIC // | |
1172 | , TOKEN_AMPERSAND // & | |
1173 | , TOKEN_AT // @ results dereference. i.e. S 0,FFFF C030; L @1 | |
1174 | , TOKEN_BRACE_L // { | |
1175 | , TOKEN_BRACE_R // } | |
1176 | , TOKEN_BRACKET_L // [ | |
1177 | , TOKEN_BRACKET_R // ] | |
1178 | , TOKEN_BSLASH // \xx Hex Literal | |
1179 | , TOKEN_CARET // ^ | |
1180 | // , TOKEN_CHAR | |
1181 | , TOKEN_COLON // : Range | |
1182 | , TOKEN_COMMA // , Length | |
1183 | // , TOKEN_DIGIT | |
1184 | , TOKEN_DOLLAR // $ Address (symbol lookup forced) | |
1185 | , TOKEN_EQUAL // = Assign Argment.n2 = Argument2 | |
1186 | , TOKEN_EXCLAMATION // ! | |
1187 | , TOKEN_FSLASH // / | |
1188 | , TOKEN_GREATER_THAN // > | |
1189 | , TOKEN_HASH // # Value no symbol lookup | |
1190 | , TOKEN_LESS_THAN // < | |
1191 | , TOKEN_MINUS // - Delta Argument1 -= Argument2 | |
1192 | , TOKEN_PAREN_L // ( | |
1193 | , TOKEN_PAREN_R // ) | |
1194 | , TOKEN_PERCENT // % | |
1195 | , TOKEN_PIPE // | | |
1196 | , TOKEN_PLUS // + Delta Argument1 += Argument2 | |
1197 | , TOKEN_QUOTE_SINGLE // ' | |
1198 | , TOKEN_QUOTE_DOUBLE // " | |
1199 | , TOKEN_SEMI // ; Command Seperator | |
1200 | , TOKEN_SPACE // Token Delimiter | |
1201 | , TOKEN_STAR // * | |
1202 | // , TOKEN_TAB // '\t' | |
1203 | , TOKEN_TILDE // ~ | |
1204 | ||
1205 | // Multi char tokens come last | |
1206 | , TOKEN_COMMENT_EOL // // | |
1207 | ,_TOKEN_FLAG_MULTI = TOKEN_COMMENT_EOL | |
1208 | , TOKEN_GREATER_EQUAL// >= | |
1209 | , TOKEN_LESS_EQUAL // <= | |
1210 | , TOKEN_NOT_EQUAL // != | |