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