Compare commits

..

12 Commits

Author SHA1 Message Date
37c56f30f7 Remove spurious nested make 2025-07-10 11:35:33 +00:00
3b8f72d53c Add skoolkit utilities 2025-07-09 21:56:44 +01:00
3a7cbdf550 Add licence info to README 2025-07-06 14:57:53 +01:00
051aab4695 Add inpaws and speed up building 2025-07-06 14:57:31 +01:00
bd1dbf9e19 Add README info on extensions 2025-06-24 20:29:09 +00:00
e2eefe89c2 Add usage gif to README 2025-06-23 22:29:19 +01:00
c068a870cf Add debug detail to README 2025-06-23 15:37:06 +00:00
765263ab4c more details in README 2025-06-23 15:33:35 +00:00
c795732223 Bah, md 2025-06-23 15:29:46 +00:00
b80c22eaff Add more usage information to README 2025-06-23 15:27:59 +00:00
7154c9bfc8 New barebones project using various tools 2025-06-23 14:34:21 +00:00
55b456ec06 Remove old project 2025-06-23 14:19:38 +00:00
12 changed files with 222 additions and 235 deletions

View File

@@ -5,10 +5,12 @@ RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
make \
python3-pip \
unzip \
&& rm -rf /var/lib/apt/lists/*
ADD https://github.com/z00m128/sjasmplus.git#v1.21.0 /sjasmplus
RUN cd /sjasmplus && make && make install
RUN cd /sjasmplus && make -j8 && make install
ADD https://boarstone.mcphail.uk/mcphail/spectrum_remload.git /ttttt
RUN cd /ttttt && make ttttt
ADD https://github.com/einar-saukas/ZX0.git /zx0
@@ -17,6 +19,10 @@ RUN cd /zx0/src/ \
&& gcc -O2 -o dzx0 dzx0.c
ADD https://www.boriel.com/files/zxb/zxbasic-1.18.1-linux64.tar.gz .
RUN tar xf zxbasic*
ADD https://github.com/Mastodon-/inpaws.git /inpaws
RUN cd /inpaws/ \
&& make -j8
RUN python3 -m pip install --break-system-packages skoolkit
FROM build AS z88dk
RUN apt-get update \
@@ -58,6 +64,7 @@ RUN cpanm -l $HOME/perl5 --no-wget local::lib Template::Plugin::YAML \
&& cd ${Z88DK_PATH} \
&& eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)" \
&& chmod 777 build.sh \
&& sed -i -e "s/make/make -j8/g" build.sh \
&& BUILD_SDCC=1 BUILD_SDCC_HTTP=1 ./build.sh \
&& make install-clean bins-clean
@@ -83,6 +90,9 @@ COPY --from=build /zxbasic/zxbasm.py /opt/zxbasic/zxbasm
COPY --from=build /zxbasic/zxbc.py /opt/zxbasic/zxbc
COPY --from=build /zxbasic/zxbpp.py /opt/zxbasic/zxbpp
COPY --from=build /zxbasic/src /opt/zxbasic/src
COPY --from=build /inpaws/inpaws /bin/inpaws
COPY --from=build /usr/local/bin/ /usr/local/bin/
COPY --from=build /usr/local/lib/python3.12/dist-packages/skoolkit/ /usr/local/lib/python3.12/dist-packages/skoolkit/
COPY --from=z88dk /opt/z88dk/bin /opt/z88dk/bin
COPY --from=z88dk /opt/z88dk/lib /opt/z88dk/lib
COPY --from=z88dk /opt/z88dk/include /opt/z88dk/include

6
.gitignore vendored
View File

@@ -1,4 +1,8 @@
.tmp/
*.tap
*.sna
*.sld
*.sld
*.tzx
*.block
*.zx0
*.bin

View File

@@ -1,14 +1,35 @@
myprog.sna myprog.tap myprog.sld: main.asm loader.asm print.asm
sjasmplus --sld=myprog.sld --fullpath main.asm
speccydev.tzx: speccydev.tap
tapeconv speccydev.tap speccydev.tzx
speccydev.tap: sjasm.tap loader.tap boriel.zx0.block
cat loader.tap sjasm.tap boriel.zx0.block > speccydev.tap
myprog.sna sjasm.tap myprog.sld: speccydev.asm dzx0_standard.asm boriel.zx0
sjasmplus --sld=myprog.sld --fullpath speccydev.asm
loader.tap: loader.bas
zmakebas -a 30 -n SpeccyDev -o loader.tap loader.bas
boriel.bin: boriel.zxb
zxbc -S 40000 -o boriel.bin boriel.zxb
boriel.zx0: boriel.bin
zx0 -f boriel.bin boriel.zx0
boriel.zx0.block: boriel.zx0
ttttt boriel.zx0 data
clean:
rm -f *.tap
rm -f *.sna
rm -f *.sld
rm -f *.block
rm -f *.tzx
rm -f *.bin
rm -f *.zx0
rm -rf .tmp/
start_new_project:
make clean
start_new_project: clean
rm -rf .git
git init -b main
git add .devcontainer/ .vscode/ .gitignore

View File

@@ -34,10 +34,82 @@ The devcontainer contains:
- zxbasm (assembler)
- zxbpp (preprocessor)
- ttttt (converts binaries into .tap blocks)
- inpaws (interactive fiction compiler/extractor for Gilsoft's PAW)
- skoolkit (tools for creating browseable disassemblies of Spectrum games)
- sna2ctl.py
- sna2skool.py
- skool2html.py
- skool2asm.py
- skool2ctl.py
- skool2bin.py
- tap2sna.py
- snapinfo.py
- trace.py
- rzxplay.py
- tapinfo.py
- rzxinfo.py
- bin2tap.py
- bin2sna.py
- snapmod.py
- sna2img.py
- git (version control)
- make (build control)
Build the example project by running `make` from the terminal or the VSCode extension.
Several useful VSCode extentsions will be installed, including a Z80 assembly language server, Z80 and C debugger, Makefile support, BASIC syntax highlighter and more.
Thanks to the many authors of these wonderful tools and extensions; to think what we could have made with these in 1985!
## Install
This devcontainer should work in Windows, Linux and MacOS. It is recommended to install:
- git, then configure user name and email address
- docker, or alternative like podman
- (Windows only, optional) Windows Subsystem for Linux, version 2
- Microsoft's vscode
- the "Dev Containers" extension (from Microsoft) within vscode
Make sure docker (or your alternative) is running before trying to use the devcontainer.
## Usage
![A terminal window running the commands outlined below](res/speccydev.gif)
Open a terminal and navigate to the directory which will contain your Spectrum projects. Run `git clone https://github.com/mcphail/speccydev.git your_project_name` and enter that directory. Start vscode by running `code .` inside the directory.
If you have installed the Dev Containers extension correctly, a popup will offer to reload the project within a devcontainer. Go ahead and allow this. The first time you use this devcontainer, it may take a few minutes to download and start. It should open more quickly on subsequent use.
Open the bottom bar in vscode to expose the terminal or select "Terminal -> New Terminal" from the menu bar. Try running some Linux commands like `ls -lh` or `date`. Build the example project by running `make` from the terminal or the VSCode extension. Experiment with editing some of the source files and running `make` again. Experiment with some of the assemblers, compilers and other tools mentioned above. The `Makefile` contains example usage of tools like sjasmplus, zmakebas, Boriel's BASIC and the FUSE utilities.
When you are ready to start your own project, run `make start_new_project` to wipe out the example code and start afresh.
## Debugging
Debug in the built in simulator or in CSpect externally (example CSpect invocation on Windows would be `CSpect.exe -w2 -debug -remote`). The simulator is set up to expect a binary called `myprog.sna` and a map file called `myprog.sld` but this can be configured in the `.vscode/launch.json` file.
Debug in the built in simulator or in CSpect externally (example CSpect invocation on Windows would be `CSpect.exe -w2 -debug -remote`).
*Note: to use CSpect debugging from a Linux host you will have to edit the file `.vscode/launch.json` to change the `"hostname"` parameter to `"localhost"`*
## Licences
pamso - copyright Julián Albo and released under the GPL
sjasmplus - copyright aprisobal and released under BSD 3-clause
z80asm - copyright Bas Wijnen and released under GPL v3 or later
z80dasm - copyright Jan Panteltje and Tomaz Solc and released under GPL v2
zmakebas - placed under Public Domain by Russell Marks
z88dk - copyright the z88dk authors and released under the Clarified Artistic License
FUSE utilities - copyright Philip Kendall and contributors and released under GPL v2
zx0 and dzx0 - copyright Einar Saukas and released under BSD 3-clause
Boriel BASIC - copyleft Jose Rodriguez-Rosa and released under AGPL v3 and portions under MIT
ttttt - placed under Public Domain by Neil McPhail
inpaws - copyright "Mastodon" and released under GPL v3
skoolkit - copyright Richard Dymond and Philip M Anderson and released under GPL v3 or later

5
boriel.zxb Normal file
View File

@@ -0,0 +1,5 @@
10 CLS
20 FOR i = 0 TO 23
30 PRINT "ZX Spectrum Rules OK!"
40 NEXT i
50 PAUSE 0

61
dzx0_standard.asm Normal file
View File

@@ -0,0 +1,61 @@
; -----------------------------------------------------------------------------
; ZX0 decoder by Einar Saukas & Urusergi
; "Standard" version (68 bytes only)
; -----------------------------------------------------------------------------
; Parameters:
; HL: source address (compressed data)
; DE: destination address (decompressing)
; -----------------------------------------------------------------------------
dzx0_standard:
ld bc, $ffff ; preserve default offset 1
push bc
inc bc
ld a, $80
dzx0s_literals:
call dzx0s_elias ; obtain length
ldir ; copy literals
add a, a ; copy from last offset or new offset?
jr c, dzx0s_new_offset
call dzx0s_elias ; obtain length
dzx0s_copy:
ex (sp), hl ; preserve source, restore offset
push hl ; preserve offset
add hl, de ; calculate destination - offset
ldir ; copy from offset
pop hl ; restore offset
ex (sp), hl ; preserve offset, restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0s_literals
dzx0s_new_offset:
pop bc ; discard last offset
ld c, $fe ; prepare negative offset
call dzx0s_elias_loop ; obtain offset MSB
inc c
ret z ; check end marker
ld b, c
ld c, (hl) ; obtain offset LSB
inc hl
rr b ; last offset bit becomes first length bit
rr c
push bc ; preserve new offset
ld bc, 1 ; obtain length
call nc, dzx0s_elias_backtrack
inc bc
jr dzx0s_copy
dzx0s_elias:
inc c ; interlaced Elias gamma coding
dzx0s_elias_loop:
add a, a
jr nz, dzx0s_elias_skip
ld a, (hl) ; load another group of 8 bits
inc hl
rla
dzx0s_elias_skip:
ret c
dzx0s_elias_backtrack:
add a, a
rl c
rl b
jr dzx0s_elias_loop
; -----------------------------------------------------------------------------

View File

@@ -1,25 +0,0 @@
MODULE basic_loader
ORG #5c00
basic_start:
db 0, 0 ; line number
dw line_length
line_start:
db #fd, '0', #0e, 0, 0 ; CLEAR
dw code_start_addr - 1
db 0, ':'
db #ef, '"' ; LOAD "
db "code"
db '"', #af, ':' ; name"CODE
db #f5, #c0 ; PRINT USR
db '0', #0e, 0, 0
dw code_run_addr
db 0, #0d
line_length EQU $ - line_start
basic_length EQU $ - basic_start
EMPTYTAP "myprog.tap"
SAVETAP "myprog.tap", BASIC, "myprog", basic_start, basic_length, 0
SAVETAP "myprog.tap", CODE, "code", code_start_addr, code_length
ENDMODULE

5
loader.bas Normal file
View File

@@ -0,0 +1,5 @@
10 REM This file was created
20 REM using zmakebas
30 CLEAR 32767
40 LOAD ""CODE
50 RANDOMIZE USR 32768

View File

@@ -1,22 +0,0 @@
code_start_addr EQU #8000
ORG code_start_addr
MODULE main
@code_run_addr:
ld a, 57
ld bc, 64
ld hl, 0
call print_string
db "Hello, world!", 0
ret
ENDMODULE
INCLUDE print.asm
code_length EQU $ - code_start_addr
DEVICE ZXSPECTRUM48
SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION
SAVESNA "myprog.sna", code_run_addr
INCLUDE loader.asm

180
print.asm
View File

@@ -1,180 +0,0 @@
ink_black EQU 0
ink_blue EQU 1
ink_red EQU 2
ink_magenta EQU 3
ink_green EQU 4
ink_cyan EQU 5
ink_yellow EQU 6
ink_white EQU 7
black EQU ink_black
blue EQU ink_blue
red EQU ink_red
magenta EQU ink_magenta
green EQU ink_green
cyan EQU ink_cyan
yellow EQU ink_yellow
white EQU ink_white
paper_black EQU 0
paper_blue EQU 8
paper_red EQU 16
paper_magenta EQU 24
paper_green EQU 32
paper_cyan EQU 40
paper_yellow EQU 48
paper_white EQU 56
bright EQU 64
flash EQU 128
attr_list_end EQU flash | bright | ink_black | paper_black
MODULE print
bm_start EQU #4000
attr_area EQU #5800
bm_len EQU 6144
attr_len EQU 768
CHARS EQU #5c36
char_posn:
dw #4000
MODULE print_string
; Set HL to be row and column and follow the call with a null-terminated string
; All registers preserved
; char_posn will have been moved to after string, but HL will still have coordinates of string start
@print_string:
call set_char_posn
ex (sp), hl
push af
loop:
ld a, (hl)
inc hl
or a
jr z, exit
call print_char
jr loop
exit:
pop af
ex (sp), hl
ret
ENDMODULE
MODULE print_char
; Prints the single character from the A register
; All registers preserved
; char_posn will point to next square
@print_char:
push hl
push de
push af
ld h, 0
ld l, a
add hl, hl
add hl, hl
add hl, hl
ld d, h
ld e, l
ld hl, (print.CHARS)
add hl, de
ld d, h
ld e, l
ld hl, (print.char_posn)
push bc
ld b, 8
loop:
ld a, (de)
ld (hl), a
inc h
inc de
djnz loop
ld hl, (print.char_posn)
inc l
jr nz, update_char_posn
ld a, #50
cp h
jr nz, next_third
ld hl, print.bm_start
jr update_char_posn
next_third:
ld a, 8
add a, h
ld h, a
update_char_posn:
ld (print.char_posn), hl
pop bc
pop af
pop de
pop hl
ret
ENDMODULE
MODULE set_char_posn
; Pass row and column, in that order, in HL
@set_char_posn:
push hl
push af
ld a, h
; check for top third
ld h, %01000000
sub 8
jr c, set_column
; check for middle third
ld h, %01001000
sub 8
jr c, set_column
; must be bottom third
ld h, %01010000
sub 8
set_column:
; restore the row offset of the third and shift it into upper 3 bits of L
add a, 8
sla a
sla a
sla a
sla a
sla a
or l
ld l, a
ld (print.char_posn), hl
pop af
pop hl
ret
ENDMODULE
MODULE set_attributes
; Row and column in HL
; db list of attributes follows call
; terminate with attr_list_end byte (bright flashing black on black)
@set_attributes:
ex de, hl
ex (sp), hl
push de
push hl
ld h, 0
ld l, d
ld d, h
add hl, hl
add hl, hl
add hl, hl
add hl, hl
add hl, hl
add hl, de
ld de, print.attr_area
add hl, de
pop de
ex de, hl
push af
loop:
ld a, (hl)
inc hl
cp attr_list_end
jr z, exit
ld (de), a
inc de
jr loop
exit:
pop af
pop de
ex (sp), hl
ex de, hl
ret
ENDMODULE
ENDMODULE

BIN
res/speccydev.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

36
speccydev.asm Normal file
View File

@@ -0,0 +1,36 @@
code_start_addr EQU #8000
org code_start_addr
; headerless load
scf
ld a, #ff
ld de, boriel_size
ld ix, compressed_boriel
call #0556
decompress:
ld hl, compressed_boriel
ld de, uncompressed_boriel
call dzx0.dzx0_standard
call uncompressed_boriel
ret
MODULE dzx0
INCLUDE "dzx0_standard.asm"
ENDMODULE
code_length EQU $ - code_start_addr
compressed_boriel:
INCBIN "boriel.zx0"
boriel_size EQU $ - compressed_boriel
uncompressed_boriel EQU 40000
DEVICE ZXSPECTRUM48
SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION
SAVESNA "myprog.sna", decompress
EMPTYTAP "sjasm.tap"
SAVETAP "sjasm.tap", CODE, "sjasm", code_start_addr, code_length