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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.html +2330 -2670
  3. data/README.md +391 -101
  4. data/ext/hruby_sim/hruby_rcsim_build.c +400 -3
  5. data/ext/hruby_sim/hruby_sim.h +2 -1
  6. data/ext/hruby_sim/hruby_sim_calc.c +1 -1
  7. data/ext/hruby_sim/hruby_sim_core.c +15 -5
  8. data/ext/hruby_sim/hruby_sim_tree_calc.c +1 -1
  9. data/lib/HDLRuby/hdr_samples/c_program/echo.c +33 -0
  10. data/lib/HDLRuby/hdr_samples/ruby_program/echo.rb +9 -0
  11. data/lib/HDLRuby/hdr_samples/ruby_program/stdrw.rb +6 -0
  12. data/lib/HDLRuby/hdr_samples/ruby_program/sw_cpu_terminal.rb +614 -0
  13. data/lib/HDLRuby/hdr_samples/ruby_program/sw_inc_mem.rb +32 -0
  14. data/lib/HDLRuby/hdr_samples/ruby_program/sw_log.rb +33 -0
  15. data/lib/HDLRuby/hdr_samples/with_board.rb +63 -0
  16. data/lib/HDLRuby/hdr_samples/with_clocks.rb +42 -0
  17. data/lib/HDLRuby/hdr_samples/with_of.rb +1 -1
  18. data/lib/HDLRuby/hdr_samples/with_program_c.rb +28 -0
  19. data/lib/HDLRuby/hdr_samples/with_program_ruby.rb +28 -0
  20. data/lib/HDLRuby/hdr_samples/with_program_ruby_cpu.rb +234 -0
  21. data/lib/HDLRuby/hdr_samples/with_program_ruby_io.rb +23 -0
  22. data/lib/HDLRuby/hdr_samples/with_program_ruby_mem.rb +58 -0
  23. data/lib/HDLRuby/hdr_samples/with_program_ruby_threads.rb +56 -0
  24. data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +2 -4
  25. data/lib/HDLRuby/hdrcc.rb +60 -21
  26. data/lib/HDLRuby/hruby_error.rb +13 -0
  27. data/lib/HDLRuby/hruby_high.rb +50 -7
  28. data/lib/HDLRuby/hruby_low.rb +74 -30
  29. data/lib/HDLRuby/hruby_rcsim.rb +89 -5
  30. data/lib/HDLRuby/std/clocks.rb +118 -50
  31. data/lib/HDLRuby/std/std.rb +5 -0
  32. data/lib/HDLRuby/ui/hruby_board.rb +1079 -0
  33. data/lib/HDLRuby/version.rb +1 -1
  34. data/lib/c/Rakefile +8 -0
  35. data/lib/c/cHDL.h +12 -0
  36. data/lib/c/extconf.rb +7 -0
  37. data/lib/rubyHDL.rb +33 -0
  38. data/tuto/gui_accum.png +0 -0
  39. data/tuto/gui_board.png +0 -0
  40. data/tuto/tutorial_sw.html +2263 -1890
  41. data/tuto/tutorial_sw.md +957 -62
  42. metadata +24 -5
  43. data/README.pdf +0 -0
  44. 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