Skip to content

Commit ce0c521

Browse files
Make F64 fonts and unused addon source visible
FossilOrigin-Name: d7a99d6f1d39c6f5a5d748673347f54cd3713894f501fc225ab83c4b4e14550d
1 parent c14d292 commit ce0c521

File tree

9 files changed

+327
-20
lines changed

9 files changed

+327
-20
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*.bin binary
22
*.dsk binary
33
*.exe binary
4+
*.f64 binary
45
*.fs linguist-language=Forth
56
*.fzx binary
67
*.mgt binary

.gitignore

+10-17
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
# Ignore ZX Spectrum disk images:
2-
*.dsk
3-
*.mgt
4-
*.trd
1+
# Ignore the internal resources:
2+
_meta/
3+
000-info.txt
54

65
# Ignore ZX Spectrum emulator snapshots:
76
*.sna
87
*.szx
98
*.z80
109

11-
# Ignore the development resources:
12-
_meta/
10+
# Ignore ZX Spectrum disk images:
11+
*.dsk
12+
*.mgt
13+
*.trd
1314

1415
# Ignore the documentation:
15-
doc/*.docbook
16-
doc/*.docbook.gz
17-
doc/*.docbook.zip
16+
doc/*.dbk
17+
doc/*.dbk.gz
18+
doc/*.dbk.zip
1819
doc/*.epub
1920
doc/*.html
2021
doc/*.html.gz
@@ -24,12 +25,4 @@ doc/*.pdf
2425
doc/*.pdf.gz
2526
doc/*.pdf.zip
2627

27-
# Ignore some files which are not ready yet:
28-
bin/fonts/mini.f64
29-
bin/fonts/nbot.f64
30-
bin/fonts/omn1.f64
31-
bin/fonts/omn2.f64
32-
bin/fonts/owen.f64
33-
src/addons/64-4.z80s
34-
3528
# vim: filetype=config

README.adoc

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
= Solo Forth
22
:author: Marcos Cruz (programandala.net)
3-
:revdate: 2020-03-08
3+
:revdate: 2020-04-03
44
:toc:
55
:linkattrs:
66

77
// This file is part of Solo Forth
88
// http://programandala.net/en.program.solo_forth.html
99

10-
// Last modified: 202003081418
10+
// Last modified: 202004030130
1111

1212
// Description {{{1
1313
== Description
@@ -313,7 +313,7 @@ hard drives, flash cards, and a lot of memory.
313313
| make | | Files used by ``make`` to build the system
314314
| screenshots | | Version screenshots
315315
| src | | Sources
316-
| src | addons | Code that is loaded from disk
316+
| src | addons | Code to be loaded from disk. Not used yet.
317317
| src | doc | Files used to build the documentation
318318
| src | inc | Z80 symbols
319319
| src | lib | Library

bin/fonts/mini.f64

336 Bytes
Binary file not shown.

bin/fonts/nbot.f64

336 Bytes
Binary file not shown.

bin/fonts/omn1.f64

336 Bytes
Binary file not shown.

bin/fonts/omn2.f64

336 Bytes
Binary file not shown.

bin/fonts/owen.f64

336 Bytes
Binary file not shown.

src/addons/64-4.z80s

+313
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
; -----------------------------------------------------------------------------
2+
; 64#4 - 4x8 FONT DRIVER FOR 64 COLUMNS (c) 2007, 2011
3+
;
4+
; Original by Andrew Owen (657 bytes)
5+
; Optimized by Crisis (602 bytes)
6+
; Reimplemented by Einar Saukas (494 bytes)
7+
; -----------------------------------------------------------------------------
8+
9+
org 64874 ; any address will do but this is just before
10+
; the UDGs [CHANGE HERE TO CHOOSE ANOTHER
11+
; ADDRESS]
12+
13+
STR_NUM EQU 4 ; stream #4 [CHANGE HERE TO CHOOSE ANOTHER
14+
; STREAM NUMBER]
15+
16+
; -----------------------------------------------------------------------------
17+
; CREATE CHANNEL AND ATTACH STREAM
18+
; Based on code by Ian Beardsmore from Your Spectrum issue 7, September 1984.
19+
20+
ld hl, (0x5c53) ; store system variable PROG in HL
21+
dec hl
22+
ld bc, 5 ; allocate 5 bytes for channel below BASIC area
23+
push bc
24+
call 0x1655 ; call the MAKE-ROOM routine
25+
pop bc
26+
ld hl, CH_DATA + 4
27+
lddr ; copy CH_DATA to new channel space
28+
ld hl, (0x5c4f) ; store system variable CHANS in HL
29+
ex de, hl
30+
inc hl
31+
inc hl ; now HL = allocated address + 1
32+
sbc hl, de ; calculate offset between start of channels
33+
; area and start of the new channel space
34+
; (notice the carry flag was already cleared
35+
; from executing CALL 0x1655 earlier)
36+
ld (STR_OFF), hl ; attach stream by storing channel address
37+
; offset in streams table
38+
ret
39+
40+
STR_OFF EQU 0x5c10+((STR_NUM+3)*2) ; address of channel offset in streams table
41+
42+
CH_DATA:
43+
defw CH_ADDR ; address of the PRINT # routine
44+
defw 0x15c4 ; address of the INPUT # routine
45+
defb 'S' ; channel type 'S'
46+
47+
; -----------------------------------------------------------------------------
48+
; CHANNEL WRAPPER FOR THE 64-COLUMN DISPLAY DRIVER
49+
; Based on code by Tony Samuels from Your Spectrum issue 20, November 1985.
50+
51+
CH_ADDR:
52+
ld b, 0 ; save a few bytes later using B instead of 0
53+
ld hl, AT_FLAG ; initial address of local variables
54+
dec (hl) ; check AT_FLAG value by decrementing it
55+
jp m, CHK_AT ; expecting a regular character?
56+
jr z, GET_COL ; expecting the AT column?
57+
58+
; -----------------------------------------------------------------------------
59+
; UNCOMMENT TO ENABLE STANDARD INVERSE (use INVERSE 1 for inversed characters)
60+
;
61+
; #ifdef _STANDARD_INVERSE
62+
; dec (hl) ; check AT_FLAG value by decrementing it again
63+
; jr nz, GET_ROW ; expecting the AT row?
64+
; and a ; check INVERSE parameter
65+
; jr z, SET_INV ; specified INVERSE zero?
66+
; ld a, 0x2f ; opcode for 'CPL'
67+
;SET_INV:
68+
; ld (INV_C), a ; either 'NOP' or 'CPL'
69+
; ret
70+
; #endif _STANDARD_INVERSE
71+
; -----------------------------------------------------------------------------
72+
73+
GET_ROW:
74+
cp 24 ; specified row greater than 23?
75+
jr nc, ERROR_B ; error if so
76+
inc hl ; dirty trick to store new row into AT_ROW
77+
GET_COL:
78+
cp 64 ; specified column greater than 63?
79+
jr nc, ERROR_B ; error if so
80+
inc hl
81+
ld (hl), a ; store new column into AT_COL
82+
ret
83+
84+
ERROR_B:
85+
ld (hl), b ; reset AT_FLAG
86+
rst 8 ; error "B Integer out of range"
87+
defb 10
88+
89+
CHK_AT:
90+
cp 0x16 ; specified keyword 'AT'?
91+
92+
; -----------------------------------------------------------------------------
93+
; UNCOMMENT TO ENABLE STANDARD INVERSE (use INVERSE 1 for inversed characters)
94+
;
95+
; #ifdef _STANDARD_INVERSE
96+
; jr nz, CHK_INV ; continue otherwise
97+
; ld (hl), 3 ; change AT_FLAG to expect row value next time
98+
; ret
99+
;CHK_INV:
100+
; cp 0x14 ; specified keyword 'INVERSE'?
101+
; #endif _STANDARD_INVERSE
102+
; -----------------------------------------------------------------------------
103+
104+
jr nz, CHK_CR ; continue otherwise
105+
ld (hl), 2 ; change AT_FLAG to expect row value next time
106+
ret ; (or to expect INVERSE parameter next time)
107+
108+
CHK_CR:
109+
inc (hl) ; increment AT_FLAG to restore previous value
110+
inc hl ; now HL references AT_COL address
111+
cp 0x0d ; specified carriage return?
112+
jr z, NEXT_ROW ; change row if so
113+
114+
; -----------------------------------------------------------------------------
115+
; UNCOMMENT TO ENABLE FAST COMMA (jump directly to next column multiple of 16)
116+
;
117+
; #ifdef _FAST_COMMA
118+
; cp 0x06 ; specified comma?
119+
; jr nz, DRIVER ; continue otherwise
120+
; ld a, (hl)
121+
; or 0x0f ; change column to destination minus 1
122+
; ld (hl),a
123+
; jr END_LOOP + 1 ; increment column and row if needed
124+
; #endif _FAST_COMMA
125+
; -----------------------------------------------------------------------------
126+
127+
; -----------------------------------------------------------------------------
128+
; UNCOMMENT TO ENABLE STANDARD COMMA (print spaces until column multiple of 16)
129+
;
130+
; #ifdef _STANDARD_COMMA
131+
; cp 0x06 ; specified comma?
132+
; jr nz, DRIVER ; continue otherwise
133+
;LOOP: ld a, 32 ; print space
134+
; call DRIVER
135+
; ret c ; stop if row changed (reached column zero)
136+
; ld a, (hl)
137+
; and 0x0f
138+
; ret z ; stop if reached column 16, 32 or 48
139+
; jr LOOP ; repeat otherwise
140+
; #endif _STANDARD_COMMA
141+
; -----------------------------------------------------------------------------
142+
143+
; -----------------------------------------------------------------------------
144+
; 64-COLUMN DISPLAY DRIVER
145+
146+
DRIVER:
147+
148+
push hl ; save AT_COL address for later
149+
ld e, a ; store character value in E
150+
ld c, (hl) ; store current column in BC
151+
152+
; Check if character font must be rotated, self-modifying the code accordingly
153+
154+
xor c ; compare BIT 0 from character value and column
155+
rra
156+
ld a, 256-(END_LOOP-SKIP_RLC) ; instruction DJNZ skipping rotation
157+
jr nc, NOT_RLC ; decide based on BIT 0 comparison
158+
ld a, 256-(END_LOOP-INIT_RLC) ; instruction DJNZ using rotation
159+
NOT_RLC:
160+
ld (END_LOOP - 1), a ; modify DJNZ instruction directly
161+
162+
; Check the half screen byte to be changed, self-modifying the code accordingly
163+
164+
srl c ; check BIT 0 from current column
165+
ld a, %00001111 ; mask to change left half of the screen byte
166+
jr nc, SCR_LEFT ; decide based on odd or even column
167+
cpl ; mask to change right half of the screen byte
168+
SCR_LEFT:
169+
ld (SCR_MASK + 1), a ; modify screen mask value directly
170+
cpl
171+
ld (FONT_MASK + 1), a ; modify font mask value directly
172+
173+
; Calculate location of the first byte to be changed on screen
174+
; The row value is a 5 bits value (0-23), here represented as %000RRrrr
175+
; The column value is a 6 bits value (0-63), here represented as %00CCCCCc
176+
; Formula: 0x4000 + ((row & 0x18) << 8) + ((row & 0x07) << 5) + (col >> 1)
177+
178+
inc hl ; now HL references AT_ROW address
179+
ld a, (hl) ; now A = %000RRrrr
180+
call 0x0e9e ; now HL = %010RR000rrr00000
181+
add hl, bc ; now HL = %010RR000rrrCCCCC
182+
ex de, hl ; now DE = %010RR000rrrCCCCC
183+
184+
; Calculate location of the character font data in FONT_ADDR
185+
; Formula: FONT_ADDR + 7 * INT ((char-32)/2) - 1
186+
187+
ld h, b ; now HL = char
188+
srl l ; now HL = INT (char/2)
189+
ld c, l ; now BC = INT (char/2)
190+
add hl, hl ; now HL = 2 * INT (char/2)
191+
add hl, hl ; now HL = 4 * INT (char/2)
192+
add hl, hl ; now HL = 8 * INT (char/2)
193+
sbc hl, bc ; now HL = 7 * INT (char/2)
194+
ld bc, FONT_ADDR - 0x71
195+
add hl, bc ; now HL = FONT_ADDR + 7 * INT (char/2) - 0x71
196+
197+
; Main loop to copy 8 font bytes into screen (1 blank + 7 from font data)
198+
199+
xor a ; first font byte is always blank
200+
ld b, 8 ; execute loop 8 times
201+
INIT_RLC:
202+
rlca ; switch position between bits 0-3 and bits 4-7
203+
rlca
204+
rlca
205+
rlca
206+
SKIP_RLC:
207+
208+
; -----------------------------------------------------------------------------
209+
; UNCOMMENT TO ENABLE STANDARD INVERSE
210+
;
211+
; #ifdef _STANDARD_INVERSE
212+
;INV_C: nop ; either 'NOP' or 'CPL'
213+
; #endif _STANDARD_INVERSE
214+
; -----------------------------------------------------------------------------
215+
216+
FONT_MASK:
217+
and %11110000 ; mask half of the font byte
218+
ld c, a ; store half of the font byte in C
219+
ld a, (de) ; get screen byte
220+
SCR_MASK:
221+
and %00001111 ; mask half of the screen byte
222+
or c ; combine half screen and half font
223+
ld (de), a ; write result back to screen
224+
inc d ; next screen location
225+
inc hl ; next font data location
226+
ld a, (hl) ; store next font byte in A
227+
djnz INIT_RLC ; repeat loop 8 times
228+
END_LOOP:
229+
230+
pop hl ; restore AT_COL address
231+
inc (hl) ; next column
232+
bit 6, (hl) ; column lower than 64?
233+
ret z ; return if so
234+
NEXT_ROW:
235+
ld (hl), b ; reset AT_COL
236+
inc hl ; store AT_ROW address in HL
237+
inc (hl) ; next row
238+
ld a, (hl)
239+
cp 24 ; row lower than 23?
240+
ret c ; return if so
241+
ld (hl), b ; reset AT_ROW
242+
ret ; done!
243+
244+
; -----------------------------------------------------------------------------
245+
; LOCAL VARIABLES
246+
247+
AT_FLAG:
248+
defb 0 ; flag to control processing keyword 'AT'
249+
; value 2 if received 'AT', expecting row
250+
; value 1 if received row, expecting column
251+
; value 0 if expecting regular character
252+
AT_COL:
253+
defb 0 ; current column position (0-31)
254+
AT_ROW:
255+
defb 0 ; current row position (0-23)
256+
257+
; -----------------------------------------------------------------------------
258+
; HALF WIDTH 4x8 FONT designed by Andrew Owen
259+
; Top row is always zero and not stored (96 chars x 7 / 2 = 336 bytes)
260+
261+
FONT_ADDR:
262+
defb 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x00 ; !
263+
defb 0x52, 0x57, 0x02, 0x02, 0x07, 0x02, 0x00 ;"#
264+
defb 0x25, 0x71, 0x62, 0x32, 0x74, 0x25, 0x00 ;$%
265+
defb 0x22, 0x42, 0x20, 0x40, 0x50, 0x30, 0x00 ;&'
266+
defb 0x14, 0x22, 0x41, 0x41, 0x41, 0x22, 0x14 ;()
267+
defb 0x20, 0x70, 0x22, 0x57, 0x02, 0x00, 0x00 ;*+
268+
defb 0x00, 0x00, 0x00, 0x07, 0x00, 0x20, 0x20 ;,-
269+
defb 0x01, 0x01, 0x02, 0x02, 0x04, 0x24, 0x00 ;./
270+
defb 0x22, 0x56, 0x52, 0x52, 0x52, 0x27, 0x00 ;01
271+
defb 0x27, 0x51, 0x12, 0x21, 0x45, 0x72, 0x00 ;23
272+
defb 0x57, 0x54, 0x56, 0x71, 0x15, 0x12, 0x00 ;45
273+
defb 0x17, 0x21, 0x61, 0x52, 0x52, 0x22, 0x00 ;67
274+
defb 0x22, 0x55, 0x25, 0x53, 0x52, 0x24, 0x00 ;89
275+
defb 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x02 ;:;
276+
defb 0x00, 0x10, 0x27, 0x40, 0x27, 0x10, 0x00 ;<=
277+
defb 0x02, 0x45, 0x21, 0x12, 0x20, 0x42, 0x00 ;>?
278+
defb 0x23, 0x55, 0x75, 0x77, 0x45, 0x35, 0x00 ;@A
279+
defb 0x63, 0x54, 0x64, 0x54, 0x54, 0x63, 0x00 ;BC
280+
defb 0x67, 0x54, 0x56, 0x54, 0x54, 0x67, 0x00 ;DE
281+
defb 0x73, 0x44, 0x64, 0x45, 0x45, 0x43, 0x00 ;FG
282+
defb 0x57, 0x52, 0x72, 0x52, 0x52, 0x57, 0x00 ;HI
283+
defb 0x35, 0x15, 0x16, 0x55, 0x55, 0x25, 0x00 ;JK
284+
defb 0x45, 0x47, 0x45, 0x45, 0x45, 0x75, 0x00 ;LM
285+
defb 0x62, 0x55, 0x55, 0x55, 0x55, 0x52, 0x00 ;NO
286+
defb 0x62, 0x55, 0x55, 0x65, 0x45, 0x43, 0x00 ;PQ
287+
defb 0x63, 0x54, 0x52, 0x61, 0x55, 0x52, 0x00 ;RS
288+
defb 0x75, 0x25, 0x25, 0x25, 0x25, 0x22, 0x00 ;TU
289+
defb 0x55, 0x55, 0x55, 0x55, 0x27, 0x25, 0x00 ;VW
290+
defb 0x55, 0x55, 0x25, 0x22, 0x52, 0x52, 0x00 ;XY
291+
defb 0x73, 0x12, 0x22, 0x22, 0x42, 0x72, 0x03 ;Z[
292+
defb 0x46, 0x42, 0x22, 0x22, 0x12, 0x12, 0x06 ;\]
293+
defb 0x20, 0x50, 0x00, 0x00, 0x00, 0x00, 0x0f ;^_
294+
defb 0x20, 0x10, 0x03, 0x05, 0x05, 0x03, 0x00 ;�a
295+
defb 0x40, 0x40, 0x63, 0x54, 0x54, 0x63, 0x00 ;bc
296+
defb 0x10, 0x10, 0x32, 0x55, 0x56, 0x33, 0x00 ;de
297+
defb 0x10, 0x20, 0x73, 0x25, 0x25, 0x43, 0x06 ;fg
298+
defb 0x42, 0x40, 0x66, 0x52, 0x52, 0x57, 0x00 ;hi
299+
defb 0x14, 0x04, 0x35, 0x16, 0x15, 0x55, 0x20 ;jk
300+
defb 0x60, 0x20, 0x25, 0x27, 0x25, 0x75, 0x00 ;lm
301+
defb 0x00, 0x00, 0x62, 0x55, 0x55, 0x52, 0x00 ;no
302+
defb 0x00, 0x00, 0x63, 0x55, 0x55, 0x63, 0x41 ;pq
303+
defb 0x00, 0x00, 0x53, 0x66, 0x43, 0x46, 0x00 ;rs
304+
defb 0x00, 0x20, 0x75, 0x25, 0x25, 0x12, 0x00 ;tu
305+
defb 0x00, 0x00, 0x55, 0x55, 0x27, 0x25, 0x00 ;vw
306+
defb 0x00, 0x00, 0x55, 0x25, 0x25, 0x53, 0x06 ;xy
307+
defb 0x01, 0x02, 0x72, 0x34, 0x62, 0x72, 0x01 ;z{
308+
defb 0x24, 0x22, 0x22, 0x21, 0x22, 0x22, 0x04 ;|}
309+
defb 0x56, 0xa9, 0x06, 0x04, 0x06, 0x09, 0x06 ;~�
310+
311+
; -----------------------------------------------------------------------------
312+
; NOTE: Other choices for 4x8 fonts designed by Einar Saukas available on tape!
313+
; -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)