12 #define x r26 //==Xlo==Mh
13 #define t r27 //==Xhi==Ml
21 #define Mh r26 //mod3 vars
40 .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
41 .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
45 mod3: ; mod3(Mh.Ml) -> t
74 ; definitions to mul-tree readable:
77 .macro always _bit ; nop; for when a test() is not necessary (see tree)
79 .macro never _bit ; nop; for when a test() is not necessary (see tree)
81 .macro test _bit,_jmpto
89 .macro shift8 ; top three bits don't need to be corrrect, so save cycles by not carrying
92 .macro shift0 ; nop; last shift is common
99 .macro add_shift8 ; ditto with carrying
103 .macro add_shift0 ; last shift is common
120 MOV tmp, t ; NOTE: must move value away from `t`, as that is also hi(X)
121 LDI Xhi, hi8(data) ; TODO: can skip if &data < 0xff (it is)
123 ADD Xlo, tmp ;<-- the offset (formerly `t`) into data[]
124 ADC Xhi, zero ; ditto skip
135 /* decision tree multiplication saves cycles and (hopefully) reduces code size
142 _?000 _?100 _?001 _?101
144 _0000 _1000 _0100 _1100 _1001 _0101 _1101
146 ... ... ... ... ... ... ...
148 B0 58 84 8C 69 75 9D */
165 RJMP end_mul ; calc'd 0xb0
176 RJMP end_mul ; calc'd 0x58
181 RJMP upper_8 ;'ll calc 0x84
184 upper_8: ; used twice, so deduplicated
193 RJMP end_mul ; calc'd 0x8c
210 RJMP end_mul ; calc'd 0x69
223 RJMP end_mul ; calc'd 0x75
237 LSR a1 ;final shift is a common operation for all
239 MOV t, a1 ;;TODO: use a1 in main() directly
243 RET ; TODO: replace CALL/RET with IJMP?
251 ;;TODO: setup stack pointer, portb, clock, sleep mode, timer0
253 sample: ;;TODO: this will probably become the timer0 overflow interrupt handler
405 rjmp sample ;;TODO: -> RETI