mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-06-07 11:29:33 +00:00
APU fixed
* Fixed type that caused triangle linear counter to be ignored * Changed sweep to shift the current period, not the register value * Moved muting logic early to avoid setting DOC registers when not needed
This commit is contained in:
parent
8011f268a2
commit
bdb4006e22
359
demos/smb/apu.s
359
demos/smb/apu.s
|
@ -105,6 +105,9 @@ copy_instruments_to_doc
|
||||||
|
|
||||||
lda #$0500
|
lda #$0500
|
||||||
jsr copy_triangle
|
jsr copy_triangle
|
||||||
|
|
||||||
|
lda #$0600
|
||||||
|
jsr copy_noise
|
||||||
rts
|
rts
|
||||||
|
|
||||||
;--------------------------
|
;--------------------------
|
||||||
|
@ -190,6 +193,24 @@ copy_triangle
|
||||||
mx %00
|
mx %00
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
copy_noise
|
||||||
|
sep #$30
|
||||||
|
mx %11
|
||||||
|
|
||||||
|
stz sound_address
|
||||||
|
xba
|
||||||
|
sta sound_address+1
|
||||||
|
|
||||||
|
ldx #0
|
||||||
|
:loop
|
||||||
|
lda noise_wave,x
|
||||||
|
sta sound_data
|
||||||
|
inx
|
||||||
|
bne :loop
|
||||||
|
|
||||||
|
rep #$30
|
||||||
|
mx %00
|
||||||
|
rts
|
||||||
;--------------------------
|
;--------------------------
|
||||||
|
|
||||||
triangle_wave
|
triangle_wave
|
||||||
|
@ -210,6 +231,23 @@ triangle_wave
|
||||||
hex 41424446484a4c4e50525456585a5c5e
|
hex 41424446484a4c4e50525456585a5c5e
|
||||||
hex 60626466686a6c6e70727476787a7c7e
|
hex 60626466686a6c6e70727476787a7c7e
|
||||||
|
|
||||||
|
noise_wave
|
||||||
|
hex 8f968f763e6fd49ab1e564e295a9bcc9
|
||||||
|
hex 717b6629e6970b865dc0e0d840d32a96
|
||||||
|
hex 3bd4c5d407b78923d8c9766bea128e8a
|
||||||
|
hex c9ee5ddbed3119ff14b4d9a44bfbb7c4
|
||||||
|
hex 7a56e26e8aac9ebf1653c0260446231b
|
||||||
|
hex 73431495fc585e943edacf8f5bb970e6
|
||||||
|
hex 118dc361bee99c98f32d25f06a33715a
|
||||||
|
hex 585344f7f3e2f3c36c37cfd78e40147f
|
||||||
|
hex a4b20624ac633b42b3aac5407fac4ba9
|
||||||
|
hex a4d71a1d020a7757ea244b103f0b7a76
|
||||||
|
hex 9b533a60cda31e0fa2ce3491b55c4f26
|
||||||
|
hex ea47a61f661deec128129372c3471a9b
|
||||||
|
hex f85c3c077168d413184a139440460950
|
||||||
|
hex dee3f9bdb65e162b08ed9231a72fb943
|
||||||
|
hex 1ba599be80dc2812afa63cc2317cdb1a
|
||||||
|
hex 8d99d56327bc50dc975bee94754f561b
|
||||||
;--------------------------
|
;--------------------------
|
||||||
|
|
||||||
setup_doc_registers
|
setup_doc_registers
|
||||||
|
@ -227,6 +265,9 @@ setup_doc_registers
|
||||||
ldx #triangle_sound_settings
|
ldx #triangle_sound_settings
|
||||||
jsr copy_register_config
|
jsr copy_register_config
|
||||||
|
|
||||||
|
ldx #noise_sound_settings
|
||||||
|
jsr copy_register_config
|
||||||
|
|
||||||
rep #$20
|
rep #$20
|
||||||
mx %00
|
mx %00
|
||||||
|
|
||||||
|
@ -295,7 +336,8 @@ timer_sound_settings = * ; set up oscillator 30 for i
|
||||||
pulse1_oscillator = 0
|
pulse1_oscillator = 0
|
||||||
pulse2_oscillator = 2
|
pulse2_oscillator = 2
|
||||||
triangle_oscillator = 4
|
triangle_oscillator = 4
|
||||||
default_freq = 5000
|
noise_oscillator = 6
|
||||||
|
default_freq = 800
|
||||||
pulse1_sound_settings = *
|
pulse1_sound_settings = *
|
||||||
dfb $00+pulse1_oscillator,default_freq ; frequency low register
|
dfb $00+pulse1_oscillator,default_freq ; frequency low register
|
||||||
dfb $20+pulse1_oscillator,default_freq/256 ; frequency high register
|
dfb $20+pulse1_oscillator,default_freq/256 ; frequency high register
|
||||||
|
@ -320,6 +362,14 @@ triangle_sound_settings = *
|
||||||
dfb $c0+triangle_oscillator,0 ; wavetable size register, 256 byte length
|
dfb $c0+triangle_oscillator,0 ; wavetable size register, 256 byte length
|
||||||
dfb $a0+triangle_oscillator,0 ; mode register, set to free run
|
dfb $a0+triangle_oscillator,0 ; mode register, set to free run
|
||||||
|
|
||||||
|
noise_sound_settings = *
|
||||||
|
dfb $00+noise_oscillator,default_freq ; frequency low register
|
||||||
|
dfb $20+noise_oscillator,default_freq/256 ; frequency high register
|
||||||
|
dfb $40+noise_oscillator,128 ; volume register, volume = 0
|
||||||
|
dfb $80+noise_oscillator,6 ; wavetable pointer register, point to $0600
|
||||||
|
dfb $c0+noise_oscillator,0 ; wavetable size register, 256 byte length
|
||||||
|
dfb $a0+noise_oscillator,0 ; mode register, set to free run
|
||||||
|
|
||||||
backup_interrupt_ptr ds 4
|
backup_interrupt_ptr ds 4
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------------------
|
||||||
|
@ -365,9 +415,9 @@ clock_sweep mac
|
||||||
sta ]1+{APU_PULSE1_RELOAD_FLAG-APU_PULSE1}
|
sta ]1+{APU_PULSE1_RELOAD_FLAG-APU_PULSE1}
|
||||||
|
|
||||||
lda ]1+{APU_PULSE1_REG2-APU_PULSE1} ; get the barrel shift argument from the register
|
lda ]1+{APU_PULSE1_REG2-APU_PULSE1} ; get the barrel shift argument from the register
|
||||||
bpl no_sweep ; if sweep is not enabled, do nothing
|
bpl no_sweep ; if sweep is not enabled, do nothing
|
||||||
and #$07
|
and #$07
|
||||||
beq no_sweep ; shift must be != 0
|
beq no_sweep ; shift must be != 0
|
||||||
asl
|
asl
|
||||||
tax
|
tax
|
||||||
|
|
||||||
|
@ -379,10 +429,7 @@ clock_sweep mac
|
||||||
lda ]1+{APU_PULSE1_CURRENT_PERIOD-APU_PULSE1}
|
lda ]1+{APU_PULSE1_CURRENT_PERIOD-APU_PULSE1}
|
||||||
cmp #8
|
cmp #8
|
||||||
bcc no_sweep0 ; current period must be >= 8
|
bcc no_sweep0 ; current period must be >= 8
|
||||||
|
jmp (bitshift,x) ; shift it by the shifter amount
|
||||||
lda ]1+{APU_PULSE1_REG3-APU_PULSE1} ; raw period stored in the register
|
|
||||||
and #$7FF
|
|
||||||
jmp (bitshift,x) ; shift it by the shifter amount
|
|
||||||
bitshift da bitshift_0,bitshift_1,bitshift_2,bitshift_3,bitshift_4,bitshift_5,bitshift_6,bitshift_7
|
bitshift da bitshift_0,bitshift_1,bitshift_2,bitshift_3,bitshift_4,bitshift_5,bitshift_6,bitshift_7
|
||||||
bitshift_7 lsr
|
bitshift_7 lsr
|
||||||
bitshift_6 lsr
|
bitshift_6 lsr
|
||||||
|
@ -400,21 +447,9 @@ bitshift_0
|
||||||
FIN
|
FIN
|
||||||
no_negate clc
|
no_negate clc
|
||||||
adc ]1+{APU_PULSE1_CURRENT_PERIOD-APU_PULSE1}
|
adc ]1+{APU_PULSE1_CURRENT_PERIOD-APU_PULSE1}
|
||||||
sta ]1+{APU_PULSE1_TARGET_PERIOD-APU_PULSE1}
|
|
||||||
|
|
||||||
stz ]1+{APU_PULSE1_MUTE-APU_PULSE1}
|
|
||||||
ldy #1
|
|
||||||
cmp #$800
|
cmp #$800
|
||||||
bcc *+5
|
bcs no_sweep0
|
||||||
sty ]1+{APU_PULSE1_MUTE-APU_PULSE1} ; mute the output is the period is too large
|
sta ]1+{APU_PULSE1_CURRENT_PERIOD-APU_PULSE1}
|
||||||
bcs *+5
|
|
||||||
sta ]1+{APU_PULSE1_CURRENT_PERIOD-APU_PULSE1} ; set the current period if the target is within a valid range
|
|
||||||
|
|
||||||
lda ]1+{APU_PULSE1_CURRENT_PERIOD-APU_PULSE1}
|
|
||||||
cmp #8
|
|
||||||
bcs *+5
|
|
||||||
sty ]1+{APU_PULSE1_MUTE-APU_PULSE1} ; mute the output if the period is too small
|
|
||||||
|
|
||||||
no_sweep0
|
no_sweep0
|
||||||
sep #$20
|
sep #$20
|
||||||
no_sweep
|
no_sweep
|
||||||
|
@ -469,11 +504,19 @@ envelope_out <<<
|
||||||
|
|
||||||
apu_frame_steps equ 5
|
apu_frame_steps equ 5
|
||||||
PULSE_HALT_FLAG equ $20
|
PULSE_HALT_FLAG equ $20
|
||||||
|
NOISE_HALT_FLAG equ $20 ; noise and pulse channels have halt flagin same bit position in REG1
|
||||||
PULSE_CONST_VOL_FLAG equ $10
|
PULSE_CONST_VOL_FLAG equ $10
|
||||||
|
NOISE_CONST_VOL_FLAG equ $10
|
||||||
TRIANGLE_HALT_FLAG equ $80
|
TRIANGLE_HALT_FLAG equ $80
|
||||||
|
|
||||||
|
mx %11
|
||||||
interrupt_handler = *
|
interrupt_handler = *
|
||||||
|
|
||||||
|
ldal $E0C034 ; save the border color
|
||||||
|
stal border_color
|
||||||
|
lda #1
|
||||||
|
jsr setborder
|
||||||
|
|
||||||
phb
|
phb
|
||||||
phd
|
phd
|
||||||
|
|
||||||
|
@ -482,14 +525,17 @@ interrupt_handler = *
|
||||||
|
|
||||||
clc
|
clc
|
||||||
xce
|
xce
|
||||||
rep #$30
|
|
||||||
mx %00
|
|
||||||
|
|
||||||
lda #$c000
|
pea $c000
|
||||||
tcd
|
pld
|
||||||
|
|
||||||
sep #$30
|
; Make sure it's the oscillator we care about
|
||||||
mx %11
|
|
||||||
|
ldal osc_interrupt ; which oscillator generated the interrupt?
|
||||||
|
and #%00111110
|
||||||
|
cmp #2*interrupt_oscillator
|
||||||
|
beq *+5
|
||||||
|
brl :not_timer ; Only service timer interrupts
|
||||||
|
|
||||||
; Update the frame counter. We double-count so that frame counter can be used directly to dispatch to the
|
; Update the frame counter. We double-count so that frame counter can be used directly to dispatch to the
|
||||||
; appropriate tick handler
|
; appropriate tick handler
|
||||||
|
@ -509,12 +555,13 @@ interrupt_handler = *
|
||||||
clock_length_counter APU_PULSE1;#PULSE_HALT_FLAG
|
clock_length_counter APU_PULSE1;#PULSE_HALT_FLAG
|
||||||
clock_length_counter APU_PULSE2;#PULSE_HALT_FLAG
|
clock_length_counter APU_PULSE2;#PULSE_HALT_FLAG
|
||||||
clock_length_counter APU_TRIANGLE;#TRIANGLE_HALT_FLAG
|
clock_length_counter APU_TRIANGLE;#TRIANGLE_HALT_FLAG
|
||||||
|
clock_length_counter APU_NOISE;#NOISE_HALT_FLAG
|
||||||
|
|
||||||
; clock the sweep units
|
; clock the sweep units
|
||||||
clock_sweep APU_PULSE1;0
|
clock_sweep APU_PULSE1;0
|
||||||
clock_sweep APU_PULSE2;1
|
clock_sweep APU_PULSE2;1
|
||||||
|
|
||||||
; quarter frame updates run every APU frame (for 4-cycle)
|
; quarter frame updates run every APU frame
|
||||||
:quarter_frame
|
:quarter_frame
|
||||||
|
|
||||||
; clock the envelopes and triangle linear counter
|
; clock the envelopes and triangle linear counter
|
||||||
|
@ -522,43 +569,24 @@ interrupt_handler = *
|
||||||
|
|
||||||
clock_envelope APU_PULSE1
|
clock_envelope APU_PULSE1
|
||||||
clock_envelope APU_PULSE2
|
clock_envelope APU_PULSE2
|
||||||
|
clock_envelope APU_NOISE
|
||||||
|
|
||||||
:no_frame
|
:no_frame
|
||||||
jsr access_doc_registers
|
jsr access_doc_registers
|
||||||
|
|
||||||
ldal osc_interrupt ; which oscillator generated the interrupt?
|
; Set the parameters for the first square wave channel.
|
||||||
and #%00111110
|
;
|
||||||
lsr
|
; First, set the frequency, if the period is <8 then the pulse channel is muted,
|
||||||
cmp #interrupt_oscillator
|
; to test that first
|
||||||
beq *+5
|
|
||||||
brl :not_timer ; Only service timer interrupts
|
|
||||||
|
|
||||||
; Set the parameters for the first square wave channel
|
|
||||||
|
|
||||||
lda #$80+pulse1_oscillator
|
|
||||||
sta sound_address
|
|
||||||
lda APU_PULSE1_REG1 ; Get the cycle duty bits
|
|
||||||
jsr set_pulse_duty_cycle
|
|
||||||
|
|
||||||
lda #$40+pulse1_oscillator
|
|
||||||
sta sound_address
|
|
||||||
|
|
||||||
lda APU_PULSE1_MUTE ; If the sweep muted the channel, no output
|
lda APU_PULSE1_MUTE ; If the sweep muted the channel, no output
|
||||||
beq :no_mute_pulse1
|
bne :mute_pulse1
|
||||||
lda #0
|
|
||||||
bra :set_volume_pulse1
|
|
||||||
:no_mute_pulse1
|
|
||||||
lda APU_PULSE1_LENGTH_COUNTER ; If the length counter is zero, no output
|
lda APU_PULSE1_LENGTH_COUNTER ; If the length counter is zero, no output
|
||||||
beq :set_volume_pulse1
|
beq :mute_pulse1
|
||||||
lda APU_PULSE1_REG1
|
|
||||||
bit #PULSE_CONST_VOL_FLAG ; Check the constant volume bit
|
|
||||||
bne :set_volume_pulse1
|
|
||||||
lda APU_PULSE1_ENVELOPE
|
|
||||||
:set_volume_pulse1
|
|
||||||
jsr set_pulse_volume
|
|
||||||
|
|
||||||
rep #$30
|
rep #$30
|
||||||
lda APU_PULSE1_CURRENT_PERIOD
|
lda APU_PULSE1_CURRENT_PERIOD
|
||||||
|
cmp #8
|
||||||
|
bcc :mute_pulse1
|
||||||
|
|
||||||
jsr get_pulse_freq ; return freq in 16-bit accumulator
|
jsr get_pulse_freq ; return freq in 16-bit accumulator
|
||||||
sep #$30
|
sep #$30
|
||||||
ldx #$00+pulse1_oscillator
|
ldx #$00+pulse1_oscillator
|
||||||
|
@ -569,32 +597,36 @@ interrupt_handler = *
|
||||||
xba
|
xba
|
||||||
sta sound_data
|
sta sound_data
|
||||||
|
|
||||||
; Now do the second square wave
|
lda #$80+pulse1_oscillator
|
||||||
|
|
||||||
lda #$80+pulse2_oscillator
|
|
||||||
sta sound_address
|
sta sound_address
|
||||||
lda APU_PULSE2_REG1 ; Get the cycle duty bits
|
lda APU_PULSE1_REG1 ; Get the cycle duty bits
|
||||||
jsr set_pulse_duty_cycle
|
jsr set_pulse_duty_cycle
|
||||||
|
|
||||||
lda #$40+pulse2_oscillator
|
lda #$40+pulse1_oscillator
|
||||||
sta sound_address
|
sta sound_address
|
||||||
|
lda APU_PULSE1_REG1
|
||||||
|
bit #PULSE_CONST_VOL_FLAG ; Check the constant volume bit
|
||||||
|
bne :set_volume_pulse1
|
||||||
|
lda APU_PULSE1_ENVELOPE
|
||||||
|
bra :set_volume_pulse1
|
||||||
|
|
||||||
lda APU_PULSE2_MUTE ; If the sweep muted the channel, no output
|
:mute_pulse1
|
||||||
beq :no_mute_pulse2
|
sep #$30
|
||||||
|
lda #$40+pulse1_oscillator
|
||||||
|
sta sound_address
|
||||||
lda #0
|
lda #0
|
||||||
bra :set_volume_pulse2
|
:set_volume_pulse1 jsr set_pulse_volume
|
||||||
:no_mute_pulse2
|
|
||||||
lda APU_PULSE2_LENGTH_COUNTER ; If the length counter is zero, no output
|
|
||||||
beq :set_volume_pulse2
|
|
||||||
lda APU_PULSE2_REG1
|
|
||||||
bit #PULSE_CONST_VOL_FLAG ; Check the constant volume bit
|
|
||||||
bne :set_volume_pulse2
|
|
||||||
lda APU_PULSE2_ENVELOPE
|
|
||||||
:set_volume_pulse2
|
|
||||||
jsr set_pulse_volume
|
|
||||||
|
|
||||||
|
; Now do the second square wave
|
||||||
|
lda APU_PULSE2_MUTE ; If the sweep muted the channel, no output
|
||||||
|
bne :mute_pulse2
|
||||||
|
lda APU_PULSE2_LENGTH_COUNTER ; If the length counter is zero, no output
|
||||||
|
beq :mute_pulse2
|
||||||
rep #$30
|
rep #$30
|
||||||
lda APU_PULSE2_CURRENT_PERIOD
|
lda APU_PULSE2_CURRENT_PERIOD
|
||||||
|
cmp #8
|
||||||
|
bcc :mute_pulse2
|
||||||
|
|
||||||
jsr get_pulse_freq ; return freq in 16-bic accumulator
|
jsr get_pulse_freq ; return freq in 16-bic accumulator
|
||||||
sep #$30
|
sep #$30
|
||||||
ldx #$00+pulse2_oscillator
|
ldx #$00+pulse2_oscillator
|
||||||
|
@ -605,25 +637,48 @@ interrupt_handler = *
|
||||||
xba
|
xba
|
||||||
sta sound_data
|
sta sound_data
|
||||||
|
|
||||||
; Now the triangle wave. This wave needs linear counter support to be silenced
|
lda #$80+pulse2_oscillator
|
||||||
; brl :not_timer
|
|
||||||
|
|
||||||
lda #$40+triangle_oscillator
|
|
||||||
sta sound_address
|
sta sound_address
|
||||||
lda APU_TRIANGLE_LENGTH_COUNTER ; If the length counter is zero, no output
|
lda APU_PULSE2_REG1 ; Get the cycle duty bits
|
||||||
beq :set_volume_triangle
|
jsr set_pulse_duty_cycle
|
||||||
lda APU_TRIANGLE_LENGTH_COUNTER
|
|
||||||
beq :set_volume_triangle
|
|
||||||
lda #12 ; Triangle is a bit softer than pulse channels
|
|
||||||
:set_volume_triangle
|
|
||||||
jsr set_pulse_volume
|
|
||||||
|
|
||||||
|
lda #$40+pulse2_oscillator
|
||||||
|
sta sound_address
|
||||||
|
lda APU_PULSE2_REG1
|
||||||
|
bit #PULSE_CONST_VOL_FLAG ; Check the constant volume bit
|
||||||
|
bne :set_volume_pulse2
|
||||||
|
lda APU_PULSE2_ENVELOPE
|
||||||
|
bra :set_volume_pulse2
|
||||||
|
:mute_pulse2
|
||||||
|
sep #$30
|
||||||
|
lda #$40+pulse2_oscillator
|
||||||
|
sta sound_address
|
||||||
|
lda #0
|
||||||
|
:set_volume_pulse2 jsr set_pulse_volume
|
||||||
|
|
||||||
|
; Now the triangle wave. This wave needs linear counter support to be silenced
|
||||||
|
|
||||||
|
lda APU_TRIANGLE_LENGTH_COUNTER ; If the length counter is zero, no output
|
||||||
|
beq :mute_triangle
|
||||||
|
lda APU_TRIANGLE_LINEAR_COUNTER ; If the linear counter is zero, no output
|
||||||
|
beq :mute_triangle
|
||||||
rep #$30
|
rep #$30
|
||||||
lda APU_TRIANGLE_REG3
|
lda APU_TRIANGLE_CURRENT_PERIOD
|
||||||
|
cmp #2
|
||||||
|
bcc :mute_triangle
|
||||||
|
|
||||||
|
; NOTE on Triangle channel frequence from https://www.nesdev.org/wiki/APU_Triangle
|
||||||
|
;
|
||||||
|
; Unlike the pulse channels, the triangle channel supports frequencies up to the maximum frequency the
|
||||||
|
; timer will allow, meaning frequencies up to fCPU/32 (about 55.9 kHz for NTSC) are possible - far above
|
||||||
|
; the audible range. Some games, e.g. Mega Man 2, "silence" the triangle channel by setting the timer to
|
||||||
|
; zero, which produces a popping sound when an audible frequency is resumed, easily heard e.g. in Crash
|
||||||
|
; Man's stage. At the expense of accuracy, these can be eliminated in an emulator e.g. by halting the
|
||||||
|
; triangle channel when an ultrasonic frequency is set (a timer value less than 2).
|
||||||
|
|
||||||
jsr get_pulse_freq ; return freq in 16-bic accumulator
|
jsr get_pulse_freq ; return freq in 16-bic accumulator
|
||||||
lsr
|
lsr
|
||||||
sep #$30
|
sep #$30
|
||||||
|
|
||||||
ldx #$00+triangle_oscillator
|
ldx #$00+triangle_oscillator
|
||||||
stx sound_address
|
stx sound_address
|
||||||
sta sound_data
|
sta sound_data
|
||||||
|
@ -632,14 +687,50 @@ interrupt_handler = *
|
||||||
xba
|
xba
|
||||||
sta sound_data
|
sta sound_data
|
||||||
|
|
||||||
; lda border_color
|
lda #$40+triangle_oscillator
|
||||||
; inc
|
sta sound_address
|
||||||
; and #$03
|
lda #12 ; Triangle is a bit softer than pulse channels
|
||||||
; sta border_color
|
bra :set_volume_triangle
|
||||||
; jsr setborder
|
|
||||||
|
:mute_triangle
|
||||||
|
sep #$30
|
||||||
|
lda #$40+triangle_oscillator
|
||||||
|
sta sound_address
|
||||||
|
lda #0
|
||||||
|
:set_volume_triangle jsr set_pulse_volume
|
||||||
|
|
||||||
|
; Now the noise channel. It's mixer volume output is ~half of the pulse channels
|
||||||
|
|
||||||
|
lda #$40+noise_oscillator
|
||||||
|
sta sound_address
|
||||||
|
|
||||||
|
lda APU_NOISE_LENGTH_COUNTER ; If the length counter is zero, no output
|
||||||
|
beq :set_volume_noise
|
||||||
|
lda APU_NOISE_REG1
|
||||||
|
bit #NOISE_CONST_VOL_FLAG ; Check the constant volume bit
|
||||||
|
bne :set_volume_noise
|
||||||
|
lda APU_NOISE_ENVELOPE
|
||||||
|
:set_volume_noise
|
||||||
|
jsr set_pulse_volume
|
||||||
|
|
||||||
|
rep #$30
|
||||||
|
lda APU_NOISE_CURRENT_PERIOD
|
||||||
|
jsr get_pulse_freq ; return freq in 16-bic accumulator
|
||||||
|
sep #$30
|
||||||
|
|
||||||
|
ldx #$00+noise_oscillator
|
||||||
|
stx sound_address
|
||||||
|
sta sound_data
|
||||||
|
ldx #$20+noise_oscillator
|
||||||
|
stx sound_address
|
||||||
|
xba
|
||||||
|
sta sound_data
|
||||||
|
|
||||||
:not_timer
|
:not_timer
|
||||||
sep #$30
|
sep #$30
|
||||||
|
lda #0
|
||||||
|
jsr setborder
|
||||||
|
|
||||||
pld
|
pld
|
||||||
plb
|
plb
|
||||||
clc
|
clc
|
||||||
|
@ -819,6 +910,23 @@ APU_TRIANGLE_CURRENT_PERIOD dw 0
|
||||||
APU_TRIANGLE_START_FLAG dfb 0
|
APU_TRIANGLE_START_FLAG dfb 0
|
||||||
APU_TRIANGLE_LINEAR_COUNTER dfb 0
|
APU_TRIANGLE_LINEAR_COUNTER dfb 0
|
||||||
|
|
||||||
|
|
||||||
|
APU_NOISE
|
||||||
|
APU_NOISE_REG1 ds 1 ; --LC NNNN - length counter halt, constant volume/evelope, envelope period/volume
|
||||||
|
APU_NOISE_REG2 ds 1 ; ---- ---- - Unused
|
||||||
|
APU_NOISE_REG3 ds 1 ; M--- PPPP - Mode and period lookup
|
||||||
|
APU_NOISE_REG4 ds 1 ; llll l--- - Length counter load
|
||||||
|
|
||||||
|
APU_NOISE_LENGTH_COUNTER dfb 0 ; internal register for the length counter
|
||||||
|
APU_NOISE_RELOAD_FLAG dfb 0 ; unused
|
||||||
|
APU_NOISE_SWEEP_DIVIDER dfb 0 ; unused
|
||||||
|
APU_NOISE_TARGET_PERIOD dw 0 ; unused
|
||||||
|
APU_NOISE_CURRENT_PERIOD dw 0 ; internal register to hold the current period driving the oscillator
|
||||||
|
APU_NOISE_MUTE dfb 0 ; unused
|
||||||
|
APU_NOISE_START_FLAG dfb 0
|
||||||
|
APU_NOISE_ENVELOPE_DIVIDER dfb 0
|
||||||
|
APU_NOISE_ENVELOPE dfb 0
|
||||||
|
|
||||||
APU_STATUS ds 1
|
APU_STATUS ds 1
|
||||||
|
|
||||||
mx %11
|
mx %11
|
||||||
|
@ -906,7 +1014,7 @@ APU_PULSE2_REG4_WRITE ENT
|
||||||
stal APU_PULSE2_CURRENT_PERIOD+1
|
stal APU_PULSE2_CURRENT_PERIOD+1
|
||||||
|
|
||||||
ldal APU_STATUS
|
ldal APU_STATUS
|
||||||
bit #$01
|
bit #$02
|
||||||
beq :no_reload
|
beq :no_reload
|
||||||
|
|
||||||
ldal APU_PULSE2_REG4
|
ldal APU_PULSE2_REG4
|
||||||
|
@ -971,6 +1079,65 @@ APU_TRIANGLE_REG4_WRITE ENT
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
|
|
||||||
|
APU_NOISE_REG1_WRITE ENT
|
||||||
|
stal APU_NOISE_REG1
|
||||||
|
rtl
|
||||||
|
|
||||||
|
APU_NOISE_REG2_WRITE ENT
|
||||||
|
stal APU_NOISE_REG2
|
||||||
|
rtl
|
||||||
|
|
||||||
|
APU_NOISE_REG3_WRITE ENT
|
||||||
|
php
|
||||||
|
phx
|
||||||
|
pha
|
||||||
|
|
||||||
|
stal APU_NOISE_REG3
|
||||||
|
and #$0F
|
||||||
|
asl
|
||||||
|
tax
|
||||||
|
ldal NoisePeriodTable,x
|
||||||
|
sta APU_NOISE_CURRENT_PERIOD
|
||||||
|
ldal NoisePeriodTable+1,x
|
||||||
|
sta APU_NOISE_CURRENT_PERIOD+1
|
||||||
|
|
||||||
|
pla
|
||||||
|
plx
|
||||||
|
plp
|
||||||
|
rtl
|
||||||
|
|
||||||
|
APU_NOISE_REG4_WRITE ENT
|
||||||
|
php
|
||||||
|
phx
|
||||||
|
pha
|
||||||
|
|
||||||
|
stal APU_NOISE_REG4
|
||||||
|
|
||||||
|
ldal APU_STATUS
|
||||||
|
bit #$08
|
||||||
|
beq :no_reload
|
||||||
|
|
||||||
|
ldal APU_NOISE_REG4
|
||||||
|
and #$F8
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
tax
|
||||||
|
ldal LengthTable,x
|
||||||
|
stal APU_NOISE_LENGTH_COUNTER ; Immediately start the counter
|
||||||
|
lda #1
|
||||||
|
stal APU_NOISE_START_FLAG
|
||||||
|
|
||||||
|
:no_reload
|
||||||
|
pla
|
||||||
|
plx
|
||||||
|
plp
|
||||||
|
rtl
|
||||||
|
|
||||||
|
; Lookup from bottom 4 bits of NOISE_REG3
|
||||||
|
NoisePeriodTable dw 4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068
|
||||||
|
|
||||||
|
|
||||||
APU_STATUS_WRITE ENT
|
APU_STATUS_WRITE ENT
|
||||||
stal APU_STATUS
|
stal APU_STATUS
|
||||||
pha
|
pha
|
||||||
|
@ -997,5 +1164,11 @@ APU_STATUS_WRITE ENT
|
||||||
stz APU_TRIANGLE_LENGTH_COUNTER
|
stz APU_TRIANGLE_LENGTH_COUNTER
|
||||||
:triangle_on
|
:triangle_on
|
||||||
|
|
||||||
|
; Noise
|
||||||
|
bit #$08
|
||||||
|
bne :noise_on
|
||||||
|
stz APU_NOISE_LENGTH_COUNTER
|
||||||
|
:noise_on
|
||||||
|
|
||||||
pla
|
pla
|
||||||
rtl
|
rtl
|
||||||
|
|
|
@ -44,6 +44,7 @@ Tmp1 equ 130
|
||||||
stz CursorRow
|
stz CursorRow
|
||||||
|
|
||||||
jsr InitGraphics
|
jsr InitGraphics
|
||||||
|
jsr DrawStaticUI
|
||||||
jsr APUStartUp
|
jsr APUStartUp
|
||||||
|
|
||||||
sep #$30
|
sep #$30
|
||||||
|
@ -55,7 +56,7 @@ Tmp1 equ 130
|
||||||
:update
|
:update
|
||||||
jsr DrawUI
|
jsr DrawUI
|
||||||
:evtloop
|
:evtloop
|
||||||
jsr DrawDynUI ; Always update to see changing internal APU values
|
; jsr DrawDynUI ; Always update to see changing internal APU values
|
||||||
jsr _ReadControl
|
jsr _ReadControl
|
||||||
bit #PAD_KEY_DOWN ; Only response to actual key presses
|
bit #PAD_KEY_DOWN ; Only response to actual key presses
|
||||||
beq :evtloop
|
beq :evtloop
|
||||||
|
@ -107,31 +108,100 @@ Toggle
|
||||||
asl
|
asl
|
||||||
tax
|
tax
|
||||||
jmp (:toggle1,x)
|
jmp (:toggle1,x)
|
||||||
:toggle1 da Toggle4000,Toggle4001,Toggle4002,Toggle4003,Toggle4015
|
:toggle1 da Toggle4000,Toggle4001,Toggle4002,Toggle4003
|
||||||
|
da Toggle4008,Toggle400A,Toggle400B,ToggleNoop
|
||||||
|
da Toggle4004,Toggle4005,Toggle4006,Toggle4007
|
||||||
|
da Toggle400C,Toggle400E,Toggle400F,Toggle4015
|
||||||
|
ToggleNoop
|
||||||
|
brl ToggleExit
|
||||||
|
|
||||||
Toggle4000
|
Toggle4000
|
||||||
lda APU_PULSE1_REG1
|
lda APU_PULSE1_REG1
|
||||||
ldx CursorCol
|
ldx CursorCol
|
||||||
eor ToggleTable,x
|
eor ToggleTable,x
|
||||||
jsl APU_PULSE1_REG1_WRITE
|
jsl APU_PULSE1_REG1_WRITE
|
||||||
bra ToggleExit
|
brl ToggleExit
|
||||||
Toggle4001
|
Toggle4001
|
||||||
lda APU_PULSE1_REG2
|
lda APU_PULSE1_REG2
|
||||||
ldx CursorCol
|
ldx CursorCol
|
||||||
eor ToggleTable,x
|
eor ToggleTable,x
|
||||||
jsl APU_PULSE1_REG2_WRITE
|
jsl APU_PULSE1_REG2_WRITE
|
||||||
bra ToggleExit
|
brl ToggleExit
|
||||||
Toggle4002
|
Toggle4002
|
||||||
lda APU_PULSE1_REG3
|
lda APU_PULSE1_REG3
|
||||||
ldx CursorCol
|
ldx CursorCol
|
||||||
eor ToggleTable,x
|
eor ToggleTable,x
|
||||||
jsl APU_PULSE1_REG3_WRITE
|
jsl APU_PULSE1_REG3_WRITE
|
||||||
bra ToggleExit
|
brl ToggleExit
|
||||||
Toggle4003
|
Toggle4003
|
||||||
lda APU_PULSE1_REG4
|
lda APU_PULSE1_REG4
|
||||||
ldx CursorCol
|
ldx CursorCol
|
||||||
eor ToggleTable,x
|
eor ToggleTable,x
|
||||||
jsl APU_PULSE1_REG4_WRITE
|
jsl APU_PULSE1_REG4_WRITE
|
||||||
bra ToggleExit
|
brl ToggleExit
|
||||||
|
|
||||||
|
Toggle4004
|
||||||
|
lda APU_PULSE2_REG1
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_PULSE2_REG1_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
Toggle4005
|
||||||
|
lda APU_PULSE2_REG2
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_PULSE2_REG2_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
Toggle4006
|
||||||
|
lda APU_PULSE2_REG3
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_PULSE2_REG3_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
Toggle4007
|
||||||
|
lda APU_PULSE2_REG4
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_PULSE2_REG4_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
|
||||||
|
Toggle4008
|
||||||
|
lda APU_TRIANGLE_REG1
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_TRIANGLE_REG1_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
Toggle400A
|
||||||
|
lda APU_TRIANGLE_REG3
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_TRIANGLE_REG3_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
Toggle400B
|
||||||
|
lda APU_TRIANGLE_REG4
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_TRIANGLE_REG4_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
|
||||||
|
Toggle400C
|
||||||
|
lda APU_NOISE_REG1
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_NOISE_REG1_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
Toggle400E
|
||||||
|
lda APU_NOISE_REG3
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_NOISE_REG3_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
Toggle400F
|
||||||
|
lda APU_NOISE_REG4
|
||||||
|
ldx CursorCol
|
||||||
|
eor ToggleTable,x
|
||||||
|
jsl APU_NOISE_REG4_WRITE
|
||||||
|
brl ToggleExit
|
||||||
|
|
||||||
Toggle4015
|
Toggle4015
|
||||||
lda APU_STATUS
|
lda APU_STATUS
|
||||||
|
@ -150,36 +220,66 @@ ToggleTable dfb $80,$40,$20,$10,$08,$04,$02,$01
|
||||||
mx %00
|
mx %00
|
||||||
MoveUp
|
MoveUp
|
||||||
lda CursorRow
|
lda CursorRow
|
||||||
|
bne :not_0
|
||||||
|
lda #6
|
||||||
|
sta CursorRow
|
||||||
|
rts
|
||||||
|
:not_0
|
||||||
|
cmp #8
|
||||||
|
bne :not_8
|
||||||
|
lda #15
|
||||||
|
sta CursorRow
|
||||||
|
rts
|
||||||
|
:not_8
|
||||||
dec
|
dec
|
||||||
bpl *+5
|
|
||||||
lda #4
|
|
||||||
sta CursorRow
|
sta CursorRow
|
||||||
rts
|
rts
|
||||||
|
|
||||||
MoveDown
|
MoveDown
|
||||||
lda CursorRow
|
lda CursorRow
|
||||||
|
cmp #6
|
||||||
|
bne :not_6
|
||||||
|
stz CursorRow
|
||||||
|
rts
|
||||||
|
:not_6
|
||||||
|
cmp #15
|
||||||
|
bne :not_15
|
||||||
|
lda #8
|
||||||
|
sta CursorRow
|
||||||
|
rts
|
||||||
|
:not_15
|
||||||
inc
|
inc
|
||||||
cmp #5
|
|
||||||
bcc *+5
|
|
||||||
lda #0
|
|
||||||
sta CursorRow
|
sta CursorRow
|
||||||
rts
|
rts
|
||||||
|
|
||||||
MoveLeft
|
MoveLeft
|
||||||
lda CursorCol
|
lda CursorCol
|
||||||
dec
|
dec
|
||||||
bpl *+5
|
bpl :store
|
||||||
|
lda CursorRow
|
||||||
|
cmp #15
|
||||||
|
beq :skip
|
||||||
|
eor #8
|
||||||
|
sta CursorRow
|
||||||
|
:skip
|
||||||
lda #7
|
lda #7
|
||||||
sta CursorCol
|
:store sta CursorCol
|
||||||
rts
|
rts
|
||||||
|
|
||||||
MoveRight
|
MoveRight
|
||||||
lda CursorCol
|
lda CursorCol
|
||||||
inc
|
inc
|
||||||
cmp #8
|
cmp #8
|
||||||
bcc *+5
|
bcc :store
|
||||||
|
|
||||||
|
lda CursorRow
|
||||||
|
cmp #15
|
||||||
|
beq :skip
|
||||||
|
eor #8
|
||||||
|
sta CursorRow
|
||||||
|
:skip
|
||||||
lda #0
|
lda #0
|
||||||
sta CursorCol
|
:store sta CursorCol
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Read the keyboard and paddle controls and return in a game-controller-like format
|
; Read the keyboard and paddle controls and return in a game-controller-like format
|
||||||
|
@ -260,10 +360,24 @@ DefaultPalette ENT
|
||||||
|
|
||||||
; UI string templates
|
; UI string templates
|
||||||
PULSE1_TITLE str 'PULSE1'
|
PULSE1_TITLE str 'PULSE1'
|
||||||
|
PULSE2_TITLE str 'PULSE2'
|
||||||
|
TRIANGLE_TITLE str 'TRIANGLE'
|
||||||
|
NOISE_TITLE str 'NOISE'
|
||||||
|
CONTROL_TITLE str 'CONTROL'
|
||||||
|
|
||||||
PULSE_REG1_STR str 'DDLCVVVV'
|
PULSE_REG1_STR str 'DDLCVVVV'
|
||||||
PULSE_REG2_STR str 'EPPPNSSS'
|
PULSE_REG2_STR str 'EPPPNSSS'
|
||||||
PULSE_REG3_STR str 'TTTTTTTT'
|
PULSE_REG3_STR str 'TTTTTTTT'
|
||||||
PULSE_REG4_STR str 'LLLLLTTT'
|
PULSE_REG4_STR str 'LLLLLTTT'
|
||||||
|
|
||||||
|
TRIANGLE_REG1_STR str 'CRRRRRRR'
|
||||||
|
TRIANGLE_REG3_STR str 'TTTTTTTT'
|
||||||
|
TRIANGLE_REG4_STR str 'LLLLLTTT'
|
||||||
|
|
||||||
|
NOISE_REG1_STR str '--LCVVVV'
|
||||||
|
NOISE_REG3_STR str 'L---PPPP'
|
||||||
|
NOISE_REG4_STR str 'LLLLL---'
|
||||||
|
|
||||||
APU_STATUS_STR str '---DNT21'
|
APU_STATUS_STR str '---DNT21'
|
||||||
|
|
||||||
ROW_SPAN equ {8*160}
|
ROW_SPAN equ {8*160}
|
||||||
|
@ -289,96 +403,232 @@ DrawDynUI
|
||||||
lda APU_PULSE1_CURRENT_PERIOD
|
lda APU_PULSE1_CURRENT_PERIOD
|
||||||
jsr DrawWord
|
jsr DrawWord
|
||||||
|
|
||||||
|
; Draw stuff that will never be updated
|
||||||
|
DrawStaticUI
|
||||||
|
ldx #{6*4}+{ROW_SPAN*3}
|
||||||
|
ldy #$1111
|
||||||
|
lda #PULSE1_TITLE
|
||||||
|
jsr DrawString
|
||||||
|
|
||||||
|
ldx #{22*4}+{ROW_SPAN*3}
|
||||||
|
ldy #$1111
|
||||||
|
lda #PULSE2_TITLE
|
||||||
|
jsr DrawString
|
||||||
|
|
||||||
|
ldx #{6*4}+{ROW_SPAN*10}
|
||||||
|
ldy #$1111
|
||||||
|
lda #TRIANGLE_TITLE
|
||||||
|
jsr DrawString
|
||||||
|
|
||||||
|
ldx #{22*4}+{ROW_SPAN*10}
|
||||||
|
ldy #$1111
|
||||||
|
lda #NOISE_TITLE
|
||||||
|
jsr DrawString
|
||||||
|
|
||||||
|
ldx #{22*4}+{ROW_SPAN*16}
|
||||||
|
ldy #$1111
|
||||||
|
lda #CONTROL_TITLE
|
||||||
|
jsr DrawString
|
||||||
|
|
||||||
DrawUI
|
DrawUI
|
||||||
ldx #{1*4}+{ROW_SPAN*5}
|
jsr DrawPulse1
|
||||||
|
jsr DrawPulse2
|
||||||
|
jsr DrawTriangle
|
||||||
|
jsr DrawNoise
|
||||||
|
jsr DrawControl
|
||||||
|
|
||||||
|
jsr DrawCursor
|
||||||
|
rts
|
||||||
|
|
||||||
|
PULSE1_X equ 1
|
||||||
|
PULSE1_Y equ 5
|
||||||
|
DrawPulse1
|
||||||
|
ldx #{PULSE1_X*4}+{ROW_SPAN*PULSE1_Y}
|
||||||
ldy #$4444
|
ldy #$4444
|
||||||
lda #$4000
|
lda #$4000
|
||||||
jsr DrawWord
|
jsr DrawWord
|
||||||
|
|
||||||
ldy #PULSE_REG1_STR
|
ldy #PULSE_REG1_STR
|
||||||
lda APU_PULSE1_REG1
|
lda APU_PULSE1_REG1
|
||||||
ldx #{6*4}+{ROW_SPAN*5}
|
ldx #{{PULSE1_X+5}*4}+{ROW_SPAN*PULSE1_Y}
|
||||||
jsr DrawBitsHL
|
jsr DrawBitsHL
|
||||||
|
|
||||||
ldx #{15*4}+{ROW_SPAN*5}
|
|
||||||
ldy #$5555
|
|
||||||
lda APU_PULSE1_REG1
|
|
||||||
jsr DrawByte
|
|
||||||
|
|
||||||
|
ldx #{PULSE1_X*4}+{ROW_SPAN*{PULSE1_Y+1}}
|
||||||
|
|
||||||
ldx #{1*4}+{ROW_SPAN*6}
|
|
||||||
ldy #$4444
|
ldy #$4444
|
||||||
lda #$4001
|
lda #$4001
|
||||||
jsr DrawWord
|
jsr DrawWord
|
||||||
|
|
||||||
ldy #PULSE_REG2_STR
|
ldy #PULSE_REG2_STR
|
||||||
lda APU_PULSE1_REG2
|
lda APU_PULSE1_REG2
|
||||||
ldx #{6*4}+{ROW_SPAN*6}
|
ldx #{{PULSE1_X+5}*4}+{ROW_SPAN*{PULSE1_Y+1}}
|
||||||
jsr DrawBitsHL
|
jsr DrawBitsHL
|
||||||
|
|
||||||
ldx #{15*4}+{ROW_SPAN*6}
|
|
||||||
ldy #$5555
|
|
||||||
lda APU_PULSE1_REG2
|
|
||||||
jsr DrawByte
|
|
||||||
|
|
||||||
|
ldx #{PULSE1_X*4}+{ROW_SPAN*{PULSE1_Y+2}}
|
||||||
|
|
||||||
ldx #{1*4}+{ROW_SPAN*7}
|
|
||||||
ldy #$4444
|
ldy #$4444
|
||||||
lda #$4002
|
lda #$4002
|
||||||
jsr DrawWord
|
jsr DrawWord
|
||||||
|
|
||||||
ldy #PULSE_REG3_STR
|
ldy #PULSE_REG3_STR
|
||||||
lda APU_PULSE1_REG3
|
lda APU_PULSE1_REG3
|
||||||
ldx #{6*4}+{ROW_SPAN*7}
|
ldx #{{PULSE1_X+5}*4}+{ROW_SPAN*{PULSE1_Y+2}}
|
||||||
jsr DrawBitsHL
|
jsr DrawBitsHL
|
||||||
|
|
||||||
ldx #{15*4}+{ROW_SPAN*7}
|
|
||||||
ldy #$5555
|
|
||||||
lda APU_PULSE1_REG3
|
|
||||||
jsr DrawByte
|
|
||||||
|
|
||||||
|
ldx #{PULSE1_X*4}+{ROW_SPAN*{PULSE1_Y+3}}
|
||||||
|
|
||||||
ldx #{1*4}+{ROW_SPAN*8}
|
|
||||||
ldy #$4444
|
ldy #$4444
|
||||||
lda #$4003
|
lda #$4003
|
||||||
jsr DrawWord
|
jsr DrawWord
|
||||||
|
|
||||||
ldy #PULSE_REG4_STR
|
ldy #PULSE_REG4_STR
|
||||||
lda APU_PULSE1_REG4
|
lda APU_PULSE1_REG4
|
||||||
ldx #{6*4}+{ROW_SPAN*8}
|
ldx #{{PULSE1_X+5}*4}+{ROW_SPAN*{PULSE1_Y+3}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
rts
|
||||||
|
|
||||||
|
PULSE2_X equ 17
|
||||||
|
PULSE2_Y equ 5
|
||||||
|
DrawPulse2
|
||||||
|
ldx #{PULSE2_X*4}+{ROW_SPAN*PULSE2_Y}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$4004
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #PULSE_REG1_STR
|
||||||
|
lda APU_PULSE2_REG1
|
||||||
|
ldx #{{PULSE2_X+5}*4}+{ROW_SPAN*PULSE2_Y}
|
||||||
jsr DrawBitsHL
|
jsr DrawBitsHL
|
||||||
|
|
||||||
ldx #{15*4}+{ROW_SPAN*8}
|
ldx #{PULSE2_X*4}+{ROW_SPAN*{PULSE2_Y+1}}
|
||||||
ldy #$5555
|
ldy #$4444
|
||||||
lda APU_PULSE1_REG4
|
lda #$4005
|
||||||
jsr DrawByte
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #PULSE_REG2_STR
|
||||||
|
lda APU_PULSE2_REG2
|
||||||
|
ldx #{{PULSE2_X+5}*4}+{ROW_SPAN*{PULSE2_Y+1}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
ldx #{PULSE2_X*4}+{ROW_SPAN*{PULSE2_Y+2}}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$4006
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #PULSE_REG3_STR
|
||||||
|
lda APU_PULSE2_REG3
|
||||||
|
ldx #{{PULSE2_X+5}*4}+{ROW_SPAN*{PULSE2_Y+2}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
ldx #{PULSE2_X*4}+{ROW_SPAN*{PULSE2_Y+3}}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$4007
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #PULSE_REG4_STR
|
||||||
|
lda APU_PULSE2_REG4
|
||||||
|
ldx #{{PULSE2_X+5}*4}+{ROW_SPAN*{PULSE2_Y+3}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
TRIANGLE_X equ 1
|
||||||
|
TRIANGLE_Y equ 12
|
||||||
|
DrawTriangle
|
||||||
|
ldx #{TRIANGLE_X*4}+{ROW_SPAN*TRIANGLE_Y}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$4008
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #TRIANGLE_REG1_STR
|
||||||
|
lda APU_TRIANGLE_REG1
|
||||||
|
ldx #{{TRIANGLE_X+5}*4}+{ROW_SPAN*TRIANGLE_Y}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
|
||||||
|
ldx #{TRIANGLE_X*4}+{ROW_SPAN*{TRIANGLE_Y+1}}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$400A
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #TRIANGLE_REG3_STR
|
||||||
|
lda APU_PULSE2_REG3
|
||||||
|
ldx #{{TRIANGLE_X+5}*4}+{ROW_SPAN*{TRIANGLE_Y+1}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
|
||||||
|
ldx #{TRIANGLE_X*4}+{ROW_SPAN*{TRIANGLE_Y+2}}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$400B
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #TRIANGLE_REG4_STR
|
||||||
|
lda APU_TRIANGLE_REG4
|
||||||
|
ldx #{{TRIANGLE_X+5}*4}+{ROW_SPAN*{TRIANGLE_Y+2}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
NOISE_X equ 17
|
||||||
|
NOISE_Y equ 12
|
||||||
|
DrawNoise
|
||||||
|
ldx #{NOISE_X*4}+{ROW_SPAN*NOISE_Y}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$400C
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #NOISE_REG1_STR
|
||||||
|
lda APU_NOISE_REG1
|
||||||
|
ldx #{{NOISE_X+5}*4}+{ROW_SPAN*NOISE_Y}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
|
||||||
|
ldx #{NOISE_X*4}+{ROW_SPAN*{NOISE_Y+1}}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$400E
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #NOISE_REG3_STR
|
||||||
|
lda APU_NOISE_REG3
|
||||||
|
ldx #{{NOISE_X+5}*4}+{ROW_SPAN*{NOISE_Y+1}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
|
||||||
|
ldx #{NOISE_X*4}+{ROW_SPAN*{NOISE_Y+2}}
|
||||||
|
ldy #$4444
|
||||||
|
lda #$400F
|
||||||
|
jsr DrawWord
|
||||||
|
|
||||||
|
ldy #NOISE_REG4_STR
|
||||||
|
lda APU_NOISE_REG4
|
||||||
|
ldx #{{NOISE_X+5}*4}+{ROW_SPAN*{NOISE_Y+2}}
|
||||||
|
jsr DrawBitsHL
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
; Draw the APU Status byte
|
; Draw the APU Status byte
|
||||||
|
CONTROL_X equ 17
|
||||||
ldx #{1*4}+{ROW_SPAN*10}
|
CONTROL_Y equ 18
|
||||||
|
DrawControl
|
||||||
|
ldx #{CONTROL_X*4}+{ROW_SPAN*CONTROL_Y}
|
||||||
ldy #$4444
|
ldy #$4444
|
||||||
lda #$4015
|
lda #$4015
|
||||||
jsr DrawWord
|
jsr DrawWord
|
||||||
|
|
||||||
ldy #APU_STATUS_STR
|
ldy #APU_STATUS_STR
|
||||||
lda APU_STATUS
|
lda APU_STATUS
|
||||||
ldx #{6*4}+{ROW_SPAN*10}
|
ldx #{{CONTROL_X+5}*4}+{ROW_SPAN*CONTROL_Y}
|
||||||
jsr DrawBitsHL
|
jsr DrawBitsHL
|
||||||
|
|
||||||
ldx #{15*4}+{ROW_SPAN*10}
|
rts
|
||||||
ldy #$5555
|
|
||||||
lda APU_STATUS
|
|
||||||
jsr DrawByte
|
|
||||||
|
|
||||||
|
DrawCursor
|
||||||
lda CursorRow
|
lda CursorRow
|
||||||
asl
|
asl
|
||||||
tax
|
tax
|
||||||
lda row2screen,x ; Get the physical position of each logical row
|
lda row2screen,x ; Get the physical position of each logical row
|
||||||
|
|
||||||
asl
|
asl
|
||||||
asl
|
asl
|
||||||
asl
|
asl
|
||||||
|
@ -393,9 +643,10 @@ DrawUI
|
||||||
asl
|
asl
|
||||||
asl
|
asl
|
||||||
sta 1,s
|
sta 1,s
|
||||||
|
|
||||||
lda CursorCol
|
lda CursorCol
|
||||||
clc
|
clc
|
||||||
adc #6
|
adc col2screen,x
|
||||||
asl
|
asl
|
||||||
asl
|
asl
|
||||||
clc
|
clc
|
||||||
|
@ -409,7 +660,8 @@ DrawUI
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
row2screen dw 5,6,7,8,10
|
row2screen dw 5,6,7,8,12,13,14,0,5,6,7,8,12,13,14,18 ; 16 logical rows, 0-7 are column 1, 8-15 column 2
|
||||||
|
col2screen dw 6,6,6,6,6, 6, 6, 0,22,22,22,22,22,22,22,22 ;
|
||||||
; Draw a byte as a series of bits using the template strings and
|
; Draw a byte as a series of bits using the template strings and
|
||||||
; the bit values to set the color
|
; the bit values to set the color
|
||||||
;
|
;
|
||||||
|
@ -448,6 +700,16 @@ DrawBitsHL
|
||||||
bcc :loop
|
bcc :loop
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
setborder
|
||||||
|
php
|
||||||
|
sep #$20
|
||||||
|
eorl $E0C034
|
||||||
|
and #$0F
|
||||||
|
eorl $E0C034
|
||||||
|
stal $E0C034
|
||||||
|
plp
|
||||||
|
rts
|
||||||
|
|
||||||
put App.Msg.s
|
put App.Msg.s
|
||||||
put font.s
|
put font.s
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user