videochargen/main.S

112 lines
1.7 KiB
ArmAsm

#include <avr/io.h>
#include "macro.h"
#include "const.h"
.data
frame:
.word 0
line:
.word 0
.text
.global main
main:
ldi r16, 0x30 ; port B, pin 4 and 5 as output
sts DDRB, r16
; set interrupt vectors at address 0x0, not bootloader
; timing is important, see atmel datasheet
ldi r16, (1 << IVCE)
ldi r17, 0
out IO(MCUCR), r16
out IO(MCUCR), r17
ldi r16, 0xa ; external interrupt 0 and 1, falling edge
sts EICRA, r16
ldi r16, 0x3 ; external interrupt 0 and 1, mask enable
sts EIMSK, r16
sei ; global interrupt enable
1:
rjmp 1b
.global int_horizontal_sync
int_horizontal_sync:
push r31
in r31, IO(SREG) ; status register
push r31
push r30
; if (line >= VERTICAL_OFFSET), then enter
lds r30, line
lds r31, line + 1
adiw z, 1
sts line, r30
sts line + 1, r31
cpi r31, 0
brne enter
cpi r30, VERTICAL_OFFSET
brlo int_horizontal_sync_end
enter:
ldi r31, HORIZONTAL_OFFSET_CYCLE ; skip back porch
1:
dec r31
brne 1b
; do things
lds r31, frame
cpi r31, 0
breq 2f
1:
dec r31
brne 1b
2:
sbi IO(PORTB), 4
nop
nop
nop
nop
nop
cbi IO(PORTB), 4
int_horizontal_sync_end:
pop r30
pop r31
out IO(SREG), r31
pop r31
reti
.global int_vertical_sync
int_vertical_sync:
push r31
in r31, IO(SREG)
push r31
push r30
lds r31, frame + 1
lds r30, frame
adiw z, 1
sts frame + 1, r31
sts frame, r30
ldi r30, 1
ldi r31, 0
sts line, r30
sts line + 1, r31
int_vertical_sync_end:
pop r30
pop r31
out IO(SREG), r31
pop r31
reti