Module: Ruby6502
- Defined in:
- lib/ruby6502.rb,
lib/ruby6502/version.rb,
ext/ruby6502/ruby6502.c
Constant Summary collapse
- INSTRUCTION_HOOKS =
[]
- READ_WRITE_HOOKS =
{}
- VERSION =
"0.1.0"
Class Method Summary collapse
- .a_register ⇒ Object
- .clear_instruction_hooks ⇒ Object
- .configure_rng(location) ⇒ Object
- .deregister_read_write_hook(location, read_or_write) ⇒ Object
- .exec(tickCount) ⇒ Object
- .execute_instruction_hooks ⇒ Object
- .execute_read_write_hook(location, read_or_write) ⇒ Object
- .instruction_count ⇒ Object
- .instruction_hooks? ⇒ Boolean
- .interrupt_request ⇒ Object
- .load(bytearray, location: 0) ⇒ Object
- .load_byte(location, r_value) ⇒ Object
- .memory_size ⇒ Object
- .non_maskable_interrupt ⇒ Object
- .program_counter ⇒ Object
- .read(location:, bytes:) ⇒ Object
- .read_byte(location) ⇒ Object
- .read_write_hooks? ⇒ Boolean
- .register_instruction_hook(&hook) ⇒ Object
- .register_read_write_hook(location, read_or_write, &hook) ⇒ Object
- .reset ⇒ Object
- .set_instruction_hooks ⇒ Object
- .set_read_write_hooks ⇒ Object
- .stack_pointer ⇒ Object
- .status_flags ⇒ Object
- .step ⇒ Object
- .step_times(stepCount) ⇒ Object
- .tick_count ⇒ Object
- .unset_instruction_hooks ⇒ Object
- .unset_read_write_hooks ⇒ Object
- .x_register ⇒ Object
- .y_register ⇒ Object
Class Method Details
.a_register ⇒ Object
26 27 28 29 |
# File 'ext/ruby6502/ruby6502.c', line 26 static VALUE a_register(VALUE self) { return UINT2NUM(getA()); } |
.clear_instruction_hooks ⇒ Object
53 54 55 56 |
# File 'lib/ruby6502.rb', line 53 def clear_instruction_hooks unset_instruction_hooks INSTRUCTION_HOOKS.clear end |
.configure_rng(location) ⇒ Object
198 199 200 201 202 203 204 205 206 |
# File 'ext/ruby6502/ruby6502.c', line 198 static VALUE configure_rng(VALUE self, VALUE location) { uint16_t address; address = (uint16_t) NUM2UINT(location); if ( address > 0 && address < MEMSIZE ) { rng_hook_address = address; } } |
.deregister_read_write_hook(location, read_or_write) ⇒ Object
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/ruby6502.rb', line 74 def deregister_read_write_hook(location, read_or_write) if read_or_write == :read_write READ_WRITE_HOOKS.delete([location, :read]) READ_WRITE_HOOKS.delete([location, :write]) else READ_WRITE_HOOKS.delete([location, read_or_write]) end unset_read_write_hooks if READ_WRITE_HOOKS.empty? end |
.exec(tickCount) ⇒ Object
90 91 92 93 94 |
# File 'ext/ruby6502/ruby6502.c', line 90 static VALUE exec(VALUE self, VALUE tickCount) { exec6502((uint32_t) NUM2ULONG(tickCount)); return instruction_count(self); } |
.execute_instruction_hooks ⇒ Object
88 89 90 |
# File 'lib/ruby6502.rb', line 88 def execute_instruction_hooks INSTRUCTION_HOOKS.each(&:call) end |
.execute_read_write_hook(location, read_or_write) ⇒ Object
92 93 94 |
# File 'lib/ruby6502.rb', line 92 def execute_read_write_hook(location, read_or_write) READ_WRITE_HOOKS[[location, read_or_write]]&.call(read_or_write) end |
.instruction_count ⇒ Object
46 47 48 49 |
# File 'ext/ruby6502/ruby6502.c', line 46 static VALUE instruction_count(VALUE self) { return ULONG2NUM(getInstructions()); } |
.instruction_hooks? ⇒ Boolean
168 169 170 171 172 173 174 175 |
# File 'ext/ruby6502/ruby6502.c', line 168 static VALUE get_has_instruction_hooks(VALUE self) { if ( has_instruction_hooks ) { return Qtrue; } else { return Qfalse; } } |
.interrupt_request ⇒ Object
62 63 64 65 66 |
# File 'ext/ruby6502/ruby6502.c', line 62 static VALUE interrupt_request(VALUE self) { irq6502(); return Qtrue; } |
.load(bytearray, location: 0) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/ruby6502.rb', line 10 def load(bytearray, location: 0) byte_size = bytearray.size location = location.to_i if location < 0 raise "Cannot load to a negative memory location" end if memory_size < location + byte_size raise "Loading #{byte_size} bytes to #{format("%04x", location)} would overflow memory" end bytearray.each do |byte| byte_to_load = byte.to_i & 0xff load_byte(location, byte_to_load) location += 1 end end |
.load_byte(location, r_value) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'ext/ruby6502/ruby6502.c', line 143 static VALUE load_byte(VALUE self, VALUE location, VALUE r_value) { uint16_t address; uint8_t value; address = (uint16_t) NUM2UINT(location); value = (uint8_t) NUM2UINT(r_value); write_address(address, value); return location; } |
.memory_size ⇒ Object
96 97 98 99 |
# File 'ext/ruby6502/ruby6502.c', line 96 static VALUE memory_size(VALUE self) { return UINT2NUM(MEMSIZE); } |
.non_maskable_interrupt ⇒ Object
68 69 70 71 72 |
# File 'ext/ruby6502/ruby6502.c', line 68 static VALUE non_maskable_interrupt(VALUE self) { nmi6502(); return Qtrue; } |
.program_counter ⇒ Object
16 17 18 19 |
# File 'ext/ruby6502/ruby6502.c', line 16 static VALUE program_counter(VALUE self) { return UINT2NUM(getPC()); } |
.read(location:, bytes:) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/ruby6502.rb', line 29 def read(location:, bytes:) location = location.to_i bytes = bytes.to_i unless location >= 0 && location < memory_size raise "#{location} is outside memory bounds" end unless bytes >= 0 raise "Must read a positive number of bytes" end raise "#{format("%04x", location + bytes)} is outside bounds" if location + bytes > memory_size bytes.times.map do |byte| read_byte(location + byte) end end |
.read_byte(location) ⇒ Object
118 119 120 121 122 123 124 125 |
# File 'ext/ruby6502/ruby6502.c', line 118 static VALUE read_byte(VALUE self, VALUE location) { uint16_t address; address = (uint16_t) NUM2UINT(location); return UINT2NUM(read_address(address)); } |
.read_write_hooks? ⇒ Boolean
189 190 191 192 193 194 195 196 |
# File 'ext/ruby6502/ruby6502.c', line 189 static VALUE get_has_read_write_hooks(VALUE self) { if ( has_read_write_hooks ) { return Qtrue; } else { return Qfalse; } } |
.register_instruction_hook(&hook) ⇒ Object
48 49 50 51 |
# File 'lib/ruby6502.rb', line 48 def register_instruction_hook(&hook) set_instruction_hooks unless instruction_hooks? INSTRUCTION_HOOKS << hook end |
.register_read_write_hook(location, read_or_write, &hook) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/ruby6502.rb', line 58 def register_read_write_hook(location, read_or_write, &hook) read_or_write = read_or_write.to_sym unless [:read, :write, :read_write].include?(read_or_write) raise "#{read_or_write} must be one of :read, :write, :read_write" end set_read_write_hooks unless read_write_hooks? if read_or_write == :read_write READ_WRITE_HOOKS[[location, :read]] = hook READ_WRITE_HOOKS[[location, :write]] = hook else READ_WRITE_HOOKS[[location, read_or_write]] = hook end end |
.reset ⇒ Object
56 57 58 59 60 |
# File 'ext/ruby6502/ruby6502.c', line 56 static VALUE reset(VALUE self) { reset6502(); return Qtrue; } |
.set_instruction_hooks ⇒ Object
156 157 158 159 160 |
# File 'ext/ruby6502/ruby6502.c', line 156 static VALUE set_instruction_hooks(VALUE self) { has_instruction_hooks = 1; return Qtrue; } |
.set_read_write_hooks ⇒ Object
177 178 179 180 181 |
# File 'ext/ruby6502/ruby6502.c', line 177 static VALUE set_read_write_hooks(VALUE self) { has_read_write_hooks = 1; return Qtrue; } |
.stack_pointer ⇒ Object
21 22 23 24 |
# File 'ext/ruby6502/ruby6502.c', line 21 static VALUE stack_pointer(VALUE self) { return UINT2NUM(getSP()); } |
.status_flags ⇒ Object
41 42 43 44 |
# File 'ext/ruby6502/ruby6502.c', line 41 static VALUE status_flags(VALUE self) { return UINT2NUM(getStatus()); } |
.step ⇒ Object
74 75 76 77 78 |
# File 'ext/ruby6502/ruby6502.c', line 74 static VALUE step(VALUE self) { step6502(); return instruction_count(self); } |
.step_times(stepCount) ⇒ Object
80 81 82 83 84 85 86 87 88 |
# File 'ext/ruby6502/ruby6502.c', line 80 static VALUE step_times(VALUE self, VALUE stepCount) { int steps = NUM2INT(stepCount); for(int i = 0; i < steps; ++i) { step6502(); } return instruction_count(self); } |
.tick_count ⇒ Object
51 52 53 54 |
# File 'ext/ruby6502/ruby6502.c', line 51 static VALUE tick_count(VALUE self) { return ULL2NUM(getTicks()); } |
.unset_instruction_hooks ⇒ Object
162 163 164 165 166 |
# File 'ext/ruby6502/ruby6502.c', line 162 static VALUE unset_instruction_hooks(VALUE self) { has_instruction_hooks = 0; return Qtrue; } |
.unset_read_write_hooks ⇒ Object
183 184 185 186 187 |
# File 'ext/ruby6502/ruby6502.c', line 183 static VALUE unset_read_write_hooks(VALUE self) { has_read_write_hooks = 0; return Qtrue; } |
.x_register ⇒ Object
31 32 33 34 |
# File 'ext/ruby6502/ruby6502.c', line 31 static VALUE x_register(VALUE self) { return UINT2NUM(getX()); } |
.y_register ⇒ Object
36 37 38 39 |
# File 'ext/ruby6502/ruby6502.c', line 36 static VALUE y_register(VALUE self) { return UINT2NUM(getY()); } |