Skip to content

Instantly share code, notes, and snippets.

@xkamail
Last active February 24, 2023 12:54
Show Gist options
  • Save xkamail/9039041d3024fd883a0f2243dc0d6e13 to your computer and use it in GitHub Desktop.
Save xkamail/9039041d3024fd883a0f2243dc0d6e13 to your computer and use it in GitHub Desktop.
Multiply 16x16 (Signed) array 8bit and then sum all to 3 bytes
.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