Ruby binding for the Z80 library.
First, make sure that you have the Z80 library installed on your system.
Then add the z80 gem to the Gemfile of your project and run bundle:
gem 'z80'
Or install the gem directly:
gem install z80
Configure the environment variables C_INCLUDE_PATH and LIBRARY_PATH by adding the installation prefix of the library:
export C_INCLUDE_PATH="$C_INCLUDE_PATH:$(brew --prefix)/include" export LIBRARY_PATH="$LIBRARY_PATH:$(brew --prefix)/lib"
Tell gem the installation prefix of the library:
gem install z80 -- --with-Z80-dir=$(brew --prefix)This small script demonstrates how to run the CP/M versions of zexall and zexdoc with a few lines of code:
require 'z80' memory = quit = nil cpu = Z80.new cpu.fetch_opcode = cpu.fetch = cpu.read do |context, address| memory[address] end cpu.write do |context, address, value| memory[address] = value end cpu.hook do |context, address| case address when 0 # END cpu.terminate quit = true 0 # NOP when 5 # PRINT i = cpu.de while (c = memory[i]) != 0x24 putc(c == 0xA ? "\n" : c) if c != 0xD i = (i + 1) & 0xFFFF end 0xC9 # RET else 0 # NOP end end $stdout.sync = true if $stdout.tty? ARGV.each do |file_path| program = file_path == '-' ? $stdin.read : File.read(file_path) puts "#{file_path}:" quit = false memory = Array.new(65536, 0) memory[0x0100, program.size] = program.bytes memory[0] = memory[5] = Z80::HOOK cpu.power true cpu.pc = 0x0100 cpu.run(Z80::MAXIMUM_CYCLES) until quit puts break if file_path == '-' end
Want to try it? Use this:
curl ftp://ftp.ping.de/pub/misc/emulators/yaze-1.14.tar.gz | tar -xOzf- yaze-1.14/test/zexall.com | ruby -e'eval `curl https://zxe.io/software/Z80-Ruby/scripts/run-yaze-zex.rb`' -
This runs any tape from Patrik Rak's Zilog Z80 CPU Test Suite (except z80ccfscr.tap):
require 'z80' module Opcode RET = 0xC9 NOP = 0x00 CALL = 0xCD end quit = cursor_x = tab = memory = nil cpu = Z80.new cpu.fetch_opcode = cpu.fetch = cpu.read do |context, address| memory[address] end cpu.write do |context, address, value| memory[address] = value if address > 0x3FFF end cpu.in do |context, port| port.odd? ? 255 : 191 end cpu.hook do |context, address| case address when 0x0010 # PRINT if tab == 0 case (c = cpu.a) when 0x0D # CR putc "\n" cursor_x = 0 when 0x17 # TAB tab = 2 when 0x7F # © printf "©" cursor_x += 1 else if c >= 32 && c < 127 putc c cursor_x += 1 end end elsif (tab -= 1) != 0 c = 0x1F & cpu.a x = 0x1F & cursor_x if c < x putc "\n" cursor_x = 0 else cursor_x += (c -= x) end print ' ' * c end Opcode::RET when 0x7003 # Exit cpu.terminate quit = true Opcode::NOP else Opcode::NOP end end $stdout.sync = true if $stdout.tty? ARGV.each do |file_path| program = file_path == '-' ? $stdin.read : File.read(file_path) puts "#{file_path}:" quit = false cursor_x = tab = 0 memory = Array.new(65536, 0) memory[0x8000, program.size - 91] = program.bytes[91..-1] memory[0x0010] = Z80::HOOK # THE 'PRINT A CHARACTER' RESTART memory[0x0D6B] = Opcode::RET # THE 'CLS' COMMAND ROUTINE memory[0x1601] = Opcode::RET # THE 'CHAN_OPEN' SUBROUTINE memory[0x7000] = Opcode::CALL # -. memory[0x7001] = 0x00 # |- call 8000h memory[0x7002] = 0x80 # -' memory[0x7003] = Z80::HOOK cpu.power true cpu.im = 1 cpu.i = 0x3F cpu.pc = 0x7000 cpu.run(Z80::MAXIMUM_CYCLES) until quit break if file_path == '-' end
Want to try it? Use this:
curl http://zxds.raxoft.cz/taps/misc/z80test-1.2a.zip | bsdtar -xOf- z80test-1.2a/z80full.tap | ruby -e'eval `curl https://zxe.io/software/Z80-Ruby/scripts/run-raxoft-z80test.rb`' -
Copyright © 2023-2024 Manuel Sainz de Baranda y Goñi.
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.