(C) ESC.  E97 ROM.  E.A.Eremin, 1997

LoROM=4000h!!!

---------------------------------------------------------
sub DIV/MOD (division with mod): LoRom+0000
    Formula: A mod B = A - (A div B) * B
IN: R1,R2; OUT: R1=R1 DIV R2; R2=R1 MOD R2; R0,R3 is kept
---------------------------------------------------------
0E20 R0 ==> stack
0110 R1 ==> R0
0621 R1 div R2 ==> R1
0512 R1 * R2 ==> R2
0320 R0 - R2 ==>R0
0102 R0 ==> R2
0E30 stack ==> R0
0D00 return

---------------------------------------------------
sub ABS (absolute value): LoRom+0010h
    Formula: if A<0  abs(A)=not(A)+1; else abs(A)=A
IN: R1 - number; OUT: R1=ABS(R1); R0,R2,R3 is kept
---------------------------------------------------
2401 compare R1 with 0 (0 - "short constant")
3D02 if <0, then pc = pc+2
0D00 return
0E11 NOT R1 ==> R1
2211 +1 to R1 (1 - "short const")
0D00 return

----------------------------------------------------------
sub IntToStr (convert number to text string): LoROM+001Ch
    Dec numbers of result are get by ciclic division by 10
    Zero suppression: "-00070" ==> "   -70"
IN: R1-integer; R3-string buffer address; R0-R3 is kept
----------------------------------------------------------
0E20 R0 ==> stack
0E21 R1 ==> stack
0E22 R2 ==> stack
2401 compare R1 with 0 (0 - "short const")
3D06 if <0, then pc = pc+6: "-"
C1D7 20b ==> (R3)b: " " if R1>=0
0020
1D06 pc = pc+6: bypass abs
C1D7 2Db ==> (R3)b: "-" if R1<0
002D
9DDE call sub ABS ( ABS(R1) )
2150 5 ==> to R0 (5 - "short const"): 5 digits
0203 R0 + R3 ==> R3: +5 to R3, to point at the end of text!
21A2 10 ==> R2 (10 - "short const"): convert to 10 system
9DC6 call sub DIV/MOD (R2 - digit)
02D2 R2 + 30 ==> R2: number ==> code, for example, 3 ==> "3"
0030                 const 30
C127 R2b ==> (R3)b: remember digit
2313 -1 from R3 (next digit)
2310 -1 from R0 (digits counter)
4DF0 if <>0, then pc = pc-10h: to 10 ==> R2 and repeat cycle
2140 4 ==> R0 - can't be >4  nonsignificant zeros
0131 R3 ==> R1 (beg. of the text) - pointer to current symbol
0132 R3 ==> R2
2212 +1 to R2 - pointer to next symbol
C4D6 compare 30b with (R2)b: "0"?
0030                      const 30
4D0C if <>0, then pc = pc+0Ch: significant digit found - exit
C156 (R1)b ==> (R2)b - copy sign ("-" or " ")
C1D5 20b ==> (R1)b: " " to line - erase old sign
0020                const 20
2211 +1 to R1: prepare sign address before checking next digit
2310 -1 from R0: counter
4DEC if <>0, then pc = pc-14h: to instruct. +1 to R2 and repeat
0E32 stack ==> R2
0E31 stack ==> R1
0E30 stack ==> R0
0D00 return

----------------------------------------------------
sub WriteInteger (output integer number): LoROM+0068
IN: R1 - number; R3 - buffer address;  OUT: no;
    R0-R3 is kept
----------------------------------------------------
9DB2 call sub IntToStr [6A+B2=1C]
                        returns line to (R3) address
0E23 R3 ==> stack
0E22 R2 ==> stack
2162 6 ==> R2 (6 - "short const"): length
9D06 call sub WriteString: line output
0E32 stack ==> R2
0E33 stack ==> R3
0D00 return

-------------------------------------------------------
sub WriteString (output line to display): LoROM+0078
IN: R2 - number of symbols; R3 - line address; OUT: no;
    R0 and R1 is kept, R2 and R3 not
-------------------------------------------------------
0E20 R0 ==> stack
C170 (R3)b ==> R0b: current symbol to R0
9D0A call sub OUTSYM: symbol output
2213 +1 to R3: next symbol address
2312 -1 from R2: symbol counter
4DF6 if <>0, then pc = pc-0Ah: to instruc. (R3)b ==> R0b and repeat
0E30 stack ==> R0
0D00 return

-------------------------------------------------
sub OUTSYM (output symbol to display): LoROM+0088
IN: R0 - symbol;  OUT: no;  R0-R3 is kept
-------------------------------------------------
0E21 R1 ==> stack
0A21 port 2 ==> R1: read status port
E401 compare 0b with R1b (0 - "short const")
2DFA if >=0, then pc = pc-6: repeat
     (READY - high bit of low byte = 1, byte<0!)
0B03 R0 ==> port 3: symbol to display data port
0E31 stack ==> R1
0D00 return

------------------------------------------------------
sub MovMas (copy array): LoROM+0096
IN: R1,R2 - beginning of source and destination arrays
    R0 - number of bytes;
OUT - no; R3 is kept, rest registers - not
------------------------------------------------------
0421 compare R1 with R2
2D14 if >=0, then pc = pc+14: to MovMas+, else prepare MovMas-
0201 R0+R1 ==> R1
2311 -1 from R1 (end of 1 array)
0202 R0+R2 ==>R2
2312 -1 from R2 (end of 2 array)

------------------------------------------------
sub MovMas- (copy array, dec. addr.): LoROM+00A2
IN: R1, R2 - end of arrays (last byte address)
    R0 - number of bytes;
OUT - no; R3 is kept, rest registeers - not
------------------------------------------------
C156 (R1)b ==> (R2)b: copy current byte
2311 -1 from R1: 1 array address
2312 -1 from R2: 2 array address
2310 -1 from R0: byte counter
4DF6 if <>0, then pc = pc-10: to repeat cycle
0D00 return

--------------------------------------------------
sub MovMas+ (copy array, inc. addr.): LoROM+00AE
IN: R1, R2 - beg. of source and destination arrays
    R0 - number of bytes;
OUT - no; R3 is kept, rest registeers - not
--------------------------------------------------
C156 (R1)b ==> (R2)b: copy curren byte
2211 +1 to R1: 1 array address
2212 +1 to R2: 2 array address
2310 -1 from R0: byte counter
4DF6 if <>0,  pc = pc-10: to repeat cycle
0D00 return

##### Library for Pascal programs #####
---------------------------------------------
sub WriteChar (output CHAR type): LoROM+00BA
    (OUTSYM - from R0, but Pascal - from R1!)
IN: R1 - symbol; OUT - no; R0-R3 is kept
---------------------------------------------
0E20 R0 ==> stack
0110 R1 ==> R0: symbol
9DC8 call sub OUTSYM: symbol output [C0+C8=88]
0E30 stack ==> R0
0D00 return

------------------------------------------------------
sub WriteBoolean (output BOOLEAN type): LoROM+00C4
    If R1=0 - print FALSE, else - TRUE
IN: R1 - value; OUT - no; R0, R1 is kept, R2, R3 - not
------------------------------------------------------
E401 compare R1b with 0b (0 - "short const")
5D0A if =0, hen pc = pc+0A: to "FALSE" output
9D12 call sub WritePasString: output text after call
5404 (4)T \
5552 RU    > text TRUE (4 - it's length)
0045 E(0) /
0D00 return
9D08 call sub WritePasString: output text after call
4605 (5)F \
4C41 AL    > text FALSE
4553 SE   /
0D00 return

-----------------------------------------------------
sub WritePasString (output text, allocated after call
   instruction): LoROM+00DC
IN: (text address in stack memory!)
OUT: R2=0; R3 - next addres after text;
R0, R1 - is kept, R2, R3 - not
-----------------------------------------------------
0E33 stack ==> R3: text address from stack to R3
8172 (R3)b ==> R2: convert text length to word!
2213 +1 to R3: beginning of the text
9D94 call sub WriteString: line output [E4+94=78]
2213 +1 to R3
07D3 R3 and
FFFE    const FFFE ==> R3 (reset low bit - even value)
1C03 R3 ==> PC: jump to the next address after the text

---------------------------------
sub LN (CR/LF output): LoROM+00EC
IN, OUT: no; R0-R3 is kept
---------------------------------
0E20 R0 ==> stack
21D0 13 ==> R0 (13 - "short const"): CR
9D96 call sub OUTSYM: output symbol [F2+96=88]
21A0 10 ==> R0 (10 - "short const"): LF
9D92 call sub OUTSYM: output symbol [F6+92=88]
0E30 stack ==> R0
0D00 return

##### Input subrotines #####
-----------------------------------------------
sub INSYMe (input symbol WITH echo): LoROM+00FA
OUT: R0: symbol;  R1 - R3 is kept
-----------------------------------------------
9D02 call sub INSYM: input from keyboard
1D8A go to OUTSYM sub [FE+8A=88]

-----------------------------------------------
sub INSYM (input symbol WITHOUT echo): LoROM+FE
IN: no;  OUT: R0 - symbol;  R1 - R3 is kept
-----------------------------------------------
0A00 port 0 ==> R0: read status port
E400 compare R0b with 0b (0 - "short const")
2DFA if >=0, then pc = pc-6: to repeat cycle
     (READY - high bit of low byte = 1, byte<0!)
0A10 port 1 ==> R0: get data from keyboard port
0D00 return

##### ROM2 calls #####
(ROM2 is a part of ROM, that can't be read in "E97"
instructions, but can be executed; this is done for
more quick pfogram realization)
------------------------------------------------------
sub Input_Integer (input INTEGER number): LoROM+0108
IN: no;  OUT: R1 - input result;  R0, R2, R3 - is kept
------------------------------------------------------
1D78 go to 10A+78=182

--------------------------------------------------
sub Input_Boolean (input BOOLEAN type): LoROM+010A
IN: no;  OUT: R1 - 0 if FALSE  and 1 if TRUE;
R0, R2, R3 - is kept
--------------------------------------------------
1D74 go to 10C+74=180

0000
0000

##### G4114 - get ROM version #####
0E30
1C00
9DFA
0103
02D3
0016
01D2
0018
07D0
F000
08D0
0078
9C00
0F00
4328
2029
5345
2043
2020
3931
3739
2020
3156
312E
2020
0D0A

0000
0000
0000
0000
0000
0000
0000

##### Addition #####
-------------------------------------------------------
sub NewWriteInteger (output INTEGER number): LoROM+0152
 [in contradistinction from old sub WriteInteger,
 creates buffer itself; can print number in old way 
 "right-align" (N=    -1) and "left-align" (N=-1)]
IN: R0=0 - "left-align", else - "right-align",
    R1 - number;  OUT: no;  R0-R3 is kept
-------------------------------------------------------
0E22 R2 ==> stack
0E23 R3 ==> stack
0E5D SP - 6 ==> SP
0006   (6 byte is reserved for buffer)
0E73 SP ==> R3 (buffer address)
9C0D call sub IntToStr
401C       (returns line, pointed by R3)
2162 6 ==> R2 (string length)
2400 compare R0 with 0
4D0C bypas, if <>0 - to "right-align" output
C47D compare (R3)b with space code
0020
4D06 exit, if not
2312 R2 - 1 ==> R2 (dec simbol counter)
2213 R3 + 1 ==> R3 (inc address)
1DF4 repeat cycle (to compare with space code)
9C0D call sub WriteString: output string
4078
0E4D SP + 6 ==> SP
0006   (release memory)
0E33 stack ==> R3
0E32 stack ==> R2
0D00 return

 Last line of file must be '.'!!!
.
