├── .gitattributes ├── .gitignore ├── CMakeLists.txt ├── README.md ├── VirtualPCCpp.sln └── VirtualPCCpp ├── Assembly Documentation.txt ├── Assembly.cpp ├── Assembly.h ├── CPU Documentation.txt ├── CPU.cpp ├── CPU.h ├── Change Log.txt ├── GPU.cpp ├── GPU.h ├── GPUAssembly.cpp ├── GPUAssembly.h ├── GPUCore.cpp ├── GPUCore.h ├── GPU_Program.txt ├── HDD.txt ├── KeyboardInputExample.txt ├── Main.cpp ├── Memory.cpp ├── Memory.h ├── NSSDL.cpp ├── NSSDL.h ├── PC.cpp ├── PC.h ├── Program.txt ├── SDLWindow.cpp ├── SDLWindow.h ├── String.h ├── VirtualPCCpp.vcxproj ├── VirtualPCCpp.vcxproj.filters └── fontBasic.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.1.3) 2 | project (VirtualPCCpp) 3 | add_executable (vpc 4 | ./VirtualPCCpp/NSSDL.cpp 5 | ./VirtualPCCpp/SDLWindow.cpp 6 | ./VirtualPCCpp/Next.cpp 7 | ./VirtualPCCpp/Memory.cpp 8 | ./VirtualPCCpp/Assembly.cpp 9 | ./VirtualPCCpp/CPU.cpp 10 | ./VirtualPCCpp/PC.cpp 11 | ./VirtualPCCpp/Main.cpp 12 | ./VirtualPCCpp/GPU.cpp) 13 | find_package(SDL2 REQUIRED) 14 | include_directories(${SDL_INCLUDE_DIRS}) 15 | target_link_libraries(vpc ${SDL2_LIBRARIES}) 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VirtualPCCpp 2 | **Main branch i am working on is Reworked right now, latest commits are on it. I will merge them *soon*** 3 | -------------------------------------------------------------------------------- /VirtualPCCpp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VirtualPCCpp", "VirtualPCCpp\VirtualPCCpp.vcxproj", "{746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Debug|x64.ActiveCfg = Debug|x64 17 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Debug|x64.Build.0 = Debug|x64 18 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Debug|x86.ActiveCfg = Debug|Win32 19 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Debug|x86.Build.0 = Debug|Win32 20 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Release|x64.ActiveCfg = Release|x64 21 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Release|x64.Build.0 = Release|x64 22 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Release|x86.ActiveCfg = Release|Win32 23 | {746C87CF-EAFF-4CE0-91E6-DA8E1E908D04}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /VirtualPCCpp/Assembly Documentation.txt: -------------------------------------------------------------------------------- 1 | General info: 2 | You explicitly need 1 space between instructions and arguments (or a new line) 3 | RGB values are limited from 0 to 127 4 | Character space is limited X: 0 - 56, Y: 0 - 26 (For the resolution of 320x240) 5 | Comments can be written with //, that line is ignored 6 | Each instruction needs to be in its own seperate line or error checking may be wrong 7 | 8 | You have data sections so you can do: 9 | data_s //Start of data section 10 | u8 x 5 //Variable x with type of 1 byte and stored value 5 11 | u16a y 3 1 2 3 //Array y with type of 2 byte elements (3 of them) with values 1 2 and 3 12 | data_e //End of data section 13 | 14 | You have interrupt part of the code which allows you to do: 15 | inter_s //Start of interrupt code 16 | //Any instruction can go here 17 | inter_e //End of interrupt code 18 | 19 | You can set jump postions for jmp and cmp instructions 20 | 21 | forward: 22 | 23 | You define jump positions by typing the name of it and putting a colon at the end of it 24 | 25 | Interrupt code executes on an interrupt, current ones are only keyboard input 26 | 27 | You can do REG0, REG1 and REG_INT for accessing register0, register1 and interruptRegister as arguments for instructions 28 | 29 | Instruction set: 30 | load0_24 - Load to register0 from ram, 3 bytes 1 argument (index of origin memory in ram) 31 | load1_24 - Load to register1 from ram, 3 bytes 1 argument (index of origin memory in ram) 32 | load0_16 - Load to register0 from ram, 2 bytes 1 argument (index of origin memory in ram) 33 | load1_16 - Load to register1 from ram, 2 bytes 1 argument (index of origin memory in ram) 34 | load0_8 - Load to register0 from ram, 1 byte 1 argument (index of origin memory in ram) 35 | load1_8 - Load to register1 from ram, 1 byte 1 argument (index of origin memory in ram) 36 | load0_24a - Load to register0 from ram with offset, 3 bytes 2 argument (index of origin memory in ram, index of offset in ram) 37 | load1_24a - Load to register1 from ram with offset, 3 bytes 2 argument (index of origin memory in ram, index of offset in ram) 38 | load0_16a - Load to register0 from ram with offset, 2 bytes 2 argument (index of origin memory in ram, index of offset in ram) 39 | load1_16a - Load to register1 from ram with offset, 2 bytes 2 argument (index of origin memory in ram, index of offset in ram) 40 | load0_8a - Load to register0 from ram with offset, 1 byte 2 argument (index of origin memory in ram, index of offset in ram) 41 | load1_8a - Load to register1 from ram with offset, 1 byte 2 argument (index of origin memory in ram, index of offset in ram) 42 | clr0 - Clear register0, 0 arguments 43 | clr1 - Clear register1, 0 arguments 44 | wrt0_24 - Write from register0 to ram, 3 bytes 1 argument (index of target memory in ram) 45 | wrt1_24 - Write from register1 to ram, 3 bytes 1 argument (index of target memory in ram) 46 | wrt0_16 - Write from register0 to ram, 2 bytes 1 argument (index of target memory in ram) 47 | wrt1_16 - Write from register1 to ram, 2 bytes 1 argument (index of target memory in ram) 48 | wrt0_8 - Write from register0 to ram, 1 byte 1 argument (index of target memory in ram) 49 | wrt1_8 - Write from register1 to ram, 1 byte 1 argument (index of target memory in ram) 50 | wrt0_24a - Write from register0 to ram with offset, 3 bytes 2 argument (index of origin memory in ram, index of offset in ram) 51 | wrt1_24a - Write from register1 to ram with offset, 3 bytes 2 argument (index of origin memory in ram, index of offset in ram) 52 | wrt0_16a - Write from register0 to ram with offset, 2 bytes 2 argument (index of origin memory in ram, index of offset in ram) 53 | wrt1_16a - Write from register1 to ram with offset, 2 bytes 2 argument (index of origin memory in ram, index of offset in ram) 54 | wrt0_8a - Write from register0 to ram with offset, 1 byte 2 argument (index of origin memory in ram, index of offset in ram) 55 | wrt1_8a - Write from register1 to ram with offset, 1 byte 2 argument (index of origin memory in ram, index of offset in ram) 56 | wrtR_H - Write from ram to hdd, 2 arguments (index of origin memory in ram, index of target memory in hdd) 57 | wrtH_R - Write from hdd to ram, 2 arguments (index of origin memory in hdd, index of target memory in ram) 58 | sum - Adds register0 and register1, 0 arguments 59 | sub - Subtracts register0 and register1, 0 arguments 60 | mlt - Multiplies register0 and register1, 0 arguments 61 | div - Divides register0 and register1, 0 arguments 62 | reg0_b - Check if register0 is greater than register1, 0 arguments 63 | reg0_be - Check if register0 is greater or equal to register1, 0 arguments 64 | reg1_b - Check if register1 is greater than register0, 0 arguments 65 | reg1_be - Check if register1 is greater or equal to register0, 0 arguments 66 | reg_eql - Check if register0 and register1 are the same size, 0 arguments 67 | reg_dif - Check if register0 and register1 are different size, 0 arguments 68 | jmp - Sets program counter to target position, 1 argument (target jump position) 69 | cmp - Compares register0 to a condition, 2 arguments (0 or 1 for the condition (false or true), jump position if condition is not met) 70 | cmp_a - Compares if two arrays contain same elements 2 arguments (size needs of arrays (they need to be same) needs to be loaded into register0, first array, second array) 71 | cot0 - Print to console contents of register0, 0 arguments 72 | cot1 - Print to console contents of register1, 0 arguments 73 | chk_k - Put current keyboard input value into cache, 1 argument (place in cache) 74 | wait - CPU waits a number of cycles, 1 argument (waiting time) 75 | clr_comm - Clears GPU command bufer, 0 arguments 76 | clr_vram - Clears GPU vRam, 0 arguments 77 | stop - Stops the PC (this one is always needed in the end of the program) 78 | 79 | Character codes: 80 | 0: 0, -: 21, C: 42, X: 63, p: 84 81 | 1: 1, ,: 22, D: 43, Y: 64, q: 85 82 | 2: 2, .: 23, E: 44, Z: 65, r: 86 83 | 3: 3, /: 24, F: 45, _: 66, s: 87 84 | 4: 4, \: 25, G: 46, : 67, t: 88 85 | 5: 5, :: 26, H: 47, @: 68, u: 89 86 | 6: 6, ;: 27, I: 48, a: 69, v: 90 87 | 7: 7, <: 28, J: 49, b: 70, w: 91 88 | 8: 8, >: 29, K: 50, c: 71, x: 92 89 | 9: 9, =: 30, L: 51, d: 72, y: 93 90 | !: 10, ?: 31, M: 52, e: 73, z: 94 91 | ": 11, [: 32, N: 53, f: 74, 92 | #: 12, ]: 33, O: 54, g: 75, 93 | $: 13, {: 34, P: 55, h: 76, 94 | %: 14, }: 35, Q: 56, i: 77, 95 | &: 15, `: 36, R: 57, j: 78, 96 | ': 16, ^: 37, S: 58, k: 79, 97 | (: 17, |: 38, T: 59, l: 80, 98 | ): 18, ~: 39, U: 60, m: 81, 99 | *: 19, A: 40, V: 61, n: 82, 100 | +: 20, B: 41, W: 62, o: 83, 101 | 102 | Keyboard character codes: 103 | Backspace: 96, 104 | Space: 67, 105 | Return: 95 106 | 107 | -------------------------------------------------------------------------------- /VirtualPCCpp/Assembly.cpp: -------------------------------------------------------------------------------- 1 | #include "Assembly.h" 2 | 3 | namespace Assembly { 4 | 5 | std::vector lines; 6 | 7 | void convertByte(int& number, byte& b1, byte& b2, byte& b3) { 8 | b1 = number & 0xff; 9 | b2 = (byte)(number >> 8); 10 | b3 = (byte)(number >> 16); 11 | } 12 | 13 | bool checkArgSize(int& arg, int argc, std::string& instruction, unsigned int& instructionC, int maxSize) { 14 | if (arg > maxSize) { 15 | std::cout << "Error: Argument " << argc << " exceeds size limit of " << maxSize << " at instruction " << instruction << " at position " << instructionC + 1 + argc << '\n'; 16 | return true; 17 | }else{ 18 | return false; 19 | } 20 | } 21 | 22 | void checkJmpPos(int& arg, std::string argument, std::vector& jumpNames, std::vector jumpPos) { 23 | bool varExists = false; 24 | int id = 0; 25 | 26 | for (unsigned int i = 0; i < jumpNames.size(); i++) { 27 | if (argument == jumpNames[i]) { 28 | varExists = true; 29 | id = i; 30 | break; 31 | } 32 | } 33 | 34 | if (varExists == true) { 35 | arg = jumpPos[id]; 36 | } 37 | } 38 | 39 | void checkArgType(int& arg, std::string& argument, CPU& cpu, std::vector& vars, std::vector& varValues) { 40 | bool varExists = false; 41 | int id = 0; 42 | 43 | for (unsigned int i = 0; i < vars.size(); i++) { 44 | if (argument == vars[i]) { 45 | varExists = true; 46 | id = i; 47 | break; 48 | } 49 | } 50 | 51 | if (varExists == true) { 52 | arg = varValues[id]; 53 | }else if (varExists == false) { 54 | if (argument == "REG0") { 55 | arg = cpu.ram.memory.size() + 1; 56 | }else if (argument == "REG1") { 57 | arg = cpu.ram.memory.size() + 2; 58 | }else if (argument == "REG_INT") { 59 | arg = cpu.ram.memory.size() + 3; 60 | }else { 61 | arg = std::stoi(argument); 62 | } 63 | } 64 | } 65 | 66 | void readFile(std::string path, std::vector& code) { 67 | std::string line; 68 | std::ifstream myfile(path); 69 | std::string prefix = "//"; 70 | 71 | if (myfile.is_open()){ 72 | while (getline (myfile,line)) { 73 | if (!(line[0] == '/' && line[1] == '/')) { 74 | if (line != "") { 75 | lines.push_back(line); 76 | std::string buf; 77 | std::stringstream ss(line); 78 | 79 | while (ss >> buf) { 80 | if (buf[0] == '/' && buf[1] == '/') {break;} 81 | code.push_back(buf); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | } 88 | 89 | void Compile(std::vector& code, CPU& cpu, std::vector& vValues, std::vector& vNames, int& finalCP) { 90 | std::vector charactersA = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '\"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', '-', ',', '.', '/', '\\', ':', ';', '<', '>', '=', '?', '[', ']', '{', '}', '`', '^', '|', '~', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', ' ', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; 91 | 92 | int currentPos = 0; 93 | int additionalMemory = 0; 94 | int GadditionalMemory = 0; 95 | int line = 0; 96 | std::vector jumpPositions; 97 | std::vector jumpNames; 98 | std::vector varValues; 99 | std::vector vars; 100 | 101 | bool dataM = false; 102 | bool GdataM = false; 103 | bool interM = false; 104 | bool hasStop = false; 105 | 106 | for (unsigned int i = 0; i < code.size(); i++) { 107 | 108 | std::string instruction = code[i]; 109 | 110 | if(instruction == "data_s") { 111 | dataM = true; 112 | i++; 113 | instruction = code[i]; 114 | } 115 | 116 | if(instruction == "data_e") { 117 | dataM = false; 118 | currentPos += additionalMemory; 119 | i++; 120 | instruction = code[i]; 121 | } 122 | 123 | if (instruction == "inter_s") { 124 | interM = true; 125 | i++; 126 | instruction = code[i]; 127 | } 128 | 129 | if (instruction == "inter_e") { 130 | interM = false; 131 | currentPos += 3; 132 | i++; 133 | instruction = code[i]; 134 | } 135 | 136 | if (dataM == true && interM == false) { 137 | if (instruction == "u8") { 138 | additionalMemory++; 139 | i += 2; 140 | }else if (instruction == "u16") { 141 | additionalMemory += 2; 142 | i += 2; 143 | }else if (instruction == "u24") { 144 | additionalMemory += 3; 145 | i += 2; 146 | }else if(instruction == "u8a") { 147 | std::string arg2 = code[i + 2]; 148 | 149 | int Arg2 = std::stoi(arg2); 150 | 151 | for (int j = 0; j < Arg2; j++) { 152 | additionalMemory++; 153 | } 154 | 155 | i += (2 + Arg2); 156 | }else if(instruction == "u16a") { 157 | std::string arg2 = code[i + 2]; 158 | 159 | int Arg2 = std::stoi(arg2); 160 | 161 | for (int j = 0; j < Arg2; j++) { 162 | additionalMemory += 2; 163 | } 164 | 165 | i += 2 + Arg2; 166 | }else if(instruction == "u24a") { 167 | std::string arg2 = code[i + 2]; 168 | 169 | int Arg2 = std::stoi(arg2); 170 | 171 | for (int j = 0; j < Arg2; j++) { 172 | additionalMemory += 3; 173 | } 174 | 175 | i += 2 + Arg2; 176 | }if (instruction == "g8") { 177 | i += 2; 178 | }else if (instruction == "g16") { 179 | i += 2; 180 | }else { 181 | std::cout << "Unknown instruction >" << instruction << "< at line" << line << '\n'; 182 | std::cout << '\n'; 183 | std::cout << lines[line] << '\n'; 184 | std::cout << "^" << '\n'; 185 | std::cout << '\n'; 186 | std::cout << "Compilation terminated." << '\n'; 187 | cpu.ram.Clear(); 188 | break; 189 | } 190 | }else if (dataM == false) { 191 | if (instruction == "load0_8") { 192 | currentPos += 3; 193 | i++; 194 | line++; 195 | }else if (instruction == "load1_8") { 196 | currentPos += 3; 197 | i++; 198 | line++; 199 | }else if (instruction == "load0_16") { 200 | currentPos += 3; 201 | i++; 202 | line++; 203 | }else if (instruction == "load1_16") { 204 | currentPos += 3; 205 | i++; 206 | line++; 207 | }else if (instruction == "load0_24") { 208 | currentPos += 3; 209 | i++; 210 | line++; 211 | }else if (instruction == "load1_24") { 212 | currentPos += 3; 213 | i++; 214 | line++; 215 | }else if (instruction == "load0_8a") { 216 | currentPos += 5; 217 | i += 2; 218 | line++; 219 | }else if (instruction == "load1_8a") { 220 | currentPos += 5; 221 | i += 2; 222 | line++; 223 | }else if (instruction == "load0_16a") { 224 | currentPos += 5; 225 | i += 2; 226 | line++; 227 | }else if (instruction == "load1_16a") { 228 | currentPos += 5; 229 | i += 2; 230 | line++; 231 | }else if (instruction == "load0_24a") { 232 | currentPos += 5; 233 | i += 2; 234 | line++; 235 | }else if (instruction == "load1_24a") { 236 | currentPos += 5; 237 | i += 2; 238 | line++; 239 | }else if (instruction == "clr0") { 240 | currentPos++; 241 | line++; 242 | }else if (instruction == "clr1") { 243 | currentPos++; 244 | line++; 245 | }else if (instruction == "wrt0_24") { 246 | currentPos += 3; 247 | i++; 248 | line++; 249 | }else if (instruction == "wrt1_24") { 250 | currentPos += 3; 251 | i++; 252 | line++; 253 | }else if (instruction == "wrt0_16") { 254 | currentPos += 3; 255 | i++; 256 | line++; 257 | }else if (instruction == "wrt1_16") { 258 | currentPos += 3; 259 | i++; 260 | line++; 261 | }else if (instruction == "wrt0_8") { 262 | currentPos += 3; 263 | i++; 264 | line++; 265 | }else if (instruction == "wrt1_8") { 266 | currentPos += 3; 267 | i++; 268 | line++; 269 | }else if (instruction == "wrt0_24a") { 270 | currentPos += 5; 271 | i += 2; 272 | line++; 273 | }else if (instruction == "wrt1_24a") { 274 | currentPos += 5; 275 | i += 2; 276 | line++; 277 | }else if (instruction == "wrt0_16a") { 278 | currentPos += 5; 279 | i += 2; 280 | line++; 281 | }else if (instruction == "wrt1_16a") { 282 | currentPos += 5; 283 | i += 2; 284 | line++; 285 | }else if (instruction == "wrt0_8a") { 286 | currentPos += 5; 287 | i += 2; 288 | line++; 289 | }else if (instruction == "wrt1_8a") { 290 | currentPos += 5; 291 | i += 2; 292 | line++; 293 | }else if (instruction == "wrtR_H") { 294 | currentPos++; 295 | line++; 296 | }else if (instruction == "wrtH_R") { 297 | currentPos++; 298 | line++; 299 | }else if (instruction == "sum") { 300 | currentPos++; 301 | line++; 302 | }else if (instruction == "sub") { 303 | currentPos++; 304 | line++; 305 | }else if (instruction == "mlt") { 306 | currentPos++; 307 | line++; 308 | }else if (instruction == "div") { 309 | currentPos++; 310 | line++; 311 | }else if (instruction == "reg0_b") { 312 | currentPos++; 313 | line++; 314 | }else if (instruction == "reg0_be") { 315 | currentPos++; 316 | line++; 317 | }else if (instruction == "reg1_b") { 318 | currentPos++; 319 | line++; 320 | }else if (instruction == "reg1_be") { 321 | currentPos++; 322 | line++; 323 | }else if (instruction == "reg_eql") { 324 | currentPos++; 325 | line++; 326 | }else if (instruction == "reg_dif") { 327 | currentPos++; 328 | line++; 329 | }else if (instruction == "jmp") { 330 | currentPos += 3; 331 | i++; 332 | line++; 333 | }else if (instruction == "cmp") { 334 | currentPos += 4; 335 | i += 2; 336 | line++; 337 | }else if (instruction == "cmp_a") { 338 | currentPos += 5; 339 | i += 2; 340 | line++; 341 | }else if (instruction == "cot0") { 342 | currentPos++; 343 | line++; 344 | }else if (instruction == "cot1") { 345 | currentPos++; 346 | line++; 347 | }/*else if (instruction == "cs_out0") { 348 | currentPos += 3; 349 | i += 2; 350 | line++; 351 | }else if (instruction == "cs_out1") { 352 | currentPos += 3; 353 | i += 2; 354 | line++; 355 | }else if (instruction == "clr_comm") { 356 | currentPos++; 357 | line++; 358 | }else if (instruction == "clr_vram") { 359 | currentPos++; 360 | line++; 361 | }*/else if (instruction == "gpu_str") { 362 | currentPos++; 363 | line++; 364 | }else if (instruction == "load0_8g") { 365 | currentPos += 3; 366 | i++; 367 | line++; 368 | }else if (instruction == "load1_8g") { 369 | currentPos += 3; 370 | i++; 371 | line++; 372 | }else if (instruction == "load0_16g") { 373 | currentPos += 3; 374 | i++; 375 | line++; 376 | }else if (instruction == "load1_16g") { 377 | currentPos += 3; 378 | i++; 379 | line++; 380 | }else if (instruction == "wrt0_16g") { 381 | currentPos += 3; 382 | i++; 383 | line++; 384 | }else if (instruction == "wrt1_16g") { 385 | currentPos += 3; 386 | i++; 387 | line++; 388 | }else if (instruction == "wrt0_8g") { 389 | currentPos += 3; 390 | i++; 391 | line++; 392 | }else if (instruction == "wrt1_8g") { 393 | currentPos += 3; 394 | i++; 395 | line++; 396 | }else if (instruction == "wait") { 397 | currentPos += 2; 398 | i++; 399 | line++; 400 | }else if(instruction == "stop") { 401 | currentPos++; 402 | line++; 403 | }else{ 404 | if (instruction.back() == ':') { 405 | std::string tmp = instruction; 406 | tmp.erase(tmp.end() - 1); 407 | jumpNames.push_back(tmp); 408 | jumpPositions.push_back(currentPos); 409 | line++; 410 | }else{ 411 | std::cout << "Unknown instruction >" << instruction << "< at line " << line << '\n'; 412 | std::cout << '\n'; 413 | std::cout << lines[line] << '\n'; 414 | std::cout << "^" << '\n'; 415 | std::cout << '\n'; 416 | std::cout << "Compilation terminated." << '\n'; 417 | cpu.ram.Clear(); 418 | break; 419 | } 420 | } 421 | 422 | } 423 | 424 | } 425 | 426 | currentPos = 0; 427 | additionalMemory = 0; 428 | 429 | for (unsigned int i = 0; i < code.size(); i++) { 430 | 431 | std::string instruction = code[i]; 432 | 433 | if(instruction == "data_s") { 434 | dataM = true; 435 | i++; 436 | line++; 437 | instruction = code[i]; 438 | } 439 | 440 | if(instruction == "data_e") { 441 | dataM = false; 442 | currentPos += additionalMemory; 443 | cpu.programCounter = currentPos; 444 | i++; 445 | line++; 446 | instruction = code[i]; 447 | } 448 | 449 | if (instruction == "inter_s") { 450 | interM = true; 451 | cpu.interPos = currentPos; 452 | i++; 453 | line++; 454 | instruction = code[i]; 455 | } 456 | 457 | if (instruction == "inter_e") { 458 | interM = false; 459 | cpu.ram.memory[currentPos++] = 30; 460 | cpu.interTartgetPos = currentPos; 461 | cpu.ram.memory[currentPos++] = 0; 462 | cpu.ram.memory[currentPos++] = 0; 463 | cpu.programCounter = currentPos; 464 | i++; 465 | line++; 466 | instruction = code[i]; 467 | } 468 | 469 | if (dataM == true && interM == false) { 470 | if (instruction == "u8") { 471 | std::string arg1 = code[i + 1]; 472 | std::string arg2 = code[i + 2]; 473 | 474 | vars.push_back(arg1); 475 | int Arg2 = std::stoi(arg2); 476 | varValues.push_back(additionalMemory); 477 | 478 | cpu.ram.memory[additionalMemory++] = (byte)Arg2; 479 | i += 2; 480 | line++; 481 | }else if (instruction == "u16") { 482 | std::string arg1 = code[i + 1]; 483 | std::string arg2 = code[i + 2]; 484 | 485 | vars.push_back(arg1); 486 | int Arg2 = std::stoi(arg2); 487 | varValues.push_back(additionalMemory); 488 | 489 | byte b1, b2, b3; 490 | convertByte(Arg2, b1, b2, b3); 491 | cpu.ram.memory[additionalMemory++] = b1; 492 | cpu.ram.memory[additionalMemory++] = b2; 493 | i += 2; 494 | line++; 495 | }else if (instruction == "u24") { 496 | std::string arg1 = code[i + 1]; 497 | std::string arg2 = code[i + 2]; 498 | 499 | vars.push_back(arg1); 500 | int Arg2 = std::stoi(arg2); 501 | varValues.push_back(additionalMemory); 502 | 503 | byte b1, b2, b3; 504 | convertByte(Arg2, b1, b2, b3); 505 | cpu.ram.memory[additionalMemory++] = b1; 506 | cpu.ram.memory[additionalMemory++] = b2; 507 | cpu.ram.memory[additionalMemory++] = b3; 508 | i += 2; 509 | line++; 510 | }else if(instruction == "u8a") { 511 | std::string arg1 = code[i + 1]; 512 | std::string arg2 = code[i + 2]; 513 | 514 | vars.push_back(arg1); 515 | int Arg2 = std::stoi(arg2); 516 | varValues.push_back(additionalMemory); 517 | 518 | for (int j = 0; j < Arg2; j++) { 519 | int element; 520 | checkArgType(element, code[i + 3 + j], cpu, vars, varValues); 521 | cpu.ram.memory[additionalMemory++] = (byte)element; 522 | } 523 | 524 | i += (2 + Arg2); 525 | line++; 526 | }else if(instruction == "u16a") { 527 | std::string arg1 = code[i + 1]; 528 | std::string arg2 = code[i + 2]; 529 | 530 | vars.push_back(arg1); 531 | int Arg2 = std::stoi(arg2); 532 | varValues.push_back(additionalMemory); 533 | 534 | for (int j = 0; j < Arg2; j++) { 535 | int element; 536 | checkArgType(element, code[i + 3 + j], cpu, vars, varValues); 537 | byte b1, b2, b3; 538 | convertByte(element, b1, b2, b3); 539 | cpu.ram.memory[additionalMemory++] = b1; 540 | cpu.ram.memory[additionalMemory++] = b2; 541 | } 542 | 543 | i += 2 + Arg2; 544 | line++; 545 | }else if(instruction == "u24a") { 546 | std::string arg1 = code[i + 1]; 547 | std::string arg2 = code[i + 2]; 548 | 549 | vars.push_back(arg1); 550 | int Arg2 = std::stoi(arg2); 551 | varValues.push_back(additionalMemory); 552 | 553 | for (int j = 0; j < Arg2; j++) { 554 | int element; 555 | checkArgType(element, code[i + 3 + j], cpu, vars, varValues); 556 | byte b1, b2, b3; 557 | convertByte(element, b1, b2, b3); 558 | cpu.ram.memory[additionalMemory++] = b1; 559 | cpu.ram.memory[additionalMemory++] = b2; 560 | cpu.ram.memory[additionalMemory++] = b3; 561 | } 562 | 563 | i += 2 + Arg2; 564 | line++; 565 | }else if (instruction == "g8") { 566 | std::string arg1 = code[i + 1]; 567 | std::string arg2 = code[i + 2]; 568 | 569 | vNames.push_back(arg1); 570 | int Arg2 = std::stoi(arg2); 571 | vValues.push_back(GadditionalMemory); 572 | 573 | cpu.gpu.vRam.memory[GadditionalMemory++] = (byte)Arg2; 574 | i += 2; 575 | line++; 576 | }else if (instruction == "g16") { 577 | std::string arg1 = code[i + 1]; 578 | std::string arg2 = code[i + 2]; 579 | 580 | vNames.push_back(arg1); 581 | int Arg2 = std::stoi(arg2); 582 | vValues.push_back(GadditionalMemory); 583 | 584 | byte b1, b2, b3; 585 | convertByte(Arg2, b1, b2, b3); 586 | cpu.gpu.vRam.memory[GadditionalMemory++] = b1; 587 | cpu.gpu.vRam.memory[GadditionalMemory++] = b2; 588 | i += 2; 589 | line++; 590 | }else { 591 | std::cout << "Unknown instruction >" << instruction << "< at line " << line << '\n'; 592 | std::cout << '\n'; 593 | std::cout << lines[line] << '\n'; 594 | std::cout << "^" << '\n'; 595 | std::cout << '\n'; 596 | std::cout << "Compilation terminated." << '\n'; 597 | cpu.ram.Clear(); 598 | cpu.gpu.vRam.Clear(); 599 | break; 600 | } 601 | }else if (dataM == false) { 602 | if (instruction == "load0_8") { 603 | std::string arg1 = code[i + 1]; 604 | 605 | cpu.ram.memory[currentPos++] = 5; 606 | 607 | int Arg1; 608 | checkArgType(Arg1, arg1, cpu, vars, varValues); 609 | 610 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 611 | 612 | byte b1, b2, b3; 613 | convertByte(Arg1, b1, b2, b3); 614 | cpu.ram.memory[currentPos++] = b1; 615 | cpu.ram.memory[currentPos++] = b2; 616 | 617 | i++; 618 | line++; 619 | }else if (instruction == "load1_8") { 620 | std::string arg1 = code[i + 1]; 621 | 622 | cpu.ram.memory[currentPos++] = 6; 623 | 624 | int Arg1; 625 | checkArgType(Arg1, arg1, cpu, vars, varValues); 626 | 627 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 628 | 629 | byte b1, b2, b3; 630 | convertByte(Arg1, b1, b2, b3); 631 | cpu.ram.memory[currentPos++] = b1; 632 | cpu.ram.memory[currentPos++] = b2; 633 | 634 | i++; 635 | line++; 636 | }else if (instruction == "load0_16") { 637 | std::string arg1 = code[i + 1]; 638 | 639 | cpu.ram.memory[currentPos++] = 3; 640 | 641 | int Arg1; 642 | checkArgType(Arg1, arg1, cpu, vars, varValues); 643 | 644 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 645 | 646 | byte b1, b2, b3; 647 | convertByte(Arg1, b1, b2, b3); 648 | cpu.ram.memory[currentPos++] = b1; 649 | cpu.ram.memory[currentPos++] = b2; 650 | 651 | i++; 652 | line++; 653 | }else if (instruction == "load1_16") { 654 | std::string arg1 = code[i + 1]; 655 | 656 | cpu.ram.memory[currentPos++] = 4; 657 | 658 | int Arg1; 659 | checkArgType(Arg1, arg1, cpu, vars, varValues); 660 | 661 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 662 | 663 | byte b1, b2, b3; 664 | convertByte(Arg1, b1, b2, b3); 665 | cpu.ram.memory[currentPos++] = b1; 666 | cpu.ram.memory[currentPos++] = b2; 667 | 668 | i++; 669 | line++; 670 | }else if (instruction == "load0_24") { 671 | std::string arg1 = code[i + 1]; 672 | 673 | cpu.ram.memory[currentPos++] = 1; 674 | 675 | int Arg1; 676 | checkArgType(Arg1, arg1, cpu, vars, varValues); 677 | 678 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 679 | 680 | byte b1, b2, b3; 681 | convertByte(Arg1, b1, b2, b3); 682 | cpu.ram.memory[currentPos++] = b1; 683 | cpu.ram.memory[currentPos++] = b2; 684 | 685 | i++; 686 | line++; 687 | }else if (instruction == "load1_24") { 688 | std::string arg1 = code[i + 1]; 689 | 690 | cpu.ram.memory[currentPos++] = 2; 691 | 692 | int Arg1; 693 | checkArgType(Arg1, arg1, cpu, vars, varValues); 694 | 695 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 696 | 697 | byte b1, b2, b3; 698 | convertByte(Arg1, b1, b2, b3); 699 | cpu.ram.memory[currentPos++] = b1; 700 | cpu.ram.memory[currentPos++] = b2; 701 | 702 | i++; 703 | line++; 704 | }else if (instruction == "load0_8a") { 705 | std::string arg1 = code[i + 1]; 706 | std::string arg2 = code[i + 2]; 707 | 708 | cpu.ram.memory[currentPos++] = 46; 709 | 710 | int Arg1; 711 | checkArgType(Arg1, arg1, cpu, vars, varValues); 712 | 713 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 714 | 715 | int Arg2; 716 | checkArgType(Arg2, arg2, cpu, vars, varValues); 717 | 718 | byte b1, b2, b3; 719 | convertByte(Arg1, b1, b2, b3); 720 | cpu.ram.memory[currentPos++] = b1; 721 | cpu.ram.memory[currentPos++] = b2; 722 | 723 | byte b4, b5, b6; 724 | convertByte(Arg2, b4, b5, b6); 725 | cpu.ram.memory[currentPos++] = b4; 726 | cpu.ram.memory[currentPos++] = b5; 727 | 728 | i += 2; 729 | line++; 730 | }else if (instruction == "load1_8a") { 731 | std::string arg1 = code[i + 1]; 732 | std::string arg2 = code[i + 2]; 733 | 734 | cpu.ram.memory[currentPos++] = 47; 735 | 736 | int Arg1; 737 | checkArgType(Arg1, arg1, cpu, vars, varValues); 738 | 739 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 740 | 741 | int Arg2; 742 | checkArgType(Arg2, arg2, cpu, vars, varValues); 743 | 744 | byte b1, b2, b3; 745 | convertByte(Arg1, b1, b2, b3); 746 | cpu.ram.memory[currentPos++] = b1; 747 | cpu.ram.memory[currentPos++] = b2; 748 | 749 | byte b4, b5, b6; 750 | convertByte(Arg2, b4, b5, b6); 751 | cpu.ram.memory[currentPos++] = b4; 752 | cpu.ram.memory[currentPos++] = b5; 753 | 754 | i += 2; 755 | line++; 756 | }else if (instruction == "load0_16a") { 757 | std::string arg1 = code[i + 1]; 758 | std::string arg2 = code[i + 2]; 759 | 760 | cpu.ram.memory[currentPos++] = 44; 761 | 762 | int Arg1; 763 | checkArgType(Arg1, arg1, cpu, vars, varValues); 764 | 765 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 766 | 767 | int Arg2; 768 | checkArgType(Arg2, arg2, cpu, vars, varValues); 769 | 770 | byte b1, b2, b3; 771 | convertByte(Arg1, b1, b2, b3); 772 | cpu.ram.memory[currentPos++] = b1; 773 | cpu.ram.memory[currentPos++] = b2; 774 | 775 | byte b4, b5, b6; 776 | convertByte(Arg2, b4, b5, b6); 777 | cpu.ram.memory[currentPos++] = b4; 778 | cpu.ram.memory[currentPos++] = b5; 779 | 780 | i += 2; 781 | line++; 782 | }else if (instruction == "load1_16a") { 783 | std::string arg1 = code[i + 1]; 784 | std::string arg2 = code[i + 2]; 785 | 786 | cpu.ram.memory[currentPos++] = 45; 787 | 788 | int Arg1; 789 | checkArgType(Arg1, arg1, cpu, vars, varValues); 790 | 791 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 792 | 793 | int Arg2; 794 | checkArgType(Arg2, arg2, cpu, vars, varValues); 795 | 796 | byte b1, b2, b3; 797 | convertByte(Arg1, b1, b2, b3); 798 | cpu.ram.memory[currentPos++] = b1; 799 | cpu.ram.memory[currentPos++] = b2; 800 | 801 | byte b4, b5, b6; 802 | convertByte(Arg2, b4, b5, b6); 803 | cpu.ram.memory[currentPos++] = b4; 804 | cpu.ram.memory[currentPos++] = b5; 805 | 806 | i += 2; 807 | line++; 808 | }else if (instruction == "load0_24a") { 809 | std::string arg1 = code[i + 1]; 810 | std::string arg2 = code[i + 2]; 811 | 812 | cpu.ram.memory[currentPos++] = 42; 813 | 814 | int Arg1; 815 | checkArgType(Arg1, arg1, cpu, vars, varValues); 816 | 817 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 818 | 819 | int Arg2; 820 | checkArgType(Arg2, arg2, cpu, vars, varValues); 821 | 822 | byte b1, b2, b3; 823 | convertByte(Arg1, b1, b2, b3); 824 | cpu.ram.memory[currentPos++] = b1; 825 | cpu.ram.memory[currentPos++] = b2; 826 | 827 | byte b4, b5, b6; 828 | convertByte(Arg2, b4, b5, b6); 829 | cpu.ram.memory[currentPos++] = b4; 830 | cpu.ram.memory[currentPos++] = b5; 831 | 832 | i += 2; 833 | line++; 834 | }else if (instruction == "load1_24a") { 835 | std::string arg1 = code[i + 1]; 836 | std::string arg2 = code[i + 2]; 837 | 838 | cpu.ram.memory[currentPos++] = 43; 839 | 840 | int Arg1; 841 | checkArgType(Arg1, arg1, cpu, vars, varValues); 842 | 843 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 844 | 845 | int Arg2; 846 | checkArgType(Arg2, arg2, cpu, vars, varValues); 847 | 848 | byte b1, b2, b3; 849 | convertByte(Arg1, b1, b2, b3); 850 | cpu.ram.memory[currentPos++] = b1; 851 | cpu.ram.memory[currentPos++] = b2; 852 | 853 | byte b4, b5, b6; 854 | convertByte(Arg2, b4, b5, b6); 855 | cpu.ram.memory[currentPos++] = b4; 856 | cpu.ram.memory[currentPos++] = b5; 857 | 858 | i += 2; 859 | line++; 860 | }else if (instruction == "clr0") { 861 | cpu.ram.memory[currentPos++] = 4; 862 | line++; 863 | }else if (instruction == "clr1") { 864 | cpu.ram.memory[currentPos++] = 5; 865 | line++; 866 | }else if (instruction == "wrt0_24") { 867 | std::string arg1 = code[i + 1]; 868 | 869 | cpu.ram.memory[currentPos++] = 7; 870 | 871 | int Arg1; 872 | checkArgType(Arg1, arg1, cpu, vars, varValues); 873 | 874 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 875 | 876 | byte b1, b2, b3; 877 | convertByte(Arg1, b1, b2, b3); 878 | cpu.ram.memory[currentPos++] = b1; 879 | cpu.ram.memory[currentPos++] = b2; 880 | 881 | i++; 882 | line++; 883 | }else if (instruction == "wrt1_24") { 884 | std::string arg1 = code[i + 1]; 885 | 886 | cpu.ram.memory[currentPos++] = 8; 887 | 888 | int Arg1; 889 | checkArgType(Arg1, arg1, cpu, vars, varValues); 890 | 891 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 892 | 893 | byte b1, b2, b3; 894 | convertByte(Arg1, b1, b2, b3); 895 | cpu.ram.memory[currentPos++] = b1; 896 | cpu.ram.memory[currentPos++] = b2; 897 | 898 | i++; 899 | line++; 900 | }else if (instruction == "wrt0_16") { 901 | std::string arg1 = code[i + 1]; 902 | 903 | cpu.ram.memory[currentPos++] = 9; 904 | 905 | int Arg1; 906 | checkArgType(Arg1, arg1, cpu, vars, varValues); 907 | 908 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 909 | 910 | byte b1, b2, b3; 911 | convertByte(Arg1, b1, b2, b3); 912 | cpu.ram.memory[currentPos++] = b1; 913 | cpu.ram.memory[currentPos++] = b2; 914 | 915 | i++; 916 | line++; 917 | }else if (instruction == "wrt1_16") { 918 | std::string arg1 = code[i + 1]; 919 | 920 | cpu.ram.memory[currentPos++] = 10; 921 | 922 | int Arg1; 923 | checkArgType(Arg1, arg1, cpu, vars, varValues); 924 | 925 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 926 | 927 | byte b1, b2, b3; 928 | convertByte(Arg1, b1, b2, b3); 929 | cpu.ram.memory[currentPos++] = b1; 930 | cpu.ram.memory[currentPos++] = b2; 931 | 932 | i++; 933 | line++; 934 | }else if (instruction == "wrt0_8") { 935 | std::string arg1 = code[i + 1]; 936 | 937 | cpu.ram.memory[currentPos++] = 11; 938 | 939 | int Arg1; 940 | checkArgType(Arg1, arg1, cpu, vars, varValues); 941 | 942 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 943 | 944 | byte b1, b2, b3; 945 | convertByte(Arg1, b1, b2, b3); 946 | cpu.ram.memory[currentPos++] = b1; 947 | cpu.ram.memory[currentPos++] = b2; 948 | 949 | i++; 950 | line++; 951 | }else if (instruction == "wrt1_8") { 952 | std::string arg1 = code[i + 1]; 953 | 954 | cpu.ram.memory[currentPos++] = 12; 955 | 956 | int Arg1; 957 | checkArgType(Arg1, arg1, cpu, vars, varValues); 958 | 959 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 960 | 961 | byte b1, b2, b3; 962 | convertByte(Arg1, b1, b2, b3); 963 | cpu.ram.memory[currentPos++] = b1; 964 | cpu.ram.memory[currentPos++] = b2; 965 | 966 | i++; 967 | line++; 968 | }else if (instruction == "wrt0_24a") { 969 | std::string arg1 = code[i + 1]; 970 | std::string arg2 = code[i + 2]; 971 | 972 | cpu.ram.memory[currentPos++] = 48; 973 | 974 | int Arg1; 975 | checkArgType(Arg1, arg1, cpu, vars, varValues); 976 | 977 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 978 | 979 | int Arg2; 980 | checkArgType(Arg2, arg2, cpu, vars, varValues); 981 | 982 | byte b1, b2, b3; 983 | convertByte(Arg1, b1, b2, b3); 984 | cpu.ram.memory[currentPos++] = b1; 985 | cpu.ram.memory[currentPos++] = b2; 986 | 987 | byte b4, b5, b6; 988 | convertByte(Arg2, b4, b5, b6); 989 | cpu.ram.memory[currentPos++] = b4; 990 | cpu.ram.memory[currentPos++] = b5; 991 | 992 | i += 2; 993 | line++; 994 | }else if (instruction == "wrt1_24a") { 995 | std::string arg1 = code[i + 1]; 996 | std::string arg2 = code[i + 2]; 997 | 998 | cpu.ram.memory[currentPos++] = 49; 999 | 1000 | int Arg1; 1001 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1002 | 1003 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1004 | 1005 | int Arg2; 1006 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1007 | 1008 | byte b1, b2, b3; 1009 | convertByte(Arg1, b1, b2, b3); 1010 | cpu.ram.memory[currentPos++] = b1; 1011 | cpu.ram.memory[currentPos++] = b2; 1012 | 1013 | byte b4, b5, b6; 1014 | convertByte(Arg2, b4, b5, b6); 1015 | cpu.ram.memory[currentPos++] = b4; 1016 | cpu.ram.memory[currentPos++] = b5; 1017 | 1018 | i += 2; 1019 | line++; 1020 | }else if (instruction == "wrt0_16a") { 1021 | std::string arg1 = code[i + 1]; 1022 | std::string arg2 = code[i + 2]; 1023 | 1024 | cpu.ram.memory[currentPos++] = 50; 1025 | 1026 | int Arg1; 1027 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1028 | 1029 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1030 | 1031 | int Arg2; 1032 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1033 | 1034 | byte b1, b2, b3; 1035 | convertByte(Arg1, b1, b2, b3); 1036 | cpu.ram.memory[currentPos++] = b1; 1037 | cpu.ram.memory[currentPos++] = b2; 1038 | 1039 | byte b4, b5, b6; 1040 | convertByte(Arg2, b4, b5, b6); 1041 | cpu.ram.memory[currentPos++] = b4; 1042 | cpu.ram.memory[currentPos++] = b5; 1043 | 1044 | i += 2; 1045 | line++; 1046 | }else if (instruction == "wrt1_16a") { 1047 | std::string arg1 = code[i + 1]; 1048 | std::string arg2 = code[i + 2]; 1049 | 1050 | cpu.ram.memory[currentPos++] = 51; 1051 | 1052 | int Arg1; 1053 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1054 | 1055 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1056 | 1057 | int Arg2; 1058 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1059 | 1060 | byte b1, b2, b3; 1061 | convertByte(Arg1, b1, b2, b3); 1062 | cpu.ram.memory[currentPos++] = b1; 1063 | cpu.ram.memory[currentPos++] = b2; 1064 | 1065 | byte b4, b5, b6; 1066 | convertByte(Arg2, b4, b5, b6); 1067 | cpu.ram.memory[currentPos++] = b4; 1068 | cpu.ram.memory[currentPos++] = b5; 1069 | 1070 | i += 2; 1071 | line++; 1072 | }else if (instruction == "wrt0_8a") { 1073 | std::string arg1 = code[i + 1]; 1074 | std::string arg2 = code[i + 2]; 1075 | 1076 | cpu.ram.memory[currentPos++] = 52; 1077 | 1078 | int Arg1; 1079 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1080 | 1081 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1082 | 1083 | int Arg2; 1084 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1085 | 1086 | byte b1, b2, b3; 1087 | convertByte(Arg1, b1, b2, b3); 1088 | cpu.ram.memory[currentPos++] = b1; 1089 | cpu.ram.memory[currentPos++] = b2; 1090 | 1091 | byte b4, b5, b6; 1092 | convertByte(Arg2, b4, b5, b6); 1093 | cpu.ram.memory[currentPos++] = b4; 1094 | cpu.ram.memory[currentPos++] = b5; 1095 | 1096 | i += 2; 1097 | line++; 1098 | }else if (instruction == "wrt1_8a") { 1099 | std::string arg1 = code[i + 1]; 1100 | std::string arg2 = code[i + 2]; 1101 | 1102 | cpu.ram.memory[currentPos++] = 53; 1103 | 1104 | int Arg1; 1105 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1106 | 1107 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1108 | 1109 | int Arg2; 1110 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1111 | 1112 | byte b1, b2, b3; 1113 | convertByte(Arg1, b1, b2, b3); 1114 | cpu.ram.memory[currentPos++] = b1; 1115 | cpu.ram.memory[currentPos++] = b2; 1116 | 1117 | byte b4, b5, b6; 1118 | convertByte(Arg2, b4, b5, b6); 1119 | cpu.ram.memory[currentPos++] = b4; 1120 | cpu.ram.memory[currentPos++] = b5; 1121 | 1122 | i += 2; 1123 | line++; 1124 | }else if (instruction == "wrtR_H") { 1125 | cpu.ram.memory[currentPos++] = 15; 1126 | line++; 1127 | }else if (instruction == "wrtH_R") { 1128 | cpu.ram.memory[currentPos++] = 16; 1129 | line++; 1130 | }else if (instruction == "sum") { 1131 | cpu.ram.memory[currentPos++] = 20; 1132 | line++; 1133 | }else if (instruction == "sub") { 1134 | cpu.ram.memory[currentPos++] = 21; 1135 | line++; 1136 | }else if (instruction == "mlt") { 1137 | cpu.ram.memory[currentPos++] = 22; 1138 | line++; 1139 | }else if (instruction == "div") { 1140 | cpu.ram.memory[currentPos++] = 23; 1141 | line++; 1142 | }else if (instruction == "reg0_b") { 1143 | cpu.ram.memory[currentPos++] = 24; 1144 | line++; 1145 | }else if (instruction == "reg0_be") { 1146 | cpu.ram.memory[currentPos++] = 25; 1147 | line++; 1148 | }else if (instruction == "reg1_b") { 1149 | cpu.ram.memory[currentPos++] = 26; 1150 | line++; 1151 | }else if (instruction == "reg1_be") { 1152 | cpu.ram.memory[currentPos++] = 27; 1153 | line++; 1154 | }else if (instruction == "reg_eql") { 1155 | cpu.ram.memory[currentPos++] = 28; 1156 | line++; 1157 | }else if (instruction == "reg_dif") { 1158 | cpu.ram.memory[currentPos++] = 29; 1159 | line++; 1160 | }else if (instruction == "jmp") { 1161 | std::string arg1 = code[i + 1]; 1162 | int pos; 1163 | 1164 | cpu.ram.memory[currentPos++] = 30; 1165 | 1166 | checkJmpPos(pos, arg1, jumpNames, jumpPositions); 1167 | 1168 | byte b1, b2, b3; 1169 | convertByte(pos, b1, b2, b3); 1170 | cpu.ram.memory[currentPos++] = b1; 1171 | cpu.ram.memory[currentPos++] = b2; 1172 | 1173 | i++; 1174 | line++; 1175 | }else if (instruction == "cmp") { 1176 | std::string arg1 = code[i + 1]; 1177 | std::string arg2 = code[i + 2]; 1178 | 1179 | cpu.ram.memory[currentPos++] = 31; 1180 | 1181 | int Arg1; 1182 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1183 | 1184 | int pos; 1185 | 1186 | checkJmpPos(pos, arg2, jumpNames, jumpPositions); 1187 | 1188 | cpu.ram.memory[currentPos++] = (byte)Arg1; 1189 | byte b1, b2, b3; 1190 | convertByte(pos, b1, b2, b3); 1191 | cpu.ram.memory[currentPos++] = b1; 1192 | cpu.ram.memory[currentPos++] = b2; 1193 | 1194 | i += 2; 1195 | line++; 1196 | }else if (instruction == "cmp_a") { 1197 | std::string arg1 = code[i + 1]; 1198 | std::string arg2 = code[i + 2]; 1199 | 1200 | cpu.ram.memory[currentPos++] = 54; 1201 | 1202 | int Arg1; 1203 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1204 | 1205 | int Arg2; 1206 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1207 | 1208 | byte b1, b2, b3; 1209 | convertByte(Arg1, b1, b2, b3); 1210 | cpu.ram.memory[currentPos++] = b1; 1211 | cpu.ram.memory[currentPos++] = b2; 1212 | 1213 | byte b4, b5, b6; 1214 | convertByte(Arg2, b4, b5, b6); 1215 | cpu.ram.memory[currentPos++] = b4; 1216 | cpu.ram.memory[currentPos++] = b5; 1217 | 1218 | i += 2; 1219 | line++; 1220 | }else if (instruction == "cot0") { 1221 | cpu.ram.memory[currentPos++] = 40; 1222 | line++; 1223 | }else if (instruction == "cot1") { 1224 | cpu.ram.memory[currentPos++] = 41; 1225 | line++; 1226 | }else if (instruction == "cs_out0") { 1227 | cpu.ram.memory[currentPos++] = 80; 1228 | 1229 | std::string arg1 = code[i + 1]; 1230 | std::string arg2 = code[i + 2]; 1231 | 1232 | int Arg1; 1233 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1234 | 1235 | int Arg2; 1236 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1237 | 1238 | cpu.ram.memory[currentPos++] = (byte)Arg1; 1239 | cpu.ram.memory[currentPos++] = (byte)Arg2; 1240 | 1241 | i += 2; 1242 | line++; 1243 | }else if (instruction == "cs_out1") { 1244 | cpu.ram.memory[currentPos++] = 81; 1245 | 1246 | std::string arg1 = code[i + 1]; 1247 | std::string arg2 = code[i + 2]; 1248 | 1249 | int Arg1; 1250 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1251 | 1252 | int Arg2; 1253 | checkArgType(Arg2, arg2, cpu, vars, varValues); 1254 | 1255 | cpu.ram.memory[currentPos++] = (byte)Arg1; 1256 | cpu.ram.memory[currentPos++] = (byte)Arg2; 1257 | 1258 | i += 2; 1259 | line++; 1260 | }else if (instruction == "clr_comm") { 1261 | cpu.ram.memory[currentPos++] = 82; 1262 | line++; 1263 | }else if (instruction == "clr_vram") { 1264 | cpu.ram.memory[currentPos++] = 83; 1265 | line++; 1266 | }if (instruction == "load0_8g") { 1267 | std::string arg1 = code[i + 1]; 1268 | 1269 | cpu.ram.memory[currentPos++] = 87; 1270 | 1271 | int Arg1; 1272 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1273 | 1274 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1275 | 1276 | byte b1, b2, b3; 1277 | convertByte(Arg1, b1, b2, b3); 1278 | cpu.ram.memory[currentPos++] = b1; 1279 | cpu.ram.memory[currentPos++] = b2; 1280 | 1281 | i++; 1282 | line++; 1283 | }else if (instruction == "load1_8g") { 1284 | std::string arg1 = code[i + 1]; 1285 | 1286 | cpu.ram.memory[currentPos++] = 88; 1287 | 1288 | int Arg1; 1289 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1290 | 1291 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1292 | 1293 | byte b1, b2, b3; 1294 | convertByte(Arg1, b1, b2, b3); 1295 | cpu.ram.memory[currentPos++] = b1; 1296 | cpu.ram.memory[currentPos++] = b2; 1297 | 1298 | i++; 1299 | line++; 1300 | }else if (instruction == "load0_16g") { 1301 | std::string arg1 = code[i + 1]; 1302 | 1303 | cpu.ram.memory[currentPos++] = 85; 1304 | 1305 | int Arg1; 1306 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1307 | 1308 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1309 | 1310 | byte b1, b2, b3; 1311 | convertByte(Arg1, b1, b2, b3); 1312 | cpu.ram.memory[currentPos++] = b1; 1313 | cpu.ram.memory[currentPos++] = b2; 1314 | 1315 | i++; 1316 | line++; 1317 | }else if (instruction == "load1_16g") { 1318 | std::string arg1 = code[i + 1]; 1319 | 1320 | cpu.ram.memory[currentPos++] = 86; 1321 | 1322 | int Arg1; 1323 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1324 | 1325 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1326 | 1327 | byte b1, b2, b3; 1328 | convertByte(Arg1, b1, b2, b3); 1329 | cpu.ram.memory[currentPos++] = b1; 1330 | cpu.ram.memory[currentPos++] = b2; 1331 | 1332 | i++; 1333 | line++; 1334 | }else if (instruction == "wrt0_16g") { 1335 | std::string arg1 = code[i + 1]; 1336 | 1337 | cpu.ram.memory[currentPos++] = 89; 1338 | 1339 | int Arg1; 1340 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1341 | 1342 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1343 | 1344 | byte b1, b2, b3; 1345 | convertByte(Arg1, b1, b2, b3); 1346 | cpu.ram.memory[currentPos++] = b1; 1347 | cpu.ram.memory[currentPos++] = b2; 1348 | 1349 | i++; 1350 | line++; 1351 | }else if (instruction == "wrt1_16g") { 1352 | std::string arg1 = code[i + 1]; 1353 | 1354 | cpu.ram.memory[currentPos++] = 90; 1355 | 1356 | int Arg1; 1357 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1358 | 1359 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1360 | 1361 | byte b1, b2, b3; 1362 | convertByte(Arg1, b1, b2, b3); 1363 | cpu.ram.memory[currentPos++] = b1; 1364 | cpu.ram.memory[currentPos++] = b2; 1365 | 1366 | i++; 1367 | line++; 1368 | }else if (instruction == "wrt0_8g") { 1369 | std::string arg1 = code[i + 1]; 1370 | 1371 | cpu.ram.memory[currentPos++] = 91; 1372 | 1373 | int Arg1; 1374 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1375 | 1376 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1377 | 1378 | byte b1, b2, b3; 1379 | convertByte(Arg1, b1, b2, b3); 1380 | cpu.ram.memory[currentPos++] = b1; 1381 | cpu.ram.memory[currentPos++] = b2; 1382 | 1383 | i++; 1384 | line++; 1385 | }else if (instruction == "wrt1_8g") { 1386 | std::string arg1 = code[i + 1]; 1387 | 1388 | cpu.ram.memory[currentPos++] = 92; 1389 | 1390 | int Arg1; 1391 | checkArgType(Arg1, arg1, cpu, vNames, vValues); 1392 | 1393 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 1394 | 1395 | byte b1, b2, b3; 1396 | convertByte(Arg1, b1, b2, b3); 1397 | cpu.ram.memory[currentPos++] = b1; 1398 | cpu.ram.memory[currentPos++] = b2; 1399 | 1400 | i++; 1401 | line++; 1402 | }else if (instruction == "gpu_str") { 1403 | cpu.ram.memory[currentPos++] = 84; 1404 | line++; 1405 | }else if (instruction == "wait") { 1406 | cpu.ram.memory[currentPos++] = 32; 1407 | 1408 | std::string arg1 = code[i + 1]; 1409 | 1410 | int Arg1; 1411 | checkArgType(Arg1, arg1, cpu, vars, varValues); 1412 | 1413 | if(checkArgSize(Arg1, 1, instruction, i, 255) == true) { break; } 1414 | 1415 | cpu.ram.memory[currentPos++] = (byte)Arg1; 1416 | 1417 | i++; 1418 | line++; 1419 | }else if(instruction == "stop") { 1420 | cpu.ram.memory[currentPos++] = 17; 1421 | hasStop = true; 1422 | line++; 1423 | }else{ 1424 | if (instruction.back() == ':') { 1425 | line++; 1426 | }else{ 1427 | std::cout << "Unknown instruction >" << instruction << "< at line " << line << '\n'; 1428 | std::cout << '\n'; 1429 | std::cout << lines[line] << '\n'; 1430 | std::cout << "^" << '\n'; 1431 | std::cout << '\n'; 1432 | std::cout << "Compilation terminated." << '\n'; 1433 | cpu.ram.Clear(); 1434 | break; 1435 | } 1436 | } 1437 | 1438 | } 1439 | 1440 | } 1441 | 1442 | if (hasStop == false) { 1443 | std::cout << "Compilation terminated, no > stop < instruction found." << '\n'; 1444 | cpu.ram.Clear(); 1445 | } 1446 | 1447 | finalCP = GadditionalMemory; 1448 | 1449 | std::cout << "Program size is: " << currentPos << " bytes" << '\n'; 1450 | std::cout << '\n'; 1451 | } 1452 | } -------------------------------------------------------------------------------- /VirtualPCCpp/Assembly.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "CPU.h" 10 | 11 | typedef unsigned char byte; 12 | 13 | namespace Assembly { 14 | void Compile(std::vector& code, CPU& cpu, std::vector& vValues, std::vector& vNames, int& finalCP); 15 | void readFile(std::string path, std::vector& code); 16 | } -------------------------------------------------------------------------------- /VirtualPCCpp/CPU Documentation.txt: -------------------------------------------------------------------------------- 1 | --By Joco223-- 2 | 3 | This is the documentation of the vCPU (v standing for virtual) of the vPC project i am working on. Started working on it 17-09-2017. 4 | Link to the GitHub repostory: https://github.com/Joco223/VirtualPCCpp 5 | Last time updated: 15-12-2017. 6 | 7 | --I will be calling the cpu vCPU throughout the documentation since i don't have a proper name for it yet (Open for suggestions)-- 8 | 9 | vCPU has following specifications: 10 | -Direct access to RAM (Which it uses as its main memory) 11 | 12 | -Direct access to HDD (used for permanent data storage) 13 | -There is a sector size and number of sectors variable when creating the vCPU for making the HDD, it is only used for writing it to a 14 | file, doesn't affect writing and reading from the HDD, 15 | 16 | -One register for loading instructions into and executing them from it, registerOP. 17 | 18 | -Two registers for doing operations on, register0 and register1. 19 | 20 | -An instruction counter used for keeping track of the current instruction. 21 | 22 | -One register for storing the current interrupt value. (Values such as key code of the key pressed) 23 | 24 | -3 variables used for handling interrupts 25 | -It handles interrupts such as that, when Assembler compiles the program, it inserts the start of the interrupt code into one variable, 26 | inserts a >jmp< instruction at the end of the interrupt code. When an interrupt happens, the vCPU stores the current position where it 27 | left off and injects it into the built in >jmp< instruction at the end of interrupt code so it returns where it left off and continues 28 | on executing the program. 29 | 30 | -Current time variable that is used for counting number of operations to skip which is given by the wait isntruction. 31 | 32 | -A halt boolean which turns on when the vCPU tries to execute a command with value of 0 (no command), and it stops running. 33 | 34 | -Direct access to the vGPU. (Which is used for displaying characters (And soon more advanced stuff) onto the virtual screen) 35 | 36 | -Default RAM size is 64,000 bytes. 37 | 38 | -No signed number support or numbers with decimals yet. 39 | 40 | -Last byte in multy-byte numbers is the most significant one. 41 | 42 | -------------------------------------------------------------------------------------------------------------------------------------------------- 43 | 44 | The vCPU works on a cycle called each update, on each cycle it: 45 | 1. Loads the current instruction into registerOP. 46 | 2. Executes the loaded instruction. 47 | 3. Checks if an interrupt happened in that cycle. 48 | 49 | List of available instructions currently: 50 | 0. Halts the vCPU. 51 | 1. Loads a number of 3 bytes into register0 from the given memory adress from RAM. 52 | 2. Loads a number of 3 bytes into register1 from the given memory adress from RAM. 53 | 3. Loads a number of 2 bytes into register0 from the given memory adress from RAM. 54 | 4. Loads a number of 2 bytes into register1 from the given memory adress from RAM. 55 | 5. Loads a number of a single byte into register0 from the given memory adress from RAM. 56 | 6. Loads a number of a single byte into register1 from the given memory adress from RAM. 57 | 7. Writes a number of 3 bytes from register0 to the given memory adress in RAM. 58 | 8. Writes a number of 3 bytes from register1 to the given memory adress in RAM. 59 | 9. Writes a number of 2 bytes from register0 to the given memory adress in RAM. 60 | 10. Writes a number of 2 bytes from register1 to the given memory adress in RAM. 61 | 11. Writes a number of a single byte from register0 to the given memory adress in RAM. 62 | 12. Writes a number of a single byte from register1 to the given memory adress in RAM. 63 | 64 | 15. Copy a single byte from RAM to HDD from the given memory adress to the given memory adress. 65 | 16. Copy a single byte from HDD to RAM from the given memory adress to the given memory adress. 66 | ^ I am working on these and add more advanced ones later on. 67 | 17. Shuts-down the vPC and saves the HDD to the HDD.txt file. 68 | 69 | 20. Sums values stored in register0 and register 1 and stores the result in register0. 70 | 21. Subtracts values stored in register0 and register1 and stores the result in register0. 71 | 22. Multiplies value stored in register0 by the value in register1 and stores the result in register0. 72 | 23. Divides value stored in register0 by the value in register1 and stores the result in register0. (Integer division) 73 | 24. Checks if the value stored in register0 is greater than the value stored in register1 and stores the result in register0. 74 | 25. Checks if the value stored in register0 is greater or equal to the value stored in register1 and stores the result in register0. 75 | 26. Checks if the value stored in register0 is smaller than the value stored in register1 and stores the result in register0. 76 | 27. Checks if the value stored in tegister0 is smaller or equal to the value stored in register1 and stores the result in register0. 77 | 28. Checks if register0 and register1 store the same value. 78 | 29. Checks if register0 and register1 store different values. 79 | 30. Sets program counter to the given value. 80 | 31. Compares value in register0 to the given value and continues if result is true, sets program counter to the given value if result is false. 81 | 32. Pauses the vCPU from incrementing program counter by the given time. (Number of cycles) 82 | 83 | 40. Prints to console (CMD) current value stored in register0. 84 | 41. Prints to console (CMD) current value stored in register1. 85 | 86 | 42. Loads a number of 3 bytes into regiser0 from the given memory adress from RAM with a given offset. 87 | 43. Loads a number of 3 bytes into regiser1 from the given memory adress from RAM with a given offset. 88 | 44. Loads a number of 2 bytes into regiser0 from the given memory adress from RAM with a given offset. 89 | 45. Loads a number of 2 bytes into regiser1 from the given memory adress from RAM with a given offset. 90 | 46. Loads a number of a single byte into regiser0 from the given memory adress from RAM with a given offset. 91 | 47. Loads a number of a single byte into regiser1 from the given memory adress from RAM with a given offset. 92 | 48. Writes a number of 3 bytes from register0 to the given memory adress in RAM with a given offset. 93 | 49. Writes a number of 3 bytes from register1 to the given memory adress in RAM with a given offset. 94 | 50. Writes a number of 2 bytes from register0 to the given memory adress in RAM with a given offset. 95 | 51. Writes a number of 2 bytes from register1 to the given memory adress in RAM with a given offset. 96 | 52. Writes a number of a single byte from register0 to the given memory adress in RAM with a given offset. 97 | 53. Writes a number of a single byte from register1 to the given memory adress in RAM with a given offset. 98 | 54. Compares if two sets of values are the same. Both sets memory adress is given and their size. Result is stored in register0. 99 | 100 | 80. Displays a character at the given X and Y coordinates on the vScreen. Character displayed is used as character code value stored in register0. 101 | 81. Displays a character at the given X and Y coordinates on the vScreen. Character displayed is used as character code value stored in register1. 102 | 103 | 82. Clears GPU command buffer. 104 | 83. Clears GPU VRAM. 105 | 106 | -------------------------------------------------------------------------------------------------------------------------------------------------- 107 | 108 | Character codes: 109 | 0: 0, -: 21, C: 42, X: 63, p: 84 110 | 1: 1, ,: 22, D: 43, Y: 64, q: 85 111 | 2: 2, .: 23, E: 44, Z: 65, r: 86 112 | 3: 3, /: 24, F: 45, _: 66, s: 87 113 | 4: 4, \: 25, G: 46, : 67, t: 88 114 | 5: 5, :: 26, H: 47, @: 68, u: 89 115 | 6: 6, ;: 27, I: 48, a: 69, v: 90 116 | 7: 7, <: 28, J: 49, b: 70, w: 91 117 | 8: 8, >: 29, K: 50, c: 71, x: 92 118 | 9: 9, =: 30, L: 51, d: 72, y: 93 119 | !: 10, ?: 31, M: 52, e: 73, z: 94 120 | ": 11, [: 32, N: 53, f: 74, 121 | #: 12, ]: 33, O: 54, g: 75, 122 | $: 13, {: 34, P: 55, h: 76, 123 | %: 14, }: 35, Q: 56, i: 77, 124 | &: 15, `: 36, R: 57, j: 78, 125 | ': 16, ^: 37, S: 58, k: 79, 126 | (: 17, |: 38, T: 59, l: 80, 127 | ): 18, ~: 39, U: 60, m: 81, 128 | *: 19, A: 40, V: 61, n: 82, 129 | +: 20, B: 41, W: 62, o: 83, -------------------------------------------------------------------------------- /VirtualPCCpp/CPU.cpp: -------------------------------------------------------------------------------- 1 | #include "CPU.h" 2 | 3 | CPU::CPU(int sectorSize_, int numSectors_, Memory& ram_, Memory& hdd_, GPU& gpu_) 4 | : 5 | registerOP(0), 6 | register0(0), 7 | register1(0), 8 | programCounter(0), 9 | interruptRegister(0), 10 | currentTime(0), 11 | ram(ram_), 12 | halt(false), 13 | interrupted(false), 14 | sectorSize(sectorSize_), 15 | numSectors(numSectors_), 16 | hdd(hdd_), 17 | gpu(gpu_) 18 | { 19 | 20 | std::ifstream HDD; 21 | HDD.open("HDD.txt"); 22 | std::string line; 23 | 24 | int j = 0; 25 | int i = 0; 26 | 27 | if (HDD.is_open()){ 28 | while (getline (HDD,line)) { 29 | std::string buf; 30 | std::stringstream ss(line); 31 | 32 | while (ss >> buf) { 33 | hdd.memory[j * sectorSize + i] = std::stoi(buf); 34 | i++; 35 | } 36 | i = 0; 37 | j++; 38 | } 39 | } 40 | 41 | HDD.close(); 42 | } 43 | 44 | int CPU::checkArgument(int source, int size) { 45 | if ((unsigned int)source <= ram.memory.size()) { 46 | if(size == 1) { return ram.memory[source] & 0xFF; } else {return 0;} 47 | if(size == 2) { return ram.memory[source + 1] << 8 | (ram.memory[source] & 0xFF); } else {return 0;} 48 | if(size == 3) { return ram.memory[source + 2] << 16 | (ram.memory[source + 1] << 8) | (ram.memory[source] & 0xFF); } else {return 0;} 49 | }else if (source == ram.memory.size() + 1) { 50 | return register0; 51 | }else if (source == ram.memory.size() + 2) { 52 | return register1; 53 | }else if (source == ram.memory.size() + 3){ 54 | return interruptRegister; 55 | }else { 56 | return 0; 57 | } 58 | } 59 | 60 | int CPU::checkArgumentG(int source, int size) { 61 | if ((unsigned int)source <= gpu.vRam.memory.size()) { 62 | if(size == 1) { return gpu.vRam.memory[source] & 0xFF; } else {return 0;} 63 | if(size == 2) { return gpu.vRam.memory[source + 1] << 8 | (gpu.vRam.memory[source] & 0xFF); } else {return 0;} 64 | if(size == 3) { return gpu.vRam.memory[source + 2] << 16 | (gpu.vRam.memory[source + 1] << 8) | (gpu.vRam.memory[source] & 0xFF); } else {return 0;} 65 | }else if (source == gpu.vRam.memory.size() + 1) { 66 | return register0; 67 | }else if (source == gpu.vRam.memory.size() + 2) { 68 | return register1; 69 | }else if (source == gpu.vRam.memory.size() + 3){ 70 | return interruptRegister; 71 | }else { 72 | return 0; 73 | } 74 | } 75 | 76 | extern bool quit; 77 | 78 | void CPU::execute(u16 registerIns) { 79 | u16 opCode = registerIns; 80 | 81 | switch (opCode) { 82 | case 0: { //Halt 83 | halt = true; 84 | break; } 85 | 86 | case 1: { //Load to register0 from ram, 3 bytes 87 | byte arg1 = ram.memory[programCounter + 1]; 88 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 89 | register0 = checkArgument(memPos, 3); 90 | programCounter += 2; 91 | programCounter++; 92 | break; } 93 | 94 | case 2: { //Load to register1 from ram, 3 bytes 95 | byte arg1 = ram.memory[programCounter + 1]; 96 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 97 | register1 = checkArgument(memPos, 3); 98 | programCounter += 2; 99 | programCounter++; 100 | break; } 101 | 102 | case 3: { //Load to register0 from ram, 2 bytes 103 | byte arg1 = ram.memory[programCounter + 1]; 104 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 105 | register0 = checkArgument(memPos, 2); 106 | programCounter += 2; 107 | programCounter++; 108 | break; } 109 | 110 | case 4: { //Load to register1 from ram, 2 bytes 111 | byte arg1 = ram.memory[programCounter + 1]; 112 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 113 | register1 = checkArgument(memPos, 2); 114 | programCounter += 2; 115 | programCounter++; 116 | break; } 117 | 118 | case 5: { //Load to register0 from ram, 1 byte 119 | byte arg1 = ram.memory[programCounter + 1]; 120 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 121 | register0 = checkArgument(memPos, 1); 122 | programCounter += 2; 123 | programCounter++; 124 | break; } 125 | 126 | case 6: { //Load to register1 from ram, 1 byte 127 | byte arg1 = ram.memory[programCounter + 1]; 128 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 129 | register1 = checkArgument(memPos, 1); 130 | programCounter += 2; 131 | programCounter++; 132 | break; } 133 | 134 | case 7: { //Write from register0 to ram 3 bytes 135 | byte arg1 = ram.memory[programCounter + 1]; 136 | int position = ram.memory[programCounter + 2] << 8 | arg1; 137 | ram.memory[position] = register0 & 0xFF; 138 | ram.memory[position + 1] = (byte)(register0 >> 8); 139 | ram.memory[position + 2] = (byte)(register0 >> 16); 140 | programCounter += 2; 141 | programCounter++; 142 | break; } 143 | 144 | case 8: { //Write from register1 to ram 3 bytes 145 | byte arg1 = ram.memory[programCounter + 1]; 146 | int position = ram.memory[programCounter + 2] << 8 | arg1; 147 | ram.memory[position] = register1 & 0xFF; 148 | ram.memory[position + 1] = (byte)(register1 >> 8); 149 | ram.memory[position + 2] = (byte)(register1 >> 16); 150 | programCounter += 2; 151 | programCounter++; 152 | break; } 153 | 154 | case 9: { //Write from register0 to ram 2 bytes 155 | byte arg1 = ram.memory[programCounter + 1]; 156 | int position = ram.memory[programCounter + 2] << 8 | arg1; 157 | ram.memory[position] = (register0 & 0xFF); 158 | ram.memory[position + 1] = (byte)(register0 >> 8); 159 | programCounter += 2; 160 | programCounter++; 161 | break; } 162 | 163 | case 10: { //Write from register1 to ram 2 bytes 164 | byte arg1 = ram.memory[programCounter + 1]; 165 | int position = ram.memory[programCounter + 2] << 8 | arg1; 166 | ram.memory[position] = (register1 & 0xFF); 167 | ram.memory[position + 1] = (byte)(register1 >> 8); 168 | programCounter += 2; 169 | programCounter++; 170 | break; } 171 | 172 | case 11: { //Write from register0 to ram 1 byte 173 | byte arg1 = ram.memory[programCounter + 1]; 174 | int position = ram.memory[programCounter + 2] << 8 | arg1; 175 | ram.memory[position] = (register0 & 0xFF); 176 | programCounter += 2; 177 | programCounter++; 178 | break; } 179 | 180 | case 12: { //Write from register1 to ram 1 byte 181 | byte arg1 = ram.memory[programCounter + 1]; 182 | int position = ram.memory[programCounter + 2] << 8 | arg1; 183 | ram.memory[position] = (register1 & 0xFF); 184 | programCounter += 2; 185 | programCounter++; 186 | break; } 187 | 188 | case 15: { //Write from ram to hdd 189 | int position = register0; 190 | 191 | int position2 = register1; 192 | 193 | hdd.memory[position2] = ram.memory[position]; 194 | programCounter++; 195 | break; } 196 | 197 | case 16: { //Write from hdd to ram 198 | int position = register0; 199 | 200 | int position2 = register1; 201 | 202 | ram.memory[position2] = hdd.memory[position]; 203 | programCounter++; 204 | break; } 205 | 206 | case 17: { //Shutdown the pc 207 | std::ofstream file; 208 | 209 | file.open("HDD.txt", std::ios::out | std::ios::trunc); 210 | file.close(); 211 | 212 | file.open("HDD.txt"); 213 | for (int i = 0; i < numSectors; i++) { 214 | for (int j = 0; j < sectorSize; j++) { 215 | file << (int)hdd.memory[i * sectorSize + j] << " "; 216 | } 217 | file << '\n'; 218 | } 219 | file.close(); 220 | std::cout << '\n'; 221 | std::cout << "The PC has shut down" << '\n'; 222 | programCounter++; 223 | //halt = true; 224 | break; } 225 | 226 | case 20: { //Add register0 and register1 227 | register0 = register0 + register1; 228 | programCounter++; 229 | break; } 230 | 231 | case 21: { //Subtract register1 from register0 232 | register0 = register0 - register1; 233 | programCounter++; 234 | break; } 235 | 236 | case 22: { //Multiply register0 and register1 237 | register0 = register0 * register1; 238 | programCounter++; 239 | break; } 240 | 241 | case 23: { //Divide register0 by register1 242 | register0 = register0 / register1; 243 | programCounter++; 244 | break; } 245 | 246 | case 24: { //Check if register0 is greater than register1 247 | register0 = register0 > register1; 248 | programCounter++; 249 | break; } 250 | 251 | case 25: { //Check if register0 is greater or equal to register1 252 | register0 = register0 >= register1; 253 | programCounter++; 254 | break; } 255 | 256 | case 26: { //Check if register1 is greater than register0 257 | register0 = register0 < register1; 258 | programCounter++; 259 | break; } 260 | 261 | case 27: { //Check if register1 is greater or equal to register0 262 | register0 = register0 <= register1; 263 | programCounter++; 264 | break; } 265 | 266 | case 28: { //Check if register0 and register1 have same values 267 | register0 = register0 == register1; 268 | programCounter++; 269 | break; } 270 | 271 | case 29: { //Check if register0 is different than register1 272 | register0 = register0 != register1; 273 | programCounter++; 274 | break; } 275 | 276 | case 30: { //Jump to place in code 277 | byte arg1 = ram.memory[programCounter + 1]; 278 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 279 | 280 | programCounter = memPos; 281 | break; } 282 | 283 | case 31: { //Compare to true/false 284 | byte condition = ram.memory[programCounter + 1]; 285 | byte arg1 = ram.memory[programCounter + 2]; 286 | int position = ram.memory[programCounter + 3] << 8 | arg1; 287 | if (register0 == condition) { 288 | programCounter += 3; 289 | programCounter++; 290 | }else if(register0 != condition){ 291 | programCounter = position; 292 | } 293 | break; } 294 | 295 | case 32: { //Wait a number of cycles 296 | int memPos = register0; 297 | int waitTime = checkArgument(memPos, 3); 298 | if (currentTime < waitTime) { 299 | currentTime++; 300 | }else if (currentTime >= waitTime) { 301 | currentTime = 0; 302 | programCounter++; 303 | } 304 | break; } 305 | 306 | case 40: { //Cout from register1 307 | std::cout << register0 << '\n'; 308 | programCounter++; 309 | break; } 310 | 311 | case 41: { //Cout from register2 312 | std::cout << register1 << '\n'; 313 | programCounter++; 314 | break; } 315 | 316 | case 42: { //Load 3 bytes into register0 with offset 317 | byte arg1 = ram.memory[programCounter + 1]; 318 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 319 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 320 | register0 = checkArgument(memPos + offset * 3, 3); 321 | programCounter += 4; 322 | programCounter++; 323 | break; } 324 | 325 | case 43: { //Load 3 bytes into register1 with offset 326 | byte arg1 = ram.memory[programCounter + 1]; 327 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 328 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 329 | register1 = checkArgument(memPos + offset * 3, 3); 330 | programCounter += 4; 331 | programCounter++; 332 | break; } 333 | 334 | case 44: { //Load 2 bytes into register0 with offset 335 | byte arg1 = ram.memory[programCounter + 1]; 336 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 337 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 338 | register0 = checkArgument(memPos + offset * 2, 2); 339 | programCounter += 4; 340 | programCounter++; 341 | break; } 342 | 343 | case 45: { //Load 2 bytes into register1 with offset 344 | byte arg1 = ram.memory[programCounter + 1]; 345 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 346 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 347 | register1 = checkArgument(memPos + offset * 2, 2); 348 | programCounter += 4; 349 | programCounter++; 350 | break; } 351 | 352 | case 46: { //Load 1 byte into register0 with offset 353 | byte arg1 = ram.memory[programCounter + 1]; 354 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 355 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 356 | register0 = checkArgument(memPos + offset, 1); 357 | programCounter += 4; 358 | programCounter++; 359 | break; } 360 | 361 | case 47: { //Load 1 byte into register1 with offset 362 | byte arg1 = ram.memory[programCounter + 1]; 363 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 364 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 365 | register1 = checkArgument(memPos + offset, 1); 366 | programCounter += 4; 367 | programCounter++; 368 | break; } 369 | 370 | case 48: { //Write from register0 to ram 3 bytes with offset 371 | byte arg1 = ram.memory[programCounter + 1]; 372 | int position = ram.memory[programCounter + 2] << 8 | arg1; 373 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 374 | ram.memory[position + offset] = register0 & 0xFF; 375 | ram.memory[position + 1 + offset] = (byte)(register0 >> 8); 376 | ram.memory[position + 2 + offset] = (byte)(register0 >> 16); 377 | programCounter += 4; 378 | programCounter++; 379 | break; } 380 | 381 | case 49: { //Write from register1 to ram 3 bytes with offset 382 | byte arg1 = ram.memory[programCounter + 1]; 383 | int position = ram.memory[programCounter + 2] << 8 | arg1; 384 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 385 | ram.memory[position + offset] = register1 & 0xFF; 386 | ram.memory[position + 1 + offset] = (byte)(register1 >> 8); 387 | ram.memory[position + 2 + offset] = (byte)(register1 >> 16); 388 | programCounter += 4; 389 | programCounter++; 390 | break; } 391 | 392 | case 50: { //Write from register0 to ram 2 bytes with offset 393 | byte arg1 = ram.memory[programCounter + 1]; 394 | int position = ram.memory[programCounter + 2] << 8 | arg1; 395 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 396 | ram.memory[position + offset] = (register0 & 0xFF); 397 | ram.memory[position + 1 + offset] = (byte)(register0 >> 8); 398 | programCounter += 4; 399 | programCounter++; 400 | break; } 401 | 402 | case 51: { //Write from register1 to ram 2 bytes with offset 403 | byte arg1 = ram.memory[programCounter + 1]; 404 | int position = ram.memory[programCounter + 2] << 8 | arg1; 405 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 406 | ram.memory[position + offset] = (register1 & 0xFF); 407 | ram.memory[position + 1 + offset] = (byte)(register1 >> 8); 408 | programCounter += 4; 409 | programCounter++; 410 | break; } 411 | 412 | case 52: { //Write from register0 to ram 1 byte with offset 413 | byte arg1 = ram.memory[programCounter + 1]; 414 | int position = ram.memory[programCounter + 2] << 8 | arg1; 415 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 416 | ram.memory[position + offset] = (register0 & 0xFF); 417 | programCounter += 4; 418 | programCounter++; 419 | break; } 420 | 421 | case 53: { //Write from register1 to ram 1 byte with offset 422 | byte arg1 = ram.memory[programCounter + 1]; 423 | int position = ram.memory[programCounter + 2] << 8 | arg1; 424 | int offset = checkArgument(ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3], 1); 425 | ram.memory[position + offset] = (register1 & 0xFF); 426 | programCounter += 4; 427 | programCounter++; 428 | break; } 429 | 430 | case 54: { //Compare two arrays of 8bit elements if they are the same (Up to 8 elements length) 431 | int size = register0; 432 | int pos1 = ram.memory[programCounter + 2] << 8 | ram.memory[programCounter + 1]; 433 | int pos2 = ram.memory[programCounter + 4] << 8 | ram.memory[programCounter + 3]; 434 | 435 | bool same = true; 436 | 437 | for (int i = 0; i < size; i++) { 438 | int left = checkArgument(pos1 + i, 1); 439 | int right = checkArgument(pos2 + i, 1); 440 | if (left != right) { 441 | same = false; 442 | break; 443 | } 444 | } 445 | 446 | register0 = same; 447 | programCounter += 4; 448 | programCounter++; 449 | break; } 450 | 451 | case 80: { //Draw a character from register0 452 | /*byte arg1 = register0; 453 | byte arg2 = ram.memory[ram.memory[programCounter + 1]]; 454 | byte arg3 = ram.memory[ram.memory[programCounter + 2]]; 455 | 456 | gpu.commandBuffer.memory[gpu.commandCounter] = 4; 457 | 458 | gpu.commandArgBuffer.memory[gpu.commandArgCounter + 0] = arg1; 459 | gpu.commandArgBuffer.memory[gpu.commandArgCounter + 1] = arg2; 460 | gpu.commandArgBuffer.memory[gpu.commandArgCounter + 2] = arg3; 461 | 462 | programCounter += 2; 463 | programCounter++;*/ 464 | break; } 465 | 466 | case 81: { //Draw a character from register1 467 | /*byte arg1 = register1; 468 | byte arg2 = ram.memory[ram.memory[programCounter + 1]]; 469 | byte arg3 = ram.memory[ram.memory[programCounter + 2]]; 470 | 471 | gpu.commandBuffer.memory[gpu.commandCounter] = 4; 472 | 473 | gpu.commandArgBuffer.memory[gpu.commandArgCounter + 0] = arg1; 474 | gpu.commandArgBuffer.memory[gpu.commandArgCounter + 1] = arg2; 475 | gpu.commandArgBuffer.memory[gpu.commandArgCounter + 2] = arg3; 476 | 477 | programCounter += 2; 478 | programCounter++;*/ 479 | break; } 480 | 481 | case 82: { //Clear GPU commandBuffer 482 | /*gpu.commandBuffer.memory[gpu.commandCounter] = 5; 483 | programCounter++;*/ 484 | break; } 485 | 486 | case 83: { //Clear GPU VRAM 487 | /*if (gpu.functionCounter == gpu.firstAvailableByte) { 488 | gpu.commandBuffer.memory[gpu.commandCounter] = 6; 489 | programCounter++; 490 | }*/ 491 | break; } 492 | 493 | case 84: { 494 | gpu.startCores(); 495 | programCounter++; 496 | break; } 497 | 498 | case 85: { //Load to register0 from ram, 2 bytes 499 | byte arg1 = ram.memory[programCounter + 1]; 500 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 501 | register0 = checkArgumentG(memPos, 2); 502 | programCounter += 2; 503 | programCounter++; 504 | break; } 505 | 506 | case 86: { //Load to register1 from ram, 2 bytes 507 | byte arg1 = ram.memory[programCounter + 1]; 508 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 509 | register1 = checkArgumentG(memPos, 2); 510 | programCounter += 2; 511 | programCounter++; 512 | break; } 513 | 514 | case 87: { //Load to register0 from ram, 1 byte 515 | byte arg1 = ram.memory[programCounter + 1]; 516 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 517 | register0 = checkArgumentG(memPos, 1); 518 | programCounter += 2; 519 | programCounter++; 520 | break; } 521 | 522 | case 88: { //Load to register1 from ram, 1 byte 523 | byte arg1 = ram.memory[programCounter + 1]; 524 | int memPos = ram.memory[programCounter + 2] << 8 | arg1; 525 | register1 = checkArgumentG(memPos, 1); 526 | programCounter += 2; 527 | programCounter++; 528 | break; } 529 | 530 | case 89: { //Write from register0 to ram 2 bytes 531 | byte arg1 = ram.memory[programCounter + 1]; 532 | int position = ram.memory[programCounter + 2] << 8 | arg1; 533 | gpu.vRam.memory[position] = (register0 & 0xFF); 534 | gpu.vRam.memory[position + 1] = (byte)(register0 >> 8); 535 | programCounter += 2; 536 | programCounter++; 537 | break; } 538 | 539 | case 90: { //Write from register1 to ram 2 bytes 540 | byte arg1 = ram.memory[programCounter + 1]; 541 | int position = ram.memory[programCounter + 2] << 8 | arg1; 542 | gpu.vRam.memory[position] = (register1 & 0xFF); 543 | gpu.vRam.memory[position + 1] = (byte)(register1 >> 8); 544 | programCounter += 2; 545 | programCounter++; 546 | break; } 547 | 548 | case 91: { //Write from register0 to ram 1 byte 549 | byte arg1 = ram.memory[programCounter + 1]; 550 | int position = ram.memory[programCounter + 2] << 8 | arg1; 551 | gpu.vRam.memory[position] = (register0 & 0xFF); 552 | programCounter += 2; 553 | programCounter++; 554 | break; } 555 | 556 | case 92: { //Write from register1 to ram 1 byte 557 | byte arg1 = ram.memory[programCounter + 1]; 558 | int position = ram.memory[programCounter + 2] << 8 | arg1; 559 | gpu.vRam.memory[position] = (register1 & 0xFF); 560 | programCounter += 2; 561 | programCounter++; 562 | break; } 563 | } 564 | } 565 | 566 | void CPU::interrupt(){ 567 | if (interrupted == true) { 568 | 569 | currentIntPos = programCounter; 570 | 571 | byte b1 = currentIntPos & 0xff; 572 | byte b2 = (byte)(currentIntPos >> 8); 573 | 574 | ram.memory[interTartgetPos] = b1; 575 | ram.memory[interTartgetPos + 1] = b2; 576 | 577 | programCounter = interPos; 578 | 579 | interrupted = false; 580 | } 581 | } 582 | 583 | 584 | void CPU::tick() { 585 | if (halt == false) { 586 | registerOP = ram.memory[programCounter]; 587 | execute(registerOP); 588 | interrupt(); 589 | } 590 | } -------------------------------------------------------------------------------- /VirtualPCCpp/CPU.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Memory.h" 10 | #include "GPU.h" 11 | 12 | typedef unsigned char byte; 13 | typedef uint16_t u16; 14 | 15 | class CPU { 16 | public: 17 | Memory& ram; 18 | Memory& hdd; 19 | int registerOP; 20 | int register0; 21 | int register1; 22 | int programCounter; 23 | int sectorSize; 24 | int numSectors; 25 | int interruptRegister; 26 | int interPos; 27 | int interTartgetPos; 28 | int currentIntPos; 29 | bool interrupted; 30 | u16 currentTime; 31 | GPU& gpu; 32 | bool halt; 33 | 34 | CPU(int, int, Memory&, Memory&, GPU&); 35 | int checkArgument(int, int); 36 | int checkArgumentG(int, int); 37 | void execute(u16); 38 | void interrupt(); 39 | void tick(); 40 | }; -------------------------------------------------------------------------------- /VirtualPCCpp/Change Log.txt: -------------------------------------------------------------------------------- 1 | 64th commit - 28/12/2017 2 | -GPU is fully programable now, basic instructions available, write your gpu programs in GPU_Program.txt 3 | -When creating GPU in Main.cpp, 3rd and 4th argument is number of X cores and number of Y cores respectively 4 | -cs_out commands, clr_comm and clr_vram have been removed from the cpu 5 | 6 | 65-66th commit - 30/12/2017 7 | -Changed how GPU cores work, now each one has its own local memory of 256 bytes and it can read/write to it. Support for read only VRAM from the cores is coming soon 8 | -Added task queue to the gpu so you can create as big of a task list which the gpu cores will execute 9 | -You set the task size by using command >kernel_size< in GPU Assembly followed by 2 numbers for x and y size respectively. 10 | -GPU Assembly documentation coming soon 11 | 12 | 67th committ - 31/12/2017 13 | -Added instructions to CPU and GPU Cores to access VRam, CPU can read/write to it while GPU cores can only read from it 14 | -Added min and max instructions to the GPU Cores and they take 3 arguments, its meant to be used for triangle drawing 15 | -Added a signed register 0 bigger or equal to register 1 instruction to GPU Cores, written as reg0_be_s, other ones coming soon 16 | -Made a very basic GPU program to draw a triangle to the screen -------------------------------------------------------------------------------- /VirtualPCCpp/GPU.cpp: -------------------------------------------------------------------------------- 1 | #include "GPU.h" 2 | 3 | 4 | GPU::GPU(int commandBufferSize, int vRamSize, int coreCount, int commandArgBufferSize, SDLWindow* screen_, Memory& ram_) 5 | : 6 | commandBuffer(Memory(commandBufferSize)), 7 | commandArgBuffer(Memory(commandArgBufferSize)), 8 | vRam(Memory(vRamSize)), 9 | ram(ram_), 10 | screen(screen_) 11 | { 12 | for (int x = 0; x < coreCount; x++) { 13 | cores.emplace_back(vRam, screen_, 256, x, 0); 14 | } 15 | 16 | //srand(time(NULL)); 17 | 18 | int countR = 0; 19 | int characterCount = 0; 20 | characters.resize(99); 21 | 22 | std::string line; 23 | std::ifstream myfile ("fontBasic.txt"); 24 | 25 | for (int i = 0; i < 99; i++) { 26 | characters[i].rows.resize(8); 27 | } 28 | 29 | if (myfile.is_open()){ 30 | while (getline (myfile,line)) { 31 | if (countR < 8) { 32 | characters[characterCount].rows[countR] = line; 33 | countR++; 34 | }else{ 35 | characterCount++; 36 | countR = 0; 37 | } 38 | } 39 | } 40 | } 41 | 42 | void convertByte(int number, byte& b1, byte& b2, byte& b3) { 43 | b1 = number & 0xff; 44 | b2 = (byte)(number >> 8); 45 | b3 = (byte)(number >> 16); 46 | } 47 | 48 | void GPU::executeCommand() { 49 | /*byte instruction = commandBuffer.memory[commandCounter]; 50 | 51 | switch (instruction) { 52 | 53 | case 0: { 54 | commandBuffer.Clear(); 55 | commandArgBuffer.Clear(); 56 | commandCounter = 0; 57 | break; } 58 | 59 | case 1: { 60 | for(int i = 0;) 61 | break; } 62 | 63 | case 2: { 64 | //TODO 65 | break; } 66 | 67 | case 3: { 68 | byte arg1p1 = commandArgBuffer.memory[commandArgCounter + 0]; 69 | byte arg1p2 = commandArgBuffer.memory[commandArgCounter + 1]; 70 | byte arg1p3 = commandArgBuffer.memory[commandArgCounter + 2]; 71 | byte arg2p1 = commandArgBuffer.memory[commandArgCounter + 3]; 72 | byte arg2p2 = commandArgBuffer.memory[commandArgCounter + 4]; 73 | byte arg2p3 = commandArgBuffer.memory[commandArgCounter + 5]; 74 | 75 | int arg1 = arg1p3 << 16 | arg1p2 << 8 | (arg1p1 & 0xFF); 76 | int arg2 = arg2p3 << 16 | arg2p2 << 8 | (arg2p1 & 0xFF); 77 | 78 | for (int i = 0; i < arg2; i++) { 79 | vRam.memory[(i * 8) + firstAvailableByte + 0] = 3; 80 | vRam.memory[(i * 8) + firstAvailableByte + 1] = ram.memory[(i * 7) + arg1 + 0]; 81 | vRam.memory[(i * 8) + firstAvailableByte + 2] = ram.memory[(i * 7) + arg1 + 1]; 82 | vRam.memory[(i * 8) + firstAvailableByte + 3] = ram.memory[(i * 7) + arg1 + 2]; 83 | vRam.memory[(i * 8) + firstAvailableByte + 4] = ram.memory[(i * 7) + arg1 + 3]; 84 | vRam.memory[(i * 8) + firstAvailableByte + 5] = ram.memory[(i * 7) + arg1 + 4]; 85 | vRam.memory[(i * 8) + firstAvailableByte + 6] = ram.memory[(i * 7) + arg1 + 5]; 86 | vRam.memory[(i * 8) + firstAvailableByte + 7] = ram.memory[(i * 7) + arg1 + 6]; 87 | } 88 | 89 | firstAvailableByte += 8 * arg2; 90 | 91 | commandArgCounter += 6; 92 | commandCounter++; 93 | break; } 94 | 95 | case 4: { 96 | byte arg1 = commandArgBuffer.memory[commandArgCounter + 0]; 97 | byte arg2 = commandArgBuffer.memory[commandArgCounter + 1]; 98 | byte arg3 = commandArgBuffer.memory[commandArgCounter + 2]; 99 | 100 | character cc = characters[arg1]; 101 | 102 | for (int i = 0; i < 7; i++) { 103 | std::string cr = cc.rows[i]; 104 | for (int j = 0; j < 6; j++) { 105 | int xPos = (arg2 * 6) + j + 1; 106 | byte b1, b2, b3; 107 | convertByte(xPos, b1, b2, b3); 108 | int yPos = (arg3 * 7) + i + 1; 109 | byte b4, b5, b6; 110 | convertByte(yPos, b4, b5, b6); 111 | if (cr[j] == '0') { 112 | vRam.memory[firstAvailableByte + 0] = 3; 113 | vRam.memory[firstAvailableByte + 1] = b1; 114 | vRam.memory[firstAvailableByte + 2] = b2; 115 | vRam.memory[firstAvailableByte + 3] = b4; 116 | vRam.memory[firstAvailableByte + 4] = b5; 117 | vRam.memory[firstAvailableByte + 5] = 0; 118 | vRam.memory[firstAvailableByte + 6] = 0; 119 | vRam.memory[firstAvailableByte + 7] = 0; 120 | 121 | firstAvailableByte += 8; 122 | }else if (cr[j] = '1') { 123 | vRam.memory[firstAvailableByte + 0] = 3; 124 | vRam.memory[firstAvailableByte + 1] = b1; 125 | vRam.memory[firstAvailableByte + 2] = b2; 126 | vRam.memory[firstAvailableByte + 3] = b4; 127 | vRam.memory[firstAvailableByte + 4] = b5; 128 | vRam.memory[firstAvailableByte + 5] = 255; 129 | vRam.memory[firstAvailableByte + 6] = 255; 130 | vRam.memory[firstAvailableByte + 7] = 255; 131 | 132 | firstAvailableByte += 8; 133 | } 134 | } 135 | } 136 | 137 | commandArgCounter += 3; 138 | commandCounter++; 139 | break; } 140 | 141 | case 5: { 142 | commandBuffer.Clear(); 143 | commandArgBuffer.Clear(); 144 | commandCounter = 0; 145 | commandArgCounter = 0; 146 | break; } 147 | 148 | case 6: { 149 | vRam.Clear(); 150 | functionCounter = 0; 151 | firstAvailableByte = 0; 152 | 153 | break; } 154 | }*/ 155 | } 156 | 157 | void GPU::executeThread() { 158 | /*byte instruction = vRam.memory[functionCounter]; 159 | 160 | switch (instruction) { 161 | 162 | case 1: { 163 | //TODO 164 | break; } 165 | case 2: { 166 | //TODO 167 | break; } 168 | 169 | case 3: { 170 | byte arg1b1 = vRam.memory[functionCounter + 1]; 171 | byte arg1b2 = vRam.memory[functionCounter + 2]; 172 | byte arg2b1 = vRam.memory[functionCounter + 3]; 173 | byte arg2b2 = vRam.memory[functionCounter + 4]; 174 | byte arg3 = vRam.memory[functionCounter + 5]; 175 | byte arg4 = vRam.memory[functionCounter + 6]; 176 | byte arg5 = vRam.memory[functionCounter + 7]; 177 | 178 | int arg1 = arg1b2 << 8 | (arg1b1 & 0xFF); 179 | int arg2 = arg2b2 << 8 | (arg2b1 & 0xFF); 180 | 181 | byte r = arg3 * 2; 182 | byte g = arg4 * 2; 183 | byte b = arg5 * 2; 184 | 185 | screen->pixels[arg2 * 320 + arg1] = int(b << 16) | int(g << 8) | int(r); 186 | functionCounter += 7; 187 | functionCounter++; 188 | break; } 189 | }*/ 190 | } 191 | 192 | void GPU::startCores() { 193 | for (int i = 0; i < cores.size(); i++) { 194 | //int numb = rand() % tasks.size(); 195 | if (tasks.size() > 0) { 196 | cores[i].programCounter = programCounter; 197 | cores[i].idX = tasks[0].x; 198 | cores[i].idY = tasks[0].y; 199 | tasks.erase(tasks.begin()); 200 | cores[i].halt = false; 201 | }else{ 202 | cores[i].idX = 0; 203 | cores[i].idY = 0; 204 | } 205 | } 206 | } 207 | 208 | void GPU::tick() { 209 | for (int i = 0; i < cores.size(); i++) { 210 | if (cores[i].halt == true) { 211 | if (tasks.size() > 0) { 212 | cores[i].programCounter = programCounter; 213 | cores[i].idX = tasks[0].x; 214 | cores[i].idY = tasks[0].y; 215 | tasks.erase(tasks.begin()); 216 | cores[i].halt = false; 217 | } 218 | }else{ 219 | cores[i].tick(); 220 | } 221 | } 222 | } -------------------------------------------------------------------------------- /VirtualPCCpp/GPU.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "Memory.h" 12 | #include "SDLWindow.h" 13 | #include "GPUCore.h" 14 | 15 | typedef unsigned char byte; 16 | typedef uint16_t u16; 17 | 18 | struct character { 19 | std::vector rows; 20 | }; 21 | 22 | struct task_id { 23 | int x; 24 | int y; 25 | }; 26 | 27 | class GPU { 28 | public: 29 | Memory commandBuffer; 30 | Memory commandArgBuffer; 31 | std::vector stack; 32 | Memory vRam; 33 | Memory& ram; 34 | SDLWindow* screen; 35 | int programCounter; 36 | std::vector tasks; 37 | std::vector characters; 38 | std::vector cores; 39 | 40 | GPU(int, int, int, int, SDLWindow*, Memory&); 41 | void executeCommand(); 42 | void executeThread(); 43 | void startCores(); 44 | void tick(); 45 | }; -------------------------------------------------------------------------------- /VirtualPCCpp/GPUAssembly.cpp: -------------------------------------------------------------------------------- 1 | #include "GPUAssembly.h" 2 | 3 | namespace GPUAssembly { 4 | 5 | std::vector lines; 6 | 7 | void convertByte(int& number, byte& b1, byte& b2, byte& b3) { 8 | b1 = number & 0xff; 9 | b2 = (byte)(number >> 8); 10 | b3 = (byte)(number >> 16); 11 | } 12 | 13 | bool checkArgSize(int& arg, int argc, std::string& instruction, unsigned int& instructionC, int maxSize) { 14 | if (arg > maxSize) { 15 | std::cout << "Error: Argument " << argc << " exceeds size limit of " << maxSize << " at instruction " << instruction << " at position " << instructionC + 1 + argc << '\n'; 16 | return true; 17 | }else{ 18 | return false; 19 | } 20 | } 21 | 22 | void checkJmpPos(int& arg, std::string argument, std::vector& jumpNames, std::vector jumpPos) { 23 | bool varExists = false; 24 | int id = 0; 25 | 26 | for (unsigned int i = 0; i < jumpNames.size(); i++) { 27 | if (argument == jumpNames[i]) { 28 | varExists = true; 29 | id = i; 30 | break; 31 | } 32 | } 33 | 34 | if (varExists == true) { 35 | arg = jumpPos[id]; 36 | } 37 | } 38 | 39 | void checkArgType(int& arg, std::string& argument, GPU& gpu, std::vector& vars, std::vector& varValues) { 40 | bool varExists = false; 41 | int id = 0; 42 | 43 | for (unsigned int i = 0; i < vars.size(); i++) { 44 | if (argument == vars[i]) { 45 | varExists = true; 46 | id = i; 47 | break; 48 | } 49 | } 50 | 51 | if (varExists == true) { 52 | arg = varValues[id]; 53 | }else if (varExists == false) { 54 | if (argument == "reg0") { 55 | arg = 256 + 1; 56 | }else if (argument == "reg1") { 57 | arg = 256 + 2; 58 | }else if (argument == "idx") { 59 | arg = 256 + 3; 60 | }else if (argument == "idy") { 61 | arg = 256 + 4; 62 | }else { 63 | arg = std::stoi(argument); 64 | } 65 | } 66 | } 67 | 68 | void checkArgTypeV(int& arg, std::string& argument, GPU& gpu, std::vector& vars, std::vector& varValues) { 69 | bool varExists = false; 70 | int id = 0; 71 | 72 | for (unsigned int i = 0; i < vars.size(); i++) { 73 | if (argument == vars[i]) { 74 | varExists = true; 75 | id = i; 76 | break; 77 | } 78 | } 79 | 80 | if (varExists == true) { 81 | arg = varValues[id]; 82 | } 83 | } 84 | 85 | void readFile(std::string path, std::vector& code) { 86 | std::string line; 87 | std::ifstream myfile(path); 88 | std::string prefix = "//"; 89 | 90 | if (myfile.is_open()){ 91 | while (getline (myfile,line)) { 92 | if (!(line[0] == '/' && line[1] == '/')) { 93 | if (line != "") { 94 | lines.push_back(line); 95 | std::string buf; 96 | std::stringstream ss(line); 97 | 98 | while (ss >> buf) { 99 | if (buf[0] == '/' && buf[1] == '/') {break;} 100 | code.push_back(buf); 101 | } 102 | } 103 | } 104 | } 105 | } 106 | } 107 | 108 | void Compile(std::vector& code, GPU& gpu, std::vector& vValues, std::vector& vNames, int newCP) { 109 | 110 | 111 | int currentPos = newCP; 112 | int additionalMemory = 0; 113 | int line = 0; 114 | std::vector jumpPositions; 115 | std::vector vars; 116 | std::vector jumpNames; 117 | std::vector varValues; 118 | 119 | bool dataM = false; 120 | 121 | for (unsigned int i = 0; i < code.size(); i++) { 122 | 123 | std::string instruction = code[i]; 124 | 125 | if(instruction == "data_s") { 126 | dataM = true; 127 | i++; 128 | instruction = code[i]; 129 | line++; 130 | } 131 | 132 | if(instruction == "data_e") { 133 | dataM = false; 134 | currentPos += additionalMemory; 135 | i++; 136 | instruction = code[i]; 137 | line++; 138 | } 139 | 140 | if (dataM == true) { 141 | if (instruction == "u8") { 142 | additionalMemory++; 143 | i += 2; 144 | line++; 145 | }else if (instruction == "u16") { 146 | additionalMemory += 2; 147 | line++; 148 | i += 2; 149 | }else { 150 | std::cout << "Unknown instruction >" << instruction << "< at line " << line << '\n'; 151 | std::cout << '\n'; 152 | std::cout << lines[line] << '\n'; 153 | std::cout << "^" << '\n'; 154 | std::cout << '\n'; 155 | std::cout << "Compilation terminated." << '\n'; 156 | gpu.vRam.Clear(); 157 | break; 158 | } 159 | }else if (dataM == false) { 160 | if (instruction == "load0_8") { 161 | currentPos += 3; 162 | i++; 163 | line++; 164 | }else if (instruction == "load1_8") { 165 | currentPos += 3; 166 | i++; 167 | line++; 168 | }else if (instruction == "load0_16") { 169 | currentPos += 3; 170 | i++; 171 | line++; 172 | }else if (instruction == "load1_16") { 173 | currentPos += 3; 174 | i++; 175 | line++; 176 | }else if (instruction == "wrt0_16") { 177 | currentPos += 3; 178 | i++; 179 | line++; 180 | }else if (instruction == "wrt1_16") { 181 | currentPos += 3; 182 | i++; 183 | line++; 184 | }else if (instruction == "wrt0_8") { 185 | currentPos += 3; 186 | i++; 187 | line++; 188 | }else if (instruction == "wrt1_8") { 189 | currentPos += 3; 190 | i++; 191 | line++; 192 | }else if (instruction == "sum") { 193 | currentPos++; 194 | line++; 195 | }else if (instruction == "sub") { 196 | currentPos++; 197 | line++; 198 | }else if (instruction == "mlt") { 199 | currentPos++; 200 | line++; 201 | }else if (instruction == "div") { 202 | currentPos++; 203 | line++; 204 | }else if (instruction == "reg0_b") { 205 | currentPos++; 206 | line++; 207 | }else if (instruction == "reg0_be") { 208 | currentPos++; 209 | line++; 210 | }else if (instruction == "reg0_be_s") { 211 | currentPos++; 212 | line++; 213 | }else if (instruction == "reg1_b") { 214 | currentPos++; 215 | line++; 216 | }else if (instruction == "reg1_be") { 217 | currentPos++; 218 | line++; 219 | }else if (instruction == "reg_eql") { 220 | currentPos++; 221 | line++; 222 | }else if (instruction == "reg_dif") { 223 | currentPos++; 224 | line++; 225 | }else if (instruction == "jmp") { 226 | currentPos += 3; 227 | i++; 228 | line++; 229 | }else if (instruction == "cmp") { 230 | currentPos += 4; 231 | i += 2; 232 | line++; 233 | }else if (instruction == "get_idx") { 234 | currentPos++; 235 | line++; 236 | }else if (instruction == "get_idy") { 237 | currentPos++; 238 | line++; 239 | }else if (instruction == "p_out") { 240 | currentPos++; 241 | line++; 242 | }else if (instruction == "loadR") { 243 | currentPos += 3; 244 | i++; 245 | line++; 246 | }else if (instruction == "loadG") { 247 | currentPos += 3; 248 | i++; 249 | line++; 250 | }else if (instruction == "loadB") { 251 | currentPos += 3; 252 | i++; 253 | line++; 254 | }else if (instruction == "kernel_size") { 255 | i += 2; 256 | line++; 257 | }else if (instruction == "load0_8g") { 258 | currentPos += 3; 259 | i++; 260 | line++; 261 | }else if (instruction == "load1_8g") { 262 | currentPos += 3; 263 | i++; 264 | line++; 265 | }else if (instruction == "load0_16g") { 266 | currentPos += 3; 267 | i++; 268 | line++; 269 | }else if (instruction == "load1_16g") { 270 | currentPos += 3; 271 | i++; 272 | line++; 273 | }else if (instruction == "max") { 274 | currentPos += 7; 275 | i += 3; 276 | line++; 277 | }else if (instruction == "min") { 278 | currentPos += 7; 279 | i += 3; 280 | line++; 281 | }else{ 282 | if (instruction.back() == ':') { 283 | std::string tmp = instruction; 284 | tmp.erase(tmp.end() - 1); 285 | jumpNames.push_back(tmp); 286 | jumpPositions.push_back(currentPos); 287 | line++; 288 | }else{ 289 | std::cout << "Unknown instruction >" << instruction << "< at line " << line << '\n'; 290 | std::cout << '\n'; 291 | std::cout << lines[line] << '\n'; 292 | std::cout << "^" << '\n'; 293 | std::cout << '\n'; 294 | std::cout << "Compilation terminated." << '\n'; 295 | gpu.vRam.Clear(); 296 | return; 297 | break; 298 | } 299 | } 300 | 301 | } 302 | 303 | } 304 | 305 | currentPos = 0; 306 | additionalMemory = 0; 307 | 308 | for (unsigned int i = 0; i < code.size(); i++) { 309 | 310 | std::string instruction = code[i]; 311 | 312 | if(instruction == "data_s") { 313 | dataM = true; 314 | i++; 315 | line++; 316 | instruction = code[i]; 317 | } 318 | 319 | if(instruction == "data_e") { 320 | dataM = false; 321 | currentPos += additionalMemory; 322 | gpu.programCounter = currentPos; 323 | i++; 324 | line++; 325 | instruction = code[i]; 326 | } 327 | 328 | if (dataM == true) { 329 | if (instruction == "u8") { 330 | std::string arg1 = code[i + 1]; 331 | std::string arg2 = code[i + 2]; 332 | 333 | vars.push_back(arg1); 334 | int Arg2 = std::stoi(arg2); 335 | varValues.push_back(additionalMemory); 336 | 337 | for (int k = 0; k < gpu.cores.size(); k++) { 338 | gpu.cores[k].intMem.memory[additionalMemory] = (byte)Arg2; 339 | } 340 | 341 | additionalMemory++; 342 | i += 2; 343 | line++; 344 | }else if (instruction == "u16") { 345 | std::string arg1 = code[i + 1]; 346 | std::string arg2 = code[i + 2]; 347 | 348 | vars.push_back(arg1); 349 | int Arg2 = std::stoi(arg2); 350 | varValues.push_back(additionalMemory); 351 | 352 | byte b1, b2, b3; 353 | convertByte(Arg2, b1, b2, b3); 354 | 355 | for (int k = 0; k < gpu.cores.size(); k++) { 356 | gpu.cores[k].intMem.memory[additionalMemory] = b1; 357 | gpu.cores[k].intMem.memory[additionalMemory] = b2; 358 | } 359 | 360 | additionalMemory += 2; 361 | i += 2; 362 | line++; 363 | }else{ 364 | std::cout << "Unknown instruction >" << instruction << "< at line " << line << '\n'; 365 | std::cout << '\n'; 366 | std::cout << lines[line] << '\n'; 367 | std::cout << "^" << '\n'; 368 | std::cout << '\n'; 369 | std::cout << "Compilation terminated." << '\n'; 370 | gpu.vRam.Clear(); 371 | break; 372 | } 373 | }else if (dataM == false) { 374 | if (instruction == "load0_8") { 375 | std::string arg1 = code[i + 1]; 376 | 377 | gpu.vRam.memory[currentPos++] = 3; 378 | 379 | int Arg1; 380 | checkArgType(Arg1, arg1, gpu, vars, varValues); 381 | 382 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 383 | 384 | byte b1, b2, b3; 385 | convertByte(Arg1, b1, b2, b3); 386 | gpu.vRam.memory[currentPos++] = b1; 387 | gpu.vRam.memory[currentPos++] = b2; 388 | 389 | i++; 390 | line++; 391 | }else if (instruction == "load1_8") { 392 | std::string arg1 = code[i + 1]; 393 | 394 | gpu.vRam.memory[currentPos++] = 4; 395 | 396 | int Arg1; 397 | checkArgType(Arg1, arg1, gpu, vars, varValues); 398 | 399 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 400 | 401 | byte b1, b2, b3; 402 | convertByte(Arg1, b1, b2, b3); 403 | gpu.vRam.memory[currentPos++] = b1; 404 | gpu.vRam.memory[currentPos++] = b2; 405 | 406 | i++; 407 | line++; 408 | }else if (instruction == "load0_16") { 409 | std::string arg1 = code[i + 1]; 410 | 411 | gpu.vRam.memory[currentPos++] = 1; 412 | 413 | int Arg1; 414 | checkArgType(Arg1, arg1, gpu, vars, varValues); 415 | 416 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 417 | 418 | byte b1, b2, b3; 419 | convertByte(Arg1, b1, b2, b3); 420 | gpu.vRam.memory[currentPos++] = b1; 421 | gpu.vRam.memory[currentPos++] = b2; 422 | 423 | i++; 424 | line++; 425 | }else if (instruction == "load1_16") { 426 | std::string arg1 = code[i + 1]; 427 | 428 | gpu.vRam.memory[currentPos++] = 2; 429 | 430 | int Arg1; 431 | checkArgType(Arg1, arg1, gpu, vars, varValues); 432 | 433 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 434 | 435 | byte b1, b2, b3; 436 | convertByte(Arg1, b1, b2, b3); 437 | gpu.vRam.memory[currentPos++] = b1; 438 | gpu.vRam.memory[currentPos++] = b2; 439 | 440 | i++; 441 | line++; 442 | }else if (instruction == "wrt0_16") { 443 | std::string arg1 = code[i + 1]; 444 | 445 | gpu.vRam.memory[currentPos++] = 5; 446 | 447 | int Arg1; 448 | checkArgType(Arg1, arg1, gpu, vars, varValues); 449 | 450 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 451 | 452 | byte b1, b2, b3; 453 | convertByte(Arg1, b1, b2, b3); 454 | gpu.vRam.memory[currentPos++] = b1; 455 | gpu.vRam.memory[currentPos++] = b2; 456 | 457 | i++; 458 | line++; 459 | }else if (instruction == "wrt1_16") { 460 | std::string arg1 = code[i + 1]; 461 | 462 | gpu.vRam.memory[currentPos++] = 6; 463 | 464 | int Arg1; 465 | checkArgType(Arg1, arg1, gpu, vars, varValues); 466 | 467 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 468 | 469 | byte b1, b2, b3; 470 | convertByte(Arg1, b1, b2, b3); 471 | gpu.vRam.memory[currentPos++] = b1; 472 | gpu.vRam.memory[currentPos++] = b2; 473 | 474 | i++; 475 | line++; 476 | }else if (instruction == "wrt0_8") { 477 | std::string arg1 = code[i + 1]; 478 | 479 | gpu.vRam.memory[currentPos++] = 7; 480 | 481 | int Arg1; 482 | checkArgType(Arg1, arg1, gpu, vars, varValues); 483 | 484 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 485 | 486 | byte b1, b2, b3; 487 | convertByte(Arg1, b1, b2, b3); 488 | gpu.vRam.memory[currentPos++] = b1; 489 | gpu.vRam.memory[currentPos++] = b2; 490 | 491 | i++; 492 | line++; 493 | }else if (instruction == "wrt1_8") { 494 | std::string arg1 = code[i + 1]; 495 | 496 | gpu.vRam.memory[currentPos++] = 8; 497 | 498 | int Arg1; 499 | checkArgType(Arg1, arg1, gpu, vars, varValues); 500 | 501 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 502 | 503 | byte b1, b2, b3; 504 | convertByte(Arg1, b1, b2, b3); 505 | gpu.vRam.memory[currentPos++] = b1; 506 | gpu.vRam.memory[currentPos++] = b2; 507 | 508 | i++; 509 | line++; 510 | }else if (instruction == "sum") { 511 | gpu.vRam.memory[currentPos++] = 10; 512 | line++; 513 | }else if (instruction == "sub") { 514 | gpu.vRam.memory[currentPos++] = 11; 515 | line++; 516 | }else if (instruction == "mlt") { 517 | gpu.vRam.memory[currentPos++] = 12; 518 | line++; 519 | }else if (instruction == "div") { 520 | gpu.vRam.memory[currentPos++] = 13; 521 | line++; 522 | }else if (instruction == "reg0_b") { 523 | gpu.vRam.memory[currentPos++] = 14; 524 | line++; 525 | }else if (instruction == "reg0_be") { 526 | gpu.vRam.memory[currentPos++] = 15; 527 | line++; 528 | }else if (instruction == "reg0_be_s") { 529 | gpu.vRam.memory[currentPos++] = 29; 530 | line++; 531 | }else if (instruction == "reg1_b") { 532 | gpu.vRam.memory[currentPos++] = 16; 533 | line++; 534 | }else if (instruction == "reg1_be") { 535 | gpu.vRam.memory[currentPos++] = 17; 536 | line++; 537 | }else if (instruction == "reg_eql") { 538 | gpu.vRam.memory[currentPos++] = 18; 539 | line++; 540 | }else if (instruction == "reg_dif") { 541 | gpu.vRam.memory[currentPos++] = 19; 542 | line++; 543 | }else if (instruction == "jmp") { 544 | std::string arg1 = code[i + 1]; 545 | int pos; 546 | 547 | gpu.vRam.memory[currentPos++] = 20; 548 | 549 | checkJmpPos(pos, arg1, jumpNames, jumpPositions); 550 | 551 | byte b1, b2, b3; 552 | convertByte(pos, b1, b2, b3); 553 | gpu.vRam.memory[currentPos++] = b1; 554 | gpu.vRam.memory[currentPos++] = b2; 555 | 556 | i++; 557 | line++; 558 | }else if (instruction == "cmp") { 559 | std::string arg1 = code[i + 1]; 560 | std::string arg2 = code[i + 2]; 561 | 562 | gpu.vRam.memory[currentPos++] = 21; 563 | 564 | int Arg1; 565 | checkArgType(Arg1, arg1, gpu, vars, varValues); 566 | 567 | int pos; 568 | 569 | checkJmpPos(pos, arg2, jumpNames, jumpPositions); 570 | 571 | gpu.vRam.memory[currentPos++] = (byte)Arg1; 572 | byte b1, b2, b3; 573 | convertByte(pos, b1, b2, b3); 574 | gpu.vRam.memory[currentPos++] = b1; 575 | gpu.vRam.memory[currentPos++] = b2; 576 | 577 | i += 2; 578 | line++; 579 | }else if(instruction == "get_idx") { 580 | gpu.vRam.memory[currentPos++] = 31; 581 | line++; 582 | }else if(instruction == "get_idy") { 583 | gpu.vRam.memory[currentPos++] = 32; 584 | line++; 585 | }else if(instruction == "p_out") { 586 | gpu.vRam.memory[currentPos++] = 30; 587 | line++; 588 | }else if (instruction == "loadR") { 589 | std::string arg1 = code[i + 1]; 590 | 591 | gpu.vRam.memory[currentPos++] = 26; 592 | 593 | int Arg1; 594 | checkArgType(Arg1, arg1, gpu, vars, varValues); 595 | 596 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 597 | 598 | byte b1, b2, b3; 599 | convertByte(Arg1, b1, b2, b3); 600 | gpu.vRam.memory[currentPos++] = b1; 601 | gpu.vRam.memory[currentPos++] = b2; 602 | 603 | i++; 604 | line++; 605 | }else if (instruction == "loadG") { 606 | std::string arg1 = code[i + 1]; 607 | 608 | gpu.vRam.memory[currentPos++] = 27; 609 | 610 | int Arg1; 611 | checkArgType(Arg1, arg1, gpu, vars, varValues); 612 | 613 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 614 | 615 | byte b1, b2, b3; 616 | convertByte(Arg1, b1, b2, b3); 617 | gpu.vRam.memory[currentPos++] = b1; 618 | gpu.vRam.memory[currentPos++] = b2; 619 | 620 | i++; 621 | line++; 622 | }else if (instruction == "loadB") { 623 | std::string arg1 = code[i + 1]; 624 | 625 | gpu.vRam.memory[currentPos++] = 28; 626 | 627 | int Arg1; 628 | checkArgType(Arg1, arg1, gpu, vars, varValues); 629 | 630 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 631 | 632 | byte b1, b2, b3; 633 | convertByte(Arg1, b1, b2, b3); 634 | gpu.vRam.memory[currentPos++] = b1; 635 | gpu.vRam.memory[currentPos++] = b2; 636 | 637 | i++; 638 | line++; 639 | }else if (instruction == "kernel_size") { 640 | std::string arg1 = code[i + 1]; 641 | std::string arg2 = code[i + 2]; 642 | 643 | int xSize = std::stoi(arg1); 644 | int ySize = std::stoi(arg2); 645 | 646 | for (int y = 0; y < ySize; y++) { 647 | for (int x = 0; x < xSize; x++) { 648 | task_id tmp; 649 | tmp.x = x; 650 | tmp.y = y; 651 | gpu.tasks.push_back(tmp); 652 | } 653 | } 654 | 655 | auto rng = std::default_random_engine {}; 656 | std::shuffle(gpu.tasks.begin(), gpu.tasks.end(), rng); 657 | 658 | i += 2; 659 | line++; 660 | }else if (instruction == "load0_8g") { 661 | std::string arg1 = code[i + 1]; 662 | 663 | gpu.vRam.memory[currentPos++] = 35; 664 | 665 | int Arg1; 666 | checkArgTypeV(Arg1, arg1, gpu, vNames, vValues); 667 | 668 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 669 | 670 | byte b1, b2, b3; 671 | convertByte(Arg1, b1, b2, b3); 672 | gpu.vRam.memory[currentPos++] = b1; 673 | gpu.vRam.memory[currentPos++] = b2; 674 | 675 | i++; 676 | line++; 677 | }else if (instruction == "load1_8g") { 678 | std::string arg1 = code[i + 1]; 679 | 680 | gpu.vRam.memory[currentPos++] = 36; 681 | 682 | int Arg1; 683 | checkArgTypeV(Arg1, arg1, gpu, vNames, vValues); 684 | 685 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 686 | 687 | byte b1, b2, b3; 688 | convertByte(Arg1, b1, b2, b3); 689 | gpu.vRam.memory[currentPos++] = b1; 690 | gpu.vRam.memory[currentPos++] = b2; 691 | 692 | i++; 693 | line++; 694 | }else if (instruction == "load0_16g") { 695 | std::string arg1 = code[i + 1]; 696 | 697 | gpu.vRam.memory[currentPos++] = 33; 698 | 699 | int Arg1; 700 | checkArgTypeV(Arg1, arg1, gpu, vNames, vValues); 701 | 702 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 703 | 704 | byte b1, b2, b3; 705 | convertByte(Arg1, b1, b2, b3); 706 | gpu.vRam.memory[currentPos++] = b1; 707 | gpu.vRam.memory[currentPos++] = b2; 708 | 709 | i++; 710 | line++; 711 | }else if (instruction == "load1_16g") { 712 | std::string arg1 = code[i + 1]; 713 | 714 | gpu.vRam.memory[currentPos++] = 34; 715 | 716 | int Arg1; 717 | checkArgTypeV(Arg1, arg1, gpu, vNames, vValues); 718 | 719 | if(checkArgSize(Arg1, 1, instruction, i, 65535) == true) { break; } 720 | 721 | byte b1, b2, b3; 722 | convertByte(Arg1, b1, b2, b3); 723 | gpu.vRam.memory[currentPos++] = b1; 724 | gpu.vRam.memory[currentPos++] = b2; 725 | 726 | i++; 727 | line++; 728 | }else if (instruction == "max") { 729 | std::string arg1 = code[i + 1]; 730 | std::string arg2 = code[i + 2]; 731 | std::string arg3 = code[i + 3]; 732 | 733 | gpu.vRam.memory[currentPos++] = 37; 734 | 735 | int Arg1; 736 | checkArgType(Arg1, arg1, gpu, vars, varValues); 737 | 738 | int Arg2; 739 | checkArgType(Arg2, arg2, gpu, vars, varValues); 740 | 741 | int Arg3; 742 | checkArgType(Arg3, arg3, gpu, vars, varValues); 743 | 744 | byte b1, b2, b3; 745 | convertByte(Arg1, b1, b2, b3); 746 | gpu.vRam.memory[currentPos++] = b1; 747 | gpu.vRam.memory[currentPos++] = b2; 748 | 749 | byte b4, b5, b6; 750 | convertByte(Arg2, b4, b5, b6); 751 | gpu.vRam.memory[currentPos++] = b4; 752 | gpu.vRam.memory[currentPos++] = b5; 753 | 754 | byte b7, b8, b9; 755 | convertByte(Arg3, b7, b8, b9); 756 | gpu.vRam.memory[currentPos++] = b7; 757 | gpu.vRam.memory[currentPos++] = b8; 758 | 759 | i += 3; 760 | line++; 761 | }else if (instruction == "min") { 762 | std::string arg1 = code[i + 1]; 763 | std::string arg2 = code[i + 2]; 764 | std::string arg3 = code[i + 3]; 765 | 766 | gpu.vRam.memory[currentPos++] = 38; 767 | 768 | int Arg1; 769 | checkArgType(Arg1, arg1, gpu, vars, varValues); 770 | 771 | int Arg2; 772 | checkArgType(Arg2, arg2, gpu, vars, varValues); 773 | 774 | int Arg3; 775 | checkArgType(Arg3, arg3, gpu, vars, varValues); 776 | 777 | byte b1, b2, b3; 778 | convertByte(Arg1, b1, b2, b3); 779 | gpu.vRam.memory[currentPos++] = b1; 780 | gpu.vRam.memory[currentPos++] = b2; 781 | 782 | byte b4, b5, b6; 783 | convertByte(Arg2, b4, b5, b6); 784 | gpu.vRam.memory[currentPos++] = b4; 785 | gpu.vRam.memory[currentPos++] = b5; 786 | 787 | byte b7, b8, b9; 788 | convertByte(Arg3, b7, b8, b9); 789 | gpu.vRam.memory[currentPos++] = b7; 790 | gpu.vRam.memory[currentPos++] = b8; 791 | 792 | i += 3; 793 | line++; 794 | }else{ 795 | if (instruction.back() == ':') { 796 | line++; 797 | }else{ 798 | std::cout << "Unknown instruction >" << instruction << "< at line " << line << '\n'; 799 | std::cout << '\n'; 800 | std::cout << lines[line] << '\n'; 801 | std::cout << "^" << '\n'; 802 | std::cout << '\n'; 803 | std::cout << "Compilation terminated." << '\n'; 804 | gpu.vRam.Clear(); 805 | break; 806 | } 807 | } 808 | 809 | } 810 | 811 | } 812 | 813 | std::cout << "GPU program size is: " << currentPos << " bytes" << '\n'; 814 | std::cout << '\n'; 815 | } 816 | } -------------------------------------------------------------------------------- /VirtualPCCpp/GPUAssembly.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "CPU.h" 12 | #include "GPU.h" 13 | #include "GPUCore.h" 14 | 15 | typedef unsigned char byte; 16 | 17 | namespace GPUAssembly { 18 | void Compile(std::vector& code, GPU& cpu, std::vector& vValues, std::vector& vNames, int newCP); 19 | void readFile(std::string path, std::vector& code); 20 | } -------------------------------------------------------------------------------- /VirtualPCCpp/GPUCore.cpp: -------------------------------------------------------------------------------- 1 | #include "GPUCore.h" 2 | 3 | GPUCore::GPUCore(Memory& vRam_, SDLWindow* screen_, int intMemSize, int idX_, int idY_) 4 | : 5 | vRam(vRam_), 6 | screen(screen_), 7 | halt(true), 8 | idX(idX_), 9 | intMem(Memory(intMemSize)), 10 | idY(idY_) 11 | {} 12 | 13 | void GPUCore::tick() { 14 | if (halt == false) { 15 | registerOP = vRam.memory[programCounter]; 16 | execute(registerOP); 17 | } 18 | } 19 | 20 | int GPUCore::checkArgumentV(int source, int size) { 21 | if ((unsigned int)source <= vRam.memory.size()) { 22 | if(size == 1) { return vRam.memory[source] & 0xFF; } 23 | if(size == 2) { return (vRam.memory[source + 1] << 8 | (vRam.memory[source] & 0xFF)); } 24 | }else { 25 | return 0; 26 | } 27 | } 28 | 29 | int GPUCore::checkArgumentInt(int source, int size) { 30 | if ((unsigned int)source <= intMem.memory.size()) { 31 | if(size == 1) { return intMem.memory[source] & 0xFF; } 32 | if(size == 2) { return intMem.memory[source + 1] << 8 | (intMem.memory[source] & 0xFF); } 33 | }else if (source == intMem.memory.size() + 1) { 34 | return register0; 35 | }else if (source == intMem.memory.size() + 2) { 36 | return register1; 37 | }else if (source == intMem.memory.size() + 3) { 38 | return idX; 39 | }else if (source == intMem.memory.size() + 4) { 40 | return idY; 41 | }else { 42 | return 0; 43 | } 44 | } 45 | 46 | void GPUCore::execute(int registerOP) { 47 | int inst = registerOP; 48 | 49 | switch (inst) { 50 | case 0: { 51 | halt = true; 52 | break; } 53 | 54 | case 1: { //Load to register0 from ram, 2 bytes 55 | byte arg1 = vRam.memory[programCounter + 1]; 56 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 57 | register0 = checkArgumentInt(memPos, 2); 58 | programCounter += 2; 59 | programCounter++; 60 | break; } 61 | 62 | case 2: { //Load to register1 from ram, 2 bytes 63 | byte arg1 = vRam.memory[programCounter + 1]; 64 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 65 | register1 = checkArgumentInt(memPos, 2); 66 | programCounter += 2; 67 | programCounter++; 68 | break; } 69 | 70 | case 3: { //Load to register0 from ram, 1 byte 71 | byte arg1 = vRam.memory[programCounter + 1]; 72 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 73 | register0 = checkArgumentInt(memPos, 1); 74 | programCounter += 2; 75 | programCounter++; 76 | break; } 77 | 78 | case 4: { //Load to register1 from ram, 1 byte 79 | byte arg1 = vRam.memory[programCounter + 1]; 80 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 81 | register1 = checkArgumentInt(memPos, 1); 82 | programCounter += 2; 83 | programCounter++; 84 | break; } 85 | 86 | case 5: { //Write from register0 to ram 2 bytes 87 | byte arg1 = vRam.memory[programCounter + 1]; 88 | int position = vRam.memory[programCounter + 2] << 8 | arg1; 89 | intMem.memory[position] = (register0 & 0xFF); 90 | intMem.memory[position + 1] = (byte)(register0 >> 8); 91 | programCounter += 2; 92 | programCounter++; 93 | break; } 94 | 95 | case 6: { //Write from register1 to ram 2 bytes 96 | byte arg1 = vRam.memory[programCounter + 1]; 97 | int position = vRam.memory[programCounter + 2] << 8 | arg1; 98 | intMem.memory[position] = (register1 & 0xFF); 99 | intMem.memory[position + 1] = (byte)(register1 >> 8); 100 | programCounter += 2; 101 | programCounter++; 102 | break; } 103 | 104 | case 7: { //Write from register0 to ram 1 byte 105 | byte arg1 = vRam.memory[programCounter + 1]; 106 | int position = vRam.memory[programCounter + 2] << 8 | arg1; 107 | intMem.memory[position] = (register0 & 0xFF); 108 | programCounter += 2; 109 | programCounter++; 110 | break; } 111 | 112 | case 8: { //Write from register1 to ram 1 byte 113 | byte arg1 = vRam.memory[programCounter + 1]; 114 | int position = vRam.memory[programCounter + 2] << 8 | arg1; 115 | intMem.memory[position] = (register1 & 0xFF); 116 | programCounter += 2; 117 | programCounter++; 118 | break; } 119 | 120 | case 10: { //Add register0 and register1 121 | register0 = register0 + register1; 122 | programCounter++; 123 | break; } 124 | 125 | case 11: { //Subtract register1 from register0 126 | register0 = register0 - register1; 127 | programCounter++; 128 | break; } 129 | 130 | case 12: { //Multiply register0 and register1 131 | register0 = register0 * register1; 132 | programCounter++; 133 | break; } 134 | 135 | case 13: { //Divide register0 by register1 136 | register0 = register0 / register1; 137 | programCounter++; 138 | break; } 139 | 140 | case 14: { //Check if register0 is greater than register1 141 | register0 = register0 > register1; 142 | programCounter++; 143 | break; } 144 | 145 | case 15: { //Check if register0 is greater or equal to register1 146 | register0 = register0 >= register1; 147 | programCounter++; 148 | break; } 149 | 150 | case 16: { //Check if register1 is greater than register0 151 | register0 = register0 < register1; 152 | programCounter++; 153 | break; } 154 | 155 | case 17: { //Check if register1 is greater or equal to register0 156 | register0 = register0 <= register1; 157 | programCounter++; 158 | break; } 159 | 160 | case 18: { //Check if register0 and register1 have same values 161 | register0 = register0 == register1; 162 | programCounter++; 163 | break; } 164 | 165 | case 19: { //Check if register0 is different than register1 166 | register0 = register0 != register1; 167 | programCounter++; 168 | break; } 169 | 170 | case 20: { //Jump to place in code 171 | byte arg1 = vRam.memory[programCounter + 1]; 172 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 173 | 174 | programCounter = memPos; 175 | break; } 176 | 177 | case 21: { //Compare to true/false 178 | byte condition = vRam.memory[programCounter + 1]; 179 | byte arg1 = vRam.memory[programCounter + 2]; 180 | int position = vRam.memory[programCounter + 3] << 8 | arg1; 181 | if (register0 == condition) { 182 | programCounter += 3; 183 | programCounter++; 184 | }else if(register0 != condition){ 185 | programCounter = position; 186 | } 187 | break; } 188 | 189 | case 26: { //Load to register1 from ram, 1 byte 190 | byte arg1 = vRam.memory[programCounter + 1]; 191 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 192 | regR = checkArgumentInt(memPos, 1); 193 | programCounter += 2; 194 | programCounter++; 195 | break; } 196 | 197 | case 27: { //Load to register1 from ram, 1 byte 198 | byte arg1 = vRam.memory[programCounter + 1]; 199 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 200 | regG = checkArgumentInt(memPos, 1); 201 | programCounter += 2; 202 | programCounter++; 203 | break; } 204 | 205 | case 28: { //Load to register1 from ram, 1 byte 206 | byte arg1 = vRam.memory[programCounter + 1]; 207 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 208 | regB = checkArgumentInt(memPos, 1); 209 | programCounter += 2; 210 | programCounter++; 211 | break; } 212 | 213 | case 29: { //Check if register0 is greater or equal to register1 214 | int x = static_cast(register0 >> 32) | static_cast(register0 >> 24) | static_cast(register0 >> 16) | static_cast(register0 >> 8) | static_cast(register0 >> 0xff); 215 | int y = static_cast(register1 >> 32) | static_cast(register1 >> 24) | static_cast(register1 >> 16) | static_cast(register1 >> 8) | static_cast(register1 >> 0xff); 216 | 217 | register0 = x >= y; 218 | programCounter++; 219 | break; } 220 | 221 | case 30: { //Color a single pixel on screen 222 | screen->pixels[register1 * 320 + register0] = int(regB << 16) | int(regG << 8) | int(regR); 223 | 224 | programCounter++; 225 | break; } 226 | 227 | case 31: { //Get core id 228 | register0 = idX; 229 | programCounter++; 230 | break; } 231 | 232 | case 32: { //Get core id 233 | register0 = idY; 234 | programCounter++; 235 | break; } 236 | 237 | case 33: { //Load to register0 from ram, 2 bytes 238 | byte arg1 = vRam.memory[programCounter + 1]; 239 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 240 | register0 = checkArgumentV(memPos, 2); 241 | programCounter += 2; 242 | programCounter++; 243 | break; } 244 | 245 | case 34: { //Load to register1 from ram, 2 bytes 246 | byte arg1 = vRam.memory[programCounter + 1]; 247 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 248 | register1 = checkArgumentV(memPos, 2); 249 | programCounter += 2; 250 | programCounter++; 251 | break; } 252 | 253 | case 35: { //Load to register0 from ram, 1 byte 254 | byte arg1 = vRam.memory[programCounter + 1]; 255 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 256 | register0 = checkArgumentV(memPos, 1); 257 | programCounter += 2; 258 | programCounter++; 259 | break; } 260 | 261 | case 36: { //Load to register1 from ram, 1 byte 262 | byte arg1 = vRam.memory[programCounter + 1]; 263 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 264 | register1 = checkArgumentV(memPos, 1); 265 | programCounter += 2; 266 | programCounter++; 267 | break; } 268 | 269 | case 37: { 270 | byte arg1 = vRam.memory[programCounter + 1]; 271 | byte arg2 = vRam.memory[programCounter + 3]; 272 | byte arg3 = vRam.memory[programCounter + 5]; 273 | 274 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 275 | int memPos2 = vRam.memory[programCounter + 4] << 8 | arg2; 276 | int memPos3 = vRam.memory[programCounter + 6] << 8 | arg3; 277 | 278 | int v1 = checkArgumentInt(memPos, 2); 279 | int v2 = checkArgumentInt(memPos2, 2); 280 | int v3 = checkArgumentInt(memPos3, 2); 281 | 282 | register0 = std::max({v1, v2, v3}); 283 | 284 | programCounter += 6; 285 | programCounter++; 286 | break; } 287 | 288 | case 38: { 289 | byte arg1 = vRam.memory[programCounter + 1]; 290 | byte arg2 = vRam.memory[programCounter + 3]; 291 | byte arg3 = vRam.memory[programCounter + 5]; 292 | 293 | int memPos = vRam.memory[programCounter + 2] << 8 | arg1; 294 | int memPos2 = vRam.memory[programCounter + 4] << 8 | arg2; 295 | int memPos3 = vRam.memory[programCounter + 6] << 8 | arg3; 296 | 297 | int v1 = checkArgumentInt(memPos, 2); 298 | int v2 = checkArgumentInt(memPos2, 2); 299 | int v3 = checkArgumentInt(memPos3, 2); 300 | 301 | register0 = std::min({v1, v2, v3}); 302 | 303 | programCounter += 6; 304 | programCounter++; 305 | break; } 306 | 307 | } 308 | } -------------------------------------------------------------------------------- /VirtualPCCpp/GPUCore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "Memory.h" 8 | #include "SDLWindow.h" 9 | 10 | typedef unsigned char byte; 11 | 12 | class GPUCore { 13 | public: 14 | Memory& vRam; 15 | Memory intMem; 16 | SDLWindow* screen; 17 | int registerOP; 18 | int register0; 19 | int register1; 20 | int programCounter; 21 | byte regR, regG, regB; 22 | int idX; 23 | int idY; 24 | bool halt; 25 | 26 | GPUCore(Memory&, SDLWindow*, int, int, int); 27 | int checkArgumentV(int, int); 28 | int checkArgumentInt(int, int); 29 | void execute(int); 30 | void tick(); 31 | }; -------------------------------------------------------------------------------- /VirtualPCCpp/GPU_Program.txt: -------------------------------------------------------------------------------- 1 | data_s 2 | u16 minX 0 3 | u16 maxX 0 4 | u16 minY 0 5 | u16 maxY 0 6 | 7 | u8 two 2 8 | u8 one 1 9 | u8 zero 0 10 | 11 | u8 white 255 12 | 13 | u16 posX 0 14 | u16 posY 0 15 | 16 | u16 w0 0 17 | u16 w1 0 18 | u16 w2 0 19 | 20 | u16 x1f 0 21 | u16 y1f 0 22 | u16 x2f 0 23 | u16 y2f 0 24 | u16 x3f 0 25 | u16 y3f 0 26 | 27 | u16 a 0 28 | u16 b 0 29 | u16 c 0 30 | u16 d 0 31 | u16 e 0 32 | u16 f 0 33 | data_e 34 | 35 | kernel_size 201 201 36 | 37 | 38 | load0_16g x1 39 | wrt0_16 x1f 40 | 41 | load0_16g x2 42 | wrt0_16 x2f 43 | 44 | load0_16g x3 45 | wrt0_16 x3f 46 | 47 | 48 | load0_16g y1 49 | wrt0_16 y1f 50 | 51 | load0_16g y2 52 | wrt0_16 y2f 53 | 54 | load0_16g y3 55 | wrt0_16 y3f 56 | 57 | 58 | 59 | max x1f x2f x3f 60 | wrt0_16 maxX 61 | 62 | min x1f x2f x3f 63 | wrt0_16 minX 64 | 65 | 66 | max y1f y2f y3f 67 | wrt0_16 maxY 68 | 69 | min y1f y2f y3f 70 | wrt0_16 minY 71 | 72 | 73 | get_idx 74 | wrt0_16 posX 75 | 76 | get_idy 77 | wrt0_16 posY 78 | 79 | 80 | 81 | 82 | load0_16 x3f 83 | load1_16 x2f 84 | sub 85 | wrt0_16 a 86 | 87 | load0_16 posY 88 | load1_16 y2f 89 | sub 90 | wrt0_16 b 91 | 92 | 93 | load0_16 y3f 94 | load1_16 y2f 95 | sub 96 | wrt0_16 c 97 | 98 | load0_16 posX 99 | load1_16 x2f 100 | sub 101 | wrt0_16 d 102 | 103 | 104 | load0_16 a 105 | load1_16 b 106 | mlt 107 | wrt0_16 e 108 | 109 | load0_16 c 110 | load1_16 d 111 | mlt 112 | wrt0_16 f 113 | 114 | 115 | load0_16 e 116 | load1_16 f 117 | sub 118 | wrt0_16 w0 119 | 120 | 121 | 122 | 123 | load0_16 x1f 124 | load1_16 x3f 125 | sub 126 | wrt0_16 a 127 | 128 | load0_16 posY 129 | load1_16 y3f 130 | sub 131 | wrt0_16 b 132 | 133 | 134 | load0_16 y1f 135 | load1_16 y3f 136 | sub 137 | wrt0_16 c 138 | 139 | load0_16 posX 140 | load1_16 x3f 141 | sub 142 | wrt0_16 d 143 | 144 | 145 | load0_16 a 146 | load1_16 b 147 | mlt 148 | wrt0_16 e 149 | 150 | load0_16 c 151 | load1_16 d 152 | mlt 153 | wrt0_16 f 154 | 155 | 156 | load0_16 e 157 | load1_16 f 158 | sub 159 | wrt0_16 w1 160 | 161 | 162 | 163 | 164 | load0_16 x2f 165 | load1_16 x1f 166 | sub 167 | wrt0_16 a 168 | 169 | load0_16 posY 170 | load1_16 y1f 171 | sub 172 | wrt0_16 b 173 | 174 | 175 | load0_16 y2f 176 | load1_16 y1f 177 | sub 178 | wrt0_16 c 179 | 180 | load0_16 posX 181 | load1_16 x1f 182 | sub 183 | wrt0_16 d 184 | 185 | 186 | load0_16 a 187 | load1_16 b 188 | mlt 189 | wrt0_16 e 190 | 191 | load0_16 c 192 | load1_16 d 193 | mlt 194 | wrt0_16 f 195 | 196 | 197 | load0_16 e 198 | load1_16 f 199 | sub 200 | wrt0_16 w2 201 | 202 | 203 | 204 | load0_16 w0 205 | load1_8 zero 206 | reg0_be_s 207 | cmp 1 part1 208 | 209 | load0_16 w1 210 | load1_8 zero 211 | reg0_be_s 212 | cmp 1 part2 213 | 214 | load0_16 w2 215 | load1_8 zero 216 | reg0_be_s 217 | cmp 1 part3 218 | 219 | loadR posX 220 | loadG zero 221 | loadB posY 222 | 223 | get_idx 224 | load1_16 posY 225 | 226 | p_out 227 | 228 | part3: 229 | 230 | part2: 231 | 232 | part1: 233 | -------------------------------------------------------------------------------- /VirtualPCCpp/HDD.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 22 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 23 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 26 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 28 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 29 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 31 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 34 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 38 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 39 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 42 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 45 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 46 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 47 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 51 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 52 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 53 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 54 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 56 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 57 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 58 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 63 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 64 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 65 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 66 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 67 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 68 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 69 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 70 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 71 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 72 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 73 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 74 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 75 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 76 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 78 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 79 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 81 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 82 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 84 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 86 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 87 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 88 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 90 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 91 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 92 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 93 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 94 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 95 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 98 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 99 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 101 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 102 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 103 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 104 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 105 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 106 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 107 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 108 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 109 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 110 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 111 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 112 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 113 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 114 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 115 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 116 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 117 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 118 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 120 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 121 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 122 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 123 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 125 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 126 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 129 | -------------------------------------------------------------------------------- /VirtualPCCpp/KeyboardInputExample.txt: -------------------------------------------------------------------------------- 1 | data_s 2 | u8 x 0 3 | u8 x2 0 4 | u8 down 66 5 | u8 space 67 6 | u8a target 11 84 80 73 69 87 73 67 91 83 86 79 //Little easter egg here :) 7 | u8a current 11 0 0 0 0 0 0 0 0 0 0 0 8 | u8 y 0 9 | u8 one 1 10 | u8 char 0 11 | u8 enter 95 12 | u8 back 96 13 | u8 zero 0 14 | u8 three 11 15 | u8 n 82 16 | u8 o 83 17 | data_e 18 | 19 | inter_s 20 | load0_8 REG_INT 21 | 22 | load1_8 back 23 | reg_eql 24 | cmp 1 forward 25 | load0_8 zero 26 | wrt0_8a current x 27 | load0_8 x 28 | load1_8 one 29 | sub 30 | wrt0_8 x 31 | load0_8 space 32 | cs_out0 x2 y 33 | load0_8 x2 34 | load1_8 one 35 | sub 36 | wrt0_8 x2 37 | jmp return 38 | 39 | forward: 40 | load0_8 REG_INT 41 | load1_8 enter 42 | reg_eql 43 | cmp 1 forward2 44 | 45 | load0_8 three 46 | cmp_a target current 47 | cmp 1 forward3 48 | load0_8 space 49 | cs_out0 x2 y 50 | load0_8 y 51 | load1_8 one 52 | sum 53 | wrt0_8 y 54 | load0_8 zero 55 | wrt0_8 x 56 | load0_8 n 57 | cs_out0 x y 58 | load0_8 x 59 | load1_8 one 60 | sum 61 | wrt0_8 x 62 | load0_8 o 63 | cs_out0 x y 64 | load0_8 y 65 | load1_8 one 66 | sum 67 | wrt0_8 y 68 | load0_8 zero 69 | wrt0_8 x 70 | wrt0_8 x2 71 | jmp return 72 | 73 | forward3: 74 | load0_8 space 75 | cs_out0 x2 y 76 | load0_8 zero 77 | wrt0_8 x 78 | wrt0_8 x2 79 | load0_8 y 80 | load1_8 one 81 | sum 82 | wrt0_8 y 83 | jmp return 84 | 85 | forward2: 86 | load0_8 REG_INT 87 | wrt0_8a current x 88 | load0_8 REG_INT 89 | cs_out0 x y 90 | load0_8 x 91 | load1_8 one 92 | sum 93 | wrt0_8 x 94 | load0_8 x2 95 | load1_8 one 96 | sum 97 | wrt0_8 x2 98 | inter_e 99 | 100 | return: 101 | load0_8 down 102 | cs_out0 x2 y 103 | clr_comm 104 | clr_vram 105 | jmp return 106 | 107 | stop -------------------------------------------------------------------------------- /VirtualPCCpp/Main.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #endif 4 | 5 | #ifdef __linux 6 | #include 7 | #endif 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "NSSDL.h" 14 | #include "SDLWindow.h" 15 | #include "Memory.h" 16 | #include "CPU.h" 17 | #include "PC.h" 18 | #include "GPU.h" 19 | #include "Assembly.h" 20 | #include "GPUAssembly.h" 21 | 22 | int width = 320; 23 | int height = 240; 24 | 25 | bool quit = false; 26 | 27 | typedef unsigned char byte; 28 | 29 | int main(int argc, char* argv[]) { 30 | SDL_Event event; 31 | 32 | SDL_Window* window2; 33 | SDL_Surface* surface2; 34 | SDL_Surface* pixelSpace2; 35 | SDL_Renderer* renderer2; 36 | SDL_Texture* texture2; 37 | unsigned int* pixels2; 38 | 39 | SDLWindow pc1W(window2, surface2, pixelSpace2, renderer2, texture2, pixels2); 40 | 41 | Memory ram1(64000); 42 | Memory hdd1(128 * 128); 43 | 44 | GPU gpu1(4096, 64000, 256, 16384, &pc1W, ram1); 45 | 46 | NSSDL::initSDL(gpu1.screen, width, height); 47 | 48 | CPU cpu1(128, 128, ram1, hdd1, gpu1); 49 | 50 | std::vector code; 51 | std::vector gpu_code; 52 | 53 | std::vector vValues; 54 | std::vector vNames; 55 | int addMem = 0; 56 | 57 | Assembly::readFile("Program.txt", code); 58 | 59 | Assembly::Compile(code, cpu1, vValues, vNames, addMem); 60 | 61 | GPUAssembly::readFile("GPU_Program.txt", gpu_code); 62 | 63 | GPUAssembly::Compile(gpu_code, gpu1, vValues, vNames, addMem); 64 | 65 | //std::cout << (int)gpu1.vRam.memory[0] << " " << (int)gpu1.vRam.memory[1] << '\n'; 66 | 67 | PC pc1(cpu1, ram1, hdd1, gpu1.screen); 68 | 69 | int count = 0; 70 | 71 | bool shift = false; 72 | bool caps_lock = false; 73 | bool space = false; 74 | 75 | while (quit == false) { 76 | while (SDL_PollEvent(&event)) { 77 | switch (event.type) { 78 | case SDL_QUIT: 79 | quit = true; 80 | break; 81 | case SDL_KEYDOWN: 82 | switch (event.key.keysym.sym) { 83 | case SDLK_LSHIFT: shift = !shift; std::cout << "Shift is: " << shift << '\n'; break; 84 | case SDLK_RSHIFT: shift = !shift; std::cout << "Shift is: " << shift << '\n';break; 85 | case SDLK_CAPSLOCK: caps_lock = !caps_lock; std::cout << "Caps Lock is: " << caps_lock << '\n';break; 86 | case SDLK_1: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 10; } else { pc1.cpu.interruptRegister = 1; } break; 87 | case SDLK_2: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 68; } else { pc1.cpu.interruptRegister = 2; } break; 88 | case SDLK_3: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 12; } else { pc1.cpu.interruptRegister = 3; } break; 89 | case SDLK_4: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 13; } else { pc1.cpu.interruptRegister = 4; } break; 90 | case SDLK_5: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 14; } else { pc1.cpu.interruptRegister = 5; } break; 91 | case SDLK_6: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 37; } else { pc1.cpu.interruptRegister = 6; } break; 92 | case SDLK_7: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 15; } else { pc1.cpu.interruptRegister = 7; } break; 93 | case SDLK_8: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 19; } else { pc1.cpu.interruptRegister = 8; } break; 94 | case SDLK_9: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 17; } else { pc1.cpu.interruptRegister = 9; } break; 95 | case SDLK_0: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 18; } else { pc1.cpu.interruptRegister = 0; } break; 96 | case SDLK_PERIOD: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 29; } else { pc1.cpu.interruptRegister = 23; } break; 97 | case SDLK_COMMA: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 28; } else { pc1.cpu.interruptRegister = 22; } break; 98 | case SDLK_a: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 40; } else { pc1.cpu.interruptRegister = 69; } break; 99 | case SDLK_b: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 41; } else { pc1.cpu.interruptRegister = 70; } break; 100 | case SDLK_c: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 42; } else { pc1.cpu.interruptRegister = 71; } break; 101 | case SDLK_d: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 43; } else { pc1.cpu.interruptRegister = 72; } break; 102 | case SDLK_e: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 44; } else { pc1.cpu.interruptRegister = 73; } break; 103 | case SDLK_f: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 45; } else { pc1.cpu.interruptRegister = 74; } break; 104 | case SDLK_g: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 46; } else { pc1.cpu.interruptRegister = 75; } break; 105 | case SDLK_h: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 47; } else { pc1.cpu.interruptRegister = 76; } break; 106 | case SDLK_i: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 48; } else { pc1.cpu.interruptRegister = 77; } break; 107 | case SDLK_j: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 49; } else { pc1.cpu.interruptRegister = 78; } break; 108 | case SDLK_k: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 50; } else { pc1.cpu.interruptRegister = 79; } break; 109 | case SDLK_l: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 51; } else { pc1.cpu.interruptRegister = 80; } break; 110 | case SDLK_m: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 52; } else { pc1.cpu.interruptRegister = 81; } break; 111 | case SDLK_n: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 53; } else { pc1.cpu.interruptRegister = 82; } break; 112 | case SDLK_o: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 54; } else { pc1.cpu.interruptRegister = 83; } break; 113 | case SDLK_p: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 55; } else { pc1.cpu.interruptRegister = 84; } break; 114 | case SDLK_q: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 56; } else { pc1.cpu.interruptRegister = 85; } break; 115 | case SDLK_r: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 57; } else { pc1.cpu.interruptRegister = 86; } break; 116 | case SDLK_s: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 58; } else { pc1.cpu.interruptRegister = 87; } break; 117 | case SDLK_t: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 59; } else { pc1.cpu.interruptRegister = 88; } break; 118 | case SDLK_u: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 60; } else { pc1.cpu.interruptRegister = 89; } break; 119 | case SDLK_v: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 61; } else { pc1.cpu.interruptRegister = 90; } break; 120 | case SDLK_w: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 62; } else { pc1.cpu.interruptRegister = 91; } break; 121 | case SDLK_x: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 63; } else { pc1.cpu.interruptRegister = 92; } break; 122 | case SDLK_y: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 64; } else { pc1.cpu.interruptRegister = 93; } break; 123 | case SDLK_z: pc1.cpu.interrupted = true; if(caps_lock == true) { pc1.cpu.interruptRegister = 65; } else { pc1.cpu.interruptRegister = 94; } break; 124 | case SDLK_MINUS: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 66; } else { pc1.cpu.interruptRegister = 21; } break; 125 | case SDLK_PLUS: pc1.cpu.interrupted = true; if(shift == true) { pc1.cpu.interruptRegister = 30; } else { pc1.cpu.interruptRegister = 20; } break; 126 | case SDLK_BACKSPACE: pc1.cpu.interrupted = true; pc1.cpu.interruptRegister = 96; break; 127 | case SDLK_SPACE: pc1.cpu.interrupted = true; pc1.cpu.interruptRegister = 67; space = !space; break; 128 | case SDLK_RETURN: pc1.cpu.interrupted = true; pc1.cpu.interruptRegister = 95; break; 129 | } 130 | break; 131 | } 132 | 133 | } 134 | 135 | if (space) { 136 | pc1.cpu.tick(); 137 | gpu1.tick(); 138 | } 139 | NSSDL::updateSDL(pc1.screen); 140 | } 141 | 142 | SDL_Quit(); 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /VirtualPCCpp/Memory.cpp: -------------------------------------------------------------------------------- 1 | #include "Memory.h" 2 | 3 | Memory::Memory(int size) { 4 | memory.resize(size); 5 | Clear(); 6 | } 7 | 8 | void Memory::Clear() { 9 | for (unsigned int i = 0; i < memory.size(); i++) { 10 | memory[(int)i] = 0; 11 | } 12 | } 13 | 14 | bool Memory::Empty() { 15 | for (unsigned int i = 0; i < memory.size(); i++) { 16 | if (memory[(int)i] != 0) { 17 | return false; 18 | } 19 | } 20 | return true; 21 | } 22 | -------------------------------------------------------------------------------- /VirtualPCCpp/Memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | typedef unsigned char byte; 7 | typedef uint16_t u16; 8 | 9 | class Memory { 10 | public: 11 | std::vector memory; 12 | 13 | Memory(int); 14 | 15 | void Clear(); 16 | bool Empty(); 17 | }; -------------------------------------------------------------------------------- /VirtualPCCpp/NSSDL.cpp: -------------------------------------------------------------------------------- 1 | #include "NSSDL.h" 2 | 3 | 4 | namespace NSSDL{ 5 | int initSDL(SDLWindow* window, int& width, int& height) { 6 | window->window = nullptr; 7 | window->surface = nullptr; 8 | window->renderer = nullptr; 9 | window->texture = nullptr; 10 | window->pixelSpace = nullptr; 11 | 12 | window->window = SDL_CreateWindow("Virtual PC", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN); 13 | window->surface = SDL_GetWindowSurface(window->window); 14 | window->pixelSpace = SDL_CreateRGBSurface(0, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); 15 | window->pixels = (unsigned int*)window->pixelSpace->pixels; 16 | window->renderer = SDL_CreateRenderer(window->window, -1, SDL_RENDERER_ACCELERATED); 17 | window->texture = SDL_CreateTexture(window->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); 18 | 19 | return 0; 20 | } 21 | 22 | void updateSDL(SDLWindow* window) { 23 | SDL_UpdateTexture(window->texture, NULL, window->pixels, window->pixelSpace->pitch); 24 | SDL_RenderClear(window->renderer); 25 | SDL_RenderCopy(window->renderer, window->texture, NULL, NULL); 26 | SDL_RenderPresent(window->renderer); 27 | } 28 | 29 | void cleanSDL(SDLWindow* window) { 30 | SDL_DestroyTexture(window->texture); 31 | SDL_DestroyRenderer(window->renderer); 32 | SDL_DestroyWindow(window->window); 33 | } 34 | } -------------------------------------------------------------------------------- /VirtualPCCpp/NSSDL.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SDLWindow.h" 4 | 5 | namespace NSSDL { 6 | int initSDL(SDLWindow* window, int& width, int &height); 7 | void updateSDL(SDLWindow* window); 8 | void cleanSDL(SDLWindow* window); 9 | } -------------------------------------------------------------------------------- /VirtualPCCpp/PC.cpp: -------------------------------------------------------------------------------- 1 | #include "PC.h" 2 | 3 | PC::PC(CPU cpu_, Memory ram_, Memory hdd_, SDLWindow* screen_) 4 | : 5 | cpu(cpu_), 6 | ram(ram_), 7 | hdd(hdd_), 8 | screen(screen_) 9 | {} -------------------------------------------------------------------------------- /VirtualPCCpp/PC.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SDLWindow.h" 4 | #include "Memory.h" 5 | #include "CPU.h" 6 | 7 | typedef unsigned char byte; 8 | 9 | class PC { 10 | public: 11 | CPU cpu; 12 | Memory ram; 13 | Memory hdd; 14 | SDLWindow* screen; 15 | 16 | PC(CPU, Memory, Memory, SDLWindow*); 17 | }; -------------------------------------------------------------------------------- /VirtualPCCpp/Program.txt: -------------------------------------------------------------------------------- 1 | data_s 2 | g8 f 5 3 | g16 x1 30 4 | g16 y1 200 5 | g16 x2 100 6 | g16 y2 25 7 | g16 x3 200 8 | g16 y3 120 9 | data_e 10 | 11 | inter_s 12 | inter_e 13 | 14 | gpu_str 15 | 16 | stop -------------------------------------------------------------------------------- /VirtualPCCpp/SDLWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "SDLWindow.h" 2 | 3 | SDLWindow::SDLWindow(SDL_Window* window_, SDL_Surface* surface_, SDL_Surface* pixelSpace_, SDL_Renderer* renderer_, SDL_Texture* texture_, unsigned int* pixels_) { 4 | window = window_; 5 | surface = surface_; 6 | pixelSpace = pixelSpace_; 7 | renderer = renderer_; 8 | texture = texture_; 9 | pixels = pixels_; 10 | } -------------------------------------------------------------------------------- /VirtualPCCpp/SDLWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | #include 5 | #endif 6 | 7 | #ifdef __linux 8 | #include 9 | #endif 10 | 11 | class SDLWindow { 12 | public: 13 | SDL_Window* window; 14 | SDL_Surface* surface; 15 | SDL_Surface* pixelSpace; 16 | SDL_Renderer* renderer; 17 | SDL_Texture* texture; 18 | unsigned int* pixels; 19 | 20 | SDLWindow(SDL_Window*, SDL_Surface*, SDL_Surface*, SDL_Renderer*, SDL_Texture*, unsigned int*); 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /VirtualPCCpp/String.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef unsigned char byte; 4 | 5 | class String { 6 | public: 7 | int memPos; 8 | byte& c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16; 9 | 10 | String(); 11 | String(int, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&, byte&); 12 | }; -------------------------------------------------------------------------------- /VirtualPCCpp/VirtualPCCpp.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 15.0 56 | {746c87cf-eaff-4ce0-91e6-da8e1e908d04} 57 | Win32Proj 58 | VirtualPCCpp 59 | 10.0.15063.0 60 | 61 | 62 | 63 | Application 64 | true 65 | v141 66 | Unicode 67 | true 68 | 69 | 70 | Application 71 | false 72 | v141 73 | true 74 | Unicode 75 | true 76 | 77 | 78 | Application 79 | true 80 | v141 81 | Unicode 82 | 83 | 84 | Application 85 | false 86 | v141 87 | true 88 | Unicode 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | true 110 | 111 | 112 | true 113 | 114 | 115 | false 116 | 117 | 118 | false 119 | 120 | 121 | 122 | 123 | 124 | Level3 125 | Disabled 126 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | C:\Users\jovanipavle\Documents\Visual Studio 2017\Libraries\SDL2-2.0.5\include;%(AdditionalIncludeDirectories) 128 | false 129 | false 130 | 131 | 132 | Console 133 | C:\Users\jovanipavle\Documents\Visual Studio 2017\Libraries\SDL2-2.0.5\lib\x86;%(AdditionalLibraryDirectories) 134 | SDL2.lib;SDL2main.lib;%(AdditionalDependencies) 135 | 136 | 137 | 138 | 139 | 140 | 141 | Level3 142 | Disabled 143 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 144 | 145 | 146 | Console 147 | 148 | 149 | 150 | 151 | Level3 152 | 153 | 154 | MaxSpeed 155 | true 156 | true 157 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 158 | C:\Users\jovanipavle\Documents\Visual Studio 2017\Libraries\SDL2-2.0.5\include;%(AdditionalIncludeDirectories) 159 | false 160 | false 161 | 162 | 163 | Console 164 | true 165 | true 166 | C:\Users\jovanipavle\Documents\Visual Studio 2017\Libraries\SDL2-2.0.5\lib\x86;%(AdditionalLibraryDirectories) 167 | SDL2.lib;SDL2main.lib;%(AdditionalDependencies) 168 | 169 | 170 | 171 | 172 | Level3 173 | 174 | 175 | MaxSpeed 176 | true 177 | true 178 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 179 | 180 | 181 | Console 182 | true 183 | true 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /VirtualPCCpp/VirtualPCCpp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | 79 | 80 | Resource Files 81 | 82 | 83 | Resource Files 84 | 85 | 86 | Resource Files 87 | 88 | 89 | Resource Files 90 | 91 | 92 | Resource Files 93 | 94 | 95 | Resource Files 96 | 97 | 98 | Resource Files 99 | 100 | 101 | Resource Files 102 | 103 | 104 | -------------------------------------------------------------------------------- /VirtualPCCpp/fontBasic.txt: -------------------------------------------------------------------------------- 1 | 011100 2 | 100010 3 | 100110 4 | 101010 5 | 110010 6 | 100010 7 | 011100 8 | 000000 9 | 10 | 001000 11 | 011000 12 | 001000 13 | 001000 14 | 001000 15 | 001000 16 | 011100 17 | 000000 18 | 19 | 011100 20 | 100010 21 | 000100 22 | 001000 23 | 010000 24 | 100000 25 | 111110 26 | 000000 27 | 28 | 011100 29 | 100010 30 | 000010 31 | 001100 32 | 000010 33 | 100010 34 | 011100 35 | 000000 36 | 37 | 010100 38 | 010100 39 | 010100 40 | 011100 41 | 000100 42 | 000100 43 | 000100 44 | 000000 45 | 46 | 111110 47 | 100000 48 | 100000 49 | 111100 50 | 000010 51 | 000010 52 | 111100 53 | 000000 54 | 55 | 011100 56 | 100000 57 | 100000 58 | 111100 59 | 100010 60 | 100010 61 | 011100 62 | 000000 63 | 64 | 111110 65 | 000010 66 | 000010 67 | 000100 68 | 001000 69 | 001000 70 | 001000 71 | 000000 72 | 73 | 011100 74 | 100010 75 | 100010 76 | 011100 77 | 100010 78 | 100010 79 | 011100 80 | 000000 81 | 82 | 011100 83 | 100010 84 | 100010 85 | 011110 86 | 000010 87 | 000010 88 | 011100 89 | 000000 90 | 91 | 001000 92 | 001000 93 | 001000 94 | 001000 95 | 001000 96 | 000000 97 | 001000 98 | 000000 99 | 100 | 010100 101 | 010100 102 | 000000 103 | 000000 104 | 000000 105 | 000000 106 | 000000 107 | 000000 108 | 109 | 000000 110 | 010100 111 | 111110 112 | 010100 113 | 111110 114 | 010100 115 | 000000 116 | 000000 117 | 118 | 011100 119 | 101010 120 | 101000 121 | 011100 122 | 001010 123 | 101010 124 | 011100 125 | 000000 126 | 127 | 000000 128 | 010010 129 | 000100 130 | 001000 131 | 010000 132 | 100100 133 | 000000 134 | 000000 135 | 136 | 000000 137 | 011000 138 | 101000 139 | 010000 140 | 101010 141 | 100100 142 | 011010 143 | 000000 144 | 145 | 001000 146 | 001000 147 | 000000 148 | 000000 149 | 000000 150 | 000000 151 | 000000 152 | 000000 153 | 154 | 001000 155 | 010000 156 | 010000 157 | 010000 158 | 010000 159 | 010000 160 | 001000 161 | 000000 162 | 163 | 001000 164 | 000100 165 | 000100 166 | 000100 167 | 000100 168 | 000100 169 | 001000 170 | 000000 171 | 172 | 010100 173 | 001000 174 | 010100 175 | 000000 176 | 000000 177 | 000000 178 | 000000 179 | 000000 180 | 181 | 000000 182 | 001000 183 | 001000 184 | 111110 185 | 001000 186 | 001000 187 | 000000 188 | 000000 189 | 190 | 000000 191 | 000000 192 | 000000 193 | 011100 194 | 000000 195 | 000000 196 | 000000 197 | 000000 198 | 199 | 000000 200 | 000000 201 | 000000 202 | 000000 203 | 000000 204 | 001000 205 | 010000 206 | 000000 207 | 208 | 000000 209 | 000000 210 | 000000 211 | 000000 212 | 000000 213 | 001000 214 | 000000 215 | 000000 216 | 217 | 000100 218 | 000100 219 | 001000 220 | 001000 221 | 001000 222 | 010000 223 | 010000 224 | 000000 225 | 226 | 010000 227 | 010000 228 | 001000 229 | 001000 230 | 001000 231 | 000100 232 | 000100 233 | 000000 234 | 235 | 000000 236 | 001000 237 | 001000 238 | 000000 239 | 001000 240 | 001000 241 | 000000 242 | 000000 243 | 244 | 000000 245 | 001000 246 | 001000 247 | 000000 248 | 001000 249 | 001000 250 | 010000 251 | 000000 252 | 253 | 000000 254 | 000100 255 | 001000 256 | 010000 257 | 001000 258 | 000100 259 | 000000 260 | 000000 261 | 262 | 000000 263 | 010000 264 | 001000 265 | 000100 266 | 001000 267 | 010000 268 | 000000 269 | 000000 270 | 271 | 000000 272 | 000000 273 | 111110 274 | 000000 275 | 111110 276 | 000000 277 | 000000 278 | 000000 279 | 280 | 011000 281 | 010100 282 | 000100 283 | 001000 284 | 001000 285 | 000000 286 | 001000 287 | 000000 288 | 289 | 011100 290 | 010000 291 | 010000 292 | 010000 293 | 010000 294 | 010000 295 | 011100 296 | 000000 297 | 298 | 011100 299 | 000100 300 | 000100 301 | 000100 302 | 000100 303 | 000100 304 | 011100 305 | 000000 306 | 307 | 000100 308 | 001000 309 | 001000 310 | 010000 311 | 001000 312 | 001000 313 | 000100 314 | 000000 315 | 316 | 010000 317 | 001000 318 | 001000 319 | 000100 320 | 001000 321 | 001000 322 | 010000 323 | 000000 324 | 325 | 001000 326 | 000100 327 | 000000 328 | 000000 329 | 000000 330 | 000000 331 | 000000 332 | 000000 333 | 334 | 001000 335 | 010100 336 | 000000 337 | 000000 338 | 000000 339 | 000000 340 | 000000 341 | 000000 342 | 343 | 001000 344 | 001000 345 | 001000 346 | 001000 347 | 001000 348 | 001000 349 | 001000 350 | 000000 351 | 352 | 000000 353 | 000000 354 | 010000 355 | 101010 356 | 000100 357 | 000000 358 | 000000 359 | 000000 360 | 361 | 001000 362 | 010100 363 | 010100 364 | 100010 365 | 111110 366 | 100010 367 | 100010 368 | 000000 369 | 370 | 111100 371 | 100010 372 | 100010 373 | 111100 374 | 100010 375 | 100010 376 | 111100 377 | 000000 378 | 379 | 011100 380 | 100010 381 | 100000 382 | 100000 383 | 100000 384 | 100010 385 | 011100 386 | 000000 387 | 388 | 111100 389 | 100010 390 | 100010 391 | 100010 392 | 100010 393 | 100010 394 | 111100 395 | 000000 396 | 397 | 111110 398 | 100000 399 | 100000 400 | 111110 401 | 100000 402 | 100000 403 | 111110 404 | 000000 405 | 406 | 111110 407 | 100000 408 | 100000 409 | 111100 410 | 100000 411 | 100000 412 | 100000 413 | 000000 414 | 415 | 011100 416 | 100010 417 | 100000 418 | 100000 419 | 100110 420 | 100010 421 | 011100 422 | 000000 423 | 424 | 100010 425 | 100010 426 | 100010 427 | 111110 428 | 100010 429 | 100010 430 | 100010 431 | 000000 432 | 433 | 011100 434 | 001000 435 | 001000 436 | 001000 437 | 001000 438 | 001000 439 | 011100 440 | 000000 441 | 442 | 111110 443 | 000010 444 | 000010 445 | 000010 446 | 100010 447 | 100010 448 | 011100 449 | 000000 450 | 451 | 100100 452 | 100100 453 | 101000 454 | 110000 455 | 101000 456 | 100100 457 | 100100 458 | 000000 459 | 460 | 100000 461 | 100000 462 | 100000 463 | 100000 464 | 100000 465 | 100000 466 | 111110 467 | 000000 468 | 469 | 100010 470 | 110110 471 | 101010 472 | 100010 473 | 100010 474 | 100010 475 | 100010 476 | 000000 477 | 478 | 110010 479 | 110010 480 | 101010 481 | 101010 482 | 101010 483 | 100110 484 | 100110 485 | 000000 486 | 487 | 011100 488 | 100010 489 | 100010 490 | 100010 491 | 100010 492 | 100010 493 | 011100 494 | 000000 495 | 496 | 111100 497 | 100010 498 | 100010 499 | 111100 500 | 100000 501 | 100000 502 | 100000 503 | 000000 504 | 505 | 011100 506 | 100010 507 | 100010 508 | 100010 509 | 100010 510 | 100100 511 | 011010 512 | 000000 513 | 514 | 111100 515 | 100010 516 | 100010 517 | 111100 518 | 100010 519 | 100010 520 | 100010 521 | 000000 522 | 523 | 011100 524 | 100010 525 | 100000 526 | 011100 527 | 000010 528 | 100010 529 | 011100 530 | 000000 531 | 532 | 111110 533 | 001000 534 | 001000 535 | 001000 536 | 001000 537 | 001000 538 | 001000 539 | 000000 540 | 541 | 100010 542 | 100010 543 | 100010 544 | 100010 545 | 100010 546 | 100010 547 | 011100 548 | 000000 549 | 550 | 100010 551 | 100010 552 | 100010 553 | 100010 554 | 010100 555 | 010100 556 | 001000 557 | 000000 558 | 559 | 100010 560 | 100010 561 | 100010 562 | 100010 563 | 100010 564 | 101010 565 | 010100 566 | 000000 567 | 568 | 100010 569 | 100010 570 | 010100 571 | 001000 572 | 010100 573 | 100010 574 | 100010 575 | 000000 576 | 577 | 100010 578 | 100010 579 | 010100 580 | 010100 581 | 001000 582 | 001000 583 | 001000 584 | 000000 585 | 586 | 111110 587 | 000010 588 | 000100 589 | 001000 590 | 010000 591 | 100000 592 | 111110 593 | 000000 594 | 595 | 000000 596 | 000000 597 | 000000 598 | 000000 599 | 000000 600 | 000000 601 | 111110 602 | 000000 603 | 604 | 000000 605 | 000000 606 | 000000 607 | 000000 608 | 000000 609 | 000000 610 | 000000 611 | 000000 612 | 613 | 000000 614 | 011100 615 | 100010 616 | 101010 617 | 101110 618 | 100000 619 | 011110 620 | 000000 621 | 622 | 000000 623 | 000000 624 | 011100 625 | 000010 626 | 011110 627 | 100010 628 | 011110 629 | 000000 630 | 631 | 100000 632 | 100000 633 | 111100 634 | 100010 635 | 100010 636 | 100010 637 | 011100 638 | 000000 639 | 640 | 000000 641 | 000000 642 | 011100 643 | 100010 644 | 100000 645 | 100010 646 | 011100 647 | 000000 648 | 649 | 000010 650 | 000010 651 | 011110 652 | 100010 653 | 100010 654 | 100010 655 | 011100 656 | 000000 657 | 658 | 000000 659 | 000000 660 | 011100 661 | 100010 662 | 111110 663 | 100000 664 | 011110 665 | 000000 666 | 667 | 000000 668 | 001100 669 | 010000 670 | 111100 671 | 010000 672 | 010000 673 | 010000 674 | 000000 675 | 676 | 000000 677 | 000000 678 | 011110 679 | 100010 680 | 011110 681 | 000010 682 | 011100 683 | 000000 684 | 685 | 000000 686 | 100000 687 | 100000 688 | 101100 689 | 110010 690 | 100010 691 | 100010 692 | 000000 693 | 694 | 000000 695 | 001000 696 | 000000 697 | 001000 698 | 001000 699 | 001000 700 | 001000 701 | 000000 702 | 703 | 000000 704 | 000010 705 | 000000 706 | 000010 707 | 000010 708 | 010010 709 | 001100 710 | 000000 711 | 712 | 000000 713 | 010000 714 | 010010 715 | 010100 716 | 011000 717 | 010100 718 | 010010 719 | 000000 720 | 721 | 000000 722 | 011000 723 | 001000 724 | 001000 725 | 001000 726 | 001000 727 | 001000 728 | 000000 729 | 730 | 000000 731 | 000000 732 | 110100 733 | 101010 734 | 100010 735 | 100010 736 | 100010 737 | 000000 738 | 739 | 000000 740 | 000000 741 | 111100 742 | 100010 743 | 100010 744 | 100010 745 | 100010 746 | 000000 747 | 748 | 000000 749 | 000000 750 | 011100 751 | 100010 752 | 100010 753 | 100010 754 | 011100 755 | 000000 756 | 757 | 000000 758 | 000000 759 | 111100 760 | 100010 761 | 111100 762 | 100000 763 | 100000 764 | 000000 765 | 766 | 000000 767 | 000000 768 | 011110 769 | 100010 770 | 011110 771 | 000010 772 | 000010 773 | 000000 774 | 775 | 000000 776 | 000000 777 | 101100 778 | 110010 779 | 100000 780 | 100000 781 | 100000 782 | 000000 783 | 784 | 000000 785 | 000000 786 | 011110 787 | 100000 788 | 011100 789 | 000010 790 | 111100 791 | 000000 792 | 793 | 000000 794 | 001000 795 | 011100 796 | 001000 797 | 001000 798 | 001000 799 | 000100 800 | 000000 801 | 802 | 000000 803 | 000000 804 | 100010 805 | 100010 806 | 100010 807 | 100010 808 | 011110 809 | 000000 810 | 811 | 000000 812 | 000000 813 | 100010 814 | 100010 815 | 100010 816 | 010100 817 | 001000 818 | 000000 819 | 820 | 000000 821 | 000000 822 | 100010 823 | 100010 824 | 101010 825 | 101010 826 | 011110 827 | 000000 828 | 829 | 000000 830 | 000000 831 | 100010 832 | 010100 833 | 001000 834 | 010100 835 | 100010 836 | 000000 837 | 838 | 000000 839 | 000000 840 | 100010 841 | 100010 842 | 011110 843 | 000010 844 | 011100 845 | 000000 846 | 847 | 000000 848 | 000000 849 | 111110 850 | 000100 851 | 001000 852 | 010000 853 | 111110 854 | 000000 855 | 856 | 222222 857 | 222222 858 | 222222 859 | 222222 860 | 222222 861 | 222222 862 | 222222 863 | 222222 --------------------------------------------------------------------------------