12 #define x r26 //==Xlo==Mh
13 #define t r27 //==Xhi==Ml
21 #define Mh r26 //mod3 vars
39 .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
40 .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
44 mod3: ; mod3(Mh.Ml) -> t
48 ADC (Mh, zero, carry) //Mh only holds the carry bit
73 ; definitions to mul-tree readable:
74 .macro always _bit ; nop; for when a test() is not necessary (see tree)
76 .macro never _bit ; nop; for when a test() is not necessary (see tree)
78 .macro test _bit,_jmpto
86 .macro shift8 ; top three bits don't need to be corrrect, so save cycles by not carrying
89 .macro shift0 ; nop; last shift is common
96 .macro add_shift8 ; ditto with carrying
100 .macro add_shift0 ; last shift is common
115 MOV (tmp, t) //NOTE: must move value away from `t`, as that is also hi(X)
119 ADD Xlo, tmp ;<-- the offset (formerly `t`) into data[]
131 /* decision tree multiplication saves cycles and (hopefully) reduces code size
138 _?000 _?100 _?001 _?101
140 _0000 _1000 _0100 _1100 _1001 _0101 _1101
142 ... ... ... ... ... ... ...
144 B0 58 84 8C 69 75 9D */
161 RJMP (end_mul) // calc'd 0xb0
172 RJMP (end_mul) // calc'd 0x58
177 RJMP (upper_8) //'ll calc 0x84
180 upper_8: /* used twice, so deduplicated */
189 RJMP (end_mul) // calc'd 0x8c
206 RJMP (end_mul) // calc'd 0x69
219 RJMP (end_mul) // calc'd 0x75
233 LSR (a1) //final shift is a common operation for all
235 MOV (t, a1) //TODO: use a1 in main() directly
239 RET //TODO: replace CALL/RET with IJMP? (requires undoing goto-mul-hack)
247 //TODO: setup stack pointer, portb, clock, sleep mode, timer0
249 sample: //TODO: this will probably become the timer0 overflow interrupt handler
394 putchar(acc<<4); //TODO
396 ADC (i1, zero, !i0) //XXX: must use "sbci i1,-1" in the assembly version
397 ADC (i2, zero, !i0&&!i1) // sbci i2,-1
398 ADC (i3, zero, !i0&&!i1&&!i2) // sbci i3,-1