2021-06-26 17:15:17 +00:00
|
|
|
#include <avr/io.h>
|
|
|
|
#include "macro.h"
|
2021-06-27 19:57:02 +00:00
|
|
|
#include "const.h"
|
2021-06-26 17:15:17 +00:00
|
|
|
|
|
|
|
.text
|
|
|
|
|
2021-06-27 19:57:02 +00:00
|
|
|
.global main
|
|
|
|
main:
|
|
|
|
ldi r16, 0x30 ; port B, pin 4 and 5 as output
|
2021-06-26 17:15:17 +00:00
|
|
|
sts DDRB, r16
|
|
|
|
|
2021-06-27 19:57:02 +00:00
|
|
|
; set interrupt vectors at address 0x0, not bootloader
|
|
|
|
; timing is important, see atmel datasheet
|
|
|
|
ldi r16, (1 << IVCE)
|
2021-06-26 17:15:17 +00:00
|
|
|
ldi r17, 0
|
|
|
|
out IO(MCUCR), r16
|
|
|
|
out IO(MCUCR), r17
|
|
|
|
|
2021-06-26 21:42:23 +00:00
|
|
|
ldi r16, 0xa ; external interrupt 0 and 1, falling edge
|
2021-06-26 17:15:17 +00:00
|
|
|
sts EICRA, r16
|
|
|
|
|
2021-06-26 21:42:23 +00:00
|
|
|
ldi r16, 0x3 ; external interrupt 0 and 1, mask enable
|
2021-06-26 17:15:17 +00:00
|
|
|
sts EIMSK, r16
|
|
|
|
|
2021-07-03 09:54:31 +00:00
|
|
|
ldi r16, 0x02 ; don't connect output pins to timer, CTC[1:0] mode
|
|
|
|
sts TCCR0A, r16
|
2021-07-03 10:05:49 +00:00
|
|
|
ldi r16, 0x01 ; CTC[2] mode, no prescaler
|
2021-07-03 09:54:31 +00:00
|
|
|
sts TCCR0B, r16
|
|
|
|
|
|
|
|
; init variables
|
|
|
|
ldi r16, 0
|
|
|
|
sts frame, r16
|
|
|
|
sts frame + 1, r16
|
|
|
|
sts line + 1, r16
|
|
|
|
ldi r16, 1
|
|
|
|
sts line, r16
|
|
|
|
|
2021-08-10 07:26:51 +00:00
|
|
|
; r0 always holds 0
|
|
|
|
clr r0
|
|
|
|
|
2021-07-03 13:44:01 +00:00
|
|
|
call setup_c
|
2021-07-03 13:02:01 +00:00
|
|
|
|
2021-06-27 19:57:02 +00:00
|
|
|
sei ; global interrupt enable
|
2021-06-26 17:15:17 +00:00
|
|
|
|
|
|
|
1:
|
2021-06-27 19:57:02 +00:00
|
|
|
rjmp 1b
|
|
|
|
|
2021-06-26 21:42:23 +00:00
|
|
|
.global int_horizontal_sync
|
2021-06-28 19:54:25 +00:00
|
|
|
int_horizontal_sync: ; +3
|
|
|
|
push r31 ; +5
|
|
|
|
in r31, IO(SREG) ; +6, status register
|
|
|
|
push r31 ; +8
|
|
|
|
push r30 ; +10
|
2021-06-28 19:38:39 +00:00
|
|
|
|
|
|
|
; if (line >= VERTICAL_OFFSET), then enter
|
2021-06-28 19:54:25 +00:00
|
|
|
lds r30, line ; +12
|
|
|
|
lds r31, line + 1 ; +14
|
|
|
|
adiw z, 1 ; +16
|
|
|
|
sts line, r30 ; +18
|
|
|
|
sts line + 1, r31 ; +20
|
|
|
|
cpi r31, 0 ; +21
|
2021-08-10 07:26:51 +00:00
|
|
|
breq enter ; +23
|
|
|
|
jmp int_horizontal_sync_end
|
2021-06-27 19:57:02 +00:00
|
|
|
|
2021-06-27 20:37:11 +00:00
|
|
|
enter:
|
2021-06-28 19:54:25 +00:00
|
|
|
; here, +23 or +24 cycles have passed since horizontal sync
|
|
|
|
; so, there are still ~168 cycles before first useful data
|
2021-07-03 09:54:31 +00:00
|
|
|
ldi r31, 0
|
|
|
|
sts TCNT0, r31
|
|
|
|
ldi r31, HORIZONTAL_OFFSET ; set counter TOP
|
|
|
|
sts OCR0A, r31
|
|
|
|
|
|
|
|
ldi r31, 0x7 ; clear any pending interrupt
|
|
|
|
sts TIFR0, r31
|
2021-06-27 20:37:11 +00:00
|
|
|
|
2021-07-03 09:54:31 +00:00
|
|
|
lds r31, TIMSK0
|
|
|
|
ori r31, 0x02 ; mask enable interrupt timer A
|
|
|
|
sts TIMSK0, r31
|
|
|
|
|
|
|
|
int_horizontal_sync_end:
|
|
|
|
pop r30
|
|
|
|
pop r31
|
|
|
|
out IO(SREG), r31
|
|
|
|
pop r31
|
|
|
|
reti
|
|
|
|
|
|
|
|
.global int_timer_0
|
|
|
|
int_timer_0:
|
|
|
|
; here we are at the beginning of the visible line
|
|
|
|
push r31
|
|
|
|
in r31, IO(SREG)
|
|
|
|
push r31
|
2021-07-03 13:02:01 +00:00
|
|
|
push r30
|
|
|
|
push r29
|
2021-07-03 09:54:31 +00:00
|
|
|
|
|
|
|
; turn off interrupt
|
|
|
|
lds r31, TIMSK0
|
|
|
|
andi r31, 0xfd ; mask disable interrupt timer A
|
|
|
|
sts TIMSK0, r31
|
|
|
|
|
2021-08-10 07:26:51 +00:00
|
|
|
clr r0
|
|
|
|
ldi zl, pm_lo8(line_jump_table)
|
|
|
|
ldi zh, pm_hi8(line_jump_table)
|
2021-06-27 20:37:11 +00:00
|
|
|
|
2021-08-10 07:26:51 +00:00
|
|
|
lds r29, line
|
|
|
|
add zl, r29
|
|
|
|
adc zh, r0
|
|
|
|
add zl, r29
|
|
|
|
adc zh, r0
|
|
|
|
|
|
|
|
ijmp
|
2021-06-27 19:57:02 +00:00
|
|
|
|
2021-08-11 07:04:59 +00:00
|
|
|
.global jump_table_return_address
|
2021-08-10 07:26:51 +00:00
|
|
|
jump_table_return_address:
|
2021-07-03 13:02:01 +00:00
|
|
|
pop r29
|
|
|
|
pop r30
|
2021-06-26 20:34:22 +00:00
|
|
|
pop r31
|
|
|
|
out IO(SREG), r31
|
|
|
|
pop r31
|
|
|
|
reti
|
2021-06-26 17:15:17 +00:00
|
|
|
|
2021-06-26 21:42:23 +00:00
|
|
|
.global int_vertical_sync
|
|
|
|
int_vertical_sync:
|
|
|
|
push r31
|
2021-06-27 19:57:02 +00:00
|
|
|
in r31, IO(SREG)
|
|
|
|
push r31
|
2021-06-28 19:38:39 +00:00
|
|
|
push r30
|
2021-06-27 19:57:02 +00:00
|
|
|
|
2021-06-28 19:38:39 +00:00
|
|
|
lds r31, frame + 1
|
|
|
|
lds r30, frame
|
|
|
|
adiw z, 1
|
|
|
|
sts frame + 1, r31
|
|
|
|
sts frame, r30
|
2021-06-27 19:57:02 +00:00
|
|
|
|
2021-06-28 19:38:39 +00:00
|
|
|
ldi r30, 1
|
|
|
|
ldi r31, 0
|
|
|
|
sts line, r30
|
|
|
|
sts line + 1, r31
|
2021-06-27 19:57:02 +00:00
|
|
|
|
|
|
|
int_vertical_sync_end:
|
2021-06-28 19:38:39 +00:00
|
|
|
pop r30
|
2021-06-27 19:57:02 +00:00
|
|
|
pop r31
|
|
|
|
out IO(SREG), r31
|
2021-06-26 21:42:23 +00:00
|
|
|
pop r31
|
|
|
|
reti
|
|
|
|
|
|
|
|
|