====== Тесей: библиотека арифметических функций ======
Данная библиотека арифметических функций составлена Сергеем Вакуленко
по материалам сайта Ангстрем [[http://www.angstrem.ru/product/risc.htm]].
===== Вызов функций библиотеки =====
Беззнаковое умножение 8x8
movl %a0,0Fh ; Исходные...
movl %a1,0Fh ; ...данные
jsr mul8u ; Вызов рабочей подпрограммы
Знаковое умножение 8x8
movl %a0,0Fh ; Исходные...
movl %a1,0Fh ; ...данные
jsr mul8s ; Вызов рабочей подпрограммы
Беззнаковое умножение 16x16
movl %a0,0Fh ; Исходные...
movl %a1,0Fh ; ...данные
movl %a2,0Fh ; Исходные...
movl %a3,0Fh ; ...данные
jsr mul16u ; Вызов рабочей подпрограммы
Знаковое умножение 16x16
movl %a0,0Fh ; Исходные...
movl %a1,0Fh ; ...данные
movl %a2,0Fh ; Исходные...
movl %a3,0Fh ; ...данные
jsr mul16s ; Вызов рабочей подпрограммы
Беззнаковое деление 8x8
movl %a0,0Fh ; Исходные...
movl %a1,02h ; ...данные
jsr div8u ; Вызов рабочей подпрограммы
Знаковое деление 8x8
movl %a0,0Fh ; Исходные...
movl %a1,02h ; ...данные
jsr div8s ; Вызов рабочей подпрограммы
Беззнаковое деление 16x16
movl %a0,0Fh ; Исходные...
movl %a1,03h ; ...данные
movl %a2,03h ; Исходные...
movl %a3,00h ; ...данные
jsr div16u ; Вызов рабочей подпрограммы
===== Беззнаковое умножение 8x8 =====
Вход:
* %A0 - 1-ый множитель
* %A1 - 2-ой множитель
Выход:
* %A2 - ст. байт результата
* %A1 - мл. байт результата
Используется:
* %A3 - счётчик сдвигов
mul8u:
xor %a2, %a2 ; Инициализация ст. байта результата и CF
movl %a3, 9 ; Число битов в байте + 1
jmp $4f ; На нулевой сдвиг 2-го множителя
$2: add %a2, %a0 ; Сложение ст. байта результата с 1-ым множителем
$3: rrc %a2 ; Циклич. сдвиг вправо ст. байта результата
$4: rrc %a1 ; Циклич. сдвиг вправо мл. байта результата и 2-го множителя
jc $5f ; Если CF=1
dec %a3 ; Пока не все
jnz $3b ; сдвиги
rts ; Выход из подпрограммы
$5: dec %a3 ; Пока не все
sst 1 ; CF=1
jnz $2b ; сдвиги
rts ; Выход из подпрограммы
===== Знаковое умножение 8x8 =====
Вход:
* %A0 - 1-ый множитель
* %A1 - 2-ой множитель
Выход:
* %A2 - ст. байт результата
* %A1 - мл. байт результата
Используется:
* %A3 - счётчик сдвигов
mul8s:
xor %a2, %a2 ; Инициализация ст. байта результата и CF
movl %a3, 8 ; Число битов в байте
jmp $3f ; На битовую проверку
$2: add %a2, %a0 ; Сложение ст. байта результата с 1-ым множителем
$3: bttl %a1, 0001b ; Установлен бит 0 в мл. байте результата и 2-го множителе?
jz .+1 ; Нет
sub %a2, %a0 ; Восстановление ст. байта результата
shra %a2 ; Арифметич. сдвиг вправо ст. байта результата
rrc %a1 ; Циклич. сдвиг вправо мл. байта результата и 2-го множителя
jc $5f ; Если CF=1
dec %a3 ; Пока не все
jnz $3b ; сдвиги
rts ; Выход из подпрограммы
$5: dec %a3 ; Пока не все
sst 1 ; CF=1
jnz $2b ; сдвиги
rts ; Выход из подпрограммы
===== Беззнаковое умножение 16x16 =====
Вход:
* %A0 - мл. байт 1-го множителя
* %A1 - ст. байт 1-го множителя
* %A2 - мл. байт 2-го множителя
* %A3 - ст. байт 2-го множителя
Выход:
* %A2 - байт 0 результата
* %A3 - байт 1 результата
* %A4 - байт 2 результата
* %A5 - байт 3 результата
Используется:
* %A6 - счётчик сдвигов
mul16u:
clr %a5 ; Инициализация байта 3 результата
xor %a4, %a4 ; Инициализация байта 2 результата и CF
movl %a6, 17 ; Число битов в байте + 1
jmp $4f ; На нулевой сдвиг 2-го множителя
$2: add %a4, %a0 ; Сложение байта 2 результата с мл. байтом 1-го множителя
adc %a5 ; Сложение байта 3 результата с CF
jnc $100f ; Если не установлен CF
add %a5, %a1 ; Сложение байта 3 результата с ст. байтом 1-го множителя
sst 1 ; Восстановление
jmp $3f ; CF
$100: add %a5, %a1 ; Сложение байта 3 результата с ст. байтом 1-го множителя
$3: rrc %a5 ; Циклич. сдвиг вправо байта 3 результата
rrc %a4 ; Циклич. сдвиг вправо байта 2 результата
$4: rrc %a3 ; Циклич. сдвиг вправо байта 1 результата и мл.б. 2 множителя
rrc %a2 ; Циклич. сдвиг вправо байта 0 результата и ст.б. 2 множителя
jc $5f ; Если CF=1
dec %a6 ; Пока не все
jnz $3b ; сдвиги
rts ; Выход из подпрограммы
$5: dec %a6 ; Пока не все
sst 1 ; CF=1
jnz $2b ; сдвиги
rts ; Выход из подпрограммы
===== Знаковое умножение 16x16 =====
Вход:
* %A0 - мл. байт 1-го множителя
* %A1 - ст. байт 1-го множителя
* %A2 - мл. байт 2-го множителя
* %A3 - ст. байт 2-го множителя
Выход:
* %A2 - байт 0 результата
* %A3 - байт 1 результата
* %A4 - байт 2 результата
* %A5 - байт 3 результата
Используется:
* %A6 - счётчик сдвигов
// Недоделано - пока оставляю эту п/программу, займусь лучше следующими //
mul16s:
clr %a5 ; Инициализация байта 3 результата
xor %a4, %a4 ; Инициализация байта 2 результата и CF
movl %a6, 16 ; Число битов в байте
$1: JNC $3f
$2: add %a4, %a0 ; Сложение байта 2 результата с мл. байтом 1-го множителя
adc %a5 ; Сложение байта 3 результата с CF
jnc $100f ; Если не установлен CF
add %a5, %a1 ; Сложение байта 3 результата с ст. байтом 1-го множителя
sst 1 ; Восстановление
jmp $3f ; CF
$100: add %a5, %a1 ; Сложение байта 3 результата с ст. байтом 1-го множителя
$3:
jsr RBTTL
jz .+1 ; Нет
sub %a4, %a0 ; Восстановление байта 2 результата
jsr RBTTL
jz $4f ; Нет
sbc %a5 ; Восстановление
jnc $200f ; Если не установлен CF
sub %a5, %a1 ; байта 3 результата
sst 1 ; Восстановление
jmp $4f ; CF
$200: sub %a5, %a1 ; байта 3 результата
$4:
shra %a5 ; Арифметич.сдвиг вправо байта 3 результата
rrc %a4 ; Циклич. сдвиг вправо байта 2 результата
rrc %a3 ; Циклич. сдвиг вправо байта 1 результата и мл.б. 2 множителя
rrc %a2 ; Циклич. сдвиг вправо байта 0 результата и ст.б. 2 множителя
JSR RDEC ; {Это}
jnz $1b ; {всё}
rts ; {временно}
;???
jc $5f ; Если CF=1
dec %a6 ; Пока не все
jnz $3b ; сдвиги
rts ; Выход из подпрограммы
$5: dec %a6 ; Пока не все
sst 1 ; CF=1
jnz $2b ; сдвиги
rts ; Выход из подпрограммы
;
; П/программки для сохранения бита C
;
RDEC: jc $1f
dec %a6
rts
$1: dec %a6
sst 1
rts
RBTTL: jc $1f
bttl %a2, 0001b
rts
$1: bttl %a2, 0001b
sst 1
rts
;RBTTH: jc $1f
; btth %a4, 1000b
; rts
;$1: btth %a4, 1000b
; sst 1
; rts
;
;CBTTH1:
; jc .+2
; btth %a1, 1000b
; rts
; btth %a1, 1000b
; sst 1
; rts
===== Беззнаковое деление 8/8 =====
Вход:
* %A0 - делимое
* %A1 - делитель
Выход:
* %A0 - частное
* %A2 - остаток
Используется:
* %A3 - счётчик сдвигов
div8u:
xor %a2, %a2 ; Инициализация остатка и CF
movl %a3, 9 ; Число битов в байте + 1
$1: rlc %a0 ; Циклич. сдвиг влево делимого и частного
jc $4f ; Если CF=1
dec %a3 ; Пока не все
jnz $2f ; сдвиги
rts ; Выход из подпрограммы
$4: dec %a3 ; Пока не все
sst 1 ; CF=1
jnz $2f ; сдвиги
rts ; Выход из подпрограммы
$2: rlc %a2 ; Циклич. сдвиг влево остатка
sub %a2, %a1 ; Вычитание из остатка делителя
jnc $3f ; Если разность >0
add %a2, %a1 ; Иначе - восстанавливается остаток
cst 1 ; CF=0
jmp $1b ; Следующий цикл
$3: sst 1 ; CF=1
jmp $1b ; Следующий цикл
===== Знаковое деление 8/8 =====
Вход:
* %A0 - делимое
* %A1 - делитель
Выход:
* %A0 - частное
* %A2 - остаток
Используется:
* %A3 - счётчик сдвигов
* %A4 - знаковый регистр
div8s:
mov %a4, %a0 ; Делимое - в знаковый регистр
xor %a4, %a1 ; XOR знакового регистра с делителем
btth %a1, 1000b ; Делитель <0?
jz .+1 ; Нет
neg %a1 ; Смена знака делителя
btth %a0, 1000b ; Делимое <0?
jz .+1 ; Нет
neg %a0 ; Смена знака делимого
clr %a2 ; Инициализация остатка
movl %a3, 9 ; Число битов в байте + 1
$1: rlc %a0 ; Циклич. сдвиг влево делимого и частного
jc $4f ; Если CF=1
dec %a3 ; Пока не все
jnz $2f ; сдвиги
jmp $5f ;
$4: dec %a3 ; Пока не все
sst 1 ; CF=1
jnz $2f ; сдвиги
$5: btth %a4, 1000b ; Знаковый регистр <0?
jz .+1 ; Нет
neg %a0 ; Смена знака знакового регистра
rts ; Выход из подпрограммы
$2: rlc %a2 ; Циклич. сдвиг влево остатка
sub %a2, %a1 ; Вычитание из остатка делителя
jnc $3f ; Если разность >0
add %a2, %a1 ; Иначе - восстанавливается остаток
cst 1 ; CF=0
jmp $1b ; Следующий цикл
$3: sst 1 ; CF=1
jmp $1b ; Следующий цикл
===== Беззнаковое деление 16/16 =====
Вход:
* %A0 - мл. байт делимого
* %A1 - ст. байт делимого
* %A2 - мл. байт делителя
* %A3 - ст. байт делителя
Выход:
* %A0 - мл. байт частного
* %A1 - ст. байт частного
* %A4 - мл. байт остатка
* %A5 - ст. байт остатка
Используется:
* %A6 - счётчик сдвигов
div16u:
clr %a4 ; Инициализация мл. байта остатка
xor %a5, %a5 ; Инициализация ст. байта остатка и CF
movl %a6, 17 ; Число битов в байте + 1
$1: rlc %a0 ; Циклич. сдвиг влево мл.б. делимого и мл.б. частного
rlc %a1 ; Циклич. сдвиг влево ст.б. делимого и ст.б. частного
jc $4f ; Если CF=1
dec %a6 ; Пока не все
jnz $2f ; сдвиги
rts ; Выход из подпрограммы
$4: dec %a6 ; Пока не все
sst 1 ; CF=1
jnz $2f ; сдвиги
rts ; Выход из подпрограммы
$2: rlc %a4 ; Циклич. сдвиг влево мл. байта остатка
rlc %a5 ; Циклич. сдвиг влево ст. байта остатка
sub %a4, %a2 ; Вычитание из мл.б. остатка мл.б. делителя
sbc %a5 ; Вычитание из ст.б. остатка CF
jc $5f ; Если разность <0
sub %a5, %a3 ; Вычитание из ст.б. остатка ст.б. делителя
jnc $3f ; Если разность >0
add %a4, %a2 ; Иначе -
adc %a5 ; восстанавливается
add %a5, %a3 ; остаток
cst 1 ; CF=0
jmp $1b ; Следующий цикл
$3: sst 1 ; CF=1
jmp $1b ; Следующий цикл
$5: add %a4, %a2 ; Восстанавливается
adc %a5 ; остаток
cst 1 ; CF=0
jmp $1b ; Следующий цикл