Last active
February 24, 2023 12:54
-
-
Save xkamail/9039041d3024fd883a0f2243dc0d6e13 to your computer and use it in GitHub Desktop.
Multiply 16x16 (Signed) array 8bit and then sum all to 3 bytes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.macro lock | |
push RA | |
push RB | |
push RC | |
push RD | |
push RE | |
push RF | |
push RI | |
push RT | |
.endmacro | |
.macro unlock | |
pop RT | |
pop RI | |
pop RF | |
pop RE | |
pop RD | |
pop RC | |
pop RB | |
pop RA | |
.endmacro | |
.def RA = R16 | |
.def RB = R17 | |
.def RC = R18 | |
.def RD = R19 | |
.def RE = R20 | |
.def RF = R21 | |
.def RI = R22 | |
.def RT = R23 | |
.equ A_ADDR = 0x100 // 16 items | |
.equ B_ADDR = 0x120 // 16 items | |
.equ MUL_ADDR = 0x140 // 32 items | |
.equ SUM_ADDR = 0x200 // result 3 Bytes | |
start: | |
ldi RA, HIGH(RAMEND) | |
ldi RB, HIGH(RAMEND) | |
call LOAD_A | |
call LOAD_B | |
call MUL_AB | |
call SUM_ALL | |
h: rjmp h | |
; load a from flash and then store into ram | |
LOAD_A: | |
lock | |
ldi ZH, HIGH(DATA_A<<1) | |
ldi ZL, LOW(DATA_A<<1) | |
ldi XH, HIGH(A_ADDR) | |
ldi XL, LOW(A_ADDR) | |
ldi RI, 16 | |
LA: | |
lpm RC, Z+ | |
st X+,RC | |
dec RI | |
brne LA | |
unlock | |
ret | |
LOAD_B: | |
lock | |
ldi ZH, HIGH(DATA_B<<1) | |
ldi ZL, LOW(DATA_B<<1) | |
ldi XH, HIGH(B_ADDR) | |
ldi XL, LOW(B_ADDR) | |
ldi RI, 16 | |
LB: | |
lpm RC, Z+ | |
st X+,RC | |
dec RI | |
brne LB | |
unlock | |
ret | |
MUL_AB: | |
lock | |
ldi RI, 16 | |
ldi XH, HIGH(A_ADDR) | |
ldi XL, LOW(A_ADDR) | |
ldi YH, HIGH(B_ADDR) | |
ldi YL, LOW(B_ADDR) | |
ldi ZH, HIGH(MUL_ADDR) | |
ldi ZL, LOW(MUL_ADDR) | |
LMUL: | |
ld RA, X+ | |
ld RB, Y+ | |
MULS RA,RB // --> [R1:R0] | |
// @ R1 วาง R1 ก่อน | |
// @+1 R0 วาง R0 ตาม | |
st Z+, R1 | |
st Z+, R0 | |
dec RI | |
brne LMUL | |
unlock | |
ret | |
; sum and store into @SUM_ADDR | |
SUM_ALL: | |
lock | |
clr RC | |
clr RB | |
clr RA | |
; [RC:RB:RA] <-- | |
; [RF:RE:RD] @MUL_ADDR | |
ldi RI, 16 | |
ldi XH, HIGH(MUL_ADDR) | |
ldi XL, LOW(MUL_ADDR) | |
; load to RE(high byte), RD(low byte) | |
; guess RF | |
; then RA+RD, RB+RE+c, RC+RF+c | |
SUML: | |
ld RE, X+ | |
ld RD, X+ | |
clr RF // init to 0x00 | |
; guess RF value from RE | |
lsl RE | |
brcc positive | |
negative: ldi RF, 0xFF | |
positive: nop | |
; [RF:RE:RD] done | |
add RA, RD | |
adc RB, RE | |
adc RC, RF | |
dec RI | |
brne SUML | |
// store result [RC:RB:RA] | |
ldi YH, HIGH(SUM_ADDR) | |
ldi YL, LOW(SUM_ADDR) | |
st Y, RC | |
std Y+1, RB | |
std Y+2, RA | |
unlock | |
ret | |
// mockup data | |
.org $777 | |
;DATA_A: .DB -1,-2,-3,-4,-5,-6,-7,10,12,0xF,-11,12,13,14,0xFF | |
;DATA_B: .DB 1,2,3,-4,-5,-6,-7,10,12,0xF,-11,12,0,0,1 | |
// easy to sum | |
DATA_A: .DB 0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F | |
DATA_B: .DB 0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment