📄 e3.asm_base_for_e3c
字号:
;----------------------------------------------------------------------;; e3 v0.6 Copyright (C) 2000 Albrecht Kleine <kleine@ak.sax.de>;; This program is free software; you can redistribute it and/or modify; it under the terms of the GNU General Public License as published by; the Free Software Foundation; either version 2 of the License, or; (at your option) any later version.;; This program is distributed in the hope that it will be useful,; but WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License; along with this program; if not, write to the Free Software; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.;;----------------------------------------------------------------------;;;;;;%include 'e3.inc' ;define where the helper files are;;;;;; ;file is created by "make"%define LIBDIR "/usr/local/lib/" %ifdef LINUX %define CURSORMGNT%else %undef CRIPLED_ELF%endif;;----------------------------------------------------------------------%define LESSWRITEOPS ;NEW for e3 0.5;section .text ;here it goes....bits 32 %ifdef CRIPLED_ELF;; building e3 via "nasm -f bin ...." using an idea from ;"A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux"; org 0x08048000ehdr: db 0x7F, "ELF", 1, 1, 1, 0 ;Elf32_Ehdr starts here dd 0,0 dw 2 ;e_type dw 3 ;e_machine dd 1 ;e_version dd _start ;e_entry dd phdr1- $$ ;e_phoff dd 0 ;e_shoff dd 0 ;e_flags dw ehdrsize ;e_ehsize dw phdrsize ;e_phentsize dw 2 ;e_phnumphdr1: ;Elf32_Phdr starts here dd 1 ;both p_type and e_shentsize,e_shnum dw 0 ;both p_offset and e_shstrndxehdrsize equ $ - ehdr dw 0 dd $$ ;p_vaddr dd $$ ;p_paddr dd filesize ;p_filesz dd filesize ;p_memsz dd 5 ;p_flags i.e. READ/EXECUTE dd 0; 0x1000 ;p_alignphdrsize equ $ - phdr1phdr2: ;another Elf32_Phdr starts here dd 1 ;p_type dd filesize dd $$+filesize dd $$+filesize dd 0 ;p_filesz dd bsssize ;p_memsz dd 6 ;p_flags i.e. READ/WRITE dd 0; 0x1000 ;p_align%endif;;%ifdef LESSWRITEOPS ;constraints %define LESSWRITEOPS_OR_CURSORMGNT%endif%ifdef CURSORMGNT %define LESSWRITEOPS_OR_CURSORMGNT%endif;global _start;; start with OUTER editor loop;_start: call SetTermStruc call ReadResource%ifdef BEOS pop eax pop ebx ;args counter (1....x) xor esi,esi ;init for 'no args' dec ebx jz noarg pop esi mov esi,[esi] ;points to our_name0[args]0env..... cldprog: lodsb or al,al jne prognoarg: ;continued...%else pop eax ;Linux: arguments # pop ebx ;Linux: argv[0] pop esi ;Linux: esi points to first arg (filename) %endif;-------%ifdef CURSORMGNT or esi,esi jz moreenvmorearg:pop ecx ;arguments until NULL or ecx,ecx jnz morearg;-------moreenv:pop ecx jecxz ReStart cmp dword[ecx],'TERM' ;a short test for "TERM=linux" jnz moreenv cmp dword[ecx+5],'linu' jnz ReStart add byte[revvoff],boldlen ;special inverse cursor on linux terminals%endif ;-------ReStart:call NewFile jc E3exitMainCharLoop:call DispNewScreen call RestoreStatusLine call HandleChar cmp byte [endeedit],0 je MainCharLoop xor esi,esi ;just like if no arg is present cmp byte [endeedit],2 je ReStart ;^KD repeat edit using another fileE3exit: call KursorStatusLine mov ecx,text ;enter next line on terminal NEWLINE is @ byte [text] xor edx,edx inc edx ;mov edx,1 call WriteFile0;-------%ifdef BEOS mov ecx,8001h ;TCSETA%else %ifdef LINUX mov ecx,5402h ;TCSETS asm/ioctls.h%else mov ecx,802c7414h ;TIOCSETA%endif%endif call IOctlTerminal0 ;restore termios settings jmp Exit;----------------------------------------------------------------------;; MAIN function for processing keys;HandleChar:call ReadChar jz ExtAscii ;DOS version got ah=0 by int 16 for F-keys and cursor keys cmp al,1ch jae NormChar mov bl,al add bl,jumps1 jmp short CompJump2NormChar:call CheckMode jnz OverWriteChar push eax xor eax,eax inc eax call InsertByte pop eax jc InsWriteEnd ;error: text buffer fullOverWriteChar:cld stosb mov byte [changed],CHANGEDInsWriteEnd:ret;-------;; helper for HandleChar;CtrlKMenu:mov ebx,Ktable mov ecx,20204b5eh ;^K jmp short MenuCtrlQMenu:mov ebx,Qtable mov ecx,2020515eh ;^QMenu: call MakeScanCode jnc EndeRet ;if no valid scancodeExtAscii:mov bl,ah ;don't use al (carries char e.g. TAB) sub bl,lowest ;= scan code first key in jumptab1 jb EndeRet cmp bl,jumps1 jae EndeRetCompJump2:mov bh,0 lea ebx,[bx] ;1 byte shorter than 'and ebx,0ffh' movzx ebx,word [2*ebx+jumptab1] ;2*ebx is due 2 byte per entry add ebx,_start ;offset inside code;------- call ebx ;the general code jump dispatcher;------- cmp byte [numeriere],1 ;after return from functions... jnz BZNret ;...decide whether count current line number push edi mov esi,sot xchg esi,edi xor edx,edxBZNLoop:inc edx ;edx=linenr counter call LookForward inc edi ;point to start of next line cmp edi,esi jbe BZNLoop mov [linenr],edx pop edi mov byte [numeriere],0BZNret: ret;-------MakeScanCode:call WriteTwo ;ebx expects xlat-table push ebx call GetChar pop ebx and al,01fh cmp al,27 jnb EndeRet xlatb mov ah,al ;returns pseudo "scancode"EndeRet:ret ;exception: ok=cy here;----------------------------------------------------------------------;; processing special keys: cursor, ins, del;KeyRet: call CheckMode jnz OvrRet call CountToLineBegin ;set esi / returns eax inc esi inc esi or eax,eax jz KeyRetNoIndent xor eax,eax dec eaxKeyRetSrch:inc eax ;search non (SPACE or TABCHAR) cmp byte [esi+eax],SPACECHAR je KeyRetSrch cmp byte [esi+eax],TABCHAR je KeyRetSrchKeyRetNoIndent: push esi push eax ;eax is 0 or =indented chars call GoDown pop eax push eax inc eax ;1 extra for 0ah call InsertByte pop ecx ;# blanks pop esi ;where to copy jc SimpleRet inc dword [linenr] mov al,NEWLINE cld stosb jecxz SimpleRet rep movsb ;copy upper line i.e. SPACES,TABS into nextSimpleRet:retOvrRet: xor eax,eax mov [ch2linebeg],eax jmp short DownRet;-------KeyDown:call CountColToLineBeginVisDownRet:call GoDown call LookLineDown jmp short SetColumn;-------KeyUp: call GoUp call CountColToLineBeginVis call LookLineUp jmp short SetColumn;-------KeyPgUp:call CountColToLineBeginVis call LookPageUp jmp short SetColumn;-------KeyPgDn:call CountColToLineBeginVis call LookPgDown ;1st char last line;-------SetColumn:mov ecx,[ch2linebeg] ;maximal columns xor edx,edx ;counts visible columns i.e. expand TABs dec ediSCloop: inc edi cmp edx,ecx ;from CountColToLineBeginVis jae SCret cmp byte [edi],NEWLINE ;don't go beyond line earlier line end jz SCret cmp byte [edi],TABCHAR jz SCtab inc edx ;count columns jmp short SCloopSCtab: call SpacesForTab add dl,ah cmp edx,ecx ;this tab to far away right? jna SCloop ;noSCret: ret;-------KeyHome:call CountToLineBegin sub edi,eax ret;-------KeyEnd: call CountToLineEnd add edi,eax ;points to a 0ah char ret;-------KeyIns: not byte [insstat] ret;-------KeyDell:call KeyLeft jz KeyDell2KeyDel: cmp edi,ebp jnb KeyLeftEnd xor eax,eax ;delete one @ cursor inc eax jmp DeleteByteKeyDell2:cmp edi, sot ;delete newline char jbe KeyLeftEnd dec dword [linenr] dec edi jmp KeyCtrlT1;-------KeyLeft:cmp byte [edi-1],NEWLINE ;FIXME another check of BOF jz KeyLeftEnd ;jmp if at BOL dec ediKeyLeftEnd:ret;-------KeyRight:cmp byte [edi],NEWLINE jz KeyRightEnd ;at right margin inc ediKeyRightEnd:ret;-------KeyCLeft3:cmp edi, sot jbe KeyCLEnd dec ediKeyCtrlLeft:call KeyLeft jz KeyCLeft3 cmp byte [edi],2fh jbe KeyCtrlLeft cmp byte [edi-1],2fh ja KeyCtrlLeftKeyCLEnd:ret;-------KeyCRight3:call CheckEof jae KeyCREnd inc ediKeyCtrlRight:call KeyRight jz KeyCRight3 cmp byte [edi],2fh jbe KeyCtrlRight cmp byte [edi-1],2fh ja KeyCtrlRightKeyCREnd:ret;----------------------------------------------------------------------;; processing special keys from the Ctrl-Q menu;KeyCtrlQE:call LookPgBegin ;goto top left on screen call KursorFirstLine jmp short CQFNum;-------KeyCtrlQX:call LookPgEnd ;1st goto last line on screen call KeyEnd ;2nd goto line end call KursorLastLine jmp short CQFNum;-------KeyCtrlQV:cmp byte [bereitsges],0 ;goto last ^QA,^QF pos jz CtrlQFEnd mov edi,[oldQFpos] jmp short CQFNum;-------KeyCtrlQA:mov byte [bereitsges],2 call AskForReplace jc CtrlQFEndCQACtrlL:push edi call FindText jc CtrlQFNotFound mov eax,[suchlaenge] call DeleteByte mov eax,[repllaenge] call InsertByte mov esi,replacetext call MoveBlock jmp short CQFFound;-------KeyCtrlQF:mov byte [bereitsges],1 call AskForFind jc CtrlQFEndCQFCtrlL:push edi call FindText jc CtrlQFNotFoundCQFFound:mov [oldQFpos],edi pop esi ;dummyCQFNum: mov byte [numeriere],1 retCtrlQFNotFound:pop ediCtrlQFEnd:ret;-------KeyCtrlQC:mov edi,ebp jmp short CQFNum;-------KeyCtrlQR:mov edi,sot jmp short CQFNum;-------KeyCtrlQP:mov edi,[veryold] jmp short CQFNum ;-------KeyCtrlL:mov al,[bereitsges] ;2^QA 1^QF 0else dec al jz CQFCtrlL dec al jz CQACtrlLSimpleRet4:ret;-------KeyCtrlQB:xchg eax,edi mov edi,[blockbegin]CtrlQB2:or edi,edi ;exit of no marker set jnz CQFNum xchg edi,eax ret;-------KeyCtrlQK:xchg eax,edi mov edi,[blockende] jmp short CtrlQB2;-------KeyCtrlQI:call GetAsciiToInteger jc SimpleRet4 mov edi,sot call LookPD2JmpCQFN:jmp short CQFNum;-------KeyCtrlQDel:call KeyLeft ;delete all left of cursor call CountToLineBegin sub edi,eax call DeleteByteCheckMarker jmp short KeyCtrlT1;-------KeyCtrlQY:call CountToLineEnd jmp short CtrlTEnd1;-------KeyCtrlY:call CountToLineBegin sub edi,eax ;edi at begin call CountToLineEnd call DeleteByteCheckMarker jmp short KeyCtrlT1;-------KeyCtrlT:call CountToWordBegin cmp byte [edi],NEWLINE jnz CtrlTEnd1KeyCtrlT1:call CheckEof jz SimpleRet4 xor eax,eax inc eax ;1 for 0ahCtrlTEnd1:jmp DeleteByteCheckMarker;----------------------------------------------------------------------;; processing special Keys from Ctrl-K menu;KeyCtrlKY:call CheckBlock jc SimpleRet3 ;no block: no action mov eax,[blockende] mov edi,esi ;esi is blockbegin (side effect in CheckBlock) sub eax,esi ;block length call DeleteByte ;out ecx:=0 mov [blockende],ecx ;i.e. NO block valid now mov [blockbegin],ecx jmp short JmpCQFN;-------KeyCtrlKH:xor byte [showblock],1 ;flip flopSimpleRet3:ret;-------KeyCtrlKK:mov [blockende],edi jmp short KCKB;-------KeyCtrlKW:call CheckBlock jc SimpleRet2 ;no action call SaveBlock jmp short CtrlKREnd;-------KeyCtrlKC:call CopyBlock jc SimpleRet2CtrlKC2:mov [blockbegin],edi add eax,edi mov [blockende],eax ret;-------KeyCtrlKV:call CopyBlock jc SimpleRet2 push edi cmp edi,[blockbegin] pushf mov edi,[blockbegin] call DeleteByte neg eax ;(for optimizing eax is negated there) popf pop edi jb CtrlKC2 mov [blockende],edi sub edi,eaxKeyCtrlKB:mov [blockbegin],ediKCKB: mov byte [showblock],1SimpleRet2:ret;-------KeyCtrlKR:call ReadBlock jc CtrlKREnd call KeyCtrlKB add ecx,edi mov [blockende],ecxCtrlKREnd:jmp RestKursPos;-------KeyCtrlKS:call SaveFile pushf ;(called by ^kd) call RestKursPos popf jc CtrlKSEnd mov byte [changed],UNCHANGEDCtrlKSEnd:ret;-------KeyCtrlKQ:cmp byte [changed],UNCHANGED jz KCKXend mov esi,asksave call DE1 call RestKursPos and al,0dfh cmp al,'Y' jnz KCKXend ;Y for request SAVE changesKeyCtrlKX:call KeyCtrlKS jc CtrlKSEndKCKXend:inc byte [endeedit]KeyKXend:ret KeyCtrlKD:call KeyCtrlKS jc CtrlKSEnd mov byte [endeedit],2 ret;---------------------------------------------------------------------;; the general PAGE DISPLAY function: called after any pressed key;; side effect: sets 'columne' for RestoreStatusLine function (displays columne); variable kurspos: for placing the cursor at new position; register bh counts lines; register bl counts columns visible on screen (w/o left scrolled); register edx counts columns in text lines; register ecx screen line counter and helper for rep stos; register esi text index; register edi screen line buffer index;DispNewScreen: call GetEditScreenSize ;check changed tty size xor eax,eax mov byte[isbold],al mov byte[inverse],al mov [zloffst],eax mov [columne],eax mov [fileptr],edi ;for seeking current cursor pos call CountColToLineBeginVis ;i.e. expanding TABs mov ebx,[columns] cmp eax,ebx jb DispShortLine sub eax,ebx inc eax mov [zloffst],eaxDispShortLine:call LookPgBegin ;go on 1st char upper left on screen mov esi,edi ;esi for reading chars from text mov ecx,[lines] jecxz KeyKXend ;window appears too small cld mov bh,0 ;first line dec bhDispNewLine:inc bh ;new line mov edi,screenline ;line display buffer xor edx,edx ;reset char counter mov bl,0 ;reset screen column to 0%ifdef LESSWRITEOPS call SetColor2 ;set initial character color per each line%endif DispCharLoop: cmp esi,[fileptr] ;display char @ cursor postion ? jnz DispCharL1 cmp byte[tabcnt],0 jnz DispCharL1 mov [kurspos],ebx mov byte [columne],bl mov eax,[zloffst] ;chars scrolled left hidden add [columne],eax%ifdef CURSORMGNT stc call SetInverseStatus jnc DispEndLine%endif DispCharL1:call SetColor ;set color if neccessary;-------DispEndLine:cmp esi,ebp ja FillLine ;we have passed EOF, so now fill rest of screen cmp byte[tabcnt],0 jz ELZ dec byte[tabcnt] jmp short ELZ2ELZ: cmp esi,ebp jnz ELZ6
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -