Welcome, Guest |
You have to register before you can post on our site.
|
Online Users |
There are currently 283 online users. » 0 Member(s) | 281 Guest(s) Bing, Google
|
Latest Threads |
Strange Happenings
Forum: Bug Reports
Last Post: boriel
05-23-2025, 09:15 AM
» Replies: 4
» Views: 745
|
.tap file code not execut...
Forum: Help & Support
Last Post: Zoran
04-28-2025, 10:59 AM
» Replies: 4
» Views: 1,047
|
Exit from more than one l...
Forum: Wishlist
Last Post: Duefectu
04-23-2025, 10:06 PM
» Replies: 3
» Views: 857
|
put small ASM programs li...
Forum: How-To & Tutorials
Last Post: Zoran
04-18-2025, 02:02 PM
» Replies: 6
» Views: 2,482
|
Creating +3 Menus - Loadi...
Forum: Help & Support
Last Post: merlinkv
04-16-2025, 02:08 PM
» Replies: 6
» Views: 1,414
|
Randomize not very random...
Forum: Help & Support
Last Post: Zoran
04-08-2025, 10:40 AM
» Replies: 4
» Views: 1,542
|
Scope rules
Forum: Bug Reports
Last Post: Zoran
04-04-2025, 09:46 AM
» Replies: 2
» Views: 744
|
Using constants not allow...
Forum: Bug Reports
Last Post: baltasarq
03-19-2025, 10:00 PM
» Replies: 8
» Views: 1,910
|
404 page not found
Forum: Documentation
Last Post: boriel
03-08-2025, 07:16 PM
» Replies: 5
» Views: 3,487
|
Spectrum keywords codes
Forum: Bug Reports
Last Post: boriel
03-08-2025, 11:00 AM
» Replies: 1
» Views: 697
|
|
|
ZX Basic 1.4 (beta) is out |
Posted by: boriel - 01-29-2014, 05: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 - 01-25-2014, 05: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 - 01-25-2014, 05: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 - 01-21-2014, 07: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 - 01-20-2014, 12: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 - 01-07-2014, 10: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
|
|
|
Adding new commands to ZX BASIC |
Posted by: cheveron - 12-06-2013, 09:43 AM - Forum: ZX Basic Compiler
- Replies (7)
|
 |
Just to help me understand the structure of the language a bit better I'd like to know what the method would be for adding commands. I'm mainly interested in adding the following commands from SE Basic IV:
CLUT: select color look-up table (0 to 3)
COLOR: absolute attribute value (0 to 255)
PALETTE: set ULAplus registers
RESET: restore palette from palette buffer (first 64 bytes after screen)
PUT: wrapper for LDIR
SCROLL: text display scrolling
SOUND: set AY registers
SPEED: set CPU speed for clones
But I can also provide support for the one everyone is always asking for:
PLAY
All of this can be done without requiring either the SE Basic ROM or the 128 ROM. Having said that PLAY isn't very versatile, can't be interrupt driven, and has a fairly large RAM overhead (the routine takes 2296 bytes).
|
|
|
Embedded codes |
Posted by: britlion - 10-28-2013, 07:25 PM - Forum: Core
- Replies (4)
|
 |
I see Battle Bunny came up with a good idea here:
http://www.worldofspectrum.org/forums/sh...post732193
I suggest we steal it, and persuade Boriel to include it in the compiler. So you can do
Print "{PAPER 3} Hello world" to embed the paper 3 in the string. Or More usefully block graphics and {C} symbol in a more logical format.
Clearly needs a way of turning on and off globally via command line, and locally or a string via some #command....
But I think it would make it easier to enter some odd codes.
|
|
|
[msx] found a bug from the compiler, i think |
Posted by: nitrofurano - 09-22-2013, 08:30 PM - Forum: Bug Reports
- No Replies
|
 |
the example i tried was this one
<!-- m --><a class="postlink" href="https://dl.dropboxusercontent.com/u/795795/retrocoding/msx/_example02ag_msxzxbasic_lacedpostscriptscreen7.zip">https://dl.dropboxusercontent.com/u/795 ... creen7.zip</a><!-- m -->
was about drawing vectorial drawings on laced screeen7 on msx
what appeared as error message from the terminal:
Code: msxscreen.bas:3: warning: SUB 'msxscreen' declared as FASTCALL with 4 parameters
Traceback (most recent call last):
File "/opt/zxbasiccompiler/zxbasiccompiler_zxspectrum/zxb.py", line 312, in <module>
sys.exit(main(sys.argv)) # Exit
File "/opt/zxbasiccompiler/zxbasiccompiler_zxspectrum/zxb.py", line 265, in main
asm_output = backend.emmit(MEMORY)
File "/mnt/sda4/opt/zxbasiccompiler/zxbasiccompiler_zxspectrum/backend/__init__.py", line 2368, in emmit
output_join(output, QUADS[i.quad[0]][1](i))
File "/mnt/sda4/opt/zxbasiccompiler/zxbasiccompiler_zxspectrum/backend/__16bit.py", line 413, in _modu16
if op2[0] in ('_', '$'):
TypeError: 'int' object has no attribute '__getitem__'
|
|
|
|