Add example project, devcontainer config and debugger config
This commit is contained in:
parent
5ffbe818b6
commit
0a5cf0d943
21
.devcontainer/devcontainer.json
Normal file
21
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "ZX Spectrum dev tools",
|
||||||
|
"image": "boarstone.mcphail.uk/mcphail/speccydev",
|
||||||
|
"remoteUser": "ubuntu",
|
||||||
|
"runArgs": [
|
||||||
|
"--network=host"
|
||||||
|
],
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"maziac.dezog",
|
||||||
|
"maziac.asm-code-lens",
|
||||||
|
"maziac.z80-instruction-set",
|
||||||
|
"maziac.hex-hover-converter",
|
||||||
|
"maziac.sna-fileviewer",
|
||||||
|
"maziac.nex-fileviewer",
|
||||||
|
"ms-vscode.makefile-tools"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
110
.vscode/launch.json
vendored
Normal file
110
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "dezog",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Simulator - ZX81 56k RAM",
|
||||||
|
"remoteType": "zsim",
|
||||||
|
"zsim": {
|
||||||
|
"visualMemory": true,
|
||||||
|
"preset": "zx81",
|
||||||
|
"memoryModel": "ZX81-56K"
|
||||||
|
},
|
||||||
|
"sjasmplus": [
|
||||||
|
{
|
||||||
|
"path": "myprog.sld"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commandsAfterLaunch": [],
|
||||||
|
"history": {
|
||||||
|
"reverseDebugInstructionCount": 1000000,
|
||||||
|
"spotCount": 10,
|
||||||
|
"codeCoverageEnabled": true
|
||||||
|
},
|
||||||
|
"startAutomatically": false,
|
||||||
|
"rootFolder": "${workspaceFolder}",
|
||||||
|
"load": "myprog.p"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "dezog",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Simulator - ZX128K Spectrum",
|
||||||
|
"remoteType": "zsim",
|
||||||
|
"zsim": {
|
||||||
|
"visualMemory": true,
|
||||||
|
"preset": "spectrum",
|
||||||
|
"memoryModel": "ZX128K"
|
||||||
|
},
|
||||||
|
"sjasmplus": [
|
||||||
|
{
|
||||||
|
"path": "myprog.sld"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commandsAfterLaunch": [],
|
||||||
|
"history": {
|
||||||
|
"reverseDebugInstructionCount": 1000000,
|
||||||
|
"spotCount": 10,
|
||||||
|
"codeCoverageEnabled": true
|
||||||
|
},
|
||||||
|
"startAutomatically": false,
|
||||||
|
"rootFolder": "${workspaceFolder}",
|
||||||
|
"load": "myprog.sna",
|
||||||
|
"topOfStack": "0x5d58"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "dezog",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "CSpect",
|
||||||
|
"remoteType": "cspect",
|
||||||
|
"sjasmplus": [
|
||||||
|
{
|
||||||
|
"path": "myprog.sld"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commandsAfterLaunch": [],
|
||||||
|
"history": {
|
||||||
|
"reverseDebugInstructionCount": 1000000,
|
||||||
|
"spotCount": 10,
|
||||||
|
"codeCoverageEnabled": false
|
||||||
|
},
|
||||||
|
"startAutomatically": false,
|
||||||
|
"rootFolder": "${workspaceFolder}",
|
||||||
|
"load": "myprog.sna",
|
||||||
|
"topOfStack": "0x5d58",
|
||||||
|
"cspect": {
|
||||||
|
"hostname": "host.docker.internal"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"cspect": {
|
||||||
|
"hostname": "localhost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "dezog",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Simulator - ZX48K Spectrum",
|
||||||
|
"remoteType": "zsim",
|
||||||
|
"zsim": {
|
||||||
|
"visualMemory": true,
|
||||||
|
"preset": "spectrum",
|
||||||
|
"memoryModel": "ZX48K"
|
||||||
|
},
|
||||||
|
"sjasmplus": [
|
||||||
|
{
|
||||||
|
"path": "myprog.sld"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commandsAfterLaunch": [],
|
||||||
|
"history": {
|
||||||
|
"reverseDebugInstructionCount": 1000000,
|
||||||
|
"spotCount": 10,
|
||||||
|
"codeCoverageEnabled": true
|
||||||
|
},
|
||||||
|
"startAutomatically": false,
|
||||||
|
"rootFolder": "${workspaceFolder}",
|
||||||
|
"load": "myprog.sna",
|
||||||
|
"topOfStack": "0x5d58"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
10
Makefile
Normal file
10
Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
myprog.sna myprog.tap myprog.sld: main.asm loader.asm print.asm
|
||||||
|
sjasmplus --sld=myprog.sld --fullpath main.asm
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.tap
|
||||||
|
rm -f *.sna
|
||||||
|
rm -f *.sld
|
||||||
|
rm -rf .tmp/
|
||||||
|
|
||||||
|
.PHONY: clean
|
@ -1 +1,9 @@
|
|||||||
Development tools for the ZX Spectrum
|
Development tools for the ZX Spectrum
|
||||||
|
|
||||||
|
The Dockerfile is the basis of the devcontainer.
|
||||||
|
|
||||||
|
The devcontainer contains various assemblers etc.
|
||||||
|
|
||||||
|
Build the example project by running `make` from the terminal or the VSCode extension.
|
||||||
|
|
||||||
|
Debug in the build in simulator or in CSpect externally (example CSpect invocation on Windows would be `CSpect.exe -w2 -debug -remote`).
|
||||||
|
25
loader.asm
Normal file
25
loader.asm
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
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
|
22
main.asm
Normal file
22
main.asm
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
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
Normal file
180
print.asm
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
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
|
Loading…
x
Reference in New Issue
Block a user