| Index | Manual | Download | Source | Macros | Embedded word Case ins.
Sitemap | Links | Forum | Tests | Projects

# calcling.htm
Data
Data
Procedures
MainGui
PaintWindow

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

↑ Data

                                ; 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
  This is the graphic entry procedure which calls PaintWindow and then it reads mouse and keyboard from the terminal.
Called by
  MainCon.
Calls
  PaintWindow.

    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
  Procedure PaintWindow resizes the terminal window when it is too small and then it paints the entire window with lines for input expression, --> for the result and 6 * 7 buttons, using ANSI escape codes. -->
Called by
  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

▲Back to the top▲