├── .gitattributes ├── .gitignore ├── 6502_func_test.bin ├── 6502_func_test.dat ├── 6502_func_test.lst ├── 6502_functional_test.asm ├── BCDCodes.dev ├── BCDCodes.layout ├── Bin2Hex.dev ├── Bin2Hex.layout ├── ConsoleIO.cpp ├── ConsoleIO.h ├── DevJournal.txt ├── Display.cpp ├── Display.h ├── GraphDisp.cpp ├── GraphDisp.h ├── MKBasic.cpp ├── MKBasic.dev ├── MKBasic.h ├── MKBasic.layout ├── MKCpu.cpp ├── MKCpu.h ├── MKGenException.cpp ├── MKGenException.h ├── Makefile.win ├── MassStorage.cpp ├── MassStorage.h ├── MemMapDev.cpp ├── MemMapDev.h ├── Memory.cpp ├── Memory.h ├── Notes.txt ├── ProgrammersReferenceManual.txt ├── ReadMe.txt ├── TestBCD.65s ├── VMachine.cpp ├── VMachine.h ├── bcd.c ├── benchmarks.txt ├── bin2hex.c ├── c64_char.dat ├── dummy.ram ├── dummy.rom ├── eh_basic.asm ├── eh_basic_kow.asm ├── eh_basic_mk.asm ├── ehbas.dat ├── ehbas_grdemo.snap ├── ehbas_grdemo_loop.snap ├── ehbas_nogrdev.dat ├── ehbas_xx.dat ├── grdevdemo.bas ├── hello_world.bas ├── main.cpp ├── makefile ├── makefile.mingw ├── makeming.bat ├── microchess.asm ├── microchess.bin ├── microchess.cfg ├── microchess.dat ├── microchess.lst ├── mingw-w64.bat ├── numbers.bas ├── system.h ├── t_adc_bcd_01.65s ├── t_adc_bcd_01.dat ├── t_sbc_bcd_01.65s ├── t_sbc_bcd_01.dat ├── tall.bin ├── tall.dat ├── tb.asm ├── tb.dat ├── tb.snap ├── tbe.dat ├── test_char_io_01.65s ├── test_char_io_01.dat ├── test_grtxt.bas ├── testall.asm ├── testall.dat ├── testall.lst ├── testall.o ├── testall_cl65.cfg ├── testbcd.dat ├── tinybasic.asm ├── tinybasic.cfg └── tinybasic.dat /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /6502_func_test.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makarcz/vm6502/4166e540db12a8238f1896632f05afb2f4d45390/6502_func_test.bin -------------------------------------------------------------------------------- /BCDCodes.dev: -------------------------------------------------------------------------------- 1 | [Project] 2 | FileName=BCDCodes.dev 3 | Name=BCDCodes 4 | Type=1 5 | Ver=2 6 | ObjFiles= 7 | Includes= 8 | Libs= 9 | PrivateResource= 10 | ResourceIncludes= 11 | MakeIncludes= 12 | Compiler= 13 | CppCompiler= 14 | Linker= 15 | IsCpp=0 16 | Icon= 17 | ExeOutput= 18 | ObjectOutput= 19 | LogOutput= 20 | LogOutputEnabled=0 21 | OverrideOutput=0 22 | OverrideOutputName= 23 | HostApplication= 24 | UseCustomMakefile=0 25 | CustomMakefile= 26 | CommandLine= 27 | Folders= 28 | IncludeVersionInfo=0 29 | SupportXPThemes=0 30 | CompilerSet=3 31 | CompilerSettings=0000000100000000000000000 32 | UnitCount=1 33 | 34 | [VersionInfo] 35 | Major=1 36 | Minor=0 37 | Release=0 38 | Build=0 39 | LanguageID=1033 40 | CharsetID=1252 41 | CompanyName= 42 | FileVersion= 43 | FileDescription=Developed using the Dev-C++ IDE 44 | InternalName= 45 | LegalCopyright= 46 | LegalTrademarks= 47 | OriginalFilename= 48 | ProductName= 49 | ProductVersion= 50 | AutoIncBuildNr=0 51 | SyncProduct=1 52 | 53 | [Unit1] 54 | FileName=bcd.c 55 | CompileCpp=0 56 | Folder= 57 | Compile=1 58 | Link=1 59 | Priority=1000 60 | OverrideBuildCmd=0 61 | BuildCmd= 62 | 63 | -------------------------------------------------------------------------------- /BCDCodes.layout: -------------------------------------------------------------------------------- 1 | [Editors] 2 | Order=0 3 | Focused=0 4 | [Editor_0] 5 | CursorCol=1 6 | CursorRow=34 7 | TopLine=1 8 | LeftChar=1 9 | -------------------------------------------------------------------------------- /Bin2Hex.dev: -------------------------------------------------------------------------------- 1 | [Project] 2 | FileName=Bin2Hex.dev 3 | Name=Bin2Hex 4 | Type=1 5 | Ver=2 6 | ObjFiles= 7 | Includes= 8 | Libs= 9 | PrivateResource= 10 | ResourceIncludes= 11 | MakeIncludes= 12 | Compiler= 13 | CppCompiler= 14 | Linker= 15 | IsCpp=0 16 | Icon= 17 | ExeOutput= 18 | ObjectOutput= 19 | LogOutput= 20 | LogOutputEnabled=0 21 | OverrideOutput=0 22 | OverrideOutputName= 23 | HostApplication= 24 | UseCustomMakefile=0 25 | CustomMakefile= 26 | CommandLine= 27 | Folders= 28 | IncludeVersionInfo=0 29 | SupportXPThemes=0 30 | CompilerSet=3 31 | CompilerSettings=0000000100000000000000000 32 | UnitCount=1 33 | 34 | [VersionInfo] 35 | Major=1 36 | Minor=0 37 | Release=0 38 | Build=0 39 | LanguageID=1033 40 | CharsetID=1252 41 | CompanyName= 42 | FileVersion= 43 | FileDescription=Developed using the Dev-C++ IDE 44 | InternalName= 45 | LegalCopyright= 46 | LegalTrademarks= 47 | OriginalFilename= 48 | ProductName= 49 | ProductVersion= 50 | AutoIncBuildNr=0 51 | SyncProduct=1 52 | 53 | [Unit1] 54 | FileName=bin2hex.c 55 | CompileCpp=0 56 | Folder= 57 | Compile=1 58 | Link=1 59 | Priority=1000 60 | OverrideBuildCmd=0 61 | BuildCmd= 62 | 63 | -------------------------------------------------------------------------------- /Bin2Hex.layout: -------------------------------------------------------------------------------- 1 | [Editor_0] 2 | CursorCol=26 3 | CursorRow=111 4 | TopLine=28 5 | LeftChar=1 6 | [Editors] 7 | Order=0 8 | Focused=0 9 | -------------------------------------------------------------------------------- /ConsoleIO.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: ConsoleIO.cpp 7 | * 8 | * Purpose: Implementation of ConsoleIO class. 9 | * The ConsoleIO class has methods helpful when 10 | * UI is utilizing STDIO (DOS) console OR curses on 11 | * Linux. 12 | * 13 | * Date: 8/26/2016 14 | * 15 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 16 | * 17 | * Contact: makarcz@yahoo.com 18 | * 19 | * License Agreement and Warranty: 20 | 21 | This software is provided with No Warranty. 22 | I (Marek Karcz) will not be held responsible for any damage to 23 | computer systems, data or user's health resulting from use. 24 | Please proceed responsibly and apply common sense. 25 | This software is provided in hope that it will be useful. 26 | It is free of charge for non-commercial and educational use. 27 | Distribution of this software in non-commercial and educational 28 | derivative work is permitted under condition that original 29 | copyright notices and comments are preserved. Some 3-rd party work 30 | included with this project may require separate application for 31 | permission from their respective authors/copyright owners. 32 | 33 | *-------------------------------------------------------------------- 34 | */ 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "system.h" 40 | #include "ConsoleIO.h" 41 | 42 | #include "MKGenException.h" 43 | 44 | #if defined(WINDOWS) 45 | #include 46 | #endif 47 | 48 | #if defined(LINUX) 49 | #include 50 | #include 51 | #include 52 | #include 53 | 54 | static WINDOW *g_pWin = NULL; 55 | #endif 56 | 57 | using namespace std; 58 | 59 | namespace MKBasic { 60 | 61 | /* 62 | *-------------------------------------------------------------------- 63 | * Method: 64 | * Purpose: 65 | * Arguments: 66 | * Returns: 67 | *-------------------------------------------------------------------- 68 | */ 69 | ConsoleIO::ConsoleIO() 70 | { 71 | 72 | } 73 | 74 | /* 75 | *-------------------------------------------------------------------- 76 | * Method: 77 | * Purpose: 78 | * Arguments: 79 | * Returns: 80 | *-------------------------------------------------------------------- 81 | */ 82 | ConsoleIO::~ConsoleIO() 83 | { 84 | 85 | } 86 | 87 | #if defined(WINDOWS) 88 | 89 | /* 90 | *-------------------------------------------------------------------- 91 | * Method: ClearScreen() 92 | * Purpose: Clear the console screen. 93 | * Arguments: n/a 94 | * Returns: n/a 95 | *-------------------------------------------------------------------- 96 | */ 97 | void ConsoleIO::ClearScreen() 98 | { 99 | HANDLE hStdOut; 100 | CONSOLE_SCREEN_BUFFER_INFO csbi; 101 | DWORD count; 102 | DWORD cellCount; 103 | COORD homeCoords = { 0, 0 }; 104 | 105 | hStdOut = GetStdHandle( STD_OUTPUT_HANDLE ); 106 | if (hStdOut == INVALID_HANDLE_VALUE) return; 107 | 108 | /* Get the number of cells in the current buffer */ 109 | if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return; 110 | cellCount = csbi.dwSize.X *csbi.dwSize.Y; 111 | 112 | /* Fill the entire buffer with spaces */ 113 | if (!FillConsoleOutputCharacter( 114 | hStdOut, 115 | (TCHAR) ' ', 116 | cellCount, 117 | homeCoords, 118 | &count 119 | )) return; 120 | 121 | /* Fill the entire buffer with the current colors and attributes */ 122 | if (!FillConsoleOutputAttribute( 123 | hStdOut, 124 | csbi.wAttributes, 125 | cellCount, 126 | homeCoords, 127 | &count 128 | )) return; 129 | 130 | /* Move the cursor home */ 131 | SetConsoleCursorPosition( hStdOut, homeCoords ); 132 | } 133 | 134 | /* 135 | *-------------------------------------------------------------------- 136 | * Method: ScrHome() 137 | * Purpose: Bring the console cursor to home position. 138 | * Arguments: n/a 139 | * Returns: n/a 140 | *-------------------------------------------------------------------- 141 | */ 142 | void ConsoleIO::ScrHome() 143 | { 144 | HANDLE hStdOut; 145 | COORD homeCoords = { 0, 0 }; 146 | 147 | hStdOut = GetStdHandle( STD_OUTPUT_HANDLE ); 148 | if (hStdOut == INVALID_HANDLE_VALUE) return; 149 | 150 | /* Move the cursor home */ 151 | SetConsoleCursorPosition( hStdOut, homeCoords ); 152 | } 153 | 154 | #endif // WINDOWS 155 | 156 | #if defined(LINUX) 157 | 158 | /* 159 | *-------------------------------------------------------------------- 160 | * Method: ClearScreen() 161 | * Purpose: Clear the console screen. 162 | * Arguments: n/a 163 | * Returns: n/a 164 | *-------------------------------------------------------------------- 165 | */ 166 | void ConsoleIO::ClearScreen() 167 | { 168 | if (isendwin() || NULL == g_pWin) { 169 | system("clear"); 170 | } else { 171 | clear(); 172 | refresh(); 173 | } 174 | } 175 | 176 | /* 177 | *-------------------------------------------------------------------- 178 | * Method: ScrHome() 179 | * Purpose: Bring the console cursor to home position. 180 | * Arguments: n/a 181 | * Returns: n/a 182 | *-------------------------------------------------------------------- 183 | */ 184 | void ConsoleIO::ScrHome() 185 | { 186 | if (!isendwin() && NULL != g_pWin) { 187 | move(0, 0); 188 | refresh(); 189 | } else { 190 | cout << "\033[1;1H"; 191 | } 192 | } 193 | 194 | #endif // #define LINUX 195 | 196 | /* 197 | *-------------------------------------------------------------------- 198 | * Method: GetChar() 199 | * Purpose: Get character from console. 200 | * Arguments: n/a 201 | * Returns: int - character code. 202 | *-------------------------------------------------------------------- 203 | */ 204 | int ConsoleIO::GetChar() 205 | { 206 | #if defined(LINUX) 207 | if (!isendwin() && NULL != g_pWin) 208 | return getch(); 209 | else 210 | return getchar(); 211 | #else 212 | return getch(); 213 | #endif 214 | } 215 | /* 216 | *-------------------------------------------------------------------- 217 | * Method: KbHit() 218 | * Purpose: Check if key has been pressed. 219 | * Arguments: n/a 220 | * Returns: bool - true if key pressed 221 | *-------------------------------------------------------------------- 222 | */ 223 | bool ConsoleIO::KbHit() 224 | { 225 | #if defined(LINUX) 226 | if (!isendwin() && NULL != g_pWin) { 227 | int ch = getch(); 228 | 229 | if (ch != ERR) { 230 | ungetch(ch); 231 | return true; 232 | } else { 233 | return false; 234 | } 235 | } else { 236 | static const int STDIN = 0; 237 | static bool initialized = false; 238 | 239 | if (! initialized) { 240 | // Use termios to turn off line buffering 241 | termios term; 242 | tcgetattr(STDIN, &term); 243 | term.c_lflag &= ~(ICANON | ECHO); 244 | tcsetattr(STDIN, TCSANOW, &term); 245 | setbuf(stdin, NULL); 246 | initialized = true; 247 | } 248 | 249 | int bytesWaiting; 250 | ioctl(STDIN, FIONREAD, &bytesWaiting); 251 | return (bytesWaiting > 0); 252 | 253 | } 254 | #else 255 | return (kbhit() != 0); 256 | #endif 257 | } 258 | 259 | 260 | /* 261 | *-------------------------------------------------------------------- 262 | * Method: InitCursesScr() 263 | * Purpose: Initialize nsurses screen. 264 | * Arguments: n/a 265 | * Returns: n/a 266 | *-------------------------------------------------------------------- 267 | */ 268 | void ConsoleIO::InitCursesScr() 269 | { 270 | fflush(stdin); 271 | #if defined(LINUX) 272 | if (NULL == g_pWin) { 273 | g_pWin = initscr(); 274 | cbreak(); 275 | keypad(stdscr, TRUE); 276 | noecho(); 277 | nodelay(stdscr, TRUE); 278 | scrollok(stdscr, TRUE); 279 | } else if (isendwin()) { 280 | refresh(); 281 | } 282 | #endif 283 | } 284 | 285 | /* 286 | *-------------------------------------------------------------------- 287 | * Method: closeCursesScr() 288 | * Purpose: Close nsurses screen. 289 | * Arguments: n/a 290 | * Returns: n/a 291 | *-------------------------------------------------------------------- 292 | */ 293 | void ConsoleIO::CloseCursesScr() 294 | { 295 | #if defined(LINUX) 296 | if (!isendwin() && NULL != g_pWin) { 297 | endwin(); 298 | } 299 | #endif 300 | } 301 | 302 | /* 303 | *-------------------------------------------------------------------- 304 | * Method: PrintChar() 305 | * Purpose: Print character on the screen. 306 | * Arguments: char - character. 307 | * Returns: n/a 308 | *-------------------------------------------------------------------- 309 | */ 310 | void ConsoleIO::PrintChar(char c) 311 | { 312 | #if defined(LINUX) 313 | if (!isendwin() && NULL != g_pWin) { 314 | echochar(c); 315 | } else { 316 | cout << c << flush; 317 | } 318 | #else 319 | cout << c; 320 | #endif 321 | } 322 | 323 | /* 324 | *-------------------------------------------------------------------- 325 | * Method: PrintString() 326 | * Purpose: Print string on the screen. 327 | * Arguments: char * - pointer to char array. 328 | * Returns: n/a 329 | *-------------------------------------------------------------------- 330 | */ 331 | void ConsoleIO::PrintString(string s) 332 | { 333 | #if defined(LINUX) 334 | if (!isendwin() && NULL != g_pWin) { 335 | addstr(s.c_str()); 336 | refresh(); 337 | } else { 338 | cout << s; 339 | } 340 | #else 341 | cout << s; 342 | #endif 343 | } 344 | 345 | /* 346 | *-------------------------------------------------------------------- 347 | * Method: Beep() 348 | * Purpose: 349 | * Arguments: 350 | * Returns: 351 | *-------------------------------------------------------------------- 352 | */ 353 | void ConsoleIO::Beep() 354 | { 355 | #if defined(LINUX) 356 | if (!isendwin() && NULL != g_pWin) { 357 | beep(); 358 | } else { 359 | cout << "\a"; 360 | } 361 | #else 362 | cout << "\a"; 363 | #endif 364 | } 365 | 366 | } // END namespace MKBasic 367 | -------------------------------------------------------------------------------- /ConsoleIO.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: ConsoleIO.h 7 | * 8 | * Purpose: Prototype of ConsoleIO class. 9 | * 10 | * Date: 8/26/2016 11 | * 12 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 13 | * 14 | * Contact: makarcz@yahoo.com 15 | * 16 | * License Agreement and Warranty: 17 | 18 | This software is provided with No Warranty. 19 | I (Marek Karcz) will not be held responsible for any damage to 20 | computer systems, data or user's health resulting from use. 21 | Please proceed responsibly and apply common sense. 22 | This software is provided in hope that it will be useful. 23 | It is free of charge for non-commercial and educational use. 24 | Distribution of this software in non-commercial and educational 25 | derivative work is permitted under condition that original 26 | copyright notices and comments are preserved. Some 3-rd party work 27 | included with this project may require separate application for 28 | permission from their respective authors/copyright owners. 29 | 30 | *-------------------------------------------------------------------- 31 | */ 32 | #ifndef CONSOLEIO_H 33 | #define CONSOLEIO_H 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "system.h" 40 | 41 | //#define WINDOWS 1 42 | #if defined (WINDOWS) 43 | #include 44 | #endif 45 | 46 | using namespace std; 47 | 48 | namespace MKBasic { 49 | 50 | class ConsoleIO 51 | { 52 | public: 53 | 54 | ConsoleIO(); 55 | ~ConsoleIO(); 56 | 57 | void ClearScreen(); 58 | void ScrHome(); 59 | void InitCursesScr(); 60 | void CloseCursesScr(); 61 | void PrintChar(char c); 62 | void PrintString(string s); 63 | bool KbHit(); 64 | int GetChar(); 65 | void Beep(); 66 | 67 | }; 68 | 69 | } // namespace MKBasic 70 | 71 | #endif // #ifndef CONSOLEIO_H 72 | -------------------------------------------------------------------------------- /Display.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: Display.cpp 7 | * 8 | * Purpose: Implementation of Display class. 9 | * The Display class emulates the character I/O device. 10 | * It defines the abstract device. The actual 11 | * input/output to the screen of the platform on which 12 | * the emulator runs is defined in MemMapDev class 13 | * or on higher level of abstraction. 14 | * 15 | * Date: 8/25/2016 16 | * 17 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 18 | * 19 | * Contact: makarcz@yahoo.com 20 | * 21 | * License Agreement and Warranty: 22 | 23 | This software is provided with No Warranty. 24 | I (Marek Karcz) will not be held responsible for any damage to 25 | computer systems, data or user's health resulting from use. 26 | Please proceed responsibly and apply common sense. 27 | This software is provided in hope that it will be useful. 28 | It is free of charge for non-commercial and educational use. 29 | Distribution of this software in non-commercial and educational 30 | derivative work is permitted under condition that original 31 | copyright notices and comments are preserved. Some 3-rd party work 32 | included with this project may require separate application for 33 | permission from their respective authors/copyright owners. 34 | 35 | *-------------------------------------------------------------------- 36 | */ 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "Display.h" 42 | #include "MKGenException.h" 43 | 44 | using namespace std; 45 | 46 | 47 | #if defined(LINUX) 48 | #include 49 | 50 | extern bool g_initialized; 51 | 52 | #endif 53 | 54 | /* 55 | *-------------------------------------------------------------------- 56 | * Method: 57 | * Purpose: 58 | * Arguments: 59 | * Returns: 60 | *-------------------------------------------------------------------- 61 | */ 62 | 63 | namespace MKBasic { 64 | 65 | /* 66 | *-------------------------------------------------------------------- 67 | * Method: 68 | * Purpose: 69 | * Arguments: 70 | * Returns: 71 | *-------------------------------------------------------------------- 72 | */ 73 | Display::Display() 74 | { 75 | InitScr(); 76 | } 77 | 78 | /* 79 | *-------------------------------------------------------------------- 80 | * Method: 81 | * Purpose: 82 | * Arguments: 83 | * Returns: 84 | *-------------------------------------------------------------------- 85 | */ 86 | Display::~Display() 87 | { 88 | } 89 | 90 | /* 91 | *-------------------------------------------------------------------- 92 | * Method: InitScr() 93 | * Purpose: Initialize screen. 94 | * Arguments: n/a 95 | * Returns: n/a 96 | *-------------------------------------------------------------------- 97 | */ 98 | void Display::InitScr() 99 | { 100 | mpConIO = new ConsoleIO(); 101 | if (NULL == mpConIO) 102 | throw MKGenException("Display::InitScr() : Out of memory - ConsoleIO"); 103 | mLastChar = 0; 104 | mScrLines = SCREENDIM_ROW; 105 | mScrColumns = SCREENDIM_COL; 106 | mShellConsoleWidth = GetConsoleWidth(); 107 | if (mScrColumns > mShellConsoleWidth) { 108 | mScrColumns = mShellConsoleWidth; 109 | } 110 | ClrScr(); 111 | } 112 | 113 | #if defined(WINDOWS) 114 | 115 | #include 116 | #include 117 | 118 | /* 119 | *-------------------------------------------------------------------- 120 | * Method: GetConsoleWidth() 121 | * Purpose: Obtain the width of shell console (the real one, not 122 | * the emulated one) on Windows. 123 | * Arguments: n/a 124 | * Returns: int - width of the shell console. 125 | *-------------------------------------------------------------------- 126 | */ 127 | int Display::GetConsoleWidth() 128 | { 129 | HANDLE hStdOut; 130 | CONSOLE_SCREEN_BUFFER_INFO csbi; 131 | 132 | hStdOut = GetStdHandle( STD_OUTPUT_HANDLE ); 133 | if (hStdOut == INVALID_HANDLE_VALUE) return -1; 134 | 135 | if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return -2; 136 | 137 | return csbi.dwSize.X; 138 | } 139 | 140 | #endif 141 | 142 | #if defined(LINUX) 143 | 144 | #include 145 | 146 | /* 147 | *-------------------------------------------------------------------- 148 | * Method: GetConsoleWidth() 149 | * Purpose: Obtain the width of shell console (the real one, not 150 | * the emulated one) on Linux. 151 | * Arguments: n/a 152 | * Returns: int - width of the shell console. 153 | *-------------------------------------------------------------------- 154 | */ 155 | int Display::GetConsoleWidth() 156 | { 157 | unsigned int conwidth = SCREENDIM_COL; 158 | char *termtype = getenv("TERM"); 159 | static char termbuf[2048]; 160 | 161 | if (tgetent(termbuf, termtype) < 0) { 162 | cout << "WARNING: Could not access the termcap data base." << endl; 163 | cout << " Unable to determine console width." << endl; 164 | } else { 165 | conwidth = tgetnum("co"); 166 | } 167 | 168 | return conwidth; 169 | } 170 | 171 | #endif 172 | 173 | /* 174 | *-------------------------------------------------------------------- 175 | * Method: 176 | * Purpose: 177 | * Arguments: 178 | * Returns: 179 | *-------------------------------------------------------------------- 180 | */ 181 | void Display::ScrollUp() 182 | { 183 | for (unsigned int row=0; row= mScrLines) { 255 | ScrollUp(); 256 | mCursorCoord.row = mScrLines-1; 257 | } 258 | } else if (c == SCREENSPECCHARS_CR) { 259 | mLastChar = SCREENSPECCHARS_CR; 260 | mCursorCoord.col = 0; 261 | } else if (c == SCREENSPECCHARS_TB) { 262 | mLastChar = SCREENSPECCHARS_TB; 263 | mCursorCoord.col += DISP_TABSIZE; 264 | if (mCursorCoord.col >= mScrColumns) { 265 | mCursorCoord.col = mScrColumns-1; // must work on it some more 266 | } 267 | } else if (c == SCREENSPECCHARS_BS) { 268 | mLastChar = SCREENSPECCHARS_BS; 269 | if (mCursorCoord.col > 0) mCursorCoord.col--; 270 | } else if (c == SCREENSPECCHARS_BE) { 271 | mLastChar = SCREENSPECCHARS_BE; 272 | // no action 273 | } 274 | else { 275 | mScreen[mCursorCoord.row][mCursorCoord.col] = c; 276 | mLastChar = c; 277 | mCursorCoord.col++; 278 | if (mCursorCoord.col >= mScrColumns) { 279 | mCursorCoord.col = 0; 280 | mCursorCoord.row++; 281 | if (mCursorCoord.row >= mScrLines) { 282 | ScrollUp(); 283 | mCursorCoord.row = mScrLines-1; 284 | } 285 | } 286 | } 287 | } 288 | } 289 | 290 | /* 291 | *-------------------------------------------------------------------- 292 | * Method: ClrScr() 293 | * Purpose: Fill the screen with spaces. Set cursor in left-upper 294 | * corner. 295 | * Arguments: n/a 296 | * Returns: n/a 297 | *-------------------------------------------------------------------- 298 | */ 299 | void Display::ClrScr() 300 | { 301 | for (unsigned int col=0; col mScrColumns) line = line + "\n"; 352 | scr = scr + line; 353 | } 354 | mpConIO->PrintString(scr); 355 | } 356 | 357 | /* 358 | *-------------------------------------------------------------------- 359 | * Method: GetCursorCoord() 360 | * Purpose: Get cursor coordinates. 361 | * Arguments: n/a 362 | * Returns: pointer to cursor coordinates 363 | *-------------------------------------------------------------------- 364 | */ 365 | CursorCoord *Display::GetCursorCoord() 366 | { 367 | return &mCursorCoord; 368 | } 369 | 370 | /* 371 | *-------------------------------------------------------------------- 372 | * Method: 373 | * Purpose: 374 | * Arguments: 375 | * Returns: 376 | *-------------------------------------------------------------------- 377 | */ 378 | char Display::GetLastChar() 379 | { 380 | return mLastChar; 381 | } 382 | 383 | } // namespace MKBasic 384 | -------------------------------------------------------------------------------- /Display.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: Display.h 7 | * 8 | * Purpose: Prototype of Display class and all supportig data 9 | * structures, enumerations, constants and macros. 10 | * 11 | * Date: 8/25/2016 12 | * 13 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 14 | * 15 | * Contact: makarcz@yahoo.com 16 | * 17 | * License Agreement and Warranty: 18 | 19 | This software is provided with No Warranty. 20 | I (Marek Karcz) will not be held responsible for any damage to 21 | computer systems, data or user's health resulting from use. 22 | Please proceed responsibly and apply common sense. 23 | This software is provided in hope that it will be useful. 24 | It is free of charge for non-commercial and educational use. 25 | Distribution of this software in non-commercial and educational 26 | derivative work is permitted under condition that original 27 | copyright notices and comments are preserved. Some 3-rd party work 28 | included with this project may require separate application for 29 | permission from their respective authors/copyright owners. 30 | 31 | *-------------------------------------------------------------------- 32 | */ 33 | #ifndef DISPLAY_H 34 | #define DISPLAY_H 35 | 36 | #include "system.h" 37 | #include "ConsoleIO.h" 38 | 39 | #define DISP_TABSIZE 4 40 | 41 | namespace MKBasic { 42 | 43 | enum eScreenDimensions { 44 | SCREENDIM_COL = 80, 45 | SCREENDIM_ROW = 24 46 | }; 47 | 48 | enum eScreenSpecChars { 49 | SCREENSPECCHARS_NL = (int)'\n', // new line 50 | SCREENSPECCHARS_CR = (int)'\r', // caret 51 | SCREENSPECCHARS_TB = (int)'\t', // tab 52 | SCREENSPECCHARS_BS = (int)'\b', // backspace 53 | SCREENSPECCHARS_BE = (int)'\a' // bell 54 | }; 55 | 56 | struct CursorCoord { 57 | unsigned int row; 58 | unsigned int col; 59 | }; 60 | 61 | class Display 62 | { 63 | public: 64 | 65 | Display(); 66 | ~Display(); 67 | void GotoXY(unsigned int col, unsigned int row); 68 | void PutChar(char c); 69 | void ClrScr(); 70 | char GetCharAt(unsigned int col, unsigned int row); 71 | void ShowScr(); 72 | CursorCoord *GetCursorCoord(); 73 | char GetLastChar(); 74 | 75 | protected: 76 | 77 | private: 78 | 79 | char mScreen[SCREENDIM_ROW][SCREENDIM_COL]; 80 | char mLastChar; 81 | CursorCoord mCursorCoord; 82 | unsigned int mShellConsoleWidth; 83 | unsigned int mScrLines; 84 | unsigned int mScrColumns; 85 | ConsoleIO *mpConIO; 86 | 87 | void InitScr(); 88 | void ScrollUp(); 89 | bool IsSpecChar(char c); 90 | int GetConsoleWidth(); 91 | 92 | }; 93 | 94 | } // namespace MKBasic 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /GraphDisp.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: GraphDisp.h 7 | * 8 | * Purpose: Prototype of GraphDisp class and supporting data 9 | * structures, enumerations, constants and macros. 10 | * 11 | * Date: 8/25/2016 12 | * 13 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 14 | * 15 | * Contact: makarcz@yahoo.com 16 | * 17 | * License Agreement and Warranty: 18 | 19 | This software is provided with No Warranty. 20 | I (Marek Karcz) will not be held responsible for any damage to 21 | computer systems, data or user's health resulting from use. 22 | Please proceed responsibly and apply common sense. 23 | This software is provided in hope that it will be useful. 24 | It is free of charge for non-commercial and educational use. 25 | Distribution of this software in non-commercial and educational 26 | derivative work is permitted under condition that original 27 | copyright notices and comments are preserved. Some 3-rd party work 28 | included with this project may require separate application for 29 | permission from their respective authors/copyright owners. 30 | 31 | *-------------------------------------------------------------------- 32 | */ 33 | #ifndef GRAPHDISP_H 34 | #define GRAPHDISP_H 35 | 36 | /* 37 | * Rudimentary emulation of generic raster graphics RGB display device. 38 | */ 39 | 40 | #include 41 | #include 42 | 43 | // defaults 44 | #define GRDISP_VR_X 320 45 | #define GRDISP_VR_Y 200 46 | #define CHROM_8x8_SIZE 2048 47 | 48 | using namespace std; 49 | 50 | namespace MKBasic { 51 | 52 | const int GRAPHDISP_MAXW = 960; // "real" display width or maximum virtual width 53 | const int GRAPHDISP_MAXH = 600; // "real" display width or maximum virtual height 54 | 55 | class GraphDisp { 56 | 57 | public: 58 | 59 | bool mContLoop; // = true; 60 | bool mMainLoopActive; // = false; 61 | 62 | GraphDisp(); 63 | GraphDisp(int width, int height); 64 | ~GraphDisp(); 65 | void Start(GraphDisp *pgd); 66 | void Stop(); 67 | void SetPixel(int x, int y); 68 | void ErasePixel(int x, int y); 69 | void DrawLine(int x1, int y1, int x2, int y2); 70 | void EraseLine(int x1, int y1, int x2, int y2); 71 | void SetBgColor(int r, int g, int b); 72 | void SetFgColor(int r, int g, int b); 73 | void Update(); 74 | void ReadEvents(); 75 | void ClearScreen(); 76 | //void MainLoop(); 77 | bool IsMainLoopActive(); 78 | void PrintChar8x8(int code, int col, int row, bool reversed); 79 | void CopyCharRom8x8(unsigned char *pchrom); 80 | 81 | private: 82 | 83 | int mWidth; // virtual display width 84 | int mHeight; // virtual display height 85 | int mPixelSizeX; // virtual pixel width 86 | int mPixelSizeY; // virtual pixel height 87 | int mWinPosX; // SDL window position coordinate X 88 | int mWinPosY; // SDL window position coordinate Y 89 | int mBgRgbR; // bg color, RGB red intensity 90 | int mBgRgbG; // bg color, RGB green intensity 91 | int mBgRgbB; // bg color, RGB blue intensity 92 | int mFgRgbR; // fg color, RGB red intensity 93 | int mFgRgbG; // fg color, RGB green intensity 94 | int mFgRgbB; // fg color, RGB blue intensity 95 | SDL_Window *mpWindow; 96 | SDL_Surface *mpSurface; 97 | SDL_Renderer *mpRenderer; 98 | thread mMainLoopThread; 99 | unsigned char mCharROM8x8[CHROM_8x8_SIZE]; 100 | 101 | void Initialize(); 102 | void UpdateSurface(); 103 | void Clear(); 104 | void GetDesktopResolution(int& horizontal, int& vertical); 105 | void DrawLine(int x1, int y1, int x2, int y2, bool draworerase); 106 | void RenderPixel(int x, int y, bool set); 107 | void RenderChar8x8(unsigned char chdef[8], int x, int y, bool reversed); 108 | 109 | }; // class GraphDisp 110 | 111 | } // namespace MKBasic 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /MKBasic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: 7 | * 8 | * Purpose: Implementation of MKBasic class. 9 | * NOTE: This is obsolete concept and will likely be 10 | * removed from project. 11 | * 12 | * Date: 8/25/2016 13 | * 14 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 15 | * 16 | * Contact: makarcz@yahoo.com 17 | * 18 | * License Agreement and Warranty: 19 | 20 | This software is provided with No Warranty. 21 | I (Marek Karcz) will not be held responsible for any damage to 22 | computer systems, data or user's health resulting from use. 23 | Please proceed responsibly and apply common sense. 24 | This software is provided in hope that it will be useful. 25 | It is free of charge for non-commercial and educational use. 26 | Distribution of this software in non-commercial and educational 27 | derivative work is permitted under condition that original 28 | copyright notices and comments are preserved. Some 3-rd party work 29 | included with this project may require separate application for 30 | permission from their respective authors/copyright owners. 31 | 32 | *-------------------------------------------------------------------- 33 | */ 34 | #include "MKBasic.h" 35 | 36 | namespace MKBasic { 37 | 38 | MKBasic::MKBasic() 39 | { 40 | } 41 | 42 | MKBasic::~MKBasic() 43 | { 44 | } 45 | 46 | } // namespace MKBasic 47 | -------------------------------------------------------------------------------- /MKBasic.dev: -------------------------------------------------------------------------------- 1 | [Project] 2 | FileName=MKBasic.dev 3 | Name=MKBasic 4 | Type=1 5 | Ver=2 6 | ObjFiles= 7 | Includes= 8 | Libs= 9 | PrivateResource= 10 | ResourceIncludes= 11 | MakeIncludes= 12 | Compiler= 13 | CppCompiler= 14 | Linker= 15 | IsCpp=1 16 | Icon= 17 | ExeOutput= 18 | ObjectOutput= 19 | LogOutput= 20 | LogOutputEnabled=0 21 | OverrideOutput=0 22 | OverrideOutputName=MKBasic.exe 23 | HostApplication= 24 | UseCustomMakefile=0 25 | CustomMakefile= 26 | CommandLine= 27 | Folders= 28 | IncludeVersionInfo=0 29 | SupportXPThemes=0 30 | CompilerSet=3 31 | CompilerSettings=00000001c0111000001000000 32 | UnitCount=14 33 | 34 | [VersionInfo] 35 | Major=1 36 | Minor=0 37 | Release=0 38 | Build=0 39 | LanguageID=1033 40 | CharsetID=1252 41 | CompanyName= 42 | FileVersion=1.0.0.0 43 | FileDescription=Developed using the Dev-C++ IDE 44 | InternalName= 45 | LegalCopyright= 46 | LegalTrademarks= 47 | OriginalFilename= 48 | ProductName= 49 | ProductVersion=1.0.0.0 50 | AutoIncBuildNr=0 51 | SyncProduct=1 52 | 53 | [Unit1] 54 | FileName=main.cpp 55 | CompileCpp=1 56 | Folder= 57 | Compile=1 58 | Link=1 59 | Priority=1000 60 | OverrideBuildCmd=0 61 | BuildCmd= 62 | 63 | [Unit2] 64 | FileName=VMachine.h 65 | CompileCpp=1 66 | Folder= 67 | Compile=1 68 | Link=1 69 | Priority=1000 70 | OverrideBuildCmd=0 71 | BuildCmd= 72 | 73 | [Unit3] 74 | FileName=VMachine.cpp 75 | CompileCpp=1 76 | Folder= 77 | Compile=1 78 | Link=1 79 | Priority=1000 80 | OverrideBuildCmd=0 81 | BuildCmd= 82 | 83 | [Unit4] 84 | FileName=MKBasic.h 85 | CompileCpp=1 86 | Folder= 87 | Compile=1 88 | Link=1 89 | Priority=1000 90 | OverrideBuildCmd=0 91 | BuildCmd= 92 | 93 | [Unit5] 94 | FileName=MKBasic.cpp 95 | CompileCpp=1 96 | Folder= 97 | Compile=1 98 | Link=1 99 | Priority=1000 100 | OverrideBuildCmd=0 101 | BuildCmd= 102 | 103 | [Unit6] 104 | FileName=MKCpu.h 105 | CompileCpp=1 106 | Folder= 107 | Compile=1 108 | Link=1 109 | Priority=1000 110 | OverrideBuildCmd=0 111 | BuildCmd= 112 | 113 | [Unit7] 114 | FileName=MKCpu.cpp 115 | CompileCpp=1 116 | Folder= 117 | Compile=1 118 | Link=1 119 | Priority=1000 120 | OverrideBuildCmd=0 121 | BuildCmd= 122 | 123 | [Unit8] 124 | FileName=Memory.h 125 | CompileCpp=1 126 | Folder= 127 | Compile=1 128 | Link=1 129 | Priority=1000 130 | OverrideBuildCmd=0 131 | BuildCmd= 132 | 133 | [Unit9] 134 | FileName=Memory.cpp 135 | CompileCpp=1 136 | Folder= 137 | Compile=1 138 | Link=1 139 | Priority=1000 140 | OverrideBuildCmd=0 141 | BuildCmd= 142 | 143 | [Unit10] 144 | FileName=Display.h 145 | CompileCpp=1 146 | Folder= 147 | Compile=1 148 | Link=1 149 | Priority=1000 150 | OverrideBuildCmd=0 151 | BuildCmd= 152 | 153 | [Unit11] 154 | FileName=Display.cpp 155 | CompileCpp=1 156 | Folder= 157 | Compile=1 158 | Link=1 159 | Priority=1000 160 | OverrideBuildCmd=0 161 | BuildCmd= 162 | 163 | [Unit12] 164 | FileName=MKGenException.h 165 | CompileCpp=1 166 | Folder= 167 | Compile=1 168 | Link=1 169 | Priority=1000 170 | OverrideBuildCmd=0 171 | BuildCmd= 172 | 173 | [Unit13] 174 | FileName=MKGenException.cpp 175 | CompileCpp=1 176 | Folder= 177 | Compile=1 178 | Link=1 179 | Priority=1000 180 | OverrideBuildCmd=0 181 | BuildCmd= 182 | 183 | [Unit14] 184 | FileName=system.h 185 | CompileCpp=1 186 | Folder= 187 | Compile=1 188 | Link=1 189 | Priority=1000 190 | OverrideBuildCmd=0 191 | BuildCmd= 192 | 193 | -------------------------------------------------------------------------------- /MKBasic.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: 7 | * 8 | * Purpose: Prototype of MKBasic class and all supporting data 9 | * structures, enumerations, constants and macros. 10 | * NOTE: This is obsolete concept and will likely be 11 | * removed from project. 12 | * 13 | * Date: 8/25/2016 14 | * 15 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 16 | * 17 | * Contact: makarcz@yahoo.com 18 | * 19 | * License Agreement and Warranty: 20 | 21 | This software is provided with No Warranty. 22 | I (Marek Karcz) will not be held responsible for any damage to 23 | computer systems, data or user's health resulting from use. 24 | Please proceed responsibly and apply common sense. 25 | This software is provided in hope that it will be useful. 26 | It is free of charge for non-commercial and educational use. 27 | Distribution of this software in non-commercial and educational 28 | derivative work is permitted under condition that original 29 | copyright notices and comments are preserved. Some 3-rd party work 30 | included with this project may require separate application for 31 | permission from their respective authors/copyright owners. 32 | 33 | *-------------------------------------------------------------------- 34 | */ 35 | #ifndef MKBASIC_H 36 | #define MKBASIC_H 37 | 38 | #include "VMachine.h" 39 | 40 | namespace MKBasic { 41 | 42 | class MKBasic : public VMachine 43 | { 44 | public: 45 | MKBasic(); 46 | ~MKBasic(); 47 | protected: 48 | }; 49 | 50 | } // namespace MKBasic 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /MKBasic.layout: -------------------------------------------------------------------------------- 1 | [Editors] 2 | Order=0,7,8,1,2,5,6 3 | Focused=0 4 | [Editor_0] 5 | CursorCol=17 6 | CursorRow=470 7 | TopLine=424 8 | LeftChar=1 9 | [Editor_1] 10 | CursorCol=33 11 | CursorRow=38 12 | TopLine=28 13 | LeftChar=1 14 | [Editor_2] 15 | CursorCol=15 16 | CursorRow=600 17 | TopLine=554 18 | LeftChar=1 19 | [Editor_5] 20 | CursorCol=1 21 | CursorRow=1 22 | TopLine=260 23 | LeftChar=1 24 | [Editor_6] 25 | CursorCol=17 26 | CursorRow=1151 27 | TopLine=332 28 | LeftChar=1 29 | [Editor_7] 30 | CursorCol=1 31 | CursorRow=1 32 | TopLine=25 33 | LeftChar=1 34 | [Editor_8] 35 | CursorCol=1 36 | CursorRow=1 37 | TopLine=220 38 | LeftChar=1 39 | -------------------------------------------------------------------------------- /MKGenException.cpp: -------------------------------------------------------------------------------- 1 | #include "MKGenException.h" 2 | 3 | namespace MKBasic { 4 | 5 | MKGenException::MKGenException() 6 | { 7 | msCause = "Ouch!"; 8 | } 9 | 10 | MKGenException::MKGenException(string cause) 11 | { 12 | msCause = cause; 13 | } 14 | 15 | string MKGenException::GetCause() 16 | { 17 | return msCause; 18 | } 19 | 20 | } // namespace MKBasic 21 | -------------------------------------------------------------------------------- /MKGenException.h: -------------------------------------------------------------------------------- 1 | #ifndef MKGENEXCEPTION_H 2 | #define MKGENEXCEPTION_H 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | namespace MKBasic { 10 | 11 | class MKGenException : public exception { 12 | public: 13 | MKGenException(); 14 | MKGenException(string cause); 15 | ~MKGenException() throw() {}; 16 | string GetCause(); 17 | 18 | private: 19 | string msCause; 20 | }; 21 | 22 | } // namespace MKBasic 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Makefile.win: -------------------------------------------------------------------------------- 1 | # Project: MKBasic 2 | # Makefile created by Dev-C++ 5.11 3 | 4 | CPP = g++.exe -D__DEBUG__ 5 | CC = gcc.exe -D__DEBUG__ 6 | WINDRES = windres.exe 7 | OBJ = main.o VMachine.o MKBasic.o MKCpu.o Memory.o Display.o MKGenException.o 8 | LINKOBJ = main.o VMachine.o MKBasic.o MKCpu.o Memory.o Display.o MKGenException.o 9 | LIBS = -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib32" -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib32" -static-libgcc -m32 -g3 10 | INCS = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" 11 | CXXINCS = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++" 12 | BIN = MKBasic.exe 13 | CXXFLAGS = $(CXXINCS) -m32 -std=c++11 -Wall -Wextra -pedantic -g3 14 | CFLAGS = $(INCS) -m32 -std=c++11 -Wall -Wextra -pedantic -g3 15 | RM = rm.exe -f 16 | 17 | .PHONY: all all-before all-after clean clean-custom 18 | 19 | all: all-before $(BIN) all-after 20 | 21 | clean: clean-custom 22 | ${RM} $(OBJ) $(BIN) 23 | 24 | $(BIN): $(OBJ) 25 | $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) 26 | 27 | main.o: main.cpp 28 | $(CPP) -c main.cpp -o main.o $(CXXFLAGS) 29 | 30 | VMachine.o: VMachine.cpp 31 | $(CPP) -c VMachine.cpp -o VMachine.o $(CXXFLAGS) 32 | 33 | MKBasic.o: MKBasic.cpp 34 | $(CPP) -c MKBasic.cpp -o MKBasic.o $(CXXFLAGS) 35 | 36 | MKCpu.o: MKCpu.cpp 37 | $(CPP) -c MKCpu.cpp -o MKCpu.o $(CXXFLAGS) 38 | 39 | Memory.o: Memory.cpp 40 | $(CPP) -c Memory.cpp -o Memory.o $(CXXFLAGS) 41 | 42 | Display.o: Display.cpp 43 | $(CPP) -c Display.cpp -o Display.o $(CXXFLAGS) 44 | 45 | MKGenException.o: MKGenException.cpp 46 | $(CPP) -c MKGenException.cpp -o MKGenException.o $(CXXFLAGS) 47 | -------------------------------------------------------------------------------- /MassStorage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: MassStorage.cpp 7 | * 8 | * Purpose: Implementation of MassStorage class. 9 | * To emulate disk-like mass storage device for data. 10 | * 11 | * Date: 8/16/2017 12 | * 13 | * Copyright: (C) by Marek Karcz 2016, 2017. All rights reserved. 14 | * 15 | * Contact: makarcz@yahoo.com 16 | * 17 | * License Agreement and Warranty: 18 | 19 | This software is provided with No Warranty. 20 | I (Marek Karcz) will not be held responsible for any damage to 21 | computer systems, data or user's health resulting from use. 22 | Please proceed responsibly and apply common sense. 23 | This software is provided in hope that it will be useful. 24 | It is free of charge for non-commercial and educational use. 25 | Distribution of this software in non-commercial and educational 26 | derivative work is permitted under condition that original 27 | copyright notices and comments are preserved. Some 3-rd party work 28 | included with this project may require separate application for 29 | permission from their respective authors/copyright owners. 30 | 31 | *-------------------------------------------------------------------- 32 | */ 33 | 34 | #include 35 | #include "MassStorage.h" 36 | #include "MKGenException.h" 37 | #include "system.h" 38 | 39 | namespace MKBasic { 40 | 41 | constexpr int MassStorage::sect_per_track[]; 42 | 43 | /* 44 | *-------------------------------------------------------------------- 45 | * Method: MassStorage() 46 | * Purpose: Class default constructor. 47 | * Arguments: 48 | * Returns: 49 | *-------------------------------------------------------------------- 50 | */ 51 | MassStorage::MassStorage() 52 | { 53 | Initialize(); 54 | } 55 | 56 | /* 57 | *-------------------------------------------------------------------- 58 | * Method: ~MassStorage() 59 | * Purpose: Class destructor. 60 | * Arguments: 61 | * Returns: 62 | *-------------------------------------------------------------------- 63 | */ 64 | MassStorage::~MassStorage() 65 | { 66 | 67 | } 68 | 69 | /* 70 | *-------------------------------------------------------------------- 71 | * Method: Initialize() 72 | * Purpose: Initialize internal variables. 73 | * Arguments: 74 | * Returns: 75 | *-------------------------------------------------------------------- 76 | */ 77 | void MassStorage::Initialize() 78 | { 79 | // TO DO: add code to initialize class 80 | 81 | // initialize standard disk images 82 | DiskTrack dtrk; 83 | DiskImage ditbl[] = { 84 | {0, "DISK0", {dtrk}}, 85 | {1, "DISK1", {dtrk}}, 86 | {2, "DISK2", {dtrk}}, 87 | {3, "DISK3", {dtrk}}, 88 | {4, "DISK4", {dtrk}}, 89 | {5, "DISK5", {dtrk}}, 90 | {6, "DISK6", {dtrk}}, 91 | {7, "DISK7", {dtrk}}, 92 | {8, "DISK8", {dtrk}}, 93 | {9, "DISK9", {dtrk}} 94 | }; 95 | for (int i=0; i < num_of_images; i++) { 96 | mDiskImages[i].id = ditbl[i].id; 97 | mDiskImages[i].name = ditbl[i].name; 98 | string fname = mDiskImages[i].name + "_" + to_string(mDiskImages[i].id) + ".disk"; 99 | FILE *fp = fopen(fname.c_str(), "r"); 100 | if (NULL == fp) { 101 | Format(mDiskImages[i].id, mDiskImages[i].name); 102 | Flush(mDiskImages[i].id); 103 | } else { 104 | LoadFromFile(mDiskImages[i].id, mDiskImages[i].name); 105 | fclose(fp); 106 | } 107 | } 108 | } 109 | 110 | /* 111 | *-------------------------------------------------------------------- 112 | * Method: Format() 113 | * Purpose: Format the disk image. 114 | * Arguments: id - the number / id of the disk image to format 115 | * name - the new name of the disk image 116 | * Returns: int - 0 if OK, less than 0 if error. 117 | *-------------------------------------------------------------------- 118 | */ 119 | int MassStorage::Format (int id, string name) 120 | { 121 | int ret = 0; 122 | 123 | // TO DO: add code to format disk image 124 | DiskImage dimg; 125 | dimg.name = name; 126 | for (int track=0; track < max_numof_tracks; track++) { 127 | dimg.data[track].num = track+1; 128 | dimg.data[track].num_of_sectors = sect_per_track[track]; 129 | if (track+1 == 18) { // BAM + directory 130 | dimg.data[track].data[0x00] = 0x12; // point to track 18 131 | dimg.data[track].data[0x01] = 0x01; // and sector 1 (directory) 132 | dimg.data[track].data[0x02] = 0x41; // DOS version 133 | dimg.data[track].data[0x03] = 0x01; // unused 134 | // BAM 135 | for (int sector = 0x04; sector < 0x90; sector += 4) { 136 | dimg.data[track].data[sector] = dimg.data[track].num_of_sectors; 137 | dimg.data[track].data[sector+1] = 0xff; 138 | dimg.data[track].data[sector+2] = 0xff; 139 | dimg.data[track].data[sector+3] = ~(0xff << (dimg.data[track].num_of_sectors - 16)); 140 | } 141 | } else { 142 | 143 | } 144 | } 145 | 146 | return ret; 147 | } 148 | 149 | /* 150 | *-------------------------------------------------------------------- 151 | * Method: Flush() 152 | * Purpose: Save image data to disk file. 153 | * Arguments: id - the disk image id 154 | * Returns: int - 0 if OK, less than 0 if error 155 | *-------------------------------------------------------------------- 156 | */ 157 | int MassStorage::Flush (int id) 158 | { 159 | int ret = 0; 160 | 161 | // TO DO: add code to flush disk image to file 162 | 163 | return ret; 164 | } 165 | 166 | /* 167 | *-------------------------------------------------------------------- 168 | * Method: ReadSectorData() 169 | * Purpose: Read data from disk's image sector. 170 | * Arguments: id - disk image id 171 | * track - track# 172 | * sector - sector# 173 | * Returns: pointer to data 174 | *-------------------------------------------------------------------- 175 | */ 176 | unsigned char * MassStorage::ReadSectorData(int id, 177 | int track, 178 | int sector) 179 | { 180 | // TO DO: add code to read data 181 | 182 | return mSectorBuf; 183 | } 184 | 185 | /* 186 | *-------------------------------------------------------------------- 187 | * Method: WriteSectorData() 188 | * Purpose: Write data to disk's image sector. 189 | * Arguments: id - the disk image id 190 | * track - track# 191 | * sector - sector# 192 | * buf - pointer to data 193 | * Returns: int - 0 if OK, less than 0 if error 194 | *-------------------------------------------------------------------- 195 | */ 196 | int MassStorage::WriteSectorData (int id, 197 | int track, 198 | int sector, 199 | unsigned char *buf) 200 | { 201 | int ret = 0; 202 | 203 | // TO DO: add code to write sector data 204 | 205 | return ret; 206 | } 207 | 208 | /* 209 | *-------------------------------------------------------------------- 210 | * Method: LoadFromFile() 211 | * Purpose: Load image data from file. 212 | * Arguments: id - the disk image id 213 | * name - disk image name 214 | * Returns: int - 0 if OK, less than 0 if error 215 | *-------------------------------------------------------------------- 216 | */ 217 | int MassStorage::LoadFromFile(int id, string name) 218 | { 219 | int ret = 0; 220 | 221 | return ret; 222 | } 223 | 224 | } // namespace MKBasic -------------------------------------------------------------------------------- /MassStorage.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: MassStorage.h 7 | * 8 | * Purpose: Prototype of MassStorage class and supporting data 9 | * structures, constants, enumerations and macros. 10 | * 11 | * Date: 8/16/2017 12 | * 13 | * Copyright: (C) by Marek Karcz 2016, 2017. All rights reserved. 14 | * 15 | * Contact: makarcz@yahoo.com 16 | * 17 | * License Agreement and Warranty: 18 | 19 | This software is provided with No Warranty. 20 | I (Marek Karcz) will not be held responsible for any damage to 21 | computer systems, data or user's health resulting from use. 22 | Please proceed responsibly and apply common sense. 23 | This software is provided in hope that it will be useful. 24 | It is free of charge for non-commercial and educational use. 25 | Distribution of this software in non-commercial and educational 26 | derivative work is permitted under condition that original 27 | copyright notices and comments are preserved. Some 3-rd party work 28 | included with this project may require separate application for 29 | permission from their respective authors/copyright owners. 30 | 31 | *-------------------------------------------------------------------- 32 | */ 33 | #ifndef MASSSTORAGE_H 34 | #define MASSSTORAGE_H 35 | 36 | #include 37 | 38 | using namespace std; 39 | 40 | namespace MKBasic { 41 | 42 | class MassStorage { 43 | 44 | public: 45 | 46 | // CBM 1541 format 47 | static const int max_numof_sectors = 21; 48 | static const int sector_size = 256; 49 | static const int max_numof_tracks = 35; 50 | static const int num_of_images = 10; 51 | constexpr static int sect_per_track[] = 52 | {21, 21, 21, 21, 21, 21, 21, 53 | 21, 21, 21, 21, 21, 21, 21, 54 | 21, 21, 21, 55 | 19, 19, 19, 19, 19, 19, 19, 56 | 18, 18, 18, 18, 18, 18, 57 | 17, 17, 17, 17, 17}; 58 | 59 | MassStorage(); 60 | ~MassStorage(); 61 | int Format (int id, string name); // format disk image 62 | int Flush (int id); // flush disk image to hard drive 63 | unsigned char *ReadSectorData(int id, 64 | int track, 65 | int sector); // read data from sector 66 | int WriteSectorData (int id, 67 | int track, 68 | int sector, 69 | unsigned char *buf); // write data to sector 70 | 71 | private: 72 | 73 | // definition of a disk track structure 74 | struct DiskTrack { 75 | 76 | int num; 77 | int num_of_sectors; 78 | unsigned char data[max_numof_sectors * sector_size]; 79 | 80 | }; 81 | 82 | // definition of a disk image structure 83 | struct DiskImage { 84 | 85 | int id; 86 | string name; 87 | DiskTrack data[max_numof_tracks]; 88 | }; 89 | 90 | unsigned char mSectorBuf[sector_size]; // buffer for sector data 91 | DiskImage mDiskImages[num_of_images]; // buffer for all disk images 92 | 93 | void Initialize(); 94 | int LoadFromFile(int id, string name); // load image from disk cache 95 | 96 | }; // class MassStorage 97 | 98 | } // namespace MKBasic 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /MemMapDev.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: MemMapDev.h 7 | * 8 | * Purpose: Prototype of MemMapDev class and all supporting 9 | * data structures, enumarators, constants and macros. 10 | * 11 | * Date: 8/25/2016 12 | * 13 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 14 | * 15 | * Contact: makarcz@yahoo.com 16 | * 17 | * License Agreement and Warranty: 18 | 19 | This software is provided with No Warranty. 20 | I (Marek Karcz) will not be held responsible for any damage to 21 | computer systems, data or user's health resulting from use. 22 | Please proceed responsibly and apply common sense. 23 | This software is provided in hope that it will be useful. 24 | It is free of charge for non-commercial and educational use. 25 | Distribution of this software in non-commercial and educational 26 | derivative work is permitted under condition that original 27 | copyright notices and comments are preserved. Some 3-rd party work 28 | included with this project may require separate application for 29 | permission from their respective authors/copyright owners. 30 | 31 | *-------------------------------------------------------------------- 32 | */ 33 | #ifndef MEMMAPDEV_H 34 | #define MEMMAPDEV_H 35 | 36 | #include 37 | #include 38 | #include "system.h" 39 | //#include "Memory.h" 40 | #include "GraphDisp.h" 41 | #include "Display.h" 42 | #include "ConsoleIO.h" 43 | 44 | #if defined(LINUX) 45 | #include 46 | #include 47 | #include 48 | #endif 49 | 50 | // some default definitions 51 | #define CHARIO_ADDR 0xE000 52 | #define GRDISP_ADDR 0xE002 53 | #define CHARIO_BUF_SIZE 256 54 | #define CHARTBL_BANK 0x0B // $B000 55 | #define CHARTBL_LEN 0x1000 // 4 kB 56 | #define TXTCRSR_MAXCOL 79 57 | #define TXTCRSR_MAXROW 24 58 | 59 | using namespace std; 60 | 61 | /* 62 | *-------------------------------------------------------------------- 63 | * Method: 64 | * Purpose: 65 | * Arguments: 66 | * Returns: 67 | *-------------------------------------------------------------------- 68 | */ 69 | 70 | namespace MKBasic { 71 | 72 | class Memory; 73 | 74 | // Definitions for memory mapped devices handling. 75 | 76 | // memory address ranges 77 | struct AddrRange { 78 | unsigned short start_addr, end_addr; // inclusive address range 79 | 80 | AddrRange(unsigned short staddr, unsigned short endaddr) 81 | { 82 | start_addr = staddr; 83 | end_addr = endaddr; 84 | } 85 | }; 86 | 87 | // device parameters 88 | struct DevPar { 89 | string name, value; 90 | 91 | DevPar(string n, string v) 92 | { 93 | name = n; 94 | value = v; 95 | } 96 | }; 97 | 98 | typedef vector MemAddrRanges; 99 | typedef vector DevParams; 100 | 101 | class MemMapDev; 102 | 103 | // Class MemMapDev implements functionality of all 104 | // memory mapped devices. 105 | 106 | // device register read, arguments: address 107 | typedef int (MemMapDev::*ReadFunPtr)(int); 108 | // device register write, arguments: address, value 109 | typedef void (MemMapDev::*WriteFunPtr)(int,int); 110 | 111 | // Definition of device. 112 | struct Device { 113 | int num; // device number 114 | string name; // device name 115 | MemAddrRanges addr_ranges; // vector of memory address ranges for this device 116 | ReadFunPtr read_fun_ptr; // pointer to memory register read function 117 | WriteFunPtr write_fun_ptr; // pointer to memory register write function 118 | DevParams params; // list of device parameters 119 | 120 | Device() 121 | { 122 | num = -1; 123 | } 124 | 125 | Device(int dnum, 126 | string dname, 127 | MemAddrRanges addrranges, 128 | ReadFunPtr prdfun, 129 | WriteFunPtr pwrfun, 130 | DevParams parms) 131 | { 132 | num = dnum; 133 | name = dname; 134 | addr_ranges = addrranges; 135 | read_fun_ptr = prdfun; 136 | write_fun_ptr = pwrfun; 137 | params = parms; 138 | } 139 | }; 140 | 141 | typedef vector MemMappedDevices; 142 | 143 | // currently supported devices 144 | enum DevNums { 145 | DEVNUM_CHARIO = 0, // character I/O device 146 | DEVNUM_GRDISP = 1 // raster graphics display device 147 | }; 148 | 149 | /* 150 | * NOTE regarding device address ranges. 151 | * 152 | * The emulated device is a model of a electronic device that is connected 153 | * to the CPU-s bus (address, memory, control signals). 154 | * Depending on the device, the memory address range may be as simple as 155 | * a single memory address or it may contain multiple memory addresses 156 | * or ranges of addresses positioned at various non-contiguous places. 157 | * The functions of these addresses are handled internally by the MemMapDev 158 | * class. The client (user) initializing the device, if providing custom 159 | * memory ranges must know more details about device in order to provide 160 | * accurate data. E.g.: if device requires a single address as an entry 161 | * point, just one memory range is needed with start_addr == end_addr. 162 | * If device is more complicated and requires range of addresses to access 163 | * its control registers, another range of addresses to map memory access 164 | * etc., device should be setup accordingly by calling SetupDevice method 165 | * with proper arguments. Device setup is not mandatory, each device that 166 | * is mainained is initialized wit default parameters. 167 | */ 168 | 169 | // offsets of raster graphics device registers 170 | enum GraphDevRegs { 171 | GRAPHDEVREG_X = 0, 172 | GRAPHDEVREG_Y = 2, 173 | GRAPHDEVREG_PXCOL_R = 3, 174 | GRAPHDEVREG_PXCOL_G = 4, 175 | GRAPHDEVREG_PXCOL_B = 5, 176 | GRAPHDEVREG_BGCOL_R = 6, 177 | GRAPHDEVREG_BGCOL_G = 7, 178 | GRAPHDEVREG_BGCOL_B = 8, 179 | GRAPHDEVREG_CMD = 9, 180 | GRAPHDEVREG_X2 = 10, 181 | GRAPHDEVREG_Y2 = 12, 182 | GRAPHDEVREG_CHRTBL = 13, // set the 2 kB bank where char. table resides 183 | GRAPHDEVREG_TXTCURX = 14, // set text cursor position (column) 184 | GRAPHDEVREG_TXTCURY = 15, // set text cursor position (row) 185 | GRAPHDEVREG_PUTC = 16, // output char. to current pos. and move cursor 186 | GRAPHDEVREG_CRSMODE = 17, // set cursor mode (0 - not visible, 1 - block...) 187 | GRAPHDEVREG_TXTMODE = 18, // set text mode (0 - normal, 1 - reverse) 188 | //--------------------------- 189 | GRAPHDEVREG_END 190 | }; 191 | /* 192 | * Note to GRAPHDEVREG_PUTC: 193 | * value put to register is not an ASCII code of the character, but rather 194 | * a screen code in order how character is positioned in character table. 195 | * Each character definition takes 8 bytes. There is 4096 bytes which defines 196 | * 512 characters. First 256 are normal color and next 256 are reverse color 197 | * definitions. 198 | */ 199 | 200 | 201 | // graphics display commands 202 | enum GraphDevCmds { 203 | GRAPHDEVCMD_CLRSCR = 0, 204 | GRAPHDEVCMD_SETPXL = 1, 205 | GRAPHDEVCMD_CLRPXL = 2, 206 | GRAPHDEVCMD_SETBGC = 3, 207 | GRAPHDEVCMD_SETFGC = 4, 208 | GRAPHDEVCMD_DRAWLN = 5, 209 | GRAPHDEVCMD_ERASLN = 6 210 | }; 211 | 212 | // Cursor modes. 213 | // note: bit 7 will decide if cursor will blink (1) 214 | #define CRS_BLINK 0x80 215 | enum TextCursorModes { 216 | GRAPHDEVCRSMODE_BLANK = 0, // not visible 217 | GRAPHDEVCRSMODE_BLOCK = 1, // block 218 | GRAPHDEVCRSMODE_UND = 2, // underscore 219 | //------------------------------------------ 220 | GRAPHDEVCRSMODE_END 221 | }; 222 | 223 | // Text modes. 224 | enum TextModes { 225 | GRAPHDEVTXTMODE_NORMAL = 0, // normal mode 226 | GRAPHDEVTXTMODE_REVERSE = 1, // reverse colors mode 227 | //------------------------------------------ 228 | GRAPHDEVTXTMODE_END 229 | }; 230 | 231 | struct GraphDeviceRegs { 232 | unsigned char mGraphDispLoX; 233 | unsigned char mGraphDispHiX; 234 | unsigned char mGraphDispY; 235 | unsigned char mGraphDispLoX2; 236 | unsigned char mGraphDispHiX2; 237 | unsigned char mGraphDispY2; 238 | unsigned char mGraphDispPixColR; 239 | unsigned char mGraphDispPixColG; 240 | unsigned char mGraphDispPixColB; 241 | unsigned char mGraphDispBgColR; 242 | unsigned char mGraphDispBgColG; 243 | unsigned char mGraphDispBgColB; 244 | unsigned char mGraphDispChrTbl; // 2 kB char. table bank (0-31) 245 | unsigned char mGraphDispTxtCurX; // text cursor column 246 | unsigned char mGraphDispTxtCurY; // text cursor row 247 | unsigned char mGraphDispCrsMode; // cursor mode 248 | unsigned char mGraphDispTxtMode; // text mode 249 | }; 250 | 251 | // Functionality of memory mapped devices 252 | class MemMapDev { 253 | 254 | public: 255 | 256 | MemMapDev(); 257 | MemMapDev(Memory *pmem); 258 | ~MemMapDev(); 259 | 260 | Device GetDevice(int devnum); 261 | int SetupDevice(int devnum, MemAddrRanges memranges, DevParams params); 262 | 263 | char GetCharIn(); 264 | char GetCharOut(); 265 | void CharIOFlush(); 266 | unsigned short GetCharIOAddr(); 267 | bool GetCharIOEchoOn(); 268 | bool IsCharIOActive(); 269 | Display* ActivateCharIO(); 270 | Display* GetDispPtr(); 271 | void DeactivateCharIO(); 272 | 273 | int CharIODevice_Read(int addr); 274 | void CharIODevice_Write(int addr, int val); 275 | 276 | unsigned short GetGraphDispAddrBase(); 277 | void ActivateGraphDisp(); 278 | void DeactivateGraphDisp(); 279 | 280 | int GraphDispDevice_Read(int addr); 281 | void GraphDispDevice_Write(int addr, int val); 282 | 283 | void GraphDisp_ReadEvents(); 284 | void GraphDisp_Update(); 285 | 286 | //void SetCharIODispPtr(Display *p, bool active); 287 | 288 | private: 289 | 290 | Memory *mpMem; // pointer to memory object 291 | MemMappedDevices mDevices; 292 | char mCharIOBufIn[CHARIO_BUF_SIZE]; 293 | char mCharIOBufOut[CHARIO_BUF_SIZE]; 294 | unsigned int mInBufDataBegin; 295 | unsigned int mInBufDataEnd; 296 | unsigned int mOutBufDataBegin; 297 | unsigned int mOutBufDataEnd; 298 | unsigned int mCharIOAddr; 299 | bool mIOEcho; 300 | unsigned int mGraphDispAddr; 301 | GraphDisp *mpGraphDisp; // pointer to Graphics Device object 302 | Display *mpCharIODisp; // pointer to character I/O device object 303 | bool mCharIOActive; // indicate if character I/O is active 304 | GraphDeviceRegs mGrDevRegs; // graphics display device registers 305 | unsigned int mCharTblAddr; // start address of characters table 306 | ConsoleIO *mpConsoleIO; 307 | 308 | void Initialize(); 309 | 310 | unsigned char ReadCharKb(bool nonblock); 311 | void PutCharIO(char c); 312 | //void SetCurses(); 313 | 314 | }; 315 | 316 | } // namespace MKBasic 317 | 318 | #endif // MEMMAPDEV_H 319 | -------------------------------------------------------------------------------- /Memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: Memory.h 7 | * 8 | * Purpose: Prototype of Memory class and supporting data 9 | * structures, constants, enumerations and macros. 10 | * 11 | * Date: 8/25/2016 12 | * 13 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 14 | * 15 | * Contact: makarcz@yahoo.com 16 | * 17 | * License Agreement and Warranty: 18 | 19 | This software is provided with No Warranty. 20 | I (Marek Karcz) will not be held responsible for any damage to 21 | computer systems, data or user's health resulting from use. 22 | Please proceed responsibly and exercise common sense. 23 | This software is provided in hope that it will be useful. 24 | It is free of charge for non-commercial and educational use. 25 | Distribution of this software in non-commercial and educational 26 | derivative work is permitted under condition that original 27 | copyright notices and comments are preserved. Some 3-rd party work 28 | included with this project may require separate application for 29 | permission from their respective authors/copyright owners. 30 | 31 | *-------------------------------------------------------------------- 32 | */ 33 | #ifndef MEMORY_H 34 | #define MEMORY_H 35 | 36 | #include "system.h" 37 | #include "MemMapDev.h" 38 | 39 | #define MAX_8BIT_ADDR 0xFFFF 40 | #define MEM_PAGE_SIZE 0x100 41 | #define ROM_BEGIN 0xD000 42 | #define ROM_END 0xDFFF 43 | #define MIN_ROM_BEGIN 0x0200 44 | 45 | using namespace std; 46 | 47 | namespace MKBasic { 48 | 49 | class Memory 50 | { 51 | public: 52 | 53 | Memory(); 54 | ~Memory(); 55 | 56 | void Initialize(); 57 | unsigned char Peek8bit(unsigned short addr); 58 | unsigned char Peek8bitImg(unsigned short addr); 59 | unsigned short Peek16bit(unsigned short addr); 60 | void Poke8bit(unsigned short addr, unsigned char val); // write to memory and call memory mapped device handle 61 | void Poke8bitImg(unsigned short addr, unsigned char val); // write to memory image only 62 | void SetCharIO(unsigned short addr, bool echo); 63 | void DisableCharIO(); 64 | unsigned short GetCharIOAddr(); 65 | char GetCharIn(); 66 | char GetCharOut(); 67 | void EnableROM(); 68 | void DisableROM(); 69 | void SetROM(unsigned short start, unsigned short end); 70 | void EnableROM(unsigned short start, unsigned short end); 71 | unsigned short GetROMBegin(); 72 | unsigned short GetROMEnd(); 73 | bool IsROMEnabled(); 74 | int AddDevice(int devnum); 75 | int DeleteDevice(int devnum); 76 | void SetupDevice(int devnum, MemAddrRanges memranges, DevParams params); 77 | 78 | void SetGraphDisp(unsigned short addr); 79 | void DisableGraphDisp(); 80 | unsigned short GetGraphDispAddr(); 81 | void GraphDisp_ReadEvents(); 82 | void GraphDisp_Update(); 83 | bool GraphDispOp(); 84 | MemMapDev *GetMemMapDevPtr(); 85 | 86 | protected: 87 | 88 | private: 89 | 90 | unsigned char m8bitMem[MAX_8BIT_ADDR+1]; 91 | // array of device usage for each memory page 92 | // this is performance optimization array that keeps values >= 0 under the 93 | // indexes of memory pages where the memory mapped device is active or -1 94 | // if there is no active device on given memory page 95 | int mMemPageDev[MEM_PAGE_SIZE]; 96 | unsigned short mCharIOAddr; 97 | bool mCharIOActive; 98 | bool mIOEcho; 99 | unsigned short mROMBegin; 100 | unsigned short mROMEnd; 101 | bool mROMActive; 102 | vector mActiveDeviceVec; // active devices 103 | MemMapDev *mpMemMapDev; // pointer to MemMapDev object 104 | bool mGraphDispActive; 105 | bool mDispOp; 106 | 107 | unsigned char ReadCharKb(bool nonblock); 108 | void PutCharIO(char c); 109 | }; 110 | 111 | } // namespace MKBasic 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /Notes.txt: -------------------------------------------------------------------------------- 1 | 2 | http://visual6502.org/wiki/index.php?title=6502DecimalMode 3 | 4 | 5 | NV-BDIZC 6 | 7 | Tests for ADC 8 | 00 + 00 and C=0 gives 00 and N=0 V=0 Z=1 C=0 (simulate) 9 | 79 + 00 and C=1 gives 80 and N=1 V=1 Z=0 C=0 (simulate) 10 | 24 + 56 and C=0 gives 80 and N=1 V=1 Z=0 C=0 (simulate) 11 | 93 + 82 and C=0 gives 75 and N=0 V=1 Z=0 C=1 (simulate) 12 | 89 + 76 and C=0 gives 65 and N=0 V=0 Z=0 C=1 (simulate) 13 | 89 + 76 and C=1 gives 66 and N=0 V=0 Z=1 C=1 (simulate) 14 | 80 + f0 and C=0 gives d0 and N=0 V=1 Z=0 C=1 (simulate) 15 | 80 + fa and C=0 gives e0 and N=1 V=0 Z=0 C=1 (simulate) 16 | 2f + 4f and C=0 gives 74 and N=0 V=0 Z=0 C=0 (simulate) 17 | 6f + 00 and C=1 gives 76 and N=0 V=0 Z=0 C=0 (simulate) 18 | Tests for SBC 19 | 00 - 00 and C=0 gives 99 and N=1 V=0 Z=0 C=0 (simulate) 20 | 00 - 00 and C=1 gives 00 and N=0 V=0 Z=1 C=1 (simulate) 21 | 00 - 01 and C=1 gives 99 and N=1 V=0 Z=0 C=0 (simulate) 22 | 0a - 00 and C=1 gives 0a and N=0 V=0 Z=0 C=1 (simulate) 23 | 0b - 00 and C=0 gives 0a and N=0 V=0 Z=0 C=1 (simulate) 24 | 9a - 00 and C=1 gives 9a and N=1 V=0 Z=0 C=1 (simulate) 25 | 9b - 00 and C=0 gives 9a and N=1 V=0 Z=0 C=1 (simulate) -------------------------------------------------------------------------------- /TestBCD.65s: -------------------------------------------------------------------------------- 1 | ; Verify decimal mode behavior 2 | ; Written by Bruce Clark. This code is public domain. 3 | ; 4 | ; Returns: 5 | ; ERROR = 0 if the test passed 6 | ; ERROR = 1 if the test failed 7 | ; 8 | ; This routine requires 17 bytes of RAM -- 1 byte each for: 9 | ; AR, CF, DA, DNVZC, ERROR, HA, HNVZC, N1, N1H, N1L, N2, N2L, NF, VF, and ZF 10 | ; and 2 bytes for N2H 11 | ; 12 | ; Variables: 13 | ; N1 and N2 are the two numbers to be added or subtracted 14 | ; N1H, N1L, N2H, and N2L are the upper 4 bits and lower 4 bits of N1 and N2 15 | ; DA and DNVZC are the actual accumulator and flag results in decimal mode 16 | ; HA and HNVZC are the accumulator and flag results when N1 and N2 are 17 | ; added or subtracted using binary arithmetic 18 | ; AR, NF, VF, ZF, and CF are the predicted decimal mode accumulator and 19 | ; flag results, calculated using binary arithmetic 20 | ; 21 | ; This program takes approximately 1 minute at 1 MHz (a few seconds more on 22 | ; a 65C02 than a 6502 or 65816) 23 | ; 24 | *=$0300 25 | 26 | AR: .DB 0 27 | CF: .DB 0 28 | DA: .DB 0 29 | DNVZC: .DB 0 30 | ERROR: .DB 0 31 | HA: .DB 0 32 | HNVZC: .DB 0 33 | N1: .DB 0 34 | N1H: .DB 0 35 | N1L: .DB 0 36 | N2: .DB 0 37 | N2L: .DB 0 38 | NF: .DB 0 39 | VF: .DB 0 40 | ZF: .DB 0 41 | N2H: .DB 0,0 42 | 43 | *=$0400 44 | 45 | TEST: LDY #1 ; initialize Y (used to loop through carry flag values) 46 | STY ERROR ; store 1 in ERROR until the test passes 47 | LDA #0 ; initialize N1 and N2 48 | STA N1 49 | STA N2 50 | LOOP1: LDA N2 ; N2L = N2 & $0F 51 | AND #$0F ; [1] see text 52 | STA N2L 53 | LDA N2 ; N2H = N2 & $F0 54 | AND #$F0 ; [2] see text 55 | STA N2H 56 | ORA #$0F ; N2H+1 = (N2 & $F0) + $0F 57 | STA N2H+1 58 | LOOP2: LDA N1 ; N1L = N1 & $0F 59 | AND #$0F ; [3] see text 60 | STA N1L 61 | LDA N1 ; N1H = N1 & $F0 62 | AND #$F0 ; [4] see text 63 | STA N1H 64 | JSR ADD 65 | JSR A6502 66 | JSR COMPARE 67 | BNE DONE 68 | JSR SUB 69 | JSR S6502 70 | JSR COMPARE 71 | BNE DONE 72 | INC N1 ; [5] see text 73 | BNE LOOP2 ; loop through all 256 values of N1 74 | INC N2 ; [6] see text 75 | BNE LOOP1 ; loop through all 256 values of N2 76 | DEY 77 | BPL LOOP1 ; loop through both values of the carry flag 78 | LDA #0 ; test passed, so store 0 in ERROR 79 | STA ERROR 80 | DONE: RTS 81 | BRK 82 | 83 | ; Calculate the actual decimal mode accumulator and flags, the accumulator 84 | ; and flag results when N1 is added to N2 using binary arithmetic, the 85 | ; predicted accumulator result, the predicted carry flag, and the predicted 86 | ; V flag 87 | ; 88 | ADD: SED ; decimal mode 89 | CPY #1 ; set carry if Y = 1, clear carry if Y = 0 90 | LDA N1 91 | ADC N2 92 | STA DA ; actual accumulator result in decimal mode 93 | PHP 94 | PLA 95 | STA DNVZC ; actual flags result in decimal mode 96 | CLD ; binary mode 97 | CPY #1 ; set carry if Y = 1, clear carry if Y = 0 98 | LDA N1 99 | ADC N2 100 | STA HA ; accumulator result of N1+N2 using binary arithmetic 101 | 102 | PHP 103 | PLA 104 | STA HNVZC ; flags result of N1+N2 using binary arithmetic 105 | CPY #1 106 | LDA N1L 107 | ADC N2L 108 | CMP #$0A 109 | LDX #0 110 | BCC A1 111 | INX 112 | ADC #5 ; add 6 (carry is set) 113 | AND #$0F 114 | SEC 115 | A1: ORA N1H 116 | ; 117 | ; if N1L + N2L < $0A, then add N2 & $F0 118 | ; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) 119 | ; 120 | ADC N2H,X 121 | PHP 122 | BCS A2 123 | CMP #$A0 124 | BCC A3 125 | A2: ADC #$5F ; add $60 (carry is set) 126 | SEC 127 | A3: STA AR ; predicted accumulator result 128 | PHP 129 | PLA 130 | STA CF ; predicted carry result 131 | PLA 132 | ; 133 | ; note that all 8 bits of the P register are stored in VF 134 | ; 135 | STA VF ; predicted V flags 136 | RTS 137 | 138 | ; Calculate the actual decimal mode accumulator and flags, and the 139 | ; accumulator and flag results when N2 is subtracted from N1 using binary 140 | ; arithmetic 141 | ; 142 | SUB: SED ; decimal mode 143 | CPY #1 ; set carry if Y = 1, clear carry if Y = 0 144 | LDA N1 145 | SBC N2 146 | STA DA ; actual accumulator result in decimal mode 147 | PHP 148 | PLA 149 | STA DNVZC ; actual flags result in decimal mode 150 | CLD ; binary mode 151 | CPY #1 ; set carry if Y = 1, clear carry if Y = 0 152 | LDA N1 153 | SBC N2 154 | STA HA ; accumulator result of N1-N2 using binary arithmetic 155 | 156 | PHP 157 | PLA 158 | STA HNVZC ; flags result of N1-N2 using binary arithmetic 159 | RTS 160 | 161 | ; Calculate the predicted SBC accumulator result for the 6502 and 65816 162 | 163 | ; 164 | SUB1: CPY #1 ; set carry if Y = 1, clear carry if Y = 0 165 | LDA N1L 166 | SBC N2L 167 | LDX #0 168 | BCS S11 169 | INX 170 | SBC #5 ; subtract 6 (carry is clear) 171 | AND #$0F 172 | CLC 173 | S11: ORA N1H 174 | ; 175 | ; if N1L - N2L >= 0, then subtract N2 & $F0 176 | ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) 177 | ; 178 | SBC N2H,X 179 | BCS S12 180 | SBC #$5F ; subtract $60 (carry is clear) 181 | S12: STA AR 182 | RTS 183 | 184 | ; Calculate the predicted SBC accumulator result for the 6502 and 65C02 185 | 186 | ; 187 | SUB2: CPY #1 ; set carry if Y = 1, clear carry if Y = 0 188 | LDA N1L 189 | SBC N2L 190 | LDX #0 191 | BCS S21 192 | INX 193 | AND #$0F 194 | CLC 195 | S21: ORA N1H 196 | ; 197 | ; if N1L - N2L >= 0, then subtract N2 & $F0 198 | ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) 199 | ; 200 | SBC N2H,X 201 | BCS S22 202 | SBC #$5F ; subtract $60 (carry is clear) 203 | S22: CPX #0 204 | BEQ S23 205 | SBC #6 206 | S23: STA AR ; predicted accumulator result 207 | RTS 208 | 209 | ; Compare accumulator actual results to predicted results 210 | ; 211 | ; Return: 212 | ; Z flag = 1 (BEQ branch) if same 213 | ; Z flag = 0 (BNE branch) if different 214 | ; 215 | COMPARE: 216 | LDA DA 217 | CMP AR 218 | BNE C1 219 | LDA DNVZC ; [7] see text 220 | EOR NF 221 | AND #$80 ; mask off N flag 222 | BNE C1 223 | LDA DNVZC ; [8] see text 224 | EOR VF 225 | AND #$40 ; mask off V flag 226 | BNE C1 ; [9] see text 227 | LDA DNVZC 228 | EOR ZF ; mask off Z flag 229 | AND #2 230 | BNE C1 ; [10] see text 231 | LDA DNVZC 232 | EOR CF 233 | AND #1 ; mask off C flag 234 | C1: RTS 235 | 236 | ; These routines store the predicted values for ADC and SBC for the 6502, 237 | ; 65C02, and 65816 in AR, CF, NF, VF, and ZF 238 | 239 | A6502: LDA VF 240 | ; 241 | ; since all 8 bits of the P register were stored in VF, bit 7 of VF contains 242 | ; the N flag for NF 243 | ; 244 | STA NF 245 | LDA HNVZC 246 | STA ZF 247 | RTS 248 | 249 | S6502: JSR SUB1 250 | LDA HNVZC 251 | STA NF 252 | STA VF 253 | STA ZF 254 | STA CF 255 | RTS 256 | 257 | A65C02: LDA AR 258 | PHP 259 | PLA 260 | STA NF 261 | STA ZF 262 | RTS 263 | 264 | S65C02: JSR SUB2 265 | LDA AR 266 | PHP 267 | PLA 268 | STA NF 269 | STA ZF 270 | LDA HNVZC 271 | STA VF 272 | STA CF 273 | RTS 274 | 275 | A65816: LDA AR 276 | PHP 277 | PLA 278 | STA NF 279 | STA ZF 280 | RTS 281 | 282 | S65816: JSR SUB1 283 | LDA AR 284 | PHP 285 | PLA 286 | STA NF 287 | STA ZF 288 | LDA HNVZC 289 | STA VF 290 | STA CF 291 | RTS 292 | -------------------------------------------------------------------------------- /VMachine.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: VMachine.h 7 | * 8 | * Purpose: Prototype of VMachine class and all supporting data 9 | * structures, enumerations, constants and macros. 10 | * 11 | * Date: 8/25/2016 12 | * 13 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 14 | * 15 | * Contact: makarcz@yahoo.com 16 | * 17 | * License Agreement and Warranty: 18 | 19 | This software is provided with No Warranty. 20 | I (Marek Karcz) will not be held responsible for any damage to 21 | computer systems, data or user's health resulting from use. 22 | Please proceed responsibly and apply common sense. 23 | This software is provided in hope that it will be useful. 24 | It is free of charge for non-commercial and educational use. 25 | Distribution of this software in non-commercial and educational 26 | derivative work is permitted under condition that original 27 | copyright notices and comments are preserved. Some 3-rd party work 28 | included with this project may require separate application for 29 | permission from their respective authors/copyright owners. 30 | 31 | *-------------------------------------------------------------------- 32 | */ 33 | #ifndef VMACHINE_H 34 | #define VMACHINE_H 35 | 36 | #include 37 | #include 38 | #include 39 | #include "system.h" 40 | #include "MKCpu.h" 41 | #include "Memory.h" 42 | #include "Display.h" 43 | #include "ConsoleIO.h" 44 | 45 | //#define WINDOWS 1 46 | #if defined (WINDOWS) 47 | #include 48 | #endif 49 | 50 | #define IOREFRESH 32 51 | #define OPINTERRUPT 25 // operator interrupt code (CTRL-Y) 52 | #define HDRMAGICKEY "SNAPSHOT2" 53 | #define HDRMAGICKEY_OLD "SNAPSHOT" 54 | #define HDRDATALEN 128 55 | #define HDRDATALEN_OLD 15 56 | #define HEXEOF ":00000001FF" 57 | // take emulation speed measurement every 2 minutes (120,000,000 usec) 58 | #define PERFSTAT_INTERVAL 120000000 59 | // but not more often than 30,000,000 clock ticks 60 | #define PERFSTAT_CYCLES 30000000 61 | #define DBG_TRACE_SIZE 200 // maximum size of debug messages queue 62 | 63 | using namespace std; 64 | using namespace chrono; 65 | 66 | // Macros for debug log. 67 | #define ADD_DBG_LOADMEM(lc,txt) \ 68 | if (mDebugTraceActive) \ 69 | { \ 70 | stringstream ss; \ 71 | string msg, s; \ 72 | ss << lc; \ 73 | ss >> s; \ 74 | msg = "LINE #" + s + txt; \ 75 | AddDebugTrace(msg); \ 76 | } 77 | 78 | #define ADD_DBG_LDMEMPARHEX(name,value) \ 79 | if (mDebugTraceActive) \ 80 | { \ 81 | string msg; \ 82 | msg = (string)name + " = $" + Addr2HexStr(value); \ 83 | AddDebugTrace(msg); \ 84 | } 85 | 86 | #define ADD_DBG_LDMEMPARVAL(name,value) \ 87 | if (mDebugTraceActive) \ 88 | { \ 89 | string msg; \ 90 | msg = (string)name + " = " + Addr2DecStr(value); \ 91 | AddDebugTrace(msg); \ 92 | } 93 | 94 | // Macro to save header data: v - value, fp - file pointer, n - data counter (dec) 95 | #define SAVE_HDR_DATA(v,fp,n) {fputc(v, fp); n--;} 96 | 97 | namespace MKBasic { 98 | 99 | // Types of memory image definition file. 100 | enum eMemoryImageTypes { 101 | MEMIMG_UNKNOWN = 0, 102 | MEMIMG_VM65DEF, 103 | MEMIMG_INTELHEX, 104 | MEMIMG_BIN 105 | }; 106 | 107 | // Types of memory image load errors 108 | enum eMemImgLoadErrors { 109 | MEMIMGERR_OK = 0, // all is good 110 | // binary format 111 | MEMIMGERR_RAMBIN_OPEN, // unable to open file 112 | MEMIMGERR_RAMBIN_EOF, // unexpected EOF (image shorter then 64 kB) 113 | MEMIMGERR_RAMBIN_HDR, // header problem 114 | MEMIMGERR_RAMBIN_NOHDR, // no header found 115 | MEMIMGERR_RAMBIN_HDRANDEOF, // header problem and unexpected EOF 116 | MEMIMGERR_RAMBIN_NOHDRANDEOF, // header not found and unexoected EOF 117 | // Intel HEX format 118 | MEMIMGERR_INTELH_OPEN, // unable to open file 119 | MEMIMGERR_INTELH_SYNTAX, // syntax error 120 | MEMIMGERR_INTELH_FMT, // format error 121 | // VM65 memory definition 122 | MEMIMGERR_VM65_OPEN, // unable to open file 123 | MEMIMGERR_VM65_IGNPROCWRN, // processing warnings (ignored, not critical) 124 | //------------------------------------------------------------------------- 125 | MEMIMGERR_UNKNOWN 126 | }; 127 | 128 | // Types of other errors 129 | enum eVMErrors { 130 | VMERR_OK = 0, // all is good 131 | VMERR_SAVE_SNAPSHOT = MEMIMGERR_UNKNOWN+1, // problem saving memory image 132 | // snapshot 133 | //------------------------------------------------------------------------- 134 | VMERR_UNKNOWN // unknown error 135 | }; 136 | 137 | struct PerfStats { 138 | time_point 139 | begin_time; // the moment of time count start 140 | long cycles; // performance stats 141 | long prev_cycles; // previously measured stats 142 | long prev_usec; // previously measured stats 143 | int perf_onemhz; // avg. % perf. based on 1MHz CPU. 144 | }; 145 | 146 | class VMachine 147 | { 148 | public: 149 | VMachine(); 150 | VMachine(string romfname, string ramfname); 151 | ~VMachine(); 152 | 153 | void InitVM(); 154 | Regs *Run(); 155 | Regs *Run(unsigned short addr); 156 | Regs *Exec(); 157 | Regs *Exec(unsigned short addr); 158 | Regs *Step(); 159 | Regs *Step(unsigned short addr); 160 | void LoadROM(string romfname); 161 | int LoadRAM(string ramfname); 162 | int LoadRAMBin(string ramfname); 163 | int LoadRAMHex(string hexfname); 164 | int LoadRAMDef(string memfname); 165 | unsigned short MemPeek8bit(unsigned short addr); 166 | void MemPoke8bit(unsigned short addr, unsigned char v); 167 | Regs *GetRegs(); 168 | void SetCharIO(unsigned short addr, bool echo); 169 | void DisableCharIO(); 170 | unsigned short GetCharIOAddr(); 171 | bool GetCharIOActive(); 172 | bool GetGraphDispActive(); 173 | void ShowIO(); 174 | void ClearScreen(); 175 | void ScrHome(); 176 | bool IsAutoExec(); 177 | bool IsAutoReset(); 178 | void EnableROM(); 179 | void DisableROM(); 180 | void SetROM(unsigned short start, unsigned short end); 181 | void EnableROM(unsigned short start, unsigned short end); 182 | unsigned short GetROMBegin(); 183 | unsigned short GetROMEnd(); 184 | bool IsROMEnabled(); 185 | unsigned short GetRunAddr(); 186 | void SetOpInterrupt(bool opint); 187 | bool IsOpInterrupt(); 188 | queue GetExecHistory(); 189 | unsigned short Disassemble(unsigned short addr, char *buf); 190 | void Reset(); 191 | void Interrupt(); 192 | int SaveSnapshot(string fname); 193 | int GetLastError(); 194 | void SetGraphDisp(unsigned short addr); 195 | void DisableGraphDisp(); 196 | unsigned short GetGraphDispAddr(); 197 | PerfStats GetPerfStats(); // returns performance stats based on 1 million 198 | // cycles per second (1 MHz CPU). 199 | void EnableExecHistory(bool enexehist); 200 | bool IsExecHistoryActive(); 201 | void EnableDebugTrace(); 202 | void DisableDebugTrace(); 203 | bool IsDebugTraceActive(); 204 | void EnablePerfStats(); 205 | void DisablePerfStats(); 206 | bool IsPerfStatsActive(); 207 | queue GetDebugTraces(); 208 | 209 | 210 | protected: 211 | 212 | private: 213 | 214 | MKCpu *mpCPU; // object maintained locally 215 | Memory *mpROM; // object maintained locally 216 | Memory *mpRAM; // object maintained locally 217 | Display *mpDisp; // just a pointer 218 | ConsoleIO *mpConIO; // object maintained locally 219 | unsigned short mRunAddr; 220 | unsigned short mCharIOAddr; 221 | bool mCharIOActive; 222 | bool mCharIO; 223 | bool mOpInterrupt; // operator interrupt from console 224 | bool mAutoExec; 225 | bool mAutoReset; 226 | int mError; // last error code 227 | bool mGraphDispActive; 228 | bool mOldStyleHeader; 229 | PerfStats mPerfStats; 230 | queue mDebugTraces; 231 | bool mPerfStatsActive; 232 | bool mDebugTraceActive; 233 | time_point mBeginTime; 234 | 235 | int LoadMEM(string memfname, Memory *pmem); 236 | void ShowDisp(); 237 | bool HasHdrData(FILE *fp); 238 | bool HasOldHdrData(FILE *fp); 239 | bool LoadHdrData(FILE *fp); 240 | void SaveHdrData(FILE *fp); 241 | eMemoryImageTypes GetMemoryImageType(string ramfname); 242 | int CalcCurrPerf(); 243 | void AddDebugTrace(string msg); 244 | string Addr2HexStr(unsigned short addr); 245 | string Addr2DecStr(unsigned short addr); 246 | }; 247 | 248 | } // namespace MKBasic 249 | 250 | #endif 251 | -------------------------------------------------------------------------------- /bcd.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | unsigned char conv2bcd(unsigned short v) 8 | { 9 | unsigned char arg8 = 0; 10 | arg8 = (unsigned char)((v/10) << 4); 11 | arg8 |= ((unsigned char)(v - (v/10)*10)) & 0x0F; 12 | return arg8; 13 | } 14 | 15 | char *conv24bitbin(unsigned char v) 16 | { 17 | static char retbuf[5]; 18 | int i=3; 19 | 20 | memset(retbuf, '0', 4); 21 | retbuf[4]=0; 22 | if (v == 0) return retbuf; 23 | while (v > 0 && i >= 0) { 24 | int r = v % 2; 25 | retbuf[i] = ((r==0) ? '0' : '1'); 26 | v = v/2; 27 | i--; 28 | } 29 | 30 | return retbuf; 31 | } 32 | 33 | /* run this program using the console pauser or add your own getch, system("pause") or input loop */ 34 | 35 | int main(int argc, char *argv[]) 36 | { 37 | unsigned short v = 0; 38 | 39 | for (v = 0; v < 100; v++) { 40 | unsigned char cv = conv2bcd(v), hinyb, lonyb; 41 | hinyb = (cv & 0xF0) >> 4; 42 | lonyb = cv & 0x0F; 43 | char buf_hinyb[5], buf_lonyb[5]; 44 | strcpy(buf_hinyb, conv24bitbin(hinyb)); 45 | strcpy(buf_lonyb, conv24bitbin(lonyb)); 46 | printf("%d (dec) \t= %4s(%d) %4s(%d) (BCD, dec:%d)\n", v, 47 | buf_hinyb, 48 | hinyb, 49 | buf_lonyb, 50 | lonyb, 51 | cv); 52 | } 53 | 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /benchmarks.txt: -------------------------------------------------------------------------------- 1 | BM1 2 | 3 | 10 S=0 4 | 20 X=0 5 | 30 FOR I=1 TO 1000 6 | 40 S=S+X*X 7 | 50 X=X+0.00123 8 | 60 NEXT I 9 | 70 PRINT S,X 10 | 80 END 11 | 12 | 3.9 seconds on Z80 BBC BASIC (CP/M), 10MHz Z80 13 | 32 seconds in C64 WinVice emulator. 14 | 29 sec in C64 FrodoSC emulator. 15 | 4 seconds on VM65 with GD OFF, on PC1 (*) 16 | 4.5 seconds on VM65 with GD ON, on PC1 (*) 17 | 5 seconds on VM65 with GD OFF, on PC2 (*) 18 | 5 seconds on VM65 with GD ON, on PC2 (*) 19 | 20 | *) See NOTES. 21 | 22 | ------------------------------------------------------ 23 | 24 | BM2 25 | 26 | 130 PRINT "BM2" 27 | 140 FOR N=1 TO 1000 28 | 150 FOR K=2 TO 500 29 | 160 M=N/K 30 | 170 L=INT(M) 31 | 180 IF L=0 THEN 230 32 | 190 IF L=1 THEN 220 33 | 200 IF M>L THEN 220 34 | 210 IF M=L THEN 240 35 | 220 NEXT K 36 | 230 PRINT N 37 | 240 NEXT N 38 | 250 PRINT "E" 39 | 260 END 40 | 41 | 5 min 20 sec on Z80 BBC BASIC (CP/M), 10MHz Z80 42 | 19 min 52 sec on C64 WinVice emulator 43 | 2 min 44 sec on VM65 with GD OFF on PC1 (*) at ??? % (**) 44 | 3 min 15 sec on VM65 with GD ON on PC1 at ??? % 45 | 3 min 18 sec on VM65 with GD OFF on PC2 (*) at 486 % 46 | 3 min 33 sec on VM65 with GD ON on PC2 at 478 % (**) 47 | 48 | *), **) See NOTES. 49 | 50 | ------------------------------------------------------ 51 | 52 | BM3 53 | 54 | 10 LET W=500:DIM F(W):LET P=1:LET A=3 55 | 20 LET F(P)=A:LET P=P+1:IF P>W THEN STOP 56 | 30 LET A=A+2:LET X=1 57 | 40 LET S=A/F(X):IF S=INT(S) THEN 30 58 | 50 LET X=X+1:IF X

SIZE THEN 17 91 | 14 FLAGS(K)=0 92 | 15 K=K+PRIME 93 | 16 GOTO 13 94 | 17 COUNT=COUNT+1 95 | 18 NEXT I 96 | 19 PRINT COUNT," PRIMES" 97 | 98 | Results: 99 | VM65 - 57 seconds with GD OFF 100 | VM65 - 62 seconds with GD ON 101 | 102 | ------------------------------------------------------ 103 | 104 | BM5 105 | Primes generator, BASIC benchmark, based on above code. 106 | 107 | 10 S=8190: DIM F(8191): N=0 108 | 20 FOR I=0 TO S: F(I)=1: NEXT I 109 | 30 FOR I=0 TO S: IF F(I)=0 THEN 80 110 | 40 P=I+I+3: K=I+P 111 | 50 IF K>S THEN 70 112 | 60 F(K)=0: K=K+P: GOTO 50 113 | 70 N=N+1: PRINT P;" "; 114 | 80 NEXT I 115 | 90 PRINT: PRINT N;" PRIMES": END 116 | 117 | Results: 118 | VM65 - 55 seconds with GD OFF 119 | VM65 - 60 seconds with GD ON 120 | 121 | ------------------------------------------------------ 122 | 123 | NOTES: 124 | 125 | *) 126 | 127 | PC1 stats: 128 | Type: Desktop 129 | CPU: 2.49 GHz (64-bit Quad-core Q8300) 130 | RAM: 4,060 MB 131 | OS: Windows 10 Pro (no SP) [6.2.9200] 132 | 133 | PC2 stats: 134 | Type: Laptop 135 | CPU: 2.3 GHz (64-bit Quad-core i5-6300HQ) 136 | RAM: 15.9 GB 137 | OS: Win 10 Home. 138 | 139 | **) 140 | 141 | Emulation speed is measured inside emulator with 1 MHz CPU as a reference. 142 | In other words 100% speed is achieved when emulator executes 1,000,000 cycles 143 | in 1 second. Measurements are taken at the end of execution. Each time the 144 | average of previous measurements and current speed measurement result are 145 | summed together and divided by 2 to provide continuous calculation of average 146 | emulation speed in a single session. 147 | 148 | Executing 6502 code with no memory mapped devices enabled shows emulation 149 | speed ~645 % (PC1) or ~470 % (PC2). 150 | 151 | Emulation speed will likely decrease with # of enabled I/O devices and 152 | with # of enabled debugging facilities (e.g.: op-code execute history), 153 | but this depens on the PC specs and the current load on the system. 154 | With a graphics demo program modified to run in a continuous loop with char 155 | I/O enabled, graphics device enabled and actively used, op-code execute 156 | history disabled, I'm getting a decent performance of 407% on PC1. 157 | 158 | Note that all above benchmarks were ran with op-code execute history 159 | disabled and character I/O emulation enabled unless specified otherwise. 160 | 161 | **) 162 | 163 | Each place where results are preceeded with ??? they are outdated and 164 | tests must be repeated due to changes in code. 165 | 166 | 167 | -------------------------------------------------------------------------------- /bin2hex.c: -------------------------------------------------------------------------------- 1 | /* 2 | *---------------------------------------------------------------------------- 3 | * File: bin2hex.c 4 | * 5 | * Author: Marek Karcz 6 | * 7 | * Date created: 3/8/2016 8 | * 9 | * Purpose: Convert binary file to memory image definition (plain text) file. 10 | *---------------------------------------------------------------------------- 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | const int DEBUG = 0; 19 | const char *hdr1 = "; Created with BIN2HEX (C) Marek Karcz 2016. All rights reserved.\n"; 20 | 21 | char g_szInputFileName[256] = {0}; 22 | char g_szHexFileName[256] = {0}; 23 | int g_nStartAddr = 2048; /* $0800 */ 24 | int g_nExecAddr = 2048; /* $0800 */ 25 | int g_nSuppressAutoExec = 1; 26 | int g_nSuppressAllZeroRows = 0; 27 | int g_nConvert2IntelHex = 0; 28 | 29 | void ScanArgs(int argc, char *argv[]); 30 | void ConvertFile(void); 31 | void Convert2IntelHex(void); 32 | 33 | /* 34 | *-------------------------------------------------------------------- 35 | * Method: Usage() 36 | * Purpose: Print usage information/help. 37 | * Arguments: char * - program name. 38 | * Returns: n/a 39 | *-------------------------------------------------------------------- 40 | */ 41 | void Usage(char *prgn) 42 | { 43 | printf("\nProgram: %s\n Convert binary file to Intel HEX format.\nOR\n", prgn); 44 | printf(" Convert binary file to memory image definition for MKBASIC (VM65) emulator.\n\n"); 45 | printf("Copyright: Marek Karcz 2016. All rights reserved.\n"); 46 | printf("Free for personal and educational use.\n\n"); 47 | printf("Usage:\n\n"); 48 | printf(" %s -f input -o output [-w addr] [-x exec] [[-s] [-z] | -i]\n\n", prgn); 49 | printf("Where:\n\n"); 50 | printf(" input - binary file name\n"); 51 | printf(" output - output file name\n"); 52 | printf(" addr - starting address to load data (default: %d)\n", g_nStartAddr); 53 | printf(" exec - address to auto-execute code from (default: %d)\n", g_nExecAddr); 54 | printf(" -s - suppress auto-execute statement in output\n"); 55 | printf(" -z - suppress data blocks with 0-s only\n"); 56 | printf(" -i - convert to Intel HEX format\n"); 57 | printf(" NOTE: When this switch is used, addr, exec, -s, -z are ignored,\n"); 58 | printf(" addr = 0, exec is not set and data blocks with 0-s only\n"); 59 | printf(" are always suppressed.\n"); 60 | printf("\n"); 61 | } 62 | 63 | /* 64 | *-------------------------------------------------------------------- 65 | * Method: ScanArgs() 66 | * Purpose: Scan/parse command line arguments and set internal 67 | * flags and parameters. 68 | * Arguments: int argc - # of command line arguments, 69 | * char *argv[] - array of command line arguments. 70 | * Returns: n/a 71 | *-------------------------------------------------------------------- 72 | */ 73 | void ScanArgs(int argc, char *argv[]) 74 | { 75 | int n = 1; 76 | 77 | while (n < argc) 78 | { 79 | if (strcmp(argv[n], "-f") == 0) 80 | { 81 | n++; 82 | strcpy(g_szInputFileName,argv[n]); 83 | } 84 | else if (strcmp(argv[n],"-o") == 0) 85 | { 86 | n++; 87 | strcpy(g_szHexFileName,argv[n]); 88 | } 89 | else if (strcmp(argv[n],"-w") == 0) 90 | { 91 | n++; 92 | g_nStartAddr = atoi(argv[n]); 93 | g_nExecAddr = g_nStartAddr; 94 | g_nSuppressAutoExec = 0; 95 | } 96 | else if (strcmp(argv[n],"-x") == 0) 97 | { 98 | n++; 99 | g_nExecAddr = atoi(argv[n]); 100 | g_nSuppressAutoExec = 0; 101 | } 102 | else if (strcmp(argv[n],"-s") == 0) 103 | { 104 | g_nSuppressAutoExec = 1; 105 | } 106 | else if (strcmp(argv[n],"-z") == 0) 107 | { 108 | g_nSuppressAllZeroRows = 1; 109 | } 110 | else if (strcmp(argv[n],"-i") == 0) 111 | { 112 | g_nConvert2IntelHex = 1; 113 | } 114 | 115 | n++; 116 | } 117 | } 118 | 119 | /* 120 | *-------------------------------------------------------------------- 121 | * Method: ConvertFile() 122 | * Purpose: Convert binary file to plain text memory definition 123 | * file for MKBASIC (VM65) emulator. 124 | * Arguments: n/a 125 | * Returns: n/a 126 | *-------------------------------------------------------------------- 127 | */ 128 | void ConvertFile(void) 129 | { 130 | FILE *fpi = NULL; 131 | FILE *fpo = NULL; 132 | unsigned char bt[17]; 133 | char hex[80]; 134 | int i, addr, allzero, prev_allzero; 135 | 136 | addr = g_nStartAddr; 137 | printf("Processing...\n"); 138 | printf("Start address: $%04x\n", addr); 139 | if (NULL != (fpi = fopen(g_szInputFileName,"rb"))) 140 | { 141 | if (NULL != (fpo = fopen(g_szHexFileName,"w"))) 142 | { 143 | time_t t = time(NULL); 144 | struct tm *tm = localtime(&t); 145 | char s[64] = {0}; 146 | strftime(s, sizeof(s), "; %c\n", tm); 147 | 148 | fputs(hdr1, fpo); 149 | fputs(s, fpo); 150 | sprintf(hex, "ADDR\n$%04x\nORG\n$%04x\n", g_nExecAddr, addr); 151 | if (DEBUG) printf("Adding line:\n%s\n", hex); 152 | fputs(hex,fpo); 153 | prev_allzero = 1; 154 | while(0 == feof(fpi) && addr <= 0xFFFF) 155 | { 156 | memset(bt, 0, 17); 157 | memset(hex, 0, 80); 158 | if (DEBUG) printf("Reading input file..."); 159 | fread(bt, sizeof(char), 16, fpi); 160 | if (DEBUG) printf("done.\n"); 161 | if (DEBUG) printf("Preparing hex string...\n"); 162 | allzero = 1; 163 | for(i=0; i<16; i++) 164 | { 165 | if (DEBUG) printf("Code: %d\n", bt[i]); 166 | if (*hex == 0) sprintf(hex, "$%02x", bt[i]); 167 | else sprintf(hex, "%s $%02x", hex, bt[i]); 168 | if (allzero && bt[i] > 0) 169 | allzero = 0; 170 | } 171 | if (g_nSuppressAllZeroRows && prev_allzero && 0 == allzero) { 172 | char buff[20]; 173 | sprintf (buff, "ORG\n$%04x\n", addr); 174 | fputs(buff, fpo); 175 | } 176 | if (0 == g_nSuppressAllZeroRows 177 | || 178 | (g_nSuppressAllZeroRows && 0 == allzero) 179 | ) 180 | { 181 | sprintf(hex, "%s\n", hex); 182 | if (DEBUG) printf("Adding line: %s", hex); 183 | fputs(hex, fpo); 184 | } 185 | addr += 16; 186 | prev_allzero = allzero; 187 | } 188 | if (0 == g_nSuppressAutoExec) 189 | { 190 | memset(hex, 80, sizeof(char)); 191 | sprintf(hex, "EXEC\n$%04x\n", g_nExecAddr); 192 | if (DEBUG) printf("Adding line: %s", hex); 193 | fputs(hex, fpo); 194 | } 195 | fclose(fpi); 196 | fclose(fpo); 197 | printf("Done.\n"); 198 | printf("End address: $%04x\n", (addr <= 0xFFFF) ? addr : 0xFFFF); 199 | printf("Run address: $%04x\n", g_nExecAddr); 200 | } 201 | else 202 | printf("ERROR: Unable to create output file.\n"); 203 | } 204 | else 205 | printf("ERROR: Unable to open input file.\n"); 206 | } 207 | 208 | /* 209 | *-------------------------------------------------------------------- 210 | * Method: Convert2IntelHex() 211 | * Purpose: Convert binary file to Intel HEX format. 212 | * Arguments: n/a 213 | * Returns: n/a 214 | *-------------------------------------------------------------------- 215 | */ 216 | void Convert2IntelHex(void) 217 | { 218 | FILE *fpi = NULL; 219 | FILE *fpo = NULL; 220 | unsigned char bt[17], cksum; 221 | char hex[80]; 222 | int i, allzero; 223 | unsigned int addr; 224 | 225 | addr = 0; 226 | g_nSuppressAllZeroRows = 1; 227 | g_nExecAddr = 0; 228 | printf("Processing...\n"); 229 | printf("Start address: $%04x\n", addr); 230 | if (NULL != (fpi = fopen(g_szInputFileName,"rb"))) 231 | { 232 | if (NULL != (fpo = fopen(g_szHexFileName,"w"))) 233 | { 234 | while(0 == feof(fpi) && addr <= 0xFFFF) 235 | { 236 | memset(bt, 0, 17); 237 | memset(hex, 0, 80); 238 | if (DEBUG) printf("Reading input file..."); 239 | fread(bt, sizeof(char), 16, fpi); 240 | if (DEBUG) printf("done.\n"); 241 | if (DEBUG) printf("Preparing hex string...\n"); 242 | /* start the Intel HEX data record, all data blocks 243 | generated by this program are 16-bytes long 244 | */ 245 | sprintf(hex, ":10%04x00", addr); 246 | cksum = 0; 247 | allzero = 1; 248 | /* append data to record */ 249 | for(i=0; i<16; i++) 250 | { 251 | cksum += bt[i]; 252 | if (DEBUG) printf("Code: %d\n", bt[i]); 253 | sprintf(hex, "%s%02x", hex, bt[i]); 254 | if (allzero && bt[i]) allzero = 0; 255 | } 256 | cksum = ~cksum + 1; /* Two's complement of modulo 256 sum */ 257 | /* end record with check sum value */ 258 | sprintf(hex, "%s%02x", hex, cksum); 259 | /* output only if non-zero data present in 16-byte block */ 260 | if (0 == g_nSuppressAllZeroRows 261 | || 262 | (g_nSuppressAllZeroRows && 0 == allzero) 263 | ) 264 | { 265 | sprintf(hex, "%s\n", hex); 266 | if (DEBUG) printf("Adding line: %s", hex); 267 | fputs(hex, fpo); 268 | } 269 | addr += 16; 270 | } 271 | /* add EOF */ 272 | hex[0] = 0; 273 | strcpy(hex, ":00000001FF"); 274 | sprintf(hex, "%s\n", hex); 275 | fputs(hex, fpo); 276 | fclose(fpi); 277 | fclose(fpo); 278 | printf("Done.\n"); 279 | printf("End address: $%04x\n", (addr <= 0xFFFF) ? addr : 0xFFFF); 280 | printf("Run address: $%04x\n", g_nExecAddr); 281 | } 282 | else 283 | printf("ERROR: Unable to create output file.\n"); 284 | } 285 | else 286 | printf("ERROR: Unable to open input file.\n"); 287 | } 288 | 289 | /* 290 | *-------------------------------------------------------------------- 291 | * Method: main() 292 | * Purpose: Main program loop/routine. 293 | * Arguments: int argc - # of provided in command line arguments. 294 | * char *argv[] - array of command line arguments. 295 | * Returns: int - always 0. 296 | *-------------------------------------------------------------------- 297 | */ 298 | int main(int argc, char *argv[]) 299 | { 300 | if (argc == 1) 301 | Usage(argv[0]); 302 | else { 303 | ScanArgs(argc, argv); 304 | if (*g_szInputFileName == 0 || *g_szHexFileName == 0) 305 | Usage(argv[0]); 306 | else { 307 | if (0 == g_nConvert2IntelHex) 308 | ConvertFile(); 309 | else 310 | Convert2IntelHex(); 311 | } 312 | } 313 | return 0; 314 | } 315 | 316 | 317 | -------------------------------------------------------------------------------- /c64_char.dat: -------------------------------------------------------------------------------- 1 | ADDR 2 | $b000 3 | ; Created with BIN2HEX (C) Marek Karcz 2016. All rights reserved. 4 | ; 09/08/16 13:19:24 5 | ; This is the character ROM dump of C64. 6 | ; C64 char ROM begins @$D000 and takes 4 kB ($1000): $D000..$DFFF. 7 | ; This image loads to address $B000 so I can use it with EhBASIC. 8 | ; Use EhBASIC with modified RAM Top @$B000. 9 | ; 10 | ORG 11 | $b000 12 | $3c $66 $6e $6e $60 $62 $3c $00 $18 $3c $66 $7e $66 $66 $66 $00 13 | $7c $66 $66 $7c $66 $66 $7c $00 $3c $66 $60 $60 $60 $66 $3c $00 14 | $78 $6c $66 $66 $66 $6c $78 $00 $7e $60 $60 $78 $60 $60 $7e $00 15 | $7e $60 $60 $78 $60 $60 $60 $00 $3c $66 $60 $6e $66 $66 $3c $00 16 | $66 $66 $66 $7e $66 $66 $66 $00 $3c $18 $18 $18 $18 $18 $3c $00 17 | $1e $0c $0c $0c $0c $6c $38 $00 $66 $6c $78 $70 $78 $6c $66 $00 18 | $60 $60 $60 $60 $60 $60 $7e $00 $63 $77 $7f $6b $63 $63 $63 $00 19 | $66 $76 $7e $7e $6e $66 $66 $00 $3c $66 $66 $66 $66 $66 $3c $00 20 | $7c $66 $66 $7c $60 $60 $60 $00 $3c $66 $66 $66 $66 $3c $0e $00 21 | $7c $66 $66 $7c $78 $6c $66 $00 $3c $66 $60 $3c $06 $66 $3c $00 22 | $7e $18 $18 $18 $18 $18 $18 $00 $66 $66 $66 $66 $66 $66 $3c $00 23 | $66 $66 $66 $66 $66 $3c $18 $00 $63 $63 $63 $6b $7f $77 $63 $00 24 | $66 $66 $3c $18 $3c $66 $66 $00 $66 $66 $66 $3c $18 $18 $18 $00 25 | $7e $06 $0c $18 $30 $60 $7e $00 $3c $30 $30 $30 $30 $30 $3c $00 26 | $0c $12 $30 $7c $30 $62 $fc $00 $3c $0c $0c $0c $0c $0c $3c $00 27 | $00 $18 $3c $7e $18 $18 $18 $18 $00 $10 $30 $7f $7f $30 $10 $00 28 | $00 $00 $00 $00 $00 $00 $00 $00 $18 $18 $18 $18 $00 $00 $18 $00 29 | $66 $66 $66 $00 $00 $00 $00 $00 $66 $66 $ff $66 $ff $66 $66 $00 30 | $18 $3e $60 $3c $06 $7c $18 $00 $62 $66 $0c $18 $30 $66 $46 $00 31 | $3c $66 $3c $38 $67 $66 $3f $00 $06 $0c $18 $00 $00 $00 $00 $00 32 | $0c $18 $30 $30 $30 $18 $0c $00 $30 $18 $0c $0c $0c $18 $30 $00 33 | $00 $66 $3c $ff $3c $66 $00 $00 $00 $18 $18 $7e $18 $18 $00 $00 34 | $00 $00 $00 $00 $00 $18 $18 $30 $00 $00 $00 $7e $00 $00 $00 $00 35 | $00 $00 $00 $00 $00 $18 $18 $00 $00 $03 $06 $0c $18 $30 $60 $00 36 | $3c $66 $6e $76 $66 $66 $3c $00 $18 $18 $38 $18 $18 $18 $7e $00 37 | $3c $66 $06 $0c $30 $60 $7e $00 $3c $66 $06 $1c $06 $66 $3c $00 38 | $06 $0e $1e $66 $7f $06 $06 $00 $7e $60 $7c $06 $06 $66 $3c $00 39 | $3c $66 $60 $7c $66 $66 $3c $00 $7e $66 $0c $18 $18 $18 $18 $00 40 | $3c $66 $66 $3c $66 $66 $3c $00 $3c $66 $66 $3e $06 $66 $3c $00 41 | $00 $00 $18 $00 $00 $18 $00 $00 $00 $00 $18 $00 $00 $18 $18 $30 42 | $0e $18 $30 $60 $30 $18 $0e $00 $00 $00 $7e $00 $7e $00 $00 $00 43 | $70 $18 $0c $06 $0c $18 $70 $00 $3c $66 $06 $0c $18 $00 $18 $00 44 | $00 $00 $00 $ff $ff $00 $00 $00 $08 $1c $3e $7f $7f $1c $3e $00 45 | $18 $18 $18 $18 $18 $18 $18 $18 $00 $00 $00 $ff $ff $00 $00 $00 46 | $00 $00 $ff $ff $00 $00 $00 $00 $00 $ff $ff $00 $00 $00 $00 $00 47 | $00 $00 $00 $00 $ff $ff $00 $00 $30 $30 $30 $30 $30 $30 $30 $30 48 | $0c $0c $0c $0c $0c $0c $0c $0c $00 $00 $00 $e0 $f0 $38 $18 $18 49 | $18 $18 $1c $0f $07 $00 $00 $00 $18 $18 $38 $f0 $e0 $00 $00 $00 50 | $c0 $c0 $c0 $c0 $c0 $c0 $ff $ff $c0 $e0 $70 $38 $1c $0e $07 $03 51 | $03 $07 $0e $1c $38 $70 $e0 $c0 $ff $ff $c0 $c0 $c0 $c0 $c0 $c0 52 | $ff $ff $03 $03 $03 $03 $03 $03 $00 $3c $7e $7e $7e $7e $3c $00 53 | $00 $00 $00 $00 $00 $ff $ff $00 $36 $7f $7f $7f $3e $1c $08 $00 54 | $60 $60 $60 $60 $60 $60 $60 $60 $00 $00 $00 $07 $0f $1c $18 $18 55 | $c3 $e7 $7e $3c $3c $7e $e7 $c3 $00 $3c $7e $66 $66 $7e $3c $00 56 | $18 $18 $66 $66 $18 $18 $3c $00 $06 $06 $06 $06 $06 $06 $06 $06 57 | $08 $1c $3e $7f $3e $1c $08 $00 $18 $18 $18 $ff $ff $18 $18 $18 58 | $c0 $c0 $30 $30 $c0 $c0 $30 $30 $18 $18 $18 $18 $18 $18 $18 $18 59 | $00 $00 $03 $3e $76 $36 $36 $00 $ff $7f $3f $1f $0f $07 $03 $01 60 | $00 $00 $00 $00 $00 $00 $00 $00 $f0 $f0 $f0 $f0 $f0 $f0 $f0 $f0 61 | $00 $00 $00 $00 $ff $ff $ff $ff $ff $00 $00 $00 $00 $00 $00 $00 62 | $00 $00 $00 $00 $00 $00 $00 $ff $c0 $c0 $c0 $c0 $c0 $c0 $c0 $c0 63 | $cc $cc $33 $33 $cc $cc $33 $33 $03 $03 $03 $03 $03 $03 $03 $03 64 | $00 $00 $00 $00 $cc $cc $33 $33 $ff $fe $fc $f8 $f0 $e0 $c0 $80 65 | $03 $03 $03 $03 $03 $03 $03 $03 $18 $18 $18 $1f $1f $18 $18 $18 66 | $00 $00 $00 $00 $0f $0f $0f $0f $18 $18 $18 $1f $1f $00 $00 $00 67 | $00 $00 $00 $f8 $f8 $18 $18 $18 $00 $00 $00 $00 $00 $00 $ff $ff 68 | $00 $00 $00 $1f $1f $18 $18 $18 $18 $18 $18 $ff $ff $00 $00 $00 69 | $00 $00 $00 $ff $ff $18 $18 $18 $18 $18 $18 $f8 $f8 $18 $18 $18 70 | $c0 $c0 $c0 $c0 $c0 $c0 $c0 $c0 $e0 $e0 $e0 $e0 $e0 $e0 $e0 $e0 71 | $07 $07 $07 $07 $07 $07 $07 $07 $ff $ff $00 $00 $00 $00 $00 $00 72 | $ff $ff $ff $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $ff $ff $ff 73 | $03 $03 $03 $03 $03 $03 $ff $ff $00 $00 $00 $00 $f0 $f0 $f0 $f0 74 | $0f $0f $0f $0f $00 $00 $00 $00 $18 $18 $18 $f8 $f8 $00 $00 $00 75 | $f0 $f0 $f0 $f0 $00 $00 $00 $00 $f0 $f0 $f0 $f0 $0f $0f $0f $0f 76 | $c3 $99 $91 $91 $9f $99 $c3 $ff $e7 $c3 $99 $81 $99 $99 $99 $ff 77 | $83 $99 $99 $83 $99 $99 $83 $ff $c3 $99 $9f $9f $9f $99 $c3 $ff 78 | $87 $93 $99 $99 $99 $93 $87 $ff $81 $9f $9f $87 $9f $9f $81 $ff 79 | $81 $9f $9f $87 $9f $9f $9f $ff $c3 $99 $9f $91 $99 $99 $c3 $ff 80 | $99 $99 $99 $81 $99 $99 $99 $ff $c3 $e7 $e7 $e7 $e7 $e7 $c3 $ff 81 | $e1 $f3 $f3 $f3 $f3 $93 $c7 $ff $99 $93 $87 $8f $87 $93 $99 $ff 82 | $9f $9f $9f $9f $9f $9f $81 $ff $9c $88 $80 $94 $9c $9c $9c $ff 83 | $99 $89 $81 $81 $91 $99 $99 $ff $c3 $99 $99 $99 $99 $99 $c3 $ff 84 | $83 $99 $99 $83 $9f $9f $9f $ff $c3 $99 $99 $99 $99 $c3 $f1 $ff 85 | $83 $99 $99 $83 $87 $93 $99 $ff $c3 $99 $9f $c3 $f9 $99 $c3 $ff 86 | $81 $e7 $e7 $e7 $e7 $e7 $e7 $ff $99 $99 $99 $99 $99 $99 $c3 $ff 87 | $99 $99 $99 $99 $99 $c3 $e7 $ff $9c $9c $9c $94 $80 $88 $9c $ff 88 | $99 $99 $c3 $e7 $c3 $99 $99 $ff $99 $99 $99 $c3 $e7 $e7 $e7 $ff 89 | $81 $f9 $f3 $e7 $cf $9f $81 $ff $c3 $cf $cf $cf $cf $cf $c3 $ff 90 | $f3 $ed $cf $83 $cf $9d $03 $ff $c3 $f3 $f3 $f3 $f3 $f3 $c3 $ff 91 | $ff $e7 $c3 $81 $e7 $e7 $e7 $e7 $ff $ef $cf $80 $80 $cf $ef $ff 92 | $ff $ff $ff $ff $ff $ff $ff $ff $e7 $e7 $e7 $e7 $ff $ff $e7 $ff 93 | $99 $99 $99 $ff $ff $ff $ff $ff $99 $99 $00 $99 $00 $99 $99 $ff 94 | $e7 $c1 $9f $c3 $f9 $83 $e7 $ff $9d $99 $f3 $e7 $cf $99 $b9 $ff 95 | $c3 $99 $c3 $c7 $98 $99 $c0 $ff $f9 $f3 $e7 $ff $ff $ff $ff $ff 96 | $f3 $e7 $cf $cf $cf $e7 $f3 $ff $cf $e7 $f3 $f3 $f3 $e7 $cf $ff 97 | $ff $99 $c3 $00 $c3 $99 $ff $ff $ff $e7 $e7 $81 $e7 $e7 $ff $ff 98 | $ff $ff $ff $ff $ff $e7 $e7 $cf $ff $ff $ff $81 $ff $ff $ff $ff 99 | $ff $ff $ff $ff $ff $e7 $e7 $ff $ff $fc $f9 $f3 $e7 $cf $9f $ff 100 | $c3 $99 $91 $89 $99 $99 $c3 $ff $e7 $e7 $c7 $e7 $e7 $e7 $81 $ff 101 | $c3 $99 $f9 $f3 $cf $9f $81 $ff $c3 $99 $f9 $e3 $f9 $99 $c3 $ff 102 | $f9 $f1 $e1 $99 $80 $f9 $f9 $ff $81 $9f $83 $f9 $f9 $99 $c3 $ff 103 | $c3 $99 $9f $83 $99 $99 $c3 $ff $81 $99 $f3 $e7 $e7 $e7 $e7 $ff 104 | $c3 $99 $99 $c3 $99 $99 $c3 $ff $c3 $99 $99 $c1 $f9 $99 $c3 $ff 105 | $ff $ff $e7 $ff $ff $e7 $ff $ff $ff $ff $e7 $ff $ff $e7 $e7 $cf 106 | $f1 $e7 $cf $9f $cf $e7 $f1 $ff $ff $ff $81 $ff $81 $ff $ff $ff 107 | $8f $e7 $f3 $f9 $f3 $e7 $8f $ff $c3 $99 $f9 $f3 $e7 $ff $e7 $ff 108 | $ff $ff $ff $00 $00 $ff $ff $ff $f7 $e3 $c1 $80 $80 $e3 $c1 $ff 109 | $e7 $e7 $e7 $e7 $e7 $e7 $e7 $e7 $ff $ff $ff $00 $00 $ff $ff $ff 110 | $ff $ff $00 $00 $ff $ff $ff $ff $ff $00 $00 $ff $ff $ff $ff $ff 111 | $ff $ff $ff $ff $00 $00 $ff $ff $cf $cf $cf $cf $cf $cf $cf $cf 112 | $f3 $f3 $f3 $f3 $f3 $f3 $f3 $f3 $ff $ff $ff $1f $0f $c7 $e7 $e7 113 | $e7 $e7 $e3 $f0 $f8 $ff $ff $ff $e7 $e7 $c7 $0f $1f $ff $ff $ff 114 | $3f $3f $3f $3f $3f $3f $00 $00 $3f $1f $8f $c7 $e3 $f1 $f8 $fc 115 | $fc $f8 $f1 $e3 $c7 $8f $1f $3f $00 $00 $3f $3f $3f $3f $3f $3f 116 | $00 $00 $fc $fc $fc $fc $fc $fc $ff $c3 $81 $81 $81 $81 $c3 $ff 117 | $ff $ff $ff $ff $ff $00 $00 $ff $c9 $80 $80 $80 $c1 $e3 $f7 $ff 118 | $9f $9f $9f $9f $9f $9f $9f $9f $ff $ff $ff $f8 $f0 $e3 $e7 $e7 119 | $3c $18 $81 $c3 $c3 $81 $18 $3c $ff $c3 $81 $99 $99 $81 $c3 $ff 120 | $e7 $e7 $99 $99 $e7 $e7 $c3 $ff $f9 $f9 $f9 $f9 $f9 $f9 $f9 $f9 121 | $f7 $e3 $c1 $80 $c1 $e3 $f7 $ff $e7 $e7 $e7 $00 $00 $e7 $e7 $e7 122 | $3f $3f $cf $cf $3f $3f $cf $cf $e7 $e7 $e7 $e7 $e7 $e7 $e7 $e7 123 | $ff $ff $fc $c1 $89 $c9 $c9 $ff $00 $80 $c0 $e0 $f0 $f8 $fc $fe 124 | $ff $ff $ff $ff $ff $ff $ff $ff $0f $0f $0f $0f $0f $0f $0f $0f 125 | $ff $ff $ff $ff $00 $00 $00 $00 $00 $ff $ff $ff $ff $ff $ff $ff 126 | $ff $ff $ff $ff $ff $ff $ff $00 $3f $3f $3f $3f $3f $3f $3f $3f 127 | $33 $33 $cc $cc $33 $33 $cc $cc $fc $fc $fc $fc $fc $fc $fc $fc 128 | $ff $ff $ff $ff $33 $33 $cc $cc $00 $01 $03 $07 $0f $1f $3f $7f 129 | $fc $fc $fc $fc $fc $fc $fc $fc $e7 $e7 $e7 $e0 $e0 $e7 $e7 $e7 130 | $ff $ff $ff $ff $f0 $f0 $f0 $f0 $e7 $e7 $e7 $e0 $e0 $ff $ff $ff 131 | $ff $ff $ff $07 $07 $e7 $e7 $e7 $ff $ff $ff $ff $ff $ff $00 $00 132 | $ff $ff $ff $e0 $e0 $e7 $e7 $e7 $e7 $e7 $e7 $00 $00 $ff $ff $ff 133 | $ff $ff $ff $00 $00 $e7 $e7 $e7 $e7 $e7 $e7 $07 $07 $e7 $e7 $e7 134 | $3f $3f $3f $3f $3f $3f $3f $3f $1f $1f $1f $1f $1f $1f $1f $1f 135 | $f8 $f8 $f8 $f8 $f8 $f8 $f8 $f8 $00 $00 $ff $ff $ff $ff $ff $ff 136 | $00 $00 $00 $ff $ff $ff $ff $ff $ff $ff $ff $ff $ff $00 $00 $00 137 | $fc $fc $fc $fc $fc $fc $00 $00 $ff $ff $ff $ff $0f $0f $0f $0f 138 | $f0 $f0 $f0 $f0 $ff $ff $ff $ff $e7 $e7 $e7 $07 $07 $ff $ff $ff 139 | $0f $0f $0f $0f $ff $ff $ff $ff $0f $0f $0f $0f $f0 $f0 $f0 $f0 140 | $3c $66 $6e $6e $60 $62 $3c $00 $00 $00 $3c $06 $3e $66 $3e $00 141 | $00 $60 $60 $7c $66 $66 $7c $00 $00 $00 $3c $60 $60 $60 $3c $00 142 | $00 $06 $06 $3e $66 $66 $3e $00 $00 $00 $3c $66 $7e $60 $3c $00 143 | $00 $0e $18 $3e $18 $18 $18 $00 $00 $00 $3e $66 $66 $3e $06 $7c 144 | $00 $60 $60 $7c $66 $66 $66 $00 $00 $18 $00 $38 $18 $18 $3c $00 145 | $00 $06 $00 $06 $06 $06 $06 $3c $00 $60 $60 $6c $78 $6c $66 $00 146 | $00 $38 $18 $18 $18 $18 $3c $00 $00 $00 $66 $7f $7f $6b $63 $00 147 | $00 $00 $7c $66 $66 $66 $66 $00 $00 $00 $3c $66 $66 $66 $3c $00 148 | $00 $00 $7c $66 $66 $7c $60 $60 $00 $00 $3e $66 $66 $3e $06 $06 149 | $00 $00 $7c $66 $60 $60 $60 $00 $00 $00 $3e $60 $3c $06 $7c $00 150 | $00 $18 $7e $18 $18 $18 $0e $00 $00 $00 $66 $66 $66 $66 $3e $00 151 | $00 $00 $66 $66 $66 $3c $18 $00 $00 $00 $63 $6b $7f $3e $36 $00 152 | $00 $00 $66 $3c $18 $3c $66 $00 $00 $00 $66 $66 $66 $3e $0c $78 153 | $00 $00 $7e $0c $18 $30 $7e $00 $3c $30 $30 $30 $30 $30 $3c $00 154 | $0c $12 $30 $7c $30 $62 $fc $00 $3c $0c $0c $0c $0c $0c $3c $00 155 | $00 $18 $3c $7e $18 $18 $18 $18 $00 $10 $30 $7f $7f $30 $10 $00 156 | $00 $00 $00 $00 $00 $00 $00 $00 $18 $18 $18 $18 $00 $00 $18 $00 157 | $66 $66 $66 $00 $00 $00 $00 $00 $66 $66 $ff $66 $ff $66 $66 $00 158 | $18 $3e $60 $3c $06 $7c $18 $00 $62 $66 $0c $18 $30 $66 $46 $00 159 | $3c $66 $3c $38 $67 $66 $3f $00 $06 $0c $18 $00 $00 $00 $00 $00 160 | $0c $18 $30 $30 $30 $18 $0c $00 $30 $18 $0c $0c $0c $18 $30 $00 161 | $00 $66 $3c $ff $3c $66 $00 $00 $00 $18 $18 $7e $18 $18 $00 $00 162 | $00 $00 $00 $00 $00 $18 $18 $30 $00 $00 $00 $7e $00 $00 $00 $00 163 | $00 $00 $00 $00 $00 $18 $18 $00 $00 $03 $06 $0c $18 $30 $60 $00 164 | $3c $66 $6e $76 $66 $66 $3c $00 $18 $18 $38 $18 $18 $18 $7e $00 165 | $3c $66 $06 $0c $30 $60 $7e $00 $3c $66 $06 $1c $06 $66 $3c $00 166 | $06 $0e $1e $66 $7f $06 $06 $00 $7e $60 $7c $06 $06 $66 $3c $00 167 | $3c $66 $60 $7c $66 $66 $3c $00 $7e $66 $0c $18 $18 $18 $18 $00 168 | $3c $66 $66 $3c $66 $66 $3c $00 $3c $66 $66 $3e $06 $66 $3c $00 169 | $00 $00 $18 $00 $00 $18 $00 $00 $00 $00 $18 $00 $00 $18 $18 $30 170 | $0e $18 $30 $60 $30 $18 $0e $00 $00 $00 $7e $00 $7e $00 $00 $00 171 | $70 $18 $0c $06 $0c $18 $70 $00 $3c $66 $06 $0c $18 $00 $18 $00 172 | $00 $00 $00 $ff $ff $00 $00 $00 $18 $3c $66 $7e $66 $66 $66 $00 173 | $7c $66 $66 $7c $66 $66 $7c $00 $3c $66 $60 $60 $60 $66 $3c $00 174 | $78 $6c $66 $66 $66 $6c $78 $00 $7e $60 $60 $78 $60 $60 $7e $00 175 | $7e $60 $60 $78 $60 $60 $60 $00 $3c $66 $60 $6e $66 $66 $3c $00 176 | $66 $66 $66 $7e $66 $66 $66 $00 $3c $18 $18 $18 $18 $18 $3c $00 177 | $1e $0c $0c $0c $0c $6c $38 $00 $66 $6c $78 $70 $78 $6c $66 $00 178 | $60 $60 $60 $60 $60 $60 $7e $00 $63 $77 $7f $6b $63 $63 $63 $00 179 | $66 $76 $7e $7e $6e $66 $66 $00 $3c $66 $66 $66 $66 $66 $3c $00 180 | $7c $66 $66 $7c $60 $60 $60 $00 $3c $66 $66 $66 $66 $3c $0e $00 181 | $7c $66 $66 $7c $78 $6c $66 $00 $3c $66 $60 $3c $06 $66 $3c $00 182 | $7e $18 $18 $18 $18 $18 $18 $00 $66 $66 $66 $66 $66 $66 $3c $00 183 | $66 $66 $66 $66 $66 $3c $18 $00 $63 $63 $63 $6b $7f $77 $63 $00 184 | $66 $66 $3c $18 $3c $66 $66 $00 $66 $66 $66 $3c $18 $18 $18 $00 185 | $7e $06 $0c $18 $30 $60 $7e $00 $18 $18 $18 $ff $ff $18 $18 $18 186 | $c0 $c0 $30 $30 $c0 $c0 $30 $30 $18 $18 $18 $18 $18 $18 $18 $18 187 | $33 $33 $cc $cc $33 $33 $cc $cc $33 $99 $cc $66 $33 $99 $cc $66 188 | $00 $00 $00 $00 $00 $00 $00 $00 $f0 $f0 $f0 $f0 $f0 $f0 $f0 $f0 189 | $00 $00 $00 $00 $ff $ff $ff $ff $ff $00 $00 $00 $00 $00 $00 $00 190 | $00 $00 $00 $00 $00 $00 $00 $ff $c0 $c0 $c0 $c0 $c0 $c0 $c0 $c0 191 | $cc $cc $33 $33 $cc $cc $33 $33 $03 $03 $03 $03 $03 $03 $03 $03 192 | $00 $00 $00 $00 $cc $cc $33 $33 $cc $99 $33 $66 $cc $99 $33 $66 193 | $03 $03 $03 $03 $03 $03 $03 $03 $18 $18 $18 $1f $1f $18 $18 $18 194 | $00 $00 $00 $00 $0f $0f $0f $0f $18 $18 $18 $1f $1f $00 $00 $00 195 | $00 $00 $00 $f8 $f8 $18 $18 $18 $00 $00 $00 $00 $00 $00 $ff $ff 196 | $00 $00 $00 $1f $1f $18 $18 $18 $18 $18 $18 $ff $ff $00 $00 $00 197 | $00 $00 $00 $ff $ff $18 $18 $18 $18 $18 $18 $f8 $f8 $18 $18 $18 198 | $c0 $c0 $c0 $c0 $c0 $c0 $c0 $c0 $e0 $e0 $e0 $e0 $e0 $e0 $e0 $e0 199 | $07 $07 $07 $07 $07 $07 $07 $07 $ff $ff $00 $00 $00 $00 $00 $00 200 | $ff $ff $ff $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $ff $ff $ff 201 | $01 $03 $06 $6c $78 $70 $60 $00 $00 $00 $00 $00 $f0 $f0 $f0 $f0 202 | $0f $0f $0f $0f $00 $00 $00 $00 $18 $18 $18 $f8 $f8 $00 $00 $00 203 | $f0 $f0 $f0 $f0 $00 $00 $00 $00 $f0 $f0 $f0 $f0 $0f $0f $0f $0f 204 | $c3 $99 $91 $91 $9f $99 $c3 $ff $ff $ff $c3 $f9 $c1 $99 $c1 $ff 205 | $ff $9f $9f $83 $99 $99 $83 $ff $ff $ff $c3 $9f $9f $9f $c3 $ff 206 | $ff $f9 $f9 $c1 $99 $99 $c1 $ff $ff $ff $c3 $99 $81 $9f $c3 $ff 207 | $ff $f1 $e7 $c1 $e7 $e7 $e7 $ff $ff $ff $c1 $99 $99 $c1 $f9 $83 208 | $ff $9f $9f $83 $99 $99 $99 $ff $ff $e7 $ff $c7 $e7 $e7 $c3 $ff 209 | $ff $f9 $ff $f9 $f9 $f9 $f9 $c3 $ff $9f $9f $93 $87 $93 $99 $ff 210 | $ff $c7 $e7 $e7 $e7 $e7 $c3 $ff $ff $ff $99 $80 $80 $94 $9c $ff 211 | $ff $ff $83 $99 $99 $99 $99 $ff $ff $ff $c3 $99 $99 $99 $c3 $ff 212 | $ff $ff $83 $99 $99 $83 $9f $9f $ff $ff $c1 $99 $99 $c1 $f9 $f9 213 | $ff $ff $83 $99 $9f $9f $9f $ff $ff $ff $c1 $9f $c3 $f9 $83 $ff 214 | $ff $e7 $81 $e7 $e7 $e7 $f1 $ff $ff $ff $99 $99 $99 $99 $c1 $ff 215 | $ff $ff $99 $99 $99 $c3 $e7 $ff $ff $ff $9c $94 $80 $c1 $c9 $ff 216 | $ff $ff $99 $c3 $e7 $c3 $99 $ff $ff $ff $99 $99 $99 $c1 $f3 $87 217 | $ff $ff $81 $f3 $e7 $cf $81 $ff $c3 $cf $cf $cf $cf $cf $c3 $ff 218 | $f3 $ed $cf $83 $cf $9d $03 $ff $c3 $f3 $f3 $f3 $f3 $f3 $c3 $ff 219 | $ff $e7 $c3 $81 $e7 $e7 $e7 $e7 $ff $ef $cf $80 $80 $cf $ef $ff 220 | $ff $ff $ff $ff $ff $ff $ff $ff $e7 $e7 $e7 $e7 $ff $ff $e7 $ff 221 | $99 $99 $99 $ff $ff $ff $ff $ff $99 $99 $00 $99 $00 $99 $99 $ff 222 | $e7 $c1 $9f $c3 $f9 $83 $e7 $ff $9d $99 $f3 $e7 $cf $99 $b9 $ff 223 | $c3 $99 $c3 $c7 $98 $99 $c0 $ff $f9 $f3 $e7 $ff $ff $ff $ff $ff 224 | $f3 $e7 $cf $cf $cf $e7 $f3 $ff $cf $e7 $f3 $f3 $f3 $e7 $cf $ff 225 | $ff $99 $c3 $00 $c3 $99 $ff $ff $ff $e7 $e7 $81 $e7 $e7 $ff $ff 226 | $ff $ff $ff $ff $ff $e7 $e7 $cf $ff $ff $ff $81 $ff $ff $ff $ff 227 | $ff $ff $ff $ff $ff $e7 $e7 $ff $ff $fc $f9 $f3 $e7 $cf $9f $ff 228 | $c3 $99 $91 $89 $99 $99 $c3 $ff $e7 $e7 $c7 $e7 $e7 $e7 $81 $ff 229 | $c3 $99 $f9 $f3 $cf $9f $81 $ff $c3 $99 $f9 $e3 $f9 $99 $c3 $ff 230 | $f9 $f1 $e1 $99 $80 $f9 $f9 $ff $81 $9f $83 $f9 $f9 $99 $c3 $ff 231 | $c3 $99 $9f $83 $99 $99 $c3 $ff $81 $99 $f3 $e7 $e7 $e7 $e7 $ff 232 | $c3 $99 $99 $c3 $99 $99 $c3 $ff $c3 $99 $99 $c1 $f9 $99 $c3 $ff 233 | $ff $ff $e7 $ff $ff $e7 $ff $ff $ff $ff $e7 $ff $ff $e7 $e7 $cf 234 | $f1 $e7 $cf $9f $cf $e7 $f1 $ff $ff $ff $81 $ff $81 $ff $ff $ff 235 | $8f $e7 $f3 $f9 $f3 $e7 $8f $ff $c3 $99 $f9 $f3 $e7 $ff $e7 $ff 236 | $ff $ff $ff $00 $00 $ff $ff $ff $e7 $c3 $99 $81 $99 $99 $99 $ff 237 | $83 $99 $99 $83 $99 $99 $83 $ff $c3 $99 $9f $9f $9f $99 $c3 $ff 238 | $87 $93 $99 $99 $99 $93 $87 $ff $81 $9f $9f $87 $9f $9f $81 $ff 239 | $81 $9f $9f $87 $9f $9f $9f $ff $c3 $99 $9f $91 $99 $99 $c3 $ff 240 | $99 $99 $99 $81 $99 $99 $99 $ff $c3 $e7 $e7 $e7 $e7 $e7 $c3 $ff 241 | $e1 $f3 $f3 $f3 $f3 $93 $c7 $ff $99 $93 $87 $8f $87 $93 $99 $ff 242 | $9f $9f $9f $9f $9f $9f $81 $ff $9c $88 $80 $94 $9c $9c $9c $ff 243 | $99 $89 $81 $81 $91 $99 $99 $ff $c3 $99 $99 $99 $99 $99 $c3 $ff 244 | $83 $99 $99 $83 $9f $9f $9f $ff $c3 $99 $99 $99 $99 $c3 $f1 $ff 245 | $83 $99 $99 $83 $87 $93 $99 $ff $c3 $99 $9f $c3 $f9 $99 $c3 $ff 246 | $81 $e7 $e7 $e7 $e7 $e7 $e7 $ff $99 $99 $99 $99 $99 $99 $c3 $ff 247 | $99 $99 $99 $99 $99 $c3 $e7 $ff $9c $9c $9c $94 $80 $88 $9c $ff 248 | $99 $99 $c3 $e7 $c3 $99 $99 $ff $99 $99 $99 $c3 $e7 $e7 $e7 $ff 249 | $81 $f9 $f3 $e7 $cf $9f $81 $ff $e7 $e7 $e7 $00 $00 $e7 $e7 $e7 250 | $3f $3f $cf $cf $3f $3f $cf $cf $e7 $e7 $e7 $e7 $e7 $e7 $e7 $e7 251 | $cc $cc $33 $33 $cc $cc $33 $33 $cc $66 $33 $99 $cc $66 $33 $99 252 | $ff $ff $ff $ff $ff $ff $ff $ff $0f $0f $0f $0f $0f $0f $0f $0f 253 | $ff $ff $ff $ff $00 $00 $00 $00 $00 $ff $ff $ff $ff $ff $ff $ff 254 | $ff $ff $ff $ff $ff $ff $ff $00 $3f $3f $3f $3f $3f $3f $3f $3f 255 | $33 $33 $cc $cc $33 $33 $cc $cc $fc $fc $fc $fc $fc $fc $fc $fc 256 | $ff $ff $ff $ff $33 $33 $cc $cc $33 $66 $cc $99 $33 $66 $cc $99 257 | $fc $fc $fc $fc $fc $fc $fc $fc $e7 $e7 $e7 $e0 $e0 $e7 $e7 $e7 258 | $ff $ff $ff $ff $f0 $f0 $f0 $f0 $e7 $e7 $e7 $e0 $e0 $ff $ff $ff 259 | $ff $ff $ff $07 $07 $e7 $e7 $e7 $ff $ff $ff $ff $ff $ff $00 $00 260 | $ff $ff $ff $e0 $e0 $e7 $e7 $e7 $e7 $e7 $e7 $00 $00 $ff $ff $ff 261 | $ff $ff $ff $00 $00 $e7 $e7 $e7 $e7 $e7 $e7 $07 $07 $e7 $e7 $e7 262 | $3f $3f $3f $3f $3f $3f $3f $3f $1f $1f $1f $1f $1f $1f $1f $1f 263 | $f8 $f8 $f8 $f8 $f8 $f8 $f8 $f8 $00 $00 $ff $ff $ff $ff $ff $ff 264 | $00 $00 $00 $ff $ff $ff $ff $ff $ff $ff $ff $ff $ff $00 $00 $00 265 | $fe $fc $f9 $93 $87 $8f $9f $ff $ff $ff $ff $ff $0f $0f $0f $0f 266 | $f0 $f0 $f0 $f0 $ff $ff $ff $ff $e7 $e7 $e7 $07 $07 $ff $ff $ff 267 | $0f $0f $0f $0f $ff $ff $ff $ff $0f $0f $0f $0f $f0 $f0 $f0 $f0 268 | ;$00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 269 | -------------------------------------------------------------------------------- /dummy.ram: -------------------------------------------------------------------------------- 1 | ORG 2 | $0200 3 | ; 4 | ; test program #1 5 | ; address: $0200 6 | ; load Acc with value 12 7 | ; write Acc to address $c000 (49152) 8 | ; 9 | ; nop 10 | ; nop 11 | ; lda #$0c 12 | ; sta $c000 13 | ; brk 14 | ; 15 | $EA $EA $A9 $0c $8D $00 $c0 $00 $00 16 | ; 17 | ; test program #2 18 | ; address: $0400 19 | ; copy 0-terminated string from 20 | ; address $d000 to $0200 21 | ; "Hello World!" 22 | ; 23 | ; ORG=$0400 24 | ; hello: 25 | ; ldx #0 26 | ; loop: 27 | ; lda $d000,x 28 | ; beq $06 ;branch to end (+6) if A=0 29 | ; sta $0200,x 30 | ; inx 31 | ; bne $f5 ; branch to loop (-11) if X<>0 32 | ; end: 33 | ; brk 34 | ORG 35 | $0400 36 | $A2 $00 37 | $BD $00 $d0 38 | $F0 $06 39 | $9D $00 $02 40 | $E8 41 | $D0 $F5 42 | $00 $00 43 | ; data 44 | ; address: $d000 45 | ORG 46 | $D000 47 | ;DEC: 53248 48 | ; "Hello World!" 49 | 72 101 108 108 111 32 87 111 114 108 100 33 0 50 | ; 51 | ; test program #3 - copy Hello World! string to $0300 52 | ; using different assembly instructions 53 | ; address: $0500 54 | ; 55 | ; ORG=$0500 ;dec: 1280 56 | ; hello: 57 | ; lda #0 58 | ; sta $05 59 | ; ldx $05 60 | ; loop: 61 | ; lda $d000,x 62 | ; sta $0300,x 63 | ; beq end ;(+6) 64 | ; inx 65 | ; beq end ;(+3) 66 | ; jmp loop 67 | ; end: 68 | ; brk 69 | ORG 70 | $0500 71 | ;DEC: 1280 72 | $A9 $00 73 | $85 $05 74 | $A6 $05 75 | $BD $00 $d0 76 | $9D $00 $03 77 | $F0 $06 78 | $E8 79 | $F0 $03 80 | $4C $06 $05 81 | $00 $00 82 | ; 83 | ; test program #4 84 | ; left-shift memory location $05 at zero page, 85 | ; then location $06 using zero page indexed addressing, 86 | ; then memory location $c001 (outside zero page) using absolute addressing 87 | ; then location $c002 using indexed absolute addressing 88 | ; and finally left-shift Acc. 89 | ; stop after each step for debugging 90 | ; exit loop when Acc=0 91 | ; 92 | ; start: 93 | ; lda #$ff 94 | ; ldx #$01 95 | ; sta $05 96 | ; sta $05,x 97 | ; sta $c000,x 98 | ; inx 99 | ; sta $c000,x 100 | ; ldx #$01 101 | ; loop2: 102 | ; brk 103 | ; asl $05 104 | ; asl $05,x 105 | ; asl $c001 106 | ; asl $c001,x 107 | ; asl 108 | ; bne loop2 ;(-15 or $f1) 109 | ; brk 110 | ORG 111 | $0600 112 | $A9 $FF 113 | $A2 $01 114 | $85 $05 115 | $95 $05 116 | $9D $00 $C0 117 | $E8 118 | $9D $00 $C0 119 | $A2 $01 120 | $00 $00 121 | $06 $05 122 | $16 $05 123 | $0E $01 $C0 124 | $1E $01 $C0 125 | $0A 126 | $D0 $F1 127 | $00 $00 128 | ; 129 | ; test program #5 130 | ; Test ORA opcode with various arguments and addressing modes. 131 | ; At each break, the contents of Acc should equal $AA. 132 | ; 133 | ; start: 134 | ; lda #$aa ;%10101010 135 | ; sta $05 136 | ; sta $aa 137 | ; lda #$00 138 | ; tax 139 | ; ora ($05,x) 140 | ; brk 141 | ; lda #$00 142 | ; ora $05 143 | ; brk 144 | ; lda #$00 145 | ; ora #$aa 146 | ; brk 147 | ; lda #$00 148 | ; ora $0005 149 | ; brk 150 | ; lda #$05 151 | ; sta $06 152 | ; lda #$00 153 | ; sta $07 154 | ; tay 155 | ; ora ($06),y 156 | ; brk 157 | ; lda #$00 158 | ; tax 159 | ; ora $05,x 160 | ; brk 161 | ; lda #$00 162 | ; tay 163 | ; ora $0005,y 164 | ; brk 165 | ; lda #$00 166 | ; tax 167 | ; ora $0005,x 168 | ; brk 169 | ORG 170 | $0700 171 | $A9 $AA 172 | $85 $05 173 | $85 $AA 174 | $A9 $00 175 | $AA 176 | $01 $05 177 | $00 $00 178 | $A9 $00 179 | $05 $05 180 | $00 $00 181 | $A9 $00 182 | $09 $AA 183 | $00 $00 184 | $A9 $00 185 | $0D $05 $00 186 | $00 $00 187 | $A9 $05 188 | $85 $06 189 | $A9 $00 190 | $85 $07 191 | $A8 192 | $11 $06 193 | $00 $00 194 | $A9 $00 195 | $AA 196 | $15 $05 197 | $00 $00 198 | $A9 $00 199 | $A8 200 | $19 $05 $00 201 | $00 $00 202 | $A9 $00 203 | $AA 204 | $1D $05 $00 205 | $00 $00 206 | ; 207 | ; test program #6 208 | ; Test JSR opcode. 209 | ; After each break examine memory at $c000 and $c001. 210 | ; After 1-st break, $c000 should equal $dd. 211 | ; Return address-1 ($0802) should be on stack. 212 | ; After 2-nd break, PC counter should be at $0805. 213 | ; After 3-rd break, $c000 should equal $ee. 214 | ; Return address-1 ($0807) should be on stack. 215 | ; After 4-th break, PC counter should be at $080a. 216 | ; 217 | ; start: 218 | ; jsr sub1 219 | ; brk 220 | ; jsr sub2 221 | ; brk 222 | ; brk 223 | ; brk 224 | ; sub1: 225 | ; lda #$dd 226 | ; sta $c000 227 | ; brk 228 | ; rts 229 | ; sub2: 230 | ; lda #$ee 231 | ; sta $c000 232 | ; brk 233 | ; rts 234 | ; 235 | ORG 236 | $0800 237 | $20 $0B $08 238 | $00 $00 239 | $20 $13 $08 240 | $00 241 | $00 242 | $00 243 | $A9 $DD 244 | $8D $00 $C0 245 | $00 $00 246 | $60 247 | $A9 $EE 248 | $8D $00 $C0 249 | $00 $00 250 | $60 251 | ; 252 | ; test program #7 253 | ; Test ADC opcode. 254 | ; Expected results: 255 | ; First break: Acc=$01, Carry=1 256 | ; 2-nd break: Acc=$02, Carry=1 257 | ; 3-rd break: Acc=$22, Carry=0 258 | ; 4-th break: Acc=$23, Carry=0 259 | ; 260 | ; start: 261 | ; clc 262 | ; lda #$ff 263 | ; adc #$02 264 | ; brk 265 | ; sec 266 | ; lda #$ff 267 | ; adc #$02 268 | ; brk 269 | ; clc 270 | ; lda #$20 271 | ; adc #$02 272 | ; brk 273 | ; sec 274 | ; lda #$20 275 | ; adc #$02 276 | ; brk 277 | ; 278 | ORG 279 | $0900 280 | $18 281 | $A9 $FF 282 | $69 $02 283 | $00 $00 284 | $38 285 | $A9 $FF 286 | $69 $02 287 | $00 $00 288 | $18 289 | $A9 $20 290 | $69 $02 291 | $00 $00 292 | $38 293 | $A9 $20 294 | $69 $02 295 | $00 $00 296 | ; 297 | ; test program #8 298 | ; Test ROR opcode. 299 | ; 300 | ; start: 301 | ; sec 302 | ; lda #$00 303 | ; loop: 304 | ; ror 305 | ; brk 306 | ; bcc loop ;(-5 -> $FB) 307 | ; brk 308 | ; 309 | ORG 310 | $0920 311 | $38 312 | $A9 $00 313 | $6A 314 | $00 $00 315 | $90 $FB 316 | $00 $00 317 | ; -------------------------------------------------------------------------------- /dummy.rom: -------------------------------------------------------------------------------- 1 | ORG 2 | $0200 3 | ; 4 | ; test program #1 5 | ; address: $0200 6 | ; load Acc with value 12 7 | ; write Acc to address $c000 (49152) 8 | ; 9 | ; nop 10 | ; nop 11 | ; lda #$0c 12 | ; sta $c000 13 | ; brk 14 | ; 15 | $EA $EA $A9 $0c $8D $00 $c0 $00 $00 16 | ; 17 | ; test program #2 18 | ; address: $0400 19 | ; copy 0-terminated string from 20 | ; address $d000 to $0200 21 | ; "Hello World!" 22 | ; 23 | ; ORG=$0400 24 | ; hello: 25 | ; ldx #0 26 | ; loop: 27 | ; lda $d000,x 28 | ; beq $06 ;branch to end (+6) if A=0 29 | ; sta $0200,x 30 | ; inx 31 | ; bne $f5 ; branch to loop (-11) if X<>0 32 | ; end: 33 | ; brk 34 | ORG 35 | $0400 36 | $A2 $00 37 | $BD $00 $d0 38 | $F0 $06 39 | $9D $00 $02 40 | $E8 41 | $D0 $F5 42 | $00 $00 43 | ; data 44 | ; address: $d000 45 | ORG 46 | $D000 47 | ;DEC: 53248 48 | ; "Hello World!" 49 | 72 101 108 108 111 32 87 111 114 108 100 33 0 50 | ; 51 | ; test program #3 - copy Hello World! string to $0300 52 | ; using different assembly instructions 53 | ; address: $0500 54 | ; 55 | ; ORG=$0500 ;dec: 1280 56 | ; hello: 57 | ; lda #0 58 | ; sta $05 59 | ; ldx $05 60 | ; loop: 61 | ; lda $d000,x 62 | ; sta $0300,x 63 | ; beq end ;(+6) 64 | ; inx 65 | ; beq end ;(+3) 66 | ; jmp loop 67 | ; end: 68 | ; brk 69 | ORG 70 | $0500 71 | ;DEC: 1280 72 | $A9 $00 73 | $85 $05 74 | $A6 $05 75 | $BD $00 $d0 76 | $9D $00 $03 77 | $F0 $06 78 | $E8 79 | $F0 $03 80 | $4C $06 $05 81 | $00 $00 82 | ; 83 | ; test program #4 84 | ; left-shift memory location $05 at zero page, 85 | ; then location $06 using zero page indexed addressing, 86 | ; then memory location $c001 (outside zero page) using absolute addressing 87 | ; then location $c002 using indexed absolute addressing 88 | ; and finally left-shift Acc. 89 | ; stop after each step for debugging 90 | ; exit loop when Acc=0 91 | ; 92 | ; start: 93 | ; lda #$ff 94 | ; ldx #$01 95 | ; sta $05 96 | ; sta $05,x 97 | ; sta $c000,x 98 | ; inx 99 | ; sta $c000,x 100 | ; ldx #$01 101 | ; loop2: 102 | ; brk 103 | ; asl $05 104 | ; asl $05,x 105 | ; asl $c001 106 | ; asl $c001,x 107 | ; asl 108 | ; bne loop2 ;(-15 or $f1) 109 | ; brk 110 | ORG 111 | $0600 112 | $A9 $FF 113 | $A2 $01 114 | $85 $05 115 | $95 $05 116 | $9D $00 $C0 117 | $E8 118 | $9D $00 $C0 119 | $A2 $01 120 | $00 $00 121 | $06 $05 122 | $16 $05 123 | $0E $01 $C0 124 | $1E $01 $C0 125 | $0A 126 | $D0 $F1 127 | $00 $00 128 | ; 129 | ; test program #5 130 | ; Test ORA opcode with various arguments and addressing modes. 131 | ; At each break, the contents of Acc should equal $AA. 132 | ; 133 | ; start: 134 | ; lda #$aa ;%10101010 135 | ; sta $05 136 | ; sta $aa 137 | ; lda #$00 138 | ; tax 139 | ; ora ($05,x) 140 | ; brk 141 | ; lda #$00 142 | ; ora $05 143 | ; brk 144 | ; lda #$00 145 | ; ora #$aa 146 | ; brk 147 | ; lda #$00 148 | ; ora $0005 149 | ; brk 150 | ; lda #$05 151 | ; sta $06 152 | ; lda #$00 153 | ; sta $07 154 | ; tay 155 | ; ora ($06),y 156 | ; brk 157 | ; lda #$00 158 | ; tax 159 | ; ora $05,x 160 | ; brk 161 | ; lda #$00 162 | ; tay 163 | ; ora $0005,y 164 | ; brk 165 | ; lda #$00 166 | ; tax 167 | ; ora $0005,x 168 | ; brk 169 | ORG 170 | $0700 171 | $A9 $AA 172 | $85 $05 173 | $85 $AA 174 | $A9 $00 175 | $AA 176 | $01 $05 177 | $00 $00 178 | $A9 $00 179 | $05 $05 180 | $00 $00 181 | $A9 $00 182 | $09 $AA 183 | $00 $00 184 | $A9 $00 185 | $0D $05 $00 186 | $00 $00 187 | $A9 $05 188 | $85 $06 189 | $A9 $00 190 | $85 $07 191 | $A8 192 | $11 $06 193 | $00 $00 194 | $A9 $00 195 | $AA 196 | $15 $05 197 | $00 $00 198 | $A9 $00 199 | $A8 200 | $19 $05 $00 201 | $00 $00 202 | $A9 $00 203 | $AA 204 | $1D $05 $00 205 | $00 $00 206 | ; 207 | ; test program #6 208 | ; Test JSR opcode. 209 | ; After each break examine memory at $c000 and $c001. 210 | ; After 1-st break, $c000 should equal $dd. 211 | ; Return address-1 ($0802) should be on stack. 212 | ; After 2-nd break, PC counter should be at $0805. 213 | ; After 3-rd break, $c000 should equal $ee. 214 | ; Return address-1 ($0807) should be on stack. 215 | ; After 4-th break, PC counter should be at $080a. 216 | ; 217 | ; start: 218 | ; jsr sub1 219 | ; brk 220 | ; jsr sub2 221 | ; brk 222 | ; brk 223 | ; brk 224 | ; sub1: 225 | ; lda #$dd 226 | ; sta $c000 227 | ; brk 228 | ; rts 229 | ; sub2: 230 | ; lda #$ee 231 | ; sta $c000 232 | ; brk 233 | ; rts 234 | ; 235 | ORG 236 | $0800 237 | $20 $0B $08 238 | $00 $00 239 | $20 $13 $08 240 | $00 241 | $00 242 | $00 243 | $A9 $DD 244 | $8D $00 $C0 245 | $00 $00 246 | $60 247 | $A9 $EE 248 | $8D $00 $C0 249 | $00 $00 250 | $60 251 | ; 252 | ; test program #7 253 | ; Test ADC opcode. 254 | ; Expected results: 255 | ; First break: Acc=$01, Carry=1 256 | ; 2-nd break: Acc=$02, Carry=1 257 | ; 3-rd break: Acc=$22, Carry=0 258 | ; 4-th break: Acc=$23, Carry=0 259 | ; 260 | ; start: 261 | ; clc 262 | ; lda #$ff 263 | ; adc #$02 264 | ; brk 265 | ; sec 266 | ; lda #$ff 267 | ; adc #$02 268 | ; brk 269 | ; clc 270 | ; lda #$20 271 | ; adc #$02 272 | ; brk 273 | ; sec 274 | ; lda #$20 275 | ; adc #$02 276 | ; brk 277 | ; 278 | ORG 279 | $0900 280 | $18 281 | $A9 $FF 282 | $69 $02 283 | $00 $00 284 | $38 285 | $A9 $FF 286 | $69 $02 287 | $00 $00 288 | $18 289 | $A9 $20 290 | $69 $02 291 | $00 $00 292 | $38 293 | $A9 $20 294 | $69 $02 295 | $00 $00 296 | ; 297 | ; test program #8 298 | ; Test ROR opcode. 299 | ; 300 | ; start: 301 | ; sec 302 | ; lda #$00 303 | ; loop: 304 | ; ror 305 | ; brk 306 | ; bcc loop ;(-5 -> $FB) 307 | ; brk 308 | ; 309 | ORG 310 | $0920 311 | $38 312 | $A9 $00 313 | $6A 314 | $00 $00 315 | $90 $FB 316 | $00 $00 317 | ; -------------------------------------------------------------------------------- /ehbas_grdemo.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makarcz/vm6502/4166e540db12a8238f1896632f05afb2f4d45390/ehbas_grdemo.snap -------------------------------------------------------------------------------- /ehbas_grdemo_loop.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makarcz/vm6502/4166e540db12a8238f1896632f05afb2f4d45390/ehbas_grdemo_loop.snap -------------------------------------------------------------------------------- /grdevdemo.bas: -------------------------------------------------------------------------------- 1 | 1 REM GRAPHICS DISPLAY DEVICE DEMO 2 | 2 REM BASE ADDRESS $FFE2 3 | 3 REM DRAW HORIZONTAL AND VERTICAL LINES 4 | 4 REM DRAW SINUSOID 5 | 10 GB=65506:REM SET BASE ADDRESS 6 | 12 REM INITIALIZE, SET COLORS 7 | 15 POKE GB+1,0:POKE GB+11,0 8 | 16 POKE GB+3,0:POKE GB+4,255:POKE GB+5,0 9 | 17 POKE GB+6,0:POKE GB+7,0:POKE GB+8,0 10 | 18 POKE GB+9,3:POKE GB+9,4:POKE GB+9,0 11 | 19 GOSUB 1120:REM DRAW SINUSOID 12 | 20 Y=100:REM X-AXIS 13 | 30 GOSUB 1000 14 | 50 X=100:REM Y-AXIS 15 | 60 GOSUB 1060 16 | 70 REM SOME EXTRA DOTTED LINES 17 | 80 Y=50:GOSUB 1200 18 | 90 Y=150:GOSUB 1200 19 | 100 X=50:GOSUB 1260 20 | 110 X=150:GOSUB 1260 21 | 120 PRINT "... HIT [SPACE] TO END ..." 22 | 125 GET K$:IF K$=" " THEN END 23 | 130 FOR I=1 TO 2000:NEXT I:REM SHORT PAUSE 24 | 140 GOTO 15 25 | 998 END 26 | 999 REM ------- SUBROUTINES SECTION ------- 27 | 1000 REM DRAW HORIZONTAL LINE AT Y 28 | 1005 POKE GB+2,Y 29 | 1006 POKE GB+12,Y 30 | 1020 POKE GB,0 31 | 1025 POKE GB+10,199:POKE GB+9,5 32 | 1050 RETURN 33 | 1060 REM DRAW VERTICAL LINE AT X 34 | 1070 POKE GB,X 35 | 1075 POKE GB+10,X 36 | 1090 POKE GB+2,0 37 | 1095 POKE GB+12,199:POKE GB+9,5 38 | 1110 RETURN 39 | 1120 REM SINUSOID 40 | 1130 FOR X=0 TO 199-4 STEP 5 41 | 1140 XX=X*(6.28/200) 42 | 1145 XE=(X+5)*(6.28/200) 43 | 1150 YY=SIN(XX):YE=SIN(XE) 44 | 1160 Y=199-INT((YY+1)*100) 45 | 1165 Y2=199-INT((YE+1)*100) 46 | 1170 POKE GB,X:POKE GB+2,Y 47 | 1175 POKE GB+10,X+5:POKE GB+12,Y2:POKE GB+9,5 48 | 1180 NEXT X 49 | 1190 RETURN 50 | 1200 REM DRAW DOTTED HORIZONTAL LINE AT Y 51 | 1205 POKE GB+2,Y 52 | 1210 FOR X=0 TO 199 STEP 4 53 | 1220 POKE GB,X 54 | 1230 POKE GB+9,1 55 | 1240 NEXT X 56 | 1250 RETURN 57 | 1260 REM DRAW DOTTED VERTICAL LINE AT X 58 | 1270 POKE GB,X 59 | 1280 FOR Y=0 TO 199 STEP 4 60 | 1290 POKE GB+2,Y 61 | 1300 POKE GB+9,1 62 | 1310 NEXT Y 63 | 1320 RETURN 64 | -------------------------------------------------------------------------------- /hello_world.bas: -------------------------------------------------------------------------------- 1 | 10 LET A=0 2 | 20 PRINT A;") HELLO WORLD FROM MKHBC!" 3 | 30 LET A=A+1 4 | 40 IF A>100 THEN END 5 | 50 GOTO 20 6 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # Project: VM65 2 | 3 | SDLBASE = $(SDLDIR) 4 | SDLINCS = -I"$(SDLBASE)/include" 5 | CPP = g++ -D__DEBUG__ -DLINUX 6 | CC = gcc -D__DEBUG__ 7 | OBJ = main.o VMachine.o MKCpu.o Memory.o Display.o GraphDisp.o MemMapDev.o MKGenException.o ConsoleIO.o MassStorage.o 8 | LINKOBJ = main.o VMachine.o MKCpu.o Memory.o Display.o GraphDisp.o MemMapDev.o MKGenException.o ConsoleIO.o MassStorage.o 9 | BIN = vm65 10 | SDLLIBS = -L/usr/local/lib -lSDL2main -lSDL2 11 | INCS = 12 | CXXINCS = 13 | ifeq ($(SDLBASE),) 14 | $(error ***** SDLDIR not set) 15 | endif 16 | ifneq "$(HOSTTYPE)" "" 17 | $(info ***** HOSTTYPE already set) 18 | else 19 | $(info ***** HOSTTYPE not set. Setting...) 20 | HOSTTYPE = $(shell arch) 21 | endif 22 | $(info ***** SDLDIR = $(SDLDIR)) 23 | $(info ***** HOSTTYPE = $(HOSTTYPE)) 24 | ifeq ($(HOSTTYPE),x86_64) 25 | $(info ***** 64-bit) 26 | LIBS = -static-libgcc -g3 -ltermcap -lncurses -lpthread 27 | CLIBS = -static-libgcc -g3 28 | CXXFLAGS = $(CXXINCS) -std=c++11 -pthread -Wall -pedantic -g3 -fpermissive 29 | else 30 | $(info ***** 32-bit) 31 | LIBS = -static-libgcc -m32 -g3 -ltermcap -lncurses -lpthread 32 | CLIBS = -static-libgcc -m32 -g3 33 | CXXFLAGS = $(CXXINCS) -m32 -std=c++11 -pthread -Wall -pedantic -g3 -fpermissive 34 | endif 35 | #CFLAGS = $(INCS) -m32 -std=c++0x -Wall -pedantic -g3 36 | CFLAGS = $(INCS) -Wall -pedantic -g3 37 | RM = rm -f 38 | 39 | .PHONY: all all-before all-after clean clean-custom 40 | 41 | all: all-before $(BIN) bin2hex all-after 42 | 43 | clean: clean-custom 44 | ${RM} $(OBJ) $(BIN) bin2hex 45 | 46 | $(BIN): $(OBJ) 47 | $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) $(SDLLIBS) 48 | 49 | main.o: main.cpp 50 | $(CPP) -c main.cpp -o main.o $(CXXFLAGS) $(SDLINCS) 51 | 52 | VMachine.o: VMachine.cpp 53 | $(CPP) -c VMachine.cpp -o VMachine.o $(CXXFLAGS) $(SDLINCS) 54 | MKBasic.o: MKBasic.cpp 55 | $(CPP) -c MKBasic.cpp -o MKBasic.o $(CXXFLAGS) 56 | 57 | MKCpu.o: MKCpu.cpp 58 | $(CPP) -c MKCpu.cpp -o MKCpu.o $(CXXFLAGS) $(SDLINCS) 59 | 60 | Memory.o: Memory.cpp 61 | $(CPP) -c Memory.cpp -o Memory.o $(CXXFLAGS) $(SDLINCS) 62 | 63 | Display.o: Display.cpp 64 | $(CPP) -c Display.cpp -o Display.o $(CXXFLAGS) 65 | 66 | bin2hex: bin2hex.c 67 | $(CC) bin2hex.c -o bin2hex $(CFLAGS) $(CLIBS) 68 | 69 | MKGenException.o: MKGenException.cpp 70 | $(CPP) -c MKGenException.cpp -o MKGenException.o $(CXXFLAGS) 71 | 72 | GraphDisp.o: GraphDisp.cpp GraphDisp.h 73 | $(CPP) -c GraphDisp.cpp -o GraphDisp.o $(CXXFLAGS) $(SDLINCS) 74 | 75 | MemMapDev.o: MemMapDev.cpp MemMapDev.h 76 | $(CPP) -c MemMapDev.cpp -o MemMapDev.o $(CXXFLAGS) $(SDLINCS) 77 | 78 | ConsoleIO.o: ConsoleIO.cpp ConsoleIO.h 79 | $(CPP) -c ConsoleIO.cpp -o ConsoleIO.o $(CXXFLAGS) 80 | 81 | MassStorage.o: MassStorage.cpp MassStorage.h 82 | $(CPP) -c MassStorage.cpp -o MassStorage.o $(CXXFLAGS) 83 | -------------------------------------------------------------------------------- /makefile.mingw: -------------------------------------------------------------------------------- 1 | # Project: VM65 2 | # Makefile created by Dev-C++ 5.11 3 | # and modified for standalone MINGW compiler installation. 4 | # NOTE: 5 | # Set SDLDIR and MINGWDIR in your compilation environment, 6 | # and then 7 | # set PATH=%MINGWDIR%\mingw64\bin;%SDLDIR%\lib\x64;%PATH% 8 | 9 | #SDLDIR = "D:\src\SDL" 10 | #MINGWDIR = "C:\mingw-w64\x86_64-8.1.0" 11 | SDLBASE = $(SDLDIR) 12 | CPP = g++.exe -D__DEBUG__ 13 | CC = gcc.exe -D__DEBUG__ 14 | WINDRES = windres.exe 15 | OBJ = main.o VMachine.o MKCpu.o Memory.o Display.o GraphDisp.o MemMapDev.o MKGenException.o ConsoleIO.o MassStorage.o 16 | OBJ2 = bin2hex.o 17 | LINKOBJ = main.o VMachine.o MKCpu.o Memory.o Display.o GraphDisp.o MemMapDev.o MKGenException.o ConsoleIO.o MassStorage.o 18 | LINKOBJ2 = bin2hex.o 19 | LIBS = -L"$(MINGWDIR)\mingw64\x86_64-w64-mingw32/lib" -L"$(MINGWDIR)\mingw64\x86_64-w64-mingw32/lib" -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic -lmingw32 20 | SDLLIBS = -L"$(SDLBASE)\x86_64-w64-mingw32/lib" -lSDL2main -lSDL2 21 | INCS = -I"$(MINGWDIR)\mingw64/include" -I"$(MINGWDIR)\mingw64\x86_64-w64-mingw32/include" -I"$(MINGWDIR)\mingw64\lib\gcc\x86_64-w64-mingw32\$(GCCVER)/include" 22 | CXXINCS = -I"$(MINGWDIR)\mingw64/include" -I"$(MINGWDIR)\mingw64\x86_64-w64-mingw32/include" -I"$(MINGWDIR)\mingw64\lib\gcc\x86_64-w64-mingw32\$(GCCVER)/include" 23 | BIN = vm65.exe 24 | BIN2 = bin2hex.exe 25 | CXXFLAGS = $(CXXINCS) -std=c++11 -Wall -Wextra -pedantic -g3 26 | SDLINCS = -I"$(SDLBASE)/include" 27 | CFLAGS = $(INCS) -std=c++11 -Wall -Wextra -pedantic -g3 28 | CXXFLAGS2 = $(CXXINCS) 29 | CFLAGS2 = $(INCS) 30 | RM = del /f 31 | 32 | .PHONY: all all-before all-after clean clean-custom 33 | 34 | all: all-before $(BIN) $(BIN2) all-after 35 | 36 | clean: clean-custom 37 | ${RM} $(OBJ) $(OBJ2) $(BIN) $(BIN2) 38 | 39 | $(BIN): $(OBJ) 40 | $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) $(SDLLIBS) 41 | 42 | main.o: main.cpp 43 | $(CPP) -c main.cpp -o main.o $(CXXFLAGS) $(SDLINCS) 44 | 45 | VMachine.o: VMachine.cpp VMachine.h 46 | $(CPP) -c VMachine.cpp -o VMachine.o $(CXXFLAGS) $(SDLINCS) 47 | 48 | MKCpu.o: MKCpu.cpp MKCpu.h 49 | $(CPP) -c MKCpu.cpp -o MKCpu.o $(CXXFLAGS) $(SDLINCS) 50 | 51 | Memory.o: Memory.cpp Memory.h 52 | $(CPP) -c Memory.cpp -o Memory.o $(CXXFLAGS) $(SDLINCS) 53 | 54 | Display.o: Display.cpp Display.h 55 | $(CPP) -c Display.cpp -o Display.o $(CXXFLAGS) 56 | 57 | GraphDisp.o: GraphDisp.cpp GraphDisp.h 58 | $(CPP) -c GraphDisp.cpp -o GraphDisp.o $(CXXFLAGS) $(SDLINCS) 59 | 60 | MemMapDev.o: MemMapDev.cpp MemMapDev.h 61 | $(CPP) -c MemMapDev.cpp -o MemMapDev.o $(CXXFLAGS) $(SDLINCS) 62 | 63 | MKGenException.o: MKGenException.cpp MKGenException.h 64 | $(CPP) -c MKGenException.cpp -o MKGenException.o $(CXXFLAGS) 65 | 66 | ConsoleIO.o: ConsoleIO.cpp ConsoleIO.h 67 | $(CPP) -c ConsoleIO.cpp -o ConsoleIO.o $(CXXFLAGS) 68 | 69 | MassStorage.o: MassStorage.cpp MassStorage.h 70 | $(CPP) -c MassStorage.cpp -o MassStorage.o $(CXXFLAGS) 71 | 72 | $(BIN2): $(OBJ2) 73 | $(CC) $(LINKOBJ2) -o $(BIN2) $(LIBS) 74 | 75 | bin2hex.o: bin2hex.c 76 | $(CC) -c bin2hex.c -o bin2hex.o $(CFLAGS2) 77 | -------------------------------------------------------------------------------- /makeming.bat: -------------------------------------------------------------------------------- 1 | rem to make project on win64 with mingw 2 | rem run in mingw console 3 | 4 | mingw32-make -f makefile.mingw clean all -------------------------------------------------------------------------------- /microchess.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makarcz/vm6502/4166e540db12a8238f1896632f05afb2f4d45390/microchess.bin -------------------------------------------------------------------------------- /microchess.cfg: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | RAM0: start = $0000, size = $0400, fill = yes; 3 | RAM1: start = $0400, size = $0620, fill = yes; 4 | RAM2: start = $0A20, size = $F3E0, fill = yes; 5 | ROM1: start = $FE00, size = $1ED, fill = yes; 6 | ROM2: start = $FFED, size = $12; 7 | } 8 | 9 | SEGMENTS { 10 | BEGN: load = RAM0, type = rw; 11 | CODE: load = RAM1, type = rw; 12 | DATA: load = RAM2, type = rw; 13 | KERN: load = ROM1, type = ro; 14 | VECT: load = ROM2, type = ro; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /microchess.dat: -------------------------------------------------------------------------------- 1 | ; Created with BIN2HEX (C) Marek Karcz 2016. All rights reserved. 2 | ; Mon Mar 14 00:17:15 2016 3 | ADDR 4 | $0400 5 | ORG 6 | $0000 7 | ORG 8 | $0400 9 | $a9 $00 $85 $b7 $4c $09 $04 $ff $ff $d8 $a2 $ff $9a $a2 $c8 $86 10 | $b2 $20 $92 $07 $20 $7d $08 $c9 $43 $d0 $17 $a9 $ff $8d $07 $04 11 | $a2 $1f $bd $20 $0a $95 $50 $ca $10 $f8 $a2 $1b $86 $2c $a9 $cc 12 | $d0 $23 $c9 $45 $d0 $13 $a9 $ff $8d $07 $04 $20 $db $05 $38 $a9 13 | $01 $e5 $b7 $85 $b7 $a9 $ee $d0 $0c $c9 $40 $d0 $10 $a9 $ff $8d 14 | $07 $04 $20 $cf $06 $85 $4b $85 $4a $85 $49 $d0 $ac $c9 $0d $d0 15 | $0d $48 $a9 $ff $8d $07 $04 $68 $20 $75 $06 $4c $17 $05 $c9 $41 16 | $f0 $0a $48 $a9 $00 $8d $07 $04 $68 $4c $10 $05 $60 $a6 $b5 $30 17 | $59 $a5 $b0 $f0 $08 $e0 $08 $d0 $04 $c5 $26 $f0 $2e $f6 $23 $c9 18 | $01 $d0 $02 $f6 $23 $50 $1e $a0 $0f $a5 $b1 $d9 $60 $00 $f0 $03 19 | $88 $10 $f8 $b9 $51 $0a $d5 $24 $90 $04 $94 $26 $95 $24 $18 $08 20 | $75 $25 $95 $25 $28 $e0 $04 $f0 $03 $30 $2e $60 $a5 $28 $85 $2d 21 | $a9 $00 $85 $b5 $20 $75 $06 $20 $db $05 $20 $29 $05 $20 $db $05 22 | $a9 $08 $85 $b5 $20 $5b $06 $4c $2c $07 $e0 $f9 $d0 $0b $a5 $60 23 | $c5 $b1 $d0 $04 $a9 $00 $85 $b4 $60 $50 $fd $a0 $07 $a5 $b1 $d9 24 | $60 $00 $f0 $05 $88 $f0 $f1 $10 $f6 $b9 $51 $0a $d5 $22 $90 $02 25 | $95 $22 $c6 $b5 $a9 $fb $c5 $b5 $f0 $03 $20 $4f $06 $e6 $b5 $60 26 | $c9 $08 $b0 $12 $20 $1c $07 $a2 $1f $b5 $50 $c5 $4a $f0 $03 $ca 27 | $10 $f7 $86 $4b $86 $b0 $4c $09 $04 $a2 $10 $a9 $00 $95 $2e $ca 28 | $10 $fb $a9 $10 $85 $b0 $c6 $b0 $10 $01 $60 $20 $48 $06 $a4 $b0 29 | $a2 $08 $86 $b6 $c0 $08 $10 $41 $c0 $06 $10 $2e $c0 $04 $10 $1f 30 | $c0 $01 $f0 $09 $10 $0e $20 $b7 $05 $d0 $fb $f0 $d9 $20 $c5 $05 31 | $d0 $fb $f0 $d2 $a2 $04 $86 $b6 $20 $c5 $05 $d0 $fb $f0 $c7 $20 32 | $c5 $05 $a5 $b6 $c9 $04 $d0 $f7 $f0 $bc $a2 $10 $86 $b6 $20 $b7 33 | $05 $a5 $b6 $c9 $08 $d0 $f7 $f0 $ad $a2 $06 $86 $b6 $20 $f3 $05 34 | $50 $05 $30 $03 $20 $7d $04 $20 $48 $06 $c6 $b6 $a5 $b6 $c9 $05 35 | $f0 $eb $20 $f3 $05 $70 $8f $30 $8d $20 $7d $04 $a5 $b1 $29 $f0 36 | $c9 $20 $f0 $ee $4c $36 $05 $20 $f3 $05 $30 $03 $20 $7d $04 $20 37 | $48 $06 $c6 $b6 $60 $20 $f3 $05 $90 $02 $50 $f9 $30 $07 $08 $20 38 | $7d $04 $28 $50 $f0 $20 $48 $06 $c6 $b6 $60 $a2 $0f $38 $b4 $60 39 | $a9 $77 $f5 $50 $95 $60 $94 $50 $38 $a9 $77 $f5 $50 $95 $50 $ca 40 | $10 $eb $60 $a5 $b1 $a6 $b6 $18 $7d $40 $0a $85 $b1 $29 $88 $d0 41 | $42 $a5 $b1 $a2 $20 $ca $30 $0e $d5 $50 $d0 $f9 $e0 $10 $30 $33 42 | $a9 $7f $69 $01 $70 $01 $b8 $a5 $b5 $30 $24 $c9 $08 $10 $20 $48 43 | $08 $a9 $f9 $85 $b5 $85 $b4 $20 $75 $06 $20 $db $05 $20 $32 $05 44 | $20 $58 $06 $28 $68 $85 $b5 $a5 $b4 $30 $04 $38 $a9 $ff $60 $18 45 | $a9 $00 $60 $a9 $ff $18 $b8 $60 $a6 $b0 $b5 $50 $85 $b1 $60 $20 46 | $75 $06 $20 $db $05 $20 $32 $05 $20 $db $05 $ba $86 $b3 $a6 $b2 47 | $9a $68 $85 $b6 $68 $85 $b0 $aa $68 $95 $50 $68 $aa $68 $85 $b1 48 | $95 $50 $4c $9a $06 $ba $86 $b3 $a6 $b2 $9a $a5 $b1 $48 $a8 $a2 49 | $1f $d5 $50 $f0 $03 $ca $10 $f9 $a9 $cc $95 $50 $8a $48 $a6 $b0 50 | $b5 $50 $94 $50 $48 $8a $48 $a5 $b6 $48 $ba $86 $b2 $a6 $b3 $9a 51 | $60 $a4 $24 $ec $51 $0a $d0 $04 $a9 $00 $f0 $0a $a6 $23 $d0 $06 52 | $a6 $3e $d0 $02 $a9 $ff $a2 $04 $86 $b5 $c5 $4a $90 $0c $f0 $0a 53 | $85 $4a $a5 $b0 $85 $4b $a5 $b1 $85 $49 $a9 $2e $4c $8f $08 $a6 54 | $2c $30 $1c $a5 $49 $dd $61 $0a $d0 $11 $ca $bd $61 $0a $85 $4b 55 | $ca $bd $61 $0a $85 $49 $ca $86 $2c $d0 $1c $a9 $ff $85 $2c $a2 56 | $0c $86 $b5 $86 $4a $a2 $14 $20 $2b $05 $a2 $04 $86 $b5 $20 $29 57 | $05 $a6 $4a $e0 $0f $90 $12 $a6 $4b $b5 $50 $85 $4a $86 $b0 $a5 58 | $49 $85 $b1 $20 $75 $06 $4c $09 $04 $a9 $ff $60 $a2 $04 $06 $49 59 | $26 $4a $ca $d0 $f9 $05 $49 $85 $49 $85 $b1 $60 $18 $a9 $80 $65 60 | $2b $65 $3c $65 $3d $65 $21 $65 $2f $38 $e5 $40 $e5 $41 $e5 $22 61 | $e5 $20 $e5 $2e $e5 $3f $e5 $23 $b0 $02 $a9 $00 $4a $18 $69 $40 62 | $65 $3c $65 $3d $38 $e5 $24 $4a $18 $69 $90 $65 $2d $65 $2d $65 63 | $2d $65 $2d $65 $21 $38 $e5 $24 $e5 $24 $e5 $25 $e5 $25 $e5 $20 64 | $a6 $b1 $e0 $33 $f0 $16 $e0 $34 $f0 $12 $e0 $22 $f0 $0e $e0 $25 65 | $f0 $0a $a6 $b0 $f0 $09 $b4 $50 $c0 $10 $10 $03 $18 $69 $02 $4c 66 | $a1 $06 $ad $07 $04 $d0 $01 $60 $20 $37 $08 $20 $5b $08 $20 $42 67 | $08 $a0 $00 $20 $09 $08 $a9 $7c $20 $8f $08 $a2 $1f $98 $d5 $50 68 | $f0 $40 $ca $10 $f8 $98 $29 $01 $85 $4c $98 $4a $4a $4a $4a $29 69 | $01 $18 $65 $4c $29 $01 $d0 $03 $a9 $2a $2c $a9 $20 $20 $8f $08 70 | $20 $8f $08 $c8 $98 $29 $08 $f0 $cd $a9 $7c $20 $8f $08 $20 $54 71 | $08 $20 $37 $08 $20 $09 $08 $18 $98 $69 $08 $a8 $c0 $80 $f0 $2b 72 | $d0 $b4 $a5 $b7 $f0 $05 $bd $0d $09 $d0 $03 $bd $fd $08 $20 $8f 73 | $08 $bd $2d $09 $20 $8f $08 $d0 $ca $8a $48 $a2 $19 $a9 $2d $20 74 | $8f $08 $ca $d0 $fa $68 $aa $20 $37 $08 $60 $20 $42 $08 $a5 $4b 75 | $20 $9b $08 $a9 $20 $20 $8f $08 $a5 $4a $20 $9b $08 $a9 $20 $20 76 | $8f $08 $a5 $49 $20 $9b $08 $a9 $0d $20 $8f $08 $a9 $0a $20 $8f 77 | $08 $60 $a2 $00 $a9 $20 $20 $8f $08 $8a $20 $9b $08 $e8 $e0 $08 78 | $d0 $f2 $f0 $e3 $98 $29 $70 $20 $9b $08 $60 $86 $f6 $85 $f7 $84 79 | $f8 $ad $08 $04 $f0 $0b $a9 $c1 $85 $e0 $a9 $08 $85 $e1 $20 $f3 80 | $ff $a9 $00 $8d $08 $04 $a6 $f6 $a5 $f7 $a4 $f8 $60 $a9 $3f $20 81 | $8f $08 $20 $8b $08 $20 $8f $08 $29 $4f $60 $20 $ed $ff $60 $86 82 | $f6 $85 $f7 $20 $f0 $ff $a6 $f6 $a5 $f7 $60 $48 $4a $4a $4a $4a 83 | $20 $a4 $08 $68 $84 $f8 $29 $0f $a8 $b9 $b1 $08 $a4 $f8 $4c $8f 84 | $08 $30 $31 $32 $33 $34 $35 $36 $37 $38 $39 $41 $42 $43 $44 $45 85 | $46 $4d $69 $63 $72 $6f $43 $68 $65 $73 $73 $20 $28 $63 $29 $20 86 | $31 $39 $39 $36 $2d $32 $30 $30 $32 $20 $50 $65 $74 $65 $72 $20 87 | $4a $65 $6e $6e $69 $6e $67 $73 $2c $20 $70 $65 $74 $65 $72 $6a 88 | $40 $62 $65 $6e $6c $6f $2e $63 $6f $6d $0d $0a $00 $57 $57 $57 89 | $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $42 $42 $42 90 | $42 $42 $42 $42 $42 $42 $42 $42 $42 $42 $42 $42 $42 $57 $57 $57 91 | $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $57 $4b $51 $43 92 | $43 $42 $42 $52 $52 $50 $50 $50 $50 $50 $50 $50 $50 $4b $51 $43 93 | $43 $42 $42 $52 $52 $50 $50 $50 $50 $50 $50 $50 $50 $00 $00 $00 94 | ORG 95 | $0a20 96 | $03 $04 $00 $07 $02 $05 $01 $06 $10 $17 $11 $16 $12 $15 $14 $13 97 | $73 $74 $70 $77 $72 $75 $71 $76 $60 $67 $61 $66 $62 $65 $64 $63 98 | $00 $f0 $ff $01 $10 $11 $0f $ef $f1 $df $e1 $ee $f2 $12 $0e $1f 99 | $21 $0b $0a $06 $06 $04 $04 $04 $04 $02 $02 $02 $02 $02 $02 $02 100 | $02 $99 $25 $0b $25 $01 $00 $33 $25 $07 $36 $34 $0d $34 $34 $0e 101 | $52 $25 $0d $45 $35 $04 $55 $22 $06 $43 $33 $0f $cc $00 $00 $00 102 | ORG 103 | $fe00 104 | $ad $00 $e0 $60 $8d $00 $e0 $60 $a0 $00 $a5 $e1 $48 $b1 $e0 $f0 105 | $0b $20 $04 $fe $c8 $d0 $f6 $e6 $e1 $4c $0d $fe $68 $85 $e1 $60 106 | ORG 107 | $ffe0 108 | $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $4c $00 $fe 109 | $4c $04 $fe $4c $08 $fe $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 110 | IOADDR 111 | $E000 112 | ENIO 113 | EXEC 114 | $0400 115 | -------------------------------------------------------------------------------- /mingw-w64.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | set GCCVER=8.1.0 3 | set MINGWDIR=C:\mingw-w64\x86_64-%GCCVER% 4 | set SDLDIR=D:\src\SDL 5 | set PATH=%MINGWDIR%\mingw64\bin;%SDLDIR%\lib\x64;%PATH% 6 | rem echo %PATH% 7 | rem cd "C:\mingw-w64\x86_64-8.1.0\mingw64\bin" 8 | D: 9 | cd "D:\src\githubwrk\vm6502" 10 | "C:\Windows\system32\cmd.exe" 11 | -------------------------------------------------------------------------------- /numbers.bas: -------------------------------------------------------------------------------- 1 | 10 LET A=0 2 | 15 LET B=0 3 | 20 PRINT A;" "; 4 | 30 LET A=A+1 5 | 32 LET B=B+1 6 | 35 IF B>9 THEN GOTO 60 7 | 40 IF A>1000 THEN END 8 | 50 GOTO 20 9 | 60 PRINT 10 | 70 GOTO 15 11 | -------------------------------------------------------------------------------- /system.h: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------------------------------------- 3 | * Project: VM65 - Virtual Machine/CPU emulator programming 4 | * framework. 5 | * 6 | * File: system.h 7 | * 8 | * Purpose: Definitions related to platform portability. 9 | * 10 | * Date: 8/25/2016 11 | * 12 | * Copyright: (C) by Marek Karcz 2016. All rights reserved. 13 | * 14 | * Contact: makarcz@yahoo.com 15 | * 16 | * License Agreement and Warranty: 17 | 18 | This software is provided with No Warranty. 19 | I (Marek Karcz) will not be held responsible for any damage to 20 | computer systems, data or user's health resulting from use. 21 | Please proceed responsibly and apply common sense. 22 | This software is provided in hope that it will be useful. 23 | It is free of charge for non-commercial and educational use. 24 | Distribution of this software in non-commercial and educational 25 | derivative work is permitted under condition that original 26 | copyright notices and comments are preserved. Some 3-rd party work 27 | included with this project may require separate application for 28 | permission from their respective authors/copyright owners. 29 | 30 | *-------------------------------------------------------------------- 31 | */ 32 | #if !defined(LINUX) 33 | #define WINDOWS 34 | #endif 35 | -------------------------------------------------------------------------------- /t_adc_bcd_01.65s: -------------------------------------------------------------------------------- 1 | ; ADC, test decimal mode. 2 | ; 3 | ; NV-BDIZC 4 | ; ??1110?? 5 | ; 6 | ; The results I got on Rockwell 6502 AP 7 | ; 8 | ; 00 + 00 and C=0 gives 00 and N=0 V=0 Z=1 C=0 (3A) 9 | ; 79 + 00 and C=1 gives 80 and N=1 V=1 Z=0 C=0 (F8) 10 | ; 24 + 56 and C=0 gives 80 and N=1 V=1 Z=0 C=0 (F8) 11 | ; 93 + 82 and C=0 gives 75 and N=0 V=1 Z=0 C=1 (79) 12 | ; 89 + 76 and C=0 gives 65 and N=0 V=0 Z=0 C=1 (39) 13 | ; 89 + 76 and C=1 gives 66 and N=0 V=0 Z=0 C=1 (39) 14 | ; 80 + f0 and C=0 gives d0 and N=1 V=1 Z=0 C=1 (F9) 15 | ; 80 + fa and C=0 gives e0 and N=1 V=0 Z=0 C=1 (B9) 16 | ; 2f + 4f and C=0 gives 74 and N=0 V=0 Z=0 C=0 (38) 17 | ; 6f + 00 and C=1 gives 76 and N=0 V=0 Z=0 C=0 (38) 18 | 19 | RES=$0300 20 | 21 | *=$0200 22 | 23 | SED 24 | CLC 25 | LDA #$00 26 | ADC #$00 27 | STA RES 28 | PHP 29 | PLA 30 | STA RES+1 31 | SEC 32 | LDA #$79 33 | ADC #$00 34 | STA RES+2 35 | PHP 36 | PLA 37 | STA RES+3 38 | CLC 39 | LDA #$24 40 | ADC #$56 41 | STA RES+4 42 | PHP 43 | PLA 44 | STA RES+5 45 | CLC 46 | LDA #$93 47 | ADC #$82 48 | STA RES+6 49 | PHP 50 | PLA 51 | STA RES+7 52 | CLC 53 | LDA #$89 54 | ADC #$76 55 | STA RES+8 56 | PHP 57 | PLA 58 | STA RES+9 59 | SEC 60 | LDA #$89 61 | ADC #$76 62 | STA RES+10 63 | PHP 64 | PLA 65 | STA RES+11 66 | CLC 67 | LDA #$80 68 | ADC #$F0 69 | STA RES+12 70 | PHP 71 | PLA 72 | STA RES+13 73 | CLC 74 | LDA #$80 75 | ADC #$FA 76 | STA RES+14 77 | PHP 78 | PLA 79 | STA RES+15 80 | CLC 81 | LDA #$2F 82 | ADC #$4F 83 | STA RES+16 84 | PHP 85 | PLA 86 | STA RES+17 87 | SEC 88 | LDA #$6F 89 | ADC #$00 90 | STA RES+18 91 | PHP 92 | PLA 93 | STA RES+19 94 | BRK 95 | 96 | *=$0300 97 | 98 | .DS 20 99 | -------------------------------------------------------------------------------- /t_adc_bcd_01.dat: -------------------------------------------------------------------------------- 1 | ; Test ADC BCD mode. 2 | ORG 3 | $0200 4 | $F8 $18 $A9 $00 $69 $00 $8D $00 5 | $03 $08 $68 $8D $01 $03 $38 $A9 6 | $79 $69 $00 $8D $02 $03 $08 $68 7 | $8D $03 $03 $18 $A9 $24 $69 $56 8 | $8D $04 $03 $08 $68 $8D $05 $03 9 | $18 $A9 $93 $69 $82 $8D $06 $03 10 | $08 $68 $8D $07 $03 $18 $A9 $89 11 | $69 $76 $8D $08 $03 $08 $68 $8D 12 | $09 $03 $38 $A9 $89 $69 $76 $8D 13 | $0A $03 $08 $68 $8D $0B $03 $18 14 | $A9 $80 $69 $F0 $8D $0C $03 $08 15 | $68 $8D $0D $03 $18 $A9 $80 $69 16 | $FA $8D $0E $03 $08 $68 $8D $0F 17 | $03 $18 $A9 $2F $69 $4F $8D $10 18 | $03 $08 $68 $8D $11 $03 $38 $A9 19 | $6F $69 $00 $8D $12 $03 $08 $68 20 | $8D $13 $03 $00 $00 $00 $00 $00 21 | $00 $00 $00 $00 $00 $00 $00 $00 22 | $00 $00 $00 $00 $00 $00 $00 $00 23 | $00 $00 $00 $00 $00 $00 $00 $00 24 | $00 $00 $00 $00 $00 $00 $00 $00 25 | $00 $00 $00 $00 $00 $00 $00 $00 26 | $00 $00 $00 $00 $00 $00 $00 $00 27 | $00 $00 $00 $00 $00 $00 $00 $00 28 | $00 $00 $00 $00 $00 $00 $00 $00 29 | $00 $00 $00 $00 $00 $00 $00 $00 30 | $00 $00 $00 $00 $00 $00 $00 $00 31 | $00 $00 $00 $00 $00 $00 $00 $00 32 | $00 $00 $00 $00 $00 $00 $00 $00 33 | $00 $00 $00 $00 $00 $00 $00 $00 34 | $00 $00 $00 $00 $00 $00 $00 $00 35 | $00 $00 $00 $00 $00 $00 $00 $00 36 | 37 | -------------------------------------------------------------------------------- /t_sbc_bcd_01.65s: -------------------------------------------------------------------------------- 1 | ; SBC, test decimal mode. 2 | ; 3 | ; NV-BDIZC 4 | ; ??1110?? 5 | ; 6 | ; Expected results (I got on Rockwell 6502 AP): 7 | ; 00 - 00 and C=0 gives 99 and N=1 V=0 Z=0 C=0 (B8) 8 | ; 00 - 00 and C=1 gives 00 and N=0 V=0 Z=1 C=1 (3B) 9 | ; 00 - 01 and C=1 gives 99 and N=1 V=0 Z=0 C=0 (B8) 10 | ; 0a - 00 and C=1 gives 0a and N=0 V=0 Z=0 C=1 (39) 11 | ; 0b - 00 and C=0 gives 0a and N=0 V=0 Z=0 C=1 (39) 12 | ; 9a - 00 and C=1 gives 9a and N=1 V=0 Z=0 C=1 (B9) 13 | ; 9b - 00 and C=0 gives 9a and N=1 V=0 Z=0 C=1 (B9) 14 | ; 15 | 16 | *=$0200 17 | 18 | SED 19 | CLC 20 | LDA #$00 21 | SBC #$00 22 | STA SBT1A 23 | PHP 24 | PLA 25 | STA SBT1F 26 | SEC 27 | LDA #$00 28 | SBC #$00 29 | STA SBT2A 30 | PHP 31 | PLA 32 | STA SBT2F 33 | SEC 34 | LDA #$00 35 | SBC #$01 36 | STA SBT3A 37 | PHP 38 | PLA 39 | STA SBT3F 40 | SEC 41 | LDA #$0A 42 | SBC #$00 43 | STA SBT4A 44 | PHP 45 | PLA 46 | STA SBT4F 47 | CLC 48 | LDA #$0B 49 | SBC #$00 50 | STA SBT5A 51 | PHP 52 | PLA 53 | STA SBT5F 54 | SEC 55 | LDA #$9A 56 | SBC #$00 57 | STA SBT6A 58 | PHP 59 | PLA 60 | STA SBT6F 61 | CLC 62 | LDA #$9B 63 | SBC #$00 64 | STA SBT7A 65 | PHP 66 | PLA 67 | STA SBT7F 68 | BRK 69 | 70 | *=$0300 71 | 72 | SBT1A: .DB 0 73 | SBT1F: .DB 0 74 | SBT2A: .DB 0 75 | SBT2F: .DB 0 76 | SBT3A: .DB 0 77 | SBT3F: .DB 0 78 | SBT4A: .DB 0 79 | SBT4F: .DB 0 80 | SBT5A: .DB 0 81 | SBT5F: .DB 0 82 | SBT6A: .DB 0 83 | SBT6F: .DB 0 84 | SBT7A: .DB 0 85 | SBT7F: .DB 0 -------------------------------------------------------------------------------- /t_sbc_bcd_01.dat: -------------------------------------------------------------------------------- 1 | ; Test BCD mode. 2 | ORG 3 | $0200 4 | $F8 $18 $A9 $00 $E9 $00 $8D $00 5 | $03 $08 $68 $8D $01 $03 $38 $A9 6 | $00 $E9 $00 $8D $02 $03 $08 $68 7 | $8D $03 $03 $38 $A9 $00 $E9 $01 8 | $8D $04 $03 $08 $68 $8D $05 $03 9 | $38 $A9 $0A $E9 $00 $8D $06 $03 10 | $08 $68 $8D $07 $03 $18 $A9 $0B 11 | $E9 $00 $8D $08 $03 $08 $68 $8D 12 | $09 $03 $38 $A9 $9A $E9 $00 $8D 13 | $0A $03 $08 $68 $8D $0B $03 $18 14 | $A9 $9B $E9 $00 $8D $0C $03 $08 15 | $68 $8D $0D $03 $00 $00 $00 $00 16 | $00 $00 $00 $00 $00 $00 $00 $00 17 | $00 $00 $00 $00 $00 $00 $00 $00 18 | $00 $00 $00 $00 $00 $00 $00 $00 19 | $00 $00 $00 $00 $00 $00 $00 $00 20 | $00 $00 $00 $00 $00 $00 $00 $00 21 | $00 $00 $00 $00 $00 $00 $00 $00 22 | $00 $00 $00 $00 $00 $00 $00 $00 23 | $00 $00 $00 $00 $00 $00 $00 $00 24 | $00 $00 $00 $00 $00 $00 $00 $00 25 | $00 $00 $00 $00 $00 $00 $00 $00 26 | $00 $00 $00 $00 $00 $00 $00 $00 27 | $00 $00 $00 $00 $00 $00 $00 $00 28 | $00 $00 $00 $00 $00 $00 $00 $00 29 | $00 $00 $00 $00 $00 $00 $00 $00 30 | $00 $00 $00 $00 $00 $00 $00 $00 31 | $00 $00 $00 $00 $00 $00 $00 $00 32 | $00 $00 $00 $00 $00 $00 $00 $00 33 | $00 $00 $00 $00 $00 $00 $00 $00 34 | $00 $00 $00 $00 $00 $00 $00 $00 35 | $00 $00 $00 $00 $00 $00 $00 $00 36 | 37 | -------------------------------------------------------------------------------- /tall.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makarcz/vm6502/4166e540db12a8238f1896632f05afb2f4d45390/tall.bin -------------------------------------------------------------------------------- /tall.dat: -------------------------------------------------------------------------------- 1 | ; Created with BIN2HEX (C) Marek Karcz 2016. All rights reserved. 2 | ; 03/09/16 20:30:42 3 | ADDR 4 | $4000 5 | ORG 6 | $0000 7 | ORG 8 | $4000 9 | $a9 $00 $8d $10 $02 $a9 $55 $8d $00 $02 $a9 $aa $8d $01 $02 $a9 10 | $ff $8d $02 $02 $a9 $6e $8d $03 $02 $a9 $42 $8d $04 $02 $a9 $33 11 | $8d $05 $02 $a9 $9d $8d $06 $02 $a9 $7f $8d $07 $02 $a9 $a5 $8d 12 | $08 $02 $a9 $1f $8d $09 $02 $a9 $ce $8d $0a $02 $a9 $29 $8d $0b 13 | $02 $a9 $42 $8d $0c $02 $a9 $6c $8d $0d $02 $a9 $42 $8d $0e $02 14 | $a9 $55 $a2 $2a $a0 $73 $85 $81 $a9 $01 $85 $61 $a9 $7e $a5 $81 15 | $8d $10 $09 $a9 $7e $ad $10 $09 $95 $56 $a9 $7e $b5 $56 $84 $60 16 | $91 $60 $a9 $7e $b1 $60 $9d $ff $07 $a9 $7e $bd $ff $07 $99 $ff 17 | $07 $a9 $7e $b9 $ff $07 $81 $36 $a9 $7e $a1 $36 $86 $50 $a6 $60 18 | $a4 $50 $8e $13 $09 $a2 $22 $ae $13 $09 $8c $14 $09 $a0 $99 $ac 19 | $14 $09 $94 $2d $96 $77 $a0 $99 $b4 $2d $a2 $22 $b6 $77 $a0 $99 20 | $bc $a0 $08 $a2 $22 $be $a1 $08 $9d $00 $02 $ad $2a $02 $cd $00 21 | $02 $f0 $03 $4c $c0 $45 $a9 $fe $8d $10 $02 $a9 $55 $29 $53 $09 22 | $38 $49 $11 $85 $99 $a9 $b9 $85 $10 $a9 $e7 $85 $11 $a9 $39 $85 23 | $12 $a5 $99 $25 $10 $05 $11 $45 $12 $a2 $10 $85 $99 $a9 $bc $85 24 | $20 $a9 $31 $85 $21 $a9 $17 $85 $22 $a5 $99 $35 $10 $15 $11 $55 25 | $12 $85 $99 $a9 $6f $8d $10 $01 $a9 $3c $8d $11 $01 $a9 $27 $8d 26 | $12 $01 $a5 $99 $2d $10 $01 $0d $11 $01 $4d $12 $01 $85 $99 $a9 27 | $8a $8d $20 $01 $a9 $47 $8d $21 $01 $a9 $8f $8d $22 $01 $a5 $99 28 | $3d $10 $01 $1d $11 $01 $5d $12 $01 $a0 $20 $85 $99 $a9 $73 $8d 29 | $30 $01 $a9 $2a $8d $31 $01 $a9 $f1 $8d $32 $01 $a5 $99 $39 $10 30 | $01 $19 $11 $01 $59 $12 $01 $85 $99 $a9 $70 $85 $30 $a9 $01 $85 31 | $31 $a9 $71 $85 $32 $a9 $01 $85 $33 $a9 $72 $85 $34 $a9 $01 $85 32 | $35 $a9 $c5 $8d $70 $01 $a9 $7c $8d $71 $01 $a9 $a1 $8d $72 $01 33 | $a5 $99 $21 $20 $01 $22 $41 $24 $85 $99 $a9 $60 $85 $40 $a9 $01 34 | $85 $41 $a9 $61 $85 $42 $a9 $01 $85 $43 $a9 $62 $85 $44 $a9 $01 35 | $85 $45 $a9 $37 $8d $50 $02 $a9 $23 $8d $51 $02 $a9 $9d $8d $52 36 | $02 $a5 $99 $a0 $f0 $31 $40 $11 $42 $51 $44 $85 $a9 $a5 $a9 $cd 37 | $01 $02 $f0 $08 $a9 $01 $8d $10 $02 $4c $c0 $45 $a9 $ff $a2 $00 38 | $85 $90 $e6 $90 $e6 $90 $a5 $90 $a6 $90 $95 $90 $f6 $90 $b5 $90 39 | $a6 $91 $9d $90 $01 $ee $92 $01 $bd $90 $01 $ae $92 $01 $9d $90 40 | $01 $fe $90 $01 $bd $90 $01 $ae $93 $01 $9d $70 $01 $de $70 $01 41 | $bd $70 $01 $ae $74 $01 $9d $70 $01 $ce $73 $01 $bd $70 $01 $ae 42 | $73 $01 $95 $70 $d6 $70 $b5 $70 $a6 $72 $95 $70 $c6 $71 $c6 $71 43 | $a5 $71 $cd $02 $02 $f0 $08 $a9 $02 $8d $10 $02 $4c $c0 $45 $a9 44 | $4b $4a $0a $85 $50 $06 $50 $06 $50 $46 $50 $a5 $50 $a6 $50 $09 45 | $c9 $85 $60 $16 $4c $56 $4c $56 $4c $b5 $4c $a6 $60 $09 $41 $8d 46 | $2e $01 $5e $00 $01 $5e $00 $01 $1e $00 $01 $bd $00 $01 $ae $2e 47 | $01 $09 $81 $9d $00 $01 $4e $36 $01 $4e $36 $01 $0e $36 $01 $bd 48 | $00 $01 $2a $2a $6a $85 $70 $a6 $70 $09 $03 $95 $0c $26 $c0 $66 49 | $c0 $66 $c0 $b5 $0c $a6 $c0 $85 $d0 $36 $75 $36 $75 $76 $75 $a5 50 | $d0 $a6 $d0 $9d $00 $01 $2e $b7 $01 $2e $b7 $01 $2e $b7 $01 $6e 51 | $b7 $01 $bd $00 $01 $ae $b7 $01 $8d $dd $01 $3e $00 $01 $7e $00 52 | $01 $7e $00 $01 $ad $dd $01 $cd $03 $02 $f0 $08 $a9 $03 $8d $10 53 | $02 $4c $c0 $45 $a9 $e8 $85 $20 $a9 $42 $85 $21 $a9 $00 $09 $03 54 | $4c $d5 $42 $09 $ff $09 $30 $20 $e1 $42 $09 $42 $6c $20 $00 $09 55 | $ff $85 $30 $a6 $30 $a9 $00 $60 $95 $0d $a5 $40 $cd $04 $02 $f0 56 | $08 $a9 $04 $8d $10 $02 $4c $c0 $45 $a9 $35 $aa $ca $ca $e8 $8a 57 | $a8 $88 $88 $c8 $98 $aa $a9 $20 $9a $a2 $10 $ba $8a $85 $40 $a5 58 | $40 $cd $05 $02 $f0 $08 $a9 $05 $8d $10 $02 $4c $c0 $45 $2a $a9 59 | $6a $85 $50 $a9 $6b $85 $51 $a9 $a1 $85 $60 $a9 $a2 $85 $61 $a9 60 | $ff $69 $ff $69 $ff $e9 $ae $85 $40 $a6 $40 $75 $00 $f5 $01 $65 61 | $60 $e5 $61 $8d $20 $01 $a9 $4d $8d $21 $01 $a9 $23 $6d $20 $01 62 | $ed $21 $01 $85 $f0 $a6 $f0 $a9 $64 $8d $24 $01 $a9 $62 $8d $25 63 | $01 $a9 $26 $7d $00 $01 $fd $01 $01 $85 $f1 $a4 $f1 $a9 $e5 $8d 64 | $28 $01 $a9 $e9 $8d $29 $01 $a9 $34 $79 $00 $01 $f9 $01 $01 $85 65 | $f2 $a6 $f2 $a9 $20 $85 $70 $a9 $01 $85 $71 $a9 $24 $85 $72 $a9 66 | $01 $85 $73 $61 $41 $e1 $3f $85 $f3 $a4 $f3 $a9 $da $85 $80 $a9 67 | $00 $85 $81 $a9 $dc $85 $82 $a9 $00 $85 $83 $a9 $aa $71 $80 $f1 68 | $82 $85 $30 $a5 $30 $cd $06 $02 $f0 $08 $a9 $06 $8d $10 $02 $4c 69 | $c0 $45 $a9 $00 $85 $34 $a9 $ff $8d $30 $01 $a9 $99 $8d $9d $01 70 | $a9 $db $8d $99 $01 $a9 $2f $85 $32 $a9 $32 $85 $4f $a9 $30 $85 71 | $33 $a9 $70 $85 $af $a9 $18 $85 $30 $c9 $18 $f0 $02 $29 $00 $09 72 | $01 $c5 $30 $d0 $02 $29 $00 $a2 $00 $cd $30 $01 $f0 $04 $85 $40 73 | $a6 $40 $d5 $27 $d0 $06 $09 $84 $85 $41 $a6 $41 $29 $db $dd $00 74 | $01 $f0 $02 $29 $00 $85 $42 $a4 $42 $29 $00 $d9 $00 $01 $d0 $02 75 | $09 $0f $85 $43 $a6 $43 $09 $24 $c1 $40 $f0 $02 $09 $7f $85 $44 76 | $a4 $44 $49 $0f $d1 $33 $d0 $04 $a5 $44 $85 $15 $a5 $15 $cd $07 77 | $02 $f0 $08 $a9 $07 $8d $10 $02 $4c $c0 $45 $a9 $a5 $85 $20 $8d 78 | $20 $01 $a9 $5a $85 $21 $a2 $a5 $e0 $a5 $f0 $02 $a2 $01 $e4 $20 79 | $f0 $02 $a2 $02 $ec $20 $01 $f0 $02 $a2 $03 $86 $30 $a4 $30 $c0 80 | $a5 $f0 $02 $a0 $04 $c4 $20 $f0 $02 $a0 $05 $cc $20 $01 $f0 $02 81 | $a0 $06 $84 $31 $a5 $31 $24 $20 $d0 $02 $a9 $07 $2c $20 $01 $d0 82 | $02 $a9 $08 $24 $21 $d0 $02 $85 $42 $a5 $42 $cd $08 $02 $f0 $08 83 | $a9 $08 $8d $10 $02 $4c $c0 $45 $a9 $54 $85 $32 $a9 $b3 $85 $a1 84 | $a9 $87 $85 $43 $a2 $a1 $10 $02 $a2 $32 $b4 $00 $10 $04 $a9 $05 85 | $a6 $a1 $30 $02 $e9 $03 $30 $02 $a9 $41 $49 $30 $85 $32 $75 $00 86 | $50 $02 $a9 $03 $85 $54 $b6 $00 $75 $51 $50 $02 $a9 $e5 $75 $40 87 | $70 $05 $99 $01 $00 $65 $55 $70 $02 $a9 $00 $69 $f0 $90 $04 $85 88 | $60 $65 $43 $90 $02 $a9 $ff $65 $54 $b0 $04 $69 $87 $a6 $60 $b0 89 | $02 $a9 $00 $95 $73 $a5 $80 $cd $09 $02 $f0 $08 $a9 $09 $8d $10 90 | $02 $4c $c0 $45 $69 $00 $a9 $99 $69 $87 $18 $ea $90 $04 $69 $60 91 | $69 $93 $38 $ea $90 $01 $b8 $50 $02 $a9 $00 $69 $ad $ea $85 $30 92 | $a5 $30 $cd $0a $02 $f0 $08 $a9 $0a $8d $10 $02 $4c $c0 $45 $69 93 | $01 $a9 $27 $69 $01 $38 $08 $18 $28 $69 $00 $48 $a9 $00 $68 $85 94 | $30 $a5 $30 $cd $0b $02 $f0 $08 $a9 $0b $8d $10 $02 $4c $c0 $45 95 | $18 $a9 $42 $90 $04 $85 $33 $b0 $0a $a9 $45 $48 $a9 $61 $48 $38 96 | $08 $18 $40 $a5 $33 $cd $0c $02 $f0 $08 $a9 $0c $8d $10 $02 $4c 97 | $c0 $45 $69 $01 $78 $f8 $08 $68 $85 $20 $58 $d8 $08 $68 $65 $20 98 | $85 $21 $a5 $21 $cd $0d $02 $f0 $08 $a9 $0d $8d $10 $02 $4c $c0 99 | $45 $a9 $41 $85 $60 $e6 $60 $a5 $60 $cd $0e $02 $f0 $08 $a9 $0e 100 | $8d $10 $02 $4c $c0 $45 $a9 $fe $cd $10 $02 $d0 $03 $ee $10 $02 101 | $00 $00 $a2 $ff $9a $60 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 102 | ORG 103 | $ff00 104 | $40 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 105 | ORG 106 | $fff0 107 | $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $ff $00 $ff $00 $ff 108 | EXEC 109 | $4000 110 | -------------------------------------------------------------------------------- /tb.dat: -------------------------------------------------------------------------------- 1 | ADDR 2 | $0CF0 3 | ; Program disassembly from $0400 to $1000 2/20/2016 4 | ; Tiny Basic port for VM6502 emulator. 5 | ; Exec address: $0CF0 6 | ORG 7 | $0400 8 | ; Enable ROM and IO emulation. 9 | ENROM 10 | ENIO 11 | ; Set char IO address 12 | IOADDR 13 | $E000 14 | ; Code/Data 15 | $4C, $85, $04, $4C, $BD, $04, $4C, $2C 16 | $0F, $4C, $31, $0F, $EA, $18, $60, $5F 17 | $18, $80, $00, $20, $86, $C3, $90, $05 18 | $86, $C3, $91, $C2, $60, $B1, $C2, $A0 19 | $00, $60, $62, $05, $64, $05, $D8, $05 20 | $05, $06, $33, $06, $FD, $05, $9F, $07 21 | $42, $0B, $3F, $0B, $7A, $07, $FC, $08 22 | $95, $07, $9F, $07, $9F, $07, $BD, $0A 23 | $C1, $0A, $8A, $0A, $9B, $0A, $E9, $0A 24 | $61, $07, $51, $07, $41, $0A, $52, $0A 25 | $4F, $0A, $62, $0A, $E7, $09, $CD, $06 26 | $06, $07, $9F, $07, $15, $08, $A7, $07 27 | $B7, $06, $BF, $06, $83, $08, $A1, $06 28 | $9F, $07, $9F, $07, $A8, $08, $4F, $0B 29 | $4D, $0B, $07, $09, $AA, $04, $37, $07 30 | $BD, $04, $1B, $0B, $B1, $0A, $20, $41 31 | $54, $20, $80, $70, $0B, $A9, $00, $85 32 | $20, $85, $22, $A9, $1C, $85, $21, $85 33 | $23, $A0, $01, $B1, $22, $AA, $49, $FF 34 | $91, $22, $D1, $22, $08, $8A, $91, $22 35 | $E6, $22, $D0, $02, $E6, $23, $28, $F0 36 | $EA, $88, $D8, $A5, $20, $6D, $13, $04 37 | $85, $24, $98, $65, $21, $85, $25, $98 38 | $91, $20, $C8, $91, $20, $A5, $22, $85 39 | $C6, $85, $26, $A5, $23, $85, $C7, $85 40 | $27, $20, $87, $08, $AD, $83, $04, $85 41 | $2A, $AD, $84, $04, $85, $2B, $A9, $80 42 | $85, $C1, $A9, $30, $85, $C0, $A2, $00 43 | $86, $BE, $86, $C2, $CA, $9A, $D8, $20 44 | $F9, $06, $20, $F2, $04, $4C, $E6, $04 45 | $83, $65, $C9, $30, $B0, $7B, $C9, $08 46 | $90, $0C, $0A, $AA, $BD, $1F, $04, $48 47 | $BD, $1E, $04, $48, $08, $40, $65, $C1 48 | $AA, $B1, $C1, $48, $B5, $00, $91, $C1 49 | $68, $95, $00, $60, $20, $87, $08, $A9 50 | $21, $20, $09, $04, $A5, $2A, $38, $ED 51 | $83, $04, $AA, $A5, $2B, $ED, $84, $04 52 | $20, $A0, $07, $A5, $BE, $F0, $12, $A9 53 | $7E, $85, $2A, $A9, $20, $85, $2B, $20 54 | $A1, $06, $A6, $28, $A5, $29, $20, $A0 55 | $07, $A9, $07, $20, $09, $04, $20, $87 56 | $08, $A5, $26, $85, $C6, $A5, $27, $85 57 | $C7, $4C, $CC, $04, $A2, $7C, $E4, $C1 58 | $90, $BA, $A6, $C1, $E6, $C1, $E6, $C1 59 | $18, $60, $C6, $BD, $A5, $BD, $F0, $AC 60 | $A5, $BC, $85, $2A, $A5, $BD, $85, $2B 61 | $60, $C9, $40, $B0, $43, $48, $20, $F9 62 | $06, $6D, $83, $04, $85, $BC, $68, $48 63 | $29, $07, $6D, $84, $04, $85, $BD, $68 64 | $29, $08, $D0, $DC, $A5, $BC, $A6, $2A 65 | $85, $2A, $86, $BC, $A5, $BD, $A6, $2B 66 | $85, $2B, $86, $BD, $A5, $C6, $E9, $01 67 | $85, $C6, $B0, $02, $C6, $C7, $C5, $24 68 | $A5, $C7, $E5, $25, $90, $AA, $A5, $BC 69 | $91, $C6, $C8, $A5, $BD, $91, $C6, $60 70 | $48, $4A, $4A, $4A, $4A, $29, $0E, $AA 71 | $68, $C9, $60, $29, $1F, $B0, $02, $09 72 | $E0, $18, $F0, $07, $65, $2A, $85, $BC 73 | $98, $65, $2B, $85, $BD, $4C, $FC, $04 74 | $A5, $2C, $85, $B8, $A5, $2D, $85, $B9 75 | $20, $25, $06, $20, $14, $06, $51, $2A 76 | $AA, $20, $F9, $06, $8A, $F0, $F1, $0A 77 | $F0, $12, $A5, $B8, $85, $2C, $A5, $B9 78 | $85, $2D, $4C, $64, $05, $20, $25, $06 79 | $C9, $0D, $D0, $F6, $60, $20, $25, $06 80 | $C9, $5B, $B0, $EE, $C9, $41, $90, $EA 81 | $0A, $20, $87, $07, $A0, $00, $B1, $2C 82 | $E6, $2C, $D0, $02, $E6, $2D, $C9, $0D 83 | $18, $60, $20, $14, $06, $B1, $2C, $C9 84 | $20, $F0, $F7, $C9, $3A, $18, $10, $02 85 | $C9, $30, $60, $20, $25, $06, $90, $C2 86 | $84, $BC, $84, $BD, $A5, $BC, $A6, $BD 87 | $06, $BC, $26, $BD, $06, $BC, $26, $BD 88 | $18, $65, $BC, $85, $BC, $8A, $65, $BD 89 | $06, $BC, $2A, $85, $BD, $20, $14, $06 90 | $29, $0F, $65, $BC, $85, $BC, $98, $65 91 | $BD, $85, $BD, $20, $25, $06, $B0, $D4 92 | $4C, $80, $07, $20, $FC, $08, $A5, $BC 93 | $05, $BD, $F0, $48, $A5, $20, $85, $2C 94 | $A5, $21, $85, $2D, $20, $6D, $07, $F0 95 | $12, $A5, $28, $C5, $BC, $A5, $29, $E5 96 | $BD, $B0, $08, $20, $14, $06, $D0, $FB 97 | $4C, $7C, $06, $A5, $28, $45, $BC, $D0 98 | $04, $A5, $29, $45, $BD, $60, $20, $A6 99 | $06, $20, $F9, $06, $10, $F8, $E6, $BF 100 | $30, $03, $4C, $09, $04, $C6, $BF, $60 101 | $C9, $22, $F0, $FB, $20, $A6, $06, $20 102 | $14, $06, $D0, $F4, $4C, $14, $05, $A9 103 | $20, $20, $A6, $06, $A5, $BF, $29, $87 104 | $30, $E5, $D0, $F3, $60, $A2, $7B, $20 105 | $56, $05, $E6, $C1, $E6, $C1, $E6, $C1 106 | $38, $B5, $03, $F5, $00, $95, $00, $B5 107 | $04, $F5, $01, $50, $04, $49, $80, $09 108 | $01, $30, $0A, $D0, $04, $15, $00, $F0 109 | $02, $56, $02, $56, $02, $56, $02, $90 110 | $0C, $A0, $00, $B1, $2A, $E6, $2A, $D0 111 | $02, $E6, $2B, $09, $00, $60, $A5, $BE 112 | $F0, $28, $20, $14, $06, $D0, $FB, $20 113 | $6D, $07, $F0, $1B, $20, $4C, $07, $20 114 | $0C, $04, $B0, $09, $A5, $C4, $85, $2A 115 | $A5, $C5, $85, $2B, $60, $AD, $83, $04 116 | $85, $2A, $AD, $84, $04, $85, $2B, $4C 117 | $14, $05, $85, $BF, $4C, $49, $05, $A5 118 | $20, $85, $2C, $A5, $21, $85, $2D, $20 119 | $6D, $07, $F0, $EB, $A5, $2A, $85, $C4 120 | $A5, $2B, $85, $C5, $A9, $01, $85, $BE 121 | $60, $20, $6B, $06, $F0, $BE, $A5, $BC 122 | $85, $28, $A5, $BD, $85, $29, $4C, $14 123 | $05, $20, $FD, $0A, $20, $FA, $0A, $20 124 | $74, $06, $D0, $EA, $60, $20, $14, $06 125 | $85, $28, $20, $14, $06, $85, $29, $05 126 | $28, $60, $20, $FC, $08, $20, $80, $07 127 | $A5, $BD, $20, $87, $07, $A5, $BC, $A6 128 | $C1, $CA, $95, $00, $86, $C1, $E4, $C0 129 | $D0, $0D, $4C, $14, $05, $A6, $C1, $E0 130 | $80, $10, $F7, $B5, $00, $E6, $C1, $60 131 | $85, $BD, $86, $BC, $4C, $B8, $07, $A6 132 | $C1, $B5, $01, $10, $08, $20, $41, $0A 133 | $A9, $2D, $20, $A6, $06, $20, $FC, $08 134 | $A9, $1F, $85, $B8, $85, $BA, $A9, $2A 135 | $85, $B9, $85, $BB, $A6, $BC, $A4, $BD 136 | $38, $E6, $B8, $8A, $E9, $10, $AA, $98 137 | $E9, $27, $A8, $B0, $F4, $C6, $B9, $8A 138 | $69, $E8, $AA, $98, $69, $03, $A8, $90 139 | $F4, $8A, $38, $E6, $BA, $E9, $64, $B0 140 | $F9, $88, $10, $F6, $C6, $BB, $69, $0A 141 | $90, $FA, $09, $30, $85, $BC, $A9, $20 142 | $85, $BD, $A2, $FB, $86, $C3, $B5, $BD 143 | $05, $BD, $C9, $20, $F0, $09, $A0, $30 144 | $84, $BD, $05, $BD, $20, $A6, $06, $A6 145 | $C3, $E8, $D0, $E8, $60, $A5, $2D, $48 146 | $A5, $2C, $48, $A5, $20, $85, $2C, $A5 147 | $21, $85, $2D, $A5, $24, $A6, $25, $20 148 | $5B, $08, $F0, $03, $20, $5B, $08, $A5 149 | $2C, $38, $E5, $B6, $A5, $2D, $E5, $B7 150 | $B0, $42, $20, $6D, $07, $F0, $3D, $A6 151 | $28, $A5, $29, $20, $A0, $07, $A9, $20 152 | $20, $A6, $06, $20, $0C, $04, $B0, $2C 153 | $20, $14, $06, $D0, $F3, $20, $83, $08 154 | $4C, $2F, $08, $85, $B6, $E6, $B6, $D0 155 | $01, $E8, $86, $B7, $A4, $C1, $C0, $80 156 | $F0, $18, $20, $6B, $06, $A5, $2C, $A6 157 | $2D, $38, $E9, $02, $B0, $01, $CA, $85 158 | $2C, $4C, $48, $0B, $68, $85, $2C, $68 159 | $85, $2D, $60, $A5, $BF, $30, $FB, $A9 160 | $0D, $20, $09, $04, $AD, $11, $04, $29 161 | $7F, $85, $BF, $F0, $07, $20, $64, $0B 162 | $C6, $BF, $D0, $F9, $A9, $0A, $4C, $61 163 | $0B, $AC, $12, $04, $84, $BF, $B0, $0B 164 | $A9, $30, $85, $2C, $85, $C0, $84, $2D 165 | $20, $80, $07, $45, $80, $85, $80, $20 166 | $06, $04, $A0, $00, $A6, $C0, $29, $7F 167 | $F0, $F1, $C9, $7F, $F0, $ED, $C9, $13 168 | $F0, $DA, $C9, $0A, $F0, $D3, $CD, $10 169 | $04, $F0, $09, $CD, $0F, $04, $D0, $0A 170 | $E0, $30, $D0, $16, $A6, $2C, $84, $BF 171 | $A9, $0D, $E4, $C1, $30, $08, $A9, $07 172 | $20, $A6, $06, $4C, $B3, $08, $95, $00 173 | $E8, $E8, $CA, $86, $C0, $C9, $0D, $D0 174 | $BA, $20, $83, $08, $20, $95, $07, $85 175 | $BC, $20, $95, $07, $85, $BD, $60, $20 176 | $D6, $0A, $20, $6B, $06, $08, $20, $6D 177 | $08, $85, $B8, $86, $B9, $A5, $BC, $85 178 | $B6, $A5, $BD, $85, $B7, $A2, $00, $28 179 | $D0, $0B, $20, $6D, $07, $CA, $CA, $CA 180 | $20, $14, $06, $D0, $FA, $84, $28, $84 181 | $29, $20, $D6, $0A, $A9, $0D, $D1, $2C 182 | $F0, $11, $E8, $E8, $E8, $E8, $C8, $D1 183 | $2C, $D0, $FA, $A5, $B6, $85, $28, $A5 184 | $B7, $85, $29, $A5, $B8, $85, $BC, $A5 185 | $B9, $85, $BD, $18, $A0, $00, $8A, $F0 186 | $6E, $10, $29, $65, $2E, $85, $B8, $A5 187 | $2F, $E9, $00, $85, $B9, $B1, $2E, $91 188 | $B8, $A6, $2E, $E4, $24, $D0, $06, $A5 189 | $2F, $C5, $25, $F0, $4A, $E8, $86, $2E 190 | $D0, $02, $E6, $2F, $E6, $B8, $D0, $E5 191 | $E6, $B9, $D0, $E1, $65, $24, $85, $B8 192 | $85, $2E, $98, $65, $25, $85, $B9, $85 193 | $2F, $A5, $2E, $E5, $C6, $A5, $2F, $E5 194 | $C7, $90, $05, $C6, $2A, $4C, $14, $05 195 | $B1, $24, $91, $2E, $A6, $24, $D0, $02 196 | $C6, $25, $C6, $24, $A6, $2E, $D0, $02 197 | $C6, $2F, $CA, $86, $2E, $E4, $BC, $D0 198 | $E7, $A6, $2F, $E4, $BD, $D0, $E1, $A5 199 | $B8, $85, $24, $A5, $B9, $85, $25, $A5 200 | $28, $05, $29, $F0, $17, $A5, $28, $91 201 | $BC, $C8, $A5, $29, $91, $BC, $C8, $84 202 | $B6, $20, $14, $06, $08, $A4, $B6, $91 203 | $BC, $28, $D0, $F2, $4C, $CC, $04, $20 204 | $54, $05, $B5, $03, $29, $80, $F0, $02 205 | $A9, $FF, $85, $BC, $85, $BD, $48, $75 206 | $02, $95, $02, $68, $48, $75, $03, $95 207 | $03, $68, $55, $01, $85, $BB, $10, $03 208 | $20, $43, $0A, $A0, $11, $B5, $00, $15 209 | $01, $D0, $03, $4C, $14, $05, $38, $A5 210 | $BC, $F5, $00, $48, $A5, $BD, $F5, $01 211 | $48, $45, $BD, $30, $0A, $68, $85, $BD 212 | $68, $85, $BC, $38, $4C, $32, $0A, $68 213 | $68, $18, $36, $02, $36, $03, $26, $BC 214 | $26, $BD, $88, $D0, $D9, $A5, $BB, $10 215 | $0D, $A6, $C1, $38, $98, $F5, $00, $95 216 | $00, $98, $F5, $01, $95, $01, $60, $20 217 | $41, $0A, $20, $54, $05, $B5, $00, $75 218 | $02, $95, $02, $B5, $01, $75, $03, $95 219 | $03, $60, $20, $54, $05, $A0, $10, $B5 220 | $02, $85, $BC, $B5, $03, $85, $BD, $16 221 | $02, $36, $03, $26, $BC, $26, $BD, $90 222 | $0D, $18, $B5, $02, $75, $00, $95, $02 223 | $B5, $03, $75, $01, $95, $03, $88, $D0 224 | $E6, $60, $20, $95, $07, $AA, $B5, $00 225 | $B4, $01, $C6, $C1, $A6, $C1, $94, $00 226 | $4C, $87, $07, $A2, $7D, $20, $56, $05 227 | $B5, $01, $48, $B5, $00, $48, $20, $95 228 | $07, $AA, $68, $95, $00, $68, $95, $01 229 | $60, $20, $FD, $0A, $A5, $BC, $85, $2A 230 | $A5, $BD, $85, $2B, $60, $A2, $2C, $D0 231 | $02, $A2, $2E, $B5, $00, $C9, $80, $B0 232 | $0D, $B5, $01, $D0, $09, $A5, $2C, $85 233 | $2E, $A5, $2D, $85, $2F, $60, $A5, $2C 234 | $A4, $2E, $84, $2C, $85, $2E, $A5, $2D 235 | $A4, $2F, $84, $2D, $85, $2F, $A0, $00 236 | $60, $A5, $28, $85, $BC, $A5, $29, $85 237 | $BD, $20, $9C, $05, $A5, $C6, $85, $26 238 | $A5, $C7, $85, $27, $60, $B1, $C6, $85 239 | $BC, $20, $08, $0B, $B1, $C6, $85, $BD 240 | $E6, $C6, $D0, $02, $E6, $C7, $A5, $22 241 | $C5, $C6, $A5, $23, $E5, $C7, $B0, $E4 242 | $4C, $14, $05, $20, $24, $0B, $85, $BC 243 | $98, $4C, $82, $07, $20, $FC, $08, $A5 244 | $BC, $85, $B6, $20, $FC, $08, $A5, $BD 245 | $85, $B7, $A4, $BC, $20, $FC, $08, $A6 246 | $B7, $A5, $B6, $18, $6C, $BC, $00, $20 247 | $42, $0B, $20, $F9, $06, $4C, $87, $07 248 | $86, $2D, $E0, $00, $60, $A0, $02, $84 249 | $BC, $A0, $29, $84, $BD, $A0, $00, $B1 250 | $BC, $C9, $08, $D0, $03, $4C, $0B, $0A 251 | $60, $20, $09, $04, $A9, $FF, $2C, $11 252 | $04, $30, $02, $A9, $00, $4C, $09, $04 253 | $24, $3A, $91, $27, $10, $E1, $59, $C5 254 | $2A, $56, $10, $11, $2C, $8B, $4C, $45 255 | $D4, $A0, $80, $BD, $30, $BC, $E0, $13 256 | $1D, $94, $47, $CF, $88, $54, $CF, $30 257 | $BC, $E0, $10, $11, $16, $80, $53, $55 258 | $C2, $30, $BC, $E0, $14, $16, $90, $50 259 | $D2, $83, $49, $4E, $D4, $E5, $71, $88 260 | $BB, $E1, $1D, $8F, $A2, $21, $58, $6F 261 | $83, $AC, $22, $55, $83, $BA, $24, $93 262 | $E0, $23, $1D, $30, $BC, $20, $48, $91 263 | $49, $C6, $30, $BC, $31, $34, $30, $BC 264 | $84, $54, $48, $45, $CE, $1C, $1D, $38 265 | $0D, $9A, $49, $4E, $50, $55, $D4, $A0 266 | $10, $E7, $24, $3F, $20, $91, $27, $E1 267 | $59, $81, $AC, $30, $BC, $13, $11, $82 268 | $AC, $4D, $E0, $1D, $89, $52, $45, $54 269 | $55, $52, $CE, $E0, $15, $1D, $85, $45 270 | $4E, $C4, $E0, $2D, $98, $4C, $49, $53 271 | $D4, $EC, $24, $00, $00, $00, $00, $0A 272 | $80, $1F, $24, $93, $23, $1D, $30, $BC 273 | $E1, $50, $80, $AC, $59, $85, $52, $55 274 | $CE, $38, $0A, $86, $43, $4C, $45, $41 275 | $D2, $2B, $84, $52, $45, $CD, $1D, $A0 276 | $80, $BD, $38, $14, $85, $AD, $30, $D3 277 | $17, $64, $81, $AB, $30, $D3, $85, $AB 278 | $30, $D3, $18, $5A, $85, $AD, $30, $D3 279 | $19, $54, $2F, $30, $E2, $85, $AA, $30 280 | $E2, $1A, $5A, $85, $AF, $30, $E2, $1B 281 | $54, $2F, $98, $52, $4E, $C4, $0A, $80 282 | $80, $12, $0A, $09, $29, $1A, $0A, $1A 283 | $85, $18, $13, $09, $80, $12, $01, $0B 284 | $31, $30, $61, $72, $0B, $04, $02, $03 285 | $05, $03, $1B, $1A, $19, $0B, $09, $06 286 | $0A, $00, $00, $1C, $17, $2F, $8F, $55 287 | $53, $D2, $80, $A8, $30, $BC, $31, $2A 288 | $31, $2A, $80, $A9, $2E, $2F, $A2, $12 289 | $2F, $C1, $2F, $80, $A8, $30, $BC, $80 290 | $A9, $2F, $83, $AC, $38, $BC, $0B, $2F 291 | $80, $A8, $52, $2F, $84, $BD, $09, $02 292 | $2F, $8E, $BC, $84, $BD, $09, $93, $2F 293 | $84, $BE, $09, $05, $2F, $09, $91, $2F 294 | $80, $BE, $84, $BD, $09, $06, $2F, $84 295 | $BC, $09, $95, $2F, $09, $04, $2F, $00 296 | $00, $00, $00, $00, $00, $00, $00, $00 297 | $00, $00, $00, $00, $00, $00, $00, $00 298 | $00, $00, $00, $00, $00, $00, $00, $00 299 | $00, $00, $00, $00, $00, $00, $00, $00 300 | $00, $00, $00, $00, $00, $00, $00, $00 301 | $20, $0D, $0F, $A0, $00, $20, $1D, $0F 302 | $20, $2C, $0F, $C9, $43, $D0, $03, $4C 303 | $85, $04, $C9, $57, $D0, $03, $4C, $BD 304 | $04, $A2, $2F, $20, $1D, $0F, $4C, $F8 305 | $0C, $00, $00, $00, $00, $00, $00, $00 306 | $00, $00, $00, $00, $00, $00, $00, $00 307 | $00, $00, $00, $00, $00, $00, $00, $00 308 | $00, $00, $00, $00, $00, $00, $00, $00 309 | $00, $00, $00, $00, $00, $00, $00, $00 310 | $00, $00, $00, $00, $00, $00, $00, $00 311 | $00, $00, $00, $00, $00, $00, $00, $00 312 | $00, $00, $00, $00, $00, $00, $00, $00 313 | $00, $00, $00, $00, $00, $00, $00, $00 314 | $00, $00, $00, $00, $00, $00, $00, $00 315 | $00, $00, $00, $00, $00, $00, $00, $00 316 | $00, $00, $00, $00, $00, $00, $00, $00 317 | $00, $00, $00, $00, $00, $00, $00, $00 318 | $00, $00, $00, $00, $00, $00, $00, $00 319 | $00, $00, $00, $00, $00, $00, $00, $00 320 | $00, $00, $00, $00, $00, $00, $00, $00 321 | $00, $00, $00, $00, $00, $00, $00, $00 322 | $00, $00, $00, $00, $00, $00, $00, $00 323 | $00, $00, $00, $00, $00, $00, $00, $00 324 | $00, $00, $00, $00, $00, $00, $00, $00 325 | $00, $00, $00, $00, $00, $00, $00, $00 326 | $00, $00, $00, $00, $00, $00, $00, $00 327 | $00, $00, $00, $00, $00, $00, $00, $00 328 | $00, $00, $00, $00, $00, $00, $00, $00 329 | $00, $00, $00, $00, $00, $00, $00, $00 330 | $00, $00, $00, $00, $00, $00, $00, $00 331 | $00, $00, $00, $00, $00, $00, $00, $00 332 | $00, $00, $00, $00, $00, $00, $00, $00 333 | $00, $00, $00, $00, $00, $00, $00, $00 334 | $00, $00, $00, $00, $00, $00, $00, $00 335 | $4D, $4B, $48, $42, $43, $2D, $38, $2D 336 | $52, $32, $20, $54, $49, $4E, $59, $20 337 | $42, $41, $53, $49, $43, $20, $36, $35 338 | $30, $32, $20, $50, $4F, $52, $54, $0D 339 | $0A, $56, $65, $72, $73, $69, $6F, $6E 340 | $3A, $20, $31, $2E, $30, $2E, $33, $2C 341 | $20, $32, $2F, $32, $30, $2F, $32, $30 342 | $31, $36, $0D, $0A, $28, $4E, $4F, $54 343 | $45, $3A, $20, $55, $73, $65, $20, $55 344 | $50, $50, $45, $52, $20, $43, $41, $53 345 | $45, $2E, $29, $0D, $0A, $42, $6F, $6F 346 | $74, $20, $28, $5B, $43, $5D, $6F, $6C 347 | $64, $2F, $5B, $57, $5D, $61, $72, $6D 348 | $29, $3F, $20, $07, $FF, $00, $00, $00 349 | $00, $00, $00, $00, $00, $00, $00, $00 350 | $00, $00, $00, $00, $00, $00, $00, $00 351 | $00, $00, $00, $00, $00, $00, $00, $00 352 | $00, $00, $00, $00, $00, $00, $00, $00 353 | $00, $00, $00, $00, $00, $00, $00, $00 354 | $00, $00, $00, $00, $00, $00, $00, $00 355 | $00, $00, $00, $00, $00, $00, $00, $00 356 | $00, $00, $00, $00, $00, $00, $00, $00 357 | $00, $00, $00, $00, $00, $00, $00, $00 358 | $00, $00, $00, $00, $00, $00, $00, $00 359 | $00, $00, $00, $00, $00, $00, $00, $00 360 | $00, $00, $00, $00, $00, $00, $00, $00 361 | $00, $00, $00, $00, $00, $00, $00, $00 362 | $00, $00, $00, $00, $00, $00, $00, $00 363 | $00, $00, $00, $00, $00, $00, $00, $00 364 | $00, $00, $00, $00, $00, $00, $00, $00 365 | $00, $00, $00, $00, $00, $00, $00, $00 366 | $00, $00, $00, $00, $00, $00, $00, $00 367 | $86, $C3, $B1, $C2, $48, $C8, $B1, $C2 368 | $AA, $68, $A8, $8A, $60, $A2, $19, $A9 369 | $0D, $20, $31, $0F, $A9, $0A, $20, $31 370 | $0F, $CA, $D0, $FA, $60, $B9, $00, $0E 371 | $C9, $FF, $F0, $07, $20, $31, $0F, $C8 372 | $4C, $1D, $0F, $60, $AD, $00, $E0, $F0 373 | $FB, $85, $FE, $C9, $FF, $F0, $1E, $C9 374 | $00, $F0, $1A, $C9, $91, $F0, $16, $C9 375 | $93, $F0, $12, $C9, $80, $F0, $0E, $4C 376 | $50, $0F, $20, $F0, $FF, $A5, $FE, $60 377 | $A5, $FE, $8D, $00, $E0, $60, $00, $00 378 | $00, $00, $00, $00, $00, $00, $00, $00 379 | $00, $00, $00, $00, $00, $00, $00, $00 380 | $00, $00, $00, $00, $00, $00, $00, $00 381 | $00, $00, $00, $00, $00, $00, $00, $00 382 | $00, $00, $00, $00, $00, $00, $00, $00 383 | $00, $00, $00, $00, $00, $00, $00, $00 384 | $00, $00, $00, $00, $00, $00, $00, $00 385 | $00, $00, $00, $00, $00, $00, $00, $00 386 | $00, $00, $00, $00, $00, $00, $00, $00 387 | $00, $00, $00, $00, $00, $00, $00, $00 388 | $00, $00, $00, $00, $00, $00, $00, $00 389 | $00, $00, $00, $00, $00, $00, $00, $00 390 | $00, $00, $00, $00, $00, $00, $00, $00 391 | $00, $00, $00, $00, $00, $00, $00, $00 392 | $00, $00, $00, $00, $00, $00, $00, $00 393 | $00, $00, $00, $00, $00, $00, $00, $00 394 | $00, $00, $00, $00, $00, $00, $00, $00 395 | $00, $00, $00, $00, $00, $00, $00, $00 396 | $00, $00, $00, $00, $00, $00, $00, $00 397 | $00, $00, $00, $00, $00, $00, $00, $00 398 | $00, $00, $00, $00, $00, $00, $00, $00 399 | -------------------------------------------------------------------------------- /tb.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makarcz/vm6502/4166e540db12a8238f1896632f05afb2f4d45390/tb.snap -------------------------------------------------------------------------------- /test_char_io_01.65s: -------------------------------------------------------------------------------- 1 | ; Basic test of char I/O emulation 2 | 3 | .ORG $0200 4 | 5 | CHRGET = $E000 6 | PUTCH = $E000 7 | TXTBUF = $0400 8 | CR = $0D 9 | NL = $0A 10 | 11 | START: LDX #$00 12 | PR1: LDA PROMPT,X ;print prompt 13 | BEQ L0 14 | STA PUTCH 15 | INX 16 | BNE PR1 17 | L0: LDX #$00 18 | GETTXT: LDA CHRGET ;get text from input 19 | BEQ GETTXT 20 | CMP #CR 21 | BEQ L1 22 | CMP #NL 23 | BEQ L1 24 | STA PUTCH ;echo char 25 | STA TXTBUF,X ;store char 26 | INX 27 | BNE GETTXT 28 | L1: LDA #NL ; add line break 29 | STA TXTBUF,X 30 | STA PUTCH 31 | INX 32 | LDA #CR 33 | STA TXTBUF,X 34 | STA PUTCH 35 | INX 36 | LDA #$00 ; add null 37 | STA TXTBUF,X 38 | TAX 39 | PRINT: LDA TXTBUF,X ; print to output 40 | BEQ L2 41 | STA PUTCH 42 | INX 43 | BNE PRINT 44 | L2: BRK 45 | NOP 46 | JMP START 47 | PROMPT: .DB "Enter text:",0 48 | 49 | 50 | -------------------------------------------------------------------------------- /test_char_io_01.dat: -------------------------------------------------------------------------------- 1 | ; I/O test for MKBASIC VM. 2 | ORG 3 | $0200 4 | $A2 $00 $BD $4E $02 $F0 $06 $8D 5 | $00 $E0 $E8 $D0 $F5 $A2 $00 $AD 6 | $00 $E0 $F0 $FB $C9 $0D $F0 $0D 7 | $C9 $0A $F0 $09 $8D $00 $E0 $9D 8 | $00 $04 $E8 $D0 $EA $A9 $0A $9D 9 | $00 $04 $8D $00 $E0 $E8 $A9 $0D 10 | $9D $00 $04 $8D $00 $E0 $E8 $A9 11 | $00 $9D $00 $04 $AA $BD $00 $04 12 | $F0 $06 $8D $00 $E0 $E8 $D0 $F5 13 | $00 $00 $EA $4C $00 $02 $45 $6E 14 | $74 $65 $72 $20 $74 $65 $78 $74 15 | $3A $00 $00 $00 $00 $00 $00 $00 16 | ORG 17 | $FFFC 18 | $00 $02 19 | ENIO 20 | RESET -------------------------------------------------------------------------------- /test_grtxt.bas: -------------------------------------------------------------------------------- 1 | 5 PRINT:PRINT "BITMAP TEXT DEMO. PRESS [SPACE] TO QUIT...":PRINT 2 | 10 C=0:M=0:N=22:B=65506:POKE B+9,0 3 | 12 PRINT "NORMAL MODE, CHAR BANK ";N*2048 4 | 15 POKE B+13,N:POKE B+17,0:POKE B+18,0 5 | 20 FOR Y=0 TO 24 6 | 30 FOR X=0 TO 39 7 | 40 POKE B+14,X:POKE B+15,Y 8 | 50 POKE B+16,C 9 | 60 C=C+1:IF C<256 THEN 120 10 | 70 IF N=22 THEN N=23:GOTO 100 11 | 80 N=22:IF M=0 THEN M=1:GOTO 100 12 | 90 M=0 13 | 100 POKE B+13,N:POKE B+18,M 14 | 110 Y=Y+1:X=-1:C=0 15 | 115 IF M=0 THEN PRINT "NORMAL"; ELSE PRINT "REVERSE"; 16 | 116 PRINT " MODE, CHAR BANK ";N*2048 17 | 120 GET K$:IF K$=" " THEN END 18 | 130 NEXT X 19 | 140 NEXT Y 20 | 150 GOTO 5 21 | -------------------------------------------------------------------------------- /testall.asm: -------------------------------------------------------------------------------- 1 | ; Testing 6502 opcodes. 2 | ; Copied and adapted from AllSuiteA.asm from project hmc-6502: 3 | ; https://code.google.com/archive/p/hmc-6502/ 4 | ; EXPECTED FINAL RESULTS: $0210 = FF 5 | ; (any other number will be the test that failed) 6 | ; To build with cl65: 7 | ; cl65 -C testall_cl65.cfg -l --start-addr 16384 -t none -o tall.bin testall.asm 8 | ; then load to simulator from debug console with 'L B TALL.BIN' 9 | ; and execute with 'X 4000'. 10 | 11 | .segment "CODE1" 12 | 13 | .segment "CODE2" 14 | 15 | .ORG $4000 16 | 17 | start: 18 | ; initialize: 19 | LDA #$00 20 | STA $0210 21 | ; store each test's expected 22 | LDA #$55 23 | STA $0200 24 | LDA #$AA 25 | STA $0201 26 | LDA #$FF 27 | STA $0202 28 | LDA #$6E 29 | STA $0203 30 | LDA #$42 31 | STA $0204 32 | LDA #$33 33 | STA $0205 34 | LDA #$9D 35 | STA $0206 36 | LDA #$7F 37 | STA $0207 38 | LDA #$A5 39 | STA $0208 40 | LDA #$1F 41 | STA $0209 42 | LDA #$CE 43 | STA $020A 44 | LDA #$29 45 | STA $020B 46 | LDA #$42 47 | STA $020C 48 | LDA #$6C 49 | STA $020D 50 | LDA #$42 51 | STA $020E 52 | 53 | 54 | ; expected result: $022A = 0x55 55 | test00: 56 | LDA #85 57 | LDX #42 58 | LDY #115 59 | STA $81 60 | LDA #$01 61 | STA $61 62 | LDA #$7E 63 | LDA $81 64 | STA $0910 65 | LDA #$7E 66 | LDA $0910 67 | STA $56,X 68 | LDA #$7E 69 | LDA $56,X 70 | STY $60 71 | STA ($60),Y 72 | LDA #$7E 73 | LDA ($60),Y 74 | STA $07ff,X 75 | LDA #$7E 76 | LDA $07ff,X 77 | STA $07ff,Y 78 | LDA #$7E 79 | LDA $07ff,Y 80 | STA ($36,X) 81 | LDA #$7E 82 | LDA ($36,X) 83 | STX $50 84 | LDX $60 85 | LDY $50 86 | STX $0913 87 | LDX #$22 88 | LDX $0913 89 | STY $0914 90 | LDY #$99 91 | LDY $0914 92 | STY $2D,X 93 | STX $77,Y 94 | LDY #$99 95 | LDY $2D,X 96 | LDX #$22 97 | LDX $77,Y 98 | LDY #$99 99 | LDY $08A0,X 100 | LDX #$22 101 | LDX $08A1,Y 102 | STA $0200,X 103 | 104 | ; CHECK test00: 105 | LDA $022A 106 | CMP $0200 107 | BEQ test00pass 108 | JMP theend 109 | test00pass: 110 | LDA #$FE 111 | STA $0210 112 | 113 | 114 | ; expected result: $A9 = 0xAA 115 | test01: 116 | ; imm 117 | LDA #85 118 | AND #83 119 | ORA #56 120 | EOR #17 121 | 122 | ; zpg 123 | STA $99 124 | LDA #185 125 | STA $10 126 | LDA #231 127 | STA $11 128 | LDA #57 129 | STA $12 130 | LDA $99 131 | AND $10 132 | ORA $11 133 | EOR $12 134 | 135 | ; zpx 136 | LDX #16 137 | STA $99 138 | LDA #188 139 | STA $20 140 | LDA #49 141 | STA $21 142 | LDA #23 143 | STA $22 144 | LDA $99 145 | AND $10,X 146 | ORA $11,X 147 | EOR $12,X 148 | 149 | ; abs 150 | STA $99 151 | LDA #111 152 | STA $0110 153 | LDA #60 154 | STA $0111 155 | LDA #39 156 | STA $0112 157 | LDA $99 158 | AND $0110 159 | ORA $0111 160 | EOR $0112 161 | 162 | ; abx 163 | STA $99 164 | LDA #138 165 | STA $0120 166 | LDA #71 167 | STA $0121 168 | LDA #143 169 | STA $0122 170 | LDA $99 171 | AND $0110,X 172 | ORA $0111,X 173 | EOR $0112,X 174 | 175 | ; aby 176 | LDY #32 177 | STA $99 178 | LDA #115 179 | STA $0130 180 | LDA #42 181 | STA $0131 182 | LDA #241 183 | STA $0132 184 | LDA $99 185 | AND $0110,Y 186 | ORA $0111,Y 187 | EOR $0112,Y 188 | 189 | ; idx 190 | STA $99 191 | LDA #112 192 | STA $30 193 | LDA #$01 194 | STA $31 195 | LDA #113 196 | STA $32 197 | LDA #$01 198 | STA $33 199 | LDA #114 200 | STA $34 201 | LDA #$01 202 | STA $35 203 | LDA #197 204 | STA $0170 205 | LDA #124 206 | STA $0171 207 | LDA #161 208 | STA $0172 209 | LDA $99 210 | AND ($20,X) 211 | ORA ($22,X) 212 | EOR ($24,X) 213 | 214 | ; idy 215 | STA $99 216 | LDA #96 217 | STA $40 218 | LDA #$01 219 | STA $41 220 | LDA #97 221 | STA $42 222 | LDA #$01 223 | STA $43 224 | LDA #98 225 | STA $44 226 | LDA #$01 227 | STA $45 228 | LDA #55 229 | STA $0250 230 | LDA #35 231 | STA $0251 232 | LDA #157 233 | STA $0252 234 | LDA $99 235 | LDY #$F0 236 | AND ($40),Y 237 | ORA ($42),Y 238 | EOR ($44),Y 239 | 240 | STA $A9 241 | 242 | ; CHECK test01 243 | LDA $A9 244 | CMP $0201 245 | BEQ test02 246 | LDA #$01 247 | STA $0210 248 | JMP theend 249 | 250 | 251 | ; expected result: $71 = 0xFF 252 | test02: 253 | LDA #$FF 254 | LDX #$00 255 | 256 | STA $90 257 | INC $90 258 | INC $90 259 | LDA $90 260 | LDX $90 261 | 262 | STA $90,X 263 | INC $90,X 264 | LDA $90,X 265 | LDX $91 266 | 267 | STA $0190,X 268 | INC $0192 269 | LDA $0190,X 270 | LDX $0192 271 | 272 | STA $0190,X 273 | INC $0190,X 274 | LDA $0190,X 275 | LDX $0193 276 | 277 | STA $0170,X 278 | DEC $0170,X 279 | LDA $0170,X 280 | LDX $0174 281 | 282 | STA $0170,X 283 | DEC $0173 284 | LDA $0170,X 285 | LDX $0173 286 | 287 | STA $70,X 288 | DEC $70,X 289 | LDA $70,X 290 | LDX $72 291 | 292 | STA $70,X 293 | DEC $71 294 | DEC $71 295 | 296 | ; CHECK test02 297 | LDA $71 298 | CMP $0202 299 | BEQ test03 300 | LDA #$02 301 | STA $0210 302 | JMP theend 303 | 304 | 305 | ; expected result: $01DD = 0x6E 306 | test03: 307 | LDA #$4B 308 | LSR 309 | ASL 310 | 311 | STA $50 312 | ASL $50 313 | ASL $50 314 | LSR $50 315 | LDA $50 316 | 317 | LDX $50 318 | ORA #$C9 319 | STA $60 320 | ASL $4C,X 321 | LSR $4C,X 322 | LSR $4C,X 323 | LDA $4C,X 324 | 325 | LDX $60 326 | ORA #$41 327 | STA $012E 328 | LSR $0100,X 329 | LSR $0100,X 330 | ASL $0100,X 331 | LDA $0100,X 332 | 333 | LDX $012E 334 | ORA #$81 335 | STA $0100,X 336 | LSR $0136 337 | LSR $0136 338 | ASL $0136 339 | LDA $0100,X 340 | 341 | ; rol & ror 342 | 343 | ROL 344 | ROL 345 | ROR 346 | STA $70 347 | 348 | LDX $70 349 | ORA #$03 350 | STA $0C,X 351 | ROL $C0 352 | ROR $C0 353 | ROR $C0 354 | LDA $0C,X 355 | 356 | LDX $C0 357 | STA $D0 358 | ROL $75,X 359 | ROL $75,X 360 | ROR $75,X 361 | LDA $D0 362 | 363 | LDX $D0 364 | STA $0100,X 365 | ROL $01B7 366 | ROL $01B7 367 | ROL $01B7 368 | ROR $01B7 369 | LDA $0100,X 370 | 371 | LDX $01B7 372 | STA $01DD 373 | ROL $0100,X 374 | ROR $0100,X 375 | ROR $0100,X 376 | 377 | ; CHECK test03 378 | LDA $01DD 379 | CMP $0203 380 | BEQ test04 381 | LDA #$03 382 | STA $0210 383 | JMP theend 384 | 385 | 386 | ; expected result: $40 = 0x42 387 | test04: 388 | LDA #$E8 ;originally:#$7C 389 | STA $20 390 | LDA #$42 ;originally:#$02 391 | STA $21 392 | LDA #$00 393 | ORA #$03 394 | JMP jump1 395 | ORA #$FF ; not done 396 | jump1: 397 | ORA #$30 398 | JSR subr 399 | ORA #$42 400 | JMP ($0020) 401 | ORA #$FF ; not done 402 | subr: 403 | STA $30 404 | LDX $30 405 | LDA #$00 406 | RTS 407 | final: 408 | STA $0D,X 409 | 410 | ; CHECK test04 411 | LDA $40 412 | CMP $0204 413 | BEQ test05 414 | LDA #$04 415 | STA $0210 416 | JMP theend 417 | 418 | 419 | ; expected result: $40 = 0x33 420 | test05: 421 | LDA #$35 422 | 423 | TAX 424 | DEX 425 | DEX 426 | INX 427 | TXA 428 | 429 | TAY 430 | DEY 431 | DEY 432 | INY 433 | TYA 434 | 435 | TAX 436 | LDA #$20 437 | TXS 438 | LDX #$10 439 | TSX 440 | TXA 441 | 442 | STA $40 443 | 444 | ; CHECK test05 445 | LDA $40 446 | CMP $0205 447 | BEQ test06 448 | LDA #$05 449 | STA $0210 450 | JMP theend 451 | 452 | 453 | ; expected result: $30 = 9D 454 | test06: 455 | 456 | ; RESET TO CARRY FLAG = 0 457 | ROL 458 | 459 | LDA #$6A 460 | STA $50 461 | LDA #$6B 462 | STA $51 463 | LDA #$A1 464 | STA $60 465 | LDA #$A2 466 | STA $61 467 | 468 | LDA #$FF 469 | ADC #$FF 470 | ADC #$FF 471 | SBC #$AE 472 | 473 | STA $40 474 | LDX $40 475 | ADC $00,X 476 | SBC $01,X 477 | 478 | ADC $60 479 | SBC $61 480 | 481 | STA $0120 482 | LDA #$4D 483 | STA $0121 484 | LDA #$23 485 | ADC $0120 486 | SBC $0121 487 | 488 | STA $F0 489 | LDX $F0 490 | LDA #$64 491 | STA $0124 492 | LDA #$62 493 | STA $0125 494 | LDA #$26 495 | ADC $0100,X 496 | SBC $0101,X 497 | 498 | STA $F1 499 | LDY $F1 500 | LDA #$E5 501 | STA $0128 502 | LDA #$E9 503 | STA $0129 504 | LDA #$34 505 | ADC $0100,Y 506 | SBC $0101,Y 507 | 508 | STA $F2 509 | LDX $F2 510 | LDA #$20 511 | STA $70 512 | LDA #$01 513 | STA $71 514 | LDA #$24 515 | STA $72 516 | LDA #$01 517 | STA $73 518 | ADC ($41,X) 519 | SBC ($3F,X) 520 | 521 | STA $F3 522 | LDY $F3 523 | LDA #$DA 524 | STA $80 525 | LDA #$00 526 | STA $81 527 | LDA #$DC 528 | STA $82 529 | LDA #$00 530 | STA $83 531 | LDA #$AA 532 | ADC ($80),Y 533 | SBC ($82),Y 534 | STA $30 535 | 536 | ; CHECK test06 537 | LDA $30 538 | CMP $0206 539 | BEQ test07 540 | LDA #$06 541 | STA $0210 542 | JMP theend 543 | 544 | 545 | ; expected result: $15 = 0x7F 546 | test07: 547 | ; prepare memory 548 | LDA #$00 549 | STA $34 550 | LDA #$FF 551 | STA $0130 552 | LDA #$99 553 | STA $019D 554 | LDA #$DB 555 | STA $0199 556 | LDA #$2F 557 | STA $32 558 | LDA #$32 559 | STA $4F 560 | LDA #$30 561 | STA $33 562 | LDA #$70 563 | STA $AF 564 | LDA #$18 565 | STA $30 566 | 567 | ; imm 568 | CMP #$18 569 | BEQ beq1 ; taken 570 | AND #$00 ; not done 571 | beq1: 572 | ; zpg 573 | ORA #$01 574 | CMP $30 575 | BNE bne1 ; taken 576 | AND #$00 ; not done 577 | bne1: 578 | ; abs 579 | LDX #$00 580 | CMP $0130 581 | BEQ beq2 ; not taken 582 | STA $40 583 | LDX $40 584 | beq2: 585 | ; zpx 586 | CMP $27,X 587 | BNE bne2 ; not taken 588 | ORA #$84 589 | STA $41 590 | LDX $41 591 | bne2: 592 | ; abx 593 | AND #$DB 594 | CMP $0100,X 595 | BEQ beq3 ; taken 596 | AND #$00 ; not done 597 | beq3: 598 | ; aby 599 | STA $42 600 | LDY $42 601 | AND #$00 602 | CMP $0100,Y 603 | BNE bne3 ; taken 604 | ORA #$0F ; not done 605 | bne3: 606 | ; idx 607 | STA $43 608 | LDX $43 609 | ORA #$24 610 | CMP ($40,X) 611 | BEQ beq4 ; not taken 612 | ORA #$7F 613 | beq4: 614 | ; idy 615 | STA $44 616 | LDY $44 617 | EOR #$0F 618 | CMP ($33),Y 619 | BNE bne4 ; not taken 620 | LDA $44 621 | STA $15 622 | bne4: 623 | 624 | ; CHECK test07 625 | LDA $15 626 | CMP $0207 627 | BEQ test08 628 | LDA #$07 629 | STA $0210 630 | JMP theend 631 | 632 | 633 | ; expected result: $42 = 0xA5 634 | test08: 635 | ; prepare memory 636 | LDA #$A5 637 | STA $20 638 | STA $0120 639 | LDA #$5A 640 | STA $21 641 | 642 | ; cpx imm... 643 | LDX #$A5 644 | CPX #$A5 645 | BEQ b1 ; taken 646 | LDX #$01 ; not done 647 | b1: 648 | ; cpx zpg... 649 | CPX $20 650 | BEQ b2 ; taken 651 | LDX #$02 ; not done 652 | b2: 653 | ; cpx abs... 654 | CPX $0120 655 | BEQ b3 ; taken 656 | LDX #$03 ; not done 657 | b3: 658 | ; cpy imm... 659 | STX $30 660 | LDY $30 661 | CPY #$A5 662 | BEQ b4 ; taken 663 | LDY #$04 ; not done 664 | b4: 665 | ; cpy zpg... 666 | CPY $20 667 | BEQ b5 ; taken 668 | LDY #$05 ; not done 669 | b5: 670 | ; cpy abs... 671 | CPY $0120 672 | BEQ b6 ; taken 673 | LDY #$06 ; not done 674 | b6: 675 | ; bit zpg... 676 | STY $31 677 | LDA $31 678 | BIT $20 679 | BNE b7 ; taken 680 | LDA #$07 ; not done 681 | b7: 682 | ; bit abs... 683 | BIT $0120 684 | BNE b8 ; taken 685 | LDA #$08 ; not done 686 | b8: 687 | BIT $21 688 | BNE b9 ; not taken 689 | STA $42 690 | b9: 691 | 692 | ; CHECK test08 693 | LDA $42 694 | CMP $0208 695 | BEQ test09 696 | LDA #$08 697 | STA $0210 698 | JMP theend 699 | 700 | 701 | ; expected result: $80 = 0x1F 702 | test09: 703 | ; prepare memory 704 | LDA #$54 705 | STA $32 706 | LDA #$B3 707 | STA $A1 708 | LDA #$87 709 | STA $43 710 | 711 | ; BPL 712 | LDX #$A1 713 | BPL bpl1 ; not taken 714 | LDX #$32 715 | bpl1: 716 | LDY $00,X 717 | BPL bpl2 ; taken 718 | LDA #$05 ; not done 719 | LDX $A1 ; not done 720 | bpl2: 721 | 722 | ; BMI 723 | BMI bmi1 ; not taken 724 | SBC #$03 725 | bmi1: 726 | BMI bmi2 ; taken 727 | LDA #$41 ; not done 728 | bmi2: 729 | 730 | ; BVC 731 | EOR #$30 732 | STA $32 733 | ADC $00,X 734 | BVC bvc1 ; not taken 735 | LDA #$03 736 | bvc1: 737 | STA $54 738 | LDX $00,Y 739 | ADC $51,X 740 | BVC bvc2 ; taken 741 | LDA #$E5 ; not done 742 | bvc2: 743 | 744 | ; BVS 745 | ADC $40,X 746 | BVS bvs1 ; not taken 747 | STA $0001,Y 748 | ADC $55 749 | bvs1: 750 | BVS bvs2 ; taken 751 | LDA #$00 752 | bvs2: 753 | 754 | ; BCC 755 | ADC #$F0 756 | BCC bcc1 ; not taken 757 | STA $60 758 | ADC $43 759 | bcc1: 760 | BCC bcc2 ; taken 761 | LDA #$FF 762 | bcc2: 763 | 764 | ; BCS 765 | ADC $54 766 | BCS bcs1 ; not taken 767 | ADC #$87 768 | LDX $60 769 | bcs1: 770 | BCS bcs2 ; taken 771 | LDA #$00 ; not done 772 | bcs2: 773 | STA $73,X 774 | 775 | ; CHECK test09 776 | LDA $80 777 | CMP $0209 778 | BEQ test10 779 | LDA #$09 780 | STA $0210 781 | JMP theend 782 | 783 | 784 | ; expected result: $30 = 0xCE 785 | test10: 786 | 787 | ; RESET TO CARRY = 0 & OVERFLOW = 0 788 | ADC #$00 789 | 790 | LDA #$99 791 | ADC #$87 792 | CLC 793 | NOP 794 | BCC t10bcc1 ; taken 795 | ADC #$60 ; not done 796 | ADC #$93 ; not done 797 | t10bcc1: 798 | SEC 799 | NOP 800 | BCC t10bcc2 ; not taken 801 | CLV 802 | t10bcc2: 803 | BVC t10bvc1 ; taken 804 | LDA #$00 ; not done 805 | t10bvc1: 806 | ADC #$AD 807 | NOP 808 | STA $30 809 | 810 | ; CHECK test10 811 | LDA $30 812 | CMP $020A 813 | BEQ test11 814 | LDA #$0A 815 | STA $0210 816 | JMP theend 817 | 818 | 819 | ; expected result: $30 = 0x29 820 | test11: 821 | 822 | ; RESET TO CARRY = 0 & ZERO = 0 823 | ADC #$01 824 | 825 | LDA #$27 826 | ADC #$01 827 | SEC 828 | PHP 829 | CLC 830 | PLP 831 | ADC #$00 832 | PHA 833 | LDA #$00 834 | PLA 835 | STA $30 836 | 837 | ; CHECK test11 838 | LDA $30 839 | CMP $020B 840 | BEQ test12 841 | LDA #$0B 842 | STA $0210 843 | JMP theend 844 | 845 | 846 | ; expected result: $33 = 0x42 847 | test12: 848 | CLC 849 | LDA #$42 850 | BCC runstuff 851 | STA $33 852 | BCS t12end 853 | runstuff: 854 | LDA #$45 855 | PHA 856 | LDA #$61 857 | PHA 858 | SEC 859 | PHP 860 | CLC 861 | RTI 862 | t12end: 863 | 864 | ; CHECK test12 865 | LDA $33 866 | CMP $020C 867 | BEQ test13 868 | LDA #$0C 869 | STA $0210 870 | JMP theend 871 | 872 | 873 | ; expected result: $21 = 0x6C (simulator) 874 | ; $21 = 0x0C (ours) 875 | test13: 876 | 877 | ; RESET TO CARRY = 0 & ZERO = 0 878 | ADC #$01 879 | 880 | SEI 881 | SED 882 | PHP 883 | PLA 884 | STA $20 885 | CLI 886 | CLD 887 | PHP 888 | PLA 889 | ADC $20 890 | STA $21 891 | 892 | ; CHECK test13 893 | LDA $21 894 | CMP $020D 895 | BEQ test14 896 | LDA #$0D 897 | STA $0210 898 | JMP theend 899 | 900 | 901 | ; expect result: $60 = 0x42 902 | test14: 903 | ; !!! NOTICE: BRK doesn't work in this 904 | ; simulator, so commented instructions 905 | ; are what should be executed... 906 | ;JMP pass_intrp 907 | LDA #$41 908 | STA $60 909 | ;RTI 910 | ;pass_intrp: 911 | ;LDA #$FF 912 | ;STA $60 913 | ;BRK (two bytes) 914 | INC $60 915 | 916 | ; CHECK test14 917 | LDA $60 918 | CMP $020E 919 | BEQ suiteafinal 920 | LDA #$0E 921 | STA $0210 922 | JMP theend 923 | 924 | suiteafinal: 925 | ; IF $0210 == 0xFE, INCREMENT 926 | ; (checking that it didn't 927 | ; happen to wander off and 928 | ; not run our instructions 929 | ; to say which tests failed...) 930 | LDA #$FE 931 | CMP $0210 932 | BNE theend 933 | INC $0210 934 | theend: 935 | BRK 936 | BRK 937 | ;JMP theend 938 | LDX #$FF 939 | TXS 940 | RTS 941 | 942 | .segment "KERN" 943 | 944 | .ORG $FF00 945 | 946 | RTI 947 | 948 | .segment "VECT" 949 | 950 | .ORG $FFFA 951 | 952 | .BYTE $00,$FF,$00,$FF,$00,$FF 953 | 954 | ;-------------------------- END -------------------------------------------------------------------------------- /testall.dat: -------------------------------------------------------------------------------- 1 | ; Test 6502 emulation. 2 | ORG 3 | $4000 4 | $A9 $00 $8D $10 $02 $A9 $55 $8D 5 | $00 $02 $A9 $AA $8D $01 $02 $A9 6 | $FF $8D $02 $02 $A9 $6E $8D $03 7 | $02 $A9 $42 $8D $04 $02 $A9 $33 8 | $8D $05 $02 $A9 $9D $8D $06 $02 9 | $A9 $7F $8D $07 $02 $A9 $A5 $8D 10 | $08 $02 $A9 $1F $8D $09 $02 $A9 11 | $CE $8D $0A $02 $A9 $29 $8D $0B 12 | $02 $A9 $42 $8D $0C $02 $A9 $6C 13 | $8D $0D $02 $A9 $42 $8D $0E $02 14 | $A9 $55 $A2 $2A $A0 $73 $85 $81 15 | $A9 $01 $85 $61 $A9 $7E $A5 $81 16 | $8D $10 $09 $A9 $7E $AD $10 $09 17 | $95 $56 $A9 $7E $B5 $56 $84 $60 18 | $91 $60 $A9 $7E $B1 $60 $9D $FF 19 | $07 $A9 $7E $BD $FF $07 $99 $FF 20 | $07 $A9 $7E $B9 $FF $07 $81 $36 21 | $A9 $7E $A1 $36 $86 $50 $A6 $60 22 | $A4 $50 $8E $13 $09 $A2 $22 $AE 23 | $13 $09 $8C $14 $09 $A0 $99 $AC 24 | $14 $09 $94 $2D $96 $77 $A0 $99 25 | $B4 $2D $A2 $22 $B6 $77 $A0 $99 26 | $BC $A0 $08 $A2 $22 $BE $A1 $08 27 | $9D $00 $02 $AD $2A $02 $CD $00 28 | $02 $F0 $03 $4C $C0 $45 $A9 $FE 29 | $8D $10 $02 $A9 $55 $29 $53 $09 30 | $38 $49 $11 $85 $99 $A9 $B9 $85 31 | $10 $A9 $E7 $85 $11 $A9 $39 $85 32 | $12 $A5 $99 $25 $10 $05 $11 $45 33 | $12 $A2 $10 $85 $99 $A9 $BC $85 34 | $20 $A9 $31 $85 $21 $A9 $17 $85 35 | $22 $A5 $99 $35 $10 $15 $11 $55 36 | $12 $85 $99 $A9 $6F $8D $10 $01 37 | $A9 $3C $8D $11 $01 $A9 $27 $8D 38 | $12 $01 $A5 $99 $2D $10 $01 $0D 39 | $11 $01 $4D $12 $01 $85 $99 $A9 40 | $8A $8D $20 $01 $A9 $47 $8D $21 41 | $01 $A9 $8F $8D $22 $01 $A5 $99 42 | $3D $10 $01 $1D $11 $01 $5D $12 43 | $01 $A0 $20 $85 $99 $A9 $73 $8D 44 | $30 $01 $A9 $2A $8D $31 $01 $A9 45 | $F1 $8D $32 $01 $A5 $99 $39 $10 46 | $01 $19 $11 $01 $59 $12 $01 $85 47 | $99 $A9 $70 $85 $30 $A9 $01 $85 48 | $31 $A9 $71 $85 $32 $A9 $01 $85 49 | $33 $A9 $72 $85 $34 $A9 $01 $85 50 | $35 $A9 $C5 $8D $70 $01 $A9 $7C 51 | $8D $71 $01 $A9 $A1 $8D $72 $01 52 | $A5 $99 $21 $20 $01 $22 $41 $24 53 | $85 $99 $A9 $60 $85 $40 $A9 $01 54 | $85 $41 $A9 $61 $85 $42 $A9 $01 55 | $85 $43 $A9 $62 $85 $44 $A9 $01 56 | $85 $45 $A9 $37 $8D $50 $02 $A9 57 | $23 $8D $51 $02 $A9 $9D $8D $52 58 | $02 $A5 $99 $A0 $F0 $31 $40 $11 59 | $42 $51 $44 $85 $A9 $A5 $A9 $CD 60 | $01 $02 $F0 $08 $A9 $01 $8D $10 61 | $02 $4C $C0 $45 $A9 $FF $A2 $00 62 | $85 $90 $E6 $90 $E6 $90 $A5 $90 63 | $A6 $90 $95 $90 $F6 $90 $B5 $90 64 | $A6 $91 $9D $90 $01 $EE $92 $01 65 | $BD $90 $01 $AE $92 $01 $9D $90 66 | $01 $FE $90 $01 $BD $90 $01 $AE 67 | $93 $01 $9D $70 $01 $DE $70 $01 68 | $BD $70 $01 $AE $74 $01 $9D $70 69 | $01 $CE $73 $01 $BD $70 $01 $AE 70 | $73 $01 $95 $70 $D6 $70 $B5 $70 71 | $A6 $72 $95 $70 $C6 $71 $C6 $71 72 | $A5 $71 $CD $02 $02 $F0 $08 $A9 73 | $02 $8D $10 $02 $4C $C0 $45 $A9 74 | $4B $4A $0A $85 $50 $06 $50 $06 75 | $50 $46 $50 $A5 $50 $A6 $50 $09 76 | $C9 $85 $60 $16 $4C $56 $4C $56 77 | $4C $B5 $4C $A6 $60 $09 $41 $8D 78 | $2E $01 $5E $00 $01 $5E $00 $01 79 | $1E $00 $01 $BD $00 $01 $AE $2E 80 | $01 $09 $81 $9D $00 $01 $4E $36 81 | $01 $4E $36 $01 $0E $36 $01 $BD 82 | $00 $01 $2A $2A $6A $85 $70 $A6 83 | $70 $09 $03 $95 $0C $26 $C0 $66 84 | $C0 $66 $C0 $B5 $0C $A6 $C0 $85 85 | $D0 $36 $75 $36 $75 $76 $75 $A5 86 | $D0 $A6 $D0 $9D $00 $01 $2E $B7 87 | $01 $2E $B7 $01 $2E $B7 $01 $6E 88 | $B7 $01 $BD $00 $01 $AE $B7 $01 89 | $8D $DD $01 $3E $00 $01 $7E $00 90 | $01 $7E $00 $01 $AD $DD $01 $CD 91 | $03 $02 $F0 $08 $A9 $03 $8D $10 92 | $02 $4C $C0 $45 $A9 $E8 $85 $20 93 | $A9 $42 $85 $21 $A9 $00 $09 $03 94 | $4C $D5 $42 $09 $FF $09 $30 $20 95 | $E1 $42 $09 $42 $6C $20 $00 $09 96 | $FF $85 $30 $A6 $30 $A9 $00 $60 97 | $95 $0D $A5 $40 $CD $04 $02 $F0 98 | $08 $A9 $04 $8D $10 $02 $4C $C0 99 | $45 $A9 $35 $AA $CA $CA $E8 $8A 100 | $A8 $88 $88 $C8 $98 $AA $A9 $20 101 | $9A $A2 $10 $BA $8A $85 $40 $A5 102 | $40 $CD $05 $02 $F0 $08 $A9 $05 103 | $8D $10 $02 $4C $C0 $45 $2A $A9 104 | $6A $85 $50 $A9 $6B $85 $51 $A9 105 | $A1 $85 $60 $A9 $A2 $85 $61 $A9 106 | $FF $69 $FF $69 $FF $E9 $AE $85 107 | $40 $A6 $40 $75 $00 $F5 $01 $65 108 | $60 $E5 $61 $8D $20 $01 $A9 $4D 109 | $8D $21 $01 $A9 $23 $6D $20 $01 110 | $ED $21 $01 $85 $F0 $A6 $F0 $A9 111 | $64 $8D $24 $01 $A9 $62 $8D $25 112 | $01 $A9 $26 $7D $00 $01 $FD $01 113 | $01 $85 $F1 $A4 $F1 $A9 $E5 $8D 114 | $28 $01 $A9 $E9 $8D $29 $01 $A9 115 | $34 $79 $00 $01 $F9 $01 $01 $85 116 | $F2 $A6 $F2 $A9 $20 $85 $70 $A9 117 | $01 $85 $71 $A9 $24 $85 $72 $A9 118 | $01 $85 $73 $61 $41 $E1 $3F $85 119 | $F3 $A4 $F3 $A9 $DA $85 $80 $A9 120 | $00 $85 $81 $A9 $DC $85 $82 $A9 121 | $00 $85 $83 $A9 $AA $71 $80 $F1 122 | $82 $85 $30 $A5 $30 $CD $06 $02 123 | $F0 $08 $A9 $06 $8D $10 $02 $4C 124 | $C0 $45 $A9 $00 $85 $34 $A9 $FF 125 | $8D $30 $01 $A9 $99 $8D $9D $01 126 | $A9 $DB $8D $99 $01 $A9 $2F $85 127 | $32 $A9 $32 $85 $4F $A9 $30 $85 128 | $33 $A9 $70 $85 $AF $A9 $18 $85 129 | $30 $C9 $18 $F0 $02 $29 $00 $09 130 | $01 $C5 $30 $D0 $02 $29 $00 $A2 131 | $00 $CD $30 $01 $F0 $04 $85 $40 132 | $A6 $40 $D5 $27 $D0 $06 $09 $84 133 | $85 $41 $A6 $41 $29 $DB $DD $00 134 | $01 $F0 $02 $29 $00 $85 $42 $A4 135 | $42 $29 $00 $D9 $00 $01 $D0 $02 136 | $09 $0F $85 $43 $A6 $43 $09 $24 137 | $C1 $40 $F0 $02 $09 $7F $85 $44 138 | $A4 $44 $49 $0F $D1 $33 $D0 $04 139 | $A5 $44 $85 $15 $A5 $15 $CD $07 140 | $02 $F0 $08 $A9 $07 $8D $10 $02 141 | $4C $C0 $45 $A9 $A5 $85 $20 $8D 142 | $20 $01 $A9 $5A $85 $21 $A2 $A5 143 | $E0 $A5 $F0 $02 $A2 $01 $E4 $20 144 | $F0 $02 $A2 $02 $EC $20 $01 $F0 145 | $02 $A2 $03 $86 $30 $A4 $30 $C0 146 | $A5 $F0 $02 $A0 $04 $C4 $20 $F0 147 | $02 $A0 $05 $CC $20 $01 $F0 $02 148 | $A0 $06 $84 $31 $A5 $31 $24 $20 149 | $D0 $02 $A9 $07 $2C $20 $01 $D0 150 | $02 $A9 $08 $24 $21 $D0 $02 $85 151 | $42 $A5 $42 $CD $08 $02 $F0 $08 152 | $A9 $08 $8D $10 $02 $4C $C0 $45 153 | $A9 $54 $85 $32 $A9 $B3 $85 $A1 154 | $A9 $87 $85 $43 $A2 $A1 $10 $02 155 | $A2 $32 $B4 $00 $10 $04 $A9 $05 156 | $A6 $A1 $30 $02 $E9 $03 $30 $02 157 | $A9 $41 $49 $30 $85 $32 $75 $00 158 | $50 $02 $A9 $03 $85 $54 $B6 $00 159 | $75 $51 $50 $02 $A9 $E5 $75 $40 160 | $70 $05 $99 $01 $00 $65 $55 $70 161 | $02 $A9 $00 $69 $F0 $90 $04 $85 162 | $60 $65 $43 $90 $02 $A9 $FF $65 163 | $54 $B0 $04 $69 $87 $A6 $60 $B0 164 | $02 $A9 $00 $95 $73 $A5 $80 $CD 165 | $09 $02 $F0 $08 $A9 $09 $8D $10 166 | $02 $4C $C0 $45 $69 $00 $A9 $99 167 | $69 $87 $18 $EA $90 $04 $69 $60 168 | $69 $93 $38 $EA $90 $01 $B8 $50 169 | $02 $A9 $00 $69 $AD $EA $85 $30 170 | $A5 $30 $CD $0A $02 $F0 $08 $A9 171 | $0A $8D $10 $02 $4C $C0 $45 $69 172 | $01 $A9 $27 $69 $01 $38 $08 $18 173 | $28 $69 $00 $48 $A9 $00 $68 $85 174 | $30 $A5 $30 $CD $0B $02 $F0 $08 175 | $A9 $0B $8D $10 $02 $4C $C0 $45 176 | $18 $A9 $42 $90 $04 $85 $33 $B0 177 | $0A $A9 $45 $48 $A9 $61 $48 $38 178 | $08 $18 $40 $A5 $33 $CD $0C $02 179 | $F0 $08 $A9 $0C $8D $10 $02 $4C 180 | $C0 $45 $69 $01 $78 $F8 $08 $68 181 | $85 $20 $58 $D8 $08 $68 $65 $20 182 | $85 $21 $A5 $21 $CD $0D $02 $F0 183 | $08 $A9 $0D $8D $10 $02 $4C $C0 184 | $45 $A9 $41 $85 $60 $E6 $60 $A5 185 | $60 $CD $0E $02 $F0 $08 $A9 $0E 186 | $8D $10 $02 $4C $C0 $45 $A9 $FE 187 | $CD $10 $02 $D0 $03 $EE $10 $02 188 | $00 $00 $00 $00 $00 $00 $00 $00 189 | $00 $00 $00 $00 $00 $00 $00 $00 190 | $00 $00 $00 $00 $00 $00 $00 $00 191 | $00 $00 $00 $00 $00 $00 $00 $00 192 | $00 $00 $00 $00 $00 $00 $00 $00 193 | $00 $00 $00 $00 $00 $00 $00 $00 194 | $00 $00 $00 $00 $00 $00 $00 $00 195 | $00 $00 $00 $00 $00 $00 $00 $00 196 | -------------------------------------------------------------------------------- /testall.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makarcz/vm6502/4166e540db12a8238f1896632f05afb2f4d45390/testall.o -------------------------------------------------------------------------------- /testall_cl65.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # This is configuration file for CL65 linker to produce 3 | # binary image 64 kB long, which is to be loaded from 4 | # address $0000. 5 | # Code segment CODE1, 15 kB starts at $0400. 6 | # Code segment CODE2, 49 kB starts at $4000. 7 | # Kernel jump table segment KERN (250 B) starts at $FF00. 8 | # Vectors segment start at $FFFA. 9 | # 10 | MEMORY { 11 | RAM0: start = $0000, size = $400, fill = yes; 12 | RAM1: start = $0400, size = $3C00, fill = yes; 13 | RAM2: start = $4000, size = $BF00, fill = yes; 14 | ROM0: start = $FF00, size = $FA, fill = yes; 15 | ROM1: start = $FFFA, size = 6; 16 | } 17 | 18 | SEGMENTS { 19 | CODE1: load = RAM1, type = rw; 20 | CODE2: load = RAM2, type = rw; 21 | KERN: load = ROM0, type = ro; 22 | VECT: load = ROM1, type = ro; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /testbcd.dat: -------------------------------------------------------------------------------- 1 | ; Program disassembly from $0400 to $0600 2/9/2016 2 | ; Test BCD mode. 3 | ORG 4 | $0400 5 | $A0 $01 $8C $04 $03 $A9 $00 $8D 6 | $07 $03 $8D $0A $03 $AD $0A $03 7 | $29 $0F $8D $0B $03 $AD $0A $03 8 | $29 $F0 $8D $0F $03 $09 $0F $8D 9 | $10 $03 $AD $07 $03 $29 $0F $8D 10 | $09 $03 $AD $07 $03 $29 $F0 $8D 11 | $08 $03 $20 $5E $04 $20 $47 $05 12 | $20 $18 $05 $D0 $1D $20 $B1 $04 13 | $20 $54 $05 $20 $18 $05 $D0 $12 14 | $EE $07 $03 $D0 $D5 $EE $0A $03 15 | $D0 $BB $88 $10 $B8 $A9 $00 $8D 16 | $04 $03 $00 $00 $00 $00 $F8 $C0 17 | $01 $AD $07 $03 $6D $0A $03 $8D 18 | $02 $03 $08 $68 $8D $03 $03 $D8 19 | $C0 $01 $AD $07 $03 $6D $0A $03 20 | $8D $05 $03 $08 $68 $8D $06 $03 21 | $C0 $01 $AD $09 $03 $6D $0B $03 22 | $C9 $0A $A2 $00 $90 $06 $E8 $69 23 | $05 $29 $0F $38 $0D $08 $03 $7D 24 | $0F $03 $08 $B0 $04 $C9 $A0 $90 25 | $03 $69 $5F $38 $8D $00 $03 $08 26 | $68 $8D $01 $03 $68 $8D $0D $03 27 | $60 $F8 $C0 $01 $AD $07 $03 $ED 28 | $0A $03 $8D $02 $03 $08 $68 $8D 29 | $03 $03 $D8 $C0 $01 $AD $07 $03 30 | $ED $0A $03 $8D $05 $03 $08 $68 31 | $8D $06 $03 $60 $C0 $01 $AD $09 32 | $03 $ED $0B $03 $A2 $00 $B0 $06 33 | $E8 $E9 $05 $29 $0F $18 $0D $08 34 | $03 $FD $0F $03 $B0 $02 $E9 $5F 35 | $8D $00 $03 $60 $C0 $01 $AD $09 36 | $03 $ED $0B $03 $A2 $00 $B0 $04 37 | $E8 $29 $0F $18 $0D $08 $03 $FD 38 | $0F $03 $B0 $02 $E9 $5F $E0 $00 39 | $F0 $02 $E9 $06 $8D $00 $03 $60 40 | $AD $02 $03 $CD $00 $03 $D0 $26 41 | $AD $03 $03 $4D $0C $03 $29 $80 42 | $D0 $1C $AD $03 $03 $4D $0D $03 43 | $29 $40 $D0 $12 $AD $03 $03 $4D 44 | $0E $03 $29 $02 $D0 $08 $AD $03 45 | $03 $4D $01 $03 $29 $01 $60 $AD 46 | $0D $03 $8D $0C $03 $AD $06 $03 47 | $8D $0E $03 $60 $20 $D4 $04 $AD 48 | $06 $03 $8D $0C $03 $8D $0D $03 49 | $8D $0E $03 $8D $01 $03 $60 $AD 50 | $00 $03 $08 $68 $8D $0C $03 $8D 51 | $0E $03 $60 $20 $F4 $04 $AD $00 52 | $03 $08 $68 $8D $0C $03 $8D $0E 53 | $03 $AD $06 $03 $8D $0D $03 $8D 54 | $01 $03 $60 $AD $00 $03 $08 $68 55 | $8D $0C $03 $8D $0E $03 $60 $20 56 | $D4 $04 $AD $00 $03 $08 $68 $8D 57 | $0C $03 $8D $0E $03 $AD $06 $03 58 | $8D $0D $03 $8D $01 $03 $60 $00 59 | $00 $00 $00 $00 $00 $00 $00 $00 60 | $00 $00 $00 $00 $00 $00 $00 $00 61 | $00 $00 $00 $00 $00 $00 $00 $00 62 | $00 $00 $00 $00 $00 $00 $00 $00 63 | $00 $00 $00 $00 $00 $00 $00 $00 64 | $00 $00 $00 $00 $00 $00 $00 $00 65 | $00 $00 $00 $00 $00 $00 $00 $00 66 | $00 $00 $00 $00 $00 $00 $00 $00 67 | $00 $00 $00 $00 $00 $00 $00 $00 68 | $00 $00 $00 $00 $00 $00 $00 $00 69 | 70 | -------------------------------------------------------------------------------- /tinybasic.cfg: -------------------------------------------------------------------------------- 1 | ######################################################## 2 | # 3 | # File: tinybasic.cfg 4 | # 5 | # Purpose: cc65 configuration file for Tiny Basic 6 | # interpreter. 7 | # 8 | # Author: Marek Karcz 9 | # 10 | # Date created: January 2012 11 | # 12 | # Revision history: 13 | # 14 | # 2/13/2012 15 | # Relocated from $0400 to $4400 16 | # 17 | # 3/31/2016 18 | # Adapted for MKBASIC (VM65) emulator. 19 | # 20 | 21 | MEMORY { 22 | RAM0: start = $0000, size = $4400, fill = yes; 23 | RAM1: start = $4400, size = $08f0, fill = yes; 24 | RAM2: start = $4cf0, size = $0110, fill = yes; 25 | RAM3: start = $4e00, size = $0100, fill = yes; 26 | RAM4: start = $4f00, size = $b0ed, fill = yes; 27 | KERN: start = $ffed, size = $0d, fill = yes; 28 | VECT: start = $fffa, size = 6; 29 | } 30 | 31 | SEGMENTS { 32 | BEGN: load = RAM0, type = rw; 33 | BASIC: load = RAM1, type = rw; 34 | MAIN: load = RAM2, type = rw; 35 | MESG: load = RAM3, type = rw; 36 | SUBR: load = RAM4, type = rw; 37 | KERN: load = KERN, type = ro; 38 | VECT: load = VECT, type = ro; 39 | } 40 | 41 | --------------------------------------------------------------------------------