+++ /dev/null
-#define c3(x) (0xff & (x>>24))
-#define c2(x) (0xff & (x>>16))
-#define c1(x) (0xff & (x>> 8))
-#define c0(x) (0xff & (x ))
-#define LSL(x) carry = x>>7; x <<= 1;
-#define LSR(x) carry = x&1; x >>= 1;
-#define SWAP(x) x = ((x & 0x0F) << 4 | (x & 0xF0) >> 4);
-#define AND(x,y) x &= y;
-#define ANDI(x,n) x &= n;
-#define OR(x,y) x |= y;
-#define ORI(x,n) x |= n;
-#define EOR(x,y) x ^= y;
-#define ADD(x,y) carry = (x+y)>>8; x += y;
-#define ADC(x,y,c)x += y; x+=c; //TODO: carry
-#define SUB(x,y) x -= y; //TODO: carry
-#define SUBI(x,n) x -= (u8)n; //TODO: carry
-#define INC(x) x++; //WARN: does not set carry
-#define DEC(x) x--; sr_zero=!x;
-#define MOV(x,y) x = y;
-#define LDI(x,n) x = n;
-#define SBRC(x,b) if (x & 1<<b) //skip if cleared => do if set
-#define SBRS(x,b) if (!(x & 1<<b)) //skip if set => do if not
-#define CPSE(x,y) if (x != y) //compare, skip if equal
-#define CLR(x) x = 0;
-#define RET return;
-#define RCALL //pseudo
-int sr_zero = 0; //status register zero bit
-#define TST(x) if(x==0)sr_zero=1;else sr_zero=0; //WARN: not a complete TST mockup
-#define BREQ(l) if(sr_zero) goto l;
-#define BRNE(l) if(!sr_zero) goto l;
-int carry = 0; //status register carry bit //WARN: not respected by all mocked instructions
-int asmtmp = 0;
-#define ROL(x) asmtmp = x>>7; x <<= 1; x |= carry; carry = asmtmp;
-#define ROR(x) asmtmp = x&0x1; x >>= 1; x |= carry<<7; carry = asmtmp;
-#define NEG(x) x *= -1;
-int sr_neg = 0;
-#define CPI(x,n) sr_neg = (x-n < 0);sr_zero = (x-n == 0); //WARN: not a complete CPI mockup
-#define BRPL(l) if (sr_neg) goto l;
-#define RJMP(l) goto l;
SPH = 0x3E
CCP = 0x3C
CLKPSR = 0x36
+WDTCSR = 0x31
SMCR = 0x3A
TCCR0A = 0x2E
TCCR0B = 0x2D
.byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
.section .text
+.org 0x0000 ; RESET interrupt
+ RJMP main
+.org 0x0008 ; TIM0_OVF interrupt
+ RJMP sample
mod3: ; mod3(Mh.Ml) -> t
#define tmp _
#undef a2
RET ; TODO: replace CALL/RET with IJMP?
-main:
+main: ; setup routine
CLR zero
CLR i0
CLR i1
CLR i2
CLR i3
- ;;TODO: setup stack pointer, portb, clock, sleep mode, timer0
+ CLR acc ; we output a dummy sample before the actual first one
+
+ #define one _
+ LDI one, 1
+ LDI x, 0x5f ; RAMEND
+ OUT SPL, x ; init stack ptr
+ OUT SPH, zero ; -"-
+ OUT PUEB, zero ; disable pullups
+ OUT DDRB, one ; PORTB[0] as output
+ LDI x, 0xd8
+ OUT CCP, x ; change protected ioregs
+ OUT CLKPSR, one ; clock prescaler 1/2 (4Mhz)
+ OUT WDTCSR, zero; turn off watchdog ;;TODO: incomplete - see datasheet pg48
+ ; OUT SMCR, 2 ; sleep mode 'power down' ('idle' (default) has faster response time)
+
+ ;set timer/counter0 to 8bit fastpwm, non-inverting, no prescaler
+ LDI x, 0x81
+ OUT TCCR0A, x
+ LDI x, 0x09
+ OUT TCCR0B, x
+ OUT TIMSK0, one ; enable tim0_ovf
+ OUT TIFR0, one ; TODO: why?
+ SEI
+ #undef one
RJMP sample
-sample: ;;TODO: this will probably become the timer0 overflow interrupt handler
+
+loop:
+ SLEEP ; wait for interrupt
+ RJMP loop
+
+sample:
+ ; potential TODO: softcounter in r28 to only update duty cicle every n iterations
+ ; potential TODO: save/restore status register (SREG=0x3f)
+ OUT OCR0AL, acc ; start by outputting a sample, because routine has variable runtime
+
MOV n, i2
LSL n
LSL n
#undef tmp
ADD acc, t
- SWAP acc
- OUT OCR0AL, acc
+ SWAP acc ; acc<<4, to be passed to OCR0AL
+
SUBI i0, -1
SBCI i1, -1
SBCI i2, -1
SBCI i3, -1
- rjmp sample ;;TODO: -> RETI
+ RETI ; reenables interrupts