EuroAssembler Index Manual Download Source Macros


Sitemap Links Forum Tests Projects

viewling.htm
Data
Data
Procedures
CreateLstIndex
FileIndexReopen
FileWriteOutput
Main
ReadFile_ini
SaveViewIndex
ViewEpilogue
ViewPrologue
WindowPaint
WindowProc
WindowResize
WindowTitle

This is a GUI module of EuroTool program EuroView for Linux.


         EUROASM CPU=X64, Unicode=No, DumpWidth=36
viewling PROGRAM Format=COFF, Width=64
           %DROPMACRO *
           INCLUDEHEAD argument.htm, viewmain.htm
           INCLUDE linabi.htm, cpuext64.htm, cpuext.htm, linsfile.htm, linf64.htm, \
                   ansi.htm,string64.htm, memory64.htm, time.htm, status32.htm
[.rodata]          ; Constant data.
Help:
 DB "EuroView version %^DATE",10,10
 DB " designed to inspect binary, object, library,",10
 DB "  executable etc ""InputFile"":",9,9,"./euroview.x ""InputFile""",10,10
 DB " It also accepts arguments from the command-line or from /etc/eurotool/euroview.ini:",10
 DB 9,"-InputFile=       ",9,9,"Input file name to be inspected (alternative notation).",10
 DB 9,"-FileFormat=      ",9,9,"Default is Autodetect. /FF=? for the list of accepted formats.",10
 DB 9,"-OutputFile=      ",9,9,"Temporary file; default is ""/tmp/InputFile.lst"".",10
 DB 9,"-LeaveTemporary=no",9,9,"Do not erase OutputFile when EuroView terminates.",10,10
 DB " Accepted file formats:",,10
 %i %SETA 1
 %WHILE "%FileFormats{%i}"
 DB 9,"%FileFormats{%i+0}"
 DB 9,"%FileFormats{%i+1}"
 DB 9,"%FileFormats{%i+2}"
 DB 9,"%FileFormats{%i+3}"
 DB 9,"%FileFormats{%i+4}"
 DB 9,"%FileFormats{%i+5}"
 DB 10
 %i %SETA %i+6
 %ENDWHILE
 DB 10," Keys:",10
 DB 9,"Tab | Left button",9,9,"decrease nesting level (more detailed)",10
 DB 9,"Shift Tab | Right button",9,"increase nesting level (more compact)",10
 DB 9,"Home",9,9,9,9,"beginning of the document",10
 DB 9,"End",9,9,9,9,"end of the document",10
 DB 9,"PgUp | PgDn",9,9,9,"page up | down",10
 DB 9,"Up | Dn | mouse wheel",9,9,"line up | down",10
 DB 9,"Esc",9,9,9,9,"quit the program",10
 DB 0
FormatNames:
FF %FOR %FileFormats
     DB "%FF",0
   %ENDFOR FF
EndFormatNames:
Spaces            DB NAME_MAX * 2 * BYTE ' '
[.data]           ; Variable data.
ValResize         DB 'xxxxxxxxx'  ; Replaced by '24;150t',0
ScrollSlider      DB 0xE2,0x96,0x88,0xE2,0x96,0x88,0   ; 2 * FULL BLOCK.
ScrollBar         DB 0xE2,0x96,0x92,0xE2,0x96,0x92,0   ; 2 * MEDIUM SHADE.
[.bss]       ; Working memory variables.
File_ini          DS FILE64 ; Configuration FILE64.
FileInput         DS FILE64 ;  Input FILE64.
FileOutput        DS FILE64 ; Output FILE64.lst in ASCII.
FileIndex         DS FILE64 ; Temporary FILE64.lst.index with VIEW_INDEX records.
TtySize           DS TTYSIZE
TermIO::          DS TERMIO
LstIndex:         DS LST_INDEX
TermWidth         DD DWORD
TermHeight        DD DWORD ; Number of rows in the terminal window.
DirHeight         DD DWORD ; Number of rows in the directory window, without borders.
Level             DD DWORD ; What level of headers to display (0..4).
LevelPrevious     DD DWORD ; Used to test the change of Level.
ListPos           DD DWORD ; Ordinal of the listing line displayed in the top row of the window.
ListMax           DD DWORD ; Number of rows in the listing.
KeyBuffer         DB 32 * BYTE
[.text]
Main
Program entry.
Main:: PROC
    StdOutput EuroView::, Version::, Eol=yes
   ; Try to load arguments from the configuration file /etc/eurotool/euroview.ini.
    FileAssign File_ini,=B'/etc/eurotool/euroview.ini'
    FileExists? File_ini
    JNC .20:
    CALL ReadFile_ini
.20:MOV EAX,[ArgNr::]        ; Read arguments from the command-line.
    INC EAX
    MOV [ArgNr::],EAX
    GetArg RAX, Frame=RSP    ; Returns the line in RSI,RCX with one argument, e. g. -IF="~/file.obj"
    JC .40:                  ; If there're no more arguments.
    CALL ArgParse::          ; Use ArgParse to translate it to a public symbol Arg***.
    JNC .20:
    StdOutput ErrorMessage::
    JMP ErrorHelp:
.40:LEA RSI,[ArgInputFile::]
    CMPB [RSI],0
    JZ ErrorHelp:
    LEA RBX,[FileInput]
    FileAssign RBX,RSI
    FileExists? RBX
    JNC .50:
    LEA RSI,[RBX+FILE64.Name]
    StdOutput =B"File """,RSI,=B""" was not found.",Eol=yes
    TerminateProgram 4
.50:; Input file was specified.
    ; Create level buffers.
    BufferCreate Size=256K
    JC ErrorAlloc:
    MOV [Level0Buffer::],RAX
lvl %FOR 1..4
      BufferCreate Size=64K
      JC ErrorAlloc:
      MOV [Level%lvl{}Buffer::],RAX
    %ENDFOR
    LEA RAX,[FileIndexReopen:]
    MOV [FileIndexReopenProc::],RAX
    LEA RAX,[FileWriteOutput:]
    MOV [FileWriteOutputProc::],RAX
    MOVD [Level],0
    MOVD [ListPos],1
    CALL ViewPrologue
    CALL ViewCreate::                  ; External procedure in viewmain.htm.
    CALL ViewEpilogue
    CALL WindowResize
    CALL WindowPaint
    CALL WindowProc
    FileClose FileOutput, FileIndex
    JSt [Status::],ArgLeaveTemporary,.90:
    FileDelete FileOutput, FileIndex
.90:TerminateProgram
   ENDP Main::
FileIndexReopen
OS dependent proxy function.
FileIndexReopen: PROC
    LEA RBX,[FileIndex]
    FileClose RBX
    FileMapCreate RBX                ; Reopen and sort FileIndex. Returns the contents in RDI,RAX.
    JC ErrorFileIndex:
    RET
  ENDP FileIndexReopen:
FileWriteOutput
OS dependent proxy function.
FileWriteOutput: PROC
    FileWrite FileOutput,RSI,RCX
    JC ErrorFileOutput:
    RET
  ENDP FileWriteOutput:
SaveViewIndex
Global Linux procedure SaveViewIndex is called from analyzing and formating procedures in the OS-independet module viewmain.htm.
It will store the external structured variable ViewIndex:: to FileIndex, keep its .Size, add .Size to .FA, clear .Level and .Rem in this vairable.
Input
RBX=pointer to VIEW_INDEX variable, usually to ViewIndex::.
FileIndex is a created file.
Output
RAX=0.
RBX= is kept as a pointer to VIEW_INDEX variable.
[RBX+VIEW_INDEX.FA] is incremented by the previous [RBX+VIEW_INDEX.Size] when .Level=0.
[RBX+VIEW_INDEX.Size] is kept, but .Level bits are cleared.
[RBX+VIEW_INDEX.Rem] is cleared.
Clobbers
RAX
SaveViewIndex:: PROC
    PUSH RCX
     FileWrite FileIndex, RBX, 16
     MOV EAX,[RBX+VIEW_INDEX.Size]
     MOV ECX,EAX
     AND EAX,0x0FFF_FFFF                ; Get rid of Level bits.
     MOV [RBX+VIEW_INDEX.Size],EAX      ; Keep .Size unchanged for the next element.
     SHR ECX,28                         ; Isolate level.
     JNZ .50:
     ADD [RBX+VIEW_INDEX.FA],EAX        ; Add previous .Size to this .FA, but keep .FA unchanged when .Level >0.
.50: XOR EAX,EAX
     MOV [RBX+VIEW_INDEX.Rem],RAX       ; Always clear .Rem field.
    POP RCX
    RET
   ENDP SaveViewIndex::
WindowResize
Procedure WindowResize resizes the terminal window when it is too small and the it paints the entire window.
WindowResize PROC
    LinABI ioctl,0,TIOCGWINSZ,TtySize
    MOVZXW EDX,[TtySize.ts_lines]
    MOVZXW ECX,[TtySize.ts_cols]
    MOV EAX,20               ; Minimal acceptable lines.
    CMP EDX,EAX
    JB .10:
    MOV EAX,EDX
.10:LEA RDI,[ValResize]
    StoD RDI
    MOV AL,';'
    STOSB
    MOV EAX,150              ; Minimal acceptable columns.
    CMP ECX,EAX
    JB .13:
    MOV EAX,ECX
.13:StoD RDI
    MOV AX,'t'
    STOSW
    LinABI ioctl,0,TIOCGWINSZ,TtySize
    MOVZXW EDX,[TtySize.ts_lines]
    MOV [TermHeight],EDX
    MOVZXW ECX,[TtySize.ts_cols]
    MOV [TermWidth],ECX
    RET
 ENDP WindowResize
ReadFile_ini
Procedure ReadFile_ini reads lines from File_ini in UTF-8 and parses its each line into configuration variables Arg*** in UTF-8, too.
Input
File_ini is assigned with the name.
Clobbers
RAX,RCX,RDX,RSI,RDI
ReadFile_ini:: PROC
    SetSt [Status::],ArgFromFile       ; Tell ArgParse that arguments may not begin with / or -.
    LEA RDI,[WorkMemory::]
    Concat$ RDI, RDI,=B'Configuration "',File_ini.Name,=B'"'
.10:FileStreamOpen File_ini,BufSize=4K
    JNC .20:
    Concat$ RDI,RDI,=B'" was not found.',=B(10)
    JMP .90:
.20:FileStreamReadLn File_ini
    JBE .80:
    MOV ECX,EAX
    ; The first line may begin with BOM.
    MOV AX,[RSI]
    CMPW AX,0xBBEF   ; UTF-8 BOM?
    JNE .50:
    ADD RSI,3        ; Skip the BOM.
    SUB ECX,3
    JB .80:
    JMP .50:
.30:FileStreamReadLn File_ini
    JBE .80:
    MOV ECX,EAX
.50:CALL ArgParse::
    JNC .30:
    StdOutput ErrorMessage::, Help
    TerminateProgram 8
.80:FileClose File_ini
    LEA RDI,[WorkMemory::]
    Concat$ RDI,RDI,=B'" was accepted.',=B(10)
.90:RstSt [Status::],ArgFromFile
    RET
  ENDP ReadFile_ini
ViewPrologue
Linux function which will read ArgInputFile, memory-map it to InputPtr..InputEnd, then create files FileOutput and FileIndex with filenames ArgOutputFile (if not empty) or /tmp/ArgInputFileName.lst, /tmp/ArgInputFileName.lst.index (if ArgOutputFile= is empty).
Input
ArgInputFile, ArgOutputFile, ArgFileFormat
Output
CF=0, ArgOutputFile, ArgFileFormat (detected), FileOutput, FileIndex.
Error
ErrorFile*
ViewPrologue: PROC
    LEA RSI,[ArgInputFile::]           ; Memory-map FileInput.
    CMPB [RSI],0
    JZ ErrorFileInput:
    LEA RBX,[FileInput]
    FileAssign RBX,RSI
    FileMapOpen RBX
    JC ErrorFileInput:
    MOV [InputPtr::],RSI
    MOV [InputSize::],RAX
    LEA RDX,[RSI+RAX]
    MOV [InputEnd::],RDX
    BSR ECX,EAX
    MOV EDX,4
    ADD ECX,EDX
    SHR ECX,2
    CMP ECX,EDX                        ; Number of address digits (4..8) in listing.
    JA .10:
    MOV ECX,EDX
.10:MOV [AddressDigits::],ECX
    MOV EDX,[ArgFileFormat::]          ; Find file format.
    TEST EDX
    JNZ .20:
    CALL AutodetectFileFormat::
    MOV [FormatProcPtr::],RAX          ; FormatELF32, FormatBIN etc.
    MOV [ArgFileFormat::],ECX          ; Ordinal format number.
.20:XOR EDI,EDI
    MOV EDX,[ArgFileFormat::]          ; Set by AutodetectFormat or by cmd-line argument.
    LEA RDI,[FormatNames:]             ; Find the format uppercase name.
    MOV ECX,EndFormatNames-FormatNames
    XOR EAX,EAX
.25:DEC EDX
    JZ .28:
    REPNE SCASB
    JMP .25:
.28:MOV [FormatNamePtr::],RDI
    LEA RBX,[FileOutput]
    LEA RSI,[ArgOutputFile::]
    CMPB [RSI],0
    JZ .30:
    FileAssign RBX,RSI
    JC ErrorFileOutput:
    JMP .40:
.30:; If ArgOutputFile is not specified (default), use /tmp/ and filename without path for temporary names.
    LEA RSI,[FileInput.Name]
    MOV EAX,[FileInput.NameOffs]
    ADD RSI,RAX
    FileAssign RBX,=B"/tmp/",RSI,=b".lst"
.40:FileCreate RBX
    JC ErrorFileOutput:
    LEA RSI,[RBX+FILE64.Name]
    FileAssign FileIndex, RSI, =B".index"
    FileCreate FileIndex
    JC ErrorFileIndex
    RET
   ENDP ViewPrologue
ViewEpilogue
Windows function which will convert indexes written to FileIndex to listing lines and store the lines to FileOutput. Then it will close FileInput and FileIndex, reopen FileOutput, memory-map it to OutputPtr..OutputEnd, sort it, store indexes of listing lines to LevelnBuffer.
Input
OutputPtr..OutputEnd
Output
CF=0LevelnBuffer (n=0..4)
Error
CF=1
ViewEpilogue:: PROC
     FileClose FileOutput, FileIndex
     FileMapOpen FileOutput
     JC ErrorFileOutput
     MOV [OutputPtr::],RSI
     MOV [OutputSize::],RAX
     ADD RAX,RSI
     MOV [OutputEnd::],RAX
     FileMapOpen FileIndex
     JC ErrorFileIndex
     MOV [IndexPtr::],RSI
     ADD RSI,RAX
     MOV [IndexEnd::],RSI
     SHR EAX,4
     MOV [ListMax],EAX
     CALL CreateLstIndex::   ; Toss the index to five memory buffers for levels 0..4.
     MOVD [Level],0
     MOVD [ListPos],1
     RET
  ENDP ViewEpilogue
WindowPaint
Linux function WindowPaint will paint the entire terminal window with its title and with the partial contents of ListMax rows of the listing file (FileOutput).

The following example shows the listing with ListMax=22 rows, viewed by the terminal window with TermHeight=11 rows.
First line in terminal (title row) is fixed, it shows the program name, file format, nesting level (0..4) and filename, for instance EuroView ELF32 0 "file.o".
Vertical position of the displayed part of listing in the terminal window is specified by ListPos, which is the ordinal number of this listing row, which is displayed in terminal row 1 (just below the title row).

Cursor keys and mouse wheel manipulate only with this variable ListPos, it is saturated to 0..ListMax.

The last column in terminal window is dedicated to scroll box. The height of its slider is ScrollHeight=(TermHeight-1)*(TermHeight-1)/ListMax=10*10/22=4 saturated to 1..TermHeight-1=1..10.
Position of the topmost character of the slider is ScrollPos=(TermHeight-1)*(ListPos)/(ListMax)+1=10*7/22+1=4, saturated to 1..TermHeight-1=1..10.

Listing contains ASCII characters only, no UTF-8.

┌──────────────────────────────┐ │ListRow=1 │ │ListRow=2 │ │ListRow=3 │ │ListRow=4 │ ╔════════════════════════╗ │ ║░EuroView░FF░L░"file"░░░║<title ║ListRow=7 TermRow=1 ▒║ │ ║ListRow=8 TermRow=2 ▒║ │ ║ListRow=9 TermRow=3 █║┐<─3 │ ║ListRow=10 TermRow=4 █║│ │ ║ListRow=11 TermRow=5 █║├──4 │ ║ListRow=12 TermRow=6 █║┘ │ ║ListRow=13 TermRow=7 ▒║ │ ║ListRow=14 TermRow=8 ▒║ │ ║ListRow=15 TermRow=9 ▒║ │ ║ListRow=16 TermRow=10 ▒║ │ ╚════════════════════════╝ │ │ListRow=18 │ │ListRow=19 │ │ListRow=20 │ │ListRow=21 │ │ListRow=22 │ └──────────────────────────────┘ TermHeight=11, ListMax=22, ListPos=7, ScrollPos=3, ScrollHeight=4.
Input
[ListPos], [ListMax], [Level], [LevelXBuffer], [OutputPtr]..[OutputEnd], [IndexPtr]..[IndexEnd]
Output
Terminal window is painted.
WindowPaint PROC
    CALL WindowTitle
    StdOutput AnsiClrFg000000
    MOV R12,[OutputPtr::]
    MOV EAX,[Level]
    MOV EDX,[LevelPrevious]
    CMP EAX,EDX
    MOV [LevelPrevious],EAX
    JE .40:
    JB .30:
    ; Level is increasing from EDX to EAX. Calculate the new value of LinePos.
    ADD R12,RAX              ; Position of '#' in output line.
    BufferRetrieve [8*RDX+Level0Buffer::] ; Let RSI,RCX point to old LST_INDEX records.
    XOR EDX,EDX
    MOV EDI,[ListPos]
    TEST EDI
    JZ .15:
.10:DEC EDI
    JZ .20:
.15:LODSD                    ; EAX=LST_INDEX.FA
    CMPB [R12+RAX],'#'       ; Is the line in new level?
    LODSD                    ; Skip LST_INDEX.Size
    JNE .10:
    INC EDX                  ; The next row.
    JMP .10:
.20:TEST EDX
    JNZ .25:
    INC EDX
.25:MOV [ListPos],EDX        ; The new position is calculated.
    JMP .40:
.30:; Level is decreasing form EDX to EAX. Calculate the new value of LinePos.
    ADD R12,RDX
    BufferRetrieve [8*RAX+Level0Buffer::] ; Let RSI,RCX point to new LST_INDEX records.
    SHR ECX,3
    JZ .90:
    XOR EDI,EDI              ; Line counter in new buffer.
    MOV EDX,[ListPos]
.35:INC EDI
    LODSD                    ; EAX=LST_INDEX.FA
    CMPB [R12+RAX],'#'
    LODSD                    ; Skip LST_INDEX.Size
    JNE .35:
    DEC EDX
    JNZ .35:
    MOV [ListPos],EDI        ; The new position is calculated.
  ;;  JMP .40:
.40:; Level is unchanged or adjusted.
    MOV EAX,[Level]
    BufferRetrieve [8*RAX+Level0Buffer::] ; Let RSI,RCX point to LST_INDEX records.
    LEA R9,[RSI+RCX]         ; R9=behind the last LST_INDEX record.
    SHR ECX,3                ; SIZE# LST_INDEX = 8.
    MOV [ListMax],ECX
    MOV EDX,[ListPos]
    TEST EDX
    JZ .45:
    DEC EDX
.45:LEA RBX,[RSI+8*RDX]      ; RBX = pointer to LST_INDEX of ListPos-th record.
    MOV EDX,2                ; RDX=Terminal row (2,3,,,TerminalHeight-1).
.50:; The loop for terminal lines.
    MOV RAX,RDX              ; Terminal row number.
    LEA RDI,[AnsiAtRowCol+2]
    StoD RDI
    MOV EAX,';1H'
    STOSD                    ; AnsiAtRowCol is prepared to move the cursor to row RDX, col 1.
    StdOutput AnsiAtRowCol   ; Make the position in terminal at column 1 of row RDX.
    SUB ECX,ECX
    MOV R13D,[TermWidth]
    DEC R13                  ; Decrease TermWidth due to ScrolBox.
    CMP RBX,R9               ; At end of LST_INDEX?
    JNB .57:
    MOV ESI,[RBX+LST_INDEX.FA]
    MOV ECX,[RBX+LST_INDEX.Size]
    ADD RSI,[OutputPtr::]
    CMP RCX,R13
    JBE .57:
    MOV RCX,R13              ; Line is long, its size will be RCX=TermWidth.  Number of spaces will be R13=0
    SUB R13,R13
    JMP .60:
.57:SUB R13,RCX              ; Line is short, its size will be RCX. Number of spaces will be R13.
.60:CALL .RowPaint           ; RSI,RCX is the contents of the listing row. Size of following spaces is R13.
    ADD RBX,SIZE# LST_INDEX
    INC RDX
    CMP EDX,[TermHeight]
    JB  .50:

    ; Scroll box.
     MOV EDI,[TermHeight]     ; Calculate ScrollHeight.
    DEC EDI
    MOV EAX,EDI
    MUL RAX
    MOV ECX,[ListMax]
    TEST ECX
    JZ .90:
    DIV RCX
    CMP EAX,0                ; Saturate ScrollHeight.
    JA  .63:
    MOV EAX,1
.63:CMP EAX,EDI
    JNA .67:
    MOV EAX,EDI
.67:MOV ESI,EAX              ; Let ESI=ScrollHeight.
    MOV EAX,[ListPos]        ; Calculate ScrollPos.
    MUL RDI                  ; RDI=TermHeight-1.
    MOV ECX,[ListMax]
    DIV RCX
    INC EAX
    CMP EAX,EDI              ; Saturate ScrollPos.
    JNA .70:
    MOV EAX,EDI
.70:MOV EDX,EAX              ; EDX=ScrollPos, ESI=ScrollHeight.
    ADD ESI,EDX              ; ESI=position below the slider.
    MOV EBX,[TermHeight]
    DEC EBX
    XOR ECX,ECX              ; Row counter.
    INC ECX
.75:INC ECX                  ; Paint the scrollbox at row ECX.
    CMP ECX,EBX
    JA .90:
    LEA RDI,[AnsiAtRowCol+2]
    MOV EAX,ECX
    StoD RDI                 ; Row 2..TermHeight.
    MOV AL,';'
    STOSB
    MOV EAX,[TermWidth]
    DEC EAX
    StoD RDI
    MOV AX,'H'
    STOSW
    StdOutput AnsiAtRowCol   ; Cursor is set at row ECX.
    CMP ECX,EDX
    JAE .85:
.80:StdOutput AnsiClrBgFEFEFF,ScrollBar
    JMP .75:
.85:CMP ECX,ESI
    JA .80:
    StdOutput AnsiClrBgFEFEFF,ScrollSlider
    JMP .75:
.90:RET

.RowPaint PROC ; Print a row at cursor position in column 1.
; The row looks like
; "|dump      | Remark in level0           Spaces"  or
; "!###   range ##### Name of the level3   Spaces"
; Input: RSI,RCX is the listing row (without CR+LF). RCX is never above TermWidth. R13 is the number of spaces.
; When the Remark or Name does not fit to TermWidth, it is shortened.
    TEST RCX
    JZ .8:
    LEA RDI,[RSI+1]
    MOV AL,'#'
    CMP [RDI],AL
    JE .3:                   ; Jump when this row represents a colored level row (it starts with pipe+hash).
    StdOutput AnsiClrBgC0C0C0; No, it is and ordinary Level0 row with a dump. Paint in gray.
    MOV AL,'|'
    MOV R8,RCX
    REPNE SCASB              ; Find the second pipe '|' which terminates the dump.
    DEC RDI
    SUB RDI,RSI              ; RDI is the dump size.
    StdOutput RSI,Size=RDI   ; Paint the dump. It is always displayed as unshorten.
    ADD RSI,RDI              ; RSI points to the start of the listing remark.
    MOV RCX,R8               ; Restore RCX.
    SUB RCX,RDI
    JNA .9:
    StdOutput AnsiClrBgFFFFD0 ; Paint in yellowish colour.
    JMP .7:
.3: LEA RDI,[AnsiClrBgD0D0FF]
    CMP [RSI+4],AL
    JE .5:
    LEA RDI,[AnsiClrBgFFD0D0]
    CMP [RSI+3],AL
    JE .5:
    LEA RDI,[AnsiClrBgFFFF30]
    CMP [RSI+2],AL
    JE .5:
    LEA RDI,[AnsiClrBgD0FFD0]
.5  StdOutput RDI            ; Color1..4.
.7: StdOutput RSI,Size=RCX   ; Paint the level row.
.8: StdOutput Spaces,Size=R13
    StdOutput AnsiClrBgC0C0C0
.9:RET
  ENDP .RowPaint
 ENDP WindowPaint
WindowTitle
Construct terminal window one line title which contains EuroView FF L "file".
Input
[FormatNamePtr::], [Level], ArgInputFile::
Output
Title line is written to the terminal window.
WindowTitle PROC
    LEA RDI,[WorkMemory::]     ; Title is constructed in WorkMemory.
    MOV RDX,RDI
    MOV AX,'  '
    STOSW
    LEA RSI,[EuroView::]
    MOV ECX,8
    REP MOVSB
    MOV AX,' "'
    STOSW
    LEA RSI,[ArgInputFile::]
.10:LODSB
    CMP AL,0
    JE .20:
    STOSB
    JMP .10:
.20:MOV AL,'"'
    STOSB
    MOV EAX,' as '
    STOSD
    MOV RSI,[FormatNamePtr::]
    TEST RSI
    JZ .50:
.30:LODSB
    CMP AL,0
    JE .40:
    STOSB
    JMP .30:
.40:LEA RSI,[=B' level ']
    MOV CL,7
    REP MOVSB
    MOV AX,'0'
    OR AL,[Level]
    STOSW
.50:MOVD [AnsiAtRowCol+2],'1;1H'
    MOVB [AnsiAtRowCol+6],0
    StdOutput AnsiClrBgFFFFFF,AnsiClrFg800000,AnsiAtRowCol
    GetLengthUTF8 RDX
    MOV ESI,[TermWidth]
    CMP ECX,ESI
    JBE .60:
    StdOutput RDX,Size=RSI
    JMP .90:
.60:StdOutput RDX,Size=RCX
    SUB ESI,ECX
    StdOutput Spaces,Size=RSI
.90:RET
  ENDP WindowTitle
WindowProc
This procedure reads the keyboard and mouse and manipulates with ListPos
WindowProc PROC
    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.
    StdOutput AnsiMouseEnable
    JMP .ReadKeyboard:
.Resized:
    CALL WindowResize
    CALL WindowPaint
    MOV EBX,[ListPos]
    JMP .Saturate:
.ReadKeyboard:
    LinABI ioctl,0,TIOCGWINSZ,TtySize  ; Check if terminal dimension changed.
    MOVZXW EDX,[TtySize.ts_lines]
    MOVZXW ECX,[TtySize.ts_cols]
    CMP EDX,[TermHeight]
    JNE .Resized:
    CMP ECX,[TermWidth]
    JNE .Resized:
    XOR EDI,EDI                        ; Read the keyboard in the main window.
    LEA RSI,[KeyBuffer]
    MOV R8,RSI
    MOV [RSI],RDI
    MOV EDX,SIZE# KeyBuffer
    LinABI read,RDI,RSI,RDX
    TEST EAX
    JNA .ReadKeyboard:
    XOR ECX,ECX
    MOV EBX,[ListPos::]
key %FOR AnsiKeyCtrlHome,AnsiKeyCtrlEnd,AnsiKeyPgUp,AnsiKeyPgDn,AnsiKeyUp,AnsiKeyDn, \  Read the keyboard.
         AnsiKeyHome,AnsiKeyEnd,AnsiKeyShiftTab,AnsiKeyTab,AnsiKeyEscape
       LEA RDI,[%key]
       MOV CL,SIZE# %key
       MOV RSI,R8
       REPE CMPSB
       JE .%key:
    %ENDFOR key
    MOV RSI,R8               ; Read the mouse.
    LODSW
    CMP AX,0x5B1B            ; Esc [
    JNE .ReadKeyboard:
    LODSB
    CMP AL,0x3C              ; Less-than?
    JNE .ReadKeyboard:
    LodD                     ; Mouse button.
    JC  .ReadKeyboard:
    DEC EBX                  ; ListPos.
    CMP AL,64                ; Scroll wheel up?
    JE .Saturate:
    ADD EBX,1+1
    CMP AL,65                ; Scroll wheel down?
    JE .Saturate:
    MOV ECX,EAX              ; Not scrolled. CL=0 for left button; CL=2 for right button.
    LODSB
    CMP AL,';'
    JNE .ReadKeyboard:
    LodD
    JC .ReadKeyboard:
    MOV EBX,EAX              ; X-coordinate of mouse cursor.
    SHL EBX,16
    LODSB
    CMP AL,';'
    JNE .ReadKeyboard:
    LodD
    JC .ReadKeyboard:
    MOV BX,AX                ; Y-coordinate of mouse cursor.
    LODSB
    CMP AL,'m'
    JNE .ReadKeyboard:
    ; Mouse cursor coordinates are in EBX. Row number is in BX, button in CL.
    MOV EDX,EBX
    SHR EDX,16
    MOV EAX,[TermWidth]
    SUB EAX,3
    CMP DX,AX
    JA .Scroll:
    CMP CL,0
    JE .MouseLeftButton:
    CMP CL,2
    JE .MouseRightButton:
    JMP .ReadKeyboard:
.Scroll:                       ; Clicked at scroll box, row BX. Level is not influenced by mouse buttons.
    MOVZX EAX,BX
    TEST EAX
    JZ .30:
    DEC EAX
.30:MOV ECX,[ListMax]
    MUL RCX
    MOV ECX,[TermHeight]
    DIV RCX
    MOV [ListPos],EAX
    CALL WindowPaint
    JMP .ReadKeyboard:
.AnsiKeyUp:
    DEC EBX
.Saturate:TEST EBX
    JNS .60:
    SUB EBX,EBX
.60:CMP EBX,[ListMax]
    JB .70:
    MOV EBX,[ListMax]
.70:TEST EBX
    JNZ .75:
    INC EBX
.75:MOV [ListPos],EBX
    CALL WindowPaint
    JMP .ReadKeyboard:
.AnsiKeyDn:
    INC EBX
    JMP .Saturate:
.AnsiKeyPgUp:
    SUB EBX,[TermHeight]
    ADD EBX,2
    JMP .Saturate:
.AnsiKeyPgDn:
    ADD EBX,[TermHeight]
    SUB EBX,2
    JMP .Saturate:
.AnsiKeyCtrlHome:
.AnsiKeyHome:
    MOV EBX,0
    JMP .Saturate:
.AnsiKeyCtrlEnd:
.AnsiKeyEnd:
    MOV EBX,[ListMax::]
    SUB EBX,[DirHeight]
    ADD EBX,2
    JMP .Saturate:

.MouseRightButton:                     ; Increase level.
.AnsiKeyShiftTab:                      ; Shift Tab pressed.
    MOV EAX,[Level]
    CMP AL,4
    JAE .ReadKeyboard:
    INC AL
.80:MOV [Level],EAX
    CALL WindowPaint
    JMP .ReadKeyboard:
.MouseLeftButton:                      ; Decrease level.
.AnsiKeyTab:                           ; Tab pressed.
    MOV EAX,[Level]
    CMP EAX,0
    JLE .ReadKeyboard:
    DEC AL
    JMP .80:

ErrorHelp:
     StdOutput Help:,Eol=yes
     TerminateProgram 8
ErrorFileOutput:
     LEA RSI,[FileOutput.Name]
     JMP ErrorFile:
ErrorFileInput:
     LEA RSI,[FileInput.Name]
     JMP ErrorFile:
ErrorFileIndex:
     LEA RSI,[FileOutput.Name]
ErrorFile:
     StdOutput =B'Error in file "',RSI,=U'"',Eol=yes
     JMP .AnsiKeyEscape:
ErrorAlloc::
     StdOutput =B"Error on memory allocation.",Eol=yes
    JMP .AnsiKeyEscape:

.AnsiKeyEscape:
    FileClose FileInput, FileOutput, FileIndex
    LEA RBX,[TermIO]
    LinABI ioctl,0,TCGETS,RBX          ; Get current terminal echo.
    SetSt [RBX+TERMIO.c_lflag],ICANON+ECHO
    LinABI ioctl,0,TCSETS,RBX          ; Restore terminal echo.
    RET
 ENDP WindowProc
CreateLstIndex
This procedure will clear BUFFERs for each level (0..4) and then it will index the listing file (OutputPtr..OutputEnd) into those buffers.
Buffers contain records in the form of LST_INDEX.
Input
OutputPtr..OutputEnd is the listing mapped in memory.
Output
CF=0, LstIndex is an empty variable of LST_INDEX structure which was saved to buffers.
ListingLines is filled with the total number of lines in the listing.
Error
CF=1 allocation error.
CreateLstIndex: PROC
    BufferClear [Level0Buffer::],[Level1Buffer::],[Level2Buffer::],[Level3Buffer::],[Level4Buffer::]
    MOV RBX,[OutputPtr::]              ; Start of the listing in memory.
    XOR ECX,ECX
    MOV AL,10
    DEC RCX
    MOV RDX,RBX
.10:MOV RDI,RDX
    CMP RDI,[OutputEnd::]
    JNB .80:
    MOV RSI,RDI
    REPNE SCASB                        ; Find the end of line.
    MOV RDX,RDI
    SUB RDI,RSI                        ; Size.
    SUB RSI,RBX                        ; FA.
    SUB EDI,2                          ; Omit CR+LF.
    MOV [LstIndex.FA],ESI
    MOV [LstIndex.Size],EDI
    BufferStore [Level0Buffer::],LstIndex,SIZE# LstIndex
    JC ErrorAlloc::
    CMPB [RBX+RSI+1],'#'               ; Is the line in Level1?
    JNE .10:
    BufferStore [Level1Buffer::],LstIndex,SIZE# LstIndex
    JC ErrorAlloc::
    CMPW [RBX+RSI+1],'##'              ; Is the line in Level2?
    JNE .10:
    BufferStore [Level2Buffer::],LstIndex,SIZE# LstIndex
    CMPB [RBX+RSI+3],'#'               ; Is the line in Level3?
    JNE .10:
    BufferStore [Level3Buffer::],LstIndex,SIZE# LstIndex
    CMPD [RBX+RSI+1],'####'            ; Is the line in Level4?
    JNE .10:
    BufferStore [Level4Buffer::],LstIndex,SIZE# LstIndex
    JMP .10:
.80:BufferRetrieve [Level0Buffer::]
    SHR ECX,3                          ; SIZE# LstIndex = 8
    MOV [ListingLines::],ECX
    CLC
    RET
   ENDP CreateLstIndex
  ENDPROGRAM viewling

▲Back to the top▲