HDLRuby 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.html +2330 -2670
- data/README.md +391 -101
- data/ext/hruby_sim/hruby_rcsim_build.c +400 -3
- data/ext/hruby_sim/hruby_sim.h +2 -1
- data/ext/hruby_sim/hruby_sim_calc.c +1 -1
- data/ext/hruby_sim/hruby_sim_core.c +15 -5
- data/ext/hruby_sim/hruby_sim_tree_calc.c +1 -1
- data/lib/HDLRuby/hdr_samples/c_program/echo.c +33 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/echo.rb +9 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/stdrw.rb +6 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/sw_cpu_terminal.rb +614 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/sw_inc_mem.rb +32 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/sw_log.rb +33 -0
- data/lib/HDLRuby/hdr_samples/with_board.rb +63 -0
- data/lib/HDLRuby/hdr_samples/with_clocks.rb +42 -0
- data/lib/HDLRuby/hdr_samples/with_of.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_program_c.rb +28 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby.rb +28 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_cpu.rb +234 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_io.rb +23 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_mem.rb +58 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_threads.rb +56 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +2 -4
- data/lib/HDLRuby/hdrcc.rb +60 -21
- data/lib/HDLRuby/hruby_error.rb +13 -0
- data/lib/HDLRuby/hruby_high.rb +50 -7
- data/lib/HDLRuby/hruby_low.rb +74 -30
- data/lib/HDLRuby/hruby_rcsim.rb +89 -5
- data/lib/HDLRuby/std/clocks.rb +118 -50
- data/lib/HDLRuby/std/std.rb +5 -0
- data/lib/HDLRuby/ui/hruby_board.rb +1079 -0
- data/lib/HDLRuby/version.rb +1 -1
- data/lib/c/Rakefile +8 -0
- data/lib/c/cHDL.h +12 -0
- data/lib/c/extconf.rb +7 -0
- data/lib/rubyHDL.rb +33 -0
- data/tuto/gui_accum.png +0 -0
- data/tuto/gui_board.png +0 -0
- data/tuto/tutorial_sw.html +2263 -1890
- data/tuto/tutorial_sw.md +957 -62
- metadata +24 -5
- data/README.pdf +0 -0
- data/tuto/tutorial_sw.pdf +0 -0
@@ -0,0 +1,614 @@
|
|
1
|
+
# Use either Gosu or Curses.
|
2
|
+
$mode = :gosu
|
3
|
+
begin
|
4
|
+
require "gosu"
|
5
|
+
rescue LoadError
|
6
|
+
$mode = :curses
|
7
|
+
require "curses"
|
8
|
+
end
|
9
|
+
|
10
|
+
require "rubyHDL.rb"
|
11
|
+
|
12
|
+
if $mode == :gosu then
|
13
|
+
|
14
|
+
# Class representing the CRT monitor in Gosu
|
15
|
+
class CRT < Gosu::Window
|
16
|
+
def initialize(width=640,height=480,px_width,px_height)
|
17
|
+
super(width,height,false)
|
18
|
+
|
19
|
+
@px_width = px_width
|
20
|
+
@px_height = px_height
|
21
|
+
@cols = width / @px_width
|
22
|
+
@rows = height / @px_height
|
23
|
+
# puts "px_width=#{px_width} px_height=#{px_height} cols=#{@cols} rows=#{@rows}"
|
24
|
+
|
25
|
+
# The screen buffer.
|
26
|
+
@buf = [ Gosu::Color::BLACK ] * (@cols * @rows)
|
27
|
+
|
28
|
+
# The last pressed key
|
29
|
+
@key = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def update
|
33
|
+
# puts "Updated."
|
34
|
+
end
|
35
|
+
|
36
|
+
def draw
|
37
|
+
@rows.times do |y|
|
38
|
+
pos_y = y * @px_height
|
39
|
+
# puts "y=#{y} pos_y=#{pos_y}"
|
40
|
+
off_y = y * @cols
|
41
|
+
@cols.times do |x|
|
42
|
+
pos_x = x * @px_width
|
43
|
+
draw_rect(pos_x,pos_y, @px_width, @px_height,@buf[x+off_y])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def button_down(id)
|
49
|
+
@key = id
|
50
|
+
end
|
51
|
+
|
52
|
+
def put_pixel(x,y,val)
|
53
|
+
# puts "put_pixel x=#{x} y=#{y}"
|
54
|
+
@buf[x+y*@cols] = val
|
55
|
+
end
|
56
|
+
|
57
|
+
def getch
|
58
|
+
sleep(0.02) while(@key == nil)
|
59
|
+
case(@key)
|
60
|
+
when Gosu::KB_ESCAPE
|
61
|
+
res = 27.chr
|
62
|
+
when Gosu::KB_RETURN
|
63
|
+
res = 10.chr
|
64
|
+
when Gosu::KB_BACKSPACE
|
65
|
+
res = 127.chr
|
66
|
+
else
|
67
|
+
res = Gosu.button_id_to_char(@key)
|
68
|
+
end
|
69
|
+
# puts "res=#{res}" if !res.empty?
|
70
|
+
@key = nil
|
71
|
+
return res
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
class TermEMU
|
77
|
+
# The dimensions of the screen in pixels.
|
78
|
+
attr_reader :cols, :lines
|
79
|
+
|
80
|
+
# Initializes the screen.
|
81
|
+
def startup(width = 320, height = 240)
|
82
|
+
# Set the size of the screen and create it.
|
83
|
+
@width = width
|
84
|
+
@height = height
|
85
|
+
# Set the size of a pixel.
|
86
|
+
@px_width = 4
|
87
|
+
@px_height = 4
|
88
|
+
# Set the number of columns and lines.
|
89
|
+
@cols = @width / @px_width
|
90
|
+
@lines = @height / @px_height
|
91
|
+
# Create the screen.
|
92
|
+
@crt = CRT.new(width,height,@px_width,@px_height)
|
93
|
+
@crt.tick
|
94
|
+
# Sets the color black
|
95
|
+
@px_black = " ".ord
|
96
|
+
end
|
97
|
+
|
98
|
+
# Closes the application.
|
99
|
+
def terminate
|
100
|
+
exit
|
101
|
+
end
|
102
|
+
|
103
|
+
# Refresh the screen.
|
104
|
+
def refresh
|
105
|
+
# In case of GOSU, it is not required to do anything here.
|
106
|
+
@crt.tick
|
107
|
+
end
|
108
|
+
|
109
|
+
# Draw a pixel.
|
110
|
+
def put_pixel(x,y,val)
|
111
|
+
if val == @px_black then
|
112
|
+
@crt.put_pixel(x,y,Gosu::Color::BLACK)
|
113
|
+
else
|
114
|
+
@crt.put_pixel(x,y,Gosu::Color::WHITE)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get a keyboard input.
|
119
|
+
def getch
|
120
|
+
return @crt.getch
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
else
|
125
|
+
|
126
|
+
|
127
|
+
class TermEMU
|
128
|
+
include Curses
|
129
|
+
|
130
|
+
# Initializes the screen.
|
131
|
+
def startup
|
132
|
+
init_screen
|
133
|
+
crmode
|
134
|
+
noecho
|
135
|
+
curs_set(1)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Closes the screen.
|
139
|
+
def terminate
|
140
|
+
close_screen
|
141
|
+
end
|
142
|
+
|
143
|
+
# Draw a pixel.
|
144
|
+
def put_pixel(x,y,val)
|
145
|
+
setpos(y,x)
|
146
|
+
addstr(val.chr)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
$termEMU = TermEMU.new
|
152
|
+
|
153
|
+
# Ruby set of programs that simulate:
|
154
|
+
# * A CPU executing a shell
|
155
|
+
# * Its memory
|
156
|
+
# * A monitor
|
157
|
+
# * A keyboard communicating using UART
|
158
|
+
|
159
|
+
V_ADDR = 0xC000
|
160
|
+
K_ADDR = 0xB000
|
161
|
+
|
162
|
+
# The global simulation configuration parameters.
|
163
|
+
def configure
|
164
|
+
# Initialize the system.
|
165
|
+
|
166
|
+
begin
|
167
|
+
# For the monitor.
|
168
|
+
$termEMU.startup
|
169
|
+
|
170
|
+
RubyHDL.hSIZE = $termEMU.cols
|
171
|
+
RubyHDL.hSTART = 10
|
172
|
+
RubyHDL.hEND = 10
|
173
|
+
RubyHDL.vSIZE = $termEMU.lines
|
174
|
+
RubyHDL.vSTART = 10
|
175
|
+
RubyHDL.vEND = 10
|
176
|
+
rescue
|
177
|
+
# Failed to initialize the monitor.
|
178
|
+
$termEMU.terminate
|
179
|
+
puts "Could not initialize the monitor."
|
180
|
+
exit
|
181
|
+
end
|
182
|
+
|
183
|
+
# For the keyboard.
|
184
|
+
RubyHDL.rxCYCLE = 8
|
185
|
+
|
186
|
+
# For the memory mapping of the devices.
|
187
|
+
RubyHDL.vADDR = V_ADDR
|
188
|
+
RubyHDL.kADDR = K_ADDR
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
# Simulation of the CPU memory: filled with "." for debug purpose.
|
193
|
+
class MemoryChip
|
194
|
+
def initialize(size,width = 8, memory_map = {})
|
195
|
+
@sync = Mutex.new
|
196
|
+
@width = width
|
197
|
+
@data_mask = (2 << @width) - 1
|
198
|
+
@addr_mask = (2 << size) - 1
|
199
|
+
@cells = [0] * size
|
200
|
+
@memory_map = memory_map
|
201
|
+
end
|
202
|
+
|
203
|
+
def synchronize(&ruby_block)
|
204
|
+
@sync.synchronize(&ruby_block)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Read the memory.
|
208
|
+
def [](addr)
|
209
|
+
addr = addr.to_i & @addr_mask
|
210
|
+
# Is it a memory mapped address?
|
211
|
+
loc = @memory_map[addr]
|
212
|
+
return loc.call if loc # Yes.
|
213
|
+
# No, normal access.
|
214
|
+
return @cells[addr]
|
215
|
+
end
|
216
|
+
|
217
|
+
# Write the memory.
|
218
|
+
def []=(addr,val)
|
219
|
+
addr = addr.to_i & @addr_mask
|
220
|
+
val = val.to_i & @data_mask
|
221
|
+
# Is it a memory mapped address?
|
222
|
+
loc = @memory_map[addr]
|
223
|
+
return loc.call(val) if loc
|
224
|
+
# No, normal access.
|
225
|
+
@cells[addr] = val
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
MEM = MemoryChip.new(65536, 8, { K_ADDR => proc { RubyHDL.key_reg } })
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
# The software tasks (processes and handlers).
|
234
|
+
$tasks = []
|
235
|
+
|
236
|
+
# Simulate the reset: set up the tasks.
|
237
|
+
def cpu_rst
|
238
|
+
# Are there any running task?
|
239
|
+
$tasks.each do |task|
|
240
|
+
if task then
|
241
|
+
# First kill it.
|
242
|
+
task.kill
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# Create the new process task (the shell application).
|
247
|
+
$tasks[0] = Thread.new(&Kernel.method(:shell))
|
248
|
+
end
|
249
|
+
|
250
|
+
# Simulate the irq.
|
251
|
+
def cpu_irq
|
252
|
+
# Tell the interrupt is being serviced.
|
253
|
+
RubyHDL.ack = 1
|
254
|
+
# Launch the handler.
|
255
|
+
# Kernel.send(:handler)
|
256
|
+
$tasks[1] = Thread.new(&Kernel.method(:handler))
|
257
|
+
end
|
258
|
+
|
259
|
+
# Simulate the wake of the process.
|
260
|
+
def iwake
|
261
|
+
$tasks[0].run
|
262
|
+
end
|
263
|
+
|
264
|
+
# Simulate the return from interrupt instruction.
|
265
|
+
def iret
|
266
|
+
# Rmove the handler task.
|
267
|
+
$tasks[1] = nil
|
268
|
+
# Tells the interrupt servicing is over.
|
269
|
+
RubyHDL.ack = 0
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
# Simulation of the CPU bus and the underlining OS execution.
|
276
|
+
def cpu_bus
|
277
|
+
# Is there a bus request?
|
278
|
+
if RubyHDL.br == 1 then
|
279
|
+
# Yes, grant it.
|
280
|
+
RubyHDL.bg = 1
|
281
|
+
else
|
282
|
+
# No, release it.
|
283
|
+
RubyHDL.bg = 0
|
284
|
+
end
|
285
|
+
|
286
|
+
# Is there a memory read?
|
287
|
+
MEM.synchronize do
|
288
|
+
if RubyHDL.rwb == 1 then
|
289
|
+
# Read.
|
290
|
+
RubyHDL.dout = MEM[RubyHDL.aout]
|
291
|
+
# else
|
292
|
+
# # Write.
|
293
|
+
# MEM[RubyHDL.ain] = RubyHDL.din
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Now wake the handler if any.
|
298
|
+
$tasks[1].run if $tasks[1]
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
$monitorX = 0
|
304
|
+
$monitorY = 0
|
305
|
+
|
306
|
+
# Frame skipping for speeding up monitor.
|
307
|
+
if $mode == :gosu then
|
308
|
+
FRAME_SKIP = 100
|
309
|
+
else
|
310
|
+
FRAME_SKIP = 9
|
311
|
+
end
|
312
|
+
$frame = 0
|
313
|
+
$refreshed = false
|
314
|
+
|
315
|
+
# Simulate the monitor.
|
316
|
+
def monitor
|
317
|
+
if RubyHDL.vblank == 1 then
|
318
|
+
# Vertical blank.
|
319
|
+
$monitorX = 0
|
320
|
+
$monitorY = 0
|
321
|
+
# Refresh display (if frame not skipped).
|
322
|
+
if $frame == FRAME_SKIP then
|
323
|
+
$frame = 0
|
324
|
+
if !$refreshed then
|
325
|
+
$termEMU.refresh
|
326
|
+
$refreshed = true
|
327
|
+
end
|
328
|
+
else
|
329
|
+
$frame += 1
|
330
|
+
end
|
331
|
+
elsif RubyHDL.hblank == 1 then
|
332
|
+
# Horizontal blank.
|
333
|
+
if $monitorX != 0 then
|
334
|
+
# Start of horizontal blank, increase Y and reset X.
|
335
|
+
$monitorY += 1
|
336
|
+
$monitorX = 0
|
337
|
+
end
|
338
|
+
else
|
339
|
+
$refreshed = false
|
340
|
+
# Normal run.
|
341
|
+
# Display the pixel.
|
342
|
+
if RubyHDL.pixel > 0 then
|
343
|
+
$termEMU.put_pixel($monitorX,$monitorY,RubyHDL.pixel)
|
344
|
+
end
|
345
|
+
# Increase the X position.
|
346
|
+
$monitorX += 1
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
|
351
|
+
# Simulate the UART keyboard.
|
352
|
+
|
353
|
+
# The key buffer.
|
354
|
+
$key = nil
|
355
|
+
# The thread waiting for a key in ncurses.
|
356
|
+
$key_waiter = Thread.new do
|
357
|
+
loop do
|
358
|
+
if $termEMU then
|
359
|
+
ch = $termEMU.getch
|
360
|
+
$key = ch.ord if !ch.empty?
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# Bit position (-1 if no transmission).
|
366
|
+
$key_bitpos = -1
|
367
|
+
|
368
|
+
def keyboard
|
369
|
+
# Is there a key pressed and a previous one is not being sent.
|
370
|
+
if $key and $key_bitpos == -1 then
|
371
|
+
# Start a new transmission.
|
372
|
+
$key_bitpos = 0
|
373
|
+
RubyHDL.rx = 0
|
374
|
+
elsif $key_bitpos >= 0 and $key_bitpos < 8 then
|
375
|
+
# A key is in transmission, go on.
|
376
|
+
RubyHDL.rx = ($key >> (7-$key_bitpos)) & 1
|
377
|
+
$key_bitpos += 1
|
378
|
+
else
|
379
|
+
# End of transmission, or no transmission.
|
380
|
+
RubyHDL.rx = 1
|
381
|
+
$key_bitpos = -1
|
382
|
+
# Clears the key.
|
383
|
+
$key = nil
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
|
388
|
+
## The actual software part.
|
389
|
+
|
390
|
+
# The interrupt handler.
|
391
|
+
def handler
|
392
|
+
# Wake the process.
|
393
|
+
iwake
|
394
|
+
# Wait several clock cycles (simulate SW execution time).
|
395
|
+
10.times { sleep }
|
396
|
+
# Return from interrupt.
|
397
|
+
iret
|
398
|
+
end
|
399
|
+
|
400
|
+
|
401
|
+
# The font used for displaying.
|
402
|
+
# * 8x8 monochrome bitmap fonts for rendering
|
403
|
+
# * Author: Daniel Hepper <daniel@hepper.net>
|
404
|
+
# *
|
405
|
+
# * License: Public Domain
|
406
|
+
# *
|
407
|
+
# * Based on:
|
408
|
+
# * // Summary: font8x8.h
|
409
|
+
# * // 8x8 monochrome bitmap fonts for rendering
|
410
|
+
# * //
|
411
|
+
# * // Author:
|
412
|
+
# * // Marcel Sondaar
|
413
|
+
# * // International Business Machines (public domain VGA fonts)
|
414
|
+
# * //
|
415
|
+
# * // License:
|
416
|
+
# * // Public Domain
|
417
|
+
# *
|
418
|
+
# * Fetched from: http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm
|
419
|
+
# Constant: font8x8_basic
|
420
|
+
# Contains an 8x8 font map for unicode points U+0000 - U+007F (basic latin)
|
421
|
+
Font8x8_basic = [
|
422
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0000 (nul)
|
423
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0001
|
424
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0002
|
425
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0003
|
426
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0004
|
427
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0005
|
428
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0006
|
429
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0007
|
430
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0008
|
431
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0009
|
432
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000A
|
433
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000B
|
434
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000C
|
435
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000D
|
436
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000E
|
437
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000F
|
438
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0010
|
439
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0011
|
440
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0012
|
441
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0013
|
442
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0014
|
443
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0015
|
444
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0016
|
445
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0017
|
446
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0018
|
447
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0019
|
448
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001A
|
449
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001B
|
450
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001C
|
451
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001D
|
452
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001E
|
453
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001F
|
454
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0020 (space)
|
455
|
+
[ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00], # U+0021 (!)
|
456
|
+
[ 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0022 (")
|
457
|
+
[ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00], # U+0023 (#)
|
458
|
+
[ 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00], # U+0024 ($)
|
459
|
+
[ 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00], # U+0025 (%)
|
460
|
+
[ 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00], # U+0026 (&)
|
461
|
+
[ 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0027 (')
|
462
|
+
[ 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00], # U+0028 (()
|
463
|
+
[ 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00], # U+0029 ())
|
464
|
+
[ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00], # U+002A (*)
|
465
|
+
[ 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00], # U+002B (+)
|
466
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06], # U+002C (,)
|
467
|
+
[ 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00], # U+002D (-)
|
468
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00], # U+002E (.)
|
469
|
+
[ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00], # U+002F (/)
|
470
|
+
[ 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00], # U+0030 (0)
|
471
|
+
[ 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00], # U+0031 (1)
|
472
|
+
[ 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00], # U+0032 (2)
|
473
|
+
[ 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00], # U+0033 (3)
|
474
|
+
[ 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00], # U+0034 (4)
|
475
|
+
[ 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00], # U+0035 (5)
|
476
|
+
[ 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00], # U+0036 (6)
|
477
|
+
[ 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00], # U+0037 (7)
|
478
|
+
[ 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00], # U+0038 (8)
|
479
|
+
[ 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00], # U+0039 (9)
|
480
|
+
[ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00], # U+003A (:)
|
481
|
+
[ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06], # U+003B (;)
|
482
|
+
[ 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00], # U+003C (<)
|
483
|
+
[ 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00], # U+003D (=)
|
484
|
+
[ 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00], # U+003E (>)
|
485
|
+
[ 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00], # U+003F (?)
|
486
|
+
[ 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00], # U+0040 (@)
|
487
|
+
[ 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00], # U+0041 (A)
|
488
|
+
[ 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00], # U+0042 (B)
|
489
|
+
[ 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00], # U+0043 (C)
|
490
|
+
[ 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00], # U+0044 (D)
|
491
|
+
[ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00], # U+0045 (E)
|
492
|
+
[ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00], # U+0046 (F)
|
493
|
+
[ 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00], # U+0047 (G)
|
494
|
+
[ 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00], # U+0048 (H)
|
495
|
+
[ 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+0049 (I)
|
496
|
+
[ 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00], # U+004A (J)
|
497
|
+
[ 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00], # U+004B (K)
|
498
|
+
[ 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00], # U+004C (L)
|
499
|
+
[ 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00], # U+004D (M)
|
500
|
+
[ 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00], # U+004E (N)
|
501
|
+
[ 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00], # U+004F (O)
|
502
|
+
[ 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00], # U+0050 (P)
|
503
|
+
[ 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00], # U+0051 (Q)
|
504
|
+
[ 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00], # U+0052 (R)
|
505
|
+
[ 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00], # U+0053 (S)
|
506
|
+
[ 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+0054 (T)
|
507
|
+
[ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00], # U+0055 (U)
|
508
|
+
[ 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], # U+0056 (V)
|
509
|
+
[ 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00], # U+0057 (W)
|
510
|
+
[ 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00], # U+0058 (X)
|
511
|
+
[ 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00], # U+0059 (Y)
|
512
|
+
[ 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00], # U+005A (Z)
|
513
|
+
[ 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00], # U+005B ([)
|
514
|
+
[ 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00], # U+005C (\)
|
515
|
+
[ 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00], # U+005D (])
|
516
|
+
[ 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00], # U+005E (^)
|
517
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF], # U+005F (_)
|
518
|
+
[ 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0060 (`)
|
519
|
+
[ 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00], # U+0061 (a)
|
520
|
+
[ 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00], # U+0062 (b)
|
521
|
+
[ 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00], # U+0063 (c)
|
522
|
+
[ 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00], # U+0064 (d)
|
523
|
+
[ 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00], # U+0065 (e)
|
524
|
+
[ 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00], # U+0066 (f)
|
525
|
+
[ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F], # U+0067 (g)
|
526
|
+
[ 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00], # U+0068 (h)
|
527
|
+
[ 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+0069 (i)
|
528
|
+
[ 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E], # U+006A (j)
|
529
|
+
[ 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00], # U+006B (k)
|
530
|
+
[ 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+006C (l)
|
531
|
+
[ 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00], # U+006D (m)
|
532
|
+
[ 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00], # U+006E (n)
|
533
|
+
[ 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00], # U+006F (o)
|
534
|
+
[ 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F], # U+0070 (p)
|
535
|
+
[ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78], # U+0071 (q)
|
536
|
+
[ 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00], # U+0072 (r)
|
537
|
+
[ 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00], # U+0073 (s)
|
538
|
+
[ 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00], # U+0074 (t)
|
539
|
+
[ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00], # U+0075 (u)
|
540
|
+
[ 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], # U+0076 (v)
|
541
|
+
[ 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00], # U+0077 (w)
|
542
|
+
[ 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00], # U+0078 (x)
|
543
|
+
[ 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F], # U+0079 (y)
|
544
|
+
[ 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00], # U+007A (z)
|
545
|
+
[ 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00], # U+007B ([)
|
546
|
+
[ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00], # U+007C (|)
|
547
|
+
[ 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00], # U+007D (])
|
548
|
+
[ 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+007E (~)
|
549
|
+
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] # U+007F
|
550
|
+
]
|
551
|
+
|
552
|
+
# Character width and height.
|
553
|
+
CH_WIDTH = 8
|
554
|
+
CH_HEIGHT = 8
|
555
|
+
|
556
|
+
$print_count=0
|
557
|
+
|
558
|
+
# Prints a character on the monitor.
|
559
|
+
def print_char(posX, posY, ch)
|
560
|
+
$print_count += 1
|
561
|
+
# Compute the length of a line.
|
562
|
+
width = $termEMU.cols
|
563
|
+
# Compute the start address.
|
564
|
+
addr = V_ADDR + posY*CH_HEIGHT*width + posX*CH_WIDTH
|
565
|
+
# Draw each line.
|
566
|
+
MEM.synchronize do
|
567
|
+
CH_HEIGHT.times do |y|
|
568
|
+
CH_WIDTH.times do |x|
|
569
|
+
# Draw each pixel on the line.
|
570
|
+
MEM[addr] = (Font8x8_basic[ch&127][y] & (1 << x)) != 0 ? "#".ord : " ".ord
|
571
|
+
addr += 1
|
572
|
+
end
|
573
|
+
# Next line.
|
574
|
+
addr += width - CH_WIDTH
|
575
|
+
end
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
# The shell process.
|
580
|
+
def shell
|
581
|
+
posX = posY = 0 # Position of the cursor (in charcters).
|
582
|
+
loop do
|
583
|
+
# Wait for being waked up.
|
584
|
+
sleep
|
585
|
+
# Waked up, get the key.
|
586
|
+
ch = nil
|
587
|
+
MEM.synchronize do
|
588
|
+
ch = MEM[K_ADDR]
|
589
|
+
end
|
590
|
+
# Process it.
|
591
|
+
case ch
|
592
|
+
when 10 # Enter
|
593
|
+
print_char(posX,posY," ".ord)
|
594
|
+
posY += 1
|
595
|
+
posX = 0
|
596
|
+
when 27 # Escape
|
597
|
+
# close_screen
|
598
|
+
$termEMU.terminate
|
599
|
+
puts "The end: $print_count=#{$print_count}"
|
600
|
+
exit
|
601
|
+
when 127 # Backspace
|
602
|
+
print_char(posX,posY," ".ord)
|
603
|
+
posX -= 1
|
604
|
+
print_char(posX,posY," ".ord)
|
605
|
+
else
|
606
|
+
print_char(posX,posY,ch)
|
607
|
+
posX += 1
|
608
|
+
end
|
609
|
+
# Print the cursor
|
610
|
+
print_char(posX,posY,"_".ord)
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "rubyHDL.rb"
|
2
|
+
|
3
|
+
# Ruby program that simulate a memory: not real software!
|
4
|
+
MEM = [ 0 ] * 256
|
5
|
+
def mem
|
6
|
+
addr = RubyHDL.addr
|
7
|
+
rwb = RubyHDL.rwb
|
8
|
+
din = RubyHDL.din
|
9
|
+
|
10
|
+
if rwb == 1 then
|
11
|
+
dout = MEM[addr & 255]
|
12
|
+
# puts "Reading memory at addr=#{addr} dout=#{dout}"
|
13
|
+
RubyHDL.dout = dout
|
14
|
+
else
|
15
|
+
# puts "Writing memory at addr=#{addr} din=#{din}"
|
16
|
+
MEM[addr & 255] = din
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
# Ruby program that increments the contents of a memory.
|
24
|
+
|
25
|
+
|
26
|
+
# Access the memory.
|
27
|
+
def inc_mem
|
28
|
+
index = RubyHDL.index
|
29
|
+
val = MEM[index]
|
30
|
+
puts "Increasing #{val} at index #{index}..."
|
31
|
+
MEM[index] = val + 1
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rubyHDL.rb"
|
2
|
+
|
3
|
+
# Ruby program that logs some date from an input port.
|
4
|
+
# The log resuts are samed on file: sw_log.log
|
5
|
+
|
6
|
+
$logout = nil
|
7
|
+
$logger = nil
|
8
|
+
|
9
|
+
# Intialize the logging.
|
10
|
+
def boot
|
11
|
+
# Create the log file.
|
12
|
+
$logout = File.new("sw_log.log","w")
|
13
|
+
# Create the logging function.
|
14
|
+
$logger = Thread.new do
|
15
|
+
loop do
|
16
|
+
# Enter a waiting state.
|
17
|
+
RubyHDL.ack = 0
|
18
|
+
sleep
|
19
|
+
# Get the value.
|
20
|
+
val = RubyHDL.din
|
21
|
+
# Log it.
|
22
|
+
$logout.puts("At #{Time.now}, got #{val}")
|
23
|
+
# Tell the value has been read.
|
24
|
+
RubyHDL.ack = 1
|
25
|
+
sleep
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Wakes the logging thread.
|
31
|
+
def log
|
32
|
+
$logger.run
|
33
|
+
end
|