flat assembler
Message board for the users of flat assembler.
Index
> Windows > Writing to an Edit Control Goto page Previous 1, 2, 3, 4 |
Author |
|
revolution 14 Aug 2024, 20:24
There is no guarantee that the ? will be zero.
If you rely on it to be zero then initialise it in the code to make sure you get what you expect. |
|||
14 Aug 2024, 20:24 |
|
Stancliff 14 Aug 2024, 23:01
AsmGuru, I'm tagging you into the ring on this one. The child has been flaky all day and I presume it has to do with parameters for the create. Also, when I try to use the Msg macro to put a string on the data stack and pass it to Type the program shuts down as soon as it gets there.
Code: ; Working file for Go4th32 Forth Compiler format PE GUI 4.0 entry start include 'win32ax.inc' macro SPush value ; Push value to TOS (Top Of Stack) { sub edx, 4 ; S - 4, new cell for TOS mov [edx], dword value ; move value to TOS } macro Msg str ; msg string typed to screen { invoke MessageBox,0,str,"Debug 3",MB_OK sub edx, 4 ; S - 4, new cell for TOS mov [edx], dword str ; move byte addr of string to eax call Type ; Display string on screen } section '.data' data readable writeable ; establish R and S stacks, BoR = bottom (end) of R, R0 = start of R ; == Return Stack ===== ; R: [ESP] ; Return Stack ptr, in ESP BoR DD 0 ; Last cell of R, allow 64 cells ESP-256 R0 DD 0 ; R stack start (one beyond first) ESP ; == Data Stack ====== Ret Stk start, at run = initial [ESP] ; S: [EDX] ; Data Stack ptr, in EDX BoS: DD 128 Dup ? ; Last cell of S, allow 128 cells S0: ; S Stack start (one beyond first) ; Note: many good names from Forth are reserved by assembler, find alt's NameSz EQU 256 ; max name cnt, increases dictionary size New^ DD Reserved ; ptr to next unused rec in Name N^ DD 0 ; Name Ptr, index for Name, was DP TIB DB 128 Dup " " ; Term Input Buf adr, 128 b T^ DD 0 ; Text Ptr to current source, was IN Pad DB 128 Dup " " ; Pad adr, 128 b P^ DD Pad ; Pad ptr (temp work area) H^ DD EndKern ; ptr to current unused cell for code Fence DD Reserved -17 ; adr of last protected dictionary word Base DD 10 ; initial value for base conversion ; Start Dictionary with major words of kernal core ; Names have 8 char length w/trailing zeros, no cnt byte for string ; Code Adr = 4 byte, Param Adr = 4 byte, Status = 1 byte (0=IMM,1=Defer) Name: DB "Cold",0,0,0,0 DD Cold,0 DB 1 DB "Abort",0,0,0 DD Abort,0 DB 1 DB "Quit",0,0,0,0 DD Quit,0 DB 1 DB "Query",0,0,0 DD Query,0 DB 1 DB "Type",0,0,0,0 DD Type,0 DB 1 Reserved: DB ((NameSz *17) +Name -Reserved) Dup ? ; clear Name space ; Forth searches the dictionary to find the address of a command. My bare ; bones kernal will need close to 60 names. The Forth standard has almost ; 140 names, and with extensions like floating point, a simple assembler, ; and various data structures this can easily go over 200. ; Windows assignments _class TCHAR 'Go4th',0 _title TCHAR 'Go4th32',0 _about_title TCHAR 'About Go4th32',0 _about_text TCHAR 'Windows based Forth Compiler',13,10,\ 'Created with FLAT assembler.',0 _edit TCHAR 'EDIT',0 _error TCHAR 'Startup failed.',0 _fontface TCHAR 'Courier New',0 _bEnter dd ? ; flag for 'Return' detection editfont dd ? ; return from CreateFont in WindowProc edithwnd dd ? ; handle for child from CreateWindow(2) parhwnd dd ? ; handle for parent from CreateWindow(1) client RECT msg MSG IDC_MLEDIT = 1001 ; ID for 'EDIT' control IDR_ICON = 17 IDR_MENU = 37 ; Menu entries IDM_FILE = 100 IDM_NEW = 110 IDM_OPEN = 120 IDM_EXIT = 130 IDM_SVSEL = 140 IDM_SAVE = 150 IDM_SAVEAS = 160 IDM_EDIT = 200 IDM_UNDO = 210 IDM_FIND = 220 IDM_CUT = 230 IDM_COPY = 240 IDM_PASTE = 250 IDM_DEL = 260 IDM_HELP = 900 IDM_ABOUT = 910 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class Banner: DB "Go4th: The Windows Forth Compiler",13,10,0 NewLine: DB 13,10,0 Prompt: DB "4th? ",0 section '.idata' import data readable writeable library advapi32, 'ADVAPI32.DLL',\ comctl32, 'CONCTL32.DLL',\ comdlg32, 'COMDLG32.DLL',\ gdi32, 'GDI32.DLL',\ kernel32, 'KERNEL32.DLL',\ shell32, 'SHELL32.DLL',\ user32, 'USER32.DLL',\ wsock32, 'WSOCK32.DLL' include 'api\advapi32.inc' include 'api\comctl32.inc' include 'api\comdlg32.inc' include 'api\gdi32.inc' include 'api\kernel32.inc' include 'api\shell32.inc' include 'api\user32.inc' include 'api\wsock32.inc' section '.rsrc' resource data readable directory RT_MENU, menus, RT_VERSION, versions, RT_ICON, icons,\ RT_GROUP_ICON, group_icons resource menus, IDR_MENU, LANG_ENGLISH +SUBLANG_DEFAULT, main_menu resource versions, 1, LANG_NEUTRAL, version resource group_icons, IDR_ICON, LANG_NEUTRAL, main_icon resource icons, 1, LANG_NEUTRAL, icon_data versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+\ SUBLANG_DEFAULT,0,\ 'FileDescription','MiniPad - example program',\ 'LegalCopyright','No rights reserved.',\ 'FileVersion','1.0',\ 'ProductVersion','1.0',\ 'OriginalFilename','MINIPAD.EXE' icon main_icon,icon_data,'Go4th.ico' menu main_menu menuitem '&File', IDM_FILE, MFR_POPUP menuitem '&New', IDM_NEW menuitem '&Open', IDM_OPEN menuitem '&Exit', IDM_EXIT menuseparator menuitem '&SaveSelect', IDM_SVSEL menuitem 'Sa&ve', IDM_SAVE menuitem 'Save &As', IDM_SAVEAS, MFR_END menuitem '&Edit', IDM_EDIT, MFR_POPUP menuitem '&Undo', IDM_UNDO menuitem '&Find', IDM_FIND menuseparator menuitem '&Cut', IDM_CUT menuitem 'C&opy', IDM_COPY menuitem '&Paste', IDM_PASTE menuitem '&Delete', IDM_DEL, MFR_END menuitem '&Help',IDM_HELP, MFR_POPUP + MFR_END ; LAST POPUP - MFR_END" menuitem '&About', IDM_ABOUT, MFR_END section '.code' code readable executable writeable start: mov [R0],esp ; set esisting stack point as stack start mov [BoR],esp ; End of stack will offset from ESP sub [BoR],256 ; allow 64 cells for local return stack ; Cold: full restart, reset N^ , New^, and Fence, run Abort Cold: mov eax, [Name] mov [N^], eax mov eax, [Fence +17] mov [New^], eax ; Abort: reset data stack, set base, run Quit Abort: mov edx, S0 ; clear S, wipes all pending parameters mov [Base], 10 ; Quit: reset return stack. clears all outstanding function calls Quit: ; mov esp, R0 ; clear R, cancels all pending functions invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadIcon,eax,IDR_ICON mov [wc.hIcon],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc test eax,eax jz error invoke LoadMenu,[wc.hInstance],IDR_MENU invoke CreateWindowEx,0,_class,_title,WS_TILEDWINDOW+\ WS_VISIBLE,200,100,900,600,NULL,eax,[wc.hInstance],NULL ; mov [parhwnd],eax test eax,eax jz error msg_loop: invoke GetMessage,msg,NULL,0,0 cmp eax,0 je end_loop jb error ; Some message received mov [_bEnter], 0 ; clear test flag for 'Return' mov ecx, msg mov eax, [edithwnd] cmp [ecx + MSG.hwnd], eax jne .translate ; message to be processed by [edithwnd] cmp [ecx + MSG.message], WM_CHAR jne .translate ; Message was WM_CHAR, was it [ENTER]? cmp [ecx + MSG.wParam], VK_RETURN jne .translate ; [edithwnd] is getting WM_CHAR for [ENTER] key. raise a flag. inc [_bEnter] .translate: invoke TranslateMessage,msg invoke DispatchMessage,msg ; Message is processed, test flag for processing 'Return' cmp [_bEnter], 0 je msg_loop call Query jmp msg_loop error: invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK end_loop: invoke ExitProcess,[msg.wParam] ; Query: Move a null terminated string into Terminal Input Buffer Query: mov [TIB], 122 ; input limit (128 -prompt & null) invoke SendMessage,[edithwnd],EM_GETLINECOUNT,0,0 dec eax ; Last line is blank, back up one dec eax ; try one more (this confuses me) invoke SendMessage,[edithwnd],EM_GETLINE,eax,TIB mov [TIB +eax], 0 ; add null to string ; Test results - Write input line back out invoke MessageBox,0,TIB,"Debug 1",MB_OK invoke SendMessage,[edithwnd],EM_SETSEL,-1,-1 invoke SendMessage,[edithwnd],EM_REPLACESEL,0,TIB Msg TIB ret ; Type: (str) output str to screen Type: invoke MessageBox,0,dword[edx],"Debug 2",MB_OK invoke SendMessage,[edithwnd],EM_SETSEL,-1,-1 invoke SendMessage,[edithwnd],EM_REPLACESEL,0, dword[edx] add edx,4 ; drop TOS ret ; Add most new code here proc WindowProc hwnd,wmsg,wparam,lparam push ebx esi edi mov eax,[wmsg] cmp eax,WM_CREATE je .wmcreate cmp eax,WM_SIZE je .wmsize cmp eax,WM_SETFOCUS je .wmsetfocus cmp eax,WM_COMMAND je .wmcommand cmp eax,WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] ret .wmcreate: invoke GetClientRect,[hwnd],client invoke MessageBox,0,"Child 1","Debug 0",MB_OK invoke CreateWindowEx,0,_edit,0,WS_VISIBLE+ES_MULTILINE+\ WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+\ WS_CHILD+ES_WANTRETURN,[client.left],[client.top],\ [client.right],[client.bottom],[hwnd],IDC_MLEDIT,\ [wc.hInstance],NULL invoke MessageBox,0,"Child 2","Debug 0",MB_OK ; IDC_MLEDIT mov [edithwnd],eax or eax,eax jz .finish invoke CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,\ OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ FIXED_PITCH+FF_DONTCARE,0 ; FF_DONTCARE +FF_MODERN,_fontface mov [editfont],eax or eax,eax jz .finish invoke SendMessage,[edithwnd],WM_SETFONT,eax,FALSE invoke SendMessage,[edithwnd],EM_SETSEL,-1,-1 invoke SendMessage,[edithwnd],EM_REPLACESEL,0,Banner invoke SendMessage,[edithwnd],EM_SETSEL,-1,-1 invoke SendMessage,[edithwnd],EM_REPLACESEL,0,Prompt ; Msg Banner ; Msg Prompt ret .wmsize: invoke GetClientRect,[hwnd],client invoke MoveWindow,[edithwnd],[client.left],[client.top],\ [client.right],[client.bottom],TRUE ret .wmsetfocus: invoke SetFocus,[edithwnd] ret .wmcommand: mov eax,[wparam] and eax,0FFFFh cmp eax, IDM_NEW je .new cmp eax, IDM_OPEN je .open cmp eax, IDM_SVSEL je .svSel cmp eax, IDM_SAVE je .save cmp eax, IDM_SAVEAS je .saveAs cmp eax, IDM_UNDO je .undo cmp eax, IDM_FIND je .find cmp eax, IDM_CUT je .cut cmp eax, IDM_COPY je .copy cmp eax, IDM_PASTE je .paste cmp eax, IDM_DEL je .del cmp eax, IDM_ABOUT je .about cmp eax, IDM_EXIT je .wmdestroy jmp .defwndproc .new: invoke SendMessage,[edithwnd],WM_SETTEXT,0,0 ret .open: ; Load file to Edit Control ret .svSel: ; Write Selected to a File invoke SendMessage,[edithwnd],EM_GETSEL,0,0 ret .save: ; Write Session to a File ret .saveAs: ; Write Session to a different File name ret .undo: invoke SendMessage,[edithwnd],EM_UNDO,0,0 ret .find: ; Get Search str and try to Find it in text ret .cut: invoke SendMessage,[edithwnd],WM_CUT,0,0 ret .copy: invoke SendMessage,[edithwnd],WM_COPY,0,0 ret .paste:invoke SendMessage,[edithwnd],WM_PASTE,0,0 ret .del: invoke SendMessage,[edithwnd],WM_CLEAR,0,0 ret .about:invoke MessageBox,[parhwnd],_about_text,_about_title,MB_OK ret .wmdestroy: invoke DeleteObject,[editfont] invoke PostQuitMessage,0 .finish: ret endp EndKern: ; New compiled functions will be added starting here. |
|||
14 Aug 2024, 23:01 |
|
AsmGuru62 15 Aug 2024, 14:47
1. I think we should set all '?' into '0' as revolution suggested.
2. What should I do to create an issue in the code? Steps? 3. We also need to preserve ESI,EDI,EBX in the Window Procedure, because it is requirement from OS. |
|||
15 Aug 2024, 14:47 |
|
Stancliff 15 Aug 2024, 17:53
I will set the var's to zero, no prob.
I eventually need esi, edi, and ebx unless I do a lot of my later processing from vars instead of registers. Currently it isn't happening so that isn't my problem. I noticed that the Msg macro is crashing the windows when I assign a string addr to my S stack (edx). On rare occasions Type will print something, but mostly failure. I put PushAD and POPAD around the call to Query and nothing changed that I could see. As a guess I wonder if windows is using most of the reg's and leaving none for me but EAX? I fully expect the top of my Compiler code to originate where Query is called. I need Type printing strings before I can do much else. It is essential for getting status and debug info as I try to add more functions. |
|||
15 Aug 2024, 17:53 |
|
AsmGuru62 15 Aug 2024, 21:44
I have noticed that you are debugging your code with "MessageBox" calls.
I suggest to download OllyDbg and use it --- an excellent tool, I've been using it for decades, nothing but joy. Windows will use all registers except: EBX,ESI,EDI,EBP,ESP --- which means the code below will lose EDX after calling Windows API: Code: ; Type: (str) output str to screen Type: invoke MessageBox,0,dword[edx],"Debug 2",MB_OK invoke SendMessage,[edithwnd],EM_SETSEL,-1,-1 invoke SendMessage,[edithwnd],EM_REPLACESEL,0, dword[edx] add edx,4 ; drop TOS ret I will post some more analysis later --- have something to do right now. |
|||
15 Aug 2024, 21:44 |
|
AsmGuru62 15 Aug 2024, 22:52
Ok, so few things:
Code: proc WindowProc hwnd,wmsg,wparam,lparam push ebx esi edi mov eax,[wmsg] cmp eax,WM_CREATE je .wmcreate The PUSH-es are not needed, just use "uses" keyword: Code: proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam mov eax,[wmsg] cmp eax,WM_CREATE je .wmcreate Also, when processing the WM_CREATE, WM_SIZE, WM_COMMAND --- WindowProc should return EAX=0 and it does not. Just make a label inside WindowProc: Code: .return_zero: xor eax,eax ret And jump to it from all the places you have "RET". The line below is moving BYTE as 1st byte in TIB, but Windows wants a WORD there, not BYTE: Code: Query: mov [TIB], 122 ; input limit (128 -prompt & null) Need to specify type directly: Code: Query: mov word [TIB], 122 ; input limit (128 -prompt & null) Instead of EDX being a stack pointer --- you can use one of EBX,ESI,EDI. Even better, use a model of a stack, where you are not dependent on the values in any registers. And, of course ESP --- this register changes when you CALL any function or RETURN from one of your own functions. |
|||
15 Aug 2024, 22:52 |
|
Stancliff 15 Aug 2024, 23:01
AsmGuru62 wrote: I have noticed that you are debugging your code with "MessageBox" calls. I suggest to download OllyDbg and use it --- an excellent tool, I've been using it for decades, nothing but joy. Since you specifically did not mention EDX why did you say the code will break. IF wiwdows isn't using ESP and EBP then I could use both for stack pointers, it would be an improvement. I am worried you reversed the negation of the sentence. As long as windows can stick to the hidden registers I would have no problem, but my current problem leads me to believe the public registers are being used for something. |
|||
15 Aug 2024, 23:01 |
|
revolution 15 Aug 2024, 23:09
EAX, ECX and EDX are not preserved in the STDCALL convention. Meaning that invoke will change those registers.
|
|||
15 Aug 2024, 23:09 |
|
Ali.Z 16 Aug 2024, 00:38
you should read about x86 calling conventions, and for debugging use ollydbg and outputdebugstring function and keep your eyes on log window.
_________________ Asm For Wise Humans |
|||
16 Aug 2024, 00:38 |
|
Stancliff 16 Aug 2024, 03:44
revolution wrote: EAX, ECX and EDX are not preserved in the STDCALL convention. Meaning that invoke will change those registers. In the standard calling convention who saves and restores those registers? You just said that EBP is NOT used so I can make it my data stack instead of EDX, is this valid? Using ESP as the return stack is perfectly reasonable since that was it's design intention. The big question is whether windows is using it at the same time I would be. Is there going to be a collision or do we use them at separate times? (alternating as such) I opened OllyDbg it and had trouble seeing the faint color contrast. When I went into appearances the lines were not even showing up due to the colors selected. I also need a larger font for more clarity. Not impossible, just working hard against me seeing much of anything. Plus I have no idea how it works... another learning curve. I'm 66 and about 30% blind at this point. My cataract surgeon barely cleared me to drive at the minimum required vision level and I currently don't even have a license. I'm saying my vision is BAD. More comments and responses tomorrow, it's nearly midnight |
|||
16 Aug 2024, 03:44 |
|
revolution 16 Aug 2024, 03:54
It is "normal" to use EBP as a pointer into the stack.
It is NOT normal to manipulate ESP directly. Windows, and all OSes, do not use your stack, ever. It is your stack. Do with it whatever you want. But I suggest you don't try to be "clever" with it. Just use it the natural way and then the programming is much simpler and has fewer bugs. |
|||
16 Aug 2024, 03:54 |
|
uu 16 Aug 2024, 08:44
Stancliff wrote:
Me too, with my shortsightedness. But I can increase the font size in x64dbg (another popular debugger) for better clarity. There is also setting for colors.
|
||||||||||
16 Aug 2024, 08:44 |
|
Furs 16 Aug 2024, 13:27
revolution wrote: It is "normal" to use EBP as a pointer into the stack. |
|||
16 Aug 2024, 13:27 |
|
Stancliff 16 Aug 2024, 15:14
Thanks revolution, I feel you give decent advice. I am more worried about learning assumptions or methods that have become entrenched and need to be honored for safety reasons in situations where I don't have final authority. Dealing with my operating system falls into that group. If windows really needs a register I want to avoid it but I have to learn it from somewhere. You guys often keep me informed where I do weird things. I based my software on a 40 year old design and am trying to make it more modern, not throw it out and start over.
|
|||
16 Aug 2024, 15:14 |
|
revolution 16 Aug 2024, 20:15
Furs wrote:
Everything above ESP is your stack. The OS never touches it. Everything below ESP is not your stack. Indeed, memory below ESP isn't even guaranteed to be present, because it might be a guard page, or no page at all. If you skip over the guard page then you get a page fault, and your code crashes, even though you can theoretically still be within your address allocation. |
|||
16 Aug 2024, 20:15 |
|
Stancliff 17 Aug 2024, 00:28
Agreed, he was saying to not mess with space reserved for the stack since the stack can move down most any time and change the data. As long as it's used as a stack it is good.
I had to rebuild from MiniPad for about the eight time, but the child is working, the data stack is working, and I/O is working. Code: ; Working file for Go4th32 Forth Compiler format PE GUI 4.0 entry start include 'win32ax.inc' macro SPush value ; Push value to TOS (Top Of Stack) { sub [Stk], 4 ; S - 4, new cell for TOS mov [Stk], dword value ; move value to TOS } macro Msg str ; msg string typed to screen { sub [Stk], 4 ; S - 4, new cell for TOS mov [Stk], dword str ; move addr of string to Stk call Type ; Display string on screen } section '.data' data readable writeable ; establish R and S stacks, BoR = bottom (end) of R, R0 = start of R ; == Return Stack ===== ; R: [ESP] ; Return Stack ptr, in ESP BoR DD 0 ; Last cell of R, allow 64 cells ESP-256 R0 DD 0 ; R stack start (one beyond first) ESP ; == Data Stack ====== Ret Stk start, at run = initial [ESP] ; S: [Stk] ; Data Stack ptr, in Stk BoS: DD 128 Dup ? ; Last cell of S, allow 128 cells S0: ; S Stack start (one beyond first) ; Note: many good names from Forth are reserved by assembler, find alt's NameSz EQU 256 ; max name cnt, increases dictionary size New^ DD Reserved ; ptr to next unused rec in Name N^ DD 0 ; Name Ptr, index for Name, was DP TIB DB 128 Dup " " ; Term Input Buf adr, 128 b T^ DD 0 ; Text Ptr to current source, was IN Pad DB 128 Dup " " ; Pad adr, 128 b P^ DD Pad ; Pad ptr (temp work area) H^ DD EndKern ; ptr to current unused cell for code Fence DD Reserved -17 ; adr of last protected dictionary word Stk DD S0 ; data stack implemented in a variable Base DB 10 ; initial value for base conversion State DB 0 ; Compiler/Interpreter state, 1=comp ; Start Dictionary with major words of kernal core ; Names have 8 char length w/trailing zeros, no cnt byte for string ; Code Adr = 4 byte, Param Adr = 4 byte, Status = 1 byte (0=IMM,1=Defer) Name: DB "Cold",0,0,0,0 DD Cold,0 DB 1 DB "Abort",0,0,0 DD Abort,0 DB 1 DB "Quit",0,0,0,0 DD Quit,0 DB 1 DB "Query",0,0,0 DD Query,0 DB 1 DB "Type",0,0,0,0 DD Type,0 DB 1 DB "Interp",0,0 DD Interp,0 DB 1 DB "Wrd",0,0,0,0,0 DD Wrd,0 DB 1 Reserved: DB ((NameSz *17) +Name -Reserved) Dup ? ; clear Name space ; Forth searches the dictionary to find the address of a command. My bare ; bones kernal will need close to 60 names. The Forth standard has almost ; 140 names, and with extensions like floating point, a simple assembler, ; and various data structures this can easily go over 200. _class TCHAR 'Go4th',0 _title TCHAR 'Go4th32',0 _about_title TCHAR 'About Go4th32',0 _about_text TCHAR 'Windows based Forth Compiler',13,10,\ 'Created with FLAT assembler.',0 _edit TCHAR 'EDIT',0 _error TCHAR 'Startup failed.',0 _fontface TCHAR 'Courier New',0 _bEnter dd 0 ; flag for 'Return' detection editfont dd 0 ; return from CreateFont in WindowProc parhwnd dd 0 ; handle for parent window from Create1 edithwnd dd 0 ; handle for editor child from Create2 linehwnd dd 0 ; handle for single line child from Create3 client RECT ; ptr to RECT struct msg MSG ; ptr to MSG struct IDC_MLEDIT = 1001 ; ID for 'EDIT' control IDR_ICON = 17 IDR_MENU = 37 ; Menu entries IDM_FILE = 100 IDM_NEW = 110 IDM_OPEN = 120 IDM_EXIT = 130 IDM_SVSEL = 140 IDM_SAVE = 150 IDM_SAVEAS = 160 IDM_EDIT = 200 IDM_UNDO = 210 IDM_FIND = 220 IDM_CUT = 230 IDM_COPY = 240 IDM_PASTE = 250 IDM_DEL = 260 IDM_HELP = 900 IDM_ABOUT = 910 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class Banner: DB "Go4th: The Windows Forth Compiler",0 NewLine: DB 13,10,0 Prompt: DB 13,10,"4th? ",0 section '.idata' import data readable writeable library advapi32, 'ADVAPI32.DLL',\ comctl32, 'CONCTL32.DLL',\ comdlg32, 'COMDLG32.DLL',\ gdi32, 'GDI32.DLL',\ kernel32, 'KERNEL32.DLL',\ shell32, 'SHELL32.DLL',\ user32, 'USER32.DLL',\ wsock32, 'WSOCK32.DLL' include 'api\advapi32.inc' include 'api\comctl32.inc' include 'api\comdlg32.inc' include 'api\gdi32.inc' include 'api\kernel32.inc' include 'api\shell32.inc' include 'api\user32.inc' include 'api\wsock32.inc' section '.rsrc' resource data readable directory RT_MENU, menus, RT_VERSION, versions, RT_ICON, icons,\ RT_GROUP_ICON, group_icons resource menus, IDR_MENU, LANG_ENGLISH +SUBLANG_DEFAULT, main_menu resource versions, 1, LANG_NEUTRAL, version resource group_icons, IDR_ICON, LANG_NEUTRAL, main_icon resource icons, 1, LANG_NEUTRAL, icon_data versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+\ SUBLANG_DEFAULT,0,\ 'FileDescription','Go4th32 Forth Compiler',\ 'LegalCopyright','RDStancliff (c) 2024 All rights reserved',\ 'FileVersion','1.0',\ 'ProductVersion','1.0',\ 'OriginalFilename','Go4th32.exe' icon main_icon,icon_data,'Go4th.ico' menu main_menu menuitem '&File', IDM_FILE, MFR_POPUP menuitem '&New', IDM_NEW menuitem '&Open', IDM_OPEN menuitem '&Exit', IDM_EXIT menuseparator menuitem '&SaveSelect', IDM_SVSEL menuitem 'Sa&ve', IDM_SAVE menuitem 'Save &As', IDM_SAVEAS, MFR_END menuitem '&Edit', IDM_EDIT, MFR_POPUP menuitem '&Undo', IDM_UNDO menuitem '&Find', IDM_FIND menuseparator menuitem '&Cut', IDM_CUT menuitem 'C&opy', IDM_COPY menuitem '&Paste', IDM_PASTE menuitem '&Delete', IDM_DEL, MFR_END menuitem '&Help',IDM_HELP, MFR_POPUP + MFR_END ; LAST POPUP - MFR_END" menuitem '&About', IDM_ABOUT, MFR_END section '.code' code readable executable writeable start: mov [R0],esp ; save esisting stack point as upper bound mov [BoR],esp ; End of stack will offset from ESP... sub [BoR],256 ; allow 64 cells for lower bound Cold: mov eax, [Name] mov [N^], eax ; Name to N^, N^ ready to scan Name table mov eax,[Fence +17] ; Fence is last word delete protected mov [New^], eax ; New^ gets next added word Abort: mov [Stk], S0 ; clear S, wipes all pending parameters mov [Base], 10 ; system starts with Base 10 Quit: mov [State],0 ; system starts in Interpret state invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadIcon,eax,IDR_ICON mov [wc.hIcon],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc cmp eax,0 jz error invoke LoadMenu,[wc.hInstance],IDR_MENU invoke CreateWindowEx,0,_class,_title,WS_OVERLAPPEDWINDOW+\ WS_VISIBLE,200,100,1000,600,NULL,eax,[wc.hInstance],NULL cmp eax,0 jz error msg_loop: invoke GetMessage,msg,NULL,0,0 cmp eax,0 je end_loop jb error ; Some message received mov [_bEnter],0 ; clear test flag for 'Return' mov ecx, msg mov eax, [edithwnd] cmp [ecx + MSG.hwnd], eax jne .translate ; message to be processed by [edithwnd] cmp [ecx + MSG.message], WM_CHAR jne .translate ; Message was WM_CHAR, was it [ENTER]? cmp [ecx + MSG.wParam], VK_RETURN jne .translate ; [edithwnd] getting [ENTER] key. flag inc [_bEnter] .translate: invoke TranslateMessage,msg invoke DispatchMessage,msg ; Message sent, process flag for 'Return' cmp [_bEnter], 0 je msg_loop call Query ; Msg NewLine Msg Prompt jmp msg_loop error: invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK end_loop:invoke ExitProcess,[msg.wParam] ; Type: (str) print output str to screen Type: invoke SendMessage,[edithwnd],EM_SETSEL,-1,-1 invoke SendMessage,[edithwnd],EM_REPLACESEL,0, dword[Stk] add [Stk],4 ; pop TOS ret ; Query: Move a null terminated string into Terminal Input Buffer Query: mov word[TIB],122 ; input limit (128 - prompt & null) invoke SendMessage,[edithwnd],EM_GETLINECOUNT,0,0 dec eax ; Last line is blank, back up one dec eax ; try one more (this confuses me) invoke SendMessage,[edithwnd],EM_GETLINE,eax,dword TIB mov [TIB +eax], 0 ; add null to string ret ;Interpret: Interp: ret ;Word: Wrd: ret ; add most new functions here proc WindowProc hwnd,wmsg,wparam,lparam push ebx esi edi mov eax,[wmsg] cmp eax,WM_CREATE je .wmcreate cmp eax,WM_SIZE je .wmsize cmp eax,WM_SETFOCUS je .wmsetfocus cmp eax,WM_CHAR je .wmchar cmp eax,WM_COMMAND je .wmcommand cmp eax,WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmcreate: invoke GetClientRect,[hwnd],client invoke CreateWindowEx,0,_edit,0,WS_VISIBLE+ES_WANTRETURN+\ WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+\ ES_MULTILINE,[client.left],[client.top],[client.right],\ [client.bottom],[hwnd],0,[wc.hInstance],NULL or eax,eax jz .finish mov [edithwnd],eax invoke CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,\ OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ FIXED_PITCH+FF_DONTCARE,NULL or eax,eax jz .finish mov [editfont],eax invoke SendMessage,[edithwnd],WM_SETFONT,eax,FALSE Msg Banner Msg Prompt jmp .finish .wmsize: invoke GetClientRect,[hwnd],client invoke MoveWindow,[edithwnd],[client.left],[client.top],\ [client.right],[client.bottom],TRUE jmp .finish .wmsetfocus: invoke SetFocus,[edithwnd] jmp .finish .wmchar: invoke SendMessage,[edithwnd],WM_CHAR,ebx,ecx cmp ebx,VK_RETURN jne .defwndproc jmp .defwndproc .wmcommand: mov eax,[wparam] and eax,0FFFFh cmp eax, IDM_NEW je .new cmp eax, IDM_OPEN je .open cmp eax, IDM_SVSEL je .svSel cmp eax, IDM_SAVE je .save cmp eax, IDM_SAVEAS je .saveAs cmp eax, IDM_UNDO je .undo cmp eax, IDM_FIND je .find cmp eax, IDM_CUT je .cut cmp eax, IDM_COPY je .copy cmp eax, IDM_PASTE je .paste cmp eax, IDM_DEL je .del cmp eax, IDM_ABOUT je .about cmp eax, IDM_EXIT je .wmdestroy jmp .defwndproc .new: invoke SendMessage,[edithwnd],WM_SETTEXT,0,0 jmp .finish .open: ; Load file to Edit Control jmp .finish .svSel:invoke SendMessage,[edithwnd],EM_GETSEL,0,0 ; Write Selected to a File jmp .finish .save: ; Write Session to a File jmp .finish .saveAs: ; Write Session to a different File name jmp .finish .undo: invoke SendMessage,[edithwnd],EM_UNDO,0,0 jmp .finish .find: ; Get Search str and try to Find it in text jmp .finish .cut: invoke SendMessage,[edithwnd],WM_CUT,0,0 jmp .finish .copy: invoke SendMessage,[edithwnd],WM_COPY,0,0 jmp .finish .paste:invoke SendMessage,[edithwnd],WM_PASTE,0,0 jmp .finish .del: invoke SendMessage,[edithwnd],WM_CLEAR,0,0 jmp .finish .about: invoke MessageBox,[parhwnd],_about_text,_about_title,MB_OK jmp .finish .wmdestroy: invoke DeleteObject,[editfont] invoke PostQuitMessage,0 .finish: ret endp EndKern: ; New compiled functions will be added starting here. |
|||
17 Aug 2024, 00:28 |
|
Stancliff 18 Aug 2024, 02:37
I have had to come back and grab copies of this twice already, it corrupts so quickly. I have started to work ahead importing functions. Will be busy for a while.
|
|||
18 Aug 2024, 02:37 |
|
Goto page Previous 1, 2, 3, 4 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.