module Z80
Include this module in your program class to turn it to a powerfull Z80
macro assembler.¶ ↑
To fully benefit from z80rb powers:
-
use labels where applicable (see
Z80::Label
), -
use namespaces where appropriate (see
Program.ns
), -
use macros whenever you can,
-
modularize all just like in ruby :-).
Constants
- DebugInfo
- Relocation
Attributes
A map of alias labels and their evaluated values.
A compiled code for the Z80
CPU as a binary string.
A raw, debug information with all selections applied.
A hash containing all instanced of imported programs.
A hash containing all evaluated label values of the compiled program.
The starting address of the compiled code.
A relocation table with all selections applied.
Public Class Methods
Method used by Program
instructions was placed here to not pollute program namespace anymore.
# File lib/z80.rb, line 139 def add_code(prg, data, type = 1, mnemo = nil, *mpar) raise TypeError unless data.is_a? String l = Label.new(pc = prg.pc, type, :code) prg.debug << DebugInfo.new(pc, data.bytesize, mnemo, mpar, prg.instance_variable_get('@context_labels').dup << l) prg.code << data l end
Method used by Program
instructions was placed here to not pollute program namespace anymore.
# File lib/z80.rb, line 147 def add_reloc(prg, label, size, offset = 0, from = nil) raise Syntax, "from argument accepted only for reloc size == 1" unless from.nil? or size == 1 alloc = label.to_label(prg).to_alloc if alloc.immediate? and (size == 2 or from==:self) prg.reloc << Relocation.new(prg.pc + offset, alloc, size, from) [alloc.to_i(0, from)].pack(size == 1 ? 'c' : 's<') else prg.reloc << Relocation.new(prg.pc + offset, alloc, size, from) "\x0"*size end end
Public Instance Methods
Returns an evaluated label's value by its name.
# File lib/z80.rb, line 40 def [](name) @labels[name.to_s] end
Creates a debugger view from an instance of a Z80::Program
. Returns an array of strings.
Example debugger output:
=============== ZXMath =============== 8023: :mul 8023: 5D ld e, l 8024: 54 ld d, h 8025: 218080 ld hl, 0000H 8028: CB3F srl a :mul.loop1 802A: 3803 jr NC, 802fH -> noadd 802C: 19 add hl, de 802D: 380B jr C, 803aH 802F: 2807 jr Z, 8038H :mul.noadd -> ok 8031: CB23 sla e 8033: CB12 rl d 8035: D22880 jp NC, 8028H -> loop1 8038: 4D ld c, l :mul.ok 8039: 44 ld b, h 803A: D0 ret NC 803B: CF rst 08H 803C: 0A . ^^^^^^^^^^^^^^^ ZXMath ^^^^^^^^^^^^^^^
# File lib/z80.rb, line 67 def debug return @debug if @debug reloc = @reloc_info imports = @imports.values aliases = @alias_info @debug = @debug_info.map do |d| case d when DebugInfo data = code[d.addr, d.size] hxd = proc {|as, g| as.map {|c| '%02X'%c.ord}.join g} label = if d.labels.last.to_name " :" + d.labels.map {|n| n.to_name || n.to_i(org).to_s(16) }.join('.') end unless d.size.zero? relocs = reloc.select {|r| Integer === r.size and (d.addr...d.addr+d.size).member? r.addr } .map {|r| r.alloc.to_s} .join(', ') unless relocs.empty? label = label.to_s + " -> #{relocs}" end end if (mnemo = d.text) if (prm = d.args) mnemo = mnemo % prm.each_slice(2).map { |o, t| case t when :word data[o, 2].unpack('S<')[0] when :index if (v = data[o, 1].unpack('c')[0]) < 0 [?-, -v] else [?+, v] end when :byte data[o, 1].unpack('C')[0] when :pcrel data[o, 1].unpack('c')[0] + d.addr + d.size + org when :alias label = label.to_s + " -> #{d.labels.last.to_aliased_name(org)}" aliases[d.labels.last] end }.flatten end "#{'%04X'%(d.addr+org)}: #{hxd[data.split(''),''].ljust 12}#{mnemo.ljust 20}#{label}" elsif data.empty? and label "#{'%04X'%(d.addr+org)}: #{' '*32}#{label}" else a = d.addr - 8 + org data.split('').each_slice(8).map do |ds| a+= 8 "#{'%04X'%a}: #{hxd[ds, ' '].ljust 24}#{ds.join.gsub(/[\x0-\x1f]/, '.').ljust 8}#{label}" end end when Integer [" #{imports[d].class} ".center(38, ?=)] + imports[d].debug + [" #{imports[d].class} ".center(38, ?^)] else raise "Invalid debug element: #{d.inspect}" end end.flatten end