transcribe fakeasm into realasm (III)
[Chiptunes.git] / foo.S
diff --git a/foo.S b/foo.S
index ac7d6ad37c07babff4d9618fc9edbd89a796d84f..8e76812696dd0fdacb66dc155e153dfc33d67006 100644 (file)
--- a/foo.S
+++ b/foo.S
-#include <stdio.h>
-#include "fakeasm.h"
-typedef unsigned char u8;
+/* REGISTER NAMES */
+#define zero r16
+#define acc  r17
+#define i0   r18
+#define i1   r19
+#define i2   r20
+#define i3   r21
+#define n    r22
+#define s    r23
+#define _    r24
+;            r25
+#define x    r26 //==Xlo==Mh
+#define t    r27 //==Xhi==Ml
+;            r28
+;            r29
+;            r30 Zlo
+;            r31 Zhi
+; aliases:
+#define Xlo  r26
+#define Xhi  r27
+#define Mh   r26 //mod3 vars
+#define Ml   r27 // -"-
 
-u8 zero;       //r16
-u8 acc;                //r17
-u8 i0;         //r18
-u8 i1;         //r19
-u8 i2;         //r20
-u8 i3;         //r21
-u8 n;          //r22
-u8 s;          //r23
-u8 _;          //r24
-               //r25
-u8 x;/*==Ml*/  //r26 (Xlo)
-u8 t;/*==Mh*/  //r27 (Xhi)
-               //r28
-               //r29
-void *Z;       //r30 (Zlo)
-/*...*/                //r31 (Zhi)
-#define Mh x //mod3 vars
-#define Ml t // -"-
+/* I/O REGISTERS */
+OCR0AL = 0x26
+DDRB   = 0x01
+PUEB   = 0x03
+SPL    = 0x3D
+SPH    = 0x3E
+CCP    = 0x3C
+CLKPSR = 0x36
+SMCR   = 0x3A
+TCCR0A = 0x2E
+TCCR0B = 0x2D
+TIMSK0 = 0x2B
+TIFR0  = 0x2A
 
-// .section .data
-u8 data[] = {
-       /*.byte*/ 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58,
-       /*.byte*/ 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
-};
+.section .data
+       .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
+       .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
 
-// .section .text
+.section .text
 
-//http://homepage.divms.uiowa.edu/~jones/bcd/mod.shtml
-void mod3(void) {
-       // mod3(Mh.Ml) -> t
+mod3: ; mod3(Mh.Ml) -> t
        #define tmp _
-       ADD     (Ml, Mh)
-       CLR     (Mh)
-       ADC     (Mh, zero, carry) //Mh only holds the carry bit
-       MOV     (tmp, Ml)
-       SWAP    (tmp)
-       ANDI    (tmp, 0x0f)
-       SWAP    (Mh)
-       OR      (tmp, Mh)
-       ANDI    (Ml, 0x0f)
-       ADD     (Ml, tmp)
-       MOV     (tmp, Ml)
-       LSR     (tmp)
-       LSR     (tmp)
-       ANDI    (Ml, 0x03)
-       ADD     (Ml, tmp)
-       MOV     (tmp, Ml)
-       LSR     (tmp)
-       LSR     (tmp)
-       ANDI    (Ml, 0x03)
-       ADD     (Ml, tmp)
-       CPI     (Ml, 3)
-       BRPL    (skip)
-       SUBI    (Ml, 3)
-       skip:;
+       ADD     Ml, Mh
+       CLR     Mh
+       ADC     Mh, zero
+       MOV     tmp, Ml
+       SWAP    tmp
+       ANDI    tmp, 0x0f
+       SWAP    Mh
+       OR      tmp, Mh
+       ANDI    Ml, 0x0f
+       ADD     Ml, tmp
+       MOV     tmp, Ml
+       LSR     tmp
+       LSR     tmp
+       ANDI    Ml, 0x03
+       ADD     Ml, tmp
+       MOV     tmp, Ml
+       LSR     tmp
+       LSR     tmp
+       ANDI    Ml, 0x03
+       ADD     Ml, tmp
+       CPI     Ml, 3
+       BRPL    skip
+       SUBI    Ml, 3
+       skip:
        RET
        #undef tmp
-}
-//.macro definitions for mul-tree:
-#define always(_bit) //nop; for when a test() is not necessary (see tree)
-#define never(_bit)  //nop; for when a test() is not necessary (see tree)
-#define test(_bit,_jmpto) \
-       SBRC    (t, _bit) \
-       RJMP    (_jmpto)
-#define shift16 \
-       LSR     (a2) \
-       ROR     (a1)
-#define shift8 /*top three bits don't need to be corrrect, so save cycles by not carrying*/ \
-       LSR     (a1)
-#define shift0 //nop; last shift is common
-#define add_shift16 \
-       ADD     (a1, i0) \
-       ADC     (a2, i1, carry) \
+
+; definitions to mul-tree readable:
+.macro always _bit ; nop; for when a test() is not necessary (see tree)
+.endm
+.macro never _bit  ; nop; for when a test() is not necessary (see tree)
+.endm
+.macro test _bit,_jmpto
+       SBRC    t, _bit
+       RJMP    _jmpto
+.endm
+.macro shift16
+       LSR     a2
+       ROR     a1
+.endm
+.macro shift8 ; top three bits don't need to be corrrect, so save cycles by not carrying
+       LSR     a1
+.endm
+.macro shift0 ; nop; last shift is common
+.endm
+.macro add_shift16
+       ADD     a1, i0
+       ADC     a2, i1
        shift16
-#define add_shift8 /*ditto with carrying*/ \
-       ADD     (a1, i0) \
+.endm
+.macro add_shift8 ; ditto with carrying
+       ADD     a1, i0
        shift8
-#define add_shift0 /*last shift is common*/ \
-       ADD     (a1, i0)
-void g(void) {
-       // g(i, t) -> t
-       // tempvars: `x` and `_`
+.endm
+.macro add_shift0 ; last shift is common
+       ADD     a1, i0
+.endm
+
+g: ; g(i, t) -> t
        #define tmp _
-       ANDI    (t, 0x07)
-       MOV     (tmp, i2)
-       ANDI    (tmp, 3)
-       TST     (tmp)
-       CPSE    (tmp, zero)
-       SUBI    (t, -8)
+       ANDI    t, 0x07
+       MOV     tmp, i2
+       ANDI    tmp, 3
+       TST     tmp
+       CPSE    tmp, zero
+       SUBI    t, -8
        #undef tmp
 
        #define tmp _
-       MOV     (tmp, t) //NOTE: must move value away from `t`, as that is also hi(X)
-       tmp = data[tmp];/*
-       LDI     Xhi, hi8(data)
+       MOV     tmp, t  ; NOTE: must move value away from `t`, as that is also hi(X)
+       LDI     Xhi, hi8(data)  ; TODO: can skip if &data < 0xff (it is)
        LDI     Xlo, lo8(data)
        ADD     Xlo, tmp  ;<-- the offset (formerly `t`) into data[]
-       ADC     Xhi, zero
-       LD      tmp, X */
-       MOV     (t, tmp)
+       ADC     Xhi, zero  ; ditto skip
+       LD      tmp, X
+       MOV     t, tmp
        #undef tmp
 
        #define a1 x
        #define a2 _
        #define a0 t
-       CLR     (a2)
-       CLR     (a1)
+       CLR     a2
+       CLR     a1
 
        /* decision tree multiplication saves cycles and (hopefully) reduces code size
                             _xxx?
@@ -124,258 +141,260 @@ void g(void) {
          ...   ...     ...   ...     ...   ...   ...
           |     |       |     |       |     |     |
           B0    58     84    8C      69     75    9D   */
-               test    (0, m____1)
+               test    0, m____1
        m____0: shift16
-               never   (1)
+               never   1
        m___00: shift16
-               test    (2, m__100)
+               test    2, m__100
        m__000: shift16
-               test    (3, m_1000)
+               test    3, m_1000
        m_0000: shift16
-               always  (4)
+               always  4
                add_shift16
-               always  (5)
+               always  5
                add_shift8
-               never   (6)
+               never   6
                shift8
-               always  (7)
+               always  7
                add_shift0
-               RJMP    (end_mul) // calc'd 0xb0
+               RJMP    end_mul ; calc'd 0xb0
 
        m_1000: add_shift16
-               always  (4)
+               always  4
                add_shift16
-               never   (5)
+               never   5
                shift8
-               always  (6)
+               always  6
                add_shift8
-               never   (7)
+               never   7
                shift0
-               RJMP    (end_mul) // calc'd 0x58
+               RJMP    end_mul ; calc'd 0x58
 
        m__100: add_shift16
-               test    (3, m_1100)
+               test    3, m_1100
        m_0100: shift16
-               RJMP    (upper_8) //'ll calc 0x84
+               RJMP    upper_8 ;'ll calc 0x84
 
        m_1100: add_shift16
-       upper_8: /* used twice, so deduplicated */
-               never   (4)
+       upper_8: ; used twice, so deduplicated
+               never   4
                shift16
-               never   (5)
+               never   5
                shift8
-               never   (6)
+               never   6
                shift8
-               always  (7)
+               always  7
                add_shift0
-               RJMP    (end_mul) // calc'd 0x8c
+               RJMP    end_mul ; calc'd 0x8c
 
        m____1: add_shift16
-               never   (1)
+               never   1
        m___01: shift16
-               test    (2, m__101)
+               test    2, m__101
        m__001: shift16
-               always  (3)
+               always  3
        m_1001: add_shift16
-               never   (4)
+               never   4
                shift16
-               always  (5)
+               always  5
                add_shift8
-               always  (6)
+               always  6
                add_shift8
-               never   (7)
+               never   7
                shift0
-               RJMP    (end_mul) // calc'd 0x69
+               RJMP    end_mul ; calc'd 0x69
 
        m__101: add_shift16
-               test    (3, m_1101)
+               test    3, m_1101
        m_0101: shift16
-               always  (4)
+               always  4
                add_shift16
-               always  (5)
+               always  5
                add_shift8
-               always  (6)
+               always  6
                add_shift8
-               never   (7)
+               never   7
                shift0
-               RJMP    (end_mul) // calc'd 0x75
+               RJMP    end_mul ; calc'd 0x75
 
        m_1101: add_shift16
-               always  (4)
+               always  4
                add_shift16
-               never   (5)
+               never   5
                shift8
-               never   (6)
+               never   6
                shift8
-               always  (7)
+               always  7
                add_shift0
-               // calc'd 0x9d
+               ; calc'd 0x9d
 
        end_mul:
-               LSR (a1) //final shift is a common operation for all
+               LSR a1 ;final shift is a common operation for all
 
-       MOV     (t, a1) //TODO: use a1 in main() directly
+       MOV     t, a1 ;;TODO: use a1 in main() directly
        #undef a0
        #undef a1
        #undef a2
-       RET //TODO: replace CALL/RET with IJMP? (requires undoing goto-mul-hack)
-};
+       RET ; TODO: replace CALL/RET with IJMP?
 
-int main(void) {
-       CLR     (zero)
-       CLR     (i0)
-       CLR     (i1)
-       CLR     (i2)
-       CLR     (i3)
-       for (;;) {
-               MOV     (n, i2)
-               LSL     (n)
-               LSL     (n)
-               #define tmp _
-               MOV     (tmp, i1)
-               SWAP    (tmp)
-               ANDI    (tmp, 0x0f)
-               LSR     (tmp)
-               LSR     (tmp)
-               OR      (n, tmp)
-               #undef tmp
-               MOV     (s, i3)
-               LSR     (s)
-               ROR     (s)
-               ANDI    (s, 0x80)
-               #define tmp _
-               MOV     (tmp, i2)
-               LSR     (tmp)
-               OR      (s, tmp)
-               #undef tmp
+main:
+       CLR     zero
+       CLR     i0
+       CLR     i1
+       CLR     i2
+       CLR     i3
+       ;;TODO: setup stack pointer, portb, clock, sleep mode, timer0
+       RJMP    sample
+sample: ;;TODO: this will probably become the timer0 overflow interrupt handler
+       MOV     n, i2
+       LSL     n
+       LSL     n
+       #define tmp _
+       MOV     tmp, i1
+       SWAP    tmp
+       ANDI    tmp, 0x0f
+       LSR     tmp
+       LSR     tmp
+       OR      n, tmp
+       #undef tmp
+       MOV     s, i3
+       LSR     s
+       ROR     s
+       ANDI    s, 0x80
+       #define tmp _
+       MOV     tmp, i2
+       LSR     tmp
+       OR      s, tmp
+       #undef tmp
 
-               //voice 1:
-               MOV     (t, n)
-               RCALL   g();
-               SWAP    (t)
-               ANDI    (t, 1)
-               MOV     (acc, t)
+       voice 1:
+       MOV     t, n
+       RCALL   g
+       SWAP    t
+       ANDI    t, 1
+       MOV     acc, t
 
-               //voice 2:
-               #define tmp _
-               MOV     (tmp, i2)
-               LSL     (tmp)
-               LSL     (tmp)
-               LSL     (tmp)
-               MOV     (t, i1)
-               SWAP    (t)
-               ANDI    (t, 0xf)
-               LSR     (t)
-               OR      (t, tmp)
-               #undef tmp
-               EOR     (t, n)
-               RCALL   g();
-               LSR     (t)
-               LSR     (t)
-               ANDI    (t, 3)
-               AND     (t, s)
-               ADD     (acc, t)
+       voice 2:
+       #define tmp _
+       MOV     tmp, i2
+       LSL     tmp
+       LSL     tmp
+       LSL     tmp
+       MOV     t, i1
+       SWAP    t
+       ANDI    t, 0xf
+       LSR     t
+       OR      t, tmp
+       #undef tmp
+       EOR     t, n
+       RCALL   g
+       LSR     t
+       LSR     t
+       ANDI    t, 3
+       AND     t, s
+       ADD     acc, t
 
-               //voice 3:
-               MOV     (Ml, i2)
-               SWAP    (Ml)
-               ANDI    (Ml, 0xf0)
-               LSL     (Ml)
-               #define tmp _
-               MOV     (tmp, i1)
-               LSR     (tmp)
-               LSR     (tmp)
-               LSR     (tmp)
-               OR      (Ml, tmp)
-               #undef tmp
-               MOV     (Mh, i3)
-               SWAP    (Mh)
-               ANDI    (Mh, 0xf0)
-               LSL     (Mh)
-               #define tmp _
-               MOV     (tmp, i2)
-               LSR     (tmp)
-               LSR     (tmp)
-               LSR     (tmp)
-               OR      (Mh, tmp)
-               #undef tmp
-               RCALL   mod3();
-               ADD     (t, n)
-               RCALL   g();
-               LSR     (t)
-               LSR     (t)
-               ANDI    (t, 3)
-               MOV     (x, s)
-               INC     (x)
-               #define tmp _
-               MOV     (tmp, x)
-               LSR     (tmp)
-               LSR     (tmp)
-               ADD     (tmp, x)
-               ROR     (tmp)
-               LSR     (tmp)
-               ADD     (tmp, x)
-               ROR     (tmp)
-               LSR     (tmp)
-               ADD     (tmp, x)
-               ROR     (tmp)
-               LSR     (tmp)
-               AND     (t, tmp)
-               #undef tmp
-               ADD     (acc, t)
+       ; voice 3:
+       MOV     Ml, i2
+       SWAP    Ml
+       ANDI    Ml, 0xf0
+       LSL     Ml
+       #define tmp _
+       MOV     tmp, i1
+       LSR     tmp
+       LSR     tmp
+       LSR     tmp
+       OR      Ml, tmp
+       #undef tmp
+       MOV     Mh, i3
+       SWAP    Mh
+       ANDI    Mh, 0xf0
+       LSL     Mh
+       #define tmp _
+       MOV     tmp, i2
+       LSR     tmp
+       LSR     tmp
+       LSR     tmp
+       OR      Mh, tmp
+       #undef tmp
+       RCALL   mod3
+       ADD     t, n
+       RCALL   g
+       LSR     t
+       LSR     t
+       ANDI    t, 3
+       MOV     x, s
+       INC     x
+       #define tmp _
+       MOV     tmp, x
+       LSR     tmp
+       LSR     tmp
+       ADD     tmp, x
+       ROR     tmp
+       LSR     tmp
+       ADD     tmp, x
+       ROR     tmp
+       LSR     tmp
+       ADD     tmp, x
+       ROR     tmp
+       LSR     tmp
+       AND     t, tmp
+       #undef tmp
+       ADD     acc, t
+
+       ; voice 4:
+       MOV     Ml, i2
+       SWAP    Ml
+       ANDI    Ml, 0xf0
+       LSL     Ml
+       LSL     Ml
+       #define tmp _
+       MOV     tmp, i1
+       LSR     tmp
+       LSR     tmp
+       OR      Ml, tmp
+       #undef tmp
+       MOV     Mh, i3
+       SWAP    Mh
+       ANDI    Mh, 0xf0
+       LSL     Mh
+       LSL     Mh
+       #define tmp _
+       MOV     tmp, i2
+       LSR     tmp
+       LSR     tmp
+       OR      Mh, tmp
+       #undef tmp
+       RCALL   mod3
+       SUB     t, n
+       NEG     t
+       SUBI    t, -8
+       RCALL   g
+       LSR     t
+       ANDI    t, 3
+       INC     s
+       #define tmp _
+       MOV     tmp, s
+       LSR     tmp
+       ADD     tmp, s
+       ROR     tmp
+       LSR     tmp
+       LSR     tmp
+       ADD     tmp, s
+       ROR     tmp
+       ADD     tmp, s
+       ROR     tmp
+       LSR     tmp
+       LSR     tmp
+       AND     t, tmp
+       #undef tmp
+       ADD     acc, t
 
-               //voice 4:
-               MOV     (Ml, i2)
-               SWAP    (Ml)
-               ANDI    (Ml, 0xf0)
-               LSL     (Ml)
-               LSL     (Ml)
-               #define tmp _
-               MOV     (tmp, i1)
-               LSR     (tmp)
-               LSR     (tmp)
-               OR      (Ml, tmp)
-               #undef tmp
-               MOV     (Mh, i3)
-               SWAP    (Mh)
-               ANDI    (Mh, 0xf0)
-               LSL     (Mh)
-               LSL     (Mh)
-               #define tmp _
-               MOV     (tmp, i2)
-               LSR     (tmp)
-               LSR     (tmp)
-               OR      (Mh, tmp)
-               #undef tmp
-               RCALL   mod3();
-               SUB     (t, n)
-               NEG     (t)
-               SUBI    (t, -8)
-               RCALL   g();
-               LSR     (t)
-               ANDI    (t, 3)
-               INC     (s)
-               #define tmp _
-                MOV    (tmp, s)
-               LSR     (tmp)
-                ADD    (tmp, s)
-               ROR     (tmp)
-               LSR     (tmp)
-               LSR     (tmp)
-                ADD    (tmp, s)
-               ROR     (tmp)
-                ADD    (tmp, s)
-               ROR     (tmp)
-               LSR     (tmp)
-               LSR     (tmp)
-               AND     (t, tmp)
-               #undef tmp
-               ADD     (acc, t)
+       SWAP    acc
+       OUT     OCR0AL, acc
+       SUBI    i0, -1
+       SBCI    i1, -1
+       SBCI    i2, -1
+       SBCI    i3, -1
 
-               putchar(acc<<4); //TODO
-               SUBI    (i0, -1)
-               ADC     (i1, zero, !i0) //XXX: must use "sbci i1,-1" in the assembly version
-               ADC     (i2, zero, !i0&&!i1) //          sbci i2,-1
-               ADC     (i3, zero, !i0&&!i1&&!i2) //     sbci i3,-1
-       }
-}
+       rjmp sample ;;TODO: -> RETI
Imprint / Impressum