Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/royaltm/z80-rb

Z80 assembler DSL in ruby, build system, ZX Spectrum basic parser and more
https://github.com/royaltm/z80-rb

z80 z80-assembler zx-spectrum

Last synced: 4 months ago
JSON representation

Z80 assembler DSL in ruby, build system, ZX Spectrum basic parser and more

Awesome Lists containing this project

README

        

=ruby-Z80

* Documentation[https://royaltm.github.io/z80-rb/].
* Source repository[https://github.com/royaltm/z80-rb/].
* Download zip[https://github.com/royaltm/z80-rb/archive/master.zip].

====Gemfile
gem 'z80', git: 'https://github.com/royaltm/z80-rb.git'

==A Z80 assembler powered by Ruby.

Ruby[https://www.ruby-lang.org] 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[https://royaltm.github.io/spectrusty/web-zxspectrum/].

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[https://royaltm.github.io/spectrusty/web-zxspectrum/]:

LOAD "calculator"

and load the +calculator.tap+ file.

Enjoy!

{rdoc-image:examples/calculator.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/calculator.tap#fresh]

==Examples

Sources for the examples can be found in the {example directory}[https://github.com/royaltm/z80-rb/tree/master/examples].

Click on an image to run the example in a web emulator:

{rdoc-image:examples/bfont_demo-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/bfont_demo.tap#fresh]
{rdoc-image:examples/bfont_demo_hires-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=TC2048#tap=/z80-rb/examples/bfont_demo_hires.tap#fresh]
{rdoc-image:examples/dots-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/dots.tap#fresh]
{rdoc-image:examples/horse-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/horse.tap#fresh]
{rdoc-image:examples/ghosts-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k+#tap=/z80-rb/examples/ghosts.tap#fresh]
{rdoc-image:examples/labyrinth-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/labyrinth.tap#fresh]
{rdoc-image:examples/mathi_test-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/mathi_test.tap#fresh]
{rdoc-image:examples/multifill-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/multifill.tap#fresh]
{rdoc-image:examples/palette64-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=+2B#tap=/z80-rb/examples/palette64.tap#fresh]
{rdoc-image:examples/stars-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#tap=/z80-rb/examples/stars.tap#fresh]
{rdoc-image:examples/quat3d128-example.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=128k#tap=/z80-rb/examples/quat3d128.tap#fresh]

The {YARTZ demo}[https://github.com/royaltm/zxspectrum-demo-yartz] released at Speccy.pl/2019 was made entirely using this gem[https://github.com/royaltm/zxspectrum-demo-yartz], including music.

{rdoc-image:https://github.com/royaltm/zxspectrum-demo-yartz/raw/master/yartz.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=48k#ay=melodik#tap=https://yeondir.com/zxspectrum/files/demos/yartz.tap#fresh]

===Bootstrap

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

===DSL API
* Z80
* Z80::Program
* Z80::Program::Mnemonics
* Z80::Label
* Z80::TAP

====Z80 libraries
* Z80::Stdlib::Macros
* Z80::MathInt
* Z80::Utils::Shuffle
* Z80::Utils::SinCos
* Z80::Utils::Sort
* Z80::Utils::VecDeque

====ZX Spectrum libraries
* ZXLib::Basic
* ZXLib::Sys
* ZXLib::Math
* ZXLib::Gfx
* ZXLib::Gfx::Bobs
* ZXLib::Gfx::Clip
* ZXLib::Gfx::Draw
* ZXLib::Gfx::Sprite8
* ZXLib::AYSound

====ZX Spectrum utilities
* ZXUtils::BigFont
* ZXUtils::Emu
* ZXUtils::Benchmark
* ZXUtils::Gallery
* ZXUtils::Multitasking
* ZXUtils::MultitaskingIO
* ZXUtils::AYMusic
* ZXUtils::AYMusicPlayer
* ZXUtils::AYBasicPlayer
* ZXUtils::MusicBox
* ZX7

===Features:

=====+bin/zxgallery+

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::

{rdoc-image:examples/example_gallery1.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=+2B#tap=/z80-rb/examples/example_gallery.tap#fresh]
{rdoc-image:examples/example_gallery2.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=+2B#tap=/z80-rb/examples/example_gallery.tap#fresh]
{rdoc-image:examples/example_gallery3.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=+2B#tap=/z80-rb/examples/example_gallery.tap#fresh]
{rdoc-image:examples/example_gallery4.png}[https://royaltm.github.io/spectrusty/web-zxspectrum/#m=+2B#tap=/z80-rb/examples/example_gallery.tap#fresh]

See ZXUtils::Gallery for more information.

=====+bin/zxconv+

(requires RMagick http://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

link:examples/horse.jpg

zxconv -m4 -l -x examples/horse.jpg horse.png

link:examples/horse.png

ULA+ modes are also supported:

zxconv -m4 -l -hc -x examples/horse.jpg horse_hicolor.png

link:examples/horse_hicolor.png

zxconv -l -df -hp -x examples/horse.jpg horse_hires.png

link:examples/horse_hires.png

==Requirements
====Ruby 2.1.0 or later.
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

==Licensing

This package is free to use in open source under the terms of the {Parity Public License}[LICENSE_md.html].