268 lines
4.7 KiB
ArmAsm
268 lines
4.7 KiB
ArmAsm
// #LAYOUT# STD * #TAKE
|
|
// #LAYOUT# M65 KERNAL_1 #TAKE
|
|
// #LAYOUT# * * #IGNORE
|
|
|
|
//
|
|
// Tape head alignemnt tool
|
|
//
|
|
|
|
|
|
#if CONFIG_TAPE_HEAD_ALIGN
|
|
|
|
|
|
.label __ha_start = 12 // starting row of the chart
|
|
.label __ha_rows = 11 // number of rows for scrolling
|
|
|
|
// Helper tables
|
|
|
|
.label __ha_offsets = $1000;
|
|
.label __ha_masks = $1100;
|
|
|
|
// Generated code location
|
|
|
|
.label __ha_scroll = $1300;
|
|
|
|
// Flag for GFX effects - reuse BASIC numeric work area on zero page
|
|
|
|
.label __ha_gfxflag = TEMPF2; // 1 byte
|
|
|
|
|
|
tape_head_align:
|
|
|
|
// Make sure user really wants to launch the tool
|
|
|
|
jsr tape_ask_play
|
|
|
|
// Disable interrupts, set proper I/O values
|
|
|
|
jsr CLALL
|
|
|
|
sei
|
|
|
|
jsr IOINIT
|
|
// jsr CINT
|
|
|
|
jsr nmi_lock
|
|
|
|
// Prepare CIA timers
|
|
|
|
ldx #$02 // set timer A to 3 ticks
|
|
jsr tape_common_prepare_cia_by_x
|
|
|
|
ldx #$FF // timer to control scroll speed
|
|
stx CIA1_TIMBLO // $DC06
|
|
stx CIA1_TIMBHI // $DC07
|
|
|
|
jsr tape_motor_on
|
|
|
|
// Clear color data ($0800)
|
|
|
|
ldy #$00
|
|
!:
|
|
lda #(CONFIG_COLOR_TXT * $10 + CONFIG_COLOR_BG)
|
|
|
|
sta $0800, y
|
|
sta $0900, y
|
|
sta $0A00, y
|
|
sta $0B00, y
|
|
|
|
iny
|
|
bne !-
|
|
|
|
// Clear bitmap data ($2000)
|
|
|
|
lda #$20
|
|
sta SAL+1
|
|
tya // put 0 to .A
|
|
sta SAL+0
|
|
!:
|
|
sta (SAL), y
|
|
iny
|
|
bne !-
|
|
|
|
inc SAL+1
|
|
ldx SAL+1
|
|
cpx #$40
|
|
bne !-
|
|
|
|
// Print help message
|
|
|
|
jsr tape_head_align_print_help
|
|
|
|
// Make sure the row where the chart is being created is not visible
|
|
|
|
lda #(CONFIG_COLOR_TXT * $10 + CONFIG_COLOR_TXT)
|
|
ldy #$24
|
|
!:
|
|
sta $0800 + __ha_start * 40 + 1, y
|
|
sta $0800 + __ha_start * 40 + 1 + (__ha_rows + 1) * 40, y
|
|
|
|
dey
|
|
bne !-
|
|
|
|
// Set graphics mode
|
|
|
|
lda #$28 // graphics start at $2000, color at $0800
|
|
sta VIC_YMCSB
|
|
|
|
lda #$3B // set bit 5 to enable graphic mode
|
|
sta VIC_SCROLY
|
|
|
|
// Prepare lookup tables - to speed drawing, we are going to use two of them:
|
|
// - byte offset table will tell us which byte in memory to alter
|
|
// - mask will allow us to quickly put the pixel
|
|
|
|
ldx #$00 // loop index
|
|
ldy #$00 // temporary value for mask calculation
|
|
!:
|
|
// Byte offset is simple, just zero the 3 least significant bits
|
|
|
|
txa
|
|
and #%11111000
|
|
sta __ha_offsets, x
|
|
|
|
// Mask changes with each iteration, use our temporary value in .Y
|
|
|
|
tya
|
|
clc
|
|
ror
|
|
bne !+
|
|
lda #%10000000
|
|
!:
|
|
tay
|
|
sta __ha_masks, x
|
|
|
|
// Next iteration
|
|
|
|
inx
|
|
bne !--
|
|
|
|
// Initialize flag for additional GFX effects
|
|
|
|
stx __ha_gfxflag // .X is 0 at this moment
|
|
|
|
// Generate helper code for screen scrolling
|
|
|
|
jsr tape_head_align_gen_code
|
|
|
|
// Provide new IRQ routine address
|
|
|
|
lda #<tape_head_align_irq
|
|
sta CINV+0
|
|
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 #$FB // we want no badlines during the interrupt, this raster is 100% safe
|
|
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
|
|
|
|
// Launch the timer
|
|
|
|
ldx #%00011001 // start timer, one-shot force latch reload, count system ticks
|
|
stx CIA1_CRB // $DC0F
|
|
|
|
// Scroll the whole chart one line down
|
|
|
|
ldx #$00
|
|
!:
|
|
jsr __ha_scroll // scroll one column down, using fast generated code
|
|
|
|
txa
|
|
clc
|
|
adc #$08
|
|
tax
|
|
bne !-
|
|
|
|
// Draw decorations
|
|
|
|
lda __ha_gfxflag
|
|
inc __ha_gfxflag
|
|
clc
|
|
adc #$08
|
|
and #%00001100
|
|
bne !+
|
|
ldy #%11110001
|
|
lda #%10001111
|
|
bne !++
|
|
!:
|
|
ldy #%00000001
|
|
lda #%10000000
|
|
!:
|
|
ora __ha_chart + 7 + 8 * 0
|
|
sta __ha_chart + 7 + 8 * 0
|
|
|
|
tya
|
|
ora __ha_chart + 7 + 8 * 31
|
|
sta __ha_chart + 7 + 8 * 31
|
|
|
|
// Draw helper lines
|
|
|
|
lda __ha_gfxflag
|
|
and #%00000010
|
|
beq !+
|
|
|
|
// For 'normal'
|
|
|
|
lda #%00000001
|
|
ora __ha_chart + 7 + 8 * 6
|
|
sta __ha_chart + 7 + 8 * 6
|
|
|
|
lda #%00000001
|
|
ora __ha_chart + 7 + 8 * 13
|
|
sta __ha_chart + 7 + 8 * 13
|
|
|
|
// For 'turbo'
|
|
|
|
lda #%00010000
|
|
ora __ha_chart + 7 + 8 * 21
|
|
sta __ha_chart + 7 + 8 * 21
|
|
!:
|
|
// FALLTROUGH
|
|
|
|
tape_head_align_loop_2:
|
|
|
|
lda CIA1_TIMBLO
|
|
and CIA1_TIMBHI
|
|
eor #$FF
|
|
|
|
bne tape_head_align_loop_2
|
|
beq tape_head_align_loop_1
|
|
|
|
|
|
tape_head_align_quit:
|
|
|
|
// It makes no sense to return to system, as we already destroyed
|
|
// a lot of memory; fust clear initial BASIC text area to prevent
|
|
// data recovery attempts, and reset
|
|
|
|
ldx #$00
|
|
txa
|
|
!:
|
|
sta $0800, x
|
|
inx
|
|
bne !-
|
|
|
|
jmp hw_entry_reset
|
|
|
|
|
|
#endif // CONFIG_TAPE_HEAD_ALIGN
|