HDLRuby 3.2.0 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.html +4411 -2930
  3. data/README.md +396 -102
  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 +4163 -2081
  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