diff --git a/pt3_player/OPTIMIZATION.txt b/pt3_player/OPTIMIZATION.txt index 92d901d4..a0b0df6d 100644 --- a/pt3_player/OPTIMIZATION.txt +++ b/pt3_player/OPTIMIZATION.txt @@ -18,14 +18,15 @@ Code Optimization Decoder Type size ZP use raw decode total CPU overhead ------------------------------------------------------------- - Original 3407 22B 1F.22 31s 171s 18% - VolTableGen 3302 22B 20.0E 32s 171s 19% - SizeOpts 3262 22B 20.0A 32s 171s 19% - MoreSizeOpt 3203 22B 1F.1D 31s 171s 18% - Qkumba#1 2937 ?? 1D.18 29s 171s 17% - Qkumba#2 2879 ?? 1C.18 28s 171s 16% - Qkumba#3+vmw 2816 ?? 1C.22 28s 171s 16% - Fixes,zero init 2776 ?? 1C.10 28s 171s 16% + Original 3407 22B 1F.22 31s 171s 18.1% + VolTableGen 3302 22B 20.0E 32s 171s 18.7% + SizeOpts 3262 22B 20.0A 32s 171s 18.7% + MoreSizeOpt 3203 22B 1F.1D 31s 171s 18.1% + Qkumba#1 2937 ?? 1D.18 29s 171s 16.9% + Qkumba#2 2879 ?? 1C.18 28s 171s 16.3% + Qkumba#3+vmw 2816 ?? 1C.22 28s 171s 16.3% + Fixes,zero init 2776 ?? 1C.10 28s 171s 16.3% + Qkumba-SuperSMC 2739 ?? 1B.15 27s 171s 15.8% Times: Validated BH.PT3: 10.0B 16 1:33 93 17.2% diff --git a/pt3_player/hello.bas b/pt3_player/hello.bas index 13d55b23..71d828cb 100644 --- a/pt3_player/hello.bas +++ b/pt3_player/hello.bas @@ -1,2 +1,2 @@ - 10 PRINT "PT3 PLAYER V0.8" + 10 PRINT "PT3 PLAYER V0.9" 100 PRINT CHR$ (4)"BRUN PT3_PLAYER" diff --git a/pt3_player/interrupt_handler.s b/pt3_player/interrupt_handler.s index 107c14c9..55725465 100644 --- a/pt3_player/interrupt_handler.s +++ b/pt3_player/interrupt_handler.s @@ -55,11 +55,13 @@ pt3_play_music: beq move_to_next pt3_loop_smc: - lda #0 ; looping, move to loop location - sta current_pattern + lda #$d1 ; looping, move to loop location + ; non-zero to avoid the temptation + ; to merge with following lda #$0 + sta current_pattern_smc+1 lda #$0 - sta current_line - sta current_subframe + sta current_line_smc+1 + sta current_subframe_smc+1 sta DONE_SONG ; undo the next song beq done_interrupt ; branch always @@ -151,31 +153,35 @@ frame_count_smc: sta frame_count_smc+1 ; 3 -update_second_ones: - inc $7d0+TIME_OFFSET+3 ; 6 - inc $bd0+TIME_OFFSET+3 ; 6 - lda $bd0+TIME_OFFSET+3 ; 4 - cmp #$ba ; one past '9' ; 2 - bne done_time ; 3/2nt - lda #'0'+$80 ; 2 - sta $7d0+TIME_OFFSET+3 ; 4 - sta $bd0+TIME_OFFSET+3 ; 4 -update_second_tens: - inc $7d0+TIME_OFFSET+2 ; 6 - inc $bd0+TIME_OFFSET+2 ; 6 - lda $bd0+TIME_OFFSET+2 ; 4 - cmp #$b6 ; 6 (for 60 seconds) ; 2 - bne done_time ; 3/2nt - lda #'0'+$80 ; 2 - sta $7d0+TIME_OFFSET+2 ; 4 - sta $bd0+TIME_OFFSET+2 ; 4 + ldx $7d0+TIME_OFFSET+3 ; 4 + cpx #'9'+$80 ; 2 + bne update_second_ones ; 3/2nt + + ldx $7d0+TIME_OFFSET+2 ; 4 + cpx #'5'+$80 ; 6-1 (for 60 seconds) ; 2 + bne update_second_tens ; 3/2nt + update_minutes: inc $7d0+TIME_OFFSET ; 6 inc $bd0+TIME_OFFSET ; 6 + + ldx #'0'+$80-1 ; 2 + +update_second_tens: + inx ; 2 + stx $7d0+TIME_OFFSET+2 ; 4 + stx $bd0+TIME_OFFSET+2 ; 4 + + ldx #'0'+$80-1 ; 2 + +update_second_ones: + inx ; 2 + stx $7d0+TIME_OFFSET+3 ; 4 + stx $bd0+TIME_OFFSET+3 ; 4 ; we don't handle > 9:59 songs yet done_time: ;============= - ; 87 worst + ; 52 worst ;================================= @@ -185,7 +191,7 @@ done_time: check_keyboard: jsr get_key - cmp #0 + tax beq exit_interrupt ;==================== diff --git a/pt3_player/pt3_lib.s b/pt3_player/pt3_lib.s index 2023ab02..e61ead1e 100644 --- a/pt3_player/pt3_lib.s +++ b/pt3_player/pt3_lib.s @@ -21,6 +21,7 @@ ; + 2817 bytes -- eliminate pt3_version. Slighly faster but also bigger ; + 2828 bytes -- fix some correctness issues ; + 2776 bytes -- init vars with loop (slower, but more correct and smaller) +; + 2739 bytes -- qkumba's crazy SMC everywhere patch ; TODO ; move some of these flags to be bits rather than bytes? @@ -213,140 +214,12 @@ note_c: .byte $0 ; NOTE_TONE_DELTA_L .byte $0 ; NOTE_TONE_DELTA_H .byte $0 ; NOTE_TONE_SLIDE_TO_STEP - - -;==================================== -; Global vars that must be preserved - -current_subframe: .byte $0 -current_line: .byte $0 -current_pattern: .byte $0 -pt3_pattern_done: .byte $0 - -pt3_noise_period: .byte $0 ; Y -pt3_noise_add: .byte $0 ; Y - -pt3_envelope_period_l: .byte $0 ; Y -pt3_envelope_period_h: .byte $0 ; Y -pt3_envelope_slide_l: .byte $0 -pt3_envelope_slide_h: .byte $0 -pt3_envelope_slide_add_l:.byte $0 -pt3_envelope_slide_add_h:.byte $0 -pt3_envelope_add: .byte $0 -pt3_envelope_type: .byte $0 ; Y -pt3_envelope_type_old: .byte $0 -pt3_envelope_delay: .byte $0 -pt3_envelope_delay_orig:.byte $0 - -pt3_mixer_value: .byte $0 end_vars: -;========================== -; local variables - -note_command: ; shared space with sample_b0 -sample_b0: .byte $0 -note_command_bottom: ; shared space with sample_b1 -sample_b1: .byte $0 - -temp_word_l: .byte $0 -temp_word_h: .byte $0 - -spec_command: .byte $0 - -freq_l: .byte $00 -freq_h: .byte $00 - -e_slide_amount: .byte $0 - -prev_note: .byte $0 -prev_sliding_l: .byte $0 -prev_sliding_h: .byte $0 - -z80_h: .byte $0 -z80_l: .byte $0 -z80_d: .byte $0 -z80_e: .byte $0 - - - - - ;=========================== - ; Load Ornament - ;=========================== - ; ornament value in A - ; note offset in X - - ; Ornament table pointers are 16-bits little endian - ; There are 16 of these pointers starting at $aa:$a9 - ; Our ornament starts at address (A*2)+that pointer - ; We point ORNAMENT_H:ORNAMENT_L to this - ; then we load the length/data values - ; and then leave ORNAMENT_H:ORNAMENT_L pointing to begnning of - ; the ornament data - - ; Optimization: - ; Loop and length only used once, can be located negative - ; from the pointer, but 6502 doesn't make addressing like that - ; easy. Can't self modify as channels A/B/C have own copies - ; of the var. - -load_ornament0: +load_ornament0_sample1: lda #0 ; 2 - -load_ornament: - - sty TEMP ; save Y value ; 3 - - ;pt3->ornament_patterns[i]= - ; (pt3->data[0xaa+(i*2)]<<8)|pt3->data[0xa9+(i*2)]; - - asl ; A*2 ; 2 - tay ; 2 - - ; a->ornament_pointer=pt3->ornament_patterns[a->ornament]; - - lda PT3_LOC+PT3_ORNAMENT_LOC_L,Y ; 4+ - sta ORNAMENT_L ; 3 - - lda PT3_LOC+PT3_ORNAMENT_LOC_L+1,Y ; 4+ - - ; we're assuming PT3 is loaded to a page boundary - - adc #>PT3_LOC ; 2 - sta ORNAMENT_H ; 3 - - lda #0 ; 2 - sta note_a+NOTE_ORNAMENT_POSITION,X ; 5 - - tay ; 2 - - ; Set the loop value - ; a->ornament_loop=pt3->data[a->ornament_pointer]; - lda (ORNAMENT_L),Y ; 5+ - sta note_a+NOTE_ORNAMENT_LOOP,X ; 5 - - ; Set the length value - ; a->ornament_length=pt3->data[a->ornament_pointer]; - iny ; 2 - lda (ORNAMENT_L),Y ; 5+ - sta note_a+NOTE_ORNAMENT_LENGTH,X ; 5 - - ; Set the pointer to the value past the length - - lda ORNAMENT_L ; 3 - adc #$2 ; 2 - sta note_a+NOTE_ORNAMENT_POINTER_L,X ; 5 - lda ORNAMENT_H ; 3 - adc #$0 ; 2 - sta note_a+NOTE_ORNAMENT_POINTER_H,X ; 5 - - ldy TEMP ; restore Y value ; 3 - - rts ; 6 - - ;============ - ; 83 + jsr load_ornament ; 6 + ; fall through ;=========================== ; Load Sample @@ -419,6 +292,83 @@ load_sample: ;============ ; 76 + + ;=========================== + ; Load Ornament + ;=========================== + ; ornament value in A + ; note offset in X + + ; Ornament table pointers are 16-bits little endian + ; There are 16 of these pointers starting at $aa:$a9 + ; Our ornament starts at address (A*2)+that pointer + ; We point ORNAMENT_H:ORNAMENT_L to this + ; then we load the length/data values + ; and then leave ORNAMENT_H:ORNAMENT_L pointing to begnning of + ; the ornament data + + ; Optimization: + ; Loop and length only used once, can be located negative + ; from the pointer, but 6502 doesn't make addressing like that + ; easy. Can't self modify as channels A/B/C have own copies + ; of the var. + +load_ornament: + + sty TEMP ; save Y value ; 3 + + ;pt3->ornament_patterns[i]= + ; (pt3->data[0xaa+(i*2)]<<8)|pt3->data[0xa9+(i*2)]; + + asl ; A*2 ; 2 + tay ; 2 + + ; a->ornament_pointer=pt3->ornament_patterns[a->ornament]; + + lda PT3_LOC+PT3_ORNAMENT_LOC_L,Y ; 4+ + sta ORNAMENT_L ; 3 + + lda PT3_LOC+PT3_ORNAMENT_LOC_L+1,Y ; 4+ + + ; we're assuming PT3 is loaded to a page boundary + + adc #>PT3_LOC ; 2 + sta ORNAMENT_H ; 3 + + lda #0 ; 2 + sta note_a+NOTE_ORNAMENT_POSITION,X ; 5 + + tay ; 2 + + ; Set the loop value + ; a->ornament_loop=pt3->data[a->ornament_pointer]; + lda (ORNAMENT_L),Y ; 5+ + sta note_a+NOTE_ORNAMENT_LOOP,X ; 5 + + ; Set the length value + ; a->ornament_length=pt3->data[a->ornament_pointer]; + iny ; 2 + lda (ORNAMENT_L),Y ; 5+ + sta note_a+NOTE_ORNAMENT_LENGTH,X ; 5 + + ; Set the pointer to the value past the length + + lda ORNAMENT_L ; 3 + adc #$2 ; 2 + sta note_a+NOTE_ORNAMENT_POINTER_L,X ; 5 + lda ORNAMENT_H ; 3 + adc #$0 ; 2 + sta note_a+NOTE_ORNAMENT_POINTER_H,X ; 5 + + ldy TEMP ; restore Y value ; 3 + + rts ; 6 + + ;============ + ; 83 + + + ;==================================== ; pt3_init_song ;==================================== @@ -433,50 +383,43 @@ zero_song_structs_loop: sta note_a,X bne zero_song_structs_loop + sta pt3_noise_period_smc+1 ; 4 + sta pt3_noise_add_smc+1 ; 4 + + sta pt3_envelope_period_l_smc+1 ; 4 + sta pt3_envelope_period_h_smc+1 ; 4 + sta pt3_envelope_slide_l_smc+1 ; 4 + sta pt3_envelope_slide_h_smc+1 ; 4 + sta pt3_envelope_slide_add_l_smc+1 ; 4 + sta pt3_envelope_slide_add_h_smc+1 ; 4 + sta pt3_envelope_add_smc+1 ; 4 + sta pt3_envelope_type_smc+1 ; 4 + sta pt3_envelope_type_old_smc+1 ; 4 + sta pt3_envelope_delay_smc+1 ; 4 + sta pt3_envelope_delay_orig_smc+1 ; 4 + + sta pt3_mixer_value_smc+1 ; 4 + + sta current_pattern_smc+1 ; 4 + sta current_line_smc+1 ; 4 + sta current_subframe_smc+1 ; 4 lda #$f ; 2 sta note_a+NOTE_VOLUME ; 4 sta note_b+NOTE_VOLUME ; 4 sta note_c+NOTE_VOLUME ; 4 -.if 0 - lda #$0 ; 2 - sta note_a+NOTE_TONE_SLIDING_L ; 4 - sta note_b+NOTE_TONE_SLIDING_L ; 4 - sta note_c+NOTE_TONE_SLIDING_L ; 4 - sta note_a+NOTE_TONE_SLIDING_H ; 4 - sta note_b+NOTE_TONE_SLIDING_H ; 4 - sta note_c+NOTE_TONE_SLIDING_H ; 4 - sta note_a+NOTE_ENABLED ; 4 - sta note_b+NOTE_ENABLED ; 4 - sta note_c+NOTE_ENABLED ; 4 - sta note_a+NOTE_ENVELOPE_ENABLED ; 4 - sta note_b+NOTE_ENVELOPE_ENABLED ; 4 - sta note_c+NOTE_ENVELOPE_ENABLED ; 4 - sta note_a+NOTE_SAMPLE_POSITION ; 4 - sta note_b+NOTE_SAMPLE_POSITION ; 4 - sta note_c+NOTE_SAMPLE_POSITION ; 4 - - sta pt3_noise_period ; 4 - sta pt3_noise_add ; 4 - sta pt3_envelope_period_l ; 4 - sta pt3_envelope_period_h ; 4 - sta pt3_envelope_type ; 4 -.endif ; default ornament/sample in A ldx #(NOTE_STRUCT_SIZE*0) ; 2 - jsr load_ornament ; 6+93 - jsr load_sample1 ; 6+86 + jsr load_ornament0_sample1 ; 6+93 ; default ornament/sample in B ldx #(NOTE_STRUCT_SIZE*1) ; 2 - jsr load_ornament0 ; 6+93 - jsr load_sample1 ; 6+86 + jsr load_ornament0_sample1 ; 6+93 ; default ornament/sample in C ldx #(NOTE_STRUCT_SIZE*2) ; 2 - jsr load_ornament0 ; 6+93 - jsr load_sample1 ; 6+86 + jsr load_ornament0_sample1 ; 6+93 ;======================= ; load default speed @@ -544,7 +487,7 @@ VolTableCreator: ; Init initial variables lda #$0 - sta z80_d + sta z80_d_smc+1 ldy #$11 ; Set up self modify @@ -563,20 +506,23 @@ vol_type_33: ldx #$ea ; NOP for self modify vol_type_35: - sty z80_l ; l=16 or 17 - sta z80_e ; e=16 or 0 + sty z80_l_smc+1 ; l=16 or 17 + sta z80_e_smc+1 ; e=16 or 0 stx vol_smc ; set the self-modify code ldy #16 ; skip first row, all zeros ldx #16 ; c=16 vol_outer: clc ; add HL,DE - lda z80_l - adc z80_e - sta z80_e +z80_l_smc: + lda #$d1 +z80_e_smc: + adc #$d1 + sta z80_e_smc+1 lda #0 - adc z80_d - sta z80_d ; carry is important +z80_d_smc: + adc #$d1 + sta z80_d_smc+1 ; carry is important ; sbc hl,hl lda #0 @@ -584,7 +530,7 @@ vol_outer: eor #$ff vol_write: - sta z80_h + sta z80_h_smc+1 pha vol_inner: @@ -594,7 +540,8 @@ vol_inner: vol_smc: nop ; nop or ROL depending - lda z80_h +z80_h_smc: + lda #$d1 adc #$0 ; a=a+carry; @@ -602,11 +549,11 @@ vol_smc: iny pla ; add HL,DE - adc z80_e + adc z80_e_smc+1 pha - lda z80_h - adc z80_d - sta z80_h + lda z80_h_smc+1 + adc z80_d_smc+1 + sta z80_h_smc+1 inx ; inc C txa ; a=c @@ -616,11 +563,11 @@ vol_smc: pla - lda z80_e ; a=e + lda z80_e_smc+1 ; a=e cmp #$77 bne vol_m3 - inc z80_e + inc z80_e_smc+1 vol_m3: txa ; a=c @@ -671,12 +618,12 @@ note_enabled: ; b0 = pt3->data[a->sample_pointer + a->sample_position * 4]; lda (SAMPLE_L),Y ; 5+ - sta sample_b0 ; 4 + sta sample_b0_smc+1 ; 4 ; b1 = pt3->data[a->sample_pointer + a->sample_position * 4 + 1]; iny ; 2 lda (SAMPLE_L),Y ; 5+ - sta sample_b1 ; 4 + sta sample_b1_smc+1 ; 4 ; a->tone = pt3->data[a->sample_pointer + a->sample_position*4+2]; ; a->tone+=(pt3->data[a->sample_pointer + a->sample_position*4+3])<<8; @@ -695,7 +642,7 @@ note_enabled: ; Accumulate tone if set ; (if sample_b1 & $40) - bit sample_b1 + bit sample_b1_smc+1 bvc no_accum ; (so, if b1&0x40 is zero, skip it) sta note_a+NOTE_TONE_ACCUMULATOR_H,X @@ -735,17 +682,22 @@ note_not_too_high: ldy note_a+NOTE_TONE_SLIDING_L,X tya adc note_a+NOTE_TONE_L,X - sta note_a+NOTE_TONE_L,X + + sta temp_word_l1_smc+1 lda note_a+NOTE_TONE_H,X adc note_a+NOTE_TONE_SLIDING_H,X - sta note_a+NOTE_TONE_H,X + sta temp_word_h1_smc+1 clc ;;can be removed if ADC SLIDING_H cannot overflow - lda note_a+NOTE_TONE_L,X - adc freq_l +temp_word_l1_smc: + lda #$d1 +freq_l_smc: + adc #$d1 sta note_a+NOTE_TONE_L,X - lda note_a+NOTE_TONE_H,X - adc freq_h +temp_word_h1_smc: + lda #$d1 +freq_h_smc: + adc #$d1 and #$0f sta note_a+NOTE_TONE_H,X @@ -837,7 +789,8 @@ no_tone_sliding: calc_amplitude: ; get base value from the sample (bottom 4 bits of sample_b1) - lda sample_b1 ; a->amplitude= (b1 & 0xf); +sample_b1_smc: + lda #$d1 ; a->amplitude= (b1 & 0xf); and #$f ;======================================== @@ -845,7 +798,7 @@ calc_amplitude: ; adjust amplitude sliding - bit sample_b0 ; if ((b0 & 0x80)!=0) { + bit sample_b0_smc+1 ; if ((b0 & 0x80)!=0) { bpl done_amp_sliding ; so if top bit not set, skip tay @@ -917,7 +870,7 @@ done_clamp_amplitude: asl ; 2 asl ; 2 note_amp_smc: - ora #0 ; 4+ + ora #$d1 ; 4+ tay ; 2 lda VolumeTable,Y ; 4+ @@ -932,7 +885,8 @@ check_envelope_enable: ; if (((b0 & 0x1) == 0) && ( a->envelope_enabled)) { - lda sample_b0 +sample_b0_smc: + lda #$d1 lsr tay bcs envelope_slide @@ -954,12 +908,12 @@ envelope_slide: ; Envelope slide ; If b1 top bits are 10 or 11 - lda sample_b0 + lda sample_b0_smc+1 asl asl asl ; b0 bit 5 to carry flag lda #$20 - bit sample_b1 ; b1 bit 7 to sign flag, bit 5 to zero flag + bit sample_b1_smc+1 ; b1 bit 7 to sign flag, bit 5 to zero flag php bpl else_noise_slide ; if ((b1 & 0x80) != 0) { tya @@ -975,7 +929,7 @@ envelope_slide_down: ; j = ((b0>>1)|0xF0) + a->envelope_sliding adc note_a+NOTE_ENVELOPE_SLIDING,X - sta e_slide_amount ; j + sta e_slide_amount_smc+1 ; j envelope_slide_done: @@ -990,9 +944,10 @@ last_envelope: ; pt3->envelope_add+=j; clc - lda e_slide_amount - adc pt3_envelope_add - sta pt3_envelope_add +e_slide_amount_smc: + lda #$d1 + adc pt3_envelope_add_smc+1 + sta pt3_envelope_add_smc+1 jmp noise_slide_done ; skip else @@ -1004,7 +959,7 @@ else_noise_slide: tya clc adc note_a+NOTE_NOISE_SLIDING,X - sta pt3_noise_add + sta pt3_noise_add_smc+1 plp beq noise_slide_done ; if ((b1 & 0x20) != 0) { @@ -1016,11 +971,12 @@ noise_slide_done: ;====================== ; set mixer - lda sample_b1 ; pt3->mixer_value = ((b1 >>1) & 0x48) | pt3->mixer_value; + lda sample_b1_smc+1 ; pt3->mixer_value = ((b1 >>1) & 0x48) | pt3->mixer_value; lsr and #$48 - ora pt3_mixer_value - sta pt3_mixer_value +pt3_mixer_value_smc: + ora #$d1 + sta pt3_mixer_value_smc+1 ;======================== @@ -1056,7 +1012,7 @@ done_note: ; set mixer value ; this is a bit complex (from original code) ; after 3 calls it is set up properly - lsr pt3_mixer_value + lsr pt3_mixer_value_smc+1 handle_onoff: lda note_a+NOTE_ONOFF,X ;if (a->onoff>0) { @@ -1137,7 +1093,7 @@ decode_note: ; Init vars ldy #0 ; 2 - sty spec_command ; 4 + sty spec_command_smc+1 ; 4 ; Skip decode if note still running lda note_a+NOTE_LEN_COUNT,X ; 4+ @@ -1147,12 +1103,12 @@ decode_note: keep_decoding: lda note_a+NOTE_NOTE,X ; store prev note ; 4+ - sta prev_note ; 4 + sta prev_note_smc+1 ; 4 lda note_a+NOTE_TONE_SLIDING_H,X ; store prev sliding ; 4+ - sta prev_sliding_h ; 4 + sta prev_sliding_h_smc+1 ; 4 lda note_a+NOTE_TONE_SLIDING_L,X ; 4+ - sta prev_sliding_l ; 4 + sta prev_sliding_l_smc+1 ; 4 ;============ @@ -1169,10 +1125,12 @@ note_decode_loop: ;===> ; get next value lda (PATTERN_L),Y ; 5+ - sta note_command ; save termporarily ; 4 + sta note_command_smc+1 ; save termporarily ; 4 and #$0f ; 2 - sta note_command_bottom ; 4 - lda note_command ; 4 + sta note_command_bottom_smc+1 ; 4 + +note_command_smc: + lda #$d1 ; 2 ; FIXME: use a jump table?? ; further reflection, that would require 32-bytes of addresses @@ -1190,7 +1148,8 @@ decode_case_0X: ; $0X set special effect ;============================== ; -1 - lda note_command_bottom ; 4 +note_command_bottom_smc: + lda #$d1 ; 2 ; we can always store spec as 0 means no spec @@ -1198,25 +1157,20 @@ decode_case_0X: ; Doesn't seem to happen in practice ; But AY_emul has code to handle it - sta spec_command ; 4 + sta spec_command_smc+1 ; 4 bne decode_case_0X_not_zero ; 2/3 ;============= - ; 12 + ; 8 ; 00 case ; means end of pattern ; -1 sta note_a+NOTE_LEN_COUNT,X ; len_count=0; ; 5 - dec pt3_pattern_done ; 6 + dec pt3_pattern_done_smc+1 ; 6 jmp note_done_decoding ; 3 -decode_case_0X_not_zero: - - jmp done_decode_loop ; 3 - - decode_case_1X: ;============================== ; $1X -- Set Envelope Type @@ -1228,7 +1182,7 @@ decode_case_1X: ; 5 ; -1 - lda note_command_bottom ; 4 + lda note_command_bottom_smc+1 ; 4 bne decode_case_not_10 ; 3 decode_case_10: @@ -1250,6 +1204,8 @@ decode_case_1x_common: lda #0 ; 2 sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 5 +decode_case_0X_not_zero: + jmp done_decode_loop ; 3 decode_case_2X: @@ -1261,13 +1217,13 @@ decode_case_3X: cmp #$40 ; 2 bcs decode_case_4X ; branch greater/equal ; 3 ; -1 - lda note_command ; 3 + lda note_command_smc+1 ; 4 adc #$e0 ; same as subtract $20 ; 2 - sta pt3_noise_period ; 3 + sta pt3_noise_period_smc+1 ; 3 jmp done_decode_loop ; 3 ;=========== - ; 15 + ; 16 decode_case_4X: ;============================== @@ -1276,7 +1232,7 @@ decode_case_4X: ; cmp #$40 ; already set ; bne decode_case_5X ; 3 ; -1 - lda note_command_bottom ; set ornament to bottom nibble ; 4 + lda note_command_bottom_smc+1; set ornament to bottom nibble; 4 jsr load_ornament ; 6+93 jmp done_decode_loop ; 3 @@ -1291,7 +1247,7 @@ decode_case_5X: bcs decode_case_bX ; branch greater/equal ; 3 ; -1 - lda note_command ; 4 + lda note_command_smc+1 ; 4 adc #$b0 ; 2 sta note_a+NOTE_NOTE,X ; note=(current_val-0x50); ; 5 @@ -1310,7 +1266,7 @@ decode_case_bX: ; cmp #$b0 ; already set from before bne decode_case_cX ; 3 ; -1 - lda note_command_bottom ; 4 + lda note_command_bottom_smc+1 ; 4 beq decode_case_b0 ; 3 ; -1 sbc #1 ; envelope_type=(current_val&0xf)-1; ; 2 @@ -1347,7 +1303,7 @@ decode_case_cX: cmp #$c0 ; check top nibble $C ; 2 bne decode_case_dX ; 3 ; -1 - lda note_command_bottom ; 4 + lda note_command_bottom_smc+1 ; 4 bne decode_case_cx_not_c0 ; 3 ; -1 decode_case_c0: @@ -1374,7 +1330,7 @@ decode_case_dX: beq decode_case_fX ; 3 ; -1 - lda note_command ; 4 + lda note_command_smc+1 ; 4 sec ; 2 sbc #$d0 ; 2 beq note_done_decoding ; 3 @@ -1401,7 +1357,7 @@ decode_case_fX: sta note_a+NOTE_ENVELOPE_ENABLED,X ; 5 ; Set ornament to low byte of command - lda note_command_bottom ; 4 + lda note_command_bottom_smc+1 ; 4 jsr load_ornament ; ornament to load in A ; 6+? ; Get next byte @@ -1431,7 +1387,8 @@ note_done_decoding: ; In the same order they appear. We don't bother? handle_effects: - lda spec_command ; 4 +spec_command_smc: + lda #$d1 ; 2 ;============================== ; Effect #1 -- Tone Down @@ -1517,22 +1474,24 @@ skip_step_inc1: ; a->tone_delta=GetNoteFreq(a->note,pt3)- ; GetNoteFreq(prev_note,pt3); - lda note_a+NOTE_NOTE,X +prev_note_smc: + lda #$d1 jsr GetNoteFreq - lda freq_l - sta temp_word_l - lda freq_h - sta temp_word_h + lda freq_l_smc+1 + sta temp_word_l2_smc+1 + lda freq_h_smc+1 + sta temp_word_h2_smc+1 - lda prev_note + lda note_a+NOTE_NOTE,X jsr GetNoteFreq sec - lda temp_word_l - sbc freq_l +temp_word_l2_smc: + sbc #$d1 sta note_a+NOTE_TONE_DELTA_L,X - lda temp_word_h - sbc freq_h + lda freq_h_smc+1 +temp_word_h2_smc: + sbc #$d1 sta note_a+NOTE_TONE_DELTA_H,X ; a->slide_to_note=a->note; @@ -1540,7 +1499,7 @@ skip_step_inc1: sta note_a+NOTE_SLIDE_TO_NOTE,X ; a->note=prev_note; - lda prev_note + lda prev_note_smc+1 sta note_a+NOTE_NOTE,X ; implement file version 6 and above slide behavior @@ -1548,9 +1507,11 @@ skip_step_inc1: version_smc: jmp weird_version ; (JMP to BIT via smc) ; 3 - lda prev_sliding_l +prev_sliding_l_smc: + lda #$d1 sta note_a+NOTE_TONE_SLIDING_L,X - lda prev_sliding_h +prev_sliding_h_smc: + lda #$d1 sta note_a+NOTE_TONE_SLIDING_H,X weird_version: @@ -1562,7 +1523,7 @@ weird_version: sbc note_a+NOTE_TONE_SLIDING_L,X lda note_a+NOTE_TONE_DELTA_H,X sbc note_a+NOTE_TONE_SLIDING_H,X - bpl no_need + bpl no_effect ; a->tone_slide_step = -a->tone_slide_step; @@ -1576,8 +1537,6 @@ weird_version: adc #$0 sta note_a+NOTE_TONE_SLIDE_STEP_H,X -no_need: - jmp no_effect ;============================== @@ -1639,18 +1598,18 @@ effect_8: ; delay lda (PATTERN_L),Y ; load byte, set as speed iny - sta pt3_envelope_delay - sta pt3_envelope_delay_orig + sta pt3_envelope_delay_smc+1 + sta pt3_envelope_delay_orig_smc+1 ; low value lda (PATTERN_L),Y ; load byte, set as low iny - sta pt3_envelope_slide_add_l + sta pt3_envelope_slide_add_l_smc+1 ; high value lda (PATTERN_L),Y ; load byte, set as high iny - sta pt3_envelope_slide_add_h + sta pt3_envelope_slide_add_h_smc+1 bne no_effect ; branch always @@ -1692,30 +1651,30 @@ no_effect: set_envelope: - sta pt3_envelope_type ; 4 + sta pt3_envelope_type_smc+1 ; 4 ; give fake old to force update? maybe only needed if printing? ; pt3->envelope_type_old=0x78; lda #$78 ; 2 - sta pt3_envelope_type_old ; 4 + sta pt3_envelope_type_old_smc+1 ; 4 ; get next byte iny ; 2 lda (PATTERN_L),Y ; 5+ - sta pt3_envelope_period_h ; 4 + sta pt3_envelope_period_h_smc+1 ; 4 iny ; 2 lda (PATTERN_L),Y ; 5+ - sta pt3_envelope_period_l ; 4 + sta pt3_envelope_period_l_smc+1 ; 4 lda #1 ; 2 sta note_a+NOTE_ENVELOPE_ENABLED,X ; envelope_enabled=1 ; 5 lsr ; 2 sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 5 - sta pt3_envelope_delay ; envelope_delay=0 ; 4 - sta pt3_envelope_slide_l ; envelope_slide=0 ; 4 - sta pt3_envelope_slide_h ; 4 + sta pt3_envelope_delay_smc+1 ; envelope_delay=0 ; 4 + sta pt3_envelope_slide_l_smc+1 ; envelope_slide=0 ; 4 + sta pt3_envelope_slide_h_smc+1 ; 4 rts ; 6 ;=========== @@ -1763,7 +1722,8 @@ is_done: pt3_set_pattern: ; Lookup current pattern in pattern table - ldy current_pattern ; 4 +current_pattern_smc: + ldy #$d1 ; 2 lda PT3_LOC+PT3_PATTERN_TABLE,Y ; 4+ ; if value is $FF we are at the end of the song @@ -1771,7 +1731,7 @@ pt3_set_pattern: beq is_done ; 2/3 ;============ - ; 22 if end + ; 20 if end not_done: @@ -1817,12 +1777,12 @@ not_done: ; clear out the noise channel lda #0 ; 2 - sta pt3_noise_period ; 4 + sta pt3_noise_period_smc+1 ; 4 ; Set all three channels as active ; FIXME: num_channels, may need to be 6 if doing 6-channel pt3? lda #3 ; 2 - sta pt3_pattern_done ; 4 + sta pt3_pattern_done_smc+1 ; 4 rts ; 6 @@ -1838,12 +1798,12 @@ not_done: ; pattern done early! early_end: - inc current_pattern ; increment pattern ; 6 - sta current_line ; 4 - sta current_subframe ; 4 + inc current_pattern_smc+1 ; increment pattern ; 6 + sta current_line_smc+1 ; 4 + sta current_subframe_smc+1 ; 4 check_subframe: - lda current_subframe ; 4 + lda current_subframe_smc+1 ; 4 bne pattern_good ; 2/3 ; load a new pattern in @@ -1858,48 +1818,51 @@ pt3_make_frame: ; see if we need a new pattern ; we do if line==0 and subframe==0 ; allow fallthrough where possible - lda current_line ; 4 +current_line_smc: + lda #$d1 ; 2 beq check_subframe ; 2/3 pattern_good: ; see if we need a new line - lda current_subframe ; 4 +current_subframe_smc: + lda #$d1 ; 2 bne line_good ; 2/3 ; decode a new line jsr pt3_decode_line ; 6+? ; check if pattern done early - lda pt3_pattern_done ; 4 +pt3_pattern_done_smc: + lda #$d1 ; 2 beq early_end ; 2/3 line_good: ; Increment everything - inc current_subframe ; subframe++ ; 6 - lda current_subframe ; 4 + inc current_subframe_smc+1 ; subframe++ ; 6 + lda current_subframe_smc+1 ; 4 ; if we hit pt3_speed, move to next pt3_speed_smc: - eor #0 ; 2 + eor #$d1 ; 2 bne do_frame ; 2/3 next_line: - sta current_subframe ; reset subframe to 0 ; 4 + sta current_subframe_smc+1 ; reset subframe to 0 ; 4 - inc current_line ; and increment line ; 6 - lda current_line ; 4 + inc current_line_smc+1 ; and increment line ; 6 + lda current_line_smc+1 ; 4 eor #64 ; always end at 64. ; 2 bne do_frame ; is this always needed? ; 2/3 next_pattern: - sta current_line ; reset line to 0 ; 4 + sta current_line_smc+1 ; reset line to 0 ; 4 - inc current_pattern ; increment pattern ; 6 + inc current_pattern_smc+1 ; increment pattern ; 6 do_frame: ; AY-3-8910 register summary @@ -1914,11 +1877,11 @@ do_frame: ; R13 = Envelope Shape, 0xff means don't write ; R14/R15 = I/O (ignored) - lda #0 ; needed ; 2 - sta pt3_mixer_value ; 4 - sta pt3_envelope_add ; 4 + ldx #0 ; needed ; 2 + stx pt3_mixer_value_smc+1 ; 4 + stx pt3_envelope_add_smc+1 ; 4 - ldx #(NOTE_STRUCT_SIZE*0) ; Note A ; 2 + ;;ldx #(NOTE_STRUCT_SIZE*0) ; Note A ; 2 jsr calculate_note ; 6+? ldx #(NOTE_STRUCT_SIZE*1) ; Note B ; 2 jsr calculate_note ; 6+? @@ -2058,8 +2021,10 @@ no_scale_c: ; Noise ; frame[6]= (pt3->noise_period+pt3->noise_add)&0x1f; clc ; 2 - lda pt3_noise_period ; 4 - adc pt3_noise_add ; 4 +pt3_noise_period_smc: + lda #$d1 ; 2 +pt3_noise_add_smc: + adc #$d1 ; 2 and #$1f ; 2 sta AY_REGISTERS+6 ; 3 @@ -2090,7 +2055,7 @@ no_scale_n: ;======================= ; Mixer - lda pt3_mixer_value ; 4 + lda pt3_mixer_value_smc+1 ; 4 sta AY_REGISTERS+7 ; 3 ;======================= @@ -2107,19 +2072,24 @@ no_scale_n: ; Envelope period ; result=period+add+slide (16-bits) clc ; 2 - lda pt3_envelope_period_l ; 4 - adc pt3_envelope_add ; 4 +pt3_envelope_period_l_smc: + lda #$d1 ; 2 +pt3_envelope_add_smc: + adc #$d1 ; 2 tay ; 2 - lda pt3_envelope_period_h ; 4 +pt3_envelope_period_h_smc: + lda #$d1 ; 2 adc #0 ; 2 - sta temp_word_h ; 4 + tax ; 2 clc ; 2 tya ; 2 - adc pt3_envelope_slide_l ; 4 +pt3_envelope_slide_l_smc: + adc #$d1 ; 2 sta AY_REGISTERS+11 ; 3 - lda temp_word_h ; 4 - adc pt3_envelope_slide_h ; 4 + txa ; 2 +pt3_envelope_slide_h_smc: + adc #$d1 ; 2 sta AY_REGISTERS+12 ; 3 convert_177_smc5: @@ -2162,9 +2132,11 @@ no_scale_e: ;======================== ; Envelope shape - lda pt3_envelope_type ; 4 - cmp pt3_envelope_type_old ; 4 - sta pt3_envelope_type_old ; copy old to new ; 4 +pt3_envelope_type_smc: + lda #$d1 ; 2 +pt3_envelope_type_old_smc: + cmp #$d1 ; 2 + sta pt3_envelope_type_old_smc+1; copy old to new ; 4 bne envelope_diff ; 2/3 envelope_same: lda #$ff ; if same, store $ff ; 2 @@ -2177,22 +2149,26 @@ envelope_diff: ; end-of-frame envelope update ;============================== - lda pt3_envelope_delay ; 4 +pt3_envelope_delay_smc: + lda #$d1 ; 2 beq done_do_frame ; assume can't be negative? ; 2/3 ; do this if envelope_delay>0 - dec pt3_envelope_delay ; 6 + dec pt3_envelope_delay_smc+1 ; 6 bne done_do_frame ; 2/3 ; only do if we hit 0 - lda pt3_envelope_delay_orig ; reset envelope delay ; 4 - sta pt3_envelope_delay ; 4 +pt3_envelope_delay_orig_smc: + lda #$d1 ; reset envelope delay ; 2 + sta pt3_envelope_delay_smc+1 ; 4 clc ; 16-bit add ; 2 - lda pt3_envelope_slide_l ; 4 - adc pt3_envelope_slide_add_l ; 4 - sta pt3_envelope_slide_l ; 4 - lda pt3_envelope_slide_h ; 4 - adc pt3_envelope_slide_add_h ; 4 - sta pt3_envelope_slide_h ; 4 + lda pt3_envelope_slide_l_smc+1 ; 4 +pt3_envelope_slide_add_l_smc: + adc #$d1 ; 2 + sta pt3_envelope_slide_l_smc+1 ; 4 + lda pt3_envelope_slide_h_smc+1 ; 4 +pt3_envelope_slide_add_h_smc: + adc #$d1 ; 2 + sta pt3_envelope_slide_h_smc+1 ; 4 done_do_frame: @@ -2216,9 +2192,9 @@ GetNoteFreq: bne freq_table_2 ; 2/3 lda PT3NoteTable_ST_high,Y ; 4+ - sta freq_h ; 4 + sta freq_h_smc+1 ; 4 lda PT3NoteTable_ST_low,Y ; 4+ - sta freq_l ; 4 + sta freq_l_smc+1 ; 4 ldy TEMP ; 3 rts ; 6 @@ -2228,9 +2204,9 @@ GetNoteFreq: freq_table_2: lda PT3NoteTable_ASM_34_35_high,Y ; 4+ - sta freq_h ; 4 + sta freq_h_smc+1 ; 4 lda PT3NoteTable_ASM_34_35_low,Y ; 4+ - sta freq_l ; 4 + sta freq_l_smc+1 ; 4 ldy TEMP ; 3 rts ; 6 diff --git a/pt3_player/pt3_player.dsk b/pt3_player/pt3_player.dsk index 15ef9624..c2960db2 100644 Binary files a/pt3_player/pt3_player.dsk and b/pt3_player/pt3_player.dsk differ diff --git a/pt3_player/pt3_player.s b/pt3_player/pt3_player.s index 515485df..2a1077b8 100644 --- a/pt3_player/pt3_player.s +++ b/pt3_player/pt3_player.s @@ -36,9 +36,9 @@ pt3_setup: cmp #6 beq apple_iie_or_newer - lda #1 ; set if older than a IIe - sta apple_ii - jmp done_apple_detect + lda #$d0 ; set if older than a IIe + sta apple_ii_smc + bne done_apple_detect ; branch always apple_iie_or_newer: lda $FBC0 ; 0 on a IIc bne done_apple_detect @@ -204,18 +204,17 @@ check_done: asl ; bit 7 to carry, bit 6 to bit 7 beq main_loop ; if was all zeros, loop bcs main_loop ; if high bit set, paused + sei ; disable interrupts bmi minus_song ; if bit 6 set, then left pressed ; else, either song finished or ; right pressed plus_song: - sei ; disable interrupts jsr increment_file - jmp done_play + bcc done_play ; branch always minus_song: - sei ; disable interrupts jsr decrement_file done_play: @@ -351,7 +350,7 @@ done_name_loop: upcase: ; if Apple II/II+, uppercase the lowercase letters - lda apple_ii +apple_ii_smc: beq no_uppercase ldy #$1e @@ -409,20 +408,13 @@ no_uppercase: ; first update with current values lda WHICH_FILE - clc adc #$1 + ldy #0 jsr convert_decimal - lda which_10s - sta which_song_string - lda which_1s - sta which_song_string+1 lda #NUM_FILES + ldy #3 jsr convert_decimal - lda which_10s - sta which_song_string+3 - lda which_1s - sta which_song_string+4 ; now print modified string @@ -494,110 +486,103 @@ done_MHz: ; Time is just number of frames/50Hz - sta current_line - sta current_subframe - sta current_pattern + sta current_pattern_smc+1 + +frame_count_loop_store: + sta current_line_smc+1 + sta current_subframe_smc+1 frame_count_loop: - lda current_line - bne fc_pattern_good - lda current_subframe + lda current_line_smc+1 + ora current_subframe_smc+1 bne fc_pattern_good ; load a new pattern in jsr pt3_set_pattern lda DONE_SONG - beq fc_pattern_good - jmp done_counting + bne done_counting fc_pattern_good: - lda current_subframe + ldx current_subframe_smc+1 ;;ldx #(NOTE_STRUCT_SIZE*0) bne fc_line_good ; we only calc length of chanel A, hopefully enough lda #1 - sta pt3_pattern_done + sta pt3_pattern_done_smc+1 ; decode_note(&pt3->a,&(pt3->a_addr),pt3); - ldx #(NOTE_STRUCT_SIZE*0) jsr decode_note - lda pt3_pattern_done + lda pt3_pattern_done_smc+1 bne fc_line_good - inc current_pattern ; increment pattern - sta current_line - sta current_subframe - bne frame_count_loop ; branch always + inc current_pattern_smc+1 ; increment pattern + bne frame_count_loop_store ; branch always fc_line_good: - inc current_subframe ; subframe++ - lda current_subframe + inc current_subframe_smc+1 ; subframe++ + lda current_subframe_smc+1 eor pt3_speed_smc+1 ; if we hit pt3_speed, move to next bne fc_do_frame fc_next_line: - sta current_subframe ; reset subframe to 0 + sta current_subframe_smc+1 ; reset subframe to 0 - inc current_line ; and increment line - lda current_line + inc current_line_smc+1 ; and increment line + lda current_line_smc+1 eor #64 ; always end at 64. bne fc_do_frame ; is this always needed? fc_next_pattern: - sta current_line ; reset line to 0 + sta current_line_smc+1 ; reset line to 0 - inc current_pattern ; increment pattern + inc current_pattern_smc+1 ; increment pattern fc_do_frame: - inc time_frame - lda time_frame + inc time_frame_smc+1 +time_frame_smc: + lda #$00 eor #50 bne frame_count_loop - sta time_frame + sta time_frame_smc+1 ; see if overflow low s - lda $BD0+13+10 - cmp #'9'+$80 + ldx $BD0+13+10 + cpx #'9'+$80 bne inc_low_s ; see if overflow high s - lda $BD0+13+9 - cmp #'5'+$80 + ldx $BD0+13+9 + cpx #'5'+$80 bne inc_high_s inc $7D0+13+7 inc $BD0+13+7 - lda #'0'+$80 - sta $7D0+13+9 - sta $BD0+13+9 - bne clear_low_s + ldx #'0'+$80-1 inc_high_s: - inc $7D0+13+9 - inc $BD0+13+9 + inx + stx $7D0+13+9 + stx $BD0+13+9 clear_low_s: - lda #'0'+$80 - sta $7D0+13+10 - sta $BD0+13+10 - - bne inc_done + ldx #'0'+$80-1 inc_low_s: - inc $7D0+13+10 - inc $BD0+13+10 + inx + stx $7D0+13+10 + stx $BD0+13+10 inc_done: fc_bayern: - jmp frame_count_loop + bne frame_count_loop done_counting: @@ -605,7 +590,7 @@ done_counting: ; re-init, as we've run through it lda #0 sta DONE_PLAYING - sta current_pattern + sta current_pattern_smc+1 jmp pt3_init_song @@ -693,39 +678,34 @@ done_decrement: convert_decimal: ldx #'0'+$80 - stx which_1s - stx which_10s + stx which_1s_smc+1 + stx which_10s_smc+1 tax ; special case zero beq conv_decimal_done conv_decimal_loop: - inc which_1s - lda which_1s + inc which_1s_smc+1 +which_1s_smc: + lda #$d1 cmp #':'+$80 bne conv_decimal_not_10 lda #'0'+$80 - sta which_1s - inc which_10s + sta which_1s_smc+1 + inc which_10s_smc+1 conv_decimal_not_10: dex bne conv_decimal_loop conv_decimal_done: +which_10s_smc: + lda #$d1 + sta which_song_string,y + lda which_1s_smc+1 + sta which_song_string+1,y rts -;========= -; vars -;========= - - -time_frame: .byte $0 -apple_ii: .byte $0 -which_10s: .byte $0 -which_1s: .byte $0 - - ;========== ; filenames ;==========