From 0a84e76e4ed464de325fe83734930f2344260533 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Thu, 16 May 2019 22:16:50 -0400 Subject: [PATCH] pt3: add support for scaling the frequencies from 1.77MHz to 1MHz The ZX Spectrum (default for pt3 files) runs the AY-3-8910 at 1.77MHz. We do this by multiplying by 9/16 (which is a pain, but could be worse) --- pt3_player/README.pt3_player | 21 ++-- pt3_player/interrupt_handler.s | 25 +++-- pt3_player/pt3_lib.s | 182 ++++++++++++++++++++++++++++++++- pt3_player/pt3_player.s | 16 ++- 4 files changed, 228 insertions(+), 16 deletions(-) diff --git a/pt3_player/README.pt3_player b/pt3_player/README.pt3_player index 5be6b749..85699d5c 100644 --- a/pt3_player/README.pt3_player +++ b/pt3_player/README.pt3_player @@ -47,20 +47,27 @@ Using the PT3_PLAYER The pt3_player.dsk should boot automatically. - Use the right/left arrow keys to switch songs. - Press the space bar to pause playback. + Controls: + Right/Left arrow Switch songs + Spacebar Pause playback. + M Switch from 1MHz to 1.77MHz mode FUTURE FEATURES: Key to disable visualization Key to skip ahead/back in pattern list L to enable looping in the song -Known Bugs: -~~~~~~~~~~~ - Will try to display lowecase names on a II/II+ +ZX Compatability: +~~~~~~~~~~~~~~~~~ - ZX Spectrum songs expect a 1.77MHz AY-3-8910, but - the Apple II is 1MHz so song are higher(?) pitched + ZX Spectrum songs expect a 1.77MHz AY-3-8910, but the Apple II + is 1MHz so by default songs would sound lower + pitched. By default now we multiply by 9/16 to scale + things properly, but that does eat up extra CPU cycles. + You can toggle this on/off by pressing "M" when playing. + + In theory we can create songs that expect 1MHz, but the pt3 format + has no way of indicating this. Adding other files ~~~~~~~~~~~~~~~~~~ diff --git a/pt3_player/interrupt_handler.s b/pt3_player/interrupt_handler.s index 86e0ce5e..4f94540a 100644 --- a/pt3_player/interrupt_handler.s +++ b/pt3_player/interrupt_handler.s @@ -189,7 +189,7 @@ check_keyboard: beq exit_interrupt cmp #(' '+$80) - bne key_R + bne key_M key_space: lda #$80 eor DONE_PLAYING @@ -207,13 +207,26 @@ lowbar: jmp quiet_exit -key_R: - cmp #'R' +key_M: + cmp #'M' bne key_left - lda #$ff - eor RASTERBARS_ON - sta RASTERBARS_ON + lda convert_177 + eor #$1 + sta convert_177 + beq at_1MHz + + lda #'7'+$80 + sta $7F4 + sta $BF4 + jmp done_key + +at_1MHz: + lda #'0'+$80 + sta $7F4 + sta $BF4 + + jmp done_key key_left: diff --git a/pt3_player/pt3_lib.s b/pt3_player/pt3_lib.s index 64d2ef1b..8937ca89 100644 --- a/pt3_player/pt3_lib.s +++ b/pt3_player/pt3_lib.s @@ -1803,16 +1803,128 @@ do_frame: lda note_a+NOTE_TONE_H ; Note A Period H sta REGISTER_DUMP+1 ; into R1 + lda convert_177 + beq no_scale_a + + ; Convert from 1.77MHz to 1MHz by multiplying by 9/16 + + ; first multiply by 8 + asl REGISTER_DUMP+0 + rol REGISTER_DUMP+1 + asl REGISTER_DUMP+0 + rol REGISTER_DUMP+1 + asl REGISTER_DUMP+0 + rol REGISTER_DUMP+1 + + ; add in original to get 9 + clc + lda note_a+NOTE_TONE_L + adc REGISTER_DUMP+0 + sta REGISTER_DUMP+0 + lda note_a+NOTE_TONE_H + adc REGISTER_DUMP+1 + sta REGISTER_DUMP+1 + + ; divide by 16 to get proper value + ror REGISTER_DUMP+1 + ror REGISTER_DUMP+0 + ror REGISTER_DUMP+1 + ror REGISTER_DUMP+0 + ror REGISTER_DUMP+1 + ror REGISTER_DUMP+0 + ror REGISTER_DUMP+1 + ror REGISTER_DUMP+0 + lda REGISTER_DUMP+1 + and #$0f + sta REGISTER_DUMP+1 + +no_scale_a: + lda note_b+NOTE_TONE_L ; Note B Period L sta REGISTER_DUMP+2 ; into R2 lda note_b+NOTE_TONE_H ; Note B Period H sta REGISTER_DUMP+3 ; into R3 + lda convert_177 + beq no_scale_b + + ; Convert from 1.77MHz to 1MHz by multiplying by 9/16 + + ; first multiply by 8 + asl REGISTER_DUMP+2 + rol REGISTER_DUMP+3 + asl REGISTER_DUMP+2 + rol REGISTER_DUMP+3 + asl REGISTER_DUMP+2 + rol REGISTER_DUMP+3 + + ; add in original to get 9 + clc + lda note_b+NOTE_TONE_L + adc REGISTER_DUMP+2 + sta REGISTER_DUMP+2 + lda note_b+NOTE_TONE_H + adc REGISTER_DUMP+3 + sta REGISTER_DUMP+3 + + ; divide by 16 to get proper value + ror REGISTER_DUMP+3 + ror REGISTER_DUMP+2 + ror REGISTER_DUMP+3 + ror REGISTER_DUMP+2 + ror REGISTER_DUMP+3 + ror REGISTER_DUMP+2 + ror REGISTER_DUMP+3 + ror REGISTER_DUMP+2 + lda REGISTER_DUMP+3 + and #$0f + sta REGISTER_DUMP+3 + +no_scale_b: + lda note_c+NOTE_TONE_L ; Note C Period L sta REGISTER_DUMP+4 ; into R4 lda note_c+NOTE_TONE_H ; Note C Period H sta REGISTER_DUMP+5 ; into R5 + lda convert_177 + beq no_scale_c + + ; Convert from 1.77MHz to 1MHz by multiplying by 9/16 + + ; first multiply by 8 + asl REGISTER_DUMP+4 + rol REGISTER_DUMP+5 + asl REGISTER_DUMP+4 + rol REGISTER_DUMP+5 + asl REGISTER_DUMP+4 + rol REGISTER_DUMP+5 + + ; add in original to get 9 + clc + lda note_c+NOTE_TONE_L + adc REGISTER_DUMP+4 + sta REGISTER_DUMP+4 + lda note_c+NOTE_TONE_H + adc REGISTER_DUMP+5 + sta REGISTER_DUMP+5 + + ; divide by 16 to get proper value + ror REGISTER_DUMP+5 + ror REGISTER_DUMP+4 + ror REGISTER_DUMP+5 + ror REGISTER_DUMP+4 + ror REGISTER_DUMP+5 + ror REGISTER_DUMP+4 + ror REGISTER_DUMP+5 + ror REGISTER_DUMP+4 + lda REGISTER_DUMP+5 + and #$0f + sta REGISTER_DUMP+5 + +no_scale_c: + + ; Noise ; frame[6]= (pt3->noise_period+pt3->noise_add)&0x1f; clc @@ -1820,6 +1932,34 @@ do_frame: adc pt3_noise_add and #$1f sta REGISTER_DUMP+6 + sta temp_word_l + + lda convert_177 + beq no_scale_n + + ; Convert from 1.77MHz to 1MHz by multiplying by 9/16 + + ; first multiply by 8 + asl REGISTER_DUMP+6 + asl REGISTER_DUMP+6 + asl REGISTER_DUMP+6 + + ; add in original to get 9 + clc + lda temp_word_l + adc REGISTER_DUMP+6 + + ; divide by 16 to get proper value + ror REGISTER_DUMP+6 + ror REGISTER_DUMP+6 + ror REGISTER_DUMP+6 + ror REGISTER_DUMP+6 + lda REGISTER_DUMP+6 + and #$1f + sta REGISTER_DUMP+6 + +no_scale_n: + ; Mixer @@ -1847,13 +1987,51 @@ do_frame: clc lda pt3_envelope_slide_l adc temp_word_l -; sta temp_word_l + sta temp_word_l sta REGISTER_DUMP+11 lda temp_word_h adc pt3_envelope_slide_h -; sta temp_word_h + sta temp_word_h sta REGISTER_DUMP+12 + lda convert_177 + beq no_scale_e + + ; Convert from 1.77MHz to 1MHz by multiplying by 9/16 + + ; first multiply by 8 + asl REGISTER_DUMP+11 + rol REGISTER_DUMP+12 + asl REGISTER_DUMP+11 + rol REGISTER_DUMP+12 + asl REGISTER_DUMP+11 + rol REGISTER_DUMP+12 + + ; add in original to get 9 + clc + lda temp_word_l + adc REGISTER_DUMP+11 + sta REGISTER_DUMP+11 + lda temp_word_h + adc REGISTER_DUMP+12 + sta REGISTER_DUMP+12 + + ; divide by 16 to get proper value + ror REGISTER_DUMP+12 + ror REGISTER_DUMP+11 + ror REGISTER_DUMP+12 + ror REGISTER_DUMP+11 + ror REGISTER_DUMP+12 + ror REGISTER_DUMP+11 + ror REGISTER_DUMP+12 + ror REGISTER_DUMP+11 + lda REGISTER_DUMP+12 + and #$0f + sta REGISTER_DUMP+12 + +no_scale_e: + + ; Envelope shape lda pt3_envelope_type cmp pt3_envelope_type_old diff --git a/pt3_player/pt3_player.s b/pt3_player/pt3_player.s index fa758169..08116a65 100644 --- a/pt3_player/pt3_player.s +++ b/pt3_player/pt3_player.s @@ -334,6 +334,20 @@ done_name_loop: sta CH jsr print_both_pages ; print, tail call + ; update the MHz indicator with current state + + lda convert_177 + beq set_1MHz + + lda #'7'+$80 + jmp done_MHz + +set_1MHz: + lda #'0'+$80 +done_MHz: + sta $7F4 + sta $BF4 + ; Print Left Arrow (INVERSE) lda #'<' sta $6D0 @@ -592,5 +606,5 @@ found_message: .asciiz "FOUND" ;done_message: .asciiz "DONE PLAYING" loading_message: .asciiz "LOADING" clock_string: .asciiz "0:00 / 0:00" -mhz_string: .asciiz "1.0MHZ" +mhz_string: .asciiz "1.7MHZ"