giomba
6137f21b48
if transition_mode pin is high, then images are shown continuosly (eg the next image is shown as soon as the next_image button is pressed) but if transition_mode pin is low, then, when you press the button, the current image disappears, and the next one appears when you press the button again
236 lines
4.2 KiB
ArmAsm
236 lines
4.2 KiB
ArmAsm
#include <avr/io.h>
|
|
#include "macro.h"
|
|
#include "const.h"
|
|
|
|
|
|
.data
|
|
image:
|
|
.byte 0xff
|
|
|
|
show_image:
|
|
.byte 0x00
|
|
|
|
button_next_image:
|
|
.byte 0x0
|
|
|
|
current_jump_table:
|
|
.word 0x0
|
|
|
|
.text
|
|
|
|
.global main
|
|
main:
|
|
ldi r16, 0x30 ; port B, pin 4 and 5 as output, others as input
|
|
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
|
|
|
|
ldi r16, 0x02 ; don't connect output pins to timer, CTC[1:0] mode
|
|
sts TCCR0A, r16
|
|
ldi r16, 0x01 ; CTC[2] mode, no prescaler
|
|
sts TCCR0B, r16
|
|
|
|
; init variables
|
|
ldi r16, 0
|
|
sts frame, r16
|
|
sts frame + 1, r16
|
|
sts line, r16
|
|
ldi r16, 0xfe
|
|
sts line + 1, r16
|
|
ldi r16, 0xff
|
|
sts image, r16
|
|
ldi r16, 0
|
|
sts show_image, r16
|
|
|
|
; r0 always holds 0
|
|
clr r0
|
|
|
|
call setup_c
|
|
|
|
sei ; global interrupt enable
|
|
|
|
1:
|
|
rjmp 1b
|
|
|
|
.global int_horizontal_sync
|
|
int_horizontal_sync: ; +3
|
|
push r31 ; +5
|
|
in r31, IO(SREG) ; +6, status register
|
|
push r31 ; +8
|
|
push r30 ; +10
|
|
|
|
; if (line >= VERTICAL_OFFSET), then enter
|
|
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
|
|
breq enter ; +23
|
|
jmp int_horizontal_sync_end
|
|
|
|
enter:
|
|
; here, +23 or +24 cycles have passed since horizontal sync
|
|
; so, there are still ~168 cycles before first useful data
|
|
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
|
|
|
|
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
|
|
push r30
|
|
push r29
|
|
|
|
; turn off interrupt
|
|
lds r31, TIMSK0
|
|
andi r31, 0xfd ; mask disable interrupt timer A
|
|
sts TIMSK0, r31
|
|
|
|
lds r31, show_image
|
|
cpi r31, 0x1
|
|
brne jump_table_return_address
|
|
|
|
lds zl, current_jump_table
|
|
lds zh, current_jump_table + 1
|
|
|
|
; ldi zl, pm_lo8(line_jump_table_0)
|
|
; ldi zh, pm_hi8(line_jump_table_0)
|
|
|
|
clr r0
|
|
lds r29, line
|
|
add zl, r29
|
|
adc zh, r0
|
|
add zl, r29
|
|
adc zh, r0
|
|
|
|
ijmp
|
|
|
|
.global jump_table_return_address
|
|
jump_table_return_address:
|
|
pop r29
|
|
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 zl
|
|
push zh
|
|
push yl
|
|
push yh
|
|
|
|
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
|
|
|
|
; 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
|
|
; TODO an huge shitty spaghetti code
|
|
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
|
|
|
|
|