From 722737090796af2038864318f4b9e24a24717ed7 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 20 Dec 2019 21:54:22 +0100 Subject: [PATCH] very experimental head align tool --- .gitignore | 1 + c64/,,config_custom.s | 1 + c64/basic/,imports.s | 4 + c64/basic/basic_main_loop.s | 4 +- c64/basic/wedge_tape.s | 17 +- c64/kernal/tape/head_fit.s | 201 +++++++++++++++++++++ c64/kernal/tape/head_fit_gfx_table.s | 15 ++ c64/kernal/tape/head_fit_ptr_table.s | 20 ++ c64/kernal/tape/head_fit_set_timers.s | 31 ++++ c64/kernal/tape/load_tape_normal.s | 17 +- c64/kernal/tape/tape_common.s | 19 -- c64/kernal/tape/tape_common_motor.s | 25 +++ c64/kernal/tape/tape_normal_get_byte.s | 2 +- c64/kernal/tape/tape_normal_get_pulse.s | 9 +- c64/kernal/tape/tape_normal_setup_timers.s | 34 ++++ 15 files changed, 359 insertions(+), 41 deletions(-) create mode 100644 c64/kernal/tape/head_fit.s create mode 100644 c64/kernal/tape/head_fit_gfx_table.s create mode 100644 c64/kernal/tape/head_fit_ptr_table.s create mode 100644 c64/kernal/tape/head_fit_set_timers.s create mode 100644 c64/kernal/tape/tape_common_motor.s create mode 100644 c64/kernal/tape/tape_normal_setup_timers.s diff --git a/.gitignore b/.gitignore index e4515487..54a3a83a 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,6 @@ build/* # Various IDE project files, temporary files, etc. dump.mem +uart.sock *project .*swp diff --git a/c64/,,config_custom.s b/c64/,,config_custom.s index b3e0bc11..495739e5 100644 --- a/c64/,,config_custom.s +++ b/c64/,,config_custom.s @@ -114,6 +114,7 @@ #define CONFIG_PANIC_SCREEN #define CONFIG_DOS_WEDGE #define CONFIG_TAPE_WEDGE +#define CONFIG_HEAD_FIT_TOOL // ver experimental! #define CONFIG_BCD_SAFE_INTERRUPTS diff --git a/c64/basic/,imports.s b/c64/basic/,imports.s index 525459f4..66b389b4 100644 --- a/c64/basic/,imports.s +++ b/c64/basic/,imports.s @@ -26,3 +26,7 @@ #if CONFIG_SHOW_PAL_NTSC .label print_pal_ntsc = KERNAL.print_pal_ntsc #endif + +#if CONFIG_HEAD_FIT_TOOL +.label head_fit = KERNAL.head_fit +#endif diff --git a/c64/basic/basic_main_loop.s b/c64/basic/basic_main_loop.s index 55ea6dce..89cfe7e5 100644 --- a/c64/basic/basic_main_loop.s +++ b/c64/basic/basic_main_loop.s @@ -64,7 +64,7 @@ rsl_l1: // Check if a wedge should take over -#if CONFIG_DOS_WEDGE || CONFIG_TAPE_WEDGE +#if CONFIG_DOS_WEDGE || CONFIG_TAPE_WEDGE || CONFIG_HEAD_FIT_TOOL ldx __tokenise_work1 // here is the size of input @@ -75,7 +75,7 @@ rsl_l1: cmp #$40 // '@' beq_far wedge_dos #endif -#if CONFIG_TAPE_WEDGE +#if CONFIG_TAPE_WEDGE || CONFIG_HEAD_FIT_TOOL cmp #$1F // left arrow beq_far wedge_tape #endif diff --git a/c64/basic/wedge_tape.s b/c64/basic/wedge_tape.s index 4edbe8e8..8f247249 100644 --- a/c64/basic/wedge_tape.s +++ b/c64/basic/wedge_tape.s @@ -1,5 +1,5 @@ -#if CONFIG_TAPE_WEDGE +#if CONFIG_TAPE_WEDGE || CONFIG_HEAD_FIT_TOOL // .X has to contain size of the buffer @@ -13,6 +13,19 @@ wedge_tape: bne_far do_SYNTAX_error lda BUF+1 + +#if CONFIG_HEAD_FIT_TOOL + + cmp #$48 // 'H' + beq_far head_fit + +#endif +#if !CONFIG_TAPE_WEDGE + + jmp do_SYNTAX_error + +#endif + cmp #$4C // 'L' bne_far do_SYNTAX_error @@ -31,4 +44,4 @@ wedge_tape: jmp cmd_load_got_secondaryaddress -#endif // CONFIG_TAPE_WEDGE +#endif diff --git a/c64/kernal/tape/head_fit.s b/c64/kernal/tape/head_fit.s new file mode 100644 index 00000000..5497bd74 --- /dev/null +++ b/c64/kernal/tape/head_fit.s @@ -0,0 +1,201 @@ + +// +// Simple text mode head alignment tool +// + +// XXX this is experimental only - make it useable! + + +#if CONFIG_HEAD_FIT_TOOL + + +head_fit: + + // Start by disabling interrupts and preparing screen + + sei + jsr clear_screen + + // Now we need to create screen pointers on zero page, we can safely reuse some BASIC variables + // The 6 vectors below completely fills variables: TEMPPT, LASTPT, TEMPST + + .var HF_SCREEN_PTR1_A = TEMPPT+0 // $16-$17 + .var HF_SCREEN_PTR1_B = TEMPPT+2 // $18-$19 + .var HF_SCREEN_PTR2_A = TEMPPT+4 // $1A-$1B + .var HF_SCREEN_PTR2_B = TEMPPT+6 // $1C-$1D + .var HF_SCREEN_PTR3_A = TEMPPT+8 // $1E-$1F + .var HF_SCREEN_PTR3_B = TEMPPT+10 // $20-$21 + + ldx #11 +!: + lda head_fit_ptr_table, x + clc + adc HIBASE + sta HF_SCREEN_PTR1_A, x + + dex + lda head_fit_ptr_table, x + sta HF_SCREEN_PTR1_A, x + + dex + bpl !- + + // Reuse BASIC variable for Normal/Turbo switching + + .var HF_IS_TURBO = RESHO+0 + + inx // puts 0 into .X + sta HF_IS_TURBO + + // Setup CIA #2 timers (this will provide desired resolution), start motor + + jsr head_fit_setup_timers + jsr tape_motor_on + + // Again, reuse 3 BASIC variables + + .var HF_TMP = RESHO+1 + .var HF_SCROLL_CNT = RESHO+2 + .var HF_RASTER_MARK = RESHO+3 + + // FALLTROUGH + +head_fit_loop: + + // Store raster mark + + lda VIC_SCROLY + and #%10000000 + sta HF_RASTER_MARK + + lda #$80 + sta HF_SCROLL_CNT + + jsr tape_normal_get_pulse // ignore this pulse - too much time passed + +head_fit_loop_inner: + + jsr tape_normal_get_pulse + + // Normalize pulse length value to 0-79 + sec + adc #$08 + + sta HF_TMP + lda #$FF + sec + sbc HF_TMP + + cmp #80 + bcc !+ + lda #79 +!: + + // Display value + + tax + + clc + ror + tay // .Y now contains character offset + + lda (HF_SCREEN_PTR1_A), y + cmp #$A0 // is inversed space? + beq head_fit_char_displayed // if so, do not display anything + cmp #$20 + bne !+ + lda #$00 + beq head_fit_store_bits +!: + cmp #$61 + bne !+ + lda #$01 + bne head_fit_store_bits +!: + // Has to be #$E1 + lda #$02 + + // FALLROUGH + +head_fit_store_bits: + + sta HF_TMP + + txa + and #$01 + asl + bne !+ + lda #$01 +!: // .A is now %10 or %01 - depending on the desired pulse position + ora HF_TMP + tax // .X contains now character index, 0-4 + + lda head_fit_gfx_table, x + sta (HF_SCREEN_PTR1_A), y + +head_fit_char_displayed: + + // Check whether to decrement scroll countdown + + lda VIC_SCROLY + and #%10000000 // retrieve highest bit of raster + cmp HF_RASTER_MARK + beq head_fit_loop_inner + + // Decrement scroll countdown + + dec HF_SCROLL_CNT + bne head_fit_loop_inner + + // Scan keys + + jsr udtim_keyboard + lda STKEY + bmi !+ + + // Stop pressed - quit + + jsr tape_motor_off + jsr clear_screen + cli + rts +!: + // If space, toggle system + + cmp #$EF + bne !+ + jsr head_fit_switch_system +!: + // Scroll down the screen + + ldy #240 +!: + lda (HF_SCREEN_PTR3_A), y + sta (HF_SCREEN_PTR3_B), y + + lda (HF_SCREEN_PTR2_A), y + sta (HF_SCREEN_PTR2_B), y + + lda (HF_SCREEN_PTR1_A), y + sta (HF_SCREEN_PTR1_B), y + + dey + cpy #$FF + bne !- + + // Clear the first line + + lda #$20 + ldy #39 +!: + sta (HF_SCREEN_PTR1_A), y + dey + cpy #$FF + bne !- + + // Continue + + jmp head_fit_loop + + +#endif // CONFIG_HEAD_FIT_TOOL diff --git a/c64/kernal/tape/head_fit_gfx_table.s b/c64/kernal/tape/head_fit_gfx_table.s new file mode 100644 index 00000000..6b7133f5 --- /dev/null +++ b/c64/kernal/tape/head_fit_gfx_table.s @@ -0,0 +1,15 @@ + +// +// Screen character table for head alignemnt tool +// + + +#if CONFIG_HEAD_FIT_TOOL + + +head_fit_gfx_table: + + .byte $20, $61, $E1, $A0 + + +#endif diff --git a/c64/kernal/tape/head_fit_ptr_table.s b/c64/kernal/tape/head_fit_ptr_table.s new file mode 100644 index 00000000..12a7e743 --- /dev/null +++ b/c64/kernal/tape/head_fit_ptr_table.s @@ -0,0 +1,20 @@ + +// +// Screen pointer table for head alignemnt tool +// + + +#if CONFIG_HEAD_FIT_TOOL + + +head_fit_ptr_table: + + .word ( 40 * 0 ) + .word ( 40 * 1 ) + .word ( 40 * 6 ) + .word ( 40 * 7 ) + .word ( 40 * 12 ) + .word ( 40 * 13 ) + + +#endif // CONFIG_HEAD_FIT_TOOL diff --git a/c64/kernal/tape/head_fit_set_timers.s b/c64/kernal/tape/head_fit_set_timers.s new file mode 100644 index 00000000..ca145eec --- /dev/null +++ b/c64/kernal/tape/head_fit_set_timers.s @@ -0,0 +1,31 @@ + +// +// Save system switcher for head alignment tool +// + + +#if CONFIG_HEAD_FIT_TOOL + + +head_fit_switch_system: + + lda #$01 + eor HF_IS_TURBO + sta HF_IS_TURBO + + // FALLTROUNG + +head_fit_setup_timers: + + ldx #$08 + lda HF_IS_TURBO + beq !+ + ldx #$04 +!: + + jsr tape_normal_setup_timers_custom + + rts + + +#endif diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index ddb6ec94..749404cc 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -38,21 +38,8 @@ load_tape_normal: jsr tape_ditch_verify // only LOAD is supported, no VERIFY - // Setup CIA #2 timers - - ldx #$03 // set timer A to 4 ticks - stx CIA2_TIMALO // $DD04 - ldx #$00 - stx CIA2_TIMAHI // $DD05 - - stx CIA2_TIMBHI // $DD07 - dex // puts $FF - for running timer B as long as possible - stx CIA2_TIMBLO // $DD06 - - // Let timer A run continuously - - ldx #%00010001 // start timer, force latch reload - stx CIA2_CRA // $DD0E + // Setup CIA #2 timers + jsr tape_normal_setup_timers // Start playing jsr tape_ask_play diff --git a/c64/kernal/tape/tape_common.s b/c64/kernal/tape/tape_common.s index daf95cb0..1f133fd2 100644 --- a/c64/kernal/tape/tape_common.s +++ b/c64/kernal/tape/tape_common.s @@ -34,25 +34,6 @@ tape_break_error: jmp kernalerror_ROUTINE_TERMINATED -// -// Handle tape deck motor -// - -tape_motor_off: - - lda CPU_R6510 - ora #$20 - bne !+ // branch always - -tape_motor_on: - - lda CPU_R6510 - and #($FF - $20) -!: - sta CPU_R6510 - rts - - // // Handle screen (visible/blanked) + tape deck motor (on/off), // store/restore screen color diff --git a/c64/kernal/tape/tape_common_motor.s b/c64/kernal/tape/tape_common_motor.s new file mode 100644 index 00000000..a114ddfc --- /dev/null +++ b/c64/kernal/tape/tape_common_motor.s @@ -0,0 +1,25 @@ + +// +// Handle tape deck motor +// + + +#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO || CONFIG_HEAD_FIT_TOOL + + +tape_motor_off: + + lda CPU_R6510 + ora #$20 + bne !+ // branch always + +tape_motor_on: + + lda CPU_R6510 + and #($FF - $20) +!: + sta CPU_R6510 + rts + + +#endif diff --git a/c64/kernal/tape/tape_normal_get_byte.s b/c64/kernal/tape/tape_normal_get_byte.s index 5bb70c6a..3eb3de09 100644 --- a/c64/kernal/tape/tape_normal_get_byte.s +++ b/c64/kernal/tape/tape_normal_get_byte.s @@ -20,7 +20,7 @@ tape_normal_get_byte: // First we need a byte marker - (L,M) !: jsr tape_normal_get_pulse - cmp #($100 - $95 - $04) + cmp #($FF - $95 - $04) bcs !- // too short for a long pulse jsr tape_normal_get_pulse bcs !- // too short for a medium pulse diff --git a/c64/kernal/tape/tape_normal_get_pulse.s b/c64/kernal/tape/tape_normal_get_pulse.s index 8d08b380..1b3032d2 100644 --- a/c64/kernal/tape/tape_normal_get_pulse.s +++ b/c64/kernal/tape/tape_normal_get_pulse.s @@ -6,7 +6,7 @@ // -#if CONFIG_TAPE_NORMAL +#if CONFIG_TAPE_NORMAL || CONFIG_HEAD_FIT_TOOL tape_normal_get_pulse: @@ -26,6 +26,8 @@ tape_normal_get_pulse: ldx #%01010001 // start timer, force latch reload, count timer A underflows stx CIA2_CRB // $DD0F +#if CONFIG_TAPE_NORMAL + // Since the signal appeared to the point of timer restart we used: // bit - 4 cycles // beq - 2 cycles @@ -37,7 +39,10 @@ tape_normal_get_pulse: // this is total 17 cycles, or $4 periods of 4 ticks (timer A) each - we need to take it into account // every time we check the pulse length - cmp #($100 - $6C - $04) // short vs medium is the default check + cmp #($FF - $6C - $04) // short vs medium is the default check + +#endif + rts diff --git a/c64/kernal/tape/tape_normal_setup_timers.s b/c64/kernal/tape/tape_normal_setup_timers.s new file mode 100644 index 00000000..02ca76b2 --- /dev/null +++ b/c64/kernal/tape/tape_normal_setup_timers.s @@ -0,0 +1,34 @@ + +// +// Helper routine to setup CIA #2 timers +// + +#if CONFIG_TAPE_NORMAL + +tape_normal_setup_timers: + + ldx #$03 // set timer A to 4 ticks + + // FALLTROUGH + +#endif +#if CONFIG_TAPE_NORMAL || CONFIG_HEAD_FIT_TOOL + +tape_normal_setup_timers_custom: // entry for the head fit tool + + stx CIA2_TIMALO // $DD04 + ldx #$00 + stx CIA2_TIMAHI // $DD05 + + stx CIA2_TIMBHI // $DD07 + dex // puts $FF - for running timer B as long as possible + stx CIA2_TIMBLO // $DD06 + + // Let timer A run continuously + + ldx #%00010001 // start timer, force latch reload + stx CIA2_CRA // $DD0E + + rts + +#endif