initialisation code, interrupt vector table
authorTobias Girstmair <t@thi3nkpad.lan>
Tue, 11 Dec 2018 02:25:03 +0000 (03:25 +0100)
committerTobias Girstmair <t@thi3nkpad.lan>
Tue, 11 Dec 2018 02:34:14 +0000 (03:34 +0100)
it werks! (it's completely out of tune and too fast, but audio is coming
out of the chip. program at 5v, then play at 3v3. chip can't handle the
stereo amp, but headphones work)

fakeasm.h [deleted file]
foo.S

diff --git a/fakeasm.h b/fakeasm.h
deleted file mode 100644 (file)
index f06d5b4..0000000
--- a/fakeasm.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#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;
diff --git a/foo.S b/foo.S
index fafbed3..ff84530 100644 (file)
--- a/foo.S
+++ b/foo.S
@@ -29,6 +29,7 @@ SPL    = 0x3D
 SPH    = 0x3E
 CCP    = 0x3C
 CLKPSR = 0x36
+WDTCSR = 0x31
 SMCR   = 0x3A
 TCCR0A = 0x2E
 TCCR0B = 0x2D
@@ -41,6 +42,10 @@ data:
        .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 _
@@ -242,15 +247,47 @@ g: ; g(i, t) -> t
        #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
@@ -395,11 +432,11 @@ sample: ;;TODO: this will probably become the timer0 overflow interrupt handler
        #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
Imprint / Impressum