{"id":18419037,"url":"https://github.com/redcode/z80-ruby","last_synced_at":"2025-04-07T13:31:27.954Z","repository":{"id":163181040,"uuid":"637526679","full_name":"redcode/Z80-Ruby","owner":"redcode","description":null,"archived":false,"fork":false,"pushed_at":"2023-06-28T08:05:49.000Z","size":18,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-08-04T08:23:50.725Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://zxe.io/software/Z80","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"0bsd","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-0BSD","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-05-07T20:25:58.000Z","updated_at":"2024-01-05T04:20:26.238Z","dependencies_parsed_at":"2023-06-28T12:00:30.296Z","dependency_job_id":null,"html_url":"https://github.com/redcode/Z80-Ruby","commit_stats":null,"previous_names":[],"tags_count":5,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redcode%2FZ80-Ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redcode%2FZ80-Ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redcode%2FZ80-Ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redcode%2FZ80-Ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redcode","download_url":"https://codeload.github.com/redcode/Z80-Ruby/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247661710,"owners_count":20975106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T04:15:36.196Z","updated_at":"2025-04-07T13:31:27.577Z","avatar_url":"https://github.com/redcode.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Z80-Ruby \u003cimg src=\"https://zxe.io/software/Z80-Ruby/assets/images/Z80-Ruby.svg\" width=\"128\" align=\"right\"\u003e\n\n[![](https://zxe.io/software/Z80-Ruby/assets/images/gem-badge.svg)](https://rubygems.org/gems/z80)\n[![](https://github.com/redcode/Z80-Ruby/actions/workflows/build-and-test-extension.yml/badge.svg)](https://github.com/redcode/Z80-Ruby/actions/workflows/build-and-test-extension.yml)\n[![](https://zxe.io/software/Z80/assets/images/chat-badge.svg)](https://zxe.io/software/Z80/chat)\n\nRuby binding for the [Z80](https://github.com/redcode/Z80) library.\n\n## Installation\n\nFirst, make sure that you have the Z80 library [installed](https://github.com/redcode/Z80#installation) on your system.\n\nThen add the `z80` gem to the `Gemfile` of your project and run `bundle`:\n\n```ruby\ngem 'z80'\n```\n\nOr install the gem directly:\n\n```shell\ngem install z80\n```\n\n### Troubleshooting\n\n#### \"I installed the Z80 library through Homebrew, but `bundle` does not find it.\"\n\nConfigure the environment variables [`C_INCLUDE_PATH`](https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#index-C_005fINCLUDE_005fPATH) and [`LIBRARY_PATH`](https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#index-LIBRARY_005fPATH) by adding the installation prefix of the library:\n\n```shell\nexport C_INCLUDE_PATH=\"$C_INCLUDE_PATH:$(brew --prefix)/include\"\nexport LIBRARY_PATH=\"$LIBRARY_PATH:$(brew --prefix)/lib\"\n```\n\n#### \"I installed the Z80 library through Homebrew, but `gem` does not find it.\"\n\nTell `gem` the installation prefix of the library:\n\n```shell\ngem install z80 -- --with-Z80-dir=$(brew --prefix)\n```\n\n## Examples\n\n### Z80 Instruction Set Exerciser\n\nThis small script demonstrates how to run the [CP/M versions of `zexall` and `zexdoc`](https://github.com/redcode/Z80/wiki/Z80-Instruction-Set-Exerciser) with a few lines of code:\n\n```ruby\nrequire 'z80'\n\nmemory = quit = nil\ncpu = Z80.new\n\ncpu.fetch_opcode = cpu.fetch = cpu.read do |context, address|\n\tmemory[address]\nend\n\ncpu.write do |context, address, value|\n\tmemory[address] = value\nend\n\ncpu.hook do |context, address|\n\tcase address\n\twhen 0 # END\n\t\tcpu.terminate\n\t\tquit = true\n\t\t0 # NOP\n\twhen 5 # PRINT\n\t\ti = cpu.de\n\t\twhile (c = memory[i]) != 0x24\n\t\t\tputc(c == 0xA ? \"\\n\" : c) if c != 0xD\n\t\t\ti = (i + 1) \u0026 0xFFFF\n\t\tend\n\t\t0xC9 # RET\n\telse\n\t\t0 # NOP\n\tend\nend\n\n$stdout.sync = true if $stdout.tty?\n\nARGV.each do |file_path|\n\tprogram = file_path == '-' ? $stdin.read : File.read(file_path)\n\tputs \"#{file_path}:\"\n\tquit = false\n\tmemory = Array.new(65536, 0)\n\tmemory[0x0100, program.size] = program.bytes\n\tmemory[0] = memory[5] = Z80::HOOK\n\tcpu.power true\n\tcpu.pc = 0x0100\n\tcpu.run(Z80::MAXIMUM_CYCLES) until quit\n\tputs\n\tbreak if file_path == '-'\nend\n```\n\n\u003csup\u003e**[\u003csub\u003e\u003cimg src=\"https://zxe.io/software/Z80-Ruby/assets/images/rb.svg\" height=\"14\"\u003e\u003c/sub\u003e run-yaze-zex.rb](https://zxe.io/software/Z80-Ruby/scripts/run-yaze-zex.rb)**\u003c/sup\u003e\n\nWant to try it? Use this:\n\n```shell\ncurl 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`' -\n```\n\n### Zilog Z80 CPU Test Suite\n\nThis runs any tape from Patrik Rak's [Zilog Z80 CPU Test Suite](https://github.com/raxoft/z80test) (except `z80ccfscr.tap`):\n\n```ruby\nrequire 'z80'\n\nmodule Opcode\n\tRET  = 0xC9\n\tNOP  = 0x00\n\tCALL = 0xCD\nend\n\nquit = cursor_x = tab = memory = nil\ncpu = Z80.new\n\ncpu.fetch_opcode = cpu.fetch = cpu.read do |context, address|\n\tmemory[address]\nend\n\ncpu.write do |context, address, value|\n\tmemory[address] = value if address \u003e 0x3FFF\nend\n\ncpu.in do |context, port|\n\tport.odd? ? 255 : 191\nend\n\ncpu.hook do |context, address|\n\tcase address\n\twhen 0x0010 # PRINT\n\t\tif tab == 0\n\t\t\tcase (c = cpu.a)\n\t\t\twhen 0x0D # CR\n\t\t\t\tputc \"\\n\"\n\t\t\t\tcursor_x = 0\n\t\t\twhen 0x17 # TAB\n\t\t\t\ttab = 2\n\t\t\twhen 0x7F # ©\n\t\t\t\tprintf \"©\"\n\t\t\t\tcursor_x += 1\n\t\t\telse\n\t\t\t\tif c \u003e= 32 \u0026\u0026 c \u003c 127\n\t\t\t\t\tputc c\n\t\t\t\t\tcursor_x += 1\n\t\t\t\tend\n\t\t\tend\n\t\telsif (tab -= 1) != 0\n\t\t\tc = 0x1F \u0026 cpu.a\n\t\t\tx = 0x1F \u0026 cursor_x\n\t\t\tif c \u003c x\n\t\t\t\tputc \"\\n\"\n\t\t\t\tcursor_x = 0\n\t\t\telse\n\t\t\t\tcursor_x += (c -= x)\n\t\t\tend\n\t\t\tprint ' ' * c\n\t\tend\n\t\tOpcode::RET\n\twhen 0x7003 # Exit\n\t\tcpu.terminate\n\t\tquit = true\n\t\tOpcode::NOP\n\telse\n\t\tOpcode::NOP\n\tend\nend\n\n$stdout.sync = true if $stdout.tty?\n\nARGV.each do |file_path|\n\tprogram = file_path == '-' ? $stdin.read : File.read(file_path)\n\tputs \"#{file_path}:\"\n\tquit     = false\n\tcursor_x = tab = 0\n\tmemory   = Array.new(65536, 0)\n\tmemory[0x8000, program.size - 91] = program.bytes[91..-1]\n\tmemory[0x0010] = Z80::HOOK    # THE 'PRINT A CHARACTER' RESTART\n\tmemory[0x0D6B] = Opcode::RET  # THE 'CLS' COMMAND ROUTINE\n\tmemory[0x1601] = Opcode::RET  # THE 'CHAN_OPEN' SUBROUTINE\n\tmemory[0x7000] = Opcode::CALL # -.\n\tmemory[0x7001] = 0x00         #  |- call 8000h\n\tmemory[0x7002] = 0x80         # -'\n\tmemory[0x7003] = Z80::HOOK\n\tcpu.power true\n\tcpu.im = 1\n\tcpu.i  = 0x3F\n\tcpu.pc = 0x7000\n\tcpu.run(Z80::MAXIMUM_CYCLES) until quit\n\tbreak if file_path == '-'\nend\n```\n\n\u003csup\u003e**[\u003csub\u003e\u003cimg src=\"https://zxe.io/software/Z80-Ruby/assets/images/rb.svg\" height=\"14\"\u003e\u003c/sub\u003e run-raxoft-z80test.rb](https://zxe.io/software/Z80-Ruby/scripts/run-raxoft-z80test.rb)**\u003c/sup\u003e\n\nWant to try it? Use this:\n\n```shell\ncurl 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`' -\n```\n\n## License\n\n\u003cimg src=\"https://zxe.io/software/Z80-Ruby/assets/images/0bsd.svg\" width=\"160\" align=\"right\"\u003e\n\nCopyright © 2023-2024 Manuel Sainz de Baranda y Goñi.\n\nPermission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.\n\nTHE 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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredcode%2Fz80-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredcode%2Fz80-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredcode%2Fz80-ruby/lists"}