├── .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 |
--------------------------------------------------------------------------------