-
Source repository.
-
Download zip.
gem 'z80', git: 'https://github.com/royaltm/z80-rb.git'
Ruby is a powerful meta-language, so why not leverage its meta powers to have the ultimate macro system, compiler, and builder for the Z80 assembler?
Now, to answer the question, you’ll need:
-
a Ruby 2.1+
-
(optionally) a ZX Spectrum emulator.
then
gem install specific_install gem specific_install royaltm/z80-rb
go to Ruby’s irb
or your REP of choice and snap’&‘paste this:
require 'z80' class MyZXMath module Macros def mul8(eh, el, th, tl) # performs hl * a using (a, th, tl) # stops on CARRY out # result to (eh|el) raise ArgumentError unless th|tl != hl ns do |eoc| ld tl, l ld th, h ld hl,0 loop1 srl a jr NC, noadd add hl, th|tl jr C, eoc noadd jr Z, ok sla tl rl th jp NC, loop1 ok label unless eh == h and el == l ld el, l ld eh, h end end end end include Z80 export mul mul mul8(b, c, d, e) ret NC rst 0x08 # ERROR-1 data 1, [0x0A] # Error Report: Integer out of range end class Program include Z80 include Z80::TAP ld hl, [multiplicand] ld a, [multiplier] jp math.mul org 0x0020 multiplicand words 1 multiplier bytes 1 import MyZXMath, :math end calc = Program.new 0x8000 puts calc.debug
check the debug output:
8000: 2A0980 ld hl, (8009H) -> multiplicand 8003: 3A0B80 ld a, (800bH) -> multiplier 8006: C30C80 jp 800cH -> math.mul 8009: 00 00 .. :multiplicand 800B: 00 . :multiplier 800C: :math ============== MyZXMath ============== 800C: --- begin --- :mul 800C: 5D ld e, l 800D: 54 ld d, h 800E: 210000 ld hl, 0000H 8011: CB3F srl a :mul.loop1 8013: 3003 jr NC, 8018H -> noadd 8015: 19 add hl, de 8016: 380B jr C, 8023H -> EOC 8018: 2807 jr Z, 8021H :mul.noadd -> ok 801A: CB23 sla e 801C: CB12 rl d 801E: D21180 jp NC, 8011H -> loop1 8021: :mul.ok 8021: 4D ld c, l 8022: 44 ld b, h 8023: --- end --- :mul.EOC 8023: D0 ret NC 8024: CF rst 08H 8025: 0A . ^^^^^^^^^^^^^^ MyZXMath ^^^^^^^^^^^^^^
wait, there’s more…
require 'zxlib/basic' prog = ZXLib::Basic.parse_source <<-END 10 CLEAR #{calc.org-1} 20 LOAD ""CODE 30 INPUT "Multiplicand: ",x 40 INPUT "Multiplier: ",y 50 POKE #{calc[:multiplicand]},x-INT (x/256)*256 60 POKE #{calc[:multiplicand]+1},INT (x/256) 70 POKE #{calc[:multiplier]},y 80 PRINT "x: ", x, "y: ", y 90 PRINT USR #{calc.org} 100 GO TO 30 END puts prog
Let’s make a .tap
file now:
prog.save_tap 'calculator', line: 10 calc.save_tap 'calculator', append: true, name: 'multiply'
go to ZX Spectrum or an emulator:
LOAD "calculator"
and load the calculator.tap
file.
Enjoy!
Sources for the examples can be found in the example directory.
Click on an image to run the example in a web emulator:
The YARTZ demo released at Speccy.pl/2019 was made entirely using this gem, including music.
You may use the zxinit
tool provided by this gem to bootstrap a new program.
Provide a target file name and optionally the main class name.
$ zxinit hello_world ZXINIT: initializing program HelloWorld at ./hello_world.rb ZXINIT: ready ZXINIT: compile and run HelloWorld with: zxrun "./hello_world.rb" "hello_world.tap"
Another tool: zxrun
can be used to optionally compile ruby sources and run the emulator with the last argument provided.
$ zxrun hello_world.rb hello_world.tap 8000: :start_test 8000: D9 exx 8001: E5 push hl 8002: CD0880 call 8008H -> start 8005: E1 pop hl 8006: D9 exx 8007: C9 ret ============= HelloWorld ============= 8008: :start 8008: 3E02 ld a, 02H 800A: CD0116 call 1601H -> rom.chan_open 800D: --- begin --- 800D: 111880 ld de, 8018H -> text_data 8010: 010D00 ld bc, 000dH -> (+text_data) 8013: CD3C20 call 203cH -> rom.pr_string 8016: 180D jr 8025H -> EOC 8018: 48 65 6C 6C 6F 20 77 6F Hello wo :start.800d.text_data 8020: 72 6C 64 21 0D rld!. :start.800d.text_data 8025: --- end --- :start.800d.EOC 8025: C9 ret ^^^^^^^^^^^^^ HelloWorld ^^^^^^^^^^^^^ Program: "hello_worl" LINE 9999 (58/58) Bytes: "hello_worl" CODE 32768,38
-
Z80
-
Z80::Program
-
Z80::Program::Mnemonics
-
Z80::Label
-
Z80::TAP
-
Z80::Stdlib::Macros
-
Z80::MathInt
-
Z80::Utils::Shuffle
-
Z80::Utils::SinCos
-
Z80::Utils::Sort
-
Z80::Utils::VecDeque
-
ZXLib::Basic
-
ZXLib::Sys
-
ZXLib::Math
-
ZXLib::Gfx
-
ZXLib::Gfx::Bobs
-
ZXLib::Gfx::Clip
-
ZXLib::Gfx::Draw
-
ZXLib::Gfx::Sprite8
-
ZXLib::AYSound
-
ZXUtils::BigFont
-
ZXUtils::Emu
-
ZXUtils::Benchmark
-
ZXUtils::Gallery
-
ZXUtils::Multitasking
-
ZXUtils::MultitaskingIO
-
ZXUtils::AYMusic
-
ZXUtils::AYMusicPlayer
-
ZXUtils::AYBasicPlayer
-
ZXUtils::MusicBox
-
ZX7
ZXGALLERY 0.4: Creates a TAP file with a ZX Spectrum screen gallery. Usage: zxgallery [options] screen_files... screen_files: paths to SCR files to be appended to the tape; options: -o, --output: the target file name (the .tap extension is optional), -c, --code: the address of the code in the range: 32768..51054
- Example gallery
-
See ZXUtils::Gallery for more information.
(requires RMagick rmagick.rubyforge.org/)
ZXCONV 0.5: Converting images to ZX Spectrum is fun! Usage: zxconv source destination [options] rendering options: -m, --mode 0|1|2|3|4 color mode 0: 15 colors 1: 8 basic colors 2: 8 bright colors 3: 15 colors, bright colors have priority 4: 15 colors, basic colors only on black backgrounds -h, --hires n|c|p|i high resolution mode n: 256x192 pixels 8x8 color attributes (ZX Spectrum) c: 256x192 pixels 8x1 color attributes (ULA+) p: 512x192 pixels monochrome (ULA+) i: 256x384 pixels interlaced (ZX Spectrum 128k/ULA+) -d, --dither n|r|f[n|r|f] dithering mode phase1,phase2 n: none r: riemersma f: floyd-steinberg -c, --colors CCC.... list of allowed color indexes (0..7) -0..15, --bg N background color (0..15) -r, --ratio N/N bright/basic color level ratio -l|L, --[no-]autolevel apply auto level to source image -g|G, --[no-]autogamma apply auto gamma to source image destination format and content: -f, --format t|b|r|a zx spectrum data file format t: save as TAP; one file is created b: save as binary data; separate files for scr and bitamp r: save as ruby source a: save as assembler source -s|S, --[no-]savescr save ZX Spectrum screen data -b|B, --[no-]savebin save pixel bitmap (linear) data -a|A, --[no-]saveattr save color attributes (linear) data -i|I, --[no-]saveimg save image file (format determined by destination ext.) -x|X, --[no-]x2-pixels enlarge and normalize output image pixels (only applied for image file) default options are: -m0 -hn -dn -r4/3 -0 -ft -s -i
zxconv -m4 -l -x examples/horse.jpg horse.png
ULA+ modes are also supported:
zxconv -m4 -l -hc -x examples/horse.jpg horse_hicolor.png
zxconv -l -df -hp -x examples/horse.jpg horse_hires.png
If you want to use Bundler, then Ruby 2.3.0 will be required. The recommended Ruby version is 2.6.0.
- Author
-
Rafał Michalski
This package is free to use in open source under the terms of the Parity Public License.