📄 e3.asm_base_for_e3c
字号:
inc esi ;set esi>ebp will later trigger "ja FillLine" jmp short ELZ2 ELZ6: lodsb cmp al,TABCHAR jnz ELZ3 call SpacesForTab ;ah = space_up_to_next_tab location dec ah ;count out the tab char itself mov byte[tabcnt],ahELZ2: mov al,SPACECHARELZ3: cmp al,NEWLINE jz FillLine cmp al,SPACECHAR jae ELZ9 ;simply ignore chars like carriage_return etc. mov al,'.'ELZ9: cmp al,7fh jne ELZ8 mov al,'.'ELZ8: cmp bl,byte [columns] ;screen width jae DispEndLine ;continue reading line until end inc edx ;also count hidden chars (left margin) cmp edx,[zloffst] jbe ELZ5 ;load new char (but no display) stosB%ifdef CURSORMGNT clc call SetInverseStatus%endif inc bl ;counts displayed chars onlyELZ5: jmp DispCharLoop;-------FillLine:push ecx ;continue rest of line mov ecx,[columns] ;width sub cl,bl mov al,SPACECHAR ;fill with blanks jecxz FillLine2 cmp byte[inverse],1 ;special cursor attribute? jnz FillLine1 stosB ;only 1st char with special attribute%ifdef CURSORMGNT clc call SetInverseStatus%endif dec ecx ;one char less jz FillLine2FillLine1:rep stosB ;store the rest blanksFillLine2:pop ecx mov byte[edi],0 call ScreenLineShow dec ecx jnz near DispNewLine mov edi,[fileptr] ;restore text pointer jmp RestKursPos;----------------------------------------------------------------------; three helper subroutines called by DispNewScreen ; dealing ESC sequences for character attributes;%ifdef LESSWRITEOPS_OR_CURSORMGNTSetInverseStatus:push ecx ;returns zero flag push esi mov ecx,boldlen jnc SIS1 cmp byte [insstat],1 stc jnz SIS4 mov byte[inverse],1 mov esi,reversevideoX add esi,[revvoff] ;switch between esc seq for linux or Xterm jmp short SIS2SIS1: cmp byte[inverse],1 jnz SIS3 mov byte[inverse],0SIS6: mov byte[isbold],0SIS5: mov esi,bold0SIS2: rep movsbSIS3: clcSIS4: pop esi pop ecx ret%endif;-------SetColor:push ecx ;expects cy flag:bold / nc:normal push esi call IsShowBlock jnc SCEsc1 cmp byte [isbold],1 ;never set bold if it is already bold jz SIS4 mov byte [isbold],1SCEsc2: mov esi,bold1 jmp short SIS2SCEsc1: cmp byte [isbold],0 ;ditto jz SIS4 jmp short SIS6;-------%ifdef LESSWRITEOPSSetColor2:push ecx push esi call IsShowBlock jnc SIS5 jmp short SCEsc2%endif;;-------; a little helper for SetColor* functions;IsShowBlock:cmp byte [showblock],0 je SBlock cmp dword [blockbegin],0 je SBlock cmp [blockbegin],esi ja SBlock cmp esi,[blockende] jb SB_retSBlock: clcSB_ret: push byte boldlen pop ecx ret;-------; this helper for DispNewScreen checks screen size before writing on screen; FIXME: adjusting edit screen resize works with xterm, but not with SVGATextMode;GetEditScreenSize:%ifdef BEOS mov ecx,800Ch ;TCGETA+13%else%ifdef LINUX mov ecx,5413h ;asm/ioctls.h: #define TIOCGWINSZ 0x5413%else mov ecx,40087468h%endif%endif mov edx,winsize call IOctlTerminal mov eax,[edx] ;each 16 bit lines,columns or eax,eax jnz noerr mov eax,0x00500018 ;i.e. (80<<16)+24 (assume 80x24)noerr: dec al ;without status line mov byte [lines],al shr eax,16 mov byte [columns],al ;columns > 255 are ignored... ret;----------------------------------------------------------------------;; LOWER LEVEL screen acces function (main +2 helpers); this function does write the line buffer to screen i.e. terminal;; at first 2 special entry points:WriteTwo:mov [screenline],ecxStatusLineShow:xor ecx,ecx ;0 for last line;ScreenLineShow:pusha ;expecting in ecx screen line counted from 0%ifdef LESSWRITEOPS mov eax,[columns] add eax,32 ;estimated max ESC sequences extra bytes (i.e. boldlen*X) mul ecx ;setting edx to 0 mov ebx,edx ;flag lea edi,[eax+screenbuffer]%else xor edx,edx %endif cld mov esi,screenlinesl3: lodsb inc edx ;count message length to write%ifdef LESSWRITEOPS cmp edi,screenbuffer_end ;never read/write beyond buffer jnb sl5 cmp al,[edi] jz sl4 mov [edi],alsl5: inc ebx ;set flag whether line need redrawingsl4: inc edi%endif or al,al jnz sl3 dec edx ;one too much%ifdef LESSWRITEOPS or ebx,ebx ;redraw ? jz NoWrite ;..no: quick exit%endif push edx xor edx,edx mov dh,byte [lines] sub dh,cl call sys_writeKP ;set cursor pos before writing the line pop edx push ecx mov eax,screencolors1 ;set bold yellow on blue call sys_writeSLColors ;special for status line (ecx==0) mov ecx,screenline ;second argument: pointer to message to write call WriteFile0 pop ecx mov eax,screencolors0 ;reset to b/w call sys_writeSLColors ;special for status line (ecx==0) mov edx,[kurspos2] call sys_writeKP ;restore old cursor posNoWrite:popa ret;-------; a helper for ScreenLineShow;sys_writeSLColors: jecxz syswSL ;do nothing if not in status line retsyswSL: pusha xchg eax,ecx ;parameter points to ESC-xxx color string mov edx,scolorslen call WriteFile0 popa ret ;----------------------------------------------------------------------;; getting line INPUT from terminal / UNDER CONSTRUCTION;; expecting pointer to message text in esi;InputStringWithMessage: call WriteMess9MakeLine mov ecx,optbuffer push byte optslen pop edx jmp short InputStringInputString0:call WriteMess9MakeLine mov edx,maxfilenamelen;; expecting input line buffer in ecx; expecting max count byte in edx; return length in eax, CY for empty string (or abort via ^U);InputString:push ecx push edi push dword [kurspos2] mov ebx,[columns] sub ebx,stdtxtlen cmp edx,ebx ;TODO enable some scrolling: jb IS8 ;not yet ready, so truncate at end of line mov edx,ebxIS8: xor ebx,ebx;;;; mov [bufptr],ecx mov edi,ecxIS0: push ebx push edx mov byte [kurspos2],bl ;colum add byte [kurspos2],stdtxtlen ;offset mov bl,byte[lines] ;line# mov byte [kurspos2+1],bl%ifdef LESSWRITEOPS mov byte [screenbuffer],0 ;switching off usage of buffer v0.7%endif call StatusLineShow call GetChar pop edx pop ebx cld cmp al,15h ;^U abort (WStar) jne IS9 xor ebx,ebx ;length 0 triggers CY flag jmp short IS1IS9: cmp al,NEWLINE je IS1 cmp al,8 ;^H (translated DEL) jne IS2 or ebx,ebx ;@left border? jz IS0 dec ebx dec edi mov al,SPACECHAR mov byte [ebx+screenline+stdtxtlen],al jmp short IS0;-------IS2: cmp al,SPACECHAR jb IS0 stosb mov byte [ebx+screenline+stdtxtlen],al ;ditto inc ebx cmp ebx,edx jb IS0;-------IS1: mov al,0 stosb ;make asciz string pop dword [kurspos2] pop edi pop ecx xchg eax,ebx cmp al,1 ;set cy flag if empty string (len always <256) ret;----------;; GetChar returns ZERO flag for non ASCII (checked in HandleChar);ReadChar:mov eax,edi xchg eax,[old] ;for ^QP mov [veryold],eaxGetChar:call ReadOneChar cmp al,7FH jne RC_No7F ;special case: remap DEL to Ctrl-H mov al,8RC_No7F:cmp al,27 ;ESC ? jnz near RCready_2 call ReadOneChar ;dont care whether '[' or 'O' (should be) or any else call ReadOneChar ;e.g. [ for vt220,rxvt family O for xterm,vt100 family mov bl,47h ;47h home - the lowest cmp al,'1' jz RC_Tilde cmp al,'7' ;(on rxvt only) jz RC_Tilde cmp al,'H' jz RCready ;(on xterm only) inc bl ;48h up cmp al,'A' jz RCready inc bl ;49h PgUp cmp al,'5' jz RC_Tilde%ifndef LINUX cmp al,'I' jz RCready%endif inc bl inc bl ;4Bh left cmp al,'D' jz RCready inc bl inc bl ;4Dh right cmp al,'C' jz RCready inc bl inc bl ;4Fh end cmp al,'4' jz RC_Tilde cmp al,'8' ;(on rxvt only) jz RC_Tilde cmp al,'F' ;(on xterm only) jz RCready inc bl ;50h down cmp al,'B' jz RCready inc bl ;51h PgDn cmp al,'6' jz RC_Tilde%ifndef LINUX cmp al,'G' jz RCready%endif inc bl ;52h insert cmp al,'2' jz RC_Tilde%ifndef LINUX cmp al,'L' jz RCready%endif inc bl ;53h del cmp al,'3' jnz short RCready_2 ;slightly ignore this charsRC_Tilde:push ebx call ReadOneChar ;read another ~ (after integer 1..8) pop ebx cmp al,'~' jnz near GetChar ;could be F7,sF2 etc on linuxterm: ignored;-------RCready:xor eax,eax mov ah,blRCready_2:or al,al ;was similar in old DOS version (via BIOS int 16h) ret;-------SetTermStruc:%ifdef BEOS mov ecx,8000h ;TCGETA%else%ifdef LINUX mov ecx,5401h ;TCGETS asm/ioctls.h%else mov ecx,402c7413h ;TIOCGETA%endif%endif mov edx,orig call IOctlTerminal0 mov esi,edx mov edi,termios mov edx,edi push byte termios_size ;prepare a copy of original settings pop ecx cld rep movsb;-------%ifdef BEOS and byte [edx+12],(~2 & ~1 & ~8);icanon off, isig (^C) off, echo off and byte [edx+ 1],(~4) ;ixon off was: and word [edx+ 0],(~400h) mov ecx,8001h ;TCSETA %else%ifdef LINUX and byte [edx+12],(~2 & ~1 & ~8);icanon off, isig (^C) off, echo off and byte [edx+ 1],(~4) ;ixon off was: and word [edx+ 0],(~400h) mov byte [edx+23],1 ;set min=1 ->needed for gnome-terminal mov ecx,5402h ;TCSETS asm/ioctls.h%else and word [edx+12],(~100h & ~80h & ~8h) ;icanon off, isig (^C) off, echo off and word [edx+ 0],(~200h) mov ecx,802c7414h ;TIOCSETA%endif%endif call IOctlTerminal ;edx is termios pointer ret;-------; called by ReadChar/GetChar;ReadOneChar:mov ecx,read_b ;pointer to buf xor edx,edx inc edx ;mov edx,1 (length) call ReadFile0 mov eax,[ecx] ;[read_b] ret;----------------------------------------------------------------------;; L O O K functions; search special text locations and set register edi to;LookBackward: ;set EDI to 1 before EOL (0Ah) i.e., 2 before start of next line push ecx push ebx xor ebx,ebx cmp byte[edi-1],NEWLINE ;at BOL ? jz LBa3 cmp byte[edi],NEWLINE ;at EOL ? jnz LBa1 dec edi ;at EOL ? start search 1 char earlier inc ebx ;increase counterLBa1: mov ecx,99999 mov al,NEWLINE std repne scasb lea eax,[ebx+99997] ;mov eax,99997 / add eax,ebx sub eax,ecxLBa5: pop ebx pop ecx jmp short CheckBof;-------LBa3: xor eax,eax dec edi dec edi jmp short LBa5;-------LookForward:push ecx ;don't touch edx (if called by BZNLoop only) mov ecx,99999 mov al,NEWLINE cld repne scasb mov eax,99998 sub eax,ecx pop ecx dec ediCheckEof:cmp edi,ebp ;ptr is eof-ptr? jnz CheckEnd ;Z flag if eof jmp short CheckENumCheckBof:cmp edi, sot-1 ja CheckEndCheckENum:mov byte [numeriere],1 ;if bofCheckEnd:ret;-------LookPgBegin:mov edx,[kurspos2] ;called by DispNewScreen to get sync with 1st char on screen xor ecx,ecx mov cl,dh ;called by KeyCtrlQE (go upper left) inc cl jmp short LookPU2;-------LookPgEnd:mov edx,[kurspos2] ;goes 1st char last line on screen mov ecx,[lines] sub cl,dh jmp short LookPD2;-------LookLineUp:push byte 2 ;2 lines: THIS line and line BEFORE pop ecx dec dword [linenr] jmp short LookPU2;-------LookLineDown:push byte 2 ;2 lines: THIS and NEXT line pop ecx inc dword [linenr] jmp short LookPD2;-------LookPageUp:mov ecx,[lines] dec ecx ;PgUp,PgDown one line less sub [linenr],ecx inc ecxLookPU2:call LookBackward jb LookPUEnd ;if BOF inc edi loop LookPU2 ;after loop edi points to char left of 0ah dec ediLookPUEnd:inc edi inc edi ;now points to 1st char on screen or line ret;-------LookPgDown:mov ecx,[lines] dec ecx ;PgUp,PgDown one line less add [linenr],ecx inc ecxLookPD2:call LookForward jz LookPDEnd ;(jmp if EOF) inc edi ;1st char next line loop LookPD2 dec edi ;last char last lineLookPDEnd:sub edi,eax ;1st char last line ret;----------------------------------------------------------------------;; some more CHECK functions;CheckBlock:cmp byte [showblock],1 ;returns CY if error else ok: NC jc CheckBlockEnd mov esi,[blockende] cmp esi, sot jb CheckBlockEnd mov esi,[blockbegin] ;side effect esi points to block begin cmp esi, sot jb CheckBlockEnd cmp [blockende],esi ;^KK > ^KB ..OK if above!CheckBlockEnd:ret;-------CheckImBlock:cmp [blockbegin],edi ;^KB mark > edi ? ja CImBlockEnd ;OK cmp edi,[blockende] ;edi > ^KKCImBlockEnd:ret ;output:cy fehler / nc ok inside block;-------CheckMode:cmp byte [edi],NEWLINE ;checks for INSERT status jz ChModeEnd cmp byte [insstat],1ChModeEnd:ret ;Z flag for ins-mode;-------; a special case called by DeleteByteCheckMarker;CheckMarker: ;edx is blockbegin (^KB) ;ebx is deleate area end --- edi delete area start cmp edi,edx ;delete area start < ^KB marker ? ja CMEnd ;no cmp ebx,edx ;yes, but delete area end > ^KB ? jl CMEnd ;no mov edx,edi ;yes so block start (^KB) to delete area startCMEnd: ret;----------------------------------------------------------------------;; C O U N T functions; to return number of chars up to some place; (all of them are wrappers of Look....functions anyway);CountToLineEnd:push edi call LookForward pop edi ret ;eax=chars up to line end;-------CountColToLineBeginVis: ;counts columns represented by chars in EAX call CountToLineBegin ;i.e. EXPAND any TAB chars found push esi xor edx,edx mov esi,edi ;startpoint sub esi,eax ;to bol dec esiCCV1: inc esi cmp esi,edi jae CCVend cmp byte [esi],TABCHAR jz CCVTab inc edx ;count visible chars jmp short CCV1CCVTab: call SpacesForTab ;return space_up_to_next_tab in ah add dl,ah ;FIXME: now using 8 bits only jmp short CCV1CCVend: mov [ch2linebeg],edx ;ch2linebeg: interface to Key... functions mov eax,edx ;eax: interface to DispNewScreen pop esi ret;-------CountToLineBegin:push edi ;output eax=chars up there call LookBackward mov esi,edi ;side effect: set edi to 1st char in line pop edi ret;-------CountToWordBegin: ;output eax=chars up there mov esi,ediCountNLoop:inc esi cmp byte [esi],NEWLINE jz CTWend cmp byte [esi],SPACECHAR ;below SPACE includes tab chars jbe CountNLoop cmp byte [esi-1],2fh ja CountNLoop CTWend: mov eax,esi sub eax,edi ;maybe =0 ret;---------------------------------------------------------------------;; some CURSOR control functions;GoUp: mov al,0 mov ah,-1 jmp short UpDownGoDown: mov al,byte [lines] dec al mov ah,1UpDown: mov edx,[kurspos2] ;former was call getkurspos
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -