class Z80::Program::Register
Z80
registers are populated as singleton methods. You must not create instances of this class directly.
Available registers for use within your programs:
a, b, c, d, e, h, l, ixh, ixl, iyh, iyl, af, bc, de, hl, ix, iy, sp, i, r
There are also special registers internally used by the compiler which indicate indirect memory access:
bc_, de_, hl_, iy_, ix_, sp_ # do not use them in your programs
Instead for addressing values with registers in memory use one-element array wrapped around a 16bit register:
[bc], [de], [hl], [iy - 2], [ix + 1], [sp]
Sometimes it's desired to use arguments in macros as 8bit registers and a pair of them as 16bit register. It's possible thanks to Register#split
and Register#| methods:
macro :foo do |_, rh, rl, tt| th, tl = tt.split ld rh|rl, tl inc rh|rl ld rh|rl, th end foo h, l, bc
Attributes
Public Class Methods
# File lib/z80/registers.rb, line 43 def [](index) @@registers[index] end
# File lib/z80/registers.rb, line 46 def names @@names8 + @@namesi8 + @@names_index8 + @@names_bcdep8 + @@names16 + @@names_index16 + @@names_other end
# File lib/z80/registers.rb, line 51 def initialize(name, opc) @name = name @index = 0 @opc = opc & 0xff @bit8 = name.size != 2 && opc & 7 == opc @prefix = name.index(?x) ? "\xDD" : name.index(?y) ? "\xFD" : nil end
Public Instance Methods
This method makes possible to write indexed expressions with ix/iy
registers. Example:
ld a, [ix + 7]
# File lib/z80/registers.rb, line 126 def +(other) self[other, :+] end
This method makes possible to write indexed expressions with ix/iy
registers. Example:
ld a, [ix - 7]
# File lib/z80/registers.rb, line 132 def -(other) self[other, :-] end
Method used internally by mnemonics to make pointer of a label or register. Example:
ld b, [ix + 2] ld [hl], b
# File lib/z80/registers.rb, line 99 def [](index = 0, sgn = :+) raise Syntax, "sgn must be :+ or :- only" unless sgn == :+ or sgn == :- if name.size == 2 or pointer? if index != 0 and name[0] != ?i raise Syntax, "Only ix and iy registers may be pointers with an index." elsif !index.respond_to?(:to_alloc) sindex = sgn == :+ ? index.to_i : -index.to_i raise Syntax, "Pointer index out of range." unless (-128..127).include?(sindex) end raise Syntax, "Register #{name} can not be a pointer." unless r = @@regindex[name + '_'] or (pointer? and r = self) r = r.dup if r.index == 0 r.index = sgn == :- ? -index : index elsif index.respond_to?(:to_alloc) and !r.index.respond_to?(:to_alloc) r.index = index.send(sgn, r.index) elsif index != 0 r.index = r.index.send(sgn, index) end r else raise Syntax, "Only 16-bits registers may be pointers." end end
# File lib/z80/registers.rb, line 145 def bit8?; @bit8; end
Checks if self
can adjoin with other
: self
|other
# File lib/z80/registers.rb, line 66 def match16?(other) other.is_a?(Register) and %w[bc de hl ixhixl iyhiyl].include?(name + other.name) end
# File lib/z80/registers.rb, line 146 def one_of?(ary); ary.include?(name); end
# File lib/z80/registers.rb, line 61 def pointer? name[-1] == '_' end
# File lib/z80/registers.rb, line 58 def size name.size end
Disjoins one of 16 bit registers: bc
de
hl
ix
or iy
to array of 8bit registers: [hi
, lo
].
Useful when defining macros that may use registers passed by parameters.
# File lib/z80/registers.rb, line 73 def split case name when 'bc', 'de', 'hl' [@@regindex[name[0]], @@regindex[name[1]]] when 'ix', 'iy' [@@regindex[name + 'h'], @@regindex[name + 'l']] else raise Syntax, "Only paired registers: bc, de, hl, ix, iy can be disjoined." end end
# File lib/z80/registers.rb, line 135 def to_debug if pointer? "(#{name[0,2]}" + if prefix '%.1s%02xH' end.to_s + ')' else name end end
# File lib/z80/registers.rb, line 144 def to_i; @opc; end
Adjoins two 8 bit registers to form one 16 bit register.
Useful when defining macros that may use registers passed by parameters.
# File lib/z80/registers.rb, line 87 def |(other) if match16? other @@regindex[name + other.name] || @@regindex[name[0,2]] else raise Syntax, "Only paired registers: bc, de, hl, ix, iy can be adjoined." end end