videochargen/main.S
2022-11-04 21:44:20 +01:00

205 lines
3.8 KiB
ArmAsm

; 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 <avr/io.h>
#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