| Welcome, Guest |
You have to register before you can post on our site.
|
| Online Users |
There are currently 114 online users. » 0 Member(s) | 113 Guest(s) Google
|
| Latest Threads |
GuSprites
Forum: Help & Support
Last Post: zedex82
2026-06-19, 06:39 PM
» Replies: 2
» Views: 357
|
New video Couse / Nuevo c...
Forum: News
Last Post: Duefectu
2026-04-29, 11:02 PM
» Replies: 0
» Views: 2,702
|
location of heap manageme...
Forum: Help & Support
Last Post: boriel
2026-03-07, 12:13 AM
» Replies: 1
» Views: 745
|
non-paged supervisor code...
Forum: Help & Support
Last Post: sdo303
2026-02-20, 06:38 PM
» Replies: 8
» Views: 1,851
|
How to open fuse as an ex...
Forum: How-To & Tutorials
Last Post: Duefectu
2026-02-09, 01:52 PM
» Replies: 3
» Views: 1,745
|
Old zxbasic game errors
Forum: Help & Support
Last Post: boriel
2025-11-09, 11:52 AM
» Replies: 7
» Views: 2,541
|
Error: Undefined GLOBAL l...
Forum: Help & Support
Last Post: ardentcrest
2025-11-04, 05:46 PM
» Replies: 3
» Views: 1,397
|
A Fast(er) Plot Routine f...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-30, 03:16 PM
» Replies: 2
» Views: 1,480
|
Hall of Fame - Include fo...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-28, 03:48 PM
» Replies: 0
» Views: 820
|
[SOLVED] Array layout bug...
Forum: Bug Reports
Last Post: Zoran
2025-10-25, 05:48 PM
» Replies: 2
» Views: 1,541
|
|
|
| Error: Syntax error. Unexpected end of line [NEWLINE] |
|
Posted by: cheveron - 2014-02-20, 11:03 AM - Forum: Help & Support
- Replies (4)
|
 |
I've searched the forum for this report and I've checked the obvious stuff. My source file is plain text. I've only used accepted hex encoding. I only have one data type in a defb. The error reports line 123 but that's spurious as commenting it out changes the report to line 122 which is virtually the same. I suspect I've just hit a limitation of the inline assembler, but I'm not sure. Here's the source:
Code: ' -----------------------------------------------------------------------------
' ZXodus][Engine - Example Character Generator
' Copyright (c) 2014 Andrew Owen. All Rights Reserved.
' -----------------------------------------------------------------------------
' bank 0 = font / text
' bank 1 = gfx 1
' bank 2 = code / music
' bank 3 = gfx 2 / cards
goto start
ASM
org 80ffh
vectr:
defw intrpt
intrpt:
push af ; save registers
push bc
push de
push hl
ex af, af' ;'
exx
push af
push bc
push de
push hl
call play ; play music
pop hl
pop de
pop bc
pop af
ex af, af' ;'
exx
pop hl
pop de
pop bc
pop af
jp $0038
; ------------------------------------------------------------------------------
; PROTRACKER 3 EXTREME II (P3X) AY PLAYER
; For ZX81 (Zon-X), TC2068, and Spectrum 128.
; Copyright (c) 2004, 2007 S.V.Bulba <vorobey@mail.khstu.ru>
; http://bulba.untergrund.net (http://bulba.at.kz)
; Formatted by Gasman for Pasmo and optimized by Cheveron
; variables are 541 bytes long and follow the player
; music is in ProTracker3.6 format (minus the 100 byte header)
setup:
defb 0 ; used by ProTracker 3 Extreme II
checklp:
ld hl, setup
set 7, (hl)
bit 0, (hl)
ret z
pop hl
ld hl, delycnt
inc (hl)
ld hl, chana + chp_ntskcn
inc (hl)
mute:
xor a
ld h, a
ld l, a
ld (ayregs + ar_ampla), a
ld (ayregs + ar_amplb), hl
jp rout_a0
p3x_init:
ld hl, music - 100 ; music address
ld (modaddr + 1), hl
ld (mdaddr2 + 1), hl
push hl
ld de, 100
add hl, de
ld a, (hl)
ld (p3x_delay + 1), a
push hl
pop ix
add hl, de
ld (crpsptr), hl
ld e, (ix + 2)
add hl, de
inc hl
ld (lposptr + 1), hl
pop de
ld l, (ix + 3)
ld h, (ix + 4)
add hl, de
ld (patsptr + 1), hl
ld hl, 169
add hl, de
ld (ornptrs + 1), hl
ld hl, 105
add hl, de
ld (samptrs + 1), hl
ld hl, setup
res 7, (hl)
xor a
ld hl, vars
ld (hl), a
ld de, vars + 1
ld bc, var0end - vars - 1
ldir
inc a
ld (delycnt), a
ld hl, $f001
ld (chana + chp_ntskcn), hl
ld (chanb + chp_ntskcn), hl
ld (chanc + chp_ntskcn), hl
ld hl, emptysamorn
ld (adinpta + 1), hl
ld (chana + chp_ornptr), hl
ld (chanb + chp_ornptr), hl
ld (chanc + chp_ornptr), hl
jp rout_a0
pd_orsm:
ld (ix + 8), 0 ; pattern decoder
call setorn
ld a, (bc)
inc bc
rrca
pd_sam:
add a, a
pd_sam_:
ld e, a
ld d, 0
samptrs:
ld hl, 8481
add hl, de
ld e, (hl)
inc hl
ld d, (hl)
modaddr
ld hl, 8481
add hl, de
ld (ix + 3), l
ld (ix + 4), h
jr pd_loop
pd_vol:
rlca
rlca
rlca
rlca
ld (ix + 16), a
jr pd_lp2
pd_eoff:
ld (ix + 8), a
ld (ix - 12), a
jr pd_lp2
pd_sore:
dec a
jr nz, pd_env
ld a, (bc)
inc bc
ld (ix + 5), a
jr pd_lp2
pd_env:
call setenv
jr pd_lp2
pd_orn:
call setorn
jr pd_loop
pd_esam:
ld (ix + 8), a
ld (ix - 12), a
call nz, setenv
ld a, (bc)
inc bc
jr pd_sam_
ptdecod:
ld a, (ix + 6)
ld (prnote + 1), a
ld l, (ix - 6)
ld h, (ix - 5)
ld (prslide + 1), hl
pd_loop:
ld de, 8208
pd_lp2:
ld a, (bc)
inc bc
add a, e
jr c, pd_orsm
add a, d
jr z, pd_fin
jr c, pd_sam
add a, e
jr z, pd_rel
jr c, pd_vol
add a, e
jr z, pd_eoff
jr c, pd_sore
add a, 060h
jr c, pd_note
add a, e
jr c, pd_orn
add a, d
jr c, pd_nois
add a, e
jr c, pd_esam
add a, a
ld e, a
ld hl, spccoms + 57120
add hl, de
ld e, (hl)
inc hl
ld d, (hl)
push de
jr pd_loop
pd_nois:
ld (ns_base), a
jr pd_lp2
pd_rel:
res 0, (ix + 9)
jr pd_res
pd_note:
ld (ix + 6), a
set 0, (ix + 9)
xor a
pd_res:
ld (pdsp_ + 1), sp
ld sp, ix
ld h, a
ld l, a
push hl
push hl
push hl
push hl
push hl
push hl
pdsp_
ld sp, 12593
pd_fin:
ld a, (ix + 5)
ld (ix + 15), a
ret
c_portm:
res 2, (ix + 9)
ld a, (bc)
inc bc
inc bc
inc bc
ld (ix + 10), a
ld (ix - 7), a
ld de, nt_
ld a, (ix + 6)
ld (ix + 7), a
add a, a
ld l, a
ld h, 0
add hl, de
ld a, (hl)
inc hl
ld h, (hl)
ld l, a
push hl
prnote:
ld a, 62
ld (ix + 6), a
add a, a
ld l, a
ld h, 0
add hl, de
ld e, (hl)
inc hl
ld d, (hl)
pop hl
sbc hl, de
ld (ix + 13), l
ld (ix + 14), h
ld e, (ix - 6)
ld d, (ix - 5)
prslide:
ld de, 4369
ld (ix - 6), e
ld (ix - 5), d
ld a, (bc)
inc bc
ex af, af' ;'
ld a, (bc)
inc bc
and a
jr z, nosig
ex de, hl
nosig:
sbc hl, de
jp p, set_stp
cpl
ex af, af' ;'
neg
ex af, af' ;'
set_stp:
ld (ix + 12), a
ex af, af' ;'
ld (ix + 11), a
ld (ix - 2), 0
ret
c_gliss:
set 2, (ix + 9)
ld a, (bc)
inc bc
ld (ix + 10), a
and a
jr nz, gl36
ld a, 6 ; P3X version is always PT3.6
cp 7
sbc a, a
inc a
gl36:
ld (ix - 7), a
ld a, (bc)
inc bc
ex af, af' ;'
ld a, (bc)
inc bc
jr set_stp
c_smpos:
ld a, (bc)
inc bc
ld (ix - 11), a
ret
c_orpos:
ld a, (bc)
inc bc
ld (ix - 12), a
ret
c_vibrt:
ld a, (bc)
inc bc
ld (ix - 1), a
ld (ix - 2), a
ld a, (bc)
inc bc
ld (ix + 0), a
xor a
ld (ix - 7), a
ld (ix - 6), a
ld (ix - 5), a
ret
c_engls
ld a, (bc)
inc bc
ld (env_del + 1), a
ld (curedel), a
ld a, (bc)
inc bc
ld l, a
ld a, (bc)
inc bc
ld h, a
ld (esldadd + 1), hl
ret
c_p3x_delay:
ld a, (bc)
inc bc
ld (p3x_delay + 1), a
ld (delycnt), a ; bugfix by Lee du Caine
ret
setenv:
ld (ix + 8), e
ld (ayregs + ar_envtp), a
ld a, (bc)
inc bc
ld h, a
ld a, (bc)
inc bc
ld l, a
ld (envbase), hl
xor a
ld (ix - 12), a
ld (curedel), a
ld h, a
ld l, a
ld (curesld), hl
c_nop:
ret
setorn:
add a, a
ld e, a
ld d, 0
ld (ix - 12), d
ornptrs:
ld hl, 8481
add hl, de
ld e, (hl)
inc hl
ld d, (hl)
mdaddr2:
ld hl, 8481
add hl, de
ld (ix + 1), l
ld (ix + 2), h
ret
; all 16 addresses to protect from broken pt3 modules
spccoms:
defw c_nop
defw c_gliss
defw c_portm
defw c_smpos
defw c_orpos
defw c_vibrt
defw c_nop
defw c_nop
defw c_engls
defw c_p3x_delay
defw c_nop
defw c_nop
defw c_nop
defw c_nop
defw c_nop
defw c_nop
chregs:
xor a
ld (ampl), a
bit 0, (ix + 21)
push hl
jp z, ch_exit
ld (csp_ + 1), sp
ld l, (ix + 13)
ld h, (ix + 14)
ld sp, hl
pop de
ld h, a
ld a, (ix + 0)
ld l, a
add hl, sp
inc a
cp d
jr c, ch_orps
ld a, e
ch_orps:
ld (ix + 0), a
ld a, (ix + 18)
add a, (hl)
jp p, ch_ntp
xor a
ch_ntp:
cp 96
jr c, ch_nok
ld a, 95
ch_nok:
add a, a
ex af, af' ;'
ld l, (ix + 15)
ld h, (ix + 16)
ld sp, hl
pop de
ld h, 0
ld a, (ix + 1)
ld b, a
add a, a
add a, a
ld l, a
add hl, sp
ld sp, hl
ld a, b
inc a
cp d
jr c, ch_smps
ld a, e
ch_smps:
ld (ix + 1), a
pop bc
pop hl
ld e, (ix + 8)
ld d, (ix + 9)
add hl, de
bit 6, b
jr z, ch_noac
ld (ix + 8), l
ld (ix + 9), h
ch_noac:
ex de, hl
ex af, af' ;'
ld l, a
ld h, 0
ld sp, nt_
add hl, sp
ld sp, hl
pop hl
add hl, de
ld e, (ix + 6)
ld d, (ix + 7)
add hl, de
csp_:
ld sp, 03131h
ex (sp), hl
xor a
or (ix + 5)
jr z, ch_amp
dec (ix + 5)
jr nz, ch_amp
ld a, (ix + 22)
ld (ix + 5), a
ld l, (ix + 23)
ld h, (ix + 24)
ld a, h
add hl, de
ld (ix + 6), l
ld (ix + 7), h
bit 2, (ix + 21)
jr nz, ch_amp
ld e, (ix + 25)
ld d, (ix + 26)
and a
jr z, ch_stpp
ex de, hl
ch_stpp:
sbc hl, de
jp m, ch_amp
ld a, (ix + 19)
ld (ix + 18), a
xor a
ld (ix + 5), a
ld (ix + 6), a
ld (ix + 7), a
ch_amp:
ld a, (ix + 2)
bit 7, c
jr z, ch_noam
bit 6, c
jr z, ch_amin
cp 15
jr z, ch_noam
inc a
jr ch_svam
ch_amin:
cp 241
jr z, ch_noam
dec a
ch_svam:
ld (ix + 2), a
ch_noam:
ld l, a
ld a, b
and 15
add a, l
jp p, ch_apos
xor a
ch_apos:
cp 16
jr c, ch_vol
ld a, 15
ch_vol:
or (ix + 28)
ld l, a
ld h, 0
ld de, vt_
add hl, de
ld a, (hl)
ch_env:
bit 0, c
jr nz, ch_noen
or (ix + 20)
ch_noen:
ld (ampl), a
bit 7, b
ld a, c
jr z, no_ensl
rla
rla
sra a
sra a
sra a
add a, (ix + 4)
bit 5, b
jr z, no_enac
ld (ix + 004h), a
no_enac:
ld hl, addtoen + 1
add a, (hl)
ld (hl), a
jr ch_mix
no_ensl:
rra
add a, (ix + 3)
ld (addtons), a
bit 5, b
jr z, ch_mix
ld (ix + 3), a
ch_mix:
ld a, b
rra
and 72
ch_exit:
ld hl, ayregs + ar_mixer
or (hl)
rrca
ld (hl), a
pop hl
xor a
or (ix + 10)
ret z
dec (ix + 10)
ret nz
xor (ix + 21)
ld (ix + 21), a
rra
ld a, (ix + 11)
jr c, ch_ondl
ld a, (ix + 12)
ch_ondl:
ld (ix + 10), a
ret
play:
xor a
ld (addtoen + 1), a
ld (ayregs + ar_mixer), a
dec a
ld (ayregs + ar_envtp), a
ld hl, delycnt
dec (hl)
jr nz, pl2
ld hl, chana + chp_ntskcn
dec (hl)
jr nz, pl1b
adinpta:
ld bc, $0101
ld a, (bc)
and a
jr nz, pl1a
ld d, a
ld (ns_base), a
crpsptr equ $+1
ld hl, 0
inc hl
ld a, (hl)
inc a
jr nz, plnlp
call checklp
lposptr:
ld hl, 8481
ld a, (hl)
inc a
plnlp:
ld (crpsptr), hl
dec a
add a, a
ld e, a
rl d
patsptr:
ld hl, 8481
add hl, de
ld de, (modaddr + 1)
ld (psp_ + 1), sp
ld sp, hl
pop hl
add hl, de
ld b, h
ld c, l
pop hl
add hl, de
ld (adinptb + 1), hl
pop hl
add hl, de
ld (adinptc + 1), hl
psp_:
ld sp, 12593
pl1a:
ld ix, chana + 12
call ptdecod
ld (adinpta + 1), bc
pl1b:
ld hl, chanb + chp_ntskcn
dec (hl)
jr nz, pl1c
ld ix, chanb + 12
adinptb:
ld bc, 257
call ptdecod
ld (adinptb + 1), bc
pl1c:
ld hl, chanc + chp_ntskcn
dec (hl)
jr nz, p3x_delay
ld ix, chanc + 12
adinptc:
ld bc, 257
call ptdecod
ld (adinptc + 1), bc
p3x_delay:
ld a, 62
ld (delycnt), a
pl2:
ld ix, chana
ld hl, (ayregs + ar_tona)
call chregs
ld (ayregs + ar_tona), hl
ld a, (ampl)
ld (ayregs + ar_ampla), a
ld ix, chanb
ld hl, (ayregs + ar_tonb)
call chregs
ld (ayregs + ar_tonb), hl
ld a, (ampl)
ld (ayregs + ar_amplb), a
ld ix, chanc
ld hl, (ayregs + ar_tonc)
call chregs
ld (ayregs + ar_tonc), hl
ld hl, (ns_base_addtons)
ld a, h
add a, l
ld (ayregs + ar_noise), a
addtoen:
ld a, 62
ld e, a
add a, a
sbc a, a
ld d, a
ld hl, (envbase)
add hl, de
ld de, (curesld)
add hl, de
ld (ayregs + ar_env), hl
xor a
ld hl, curedel
or (hl)
jr z, rout_a0
dec (hl)
jr nz, rout
env_del:
ld a, 62
ld (hl), a
esldadd:
ld hl, 8481
add hl, de
ld (curesld), hl
rout:
xor a
rout_a0:
; ld de, $df0f ; Zon-X ports
; ld bc, $ffdf ;
; ld de, $f5f6 ; TC2068 ports
; ld bc, $fff5 ;
ld de, $ffbf ; 128 ports
ld bc, $fffd ;
ld hl, ayregs
lout:
out (c), a
; ld c, e ; Zon-X / TC2068
ld b, e ; 128
outi
; ld c, d ; Zon-X / TC2068
ld b, d ; 128
inc a
cp $0d
jr nz, lout
out (c), a
ld a, (hl)
and a
ret m
; ld c, e ; Zon-X / TC2068
ld b, e ; 128
out (c), a
ret
t_:
tcold_0:
defb $00 + 1, $04 + 1, $08 + 1, $0a + 1, $0c + 1, $0e + 1
defb $12 + 1, $14 + 1, $18 + 1, $24 + 1, $3c + 1, 0
tcold_1:
defb $5c + 1, 0
tcold_2:
defb $30 + 1, $36 + 1, $4c + 1, $52 + 1, $5e + 1, $70 + 1
defb $82, $8c, $9c, $9e, $a0, $a6, $a8, $aa, $ac, $ae, $ae, 0
tcnew_3:
defb $56 + 1
tcold_3:
defb $1e + 1, $22 + 1, $24 + 1, $28 + 1, $2c + 1, $2e + 1
defb $32 + 1, $be + 1, 0
tcnew_0:
defb $1c + 1, $20 + 1, $22 + 1, $26 + 1, $2a + 1, $2c + 1
defb $30 + 1, $54 + 1, $bc + 1, $be + 1, 0
tcnew_1 equ tcold_1
tcnew_2:
defb $1a + 1, $20 + 1, $24 + 1, $28 + 1, $2a + 1, $3a + 1
defb $4c + 1, $5e + 1, $ba + 1, $bc + 1, $be + 1, 0
emptysamorn equ $ - 1
defb 1, 0;, $90 ;delete $90 if you don't need default sample
; channel data offsets
chp_psinor equ 0
chp_psinsm equ 1
chp_cramsl equ 2
chp_crnssl equ 3
chp_crensl equ 4
chp_tslcnt equ 5
chp_crtnsl equ 6
chp_tnacc equ 8
chp_conoff equ 10
chp_onoffd equ 11 ; ix for ptdecod here ( + 12)
chp_offond equ 12
chp_ornptr equ 13
chp_samptr equ 15
chp_nntskp equ 17
chp_note equ 18
chp_sltont equ 19
chp_env_en equ 20
chp_flags equ 21 ; enabled - 0, simplegliss - 2
chp_tnsldl equ 22
chp_tslstp equ 23
chp_tndelt equ 25
chp_ntskcn equ 27
chp_volume equ 28
vars:
chana:
defs 29
chanb:
defs 29
chanc:
defs 29
delycnt:
defb 0 ; globalvars
curesld:
defw 0
curedel:
defb 0
ns_base_addtons:
ns_base:
defb 0
addtons:
defb 0
ar_tona equ 0 ; word 1
ar_tonb equ 2 ; word 1
ar_tonc equ 4 ; word 1
ar_noise equ 6 ; byte 1
ar_mixer equ 7 ; byte 1
ar_ampla equ 8 ; byte 1
ar_amplb equ 9 ; byte 1
ar_amplc equ 10 ; byte 1
ar_env equ 11 ; word 1
ar_envtp equ 13 ; byte 1
ar_size equ 14 ; byte 1
ayregs equ $
vt_:
incbin "volume.p3v"
envbase equ vt_ + 14
t1_ equ vt_ + 16 ; tone tables data depacked here
t_old_1 equ t1_
t_old_2 equ t_old_1 + 24
t_old_3 equ t_old_2 + 24
t_old_0 equ t_old_3 + 2
t_new_0 equ t_old_0
t_new_1 equ t_old_1
t_new_2 equ t_new_0 + 24
t_new_3 equ t_old_3
nt_:
incbin "notes.p3n"
;local vars
ampl equ ayregs + ar_amplc
var0end equ vt_ + 16 ; p3x_init zeroes from vars to
; var0end - 1
varsend equ $
mdladdr equ $
music:
incbin "stones.p3x"
END ASM
start:
PRINT "HELLO"
ASM
ld a, 80h ; high byte of vectr
ld i, a ; store it in I
call p3x_init ; initialize music
im 2 ; music on
END ASM
|
|
|
| Compile code modules/libraries? |
|
Posted by: slenkar - 2014-01-31, 07:40 PM - Forum: Wishlist
- No Replies
|
 |
Is it possible with the new compiler to compile a .bas into a library?
Like .lib files in the C language
Once they are compiled they dont need to be compiled again unless changed.
Speeds up compilation a lot
-I compiled my speccywars game again and it worked perfectly
its the same size too
|
|
|
| ZX Basic 1.4 (beta) is out |
|
Posted by: boriel - 2014-01-29, 06:14 PM - Forum: ZX Basic Compiler
- Replies (44)
|
 |
After almost a year (okay, only two month ), a new version of ZX BASIC is out.
ZX BASIC 1.4 (not 2.x) is a huge step forward in terms of compiler design.
What to expect from this version? Nothing.
What? Nothing. ZX BASIC 1.4 is a huge refactor but tries to maintain 100% backward compatibility with previous releases.
Well, there are something you might expect: Bugs.
Please, if you want to help, at this moment, the best way is to recompile your old programs with this new version and report errors.
Another method is to generate --asm files with both 1.3.x and 1.4.x and compare (diff) them, to look for differences.
Okay, yes, there are things that have already improved: - ZX BASIC 1.4. corrects hidden bugs I've discovered on 1.3 (or which haven't happened because users don't use some BASIC features...)
These bugs are hard to fix in the old version and will be there forever... But are already fixed in 1.4
- ZX BASIC 1.4 already produces better code under some circumstances. Ej. @myArray(3, 4) only takes 2 asm instructions (hundreds of them before). Some POKE sentences also were not correctly optimized. They are now.
- ZX BASIC 1.4 allows now nested scopes / functions (that is, declare a function / sub inside of another as in Pascal / C++ and some extended C compilers).
But other than that, stills the same.
The question is: OK, now I'm open to new features... and architectures (MSX, I'm looking at you). It's time to discuss then :twisted:
Download, as always, at the Download page.
|
|
|
| SPECTRA Advanced Graphics - Assembly |
|
Posted by: bloodbaz - 2014-01-25, 06:43 PM - Forum: How-To & Tutorials
- Replies (1)
|
 |
LCD has already posted up some great starter for 10 regarding ZXBC functions for the SPECTRA interface.
Most of my work is coded in Assembly (although I need to get around to some serious ZXBC programming soon) but we thought it would beuseful to share similar routines from an Assembly point of view.
I've put them under a separate, but similarly named thread - hope this is okay.
Firstly, a useful set of DEFINEs:
Code: ; ----------------------------------------------------------------------
; Spectra
; ----------------------------------------------------------------------
; SPECTRA PORT ADDRESS
SPECTRA_PORT .equ $7FDF ; 32735
; SPECTRA PORT VALUES
SPECTRA_MODE_ROW .equ 0
SPECTRA_MODE_QUAD .equ 1 ; b0
SPECTRA_MODE_DUAL .equ 2 ; b1
SPECTRA_MODE_SINGLE .equ 3 ; b0+b1
SPECTRA_COL_BASIC .equ 0
SPECTRA_COL_EXTRA .equ 4 ; b2
SPECTRA_SINGLE_BYTE .equ 0
SPECTRA_DOUBLE_BYTE .equ 8 ; b3
SPECTRA_BORDER_STANDARD .equ 0
SPECTRA_BORDER_ENHANCED .equ 16 ; b4
SPECTRA_SCREEN_BANK_A .equ 0
SPECTRA_SCREEN_BANK_B .equ 32 ; b5
SPECTRA_SCREEN_0 .equ 0
SPECTRA_SCREEN_1 .equ 64 ; b6
SPECTRA_FULL_CELL .equ 0
SPECTRA_HALF_CELL .equ 128 ; b7
SPECTRA_COL_EXTRA_SINGLE .equ 4
SPECTRA_COL_EXTRA_DOUBLE .equ 12
Next a couple of Step Up/Step Down functions that accept an address in attribute memory and locates the corresponding address above or below.
Functions are "mode specific" (Row, Quad, Dual, Single or in newer terminology - Nx8, Nx4, Nx2, Nx1). Only Quad and Dual are provided here but I can post the others up later.
The Row version is identical to standard spectrum process and is simply adding or subtracting 32 bytes.
Single (not provided at present) is more complex due the screen having a hybrid of Nx1 and Nx2 in the top 2/3rds and bottom 1/3d screen respectively.
Anyway, here they are:
Code: ; ------------------------------------------------------
; *AttrStepUp and *AttrStepDown
; Step Up and Down functions are a function of the mode
; only and half/full mode (b7) and single/double mode (b6)
; do not affect this values. As such we have the following:
; variants:
; RowAttrStepUp RowAttrStepDown
; (imp) QuadAttrStepUp QuadAttrStepDown
; (imp) DualAttrStepUp DualAttrStepDown
; SingleAttrStepUp SingleAttrStepDown
; Single is more complex because it changes resolution in the
; 3rd third.
; All StepUp/Down functions have HL as input and output
; and break A
; ------------------------------------------------------
; ------------------------------------------------------
; QuadAttrStepUp
; ------------------------------------------------------
QuadAttrStepUp:
LD A,H
DEC H
AND 1 ; In a pixel step up with { L2 L1 L0 } we do an AND 7 here
RET NZ
; Crossing a ROW
LD A,L
SUB 32
LD L,A
RET C
; LD A,H
; ADD A,2 ; In a pixel step up with { L2 L1 L0 } we do an ADD A,8 here
; LD H,A ; An ADD A, 2 is better handled with a couple of "DEC H" ops
INC H
INC H
RET
; ------------------------------------------------------
; QuadAttrStepDown
; ------------------------------------------------------
QuadAttrStepDown:
INC H
LD A,H
AND 1 ; In a pixel step down with { L2 L1 L0 } we do an AND 7 here
RET NZ
LD A,L
ADD A,32
LD L,A
RET C
; LD A,H
; SUB 2 ; In a pixel step down with { L2 L1 L0 } we do an SUB 8 here
; LD H,A ; A SUB 2 is better handled with a couple of "DEC H" ops
DEC H
DEC H
RET
; ------------------------------------------------------
; DualAttrStepUp
; ------------------------------------------------------
DualAttrStepUp:
LD A,H
DEC H
AND 3 ; In a pixel step up with { L2 L1 L0 } we do an AND 7 here
RET NZ
; Crossing a ROW
LD A,L
SUB 32
LD L,A
RET C
LD A,H
ADD A,4 ; In a pixel step up with { L2 L1 L0 } we do an ADD A,8 here
LD H,A ; An ADD A, 2 is better handled with a couple of "DEC H" ops
RET
; ------------------------------------------------------
; DualAttrStepDown
; ------------------------------------------------------
DualAttrStepDown:
INC H
LD A,H
AND 3 ; In a pixel step down with { L2 L1 L0 } we do an AND 3 here
RET NZ
LD A,L
ADD A,32
LD L,A
RET C
LD A,H
SUB 4 ; In a pixel step down with { L2 L1 L0 } we do an SUB 8 here
LD H,A
RET
This is a SPECTRA test routine. It also tests for the (now defunct) v1 firmware which didn't support half-cell mode. Pretty much all SPECTRA boards will return "2".
You will notice that at the first block has conditional compilation (IFDEF SPECTRA_EMULATION) which I used when testing via an Emulator which doesn't support SPECTRA. It allowed me to still return that it does when it doesn't.
You can remove this initial block (up to the "ELSE") and the final "ENDIF" for the true Spectra Test implementation.
Code: ; ------------------------------------------------------
; SpectraTest
; Tests for the presence of the SPECTRA interface
;
; Remarks
; To avoid any colour flash, perform a immediately before HALT before calling
; Tests for SPECTRA by OUTing, WAITing and then INing a series of bytes defined by SpectraTestBytes_v1
;
; Breaks:
; BC (returns holding SPECTRA port)
; HL (Spectra Not Found: Returns pointing to the byte that was tested for (written to the SPECTRA port))
; A (Spectra Not Found: Returns actual byte read from the SPECTRA port)
;
; Returns:
; E: 0 = Not present; 1 = SPECTRA v1; 2 = SPECTRA v2
; ------------------------------------------------------
SpectraTest:
IFDEF SPECTRA_EMULATION
IF SPECTRA_EMULATION = "v1"
LD E, 1
ELSE
LD E, 2
ENDIF
RET
ELSE
LD HL, SpectraTestBytes_v1
LD BC, SPECTRA_PORT
CALL .test
LD E, 0
RET NZ ; Not Present (E=0)
LD HL, SpectraTestBytes_v2
INC E
CALL .test
JR NZ, .end
INC E
RET ; SPECTRA v2
.end: XOR A
OUT (C), A
RET
.test: ; Write
LD A, (HL)
OUT (C), A
; Wait
XOR A
.wait: DEC A
JR NZ, .wait
; Read
IN A, (C)
; Test
CP (HL)
; Fail: Return with Z Flag Reset
RET NZ
; End of sequence (0)?
OR A
RET Z ; Pass
; Test next byte
INC HL
JR .test
SpectraTestBytes_v1:
; 0 terminates the sequence but 0 is included in the test
.defb SPECTRA_COL_EXTRA_SINGLE
.defb SPECTRA_BORDER_ENHANCED
.defb SPECTRA_SCREEN_BANK_B
.defb 0
SpectraTestBytes_v2:
.defb SPECTRA_HALF_CELL
.defb 0
ENDIF
I can post more up when I have time. Ciao!
|
|
|
| SPECTRA Advanced Graphics - Assembly |
|
Posted by: bloodbaz - 2014-01-25, 06:33 PM - Forum: How-To & Tutorials
- Replies (3)
|
 |
LCD has already posted up some great starter for 10 regarding ZXBC functions for the SPECTRA interface.
Most of my work is coded in Assembly (although I need to get around to some serious ZXBC programming soon) but we thought it would beuseful to share similar routines from an Assembly point of view.
I've put them under a separate, but similarly named thread - hope this is okay.
|
|
|
| Spectranet |
|
Posted by: ardentcrest - 2014-01-21, 08:05 AM - Forum: Wishlist
- Replies (44)
|
 |
Be nice if you could get the compiler to work with the spectranet.
Code: 10 %open #4,"file","r"
20 %oneof 100
30 INPUT #4,a$
40 PRINT a$
50 GO TO 30
100 %close #4
will not work as it sees the % as an illegal character.
|
|
|
| SPECTRA Advanced Graphics |
|
Posted by: LCD - 2014-01-20, 01:35 AM - Forum: How-To & Tutorials
- Replies (21)
|
 |
Hi boriel,
Here I show you the SPECTRA routines.
Code: function SetSpectraMode(LineHeight as Ubyte,ExtraColours as ubyte,DoubleByteColour as ubyte,EnhancedBorder as ubyte,DisplayBank as ubyte,ShadowBank as ubyte,HalfCell as ubyte) as ubyte
dim mode,r as ubyte
mode=LineHeight|(ExtraColours<<2)|(DoubleByteColour<<3)|(EnhancedBorder<<4)|(DisplayBank<<5)|(ShadowBank<<6)|(HalfCell<<7)
out $7fdf,mode
if in($7fdf)<>mode
r=0
else
r=1
end if
return r
end function
Selfexplaining... Line Height is the code for Attribute height: 0=8 pixel, 1=4 pixel, 2=2 pixel, 3=1 Pixel (unusable because attribute will overwrite system variables and not all attributes can have 1 line height, same problem with double byte flag and 2 pixel height)
It returns 1 if mode is available (SPECTRA present) or 0 if not
Code: sub ExtendedBorder(red as ubyte,green as ubyte,blue as ubyte)
dim r,g,b as ubyte
b=((blue&1)<<5)|((blue&2)>>1)
r=((red&1)<<6)|((red&2))
g=((green&1)<<7)|((green&2)<<1)
out $fe,r|g|b
end sub
This set the Border (64 colour mode) based on RGB values (0-3 for each channel)
Should be easy to convert to inline Assembly
Demo:
Code: if SetSpectraMode(0,1,0,1,0,0,0) 'Enable Enhanced Border with 64 Colours
BorderTest: 'Change Border Colours
print at 0,0;"Grey "
for a=0 to 3
ExtendedBorder(a,a,a)
pause 50
next a
for a=0 to 3
ExtendedBorder(3-a,3-a,3-a)
pause 50
next a
'Red
print at 0,0;"Red "
for a=0 to 3
ExtendedBorder(a,0,0)
pause 50
next a
for a=0 to 3
ExtendedBorder(3-a,0,0)
pause 50
next a
'Green
print at 0,0;"Green"
for a=0 to 3
ExtendedBorder(0,a,0)
pause 50
next a
for a=0 to 3
ExtendedBorder(0,3-a,0)
pause 50
next a
'Blue
print at 0,0;"Blue "
for a=0 to 3
ExtendedBorder(0,0,a)
pause 50
next a
for a=0 to 3
ExtendedBorder(0,0,3-a)
pause 50
next a
if inkey$<>" ":goto BorderTest:end if
end if
Enhanced Border (15 Colour mode):
Code: sub ZXBorderEnhanced(BorderColor as ubyte,FlashWhite as ubyte,Bri as ubyte,Fla as ubyte)
out $fe,BorderColor|(FlashWhite<<5)|(Bri<<6)|(Fla<<7)
end sub
Also very easy to convert to inline Assembly
Demo:
Code: if SetSpectraMode(0,0,0,1,0,0,0) 'Enable Enhanced Border with 15 Colours
print at 0,0;"Normal Colours"
for a=0 to 7
ZXBorderEnhanced(a,0,0,0)
pause 25
next a
print at 0,0;"Bright Colours"
for a=0 to 7
ZXBorderEnhanced(a,0,1,0)
pause 25
next a
print at 0,0;"Flash Bright Colours with black"
for a=0 to 7
ZXBorderEnhanced(a,0,1,1)
pause 100
next a
print at 0,0;"Flash Normal Colours with white"
for a=0 to 7
ZXBorderEnhanced(a,1,0,1)
pause 100
next a
print at 0,0;"And now to the 64 colours border"
pause 50
end if
More will come later.
Together with at least two games.
|
|
|
| Fucking Awesome Spectrum Engine (FASE) |
|
Posted by: antoniovillena - 2014-01-07, 11:16 PM - Forum: ZX Basic Compiler
- Replies (11)
|
 |
Hi
We are writing an engine (sprites, tiles, maps) and I would like to interface with ZX Basic. The main thread is here (sorry, it's in spanish)
http://www.mojontwins.com/mojoniaplus/vi...f=9&t=1461
Now the engine is in alpha stage and there is a SDCC working demo. This is the code:
Code: #include "bunuelera.h"
const unsigned char data[32]= {
0x00, 0x42, 0x11, 0,
0x08, 0x60, 0x60, 2,
0x09, 0xa8, 0x48, 3,
0x0a, 0x22, 0x02, 1,
0x0b, 0xd0, 0x6e, 2,
0x0c, 0xb6, 0x34, 3,
0x0d, 0x32, 0x32, 1,
0x04, 0x52, 0x5e, 0};
int main(){
// variables
int i, x= 0, y= 0;
// pasar personajes a sprites
for ( i = 0; i < 32; i++ )
sprites[i>>2][i&3]= data[i];
// inicializar engine
INIT;
// mostrar la primera pantalla al comienzo
screen= 0;
while(1){
// esto hace que el engine procese un frame generando el escenario
FRAME;
// movimiento de los enemigos
for ( i = 1; i < 8; i++ ){
if( sprites[i][3]&1 )
if( sprites[i][2] )
sprites[i][2]--;
else
sprites[i][3]^= 1;
else
if( sprites[i][2]<0x90 )
sprites[i][2]++;
else
sprites[i][3]^= 1;
if( sprites[i][3]&2 )
if( sprites[i][1]>0x08 )
sprites[i][1]--;
else
sprites[i][3]^= 2;
else
if( sprites[i][1]<0xe8 )
sprites[i][1]++;
else
sprites[i][3]^= 2;
}
// movimiento del protagonista
if( ~KeybYUIOP & 0x01 ){ // P
if( sprites[0][1]<0xee )
sprites[0][1]++;
else if( x < 11 )
sprites[0][1]= 0x02,
screen= y*12 + ++x;
}
else if( ~KeybYUIOP & 0x02 ){ // O
if( sprites[0][1]>0x02 )
sprites[0][1]--;
else if( x )
sprites[0][1]= 0xee,
screen= y*12 + --x;
}
if( ~KeybGFDSA & 0x01 ){ // A
if( sprites[0][2]<0xa0 )
sprites[0][2]++;
else if( y < 1 )
sprites[0][2]= 0x01,
screen= ++y*12 + x;
}
else if( ~KeybTREWQ & 0x01 ){ // Q
if( sprites[0][2]>0x01 )
sprites[0][2]--;
else if( y )
sprites[0][2]= 0xa0,
screen= --y*12 + x;
}
}
}
My idea is to traslate this code to ZX Basic. The engine set ups a runtime enviroment that leave between 24K and 30K bytes free from $8000 address. Basically there are 2 routines to call: INIT to initialize the engine and FRAME, that put all the stuff in the screen every frame. With this engine you can move between 8 and 16 sprites flicker free at 50fps in 48K and all 128K models. The engine has diferent implementation for each machine (floating bus in 48K, shadow screen in 128K) so the comunication is done by accessing to next memory locations:
Code: 5b00 number of screen to paint
5b01-5b96 tiles codes of actual screen
5bfe-5bff set to repaint a rectangular area of tiles
5c00-5c3f sprite info, where
5c00-5c02 first sprite
5c00 sprite number, set high bit to disable
5c01 X coord
5c02 Y coord
5c04-5c06 second sprite
...
More info in the first message of the linked thread
Regards
-----------
Buenas, estamos escribiendo un engine de sprites, tiles y mapas y me gustaría poder usar dicho engine con ZX Basic. En el hilo que enlazo arriba está todo explicado en español. No tengo mucha idea sobre ZX Basic, pero veo que hay una comunidad detrás y me gustaría que me ayudaran a traducir la demo de C a Basic.
Saludos
|
|
|
|