├── .gitattributes ├── .gitignore ├── LICENSE ├── Memory ├── mcsmp20b.coe └── tim011_test.hex ├── Microcode ├── CDP180X.mcc ├── cdp180x_code.cgf ├── cdp180x_code.coe ├── cdp180x_code.hex ├── cdp180x_code.mif ├── cdp180x_code.vhd ├── cdp180x_map.cgf ├── cdp180x_map.coe ├── cdp180x_map.hex ├── cdp180x_map.mif ├── cdp180x_map.vhd ├── tty_screen.mcc ├── tty_screen_code.cgf ├── tty_screen_code.hex ├── tty_screen_code.mif ├── tty_screen_code.vhd ├── tty_screen_map.cgf ├── tty_screen_map.hex ├── tty_screen_map.mif └── tty_screen_map.vhd ├── README.md ├── mcc.sln └── mcc ├── Alias.cs ├── App.config ├── Code.cs ├── Controller.cs ├── Examples ├── CDP180X │ ├── CDP180X.mcc │ ├── Run at 12M5 Hz.PNG │ ├── Run at 25MHz.PNG │ └── mcc.cmd ├── EMZ1001 │ ├── Fibonacci.emz │ ├── HelloWorld.emz │ ├── emz1001.mcc │ └── mcc.cmd ├── Hex_IO │ ├── HEX_IO Test circuit.jpg │ ├── Hex2Mem │ │ ├── 2000px-Flag_of_Scotland.svg.hex │ │ ├── hex2mem.mcc │ │ ├── img2tim.cmd │ │ ├── mcc.cmd │ │ ├── screenshot_hex2mem.PNG │ │ ├── test.hex │ │ ├── test_single.hex │ │ ├── tim011_test.hex │ │ ├── tim011_test_dumped_57600.hex │ │ ├── vucko_zoi84.hex │ │ └── vucko_zoi84.png │ ├── Mem2Hex │ │ ├── mcc.cmd │ │ ├── mem2hex.mcc │ │ └── screenshot_mem2hex.PNG │ └── trace_microcode.PNG └── TTY_Screen │ ├── Tty_screen_schema - page 1.png │ ├── mcc.cmd │ └── tty_screen.mcc ├── FieldElse.cs ├── FieldIf.cs ├── FieldReg.cs ├── FieldThen.cs ├── FieldVal.cs ├── Logger.cs ├── Map.cs ├── Mapper.cs ├── MccException.cs ├── MemBlock.cs ├── MicroField.cs ├── MicroInstruction.cs ├── Org.cs ├── ParsedLine.cs ├── ParsedLineWithLabel.cs ├── ParsedLineWithNoLabel.cs ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── Sub.cs ├── Symbol.cs ├── docs └── Design.JPG └── mcc.csproj /.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 262 | /Memory/MCSMP20B.bin 263 | /Memory/mcsmp20b.cgf 264 | /Memory/mcsmp20b.hex 265 | /Memory/mcsmp20b.mif 266 | /Memory/mcsmp20b.vhd 267 | -------------------------------------------------------------------------------- /Microcode/cdp180x_code.cgf: -------------------------------------------------------------------------------- 1 | #CGF file "cdp180x_code.cgf" 2 | #memory_block_name=mcc.Code 3 | #block_depth=256 4 | #data_width=64 5 | #default_word=0 6 | #default_pad_bit_value=0 7 | #pad_direction=left 8 | #data_radix=16 9 | #address_radix=16 10 | #coe_radix=MEMORY_INITIALIZATION_RADIX 11 | #coe_data=MEMORY_INITIALIZATION_VECTOR 12 | #data= 13 | @0000 14 | 0000000000100000 15 | 0000000000100000 16 | 0000000005000500 17 | 0000000428441500 18 | 800000000402A0E0 19 | 1D200300800180E0 20 | @0010 21 | 0704100000000000 22 | 8F0005000402A0E0 23 | @0013 24 | 70042104508002E0 25 | @0015 26 | 5604100000002000 27 | @0017 28 | 5604100000002000 29 | @0019 30 | 6604100000002000 31 | @001B 32 | 6604100000002000 33 | @001D 34 | 6604100000002000 35 | @001F 36 | 6604100000002000 37 | 0077440000300000 38 | 00773D0000300000 39 | 0077870000300000 40 | 0077860000300000 41 | 0077200000300000 42 | 0077420000300000 43 | 00773D0000300000 44 | 0077850000300000 45 | 0077840000300000 46 | 0077200000300000 47 | 0077460000300000 48 | 00774C0000300000 49 | 00773D0000300000 50 | 0077830000300000 51 | 0077820000300000 52 | 0077200000300000 53 | 0077580000300000 54 | 0077500000300000 55 | 00773D0000300000 56 | 00778F0000300000 57 | 00778E0000300000 58 | 0077200000300000 59 | 0077490000300000 60 | 00774E0000300000 61 | 00773D0000300000 62 | 0077890000300000 63 | 0077880000300000 64 | 0F00740000000000 65 | 0F004A0000000000 66 | 0F00740000000000 67 | 0F00510000000000 68 | 0F00740000000000 69 | 0F00580000000000 70 | 0F00740000000000 71 | 0F005F0000000000 72 | 0F00740000000000 73 | 0F00660000000000 74 | 0F00740000000000 75 | 0F006D0000000000 76 | 00770D0000300000 77 | 00770A0000300000 78 | 0203010000100000 79 | 0077300000300000 80 | 00773D0000300000 81 | 00778D0000300000 82 | 00778C0000300000 83 | 00778B0000300000 84 | 00778A0000300000 85 | 0F00020000000000 86 | 0077310000300000 87 | 00773D0000300000 88 | 00778D0000308000 89 | 00778C0000308000 90 | 00778B0000308000 91 | 00778A0000308000 92 | 0F00020000000000 93 | 0077320000300000 94 | 00773D0000300000 95 | 00778D0000310000 96 | 00778C0000310000 97 | 00778B0000310000 98 | 00778A0000310000 99 | 0F00020000000000 100 | 0077580000300000 101 | 00773D0000300000 102 | 00778D0000318000 103 | 00778C0000318000 104 | 00778B0000318000 105 | 00778A0000318000 106 | 0F00020000000000 107 | 0077500000300000 108 | 00773D0000300000 109 | 00778D0000328000 110 | 00778C0000328000 111 | 00778B0000328000 112 | 00778A0000328000 113 | 0F00020000000000 114 | 00774E0000300000 115 | 00773D0000300000 116 | 00778D0000320000 117 | 00778C0000320000 118 | 00778B0000320000 119 | 00778A0000320000 120 | 0F00020000000000 121 | 0077200000300000 122 | 0077520000300000 123 | 0F00020000000000 124 | 0E00010000000000 125 | 0F00020000200000 126 | 0F00A50000040000 127 | 16041020000200E0 128 | 0000000000000000 129 | 067B100000000000 130 | 0604100000022000 131 | 0604100000023000 132 | 13810000800280E0 133 | 060410000002A000 134 | 060410000002D860 135 | 16041020000220E0 136 | 2604100000020460 137 | 460410000001A000 138 | 060410000001A000 139 | 36041020000180E0 140 | 0100A50000000000 141 | 8F000500040AA0E0 142 | 060410005041A860 143 | 060410005081A860 144 | 0000002000000860 145 | 060410000001A000 146 | 2000000000018460 147 | 060410000001B000 148 | 0604103800040990 149 | 06041038000009B0 150 | 0604105000000000 151 | 06041038000409D0 152 | 2604100000018060 153 | 0000000400000000 154 | 2604100060013060 155 | 0604100001000000 156 | 0604100002000000 157 | 1F008F008002A0E0 158 | 1F0090008002A0E0 159 | 0604103800000590 160 | 1F0092008002A0E0 161 | 06041020000203E0 162 | 0604102000020C60 163 | 0604100000025460 164 | 0604100000024460 165 | 1C0080008002A0E0 166 | 100000000002D0E0 167 | 060410000002C860 168 | 0C00A50000000000 169 | 0F0080000002A000 170 | 0604100000000000 171 | 0604100008000000 172 | 0604100020000000 173 | 0604102000000860 174 | 0604102000000940 175 | 0604102000000920 176 | 0604102000000900 177 | 0604103800040980 178 | 06041038000009A0 179 | 0604107000000000 180 | 06041038000409C0 181 | 160410200002A0E0 182 | 1F00A9008002A0E0 183 | 1F00AA008002A0E0 184 | 1F00AB008002A0E0 185 | 1F00AC008002A0E0 186 | 1F00AD008002A0E0 187 | 0604103800000580 188 | 1F00AF008002A0E0 189 | 0604100000060000 190 | 0604100000060000 191 | 0604100000060000 192 | 0604100000060000 193 | 0604100000060000 194 | 0604100000060000 195 | 0604100000060000 196 | 0604100000060000 197 | 0604100000060000 198 | 0604100000060000 199 | 0604100000060000 200 | 0604100000060000 201 | 0604100000060000 202 | 0604100000060000 203 | 0BCA000000063000 204 | 100000008002A0E0 205 | 100000000002D0E0 206 | 060410000002C860 207 | 0F0080000002A000 208 | 1A818000800680E0 209 | 19818000800680E0 210 | 100000008005A0E0 211 | 100000020001A0E0 212 | 0000000100024860 213 | 0604100000025860 214 | 000000000005B000 215 | 200000000001B060 216 | 200000018001B460 217 | 260410000001B860 218 | 00000002000603E0 219 | 0000000080020C60 220 | 200000000001B060 221 | 200000000001B860 222 | 00000002000283E0 223 | 0000000080028C60 224 | 0000000000026000 225 | 10000002000220E0 226 | 10000000800220E0 227 | 060410000002E000 228 | 00000002000603E0 229 | 0000000080020C60 230 | 000000000001A000 231 | 000000000002E000 232 | 100000020001A0E0 233 | 1F00EE00800180E0 234 | 00000002000603E0 235 | 0000000080020C60 236 | 200000000001B060 237 | 260410000001B860 238 | 00000002000603E0 239 | 0000000080020C60 240 | 060410000001E000 241 | 100000008006A0E0 242 | 100000020002A0E0 243 | 0604100000026000 244 | #end 245 | -------------------------------------------------------------------------------- /Microcode/cdp180x_code.coe: -------------------------------------------------------------------------------- 1 | #COE file "cdp180x_code.coe" generated from "mcc.Code" 2 | MEMORY_INITIALIZATION_RADIX=16; 3 | MEMORY_INITIALIZATION_VECTOR= 4 | 0000000000100000, 5 | 0000000000100000, 6 | 0000000005000500, 7 | 0000000428441500, 8 | 800000000402A0E0, 9 | 1D200300800180E0, 10 | 0000000000000000, 11 | 0000000000000000, 12 | 0000000000000000, 13 | 0000000000000000, 14 | 0000000000000000, 15 | 0000000000000000, 16 | 0000000000000000, 17 | 0000000000000000, 18 | 0000000000000000, 19 | 0000000000000000, 20 | 0704100000000000, 21 | 8F0005000402A0E0, 22 | 0000000000000000, 23 | 70042104508002E0, 24 | 0000000000000000, 25 | 5604100000002000, 26 | 0000000000000000, 27 | 5604100000002000, 28 | 0000000000000000, 29 | 6604100000002000, 30 | 0000000000000000, 31 | 6604100000002000, 32 | 0000000000000000, 33 | 6604100000002000, 34 | 0000000000000000, 35 | 6604100000002000, 36 | 0077440000300000, 37 | 00773D0000300000, 38 | 0077870000300000, 39 | 0077860000300000, 40 | 0077200000300000, 41 | 0077420000300000, 42 | 00773D0000300000, 43 | 0077850000300000, 44 | 0077840000300000, 45 | 0077200000300000, 46 | 0077460000300000, 47 | 00774C0000300000, 48 | 00773D0000300000, 49 | 0077830000300000, 50 | 0077820000300000, 51 | 0077200000300000, 52 | 0077580000300000, 53 | 0077500000300000, 54 | 00773D0000300000, 55 | 00778F0000300000, 56 | 00778E0000300000, 57 | 0077200000300000, 58 | 0077490000300000, 59 | 00774E0000300000, 60 | 00773D0000300000, 61 | 0077890000300000, 62 | 0077880000300000, 63 | 0F00740000000000, 64 | 0F004A0000000000, 65 | 0F00740000000000, 66 | 0F00510000000000, 67 | 0F00740000000000, 68 | 0F00580000000000, 69 | 0F00740000000000, 70 | 0F005F0000000000, 71 | 0F00740000000000, 72 | 0F00660000000000, 73 | 0F00740000000000, 74 | 0F006D0000000000, 75 | 00770D0000300000, 76 | 00770A0000300000, 77 | 0203010000100000, 78 | 0077300000300000, 79 | 00773D0000300000, 80 | 00778D0000300000, 81 | 00778C0000300000, 82 | 00778B0000300000, 83 | 00778A0000300000, 84 | 0F00020000000000, 85 | 0077310000300000, 86 | 00773D0000300000, 87 | 00778D0000308000, 88 | 00778C0000308000, 89 | 00778B0000308000, 90 | 00778A0000308000, 91 | 0F00020000000000, 92 | 0077320000300000, 93 | 00773D0000300000, 94 | 00778D0000310000, 95 | 00778C0000310000, 96 | 00778B0000310000, 97 | 00778A0000310000, 98 | 0F00020000000000, 99 | 0077580000300000, 100 | 00773D0000300000, 101 | 00778D0000318000, 102 | 00778C0000318000, 103 | 00778B0000318000, 104 | 00778A0000318000, 105 | 0F00020000000000, 106 | 0077500000300000, 107 | 00773D0000300000, 108 | 00778D0000328000, 109 | 00778C0000328000, 110 | 00778B0000328000, 111 | 00778A0000328000, 112 | 0F00020000000000, 113 | 00774E0000300000, 114 | 00773D0000300000, 115 | 00778D0000320000, 116 | 00778C0000320000, 117 | 00778B0000320000, 118 | 00778A0000320000, 119 | 0F00020000000000, 120 | 0077200000300000, 121 | 0077520000300000, 122 | 0F00020000000000, 123 | 0E00010000000000, 124 | 0F00020000200000, 125 | 0F00A50000040000, 126 | 16041020000200E0, 127 | 0000000000000000, 128 | 067B100000000000, 129 | 0604100000022000, 130 | 0604100000023000, 131 | 13810000800280E0, 132 | 060410000002A000, 133 | 060410000002D860, 134 | 16041020000220E0, 135 | 2604100000020460, 136 | 460410000001A000, 137 | 060410000001A000, 138 | 36041020000180E0, 139 | 0100A50000000000, 140 | 8F000500040AA0E0, 141 | 060410005041A860, 142 | 060410005081A860, 143 | 0000002000000860, 144 | 060410000001A000, 145 | 2000000000018460, 146 | 060410000001B000, 147 | 0604103800040990, 148 | 06041038000009B0, 149 | 0604105000000000, 150 | 06041038000409D0, 151 | 2604100000018060, 152 | 0000000400000000, 153 | 2604100060013060, 154 | 0604100001000000, 155 | 0604100002000000, 156 | 1F008F008002A0E0, 157 | 1F0090008002A0E0, 158 | 0604103800000590, 159 | 1F0092008002A0E0, 160 | 06041020000203E0, 161 | 0604102000020C60, 162 | 0604100000025460, 163 | 0604100000024460, 164 | 1C0080008002A0E0, 165 | 100000000002D0E0, 166 | 060410000002C860, 167 | 0C00A50000000000, 168 | 0F0080000002A000, 169 | 0604100000000000, 170 | 0604100008000000, 171 | 0604100020000000, 172 | 0604102000000860, 173 | 0604102000000940, 174 | 0604102000000920, 175 | 0604102000000900, 176 | 0604103800040980, 177 | 06041038000009A0, 178 | 0604107000000000, 179 | 06041038000409C0, 180 | 160410200002A0E0, 181 | 1F00A9008002A0E0, 182 | 1F00AA008002A0E0, 183 | 1F00AB008002A0E0, 184 | 1F00AC008002A0E0, 185 | 1F00AD008002A0E0, 186 | 0604103800000580, 187 | 1F00AF008002A0E0, 188 | 0604100000060000, 189 | 0604100000060000, 190 | 0604100000060000, 191 | 0604100000060000, 192 | 0604100000060000, 193 | 0604100000060000, 194 | 0604100000060000, 195 | 0604100000060000, 196 | 0604100000060000, 197 | 0604100000060000, 198 | 0604100000060000, 199 | 0604100000060000, 200 | 0604100000060000, 201 | 0604100000060000, 202 | 0BCA000000063000, 203 | 100000008002A0E0, 204 | 100000000002D0E0, 205 | 060410000002C860, 206 | 0F0080000002A000, 207 | 1A818000800680E0, 208 | 19818000800680E0, 209 | 100000008005A0E0, 210 | 100000020001A0E0, 211 | 0000000100024860, 212 | 0604100000025860, 213 | 000000000005B000, 214 | 200000000001B060, 215 | 200000018001B460, 216 | 260410000001B860, 217 | 00000002000603E0, 218 | 0000000080020C60, 219 | 200000000001B060, 220 | 200000000001B860, 221 | 00000002000283E0, 222 | 0000000080028C60, 223 | 0000000000026000, 224 | 10000002000220E0, 225 | 10000000800220E0, 226 | 060410000002E000, 227 | 00000002000603E0, 228 | 0000000080020C60, 229 | 000000000001A000, 230 | 000000000002E000, 231 | 100000020001A0E0, 232 | 1F00EE00800180E0, 233 | 00000002000603E0, 234 | 0000000080020C60, 235 | 200000000001B060, 236 | 260410000001B860, 237 | 00000002000603E0, 238 | 0000000080020C60, 239 | 060410000001E000, 240 | 100000008006A0E0, 241 | 100000020002A0E0, 242 | 0604100000026000, 243 | 0000000000000000, 244 | 0000000000000000, 245 | 0000000000000000, 246 | 0000000000000000, 247 | 0000000000000000, 248 | 0000000000000000, 249 | 0000000000000000, 250 | 0000000000000000, 251 | 0000000000000000, 252 | 0000000000000000, 253 | 0000000000000000, 254 | 0000000000000000, 255 | 0000000000000000, 256 | 0000000000000000, 257 | 0000000000000000, 258 | 0000000000000000, 259 | 0000000000000000; 260 | -------------------------------------------------------------------------------- /Microcode/cdp180x_code.hex: -------------------------------------------------------------------------------- 1 | : 08 0000 00 00 00 00 00 00 10 00 00 E8 2 | : 08 0008 00 00 00 00 00 00 10 00 00 E0 3 | : 08 0010 00 00 00 00 00 05 00 05 00 DE 4 | : 08 0018 00 00 00 00 04 28 44 15 00 5B 5 | : 08 0020 00 80 00 00 00 04 02 A0 E0 D2 6 | : 08 0028 00 1D 20 03 00 80 01 80 E0 AF 7 | : 08 0080 00 07 04 10 00 00 00 00 00 5D 8 | : 08 0088 00 8F 00 05 00 04 02 A0 E0 56 9 | : 08 0098 00 70 04 21 04 50 80 02 E0 15 10 | : 08 00A8 00 56 04 10 00 00 00 20 00 C6 11 | : 08 00B8 00 56 04 10 00 00 00 20 00 B6 12 | : 08 00C8 00 66 04 10 00 00 00 20 00 96 13 | : 08 00D8 00 66 04 10 00 00 00 20 00 86 14 | : 08 00E8 00 66 04 10 00 00 00 20 00 76 15 | : 08 00F8 00 66 04 10 00 00 00 20 00 66 16 | : 08 0100 00 00 77 44 00 00 30 00 00 0C 17 | : 08 0108 00 00 77 3D 00 00 30 00 00 0B 18 | : 08 0110 00 00 77 87 00 00 30 00 00 B9 19 | : 08 0118 00 00 77 86 00 00 30 00 00 B2 20 | : 08 0120 00 00 77 20 00 00 30 00 00 10 21 | : 08 0128 00 00 77 42 00 00 30 00 00 E6 22 | : 08 0130 00 00 77 3D 00 00 30 00 00 E3 23 | : 08 0138 00 00 77 85 00 00 30 00 00 93 24 | : 08 0140 00 00 77 84 00 00 30 00 00 8C 25 | : 08 0148 00 00 77 20 00 00 30 00 00 E8 26 | : 08 0150 00 00 77 46 00 00 30 00 00 BA 27 | : 08 0158 00 00 77 4C 00 00 30 00 00 AC 28 | : 08 0160 00 00 77 3D 00 00 30 00 00 B3 29 | : 08 0168 00 00 77 83 00 00 30 00 00 65 30 | : 08 0170 00 00 77 82 00 00 30 00 00 5E 31 | : 08 0178 00 00 77 20 00 00 30 00 00 B8 32 | : 08 0180 00 00 77 58 00 00 30 00 00 78 33 | : 08 0188 00 00 77 50 00 00 30 00 00 78 34 | : 08 0190 00 00 77 3D 00 00 30 00 00 83 35 | : 08 0198 00 00 77 8F 00 00 30 00 00 29 36 | : 08 01A0 00 00 77 8E 00 00 30 00 00 22 37 | : 08 01A8 00 00 77 20 00 00 30 00 00 88 38 | : 08 01B0 00 00 77 49 00 00 30 00 00 57 39 | : 08 01B8 00 00 77 4E 00 00 30 00 00 4A 40 | : 08 01C0 00 00 77 3D 00 00 30 00 00 53 41 | : 08 01C8 00 00 77 89 00 00 30 00 00 FF 42 | : 08 01D0 00 00 77 88 00 00 30 00 00 F8 43 | : 08 01D8 00 0F 00 74 00 00 00 00 00 9C 44 | : 08 01E0 00 0F 00 4A 00 00 00 00 00 BE 45 | : 08 01E8 00 0F 00 74 00 00 00 00 00 8C 46 | : 08 01F0 00 0F 00 51 00 00 00 00 00 A7 47 | : 08 01F8 00 0F 00 74 00 00 00 00 00 7C 48 | : 08 0200 00 0F 00 58 00 00 00 00 00 8F 49 | : 08 0208 00 0F 00 74 00 00 00 00 00 6B 50 | : 08 0210 00 0F 00 5F 00 00 00 00 00 78 51 | : 08 0218 00 0F 00 74 00 00 00 00 00 5B 52 | : 08 0220 00 0F 00 66 00 00 00 00 00 61 53 | : 08 0228 00 0F 00 74 00 00 00 00 00 4B 54 | : 08 0230 00 0F 00 6D 00 00 00 00 00 4A 55 | : 08 0238 00 00 77 0D 00 00 30 00 00 0A 56 | : 08 0240 00 00 77 0A 00 00 30 00 00 05 57 | : 08 0248 00 02 03 01 00 00 10 00 00 98 58 | : 08 0250 00 00 77 30 00 00 30 00 00 CF 59 | : 08 0258 00 00 77 3D 00 00 30 00 00 BA 60 | : 08 0260 00 00 77 8D 00 00 30 00 00 62 61 | : 08 0268 00 00 77 8C 00 00 30 00 00 5B 62 | : 08 0270 00 00 77 8B 00 00 30 00 00 54 63 | : 08 0278 00 00 77 8A 00 00 30 00 00 4D 64 | : 08 0280 00 0F 00 02 00 00 00 00 00 65 65 | : 08 0288 00 00 77 31 00 00 30 00 00 96 66 | : 08 0290 00 00 77 3D 00 00 30 00 00 82 67 | : 08 0298 00 00 77 8D 00 00 30 80 00 AA 68 | : 08 02A0 00 00 77 8C 00 00 30 80 00 A3 69 | : 08 02A8 00 00 77 8B 00 00 30 80 00 9C 70 | : 08 02B0 00 00 77 8A 00 00 30 80 00 95 71 | : 08 02B8 00 0F 00 02 00 00 00 00 00 2D 72 | : 08 02C0 00 00 77 32 00 00 30 00 00 5D 73 | : 08 02C8 00 00 77 3D 00 00 30 00 00 4A 74 | : 08 02D0 00 00 77 8D 00 00 31 00 00 F1 75 | : 08 02D8 00 00 77 8C 00 00 31 00 00 EA 76 | : 08 02E0 00 00 77 8B 00 00 31 00 00 E3 77 | : 08 02E8 00 00 77 8A 00 00 31 00 00 DC 78 | : 08 02F0 00 0F 00 02 00 00 00 00 00 F5 79 | : 08 02F8 00 00 77 58 00 00 30 00 00 FF 80 | : 08 0300 00 00 77 3D 00 00 30 00 00 11 81 | : 08 0308 00 00 77 8D 00 00 31 80 00 38 82 | : 08 0310 00 00 77 8C 00 00 31 80 00 31 83 | : 08 0318 00 00 77 8B 00 00 31 80 00 2A 84 | : 08 0320 00 00 77 8A 00 00 31 80 00 23 85 | : 08 0328 00 0F 00 02 00 00 00 00 00 BC 86 | : 08 0330 00 00 77 50 00 00 30 00 00 CE 87 | : 08 0338 00 00 77 3D 00 00 30 00 00 D9 88 | : 08 0340 00 00 77 8D 00 00 32 80 00 FF 89 | : 08 0348 00 00 77 8C 00 00 32 80 00 F8 90 | : 08 0350 00 00 77 8B 00 00 32 80 00 F1 91 | : 08 0358 00 00 77 8A 00 00 32 80 00 EA 92 | : 08 0360 00 0F 00 02 00 00 00 00 00 84 93 | : 08 0368 00 00 77 4E 00 00 30 00 00 98 94 | : 08 0370 00 00 77 3D 00 00 30 00 00 A1 95 | : 08 0378 00 00 77 8D 00 00 32 00 00 47 96 | : 08 0380 00 00 77 8C 00 00 32 00 00 40 97 | : 08 0388 00 00 77 8B 00 00 32 00 00 39 98 | : 08 0390 00 00 77 8A 00 00 32 00 00 32 99 | : 08 0398 00 0F 00 02 00 00 00 00 00 4C 100 | : 08 03A0 00 00 77 20 00 00 30 00 00 8E 101 | : 08 03A8 00 00 77 52 00 00 30 00 00 54 102 | : 08 03B0 00 0F 00 02 00 00 00 00 00 34 103 | : 08 03B8 00 0E 00 01 00 00 00 00 00 2E 104 | : 08 03C0 00 0F 00 02 00 00 20 00 00 04 105 | : 08 03C8 00 0F 00 A5 00 00 04 00 00 75 106 | : 08 03D0 00 16 04 10 20 00 02 00 E0 F9 107 | : 08 03D8 00 00 00 00 00 00 00 00 00 1D 108 | : 08 03E0 00 06 7B 10 00 00 00 00 00 84 109 | : 08 03E8 00 06 04 10 00 00 02 20 00 D1 110 | : 08 03F0 00 06 04 10 00 00 02 30 00 B9 111 | : 08 03F8 00 13 81 00 00 80 02 80 E0 87 112 | : 08 0400 00 06 04 10 00 00 02 A0 00 38 113 | : 08 0408 00 06 04 10 00 00 02 D8 60 98 114 | : 08 0410 00 16 04 10 20 00 02 20 E0 98 115 | : 08 0418 00 26 04 10 00 00 02 04 60 3C 116 | : 08 0420 00 46 04 10 00 00 01 A0 00 D9 117 | : 08 0428 00 06 04 10 00 00 01 A0 00 11 118 | : 08 0430 00 36 04 10 20 00 01 80 E0 F9 119 | : 08 0438 00 01 00 A5 00 00 00 00 00 16 120 | : 08 0440 00 8F 00 05 00 04 0A A0 E0 92 121 | : 08 0448 00 06 04 10 00 50 41 A8 60 F9 122 | : 08 0450 00 06 04 10 00 50 81 A8 60 B1 123 | : 08 0458 00 00 00 00 20 00 00 08 60 14 124 | : 08 0460 00 06 04 10 00 00 01 A0 00 D9 125 | : 08 0468 00 20 00 00 00 00 01 84 60 87 126 | : 08 0470 00 06 04 10 00 00 01 B0 00 B9 127 | : 08 0478 00 06 04 10 38 00 04 09 90 8D 128 | : 08 0480 00 06 04 10 38 00 00 09 B0 69 129 | : 08 0488 00 06 04 10 50 00 00 00 00 02 130 | : 08 0490 00 06 04 10 38 00 04 09 D0 35 131 | : 08 0498 00 26 04 10 00 00 01 80 60 41 132 | : 08 04A0 00 00 00 00 04 00 00 00 00 50 133 | : 08 04A8 00 26 04 10 00 60 01 30 60 21 134 | : 08 04B0 00 06 04 10 00 01 00 00 00 29 135 | : 08 04B8 00 06 04 10 00 02 00 00 00 20 136 | : 08 04C0 00 1F 00 8F 00 80 02 A0 E0 84 137 | : 08 04C8 00 1F 00 90 00 80 02 A0 E0 7B 138 | : 08 04D0 00 06 04 10 38 00 00 05 90 3D 139 | : 08 04D8 00 1F 00 92 00 80 02 A0 E0 69 140 | : 08 04E0 00 06 04 10 20 00 02 03 E0 F5 141 | : 08 04E8 00 06 04 10 20 00 02 0C 60 64 142 | : 08 04F0 00 06 04 10 00 00 02 54 60 34 143 | : 08 04F8 00 06 04 10 00 00 02 44 60 3C 144 | : 08 0500 00 1C 00 80 00 80 02 A0 E0 55 145 | : 08 0508 00 10 00 00 00 00 02 D0 E0 29 146 | : 08 0510 00 06 04 10 00 00 02 C8 60 9F 147 | : 08 0518 00 0C 00 A5 00 00 00 00 00 2A 148 | : 08 0520 00 0F 00 80 00 00 02 A0 00 A2 149 | : 08 0528 00 06 04 10 00 00 00 00 00 B1 150 | : 08 0530 00 06 04 10 00 08 00 00 00 A1 151 | : 08 0538 00 06 04 10 00 20 00 00 00 81 152 | : 08 0540 00 06 04 10 20 00 00 08 60 11 153 | : 08 0548 00 06 04 10 20 00 00 09 40 28 154 | : 08 0550 00 06 04 10 20 00 00 09 20 40 155 | : 08 0558 00 06 04 10 20 00 00 09 00 58 156 | : 08 0560 00 06 04 10 38 00 04 09 80 B4 157 | : 08 0568 00 06 04 10 38 00 00 09 A0 90 158 | : 08 0570 00 06 04 10 70 00 00 00 00 F9 159 | : 08 0578 00 06 04 10 38 00 04 09 C0 5C 160 | : 08 0580 00 16 04 10 20 00 02 A0 E0 A7 161 | : 08 0588 00 1F 00 A9 00 80 02 A0 E0 A1 162 | : 08 0590 00 1F 00 AA 00 80 02 A0 E0 98 163 | : 08 0598 00 1F 00 AB 00 80 02 A0 E0 8F 164 | : 08 05A0 00 1F 00 AC 00 80 02 A0 E0 86 165 | : 08 05A8 00 1F 00 AD 00 80 02 A0 E0 7D 166 | : 08 05B0 00 06 04 10 38 00 00 05 80 6C 167 | : 08 05B8 00 1F 00 AF 00 80 02 A0 E0 6B 168 | : 08 05C0 00 06 04 10 00 00 06 00 00 13 169 | : 08 05C8 00 06 04 10 00 00 06 00 00 0B 170 | : 08 05D0 00 06 04 10 00 00 06 00 00 03 171 | : 08 05D8 00 06 04 10 00 00 06 00 00 FB 172 | : 08 05E0 00 06 04 10 00 00 06 00 00 F3 173 | : 08 05E8 00 06 04 10 00 00 06 00 00 EB 174 | : 08 05F0 00 06 04 10 00 00 06 00 00 E3 175 | : 08 05F8 00 06 04 10 00 00 06 00 00 DB 176 | : 08 0600 00 06 04 10 00 00 06 00 00 D2 177 | : 08 0608 00 06 04 10 00 00 06 00 00 CA 178 | : 08 0610 00 06 04 10 00 00 06 00 00 C2 179 | : 08 0618 00 06 04 10 00 00 06 00 00 BA 180 | : 08 0620 00 06 04 10 00 00 06 00 00 B2 181 | : 08 0628 00 06 04 10 00 00 06 00 00 AA 182 | : 08 0630 00 0B CA 00 00 00 06 30 00 B7 183 | : 08 0638 00 10 00 00 00 80 02 A0 E0 A8 184 | : 08 0640 00 10 00 00 00 00 02 D0 E0 F0 185 | : 08 0648 00 06 04 10 00 00 02 C8 60 66 186 | : 08 0650 00 0F 00 80 00 00 02 A0 00 71 187 | : 08 0658 00 1A 81 80 00 80 06 80 E0 99 188 | : 08 0660 00 19 81 80 00 80 06 80 E0 92 189 | : 08 0668 00 10 00 00 00 80 05 A0 E0 75 190 | : 08 0670 00 10 00 00 02 00 01 A0 E0 EF 191 | : 08 0678 00 00 00 00 01 00 02 48 60 CF 192 | : 08 0680 00 06 04 10 00 00 02 58 60 9E 193 | : 08 0688 00 00 00 00 00 00 05 B0 00 B5 194 | : 08 0690 00 20 00 00 00 00 01 B0 60 31 195 | : 08 0698 00 20 00 00 01 80 01 B4 60 A4 196 | : 08 06A0 00 26 04 10 00 00 01 B8 60 FF 197 | : 08 06A8 00 00 00 00 02 00 06 03 E0 5F 198 | : 08 06B0 00 00 00 00 00 80 02 0C 60 54 199 | : 08 06B8 00 20 00 00 00 00 01 B0 60 09 200 | : 08 06C0 00 20 00 00 00 00 01 B8 60 F9 201 | : 08 06C8 00 00 00 00 02 00 02 83 E0 C3 202 | : 08 06D0 00 00 00 00 00 80 02 8C 60 B4 203 | : 08 06D8 00 00 00 00 00 00 02 60 00 B8 204 | : 08 06E0 00 10 00 00 02 00 02 20 E0 FE 205 | : 08 06E8 00 10 00 00 00 80 02 20 E0 78 206 | : 08 06F0 00 06 04 10 00 00 02 E0 00 06 207 | : 08 06F8 00 00 00 00 02 00 06 03 E0 0F 208 | : 08 0700 00 00 00 00 00 80 02 0C 60 03 209 | : 08 0708 00 00 00 00 00 00 01 A0 00 48 210 | : 08 0710 00 00 00 00 00 00 02 E0 00 FF 211 | : 08 0718 00 10 00 00 02 00 01 A0 E0 46 212 | : 08 0720 00 1F 00 EE 00 80 01 80 E0 E3 213 | : 08 0728 00 00 00 00 02 00 06 03 E0 DE 214 | : 08 0730 00 00 00 00 00 80 02 0C 60 D3 215 | : 08 0738 00 20 00 00 00 00 01 B0 60 88 216 | : 08 0740 00 26 04 10 00 00 01 B8 60 5E 217 | : 08 0748 00 00 00 00 02 00 06 03 E0 BE 218 | : 08 0750 00 00 00 00 00 80 02 0C 60 B3 219 | : 08 0758 00 06 04 10 00 00 01 E0 00 9E 220 | : 08 0760 00 10 00 00 00 80 06 A0 E0 7B 221 | : 08 0768 00 10 00 00 02 00 02 A0 E0 F5 222 | : 08 0770 00 06 04 10 00 00 02 60 00 05 223 | : 00 0000 01 FF 224 | -------------------------------------------------------------------------------- /Microcode/cdp180x_code.mif: -------------------------------------------------------------------------------- 1 | %---------------------------------% 2 | WIDTH=64; 3 | DEPTH=256; 4 | ADDRESS_RADIX=HEX; 5 | DATA_RADIX=HEX; 6 | CONTENT BEGIN 7 | [0000 .. 0001] : 0000000000100000; 8 | 0002 : 0000000005000500; 9 | 0003 : 0000000428441500; 10 | 0004 : 800000000402A0E0; 11 | 0005 : 1D200300800180E0; 12 | 0010 : 0704100000000000; 13 | 0011 : 8F0005000402A0E0; 14 | 0013 : 70042104508002E0; 15 | [0015 .. 0017] : 5604100000002000; 16 | [0019 .. 001F] : 6604100000002000; 17 | 0020 : 0077440000300000; 18 | 0021 : 00773D0000300000; 19 | 0022 : 0077870000300000; 20 | 0023 : 0077860000300000; 21 | 0024 : 0077200000300000; 22 | 0025 : 0077420000300000; 23 | 0026 : 00773D0000300000; 24 | 0027 : 0077850000300000; 25 | 0028 : 0077840000300000; 26 | 0029 : 0077200000300000; 27 | 002A : 0077460000300000; 28 | 002B : 00774C0000300000; 29 | 002C : 00773D0000300000; 30 | 002D : 0077830000300000; 31 | 002E : 0077820000300000; 32 | 002F : 0077200000300000; 33 | 0030 : 0077580000300000; 34 | 0031 : 0077500000300000; 35 | 0032 : 00773D0000300000; 36 | 0033 : 00778F0000300000; 37 | 0034 : 00778E0000300000; 38 | 0035 : 0077200000300000; 39 | 0036 : 0077490000300000; 40 | 0037 : 00774E0000300000; 41 | 0038 : 00773D0000300000; 42 | 0039 : 0077890000300000; 43 | 003A : 0077880000300000; 44 | 003B : 0F00740000000000; 45 | 003C : 0F004A0000000000; 46 | 003D : 0F00740000000000; 47 | 003E : 0F00510000000000; 48 | 003F : 0F00740000000000; 49 | 0040 : 0F00580000000000; 50 | 0041 : 0F00740000000000; 51 | 0042 : 0F005F0000000000; 52 | 0043 : 0F00740000000000; 53 | 0044 : 0F00660000000000; 54 | 0045 : 0F00740000000000; 55 | 0046 : 0F006D0000000000; 56 | 0047 : 00770D0000300000; 57 | 0048 : 00770A0000300000; 58 | 0049 : 0203010000100000; 59 | 004A : 0077300000300000; 60 | 004B : 00773D0000300000; 61 | 004C : 00778D0000300000; 62 | 004D : 00778C0000300000; 63 | 004E : 00778B0000300000; 64 | 004F : 00778A0000300000; 65 | 0050 : 0F00020000000000; 66 | 0051 : 0077310000300000; 67 | 0052 : 00773D0000300000; 68 | 0053 : 00778D0000308000; 69 | 0054 : 00778C0000308000; 70 | 0055 : 00778B0000308000; 71 | 0056 : 00778A0000308000; 72 | 0057 : 0F00020000000000; 73 | 0058 : 0077320000300000; 74 | 0059 : 00773D0000300000; 75 | 005A : 00778D0000310000; 76 | 005B : 00778C0000310000; 77 | 005C : 00778B0000310000; 78 | 005D : 00778A0000310000; 79 | 005E : 0F00020000000000; 80 | 005F : 0077580000300000; 81 | 0060 : 00773D0000300000; 82 | 0061 : 00778D0000318000; 83 | 0062 : 00778C0000318000; 84 | 0063 : 00778B0000318000; 85 | 0064 : 00778A0000318000; 86 | 0065 : 0F00020000000000; 87 | 0066 : 0077500000300000; 88 | 0067 : 00773D0000300000; 89 | 0068 : 00778D0000328000; 90 | 0069 : 00778C0000328000; 91 | 006A : 00778B0000328000; 92 | 006B : 00778A0000328000; 93 | 006C : 0F00020000000000; 94 | 006D : 00774E0000300000; 95 | 006E : 00773D0000300000; 96 | 006F : 00778D0000320000; 97 | 0070 : 00778C0000320000; 98 | 0071 : 00778B0000320000; 99 | 0072 : 00778A0000320000; 100 | 0073 : 0F00020000000000; 101 | 0074 : 0077200000300000; 102 | 0075 : 0077520000300000; 103 | 0076 : 0F00020000000000; 104 | 0077 : 0E00010000000000; 105 | 0078 : 0F00020000200000; 106 | 0079 : 0F00A50000040000; 107 | 007A : 16041020000200E0; 108 | 007B : 0000000000000000; 109 | 007C : 067B100000000000; 110 | 007D : 0604100000022000; 111 | 007E : 0604100000023000; 112 | 007F : 13810000800280E0; 113 | 0080 : 060410000002A000; 114 | 0081 : 060410000002D860; 115 | 0082 : 16041020000220E0; 116 | 0083 : 2604100000020460; 117 | 0084 : 460410000001A000; 118 | 0085 : 060410000001A000; 119 | 0086 : 36041020000180E0; 120 | 0087 : 0100A50000000000; 121 | 0088 : 8F000500040AA0E0; 122 | 0089 : 060410005041A860; 123 | 008A : 060410005081A860; 124 | 008B : 0000002000000860; 125 | 008C : 060410000001A000; 126 | 008D : 2000000000018460; 127 | 008E : 060410000001B000; 128 | 008F : 0604103800040990; 129 | 0090 : 06041038000009B0; 130 | 0091 : 0604105000000000; 131 | 0092 : 06041038000409D0; 132 | 0093 : 2604100000018060; 133 | 0094 : 0000000400000000; 134 | 0095 : 2604100060013060; 135 | 0096 : 0604100001000000; 136 | 0097 : 0604100002000000; 137 | 0098 : 1F008F008002A0E0; 138 | 0099 : 1F0090008002A0E0; 139 | 009A : 0604103800000590; 140 | 009B : 1F0092008002A0E0; 141 | 009C : 06041020000203E0; 142 | 009D : 0604102000020C60; 143 | 009E : 0604100000025460; 144 | 009F : 0604100000024460; 145 | 00A0 : 1C0080008002A0E0; 146 | 00A1 : 100000000002D0E0; 147 | 00A2 : 060410000002C860; 148 | 00A3 : 0C00A50000000000; 149 | 00A4 : 0F0080000002A000; 150 | 00A5 : 0604100000000000; 151 | 00A6 : 0604100008000000; 152 | 00A7 : 0604100020000000; 153 | 00A8 : 0604102000000860; 154 | 00A9 : 0604102000000940; 155 | 00AA : 0604102000000920; 156 | 00AB : 0604102000000900; 157 | 00AC : 0604103800040980; 158 | 00AD : 06041038000009A0; 159 | 00AE : 0604107000000000; 160 | 00AF : 06041038000409C0; 161 | 00B0 : 160410200002A0E0; 162 | 00B1 : 1F00A9008002A0E0; 163 | 00B2 : 1F00AA008002A0E0; 164 | 00B3 : 1F00AB008002A0E0; 165 | 00B4 : 1F00AC008002A0E0; 166 | 00B5 : 1F00AD008002A0E0; 167 | 00B6 : 0604103800000580; 168 | 00B7 : 1F00AF008002A0E0; 169 | [00B8 .. 00C5] : 0604100000060000; 170 | 00C6 : 0BCA000000063000; 171 | 00C7 : 100000008002A0E0; 172 | 00C8 : 100000000002D0E0; 173 | 00C9 : 060410000002C860; 174 | 00CA : 0F0080000002A000; 175 | 00CB : 1A818000800680E0; 176 | 00CC : 19818000800680E0; 177 | 00CD : 100000008005A0E0; 178 | 00CE : 100000020001A0E0; 179 | 00CF : 0000000100024860; 180 | 00D0 : 0604100000025860; 181 | 00D1 : 000000000005B000; 182 | 00D2 : 200000000001B060; 183 | 00D3 : 200000018001B460; 184 | 00D4 : 260410000001B860; 185 | 00D5 : 00000002000603E0; 186 | 00D6 : 0000000080020C60; 187 | 00D7 : 200000000001B060; 188 | 00D8 : 200000000001B860; 189 | 00D9 : 00000002000283E0; 190 | 00DA : 0000000080028C60; 191 | 00DB : 0000000000026000; 192 | 00DC : 10000002000220E0; 193 | 00DD : 10000000800220E0; 194 | 00DE : 060410000002E000; 195 | 00DF : 00000002000603E0; 196 | 00E0 : 0000000080020C60; 197 | 00E1 : 000000000001A000; 198 | 00E2 : 000000000002E000; 199 | 00E3 : 100000020001A0E0; 200 | 00E4 : 1F00EE00800180E0; 201 | 00E5 : 00000002000603E0; 202 | 00E6 : 0000000080020C60; 203 | 00E7 : 200000000001B060; 204 | 00E8 : 260410000001B860; 205 | 00E9 : 00000002000603E0; 206 | 00EA : 0000000080020C60; 207 | 00EB : 060410000001E000; 208 | 00EC : 100000008006A0E0; 209 | 00ED : 100000020002A0E0; 210 | 00EE : 0604100000026000; 211 | END; 212 | %---------------------------------% 213 | -------------------------------------------------------------------------------- /Microcode/cdp180x_map.cgf: -------------------------------------------------------------------------------- 1 | #CGF file "cdp180x_map.cgf" 2 | #memory_block_name=mcc.Mapper 3 | #block_depth=512 4 | #data_width=8 5 | #default_word=0 6 | #default_pad_bit_value=0 7 | #pad_direction=left 8 | #data_radix=16 9 | #address_radix=16 10 | #coe_radix=MEMORY_INITIALIZATION_RADIX 11 | #coe_data=MEMORY_INITIALIZATION_VECTOR 12 | #data= 13 | @0000 14 | 7B 15 | 7A 16 | 7A 17 | 7A 18 | 7A 19 | 7A 20 | 7A 21 | 7A 22 | 7A 23 | 7A 24 | 7A 25 | 7A 26 | 7A 27 | 7A 28 | 7A 29 | 7A 30 | 7D 31 | 7D 32 | 7D 33 | 7D 34 | 7D 35 | 7D 36 | 7D 37 | 7D 38 | 7D 39 | 7D 40 | 7D 41 | 7D 42 | 7D 43 | 7D 44 | 7D 45 | 7D 46 | 7E 47 | 7E 48 | 7E 49 | 7E 50 | 7E 51 | 7E 52 | 7E 53 | 7E 54 | 7E 55 | 7E 56 | 7E 57 | 7E 58 | 7E 59 | 7E 60 | 7E 61 | 7E 62 | 7F 63 | 7F 64 | 7F 65 | 7F 66 | 7F 67 | 7F 68 | 7F 69 | 7F 70 | 80 71 | 7F 72 | 7F 73 | 7F 74 | 7F 75 | 7F 76 | 7F 77 | 7F 78 | 82 79 | 82 80 | 82 81 | 82 82 | 82 83 | 82 84 | 82 85 | 82 86 | 82 87 | 82 88 | 82 89 | 82 90 | 82 91 | 82 92 | 82 93 | 82 94 | 83 95 | 83 96 | 83 97 | 83 98 | 83 99 | 83 100 | 83 101 | 83 102 | 83 103 | 83 104 | 83 105 | 83 106 | 83 107 | 83 108 | 83 109 | 83 110 | 85 111 | 84 112 | 84 113 | 84 114 | 84 115 | 84 116 | 84 117 | 84 118 | 87 119 | 86 120 | 86 121 | 86 122 | 86 123 | 86 124 | 86 125 | 86 126 | 89 127 | 8A 128 | 8B 129 | 8D 130 | 8F 131 | 90 132 | 91 133 | 92 134 | 93 135 | 94 136 | 96 137 | 97 138 | 98 139 | 99 140 | 9A 141 | 9B 142 | 9C 143 | 9C 144 | 9C 145 | 9C 146 | 9C 147 | 9C 148 | 9C 149 | 9C 150 | 9C 151 | 9C 152 | 9C 153 | 9C 154 | 9C 155 | 9C 156 | 9C 157 | 9C 158 | 9D 159 | 9D 160 | 9D 161 | 9D 162 | 9D 163 | 9D 164 | 9D 165 | 9D 166 | 9D 167 | 9D 168 | 9D 169 | 9D 170 | 9D 171 | 9D 172 | 9D 173 | 9D 174 | 9E 175 | 9E 176 | 9E 177 | 9E 178 | 9E 179 | 9E 180 | 9E 181 | 9E 182 | 9E 183 | 9E 184 | 9E 185 | 9E 186 | 9E 187 | 9E 188 | 9E 189 | 9E 190 | 9F 191 | 9F 192 | 9F 193 | 9F 194 | 9F 195 | 9F 196 | 9F 197 | 9F 198 | 9F 199 | 9F 200 | 9F 201 | 9F 202 | 9F 203 | 9F 204 | 9F 205 | 9F 206 | A0 207 | A0 208 | A0 209 | A0 210 | A5 211 | A3 212 | A3 213 | A3 214 | A4 215 | A0 216 | A0 217 | A0 218 | A3 219 | A3 220 | A3 221 | A3 222 | A6 223 | A6 224 | A6 225 | A6 226 | A6 227 | A6 228 | A6 229 | A6 230 | A6 231 | A6 232 | A6 233 | A6 234 | A6 235 | A6 236 | A6 237 | A6 238 | A7 239 | A7 240 | A7 241 | A7 242 | A7 243 | A7 244 | A7 245 | A7 246 | A7 247 | A7 248 | A7 249 | A7 250 | A7 251 | A7 252 | A7 253 | A7 254 | A8 255 | A9 256 | AA 257 | AB 258 | AC 259 | AD 260 | AE 261 | AF 262 | B0 263 | B1 264 | B2 265 | B3 266 | B4 267 | B5 268 | B6 269 | B7 270 | B8 271 | B9 272 | BA 273 | BB 274 | BC 275 | BD 276 | BE 277 | BF 278 | C0 279 | C1 280 | C2 281 | C3 282 | C4 283 | C5 284 | 79 285 | 79 286 | 79 287 | 79 288 | 79 289 | 79 290 | 79 291 | 79 292 | 79 293 | 79 294 | 79 295 | 79 296 | 79 297 | 79 298 | 79 299 | 79 300 | 79 301 | 79 302 | C6 303 | C6 304 | C6 305 | C6 306 | C6 307 | C6 308 | C6 309 | C6 310 | C6 311 | C6 312 | C6 313 | C6 314 | C6 315 | C6 316 | C6 317 | C6 318 | 79 319 | 79 320 | 79 321 | 79 322 | 79 323 | 79 324 | 79 325 | 79 326 | 79 327 | 79 328 | 79 329 | 79 330 | 79 331 | 79 332 | CB 333 | CC 334 | 79 335 | 79 336 | 79 337 | 79 338 | 79 339 | 79 340 | 79 341 | 79 342 | 79 343 | 79 344 | 79 345 | 79 346 | 79 347 | 79 348 | 79 349 | 79 350 | 79 351 | 79 352 | 79 353 | 79 354 | 79 355 | 79 356 | 79 357 | 79 358 | 79 359 | 79 360 | 79 361 | 79 362 | 79 363 | 79 364 | 79 365 | 79 366 | CD 367 | CD 368 | CD 369 | CD 370 | CD 371 | CD 372 | CD 373 | CD 374 | CD 375 | CD 376 | CD 377 | CD 378 | CD 379 | CD 380 | CD 381 | CD 382 | 79 383 | 79 384 | 79 385 | 79 386 | 8F 387 | 79 388 | D1 389 | 92 390 | 79 391 | 79 392 | 79 393 | 79 394 | 98 395 | 79 396 | 79 397 | 9B 398 | D5 399 | D5 400 | D5 401 | D5 402 | D5 403 | D5 404 | D5 405 | D5 406 | D5 407 | D5 408 | D5 409 | D5 410 | D5 411 | D5 412 | D5 413 | D5 414 | DF 415 | DF 416 | DF 417 | DF 418 | DF 419 | DF 420 | DF 421 | DF 422 | DF 423 | DF 424 | DF 425 | DF 426 | DF 427 | DF 428 | DF 429 | DF 430 | E5 431 | E5 432 | E5 433 | E5 434 | E5 435 | E5 436 | E5 437 | E5 438 | E5 439 | E5 440 | E5 441 | E5 442 | E5 443 | E5 444 | E5 445 | E5 446 | E9 447 | E9 448 | E9 449 | E9 450 | E9 451 | E9 452 | E9 453 | E9 454 | E9 455 | E9 456 | E9 457 | E9 458 | E9 459 | E9 460 | E9 461 | E9 462 | EC 463 | EC 464 | EC 465 | EC 466 | EC 467 | EC 468 | EC 469 | EC 470 | EC 471 | EC 472 | EC 473 | EC 474 | EC 475 | EC 476 | EC 477 | EC 478 | 79 479 | 79 480 | 79 481 | 79 482 | 79 483 | 79 484 | 79 485 | 79 486 | 79 487 | 79 488 | 79 489 | 79 490 | 79 491 | 79 492 | 79 493 | 79 494 | 79 495 | 79 496 | 79 497 | 79 498 | 79 499 | 79 500 | 79 501 | 79 502 | 79 503 | 79 504 | 79 505 | 79 506 | 79 507 | 79 508 | 79 509 | 79 510 | 79 511 | 79 512 | 79 513 | 79 514 | AC 515 | 79 516 | 79 517 | AF 518 | 79 519 | 79 520 | 79 521 | 79 522 | B4 523 | 79 524 | 79 525 | B7 526 | #end 527 | -------------------------------------------------------------------------------- /Microcode/cdp180x_map.coe: -------------------------------------------------------------------------------- 1 | #COE file "cdp180x_map.coe" generated from "mcc.Mapper" 2 | MEMORY_INITIALIZATION_RADIX=16; 3 | MEMORY_INITIALIZATION_VECTOR= 4 | 7B, 5 | 7A, 6 | 7A, 7 | 7A, 8 | 7A, 9 | 7A, 10 | 7A, 11 | 7A, 12 | 7A, 13 | 7A, 14 | 7A, 15 | 7A, 16 | 7A, 17 | 7A, 18 | 7A, 19 | 7A, 20 | 7D, 21 | 7D, 22 | 7D, 23 | 7D, 24 | 7D, 25 | 7D, 26 | 7D, 27 | 7D, 28 | 7D, 29 | 7D, 30 | 7D, 31 | 7D, 32 | 7D, 33 | 7D, 34 | 7D, 35 | 7D, 36 | 7E, 37 | 7E, 38 | 7E, 39 | 7E, 40 | 7E, 41 | 7E, 42 | 7E, 43 | 7E, 44 | 7E, 45 | 7E, 46 | 7E, 47 | 7E, 48 | 7E, 49 | 7E, 50 | 7E, 51 | 7E, 52 | 7F, 53 | 7F, 54 | 7F, 55 | 7F, 56 | 7F, 57 | 7F, 58 | 7F, 59 | 7F, 60 | 80, 61 | 7F, 62 | 7F, 63 | 7F, 64 | 7F, 65 | 7F, 66 | 7F, 67 | 7F, 68 | 82, 69 | 82, 70 | 82, 71 | 82, 72 | 82, 73 | 82, 74 | 82, 75 | 82, 76 | 82, 77 | 82, 78 | 82, 79 | 82, 80 | 82, 81 | 82, 82 | 82, 83 | 82, 84 | 83, 85 | 83, 86 | 83, 87 | 83, 88 | 83, 89 | 83, 90 | 83, 91 | 83, 92 | 83, 93 | 83, 94 | 83, 95 | 83, 96 | 83, 97 | 83, 98 | 83, 99 | 83, 100 | 85, 101 | 84, 102 | 84, 103 | 84, 104 | 84, 105 | 84, 106 | 84, 107 | 84, 108 | 87, 109 | 86, 110 | 86, 111 | 86, 112 | 86, 113 | 86, 114 | 86, 115 | 86, 116 | 89, 117 | 8A, 118 | 8B, 119 | 8D, 120 | 8F, 121 | 90, 122 | 91, 123 | 92, 124 | 93, 125 | 94, 126 | 96, 127 | 97, 128 | 98, 129 | 99, 130 | 9A, 131 | 9B, 132 | 9C, 133 | 9C, 134 | 9C, 135 | 9C, 136 | 9C, 137 | 9C, 138 | 9C, 139 | 9C, 140 | 9C, 141 | 9C, 142 | 9C, 143 | 9C, 144 | 9C, 145 | 9C, 146 | 9C, 147 | 9C, 148 | 9D, 149 | 9D, 150 | 9D, 151 | 9D, 152 | 9D, 153 | 9D, 154 | 9D, 155 | 9D, 156 | 9D, 157 | 9D, 158 | 9D, 159 | 9D, 160 | 9D, 161 | 9D, 162 | 9D, 163 | 9D, 164 | 9E, 165 | 9E, 166 | 9E, 167 | 9E, 168 | 9E, 169 | 9E, 170 | 9E, 171 | 9E, 172 | 9E, 173 | 9E, 174 | 9E, 175 | 9E, 176 | 9E, 177 | 9E, 178 | 9E, 179 | 9E, 180 | 9F, 181 | 9F, 182 | 9F, 183 | 9F, 184 | 9F, 185 | 9F, 186 | 9F, 187 | 9F, 188 | 9F, 189 | 9F, 190 | 9F, 191 | 9F, 192 | 9F, 193 | 9F, 194 | 9F, 195 | 9F, 196 | A0, 197 | A0, 198 | A0, 199 | A0, 200 | A5, 201 | A3, 202 | A3, 203 | A3, 204 | A4, 205 | A0, 206 | A0, 207 | A0, 208 | A3, 209 | A3, 210 | A3, 211 | A3, 212 | A6, 213 | A6, 214 | A6, 215 | A6, 216 | A6, 217 | A6, 218 | A6, 219 | A6, 220 | A6, 221 | A6, 222 | A6, 223 | A6, 224 | A6, 225 | A6, 226 | A6, 227 | A6, 228 | A7, 229 | A7, 230 | A7, 231 | A7, 232 | A7, 233 | A7, 234 | A7, 235 | A7, 236 | A7, 237 | A7, 238 | A7, 239 | A7, 240 | A7, 241 | A7, 242 | A7, 243 | A7, 244 | A8, 245 | A9, 246 | AA, 247 | AB, 248 | AC, 249 | AD, 250 | AE, 251 | AF, 252 | B0, 253 | B1, 254 | B2, 255 | B3, 256 | B4, 257 | B5, 258 | B6, 259 | B7, 260 | B8, 261 | B9, 262 | BA, 263 | BB, 264 | BC, 265 | BD, 266 | BE, 267 | BF, 268 | C0, 269 | C1, 270 | C2, 271 | C3, 272 | C4, 273 | C5, 274 | 79, 275 | 79, 276 | 79, 277 | 79, 278 | 79, 279 | 79, 280 | 79, 281 | 79, 282 | 79, 283 | 79, 284 | 79, 285 | 79, 286 | 79, 287 | 79, 288 | 79, 289 | 79, 290 | 79, 291 | 79, 292 | C6, 293 | C6, 294 | C6, 295 | C6, 296 | C6, 297 | C6, 298 | C6, 299 | C6, 300 | C6, 301 | C6, 302 | C6, 303 | C6, 304 | C6, 305 | C6, 306 | C6, 307 | C6, 308 | 79, 309 | 79, 310 | 79, 311 | 79, 312 | 79, 313 | 79, 314 | 79, 315 | 79, 316 | 79, 317 | 79, 318 | 79, 319 | 79, 320 | 79, 321 | 79, 322 | CB, 323 | CC, 324 | 79, 325 | 79, 326 | 79, 327 | 79, 328 | 79, 329 | 79, 330 | 79, 331 | 79, 332 | 79, 333 | 79, 334 | 79, 335 | 79, 336 | 79, 337 | 79, 338 | 79, 339 | 79, 340 | 79, 341 | 79, 342 | 79, 343 | 79, 344 | 79, 345 | 79, 346 | 79, 347 | 79, 348 | 79, 349 | 79, 350 | 79, 351 | 79, 352 | 79, 353 | 79, 354 | 79, 355 | 79, 356 | CD, 357 | CD, 358 | CD, 359 | CD, 360 | CD, 361 | CD, 362 | CD, 363 | CD, 364 | CD, 365 | CD, 366 | CD, 367 | CD, 368 | CD, 369 | CD, 370 | CD, 371 | CD, 372 | 79, 373 | 79, 374 | 79, 375 | 79, 376 | 8F, 377 | 79, 378 | D1, 379 | 92, 380 | 79, 381 | 79, 382 | 79, 383 | 79, 384 | 98, 385 | 79, 386 | 79, 387 | 9B, 388 | D5, 389 | D5, 390 | D5, 391 | D5, 392 | D5, 393 | D5, 394 | D5, 395 | D5, 396 | D5, 397 | D5, 398 | D5, 399 | D5, 400 | D5, 401 | D5, 402 | D5, 403 | D5, 404 | DF, 405 | DF, 406 | DF, 407 | DF, 408 | DF, 409 | DF, 410 | DF, 411 | DF, 412 | DF, 413 | DF, 414 | DF, 415 | DF, 416 | DF, 417 | DF, 418 | DF, 419 | DF, 420 | E5, 421 | E5, 422 | E5, 423 | E5, 424 | E5, 425 | E5, 426 | E5, 427 | E5, 428 | E5, 429 | E5, 430 | E5, 431 | E5, 432 | E5, 433 | E5, 434 | E5, 435 | E5, 436 | E9, 437 | E9, 438 | E9, 439 | E9, 440 | E9, 441 | E9, 442 | E9, 443 | E9, 444 | E9, 445 | E9, 446 | E9, 447 | E9, 448 | E9, 449 | E9, 450 | E9, 451 | E9, 452 | EC, 453 | EC, 454 | EC, 455 | EC, 456 | EC, 457 | EC, 458 | EC, 459 | EC, 460 | EC, 461 | EC, 462 | EC, 463 | EC, 464 | EC, 465 | EC, 466 | EC, 467 | EC, 468 | 79, 469 | 79, 470 | 79, 471 | 79, 472 | 79, 473 | 79, 474 | 79, 475 | 79, 476 | 79, 477 | 79, 478 | 79, 479 | 79, 480 | 79, 481 | 79, 482 | 79, 483 | 79, 484 | 79, 485 | 79, 486 | 79, 487 | 79, 488 | 79, 489 | 79, 490 | 79, 491 | 79, 492 | 79, 493 | 79, 494 | 79, 495 | 79, 496 | 79, 497 | 79, 498 | 79, 499 | 79, 500 | 79, 501 | 79, 502 | 79, 503 | 79, 504 | AC, 505 | 79, 506 | 79, 507 | AF, 508 | 79, 509 | 79, 510 | 79, 511 | 79, 512 | B4, 513 | 79, 514 | 79, 515 | B7; 516 | -------------------------------------------------------------------------------- /Microcode/cdp180x_map.hex: -------------------------------------------------------------------------------- 1 | : 01 0000 00 7B 84 2 | : 01 0001 00 7A 84 3 | : 01 0002 00 7A 83 4 | : 01 0003 00 7A 82 5 | : 01 0004 00 7A 81 6 | : 01 0005 00 7A 80 7 | : 01 0006 00 7A 7F 8 | : 01 0007 00 7A 7E 9 | : 01 0008 00 7A 7D 10 | : 01 0009 00 7A 7C 11 | : 01 000A 00 7A 7B 12 | : 01 000B 00 7A 7A 13 | : 01 000C 00 7A 79 14 | : 01 000D 00 7A 78 15 | : 01 000E 00 7A 77 16 | : 01 000F 00 7A 76 17 | : 01 0010 00 7D 72 18 | : 01 0011 00 7D 71 19 | : 01 0012 00 7D 70 20 | : 01 0013 00 7D 6F 21 | : 01 0014 00 7D 6E 22 | : 01 0015 00 7D 6D 23 | : 01 0016 00 7D 6C 24 | : 01 0017 00 7D 6B 25 | : 01 0018 00 7D 6A 26 | : 01 0019 00 7D 69 27 | : 01 001A 00 7D 68 28 | : 01 001B 00 7D 67 29 | : 01 001C 00 7D 66 30 | : 01 001D 00 7D 65 31 | : 01 001E 00 7D 64 32 | : 01 001F 00 7D 63 33 | : 01 0020 00 7E 61 34 | : 01 0021 00 7E 60 35 | : 01 0022 00 7E 5F 36 | : 01 0023 00 7E 5E 37 | : 01 0024 00 7E 5D 38 | : 01 0025 00 7E 5C 39 | : 01 0026 00 7E 5B 40 | : 01 0027 00 7E 5A 41 | : 01 0028 00 7E 59 42 | : 01 0029 00 7E 58 43 | : 01 002A 00 7E 57 44 | : 01 002B 00 7E 56 45 | : 01 002C 00 7E 55 46 | : 01 002D 00 7E 54 47 | : 01 002E 00 7E 53 48 | : 01 002F 00 7E 52 49 | : 01 0030 00 7F 50 50 | : 01 0031 00 7F 4F 51 | : 01 0032 00 7F 4E 52 | : 01 0033 00 7F 4D 53 | : 01 0034 00 7F 4C 54 | : 01 0035 00 7F 4B 55 | : 01 0036 00 7F 4A 56 | : 01 0037 00 7F 49 57 | : 01 0038 00 80 47 58 | : 01 0039 00 7F 47 59 | : 01 003A 00 7F 46 60 | : 01 003B 00 7F 45 61 | : 01 003C 00 7F 44 62 | : 01 003D 00 7F 43 63 | : 01 003E 00 7F 42 64 | : 01 003F 00 7F 41 65 | : 01 0040 00 82 3D 66 | : 01 0041 00 82 3C 67 | : 01 0042 00 82 3B 68 | : 01 0043 00 82 3A 69 | : 01 0044 00 82 39 70 | : 01 0045 00 82 38 71 | : 01 0046 00 82 37 72 | : 01 0047 00 82 36 73 | : 01 0048 00 82 35 74 | : 01 0049 00 82 34 75 | : 01 004A 00 82 33 76 | : 01 004B 00 82 32 77 | : 01 004C 00 82 31 78 | : 01 004D 00 82 30 79 | : 01 004E 00 82 2F 80 | : 01 004F 00 82 2E 81 | : 01 0050 00 83 2C 82 | : 01 0051 00 83 2B 83 | : 01 0052 00 83 2A 84 | : 01 0053 00 83 29 85 | : 01 0054 00 83 28 86 | : 01 0055 00 83 27 87 | : 01 0056 00 83 26 88 | : 01 0057 00 83 25 89 | : 01 0058 00 83 24 90 | : 01 0059 00 83 23 91 | : 01 005A 00 83 22 92 | : 01 005B 00 83 21 93 | : 01 005C 00 83 20 94 | : 01 005D 00 83 1F 95 | : 01 005E 00 83 1E 96 | : 01 005F 00 83 1D 97 | : 01 0060 00 85 1A 98 | : 01 0061 00 84 1A 99 | : 01 0062 00 84 19 100 | : 01 0063 00 84 18 101 | : 01 0064 00 84 17 102 | : 01 0065 00 84 16 103 | : 01 0066 00 84 15 104 | : 01 0067 00 84 14 105 | : 01 0068 00 87 10 106 | : 01 0069 00 86 10 107 | : 01 006A 00 86 0F 108 | : 01 006B 00 86 0E 109 | : 01 006C 00 86 0D 110 | : 01 006D 00 86 0C 111 | : 01 006E 00 86 0B 112 | : 01 006F 00 86 0A 113 | : 01 0070 00 89 06 114 | : 01 0071 00 8A 04 115 | : 01 0072 00 8B 02 116 | : 01 0073 00 8D FF 117 | : 01 0074 00 8F FC 118 | : 01 0075 00 90 FA 119 | : 01 0076 00 91 F8 120 | : 01 0077 00 92 F6 121 | : 01 0078 00 93 F4 122 | : 01 0079 00 94 F2 123 | : 01 007A 00 96 EF 124 | : 01 007B 00 97 ED 125 | : 01 007C 00 98 EB 126 | : 01 007D 00 99 E9 127 | : 01 007E 00 9A E7 128 | : 01 007F 00 9B E5 129 | : 01 0080 00 9C E3 130 | : 01 0081 00 9C E2 131 | : 01 0082 00 9C E1 132 | : 01 0083 00 9C E0 133 | : 01 0084 00 9C DF 134 | : 01 0085 00 9C DE 135 | : 01 0086 00 9C DD 136 | : 01 0087 00 9C DC 137 | : 01 0088 00 9C DB 138 | : 01 0089 00 9C DA 139 | : 01 008A 00 9C D9 140 | : 01 008B 00 9C D8 141 | : 01 008C 00 9C D7 142 | : 01 008D 00 9C D6 143 | : 01 008E 00 9C D5 144 | : 01 008F 00 9C D4 145 | : 01 0090 00 9D D2 146 | : 01 0091 00 9D D1 147 | : 01 0092 00 9D D0 148 | : 01 0093 00 9D CF 149 | : 01 0094 00 9D CE 150 | : 01 0095 00 9D CD 151 | : 01 0096 00 9D CC 152 | : 01 0097 00 9D CB 153 | : 01 0098 00 9D CA 154 | : 01 0099 00 9D C9 155 | : 01 009A 00 9D C8 156 | : 01 009B 00 9D C7 157 | : 01 009C 00 9D C6 158 | : 01 009D 00 9D C5 159 | : 01 009E 00 9D C4 160 | : 01 009F 00 9D C3 161 | : 01 00A0 00 9E C1 162 | : 01 00A1 00 9E C0 163 | : 01 00A2 00 9E BF 164 | : 01 00A3 00 9E BE 165 | : 01 00A4 00 9E BD 166 | : 01 00A5 00 9E BC 167 | : 01 00A6 00 9E BB 168 | : 01 00A7 00 9E BA 169 | : 01 00A8 00 9E B9 170 | : 01 00A9 00 9E B8 171 | : 01 00AA 00 9E B7 172 | : 01 00AB 00 9E B6 173 | : 01 00AC 00 9E B5 174 | : 01 00AD 00 9E B4 175 | : 01 00AE 00 9E B3 176 | : 01 00AF 00 9E B2 177 | : 01 00B0 00 9F B0 178 | : 01 00B1 00 9F AF 179 | : 01 00B2 00 9F AE 180 | : 01 00B3 00 9F AD 181 | : 01 00B4 00 9F AC 182 | : 01 00B5 00 9F AB 183 | : 01 00B6 00 9F AA 184 | : 01 00B7 00 9F A9 185 | : 01 00B8 00 9F A8 186 | : 01 00B9 00 9F A7 187 | : 01 00BA 00 9F A6 188 | : 01 00BB 00 9F A5 189 | : 01 00BC 00 9F A4 190 | : 01 00BD 00 9F A3 191 | : 01 00BE 00 9F A2 192 | : 01 00BF 00 9F A1 193 | : 01 00C0 00 A0 9F 194 | : 01 00C1 00 A0 9E 195 | : 01 00C2 00 A0 9D 196 | : 01 00C3 00 A0 9C 197 | : 01 00C4 00 A5 96 198 | : 01 00C5 00 A3 97 199 | : 01 00C6 00 A3 96 200 | : 01 00C7 00 A3 95 201 | : 01 00C8 00 A4 93 202 | : 01 00C9 00 A0 96 203 | : 01 00CA 00 A0 95 204 | : 01 00CB 00 A0 94 205 | : 01 00CC 00 A3 90 206 | : 01 00CD 00 A3 8F 207 | : 01 00CE 00 A3 8E 208 | : 01 00CF 00 A3 8D 209 | : 01 00D0 00 A6 89 210 | : 01 00D1 00 A6 88 211 | : 01 00D2 00 A6 87 212 | : 01 00D3 00 A6 86 213 | : 01 00D4 00 A6 85 214 | : 01 00D5 00 A6 84 215 | : 01 00D6 00 A6 83 216 | : 01 00D7 00 A6 82 217 | : 01 00D8 00 A6 81 218 | : 01 00D9 00 A6 80 219 | : 01 00DA 00 A6 7F 220 | : 01 00DB 00 A6 7E 221 | : 01 00DC 00 A6 7D 222 | : 01 00DD 00 A6 7C 223 | : 01 00DE 00 A6 7B 224 | : 01 00DF 00 A6 7A 225 | : 01 00E0 00 A7 78 226 | : 01 00E1 00 A7 77 227 | : 01 00E2 00 A7 76 228 | : 01 00E3 00 A7 75 229 | : 01 00E4 00 A7 74 230 | : 01 00E5 00 A7 73 231 | : 01 00E6 00 A7 72 232 | : 01 00E7 00 A7 71 233 | : 01 00E8 00 A7 70 234 | : 01 00E9 00 A7 6F 235 | : 01 00EA 00 A7 6E 236 | : 01 00EB 00 A7 6D 237 | : 01 00EC 00 A7 6C 238 | : 01 00ED 00 A7 6B 239 | : 01 00EE 00 A7 6A 240 | : 01 00EF 00 A7 69 241 | : 01 00F0 00 A8 67 242 | : 01 00F1 00 A9 65 243 | : 01 00F2 00 AA 63 244 | : 01 00F3 00 AB 61 245 | : 01 00F4 00 AC 5F 246 | : 01 00F5 00 AD 5D 247 | : 01 00F6 00 AE 5B 248 | : 01 00F7 00 AF 59 249 | : 01 00F8 00 B0 57 250 | : 01 00F9 00 B1 55 251 | : 01 00FA 00 B2 53 252 | : 01 00FB 00 B3 51 253 | : 01 00FC 00 B4 4F 254 | : 01 00FD 00 B5 4D 255 | : 01 00FE 00 B6 4B 256 | : 01 00FF 00 B7 49 257 | : 01 0100 00 B8 46 258 | : 01 0101 00 B9 44 259 | : 01 0102 00 BA 42 260 | : 01 0103 00 BB 40 261 | : 01 0104 00 BC 3E 262 | : 01 0105 00 BD 3C 263 | : 01 0106 00 BE 3A 264 | : 01 0107 00 BF 38 265 | : 01 0108 00 C0 36 266 | : 01 0109 00 C1 34 267 | : 01 010A 00 C2 32 268 | : 01 010B 00 C3 30 269 | : 01 010C 00 C4 2E 270 | : 01 010D 00 C5 2C 271 | : 01 010E 00 79 77 272 | : 01 010F 00 79 76 273 | : 01 0110 00 79 75 274 | : 01 0111 00 79 74 275 | : 01 0112 00 79 73 276 | : 01 0113 00 79 72 277 | : 01 0114 00 79 71 278 | : 01 0115 00 79 70 279 | : 01 0116 00 79 6F 280 | : 01 0117 00 79 6E 281 | : 01 0118 00 79 6D 282 | : 01 0119 00 79 6C 283 | : 01 011A 00 79 6B 284 | : 01 011B 00 79 6A 285 | : 01 011C 00 79 69 286 | : 01 011D 00 79 68 287 | : 01 011E 00 79 67 288 | : 01 011F 00 79 66 289 | : 01 0120 00 C6 18 290 | : 01 0121 00 C6 17 291 | : 01 0122 00 C6 16 292 | : 01 0123 00 C6 15 293 | : 01 0124 00 C6 14 294 | : 01 0125 00 C6 13 295 | : 01 0126 00 C6 12 296 | : 01 0127 00 C6 11 297 | : 01 0128 00 C6 10 298 | : 01 0129 00 C6 0F 299 | : 01 012A 00 C6 0E 300 | : 01 012B 00 C6 0D 301 | : 01 012C 00 C6 0C 302 | : 01 012D 00 C6 0B 303 | : 01 012E 00 C6 0A 304 | : 01 012F 00 C6 09 305 | : 01 0130 00 79 55 306 | : 01 0131 00 79 54 307 | : 01 0132 00 79 53 308 | : 01 0133 00 79 52 309 | : 01 0134 00 79 51 310 | : 01 0135 00 79 50 311 | : 01 0136 00 79 4F 312 | : 01 0137 00 79 4E 313 | : 01 0138 00 79 4D 314 | : 01 0139 00 79 4C 315 | : 01 013A 00 79 4B 316 | : 01 013B 00 79 4A 317 | : 01 013C 00 79 49 318 | : 01 013D 00 79 48 319 | : 01 013E 00 CB F5 320 | : 01 013F 00 CC F3 321 | : 01 0140 00 79 45 322 | : 01 0141 00 79 44 323 | : 01 0142 00 79 43 324 | : 01 0143 00 79 42 325 | : 01 0144 00 79 41 326 | : 01 0145 00 79 40 327 | : 01 0146 00 79 3F 328 | : 01 0147 00 79 3E 329 | : 01 0148 00 79 3D 330 | : 01 0149 00 79 3C 331 | : 01 014A 00 79 3B 332 | : 01 014B 00 79 3A 333 | : 01 014C 00 79 39 334 | : 01 014D 00 79 38 335 | : 01 014E 00 79 37 336 | : 01 014F 00 79 36 337 | : 01 0150 00 79 35 338 | : 01 0151 00 79 34 339 | : 01 0152 00 79 33 340 | : 01 0153 00 79 32 341 | : 01 0154 00 79 31 342 | : 01 0155 00 79 30 343 | : 01 0156 00 79 2F 344 | : 01 0157 00 79 2E 345 | : 01 0158 00 79 2D 346 | : 01 0159 00 79 2C 347 | : 01 015A 00 79 2B 348 | : 01 015B 00 79 2A 349 | : 01 015C 00 79 29 350 | : 01 015D 00 79 28 351 | : 01 015E 00 79 27 352 | : 01 015F 00 79 26 353 | : 01 0160 00 CD D1 354 | : 01 0161 00 CD D0 355 | : 01 0162 00 CD CF 356 | : 01 0163 00 CD CE 357 | : 01 0164 00 CD CD 358 | : 01 0165 00 CD CC 359 | : 01 0166 00 CD CB 360 | : 01 0167 00 CD CA 361 | : 01 0168 00 CD C9 362 | : 01 0169 00 CD C8 363 | : 01 016A 00 CD C7 364 | : 01 016B 00 CD C6 365 | : 01 016C 00 CD C5 366 | : 01 016D 00 CD C4 367 | : 01 016E 00 CD C3 368 | : 01 016F 00 CD C2 369 | : 01 0170 00 79 15 370 | : 01 0171 00 79 14 371 | : 01 0172 00 79 13 372 | : 01 0173 00 79 12 373 | : 01 0174 00 8F FB 374 | : 01 0175 00 79 10 375 | : 01 0176 00 D1 B7 376 | : 01 0177 00 92 F5 377 | : 01 0178 00 79 0D 378 | : 01 0179 00 79 0C 379 | : 01 017A 00 79 0B 380 | : 01 017B 00 79 0A 381 | : 01 017C 00 98 EA 382 | : 01 017D 00 79 08 383 | : 01 017E 00 79 07 384 | : 01 017F 00 9B E4 385 | : 01 0180 00 D5 A9 386 | : 01 0181 00 D5 A8 387 | : 01 0182 00 D5 A7 388 | : 01 0183 00 D5 A6 389 | : 01 0184 00 D5 A5 390 | : 01 0185 00 D5 A4 391 | : 01 0186 00 D5 A3 392 | : 01 0187 00 D5 A2 393 | : 01 0188 00 D5 A1 394 | : 01 0189 00 D5 A0 395 | : 01 018A 00 D5 9F 396 | : 01 018B 00 D5 9E 397 | : 01 018C 00 D5 9D 398 | : 01 018D 00 D5 9C 399 | : 01 018E 00 D5 9B 400 | : 01 018F 00 D5 9A 401 | : 01 0190 00 DF 8F 402 | : 01 0191 00 DF 8E 403 | : 01 0192 00 DF 8D 404 | : 01 0193 00 DF 8C 405 | : 01 0194 00 DF 8B 406 | : 01 0195 00 DF 8A 407 | : 01 0196 00 DF 89 408 | : 01 0197 00 DF 88 409 | : 01 0198 00 DF 87 410 | : 01 0199 00 DF 86 411 | : 01 019A 00 DF 85 412 | : 01 019B 00 DF 84 413 | : 01 019C 00 DF 83 414 | : 01 019D 00 DF 82 415 | : 01 019E 00 DF 81 416 | : 01 019F 00 DF 80 417 | : 01 01A0 00 E5 79 418 | : 01 01A1 00 E5 78 419 | : 01 01A2 00 E5 77 420 | : 01 01A3 00 E5 76 421 | : 01 01A4 00 E5 75 422 | : 01 01A5 00 E5 74 423 | : 01 01A6 00 E5 73 424 | : 01 01A7 00 E5 72 425 | : 01 01A8 00 E5 71 426 | : 01 01A9 00 E5 70 427 | : 01 01AA 00 E5 6F 428 | : 01 01AB 00 E5 6E 429 | : 01 01AC 00 E5 6D 430 | : 01 01AD 00 E5 6C 431 | : 01 01AE 00 E5 6B 432 | : 01 01AF 00 E5 6A 433 | : 01 01B0 00 E9 65 434 | : 01 01B1 00 E9 64 435 | : 01 01B2 00 E9 63 436 | : 01 01B3 00 E9 62 437 | : 01 01B4 00 E9 61 438 | : 01 01B5 00 E9 60 439 | : 01 01B6 00 E9 5F 440 | : 01 01B7 00 E9 5E 441 | : 01 01B8 00 E9 5D 442 | : 01 01B9 00 E9 5C 443 | : 01 01BA 00 E9 5B 444 | : 01 01BB 00 E9 5A 445 | : 01 01BC 00 E9 59 446 | : 01 01BD 00 E9 58 447 | : 01 01BE 00 E9 57 448 | : 01 01BF 00 E9 56 449 | : 01 01C0 00 EC 52 450 | : 01 01C1 00 EC 51 451 | : 01 01C2 00 EC 50 452 | : 01 01C3 00 EC 4F 453 | : 01 01C4 00 EC 4E 454 | : 01 01C5 00 EC 4D 455 | : 01 01C6 00 EC 4C 456 | : 01 01C7 00 EC 4B 457 | : 01 01C8 00 EC 4A 458 | : 01 01C9 00 EC 49 459 | : 01 01CA 00 EC 48 460 | : 01 01CB 00 EC 47 461 | : 01 01CC 00 EC 46 462 | : 01 01CD 00 EC 45 463 | : 01 01CE 00 EC 44 464 | : 01 01CF 00 EC 43 465 | : 01 01D0 00 79 B5 466 | : 01 01D1 00 79 B4 467 | : 01 01D2 00 79 B3 468 | : 01 01D3 00 79 B2 469 | : 01 01D4 00 79 B1 470 | : 01 01D5 00 79 B0 471 | : 01 01D6 00 79 AF 472 | : 01 01D7 00 79 AE 473 | : 01 01D8 00 79 AD 474 | : 01 01D9 00 79 AC 475 | : 01 01DA 00 79 AB 476 | : 01 01DB 00 79 AA 477 | : 01 01DC 00 79 A9 478 | : 01 01DD 00 79 A8 479 | : 01 01DE 00 79 A7 480 | : 01 01DF 00 79 A6 481 | : 01 01E0 00 79 A5 482 | : 01 01E1 00 79 A4 483 | : 01 01E2 00 79 A3 484 | : 01 01E3 00 79 A2 485 | : 01 01E4 00 79 A1 486 | : 01 01E5 00 79 A0 487 | : 01 01E6 00 79 9F 488 | : 01 01E7 00 79 9E 489 | : 01 01E8 00 79 9D 490 | : 01 01E9 00 79 9C 491 | : 01 01EA 00 79 9B 492 | : 01 01EB 00 79 9A 493 | : 01 01EC 00 79 99 494 | : 01 01ED 00 79 98 495 | : 01 01EE 00 79 97 496 | : 01 01EF 00 79 96 497 | : 01 01F0 00 79 95 498 | : 01 01F1 00 79 94 499 | : 01 01F2 00 79 93 500 | : 01 01F3 00 79 92 501 | : 01 01F4 00 AC 5E 502 | : 01 01F5 00 79 90 503 | : 01 01F6 00 79 8F 504 | : 01 01F7 00 AF 58 505 | : 01 01F8 00 79 8D 506 | : 01 01F9 00 79 8C 507 | : 01 01FA 00 79 8B 508 | : 01 01FB 00 79 8A 509 | : 01 01FC 00 B4 4E 510 | : 01 01FD 00 79 88 511 | : 01 01FE 00 79 87 512 | : 01 01FF 00 B7 48 513 | : 00 0000 01 FF 514 | -------------------------------------------------------------------------------- /Microcode/cdp180x_map.mif: -------------------------------------------------------------------------------- 1 | %---------------------------------% 2 | WIDTH=8; 3 | DEPTH=512; 4 | ADDRESS_RADIX=HEX; 5 | DATA_RADIX=HEX; 6 | CONTENT BEGIN 7 | 0000 : 7B; 8 | [0001 .. 000F] : 7A; 9 | [0010 .. 001F] : 7D; 10 | [0020 .. 002F] : 7E; 11 | [0030 .. 0037] : 7F; 12 | 0038 : 80; 13 | [0039 .. 003F] : 7F; 14 | [0040 .. 004F] : 82; 15 | [0050 .. 005F] : 83; 16 | 0060 : 85; 17 | [0061 .. 0067] : 84; 18 | 0068 : 87; 19 | [0069 .. 006F] : 86; 20 | 0070 : 89; 21 | 0071 : 8A; 22 | 0072 : 8B; 23 | 0073 : 8D; 24 | 0074 : 8F; 25 | 0075 : 90; 26 | 0076 : 91; 27 | 0077 : 92; 28 | 0078 : 93; 29 | 0079 : 94; 30 | 007A : 96; 31 | 007B : 97; 32 | 007C : 98; 33 | 007D : 99; 34 | 007E : 9A; 35 | 007F : 9B; 36 | [0080 .. 008F] : 9C; 37 | [0090 .. 009F] : 9D; 38 | [00A0 .. 00AF] : 9E; 39 | [00B0 .. 00BF] : 9F; 40 | [00C0 .. 00C3] : A0; 41 | 00C4 : A5; 42 | [00C5 .. 00C7] : A3; 43 | 00C8 : A4; 44 | [00C9 .. 00CB] : A0; 45 | [00CC .. 00CF] : A3; 46 | [00D0 .. 00DF] : A6; 47 | [00E0 .. 00EF] : A7; 48 | 00F0 : A8; 49 | 00F1 : A9; 50 | 00F2 : AA; 51 | 00F3 : AB; 52 | 00F4 : AC; 53 | 00F5 : AD; 54 | 00F6 : AE; 55 | 00F7 : AF; 56 | 00F8 : B0; 57 | 00F9 : B1; 58 | 00FA : B2; 59 | 00FB : B3; 60 | 00FC : B4; 61 | 00FD : B5; 62 | 00FE : B6; 63 | 00FF : B7; 64 | 0100 : B8; 65 | 0101 : B9; 66 | 0102 : BA; 67 | 0103 : BB; 68 | 0104 : BC; 69 | 0105 : BD; 70 | 0106 : BE; 71 | 0107 : BF; 72 | 0108 : C0; 73 | 0109 : C1; 74 | 010A : C2; 75 | 010B : C3; 76 | 010C : C4; 77 | 010D : C5; 78 | [010E .. 011F] : 79; 79 | [0120 .. 012F] : C6; 80 | [0130 .. 013D] : 79; 81 | 013E : CB; 82 | 013F : CC; 83 | [0140 .. 015F] : 79; 84 | [0160 .. 016F] : CD; 85 | [0170 .. 0173] : 79; 86 | 0174 : 8F; 87 | 0175 : 79; 88 | 0176 : D1; 89 | 0177 : 92; 90 | [0178 .. 017B] : 79; 91 | 017C : 98; 92 | [017D .. 017E] : 79; 93 | 017F : 9B; 94 | [0180 .. 018F] : D5; 95 | [0190 .. 019F] : DF; 96 | [01A0 .. 01AF] : E5; 97 | [01B0 .. 01BF] : E9; 98 | [01C0 .. 01CF] : EC; 99 | [01D0 .. 01F3] : 79; 100 | 01F4 : AC; 101 | [01F5 .. 01F6] : 79; 102 | 01F7 : AF; 103 | [01F8 .. 01FB] : 79; 104 | 01FC : B4; 105 | [01FD .. 01FE] : 79; 106 | 01FF : B7; 107 | END; 108 | %---------------------------------% 109 | -------------------------------------------------------------------------------- /Microcode/tty_screen.mcc: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------- 2 | // Screen TTY Microcode (c) 2020-... zpekic@hotmail.com 3 | // Compile with https://github.com/zpekic/MicroCodeCompiler 4 | //---------------------------------------------------------- 5 | .code 6, 32, tty_screen_code.mif, tty_screen_code.cgf, tty:tty_screen_code.vhd, tty_screen_code.hex, tty_screen_code.bin, 4; 6 | .mapper 7, 6, tty_screen_map.mif, tty_screen_map.cgf, tty:tty_screen_map.vhd, tty_screen_map.hex, tty_screen_map.bin, 1; 7 | .controller tty_control_unit.vhd, 4; 8 | 9 | ready: .valfield 2 values 10 | no, 11 | char_is_zero, 12 | yes, 13 | - default no; 14 | 15 | seq_cond: .if 3 values 16 | true, // hard-code to 1 17 | char_is_zero, 18 | cursorx_ge_maxcol, 19 | cursory_ge_maxrow, 20 | cursorx_is_zero, 21 | cursory_is_zero, 22 | memory_ready, 23 | false // hard-code to 0 24 | default true; 25 | seq_then: .then 6 values next, repeat, return, fork, @ default next; // any label 26 | seq_else: .else 6 values next, repeat, return, fork, 0x00..0x3F, @ default next; // any value as it can be a trace char 27 | 28 | cursorx: .regfield 3 values same, zero, inc, dec, maxcol default same; 29 | 30 | cursory: .regfield 3 values same, zero, inc, dec, maxrow default same; 31 | 32 | data: .regfield 2 values same, char, memory, space default same; 33 | 34 | mem: .valfield 2 values 35 | nop, // no memory access 36 | read, // mem(0) is RD 37 | write, // mem(1) is WR 38 | - // forbid read and write at same time 39 | default nop; 40 | 41 | xsel .valfield 1 values cursorx, altx default cursorx; // column address output mux 42 | 43 | ysel .valfield 1 values cursory, alty default cursory; // row address output mux 44 | 45 | altx .regfield 1 values same, cursorx default same; // column alt reg 46 | 47 | alty .regfield 1 values same, cursory default same; // row alt reg 48 | 49 | reserved: .valfield 1 values -, - default 0; 50 | 51 | // useful aliases 52 | goto: .alias if false then next else; 53 | gosub: .alias if false then next else; // this works because "jump" pushes return address to stack (1 - 4 level deep only!) 54 | return: .alias if false then next else return; 55 | noop: .alias if true then next else next; 56 | 57 | .org 0; 58 | // First 4 microcode locations can't be used branch destinations 59 | // --------------------------------------------------------------------------- 60 | _reset: cursorx <= zero, cursory <= zero; 61 | 62 | _reset1: cursorx <= zero, cursory <= zero; 63 | 64 | _reset2: cursorx <= zero, cursory <= zero; 65 | 66 | _reset3: cursorx <= zero, cursory <= zero; 67 | 68 | waitChar: ready = char_is_zero, data <= char, 69 | if char_is_zero then repeat else next; 70 | 71 | if true then fork else fork; // interpret the ASCII code of char in data register as "instruction" 72 | 73 | 74 | .map 0b???_????; // default to printable character handler 75 | main: gosub printChar; 76 | 77 | cursorx <= inc; 78 | 79 | if cursorx_ge_maxcol then next else nextChar; 80 | 81 | cursorx <= zero, 82 | goto LF; 83 | 84 | .map 0b00?_????; // special characters 00-1F are not printable, so just ignore 85 | nextChar: ready = yes, 86 | if char_is_zero then waitChar else repeat; 87 | 88 | .map 0b000_0001; // 0x01 SOH == clear screen 89 | CLS: data <= space, cursory <= zero; 90 | 91 | nextRow: cursorx <= zero; 92 | 93 | nextCol: gosub printChar; 94 | 95 | cursorx <= inc; 96 | 97 | if cursorx_ge_maxcol then next else nextCol; 98 | 99 | cursory <= inc; 100 | 101 | if cursory_ge_maxrow then HOME else nextRow; 102 | 103 | .map 0b000_0010; // 0x02 STX == home 104 | HOME: cursorx <= zero, cursory <= zero, 105 | goto nextChar; 106 | 107 | .map 0b000_1010; // 0x0A LF (line feed) 108 | LF: cursory <= inc; 109 | 110 | if cursory_ge_maxrow then next else nextChar; 111 | 112 | scrollUp: cursory <= zero; 113 | 114 | copyRow: if cursory_ge_maxrow then lastLine else next; 115 | 116 | cursorx <= zero; 117 | 118 | copyCol: if cursorx_ge_maxcol then nextY else next; 119 | 120 | cursory <= inc, 121 | gosub readMem; 122 | 123 | cursory <= dec, 124 | gosub printChar; 125 | 126 | cursorx <= inc, 127 | goto copyCol; 128 | 129 | nextY: cursory <= inc, 130 | goto copyRow; 131 | 132 | lastLine: data <= space, cursory <= dec, cursorx <= zero; 133 | 134 | clearCol: if cursorx_ge_maxcol then CR else next; 135 | 136 | gosub printChar; 137 | 138 | cursorx <= inc, 139 | goto clearCol; 140 | 141 | .map 0b000_1101; // 0x0D CR (carriage return) 142 | CR: cursorx <= zero, 143 | goto nextChar; 144 | 145 | printChar: if memory_ready then next else repeat; 146 | 147 | mem = write, xsel = cursorx, ysel = cursory, 148 | return; 149 | 150 | readMem: if memory_ready then next else repeat; 151 | 152 | mem = read, xsel = cursorx, ysel = cursory, data <= memory, 153 | return; 154 | 155 | -------------------------------------------------------------------------------- /Microcode/tty_screen_code.cgf: -------------------------------------------------------------------------------- 1 | #CGF file "tty_screen_code.cgf" 2 | #memory_block_name=mcc.Code 3 | #block_depth=64 4 | #data_width=32 5 | #default_word=0 6 | #default_pad_bit_value=0 7 | #pad_direction=left 8 | #data_radix=16 9 | #address_radix=16 10 | #coe_radix=MEMORY_INITIALIZATION_RADIX 11 | #coe_data=MEMORY_INITIALIZATION_VECTOR 12 | #data= 13 | @0000 14 | 00002400 15 | 00002400 16 | 00002400 17 | 00002400 18 | 90400100 19 | 70160000 20 | 00004000 21 | 20040000 22 | 70122000 23 | 70040000 24 | 00000700 25 | 00002000 26 | 70160000 27 | 00004000 28 | 200C0000 29 | 00000800 30 | 344B0000 31 | 70042400 32 | 00000800 33 | 30040000 34 | 00000000 35 | 70042000 36 | 60010000 37 | 00000080 38 | 70020080 39 | #end 40 | -------------------------------------------------------------------------------- /Microcode/tty_screen_code.hex: -------------------------------------------------------------------------------- 1 | : 04 0000 00 00 00 12 00 EA 2 | : 04 0004 00 00 00 12 00 E6 3 | : 04 0008 00 00 00 12 00 E2 4 | : 04 000C 00 00 00 12 00 DE 5 | : 04 0010 00 48 20 00 80 04 6 | : 04 0014 00 00 61 80 00 07 7 | : 04 0018 00 38 11 00 00 9B 8 | : 04 001C 00 00 00 20 00 C0 9 | : 04 0020 00 10 05 00 00 C7 10 | : 04 0024 00 38 09 90 00 07 11 | : 04 0028 00 88 80 80 00 4C 12 | : 04 002C 00 00 00 03 80 4D 13 | : 04 0030 00 00 00 10 00 BC 14 | : 04 0034 00 38 11 00 00 7F 15 | : 04 0038 00 00 00 20 00 A4 16 | : 04 003C 00 10 06 80 00 2A 17 | : 04 0040 00 00 00 04 00 B8 18 | : 04 0044 00 1A 46 00 00 58 19 | : 04 0048 00 38 05 12 00 65 20 | : 04 004C 00 00 00 04 00 AC 21 | : 04 0050 00 18 05 00 00 8F 22 | : 04 0054 00 00 00 02 00 A6 23 | : 04 0058 00 1B A0 00 00 E9 24 | : 04 005C 00 00 00 10 00 90 25 | : 04 0060 00 13 80 00 00 09 26 | : 04 0064 00 38 12 04 00 4A 27 | : 04 0068 00 38 11 06 00 45 28 | : 04 006C 00 38 0C 20 00 2C 29 | : 04 0070 00 38 0B 04 00 45 30 | : 04 0074 00 00 00 17 80 F1 31 | : 04 0078 00 14 20 00 00 50 32 | : 04 007C 00 38 11 00 00 37 33 | : 04 0080 00 38 0F 20 00 15 34 | : 04 0084 00 38 05 10 00 2B 35 | : 04 0088 00 30 00 80 00 C4 36 | : 04 008C 00 38 01 00 40 F7 37 | : 04 0090 00 30 00 80 00 BC 38 | : 04 0094 00 38 01 01 20 0E 39 | : 00 0000 01 FF 40 | -------------------------------------------------------------------------------- /Microcode/tty_screen_code.mif: -------------------------------------------------------------------------------- 1 | %---------------------------------% 2 | WIDTH=32; 3 | DEPTH=64; 4 | ADDRESS_RADIX=HEX; 5 | DATA_RADIX=HEX; 6 | CONTENT BEGIN 7 | [0000 .. 0003] : 00001200; 8 | 0004 : 48200080; 9 | 0005 : 00618000; 10 | 0006 : 38110000; 11 | 0007 : 00002000; 12 | 0008 : 10050000; 13 | 0009 : 38099000; 14 | 000A : 88808000; 15 | 000B : 00000380; 16 | 000C : 00001000; 17 | 000D : 38110000; 18 | 000E : 00002000; 19 | 000F : 10068000; 20 | 0010 : 00000400; 21 | 0011 : 1A460000; 22 | 0012 : 38051200; 23 | 0013 : 00000400; 24 | 0014 : 18050000; 25 | 0015 : 00000200; 26 | 0016 : 1BA00000; 27 | 0017 : 00001000; 28 | 0018 : 13800000; 29 | 0019 : 38120400; 30 | 001A : 38110600; 31 | 001B : 380C2000; 32 | 001C : 380B0400; 33 | 001D : 00001780; 34 | 001E : 14200000; 35 | 001F : 38110000; 36 | 0020 : 380F2000; 37 | 0021 : 38051000; 38 | 0022 : 30008000; 39 | 0023 : 38010040; 40 | 0024 : 30008000; 41 | 0025 : 38010120; 42 | END; 43 | %---------------------------------% 44 | -------------------------------------------------------------------------------- /Microcode/tty_screen_code.vhd: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------- 2 | -- mcc V0.9.0530 - Custom microcode compiler (c)2020-... 3 | -- https://github.com/zpekic/MicroCodeCompiler 4 | -------------------------------------------------------- 5 | -- Auto-generated file, do not modify. To customize, create 'code_template.vhd' file in mcc.exe folder 6 | -- Supported placeholders: [NAME], [SIZES], [TYPE], [FIELDS], [SIGNAL], [MEMORY]. 7 | -------------------------------------------------------- 8 | library IEEE; 9 | use IEEE.STD_LOGIC_1164.all; 10 | --use IEEE.numeric_std.all; 11 | 12 | package tty_screen_code is 13 | 14 | -- memory block size 15 | constant CODE_DATA_WIDTH: positive := 32; 16 | constant CODE_ADDRESS_WIDTH: positive := 6; 17 | constant CODE_ADDRESS_LAST: positive := 63; 18 | constant CODE_IF_WIDTH: positive := 3; 19 | 20 | 21 | type tty_code_memory is array(0 to 63) of std_logic_vector(31 downto 0); 22 | 23 | signal tty_uinstruction: std_logic_vector(31 downto 0); 24 | 25 | -- 26 | -- L0008.ready: 2 valuesno,char_is_zero,yes,- default no 27 | -- 28 | alias tty_ready: std_logic_vector(1 downto 0) is tty_uinstruction(31 downto 30); 29 | constant ready_no: std_logic_vector(1 downto 0) := "00"; 30 | constant ready_char_is_zero: std_logic_vector(1 downto 0) := "01"; 31 | constant ready_yes: std_logic_vector(1 downto 0) := "10"; 32 | -- Value "11" not allowed (name '-' is not assignable) 33 | 34 | -- 35 | -- L0014.seq_cond: 3 valuestrue,char_is_zero,cursorx_ge_maxcol,cursory_ge_maxrow,cursorx_is_zero,cursory_is_zero,memory_ready,falsedefault true 36 | -- 37 | alias tty_seq_cond: std_logic_vector(2 downto 0) is tty_uinstruction(29 downto 27); 38 | constant seq_cond_true: integer := 0; 39 | constant seq_cond_char_is_zero: integer := 1; 40 | constant seq_cond_cursorx_ge_maxcol: integer := 2; 41 | constant seq_cond_cursory_ge_maxrow: integer := 3; 42 | constant seq_cond_cursorx_is_zero: integer := 4; 43 | constant seq_cond_cursory_is_zero: integer := 5; 44 | constant seq_cond_memory_ready: integer := 6; 45 | constant seq_cond_false: integer := 7; 46 | 47 | -- 48 | -- L0024.seq_then: 6 values next, repeat, return, fork, @ default next 49 | -- 50 | alias tty_seq_then: std_logic_vector(5 downto 0) is tty_uinstruction(26 downto 21); 51 | constant seq_then_next: std_logic_vector(5 downto 0) := "000000"; 52 | constant seq_then_repeat: std_logic_vector(5 downto 0) := "000001"; 53 | constant seq_then_return: std_logic_vector(5 downto 0) := "000010"; 54 | constant seq_then_fork: std_logic_vector(5 downto 0) := "000011"; 55 | -- Jump targets allowed! 56 | 57 | -- 58 | -- L0025.seq_else: 6 values next, repeat, return, fork, 0x00..0x3F, @ default next 59 | -- 60 | alias tty_seq_else: std_logic_vector(5 downto 0) is tty_uinstruction(20 downto 15); 61 | constant seq_else_next: std_logic_vector(5 downto 0) := "000000"; 62 | constant seq_else_repeat: std_logic_vector(5 downto 0) := "000001"; 63 | constant seq_else_return: std_logic_vector(5 downto 0) := "000010"; 64 | constant seq_else_fork: std_logic_vector(5 downto 0) := "000011"; 65 | -- Values from "000000" to "111111" allowed 66 | -- Jump targets allowed! 67 | 68 | -- 69 | -- L0027.cursorx: 3 values same, zero, inc, dec, maxcol default same 70 | -- 71 | alias tty_cursorx: std_logic_vector(2 downto 0) is tty_uinstruction(14 downto 12); 72 | constant cursorx_same: std_logic_vector(2 downto 0) := "000"; 73 | constant cursorx_zero: std_logic_vector(2 downto 0) := "001"; 74 | constant cursorx_inc: std_logic_vector(2 downto 0) := "010"; 75 | constant cursorx_dec: std_logic_vector(2 downto 0) := "011"; 76 | constant cursorx_maxcol: std_logic_vector(2 downto 0) := "100"; 77 | 78 | -- 79 | -- L0029.cursory: 3 values same, zero, inc, dec, maxrow default same 80 | -- 81 | alias tty_cursory: std_logic_vector(2 downto 0) is tty_uinstruction(11 downto 9); 82 | constant cursory_same: std_logic_vector(2 downto 0) := "000"; 83 | constant cursory_zero: std_logic_vector(2 downto 0) := "001"; 84 | constant cursory_inc: std_logic_vector(2 downto 0) := "010"; 85 | constant cursory_dec: std_logic_vector(2 downto 0) := "011"; 86 | constant cursory_maxrow: std_logic_vector(2 downto 0) := "100"; 87 | 88 | -- 89 | -- L0031.data: 2 values same, char, memory, space default same 90 | -- 91 | alias tty_data: std_logic_vector(1 downto 0) is tty_uinstruction(8 downto 7); 92 | constant data_same: std_logic_vector(1 downto 0) := "00"; 93 | constant data_char: std_logic_vector(1 downto 0) := "01"; 94 | constant data_memory: std_logic_vector(1 downto 0) := "10"; 95 | constant data_space: std_logic_vector(1 downto 0) := "11"; 96 | 97 | -- 98 | -- L0033.mem: 2 valuesnop,read,write,-default nop 99 | -- 100 | alias tty_mem: std_logic_vector(1 downto 0) is tty_uinstruction(6 downto 5); 101 | constant mem_nop: std_logic_vector(1 downto 0) := "00"; 102 | constant mem_read: std_logic_vector(1 downto 0) := "01"; 103 | constant mem_write: std_logic_vector(1 downto 0) := "10"; 104 | -- Value "11" not allowed (name '-' is not assignable) 105 | 106 | -- 107 | -- L0040.xsel: 1 values cursorx, altx default cursorx 108 | -- 109 | alias tty_xsel: std_logic is tty_uinstruction(4); 110 | constant xsel_cursorx: std_logic := '0'; 111 | constant xsel_altx: std_logic := '1'; 112 | 113 | -- 114 | -- L0042.ysel: 1 values cursory, alty default cursory 115 | -- 116 | alias tty_ysel: std_logic is tty_uinstruction(3); 117 | constant ysel_cursory: std_logic := '0'; 118 | constant ysel_alty: std_logic := '1'; 119 | 120 | -- 121 | -- L0044.altx: 1 values same, cursorx default same 122 | -- 123 | alias tty_altx: std_logic is tty_uinstruction(2); 124 | constant altx_same: std_logic := '0'; 125 | constant altx_cursorx: std_logic := '1'; 126 | 127 | -- 128 | -- L0046.alty: 1 values same, cursory default same 129 | -- 130 | alias tty_alty: std_logic is tty_uinstruction(1); 131 | constant alty_same: std_logic := '0'; 132 | constant alty_cursory: std_logic := '1'; 133 | 134 | -- 135 | -- L0048.reserved: 1 values -, - default 0 136 | -- 137 | alias tty_reserved: std_logic is tty_uinstruction(0); 138 | -- Value '0' not allowed (name '-' is not assignable) 139 | -- Value '1' not allowed (name '-' is not assignable) 140 | 141 | 142 | 143 | constant tty_microcode: tty_code_memory := ( 144 | 145 | -- L0059@0000._reset: cursorx <= zero, cursory <= zero 146 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 001, cursory <= 001, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 147 | 0 => "00" & O"0" & O"00" & O"00" & O"1" & O"1" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 148 | 149 | -- L0061@0001._reset1: cursorx <= zero, cursory <= zero 150 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 001, cursory <= 001, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 151 | 1 => "00" & O"0" & O"00" & O"00" & O"1" & O"1" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 152 | 153 | -- L0063@0002._reset2: cursorx <= zero, cursory <= zero 154 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 001, cursory <= 001, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 155 | 2 => "00" & O"0" & O"00" & O"00" & O"1" & O"1" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 156 | 157 | -- L0065@0003._reset3: cursorx <= zero, cursory <= zero 158 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 001, cursory <= 001, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 159 | 3 => "00" & O"0" & O"00" & O"00" & O"1" & O"1" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 160 | 161 | -- L0067@0004.waitChar: ready = char_is_zero, data <= char,if char_is_zero then repeat else next 162 | -- ready = 01, if (001) then 000001 else 000000, cursorx <= 000, cursory <= 000, data <= 01, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 163 | 4 => "01" & O"1" & O"01" & O"00" & O"0" & O"0" & "01" & "00" & '0' & '0' & '0' & '0' & '0', 164 | 165 | -- L0070@0005. if true then fork else fork 166 | -- ready = 00, if (000) then 000011 else 000011, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 167 | 5 => "00" & O"0" & O"03" & O"03" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 168 | 169 | -- L0074@0006.main: if false then next else printChar 170 | -- ready = 00, if (111) then 000000 else 100010, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 171 | 6 => "00" & O"7" & O"00" & O"42" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 172 | 173 | -- L0076@0007. cursorx <= inc 174 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 010, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 175 | 7 => "00" & O"0" & O"00" & O"00" & O"2" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 176 | 177 | -- L0078@0008. if cursorx_ge_maxcol then next else nextChar 178 | -- ready = 00, if (010) then 000000 else 001010, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 179 | 8 => "00" & O"2" & O"00" & O"12" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 180 | 181 | -- L0080@0009. cursorx <= zero,if false then next else LF 182 | -- ready = 00, if (111) then 000000 else 010011, cursorx <= 001, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 183 | 9 => "00" & O"7" & O"00" & O"23" & O"1" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 184 | 185 | -- L0084@000A.nextChar: ready = yes,if char_is_zero then waitChar else repeat 186 | -- ready = 10, if (001) then 000100 else 000001, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 187 | 10 => "10" & O"1" & O"04" & O"01" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 188 | 189 | -- L0088@000B.CLS: data <= space, cursory <= zero 190 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 000, cursory <= 001, data <= 11, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 191 | 11 => "00" & O"0" & O"00" & O"00" & O"0" & O"1" & "11" & "00" & '0' & '0' & '0' & '0' & '0', 192 | 193 | -- L0090@000C.nextRow: cursorx <= zero 194 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 001, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 195 | 12 => "00" & O"0" & O"00" & O"00" & O"1" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 196 | 197 | -- L0092@000D.nextCol: if false then next else printChar 198 | -- ready = 00, if (111) then 000000 else 100010, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 199 | 13 => "00" & O"7" & O"00" & O"42" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 200 | 201 | -- L0094@000E. cursorx <= inc 202 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 010, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 203 | 14 => "00" & O"0" & O"00" & O"00" & O"2" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 204 | 205 | -- L0096@000F. if cursorx_ge_maxcol then next else nextCol 206 | -- ready = 00, if (010) then 000000 else 001101, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 207 | 15 => "00" & O"2" & O"00" & O"15" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 208 | 209 | -- L0098@0010. cursory <= inc 210 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 000, cursory <= 010, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 211 | 16 => "00" & O"0" & O"00" & O"00" & O"0" & O"2" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 212 | 213 | -- L0100@0011. if cursory_ge_maxrow then HOME else nextRow 214 | -- ready = 00, if (011) then 010010 else 001100, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 215 | 17 => "00" & O"3" & O"22" & O"14" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 216 | 217 | -- L0103@0012.HOME: cursorx <= zero, cursory <= zero,if false then next else nextChar 218 | -- ready = 00, if (111) then 000000 else 001010, cursorx <= 001, cursory <= 001, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 219 | 18 => "00" & O"7" & O"00" & O"12" & O"1" & O"1" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 220 | 221 | -- L0107@0013.LF: cursory <= inc 222 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 000, cursory <= 010, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 223 | 19 => "00" & O"0" & O"00" & O"00" & O"0" & O"2" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 224 | 225 | -- L0109@0014. if cursory_ge_maxrow then next else nextChar 226 | -- ready = 00, if (011) then 000000 else 001010, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 227 | 20 => "00" & O"3" & O"00" & O"12" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 228 | 229 | -- L0111@0015.scrollUp: cursory <= zero 230 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 000, cursory <= 001, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 231 | 21 => "00" & O"0" & O"00" & O"00" & O"0" & O"1" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 232 | 233 | -- L0113@0016.copyRow: if cursory_ge_maxrow then lastLine else next 234 | -- ready = 00, if (011) then 011101 else 000000, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 235 | 22 => "00" & O"3" & O"35" & O"00" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 236 | 237 | -- L0115@0017. cursorx <= zero 238 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 001, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 239 | 23 => "00" & O"0" & O"00" & O"00" & O"1" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 240 | 241 | -- L0117@0018.copyCol: if cursorx_ge_maxcol then nextY else next 242 | -- ready = 00, if (010) then 011100 else 000000, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 243 | 24 => "00" & O"2" & O"34" & O"00" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 244 | 245 | -- L0119@0019. cursory <= inc,if false then next else readMem 246 | -- ready = 00, if (111) then 000000 else 100100, cursorx <= 000, cursory <= 010, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 247 | 25 => "00" & O"7" & O"00" & O"44" & O"0" & O"2" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 248 | 249 | -- L0122@001A. cursory <= dec,if false then next else printChar 250 | -- ready = 00, if (111) then 000000 else 100010, cursorx <= 000, cursory <= 011, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 251 | 26 => "00" & O"7" & O"00" & O"42" & O"0" & O"3" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 252 | 253 | -- L0125@001B. cursorx <= inc,if false then next else copyCol 254 | -- ready = 00, if (111) then 000000 else 011000, cursorx <= 010, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 255 | 27 => "00" & O"7" & O"00" & O"30" & O"2" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 256 | 257 | -- L0128@001C.nextY: cursory <= inc,if false then next else copyRow 258 | -- ready = 00, if (111) then 000000 else 010110, cursorx <= 000, cursory <= 010, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 259 | 28 => "00" & O"7" & O"00" & O"26" & O"0" & O"2" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 260 | 261 | -- L0131@001D.lastLine: data <= space, cursory <= dec, cursorx <= zero 262 | -- ready = 00, if (000) then 000000 else 000000, cursorx <= 001, cursory <= 011, data <= 11, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 263 | 29 => "00" & O"0" & O"00" & O"00" & O"1" & O"3" & "11" & "00" & '0' & '0' & '0' & '0' & '0', 264 | 265 | -- L0133@001E.clearCol: if cursorx_ge_maxcol then CR else next 266 | -- ready = 00, if (010) then 100001 else 000000, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 267 | 30 => "00" & O"2" & O"41" & O"00" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 268 | 269 | -- L0135@001F. if false then next else printChar 270 | -- ready = 00, if (111) then 000000 else 100010, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 271 | 31 => "00" & O"7" & O"00" & O"42" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 272 | 273 | -- L0137@0020. cursorx <= inc,if false then next else clearCol 274 | -- ready = 00, if (111) then 000000 else 011110, cursorx <= 010, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 275 | 32 => "00" & O"7" & O"00" & O"36" & O"2" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 276 | 277 | -- L0141@0021.CR: cursorx <= zero,if false then next else nextChar 278 | -- ready = 00, if (111) then 000000 else 001010, cursorx <= 001, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 279 | 33 => "00" & O"7" & O"00" & O"12" & O"1" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 280 | 281 | -- L0144@0022.printChar: if memory_ready then next else repeat 282 | -- ready = 00, if (110) then 000000 else 000001, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 283 | 34 => "00" & O"6" & O"00" & O"01" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 284 | 285 | -- L0146@0023. mem = write, xsel = cursorx, ysel = cursory,if false then next else return 286 | -- ready = 00, if (111) then 000000 else 000010, cursorx <= 000, cursory <= 000, data <= 00, mem = 10, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 287 | 35 => "00" & O"7" & O"00" & O"02" & O"0" & O"0" & "00" & "10" & '0' & '0' & '0' & '0' & '0', 288 | 289 | -- L0149@0024.readMem: if memory_ready then next else repeat 290 | -- ready = 00, if (110) then 000000 else 000001, cursorx <= 000, cursory <= 000, data <= 00, mem = 00, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 291 | 36 => "00" & O"6" & O"00" & O"01" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0', 292 | 293 | -- L0151@0025. mem = read, xsel = cursorx, ysel = cursory, data <= memory,if false then next else return 294 | -- ready = 00, if (111) then 000000 else 000010, cursorx <= 000, cursory <= 000, data <= 10, mem = 01, xsel = 0, ysel = 0, altx <= 0, alty <= 0, reserved = 0; 295 | 37 => "00" & O"7" & O"00" & O"02" & O"0" & O"0" & "10" & "01" & '0' & '0' & '0' & '0' & '0', 296 | 297 | -- 26 location(s) in following ranges will be filled with default value 298 | -- 0026 .. 003F 299 | 300 | others => "00" & O"0" & O"00" & O"00" & O"0" & O"0" & "00" & "00" & '0' & '0' & '0' & '0' & '0' 301 | ); 302 | 303 | end tty_screen_code; 304 | 305 | -------------------------------------------------------------------------------- /Microcode/tty_screen_map.cgf: -------------------------------------------------------------------------------- 1 | #CGF file "tty_screen_map.cgf" 2 | #memory_block_name=mcc.Mapper 3 | #block_depth=128 4 | #data_width=6 5 | #default_word=0 6 | #default_pad_bit_value=0 7 | #pad_direction=left 8 | #data_radix=2 9 | #address_radix=16 10 | #coe_radix=MEMORY_INITIALIZATION_RADIX 11 | #coe_data=MEMORY_INITIALIZATION_VECTOR 12 | #data= 13 | @0000 14 | 001010 15 | 001011 16 | 010010 17 | 001010 18 | 001010 19 | 001010 20 | 001010 21 | 001010 22 | 001010 23 | 001010 24 | 010011 25 | 001010 26 | 001010 27 | 100001 28 | 001010 29 | 001010 30 | 001010 31 | 001010 32 | 001010 33 | 001010 34 | 001010 35 | 001010 36 | 001010 37 | 001010 38 | 001010 39 | 001010 40 | 001010 41 | 001010 42 | 001010 43 | 001010 44 | 001010 45 | 001010 46 | 000110 47 | 000110 48 | 000110 49 | 000110 50 | 000110 51 | 000110 52 | 000110 53 | 000110 54 | 000110 55 | 000110 56 | 000110 57 | 000110 58 | 000110 59 | 000110 60 | 000110 61 | 000110 62 | 000110 63 | 000110 64 | 000110 65 | 000110 66 | 000110 67 | 000110 68 | 000110 69 | 000110 70 | 000110 71 | 000110 72 | 000110 73 | 000110 74 | 000110 75 | 000110 76 | 000110 77 | 000110 78 | 000110 79 | 000110 80 | 000110 81 | 000110 82 | 000110 83 | 000110 84 | 000110 85 | 000110 86 | 000110 87 | 000110 88 | 000110 89 | 000110 90 | 000110 91 | 000110 92 | 000110 93 | 000110 94 | 000110 95 | 000110 96 | 000110 97 | 000110 98 | 000110 99 | 000110 100 | 000110 101 | 000110 102 | 000110 103 | 000110 104 | 000110 105 | 000110 106 | 000110 107 | 000110 108 | 000110 109 | 000110 110 | 000110 111 | 000110 112 | 000110 113 | 000110 114 | 000110 115 | 000110 116 | 000110 117 | 000110 118 | 000110 119 | 000110 120 | 000110 121 | 000110 122 | 000110 123 | 000110 124 | 000110 125 | 000110 126 | 000110 127 | 000110 128 | 000110 129 | 000110 130 | 000110 131 | 000110 132 | 000110 133 | 000110 134 | 000110 135 | 000110 136 | 000110 137 | 000110 138 | 000110 139 | 000110 140 | 000110 141 | 000110 142 | #end 143 | -------------------------------------------------------------------------------- /Microcode/tty_screen_map.hex: -------------------------------------------------------------------------------- 1 | : 01 0000 00 0A F5 2 | : 01 0001 00 0B F3 3 | : 01 0002 00 12 EB 4 | : 01 0003 00 0A F2 5 | : 01 0004 00 0A F1 6 | : 01 0005 00 0A F0 7 | : 01 0006 00 0A EF 8 | : 01 0007 00 0A EE 9 | : 01 0008 00 0A ED 10 | : 01 0009 00 0A EC 11 | : 01 000A 00 13 E2 12 | : 01 000B 00 0A EA 13 | : 01 000C 00 0A E9 14 | : 01 000D 00 21 D1 15 | : 01 000E 00 0A E7 16 | : 01 000F 00 0A E6 17 | : 01 0010 00 0A E5 18 | : 01 0011 00 0A E4 19 | : 01 0012 00 0A E3 20 | : 01 0013 00 0A E2 21 | : 01 0014 00 0A E1 22 | : 01 0015 00 0A E0 23 | : 01 0016 00 0A DF 24 | : 01 0017 00 0A DE 25 | : 01 0018 00 0A DD 26 | : 01 0019 00 0A DC 27 | : 01 001A 00 0A DB 28 | : 01 001B 00 0A DA 29 | : 01 001C 00 0A D9 30 | : 01 001D 00 0A D8 31 | : 01 001E 00 0A D7 32 | : 01 001F 00 0A D6 33 | : 01 0020 00 06 D9 34 | : 01 0021 00 06 D8 35 | : 01 0022 00 06 D7 36 | : 01 0023 00 06 D6 37 | : 01 0024 00 06 D5 38 | : 01 0025 00 06 D4 39 | : 01 0026 00 06 D3 40 | : 01 0027 00 06 D2 41 | : 01 0028 00 06 D1 42 | : 01 0029 00 06 D0 43 | : 01 002A 00 06 CF 44 | : 01 002B 00 06 CE 45 | : 01 002C 00 06 CD 46 | : 01 002D 00 06 CC 47 | : 01 002E 00 06 CB 48 | : 01 002F 00 06 CA 49 | : 01 0030 00 06 C9 50 | : 01 0031 00 06 C8 51 | : 01 0032 00 06 C7 52 | : 01 0033 00 06 C6 53 | : 01 0034 00 06 C5 54 | : 01 0035 00 06 C4 55 | : 01 0036 00 06 C3 56 | : 01 0037 00 06 C2 57 | : 01 0038 00 06 C1 58 | : 01 0039 00 06 C0 59 | : 01 003A 00 06 BF 60 | : 01 003B 00 06 BE 61 | : 01 003C 00 06 BD 62 | : 01 003D 00 06 BC 63 | : 01 003E 00 06 BB 64 | : 01 003F 00 06 BA 65 | : 01 0040 00 06 B9 66 | : 01 0041 00 06 B8 67 | : 01 0042 00 06 B7 68 | : 01 0043 00 06 B6 69 | : 01 0044 00 06 B5 70 | : 01 0045 00 06 B4 71 | : 01 0046 00 06 B3 72 | : 01 0047 00 06 B2 73 | : 01 0048 00 06 B1 74 | : 01 0049 00 06 B0 75 | : 01 004A 00 06 AF 76 | : 01 004B 00 06 AE 77 | : 01 004C 00 06 AD 78 | : 01 004D 00 06 AC 79 | : 01 004E 00 06 AB 80 | : 01 004F 00 06 AA 81 | : 01 0050 00 06 A9 82 | : 01 0051 00 06 A8 83 | : 01 0052 00 06 A7 84 | : 01 0053 00 06 A6 85 | : 01 0054 00 06 A5 86 | : 01 0055 00 06 A4 87 | : 01 0056 00 06 A3 88 | : 01 0057 00 06 A2 89 | : 01 0058 00 06 A1 90 | : 01 0059 00 06 A0 91 | : 01 005A 00 06 9F 92 | : 01 005B 00 06 9E 93 | : 01 005C 00 06 9D 94 | : 01 005D 00 06 9C 95 | : 01 005E 00 06 9B 96 | : 01 005F 00 06 9A 97 | : 01 0060 00 06 99 98 | : 01 0061 00 06 98 99 | : 01 0062 00 06 97 100 | : 01 0063 00 06 96 101 | : 01 0064 00 06 95 102 | : 01 0065 00 06 94 103 | : 01 0066 00 06 93 104 | : 01 0067 00 06 92 105 | : 01 0068 00 06 91 106 | : 01 0069 00 06 90 107 | : 01 006A 00 06 8F 108 | : 01 006B 00 06 8E 109 | : 01 006C 00 06 8D 110 | : 01 006D 00 06 8C 111 | : 01 006E 00 06 8B 112 | : 01 006F 00 06 8A 113 | : 01 0070 00 06 89 114 | : 01 0071 00 06 88 115 | : 01 0072 00 06 87 116 | : 01 0073 00 06 86 117 | : 01 0074 00 06 85 118 | : 01 0075 00 06 84 119 | : 01 0076 00 06 83 120 | : 01 0077 00 06 82 121 | : 01 0078 00 06 81 122 | : 01 0079 00 06 80 123 | : 01 007A 00 06 7F 124 | : 01 007B 00 06 7E 125 | : 01 007C 00 06 7D 126 | : 01 007D 00 06 7C 127 | : 01 007E 00 06 7B 128 | : 01 007F 00 06 7A 129 | : 00 0000 01 FF 130 | -------------------------------------------------------------------------------- /Microcode/tty_screen_map.mif: -------------------------------------------------------------------------------- 1 | %---------------------------------% 2 | WIDTH=6; 3 | DEPTH=128; 4 | ADDRESS_RADIX=HEX; 5 | DATA_RADIX=BIN; 6 | CONTENT BEGIN 7 | 0000 : 001010; 8 | 0001 : 001011; 9 | 0002 : 010010; 10 | [0003 .. 0009] : 001010; 11 | 000A : 010011; 12 | [000B .. 000C] : 001010; 13 | 000D : 100001; 14 | [000E .. 001F] : 001010; 15 | [0020 .. 007F] : 000110; 16 | END; 17 | %---------------------------------% 18 | -------------------------------------------------------------------------------- /Microcode/tty_screen_map.vhd: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------- 2 | -- mcc V0.9.0530 - Custom microcode compiler (c)2020-... 3 | -- https://github.com/zpekic/MicroCodeCompiler 4 | -------------------------------------------------------- 5 | -- Auto-generated file, do not modify. To customize, create 'mapper_template.vhd' file in mcc.exe folder 6 | -- Supported placeholders: [SIZES], [NAME], [TYPE], [SIGNAL], [MEMORY]. 7 | -------------------------------------------------------- 8 | library IEEE; 9 | use IEEE.STD_LOGIC_1164.all; 10 | --use IEEE.numeric_std.all; 11 | 12 | package tty_screen_map is 13 | 14 | -- memory block size 15 | constant MAPPER_DATA_WIDTH: positive := 6; 16 | constant MAPPER_ADDRESS_WIDTH: positive := 7; 17 | constant MAPPER_ADDRESS_LAST: positive := 127; 18 | 19 | 20 | type tty_mapper_memory is array(0 to 127) of std_logic_vector(5 downto 0); 21 | 22 | signal tty_instructionstart: std_logic_vector(5 downto 0); 23 | 24 | 25 | 26 | constant tty_mapper: tty_mapper_memory := ( 27 | 28 | -- L0083@000A. 0b00?_???? 29 | 0 => O"12", 30 | 31 | -- L0087@000B. 0b000_0001 32 | 1 => O"13", 33 | 34 | -- L0102@0012. 0b000_0010 35 | 2 => O"22", 36 | 37 | 3 => O"12", 38 | 39 | 4 => O"12", 40 | 41 | 5 => O"12", 42 | 43 | 6 => O"12", 44 | 45 | 7 => O"12", 46 | 47 | 8 => O"12", 48 | 49 | 9 => O"12", 50 | 51 | -- L0106@0013. 0b000_1010 52 | 10 => O"23", 53 | 54 | 11 => O"12", 55 | 56 | 12 => O"12", 57 | 58 | -- L0140@0021. 0b000_1101 59 | 13 => O"41", 60 | 61 | 14 => O"12", 62 | 63 | 15 => O"12", 64 | 65 | 16 => O"12", 66 | 67 | 17 => O"12", 68 | 69 | 18 => O"12", 70 | 71 | 19 => O"12", 72 | 73 | 20 => O"12", 74 | 75 | 21 => O"12", 76 | 77 | 22 => O"12", 78 | 79 | 23 => O"12", 80 | 81 | 24 => O"12", 82 | 83 | 25 => O"12", 84 | 85 | 26 => O"12", 86 | 87 | 27 => O"12", 88 | 89 | 28 => O"12", 90 | 91 | 29 => O"12", 92 | 93 | 30 => O"12", 94 | 95 | 31 => O"12", 96 | 97 | 32 => O"06", 98 | 99 | 33 => O"06", 100 | 101 | 34 => O"06", 102 | 103 | 35 => O"06", 104 | 105 | 36 => O"06", 106 | 107 | 37 => O"06", 108 | 109 | 38 => O"06", 110 | 111 | 39 => O"06", 112 | 113 | 40 => O"06", 114 | 115 | 41 => O"06", 116 | 117 | 42 => O"06", 118 | 119 | 43 => O"06", 120 | 121 | 44 => O"06", 122 | 123 | 45 => O"06", 124 | 125 | 46 => O"06", 126 | 127 | 47 => O"06", 128 | 129 | 48 => O"06", 130 | 131 | 49 => O"06", 132 | 133 | 50 => O"06", 134 | 135 | 51 => O"06", 136 | 137 | 52 => O"06", 138 | 139 | 53 => O"06", 140 | 141 | 54 => O"06", 142 | 143 | 55 => O"06", 144 | 145 | 56 => O"06", 146 | 147 | 57 => O"06", 148 | 149 | 58 => O"06", 150 | 151 | 59 => O"06", 152 | 153 | 60 => O"06", 154 | 155 | 61 => O"06", 156 | 157 | 62 => O"06", 158 | 159 | 63 => O"06", 160 | 161 | 64 => O"06", 162 | 163 | 65 => O"06", 164 | 165 | 66 => O"06", 166 | 167 | 67 => O"06", 168 | 169 | 68 => O"06", 170 | 171 | 69 => O"06", 172 | 173 | 70 => O"06", 174 | 175 | 71 => O"06", 176 | 177 | 72 => O"06", 178 | 179 | 73 => O"06", 180 | 181 | 74 => O"06", 182 | 183 | 75 => O"06", 184 | 185 | 76 => O"06", 186 | 187 | 77 => O"06", 188 | 189 | 78 => O"06", 190 | 191 | 79 => O"06", 192 | 193 | 80 => O"06", 194 | 195 | 81 => O"06", 196 | 197 | 82 => O"06", 198 | 199 | 83 => O"06", 200 | 201 | 84 => O"06", 202 | 203 | 85 => O"06", 204 | 205 | 86 => O"06", 206 | 207 | 87 => O"06", 208 | 209 | 88 => O"06", 210 | 211 | 89 => O"06", 212 | 213 | 90 => O"06", 214 | 215 | 91 => O"06", 216 | 217 | 92 => O"06", 218 | 219 | 93 => O"06", 220 | 221 | 94 => O"06", 222 | 223 | 95 => O"06", 224 | 225 | 96 => O"06", 226 | 227 | 97 => O"06", 228 | 229 | 98 => O"06", 230 | 231 | 99 => O"06", 232 | 233 | 100 => O"06", 234 | 235 | 101 => O"06", 236 | 237 | 102 => O"06", 238 | 239 | 103 => O"06", 240 | 241 | 104 => O"06", 242 | 243 | 105 => O"06", 244 | 245 | 106 => O"06", 246 | 247 | 107 => O"06", 248 | 249 | 108 => O"06", 250 | 251 | 109 => O"06", 252 | 253 | 110 => O"06", 254 | 255 | 111 => O"06", 256 | 257 | 112 => O"06", 258 | 259 | 113 => O"06", 260 | 261 | 114 => O"06", 262 | 263 | 115 => O"06", 264 | 265 | 116 => O"06", 266 | 267 | 117 => O"06", 268 | 269 | 118 => O"06", 270 | 271 | 119 => O"06", 272 | 273 | 120 => O"06", 274 | 275 | 121 => O"06", 276 | 277 | 122 => O"06", 278 | 279 | 123 => O"06", 280 | 281 | 124 => O"06", 282 | 283 | 125 => O"06", 284 | 285 | 126 => O"06", 286 | 287 | 127 => O"06"); 288 | 289 | end tty_screen_map; 290 | 291 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | "mcc" is a compiler written in C# that takes symbolic descriptions of microcode instructions and generates mapper and microcode ROM initialization files, typically used in FPGA syntesis of CPU control units. 2 | 3 | The basic idea behind it is a standardized microcontrol unit, which is simple yet powerful and can easily drive devices such as various processors and controllers. It allows for example relatively easy recreation of 8- and 16-bit historic CPUs in VHDL. Key elements: 4 | 5 | - Mapper memory. Address is the instruction register (or any sub/superset of it), and output the entry point where the microinstruction sequence implementing it starts 6 | 7 | - Microcode memory. Address is output from microinstruction program counter, and output is the microinstruction word driving the machine 8 | 9 | - Control unit. It is driven by 3 fields of microinstruction word: 10 | 1. "if" -- this is simply a select of a n to 1 mux which decides if the condition is true or false 11 | 2. "then" -- target to execute or jump to if the condition is true 12 | 3. "else" -- target to execute of jump to if the condition is false 13 | 14 | The control unit is made simple by 2 innovations: 15 | 16 | a) The jump target and instructions are overlapped. Typically the first 4 codes are reserved for: 17 | next ... upc <= upc + 1; 18 | repeat ... upc <= upc; 19 | fork ... upc <= mapper(instruction_register); 20 | return ... upc <= stack pop; 21 | 22 | All the other targets presented on "then" or "else" are interpreted as upc <= target 23 | 24 | b) a limited depth stack (typically 4 levels) is built in. That means each upc <= target also pushes the previous address on the stack in one machine cycle, and return is also executed in 1 machine cycle. This means that at each jump the bottom of the stack is lost, in other words programmer must take care to never nest more than 3 levels if stack is 4 levels deep. 25 | 26 | You can find a bit more info about the ideas behind this here: https://hackaday.io/project/167457-tms0800-fpga-implementation-in-vhdl/log/168280-patterns-for-creating-microcode-driven-core-in-vhdl 27 | -------------------------------------------------------------------------------- /mcc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2018 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mcc", "mcc\mcc.csproj", "{B0335713-7C5D-4C36-A8C7-599F65A6C482}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B0335713-7C5D-4C36-A8C7-599F65A6C482}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B0335713-7C5D-4C36-A8C7-599F65A6C482}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B0335713-7C5D-4C36-A8C7-599F65A6C482}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B0335713-7C5D-4C36-A8C7-599F65A6C482}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {FBAB9C72-9979-410B-9D0C-61002A5B726F} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /mcc/Alias.cs: -------------------------------------------------------------------------------- 1 | namespace mcc 2 | { 3 | internal class Alias : ParsedLineWithLabel 4 | { 5 | public string[] Lines; 6 | 7 | public Alias(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".alias", lineNumber, orgValue, label, content, logger) 8 | { 9 | Lines = content.Split('\\'); 10 | for (int i = 0; i < Lines.Length; i++) 11 | { 12 | Lines[i] = Lines[i].Trim(); 13 | } 14 | } 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /mcc/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /mcc/Code.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace mcc 6 | { 7 | internal class Code : MemBlock 8 | { 9 | public Code(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".code", lineNumber, orgValue, label, content, logger) 10 | { 11 | } 12 | 13 | protected override int GenerateVhdFile(string prefix, FileInfo outputFileInfo, List fields, string otherRanges, bool isConversion, bool isRisingEdge) 14 | { 15 | Assert(!string.IsNullOrEmpty(prefix), ":.vhd expected - prefix not found"); 16 | Assert(!isConversion, "Code memory cannot be used for conversion (internal error)"); 17 | 18 | logger.Write($"Generating code '{outputFileInfo.FullName}' ..."); 19 | string template = LoadVhdPackageTemplate("code_template.vhd", false); 20 | int capacity = 2 << (this.addressWidth - 1); 21 | string defaultMicroinstruction = string.Empty; 22 | string name = outputFileInfo.Name.Substring(0, outputFileInfo.Name.IndexOf(".")); 23 | 24 | MicroField fif = fields.Find(fl => fl.GetType().ToString() == "mcc.FieldIf"); 25 | 26 | using (System.IO.StreamWriter vhdFile = new System.IO.StreamWriter(outputFileInfo.FullName, false, Encoding.ASCII)) 27 | { 28 | logger.PrintBanner(vhdFile); 29 | template = template.Replace("[NAME]", name); 30 | template = template.Replace("[FIELDS]", GetVhdFields(prefix, fields, out defaultMicroinstruction, isRisingEdge)); 31 | template = template.Replace("[SIZES]", GetVhdlSizes("CODE", fif as FieldIf)); 32 | template = template.Replace("[TYPE]", $"type {prefix}_code_memory is array(0 to {capacity - 1}) of std_logic_vector({dataWidth - 1} downto 0);"); 33 | template = template.Replace("[SIGNAL]", $"signal {prefix}_uinstruction: std_logic_vector({dataWidth - 1} downto 0);"); 34 | template = template.Replace("[INSTANCE]", $"--{prefix}_uinstruction <= {prefix}_microcode(to_integer(unsigned(TODO))); -- copy to file containing the control unit. TODO is typically replace with 'ui_address' control unit output"); 35 | template = template.Replace("[MEMORY]", $"constant {prefix}_microcode: {prefix}_code_memory := ({GetVhdMemory(capacity, defaultMicroinstruction, otherRanges, false)});"); 36 | template = template.Replace("[PLACEHOLDERS]", " [NAME], [FIELDS], [SIZES], [TYPE], [SIGNAL], [INSTANCE], [MEMORY]"); 37 | vhdFile.WriteLine(template); 38 | } 39 | 40 | logger.WriteLine(" Done."); 41 | return 1; 42 | } 43 | 44 | public static string GetFieldLabel(MicroField mf) 45 | { 46 | //Assert(mf != null && !string.IsNullOrEmpty(mf.Label), "Undefined field label"); 47 | 48 | return mf.Label; 49 | } 50 | 51 | protected string GetVhdFields(string prefix, List fields, out string defaultMicroinstruction, bool isRisingEdge) 52 | { 53 | Assert(fields != null && (fields.Count > 0), "Can't generate code - no microcode fields defined"); 54 | 55 | StringBuilder sbFields = new StringBuilder(); 56 | StringBuilder sbDefault = new StringBuilder(); 57 | List fieldLabels = fields.ConvertAll(new System.Converter(GetFieldLabel)); 58 | foreach (MicroField field in fields) 59 | { 60 | if (field.Width > 0) 61 | { 62 | // default microinstruction is based on base fields, not the overlapping ones 63 | sbDefault.Append(GetBinaryString(field.DefaultValue, field.Width)); 64 | sbDefault.Append("_"); 65 | } 66 | 67 | sbFields.AppendLine($"--"); 68 | sbFields.AppendLine($"-- {field.GetParsedLineString()}"); 69 | sbFields.AppendLine($"--"); 70 | if (field.Hi > field.Lo) 71 | { 72 | sbFields.AppendLine($"alias {prefix}_{field.Label}: \tstd_logic_vector({field.Hi - field.Lo} downto 0) is {prefix}_uinstruction({field.Hi} downto {field.Lo});"); 73 | } 74 | else 75 | { 76 | Assert(field.Hi == field.Lo, $"Unexpected field span ({field.Hi} .. {field.Lo})"); 77 | sbFields.AppendLine($"alias {prefix}_{field.Label}: \tstd_logic is {prefix}_uinstruction({field.Hi});"); 78 | } 79 | foreach (MicroField.ValueVector vv in field.Values) 80 | { 81 | string vhdLine = string.Empty; 82 | string[] altNames = vv.Name.Split('|'); 83 | 84 | for (int i = 0; i < altNames.Length; i++) 85 | { 86 | if (i == 0) 87 | { 88 | vhdLine = vv.GetVhdLine(field, field is FieldIf); 89 | sbFields.AppendLine(vhdLine); 90 | } 91 | else 92 | { 93 | sbFields.AppendLine(vhdLine.Replace(altNames[0], altNames[i])); 94 | } 95 | } 96 | } 97 | 98 | // attempt to create VHDL code for lazy copy/pasting 99 | StringBuilder sbCode = field.GetVhdlBoilerplateCode(prefix, fieldLabels, isRisingEdge); 100 | sbFields.Append(sbCode); 101 | 102 | sbFields.AppendLine(); 103 | sbFields.AppendLine(); 104 | } 105 | 106 | // remove last underscore 107 | if (sbDefault.Length > 0) 108 | { 109 | sbDefault.Remove(sbDefault.Length - 1, 1); 110 | } 111 | defaultMicroinstruction = sbDefault.ToString(); 112 | 113 | return sbFields.ToString(); 114 | } 115 | 116 | protected override string GetBlockName() 117 | { 118 | return this.GetType().ToString(); 119 | } 120 | 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /mcc/Controller.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Threading.Tasks; 7 | 8 | namespace mcc 9 | { 10 | internal class Controller : ParsedLineWithNoLabel 11 | { 12 | protected List outputFiles = new List(); 13 | protected int stackDepth; 14 | protected bool isRisingEdge = true; 15 | 16 | public Controller(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".controller", lineNumber, orgValue, label, content, logger) 17 | { 18 | Assert(orgValue < 0, "Definition statement must precede .org"); 19 | } 20 | 21 | public override void ParseContent() 22 | { 23 | int lastParamOffset = 1; 24 | bool edgeSet = false; 25 | 26 | base.ParseContent(); 27 | 28 | string[] param = this.Content.Split(','); 29 | 30 | Assert(param.Length > 1, "Missing parameter(s) - expected: filename0.ext[, filename1.ext [, ...]], stack_depth[, rising|falling]"); 31 | 32 | if ("rising".Equals(param[param.Length - 1].Trim(), StringComparison.InvariantCultureIgnoreCase)) 33 | { 34 | lastParamOffset++; 35 | isRisingEdge = true; 36 | edgeSet = true; 37 | } 38 | if ("falling".Equals(param[param.Length - 1].Trim(), StringComparison.InvariantCultureIgnoreCase)) 39 | { 40 | lastParamOffset++; 41 | isRisingEdge = false; 42 | edgeSet = true; 43 | } 44 | for (int i = 0; i < param.Length - lastParamOffset; i++) 45 | { 46 | outputFiles.Add(param[i].Trim()); 47 | } 48 | Assert(int.TryParse(param[param.Length - lastParamOffset], out this.stackDepth), "Bad stack depth"); 49 | Assert((this.stackDepth > 1) && (this.stackDepth < 9), "Stack depth must be between 2 and 8"); 50 | Assert(outputFiles.Count >= 0, "No output files specified"); 51 | if (edgeSet) 52 | { 53 | logger.WriteLine("Clock edge explicitly set to " + (isRisingEdge ? "rising_edge()" : "falling_edge()")); 54 | } 55 | else 56 | { 57 | logger.WriteLine("Warning: Clock edge implicitly (by default) set to " + (isRisingEdge ? "rising_edge()" : "falling_edge()")); 58 | } 59 | } 60 | 61 | public bool GetClockEdge() 62 | { 63 | return this.isRisingEdge; 64 | } 65 | 66 | public int GenerateFiles(string trace) 67 | { 68 | int count = 0; 69 | 70 | logger.WriteLine(trace); 71 | 72 | foreach (string fileName in this.outputFiles) 73 | { 74 | FileInfo outputFileInfo = null; 75 | string prefix = null; 76 | string[] prefixNamePair = fileName.Split(':'); 77 | 78 | switch (prefixNamePair.Length) 79 | { 80 | case 0: 81 | Assert(false, $"Filename '{fileName}' is invalid."); 82 | break; 83 | case 1: 84 | outputFileInfo = new FileInfo(prefixNamePair[0]); 85 | break; 86 | case 2: 87 | prefix = prefixNamePair[0]; 88 | outputFileInfo = new FileInfo(prefixNamePair[1]); 89 | logger.WriteLine(string.Format("Warning in line {0}: prefix '{1}' will be ignored", this.LineNumber.ToString(), prefix)); 90 | break; 91 | default: 92 | Assert(false, $"Filename '{fileName}' is invalid."); 93 | break; 94 | } 95 | 96 | switch (outputFileInfo.Extension.ToLowerInvariant()) 97 | { 98 | case ".vhd": 99 | count += GenerateVhdFile(outputFileInfo, this.isRisingEdge); 100 | break; 101 | default: 102 | logger.WriteLine(string.Format("Warning in line {0}: unsupported extension in file '{1}'", this.LineNumber.ToString(), fileName)); 103 | break; 104 | } 105 | } 106 | return count; 107 | } 108 | 109 | private int GenerateVhdFile(FileInfo outputFileInfo, bool isRisingEdge) 110 | { 111 | logger.Write($"Generating controller '{outputFileInfo.FullName}' ..."); 112 | string stack_def = string.Empty; 113 | string stack_push = string.Empty; 114 | string stack_pop = string.Empty; 115 | for (int i = 0; i < this.stackDepth; i++) 116 | { 117 | if ((this.stackDepth - i) == 1) 118 | { 119 | stack_def += $"uPC{i} "; 120 | stack_pop += $"\t\t\t\t\t\t\t\tuPC{i} <= (others => '1');\r\n"; 121 | } 122 | else 123 | { 124 | stack_def += $"uPC{i}, "; 125 | stack_pop += $"\t\t\t\t\t\t\t\tuPC{i} <= uPC{i + 1};\r\n"; 126 | } 127 | 128 | switch (i) 129 | { 130 | case 0: 131 | stack_push += $"\t\t\t\tuPC{i} <= ui_nextinstr;\r\n"; 132 | break; 133 | case 1: 134 | stack_push += $"\t\t\t\t\t\tuPC1 <= std_logic_vector(unsigned(uPC0) + 1);\r\n"; 135 | break; 136 | default: 137 | stack_push += $"\t\t\t\t\t\tuPC{i} <= uPC{i - 1};\r\n"; 138 | break; 139 | } 140 | } 141 | stack_pop = stack_pop.TrimEnd(new char[] {'\r', '\n'}); 142 | stack_push = stack_push.TrimEnd(new char[] {'\r','\n'}); 143 | 144 | string template = LoadVhdControllerTemplate("controller_template.vhd", this.isRisingEdge); 145 | string name = outputFileInfo.Name.Substring(0, outputFileInfo.Name.IndexOf(".")); 146 | using (System.IO.StreamWriter vhdFile = new System.IO.StreamWriter(outputFileInfo.FullName, false, Encoding.ASCII)) 147 | { 148 | logger.PrintBanner(vhdFile); 149 | template = template.Replace("[NAME]", name); 150 | //template = template.Replace("[PREFIX]", prefix); 151 | template = template.Replace("[STACK_DEF]", stack_def); 152 | template = template.Replace("[STACK_PUSH]", stack_push); 153 | template = template.Replace("[STACK_POP]", stack_pop); 154 | template = template.Replace("[PLACEHOLDERS]", " [NAME], [STACK_DEF], [STACK_PUSH], [STACK_POP]"); 155 | vhdFile.WriteLine(template); 156 | } 157 | 158 | logger.WriteLine(" Done."); 159 | return 1; 160 | } 161 | 162 | private string LoadVhdControllerTemplate(string fileName, bool isRisingEdge) 163 | { 164 | if (File.Exists(fileName)) 165 | { 166 | return File.ReadAllText(fileName); 167 | } 168 | else 169 | { 170 | StringBuilder sb = new StringBuilder(); 171 | sb.AppendLine($"-- Auto-generated file, do not modify. To customize, create '{fileName}' file in mcc.exe folder"); 172 | sb.AppendLine("-- Supported placeholders: [PLACEHOLDERS]."); 173 | sb.AppendLine("--------------------------------------------------------"); 174 | sb.AppendLine("library IEEE;"); 175 | sb.AppendLine("use IEEE.STD_LOGIC_1164.all;"); 176 | sb.AppendLine("use IEEE.numeric_std.all;"); 177 | sb.AppendLine(); 178 | sb.AppendLine("entity [NAME] is"); 179 | sb.AppendLine(" Generic ("); 180 | sb.AppendLine(" CODE_DEPTH : positive;"); 181 | sb.AppendLine(" IF_WIDTH : positive"); 182 | sb.AppendLine(" );"); 183 | sb.AppendLine(" Port ( "); 184 | sb.AppendLine(" -- standard inputs"); 185 | sb.AppendLine(" reset : in STD_LOGIC;"); 186 | sb.AppendLine(" clk : in STD_LOGIC;"); 187 | sb.AppendLine(" -- design specific inputs"); 188 | sb.AppendLine(" seq_cond : in STD_LOGIC_VECTOR (IF_WIDTH - 1 downto 0);"); 189 | sb.AppendLine(" seq_then : in STD_LOGIC_VECTOR (CODE_DEPTH - 1 downto 0);"); 190 | sb.AppendLine(" seq_else : in STD_LOGIC_VECTOR (CODE_DEPTH - 1 downto 0);"); 191 | sb.AppendLine(" seq_fork : in STD_LOGIC_VECTOR (CODE_DEPTH - 1 downto 0);"); 192 | sb.AppendLine(" cond : in STD_LOGIC_VECTOR (2 ** IF_WIDTH - 1 downto 0);"); 193 | sb.AppendLine(" -- outputs"); 194 | sb.AppendLine(" ui_nextinstr : buffer STD_LOGIC_VECTOR (CODE_DEPTH - 1 downto 0);"); 195 | sb.AppendLine(" ui_address : out STD_LOGIC_VECTOR (CODE_DEPTH - 1 downto 0));"); 196 | sb.AppendLine("end [NAME];"); 197 | sb.AppendLine(); 198 | sb.AppendLine("architecture Behavioral of [NAME] is"); 199 | sb.AppendLine(); 200 | sb.AppendLine("constant zero: std_logic_vector(31 downto 0) := X\"00000000\";"); 201 | sb.AppendLine(); 202 | sb.AppendLine("signal [STACK_DEF]: std_logic_vector(CODE_DEPTH - 1 downto 0);"); 203 | sb.AppendLine("signal condition, push, jump: std_logic;"); 204 | sb.AppendLine(); 205 | sb.AppendLine("begin"); 206 | sb.AppendLine(); 207 | sb.AppendLine("-- uPC holds the address of current microinstruction"); 208 | sb.AppendLine("ui_address <= uPC0;"); 209 | sb.AppendLine("-- evaluate if true/false"); 210 | sb.AppendLine("condition <= cond(to_integer(unsigned(seq_cond)));"); 211 | sb.AppendLine("-- select next instruction based on condition"); 212 | sb.AppendLine("ui_nextinstr <= seq_then when (condition = '1') else seq_else;"); 213 | sb.AppendLine("-- check if jump or one of 4 \"special\" instructions"); 214 | sb.AppendLine("jump <= '0' when (ui_nextinstr(CODE_DEPTH - 1 downto 2) = zero(CODE_DEPTH - 3 downto 0)) else '1';"); 215 | sb.AppendLine("-- push only if both branches are same"); 216 | sb.AppendLine("push <= '1' when (seq_then = seq_else) else '0';"); 217 | sb.AppendLine(); 218 | sb.AppendLine("sequence: process(reset, clk, push, jump, ui_nextinstr)"); 219 | sb.AppendLine("begin"); 220 | sb.AppendLine(" if (reset = '1') then"); 221 | sb.AppendLine(" uPC0 <= (others => '0'); -- reset clears top microcode program counter"); 222 | sb.AppendLine(" else"); 223 | sb.AppendLine(isRisingEdge ? " if (rising_edge(clk)) then" : " if (falling_edge(clk)) then"); 224 | sb.AppendLine(" if (jump = '1') then"); 225 | sb.AppendLine(" if (push = '1') then"); 226 | sb.AppendLine("[STACK_PUSH]"); 227 | sb.AppendLine(" else"); 228 | sb.AppendLine(" uPC0 <= ui_nextinstr;"); 229 | sb.AppendLine(" end if;"); 230 | sb.AppendLine(" else"); 231 | sb.AppendLine(" case (ui_nextinstr(1 downto 0)) is"); 232 | sb.AppendLine(" when \"00\" => -- next"); 233 | sb.AppendLine(" uPC0 <= std_logic_vector(unsigned(uPC0) + 1);"); 234 | sb.AppendLine(" when \"01\" => -- repeat"); 235 | sb.AppendLine(" uPC0 <= uPC0;"); 236 | sb.AppendLine(" when \"10\" => -- return"); 237 | sb.AppendLine("[STACK_POP]"); 238 | sb.AppendLine(" when \"11\" => -- fork"); 239 | sb.AppendLine(" uPC0 <= seq_fork;"); 240 | sb.AppendLine(" when others =>"); 241 | sb.AppendLine(" null;"); 242 | sb.AppendLine(" end case;"); 243 | sb.AppendLine(" end if;"); 244 | sb.AppendLine(" end if;"); 245 | sb.AppendLine(" end if;"); 246 | sb.AppendLine("end process; "); 247 | sb.AppendLine(); 248 | sb.AppendLine("end;"); 249 | 250 | return sb.ToString(); 251 | } 252 | } 253 | 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /mcc/Examples/CDP180X/Run at 12M5 Hz.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/CDP180X/Run at 12M5 Hz.PNG -------------------------------------------------------------------------------- /mcc/Examples/CDP180X/Run at 25MHz.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/CDP180X/Run at 25MHz.PNG -------------------------------------------------------------------------------- /mcc/Examples/CDP180X/mcc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @echo See https://github.com/zpekic/MicroCodeCompiler 3 | copy ..\..\sys9900\mcc\microcode\cdp180X.mcc 4 | ..\..\Sys9900\mcc\mcc\bin\Debug\mcc.exe cdp180X.mcc 5 | -------------------------------------------------------------------------------- /mcc/Examples/EMZ1001/Fibonacci.emz: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------------------------- 2 | // Fibonacci test code for EMZ1001 (c) 2022-... zpekic@hotmail.com 3 | // Compile with https://github.com/zpekic/MicroCodeCompiler 4 | //--------------------------------------------------------------------------------------------- 5 | // Test code to load into internal 1k ROM of Iskra EMZ1001 (AMI S2000) 4-bit microcontroller 6 | // http://www.bitsavers.org/components/ami/s2000/ 7 | // Full description: 8 | // https://hackaday.io/project/188614-iskra-emz1001a-a-virtual-resurrection/log/214196-test-code-fibonacci-sequence-generator 9 | //--------------------------------------------------------------------------------------------- 10 | .code 10, 8, fibonacci_code.mif, fibonacci_code.cgf, fibonacci_code.coe, fib:fibonacci_code.vhd, fibonacci_code.hex, fibonacci_code.bin, 1; 11 | .symbol 10, 256, fibonacci_sym.mif, fibonacci_sym.cgf, fibonacci_sym.coe, fib:fibonacci_sym.vhd, fibonacci_sym.hex, fibonacci_sym.bin, 32; 12 | 13 | #include "emz1001.mcc"; 14 | 15 | CR: .alias 0xD; 16 | LF: .alias 0xA; 17 | OUT_READY: .alias 1; // mask for I inputs 18 | 19 | // --------------------------------------------------------------------------- 20 | .org 0; 21 | // Execution starts at bank 0, page 0, location 0 22 | // --------------------------------------------------------------------------- 23 | NOP; 24 | 25 | LAI 0b1000; // bit3 = 50Hz, bit0 = invert D lines on output 26 | EUR; // set prescaler and inverter 27 | 28 | DEADLOOP: LBZ 0; // select RAM column 0, row 0 29 | JMS CLEAR; // clear RAM column 0 30 | 31 | LBZ 1; // select RAM column 1, row 0 32 | JMS CLEAR; // clear RAM column 1 33 | 34 | LBZ 1; // select digit 0 in RAM column 1 35 | STM 0; // RAM[1,0] = 1 36 | 37 | LBF 0b10; // select current Fibonacci number column (2), BL = 15 38 | PSH; // set all A lines high 39 | MVS; // all anodes high 40 | XCD 0b00; // BL = 14, keep BU 41 | PSH; // drive D lines, do not float them 42 | XCD 0b00; // BL = 13, keep BU 43 | PSL; // set static operation 44 | 45 | ADDLOOP: JMS BCDADD; // RAM[2,*] = RAM[0,*] + RAM[1,*] 46 | SZC; // check for overflow 47 | JMP DEADLOOP; // carry from most significant digit means overflow, start from scratch 48 | PP 14; // prepare for page 14 (instead of usual 15) 49 | JMS DISP_TTY; // display to "teletype" (ASCII sequence output) 50 | 51 | DISPLOOP: JMS DISP_LED; // display to 7-seg LEDs 52 | SOS; // check if 1 second lapsed 53 | JMP DISPLOOP; // no, continue refreshing LEDs as fast as possible 54 | 55 | JMS SHIFT0; // RAM[0,*] = RAM[1,*] 56 | 57 | JMS SHIFT1; // RAM[1,*] = RAM[2,*] 58 | 59 | JMP ADDLOOP; // RAM[0,*] and RAM[1,*] contain last two Fibonacci numbers, continue 60 | 61 | // --------------------------------------------------------------------------- 62 | .org 0b1110000000; 63 | // Page 14 as an "overflow" from busy subroutine page 15 64 | // --------------------------------------------------------------------------- 65 | DISP_TTY: LAI 12; // start displaying at digit 12 66 | XAE; // 67 | LBE 0b10; // BL = 12, BU = 2 68 | TTYLOOP: LAI 3; // ASCII digits 0..9 are hex 0x30 to 0x39 69 | XC 0; // keep BU, M.A is now 3.x 70 | OUT; // D pins <= 3X, strobe EXT low 71 | XAE; // save to E reg 72 | WAIT_DIGIT: LAI OUT_READY; 73 | SZI; 74 | JMP CONT; 75 | JMP WAIT_DIGIT; 76 | CONT: XAE; // restore 77 | XCD 0b00; // next, do not change column 78 | JMP TTYLOOP; 79 | CRLF: RSM 3; // clear M[BU, BL] 80 | RSM 2; 81 | RSM 1; 82 | RSM 0; 83 | LAI CR; // High nibble from M, low nibble from A give ASCII code 84 | OUT; 85 | WAIT_CR: LAI OUT_READY; 86 | SZI; 87 | JMP OUT_LF; 88 | JMP WAIT_CR; 89 | OUT_LF: LAI LF; // Line feed ASCII code 90 | OUT; 91 | WAIT_LF: LAI OUT_READY; 92 | SZI; 93 | RT; 94 | JMP WAIT_LF; 95 | 96 | // --------------------------------------------------------------------------- 97 | .org 0b1111000000; 98 | // Page 15 in the bank is the default place for subroutines 99 | // --------------------------------------------------------------------------- 100 | CLEAR: LAI 0; // A = 0, BU set by caller 101 | XCI 0; // Exchange with M[BU, BL], BU = BU, BL++ 102 | JMP CLEAR; // repeat until all covered (BU = 0) 103 | RT; // back 104 | 105 | SHIFT0: LBZ 0b01; // row (BL) = 0, col (BU) = 1 106 | SHIFT0LOOP: LAM 0b01; // A = M[1, BL], BU = 0 (LSB flipped) 107 | XCI 0b01; // exchange with M[0, BL], BU = 1 (LSB flipped back), BL++ 108 | JMP SHIFT0LOOP; // repeat until all moved from column 1 to 0 109 | RT; 110 | 111 | SHIFT1: LBZ 0b10; // start with column 2 112 | SHIFT1LOOP: LAM 0b11; // switch to column 1 (both bits flipped!) 113 | XCI 0b11; // switch back to column 2 114 | JMP SHIFT1LOOP; 115 | RT; 116 | 117 | DISP_LED: LAI 12; // start displaying at digit 12 118 | XAE; // 119 | LBE 0b10; // BL = 12, BU = 2 120 | RSC; // no decimal point displayed 121 | LEDLOOP: LAM 0b00; // A <= M[BU, BL] 122 | DISN; // segment pattern to D outputs (inverted) 123 | PSL; // prepare digit low (on) 124 | MVS; // update A pins (A[BL] <= '0') 125 | NOP; // delay to keep it lit for a bit 126 | NOP; 127 | NOP; 128 | NOP; 129 | NOP; 130 | NOP; 131 | PSH; // prepare digit high (off) 132 | MVS; // update A pins (A[BL] <= '1') 133 | XCD 0b00; // next, do not change column 134 | JMP LEDLOOP; 135 | RT; 136 | 137 | BCDADD: LBZ 0; // BL = 0, BU = 0 138 | RSC; // clear carry 139 | ALOOP: LAM 0b01; // A = M[0, BL], BU = 1 140 | ADCS; // C,A = A + M[1, BU] + C 141 | JMS V16_TO_18; // carry set 142 | JMS V0_TO_15; // carry not set 143 | XAE; // save A in E 144 | LAI 2; // A = 2 145 | XABU; // BU = 2 146 | XAE; // restore A 147 | XCI 0b10; // M[2, BL] = A, BU = 0 148 | JMP ALOOP; // repeat until all 16 digits 149 | RT; // done 150 | 151 | V0_TO_15: XAE; 152 | LAE; // E = A 153 | ADIS 6; // Classic DAA adjust 154 | JMP BCDCARRY; // carry set, adjustment was needed, A is correct BCD 155 | XAE; // carry not set, adjustment was not needed, restore A 156 | RT; 157 | BCDCARRY: STC; 158 | RT; 159 | 160 | V16_TO_18: ADIS 6; // 0x12 + 6 + 1 becomes 0x18 etc., carry remains set 161 | NOP; 162 | STC; // decimal carry forward 163 | RTS; // skip next 164 | -------------------------------------------------------------------------------- /mcc/Examples/EMZ1001/HelloWorld.emz: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------------------------- 2 | // Hello World test code for EMZ1001 (c) 2022-... zpekic@hotmail.com 3 | // Compile with https://github.com/zpekic/MicroCodeCompiler 4 | //--------------------------------------------------------------------------------------------- 5 | // Test code to load into internal 1k ROM of Iskra EMZ1001 (AMI S2000) 4-bit microcontroller 6 | // http://www.bitsavers.org/components/ami/s2000/ 7 | // Full description: 8 | // https://hackaday.io/project/188614-iskra-emz1001a-a-virtual-resurrection/log/214195-test-code-hello-world 9 | //--------------------------------------------------------------------------------------------- 10 | .code 10, 8, helloworld_code.mif, helloworld_code.cgf, helloworld_code.coe, hlw:helloworld_code.vhd, helloworld_code.hex, helloworld_code.bin, 1; 11 | .symbol 10, 256, helloworld_sym.mif, helloworld_sym.cgf, helloworld_sym.coe, hlw:helloworld_sym.vhd, helloworld_sym.hex, helloworld_sym.bin, 32; 12 | 13 | #include "emz1001.mcc"; 14 | 15 | CR: .alias 0xD; // ASCII code, carriage return 16 | LF: .alias 0xA; // ASCII code, newline 17 | LED_SPACE: .alias 0b00000000; // LED segment patterns 18 | LED_H: .alias 0b00110111; // H 19 | LED_E: .alias 0b01001111; // E 20 | LED_L: .alias 0b00001110; // L 21 | LED_O: .alias 0b00011101; // o 22 | LED_W: .alias 0b00111111; // close enough 23 | LED_R: .alias 0b00000101; // r 24 | LED_D: .alias 0b00111101; // d 25 | LED_EXCL: .alias 0b10110000; // ! (note decimal point is on) 26 | OUT_READY: .alias 1; // mask for I inputs 27 | 28 | // --------------------------------------------------------------------------- 29 | .org 0; 30 | // Execution starts at bank 0, page 0, location 0 31 | // --------------------------------------------------------------------------- 32 | NOP; 33 | 34 | LAI 0b1000; // bit3 = 50Hz, bit0 = invert D lines on output 35 | EUR; // set prescaler and inverter 36 | 37 | LBF 0b10; // select current column (2), BL = 15 38 | PSH; // set all A lines high 39 | MVS; // all anodes high 40 | XCD 0b00; // BL = 14, keep BU 41 | PSH; // drive D lines, do not float them 42 | XCD 0b00; // BL = 13, keep BU 43 | PSL; // set static operation 44 | 45 | JMS INIT_LED1; // store LED char patterns in memory 46 | JMS INIT_LED0; 47 | 48 | GREETINGS: LBZ 0b11; // BU = 3, BL = 0 49 | JMS CRLF; // empty line 50 | JMS H; // output character by characted on D port, with nEXT strobe 51 | JMS E; 52 | JMS L; 53 | JMS L; 54 | JMS O; 55 | JMS SPACE; 56 | JMS W; 57 | JMS O; 58 | JMS R; 59 | JMS L; 60 | JMS D; 61 | JMS EXCPOINT; 62 | JMS CRLF; 63 | 64 | DISPLOOP: JMS DISP_LED; // Refresh 7-seg display 65 | SOS; // check if 1 second lapsed 66 | JMP DISPLOOP; // no, continue refreshing LEDs as fast as possible 67 | LBF 0b00; 68 | JMS ROTATE; // yes, rotate the marquee, RAM bank 0 69 | LBF 0b01; 70 | JMS ROTATE; // RAM bank 1 to keep them in sync 71 | JMP GREETINGS; // continue ad infinitum 72 | 73 | // --------------------------------------------------------------------------- 74 | .org 0b1101000000; 75 | // Page 13 for more subroutines 76 | // ---------------------------------------------------------------------------- 77 | INITLED1_: LBF 1; // RAM bank 1 holds lower nibble of LED patterns 78 | JMS CLEAR4; // clear locations 15, 14, 13, 12 79 | LAI LED_H / 16; // store and decrement BU, leftmost is H (location 12) 80 | XCD 0b00; 81 | LAI LED_E / 16; 82 | XCD 0b00; 83 | LAI LED_L / 16; 84 | XCD 0b00; 85 | LAI LED_L / 16; 86 | XCD 0b00; 87 | LAI LED_O / 16; 88 | XCD 0b00; 89 | LAI LED_SPACE / 16; 90 | XCD 0b00; 91 | LAI LED_W / 16; 92 | XCD 0b00; 93 | LAI LED_O / 16; 94 | XCD 0b00; 95 | LAI LED_R / 16; 96 | XCD 0b00; 97 | LAI LED_L / 16; 98 | XCD 0b00; 99 | LAI LED_D / 16; 100 | XCD 0b00; 101 | LAI LED_EXCL / 16; // rightmost is ! (location 0) 102 | JMP INIT_DONE; // store and return 103 | 104 | INITLED0_: LBF 0; // RAM bank 0 holds upper nibble of LED patterns 105 | JMS CLEAR4; 106 | LAI 0xF & LED_H; 107 | XCD 0b00; 108 | LAI 0xF & LED_E; 109 | XCD 0b00; 110 | LAI 0xF & LED_L; 111 | XCD 0b00; 112 | LAI 0xF & LED_L; 113 | XCD 0b00; 114 | LAI 0xF & LED_O; 115 | XCD 0b00; 116 | LAI 0xF & LED_SPACE; 117 | XCD 0b00; 118 | LAI 0xF & LED_W; 119 | XCD 0b00; 120 | LAI 0xF & LED_O; 121 | XCD 0b00; 122 | LAI 0xF & LED_R; 123 | XCD 0b00; 124 | LAI 0xF & LED_L; 125 | XCD 0b00; 126 | LAI 0xF & LED_D; 127 | XCD 0b00; 128 | LAI 0xF & LED_EXCL; 129 | INIT_DONE: XCD 0b00; 130 | RT; // don't care for condition, just return 131 | RT; 132 | 133 | // --------------------------------------------------------------------------- 134 | .org 0b1110000000; 135 | // Page 14 in the bank is for the subroutines overflow 136 | // ---------------------------------------------------------------------------- 137 | DISP_LED_: LAI 12; // start displaying at digit 12 138 | XAE; // 139 | LBE 0b00; // BL = 12, BU = 0 140 | LEDLOOP: LAM 0b01; // A <= M[0, BL], BU = 1 141 | DISB; // direct pattern to D outputs (inverted) 142 | PSL; // prepare digit low (on) 143 | MVS; // update A pins (A[BL] <= '0') 144 | NOP; // delay to keep it lit for a bit 145 | NOP; 146 | PSH; // prepare digit high (off) 147 | MVS; // update A pins (A[BL] <= '1') 148 | LAM 0b00; 149 | XCD 0b01; // next, change column to 0 150 | JMP LEDLOOP; 151 | RT; 152 | 153 | // --------------------------------------------------------------------------- 154 | .org 0b1111000000; 155 | // Page 15 in the bank is the default place for subroutines 156 | // ---------------------------------------------------------------------------- 157 | ROTATE: LAM 0b00; // A = M[x, 15] 158 | XCI 0b00; // BL is now 0 159 | NOP; 160 | ROTLOOP: XCI 0b00; // deposit from previously visited memory cell, increment BL 161 | JMP ROTLOOP;// continue until all visited 162 | RT; 163 | 164 | INIT_LED0: PP 13; // JMS implicitly calls into page 15, so from here dispatch to page 13 165 | JMP INITLED0_; // using half of 64 nibble RAM as constant storage!! 166 | 167 | INIT_LED1: PP 13; 168 | JMP INITLED1_; 169 | 170 | DISP_LED: PP 14; 171 | JMP DISP_LED_; 172 | 173 | CRLF: LAI CR; 174 | JMS OUT_0; // old assembly trick 175 | LAI LF; 176 | OUT_0: RSM 3; // set current RAM location to 0 177 | RSM 2; 178 | OUT_xx00: RSM 1; 179 | OUT_xxx0: RSM 0; 180 | UART_OUT: OUT; 181 | UART_WAIT: LAI OUT_READY; // connected to pins 0, 1 of I inputs 182 | SZI; // skip if low 183 | RT; // signal high, ready 184 | JMP UART_WAIT; // signal low, not ready 185 | 186 | H: LAI 0x0F & 'H'; // using EMZ1001A trick that in a sequence of LAIs only 1st one is executed! 187 | E: LAI 0x0F & 'E'; 188 | L: LAI 0x0F & 'L'; 189 | O: LAI 0x0F & 'O'; 190 | D: LAI 0x0F & 'D'; 191 | OUT_4: RSM 3; // high nibble is 0b0100 for these ASCII codes 192 | STM 2; 193 | JMP OUT_xx00; 194 | 195 | W: LAI 0x0F & 'W'; 196 | R: LAI 0x0F & 'R'; 197 | OUT_5: RSM 3; // high nibble is 0b0101 for these W and R ASCII codes 198 | STM 2; 199 | RSM 1; 200 | STM 0; 201 | JMP UART_OUT; 202 | 203 | SPACE: LAI 0x0F & ' '; 204 | EXCPOINT: LAI 0x0F & '!'; 205 | OUT_2: RSM 3; 206 | RSM 2; 207 | STM 1; 208 | JMP OUT_xxx0; 209 | 210 | CLEAR4: LAI 0; // clear 4 locations in RAM bank, going backwards 211 | XCD 0b00; 212 | NOP; // don't care if we started at 15, just continue 213 | LAI 0; 214 | XCD 0b00; 215 | LAI 0; 216 | XCD 0b00; 217 | LAI 0; 218 | XCD 0b00; 219 | RT; // tiny bit faster than putting NOP here 220 | RT; 221 | 222 | -------------------------------------------------------------------------------- /mcc/Examples/EMZ1001/emz1001.mcc: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------------------------- 2 | // Include to adapt mcc as assembler for EMZ1001 (AMI S2000) (c) 2022-... zpekic@hotmail.com 3 | // More about mcc: https://github.com/zpekic/MicroCodeCompiler 4 | //--------------------------------------------------------------------------------------------- 5 | // http://www.bitsavers.org/components/ami/s2000/ 6 | // Full description: 7 | // https://hackaday.io/project/188614-iskra-emz1001a-a-virtual-resurrection/log/214194-recreating-a-simple-emz1001a-assembler 8 | //--------------------------------------------------------------------------------------------- 9 | // define any slices of the instruction word format 10 | f76 .valfield 2 values * default 0; 11 | f54 .valfield 2 values * default 0; 12 | f32 .valfield 2 values * default 0; 13 | f10 .valfield 2 values * default 0; 14 | 15 | // define instruction formats 16 | 17 | // most instructions are "implied" address mode 18 | opr8 .valfield f76 .. f10 values * default 0; 19 | // -- or -- 20 | opr6 .valfield f76 .. f32 values * default 0; 21 | val2 .valfield f10 .. f10 values * default 0; 22 | // -- or -- 23 | opr4 .valfield f76 .. f54 values * default 0; 24 | val4 .valfield f32 .. f10 values * default 0; 25 | // -- or -- 26 | opr2 .valfield f76 .. f76 values * default 0; 27 | val6 .valfield f54 .. f10 values * default 0; 28 | 29 | // "aliases" are evaluated as simple text replacement of label with everything between .alias and ; 30 | // 0-bit operand 31 | NOP .alias opr8 = 0x00; 32 | BRK .alias opr8 = 0x01; 33 | RT .alias opr8 = 0x02; 34 | RTS .alias opr8 = 0x03; 35 | PSH .alias opr8 = 0x04; 36 | PSL .alias opr8 = 0x05; 37 | AND .alias opr8 = 0x06; 38 | SOS .alias opr8 = 0x07; 39 | SBE .alias opr8 = 0x08; 40 | SZC .alias opr8 = 0x09; 41 | STC .alias opr8 = 0x0A; 42 | RSC .alias opr8 = 0x0B; 43 | LAE .alias opr8 = 0x0C; 44 | XAE .alias opr8 = 0x0D; 45 | INP .alias opr8 = 0x0E; 46 | EUR .alias opr8 = 0x0F; 47 | CMA .alias opr8 = 0x10; 48 | XABU .alias opr8 = 0x11; 49 | LAB .alias opr8 = 0x12; 50 | XAB .alias opr8 = 0x13; 51 | ADCS .alias opr8 = 0x14; 52 | XOR .alias opr8 = 0x15; 53 | ADD .alias opr8 = 0x16; 54 | SAM .alias opr8 = 0x17; 55 | DISB .alias opr8 = 0x18; 56 | MVS .alias opr8 = 0x19; 57 | OUT .alias opr8 = 0x1A; 58 | DISN .alias opr8 = 0x1B; 59 | 60 | // 2-bit operand, not inverted (0x1C .. 0x27) 61 | SZM .alias opr6 = 0b000111, val2 =; 62 | STM .alias opr6 = 0b001000, val2 =; 63 | RSM .alias opr6 = 0b001001, val2 =; 64 | 65 | // 0-bit operand 66 | SZK .alias opr8 = 0x28; 67 | SZI .alias opr8 = 0x29; 68 | RF1 .alias opr8 = 0x2A; 69 | SF1 .alias opr8 = 0x2B; 70 | RF2 .alias opr8 = 0x2C; 71 | SF2 .alias opr8 = 0x2D; 72 | TF1 .alias opr8 = 0x2E; 73 | TF2 .alias opr8 = 0x2F; 74 | 75 | // 2-bit operand, inverted (0x30 .. 0x3F) 76 | XCI .alias opr6 = 0b001100, val2 = 3 & !; 77 | XCD .alias opr6 = 0b001101, val2 = 3 & !; 78 | XC .alias opr6 = 0b001110, val2 = 3 & !; 79 | LAM .alias opr6 = 0b001111, val2 = 3 & !; 80 | 81 | // 2-bit operand, not inverted (0x40 .. 0x4F) 82 | LBZ .alias opr6 = 0b010000, val2 =; 83 | LBF .alias opr6 = 0b010001, val2 =; 84 | LBE .alias opr6 = 0b010010, val2 =; 85 | LBEP .alias opr6 = 0b010011, val2 =; 86 | 87 | // 4-bit operand, not inverted (0x50 .. 0x5F) 88 | ADIS .alias opr4 = 0b0101, val4 =; 89 | 90 | // 4-bit operand, inverted (0x60 .. 0x6F) 91 | PP .alias opr4 = 0b0110, val4 = 0xF & !; 92 | 93 | // 4-bit operand, not inverted (0x70 .. 0x7F) 94 | LAI .alias opr4 = 0b0111, val4 =; 95 | 96 | // 6-bit operand, non inverted label (0x80 .. 0xFF) 97 | JMS .alias opr2 = 0b10, val6 = 0b00111111 & @; 98 | JMP .alias opr2 = 0b11, val6 = 0b00111111 & @; 99 | -------------------------------------------------------------------------------- /mcc/Examples/EMZ1001/mcc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @echo -- Compile code for internal and external ROMs 3 | @echo See https://github.com/zpekic/MicroCodeCompiler 4 | ..\..\..\Sys9900\mcc\mcc\bin\Debug\mcc.exe /a:emz Fibonacci.emz 5 | ..\..\..\Sys9900\mcc\mcc\bin\Debug\mcc.exe /a:emz HelloWorld.emz 6 | @echo -- Convert image into 8*8 pixel character generator ROM 7 | @echo See https://github.com/zpekic/Sys_TIM-011/tree/master/Img2Tim 8 | ..\..\..\Sys_TIM-011\Sys_TIM-011\Img2Tim\Img2Tim\bin\Debug\img2tim.exe ..\doc\iskra-logo.bmp -x -c 9 | 10 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/HEX_IO Test circuit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/Hex_IO/HEX_IO Test circuit.jpg -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Hex2Mem/hex2mem.mcc: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------- 2 | // Hex2Mem Microcode (c) 2021-... zpekic@hotmail.com 3 | // Compile with https://github.com/zpekic/MicroCodeCompiler 4 | //---------------------------------------------------------- 5 | .code 7, 48, hex2mem_code.mif, hex2mem_code.cgf, hex2mem_code.coe, h2m:hex2mem_code.vhd, hex2mem_code.hex, hex2mem_code.bin, 8; 6 | .mapper 8, 7, hex2mem_map.mif, hex2mem_map.cgf, hex2mem_map.coe, h2m:hex2mem_map.vhd, hex2mem_map.hex, hex2mem_map.bin, 1; 7 | .controller hex2mem_control_unit.vhd, 8; 8 | .symbol 7, 256, hex2mem_sym.mif, hex2mem_sym.cgf, hex2mem_sym.coe, h2m:hex2mem_sym.vhd, hex2mem_sym.hex, hex2mem_sym.bin, 32; 9 | 10 | // System interface signals 11 | nBUSREQ .valfield 1 values 0, 1 default 1; 12 | nWR .valfield 1 values 0, 1 default 1; 13 | // nWAIT consumed as condition 14 | // nBUSACK consumed as condition 15 | // A(15..0) 16 | // D(7..0) 17 | 18 | // Component interface signals 19 | BUSY .valfield 1 values 0, 1 default 1; 20 | // RXD_READY load input register on low to high transition 21 | 22 | // Serial UART sender interface signals 23 | // CHAR 8-bit ASCII or 0x00 if no char is to be sent 24 | // TXDREADY sender is ready 25 | 26 | seq_cond: .if 4 values 27 | true, // hard-code to 1 28 | nWAIT, // Z80 bus - 0 to wait for memory 29 | nBUSACK, // z80 bus - 0 if CPU is 30 | input_is_zero, // do not process 0x00 input char 31 | TXDREADY, // high if tracer has processed the trace character 32 | TXDSEND, // will always be "1" but also generates a pulse to TXD 33 | TRACE_ERROR, // enable error tracing 34 | TRACE_WRITE, // enable memory write tracing 35 | TRACE_CHAR, // enable character tracing 36 | bytecnt_at_colon, 37 | hexcnt_is_odd, // hexcnt bit 0 is 1 38 | prev_is_crorlf, 39 | prev_is_spaceortab, 40 | compa_equals_compb, 41 | resetout_done, // wait for the external reset pulse to finish 42 | false // hard-code to 0 43 | default true; 44 | seq_then: .then 7 values next, repeat, return, fork, @ default next; // any label 45 | seq_else: .else 7 values next, repeat, return, fork, 0b000000..0b111111, @ default next; // any value as it can be a trace char 46 | 47 | // contains ASCII char for UART trasmit 48 | TXDCHAR .regfield 5 values 49 | same, 50 | char_F, 51 | char_space, 52 | char_cr, 53 | char_lf, 54 | char_E, // 'E' in "ERR" 55 | char_R, // 'R' in "ERR" 56 | char_I, 57 | char_B, 58 | char_A, 59 | char_C, 60 | char_EQU, 61 | char_open, 62 | char_close, 63 | -, 64 | zero, 65 | // use bit 4 to lookup using HEX2ASCII table 66 | pos_ram0, // bcd counter for character position in line (when in ERR mode) or RAM output 67 | pos_ram1, 68 | inp0, 69 | inp1, // input character 70 | lin_chk0, // bcd counter for line (when in ERR mode) or checksum 71 | lin_chk1, 72 | lin_chk2, 73 | lin_chk3, 74 | bytecnt0, 75 | bytecnt1, 76 | addr0, 77 | addr1, 78 | addr2, 79 | addr3, 80 | flags, 81 | errcode 82 | default same; 83 | 84 | // line counter 4-digit BCD 85 | lincnt_a: .valfield 1 values zero, lincnt default lincnt; // select adder "a" input, "b" is always 0 86 | lincnt_cin: .valfield 1 values 0, 1 default 0; // drive carry in to increment 87 | 88 | // position counter 4-digit BCD 89 | poscnt_a: .valfield 1 values zero, poscnt default poscnt; // select adder "a" input, "b" is always 0 90 | poscnt_cin: .valfield 1 values 0, 1 default 0; // drive carry in to increment 91 | 92 | // 16-bit address register 93 | address: .regfield 2 values 94 | same, 95 | inc, 96 | shift8ram, 97 | - 98 | default same; 99 | 100 | // internal RAM is 64*8, enough to hold a 32 byte record. Locations are: 101 | // 0x3B - colon (position only, not actually stored) 102 | // 0x3C - length (usually 0x10) 103 | // 0x3D - address, high byte 104 | // 0x3E - address, low byte 105 | // 0x3F - type (usually 0x00) 106 | // 0x00 - - data bytes from the HEX file record 107 | // - checksum value (lower byte) 108 | // internal RAM write 109 | ram_write: .valfield 1 values 0, 1 default 0; 110 | 111 | // select address for RAM read/write 112 | ram_addr: .valfield 3 values 113 | bytecnt, 114 | ptr_len, 115 | ptr_addr_hi, 116 | ptr_addr_lo, 117 | ptr_type, 118 | - 119 | - 120 | - 121 | default bytecnt; 122 | 123 | // counts incoming hex characters 124 | hexcnt: .regfield 3 values 125 | same, 126 | inc, 127 | ptr_colon, 128 | ptr_len, 129 | ptr_type, 130 | -, 131 | -, 132 | zero 133 | default same; 134 | 135 | // checksum register 136 | checksum: .regfield 2 values 137 | same, 138 | zero, 139 | add_ram, 140 | - 141 | default same; 142 | 143 | input_reset: .valfield 1 values 0, 1 default 0; // setting to 1 is async reset to char_input register 144 | 145 | // error codes are 1 to 6, 0 means no error 146 | errcode: .regfield 3 values 147 | ok, 148 | err_badchar, // ERR1 149 | err_unexpected, // ERR2 150 | err_badchecksum, // ERR3 151 | err_badrecordtype, // ERR4 152 | err_badrecordlength, // ERR5 153 | same 154 | default same; 155 | 156 | // comparator "A" source mux 157 | compa: .valfield 1 values 158 | ram, 159 | checksum_lsb 160 | default ram; 161 | 162 | // comparator "B" source mux 163 | compb: .valfield 2 values 164 | zero, 165 | one, 166 | bytecnt, 167 | bytecnt_dec // bytecnt - 1 to account for the checksum byte at the end of record 168 | default zero; 169 | 170 | // placeholder 171 | //dummy: .valfield 1 values * default 0; 172 | 173 | // useful aliases, these are evaluated as simple text replacement of label with everything between .alias and ; 174 | goto: .alias if false then next else; 175 | noop: .alias if true then next else next; 176 | back: .alias if true then return else return; 177 | 178 | // gosub definitions - this works because "jump" pushes return address to stack if both then/else are same 179 | emit: .sub TXDCHAR; 180 | print_crlf: .sub; 181 | trace: .sub; 182 | printram: .sub; 183 | printaddr: .sub; 184 | 185 | // other 186 | poscnt_zero:.alias poscnt_a = zero; 187 | lincnt_zero:.alias lincnt_a = zero; 188 | poscnt_inc: .alias poscnt_cin = 1; 189 | lincnt_inc: .alias lincnt_cin = 1; 190 | clear: .alias TXDCHAR <= zero, errcode <= ok, checksum <= zero, poscnt_zero, lincnt_zero, hexcnt <= ptr_colon; 191 | 192 | .org 0; 193 | // First 4 microcode locations can't be used branch destinations 194 | // --------------------------------------------------------------------------- 195 | _reset: clear; 196 | 197 | _reset1: clear; 198 | 199 | _reset2: clear; 200 | 201 | _reset3: clear; 202 | 203 | // indicate availability and wait for start signal 204 | // --------------------------------------------------------------------------- 205 | deadloop: BUSY = 0, if input_is_zero then repeat else next; 206 | trace(); 207 | poscnt_inc, if true then fork else fork; // jump to entry point per character code (see .map statements below) 208 | 209 | .map 0b????????; 210 | badchar: errcode <= err_badchar, if TRACE_ERROR then printerror else nextchar; // ERR1 211 | badcolon: errcode <= err_unexpected, if TRACE_ERROR then printerror else nextchar; // ERR2 212 | badchecksum:errcode <= err_badchecksum, if TRACE_ERROR then printerror else nextchar; // ERR3 213 | badtype: errcode <= err_badrecordtype, if TRACE_ERROR then printerror else nextchar; // ERR4 214 | badlength: errcode <= err_badrecordlength,if TRACE_ERROR then printerror else nextchar;// ERR5 215 | badhex: errcode <= err_unexpected, if TRACE_ERROR then next else nextchar; // ERR2 216 | printerror: emit(char_E); // ERR 217 | emit(char_R); 218 | emit(char_R); 219 | emit(errcode); 220 | emit(char_space); 221 | emit(lin_chk3); // 9999 line number (decimal) 222 | emit(lin_chk2); 223 | emit(lin_chk1); 224 | emit(lin_chk0); 225 | emit(char_space); 226 | emit(pos_ram1); // 99 char position in the line (decimal) 227 | emit(pos_ram0); 228 | emit(char_space); 229 | emit(inp1); // FF hex code of offending char 230 | hexcnt <= ptr_colon, emit(inp0); // force sync with next ':' 231 | print_crlf(); 232 | .map 0; 233 | nextchar: errcode <= ok, input_reset = 1, goto deadloop; 234 | 235 | emit: if TXDREADY then next else repeat; // sync with baudrate clock that drives UART 236 | if TXDREADY then next else repeat; 237 | if TXDREADY then next else repeat; 238 | if TXDSEND then return else return; // generate a send pulse for UART sender 239 | 240 | printramR: emit(char_R); 241 | 242 | printram: emit(char_EQU); 243 | emit(pos_ram1); 244 | emit(pos_ram0); 245 | 246 | print_crlf: emit(char_cr); 247 | emit(char_lf); 248 | back; 249 | 250 | printaddr: emit(addr3); 251 | emit(addr2); 252 | emit(addr1); 253 | emit(addr0); 254 | back; 255 | 256 | // with mapping like this lower 4 bits of mapper can be reused as ASCII to HEX decode 257 | .org 0x30; 258 | .map '0'; 259 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 260 | 261 | .org 0x31; 262 | .map '1'; 263 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 264 | 265 | .org 0x32; 266 | .map '2'; 267 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 268 | 269 | .org 0x33; 270 | .map '3'; 271 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 272 | 273 | .org 0x34; 274 | .map '4'; 275 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 276 | 277 | .org 0x35; 278 | .map '5'; 279 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 280 | 281 | .org 0x36; 282 | .map '6'; 283 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 284 | 285 | .org 0x37; 286 | .map '7'; 287 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 288 | 289 | .org 0x38; 290 | .map '8'; 291 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 292 | 293 | .org 0x39; 294 | .map '9'; 295 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 296 | 297 | .org 0x3a; 298 | .map 'a'; 299 | .map 'A'; 300 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 301 | 302 | .org 0x3b; 303 | .map 'b'; 304 | .map 'B'; 305 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 306 | 307 | .org 0x3c; 308 | .map 'c'; 309 | .map 'C'; 310 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 311 | 312 | .org 0x3d; 313 | .map 'd'; 314 | .map 'D'; 315 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 316 | 317 | .org 0x3e; 318 | .map 'e'; 319 | .map 'E'; 320 | ram_write = 1, ram_addr = bytecnt, goto hexchar; 321 | 322 | .org 0x3f; 323 | .map 'f'; 324 | .map 'F'; 325 | ram_write = 1, ram_addr = bytecnt; 326 | hexchar: if bytecnt_at_colon then badhex; 327 | if hexcnt_is_odd then next else dontadd; 328 | ram_addr = bytecnt, checksum <= add_ram; 329 | dontadd: hexcnt <= inc, goto nextchar; 330 | 331 | .map 0x0A; // LF (line feed) - try to make it work for Windows (CR,LF) and other (LF only) files 332 | if prev_is_crorlf then nextchar else newline; // ignore subsequent cr/lf 333 | 334 | .map 0x0D; // CR (carriage return) 335 | if prev_is_crorlf then nextchar else next; // ignore subsequent cr/lf 336 | newline: compa = checksum_lsb, compb = zero, if compa_equals_compb then next else badchecksum; // lower byte should be 0x00 337 | poscnt_zero, lincnt_inc, if hexcnt_is_odd then badhex else next; // should not come between 2 hex characters 338 | ram_addr = ptr_type, compa = ram, compb = one, if compa_equals_compb then lastrec; // RAM(ptr_type) - 0x01 339 | ram_addr = ptr_type, compa = ram, compb = zero, if compa_equals_compb then next else badtype; // RAM(ptr_type) - 0x00 340 | ram_addr = ptr_len, compa = ram, compb = bytecnt_dec, if compa_equals_compb then next else badlength; // RAM(ptr_length) - bytecnt 341 | 342 | ram_addr = ptr_addr_hi, address <= shift8ram, hexcnt <= zero; // A <= A(7..0) < RAM(ptr_addr_hi) 343 | ram_addr = ptr_addr_lo, address <= shift8ram, hexcnt <= zero; // A <= A(7..0) < RAM(ptr_addr_lo) 344 | 345 | writeloop: ram_addr = ptr_len, compa = ram, compb = bytecnt, if compa_equals_compb then nextrec; 346 | 347 | // ask CPU for memory, then write 1 byte with any number of optional wait cycles 348 | writemem: ram_addr = bytecnt, nBUSREQ = 0; 349 | ram_addr = bytecnt, nBUSREQ = 0, if nBUSACK then repeat else next; 350 | ram_addr = bytecnt, nBUSREQ = 0, nWR = 0; 351 | ram_addr = bytecnt, nBUSREQ = 0, nWR = 0, if nWAIT then next else repeat; 352 | 353 | if TRACE_WRITE then next else nextaddr; 354 | emit(char_A); // A[address]=data 355 | emit(char_open); 356 | printaddr(); 357 | emit(char_close); 358 | printram(); 359 | 360 | nextaddr: hexcnt <= inc; 361 | hexcnt <= inc, address <= inc, goto writeloop; // bytecnt++, A++ 362 | 363 | lastrec: lincnt_zero, if resetout_done then next else next; // clear reset_out 364 | ram_addr = ptr_len, compa = ram, compb = zero, if compa_equals_compb then next else badlength; // length of last record should be 0 365 | nextrec: hexcnt <= ptr_colon, goto nextchar; // prepare for next record 366 | 367 | dumpram: emit(char_R); // Rxx=yy 368 | emit(bytecnt1); 369 | emit(bytecnt0); 370 | printram(); 371 | back; 372 | 373 | .map 0x09; // treat tabs and spaces same way 374 | .map ' '; 375 | space: if prev_is_spaceortab then nextchar else next; // ignore a run of spaces or tabs 376 | if hexcnt_is_odd then badchar else nextchar; // two hex chars need to stick together! 377 | 378 | .map ':'; 379 | colon: checksum <= zero, if bytecnt_at_colon then next else badcolon; 380 | hexcnt <= inc; 381 | hexcnt <= inc, goto nextchar; // skip two hex positions, now pointing to "length" byte 382 | 383 | trace: if TRACE_CHAR then next else return; 384 | //print_crlf(); 385 | emit(char_I); // I= 386 | emit(char_EQU); 387 | emit(inp1); 388 | emit(inp0); 389 | emit(char_space); 390 | 391 | emit(char_A); // A=
392 | emit(char_EQU); 393 | printaddr(); 394 | emit(char_space); 395 | 396 | emit(char_C); // C= 397 | emit(char_EQU); 398 | emit(lin_chk3); 399 | emit(lin_chk2); 400 | emit(lin_chk1); 401 | emit(lin_chk0); 402 | emit(char_space); 403 | 404 | // emit(char_F); // F= 405 | // emit(char_EQU); 406 | // emit(flags); 407 | // emit(char_space); 408 | 409 | emit(char_B); // B= 410 | emit(char_EQU); 411 | emit(bytecnt1); 412 | emit(bytecnt0); 413 | emit(char_space); 414 | 415 | goto printramR; 416 | 417 | 418 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Hex2Mem/img2tim.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @echo See https://hackaday.io/project/176081-tim-011-fpga-based-vga-and-ps2-keyboard-adapter/log/186519-initializing-video-memory-for-test-purposes 3 | ..\..\..\Sys_TIM-011\Sys_TIM-011\Img2Tim\Img2Tim\obj\Debug\Img2Tim.exe *.png -i -x 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Hex2Mem/mcc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @echo See https://github.com/zpekic/MicroCodeCompiler 3 | ..\..\..\Sys9900\mcc\mcc\bin\Debug\mcc.exe hex2mem.mcc 4 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Hex2Mem/screenshot_hex2mem.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/Hex_IO/Hex2Mem/screenshot_hex2mem.PNG -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Hex2Mem/test.hex: -------------------------------------------------------------------------------- 1 | : 10 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 2 | : 10 0080 00 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 60 3 | : 10 0100 00 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 cf 4 | : 10 0180 00 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3f 5 | : 10 0200 00 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 ae 6 | : 10 0280 00 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 1e 7 | : 10 0300 00 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 8d 8 | : 10 0380 00 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 fd 9 | : 10 0400 00 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 6c 10 | : 10 0480 00 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 dc 11 | : 10 0500 00 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 4b 12 | : 10 0580 00 bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb 13 | : 10 0600 00 cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc 2a 14 | : 10 0680 00 dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 9a 15 | : 10 0700 00 ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee 09 16 | : 10 0780 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 79 17 | : 00 0000 01 FF 18 | 19 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Hex2Mem/test_single.hex: -------------------------------------------------------------------------------- 1 | : 10 0780 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 79 2 | : 00 0000 01 FF 3 | 4 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Hex2Mem/vucko_zoi84.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/Hex_IO/Hex2Mem/vucko_zoi84.png -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Mem2Hex/mcc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @echo See https://github.com/zpekic/MicroCodeCompiler 3 | ..\..\..\Sys9900\mcc\mcc\bin\Debug\mcc.exe mem2hex.mcc 4 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Mem2Hex/mem2hex.mcc: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------- 2 | // Mem2Hex Microcode (c) 2021-... zpekic@hotmail.com 3 | // Compile with https://github.com/zpekic/MicroCodeCompiler 4 | //---------------------------------------------------------- 5 | .code 6, 34, mem2hex_code.mif, mem2hex_code.cgf, mem2hex_code.coe, m2h:mem2hex_code.vhd, mem2hex_code.hex, mem2hex_code.bin, 8; 6 | .mapper 8, 6, mem2hex_map.mif, mem2hex_map.cgf, mem2hex_map.coe, m2h:mem2hex_map.vhd, mem2hex_map.hex, mem2hex_map.bin, 1; 7 | .controller mem2hex_control_unit.vhd, 4; 8 | 9 | // System interface signals 10 | nBUSREQ .valfield 1 values 0, 1 default 1; 11 | nRD .valfield 1 values 0, 1 default 1; 12 | // nWAIT consumed as condition 13 | // nBUSACK consumed as condition 14 | // A(15..0) 15 | // D(7..0) 16 | 17 | // Component interface signals 18 | BUSY .valfield 1 values 0, 1 default 1; 19 | // START consumed as condition 20 | // PAGE(7..0) 1 bit per 8k block of memory to be dumped out (0xF0 == dump 0x8000 to 0xFFFF) 21 | 22 | // Serial UART sender interface signals 23 | // CHAR 8-bit ASCII or 0x00 if no char is to be sent 24 | // TXDREADY sender is ready 25 | 26 | seq_cond: .if 4 values 27 | true, // hard-code to 1 28 | nWAIT, // Z80 bus - 0 to wait for memory 29 | nBUSACK, // z80 bus - 0 if CPU is 30 | START, // sense start hexdump signal 31 | page_match, // 1 if memory page switch matches current page 32 | mem_addr_is_zero, // mem_addr(12..0) == 0 33 | count_is_zero, // byte counter on the line is 0 34 | TXDREADY, // high if tracer has processed the trace character 35 | TXDSEND, // will always be "1" but also generates a pulse to TXD 36 | page_is_zero, 37 | -, 38 | -, 39 | -, 40 | -, 41 | -, 42 | false // hard-code to 0 43 | default true; 44 | seq_then: .then 6 values next, repeat, return, fork, @ default next; // any label 45 | seq_else: .else 6 values next, repeat, return, fork, 0b000000..0b111111, @ default next; // any value as it can be a trace char 46 | 47 | // memory address = mem_page (3 bits) & mem_addr (13 bits) 48 | mem_page .regfield 2 values same, zero, inc, - default same reset zero; // address(15 downto 13), 8 pages of 8k 49 | mem_addr .regfield 2 values same, zero, inc, - default same reset zero; // address(12 downto 0), 8k per page 50 | 51 | // number of bytes per hex line 52 | count .regfield 2 values same, load, dec, zero default same; 53 | 54 | // checksum 55 | checksum .regfield 3 values same, count, add_addr_lsb, add_addr_msb, add_d, complement, -, zero default same; 56 | 57 | // byte read from memory 58 | d .regfield 2 values same, dbus, zero, one default same; 59 | 60 | // contains ASCII char for UART trasmit 61 | CHAR .regfield 4 values 62 | same, 63 | char_colon, 64 | char_space, 65 | char_cr, 66 | char_lf, 67 | zero, 68 | d_hi, 69 | d_lo, 70 | count_hi, 71 | count_lo, 72 | addr_msb_hi, 73 | addr_msb_lo, 74 | addr_lsb_hi, 75 | addr_lsb_lo, 76 | checksum_hi, 77 | checksum_lo 78 | default same reset zero; 79 | 80 | // useful aliases, these are evaluated as simple text replacement of label with everything between .alias and ; 81 | goto: .alias if false then next else; 82 | noop: .alias if true then next else next; 83 | back: .alias if true then return else return; 84 | 85 | // gosub definitions - this works because "jump" pushes return address to stack if both then/else are same 86 | emit: .sub CHAR; 87 | printpage: .sub; 88 | lineend: .sub; 89 | readmem: .sub; 90 | printcount: .sub; 91 | printaddr: .sub; 92 | // leaving the "sub call" in "old style" to illustrate what is actually happening 93 | printd: .alias if false then printd else printd; 94 | 95 | .org 0; 96 | // First 4 microcode locations can't be used branch destinations 97 | // --------------------------------------------------------------------------- 98 | _reset: noop; 99 | 100 | _reset1: noop; 101 | 102 | _reset2: noop; 103 | 104 | _reset3: noop; 105 | 106 | // indicate availablity and wait for start signal 107 | // --------------------------------------------------------------------------- 108 | deadloop: CHAR <= zero, BUSY = 0, if START then fork else deadloop; 109 | 110 | .map 0b????????; 111 | // "instruction register" is just an 8-bit input port, each bit controls 8k memory block 112 | // for example: 10000001 (0x81) will dump 0000-3FFF first and then C000-FFFF next 113 | // fork lands here when at least one page bit is on 114 | // this is the most generic mask so it should be defined first 115 | mem_page <= zero; 116 | pageloop: printpage(); 117 | mem_page <= inc; 118 | if page_is_zero then next else pageloop; // page register is 3 bits, so when it wraps to 0 all 8 pages are done 119 | 120 | // fork lands here is all page bits are off 121 | // comes after more generic masks to override their target location 122 | .map 0b00000000; 123 | // last line is hard coded : 00 0000 01 FF 124 | // : 125 | mem_page <= zero, mem_addr <= zero, emit(char_colon); 126 | emit(char_space); 127 | // 00 128 | count <= zero, printcount(); 129 | // 0000 130 | printaddr(); 131 | // 01 132 | d <= one, printd; 133 | // FF (because checksum should add up to it), then 134 | lineend(); 135 | 136 | // done with this dump, get ready for next 137 | goto deadloop; 138 | 139 | printpage: mem_addr <= zero, if page_match then next else return; // 3-bit page register is mux select for input port bits 140 | 141 | page_line: noop; 142 | // : 143 | emit(char_colon); 144 | // 145 | emit(char_space); 146 | // 10 or 20 (record length) 147 | count <= load, printcount(); // will be 16 or 32 based on input pin 148 | // aaaa 149 | printaddr(); 150 | // 00 (type) 151 | d <= zero, printd; 152 | // 153 | 154 | page_byte: readmem(); // D <= M(page:address) 155 | printd; 156 | mem_addr <= inc, count <= dec; 157 | if count_is_zero then next else page_byte; 158 | 159 | // done with all the data bytes on this line, output end of line 160 | lineend(); 161 | 162 | // mem_addr is 13-bit reg so when it wraps to 0 we are done with 8k page 163 | if mem_addr_is_zero then return else page_line; 164 | 165 | // all lines end with checksum byte and cr, lf 166 | lineend: checksum <= complement; // checksum <= (!checksum) + 1 (base 2 complement) 167 | emit(checksum_hi); // bits 7:4 converted to ASCII 168 | emit(checksum_lo); // bits 3:0 converted to ASCII 169 | emit(char_cr); 170 | emit(char_lf); 171 | back; 172 | 173 | printcount: emit(count_hi); 174 | emit(count_lo); 175 | checksum <= count, goto printspace; // count is first byte for checksum, so simply assign 176 | 177 | printaddr: emit(addr_msb_hi); 178 | checksum <= add_addr_msb, emit(addr_msb_lo); 179 | emit(addr_lsb_hi); 180 | checksum <= add_addr_lsb, emit(addr_lsb_lo); 181 | printspace: emit(char_space); 182 | back; 183 | 184 | printd: emit(d_hi); 185 | emit(d_lo); 186 | checksum <= add_d, goto printspace; 187 | 188 | // "UART" is supposed to signal TDXREADY = 1 when presented 0x00 or when serial trasmit is done 189 | emit: if TXDREADY then next else repeat; // sync with baudrate clock that drives UART 190 | if TXDREADY then next else repeat; 191 | if TXDREADY then next else repeat; 192 | if TXDSEND then return else return; 193 | 194 | // ask CPU for memory, then read 1 byte with any number of optional wait cycles 195 | readmem: nBUSREQ = 0; 196 | nBUSREQ = 0, if nBUSACK then repeat else next; 197 | nBUSREQ = 0, nRD = 0; 198 | nBUSREQ = 0, nRD = 0, d <= dbus, if nWAIT then return else repeat; 199 | 200 | -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/Mem2Hex/screenshot_mem2hex.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/Hex_IO/Mem2Hex/screenshot_mem2hex.PNG -------------------------------------------------------------------------------- /mcc/Examples/Hex_IO/trace_microcode.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/Hex_IO/trace_microcode.PNG -------------------------------------------------------------------------------- /mcc/Examples/TTY_Screen/Tty_screen_schema - page 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/Examples/TTY_Screen/Tty_screen_schema - page 1.png -------------------------------------------------------------------------------- /mcc/Examples/TTY_Screen/mcc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @echo See https://github.com/zpekic/MicroCodeCompiler 3 | ..\..\..\..\..\Sys9900\mcc\mcc\bin\Debug\mcc.exe tty_screen.mcc -------------------------------------------------------------------------------- /mcc/Examples/TTY_Screen/tty_screen.mcc: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------- 2 | // Screen TTY Microcode (c) 2020-... zpekic@hotmail.com 3 | // Compile with https://github.com/zpekic/MicroCodeCompiler 4 | // See https://hackaday.io/project/182959-custom-circuit-testing-using-intel-hex-files/log/201614-micro-coded-controller-deep-dive 5 | //---------------------------------------------------------- 6 | 7 | // microcode size is 64 locations, each 27 bits long 8 | // microcode content will be generated in all currently available formats, but only .vhd file is used in this project 9 | .code 6, 27, tty_screen_code.mif, tty_screen_code.cgf, tty:tty_screen_code.vhd, tty_screen_code.hex, tty_screen_code.bin, 4; 10 | 11 | // mapper size is 128 words (as 7-bit ASCII code is used as "instruction") by 6 bits (to point to 1 of 64 microcode start locations) 12 | // also generate all memory file formats. Note prefix: for .vhd, which is used to prepend to all generated aliases and constants 13 | // this way multiple microcoded controllers can coexist in the same project even if their microfield have same name 14 | .mapper 7, 6, tty_screen_map.mif, tty_screen_map.cgf, tty:tty_screen_map.vhd, tty_screen_map.hex, tty_screen_map.bin, 1; 15 | 16 | // controller generated will have a 2 level hardware return stack and will advance on low to high clock transition 17 | .controller tty_control_unit.vhd, 2, rising; 18 | 19 | // MCC microengines are largely "horizontal" microcoded. Fields adding up to whole microinstruction must be defined first 20 | // order of definition and width of fields determines their position in microinstruction 21 | 22 | // 4 states to indicate the status of the TTY 23 | // valfield means the value is supposed to be present ONLY DURING CURRENT microinstruction AND WILL NOT BE PRESERVED 24 | // = assignment must be used in the code for such fields 25 | // given fields are defined MSB to LSB, ready will occupy microinstruction[31..30] 26 | // all microfields must have a default value - this allows implicit generation of microinstruction field assignments 27 | ready: .valfield 2 values 28 | no, 29 | char_is_zero, 30 | yes, 31 | - default no; 32 | 33 | // microcontroller also consumes microinstruction fields, first 3 bits to select an IF condition 34 | // true and false are handy to have around in all designs 35 | // assignment only through IF condition THEN target_true ELSE target_false 36 | seq_cond: .if 3 values 37 | true, // hard-code to 1 38 | char_is_zero, // all branch conditions needed by the design must be listed and brought into a n to 1 MUX 39 | cursorx_ge_maxcol, 40 | cursory_ge_maxrow, 41 | cursorx_is_zero, 42 | cursory_is_zero, 43 | memory_ready, 44 | false // hard-code to 0 45 | default true; 46 | 47 | // then 6 bits (because need to jump/call 64 locations) to specify THEN (to select if condition is true) 48 | seq_then: .then 6 values 49 | next, // uPC <= uPC + 1 50 | repeat, // uPC <= uPC 51 | return, // uPC <= saved uPC 52 | fork, 53 | @ default next; // any label 54 | 55 | // then 6 values for ELSE (to select if condition is false) 56 | seq_else: .else 6 values 57 | next, 58 | repeat, 59 | return, 60 | fork, 61 | 0x00..0x3F, @ default next; // any label or valid range value (allow field to be reused for constant 62 | 63 | // Screen cursor X position can stay the same, increment, decrement, or be set to maxcol 64 | // regfield means value will be SET AT THE END OF CURRENT MICROINSTRUCTION and WILL BE PRESERVED 65 | // <= assignment must be used 66 | cursorx: .regfield 3 values 67 | same, 68 | zero, // left position 69 | inc, // simple incrementer will be generated 70 | dec, // simple decrementer will be generated 71 | maxcol default same; // can be static or changed at reset time 72 | 73 | // Screen cursor Y position can stay the same, increment, decrement, or be set to maxcol 74 | cursory: .regfield 3 values 75 | same, 76 | zero, // top position 77 | inc, 78 | dec, 79 | maxrow default same; 80 | 81 | // buffer for memory value, 82 | data: .regfield 2 values 83 | same, 84 | char, // from ASCII character port input 85 | memory, // from video memory 86 | space default same; // space is used to clear video memory 87 | 88 | // video memory control bus, note that ordering of labels can be conveniently used to generate /RD and /WR signals 89 | mem: .valfield 2 values 90 | nop, // no memory access 91 | read, // mem(0) is RD 92 | write, // mem(1) is WR 93 | - // forbid read and write at same time 94 | default nop; 95 | 96 | // useful aliases 97 | goto: .alias if false then next else; 98 | return: .alias if false then next else return; 99 | noop: .alias if true then next else next; 100 | 101 | // define subroutines 102 | writeMem .sub; // equivalent to 'if true then printChar else printChar' - control unit recognizes both labels same and executes a subroutine call 103 | readMem .sub; // note no regfield parameters, so must be called with readMem(); 104 | 105 | .org 0; 106 | // First 4 microcode locations can't be used branch destinations (starting label with _ will prevent use as target) 107 | // --------------------------------------------------------------------------- 108 | _reset: noop; 109 | 110 | _reset1: noop; 111 | 112 | _reset2: noop; 113 | 114 | _reset3: cursorx <= zero, cursory <= zero; 115 | 116 | waitChar: ready = char_is_zero, data <= char, 117 | if char_is_zero then repeat else next; 118 | 119 | if true then fork else fork; // interpret the ASCII code of char in data register as "instruction" 120 | 121 | 122 | .map 0b???_????; // default to printable character handler 123 | main: writeMem(); 124 | 125 | cursorx <= inc; 126 | 127 | if cursorx_ge_maxcol then next else nextChar; 128 | 129 | cursorx <= zero, 130 | goto LF; 131 | 132 | .map 0b00?_????; // special characters 00-1F are not printable, so just ignore 133 | nextChar: ready = yes, 134 | if char_is_zero then waitChar else repeat; 135 | 136 | .map 0b000_0001; // 0x01 SOH == clear screen 137 | CLS: data <= space, cursory <= zero; 138 | 139 | nextRow: cursorx <= zero; 140 | 141 | nextCol: writeMem(); 142 | 143 | cursorx <= inc; 144 | 145 | if cursorx_ge_maxcol then next else nextCol; 146 | 147 | cursory <= inc; 148 | 149 | if cursory_ge_maxrow then HOME else nextRow; 150 | 151 | .map 0b000_0010; // 0x02 STX == home 152 | HOME: cursorx <= zero, cursory <= zero, 153 | goto nextChar; 154 | 155 | .map 0b000_1010; // 0x0A LF (line feed) 156 | LF: cursory <= inc; 157 | 158 | if cursory_ge_maxrow then next else nextChar; 159 | 160 | scrollUp: cursory <= zero; 161 | 162 | copyRow: if cursory_ge_maxrow then lastLine else next; 163 | 164 | cursorx <= zero; 165 | 166 | copyCol: if cursorx_ge_maxcol then nextY else next; 167 | 168 | cursory <= inc, 169 | readMem(); 170 | 171 | cursory <= dec, 172 | writeMem(); 173 | 174 | cursorx <= inc, 175 | goto copyCol; 176 | 177 | nextY: cursory <= inc, 178 | goto copyRow; 179 | 180 | lastLine: data <= space, cursory <= dec, cursorx <= zero; 181 | 182 | clearCol: if cursorx_ge_maxcol then CR else next; 183 | 184 | writeMem(); 185 | 186 | cursorx <= inc, 187 | goto clearCol; 188 | 189 | .map 0b000_1101; // 0x0D CR (carriage return) 190 | CR: cursorx <= zero, 191 | goto nextChar; 192 | 193 | writeMem: if memory_ready then next else repeat; // wait for video memory 194 | 195 | mem = write, // data reg is connected to dout 196 | return; 197 | 198 | readMem: if memory_ready then next else repeat; // wait for video memory 199 | 200 | mem = read, data <= memory, // data reg loads from din 201 | return; 202 | 203 | -------------------------------------------------------------------------------- /mcc/FieldElse.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Collections.Generic; 3 | 4 | namespace mcc 5 | { 6 | internal class FieldElse : MicroField 7 | { 8 | 9 | public FieldElse(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".else", lineNumber, orgValue, label, content, logger, null) 10 | { 11 | } 12 | 13 | public override StringBuilder GetVhdlBoilerplateCode(string prefix, List fieldLabels, bool risingEdge) 14 | { 15 | StringBuilder sbCode = new StringBuilder($"-- include '.controller , ;' in .mcc file to generate pre-canned microcode control unit and connect 'else' to {prefix}_{Label}"); 16 | 17 | return sbCode; 18 | } 19 | 20 | public override void CheckFieldWidth(int power2Width) 21 | { 22 | Assert((1 << this.Width) == power2Width, $".else field width {this.Width} not matching code size of {power2Width} microinstructions"); 23 | } 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /mcc/FieldIf.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Collections.Generic; 3 | 4 | namespace mcc 5 | { 6 | internal class FieldIf : MicroField 7 | { 8 | 9 | public FieldIf(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".if", lineNumber, orgValue, label, content, logger, null) 10 | { 11 | } 12 | 13 | public override StringBuilder GetVhdlBoilerplateCode(string prefix, List fieldLabels, bool risingEdge) 14 | { 15 | StringBuilder sbCode = new StringBuilder(); 16 | 17 | sbCode.AppendLine("---- Start boilerplate code (use with utmost caution!)"); 18 | sbCode.AppendLine("---- include '.controller , ;' in .mcc file to generate pre-canned microcode control unit and feed 'conditions' with:"); 19 | 20 | foreach (ValueVector vv in Values) 21 | { 22 | if (vv.Name.StartsWith("true", System.StringComparison.InvariantCultureIgnoreCase)) 23 | { 24 | sbCode.AppendLine($"-- cond({Label}_{vv.Name}) => '1',"); 25 | continue; 26 | } 27 | if (vv.Name.StartsWith("false", System.StringComparison.InvariantCultureIgnoreCase)) 28 | { 29 | sbCode.AppendLine($"-- cond({Label}_{vv.Name}) => '0',"); 30 | continue; 31 | } 32 | sbCode.AppendLine($"-- cond({Label}_{vv.Name}) => {vv.Name},"); 33 | } 34 | 35 | sbCode.Append("---- End boilerplate code"); 36 | return sbCode; 37 | } 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /mcc/FieldReg.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Collections.Generic; 3 | 4 | namespace mcc 5 | { 6 | internal class FieldReg : MicroField 7 | { 8 | public FieldReg(int lineNumber, int orgValue, string label, string content, Logger logger, List parsedLines) : base(".regfield", lineNumber, orgValue, label, content, logger, parsedLines) 9 | { 10 | 11 | } 12 | 13 | public override bool IsValidSubParameter(string name) 14 | { 15 | return string.IsNullOrEmpty(name) ? false : name.Equals(this.Label, System.StringComparison.InvariantCultureIgnoreCase); 16 | } 17 | 18 | public override StringBuilder GetVhdlBoilerplateCode(string prefix, List fieldLabels, bool isRisingEdge) 19 | { 20 | StringBuilder sbCode = new StringBuilder(); 21 | bool includeReset = (this.ResetValue >= 0); 22 | 23 | sbCode.AppendLine("---- Start boilerplate code (use with utmost caution!)"); 24 | if (includeReset) 25 | { 26 | sbCode.AppendLine($"-- update_{Label}: process(clk, {prefix}_{Label}, reset)"); 27 | sbCode.AppendLine("-- begin"); 28 | sbCode.AppendLine("-- if (reset = '1') then"); 29 | 30 | // try to figure out reset assignment? 31 | string resetLine = $"-- {Label} <= TODO;"; 32 | foreach (ValueVector vv in Values) 33 | { 34 | if (vv.Match(this.ResetValue)) 35 | { 36 | resetLine = $"-- {Label} <= {GuessVhdlExpressionFromName(Label, vv.Name, fieldLabels)};"; 37 | break; 38 | } 39 | } 40 | sbCode.AppendLine(resetLine); 41 | sbCode.AppendLine("-- else"); 42 | } 43 | else 44 | { 45 | sbCode.AppendLine($"-- update_{Label}: process(clk, {prefix}_{Label})"); 46 | sbCode.AppendLine("-- begin"); 47 | } 48 | sbCode.AppendLine(isRisingEdge ? "-- if (rising_edge(clk)) then" : "-- if (falling_edge(clk)) then"); 49 | 50 | if (HasNamedValues()) 51 | { 52 | if (Width == 1) 53 | { 54 | foreach (ValueVector vv in Values) 55 | { 56 | if (!vv.Match(this.DefaultValue)) 57 | { 58 | sbCode.AppendLine($"-- if ({prefix}_{Label} = {Label}_{vv.Name}) then"); 59 | sbCode.AppendLine($"-- {Label} <= {GuessVhdlExpressionFromName(Label, vv.Name, fieldLabels)};"); 60 | sbCode.AppendLine($"-- end if;"); 61 | continue; 62 | } 63 | } 64 | } 65 | else 66 | { 67 | bool appendOthers = false; 68 | sbCode.AppendLine($"-- case {prefix}_{Label} is"); 69 | 70 | foreach (ValueVector vv in Values) 71 | { 72 | if (vv.Match(this.DefaultValue)) 73 | { 74 | appendOthers = true; 75 | sbCode.AppendLine($"---- when {Label}_{vv.Name} =>"); 76 | sbCode.AppendLine($"---- {Label} <= {Label};"); 77 | continue; 78 | } 79 | if (vv.Name.StartsWith("-", System.StringComparison.InvariantCultureIgnoreCase)) 80 | { 81 | appendOthers = true; 82 | } 83 | else 84 | { 85 | sbCode.AppendLine($"-- when {Label}_{vv.Name} =>"); 86 | sbCode.AppendLine($"-- {Label} <= {GuessVhdlExpressionFromName(Label, vv.Name, fieldLabels)};"); 87 | } 88 | } 89 | 90 | if (appendOthers) 91 | { 92 | sbCode.AppendLine("-- when others =>"); 93 | sbCode.AppendLine("-- null;"); 94 | } 95 | sbCode.AppendLine("-- end case;"); 96 | 97 | } 98 | } 99 | else 100 | { 101 | sbCode.AppendLine($"-- {Label} <= {prefix}_{Label};"); 102 | } 103 | if (includeReset) 104 | { 105 | sbCode.AppendLine("-- end if;"); 106 | } 107 | sbCode.AppendLine("-- end if;"); 108 | sbCode.AppendLine("-- end process;"); 109 | 110 | sbCode.Append("---- End boilerplate code"); 111 | return sbCode; 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /mcc/FieldThen.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Collections.Generic; 3 | 4 | namespace mcc 5 | { 6 | internal class FieldThen : MicroField 7 | { 8 | 9 | public FieldThen(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".then", lineNumber, orgValue, label, content, logger, null) 10 | { 11 | } 12 | 13 | public override StringBuilder GetVhdlBoilerplateCode(string prefix, List fieldLabels, bool risingEdge) 14 | { 15 | StringBuilder sbCode = new StringBuilder($"-- include '.controller , ;' in .mcc file to generate pre-canned microcode control unit and connect 'then' to {prefix}_{Label}"); 16 | 17 | return sbCode; 18 | } 19 | 20 | public override void CheckFieldWidth(int power2Width) 21 | { 22 | Assert((1 << this.Width) == power2Width, $".then field width {this.Width} not matching code size of {power2Width} microinstructions"); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /mcc/FieldVal.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Collections.Generic; 3 | 4 | namespace mcc 5 | { 6 | internal class FieldVal : MicroField 7 | { 8 | public int From; 9 | public int To; 10 | 11 | public FieldVal(int lineNumber, int orgValue, string label, string content, Logger logger, List parsedLines) : base(".valfield", lineNumber, orgValue, label, content, logger, parsedLines) 12 | { 13 | this.From = -1; 14 | this.To = -1; 15 | } 16 | 17 | public override StringBuilder GetVhdlBoilerplateCode(string prefix, List fieldLabels, bool risingEdge) 18 | { 19 | StringBuilder sbCode = new StringBuilder(); 20 | 21 | sbCode.AppendLine("---- Start boilerplate code (use with utmost caution!)"); 22 | 23 | if (HasNamedValues()) 24 | { 25 | if (Width == 1) 26 | { 27 | string otherName = "TODO"; 28 | string defaultName = "TODO"; 29 | 30 | foreach (ValueVector vv in Values) 31 | { 32 | 33 | if (vv.Match(this.DefaultValue)) 34 | { 35 | defaultName = vv.Name; 36 | } 37 | else 38 | { 39 | otherName = vv.Name; 40 | } 41 | } 42 | 43 | string otherValue = GuessVhdlExpressionFromName(Label, otherName, fieldLabels); 44 | string defaultValue = GuessVhdlExpressionFromName(Label, defaultName, fieldLabels); 45 | 46 | sbCode.AppendLine($"-- {Label} <= {otherValue} when ({prefix}_{Label} = {Label}_{otherName}) else {defaultValue};"); 47 | } 48 | else 49 | { 50 | bool appendOthers = false; 51 | int count = 0; 52 | string defaultExpression = null; 53 | sbCode.AppendLine($"-- with {prefix}_{Label} select {Label} <="); 54 | 55 | foreach (ValueVector vv in Values) 56 | { 57 | count++; 58 | if (vv.Name.StartsWith("-", System.StringComparison.InvariantCultureIgnoreCase)) 59 | { 60 | appendOthers = true; 61 | } 62 | else 63 | { 64 | string[] altNames = vv.Name.Split('|'); // filter out alternate names 65 | string expression = GuessVhdlExpressionFromName(Label, altNames[0], fieldLabels); 66 | bool isDefault = false; 67 | 68 | for (int i = 0; i < altNames.Length; i++) 69 | { 70 | // BUGBUG: comma and semicolon on last lines are messed up! 71 | //if (i == 0) 72 | //{ 73 | sbCode.Append($"-- {expression} when {Label}_{altNames[i]}"); 74 | //} 75 | //else 76 | //{ 77 | // sbCode.AppendLine($"-- {expression} when {Label}_{altNames[i]}"); 78 | //} 79 | 80 | if (vv.Match(this.DefaultValue)) 81 | { 82 | isDefault = true; 83 | defaultExpression = expression; 84 | } 85 | if (!appendOthers && (count == Values.Count)) 86 | { 87 | sbCode.AppendLine(isDefault ? "; -- default value" : ";"); 88 | } 89 | else 90 | { 91 | sbCode.AppendLine(isDefault ? ", -- default value" : ","); 92 | } 93 | } 94 | } 95 | } 96 | 97 | if (appendOthers) 98 | { 99 | if (string.IsNullOrEmpty(defaultExpression)) 100 | { 101 | sbCode.AppendLine("-- (others => '0') when others;"); 102 | } 103 | else 104 | { 105 | sbCode.AppendLine($"-- {defaultExpression} when others;"); 106 | } 107 | } 108 | 109 | } 110 | } 111 | else 112 | { 113 | sbCode.AppendLine($"-- {Label} <= {prefix}_{Label};"); 114 | } 115 | sbCode.Append("---- End boilerplate code"); 116 | return sbCode; 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /mcc/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.IO; 5 | using System.Reflection; 6 | using System.Diagnostics; 7 | 8 | namespace mcc 9 | { 10 | class Logger : IDisposable 11 | { 12 | private StreamWriter logFile = null; 13 | 14 | public Logger(string[] args) 15 | { 16 | foreach (string arg in args) 17 | { 18 | string sourceFileName = arg; 19 | if (File.Exists(sourceFileName)) 20 | { 21 | string ext = sourceFileName.Substring(sourceFileName.LastIndexOf(".")); 22 | logFile = new StreamWriter(sourceFileName.Replace(ext, ".log"), false, Encoding.ASCII); 23 | break; 24 | } 25 | } 26 | } 27 | 28 | public void PrintBanner() 29 | { 30 | PrintBanner(null); 31 | if (this.logFile != null) 32 | { 33 | PrintBanner(this.logFile); 34 | } 35 | } 36 | 37 | public void PrintBanner(StreamWriter outputFile) 38 | { 39 | //string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); 40 | string fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion; 41 | //string productVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion; 42 | string dashes = "--------------------------------------------------------"; 43 | string copyRight = $"-- mcc V{fileVersion} - Custom microcode compiler (c)2020-... "; 44 | string gitHub = "-- https://github.com/zpekic/MicroCodeCompiler"; 45 | 46 | PrintLines(outputFile, new List { dashes, copyRight, gitHub, dashes }); 47 | } 48 | 49 | public void PrintHelp(StreamWriter outputFile) 50 | { 51 | List lines = new List(); 52 | 53 | lines.Add(string.Empty); 54 | lines.Add("Compile mode (generate microcode, mapper and control unit files):"); 55 | lines.Add("mcc.exe [relpath|fullpath\\]sourcefile.mcc"); 56 | lines.Add(string.Empty); 57 | lines.Add("Convert mode (generate sourcefile.coe, .cgf, .mif, .hex, .vhd files):"); 58 | lines.Add("mcc.exe [relpath|fullpath\\]sourcefile.bin [addresswidth [[wordwidth [recordwidth]]]"); 59 | lines.Add("addresswidth ... 2^addresswidth is memory depth (integer, range: 0 to 16, default: 0 which will infer from file size)"); 60 | lines.Add("wordwidth ... memory width (integer, values: 8, 16, 32 bits, default: 8 (1 byte))"); 61 | lines.Add("recordwidth ... used for .hex files (integer, values: 1, 2, 4, 8, 16, 32 bytes, default: 16)"); 62 | lines.Add(string.Empty); 63 | lines.Add("For more info see https://hackaday.io/project/172073-microcoding-for-fpgas"); 64 | 65 | PrintLines(outputFile, lines); 66 | } 67 | 68 | private void PrintLines(StreamWriter outputFile, List lines) 69 | { 70 | if (outputFile == null) 71 | { 72 | foreach (string line in lines) 73 | { 74 | System.Console.WriteLine(line); 75 | } 76 | } 77 | else 78 | { 79 | foreach (string line in lines) 80 | { 81 | outputFile.WriteLine(line); 82 | } 83 | } 84 | } 85 | 86 | public void Write(string line) 87 | { 88 | Write(this.logFile, line); 89 | } 90 | 91 | public void WriteLine(string line) 92 | { 93 | WriteLine(this.logFile, line); 94 | } 95 | 96 | private void Write(TextWriter outputFile, string line) 97 | { 98 | if (outputFile != null) 99 | { 100 | outputFile.Write(line); 101 | } 102 | if (!line.StartsWith("Info")) 103 | { 104 | if (line.StartsWith("Error")) 105 | { 106 | WriteWithColor(line, ConsoleColor.Red); 107 | return; 108 | } 109 | if (line.StartsWith("Warning")) 110 | { 111 | WriteWithColor(line, ConsoleColor.Yellow); 112 | return; 113 | } 114 | if (line.StartsWith("Success")) 115 | { 116 | WriteWithColor(line, ConsoleColor.Green); 117 | return; 118 | } 119 | System.Console.Write(line); 120 | } 121 | } 122 | 123 | private void WriteLine(TextWriter outputFile, string line) 124 | { 125 | Write(outputFile, $"{line}\r\n"); 126 | } 127 | 128 | private static void WriteWithColor(string error, ConsoleColor penColor) 129 | { 130 | ConsoleColor currentFgColor = Console.ForegroundColor; 131 | Console.ForegroundColor = penColor; 132 | System.Console.Write(error); 133 | Console.ForegroundColor = currentFgColor; 134 | } 135 | 136 | #region IDisposable Support 137 | private bool disposedValue = false; // To detect redundant calls 138 | 139 | protected virtual void Dispose(bool disposing) 140 | { 141 | if (!disposedValue) 142 | { 143 | if (disposing) 144 | { 145 | if (logFile != null) 146 | { 147 | logFile.Flush(); 148 | logFile.Dispose(); 149 | } 150 | } 151 | 152 | // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. 153 | // TODO: set large fields to null. 154 | 155 | disposedValue = true; 156 | } 157 | } 158 | 159 | // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources. 160 | // ~Logger() { 161 | // // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 162 | // Dispose(false); 163 | // } 164 | 165 | // This code added to correctly implement the disposable pattern. 166 | public void Dispose() 167 | { 168 | // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 169 | Dispose(true); 170 | // TODO: uncomment the following line if the finalizer is overridden above. 171 | // GC.SuppressFinalize(this); 172 | } 173 | #endregion 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /mcc/Map.cs: -------------------------------------------------------------------------------- 1 | namespace mcc 2 | { 3 | internal class Map : ParsedLineWithNoLabel 4 | { 5 | public int FromValue; 6 | public int ToValue; 7 | 8 | public Map(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".map", lineNumber, orgValue, label, content, logger) 9 | { 10 | Assert(orgValue > 0, "Can't map as .org not set"); 11 | } 12 | 13 | public override void ParseContent() 14 | { 15 | string from, to; 16 | int mask; 17 | 18 | base.ParseContent(); 19 | if (ParsedLine.Split3(Content, "..", out from, out to)) 20 | { 21 | Assert(GetValueAndMask(from, out FromValue, out mask, null), $"Invalid map specifier {from}"); 22 | Assert(mask == 0, $"Mask specifier '{from}' not allowed in .map range"); 23 | Assert(GetValueAndMask(to, out ToValue, out mask, null), $"Invalid map specifier {to}"); 24 | Assert(mask == 0, $"Mask specifier '{to}' not allowed in .map range"); 25 | Assert(ToValue >= FromValue, $"Range '{Content}' is empty"); 26 | if (ToValue == FromValue) 27 | { 28 | logger.WriteLine($"Warning: range '{Content}' contains only a single value of {FromValue}"); 29 | } 30 | } 31 | else 32 | { 33 | Assert(GetValueAndMask(Content, out FromValue, out mask, null), $"Invalid map specifier {Content}"); 34 | ToValue = FromValue + mask; 35 | if (mask != 0) 36 | { 37 | logger.WriteLine($"Warning: mask value {mask} detected. Range will be {FromValue} to {ToValue}"); 38 | } 39 | } 40 | } 41 | 42 | public void Project(MemBlock memory, int dataWidth) 43 | { 44 | bool generateComment = true; 45 | string data = GetBinaryString(OrgValue, dataWidth); 46 | int writeCnt = 0; 47 | 48 | for (int address = FromValue; address <= ToValue; address++) 49 | { 50 | string comment = generateComment ? GetParsedLineString() : string.Empty; 51 | memory.Write(address, data, comment, null, string.Empty, true, "mapper"); 52 | generateComment = false; 53 | writeCnt++; 54 | } 55 | 56 | switch (writeCnt) 57 | { 58 | case 0: 59 | logger.WriteLine($"Warning: No mapper locations from {FromValue} to {ToValue} set to value '{data}' (range may be bad?)"); 60 | break; 61 | case 1: 62 | logger.WriteLine($"Info: Mapper location {FromValue} set to value '{data}'"); 63 | break; 64 | default: 65 | logger.WriteLine($"Info: {writeCnt} mapper locations from {FromValue} to {ToValue} set to value '{data}'"); 66 | break; 67 | } 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /mcc/Mapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace mcc 6 | { 7 | internal class Mapper : MemBlock 8 | { 9 | public int Depth; // must be 2^n 10 | public int Width; // must be >0 11 | 12 | public Mapper(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".mapper", lineNumber, orgValue, label, content, logger) 13 | { 14 | this.Depth = -1; 15 | this.Width = -1; 16 | } 17 | 18 | protected override int GenerateVhdFile(string prefix, FileInfo outputFileInfo, List fields, string otherRanges, bool isConversion, bool isRisingEdge) 19 | { 20 | Assert(!string.IsNullOrEmpty(prefix), ":.vhd expected - prefix not found"); 21 | Assert(fields == null, "Unexpected data passed in"); 22 | 23 | logger.Write($"Generating mapper '{outputFileInfo.FullName}' ..."); 24 | string template = LoadVhdPackageTemplate(isConversion ? "conversion_template.vhd" : "mapper_template.vhd", isConversion); 25 | int capacity = 2 << (this.addressWidth - 1); 26 | string name = outputFileInfo.Name.Substring(0, outputFileInfo.Name.IndexOf(".")); 27 | 28 | using (System.IO.StreamWriter vhdFile = new System.IO.StreamWriter(outputFileInfo.FullName, false, Encoding.ASCII)) 29 | { 30 | logger.PrintBanner(vhdFile); 31 | template = template.Replace("[NAME]", name); 32 | template = template.Replace("[FIELDS]", string.Empty); 33 | template = template.Replace("[SIZES]", GetVhdlSizes("MAPPER", null)); 34 | template = template.Replace("[TYPE]", $"type {prefix}_mapper_memory is array(0 to {capacity - 1}) of std_logic_vector({dataWidth - 1} downto 0);"); 35 | template = template.Replace("[SIGNAL]", $"signal {prefix}_instructionstart: std_logic_vector({dataWidth - 1} downto 0);"); 36 | template = template.Replace("[INSTANCE]", $"--{prefix}_instructionstart <= {prefix}_mapper(to_integer(unsigned(TODO))); -- copy to file containing the control unit. TODO is typically the 'instruction_register'"); 37 | template = template.Replace("[MEMORY]", $"constant {prefix}_mapper: {prefix}_mapper_memory := ({GetVhdMemory(capacity, null, otherRanges, false)});"); 38 | template = template.Replace("[PLACEHOLDERS]", " [SIZES], [NAME], [TYPE], [INSTANCE], [SIGNAL], [MEMORY]"); 39 | vhdFile.WriteLine(template); 40 | } 41 | 42 | logger.WriteLine(" Done."); 43 | return 1; 44 | } 45 | 46 | protected override string GetBlockName() 47 | { 48 | return this.GetType().ToString(); 49 | } 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /mcc/MccException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace mcc 4 | { 5 | internal class MccException : Exception 6 | { 7 | private int line; 8 | private string file; 9 | private string customMessage; 10 | 11 | public MccException(int lineNumber, string fileName, string message) : base(message) 12 | { 13 | this.line = lineNumber; 14 | this.file = fileName; 15 | this.customMessage = message; 16 | } 17 | 18 | public override String Message 19 | { 20 | get 21 | { 22 | return $"Error in file '{file}' line {line}: {customMessage}."; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mcc/Org.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace mcc 8 | { 9 | internal class Org : ParsedLineWithNoLabel 10 | { 11 | public Org(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".org", lineNumber, orgValue, label, content, logger) 12 | { 13 | } 14 | 15 | public override void ParseContent() 16 | { 17 | int value, mask; 18 | 19 | base.ParseContent(); 20 | Assert(GetValueAndMask(this.Content, out value, out mask, null), ".org: Error parsing value"); 21 | Assert(mask == 0, string.Format(".org: Mask '{0}' not allowed", mask.ToString())); 22 | Assert(value >= 0, string.Format(".org: Value '{0}' not allowed", mask.ToString())); 23 | this.OrgValue = value; 24 | } 25 | 26 | public int GetUpdatedOrgValue(int currentOrgValue) 27 | { 28 | if (OrgValue < 0) 29 | { 30 | return currentOrgValue; 31 | } 32 | else 33 | { 34 | Assert(OrgValue >= currentOrgValue, $"Trying to set .org value to {OrgValue} (0x{OrgValue:X4}) which is below current value of {currentOrgValue} (0x{currentOrgValue:X4})."); 35 | 36 | logger.WriteLine($"Warning: .org value changed from {currentOrgValue} (0x{currentOrgValue:X4}) to {OrgValue} (0x{OrgValue:X4})"); 37 | return OrgValue; 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /mcc/ParsedLineWithLabel.cs: -------------------------------------------------------------------------------- 1 | namespace mcc 2 | { 3 | internal abstract class ParsedLineWithLabel : ParsedLine 4 | { 5 | public ParsedLineWithLabel(string statement, int lineNumber, int orgValue, string label, string content, Logger logger) : base(statement, lineNumber, orgValue, label, content, logger) 6 | { 7 | Assert(!string.IsNullOrEmpty(this.Label), "Label missing (all microinstruction field definitions and aliases require it)"); 8 | } 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /mcc/ParsedLineWithNoLabel.cs: -------------------------------------------------------------------------------- 1 | namespace mcc 2 | { 3 | internal abstract class ParsedLineWithNoLabel : ParsedLine 4 | { 5 | public ParsedLineWithNoLabel(string statement, int lineNumber, int orgValue, string label, string content, Logger logger) : base(statement, lineNumber, orgValue, label, content, logger) 6 | { 7 | Assert(string.IsNullOrEmpty(this.Label), "Label not allowed (maybe should be on subsequent microinstruction?)"); 8 | } 9 | 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /mcc/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("mcc")] 9 | [assembly: AssemblyDescription("Microcode compiler - generates mapping and microinstruction files")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("https://hackaday.io/projects/hacker/233652")] 12 | [assembly: AssemblyProduct("mcc")] 13 | [assembly: AssemblyCopyright("Copyright © 2020 -")] 14 | [assembly: AssemblyTrademark("https://github.com/zpekic")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b0335713-7c5d-4c36-a8c7-599f65a6c482")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.4.0328")] 36 | [assembly: AssemblyFileVersion("1.4.0328")] 37 | -------------------------------------------------------------------------------- /mcc/Sub.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace mcc 8 | { 9 | internal class Sub : ParsedLineWithLabel 10 | { 11 | public string[] RegNames = null; // assume no "call" parameters 12 | 13 | public Sub(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".sub", lineNumber, orgValue, label, content, logger) 14 | { 15 | } 16 | 17 | public override void ParseContent() 18 | { 19 | base.ParseContent(); 20 | if (!string.IsNullOrEmpty(this.Content)) 21 | { 22 | RegNames = this.Content.Split(','); 23 | for (int i = 0; i < RegNames.Length; i++) 24 | { 25 | RegNames[i] = RegNames[i].Trim(); 26 | } 27 | } 28 | } 29 | 30 | public bool CheckParams(List fields) 31 | { 32 | if (RegNames != null) 33 | { 34 | foreach (string regName in RegNames) 35 | { 36 | List matches = fields.FindAll(f => regName.Equals(f.Label, StringComparison.InvariantCultureIgnoreCase)); 37 | Assert(matches != null && matches.Count == 1, $"Parameter '{regName}' not found or duplicated"); 38 | Assert(matches[0].IsValidSubParameter(regName), $"Parameter '{regName}' must refer to .regvalue"); 39 | } 40 | } 41 | 42 | return true; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mcc/Symbol.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace mcc 6 | { 7 | internal class Symbol : MemBlock 8 | { 9 | private int rowCnt, colCnt; 10 | 11 | public Symbol(int lineNumber, int orgValue, string label, string content, Logger logger) : base(".symbol", lineNumber, orgValue, label, content, logger) 12 | { 13 | } 14 | 15 | internal void InitAll() 16 | { 17 | rowCnt = 1 << addressWidth; 18 | colCnt = dataWidth >> 3; 19 | byte[] byteEntry = new byte[colCnt]; 20 | for (int r = 0; r < rowCnt; r++) 21 | { 22 | for (int c = 0; c < colCnt; c++) 23 | { 24 | byteEntry[c] = (byte)' '; // initialize with spaces 25 | } 26 | Write(r, byteEntry, string.Empty, string.Empty, string.Empty, -1, "symbol"); 27 | } 28 | } 29 | 30 | internal void InitEntry(MicroInstruction mi) 31 | { 32 | string symEntry; 33 | byte[] byteEntry = new byte[colCnt]; 34 | Assert(mi.OrgValue < rowCnt, $".symbol write to entry {mi.OrgValue} beyond limit of {rowCnt}"); 35 | 36 | if (string.IsNullOrEmpty(mi.Label)) 37 | { 38 | symEntry = $"{mi.Content};"; 39 | } 40 | else 41 | { 42 | symEntry = $"{mi.Label}: {mi.Content};"; 43 | } 44 | for (int c = 0; c < colCnt; c++) 45 | { 46 | if (c < symEntry.Length) 47 | { 48 | byteEntry[c] = (byte)symEntry[c]; 49 | } 50 | else 51 | { 52 | byteEntry[c] = (byte) ' '; // fill with space 53 | } 54 | } 55 | memory.Remove(mi.OrgValue); 56 | Write(mi.OrgValue, byteEntry, mi.GetParsedLineString(), symEntry, string.Empty, -1, "symbol"); 57 | } 58 | 59 | protected override int GenerateVhdFile(string prefix, FileInfo outputFileInfo, List fields, string otherRanges, bool isConversion, bool isRisingEdge) 60 | { 61 | Assert(!string.IsNullOrEmpty(prefix), ":.vhd expected - prefix not found"); 62 | Assert(!isConversion, "Code memory cannot be used for conversion (internal error)"); 63 | 64 | logger.Write($"Generating code '{outputFileInfo.FullName}' ..."); 65 | string template = LoadVhdPackageTemplate("symbol_template.vhd", false); 66 | int capacity = 2 << (this.addressWidth - 1); 67 | string defaultMicroinstruction = string.Empty; 68 | string name = outputFileInfo.Name.Substring(0, outputFileInfo.Name.IndexOf(".")); 69 | MicroField fif = null; 70 | 71 | if (fields != null) 72 | { 73 | fif = fields.Find(fl => fl.GetType().ToString() == "mcc.FieldIf"); 74 | } 75 | 76 | using (System.IO.StreamWriter vhdFile = new System.IO.StreamWriter(outputFileInfo.FullName, false, Encoding.ASCII)) 77 | { 78 | logger.PrintBanner(vhdFile); 79 | template = template.Replace("[NAME]", name); 80 | template = template.Replace("[FIELDS]", string.Empty); 81 | template = template.Replace("[SIZES]", GetVhdlSizes("SYMBOL")); 82 | template = template.Replace("[TYPE]", GetVhdlTypes(prefix)); 83 | template = template.Replace("[SIGNAL]", GetVhdlSignals(prefix)); 84 | template = template.Replace("[INSTANCE]", string.Empty); 85 | template = template.Replace("[MEMORY]", $"constant {prefix}_symbol_entry: t_{prefix}_symbol_entry := ({GetVhdMemory(capacity, defaultMicroinstruction, otherRanges, true)});"); 86 | template = template.Replace("[PLACEHOLDERS]", " [NAME], [FIELDS], [SIZES], [TYPE], [SIGNAL], [INSTANCE], [MEMORY]"); 87 | vhdFile.WriteLine(template); 88 | } 89 | 90 | logger.WriteLine(" Done."); 91 | return 1; 92 | } 93 | 94 | protected string GetVhdlSizes(string prefix) 95 | { 96 | StringBuilder sbSizes = new StringBuilder(base.GetVhdlSizes(prefix, null)); 97 | 98 | int byte_last = this.dataWidth >> 3; 99 | int byte_width = GetLog2(byte_last); 100 | Assert(byte_width > 0, $"Symbol table width in bytes ({byte_last}) is not a power of 2"); 101 | 102 | sbSizes.AppendLine($"constant SYMBOL_BYTE_LAST: \tpositive := {byte_last - 1};"); 103 | sbSizes.AppendLine($"constant SYMBOL_BYTE_WIDTH: positive := {byte_width};"); 104 | 105 | return sbSizes.ToString(); 106 | } 107 | 108 | protected string GetVhdlSignals(string prefix) 109 | { 110 | StringBuilder sbSignals = new StringBuilder(); 111 | 112 | sbSignals.AppendLine($"signal {prefix}_symbol_byte: t_{prefix}_symbol_byte;"); 113 | sbSignals.AppendLine($"signal {prefix}_sym_d: std_logic_vector(7 downto 0);"); 114 | sbSignals.AppendLine($"signal {prefix}_sym_a: std_logic_vector(SYMBOL_ADDRESS_WIDTH + SYMBOL_BYTE_WIDTH - 1 downto 0);"); 115 | sbSignals.AppendLine("----Start boilerplate code(use with utmost caution!)"); 116 | sbSignals.AppendLine($"-- {prefix}_sym_a <= -- TODO concatenate microinstruction address and character address"); 117 | sbSignals.AppendLine($"-- {prefix}_sym_d <= {prefix}_symbol_byte(to_integer(unsigned({prefix}_sym_a)));"); 118 | sbSignals.AppendLine($"----convert symbol entries to byte-oriented ROM"); 119 | sbSignals.AppendLine($"--gen_r: for r in 0 to SYMBOL_ADDRESS_LAST generate"); 120 | sbSignals.AppendLine($"--begin"); 121 | sbSignals.AppendLine($"-- gen_c: for c in 0 to SYMBOL_BYTE_LAST generate"); 122 | sbSignals.AppendLine($"-- begin"); 123 | sbSignals.AppendLine($"-- --assert false report \"r = \" & integer'image(r) & \" c = \" & integer'image(c) severity note;"); 124 | sbSignals.AppendLine($"-- {prefix}_symbol_byte(r * (SYMBOL_BYTE_LAST + 1) + c) <= {prefix}_symbol_entry(r)(SYMBOL_DATA_WIDTH - 8 * c - 1 downto SYMBOL_DATA_WIDTH - 8 * (c + 1));"); 125 | sbSignals.AppendLine($"-- end generate;"); 126 | sbSignals.AppendLine($"--end generate;"); 127 | sbSignals.AppendLine("----End boilerplate code"); 128 | 129 | return sbSignals.ToString(); 130 | } 131 | 132 | protected string GetVhdlTypes(string prefix) 133 | { 134 | StringBuilder sbTypes = new StringBuilder(); 135 | 136 | sbTypes.AppendLine($"type t_{prefix}_symbol_entry is array(0 to SYMBOL_ADDRESS_LAST) of std_logic_vector(SYMBOL_DATA_WIDTH -1 downto 0);"); 137 | sbTypes.AppendLine($"type t_{prefix}_symbol_byte is array(0 to(SYMBOL_ADDRESS_LAST + 1) * (SYMBOL_BYTE_LAST + 1) - 1) of std_logic_vector(7 downto 0);"); 138 | 139 | return sbTypes.ToString(); 140 | } 141 | 142 | public static string GetFieldLabel(MicroField mf) 143 | { 144 | //Assert(mf != null && !string.IsNullOrEmpty(mf.Label), "Undefined field label"); 145 | 146 | return mf.Label; 147 | } 148 | 149 | protected string GetVhdFields(string prefix, List fields, out string defaultMicroinstruction, bool isRisingEdge) 150 | { 151 | Assert(fields != null && (fields.Count > 0), "Can't generate code - no microcode fields defined"); 152 | 153 | StringBuilder sbFields = new StringBuilder(); 154 | StringBuilder sbDefault = new StringBuilder(); 155 | List fieldLabels = fields.ConvertAll(new System.Converter(GetFieldLabel)); 156 | foreach (MicroField field in fields) 157 | { 158 | sbDefault.Append(GetBinaryString(field.DefaultValue, field.Width)); 159 | sbDefault.Append("_"); 160 | 161 | sbFields.AppendLine($"--"); 162 | sbFields.AppendLine($"-- {field.GetParsedLineString()}"); 163 | sbFields.AppendLine($"--"); 164 | if (field.Hi > field.Lo) 165 | { 166 | sbFields.AppendLine($"alias {prefix}_{field.Label}: \tstd_logic_vector({field.Hi - field.Lo} downto 0) is {prefix}_uinstruction({field.Hi} downto {field.Lo});"); 167 | } 168 | else 169 | { 170 | Assert(field.Hi == field.Lo, $"Unexpected field span ({field.Hi} .. {field.Lo})"); 171 | sbFields.AppendLine($"alias {prefix}_{field.Label}: \tstd_logic is {prefix}_uinstruction({field.Hi});"); 172 | } 173 | foreach (MicroField.ValueVector vv in field.Values) 174 | { 175 | sbFields.AppendLine(vv.GetVhdLine(field, field is FieldIf)); 176 | } 177 | 178 | // attempt to create VHDL code for lazy copy/pasting 179 | StringBuilder sbCode = field.GetVhdlBoilerplateCode(prefix, fieldLabels, isRisingEdge); 180 | sbFields.Append(sbCode); 181 | 182 | sbFields.AppendLine(); 183 | sbFields.AppendLine(); 184 | } 185 | 186 | // remove last underscore 187 | sbDefault.Remove(sbDefault.Length - 1, 1); 188 | defaultMicroinstruction = sbDefault.ToString(); 189 | 190 | return sbFields.ToString(); 191 | } 192 | 193 | protected override string GetBlockName() 194 | { 195 | return this.GetType().ToString(); 196 | } 197 | 198 | } 199 | 200 | } 201 | -------------------------------------------------------------------------------- /mcc/docs/Design.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpekic/MicroCodeCompiler/f2ad127bd184590464d161bcd0bdc837fd20a6b9/mcc/docs/Design.JPG -------------------------------------------------------------------------------- /mcc/mcc.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B0335713-7C5D-4C36-A8C7-599F65A6C482} 8 | Exe 9 | mcc 10 | mcc 11 | v4.6.1 12 | 512 13 | true 14 | false 15 | publish\ 16 | true 17 | Disk 18 | false 19 | Foreground 20 | 7 21 | Days 22 | false 23 | false 24 | true 25 | 0 26 | 1.0.0.%2a 27 | false 28 | true 29 | 30 | 31 | AnyCPU 32 | true 33 | full 34 | false 35 | bin\Debug\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | 40 | 41 | AnyCPU 42 | pdbonly 43 | true 44 | bin\Release\ 45 | TRACE 46 | prompt 47 | 4 48 | 49 | 50 | true 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | False 105 | Microsoft .NET Framework 4.6.1 %28x86 and x64%29 106 | true 107 | 108 | 109 | False 110 | .NET Framework 3.5 SP1 111 | false 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | --------------------------------------------------------------------------------