This is a GUI module of EuroTool program EuroCalc for Linux.
EUROASM CPU=X64, Unicode=No
calcling PROGRAM Format=COFF, Width=64
%DROPMACRO *
INCLUDEHEAD argument.htm
INCLUDE lins.htm, linabi.htm, cpuext64.htm, cpuext.htm, status32.htm
; Constants.
MinRows EQU 64 ; Minimal terminal dimensions.
MinCols EQU 36
MaxCols EQU 640
[.rodata] ; Constant data.
BoxV DB BYTE '│',0 ; BOX DRAWINGS LIGHT VERTICAL 2502
BoxDR DB BYTE '┌',0 ; BOX DRAWINGS LIGHT DOWN AND RIGHT 250C
BoxDL DB BYTE '┐',0 ; BOX DRAWINGS LIGHT DOWN AND LEFT 2510
BoxUR DB BYTE '└',0 ; BOX DRAWINGS LIGHT UP AND RIGHT 2514
BoxUL DB BYTE '┘',0 ; BOX DRAWINGS LIGHT UP AND LEFT 2518
Box2V DB BYTE '║',0 ; BOX DRAWINGS DOUBLE VERTICAL 2551
Box2DR DB BYTE '╔',0 ; BOX DRAWINGS DOUBLE DOWN AND LEFT 2554
Box2DL DB BYTE '╗',0 ; BOX DRAWINGS LIGHT DOWN AND LEFT 2557
Box2UR DB BYTE '╚',0 ; BOX DRAWINGS DOUBLE UP AND RIGHT 255A
Box2UL DB BYTE '╝',0 ; BOX DRAWINGS DOUBLE UP AND LEFT 2518
Boxes DB MaxCols*BYTE '─' ; BOX DRAWINGS LIGHT HORIZONTAL 2500
Boxes2 DB MaxCols*BYTE '═' ; BOX DRAWINGS DOUBLE HORIZONTAL 2550
Spaces DB MaxCols*BYTE ' '
Space1 DB ' ',0
EscBaseColor DB 27,'[30;47m',0 ; Zero-terminated sequences for writing to terminal.
EscEnhColor DB 27,'[38;5;160m',0 ; Red.
EscResultColor DB 27,'[38;5;28m',0
EscDimColor DB 27,'[38;5;243m',0 ; Gray.
EscEditColor DB 27,'[30;107m',0
EscEnableMouse DB 27,'[?1000;1006;1015h',0
EscDisableMouse DB 27,'[?1000;1006;1015l',0
[.data] ; Variable data.
EscResize DB 27,'[8;'
ValResize DB 'xxxxxxxxx' ; Replaced by '24;150t',0
EscLineInput DB 27,'[3;2H',0
EscLineResult DB 27,'[4;2H',0
EscLineError DB 27,'[6;10H',0
EscLine1 DB 27,'[1H',0
EscLine28 DB 27,'[28H',0
EscLineDown DB 27,'[E',0
EuroCalc DB ' EuroCalc',0
[.bss] ; Working data.
TtySize DS TTYSIZE
TermIO:: DS TERMIO
InpBufferPtr D QWORD ; Pointer to the current character within InpBuffer::.
MainWidth D DWORD ; The width of the window.
LineSize D DWORD ; Number of characters in the input line and in the result line. MainWidth-2.
MainHeight D DWORD ; Number of lines in the main window.
KeyBuffer D 32*BYTE ; Buffer for reading the keyboard.
[.text]
MainGui:: PROC
CALL PaintWindow
LEA RBX,[TermIO]
LinABI ioctl,0,TCGETS,RBX ; Load current local terminal status.
RstSt [RBX+TERMIO.c_lflag],ICANON+ECHO
LinABI ioctl,0,TCSETS,RBX ; Disable terminal echo.
.0N1:StdOutput EscEnableMouse ; Button #1 [Clr ].
LEA RDI,[InpBuffer::]
MOV [InpBufferPtr],RDI
CALL .ClearInputLine:
CALL .ClearResultLine:
.10: LEA RSI,[InpBuffer::]
MOV ECX,[LineSize]
StdOutput EscLineInput,EscEditColor
StdOutput RSI,Size=RCX ; Erase input line on screen.
.20: ; Show cursor corresponding with InpBufferPtr.
LEA RDI,[KeyBuffer] ; Room where to read the key or mouse button.
MOV RDX,RDI
MOV EAX,0x3B335B1B ; Esc [ 3 ;
STOSD
MOV RAX,[InpBufferPtr]
LEA RSI,[InpBuffer:: -2]
SUB RAX,RSI
StoD RDI ; Store column number decimal.
MOV AL,'H'
STOSB
MOV RAX,RDI
SUB RAX,RDX
StdOutput RDX,Size=RAX ; Set cursor position.
.25: ; Read keyboard and mouse.
LEA RSI,[KeyBuffer]
XOR EAX,EAX
MOV [RSI+0],RAX
MOV [RSI+8],RAX
LinABI read,0,RSI,SIZE# KeyBuffer, Fastmode=no
MOV ECX,EAX ; Number of read characters. 1 (most often) or 3..10.
MOV EAX,[RSI]
MOV RDI,[InpBufferPtr]
StdOutput EscLineError,EscBaseColor
; Process the key or button. EAX=ANSI code, CL=its size.
Dispatch CL,0n1,0n3,0n4
JMP .35: ; Jump when Esc sequence is longer than 4.
.0n1:Dispatch AL,0x0A,0x1B,0x3D,0x08,0x7F ; Single character (Enter, Esc, = or other).
LEA RDI,[InpBuffer::]
MOV ECX,[LineSize]
LEA RDI,[RDI+RCX-1]
MOV RCX,RDI
LEA RSI,[RDI-1]
SUB RCX,[InpBufferPtr]
JNA .25:
STD
REP MOVSB ; Move the text following cursor one character to the right.
CLD
STOSB ; Store other ordinary character.
MOV [InpBufferPtr],RDI
CALL .ClearResultLine:
JMP .10:
.0x08: ; Backspace character ASCII 8.
.0x7F: ; Delete character ASCII 127.
.0N2:MOV RDI,[InpBufferPtr] ; Button #2 (Bs).
MOV RSI,RDI
LEA RAX,[InpBuffer::]
CMP RDI,RAX
JNA .10:
MOV ECX,[LineSize]
ADD RCX,RAX
DEC RDI
MOV [InpBufferPtr],RDI
SUB RCX,RSI
REP MOVSB
JMP .10:
.0N42: ; Button #42 (=).
.0x0A: ; Key Enter.
.0x3D:MOV ECX,[LineSize] ; Key Equal =.
LEA RDI,[InpBuffer::]
ADD RDI,RCX
MOV AL,' '
STD
REPE SCASB
CLD
ADD RDI,3
MOVB [RDI],'='
JMP .70: ; Input terminated. Perform the calculation.
.0n3:Dispatch EAX,0x435B1B,0x445B1B,0x485B1B,0x465B1B
JMP .10:
.0x435B1B:
MOV RDI,[InpBufferPtr] ; Cursor right.
LEA RAX,[InpBuffer::]
MOV ECX,[LineSize]
ADD RAX,RCX
CMP RDI,RAX
JAE .10:
INC RDI
.30: MOV [InpBufferPtr],RDI
JMP .10:
.0x445B1B: ; Cursor left.
LEA RAX,[InpBuffer::]
CMP RDI,RAX
JNA .10:
DEC RDI
JMP .30:
.0x485B1B: ; Cursor Home.
LEA RDI,[InpBuffer::]
JMP .30:
.0x465B1B: ; Cursor End.
LEA RDI,[InpBuffer::]
MOV ECX,[LineSize]
LEA RDI,[RDI+RCX-1]
MOV AL,' '
STD
REPE SCASB
CLD
ADD RDI,2
JMP .30:
.0n4:Dispatch EAX,0x7E335B1B
JMP .10:
.0x7E335B1B: ; Key Delete.
MOV ECX,[LineSize]
LEA RAX,[InpBuffer::]
LEA RCX,[RAX+RCX-1]
MOV RDI,[InpBufferPtr]
LEA RSI,[RDI+1]
SUB RCX,RSI
REP MOVSB
JMP .10:
.35: CMP AL,27 ; Esc sequence longer than 4.
JNE .10:
CMPD [RSI+1],'[<0;' ; > Leftmouse button down. [<0;cc;rrm
JNE .10:
ADD RSI,5
XOR ECX,ECX ; Load the decimal column number cc to ECX.
XOR EAX,EAX
.40: LODSB
CALL .IsDigit?
JC .43:
LEA ECX,[4*ECX+ECX]
ADD ECX,ECX
ADD CL,AL
JMP .40:
.43: CMP AL,';'
JNE .10:
XOR EBX,EBX ; Load the decimal row number rr to EBX.
.47: LODSB
CALL .IsDigit?
JC .50:
LEA EBX,[4*EBX+EBX]
ADD EBX,EBX
ADD BL,AL
JMP .47:
.50: CMP AL,'m'
JNE .10:
CMP EBX,3
JNE .55:
LEA RAX,[InpBuffer::] ; Clicked at the input expression in row 3.
LEA RAX,[RAX+RCX-2]
MOV [InpBufferPtr],RAX
JMP .10:
.55: SHR ECX,3 ; RBX is row (1..47) and RCX is column (1..48).
MOV EAX,EBX ; Row number 7,8,9,,,27.
SUB EAX,7
JC .10:
MOV EDI,3 ; Divisor.
XOR EDX,EDX ; EDX:EAX is button row*3 (0,3,6,9,12,15,18).
DIV EDI
CMP EAX,6 ; EAX is the button-row number (0,1,2,3,4,5,6).
JA .10:
MOV EDI,6 ; Six columns of buttons.
MUL EDI
LEA EDX,[EAX+ECX+1] ; EDX=#1,#2,,,#42 is ordinal of the button.
Dispatch DL,0N1,0N2,0N42 ; Special buttons [ Clr ], [ Bs ], [ = ].
LEA RDI,[TitleBtns::] ; Otherwise clicked on ordinary button #3..#41.
XOR EAX,EAX
MOV ECX,-1
.60: REPNE SCASB
DEC EDX
JNZ .60:
MOV RSI,RDI
MOV RDI,[InpBufferPtr]
.45: LODSB
CMP AL,0
JE .65:
STOSB
JMP .45:
.65: MOV [InpBufferPtr],RDI
CALL .ClearResultLine:
JMP .10:
.70: CALL .ClearResultLine: ; Calculation of the input line.
LEA RSI,[InpBuffer::]
LEA RDI,[Pbuffer::]
CALL Parse:: ; Parse the ASCIIZ string at RSI.
MOV [PbufferEnd::],RDI ; Store numbers, parenthesis and functions to RDI=Pbuffer.
JNC .75:
StdOutput EscLineError,EscBaseColor,EscEnhColor, =B" Syntax error. "
JMP .10:
.75: LEA RSI,[Pbuffer::]
MOV RDX,[PbufferEnd::]
LEA RDI,[InpBuffer::]
CALL EchoExpression::
LEA RDI,[InpBuffer::]
MOV AL,'='
MOV ECX,[MainWidth]
SUB ECX,2
REPNE SCASB
MOV AL,' '
REP STOSB
SUB EAX,EAX
STOSB
LEA RDI,[InpBuffer::]
StdOutput EscLineInput,EscEditColor,RDI
LEA RSI,[Pbuffer::]
MOV RDX,[PbufferEnd::]
LEA RDI,[Nbuffer::]
CALL Deparent:: ; Remove parenthesis from N-records.
MOV [NbufferEnd::],RDI
JNC .80:
StdOutput EscLineError,EscBaseColor,EscEnhColor,=B" Unbalanced parenthesis. "
JMP .10:
.80: CALL Calculate:: ; Call procedures from calcmain.htm.
JNC .85:
StdOutput EscLineError,EscBaseColor,EscEnhColor,=B"Error in expression or division by 0."
JMP .10:
.85: CALL DisplayDecimalProxy::
LEA RSI,[OutBuffer::]
StdOutput EscResultColor,EscLineResult,RSI
LEA RAX,[InpBuffer::]
MOV [InpBufferPtr],RAX
JMP .20:
.ClearInputLine: PROC
LEA RDI,[InpBuffer::]
MOV ECX,[LineSize]
MOV RSI,RDI
MOV AL,' '
REP STOSB
StdOutput EscEditColor,EscLineInput,RSI,Size=RCX
RET
ENDP .ClearInputLine:
.ClearResultLine: PROC
LEA RDI,[OutBuffer::]
MOV ECX,[LineSize]
MOV RSI,RDI
MOV AL,' '
REP STOSB
StdOutput EscEditColor,EscLineResult
StdOutput RSI,Size=[LineSize]
RET
ENDP .ClearResultLine:
.IsDigit? PROC ; Return CF=1 when AL was not a digit, otherwise return value 0..9 in AL.
CMP AL,'0'
JC .9:
CMP AL,'9'+1
CMC
JC .9:
SUB AL,'0'
.9: RET
ENDP .IsDigit?
.0x1B: ; Key Esc - terminate program.
StdOutput EscDisableMouse,EscBaseColor,EscLine28
LEA RBX,[TermIO]
LinABI ioctl,0,TCGETS,RBX ; Load current local terminal status.
SetSt [RBX+TERMIO.c_lflag],ICANON+ECHO
LinABI ioctl,0,TCSETS,RBX ; Restore terminal echo.
TerminateProgram
ENDP MainGui
PaintWindow PROC
LinABI ioctl,0,TIOCGWINSZ,TtySize
MOVZXW EDX,[TtySize.ts_lines]
MOVZXW ECX,[TtySize.ts_cols]
MOV EAX,MinRows ; Minimal acceptable lines.
CMP EDX,EAX
JB .10:
MOV EAX,EDX
.10:LEA RDI,[ValResize]
StoD RDI
MOV AL,';'
STOSB
MOV EAX,MinCols ; Minimal acceptable columns.
CMP ECX,EAX
JB .20:
MOV EAX,ECX
.20:StoD RDI
MOV AX,'t'
STOSW
StdOutput EscResize
LinABI ioctl,0,TIOCGWINSZ,TtySize
MOVZXW EDX,[TtySize.ts_lines]
DEC EDX ; Reserve one low line for status.
MOV [MainHeight],EDX
MOVZXW ECX,[TtySize.ts_cols]
MOV [MainWidth],ECX
SUB ECX,2
MOV [LineSize],ECX
MOV EDI,[MainWidth] ; Start painting.
MOV EBX,EDI
MOV EAX,EDI
SUB EDI,2
LEA EDX,[2*EDI+EDI] ; Each Box2 has 3 bytes.
SUB EBX,48
SUB EAX,27
StdOutput EscLine1,EscBaseColor,Space1,EscEnhColor,EuroCalc,EscDimColor,Version::,Spaces,Size=RAX
StdOutput EscLineDown,EscBaseColor,Box2DR,Boxes2,Size=RDX,Box2DL
MOV ECX,2
.30:StdOutput EscLineDown,Box2V,EscEditColor,Spaces,Size=RDI,EscBaseColor,Box2V
LOOP .30:
StdOutput EscLineDown,Box2UR,Boxes2,Size=RDX,Box2UL
StdOutput EscLineDown,EscBaseColor,
MOV ECX,[MainWidth]
StdOutput Spaces,Size=RCX
LEA RDI,[TitleBtns::]
XOR EAX,EAX
MOV ECX,-1
MOV DH,7 ; Button rows.
.40:StdOutput EscLineDown, BoxDR,Boxes,Size=15,BoxDL,Space1,BoxDR,Boxes,BoxDL,Space1,BoxDR,Boxes,BoxDL, \
Space1,BoxDR,Boxes,BoxDL,Space1,BoxDR,Boxes,BoxDL,Space1,BoxDR,Boxes,BoxDL,Space1
StdOutput Spaces,Size=RBX
StdOutput EscLineDown
MOV DL,6 ; Button columns.
.50:REPNE SCASB ; RDI points at the ASCIIZ button title.
StdOutput BoxV,Space1
CMP [RDI+1],AL
JE .60:
CMP [RDI+2],AL
JE .70:
StdOutput RDI
JMP .80:
.60:StdOutput Space1,RDI,Space1
JMP .80:
.70:StdOutput Space1,RDI
.80:StdOutput Space1,BoxV,Space1
DEC DL
JNZ .50:
StdOutput Spaces,Size=RBX
StdOutput EscLineDown, BoxUR,Boxes,Size=15,BoxUL,Space1,BoxUR,Boxes,BoxUL,Space1,BoxUR,Boxes,BoxUL, \
Space1,BoxUR,Boxes,BoxUL,Space1,BoxUR,Boxes,BoxUL,Space1,BoxUR,Boxes,BoxUL,Space1
StdOutput Spaces,Size=RBX
DEC DH
JNZ .40:
RET
ENDP PaintWindow
DebugOutput proc StdOutput rsi,Size=rcx ret endp ENDPROGRAM calcling