diff --git a/main.S b/main.S index 573cb69..e2f268c 100644 --- a/main.S +++ b/main.S @@ -7,6 +7,29 @@ #define SP r1 #define SR r2 +;; --- register usage -------------------------------- +;; r4: synchronization between main loop and isr +;; bit0 signals byte done from isr +;; r5: data byte to be handled by isr +;; r6: bit-counter, only used within isr +;; r7: screen data start/next pointer +;; r8: screen data end pointer +;; r9: next screen data byte, prepared in mainloop + +#define SIGNAL_INIT_VALUE 0x00 +#define SIGNAL_BYTE_DONE 0x01 +#define SIGNAL_ISR_ENABLE 0x02 +#define SIGNAL_REGISTER r4 + +#define DATA_BYTE_REGISTER r5 +#define NEXT_DATA_BYTE_REGISTER r9 +#define DATA_NEXT_ADDRESS_REGISTER r7 +#define DATA_LAST_ADDRESS_REGISTER r8 + +#define BIT_COUNTER_REGISTER r6 +#define BIT_COUNTER_INIT_VALUE 0x01 +;; --------------------------------------------------- + .section ".rodata","a" screendata: @@ -43,60 +66,52 @@ green: .section ".text","ax",@progbits _start: ;; disable watchdog - mov.w #WDTPW|WDTHOLD,&WDTCTL + mov.w #WDTPW|WDTHOLD, &WDTCTL ;; configure clock system to the highest frequency - mov.b #DCO0|DCO1|DCO2,&DCOCTL - mov.b #XT2OFF|RSEL0|RSEL1|RSEL2|RSEL3,&BCSCTL1 - mov.b #0,&BCSCTL2 - mov.b #0,&BCSCTL3 + mov.b #DCO0|DCO1|DCO2, &DCOCTL + mov.b #XT2OFF|RSEL0|RSEL1|RSEL2|RSEL3, &BCSCTL1 + mov.b #0, &BCSCTL2 + mov.b #0, &BCSCTL3 ;; initialize stack pointer with value from linker mov.w #__stack, SP init: ;; configuration of GPIO Ports - mov.b #BIT0|BIT1|BIT2,&P1DIR - mov.b #BIT1|BIT4,&P2DIR - mov.b #BIT1|BIT4,&P2SEL + mov.b #BIT0|BIT1|BIT2, &P1DIR + mov.b #BIT1|BIT4, &P2DIR + mov.b #BIT1|BIT4, &P2SEL ;; timer configuration ;; configure and stop timer ;; cycle time is 56.25ns - mov.w #ID_0|MC_0|TACLR|TASSEL_2,&TA1CTL + mov.w #ID_0|MC_0|TACLR|TASSEL_2, &TA1CTL ;; 2.0us - mov.w #45,&TA1CCR0 + mov.w #45, &TA1CCR0 ;; a bit less - mov.w #10,&TA1CCR1 - mov.w #22,&TA1CCR2 + mov.w #10, &TA1CCR1 + mov.w #22, &TA1CCR2 ;; configure output mode for TA0.1 - mov.w #CCIE,&TA1CCTL0 - mov.w #OUTMOD_7,&TA1CCTL1 - mov.w #OUTMOD_7,&TA1CCTL2 - - ;; r4: synchronization between main loop and isr - ;; bit0 signals byte done from isr - ;; r5: data byte to be handled by isr - ;; r6: bit-counter, only used within isr - ;; r7: screen data start/next pointer - ;; r8: screen data end pointer - ;; r9: next screen data byte, prepared in mainloop + mov.w #CCIE, &TA1CCTL0 + mov.w #OUTMOD_7, &TA1CCTL1 + mov.w #OUTMOD_7, &TA1CCTL2 ;; initialize bit-counter for isr - mov.b #0x01,r6 + mov.b #BIT_COUNTER_INIT_VALUE, BIT_COUNTER_REGISTER ;; initialize isr-sync register - mov.b #0x00,r4 + mov.b #SIGNAL_INIT_VALUE, SIGNAL_REGISTER - ;; screen data start/next into r7 - mov.w #screendata, r7 - ;; screen data end into r8 - mov.w #screendataend, r8 - ;; load first screen data value into r5 - mov.b @r7,r5 - inc.w r7 + ;; screen data start/next into DATA_NEXT_ADDRESS_REGISTER + mov.w #screendata, DATA_NEXT_ADDRESS_REGISTER + ;; screen data end into DATA_LAST_ADDRESS_REGISTER + mov.w #screendataend, DATA_LAST_ADDRESS_REGISTER + ;; load first screen data value into DATA_BYTE_REGISTER + mov.b @DATA_NEXT_ADDRESS_REGISTER, DATA_BYTE_REGISTER + inc.w DATA_NEXT_ADDRESS_REGISTER ;; start timer in up mode - bis.w #MC0,&TA1CTL + bis.w #MC0, &TA1CTL ;; enable interrupts eint @@ -104,29 +119,29 @@ init: mainloop: ;; prepare next byte to handle by isr ;; first, check whether we are already at the end of screen data - cmp.w r7,r8 + cmp.w DATA_NEXT_ADDRESS_REGISTER, DATA_LAST_ADDRESS_REGISTER jnz mainloop_prepare_next_byte ;; in that case rollover to the start again - mov.w #screendata,r7 + mov.w #screendata, DATA_NEXT_ADDRESS_REGISTER mainloop_prepare_next_byte: ;; load the byte from the screen data next pointer - mov.b @r7,r9 + mov.b @DATA_NEXT_ADDRESS_REGISTER, NEXT_DATA_BYTE_REGISTER ;; and increase the pointer - inc.w r7 + inc.w DATA_NEXT_ADDRESS_REGISTER mainloop_wait_for_isr: ;; check bit0 in sync register, wait for the signal from ;; the isr - bit #0x01,r4 + bit #SIGNAL_BYTE_DONE, SIGNAL_REGISTER jz mainloop_wait_for_isr ;; load data - mov.b r9,r5 + mov.b NEXT_DATA_BYTE_REGISTER, DATA_BYTE_REGISTER ;; clear the signal - mov.b #0x00,r4 + bic #SIGNAL_BYTE_DONE, SIGNAL_REGISTER ;; mark the cycle - bis #BIT2,&P1OUT - bic #BIT2,&P1OUT + bis #BIT2, &P1OUT + bic #BIT2, &P1OUT ;; continue jmp mainloop @@ -136,45 +151,36 @@ mainloop_wait_for_isr: ;; r6: exclusively used by isr as bit-counter timer1_a0_isr: ;; func begin marker - bis #BIT0,&P1OUT + bis #BIT0, &P1OUT ;; check isr idle bit - bit #BIT1,r4 + bit #SIGNAL_ISR_ENABLE, SIGNAL_REGISTER jnz timer1_a0_isr_exit ;; shift msb of data register r5 into carry flag and set or reset P1.1 accordingly - rla.b r5 + rla.b DATA_BYTE_REGISTER jnc timer1_a0_isr_false_bit - bis #BIT1,&P1OUT + bis #BIT1, &P1OUT jmp timer1_a0_isr_end timer1_a0_isr_false_bit: - bic #BIT1,&P1OUT + bic #BIT1, &P1OUT ;; shift bit-counter, after eight shifts signal byte done and reset bit-counter timer1_a0_isr_end: - rla.b r6 + rla.b BIT_COUNTER_REGISTER jnc timer1_a0_isr_exit ;; reset bit-counter - mov.b #0x01,r6 + mov.b #BIT_COUNTER_INIT_VALUE, BIT_COUNTER_REGISTER ;; signal byte done - mov.b #0x01,r4 + bis #SIGNAL_BYTE_DONE, SIGNAL_REGISTER timer1_a0_isr_exit: ;; func end marker - bic #BIT0,&P1OUT + bic #BIT0, &P1OUT reti -;timer0_a1_isr: -; reti - -; --- interrupt vectors --- -; .section "__interrupt_vector_9","ax",@progbits -; .word timer0_a1_isr - .section "__interrupt_vector_14","ax",@progbits - .word timer1_a0_isr - ;; .resetvec comes from linker .section ".resetvec","ax",@progbits .word _start