; main.S ; ; This file is part of OSDY VideoCharGen ; a do-it-yourself on-screen-display image generator ; for superimposition of analog PAL signals ; #include #include "macro.h" #include "const.h" .data show_image: .byte 0x00 button_next_image: .byte 0x0 current_jump_table: .word 0x0 .text .global main_asm main_asm: ; init variables ldi r16, 0 sts show_image, r16 ; r0 always holds 0 clr r0 ; global interrupt enable sei ; endless loop 1: rjmp 1b .global int_horizontal_sync_s int_horizontal_sync_s: push r31 ; +2 push r30 ; +2 ; load timer to trigger isr at the beginning of the visible scanline ; reset counter to 0 ldi r31, 0 ; +1 sts TCNT1H, r31 ; +2 sts TCNT1L, r31 ; +2 ; set counter TOP (MSB first!) lds r31, hpos + 1 ; +2 lds r30, hpos ; +2 sts OCR1AH, r31 ; +2 sts OCR1AL, r30 ; +2 ; clear any pending interrupt ldi r31, 0x7 ; +1 sts TIFR1, r31 ; +2 ; enable interrupt timer A lds r31, TIMSK1 ; +2 ori r31, 0x02 ; +1 sts TIMSK1, r31 ; +2 ; total: 25 ; HSYNC_INT_TUNE = 25 ; this adds up for HSYNC_SYSCLOCK_TUNE pop r30 pop r31 ret .global int_timer_1 int_timer_1: ; here we are at the beginning of the visible line ; jmp (from C) ; +3 push r31 ; +2 in r31, IO(SREG) ; +1 push r31 ; +2 push r30 ; +2 push r29 ; +2 push r25 ; +2 ; turn off interrupt lds r31, TIMSK1 ; +2 andi r31, 0xfd ; mask disable interrupt timer A, +1 sts TIMSK1, r31 ; +2 lds r31, show_image ; +2 cpi r31, 0x1 ; +1 brne jump_table_return_address ; +1 (not taken) lds zl, current_jump_table ; +2 lds zh, current_jump_table + 1 ; +2 clr r0 ; +1 lds r29, line ; +2 lds r25, vpos ; +2 sub r29, r25 ; +1 add zl, r29 ; +1 adc zh, r0 ; +1 add zl, r29 ; +1 adc zh, r0 ; +1 ijmp ; +2 ; total: 39 ; HSYNC_TIMER_TUNE = 39 ; this adds up for HSYNC_SYSCLOCK_TUNE .global jump_table_return_address jump_table_return_address: pop r25 pop r29 pop r30 pop r31 out IO(SREG), r31 pop r31 reti .global int_vertical_sync_s int_vertical_sync_s: push r31 in r31, IO(SREG) push zl push zh push yl push yh ldi r30, 1 ldi r31, 0 sts line, r30 sts line + 1, r31 ; check button in r31, IO(PINB) andi r31, 0x08 breq check_if_released ldi r31, 1 sts button_next_image, r31 jmp int_vertical_sync_end check_if_released: lds r31, button_next_image cpi r31, 1 brne int_vertical_sync_end ; here button is released ; read transition mode in r31, IO(PINB) andi r31, 0x04 ; if transition mode == 1, then always show image ; Nice to have: maybe this can be written better. breq 1f ldi r31, 0 sts show_image, r31 1: lds r31, show_image cpi r31, 1 breq 1f ldi r31, 1 sts show_image, r31 rjmp 2f 1: ldi r31, 0 sts show_image, r31 rjmp end_button_release 2: ; show image ldi zl, pm_lo8(line_jump_table_0) ldi zh, pm_hi8(line_jump_table_0) clr yl lds yh, image inc yh sts image, yh add zh, yh add zh, yh sts current_jump_table, zl sts current_jump_table + 1, zh ldi r31, 0x01 sts show_image, r31 end_button_release: clr yl sts button_next_image, yl int_vertical_sync_end: pop yh pop yl pop zh pop zl out IO(SREG), r31 pop r31 reti