@@ -225,7 +225,7 @@ IMULOV: MOV (SP), R5 ;
225225 MOV #1706., R0 ; Ошибка: переполнение
226226 JMP ERRR
227227;
228- ; DAUG ? умножение двух 16-разрядных положительных чисел (R1 * R0).
228+ ; DAUG - умножение двух 16-разрядных положительных чисел (R1 * R0).
229229; Вход: R1, R0 ? положительные числа (0..32767).
230230; Выход: результат в R5 (старшее слово) и R1 (младшее).
231231; Если результат не помещается в 32 бита (переполнение), возвращает R5 = -1.
@@ -441,6 +441,41 @@ FFIX:
441441;
442442 JMP @R5 ; возврат
443443
444+ ;#####################################################################
445+ ;## FINT
446+ ;## Need FFIX
447+ ;## Need FCMP
448+ ; Для плавающего числа (float) получает целое, меньшее чем аргумент.
449+ ; Для положительных чисел идёт к нулю, для отрицательных чисел идёт от нуля.
450+ ; На основе кода процедуры INT из реализации Бейсик Вильнюс для УКНЦ.
451+ ; На входе: (SP) - адрес возврата
452+ ; (SP+2)(SP+4) - плвающее число (старшее слово, младшее слово)
453+ ; Результат: (SP)(SP+2) - плвающее число (старшее слово, младшее слово)
454+ FINT:
455+ TST 2(SP) ; проверить знак числа (старшее слово)
456+ BPL FFIX ; положительное или 0 => так же как FIX
457+ ; Отрицательное число: нужно округлить вниз, от нуля
458+ CMP -(SP),-(SP) ; резервируем место на стеке
459+ MOV 10(SP),-(SP) ; дублируем исходное число на стек
460+ MOV 10(SP),-(SP)
461+ MOV 2(SP),-(SP) ; дублируем исходное число ещё раз
462+ MOV 2(SP),-(SP)
463+ ; На стеке: исх.число, исх.число, (SP+10)(SP+12) резерв, адрес возврата, исх.число
464+ CALL FFIX ; отбрасываем дробную часть
465+ MOV (SP),10(SP) ; копируем результат FIX в зарезерв. место на стеке
466+ MOV 2(SP),12(SP)
467+ CALL FCMP ; сравниваем два floats на стеке, снимает 4 слова
468+ ; На стеке: результат FIX, адрес возврата, исходное число
469+ BEQ 1$ ; числа равны => нет дробной части
470+ CLR -(SP) ; младшее слово константы 1.0
471+ MOV #40200,-(SP) ; старшее слово константы 1.0
472+ CALL FSUB ; вычитаем 1.0 из результата FIX
473+ 1$:
474+ ; На стеке: результат INT, (SP+4) адрес возврата, (SP+6)(SP+10) исходное число
475+ MOV (SP)+,4(SP) ; копируем результат поверх исходного числа
476+ MOV (SP)+,4(SP) ; и сдвигаем указатель стека
477+ RETURN ; возврат
478+
444479;#####################################################################
445480;## FINT
446481;## Need FFIX
@@ -712,7 +747,7 @@ VISKAS: MOVB #40,(R2)+ ;
712747 MOV R5, (SP) ; адрес возврата
713748 JMP WRSTR1 ; выводим полученную строку R0, R2 = длина
714749;
715- ; DG4DL5 ? умножение 24-битного числа (R1:R0) на 4/5 (0.8)
750+ ; DG4DL5 - умножение 24-битного числа (R1:R0) на 4/5 (0.8)
716751; путём многократного деления на 2 и сложения с исходным значением.
717752; Используется для извлечения десятичных цифр при выводе чисел.
718753; Вход: R0 ? старшее слово, R1 ? младшее слово (24-битное число).
@@ -1035,7 +1070,7 @@ FSUB:
10351070
10361071;#####################################################################
10371072;## FMUL
1038- ; Умножение для плавающих чисел, параметры B и A на стеке
1073+ ; Умножение для плавающих чисел, параметры B и A на стеке.
10391074; На основе кода процедуры MLR из реализации Бейсик Вильнюс для БК-0010.
10401075; На входе: (SP) - адрес возврата
10411076; (SP+2)(SP+4) - плавающее число B (старшее, младшее слово)
@@ -1163,10 +1198,140 @@ FMUL$P: ASR R4
11631198
11641199;#####################################################################
11651200;## FDIV
1166- ; Деление для float, эмуляция FIS, параметры B и A на стеке
1201+ ; Деление для плавающих чисел, параметры B и A на стеке.
1202+ ; На основе кода процедуры DVR из реализации Бейсик Вильнюс для БК-0010.
1203+ ; На входе: (SP) - адрес возврата
1204+ ; (SP+2)(SP+4) - плавающее число B (старшее, младшее слово)
1205+ ; (SP+6)(SP+10) - плавающее число A (старшее, младшее слово)
1206+ ; Результат: (SP)(SP+2) - плавающее число (старшее слово, младшее слово)
11671207FDIV:
1168- ;TODO
1169- RETURN ;STUB
1208+ MOV (SP)+, FDIV$X+2 ; снимаем и подставляем адрес возврата
1209+ MOV R5,-(SP) ; сохранение регистров
1210+ MOV R4,-(SP)
1211+ ; Подготовительные действия
1212+ CLR R0 ; Подготовить место
1213+ CLR R1 ; для мантиссы
1214+ CLR -(SP) ; и знака результата
1215+ ASL 12(SP) ; Запомнить в стеке
1216+ ROL (SP) ; знак A
1217+ CLR -(SP) ; Выделить место для порядка результата
1218+ TST 10(SP) ; делитель 0 - ошибка
1219+ BNE 2$
1220+ TRAP 11.
1221+ 2$: BISB 15(SP),(SP) ; запомнить знак A
1222+ BEQ FDIV$0 ; A = 0 => результат 0
1223+ BISB 14(SP),R0
1224+ SWAB R0 ; заслать в R0-R1
1225+ SEC ; мантиссу A,
1226+ ROR R0 ; присоединив спереди
1227+ BISB 17(SP),R0 ; значащий разряд
1228+ BISB 16(SP),R1
1229+ SWAB R1
1230+ CLR R2 ; подготовить место
1231+ CLR R3 ; для мантиссы делителя
1232+ ASL 10(SP) ; сформировать знак
1233+ ADC 2(SP) ; результата
1234+ BISB 11(SP),R2 ; подсчитать порядок
1235+ SUB R2,(SP) ; результата
1236+ CLR R2
1237+ BISB 10(SP),R2
1238+ SWAB R2 ; заслать в R2-R3
1239+ SEC ; мантиссу B
1240+ ROR R2
1241+ BISB 13(SP),R2
1242+ BISB 12(SP),R3
1243+ SWAB R3
1244+ ; Переход на деление мантисс
1245+ CMP R0,R2 ; если A > B,
1246+ BCS FDIV$Z ; начинать вычитывать B
1247+ BHI FDIV$M ; с первого разряда A
1248+ CMP R1,R3 ; если A < B,
1249+ BHI FDIV$M ; начинать вычитывать
1250+ BNE FDIV$Z ; cо второго разряда A
1251+ CLR 14(SP) ; если A = B,
1252+ INC (SP) ; подготовить
1253+ CLR R5 ; формирование результата
1254+ BR FDIV$D ; c мантиссой 1
1255+ ;
1256+ ;REZ0: Подготовка формирования результата 0
1257+ FDIV$0: CMP (SP)+,(SP)+
1258+ BR FDIV$N
1259+ ;
1260+ ;EPERP: Обработка переполнения
1261+ FDIV$O: TRAP 6
1262+ ;
1263+ ; Обработка исчезновения порядка
1264+ EISNYK: TST (SP)+
1265+ ;NUL: Формирование результата 0
1266+ FDIV$N: CLR 10(SP)
1267+ CLR 12(SP)
1268+ BR FDIV$E
1269+ ;
1270+ ;DAUG: Деление мантисс
1271+ FDIV$M: ROR R0 ; погашение
1272+ ROR R1 ; начального сдвига
1273+ INC (SP) ; подпрограммы DALYT
1274+ ;MAZIAU:
1275+ FDIV$Z: MOV #11,R4 ; сформирование
1276+ CALL FDIV$T ; старшей части
1277+ MOVB R5,14(SP) ; мантиссы результата
1278+ TST R4 ; если мантиссы не сравнялись,
1279+ BEQ 20$ ; продолжать деление
1280+ CLR R5 ; младшая часть мантиссы
1281+ BR FDIV$D ; результата = 0
1282+ 20$: MOV #20,R4 ; продолжение деления
1283+ CALL FDIV$T
1284+ ;
1285+ ;END: Формирование результата
1286+ FDIV$D: MOV (SP)+,R4 ; формирование порядка
1287+ ADD #200,R4
1288+ BLE EISNYK ; исчезновение порядка?
1289+ CMP #377,R4
1290+ BLT FDIV$O ; переполнение?
1291+ MOVB R4,13(SP) ; Присоединение порядка к мантиссе результата
1292+ ROR (SP)+ ; присоединение знака
1293+ ROR 10(SP)
1294+ ROR R5
1295+ ADC R5 ; округление
1296+ MOV R5,12(SP)
1297+ ADC 10(SP)
1298+ BCS FDIV$O ; переполнение?
1299+ BVS FDIV$O
1300+ ;ENDD:
1301+ ;ENDM: Завершение
1302+ FDIV$E: MOV (SP)+,R4 ; восстановление регистров
1303+ MOV (SP)+,R5
1304+ CMP (SP)+,(SP)+ ; удаление числа B из стека
1305+ FDIV$X: JMP @#000000 ; возврат
1306+ ;
1307+ ;DALYT: Подпрограмма деления мантисс
1308+ FDIV$T: ASL R5 ; сдвиг результата
1309+ ASL R1 ; и мантиссы A
1310+ ROL R0
1311+ BCS 30$ ; C=1 => A > B => вычитать
1312+ CMP R2,R0 ; сравнить A и B
1313+ BHI 32$ ; B > A => сдвинуть A
1314+ BCS 30$ ; B < A => вычитать B
1315+ CMP R3,R1 ; сравнить младшие
1316+ BHI 32$ ; части
1317+ BEQ 36$ ; A = B => окончить
1318+ ;ATIMT:
1319+ 30$: SUB R3,R1 ; вычитание A-B
1320+ SBC R0 ; сравнить A и B
1321+ SUB R2,R0
1322+ INC R5 ; Формирование единицы в результате
1323+ ;SLINKT:
1324+ 32$: DEC R4 ; результат сформирован?
1325+ BGT FDIV$T ; нет - продолжить
1326+ RETURN ; нет - окончить
1327+ ;LYGU:
1328+ 36$: INC R5 ; делимое и делитель
1329+ BR 41$ ; сравнились
1330+ 40$: ASL R5 ; заполнить
1331+ 41$: DEC R4 ; конец результата
1332+ BGT 40$ ; нолями
1333+ INC R4 ; признак окончания деления
1334+ RETURN
11701335
11711336;#####################################################################
11721337;## STCP
0 commit comments