I think you are right. IMO it should say “ Access to ports between 0x4000 and 0x7ffe with the low bit SET (i.e. when the ULA's own port is not being accessed) is subject to contention on every T state”djnzx48 wrote: ↑Mon Oct 14, 2019 8:00 am I rechecked the wiki page about I/O contention. Is it just me, or does it have a mistake?
According to the description, "access to ports between 0x4000 and 0x7ffe with the low bit clear (i.e. when the ULA's own port is not being accessed) is subject to contention on every T state."
This seems to be contradicted by the table on the same page, which indicates contention on every T-state when the low bit is set. When it mentions the 'low bit clear', does that refer to the bit being set or reset?
Short beeper routines in assembly
Re: Short beeper routines in assembly
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: Short beeper routines in assembly
That makes more sense. But why is port 0x7fff not included in that range? Should 0x7ffe be changed to 0x7fff, or is that correct as it is?
Re: Short beeper routines in assembly
Yes, it should be included I think. Part of the same mistake.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Waves lapping on the shore beeper sound
I'm trying to approximate the soothing sound of gentle waves lapping on a tropical shore, but my attempts so far are closer to a stormy day at Heysham. I'm just posting this in case anyone can suggest improvements or even post better code examples*. It has to be a shortish piece of code, so no huge samples.
*to be clear: I want to make it sound more gentle.
*to be clear: I want to make it sound more gentle.
Code: Select all
org 32768 ;might be slightly better in contended memory
mloop: call wave
call wavelaprumble ;(superfluous?)
call betweenwavepause
jr mloop
;
betweenwavepause:
ld b,30
call rnd
and 15
add a,b
ld b,a
bwplp: halt
djnz bwplp
ret
;
wavelaprumble:
ld bc,10000
bwlp: call rnd
and 16
out (254),a
dec bc
ld a,b
or c
jr nz,bwlp
ret
;
wave: ld c,63
ld de,1024
ld hl,0
main: call rnd
and 16
out (254),a
ld e,c
dlp: dec e
jr nz,dlp
dlp1: dec de
ld a,d
or a
jr nz,miss
ica: dec c
ret z
miss: ld a,d
or e
jr nz,main
ld a,2
out (254),a
ret
;
;PATRIK RAK's XOR SHIFT RND generator
rnd:
push hl
push de
rsd0: ld hl,0xA280 ; yw -> zt
rsd1: ld de,0xC0DE ; xz -> yw
ld (rnd+6),hl ; x = y, z = w
ld a,l ; w = w ^ ( w << 3 )
add a,a
add a,a
add a,a
xor l
ld l,a
ld a,d ; t = x ^ (x << 1)
add a,a
xor d
ld h,a
rra ; t = t ^ (t >> 1) ^ w
xor h
xor l
ld h,e ; y = z
ld l,a ; w = t
ld (rnd+3),hl
pop de
pop hl
ret
;
Re: Short beeper routines in assembly
I think Shiru’s BeepFX is a valuable tool for prototyping beeper effects in a RAD way.
https://shiru.untergrund.net/software.shtml
To be clear, it’s an fx engine that runs in the Speccy, combined with an editor that runs on the pc. However... the editor gives you a very clear idea of which different component parts the sound you are creating has. It also has a settings randomiser which is a useful way of coming up with completely unexpected effects.
Armed with this understanding, it would be extremely quick to try out different sounds in the editor, then write your own raw asm to approximate the sounds that please you, based on their component parts.
https://shiru.untergrund.net/software.shtml
To be clear, it’s an fx engine that runs in the Speccy, combined with an editor that runs on the pc. However... the editor gives you a very clear idea of which different component parts the sound you are creating has. It also has a settings randomiser which is a useful way of coming up with completely unexpected effects.
Armed with this understanding, it would be extremely quick to try out different sounds in the editor, then write your own raw asm to approximate the sounds that please you, based on their component parts.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: Short beeper routines in assembly
Try to produce very short impulses. Regarding the occasional clicks, I'm suspecting my source of "randomness" . Perhaps with proper RNG, you could avoid it (I was to lazy to type in Rak's LCRNG to memory, sorry).
Proud owner of Didaktik M
Re: Short beeper routines in assembly
One more experiment
Code: Select all
ld hl, $0300 ; b000 21 00 03 $0ats
l_b003: ld a, (hl) ; b003 7e $07ts
inc hl ; b004 23 $06ts
and $13 ; b005 e6 13 $07ts
out ($fe), a ; b007 d3 fe $0bts
inc de ; b009 13 $06ts
ld b, d ; b00a 42 $04ts
xor a ; b00b af $04ts
out ($fe), a ; b00c d3 fe $0bts
ld a, b ; b00e 78 $04ts
and $3f ; b00f e6 3f $07ts
inc a ; b011 3c $04ts
ld b, a ; b012 47 $04ts
l_b013: djnz l_b013 ; b013 10 fe $08/$0dts
ld a, h ; b015 7c $04ts
and $00 ; b016 e6 00 $07ts
add a, $0f ; b018 c6 0f $07ts
ld h, a ; b01a 67 $04ts
jr l_b003 ; b01b 18 e6 $0ct
Proud owner of Didaktik M
Re: Short beeper routines in assembly
Here's my attempt. I don't really understand how PWM works so I ended up with some annoying high-pitched tones. Maybe I'm not toggling the speaker bit fast enough.
Code: Select all
org 32768
main:
di
ld hl, pwm_table + 240
ld (pwm_ptr+1), hl
ld hl, 0
ld (time+1), hl
ld hl, 0xC0DE
ld de, 0
ld a, 1 ; pitch
ld (pitch+1), a
ld b, a
mainloop:
add hl, hl ; 11 / 816
jr nc, no_carry ; 7 / 823 [828 taken]
ret nc ; 5 / 828
nop ; 4 / 832
nop ; 4 / 836
ld a, c ; 4 / 840
out ($fe), a ; 11 / 851 [840] [next 896]
ld a, l ; 4 / 855
xor %00101101 ; 7 / 862
ld l, a ; 4 / 866
out_loop:
pwm_ptr:
ld de, pwm_table ; 10 / 876
ld c, 12 ; 7 / 883
pwm_loop:
ld a, (de) ; 7 / 890 / 50
inc de ; 6 / 896 / 56
; first OUT
out ($fe), a ; 11 / 11 [896] [0]
ld a, r ; 9 / 20
ld a, r ; 9 / 29
dec c ; 4 / 33
jp nz, pwm_loop ; 10 / 43
; --------------------- / 659 [next 672]
ld a, (de) ; 7 / 666
inc de ; 6 / 672
; 13th OUT
out ($fe), a ; 11 / 683 [672] [next 728]
; 14th value
ld a, (de) ; 7 / 690
inc de ; 6 / 696
ex af, af' ; 4 / 700
; 15th value
ld a, (de) ; 7 / 707
ld a, (de) ; 7 / 714
inc de ; 6 / 720
nop ; 4 / 724
; 14th OUT
ex af, af' ; 4 / 728
out ($fe), a ; 11 / 739 [728] [next 784]
; 16th value
ld a, (de) ; 7 / 746
ld a, (de) ; 7 / 753
ld c, a ; 4 / 757
; retrieve 15th value
ex af, af' ; 4 / 761
djnz out_continue ; 8 / 769 [774 taken]
pitch:
ld b, 0 ; 7 / 776
nop ; 4 / 780
nop ; 4 / 784
out ($fe), a ; 11 / 795 [784] [next 840]
jp mainloop ; 10 / 805
; ============================================
out_continue:
dec de ; 6 / 780
nop ; 4 / 784
out ($fe), a ; 11 / 795 [784] [next 840]
ld a, (de) ; 7 / 802
ld a, (de) ; 7 / 809
ld a, (de) ; 7 / 816
ld a, (de) ; 7 / 823
ld a, r ; 9 / 832
xor a ; 4 / 836
ld a, c ; 4 / 840
out ($fe), a ; 11 / 851
ret nz ; 5 / 856
jp out_loop ; 10 / 866
; ============================================
no_carry: ; / 828
nop ; 4 / 832
nop ; 4 / 836
ld a, c ; 4 / 840
out ($fe), a ; 11 / 851 [840] [next 896]
; waste time
ld de, 0 ; 10 / 861
ld a, (de) ; 7 / 868
ld a, (de) ; 7 / 875
ld a, (de) ; 7 / 882
ld a, (de) ; 7 / 889
ld a, 0 ; 7 / 896
out ($fe), a ; 11 / 11 [896] [0]
ld c, a ; 4 / 15
; ---------------------
time:
ld de, 0 ; 10 / 25
inc de ; 6 / 31
ld (time+1), de ; 20 / 51
ld a, d ; 4 / 55
and 15 ; 7 / 62
bit 4, d ; 8 / 70
jr nz, reverse_wave ; 7 / 77 [82 taken]
ld de, 0 ; 10 / 87
jp continue_wave ; 10 / 97
reverse_wave:
sub 15 ; 7 / 89
neg ; 8 / 97
continue_wave:
add a, a ; 4 / 101
add a, a ; 4 / 105
add a, a ; 4 / 109
add a, a ; 4 / 113
push hl ; 11 / 124
ld hl, pwm_table ; 10 / 134
ld d, 0 ; 7 / 141
ld e, a ; 4 / 145
add hl, de ; 11 / 156
ld (pwm_ptr+1), hl ; 16 / 172
pop hl ; 10 / 182
; ---------------------
ld a, 36 ; 7 / 189
; total time = 35 * (4 + 12) + (4 + 7) = 571
delay_loop: ;571 / 760
dec a
jr nz, delay_loop
ld de, 0 ; 10 / 770
ld de, 0 ; 10 / 780
xor a ; 4 / 784
out ($fe), a ; 11 / 795 [784] [next 840]
jp mainloop ; 10 / 805
pwm_table:
db 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0
db 16, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0
db 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0
db 16, 0, 0, 16, 0, 0, 16, 0, 0, 0, 16, 0, 0, 16, 0, 0
db 16, 0, 0, 16, 0, 16, 0, 0, 16, 0, 0, 16, 0, 16, 0, 0
db 16, 0, 16, 0, 0, 16, 0, 16, 0, 16, 0, 16, 0, 0, 16, 0
db 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0
db 16, 0, 16, 0, 16, 16, 0, 16, 0, 16, 0, 16, 16, 0, 16, 0
db 16, 0, 16, 16, 0, 16, 16, 0, 16, 0, 16, 16, 0, 16, 16, 0
db 16, 16, 0, 16, 16, 0, 16, 16, 0, 16, 16, 0, 16, 16, 0, 16
db 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16
db 16, 16, 16, 0, 16, 16, 16, 16, 0, 16, 16, 16, 16, 0, 16, 16
db 16, 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16
db 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16
db 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
Re: Short beeper routines in assembly
Ohhh that would be perfect if we can get rid of those extra tones. We're nearly on the desert island now, but with a pager going off in your rucksack.
I tried reducing some of the delays and 'waste times' and it reduced the tones a lot, and didn't really affect the wave noise itself (to my uneducated ear). It's still now there though. Putting it in contended memory didn't remove the tones, but changed them into a different sound that doesn't grate quite as much.
Brilliant work. I hope these noises spikes can be smoothed out.
Re: Short beeper routines in assembly
Interesting that reducing the delays helped. I tried to keep the time between OUTs a constant 56 T-states to ensure regular output - 56 is also a multiple of 8 to avoid IO contention. I assume that more irregular delays would reduce the harmonics but in turn raise the noise floor.
I think the problem may be due to how the OUTs are performed in groups of 16, so for values that don't divide 16 the resulting pulse wave is irregular. I don't know for sure though.
I think the problem may be due to how the OUTs are performed in groups of 16, so for values that don't divide 16 the resulting pulse wave is irregular. I don't know for sure though.
Re: Short beeper routines in assembly
If you put this after the two ld a, r instructions in the code posted by djnzx48, you can get some arcing power lines in the background:
Code: Select all
inc ix
ld a, (ix)
out ($fe), a
Re: Short beeper routines in assembly
You can get another "interesting" sound by also sticking
at the start of pwm_loop.
It sounds good assembled at about 50000.
Code: Select all
inc iy
ld c, (iy)
It sounds good assembled at about 50000.
Re: Short beeper routines in assembly
Any better?
Code: Select all
org 32768
main:
di
ld hl, 0
ld (volume+1), hl
ld hl, 0
ld (time+1), hl
ld hl, 0xC0DE
ld de, 0
ld b, 16
xor a
ld c, a
ld ixl, %00101101
jp mainloop_init
; ---------------------
; runtime = 10 * 56 + 51 = 611
pwm_loop: ; / 37
xor d ; 4 / 41 [/ 97]
add a, e ; 4 / 45 [/ 101]
ld d, a ; 4 / 49 [/ 105]
and 16 ; 7 / 56 [/ 112]
out ($fe), a ; 11 / 67 [ 56]
jp pwm_delay ; 10 / 77
pwm_delay:
dec c ; 4 / 81
jr nz, pwm_loop ; 12 / 93 [taken]
;611 / 648
; ---------------------
xor d ; 4 / 652
add a, e ; 4 / 656
ld d, a ; 4 / 660
and 16 ; 7 / 667
ret c ; 5 / 672
; ---------------------
out ($fe), a ; 11 / 683 ; OUT 12
xor d ; 4 / 687
add a, e ; 4 / 691
ld d, a ; 4 / 695
and b ; 4 / 699 ; OUT 13 value
ld c, a ; 4 / 703
xor d ; 4 / 707
add a, e ; 4 / 711
ld d, a ; 4 / 715
ld a, r ; 9 / 724
ld a, c ; 4 / 728 ; OUT 13 value
; ---------------------
out ($fe), a ; 11 / 739 ; OUT 13
ld a, d ; 4 / 743
and b ; 4 / 747 ; OUT 14 value
ld c, a ; 4 / 751
xor d ; 4 / 755
add a, e ; 4 / 759
ld d, a ; 4 / 763
and b ; 4 / 767 ; OUT 15 value
ld e, a ; 4 / 771
ld a, r ; 9 / 780
ld a, c ; 4 / 784 ; OUT 14 value
out ($fe), a ; 11 / 795 [784] [next 840]
ld a, e ; 4 / 799
xor d ; 4 / 803
; 2 spare T-states!
mainloop_init:
add hl, hl ; 11 / 816
jr nc, no_carry ; 7 / 823 [828 taken]
ld (volume+2), a ; 13 / 836
mainloop:
ld a, e ; 4 / 840
out ($fe), a ; 11 / 851 [840] [next 896]
ld a, l ; 4 / 855
xor ixl ; 8 / 863
ld l, a ; 4 / 867
; OUTs:
;
; 0 0
; 1 56
; 2 112
; 3 168
; 4 224
; 5 280
; 6 336
; 7 392
; 8 448
; 9 504
; 10 560
; 11 616
; 12 672
; 13 728
; 14 784
; 15 840
; ---------
; 16 896
out_loop:
volume:
ld de, 0 ; 10 / 877
; ---------------------
ld a, d ; 4 / 881
add a, e ; 4 / 885
ld d, a ; 4 / 889
and 16 ; 7 / 896
; OUT 0
out ($fe), a ; 11 / 11 [896] [0]
ld a, r ; 9 / 20
ld c, 11 ; 7 / 27
jp pwm_loop ; 10 / 37
; ============================================
no_carry: ; / 828
nop ; 4 / 832
ex af, af' ; 4 / 836
ld a, e ; 4 / 840
out ($fe), a ; 11 / 851 [840] [next 896]
ex af, af' ; 4 / 855
ld (volume+2), a ; 13 / 868
ld a, 0 ; 7 / 875
ld a, 0 ; 7 / 882
ld a, 0 ; 7 / 889
ld a, 0 ; 7 / 896
out ($fe), a ; 11 / 11 [896] [0]
ld c, a ; 4 / 15
; ---------------------
time:
ld de, 0 ; 10 / 25
inc de ; 6 / 31
ld (time+1), de ; 20 / 51
ld a, d ; 4 / 55
and 15 ; 7 / 62
bit 4, d ; 8 / 70
jr nz, reverse_wave ; 7 / 77 [82 taken]
ld de, 0 ; 10 / 87
jp continue_wave ; 10 / 97
reverse_wave:
sub 15 ; 7 / 89
neg ; 8 / 97
continue_wave:
inc a ; 4 / 101
ld (volume+1), a ; 13 / 114
; ---------------------
ld a, 41 ; 7 / 121
; total time = 40 * (4 + 12) + (4 + 7) = 651
delay_loop: ;651 / 772
dec a
jr nz, delay_loop
nop ; 4 / 776
xor a ; 4 / 780
ld e, a ; 4 / 784
out ($fe), a ; 11 / 795 [784] [next 840]
jp extra_delay ; 19 / 805
extra_delay:
add hl, hl ; 11 / 816
jr nc, no_carry ; 7 / 823 [828 taken]
jp mainloop ; 10 / 836
Re: Short beeper routines in assembly
It's incredible. And 176 bytes. Hell.
I see the code is very different. There is the slightest memory of the ghost sounds from before, but they wouldn't even be noticed (and even if they were, they could be taken as soothing) if this was the first iteration. Do I take it that you understand what was causing the spikes previously?
How do you do it?!
Re: Short beeper routines in assembly
No idea. All I did was replace the table I was using previously with dynamically calculated values.
Re: Short beeper routines in assembly
Slightly reassuring!
I haven't pulled it apart yet, but it looks like there's extra code too. Anyway, it's a brilliant piece of work.All I did was replace the table I was using previously with dynamically calculated values.
Re: Short beeper routines in assembly
Hi. By any chance, does anyone have idea how to produce a metal (ish) sound on beeper ? Something like when two swords clash each other. I cannot afford sample due memory limits.
Proud owner of Didaktik M
Re: Short beeper routines in assembly
I don't have a routine, but the helmet sound when you die in Firelord might be a good one to steal borrow...
My Speccy site: thirdharmoniser.com
Re: Short beeper routines in assembly
I know what you mean but I failed (twice) to extract the routine. I may give it another try.
Proud owner of Didaktik M
-
- Dizzy
- Posts: 85
- Joined: Thu May 02, 2019 10:22 pm
- Contact:
Re: Short beeper routines in assembly
utz wrote: ↑Thu Nov 16, 2017 11:05 pmYeah, that's actually one of the things that I really like about the beeper. You can just throw almost random code at it and it will often do something interesting.
Anyway, here's a simple laser effect in 13 bytes. By initializing D with different values, you can control the length. 0x28 is approximately one full zap.Code: Select all
di ld d,#28 ;length/iterations loop add hl,de dec de ld a,h out (#fe),a ld a,e or d jr nz,loop ei ret
Hello,
I have used the "simple laser effect in 13 bytes" in a project related to a Jet Set Willy remake (to be released in early March if all goes well).
I want to give due credit in the Readme.
At the moment I can credit it as created by "utz". Utz, would you like to be credited in any other way? (like by your real name, for example). Please let me know .
Website: JSW Central
Re: Short beeper routines in assembly
Very kind of you wanting to credit me for this Just "utz" is fine, or if you like you could throw in a link to my website, https://irrlichtproject.de.
-
- Dizzy
- Posts: 85
- Joined: Thu May 02, 2019 10:22 pm
- Contact:
Re: Short beeper routines in assembly
Thank you . I will do as you suggest. When the game is released a month from now (if all goes well), apart from an announcement in the proper place on this forum I will also post a message here to give you the link so that you can see your code in action.
Website: JSW Central
-
- Dizzy
- Posts: 85
- Joined: Thu May 02, 2019 10:22 pm
- Contact:
Re: Short beeper routines in assembly
And so here it is, the game in which utz's "laser effect" routine has been used: "Madam Blavskja's Carnival Macabre 48K", a (slightly enhanced) port of Fabián Álvarez López (Adban de Corcy's) classic 128K Jet Set Willy game to 48K.
Utz is duly credited in Section II "Acknowledgements and thanks" of the Readme included in the ZIP file with said game. The laser effect, which is used in the game twice (in different ways), is then dissassembled (with a link to this thread) in Subsection 3 ("Playing the original game or with extra rooms") of Section X "Technical notes" of the Readme, and again in Subsection 6 ("Custom-made title screen") of Section X of the Readme. It is also mentioned in Subsection 19 ("Memory layout") of Section X, where it is indicated where the code which operates it resides in memory.
The ZIP with the game file (if you want to see the laser effect in action, besides discovering various other facets of this atmospheric JSW game, or if you want to have a look at its references in the Readme) can be downloaded freely e.g. from here.
Utz is duly credited in Section II "Acknowledgements and thanks" of the Readme included in the ZIP file with said game. The laser effect, which is used in the game twice (in different ways), is then dissassembled (with a link to this thread) in Subsection 3 ("Playing the original game or with extra rooms") of Section X "Technical notes" of the Readme, and again in Subsection 6 ("Custom-made title screen") of Section X of the Readme. It is also mentioned in Subsection 19 ("Memory layout") of Section X, where it is indicated where the code which operates it resides in memory.
The ZIP with the game file (if you want to see the laser effect in action, besides discovering various other facets of this atmospheric JSW game, or if you want to have a look at its references in the Readme) can be downloaded freely e.g. from here.
Website: JSW Central
Re: Short beeper routines in assembly
Can anyone help with a short bit of asm code that sounds vaguely like the whistling sound of something falling?
It needs to be less than a frame, and perhaps can be CALLed with a different value so that the whistle can change in tone (or should that be pitch?) as the ground approaches.
It needs to be less than a frame, and perhaps can be CALLed with a different value so that the whistle can change in tone (or should that be pitch?) as the ground approaches.