diff --git a/c64/kernal/tape/tape_head_align.s b/c64/kernal/tape/tape_head_align.s index cc84745d..d645bd9e 100644 --- a/c64/kernal/tape/tape_head_align.s +++ b/c64/kernal/tape/tape_head_align.s @@ -10,20 +10,25 @@ #if CONFIG_TAPE_HEAD_ALIGN +// XXX for Mega65 it can be done more easily, by just disabling the badlines -.label __ha_start = 11 // starting row of the chart -.label __ha_rows = 10 // number of rows for scrolling + +.label __ha_start = 11 // starting row of the chart +.label __ha_rows = 10 // number of rows for scrolling // Helper tables -.label __ha_offsets = $1000; -.label __ha_masks = $1100; +.label __ha_offsets = $1000; +.label __ha_masks = $1100; // Helper variables -.label __ha_lda_addr = $1200; // 2 bytes, for code generator -.label __ha_sta_addr = $1202; // 2 bytes, for code generator -.label __ha_gfxflag = $1204; +.label __ha_lda_addr = $1200; // 2 bytes, for code generator +.label __ha_sta_addr = $1202; // 2 bytes, for code generator +.label __ha_pulses = $1204; // 16 bytes +.label __ha_gfxflag = $1214; // 1 byte +.label __ha_loopcnt = $1215; // 1 byte + // Generated code location @@ -42,8 +47,8 @@ tape_head_align: // Disable interrupts, set proper I/O values - sei jsr CLALL + sei jsr IOINIT jsr cint_legacy @@ -133,22 +138,49 @@ tape_head_align: inx bne !-- - // Initialize flag for additional GFX effects + // Initialize flag for additional GFX effects and the pulse lengths - stx __ha_gfxflag + lda #$00 + ldx #$10 +!: + sta __ha_pulses, x + dex + bpl !- // Generate helper code for screen scrolling jsr tape_head_align_gen_code + // Provide new IRQ routine address + + lda #tape_head_align_irq + sta CINV+1 + + // Setup raster interrupt routine - see https://www.c64-wiki.com/wiki/Raster_interrupt + + lda #%01111111 // prevent CIA from generating interrupts + sta CIA1_ICR // $DC0D + + and VIC_SCROLY // clear the highest bit of RASTER + sta VIC_SCROLY // $D011 + + lda #$FF // setup interrupt on line 255, near no-badline area + sta VIC_RASTER + + lda #%00000001 // enable raster interrupts + sta VIC_IRQMSK // $D01A + cli + tape_head_align_loop_1: + // Check for STOP key + jsr udtim_keyboard jsr STOP bcs tape_head_align_quit - // XXX check for STOP, go to tape_head_align_quit - // Launch the timer ldx #%00011001 // start timer, one-shot force latch reload, count system ticks @@ -175,24 +207,26 @@ tape_head_align_loop_1: jsr tape_head_align_get_pulse jsr tape_head_align_get_pulse + // FALLTROUGH + tape_head_align_loop_2: - // Retrieve actual pulse length + // Draw pulses - jsr tape_head_align_get_pulse + ldx #$00 +!: + stx __ha_loopcnt + + lda __ha_pulses, x cmp #$FF - beq tape_head_align_drawn // skip drawing for too long pulses + beq tape_head_align_drawn // $FF - end of pulses to draw - // Put pulse on the screen; center the chart horizontaly, with some margin from top + jsr tape_head_align_draw_pulse - .label __ha_chart = $2000 + 8 * (40 * __ha_start + 4) - - tax - lda __ha_offsets, x - tay - lda __ha_masks, x - ora __ha_chart + 7, y - sta __ha_chart + 7, y + ldx __ha_loopcnt + inx + cpx #$10 + bne !- // FALLTROUGH @@ -224,9 +258,27 @@ tape_head_align_quit: + +tape_head_align_draw_pulse: + + // Put pulse on the screen; center the chart horizontaly, with some margin from top + + .label __ha_chart = $2000 + 8 * (40 * __ha_start + 4) + + tax + lda __ha_offsets, x + tay + lda __ha_masks, x + ora __ha_chart + 7, y + sta __ha_chart + 7, y +!: + rts + + + tape_head_align_apply_gfx: - // Apply GFX effects XXX improve it + // Apply GFX effects lda __ha_gfxflag inc __ha_gfxflag diff --git a/c64/kernal/tape/tape_head_align_get_pulse.s b/c64/kernal/tape/tape_head_align_get_pulse.s index 03d04d7c..c1811238 100644 --- a/c64/kernal/tape/tape_head_align_get_pulse.s +++ b/c64/kernal/tape/tape_head_align_get_pulse.s @@ -15,6 +15,7 @@ tape_head_align_get_pulse: // This routine differs from the one used to read pulse during tape reading: // - it is not as precise // - it terminates when timer reaches $FF + // - ir returns value in .Y lda #$10 !: @@ -27,14 +28,18 @@ tape_head_align_get_pulse: cpy #$FF bne !- !: + // FALLTROUGH + +tape_head_align_get_pulse_start_timer: + // Start timer again, force latch reload, count timer A underflows - ldx #%01010001 - stx CIA2_CRB // $DD0F + lda #%01010001 + sta CIA2_CRB // $DD0F - // Return with time elapsed + // Return with time elapsed in .Y - tya rts + #endif // CONFIG_TAPE_HEAD_ALIGN diff --git a/c64/kernal/tape/tape_head_align_irq.s b/c64/kernal/tape/tape_head_align_irq.s new file mode 100644 index 00000000..92535a56 --- /dev/null +++ b/c64/kernal/tape/tape_head_align_irq.s @@ -0,0 +1,54 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape head alignemnt tool - interrupt routine +// + + +#if CONFIG_TAPE_HEAD_ALIGN + + +tape_head_align_irq: + + // inc $d020 // XXX for debug only + + // Acknowledge interrupt + + asl VIC_IRQ + + // Clear table of pulses stored + + lda #$FF + ldy #$0F +!: + sta __ha_pulses, y + dey + bpl !- + + // Ignore 2 first pulses, they can be garbage + + jsr tape_head_align_get_pulse + jsr tape_head_align_get_pulse + + // Now, we can retrieve a pulse for real + + ldx #$00 +!: + jsr tape_head_align_get_pulse + tya + sta __ha_pulses, x + + // XXX terminate ion case VIC_RASTER went too far + + inx + cpx #$10 + bne !- + + // dec $d020 // XXX for debug only + + jmp return_from_interrupt + + +#endif // CONFIG_TAPE_HEAD_ALIGN