.486 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD memex proto :DWORD,:DWORD VDisplay proto :DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc include \masm32\include\masm32.inc include \masm32\include\comdlg32.inc include \masm32\include\debug.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\masm32.lib includelib \masm32\lib\comdlg32.lib includelib \masm32\lib\debug.lib ;scx equ 800; screen dimensions; elonex ;scy equ 552 ;scyneg equ -576 ;mbx equ 4; mouse base ;mby equ 45 ;wszx equ 800; window dimensions ;wszy equ 579 ;scx equ 1280; vaio ;scxa equ 640 ;scy equ 960 ;scyneg equ -984 ;mbx equ 4 ;mby equ 53-22 ;wszx equ 1280 ;wszy equ 987 scx equ 1280; amilo scxa equ 512 scy equ 736 scyneg equ -760 mbx equ 4 mby equ 53-22 wszx equ 1280 wszy equ 772 .data ClassName db "SimpleWinClass",0 AppName db "RTE",0 NRunName db "N Run Window",0 DlgName db "MyDialog",0 TestString db "Hello, everybody",0 MsgBoxCaption db "Rainbow Assembler",0 MsgBoxText db "Loop Condition Count Error",0 ATextName db "C:\AMI\QX.rbt",0; imported text; make change at WM_CREATE ;TextName db "C:\RBT\QX.rbt",0 ;TextName db "C:\RBT\1",0 TextName db "C:\VF\M\4B",0 FontName db "C:\VF\RBT\C2.rbf",0 TextHeadBuf dd 20 dup (0) ALIGN 16 FreeMsgBuf dd 16 dup(0) ; ** Bitmap Header and 16 Text Colors ** BitmapH dd 40,scx,scyneg dw 1,8 dd BI_RGB,0,0,0,256,0 Colors db 0,0,255, 0,0,0, 255,255,255, 255,128,0, 255,192,0, 255,0,255, 128,128,255, 232,255,255, 255,255,192, 255,0,0, 128,255,128, 128,80,16, 255,64,0, 255,128,128, 0,192,0, 140,140,140 db 232,232,232, 0,0,0, 0,0,0, 0,0,0 ;Registers db 30,48,46,32,45,21,0 Registers db "ACDBXY",0 AllReg db 41h,28,70h,0, 43h,24,71h,0, 44h,20,72h,0, 42h,16,73h,0, 53h,12,53h,0, 5Ah,8,5Ah,0, 58h,4,74h,0, 59h,0,75h,0, 0,0 EditClassName db "edit",0 ; ** Live Immediate Keys ** ; +-md; &oe.; => <= = ne; > < >= <=; [ ]; $?*/ ; SBWL; ; sub- push pop; cursor arrows(5); indirectSub+,- bytes(w)ap, abs+ ; wordswap, quadword; rotate ColorImm db 1,13,11,43, 0,12,11,45, 5,9,11,128, 5,53,11,129, 1,8,11,38, 2,86,11,124, 5,86,11,101, 5,52,5,46, 0,86,11,5, 1,86,11,6, 0,13,11,61, 5,13,11,13 mcimm db 1,52,11,62, 1,51,11,60, 2,52,11,11, 2,51,11,12 db 0,51,5,7, 0,52,5,8, 0,26,5,9, 0,27,5,10, 1,5,15,36, 1,53,5,63, 1,9,11,42, 0,53,11,47, 5,31,4,130, 5,48,4,28, 5,17,4,29, 5,38,4,31 db 5,12,11,27, 2,72,11,9Ch, 2,80,11,9Dh, 5,51,3,9Bh, 5,72,3,9Ch, 5,80,3,9Dh, 5,77,3,9Eh, 5,75,3,9Fh, 1,65,10,27, 1,66,10,26, 5,47,4,76h, 5,66,4,26 db 2,17,4,77h, 5,16,4,71h, 5,26,11,9, 5,27,11,10 db 5,20,6,54h, 5,23,4,69h ; AG-T for blueT; AG-I FP Integer dd 0 RawKey db 0,0,"1234567890-=",0,0 db "qwertyuiop[]",0,0,"as" db "dfghjkl;'`",0,"#zxcv" db "bnm,./",0,0,0,32,0,0,0,0,0,92 db 0,0,33,34,127,36,37,94,38,42,40,41,95,43,0,0 db "QWERTYUIOP{}",0,0,"AS" db "DFGHJKL:@¬",0,126,"ZXCV" db "BNM<>?",0,0,0,32,0,0,0,0,0,124 ALIGN 16 RegChar db 0,3,1,2, 0,0,0,0, 0,0,0,0, 0,0,0,0 db 0,0,4,0, 0,0,0,6, 7,5,0,0, 0,0,0,0 RunCursor db 0,1,2,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 db 0,0,0,0, 0,0,0,3, 4,0,0,0, 0,0,0,0 OpChar db 0,0,0,0, 0,88h,0,0, 0,21h,20h,73h, 76h,75h,0,0 dd 0,0,0,0 db 0,0,0,0, 0,0,14h,0, 0,0,24h,10h, 0,15h,0,25h db 0,0,0,0, 0,0,0,0, 0,0,0,0, 72h,74h,77h,0 dd 0,0,0,0, 0,0,0,0 db 0,0,0,0, 0,16h,0,0, 0,0,0,0, 0,0,0,0 db 0,0,0,0, 0,0,0,0, 0,0,0,0, 11h,0,0,0 db 35h,37h,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 ; signed (sign value is 0 or 90h) db 0,0,0,0, 0,88h,0,0, 0,23h,22h,7Dh, 7Eh,75h,0,0 dd 0,0,0,0 db 0,0,0,0, 0,0,14h,0, 0,0,24h,10h, 0,15h,0,27h db 0,0,0,0, 0,0,0,0, 0,0,0,0, 7Ch,74h,7Fh,0 dd 0,0,0,0, 0,0,0,0 db 0,0,0,0, 0,16h,0,0, 0,0,0,0, 0,0,0,0 db 0,0,0,0, 0,0,0,0, 0,0,0,0, 11h,0,0,0 db 35h,37h,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 pkey db "CDDXS",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? hFile HANDLE ? hGMem dd ? ; => Global Memory allocation hwndDlg dd ? hwndEdit dd ? hwndG dd ? ; Global handle to main window ;hNWnd dd ? ; N window handle txb dd ? ; => live text buffer txl dd ? ; => AMI import text buffer txf dd ? ; => fonts chrl dd ? ; => character lengths bsc dd ? ; => bitmap screen (internal) fName dd ? ; => File Name variable (used by load,save) fBase dd ? ; File Base Address variable fLen dd ? ; Load, Save byte count dbg dd ? ; Debug Display Address bmi dd ? ; => Bitmap header sx dd ? ; Bitmap Screen Cursor sy dd ? fgc db ? ; Text Foreground, Background Colors bkc db ? tx db ? ; Text Cursor ty db ? mx dd ? ; Mouse Position my dd ? x dd ? ; General y dd ? txtl dd ? ; => Start of Cursor Line txtlc0 dd ? ; Cursor line byte count lin dd ? ; => Cursor line structure lina dd ? ; => column 0 in line structure linc dd ? ; => cursor position on line linr dd ? ; => overhead resource line txta dd ? ; => text top txtb dd ? ; => text at top of screen txtc dd ? ; => text under cursor txtd dd ? ; => start of text below screen txtz dd ? ; => text bottom txtt dd ? ; => temporary text txtu dd ? ; => more temporary text txtr dd ? ; => resource text txtm dd ? ; => text marker (start of line under assembler) txtml dd ? ; => position in video line (see v0,v8) txtccr dd ? ; => temporary text cursor txtccr2 dd ? ; => ditto arrf dd ? ; => low level array strf dd ? ; => string collect array codebase dd ? ; => starting point for assembled N-code labelb dd ? ; => pointer to label list base labelc dd ? ; => current pointer to label list callb dd ? ; => pointer to call list base callc dd ? varb dd ? ; => pointer to base of list of variables varc dd ? filedata dd ? ; => pointer to file data dirh dd ? ; directory handle dirdata dd ? ; pointer to directory data btxt dd ? ; => start of text block ctxt dd ? ; => end of text block dtxt dd ? ; => ditto (untuned) video dd ? ; => mode video screens videoc dd ? ; => current mode video screen time dd ? ; time variable stb dd ? ; => assembler stack base rstack dd ? ; => run stack base stvar dd ? ; => ARun ebp variable storage mol dd ? ; => molecule MSgn dd ? ; signed molecule? mode db ? ; mode (0=text, 1=run, 2=debug) kstat db ? ; keyboard status MLen db ? ; molecule length (1=long) MWord db ? ; ditto (1=word) rb db ? ; run background color rc db ? ; run foreground color rx db ? ; run cursor position ry db ? ; NegVal db ? ; QOp db ? ; quadword multiplication and division ImmLen db ? ; length of immediate byte FPInt db ? ; FP Integer Flag kfstat db ? ; FetchEx keyboard status SJump db ? ; jump from subroutine flag (see MolAsm) ALIGN 16 fpqvar dq ? ; FP temporary quad variable jpb dd ? ; => Jump Stack Base jpc dd ? ; => Jump Stack Pointer fpvar dd ? ; FP temporary variable .code start: jmp start1 nop nop mov eax,[txb+24] mov dword ptr[ebx],12345678h fild dword ptr[ebx] fld qword ptr[edi] fistp qword ptr[edi+16] mov word ptr[eax+128],129 cdq mov ecx,10 idiv ecx rol dx,8 rol cx,8 imul edx,6 imul edx,600 imul edx,ecx or edx,edx jge st2 neg edx st2: call dword ptr[ebp-4] push [edx+ecx+34] push [ecx+edx+34] cmp edx,2 ; Code Comparison area jne stt3 stt2: add ecx,7 cmp [edi],edx je stt1 mov [eax],edi call lab1 call lab3 mov cl,[ebx+5] and cl,3 stt1: cmp esi,3 jge stt2 mov ecx,810000h sub ecx,[edx+esi-4] stt3: mov eax,[ecx+383] sub ebx,5 ret lab1: mov [edi],al ret lab3: add eax,3 ORG 200h jmp start1; ! short jump 2 bytes jmp LoadEx; others are 5 bytes (see MElr) jmp SaveEx jmp ClearEx; clear screen, current mode jmp RefreshEx; show screen, current mode (auto before input) jmp PrintEx; write character to video jmp FetchEx; fetch keydown, keyup, left mouse or right mouse start1: invoke GlobalAlloc,GMEM_FIXED,20000000h ; Set Buffer Addresses; amended from 11800000 mov hGMem,eax ;invoke VirtualAlloc,0,7000000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE mov eax,1000000h ;PrintHex eax add eax,0FFFh and eax,0FFFFF000h ;PrintHex eax mov txf,eax ; Font buffer add eax,8000h mov bmi,eax ; Bitmap Overhead buffer (colors from offset 40) add eax,800h mov lin,eax ; Cursor Line Buffer (256 chrs) add eax,800h mov linr,eax; resource line add eax,1000h mov txtt,eax; Temporary Text add eax,4000h mov txtu,eax; Further Temporary Text add eax,4000h mov labelb,eax; Red Labels add eax,20000h mov callb,eax; Orange Calls add eax,30000h mov varb,eax; Variables add eax,10000h ;mov dirdata,eax; Directory ;add eax,2000h mov arrf,eax; Free, low level variables array add eax,400h mov strf,eax; String Collect Array (Print/Input) add eax,100h mov chrl,eax; Character widths add eax,100h mov mol,eax; Molecule buffer add eax,100h mov jpb,eax; Jump Stack buffer add eax,100h ;mov filedata,eax; File Data ;add eax,100h mov stvar,eax; ARun ebp variables add eax,1800h mov dirdata,eax add eax,80000h mov filedata,eax add eax,1000h ;PrintHex eax add eax,0FFFFFh and eax,0FFF00000h ;PrintHex eax mov eax,01300000h mov txb,eax; Live Text buffer add eax,1D0000h mov txl,eax; Loaded Text buffer add eax,30000h mov codebase,eax add eax,100000h ;PrintHex eax mov eax,01700000h mov video,eax .IF eax!=01700000h PrintHex eax .ENDIF ;call codex mov al,0 call SetMode invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT push eax invoke GlobalFree,hGMem ;PrintHex hGMem ;PrintHex eax pop eax invoke ExitProcess,eax WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,0,0,wszx,wszy,\ NULL,NULL,hInst,NULL mov hwnd,eax mov hwndG,eax INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax); i.e. if eax=0 (false) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT LOCAL hScreenDC:HDC LOCAL hBitmap:HANDLE LOCAL hMemDC:HDC LOCAL rect:RECT .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF mode!=0; no process here outside mode 0 ;movzx eax,mode ;add eax,100h ;PrintHex eax jmp wdef .ELSEIF uMsg==WM_CREATE pushad call lfont ;call lti ; load import text (exchange to load Amiga file) call ltv; load live text ;PrintHex ld ;call regex call bmo ;call regex popad .ELSEIF uMsg==WM_COMMAND ;PrintHex eax ;PrintHex wParam ;PrintHex lParam mov eax,wParam shr eax,24 .IF al==5 invoke GetWindowText,hwndEdit,mol,32 invoke DestroyWindow,hwndEdit ;invoke memex,mol,8 .ENDIF .ELSEIF uMsg==WM_KEYDOWN pushad ;mov eax,wParam ;PrintHex eax mov eax,lParam shr eax,16 ;PrintHex eax .IF al==1; escape key invoke PostQuitMessage,NULL .ELSEIF al==82; Timing the Block Move call rm0 .ELSEIF al==87 .IF kstat==5 call breaknextline .ELSE call nextmap .ENDIF ; invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\ ; WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\ ; ES_AUTOHSCROLL or ES_MULTILINE,\ ; 50,35,200,25,hWnd,8,hInstance,NULL ; mov hwndEdit,eax ; invoke SetFocus, hwndEdit .ELSEIF al==69; num-lock key mov eax,eax .ELSEIF al==58; capslock key mov eax,eax .ELSE call kd0 .ENDIF popad invoke InvalidateRect, hWnd,NULL,FALSE .ELSEIF uMsg==WM_LBUTTONDOWN pushad mov kstat,0 mov ebx,txb mov eax,lParam; X and eax,0ffffh mov mx,eax mov eax,lParam; Y shr eax,16 mov my,eax call mcm popad invoke InvalidateRect, hWnd,NULL,FALSE .ELSEIF uMsg==WM_RBUTTONDOWN pushad mov kstat,0 mov ebx,txb mov eax,lParam; X and eax,0ffffh mov mx,eax mov eax,lParam; Y shr eax,16 mov my,eax call mcm popad call GoToLbl invoke InvalidateRect, hWnd,NULL,FALSE .ELSEIF uMsg==WM_PAINT pushad ;PrintHex edx .IF mode==0; call in text pushad ; invoke GetTickCount ; mov ecx,1000 ; mov time,eax ; rr: push ecx call xtxt ; pop ecx ; dec ecx ; jne rr ; invoke GetTickCount ; sub eax,time ; mov time,eax ; PrintDec time popad .ENDIF invoke BeginPaint,hWnd, ADDR ps mov hdc,eax ;PrintHex eax invoke GetWindowDC,NULL mov hScreenDC,eax invoke CreateDIBSection, hScreenDC, bmi, DIB_RGB_COLORS, addr bsc, NULL, 0 mov hBitmap,eax invoke ReleaseDC,NULL,hScreenDC ;PrintHex edx call invideo ;PrintHex edx invoke CreateCompatibleDC,hdc mov hMemDC,eax invoke SelectObject,hMemDC,hBitmap invoke GetClientRect,hWnd, addr rect invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY invoke DeleteDC,hMemDC invoke EndPaint,hWnd, addr ps invoke DeleteObject, hBitmap popad .ELSE wdef: invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp ;; ** Move Video map into internal video map invideo: pushad; move video map into internal video map mov esi,videoc mov edi,bsc ;mov ecx,115200 ; = 800x576/4 640x400/4 mov ecx, scx*(scy+24)/4 ;call regex cld rep movsd popad ret ; Keydown Routines kd0: .IF al==42 mov kstat,1 .ELSEIF al==54 mov kstat,2 .ELSEIF al==29 mov kstat,3 .ELSEIF al==56 mov kstat,5 .ELSE call kd1 mov kstat,0 .ENDIF xor eax,eax ret kd1: .IF kstat==3 .IF al==31 call stf; save text .ELSEIF al==49 ;call stf call ntf; new text .ELSEIF al==35 call live; live text .ELSEIF al==48 mov eax,txtc mov btxt,eax .ELSEIF al==46 mov eax,txtc mov ctxt,eax call TxtCopy .ELSEIF al==45 mov eax,txtc mov ctxt,eax call TxtCut .ELSEIF al==47 call TxtPaste .ELSEIF al==34 call GoToLbl .ENDIF .ELSEIF al==88; Assemble and Run .IF kstat==2 call stf1 .ELSE call ARun .ENDIF .ELSEIF al==83; Delete word call delete .ELSEIF al==81; screen down mov edi,txtb mov y,40 kd11: call mtd dec y jne kd11 mov txtb,edi mov txtc,edi call mcf .ELSEIF al==73; screen back mov edi,txtb mov y,35 kd12: call mtu dec y jne kd12 mov txtb,edi mov txtc,edi call mcf .ELSEIF al==71; top of file mov edi,txta mov txtb,edi mov txtc,edi ;invoke memex,edi,12 top1: inc edi cmp byte ptr[edi],0D8h je top2 cmp byte ptr[edi],0D2h jne top1 top2: dec edi cmp byte ptr[edi],32 je top2 inc edi mov txtc,edi ;call mcf .ELSEIF al==79; bottom of file mov edi,txtz ;PrintHex txtz mov txtc,edi ;invoke memex,edi,12 call mcb mov y,30 kd14: call mtu ;PrintHex edi dec y jne kd14 mov txtb,edi ;PrintHex txtb ;PrintHex txtc .ELSEIF al==14; backspace call back .ELSEIF al==28; return call return .ELSE call kd2 call ww xor eax,eax ret .ENDIF call ww mov eax,1 ret kd2: .IF kstat==0 .IF al==75 call mcb ret .ELSEIF al==77 call mcf ret .ELSEIF al==72 call mcu ret .ELSEIF al==80 call mcd ret .ENDIF .ENDIF mov cl,al mov edx,0 lea ebx,RawKey cmp al,86 jne kd21 mov al,63 kd21: cmp kstat,1 jb kd21a add al,64 kd21a: movzx eax,al mov dl,[ebx+eax] ;cmp dl,0 ;je kd22 call char kd22: ret ARun: pushad ;invoke GetTickCount ;mov time,eax call asm ;pushad ;invoke GetTickCount ;sub eax,time ;PrintHex eax ;popad mov x,eax popad cmp x,0; run after return from COMPLETED assembly je kd1a ;jmp kd1a invoke GetTickCount mov time,eax mov al,1 call SetMode mov eax,codebase add eax,10000h pushad mov ebp,esp ; allows ebp-200h to ebp+1000h sub ebp,1000h sub esp,1200h pushad mov ecx,1200h; load stacked variables arun1: sub ecx,4 mov ebx,stvar mov eax,[ebx+ecx] mov [ebp+ecx-200h],eax or ecx,ecx jne arun1 popad ; -12 reserved for event input, ; -16,-8,-4 for video address, dimensions mov [ebp-20],PrintEx mov [ebp-24],InputEx mov [ebp-28],InputSEx mov [ebp-32],BreakEx ; -40,-36 reserved for mouse position (see FetchEx,MmEx) mov dword ptr[ebp-44],01010102h; bkc2,fgc1,x=1,y=1 mov [ebp-260],LoadEx; #0 => Routines called by N code mov [ebp-264],SaveEx; => May be replaced by absolute address jumps mov [ebp-268],ClearEx mov [ebp-272],RefreshEx mov [ebp-276],FetchEx mov [ebp-280],TimeEx; #5 mov [ebp-284],AtnEx mov [ebp-288],SqRtEx mov [ebp-292],SetPalEx mov [ebp-296],SinEx mov [ebp-300],DirEx; #10 mov [ebp-304],FetchStringEx mov [ebp-308],FetchPalEx mov [ebp-312],MmEx; mouse move mov [ebp-316],RenEx; file rename mov [ebp-320],Cdir; create directory mov rstack,esp; run stack pointer (for escape return) ;PrintHex ARun ;call codex call eax runret: pushad mov ecx,1200h; save stacked variables arun2: sub ecx,4 mov ebx,stvar mov eax,[ebp+ecx-200h] mov [ebx+ecx],eax or ecx,ecx jne arun2 popad add esp,1200h popad ;call regex mov al,0 call SetMode invoke GetTickCount sub eax,time mov time,eax ;PrintDec time ;call codex kd1a: ret breaknextline: mov esi,txtc bnx1: inc esi cmp byte ptr[esi],0 jne bnx1 invoke memex,esi,20 add esi,80 mov byte ptr[esi],0 mov byte ptr[esi+1],0D8h mov byte ptr[esi+2],0E9h ret nextmap: mov ebx,txta nextmap1: inc ebx cmp byte ptr[ebx],0 jne nextmap1 inc ebx ;PrintHex ebx cmp ebx,txtz ja nextmap9 cmp dword ptr[ebx],07372E9D8h jne nextmap1 cmp word ptr[ebx+4],206Eh jne nextmap1 add ebx,6 .WHILE byte ptr[ebx]>2Fh inc ebx .ENDW dec ebx .IF byte ptr[ebx]=="w" mov byte ptr[ebx],"e" .ELSEIF byte ptr[ebx]=="e" mov byte ptr[ebx],"w" dec ebx inc byte ptr[ebx] .IF byte ptr[ebx]>"9" sub byte ptr[ebx],10 inc byte ptr[ebx-1] .ENDIF .ENDIF nextmap9: ret ; Character dl, from key cl char: call lns; set character line ;mov esi,txtc mov edi,linc; cursor position in chr line cmp byte ptr[edi+2],8; live text? je tl ; White Text Edit cmp cl,59; function keys; change cursor color jb wt1 cmp cl,66 ja wt1 mov dh,cl sub dh,58 mov al,kstat shl al,3 add dh,al and dh,15 ;PrintHex edx ;mov dl,32 mov esi,linc mov [esi+1],dh inc byte ptr[esi+3] ;call cins ;sub linc,4 ;invoke memex,lin,12 call lnt ret wt1: cmp cl,67; F9 change next word to cursor color jne wtd cmp kstat,2 je wtp mov dh,[edi+1] wt11: add edi,4 cmp dword ptr[edi],0 je wt19 mov [edi+1],dh cmp byte ptr[edi],32 je wt19 cmp byte ptr[edi],0 jne wt11 wt19: mov linc,edi call lnt ret wtp: invoke memex,edi,8 wtp1: mov byte ptr[edi+2],8 add edi,4 cmp byte ptr[edi],0 jne wtp1 jmp ti1 wtd: mov dh,[edi+1]; default insertion cursor color call cins; white text call lnt ret ; Live Text Edit tl: mov bh,[edi-3]; back color mov bl,[edi-4]; back character mov ch,[edi+1]; cursor color mov dh,14; space bar cmp dl,32 jne tl19 cmp ch,4; space bar terminates ascii mode jne tl11 mov byte ptr[edi+1],14 tl11: jmp ti tl19: nop ; !! colors 3,5,9 can also only be destroyed by space bar tl2: cmp cl,3; " to enter ascii mode jne tl29 cmp kstat,1 jne tl29 ;PrintHex ecx mov byte ptr[edi+1],4 jmp ti1 tl29: mov dh,4; ascii mode fixes color cmp byte ptr[edi+1],4 je ti tim: lea esi,ColorImm; immediate color characters sub esi,4 tim1: add esi,4 cmp dword ptr[esi],0 je tim9 mov al,[esi] cmp kstat,al jne tim1 cmp [esi+1],cl jne tim1 mov dh,[esi+2] mov dl,[esi+3] .IF dl==5; jump symbol .IF bl==32 mov dh,5 .ENDIF .ENDIF jmp ti tim9: nop tlab: mov eax,edi sub eax,lin cmp eax,12 jne tlab9 ;cmp dl,61h ;jb tlab9 ;cmp dl,7Ah ;ja tlab9 sub dl,00h mov dh,9 jmp ti tlab9: nop tex: cmp kstat,2; Shift-Right D,X,S jne tex9 mov al,"D" cmp cl,32 je tex1 mov al,"X" cmp cl,45 je tex1 mov al,"S" ;call regex cmp cl,31 jne tex9 tex1: push eax mov dh,bh mov dl,32 call cins pop eax mov dh,3 mov dl,al call cins mov dh,4 mov dl,1Fh .IF cl==31 mov dl,1Ch .ENDIF call cins .IF cl==31 mov dh,6 mov dl,"X" call cins .ENDIF jmp ti1 tex9: nop ts0: cmp cl,65; F7 = color 3 (sub/fn) jne ts1 mov dh,3 mov dl,40 mov [edi+1],dh jmp ti ts1: cmp cl,66; F8 = color 5 (break) jne ts9 mov dh,5 mov dl,40 mov [edi+1],dh jmp ti ts9: nop tpi: cmp cl,67 jne tpi9 tpi1: mov dh,bh mov dl,32 call cins call cins ;call cins sub linc,4 sub edi,4 mov byte ptr[edi+1],1 mov byte ptr[edi+2],7 jmp ti1 tpi9: nop tr0: cmp cl,59; Register Keys jb tr9 cmp cl,64 ja tr9 ; cmp bh,10 ; jne tr01 ; cmp kstat,1 ; jne tr01 ; cmp bh,32 ; jne trs tr01: movzx eax,cl lea esi,Registers mov dl,[esi+eax-59] cmp bl,32 je tr29 cmp bh,14 je tr2 cmp bh,10 jne tr29 tr2: add dl,70h; subscripted? mov kstat,0; direct or indirect? tr29: mov dh,6 cmp kstat,0 je tr1 cmp kstat,2 jne tr29a add dl,0CBh-41h jmp tr1 tr29a: mov dh,10 tr1: call regb; no X,Y in byte mode jmp ti ;trs: mov dh,10 ; mov dl,26 ; cmp cl,62 ; je ti ; inc dl ; cmp cl,61 ; je ti ; cmp cl,60 tr9: nop tc0: call ta0 cmp dl,"a" jb tc5 cmp dl,"z" ja tc5 cmp byte ptr[esi-4],40 jne tc5 ;sub dl,32 tc5: jmp ti ; No X,Y in byte mode regb: cmp dh,6 jne regb9 mov eax,edi regb1: sub eax,4 cmp byte ptr[eax],32 je regb9 cmp byte ptr[eax],28 jne regb1 cmp dl,58h jb regb9 cmp dl,59h ja regb9 sub dl,58h add dl,0CDh regb9: ret ti: call cins; insert text character dl,dh cmp dl,7 jne ti1 mov dl,63; ? after "if" call cins ti1: call lnt ret cra: ;call lnt ;mov edi,lin ;mov edi,[edi] ;invoke memex,edi,50 ret ; Live Autocolor and Autosubscript ta0: call tn0; var/num? cmp bh,11; v/n after 11 jne ta1 cmp bl,27 jne ta9 ta1: cmp bh,4; v/n after sbwl jne ta11 cmp bl,32 jb ta9 cmp bl,128 ja ta9 ta11: cmp bl,32; v/n after space je ta9 cmp bl,63; green after ? je ta9 ta12: cmp bl,40; bracket created by F7,F8 jne ta129 mov byte ptr[edi-4],32 mov dh,bh jmp ta9 ta129: nop ta4: cmp dh,15; subscripted index digit jne ta49 cmp bh,14; after indirect or variable je ta41 cmp bh,10 jne ta43 ta41: sub dl,20h jmp ta9 ta43: nop cmp bh,6; after (subscripted) register jne ta45 push edx; insert sub + mov dl,26 mov dh,11 call cins pop edx sub dl,20h jmp ta9 ta45: cmp bl,10h jb ta49 cmp bl,1Bh ja ta49 sub dl,20h jmp ta9 ta49: nop mov dh,bh; else back color ta9: ret tn0: mov dh,14; number else variable cmp dl,48 jb tn9 cmp dl,57 ja tn9 mov dh,15 tn9: ret ;regk: lea ebx,Registers regk0: cmp [ebx],al je regk1 inc ebx cmp byte ptr[ebx],0 jne regk0 xor al,al regk1: ret back: call lns; backspace mov edi,linc mov eax,edi sub eax,lin cmp eax,12 jg back1 back0: mov edi,txtc; col 0 merge with line above back01: dec edi cmp edi,txta jbe back09 cmp byte ptr[edi],0 jne back01 mov ecx,-1 call ttx dec txtc back09: ret back1: mov eax,[edi] mov [edi-4],eax add edi,4 cmp eax,0 jne back1 sub linc,4 call lnt ret return: call lns mov edi,txtc mov eax,edi sub eax,txta cmp eax,20 jl ltf mov esi,linc cmp kstat,0 jne ret1 mov ecx,3 call ttx mov byte ptr[edi],0 mov al,[esi+2] add al,0D0h mov [edi+1],al mov al,[esi+1] add al,0E0h mov [edi+2],al add txtc,3 ret ret1: mov ecx,4; return with shift, set hard call ttx mov byte ptr[edi],0CFh mov byte ptr[edi+1],0 mov al,[esi+2] add al,0D0h mov [edi+2],al mov al,[esi+1] add al,0E0h mov [edi+3],al add txtc,4 ret delete: ; cmp kstat,2; ? entire line je delk2 call lns mov esi,linc cmp byte ptr[esi],0 je del9 cmp kstat,1 je delk1 mov ebx,esi; character lea ecx,[ebx+4] call delr ret delk1: cmp byte ptr[esi],32; word; if not on a word, move right onto one jne delk12 delk11: add esi,4 cmp byte ptr[esi],32 je delk11 cmp byte ptr[esi],0 je del9 delk12: cmp esi,lina; move left to start of word je delk13 sub esi,4 cmp byte ptr[esi],32 jne delk12 add esi,4 delk13: mov ebx,esi delk14: add esi,4 cmp byte ptr[esi],0 je delk15 cmp byte ptr[esi],32 jne delk14 add esi,4 delk15: mov ecx,esi call delr del9: ret delr: mov linc,ebx delr1: mov eax,[ecx] mov [ebx],eax add ecx,4 add ebx,4 cmp dword ptr[ecx-4],0 jne delr1 call lnt ret delk2: mov edi,txtc; entire line delk21: dec edi cmp byte ptr[edi],0 jne delk21 inc edi mov txtc,edi mov ecx,edi delk22: inc ecx cmp byte ptr[ecx],0 jne delk22 inc ecx sub ecx,edi neg ecx call ttx call mcf ret ; *** Wordwrap routines **** ww: call wws; superfluous spaces mov edi,txtc; word wrap (not live lines) xor ecx,ecx ww1: dec edi cmp byte ptr[edi],0 jne ww1 cmp edi,txta jbe ww9 cmp byte ptr[edi+1],0D8h je ww9 inc edi cmp byte ptr[edi+2],32 jbe ww9 pushad call ww2 popad ret ww2: ; Word Wrap: characters to first temporary ;PrintHex ww2 mov ch,0; clear back and fore colors mov cl,0 mov esi,edi mov x,esi mov edi,txtt ww21: call ww2b call ww2a; write chr to temp text inc esi cmp byte ptr[esi],0; replace 0 with space - unless there`s one ; already there jne ww21 call ww2b ;cmp byte ptr[edi-1],32 ;je ww211 mov byte ptr[edi],32 inc edi ww211: inc esi call ww2p; test next line for paragraph end cmp al,0 je ww21 mov byte ptr[edi-1],0; replace end space with 0 mov y,esi; old text ends after last 0 ww3: mov esi,txtt; characters to second temporary; adds soft line breaks ;invoke memex,esi,50 ;mov eax,txtccr ;sub eax,4 ;invoke memex,eax,4 mov edi,txtu mov ebx,chrl mov edx,arrf xor ecx,ecx ww30: call ww3b movzx eax, byte ptr[esi] cmp al,32; mark space jne ww31 mov [edx],esi mov [edx+4],edi ww31: mov [edi],al inc edi .IF al>=0E0h mov [edx+9],al .ELSEIF al>=0D0h mov [edx+8],al .ELSE movzx eax, byte ptr[ebx+eax] ;PrintHex eax add ecx,eax add ecx,eax cmp ecx,scx-8; line overflow, return to space, replace with 0 jb ww32 ;PrintHex eax mov esi,[edx] mov edi,[edx+4] mov byte ptr[edi],0 mov al,[edx+8] mov [edi+1],al mov al,[edx+9] mov [edi+2],al add edi,3 xor ecx,ecx .ENDIF ww32: inc esi cmp byte ptr[esi],0 jne ww30 call ww3b cmp byte ptr[edi-1],0; new text must end with a 0 je ww33 mov byte ptr[edi],0 inc edi ww33: nop ww4: ;invoke memex,txtu,50 ;mov eax,txtccr2 ;sub eax,4 ;invoke memex,eax,4 mov ecx,edi; second temp length sub ecx,txtu push ecx mov edx,y; source length sub edx,x ;call regex sub ecx,edx; make room for new text mov edi,x call ttx mov esi,txtu; move new text in mov edi,x pop ecx ww41: mov al,[esi] mov [edi],al inc esi inc edi dec ecx jne ww41 mov eax,txtccr2 add eax,edi sub eax,esi mov txtc,eax ret ww2a: mov dl,byte ptr[esi] cmp dl,0E0h jb ww2a2 cmp dl,cl; Forecolor; write new forecolor je ww2a1 mov [edi],dl inc edi mov cl,dl ww2a1: ret ; DL=*SI; if (DL>=0xE0) {if (DL!=CL) {*Y=DL; Y++; CL=DL;} return();} ; plus variable definitions, functions and prototypes etc., ; and how does C handle indirect addressing with displacements and/or indices? ; ? use slightly different color for test operators ww2a2: cmp dl,0D0h jb ww2a4 cmp dl,ch; Backcolor; write new backcolor je ww2a3 mov [edi],dl inc edi mov ch,dl ww2a3: ret ww2a4: cmp dl,32; space handling jne ww2a6 ;PrintHex esi ;PrintHex txtc cmp esi,txtc; normal before cursor jb ww2a6 mov eax,esi; else delete spaces at line end ww2a41: inc eax cmp byte ptr[eax],0 je ww2a42 cmp byte ptr[eax],32 je ww2a41 mov [edi],dl inc edi ww2a42: ret ww2a6: mov [edi],dl; write character inc edi ret ww2b: cmp esi,txtc; mark cursor position in temp text jne ww2b1 mov txtccr,edi ww2b1: ret ww3b: cmp esi,txtccr; mark cursor position in temp text jne ww3b1 mov txtccr2,edi ww3b1: ret ww2p: mov eax,esi; New paragraph Test dec eax ww2p1: inc eax mov dl,[eax] cmp dl,0D8h; end if live line je ww2pp cmp dl,32; end if space je ww2pp cmp dl,0; or a blank line je ww2pp cmp dl,0CFh; or hard return je ww2pp cmp byte ptr[edi-2],0CFh je ww2pp cmp dl,0D0h; skip color bytes jae ww2p1 xor eax,eax; else move on ret ww2pp: mov al,1 ret ww9: ret wws: mov edi,txtc; remove superfluous spaces after cursor cmp byte ptr[edi],0 je wws9 wws1: inc edi cmp byte ptr[edi],0 jne wws1 wws3: dec edi cmp edi,txtc jbe wws9 cmp byte ptr[edi],32 jne wws9 mov ecx,-1 call ttx jmp wws3 wws9: ret TxtCut: call TxtCopy; Copy and Cut mov edi,btxt mov ecx,edi sub ecx,ctxt call ttx ret TxtCopy: mov edi,ctxt; Tune End of Text mov dtxt,edi txc1: dec edi cmp byte ptr[edi],0D0h jae txc1 inc edi mov ctxt,edi mov edi,btxt; Fetch Start Colors txc2: dec edi cmp byte ptr[edi],0D0h jae txc2 inc edi mov txtc,edi call lns mov esi,linc mov edi,txl mov al,[esi+2] add al,0D0h mov [edi+4],al mov al,[esi+1] add al,0E0h mov [edi+5],al mov esi,btxt; Copy Text mov ecx,ctxt sub ecx,esi mov [edi],ecx add dword ptr[edi],2 add edi,6 cld rep movsb mov eax,dtxt mov txtc,eax ret TxtPaste: mov edi,txtc txtp1: dec edi cmp byte ptr[edi],0D0h jae txtp1 inc edi mov esi,txl mov ecx,[esi] call ttx add esi,4 rep movsb ret invoke memex,txl,20 ret live: call lns mov esi,linc; under 8, set 8`s to 2; under 2, set 2`s to 8 mov dl,[esi+2] mov esi,lin add esi,12 lv1: cmp dl,[esi+2] jne lv2 mov al,dl neg al add al,10 mov [esi+2],al lv2: add esi,4 cmp dword ptr[esi],0 jne lv1 call lnt ret GoToLbl: mov edi,txtc mov ebx,arrf inc edi; Go to Red Label gt1: dec edi call gtc or eax,eax jne gt1 inc edi gt2: mov al,[edi] mov [ebx],al inc ebx inc edi call gtc or eax,eax jne gt2 mov byte ptr[ebx],0 mov edi,txta gt3: mov ebx,arrf add edi,1 dec ebx gt4: inc edi inc ebx mov al,[edi] cmp [ebx],al je gt4 cmp byte ptr[ebx],0 jne gtlf cmp al,0D0h jae gtp cmp al,32 je gtp gtlf: dec edi gtlf1: inc edi; next line cmp byte ptr[edi],0 jne gtlf1 inc edi cmp edi,txtz jb gt3 ret gtp: dec edi cmp byte ptr[edi],0 jne gtp inc edi mov ebx,edi add edi,2 mov txtc,edi mov edi,ebx mov ecx,6 gtp1: call mtu dec ecx jne gtp1 mov txtb,edi ret invoke memex,ebx,12 ret gtc: mov al,[edi]; Test for valid label character(0-9,A-Z,a-z) sub al,30h cmp al,9 jbe gtc1 sub al,11h cmp al,25 jbe gtc1 sub al,20h cmp al,25 jbe gtc1 xor eax,eax ret gtc1: mov eax,1 ret ; Back character, color to cl,ch; bkgcolor to al ;cbak: xor ecx,ecx cbak1: dec edi; search back for character cmp byte ptr[edi],208 jae cbak1 mov cl,[edi] cbak2: dec edi; search back for foreground cmp byte ptr[edi],224 jb cbak2 mov ch,[edi] and ch,0fh cbak3: dec edi; search back for background mov al,[edi] cmp al,208 jb cbak3 cmp al,224 jae cbak3 ;call regex ret ; Character Insertion into lin at edi; color dh, character dl cins: pushad mov ebx,edi cins2: add ebx,4 cmp dword ptr[ebx-4],0 jne cins2 cins3: sub ebx,4 mov eax,[ebx] mov [ebx+4],eax cmp ebx,edi jne cins3 mov [edi],dl mov [edi+1],dh mov al,[edi+6] mov [edi+2],al add linc,4; increment cursor popad add edi,4 ret ; Translate Text (from edi, signed ecx) ttx: pushad call ttx0 popad ret ttx0: cmp ecx,0 jg ttxf jl ttxb ret ttxf: mov esi,edi add edi,ecx mov eax,txtz sub eax,esi add eax,8 add txtz,ecx mov ecx,eax ;std ;rep movsd ; byte ptr [edi],[esi] add esi,ecx add edi,ecx ttxf2: dec esi dec edi mov byte ptr al,[esi] mov byte ptr [edi],al dec ecx jne ttxf2 ret ttxb: neg ecx mov esi,edi add esi,ecx mov eax,txtz sub eax,edi add eax,8 sub txtz,ecx mov ecx,eax ttxb2: mov byte ptr al,[esi] mov byte ptr [edi],al inc esi inc edi dec ecx jne ttxb2 ret ; Move Screen one line Down, Up mtd: dec edi; one back, then forward to a 0, then forward one more mtd3: inc edi cmp BYTE PTR[edi],0 jne mtd3 mtd2: inc edi cmp BYTE PTR[edi],255; go back from end of file jne mtd0 mtd1: call mtu mtd0: ret mtu: dec edi; Top of file? cmp edi,txta jbe mtu1 mtu2: dec edi; find next 0 cmp edi,txta jbe mtu11 cmp BYTE PTR[edi],0 jne mtu2 mtu1: inc edi cmp edi,txta ja mtu11 mtu11: ret ; {i=0; do {if (*p2!=255) {do {p2++;} while (*p2!=0); p2++;} i++;} ; while (i<40); goto kd1;} ; Move cursor back, forward, up, down, to coordinates mcb: mov eax,txtc mcb1: dec eax; move back until chr<128 cmp byte ptr[eax],208 jae mcb1 cmp eax,txta ; check for text head ja mcb2 mov txtc,eax call mcf mcb2: mov txtc,eax ret mcf: mov eax,txtc mcf1: inc eax; move forward until chr<128 cmp byte ptr[eax],208 jae mcf1 cmp eax,txtz ; check for text foot jb mcf2 mov txtc,eax call mcb mcf2: mov txtc,eax ret mcu: mov edi,txtc lea eax,[edi-8] ;invoke memex,eax,12 mcu1: dec edi cmp byte ptr[edi],0 ; up to a line end jne mcu1 cmp edi,txta; not above text head jb mcu4 mcu2: dec edi cmp byte ptr[edi],0 ; up to another line end jne mcu2 inc edi; back down to first line up mov txtc,edi cmp edi,txtb ; screen up if necessary jae mcu3 mov edi,txtb call mtu mov txtb,edi mcu3: call mcf mcu4: ret mcd: mov edi,txtc ;mov eax,txtz ;sub eax,100h ;invoke memex,eax,50 dec edi; unless on line end, move forward to line end mcd1: inc edi cmp byte ptr[edi],0 jne mcd1 inc edi; move on to next line cmp edi,txtz; not below text foot jae mcd4 cmp byte ptr[edi],255 je mcd4 mov txtc,edi cmp edi,txtd; screen down if necessary jb mcd3 mov edi,txtb call mtd mov txtb,edi mcd3: call mcf mcd4: ret ; Mouse Coordinates to Position in Text mcm: mov edi,txtb; move to correct row mov ecx,my shr ecx,4 cmp ecx,0 je mcm3 dec edi mcm2: inc edi cmp byte ptr[edi],0 jne mcm2 dec ecx jne mcm2 inc edi mcm3: mov txtc,edi mov ecx,mx; move to correct column mcm4: inc edi movzx edx, byte ptr[edi] cmp dl,0 je mcm5 cmp dl,208 jae mcm4 mov ebx,chrl movzx eax,byte ptr[ebx+edx] sub ecx,eax sub ecx,eax jge mcm4 mcm5: mov txtc,edi ret ; **** Assembler **** asm: mov stb,esp mov eax,jpb mov jpc,eax mov eax,labelb mov labelc,eax mov eax,callb mov callc,eax mov eax,varb mov varc,eax call rsline mov esi,txta asm0: cmp esi,txta je asm1 cmp byte ptr[esi],0D8h jne asm2 asm1: call asmchk cmp eax,0 je asm2 mov txtm,esi push esi ;PrintHex esi ;cmp esi,809874h ;jb aaa1 ;invoke memex,esi,12 ;aaa1: nop call lns1 mov esi,lin mov eax,esi ;invoke memex,esi,50 ;PrintHex txta call a0; line assemble ;PrintHex txtc pop esi asm2: inc esi cmp byte ptr[esi],0 jne asm2 ;mov esi,806A5Bh ;.IF esi>=81B300h ; PrintHex esi ;invoke memex,esi,12 ;.endif ;jmp ast ;PrintHex edi inc esi cmp esi,txtz jb asm0 asm9: ;PrintHex edi ;call codex ;invoke memex,labelb,10 ;invoke memex,callb,6 ;PrintHex edi call calls ;call codex ;jmp ast mov eax,1 ret asmchk: push esi asmchk2: cmp byte ptr[esi],0D2h je asmchk1 inc esi cmp byte ptr[esi],0 jne asmchk2 pop esi mov eax,1 ret asmchk1: mov byte ptr[esi],20h PrintHex asmchk1 pop esi mov eax,1 ret ;invoke memex,esi,10 ;jmp ast a0: add esi,12 ;invoke memex,esi,54; line assembly mov ebx,esi sub ebx,4 ; insert space at line end a001: add ebx,4 cmp byte ptr[ebx],0 jne a001 mov eax,[ebx] mov dword ptr[ebx+4],eax mov dword ptr[ebx+8],0 mov byte ptr[ebx],32 ;invoke memex,esi,54 a002: cmp byte ptr[esi],2Ah; => green star line jne a0029 cmp byte ptr[esi+1],14 jne a0029 pushad call ag0 popad ret a0029: nop a003: sub esi,4; real numbers line a0031: add esi,4 cmp byte ptr[esi],32 je a0031 cmp byte ptr[esi],1Fh jne a0039 cmp byte ptr[esi+4],1Fh jne a0039 push esi add esi,8 call re0 pop esi ret a0039: nop a01: sub esi,4 a02: add esi,4 cmp byte ptr[esi],32; move across non-live or spaces je a02 cmp byte ptr[esi+2],7; immediate text display je a03 cmp byte ptr[esi+2],8; live-assembler line? jne a02 cmp byte ptr[esi],0 je a09 a03: call MolAsm jmp a01 a09: ;call codex ;jmp ast ;invoke memex,callb,12 ;invoke memex,esi,10 ret ; atom: b0: 0=reg 1=mem 2=mem+index 3=imm 4=call label ; b1: MRM b2:SIB b3: operation (link) ; b4: displacement, immediate value or label line address ; molecule overhead at MSgn,MLen MolAsm: mov ebx,mol; Assemble molecule mov MSgn,0 ; default long unsigned mov MLen,1; 0=byte, 1=long (fp: 0=32-bit, 1=64-bit) mov MWord,0; 0=long,1=word mov QOp,0; quad operation mov FPInt,0; FP type 0=64-bit real, 1=64-bit integer (i) mov SJump,0; 0=return from s/r, 1=jump with no return cmp byte ptr[esi+2],7 je ImmTxt mov dh,[esi+1] cmp dh,9 je am9 ma0: ;mov ebx,mol mov al,0 sub esi,4 ma1: add esi,4 call Atom; incorporating prescripts cmp byte ptr[ebx],255; not an atom (assembled by "Atom") je ma9 ; e.g.red labels, immediate data add ebx,8 ma2: mov al,[esi] ;cmp al,0 ;je ma3 cmp al,32 je ma3 mov al,[esi] mov ah,[esi+1] cmp ah,11 je ma1 ma3: mov dword ptr[ebx],0 cmp al,1Fh je MExtend; movx; fails or jumps back to ma4 push esi call MolOut pop esi ma4: cmp byte ptr[esi],32 je ma9 ;cmp byte ptr[esi],0 ;je ma9 call MolPost jmp ma4 ma9: ret Atom: mov dword ptr[ebx],0 mov dword ptr[ebx+4],0 mov [ebx+3],al at0: mov dl,[esi] mov dh,[esi+1] cmp dh,6 je at6 cmp dh,15 je at15 cmp dh,4 je at4 cmp dh,10 je at10 cmp dh,5 je at5 cmp dh,3 je at3 cmp dh,14 je at14 cmp dh,11 je at11 jmp ast at3: mov byte ptr[ebx],4 xor ecx,ecx; check for resource subroutine xor edx,edx cmp byte ptr[esi+5],11; cursor movers? je at3c .IF byte ptr[esi]=="r"; repeat move/store cmp byte ptr[esi+4],"m" je at3r cmp byte ptr[esi+4],"s" je at3r .ENDIF cmp byte ptr[esi+5],4; print/input? jne at31 cmp byte ptr[esi+4],32 je at31 cmp byte ptr[esi],"I" je at3i ;Print Routines ;Extra Byte: (see N) at3p: mov [ebx+16],esi add esi,8 ;Atom Output code call Atom; get following atom call OpPush; push it mov byte ptr[edi],0FFh mov byte ptr[edi+1],55h mov byte ptr[edi+2],-20 ; set a call to [ebp-20] call atExtra mov [edi+3],dl add edi,4 add esp,4; Exit Atom procedure, go to ma4 jmp ma4 at3r: cmp byte ptr[esi+8],32 jne ast mov byte ptr[edi],0FCh; cld mov byte ptr[edi+1],0F3h; rep mov byte ptr[edi+2],0A5h; movsd cmp byte ptr[esi+4],"m" je at3r9 mov byte ptr[edi+2],0ABh; stosd cmp byte ptr[esi+4],"s" jne ast at3r9: add esi,8 add edi,3 add esp,4 jmp ma4 ;Output Extra Atom (follows [ebp-20]) ; bit 3 byte/long, bits 0-2 CDDXS (pkey) 1 D unsigned, 2 D signed atExtra: mov ebx,[ebx+16] movzx eax,byte ptr[ebx] lea ecx,pkey xor edx,edx dec edx atE1: inc edx cmp al,[ecx+edx] jne atE1 cmp dl,1 jne atE2 cmp MSgn,0 je atE2 inc edx atE2: cmp byte ptr[ebx+4],1Fh jne atE3 add dl,8 atE3: ;PrintHex edx ret ; Assemble input molecule at3i: mov byte ptr[edi],0FFh mov byte ptr[edi+1],55h mov byte ptr[edi+2],-24 ; set a call to [ebp-24] .IF byte ptr[esi+4]==1Ch mov byte ptr[edi+2],-28 .ENDIF add edi,3 add esi,8 call Atom call OpPop ;invoke memex,ebx,12 ;jmp ast ;mov al,0; /0 + r/m = string, /1 + r/m = value ;.IF byte ptr[esi-4]==1Fh ;mov al,1 ;.ENDIF ;mov ecx,ebx ;call CAtom add esp,4; Exit Atom procedure, go to ma4 jmp ma4 ;call codex ;jmp ast at3c: lea edx,RunCursor; run cursor atom; set [ebp] memory atom mov MLen,0; byte length overrule movzx ecx,byte ptr[esi] movzx eax,byte ptr[edx+ecx-97] dec eax mov byte ptr[ebx],1; register indirect mov byte ptr[ebx+1],5; ebp sub eax,44 mov [ebx+4],eax; index -44 to -41 for b,c,x,y add esi,4 ret at31: shl edx,8 mov dl,[esi+ecx] add ecx,4 cmp byte ptr[esi+ecx],32 je at32 cmp byte ptr[esi+ecx+1],3 je at31 at32: test edx,0FF000000h jne at321 shl edx,8 jmp at32 at321: ;PrintHex edx bswap edx mov eax,linr ;invoke memex,eax,6 sub eax,4 at33: add eax,4 cmp dword ptr[eax],0 je at35 cmp edx,[eax] jne at33 add esi,ecx; Resource routine found mov byte ptr[ebx+1],1 sub eax,linr shr eax,2 mov [ebx+4],eax ret at35: ;PrintHex ecx mov ecx,callc; write call label mov byte ptr[ebx+1],0 mov [ebx+4],ecx call albl mov callc,ecx ret ImmTxt: ;PrintHex ImmTxt; called direct by MolAsm mov byte ptr[edi],0FFh; Assemble Immediate Text mov byte ptr[edi+1],55h mov byte ptr[edi+2],-20 ; set a call to [ebp-20] xor cl,cl mov ch,1 add edi,3 mov edx,edi inc edi imt1: mov al,[esi] inc cl cmp ch,[esi+1] je imt11 mov ch,[esi+1] mov ah,ch add ah,0D0h mov [edi],ah inc edi inc cl imt11: mov [edi],al inc edi add esi,4 cmp byte ptr[esi+2],7 je imt1 cmp cl,16 jae imt2 add cl,80h mov [edx],cl ret imt2: mov byte ptr[edx],80h mov byte ptr[edi],0 inc edi ret at5: cmp dl,7; Open Condition jne at50 add esi,4 cmp byte ptr[esi],63 jne ast mov byte ptr[ebx+3],63 add esi,4 jmp at0 at50: cmp dl,5 jne at51 mov SJump,1 add esi,4 jmp at0 at51: cmp dl,9; Open Loop (repeat) jne at52 mov eax,jpc mov [eax],edi add jpc,4 add esi,4 jmp at0 at52: cmp dl,63; "Until" or "Exit" molecule jne at59 mov byte ptr[ebx+3],63 add esi,4 jmp at0 at59: jmp atbrk atbrk: mov al,[esi] sub al,30h cmp al,9 jbe atb1 sub al,10h cmp al,26 jbe atb1 sub al,20h cmp al,26 jbe atb1 call codex jmp ast atb1: mov byte ptr[edi],0FFh; set [ebp-32]; set break routine mov byte ptr[edi+1],55h mov byte ptr[edi+2],0E0h mov al,[esi] mov [edi+3],al mov al,[esi+4] mov [edi+4],al add edi,5 add esi,8 ;call codex ;jmp ast add esp,4 jmp ma4 at6: movzx ecx,dl; Register Direct .IF dl==54h mov byte ptr[ebx],5 add esi,4 ret .ENDIF lea eax,RegChar mov dl,[eax+ecx-65] mov byte ptr[ebx],0 add dl,0C0h mov [ebx+1],dl add esi,4 ret at15: mov byte ptr[ebx],3 cmp byte ptr[esi],41h jae at151 mov ch,30h; Immediate call anz0 mov [ebx+4],eax ret at151: mov byte ptr[ebx+1],1; immediate label mov ecx,callc; write call label mov [ebx+4],ecx; list address of label call albl mov callc,ecx ;PrintHex ecx ret at4: cmp byte ptr[esi],1Ch; signed or length symbol jne at41 mov MLen,0 mov ImmLen,1 add esi,4 jmp at0 at41: cmp byte ptr[esi],82h; sign symbol jne at411 mov MSgn,90h add esi,4 jmp at0 at411: cmp byte ptr[esi],1Dh; word symbol jne at412 mov byte ptr[edi],66h; set word prefix mov ImmLen,2 mov MWord,1 ;PrintHex at411 inc edi add esi,4 jmp at0 at412: .IF byte ptr[esi]==71h; set quad prefix (64-bit mul/div) inc QOp add esi,4 jmp at0 .ELSEIF byte ptr[esi]==1Fh mov ImmLen,4 add esi,4 jmp at0 .ELSEIF byte ptr[esi]==69h; set FP Integer prefix mov FPInt,1 add esi,4 jmp at0 .ENDIF at413: ; Maths Type (fsinD9FE,fcosD9FF,ftanD9F2,fsqrD9FA,atnD9F3) mov ecx,12 cmp byte ptr[esi+12],54h jne at4139 cmp byte ptr[esi+13],6 jne at4139 ;PrintHex at413 at4131: sub ecx,4 cmp byte ptr[esi+ecx],20h je at4139 cmp byte ptr[esi+ecx+1],4 jne at4139 cmp ecx,0 jne at4131 mov byte ptr[ebx],255 mov byte ptr[edi],0D9h .IF byte ptr[esi+4]==71h mov al,0FAh .ELSEIF byte ptr[esi]==61h mov al,0F3h .ELSEIF byte ptr[esi]==74h mov al,0F2h .ELSEIF byte ptr[esi]==63h mov al,0FFh .ELSEIF byte ptr[esi]==73h mov al,0FEh .ELSE ;PrintHex at4131 jmp ast .ENDIF mov [edi+1],al add edi,2 add esi,16 ;PrintHex at413 ret at4139: nop at42: mov ecx,esi; Text type cmp byte ptr[esi-4],32 jne at421 at420: add ecx,4 cmp byte ptr[ecx],32 je at422 cmp byte ptr[ecx+1],4 je at420 at421: mov byte ptr[ebx],3; immediate ascii type xor edx,edx at4211: shl edx,8 movzx eax,byte ptr[esi] add edx,eax add esi,4 cmp byte ptr[esi],32 je at4212 cmp byte ptr[esi+1],4 je at4211 at4212: mov [ebx+4],edx ret at422: mov byte ptr[ebx],255 ;data ascii type (spaces at both ends) at4221: mov al,[esi] mov [edi],al inc edi add esi,4 cmp byte ptr[esi],32 jne at4221 mov byte ptr[edi],0 inc edi ret at14: push edi call v0 pop edi ;invoke memex,ebx,8 jmp at101a v0: mov txtml,esi mov edi,varc; copy variable to end of variable list add edi,8 mov dword ptr[edi],0 v1: mov al,[esi]; (to ensure a match) mov [edi],al inc edi add esi,4 cmp byte ptr[esi],32 je v2 cmp byte ptr[esi+1],14 je v1 v2: push esi mov byte ptr[edi],0 inc edi at1401: ;sub ecx,4 ;mov eax,[esi+ecx] ;mov [edi+ecx],eax ;cmp ecx,8 ;jne at1401 mov dword ptr[edi],0 mov edi,varb sub edi,4 mov dword ptr[edi],4 mov esi,varc ;call regex ;invoke memex,labelb,40 ;jmp ast mov edx,[esi+8] v3: movzx eax,byte ptr[edi] add edi,eax ;add edi,[edi] ; compare first four bytes cmp edx,[edi+8] ; (predictable fail) jne v3; fail => next label mov ecx,10 v4: inc ecx; search for zero match mov al,[esi+ecx] cmp al,[edi+ecx] jne v3 cmp al,0; next letter jne v4 v5: ; label found (is it copied from call?) ; PrintHex v5 cmp dword ptr[edi],0 je v8 pop esi mov al,[edi+1]; set molecule length shr al,2 mov MLen,al mov eax,[edi+4]; set displacement mov [ebx+4],eax mov byte ptr[ebx],1; set indirect mov byte ptr[ebx+1],5; from base pointer ret v8: ;PrintHex esi; no label match found; undefined variable ;PrintHex v8 ;invoke memex,esi,12 pushad mov edi,txtm push edi mov ecx,5 v82: call mtu dec ecx jne v82 mov txtb,edi pop edi mov ecx,txtml sub ecx,lin shr ecx,2 v83: inc edi .IF byte ptr[edi]<0D0h dec ecx .ENDIF or ecx,ecx jne v83 mov txtc,edi popad ;mov txtc, ;mov eax,esi ;sub eax,lin jmp astv v9: ret at10: ;invoke memex,esi,4 ;jmp ast cmp byte ptr[esi],27; Register indirect ja at100 mov al,[esi]; Pre-Inc/Dec add esi,4 movzx ecx, byte ptr[esi] lea edx,RegChar mov ah,[edx+ecx-65] call cai at100: movzx ecx, byte ptr[esi] lea eax,RegChar mov dl,[eax+ecx-65] mov byte ptr[ebx],1 mov [ebx+1],dl mov dword ptr[ebx+4],0 at101: add esi,4 at101a: mov al,[esi]; at14 comes in here mov ah,[esi+1] cmp al,32 je at109 cmp al,0 je at109 .IF ah==10; Post Inc/Dec ;invoke memex,esi,4 mov [ebx+2],al jmp at101 .ENDIF cmp ah,6 jne at102 movzx ecx,al; Index Register, set Scaled Index (SIB) lea eax,RegChar mov dl,[eax+ecx-0B1h] shl dl,3 add dl,[ebx+1] mov byte ptr[ebx],2 mov byte ptr[ebx+1],4 ; scale*40h can be added to dl here mov [ebx+2],dl jmp at101 at102: nop cmp ah,11; color 11 jne at103 cmp al,1Ah; sub plus (skip) je at101 cmp al,1Bh; sub minus ;collect disp and make negative jne at109 ; any other color 11, end atom add esi,4 mov ch,10h call anz0 neg eax mov [ebx+4],eax jmp at101a at103: cmp ah,15; Displacement? jne at109 mov ch,10h call anz0 add [ebx+4],eax jmp at101a at109: ;invoke memex,mol,8 ret at11: cmp byte ptr[esi],9Ch je atpush cmp byte ptr[esi],9Dh je atpop at11f: call codex jmp ast atpush: add esp,4 add esi,4 cmp byte ptr[esi],32 je atpusha lea edx,RegChar atpush1: cmp byte ptr[esi+1],6 jne atpushm movzx eax,byte ptr[esi] mov cl,[edx+eax-41h] add cl,50h mov [edi],cl inc edi add esi,4 cmp byte ptr[esi],32 jne atpush1 jmp ma4 atpusha: mov byte ptr[edi],60h inc edi jmp ma4 atpushm: call Atom call OpPush jmp ma4 atpop: add esp,4 atpop0: add esi,4 cmp byte ptr[esi],32 je atpopa cmp byte ptr[esi+1],5 je atpopa cmp byte ptr[esi+1],6 jne atpopm mov [ebx+16],esi; pop in reverse order atpop1: add esi,4 cmp byte ptr[esi],32 jne atpop1 lea edx,RegChar push esi atpop2: sub esi,4 movzx eax,byte ptr[esi] mov cl,[edx+eax-41h] add cl,58h mov [edi],cl inc edi cmp esi,[ebx+16] jne atpop2 pop esi jmp ma4 atpopa: mov byte ptr[edi],61h inc edi jmp ma4 atpopm: call Atom call OpPop jmp ma4 MolOut: cmp byte ptr[esi],10 je MUntil mov esi,ebx mov ebx,mol ;invoke memex,ebx,8 ;jmp ast mov dl,[esi-5]; Molecule Move, Set or Op cmp dl,5 je MMove mov dl,[ebx+3] cmp dl,63 je MTest mov dl,[ebx+11] cmp dl,61 je MSet cmp dword ptr[ebx+8],0 je MEl jmp MOp MEl: ; Single atom molecule ; invoke memex,esi,4 ;invoke memex,ebx,4 ;call codex ;invoke memex,lin,8 cmp byte ptr[ebx],3 je ImmDat cmp byte ptr[ebx],4; relative call jne ast mov ecx,[ebx+4]; Transfer label to call list cmp byte ptr[ebx+1],1 je MElr mov byte ptr[edi],0E8h; E8 for call, E9 for jump; see MolAsm, at50 mov al,SJump add [edi],al inc edi mov [ecx+4],edi mov dword ptr[edi],-1 add edi,4 ret MElr: ; resource s/r call mov byte ptr[edi],0FFh mov byte ptr[edi+1],95h; amended from 55h mov eax,[ebx+4] inc eax shl eax,2 add eax,100h; resource s/r #1,2.. to -260,-264,.. neg eax mov [edi+2],eax ; amended from al add edi,6; amended from ,3 ;invoke memex,ebx,3 ;call codex ;jmp ast ret ;mov byte ptr[edi],0FFh ;mov byte ptr[edi+1],24h mov byte ptr[edi],0E8h add edi,5 mov eax,[ebx+4] imul eax,5 add eax,401202h ;PrintHex eax sub eax,edi ;invoke memex,eax,4 ;jmp ast mov [edi-4],eax ret ImmDat: mov al,[ebx+4] mov [edi],eax movzx eax,ImmLen add edi,eax ret ; Read label, call or variable to [ecx]; moves on ecx ; b0, record length; b4, code location; b8ff characters (nl/t) ; called by Atom routine at3 albl: mov edx,ecx add ecx,7 inc ecx mov ah,[esi+1] albl1: mov al,[esi] mov [ecx],al add esi,4 inc ecx cmp [esi+1],ah jne albl2 cmp byte ptr[esi],30h jae albl1 albl2: mov byte ptr[ecx],0; nulls up to dword boundary inc ecx mov eax,ecx and eax,3 jne albl2 mov eax,ecx sub eax,edx mov [edx],eax ret MOp: ; Operations on Destination: A +B (+C..) type mov ebx,mol mov esi,ebx add esi,8 mop1: call Op add esi,8 cmp dword ptr[esi],0 jne mop1 ;call codex ret MUntil: mov ebx,mol; !! but may be unconditional backjump, or end of for-next loop lea esi,[ebx+8] ;invoke memex,ebx,6 ;jmp ast call Op xor cl,1 ; write branch back instruction mov [edi],cl add edi,2 sub jpc,4 mov eax,jpc mov ecx,[eax] sub ecx,edi mov [edi-1],cl ret MTest: ; IF: Test Src on Dest: C type mov esi,mol call Move add esi,8 cmp esi,ebx je mm9 mm1: call Op add esi,8 cmp esi,ebx jne mm1 mm9: ret MSet: lea esi,[ebx+8]; set Destination = Source(s): C = A (+B) type call Move ms1: add esi,8 cmp dword ptr[esi],0 je ms9 ;invoke memex,ebx,8 call Op jmp ms1 ms9: ;call codex ret MExtend: ;fails or returns to ma4 mov ebx,mol mov byte ptr[edi],0Fh mov al,0B6h add al,MLen cmp MSgn,0 je mx1 add al,8 mx1: mov [edi+1],al add edi,2 cmp dword ptr[ebx+16],0 jne mx9 cmp byte ptr[ebx+11],5 jne mx9 cmp byte ptr[ebx+8],0 jne mx9 push esi mov al,[ebx+9] and al,7 mov ecx,ebx call CAtom pop esi add esi,4 jmp ma4 mx9: PrintHex MExtend jmp ast jmp ma4 Op: movzx edx,byte ptr[esi+3]; Operate atom at [esi] on atom at [ebx] cmp byte ptr[ebx],5 je opf lea eax,OpChar add eax,MSgn mov cl,[eax+edx] ;call regex cmp cl,20h jl op1 cmp cl,30h jl op2 cmp cl,37h je OpDiv cmp cl,35h je OpMul cmp cl,70h jl op3 push ecx mov cl,17h; comparison call op1 pop ecx ;call codex ;jmp ast ret op3: ret op1: sub cl,10h ; type 1 (+-&oe,cmp) mov ch,[esi] ;call regex cmp ch,3 je opi cmp byte ptr[ebx],0 je opr cmp byte ptr[esi],0 jne m0m opm: shl cl,3; Source Register add cl,MLen mov [edi],cl inc edi mov al,[esi+1] mov ecx,ebx call CAtom ret opr: shl cl,3; Operate on Register add cl,2 add cl,MLen mov [edi],cl inc edi mov al,[ebx+1] mov ecx,esi call CAtom ret opi: mov eax,[esi+4]; operate with immediate cmp eax,1 jne opi01 cmp cl,0; increment je OpInc cmp cl,5; decrement je OpDec opi01: mov dl,80h; imm opcode add dl,MLen; length cmp eax,80h jae opi1; ext length if long instr and imm<80h cmp dl,81h jne opi1 mov dl,83h opi1: mov [edi],dl inc edi push eax push edx mov al,cl mov ecx,ebx call CAtom pop edx pop eax ;shl cl,3; !!! displacements, indices where`s the CAt! ;add cl,[ebx+1] ;mov [edi],cl ;inc edi mov [edi],al inc edi cmp dl,81h jne opi2 dec edi mov [edi],eax add edi,4 opi2: ;call codex ret m0m: ; memory on memory (via accumulator) push ecx mov al,8Ah; source to accumulator add al,MLen mov [edi],al inc edi mov al,0 mov ecx,esi call CAtom pop ecx shl cl,3; accumulator on destination memory add cl,MLen mov [edi],cl inc edi mov al,0 mov ecx,ebx call CAtom ret op2: sub cl,20h mov ch,[esi]; shifts and rotates cmp ch,3 je op23 cmp ch,0 jne op24 cmp byte ptr[esi+1],0C1h je op25 op24: push ecx mov byte ptr[edi],0Fh; movzx (byte) source into C mov byte ptr[edi+1],0B6h add edi,2 mov al,1 mov ecx,esi call CAtom pop ecx op25: mov al,0D2h; operate with C add al,1; (long override) mov [edi],al inc edi mov al,cl mov ecx,ebx call CAtom ret op23: mov al,0C0h; immediate add al,MLen mov [edi],al inc edi mov al,cl mov ecx,ebx call CAtom mov al,[esi+4] mov [edi],al inc edi ret OpInc: mov ch,0FEh add ch,MLen mov cl,40h mov ah,0 call OpPP ret OpDec: mov ch,0FEh add ch,MLen mov cl,48h mov ah,1 call OpPP ret OpPush: mov ch,0FFh mov cl,50h mov ah,6 call OpPP ret OpPop: mov ch,8Fh mov cl,58h mov ah,0 call OpPP ;call codex ;jmp ast ret OpPP: cmp byte ptr[ebx],0; Register jne OpPP1 mov al,[ebx+1] and al,7 add al,cl mov [edi],al inc edi ret OpPP1: mov [edi],ch; Memory inc edi mov al,ah mov ecx,ebx call CAtom ret OpDiv: ;PrintHex OpDiv .IF QOp==0; unless quadword op, extend A into D mov byte ptr[edi],99h; (if qop, D must be set manually) inc edi .ENDIF cmp byte ptr[esi],3 je opd2 mov byte ptr[edi],0F7h inc edi mov al,7 mov ecx,esi call CAtom ret opd2: mov byte ptr[edi],0B9h; move imm to ecx mov eax,[esi+4] mov [edi+1],eax mov byte ptr[edi+5],0F7h; divide by ecx mov byte ptr[edi+6],0F9h add edi,7 ret OpMul: ;PrintHex OpMul cmp QOp,0 jne mulq cmp byte ptr[esi],3 je mulimm mulmem: mov byte ptr[edi],0Fh mov byte ptr[edi+1],0AFh add edi,2 mov al,[ebx+1] and al,7 mov ecx,esi call CAtom ret mulimm: cmp byte ptr[ebx],0 jne ast mov edx,[esi+4] add edx,80h cmp edx,100h jae mulimml mulimmb: mov byte ptr[edi],6Bh; R32ximm8 inc edi mov al,[ebx+1] and al,7 mov ecx,ebx call CAtom mov al,[esi+4] mov [edi],al inc edi ret mulimml: mov byte ptr[edi],69h; R32ximm32 inc edi mov al,[ebx+1] and al,7 mov ecx,ebx call CAtom mov eax,[esi+4] mov [edi],eax add edi,4 ret mulq: mov byte ptr[edi],0F7h inc edi mov al,5 mov ecx,esi call CAtom ret opf: ;Add64real DC/0; Sub DC/4; Mul DC/1; Div DC/6; DivR DC/7; DC/2 Cmp .IF dl==2Bh mov al,0 .ELSEIF dl==2Dh mov al,4 .ELSEIF dl==80h mov al,1 .ELSEIF dl==81h mov al,6 .ELSE jmp ast .ENDIF cmp byte ptr[esi],3 je opfimm mov byte ptr[edi],0DCh inc edi mov ecx,esi call CAtom ret opfimm: ; source immediate, write source via [ebx] mov dl,al shl dl,3 mov byte ptr[edi],0C7h mov byte ptr[edi+1],03h mov eax,[esi+4] mov [edi+2],eax mov byte ptr[edi+6],0DAh mov byte ptr[edi+7],03h add [edi+7],dl add edi,8 ret Move: ; Move atom at [esi] to atom at [ebx] ;call regex ;invoke memex,mol,8 mov ch,[esi] cmp ch,3 je mvi; immediate cmp ch,5 je mvfs; store fp register cmp ch,0 je mvw; write reg to reg/mem (R=>M/R) mov cl,[ebx]; read reg/mem [esi] to reg [ebx] (M/R=>R) cmp cl,0 je mvr cmp cl,5; load fp register je mvfl jmp mtom; non-register (mem to mem) mvr: mov al,8Ah; R/M to Register add al,MLen mov [edi],al inc edi mov al,[ebx+1]; register mov ecx,esi call CAtom ret mvw: mov al,88h; Register to R/M add al,MLen mov [edi],al inc edi mov al,[esi+1] mov ecx,ebx call CAtom ret mvi: cmp byte ptr[ebx],5 je mvfi mov al,[ebx+1]; immediate cmp al,0C0h jb mviM mviR: and al,7; to register cmp dword ptr[esi+4],0 je mviRZ; clear register? add al,0B0h mov [edi],al inc edi cmp MLen,0 je mviB add byte ptr[edi-1],8; long reg opcode mviL: cmp byte ptr[esi+1],1; long label? je mvilab mov eax,[esi+4]; long non-label mov [edi],eax add edi,4 ret mvilab: mov ecx,[esi+4]; immediate label mov [ecx+4],edi; set list mov dword ptr[edi],-2; set code add edi,4 ret mviB: mov al,[esi+4]; byte mov [edi],al inc edi ret mviRZ: mov ah,30h; clear register al add ah,MLen mov [edi],ah; opcode mov ah,al shl ah,3 add al,ah add al,0C0h mov [edi+1],al; xor reg,reg add edi,2 ret mviM: mov al,0C6h; immediate to memory add al,MLen mov [edi],al inc edi mov al,0 mov ecx,ebx call CAtom cmp MLen,0 je mviB jmp mviL mtom: mov al,8Ah; source to accumulator add al,MLen mov [edi],al inc edi mov al,0 mov ecx,esi call CAtom mov al,88h; accumulator to destination add al,MLen mov [edi],al inc edi mov al,0 mov ecx,ebx call CAtom ret mvfi: ; Push integer to FP unit, via [ebx] mov byte ptr[edi],0C7h mov byte ptr[edi+1],03h mov eax,[esi+4] mov [edi+2],eax mov byte ptr[edi+6],0DBh mov byte ptr[edi+7],03h add edi,8 ret mvfl: ; Push MemReal64[DD/0] or MemInt64[DF/5] to FP unit mov byte ptr[edi],0DDh .IF MLen==0 mov byte ptr[edi],0D9h .ENDIF mov al,0 .IF FPInt==1 mov byte ptr[edi],0DFh mov al,5 .ENDIF inc edi mov ecx,esi call CAtom ;PrintHex mvf ret mvfs: ; Pop FPReg to MemReal64[DD/3] or MemInt64[DF/7] mov byte ptr[edi],0DDh mov al,3 .IF FPInt==1 mov byte ptr[edi],0DFh mov al,7 .ENDIF inc edi mov ecx,ebx call CAtom ret ; code atom at [ecx]. Collect bits 3-5 (reg/op) from al (0-7) CAtom: and al,7 shl al,3 add al,[ecx+1] mov ah,[ecx] mov edx,[ecx+4] push ecx ;If ah=2 write SIB and set c=2, else set c=1 cmp ah,2 jne ca2 push eax mov al,[ecx+2] mov [edi+1],al pop eax mov ecx,2 jmp ca3 ca2: mov ecx,1 ca3: ;call regex cmp edx,0; ? displacement je ca1 add al,40h ;call regex mov [edi+ecx],dl inc ecx cmp edx,80h ; ? 32-bit displacement jb ca1 cmp edx,0FFFFFF80h jae ca1 add al,40h mov [edi+ecx-1],edx add ecx,3 ca1: mov [edi],al add edi,ecx pop ecx cmp byte ptr[ecx+2],0; post inc/dec je ca5 cmp byte ptr[ecx],1 jne ca5 mov al,[ecx+2] mov ah,[ecx+1] and ah,7 call cai ;call codex ;jmp ast ca5: ret cai: sub al,26; al: inc=26 dec=27; ah: register (0-7) ;PrintHex eax cmp al,1 ja ast cmp MLen,0; called by at10(pre) or CAtom(post) jne cail shl al,3; short increment/decrement add al,40h add al,ah mov [edi],al inc edi ret cail: mov byte ptr[edi],83h; add 4 to long register add ah,0C0h; to long register .IF al==1 add ah,28h; or subtract 4 .ENDIF mov [edi+1],ah mov byte ptr[edi+2],4 .IF MWord==1 mov byte ptr[edi+2],2 .ENDIF add edi,3 ret codex: push edi mov edi,codebase add edi,10000h invoke memex,edi,800 pop edi ret ast: mov esp,stb invoke memex,lin,64 xor eax,eax ret astv: mov esp,stb; undefined variable xor eax,eax ret MolPost: ;invoke memex,esi,4 cmp byte ptr[esi+1],5 jne mpost1 cmp byte ptr[esi],2Eh je mpret cmp byte ptr[esi],8 je mpccn cmp byte ptr[esi],10 je mpuntil mpost1: cmp byte ptr[esi+1],4 jne mpost2 cmp byte ptr[esi],76h; byte inversion je mpswap cmp byte ptr[esi],26; absolute je mpabs cmp byte ptr[esi],77h; low word inversion je mpswapw nop mpost2: mpret9: ret mpswap: movzx edx,byte ptr[esi-4] lea ecx,RegChar mov al,[ecx+edx-41h] mov byte ptr[edi],0Fh add al,0C8h mov [edi+1],al add edi,2 add esi,4 ret mpswapw: mov byte ptr[edi],66h; insert rol dx,8 mov byte ptr[edi+1],0C1h movzx edx,byte ptr[esi-8] lea ecx,RegChar mov al,[ecx+edx-41h] add al,0C0h mov [edi+2],al mov byte ptr[edi+3],08h add edi,4 add esi,4 ret mpabs: movzx edx,byte ptr[esi-4] lea ecx,RegChar mov al,[ecx+edx-41h] ;PrintHex eax mov ah,08h; or reg,reg, caution; generates unpredictable branch add ah,MLen mov [edi],ah mov ah,al shl ah,3 add ah,al add ah,0C0h mov [edi+1],ah mov byte ptr[edi+2],7Dh ; jge +2 mov byte ptr[edi+3],2 mov ah,0F6h; neg reg add ah,MLen mov [edi+4],ah add al,0D8h mov [edi+5],al add edi,6 add esi,4 ret mpret: mov byte ptr[edi],0C3h; return from call inc edi add esi,4 ret mpuntil: add esi,4; !? examine molecule; may be unconditional or for-next ret mpccn: push edi ; close condition mov ecx,edi sub jpc,4 mov eax,jpc cmp eax,jpb jb mpccnf ;PrintHex jpc ;invoke memex,jpc,4 mov edi,[eax] sub ecx,edi ;PrintHex ecx mov [edi-1],cl pop edi ;call codex ;jmp ast add esi,4 ret mpccnf: mov esp,stb mov esi,txtm mov txtb,esi mov txtc,esi mov eax,0 ret at9: ret setlabel: mov ecx,labelc; write label definition (red) mov [ecx+4],edi call albl mov labelc,ecx ret ; Red label or ORG am9: mov dl,[esi]; Color 9 cmp dl,41h jae setlabel mov ch,30h call anz0 add eax,codebase mov edi,eax mov eax,1 ret ;Read Number (ch=30h std, 10h subscripted) anz0: mov al,[esi] movzx eax,al cmp al,24h je anh sub al,ch; Decimal number an1: add esi,4 mov cl,[esi] sub cl,ch cmp cl,9 ja an9 an2: mov edx,10 mul edx movzx edx,cl add eax,edx add esi,4 mov cl,[esi] sub cl,ch cmp cl,9 jbe an2 an9: cmp byte ptr[esi],73h; s for 64k segments jne an91 shl eax,16 add esi,4 an91: ret anh: xor eax,eax anh1: add esi,4 mov cl,[esi] sub cl,30h cmp cl,9 jbe anh2 cmp cl,16h ja anh9 sub cl,7 anh2: shl eax,4 add al,cl jmp anh1 anh9: jmp an9 ; Variables: 0 table entry length, 1 1/2/4 b/w/l, ; 4 displacement, 8ff characters (null/dword terminated) ; displacement increments by element length unless overruled ag0: ;invoke memex,esi,20 mov edi,varc ag1: add esi,4 cmp byte ptr[esi],32 je ag1 cmp byte ptr[esi],0 je ag9 mov NegVal,0 .IF byte ptr[esi]==2Dh mov NegVal,1 add esi,4 .ENDIF cmp byte ptr[esi+1],15 jne ag11 mov ch,30h call anz0 mov edx,eax .IF NegVal!=0 neg edx .ENDIF ;PrintHex edx jmp ag1 ag11: mov al,4 cmp byte ptr[esi+1],4 jne ag2 mov al,[esi] sub al,1Bh add esi,4 ag2: cmp al,4; align 32-bit elements jne ag21 add edx,3 ;or edx,3 ;sub edx,3 and edx,0FFFFFFFCh ag21: mov [edi+1],al movzx ebx,al mov [edi+4],edx mov ecx,8 ag3: mov al,[esi] mov [edi+ecx],al inc ecx add esi,4 cmp byte ptr[esi],32 je ag4 cmp byte ptr[esi+1],14 je ag3 cmp byte ptr[esi+1],15; array size overrule (may be 0) jne ast push ecx mov ch,10h push edx call anz0 pop edx ;invoke memex,esi,6 ;PrintHex eax pop ecx mov ebx,eax ag4: mov byte ptr[edi+ecx],0 inc ecx test ecx,3 jne ag4 mov [edi],cl add edx,ebx ;PrintHex edx movzx eax,cl add edi,eax jmp ag1 ag9: ;invoke memex,varb,200 mov varc,edi ret ; Real Number Assembler ; Write Number to real mem64 re0: mov ebx,mol mov [ebx+36],edi re00: finit mov ebx,mol mov dword ptr[ebx],0 mov dword ptr[ebx+4],0 mov dword ptr[ebx+8],0 .IF byte ptr[esi]==2Dh mov byte ptr[ebx+9],80h add esi,4 .ENDIF .IF byte ptr[esi]==50h; special case PI fldpi fstp qword ptr[edi] add edi,8 add esi,8 jmp re04 .ENDIF mov ecx,0 mov edx,0 re01: add esi,4 .IF byte ptr[esi]==45h ; exponent push esi call reexp mov [ebx+32],esi pop esi sub esi,4 jmp re02 .ENDIF cmp byte ptr[esi],20h jne re01 mov [ebx+32],esi; mark number end sub esi,4 re02: mov al,[esi] .IF al==2Eh ; mark decimal point mov ch,cl neg ch jmp re03 .ENDIF and al,15 mov ah,cl and ah,1 .IF ah==0 mov [ebx],al .ELSE shl al,4 add [ebx],al inc ebx .ENDIF add cl,1 re03: sub esi,4 cmp byte ptr[esi],2Dh ja re02 add ch,dl ; add exponent mov ebx,mol fbld [ebx] .IF ch!=0 mov dword ptr[ebx+24],10 mov dword ptr[ebx+28],100000000 re031: cmp ch,0 jg re032 add ch,8 fidiv dword ptr[ebx+28] jmp re031 re032: cmp ch,8 jl re033 sub ch,8 fimul dword ptr[ebx+28] jmp re032 re033: cmp ch,0 je re034 dec ch fimul dword ptr[ebx+24] jmp re033 re034: nop .ENDIF fstp qword ptr[edi] add edi,8 mov esi,[ebx+32] ;invoke memex,esi,8 re04: add esi,4 cmp byte ptr[esi],20h je re04 cmp byte ptr[esi],0 jne re00 ret mov edi,[ebx+36] invoke memex,edi,8 jmp ast ret reexp: add esi,4 mov dh,0 .IF byte ptr[esi]==2Dh mov dh,1 add esi,4 .ENDIF mov dl,[esi] and dl,15 add esi,4 .IF byte ptr[esi]!=20h movzx eax,dl imul eax,10 mov dl,al mov al,[esi] add esi,4 and al,15 add dl,al .ENDIF .IF dh==1 neg dl .ENDIF ret ; Match calls to labels ; copy call to dummy label at end of list ; (avoids need for end of list test and jump) calls: mov eax,callc mov dword ptr[eax],0 mov esi,callb cmp esi,callc je cal9 cal0: mov edi,labelc; copy call to end of label list ;PrintHex labelb ;PrintHex labelc ;PrintHex callb ;PrintHex callc mov ecx,[esi]; (to ensure a match) ;call regex ;jmp ast cal01: sub ecx,4 mov eax,[esi+ecx] mov [edi+ecx],eax cmp ecx,8 jne cal01 mov dword ptr[edi],0 mov edi,labelb sub edi,4 mov dword ptr[edi],4 ;call regex ;invoke memex,labelb,40 ;jmp ast mov edx,[esi+8] cal1: add edi,[edi] ; compare first four bytes cmp edx,[edi+8] ; (predictable fail) jne cal1; fail => next label mov ecx,10 cal3: inc ecx; search for zero match mov al,[esi+ecx] cmp al,[edi+ecx] jne cal1 cmp al,0; next letter jne cal3 ;PrintHex ecx ;call regex ;jmp ast cal4: ; label found (is it copied from call?) cmp dword ptr[edi],0 je cal8 mov eax,[edi+4] mov ebx,[esi+4] cmp dword ptr[ebx],-2; absolute? je cal41 sub eax,ebx; relative sub eax,4 ;invoke memex,esi,6 ;invoke memex,edi,6 ;invoke memex,labelb,160 ;PrintHex eax mov [ebx],eax ;call codex cal42: add esi,[esi]; next call ;PrintHex esi cmp esi,callc jb cal0 ret cal41: mov eax,[edi+4]; absolute mov [ebx],eax ;PrintHex cal41 jmp cal42 cal8: PrintHex esi; no label match found for call PrintHex cal8 PrintHex cal41 invoke memex,esi,40 jmp ast cal9: ret rsline: mov esi,txta rsl1: inc esi; search for red star cmp byte ptr[esi],0 jne rsl1 inc esi cmp byte ptr[esi],255 je rsl9 cmp byte ptr[esi+2],42 jne rsl1 cmp byte ptr[esi+1],0E9h jne rsl1 mov txtr,esi rsl2: call lns1 mov esi,lin add esi,20 mov ebx,linr rsl20: mov dword ptr[ebx],0 xor ecx,ecx rsl21: mov al,[esi] mov [ebx+ecx],al inc ecx add esi,4 cmp byte ptr[esi],32 jne rsl21 add ebx,4 rsl22: add esi,4 cmp byte ptr[esi],32 je rsl22 cmp byte ptr[esi],41h jae rsl20 mov dword ptr[ebx],0 rsl9: ;invoke memex,linr,40 ;jmp ast ret ; Collect Cursor Line Characters ; 0: line address, 4 txtc position, 8 next line address ; 8+4*nchr 0=char, 1=fgc, 2=bkc lns: pushad mov esi,txtc; locate start of line lns0: cmp esi,txta je lns01 dec esi cmp byte ptr[esi],0 jne lns0 inc esi lns01: call lns1 popad ret lns1: pushad; Write characters on line at esi to "lin" structure mov edi,lin mov [edi],esi add edi,12 mov lina,edi xor ecx,ecx lns2: cmp esi,txtc; cursor position in lin jne lns20 mov linc,edi lns20: mov dl,[esi] call lnsc mov dl,[esi] inc esi or dl,dl jne lns2 mov DWORD PTR[edi],0 mov edi,lin mov eax,linc mov [edi+4],eax mov [edi+8],esi popad ret lnsc: cmp dl,224 jb lnsc1 sub dl,224 mov bl,dl ret lnsc1: cmp dl,208 jb lnsc3 sub dl,208 mov bh,dl ret lnsc3: mov [edi],dl mov [edi+1],bl mov [edi+2],bh mov byte ptr[edi+3],0 add ecx,1 add edi,4 ret ; Restore line characters to text lnt: mov esi,lin ; line chrs to temp txt ;invoke memex,esi,16 ;mov ebx,[esi+4]; cursor character mov edi,txtt mov edx,0FFFFh add esi,12 lnt0: cmp [esi+2],dh; background change je lnt1 mov dh,[esi+2] mov [edi],dh add byte ptr[edi],208 inc edi lnt1: cmp [esi+1],dl; foreground change je lnt2 mov dl,[esi+1] mov [edi],dl add byte ptr[edi],224 inc edi lnt2: mov al,[esi]; character mov [edi],al cmp esi,linc; mark cursor chr jne lnt20 mov ebx,edi lnt20: inc edi add esi,4 cmp dword ptr[esi],0 jne lnt0 mov ecx,edi; new line byte length sub ecx,txtt mov esi,lin; old line byte length mov eax,[esi+8] sub eax,[esi] ;call regex ;mov edi,txtt ;invoke memex,edi,20 mov esi,txtt; make room for new text ;call regex mov edi,lin mov edi,[edi] sub ecx,eax call ttx lnt4: mov dl,[esi]; move in temp text cmp esi,ebx jne lnt5 mov txtc,edi lnt5: mov [edi],dl inc esi inc edi cmp dl,0 jne lnt4 ret ; Write Text to Bitmap Screen xtxt: pushad ;PrintHex xtxt mov eax,video; vc=v in mode 0 (text mode) mov videoc,eax mov sx,0 mov sy,0 mov tx,0 mov ty,0 mov ebx,txtb; Start at top of screen ;invoke memex,ebx,16 ;call regex bscw1: mov al,[ebx] ; For each line or al,al je bscw2 call bchw inc ebx jmp bscw1 ; Next Text Byte bscw2: call bchw ; Fill line inc ebx call ble mov sx,0 mov tx,0 inc ty add sy,16 cmp byte ptr[ebx],255 je bscw3 cmp sy,scy jb bscw1 ; Next Line bscw3: mov txtd,ebx; set screen end cmp sy,scy; clear any remaining screen je bscw32 bscw31: mov ecx,scx shr ecx,2 mov eax,sy imul eax,scx add eax,videoc mov edi,eax mov eax,0 rep stosd inc sy cmp sy,scy jne bscw31 bscw32: ;sub ebx,100 ;invoke memex,ebx,50 popad ret ; Write Character to Bitmap bchw: cmp al,224; Foreground color jb bchw1 sub al,224 mov fgc,al ret bchw1: cmp al,208; Background color jb bchw2 sub al,208 mov bkc,al ret bchw2: ;cmp al,128; Non-Font characters ;jb bchw3 ;ret bchw30: movzx ecx,al; Calculate screen position push ecx mov eax,sy mov edx,scx mul edx add eax,sx add eax,sx add eax,videoc; PrintEx call from this point mov edi,eax mov eax,ecx; Calculate font address mov edx,128 mul edx ;add eax,4000h mov esi,txf add esi,eax mov dl,bkc mov dh,fgc cmp ebx,txtc jne bchw3b rol dx,8 bchw3b: mov y,8 ;For 8 rows bchw4: mov al, [esi] mov ecx,14 ;For 8 columns bchw6: mov [edi+ecx],dl mov [edi+ecx+scx],dl mov [edi+ecx+1],dl mov [edi+ecx+scx+1],dl rcr al,1 ;cmovc dh,[edi+ecx] jnc bchw7; ?cmove instruction to replace this unpredictable branch mov [edi+ecx],dh mov [edi+ecx+1],dh mov [edi+ecx+scx],dh mov [edi+ecx+scx+1],dh bchw7: sub ecx,2 jge bchw6 add esi,4 add edi,scx add edi,scx dec y jne bchw4 ;call regex mov edx,chrl ;invoke memex,edx,12 ;movzx eax, BYTE PTR[ebx] pop ecx mov eax,ecx movzx eax, BYTE PTR[edx+eax] ;PrintHex eax add sx,eax inc tx ret pxc: movzx ecx,al; Calculate screen position push ecx mov eax,sy mov edx,scx mul edx add eax,sx ;add eax,sx add eax,videoc; PrintEx call from this point mov edi,eax mov eax,ecx; Calculate font address mov edx,128 mul edx ;add eax,4000h mov esi,txf add esi,eax mov dl,bkc mov dh,fgc cmp ebx,txtc jne pxc3a rol dx,8 pxc3a: mov y,8 ;For 8 rows pxc4: mov al, [esi] pxc5: mov ecx,7 ;For 8 columns pxc6: mov [edi+ecx],dl ;mov [edi+ecx+scx],dl ;mov [edi+ecx+1],dl ;mov [edi+ecx+scx+1],dl rcr al,1 ;cmovc dh,[edi+ecx] jnc pxc7; ?cmove instruction to replace this unpredictable branch mov [edi+ecx],dh ;mov [edi+ecx+1],dh ;mov [edi+ecx+scx],dh ;mov [edi+ecx+scx+1],dh pxc7: sub ecx,1 jge pxc6 add esi,4 add edi,scx ;add edi,scx dec y jne pxc4 ;call regex mov edx,chrl ;invoke memex,edx,12 ;movzx eax, BYTE PTR[ebx] pop ecx mov eax,ecx movzx eax, BYTE PTR[edx+eax] ;PrintHex eax add sx,eax inc tx ret ; int pnb(unsigned char n) {if (n>=224) {fgc=n-224; return(0);} ; if (n>=208) {bkc=n-208; return(0);} ; if (n>=128) {return(0);} ; unsigned char fc,bc; int a,b,i,j; char *q0,*q; ; fc=fgc; bc=bkc; if (tx==t[5] && ty==t[7]) {fc=bkc; bc=fgc;} ; a=cy*scx+cx; q0=psc+a; b=n*128+0x4000; q=q0; ; for(j=0; j<=7; j++) {a=ft[b]; i=7; ; do {a=a<<1; *q=bc; if (a&256) {*q=fc;} q++; i--;} while (i>=0); q=q-8; ; b=b+4; q=q+scx;} cx=cx+8; tx++; return(0);} ; Write to Line End ble: mov eax,sx shl eax,1 mov sx,eax ble0: mov eax,sy mov edx,scx mul edx add eax,sx add eax,videoc mov edi,eax mov ecx,scx ; from text end to screen end .IF sx>=scx ret .ENDIF sub ecx,sx mov y,8 ; for 8 rows per line mov dl,bkc ble1: pushad ble2: mov [edi],dl mov [edi+scx],dl inc edi dec ecx jne ble2 popad add edi,scx add edi,scx dec y jne ble1 ret ; void pnbx (void) {int a=cy*scx+cx; char b=bkc,*q0,*q; q0=psc+a; ; int d,j; j=7; d=scx-cx; do {q=q0; d=scx-cx; ; do {*q=b; q++; d--;} while (d>0); q0=q0+scx; j--;} while (j>=0); return;} rm0: invoke GetTickCount; Block Move timer mov time,eax mov edx,100 rm1: mov esi,1000000h mov edi,2000000h mov ecx,03FFF00h cld rm2: mov eax,[esi] mov [edi],eax add esi,4 add edi,4 dec ecx jne rm2 ;rep movsd dec edx jne rm1 invoke GetTickCount sub eax,time mov time,eax PrintDec time call regex ret ; Bitmap Overhead Setup bmo: lea esi,BitmapH; Set up Bitmap Header mov eax,esi mov edi,bmi mov eax,edi mov ecx,40 bmo1: mov eax,[esi] mov [edi],eax add esi,4 add edi,4 sub ecx,4 jne bmo1 mov ecx,17; Set up Bitmap Colors bmo2: mov al,[esi] mov [edi+2],al mov al,[esi+1] mov [edi+1],al mov al,[esi+2] mov [edi],al mov BYTE PTR[edi+3],0 add esi,3 add edi,4 dec ecx jne bmo2 ret ; Convert Text to new format txcv: mov esi,txl mov edi,txb mov eax,txta ;add eax,5E2h mov txtb,eax add eax,2 mov txtc,eax add edi,8 add esi,8 txcv1: mov cl, [esi] sub cl,2 inc esi ;mov byte ptr[edi],32 ;inc edi txcv2: mov dl,[esi] cmp dl,0D8h; switch off live lines jne txcv21 mov dl,0D2h txcv21: cmp byte ptr[edi-2],0D2h; space at line start (to prevent wordwrap) jne txcv22 mov byte ptr[edi],32 inc edi txcv22: or dl,dl; 0 to space jne txca mov dl,32 txca: cmp dl,90h ; sub A-H jb txcb cmp dl,97h ja txcb add dl,21h txcb: cmp dl,0D0h; more color amendments jne txcb1 mov dl,0D7h txcb1: cmp dl,0E7h jne txcb2 mov dl,0E0h txcb2: txcv3: mov [edi],dl inc esi inc edi dec cl jne txcv2 inc esi mov BYTE PTR[edi],0 inc edi cmp BYTE PTR[esi],0 jne txcv1 mov BYTE PTR[edi],255 mov txtz,edi mov dword ptr[edi+1],"EndT" ret ; r=&tld[0]; q=&t[0]; p3=q; *p3=8; p3++; *p3=7; q=q+8; r=r+8; ; do {a=*r-2; r++; ; do {b=*r; if (b==0) {b=32;} *q=b; ; q++; r++; a--;} while (a>0); r++; *q=0; q++;} while (*r!=0); ; *q=255; return;} ; call memex ; ret ; New Text ntf: mov edi,txta mov txtb,edi mov txtc,edi mov ecx,0 ntf1: call mcd call mcd mov eax,0D8E92000h bswap eax mov [edi],eax mov byte ptr[edi+4],255 add edi,2 mov txtc,edi add edi,2 mov txtz,edi ret ltf: lea eax,TextHeadBuf; Load Text; called by return at top of file mov fName,eax call tfn mov ebx,txb cmp byte ptr[eax+3],41h je lti0 jmp ltv0 ; Save Text stf: ;lea eax,TextName ;PrintHex eax ;call FetchE ;invoke memex,esi,20 ;call LCCheck ; .IF eax!=0 ; pushad ; mov txtc,eax ; mov txtb,eax ; call MsgBox ; popad ; ret ; .ENDIF ; R-Shift F12 calls stf1 direct, forcing a save stf1: lea eax,TextHeadBuf mov fName,eax call tfn mov ecx,txb mov fBase,ecx mov eax,txtb; top of screen mov [ecx],eax mov eax,txtc; cursor position mov [ecx+4],eax mov edx,txtz; file length sub edx,txb add edx,8 mov fLen,edx ;PrintHex fLen ;call regex ;invoke memex,la,12 call save ret tfn: pushad; collect file name from file top mov edi,eax mov esi,txta add esi,2 tfn1: mov al,[esi] mov [edi],al inc esi inc edi cmp byte ptr[esi],32 jne tfn1 mov byte ptr[edi],0 ;invoke memex,la,12 popad ret LCCheck: ;loop and condition check mov eax,codebase add eax,0F000h mov ebx,arrf mov esi,txta ;PrintHex eax ;invoke memex,eax,10 call eax ;PrintHex eax ;PrintHex esi ;mov eax,0 ret ; Load Amiga Import Text and Font lti: lea eax, ATextName; Load Import Text lti0: mov fName,eax mov eax,txl mov fBase,eax call load mov ebx,txb; Top & Tail Text add ebx,8 mov txta,ebx add ebx,fLen mov txtz,ebx call txcv ret ltv: lea eax, TextName; Load Live Text ltv0: mov fName,eax mov eax,txb mov fBase,eax call load mov ebx,txb .IF dword ptr[ebx] < 900000h add dword ptr[ebx],100000h add dword ptr[ebx+4],100000h .ENDIF ;invoke memex,txb,16 mov ebx,txb; Top & Tail Text ;invoke memex,ebx,12 mov txta,ebx add txta,8 add ebx,fLen sub ebx,8 mov txtz,ebx mov eax,txta ltv1: inc eax cmp byte ptr[eax],0 jne ltv11 call ltvc ltv11: cmp byte ptr[eax],255 jne ltv1 cmp eax,txtz je ltv2 ;PrintHex eax ;PrintHex txtz mov txtz,eax ltv2: mov ecx,txb mov eax,[ecx] mov txtb,eax; Screen and Cursor positions mov eax,[ecx+4] mov txtc,eax ;invoke memex,ebx,12 ret ltvc: cmp byte ptr[eax+1],255 je ltvc9 mov dl,[eax+1] sub dl,0D0h cmp dl,15 ja ltvc1 mov dl,[eax+2] sub dl,0E0h cmp dl,15 ja ltvc1 ltvc9: ret ltvc1: invoke memex,eax,4 mov byte ptr[eax+1],0D2h mov byte ptr[eax+2],0E0h ret lfont: lea eax, FontName; Load Font 1 mov fName,eax mov eax,txf mov fBase,eax pushad call load ;PrintHex ecx popad mov ecx,fName ;mov BYTE PTR [ecx+7],32h; Load Font 2 ;add lc,4000h ;call load call ccl ret ccl: ; calculate character lengths mov esi,txf mov edi,chrl xor edx,edx ccl1: mov ecx,8 ccla: mov ebx,28 ccla1: mov eax,[esi+ebx] bswap eax rcl eax,cl jc ccla2 sub ebx,4 jge ccla1 dec cl jne ccla ccla2: cmp ecx,0 jne ccla3 mov ecx,4 ccla3: mov [edi+edx],ecx add esi,80h inc edx cmp edx,0d0h jne ccl1 ret ;WndProc endp LoadEx: pushad; Load File (called from run) mov fName,esi ;invoke memex,esi,12 mov fBase,ebx call load popad mov ecx,fLen ;PrintHex ecx ;invoke memex,fBase,6 ret load: invoke CreateFile,fName, GENERIC_READ,\ FILE_SHARE_READ or FILE_SHARE_WRITE, NULL,\ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL mov ecx,INVALID_HANDLE_VALUE mov hFile,eax ;PrintHex fBase ;PrintHex eax ;PrintHex ecx invoke ReadFile,hFile,fBase,14000000h,addr fLen,0 invoke CloseHandle,hFile mov ecx,fLen ret SaveEx: pushad; Save File (called from run) mov fName,esi mov fBase,ebx mov fLen,ecx call save popad mov ecx,fLen ret save: invoke CreateFile,fName, GENERIC_READ or GENERIC_WRITE,\ FILE_SHARE_READ or FILE_SHARE_WRITE, NULL,\ OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL mov hFile,eax mov edx,fLen invoke WriteFile,hFile,fBase,edx,addr fLen,0 invoke CloseHandle,hFile mov ecx,fLen ret ClearEx: ;PrintHex ClearEx pushad mov dword ptr[ebp-44],01010102h mov edi,videoc; clear current mode video, display ;PrintHex edi mov eax,03030304h mov ecx,scx*scy/4 cld rep stosd ;invoke SendMessage,hwndG,WM_PRINT,0,0 ;movzx edx,mode ;PrintHex edx popad ;PrintHex ClearEx ret RefreshEx: pushad invoke InvalidateRect, hwndG,NULL,FALSE invoke VDisplay,hwndG popad ret FetchStringEx: ; input string to location strf pushad add sx,8 mov edi,strf call SFetch popad mov eax,strf ret InputSEx: call RefreshEx mov MLen,0; string input; called at [ebp-28] jmp iex1 InputEx: call RefreshEx; called at [ebp-24] mov MLen,1 iex1: push eax; adjust stack pushad mov eax,[esp+36] mov [esp+32],eax call crs; cursor r to s mov edi,strf call SFetch call SValue mov dword ptr[esp+36],eax; this will be popped by next inst ;add dword ptr[esp+32],6 popad ;invoke memex,strf,10 ret SValue: .IF MLen==0 mov ecx,strf ret .ENDIF mov esi,strf; ignores characters outside 0-9 xor eax,eax xor edi,edi mov cl,[esi]; first character inc esi or cl,cl jz sv9 cmp cl,0BDh; negative jne sv1 inc edi sv1: sub cl,30h; ignore non-digits cmp cl,9 ja sv2 movzx edx,cl; insert digits imul eax,10 add eax,edx sv2: mov cl,[esi] inc esi or cl,cl jnz sv1 sv8: or edi,edi jz sv9 neg eax sv9: ret ; evaluate the string iaddr: ; locate write address (from r/m atom) mov edx,esp invoke memex,edx,8 mov esi,[esp+32] invoke memex,esi,2 mov bl,[esi]; MRM mov bh,bl shr bh,6; mode cmp bh,3 mov ah,bl; SIB? and ah,7 cmp ah,4 shl ah,2 xor ah,28 movzx ecx,ah mov edi,[edx+ecx]; read register SFetch: call FetchEx mov eax,[eax+8] cmp eax,0Dh je sf1 .IF al==0BCh mov al,2Ch .ELSEIF al==0BDh mov al,2Dh .ELSEIF al==0C0h mov al,27h .ELSEIF al==08h dec edi sub sx,4 mov al,32 call pxa sub sx,4 jmp SFetch .ENDIF mov [edi],al inc edi call pxa call RefreshEx jmp SFetch sf1: mov byte ptr[edi],0 mov edi,strf ret PrintEx: pushad; called by [ebp-20] mov eax,[ebp-44] mov dword ptr[rb],eax call crs mov eax,esp mov ebx,[eax+32]; Allow for "pushad" above mov dl,[ebx]; hook extra code byte (see above atExtra) mov ecx,[eax+36]; hook value to be printed (pushed value) inc dword ptr[eax+32]; move return address past extra byte cmp dl,80h; immediate or r/m output? jae PrintEx1 call px mov eax,dword ptr[rb] mov [ebp-44],eax popad ret 4; pop back value byte pushed earlier in code PrintEx1: and dl,7Fh; Immediate Print inc ebx mov al,rc; immediate calls do not change main cursor color mov al,rc push eax call pximm pop eax mov rc,al mov eax,esp add dword ptr[eax+32],ecx; additional move on to return address mov eax,dword ptr[rb] mov [ebp-44],eax popad ret ; no pushed value to pop back in immediate mode px: ; Display ecx, in mode dl sub esp,256; create local array mov edi,esp mov esi,10 mov [edi+20],ecx mov byte ptr[edi+19],8; long or byte test dl,8 jnz px02 mov byte ptr[edi+19],2; byte if bit3 is clear movzx ecx,cl px02: nop mov ebx,128 mov byte ptr[edi+ebx],0 mov byte ptr[edi+18],0; signed? mov al,dl and al,7 cmp al,3 ; => hex je pxx cmp al,0 ; => character je pxk cmp al,4 ; => null terminated string je pxs cmp al,2 ; denary: 1=unsigned, 2=signed jne px01 test dl,8; if signed, byte extend jnz px03 movsx ecx,cl px03: nop or ecx,ecx jge px01 neg ecx inc byte ptr[edi+18]; denary negative flag px01: nop mov eax,ecx px1: xor edx,edx; denary digits div esi dec ebx add dl,30h mov [edi+ebx],dl cmp eax,0 jne px1 cmp byte ptr[edi+18],0 je pxz dec ebx mov byte ptr[edi+ebx],45 jmp pxz pxk: dec ebx; character output mov [edi+ebx],cl test dl,8 jz pxk1 sub ebx,3 mov [edi+ebx],ecx pxk1: jmp pxz pxx: mov dl,[edi+19] .IF dl==2 ; word hex, not byte mov dl,4 mov ecx,[edi+20] .ENDIF pxx1: mov eax,ecx and eax,15 add eax,30h cmp eax,39h jbe pxx2 add eax,7 pxx2: dec ebx mov byte ptr[edi+ebx],al shr ecx,4 dec dl jne pxx1 dec ebx mov byte ptr[edi+ebx],24h jmp pxz pxs: mov ecx,[edi+20] pxs1: mov al,[ecx] mov [edi+ebx],al inc ebx inc ecx cmp ebx,252 jae pxs2 or al,al jne pxs1 mov byte ptr[edi+ebx],0 pxs2: mov ebx,128 jmp pxz pxz: mov al,[edi+ebx]; display call pxa inc ebx cmp byte ptr[edi+ebx],0 jne pxz mov eax,sx add eax,12 shr eax,3 mov rx,al pxret: add esp,256 ret pximm: ; Print dl bytes from [ebx], or null terminated if dl=0 xor ecx,ecx mov rc,1 cmp dl,0 jne pxj pxi1: mov al,[ebx] .IF al>=0D0h and al,15 mov rc,al .ELSE call pxa .ENDIF inc ecx inc ebx cmp byte ptr[ebx],0 jne pxi1 inc ecx jmp pxi9 pxj: mov al,[ebx] .IF al>=0D0h and al,15 mov rc,al .ELSE call pxa .ENDIF inc ecx inc ebx dec dl jnz pxj pxi9: mov eax,sx add eax,12 shr eax,3 mov rx,al ret pxa: pushad; display al at sx,sy mov dl,rb mov bkc,dl mov dh,rc mov fgc,dh call pxc popad ret pxr: call crs; display al at rx,ry call pxa ret crs: push eax movzx eax,rx; cursor position shl eax,3 mov sx,eax movzx eax,ry shl eax,3 mov sy,eax pop eax ret FetchEx: pushad call RefreshEx ;invoke SetFocus,hwndG fe1: invoke GetMessage,addr FreeMsgBuf,0,0,0 invoke DispatchMessage,addr FreeMsgBuf; activates defaults lea ebx,FreeMsgBuf mov eax,[ebx+4] ;PrintHex eax cmp eax,WM_LBUTTONDOWN je fe2 cmp eax,WM_LBUTTONUP je fe2 cmp eax,WM_RBUTTONDOWN je fe2 cmp eax,WM_RBUTTONUP je fe2 cmp eax,WM_KEYDOWN jne fe1 ;invoke memex,ebx,12 .IF byte ptr[ebx+8]==10h mov kfstat,1 .IF byte ptr[ebx+14]==54 mov kfstat,2 .ENDIF jmp fe1 .ELSEIF byte ptr[ebx+8]==11h invoke PeekMessage,addr FreeMsgBuf,0,0,0,PM_REMOVE mov kfstat,3 .IF byte ptr[ebx+15]==1 mov kfstat,4 .ELSEIF byte ptr[ebx+15]==21h mov kfstat,5 .ENDIF jmp fe1 ;invoke memex,ebx,12 .ELSEIF byte ptr[ebx+8]==27; escape to text editor ;PrintHex rstack mov esp,rstack jmp runret ret .ENDIF ;invoke DispatchMessage, addr FreeMsgBuf fe2: popad lea eax,FreeMsgBuf sub dword ptr[eax+20],mbx sub dword ptr[eax+24],mby push ecx mov ecx,[eax+20] mov [ebp-40],ecx mov ecx,[eax+24] mov [ebp-36],ecx .IF dword ptr[eax+4]==100h mov byte ptr[ebp-12],1 ; event (1=kbd, 8=leftmouse) mov cl,kfstat mov [ebp-11],cl ; status mov cl,byte ptr[eax+8] mov [ebp-10],cl ; keystroke (virtual) mov kfstat,0 .ELSEIF dword ptr[eax+4]>=204h mov byte ptr[ebp-12],9 mov byte ptr[ebp-10],0F9h .ELSEIF dword ptr[eax+4]>=201h mov byte ptr[ebp-12],8 mov byte ptr[ebp-10],0F8h ;PrintHex dword ptr[eax+4] .ENDIF pop ecx ;invoke memex,eax,12 ret BreakEx: push dword ptr[ebp-44] ;PrintHex dword ptr[ebp-44] pushad ;call RefreshEx ;lea eax,rb ;PrintHex BreakEx add dword ptr[esp+36],2 mov ebx, [esp+36] sub ebx,2 brk0: mov eax,scx mov edi,eax imul edi,464 add edi,videoc mov ecx,eax imul ecx,88 shr ecx,2 mov eax,01010101h cld rep stosd mov rb,1 mov ry,59 mov rx,1 mov rc,5 mov edi,[esp+36] sub edi,2 mov al,[edi] call pxr mov al,[edi+1] call pxa add rx,2 mov ecx,edi mov dl,11 mov rc,14 call brkpx inc ry mov rx,1 add rx,3 brkr: lea esi,AllReg brk1: mov rx,1 mov al,[esi] mov rc,6 call pxr mov al,3Dh inc rx mov rc,7 call pxr mov rc,15 inc rx movzx eax,byte ptr[esi+1] mov ecx,[esp+eax] mov dl,11 call brkpx inc ry add esi,4 cmp byte ptr[esi],0 jne brk1 brkmem: mov ry,59 mov rx,12 mov rc,14 mov ecx,ebx call brkpx mov rc,15 mov ch,0 mov esi,ebx brkm1: mov rx,12 inc ry mov cl,0 brkm2: call crs mov ah,[esi] mov al,ah rol al,4 call brkn mov al,ah call brkn inc esi inc cl add rx,2 cmp cl,16 jne brkm2 inc ch cmp ch,8 jne brkm1 call RefreshEx brki0: call FetchEx cmp dword ptr[eax+4],100h jne brki0 mov cl,[eax+8] lea esi,AllReg sub esi,4 brki1: add esi,4 cmp byte ptr[esi],0 je brki2 cmp cl,[esi+2] jne brki1 movzx ecx,byte ptr[esi+1] mov ebx,[esp+ecx] cmp ebx,120000h; trap obvious errors jb brki0 jmp brk0 brki2: .IF cl==26h sub ebx,80h jmp brk0 .ELSEIF cl==28h add ebx,80h jmp brk0 .ENDIF popad ;PrintHex dword ptr[rb] pop dword ptr[ebp-44] ;PrintHex dword ptr[rb] ret brkn: and al,15 .IF al>=10 add al,7 .ENDIF add al,30h call pxa ret brkpx: pushad call crs call px popad ret DirEx: pushad mov edi, dirdata invoke FindFirstFile, esi, filedata cmp eax,0FFFFFFFFh je dir9x mov esi, filedata mov dirh, eax direx2: call direx1 invoke FindNextFile, dirh, filedata or eax,eax jne direx2 mov dword ptr[edi+16],0 invoke FindClose, dirh jmp dir9 dir9: popad mov eax,dirdata add eax,100h ret dir9x: popad mov eax,0 ret direx1: mov eax,[esi+28] mov [edi],eax mov eax,[esi+32] mov [edi+4],eax mov eax,[esi+20] mov [edi+8],eax mov eax,[esi+24] mov [edi+12],eax xor ecx,ecx dec ecx direx11: inc ecx mov al,[esi+ecx+44] mov [edi+ecx+16],al or al,al jne direx11 add edi,128 ret TimeEx: pushad invoke GetTickCount mov time,eax popad mov eax,time ret SetPalEx: ;call regex pushad mov edi,bmi add edi,40 shl eax,2 add edi,eax spl1: mov al,[esi] mov [edi+2],al mov al,[esi+1] mov [edi+1],al mov al,[esi+2] mov [edi],al mov byte ptr[edi+3],0 add esi,4 add edi,4 dec ecx jne spl1 popad ret ; Fetch Color Map FetchPalEx: mov eax,bmi add eax,40 ret MmEx: ; move mouse pushad mov esi,[ebp-40] add esi,mbx mov edi,[ebp-36] add edi,mby invoke SetCursorPos,esi,edi popad ret RenEx: ; rename file