| Welcome, Guest |
You have to register before you can post on our site.
|
| Online Users |
There are currently 204 online users. » 0 Member(s) | 204 Guest(s)
|
| Latest Threads |
New video Couse / Nuevo c...
Forum: News
Last Post: Duefectu
2026-04-29, 11:02 PM
» Replies: 0
» Views: 213
|
location of heap manageme...
Forum: Help & Support
Last Post: boriel
2026-03-07, 12:13 AM
» Replies: 1
» Views: 485
|
non-paged supervisor code...
Forum: Help & Support
Last Post: sdo303
2026-02-20, 06:38 PM
» Replies: 8
» Views: 1,299
|
How to open fuse as an ex...
Forum: How-To & Tutorials
Last Post: Duefectu
2026-02-09, 01:52 PM
» Replies: 3
» Views: 1,389
|
Old zxbasic game errors
Forum: Help & Support
Last Post: boriel
2025-11-09, 11:52 AM
» Replies: 7
» Views: 2,079
|
Error: Undefined GLOBAL l...
Forum: Help & Support
Last Post: ardentcrest
2025-11-04, 05:46 PM
» Replies: 3
» Views: 1,080
|
A Fast(er) Plot Routine f...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-30, 03:16 PM
» Replies: 2
» Views: 1,179
|
Hall of Fame - Include fo...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-28, 03:48 PM
» Replies: 0
» Views: 630
|
[SOLVED] Array layout bug...
Forum: Bug Reports
Last Post: Zoran
2025-10-25, 05:48 PM
» Replies: 2
» Views: 1,217
|
3DOS Commands?
Forum: Help & Support
Last Post: boriel
2025-10-06, 02:54 PM
» Replies: 3
» Views: 1,381
|
|
|
| Random Functions |
|
Posted by: britlion - 2012-06-19, 12:07 AM - Forum: How-To & Tutorials
- Replies (6)
|
 |
Boriel has included a better random function in the code; but this passes through floating point numbers, which is potentially fairly slow - and for games we usually require integer numbers anyway!
I've written a few functions that are a possible alternative.
This is the base function that does the hard work of generating a random number from 0-255 in the A register (or as a return value, conveniently enough). This is the same random number generator that Boriel is using, incidentally. (Based pretty much wholly on Patrik Rak's stream random generator).
Code: FUNCTION FASTCALL randomBase () as uByte
ASM
random: ld hl,$A280 ; xz -> yw
ld de,$C0DE ; yw -> zt
ld (random+1),de ; x = y, z = w
ld a,e ; w = w ^ ( w << 3 )
add a,a
add a,a
add a,a
xor e
ld e,a
ld a,h ; t = x ^ (x << 1)
add a,a
xor h
ld d,a
rra ; t = t ^ (t >> 1) ^ w
xor d
xor e
ld h,l ; y = z
ld l,a ; w = t
ld (random+4),hl
;ret (Not necessary, since the compiler will add ret to the end)
END ASM
END FUNCTION
This function will update the seed value based on the current frames counter. To improve randomness, get the user to have a human interaction that can take a variable amount of time and then run this.
Code: SUB FASTCALL updateSeed()
REM Updates the random generator seed from the FRAMES system variable.
t()
ASM
LD A,E
EX DE,HL
LD HL,random+2
XOR (HL)
AND A
JR NZ,updateSeedNotZero
INC A
updateSeedNotZero:
LD (HL),A
LD HL,random+4
LD A,E
XOR (HL)
LD (HL),A
INC HL
LD A,D
XOR (HL)
LD (HL),A
END ASM
END SUB
The above function depends on my timer function, which gets the value in FRAMES:
Code: FUNCTION FASTCALL t() as uLong
asm
DI
LD DE,(23674)
LD D,0
LD HL,(23672)
EI
end asm
end function
This function returns a value from zero to the specified limit number (limit <= 255)
Code: FUNCTION fastcall randomBin(limit as uByte) as uByte
ASM
AND A
RET Z ; Input zero, output zero.
LD B,A ; Save A
LD C,255
randomBinLoop:
RLA
JR C, randomBinLoopExit
RR C
JR randomBinLoop ; loop back until we find a bit.
randomBinLoopExit:
randomBinRedoCall:
call random
AND C
CP B
RET Z
JR NC, randomBinRedoCall
END ASM
END FUNCTION
it's worth noting that the issue with this is that it basically rolls a random, and if it's bigger than limit, it rolls another one. This could potentially take a while, and isn't guaranteed to be fast. Though the probability of failing to hit the zone is kept to 50%, so on average it will roll 1.5 random numbers, I think, per call. This should usually be faster than a floating point multiply, I believe.
If you do want a number a random number between 0 and 1, using FIXED is quite a lot faster than float. This routine uses randombase to do that:
Code: FUNCTION FASTCALL randomFixed() as FIXED
ASM
call random
push AF
call random
ld l,A
POP AF
ld h,a
ld d,0
ld e,d
END ASM
END FUNCTION
Timings:
Code: dim time as uLong
DIM n as uInteger
DIM variable as uByte
time=t()
for n=0 to 20000
REM One line of the following three:
'variable=rnd*128
'variable=randomFixed()*128
'variable=randomBin(128)
next n
print t()-time
20,000 loops took:
variable=rnd*128 => 1180 frames.
variable=randomFixed()*128 => 613 Frames (1.92 x faster)
variable=randomBin(128) => 74 frames. (this example is 16 x faster) (worst case averages 13x faster; best case averages 22x faster)
(This does vary by limit, but is never > 89 frames for any limit chosen. Can be as low as about 52. Average is about 64.)
All three, of course, return an integer from 0 to 127 (the last 0-128; this chosen because it's a worse case scenario for timing).
For scale, 20,000 loops calling randomBase takes 37 frames. Of course, this returns a number from 0-255 regardless, with no option to set the upper bound.
|
|
|
| Re: DEFB (*solved*) |
|
Posted by: britlion - 2012-06-16, 04:53 PM - Forum: Bug Reports
- Replies (2)
|
 |
Oh dear.
DEFB 157
DEFB "Man(e;@ "
DEFB 161
test.bas:1001 Error: illegal preprocessor character '@'
Build Failed!
So much for that idea.
|
|
|
| Inequality (*solved*) |
|
Posted by: britlion - 2012-06-06, 10:24 PM - Forum: Bug Reports
- Replies (3)
|
 |
Am I doing something wrong here? I think the order of operations is messing up. This looks very odd. Is BAND a lower priority than = ?
Code: dim n as uInteger
cls
for n=0 to 65530
print at 10,10;n;" ";n BAND 7
print at 12,6;"n BAND 7 = 7 is ";
IF n BAND 7 = 7 then
print "TRUE "
else
print "FALSE"
END IF
pause 0
next n
I /think/ this is doing boolean logic of
( n BAND ( 7 = 7 ) )
Or, n BAND 1
Which can't be right, surely?
|
|
|
| HOWTO: Put BeepFX Sound into ZXB code |
|
Posted by: britlion - 2012-06-02, 01:28 PM - Forum: How-To & Tutorials
- Replies (5)
|
 |
Shiru's Beepfx (http://shiru.untergrund.net/files/beepfx.zip) is quite an interesting tool for sound effects. He doesn't believe it can be used for tunes - but it can do different pitched "tones" and include pauses, and that spells tune to me. Beepola is probably a better choice for real tune making, though.
Anyway - the asm it produces is not compatible with zxb's assembler. So I did the working out of how to tweak it to work.
So the sound calling routine would look like this:
Code: SUB sound(soundNum as uByte)
asm
#include "BeepFXPlayer.asm"
#include "SoundData.asm"
SoundEnd:
pop IX
end asm
end sub
And BeepFXPlayer would always be the same tweaks, so I present my version here:
Code: playBasic:
play:
ld hl,soundEffectsData ;address of sound effects data
di
push ix
push iy
ld b,0
ld c,a
add hl,bc
add hl,bc
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
push hl
pop ix ;put it into ix
ld a,(23624) ;get border color from BASIC vars to keep it unchanged
rra
rra
rra
and 7
ld (sfxRoutineToneborder+1),a
ld (sfxRoutineNoiseborder+1),a
readData:
ld a,(ix+0) ;read block type
or a
jr nz,readDatasound
pop iy
ei
jp SoundEnd
readDatasound:
ld c,(ix+1) ;read duration 1
ld b,(ix+2)
ld e,(ix+3) ;read duration 2
ld d,(ix+4)
push de
pop iy
dec a
jr nz,sfxRoutineNoise
;this routine generate tone with many parameters
sfxRoutineTone:
ld e,(ix+5) ;freq
ld d,(ix+6)
ld a,(ix+9) ;duty
ld (sfxRoutineToneduty+1),a
ld hl,0
sfxRoutineTonel0:
push bc
push iy
pop bc
sfxRoutineTonel1:
add hl,de
ld a,h
sfxRoutineToneduty:
cp 0
sbc a,a
and 16
sfxRoutineToneborder:
or 0
out ($fe),a
#line 78
dec bc
ld a,b
or c
jr nz,sfxRoutineTonel1
ld a,(sfxRoutineToneduty+1)
add a,(ix+10) ;duty change
ld (sfxRoutineToneduty+1),a
ld c,(ix+7) ;slide
ld b,(ix+8)
ex de,hl
add hl,bc
ex de,hl
pop bc
dec bc
ld a,b
or c
jr nz,sfxRoutineTonel0
ld c,11
nextData:
add ix,bc ;skip to the next block
jr readData
;this routine generate noise with two parameters
sfxRoutineNoise:
ld e,(ix+5) ;pitch
ld d,1
ld h,d
ld l,d
sfxRoutineNoisel0:
push bc
push iy
pop bc
sfxRoutineNoisel1:
ld a,(hl)
and 16
sfxRoutineNoiseborder:
or 0
out ($fe),a
dec d
jr nz,sfxRoutineNoisel2
ld d,e
inc hl
ld a,h
and $1f
ld h,a
sfxRoutineNoisel2:
dec bc
ld a,b
or c
jr nz,sfxRoutineNoisel1
ld a,e
add a,(ix+6) ;slide
ld e,a
pop bc
dec bc
ld a,b
or c
jr nz,sfxRoutineNoisel0
ld c,7
jr nextData
Finally, you need to run beepfx, and compile just the sound data to asm.
You'll get something like this:
Code: soundEffectsData
dw .sfx0
.sfx0
db #01
dw #0032,#0064,#01f4,#ffec,#0080
db #00
This needs some massaging to work. Change "soundEffectsData" to "soundEffectsData:"
Change "." to "soundEffectsData" And make labels have a : on the end.
Search and replace "db" with "defb"
Search and replace "dw" with "defw"
Replace # with $
All done!
Worked example:
Code: soundEffectsData:
defw soundEffectsDatasfx0
defw soundEffectsDatasfx1
soundEffectsDatasfx0:
defb $01
defw $0032,$0064,$01f4,$ffec,$0080
defb $00
soundEffectsDatasfx1:
defb $01
defw $0014,$0190,$00c8,$0005,$0110
defb $01
defw $001e,$0190,$00c8,$0008,$0110
defb $00
you can then save this as something lime soundata.asm and #'include this file into the sound routine listed above. Call with sound (n) for the sound number.
|
|
|
| Question about the Heap |
|
Posted by: LCD - 2012-05-30, 09:19 AM - Forum: Help & Support
- Replies (4)
|
 |
Hi Boriel, just following easy question:
If I use a heap of 256 bytes, where it is put into memory? I want to know where I cannot put any binary data.
Is this 65535-heapsize?
Edit: May this be problematic if I page the heap out? Is there a possibility that we can put the heap at a selected memory area (e.g. a buffer created with DEFB's) at program start (I know that changing it may crash the program).
|
|
|
| Pac Man Project |
|
Posted by: britlion - 2012-05-27, 06:13 PM - Forum: Gallery
- Replies (17)
|
 |
Clearly not finished, but I wanted feedback on how it feels. I spent /ages/ getting complex ghost behaviour right. Compare with CDS gobble a ghost, for example.
<!-- m --><a class="postlink" href="http://dl.dropbox.com/u/4903664/DemoMan.tzx">http://dl.dropbox.com/u/4903664/DemoMan.tzx</a><!-- m -->
(Yes, I know you can't die. Or eat ghosts. Yes, I know it breaks on level 2)
|
|
|
| output ASM |
|
Posted by: britlion - 2012-05-02, 11:02 AM - Forum: Bug Reports
- Replies (7)
|
 |
Not sure if this is a bug, per se - but it is certainly a bit ugly.
This even survived the peephole optimizer.
Input Basic:
IF myCurrentVector = %1000 then
Output assembly:
ld a, (ix+9)
sub 8
sub 1
jp nc, __LABEL56
Two subs in a row? And worse "Sub 1" instead of a dec?
It later tests:
IF myCurrentVector = %0001 then
as:
ld a, (ix+9)
dec a
sub 1
jp nc, __LABEL63
And I'm not even convinced that's the same test as "equal to x" Surely that's testing "If myCurrentVector>x" anyway?
|
|
|
|