|
ПЗУ1 учебного компьютера “Е97”
(C) ESC. E97 ROM. Автор Е.А.Еремин
Последняя редакция кода - 21.05.97
LoROM=4000h!!!
п/п DIV/MOD (деление с нахождением остатка): адрес LoRom+0000
Рабочая формула: A mod B = A - (A div B) * B
IN : R1,R2; OUT: R1=R1 DIV R2; R2=R1 MOD R2; R0,R3 сохраняются
0E20 |
R0 ==> стек : сохранить R0 в стеке |
0110 |
R1 ==> R0 |
0621 |
R1 div R2 ==> R1 |
0512 |
R1 * R2 ==> R2 |
0320 |
R0 - R2 ==>R0 |
0102 |
R0 ==> R2 |
0E30 |
стек ==> R0 : восстановить из стека R0 |
0D00 |
возврат из п/п |
п/п ABS (вычисление модуля): LoRom+0010h
Рабочая формула: при A<0 abs(A)=not(A)+1; иначе abs(A)=A
IN : R1; OUT: R1=ABS(R1); R0,R2,R3 сохраняются
2401 |
сравнить R1 c 0 (0 - "короткая константа") |
3D02 |
если <0, то pc = pc+2: к вычислению модуля |
0D00 |
возврат из п/п |
0E11 |
NOT R1 ==> R1 |
2211 |
+1 в R1 (1 - "короткая константа") |
0D00 |
возврат из п/п |
п/п IntToStr (преобразование числа в текстовой вид): LoROM+001Ch
Цифры в десятичном текстовом представлении числа получаются путем его циклического деления на 10. Незначащие нули перед числом заменяются пробелами, например : "-0070” ==> " -70"
IN: R1-integer; R3-адрес строки; OUT: нет; R0-R3 сохраняются
0E20 |
R0 ==> стек |
0E21 |
R1 ==> стек: сохраним регистры |
0E22 |
R2 ==> стек |
2401 |
сравнить R1 с 0 (0 - "короткая константа") |
3D06 |
если <0, то pc = pc+6: к занесению в строку знака минус |
C1D7 |
20b ==> (R3)b: занести в строку входящую в команду байтовую константу "пробел" (R1>=0) |
0020 |
константа "пробел" |
1D06 |
pc = pc+6: обход занесения знака минус и взятия модуля |
C1D7 |
2Db ==> (R3)b: занести в строку входящую в команду байтовую константу "минус" (R1<0) |
002D |
константа "минус" |
9DDE |
вызов п/п ABS (взять модуль R1) |
2150 |
5 ==> в R0 (5 - "короткая константа"): должно быть 5 цифр |
0203 |
R0 + R3 ==> R3: +5 в R3, чтобы он показывал на конец текста! |
21A2 |
10 ==> R2 (10 - "короткая константа"): для перевода в 10 с/с |
9DC6 |
вызов п/п DIV/MOD (в R2 - остаток от деления на 10, т.е. десятичная цифра) |
02D2 |
R2 + 30 ==> R2: число ==> код цифры, например, 3 ==> "3" |
0030 |
константа 30 |
C127 |
R2 ==> (R3): байт с цифрой запомнить |
2313 |
-1 из R3 (переход к очередной цифре) |
2310 |
-1 из R0 (счетчик цифр) |
4DF0 |
если <>0, то pc = pc-10h: к 10 ==> R2 и повторению цикла |
2140 |
4 ==> R0 - подавить можно не более 4-х незначащих нулей спереди |
0131 |
R3 ==> R1 (начало текста) - указатель на текущий символ |
0132 |
R3 ==> R2 |
2212 |
+1 в R2 - указатель на следующий символ |
C4D6 |
сравнить 30b с (R2)b: символ "0"? |
0030 |
константа 30 |
4D0C |
если <>0, то pc = pc+0Ch: найдена первая значащая цифра - выход |
C156 |
(R1)b ==> (R2)b - перенести знак числа ("-" или "пробел") |
C1D5 |
20b ==> (R1)b: "пробел" в строку - стереть старый знак |
0020 |
константа 20 |
2211 |
+1 в R1: подготовить адрес знака для проверки следующей цифры |
2310 |
-1 из R0: счетчик |
4DEC |
если <>0, то pc = pc-14h: к +1 в R2 и повторению цикла |
0E32 |
стек ==> R2 |
0E31 |
стек ==> R1: восстановим регистры |
0E30 |
стек ==> R0 |
0D00 |
возврат из п/п |
п/п WriteInteger (вывод целого числа): LoROM+0068
IN : R1 - число; R3 - адрес строки (т.е. буфера); OUT: нет; R0-R3 сохраняются
9DB2 |
вызов п/п IntToStr [расчет адреса: 6A+B2=1C] (вернет строку по адресу в R3) |
0E23 |
R3 ==> стек |
0E22 |
R2 ==> стек |
2162 |
6 ==> R2 (6 - "короткая константа"): длина строки |
9D06 |
вызов п/п WriteString: вывод строки |
0E32 |
стек ==> R2 |
0E33 |
стек ==> R3 |
0D00 |
возврат из п/п |
п/п WriteString (вывод строки на дисплей): LoROM+0078
IN : R2 - количество символов; R3 - адрес строки;OUT: нет; R0 и R1 сохраняются, R2 и R3 нет (R3 указывает на следующий за текстом байт!)
0E20 |
R0 ==> стек |
C170 |
(R3)b ==> R0b: очередной символ в R0 |
9D0A |
вызов п/п OUTSYM: вывод символа на дисплей |
2213 |
+1 в R3: адрес следующего символа |
2312 |
-1 из R2: счетчик символов |
4DF6 |
если <>0, то pc = pc-0Ah: к (R3)b ==> R0b и повторению |
0E30 |
стек ==> R0 |
0D00 |
возврат из п/п |
п/п OUTSYM (вывод символа на дисплей): LoROM+0088
IN: R0 - символ; OUT: нет; R0-R3 сохраняются
0E21 |
R1 ==> стек |
0A21 |
порт 2 ==> R1: чтение порта состояния |
E401 |
сравнить 0b с R1b (0 - "короткая константа") |
2DFA |
если >=0, то pc = pc-6: снова читать порт состояния (готовность - старший бит МЛАДШЕГО БАЙТА = 1, т.е. байт<0!) |
0B03 |
R0 ==> порт 3: собственно вывод символа в порт данных |
0E31 |
стек ==> R1 |
0D00 |
возврат из п/п |
п/п MovMas (перепись массива): LoROM+0096
IN: R1,R2 - начало исходного и результирующего массивов R0 - количество байт в массиве; OUT - нет; R3 сохраняется, остальные регистры - нет
0421 |
сравнить R1 c R2 |
2D14 |
если >=0,то pc = pc+14: к MovMas+, иначе подготовка к MovMas- |
0201 |
R0+R1 ==> R1 |
2311 |
-1 из R1 (конец 1 массива) |
0202 |
R0+R2 ==>R2 |
2312 |
-1 из R2 (конец 2 массива) |
п/п MovMas- (перепись массива по убыванию адресов): LoROM+00A2
IN : R1, R2 - конец (последний байт) исходного и результирующего массивов, R0 - количество байт в массиве; OUT - нет; R3 сохраняется, остальные регистры - нет
C156 |
(R1)b ==> (R2)b: перепись очередного байта |
2311 |
-1 из R1: адрес первого массива |
2312 |
-1 из R2: адрес второго массива |
2310 |
-1 из R0: счетчик байтов |
4DF6 |
если <>0, то pc = pc-10: к повторению цикла переписи |
0D00 |
возврат из п/п |
п/п MovMas+ (перепись массива по возрастанию адресов): LoROM+00AE
IN : R1, R2 - начало исходного и результирующего массивов, R0 - количество байт в массиве; OUT - нет; R3 сохраняется, остальные регистры - нет
C156 |
(R1)b ==> (R2)b: перепись очередного байта |
2211 |
+1 в R1: адрес первого массива |
2212 |
+1 в R2: адрес второго массива |
2310 |
-1 из R0: счетчик байтов |
4DF6 |
если <>0, то pc = pc-10: к повторению цикла переписи |
0D00 |
возврат из п/п |
## Библиотека исполнения для Паскаль-программ ##
п/п WriteChar (вывод значение типа CHAR): LoROM+00BA
(OUTSYM выводит символ из R0, а Паскалю удобнее из R1!)
IN : R1 - символ; OUT - нет; R0-R3 сохраняются
0E20 |
R0 ==> стек |
0110 |
R1 ==> R0: символ |
9DC8 |
вызов п/п OUTSYM: вывод символа [расчет адреса: C0+C8=88] |
0E30 |
стек ==> R0 |
0D00 |
возврат из п/п |
п/п WriteBoolean (выводит значение типа BOOLEAN): LoROM+00C4
При R1=0 выводится TRUE, иначе - FALSE
IN : R1 - значение; OUT - нет; R0, R1 сохраняются, R2, R3 - нет
E401 |
сравнить R1b с 0b (0 - "короткая константа") |
5D0A |
если =0, то pc = pc+0A: к выводу TRUE |
9D12 |
вызов п/п WritePasString: вывести текст, идущий далее |
5404 |
(4)T |
5552 |
RU текст TRUE (4 - его длина) |
0045 |
E(0) |
0D00 |
возврат из п/п |
9D08 |
вызов п/п WritePasString: вывести текст, идущий далее |
4605 |
(5)F |
4C41 |
AL текст FALSE |
4553 |
SE |
0D00 |
возврат из п/п |
п/п WritePasString (вывод текста, находящегося после вызова п/п): LoROM+00DC
IN : в стеке - адрес следующего за командой вызова п/п слова, т.е. адрес начала текста! OUT: R2=0; R3 - адрес следующего за текстом слова; R0, R1 - сохраняются, R2, R3 - нет
0E33 |
стек ==> R3: прочитать из стека адрес текста в R3 |
8172 |
(R3)b ==> R2: длина текста из байта преобразуется в слово! |
2213 |
+1 в R3: перейдем к адресу начала текста |
9D94 |
вызов п/п WriteString: вывод строки [расчет перехода: E4+94=78] |
|
(далее установим R3 на "ближайший следующий" четный адрес, т.к. это адрес следующей за текстом команды:) |
2213 |
+1 к R3 |
07D3 |
R3 and FFFE ==> R3 (сбросить младший бит) |
FFFE |
константа FFFE |
1C03 |
R3 ==> PC: перейти к следующей за текстом команде |
П/п LN (вывод CR/LF - перевод строки): LoROM+00EC
IN, OUT : нет; R0-R3 сохраняются
0E20 |
R0 ==> стек |
21D0 |
13 ==> R0 (13 - "короткая константа"): "возврат каретки" CR |
9D96 |
вызов п/п OUTSYM: вывод символа [расчет перехода: F2+96=88] |
21A0 |
10 ==> R0 (10 - "короткая константа"): "перевод строки" LF |
9D92 |
вызов п/п OUTSYM: вывод символа [расчет перехода: F6+92=88] |
0E30 |
стек ==> R0 |
0D00 |
возврат из п/п |
##### ПОДПРОГРАММЫ ВВОДА #####
П/п INSYMe (ввод символа с эхо-печатью): LoROM+00FA
IN: нет; OUT: R0: символ; R1 - R3 сохраняются
9D02 |
вызов п/п INSYM: ввод символа с клавиатуры |
1D8A |
переход к OUTSYM: к выводу [расчет перехода: FE+8A=88] |
П/п INSYM (ввод символа без эхо-печати): LoROM+FE
IN : нет; OUT: R0 - символ; R1 - R3 сохраняются
0A00 |
порт 0 ==> R0: чтение порта состояния |
E400 |
сравнить R0b с 0b (0 - "короткая константа") |
2DFA |
если >=0, то pc = pc-6: снова читать порт состояния (готовность - старший бит МЛАДШЕГО БАЙТА = 1, т.е. байт<0!) |
0A10 |
порт 1 ==> R0: собственно ввод из порта данных клавиатуры |
0D00 |
возврат из п/п |
##### ОБРАЩЕНИЯ К ПЗУ2 #####
П/п Input_Integer (ввод целого числа): LoROM+0108
IN: нет; OUT: R1 - введенное число; R0, R2, R3 - сохраняются
1D78 переход на 10A+78=182
П/п Input_Boolean (ввод значения типа BOOLEAN): LoROM+010A
IN : нет; OUT: R1 = 0 если введено TRUE и 1 если FALSE; R0, R2, R3 - сохраняются
1D74 переход на 10C+74=180
##### РЕЗЕРВ #####
0000 ...
|