The MASM Forum

Miscellaneous => Miscellaneous Projects => Topic started by: nidud on October 24, 2012, 12:59:39 AM

Title: Resource compiler for console applications
Post by: nidud on October 24, 2012, 12:59:39 AM
Hi all

One of the first programs I wrote was a 16-bit resource editor, and most of the programs I have made after that has been based on using this tool. It is very simplistic and hard to handle in some cases, but it still works.

The programs I made are still used (mostly by old farts), but the main problem with them is the lack of DOS support in newer hardware, especially printers. I also have a small baby project online, which I have been nursing for some time, but now MS is blocking the use of such applications even in XP.

Most of these programs are written in C/C++, so the plan was to convert the resource compiler to 32-bit instead of rewriting all this code. My knowledge of assembly is from 16-bit TASM, so I’m a bit rusty with regards to 32-bit MASM.

The learning curve will be to grind through the console functions first, using kernel32.lib and a few functions from user32.lib (clipboard functions).

The first problem I run into was the color setup, and here is some of the code used for manipulating colors used in 16-bit code:

Code: [Select]
include clib.inc
include conio.inc
include mouse.inc

.code

setpal proc _CType public uses bx? palid:size_t, clid:size_t
test console,CON_COLOR
jz setpal_end
ifndef __f__
mov ax,palid
mov dx,clid
mov     ch,al
mov     bx,dx
mov     ax,0040h
mov     es,ax
mov     dx,es:[0063h]
cmp dx,03D4h
jne setpal_end
cli
mov dx,03DAh
in al,dx
mov dx,03C0h
mov     al,bl
out     dx,al
mov     al,ch
out     dx,al
mov dx,03DAh
in      al,dx
mov dx,03C0h
mov     al,20h
out     dx,al
sti
else
; missing 32-bit code
endif
    setpal_end:
ret
setpal endp

resetpal proc _CType public
push si?
xor si?,si?
.repeat
    invoke setpal,si?,si?
    inc si?
.until si? == 8
mov si?,56
.repeat
    mov ax?,si?
    add ax?,-48
    invoke setpal,si?,ax?
    inc si?
.until si? == 64
invoke setpal,0014h,0006h
pop si?
ret
resetpal endp

getxya proc _CType public x:size_t, y:size_t
ifndef __f__
invoke getxyw,x,y
mov al,ah
mov ah,0
else
    local lpCharacter:dword, lpNumberOfAttributesRead:dword
mov eax,y
shl eax,16
add eax,x
mov ecx,eax
invoke ReadConsoleOutputAttribute,
    OFSH_OUTPUT,addr lpCharacter,1,ecx,addr lpNumberOfAttributesRead
mov eax,lpCharacter
and eax,00FFh
endif
ret
getxya endp

scputa proc _CType public uses ax? dx? x:size_t, y:size_t, l:size_t, a:size_t
 ifndef __f__
mov al,byte ptr x
mov ah,byte ptr y
call __getxypm
invoke wcputa,dx::ax,l,a
ShowMouseCursor
 else
local pcx:dword
push ecx
movzx ecx,byte ptr a
movzx eax,byte ptr x
movzx edx,byte ptr y
shl edx,16
mov dx,ax
invoke FillConsoleOutputAttribute,OFSH_OUTPUT,ecx,l,edx,addr pcx
pop ecx
 endif
ret
scputa endp

end

The code assign value [0..255] to index [0..15]

So, to my first question: is there a simple way to rearrange the 256 palettes like this in 32-bit, or do I have to apply a table of some sort for that?

The library used for this code could be downloaded from this site: https://sourceforge.net/projects/doszip/files/
Title: Re: Resource compiler for console applications
Post by: ToutEnMasm on October 24, 2012, 01:14:55 AM
see this sample who create a palette of 256 colors.
http://masm32.com/board/index.php?topic=813.msg7226#msg7226 (http://masm32.com/board/index.php?topic=813.msg7226#msg7226)
and forget all you know on the 16 bits.
Title: Re: Resource compiler for console applications
Post by: dedndave on October 24, 2012, 01:48:48 AM
you have a lot of ground to cover before you even think about re-writing the app for 32-bit

software INT's - a thing of the past
segmented memory model - same
manipulating the vga registers directly - not likely

start out by learning some 32-bit basics, then move into graphics
if you install the masm32 package, have a look at the examples and help folders
Title: Re: Resource compiler for console applications
Post by: nidud on October 24, 2012, 03:39:48 AM
you have a lot of ground to cover before you even think about re-writing the app for 32-bit

software INT's - a thing of the past
segmented memory model - same
manipulating the vga registers directly - not likely

start out by learning some 32-bit basics, then move into graphics
if you install the masm32 package, have a look at the examples and help folders
It is difficult to understand the 16-bit segmented memory models, but it is the foundation of it all. If you understand it, the 32/64-bit is very simple. The library is already converted to 32-bit, and it took less than a week to do so. There is however some adjustment and testing to make it work properly. Since all the software interrupts in the 16-bit code is handled by the OS, in this case 32-bit, the same functionality should be accessible in 32-bit as well.

The software interrupt below, and the 32-bit call will end up calling the same function. The only difference is the interface of the call. The first one is easy the latter is difficult.
Quote
mkdir   proc _CType public directory:dword
  ifdef __f__
   .if func(CreateDirectory,directory,0)
       sub eax,eax
   .else
       call osmaperr
   .endif
   ret
  else
    ifdef __LFN__
   cmp   _ifsmgr,0
    endif
   push   ds
   lds   dx,directory
   mov   ah,39h
    ifdef __LFN__
   je   @F
   stc
   mov   ax,7139h
      @@:
    endif
   int   21h
   pop   ds
   jc   mkdir_err
   xor   ax,ax
    mkdir_end:
   ret
    mkdir_err:
   call   osmaperr
   jmp   mkdir_end
  endif
mkdir   endp

The console mode applications do not use graphics, it is called text mode, and that’s way I like it (no irritating moving objects).

The missing thing here is illustrated in this picture:
(dont't now how to insert a bitmap, so, Start->Run->cmd.exe, right-clikc top of window->property->color)

So the question is (still), is there anybody who know anything about the function used in this API?
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 24, 2012, 03:52:56 AM
So the question is (still), is there anybody who know anything about the function used in this API?

Which function used in which API?

Also, when you post sources, do not assume that we have these includes, or that we know what mouseon etc do.

Code: [Select]
include clib.inc
include conio.inc
include mouse.inc

.code

main proc c
invoke mouseon
or byte ptr console,CON_COLOR
.if !func(editpal)
    invoke resetpal
.else
   and console,not CON_REVGA
.endif
invoke mouseoff
sub ax?,ax?
ret
main endp

    end

The typical template used here looks like this:
include \masm32\include\masm32rt.inc

.code
start:   nop
   exit

end start


Anything more idiosyncratic is likely to get ignored by forum members (because it means wasting time to rewrite the whole thing).

Oh, and before I forget: Welcome to the Forum :icon14:
Title: Re: Resource compiler for console applications
Post by: japheth on October 24, 2012, 03:59:18 AM
Quote
So the question is (still), is there anybody who know anything about the function used in this API?

Well, yes.  :bgrin:

There is no equivalent in the Win32 API to set the VGA attribute controller registers or DACs in text mode ( console ). You are more or less stuck to the 16 default colors.

Title: Re: Resource compiler for console applications
Post by: nidud on October 24, 2012, 04:41:25 AM
Quote
So the question is (still), is there anybody who know anything about the function used in this API?

Well, yes.  :bgrin:

There is no equivalent in the Win32 API to set the VGA attribute controller registers or DACs in text mode ( console ). You are more or less stuck to the 16 default colors.
Thanks!

So the 16-bit console still rules  :biggrin:

Quote
Anything more idiosyncratic is likely to get ignored by forum members (because it means wasting time to rewrite the whole thing).
Don’t waste your time on this jj, it’s complicated: stick to the Basic, its easy and comfy   :P
Quote
Oh, and before I forget: Welcome to the Forum
Thanks jj!
Title: Re: Resource compiler for console applications
Post by: dedndave on October 24, 2012, 04:43:21 AM
i am not sure that is strictly true
some functions, like RealizePalette, may alter the vga palette registers, indirectly
i haven't played with it much - it seems it would make more of a difference if i were using a 256-color mode
because newer systems have far improved graphics capabilities, we don't have as much need to do it

keep in mind, that if you were using a 256-color mode, and you changed the palette,
it would affect all visible windows, including the desktop
Title: Re: Resource compiler for console applications
Post by: ToutEnMasm on October 24, 2012, 04:45:29 AM
Quote
So the question is (still), is there anybody who know anything about the function used in this API?
The ddk is a good source for this.It's the perfect level where they can be used.
There is a graphic vga card sample.
firmware can also give some code.
The API are here to do not know all the material details and normalize there use.

Title: Re: Resource compiler for console applications
Post by: nidud on October 24, 2012, 05:32:45 AM
Quote
Since all the software interrupts in the 16-bit code is handled by the OS, in this case 32-bit, the same functionality should be accessible in 32-bit as well.
The property dialog box lets you set the value for each of the 16 colours from 0..255, so I think it must be possible.
Quote
So the question is (still), is there anybody who know anything about the function used in this API?
The ddk is a good source for this.It's the perfect level where they can be used.
There is a graphic vga card sample.
firmware can also give some code.
The API are here to do not know all the material details and normalize there use.
This is probably the solution, but
Quote
you have a lot of ground to cover before you even think about re-writing the app for 32-bit
...
start out by learning some 32-bit basics, then move into graphics
this takes time, so
Quote
The learning curve will be to grind through the console functions first, using kernel32.lib and a few functions from user32.lib (clipboard functions).
I will stic to the
Quote
You are more or less stuck to the 16 default colors.
for now, so thanks for the input so far!
Title: Re: Resource compiler for console applications
Post by: MichaelW on October 24, 2012, 05:46:20 AM
Code: [Select]
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
    hwndCon dd 0
    hdcCon  dd 0
.code
;==============================================================================
start:
;==============================================================================

    invoke GetConsoleWindow
    mov hwndCon, eax
    printf("hwndCon %X\n",eax)

    invoke GetDC, hwndCon
    mov hdcCon, eax
    printf("hdcCon %X\n",eax)

    invoke GetDeviceCaps, hdcCon, SIZEPALETTE
    printf("SIZEPALETTE %d\n\n",eax)

    invoke GetDeviceCaps, hdcCon, RASTERCAPS
    mov ebx, eax

    ; RC_BANDING Requires banding support.
    .IF ebx & RC_BANDING
        printf("RC_BANDING\n")
    .ENDIF
    ; RC_BITBLT Capable of transferring bitmaps.
    .IF ebx & RC_BITBLT
        printf("RC_BITBLT\n")
    .ENDIF
    ; RC_BITMAP64 Capable of supporting bitmaps larger than 64 KB.
    .IF ebx & RC_BITMAP64
        printf("RC_BITMAP64\n")
    .ENDIF
    ; RC_DI_BITMAP Capable of supporting the SetDIBits and GetDIBits functions.
    .IF ebx & RC_DI_BITMAP
        printf("RC_DI_BITMAP\n")
    .ENDIF
    ; RC_DIBTODEV Capable of supporting the SetDIBitsToDevice function.
    .IF ebx & RC_DIBTODEV
        printf("RC_DIBTODEV\n")
    .ENDIF
    ; RC_FLOODFILL Capable of performing flood fills.
    .IF ebx & RC_FLOODFILL
        printf("RC_FLOODFILL\n")
    .ENDIF
    ; RC_PALETTE Specifies a palette-based device.
    .IF ebx & RC_PALETTE
        printf("RC_PALETTE\n")
    .ENDIF
    ; RC_SCALING Capable of scaling.
    .IF ebx & RC_SCALING
        printf("RC_SCALING\n")
    .ENDIF
    ; RC_STRETCHBLT Capable of performing the StretchBlt function.
    .IF ebx & RC_STRETCHBLT
        printf("RC_STRETCHBLT\n")
    .ENDIF
    ; RC_STRETCHDIB Capable of performing the StretchDIBits function
    .IF ebx & RC_STRETCHDIB
        printf("RC_STRETCHDIB\n\n")
    .ENDIF

    inkey
    exit
;==============================================================================
end start
I’m not sure what to make of the GetDeviceCaps-RASTERCAPS return value. The console is not a palette-based device, but apparently supports bitmaps.
Code: [Select]
hwndCon 102D4
hdcCon E2010545
SIZEPALETTE 0

RC_BITBLT
RC_BITMAP64
RC_DI_BITMAP
RC_DIBTODEV
RC_FLOODFILL
RC_STRETCHBLT
RC_STRETCHDIB
Title: Re: Resource compiler for console applications
Post by: nidud on October 24, 2012, 06:15:39 AM
i am not sure that is strictly true
some functions, like RealizePalette, may alter the vga palette registers, indirectly
i haven't played with it much - it seems it would make more of a difference if i were using a 256-color mode
because newer systems have far improved graphics capabilities, we don't have as much need to do it

keep in mind, that if you were using a 256-color mode, and you changed the palette,
it would affect all visible windows, including the desktop
The RealizePalette entry in MSDN gives one (of many) example on using CreatePalette, but they are defined in the GDI32.LIB.

To not break the 'kernel32-only-rule', I could create a 16-bit setpal.exe and just .. execute it :lol:
Title: Re: Resource compiler for console applications
Post by: dedndave on October 24, 2012, 08:39:00 AM
i am not aware of a "kernel32-only" rule   :shock:

that is a very crippling rule, as many win32 functions lie outside kernel32
Title: Re: Resource compiler for console applications
Post by: nidud on October 24, 2012, 09:25:57 AM
you have a lot of ground to cover before you even think about re-writing the app for 32-bit
start out by learning some 32-bit basics, then move into graphics
basic console stuff first, then
GDI32.LIB - Graphics Device Interface (GDI)
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 24, 2012, 09:32:52 AM
Don’t waste your time on this jj, it’s complicated: stick to the Basic, its easy and comfy   :P

Well, under the hood it's often not comfy at all :greensml:

By the way, I liked your discussion of the expansion problem (http://sourceforge.net/projects/jwasm/forums/forum/927109/topic/5793871), and would support the warning option, especially since the workaround is very straightforward:

include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="This is a stupid test"
  .if Instr_(esi, "stuupid")
     PrintLine "stuupid found"
  .elseif Instr_(esi, "test")
     PrintLine "test found"
  .endif
  Inkey "Found something??", CrLf$
  .if Instr_(esi, "stuupid")
     PrintLine "stuupid found"
  .else
     .if Instr_(esi, "test")
          PrintLine "test found"
     .endif
  .endif
  Inkey "better??"
  Exit
end start

Title: Re: Resource compiler for console applications
Post by: nidud on October 25, 2012, 12:08:30 AM
By the way, I liked your discussion of the expansion problem (http://sourceforge.net/projects/jwasm/forums/forum/927109/topic/5793871), and would support the warning option, especially since the workaround is very straightforward:
Quote
The main argument is this: Masm’s behaviour is wrong.
Not a nice thing to bring into this snakepit of MASM fanatics jj :biggrin:

The problem in my view is all the exceptions made there, and if you continue along that path you will end up with more problems later. There is also a hidden opportunity in there, but it is complicated: I better stick to the basic ;)

I tried to follow the download link, but the page seems to be missing or blocked.
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 25, 2012, 12:21:22 AM
You are right that Masm's behaviour is "wrong", but where to draw the line? JWasm's strong points are full Masm32 compatibility plus more speed and macros for Win64. Adding features is risky with regard to the userbase.

OTOH, checking if a multiline macro is called after an .elseif seems not too difficult. A warning would really be helpful. Who needs it can use -WX aka "Treat all warnings as errors" ;-)

> I tried to follow the download link, but the page seems to be missing or blocked.
Not blocked for me, I just clicked the link in your message.
Title: Re: Resource compiler for console applications
Post by: nidud on October 25, 2012, 01:43:32 AM
You have to do it without breaking this compatibility: labelling it as a bug. But then, it is a part of the MASM design, so there.

> I tried to follow the download link, but the page seems to be missing or blocked.
include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0)
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 25, 2012, 02:15:05 AM
> You have to do it without breaking this compatibility: labelling it as a bug
You know that some software depends on bugs functioning properly  :icon_mrgreen:

I thought you meant the SourceFourge link...

MB is online at http://masm32.com/board/index.php?topic=94.0 and active: MasmBasic014Oct12.zip (362.15 kB - downloaded 23 times.)

So who could block a Masm page? AV? Provider? But then, you obviously can post here. I hope the crappy AV brigade has not blocked MasmBasic specifically... :(
Title: Re: Resource compiler for console applications
Post by: nidud on October 25, 2012, 03:13:09 AM
seems to work now, so now it’s installed.

> You know that some software depends on bugs functioning properly
hence the problem, so the warning message must come first

I compiled the sample, it produced a 3 447 641 byte .lst file, so there is definitely something under the hood :lol:
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 25, 2012, 03:31:41 AM
I compiled the sample, it produced a 3 447 641 byte .lst file

Which sample?

I just noticed that the "Simple window" template produces 380k of listing when putting .listall under the include line; however, when assembly option /Fl is specified, it jumps indeed to over 3MB. My testbed arrives at over 10MB of listing with /Fl set. Not exactly MasmBasic's fault, however: A simple MsgBox with masm32rt.inc only also produces 8MB with .listall before the include line...
Title: Re: Resource compiler for console applications
Post by: nidud on October 25, 2012, 04:20:39 AM
include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="This is a stupid test"
  .if Instr_(esi, "stuupid")
     PrintLine "stuupid found"
  .elseif Instr_(esi, "test")
     PrintLine "test found"
  .endif
  Inkey "Found something??", CrLf$
  .if Instr_(esi, "stuupid")
     PrintLine "stuupid found"
  .else
     .if Instr_(esi, "test")
          PrintLine "test found"
     .endif
  .endif
  Inkey "better??"
  Exit
end start
Title: Re: Resource compiler for console applications
Post by: dedndave on October 25, 2012, 06:16:55 AM
if you use /Fl, you may also want to use .XCREF in the source - it makes a big difference   :biggrin:
of course, it also helps to use .NOLIST and .LIST around the includes
Title: Re: Resource compiler for console applications
Post by: japheth on October 25, 2012, 07:56:06 PM
OTOH, checking if a multiline macro is called after an .elseif seems not too difficult.

That's indeed very good news! Since it is obviously a child's play, could you please tell me how to do it? With detailed source code, if you don't mind!
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 25, 2012, 09:22:20 PM
OTOH, checking if a multiline macro is called after an .elseif seems not too difficult.

That's indeed very good news! Since it is obviously a child's play, could you please tell me how to do it? With detailed source code, if you don't mind!

It's not child's play, of course, but IMHO a pretty basic exercise (sorry, can't help you with C code....):

include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0)
.data
MacTable   dd m1, m2, 0   ; see CreateMacTable
m1   dd 100   ; line count of macro
   db "Instr_", 0
m2   dd 1
   db "Instr1", 0

   SetGlobals posL, mac$
   Init
   SetGlobals
   Recall "TestElseIfDummyCode.asm", L$()
   ; call CreateMacTable      ; JWasm certainly has something like this, right?
   For_ ct=0 To eax-1
      mov edi, L$(ct)
      .if Instr_(edi, ".elseif", 1)
         add edx, 7
         mov posL, edx
         .if Instr_(edx, edi, "(")
            sub edx, posL
            Let mac$=Trim$(Mid$(edi, posL, edx))
            mov esi, offset MacTable
            .While 1
               lodsd
               .Break .if !eax
               mov ecx, [eax]
               add eax, DWORD
               .if !StringsDiffer(eax, mac$)
                  .if ecx>1
                     PrintLine "WARNING: ", mac$, " should not be used after .elseif!!"
                  .else
                     PrintLine "Congrats, using ", mac$, " is OK"
                  .endif
               .endif
            .Endw
         .endif
      .endif
   Next
   Inkey "ok"
   Exit
end start

TestElseIf.asm:

include \masm32\MasmBasic\MasmBasic.inc   ; download

Instr1 MACRO spos, src, match   ; a one-liner
  EXITM <ecx==12345678h>
ENDM
  Init
  mov ecx, 12345678h
  Let esi="This is a stupid test"
  .if Instr_(esi, "stuupid")
   PrintLine "stuupid found"
  .elseif Instr_(esi, "test")   ; useless, will expand before the jump label
   PrintLine "test found"
  .elseif Instr1(esi, "test")   ; will expand at the jump label
   PrintLine "Instr1 found it: ", Hex$(ecx)
  .endif
  Inkey CrLf$, "Found something??", CrLf$
  Exit
end start
Title: Re: Resource compiler for console applications
Post by: nidud on October 26, 2012, 04:53:09 AM
The resource editor now works, but the old version seems to be the better choice. The compiler will convert the files to OMF 32-bit format, so this will do for now.

I made an experimental IDE version for compiling the .asm, but this is 16-bit stuff. The library included is OMF (coff libs are to big). This means you need wmake, wlink and jwasm to build them.

I dump the files in the masm32 directory and tried to compile some of the samples there. Seems to work, but currently unstable stuff!
Title: Re: Resource compiler for console applications
Post by: nidud on October 26, 2012, 04:55:32 AM
The setup for tools is Alt-F1:
Quote
[ShiftF1]
asm=err jwasm -I%doszip%\include -Fl -Sg -Zd
[ShiftF2]
asm=err jwasm -I%doszip%\include -Fl -Sg -Zd -D__l__
[ShiftF3]
asm=err ml -c -I%doszip%\include -Zi
[ShiftF4]
asm=makeit.bat
[ShiftF5]
asm=rcedit

Title: Re: Resource compiler for console applications
Post by: nidud on October 26, 2012, 04:56:42 AM
Using Shift-F1 to compile:
Title: Re: Resource compiler for console applications
Post by: MichaelW on October 26, 2012, 05:01:48 AM
NULL is defined in windows.inc.
Title: Re: Resource compiler for console applications
Post by: nidud on October 26, 2012, 07:32:58 AM
NULL is defined in windows.inc.
Yes, so it works  :biggrin:
Title: Re: Resource compiler for console applications
Post by: japheth on October 26, 2012, 07:04:04 PM
It's not child's play, of course, but IMHO a pretty basic exercise (sorry, can't help you with C code....):

Even a macro that consists of just EXITM may not work, since the argument behind EXITM may be another macro. So you'll probably have to add recursion in your source sample ( which I cannot read, because I'm suffering from a severe BaSiCphobia , sorry! ).
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 26, 2012, 08:53:54 PM
... your source sample ( which I cannot read,

Strange, very strange: JWasm has no problems to read my sources :icon_mrgreen:
Title: Re: Resource compiler for console applications
Post by: nidud on October 26, 2012, 11:43:56 PM
That's indeed very good news! Since it is obviously a child's play, could you please tell me how to do it? With detailed source code, if you don't mind!
I could help you implement this providing you agree to do as follows: You will copy the content of this code and complement it to cover all the cases needed.

Code: [Select]
l0: upcode
l1: upcode,macro
l2: .if upcode
l3: .if macro
l4: .elseif upcode
l5: .elseif macro
l6: .while upcode
l7: .while macro
l8: .until upcode
l9: .until macro
lA: .continue .if upcode
lB: .continue .if macro
lC: .break .if upcode
lD: .break .if macro
lE: .endw
lF: .repeat
The first thing to do is to create a test case for this code, and insert 4 rows of X’s in the new post (made by you). In the first row you will provide the result using the oldest version of MASM you could find, the second row the newest. The next two rows will be the oldest version (J)WASM and the newest.

The next thing to do is to find the highest code level of the line-feed. This will be the proc using the fgets(..) I assume, and then the location of the first tokenize-call. Make shore that the tokenizer does not have a side job, and only do what it supposes to do: convert the line into tokens. If this is not the case, the code must be moved to a lower level. You should be in the if (GetLine()) if (Tokenize()) Parseline(tokens) situation.

Rename Parseline to Parseline2, and make a new Parseline proc. For now this proc only passes args to Passline2.

The third thing to do: Remove all exceptions below Parsline2 that contain code that test for the if (tokencount > 1 && token[0] == label).

The fourth thing to do: mail me the updated code. I will then insert a ugly hack into the Parseline proc and return the binary for testing. If the binary pass the test code (not the Regression test), then you will remove the labels from the first test and produce a new one, only including the HLL functions.

The next step will be to implement full support for the HLL code, and test to see that this work as expected.

Then comes the ugly Regression test that will reveal all the bugs created in this process. I will the retreat back into a neutral corner and stay very quiet for a month or two till somebody else fixes the mess created. :P
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 27, 2012, 01:03:49 AM
Hi nidud,

AFAICS the problem is mainly relevant for two cases: elseif macro() and or'ed macros like this:
   ; Let esi="This is a stupid test"
   .Break .if Instr_(esi, "stuupid")   ; works correctly
   ; both macros get expanded at the label, but only the second one gets tested
   .Break .if Instr_(esi, "stuupid") || Instr_(esi, "stupid")

There is, of course, a simple workaround for the latter case: two .Break .if lines.
Again, a warning for the noobs would be luxury, but Japheth seems not so eager to dig into it, so I'll pull out and leave him in peace  :icon14:
Title: Re: Resource compiler for console applications
Post by: nidud on October 27, 2012, 04:12:12 AM
I think I have solved the label issue.
I moved the expansion from GetPreprocessedLine to the ParseLine proc,
below the create a global or local code label function.

I compiled 1264 files, 16 and 32-bit, no problem.

However, using the –Zm switch created a General Failure on this code:
Code: [Select]
assert al,0,jne,"tiflushl: al=0"
And the problem line in the macro: (%)
Code: [Select]
% db "cmp &A&,&B& (&J&)  -: ",message,0

The next trick is to halt expansion of these two:
.elseif macro
.while macro
And expand them in the HLL section (with or without macros that is).

Title: Re: Resource compiler for console applications
Post by: jj2007 on October 27, 2012, 05:00:44 AM
The next trick is to halt expansion of these two:
.elseif macro
.while macro

Right, I forgot the .While macro() case in my post above.
Title: Re: Resource compiler for console applications
Post by: nidud on October 27, 2012, 07:53:41 AM
Ok, I’m in the HLL section :P

This code is called by GetPreprocessedLine:
Code: [Select]
ret_code ExpandLine_xlabel( char *string, struct asm_tok tokenarray[] )
{
    if (Token_Count > 2 && (tokenarray[1].token == T_COLON || tokenarray[1].token == T_DBL_COLON))
return 0;
    return ExpandLine( string, tokenarray );
}
At the end of ExpandLine:
Code: [Select]
std_expansion:
    i = 0;
    for (j = 0; j < Token_Count; j++) {
    if (!stricmp(tokenarray[j].string_ptr,".elseif") ||
        !stricmp(tokenarray[j].string_ptr,".while")) {
    i = 1; /* block expansion */
    break;
}
    }
    for(  ; count < Token_Count; count++ ) {
if ( ExpandToken( count, tokenarray, string, addbrackets, i ) == STRING_EXPANDED )
    rc = STRING_EXPANDED;
    }
The proc GetExpression(“.elseif func(foo)”)
Code: [Select]
    for ( ;; ) {
        ptr = ptr + strlen( ptr );
        cur_pos = *i;
        if ( ERROR == GetAndExpression( hll, i, tokenarray, ilabel, is_true, ptr, lastjmp, opndx ) )
            return( ERROR );
Return
Code: [Select]
elseif.asm(13) : Error A2243: Invalid symbol type in expression: func
Not shore how to do the actual expansion here, RunMacro() ?

Title: Re: Resource compiler for console applications
Post by: nidud on October 27, 2012, 08:12:52 AM
I forgot..
The new declaration for ParseLine:
Code: [Select]
ret_code ParseLine ( char *line, struct asm_tok tokenarray[] )
Inserted below label function:
Code: [Select]
    /* expand the line */
    if ( CurrIfState == BLOCK_ACTIVE ) {
/* expand (text) macros. If expansion occured, rescan the line */
while ( Token_Count > 0 && ExpandLine( line, tokenarray ) == STRING_EXPANDED ) {
    DebugMsg1(("GetPreprocessedLine: expanded line is >%s<\n", line));
    Token_Count = Tokenize( line, 0, TRUE );
}
    }

    /* handle directives and (anonymous) data items */
I just copyed this in there, so this needs some help.
Title: Re: Resource compiler for console applications
Post by: japheth on October 27, 2012, 06:46:02 PM
I forgot..
The new declaration for ParseLine:
Code: [Select]
ret_code ParseLine ( char *line, struct asm_tok tokenarray[] )
Inserted below label function:
Code: [Select]
    /* expand the line */
    if ( CurrIfState == BLOCK_ACTIVE ) {
/* expand (text) macros. If expansion occured, rescan the line */
while ( Token_Count > 0 && ExpandLine( line, tokenarray ) == STRING_EXPANDED ) {
    DebugMsg1(("GetPreprocessedLine: expanded line is >%s<\n", line));
    Token_Count = Tokenize( line, 0, TRUE );
}
    }

    /* handle directives and (anonymous) data items */
I just copyed this in there, so this needs some help.

Brrr, what an ugly mess - just for such a VEEEEERRRRY minor issue!? If you mix preprocessor and parser functionality like in your proposal, you'll end in a totally unreadable and unmaintainable pile of sh...

btw, you don't want to query CurrIfState once the conditional assembly directives (IF, ELSE,...) have been handled in the preprocessor.
Title: Re: Resource compiler for console applications
Post by: nidud on October 27, 2012, 08:27:29 PM
Brrr, what an ugly mess - just for such a VEEEEERRRRY minor issue!? If you mix preprocessor and parser functionality like in your proposal, you'll end in a totally unreadable and unmaintainable pile of sh...

btw, you don't want to query CurrIfState once the conditional assembly directives (IF, ELSE,...) have been handled in the preprocessor.
My mane augment is the same:
I expect the same capability of the IF statement as the ELSEIF statement: there is logic in the argument.

So, humour me a bit here without wasting too much energy on it :bgrin:

Lets take a .break from the .while issue and focus on the label situation for a moment.
The code below will illustrait the problem:
Code: [Select]
l1: mov edx,func(foo)

00000000      1  invoke foo
00000000  E800000000        *1   call foo
00000005  8BD0  l1: mov edx,eax
The line argument may be replaced with CurrSource here and just use the old declaration of Parseline.
Code: [Select]
    if (i == 2) {
while (Token_Count > 0 && ExpandLine(line, tokenarray) == STRING_EXPANDED)
    Token_Count = Tokenize(line,0,TRUE);
    }
Good (or at least better)?

result:
Code: [Select]
00000000 l1:
00000000      1  invoke foo
00000000  E800000000        *1   call foo
00000005  8BD0  mov edx,eax
Title: Re: Resource compiler for console applications
Post by: japheth on October 27, 2012, 09:55:58 PM
Good (or at least better)?

I don't dare to judge.

The only approach that has a faint chance to be implemented is to delay macro expansion by some kind of syntax extension. You can see this approach in effect in struct initialization, when a macro call is located within the initialization literal. Quite the same approach may be added to the hll directives, that is, the macro call has to be enclosed in <>:

    .if <whatever()>

with this approach, you just have to add a few lines in hll.c ( determine if there's a literal following the directive and if so, expand the rest of the line ), the rest of the code remains as it is.

Title: Re: Resource compiler for console applications
Post by: nidud on October 28, 2012, 06:26:02 AM
I looked at the source code for v2.08, and there have been some major changes there. And, as you mention above, a delayed expansion mechanism are already included. This means that I have to wait for a stable source base to play with (v2.08 have some issues, so the last stable source is still v2.06).

I did however apply some changes to the current version. The code above was removed (didn’t work very well), and a more brutal approach was inserted instead (oh yes, its very very ugly): :lol:
Code: [Select]
    /* Does line start with a code label? */
    if ( tokenarray[0].token == T_ID && ( tokenarray[1].token == T_COLON || tokenarray[1].token == T_DBL_COLON ) ) {
DebugMsg1(("ParseLine T_COLON, code label=%s\n", tokenarray[0].string_ptr ));
if( DefineProc == TRUE ) write_prologue();
/* create a global or local code label */
if( CreateLabel( tokenarray[0].string_ptr, MT_NEAR, NULL,
    ( CurrProc != NULL && tokenarray[1].token != T_DBL_COLON  ) ) == ERROR ) {
    DebugMsg(("ParseLine, CreateLabel(%s) failed, exit\n", tokenarray[0].string_ptr ));
    return( ERROR );
}
if (tokenarray[2].token != T_FINAL)
    AddLineQueue(tokenarray[2].tokpos);
strcpy(CurrSource, tokenarray[0].string_ptr);
strcat(CurrSource, tokenarray[1].string_ptr);
Token_Count = Tokenize(CurrSource, 0, TRUE);
FStoreLine();
if (CurrFile[LST])
    LstWrite(LSTTYPE_LABEL, 0, NULL);
return( NOT_ERROR );
    }
from
label: <whatever>
to
label:
<whatever>

.while and .elseif are now expanded in the hll.c file: (still incorrectly)
Code: [Select]
    case T_DOT_WHILE:
for(q = i; q < Token_Count; q++) {
        if (ExpandToken(q, tokenarray, CurrSource, 0, 0) == STRING_EXPANDED)
Token_Count = Tokenize( CurrSource, 0, TRUE );
    else
break;
}
...
    case T_DOT_ELSEIF:
for(q = i+1; q < Token_Count; q++) {
        if (ExpandToken(q, tokenarray, CurrSource, 0, 0) == STRING_EXPANDED)
Token_Count = Tokenize( CurrSource, 0, TRUE );
    else
break;
}
    case T_DOT_ELSE:
Strangely enough this seems to work very well, but a regression test will probably tell a different story.
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 28, 2012, 09:26:45 AM
...but a regression test will probably tell a different story.

Unfortunately yes. My little testbed (attached) with the .While Instr_(esi, ... stuff reports plenty of errors, while the latest JWasm build (25-Oct-2012 04:03) works just fine.
Strangely enough, your modified version assembles my fat testbed without any problems. So it must really be the specific "warning" code.

In the meantime, I have instructed my editor (RichMasm, part of the MasmBasic package (http://masm32.com/board/index.php?topic=94.0)) to issue a warning for
.While mac()
and
.elseif mac()
- imho the most relevant cases. That was really hard work for a noob who understands only BASIC, but it seems to fit the purpose, and the performance loss is acceptable: overall build time with JWasm is 0.2% slower for the RichMasm source with its 14,000 lines :biggrin:
Title: Re: Resource compiler for console applications
Post by: nidud on October 28, 2012, 08:36:01 PM
You could read the error out of the expansion code above. The break statement must be removed. They will only work if the first token is a macro, if not, the expansion of the rest of the line is dropped.

This works: .while mac() > edx
This will fail: .while edx <= mac()

However, you may have to look at the ones that fail since they could expand code in the wrong place.

I compiled two new versions, one that only fixes the label issue, and one that delay the .elseif and .while.
Title: Re: Resource compiler for console applications
Post by: nidud on October 28, 2012, 09:51:47 PM
Problem executing .EXE in local directory

This configuration will not execute jwasm in the current directory:
Quote
[ShiftF1]
asm=err jwasm -I%doszip%\include -Fl -Sg -Zd

If I delete the version in the %PATH% it will, or if I use .\jwasm.exe.
In DOS the current directory will be scanned first, then the %PATH%.
So, is this normal behavior?

Code: [Select]
; PIPE.ASM--
; Error Message Pipe for Edit
;
; PIPE <command> <args>
;
; Creates a buffer of stdout and stderr from Shell(command)
; If Shell() returns a value (errorlevel) ParseOutput() is called
;
include clib.inc
include io.inc
include dir.inc
include dos.inc
include alloc.inc
include stdio.inc
include string.inc
include process.inc

; extern parser for output
ParseOutput proto stdcall Buffer:dword, bSize:dword

.code

BUFFERSIZE equ 40000h

main proc c uses ebx edi esi
local cmd[WMAXPATH]:byte
local sa:SECURITY_ATTRIBUTES
local pi:PROCESS_INFORMATION
local sinfo:STARTUPINFO
local hRd:dword
local hWr:dword
local hDup:dword
local buffer:dword
local dwCount:dword
local ExitCode:dword
mov edi,_argc
mov esi,_argv
.if _argc > 1
    lea ebx,cmd
    lodsd
    lodsd
    invoke strcpy,ebx,eax
    sub edi,2
    .if edi
    .repeat
    invoke strcat,ebx,cstr(" ")
    lodsd
    invoke strcat,ebx,eax
    dec edi
.until !edi
    .endif
    sub eax,eax
    mov ExitCode,eax
    mov dwCount,eax
    lea edi,sinfo
    mov ecx,sizeof(STARTUPINFO)/4
    rep stosd
    mov sa.bInheritHandle,1
    mov sa.lpSecurityDescriptor,0
    mov sa.nLength,sizeof(SECURITY_ATTRIBUTES)
    .if func(CreatePipe,addr hRd,addr hWr,addr sa,0)
call GetCurrentProcess
mov edi,eax
invoke DuplicateHandle,edi,hRd,edi,addr hDup,0,0,DUPLICATE_SAME_ACCESS
mov esi,eax
invoke CloseHandle,hRd
.if esi
    mov sinfo.cb,sizeof(STARTUPINFO)
    invoke GetStartupInfoA,addr sinfo
    mov eax,hWr
    mov sinfo.hStdOutput,eax
    mov sinfo.hStdError,eax
    mov sinfo.dwFlags,STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES
    mov sinfo.wShowWindow,SW_HIDE
    .if func(CreateProcessA,0,addr cmd,0,0,10h,0,0,0,addr sinfo,addr pi)
invoke CloseHandle,hWr
mov esi,BUFFERSIZE
.if func(GlobalAlloc,GMEM_FIXED,esi)
    mov buffer,eax
    mov edi,eax
    sub eax,eax
    mov ecx,BUFFERSIZE/4
    rep stosd
    mov edi,buffer
    .repeat
invoke ReadFile,hDup,edi,esi,addr dwCount,0
.break .if !eax
mov eax,dwCount
add edi,eax
sub esi,eax
.break .if !esi
    .until !eax
.endif
      .repeat
    invoke GetExitCodeProcess,pi.hProcess,ADDR ExitCode
.until ExitCode != STILL_ACTIVE
invoke CloseHandle,pi.hProcess
invoke CloseHandle,pi.hThread
mov eax,BUFFERSIZE
sub eax,esi
.if eax
    invoke ParseOutput,buffer,eax
.endif
.if buffer
    invoke GlobalFree,buffer
.endif
sub eax,eax
    .else
    invoke _print,cstr(<"Unable to create process",10>)
mov eax,1
    .endif
.else
        invoke _print,cstr(<"Unable to duplicate handle",10>)
        mov eax,1
.endif
    .else
    invoke _print,cstr(<"Unable to create pipe",10>)
    mov eax,1
    .endif
.else
    invoke _print,cstr(<"Usage: PIPE <command> <args>",10>)
    sub eax,eax
.endif
    ret
main endp

end
Title: Re: Resource compiler for console applications
Post by: nidud on October 29, 2012, 11:32:13 PM
Turns out that the PATH environment is scanned last after all, but something else is inserted above the current directory:
Quote
If the file name does not contain a directory path, the system searches for the executable file in the following sequence:

1. The directory from which the application loaded.
2. The current directory for the parent process.
..
6. The directories that are listed in the PATH environment variable.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

At the top of this page:
Quote
93 out of 246 rated this helpful
Well, it does actually help (the information that is), but I would prefer to have flipped the two first ones.
Title: Re: Resource compiler for console applications
Post by: nidud on October 30, 2012, 12:19:42 AM
The continuing High Level Language issue.

The asm-token .elseif is not really a HLL token, but a macro:
Code: [Select]
if ( <expression> ) <statement1>
else <statement2>
<statement2> could then be else <if (<expression>)>, and the parsing of the macro should then be recursive, and all expansion done locally.

The correct usage of the .else(if) is currently then:
Code: [Select]
.if <expression>
    <statement>
.else
    .if <expression>
<statement>
    .endif
.endif

Since all these currently are pre-expanded, and only the result of <expression> is handled locally, this will be rather hard to achieve. However, if the label: <expression> issue is removed, the only problem the pre-expansion will make is this:
Code: [Select]
while (<expression>) <statement>
I created a new version that fixes the label issue, and gives a warning if code is expanded above the label.
Compiling JJ’s test case now gives this output:
Code: [Select]
test1.asm(7) : Warning A4275: Code expanded above label: .elseif
Title: Re: Resource compiler for console applications
Post by: jj2007 on October 30, 2012, 01:44:16 AM
Hi nidud,

The warning works fine but somewhere a regression has crept in - see Jwasm expands macros inside quoted text (https://sourceforge.net/tracker/?func=detail&aid=3142937&group_id=255677&atid=1126895)...

Sorry that I can't help you with that - C is just not my cup of tea...

jj
Title: Re: Resource compiler for console applications
Post by: nidud on October 30, 2012, 05:09:40 AM
This is compiled by the source of version 2.06e; so all improvements and bug fixes done in later releases are not included in this binary.

The aim here is to find a way to handle the <expression> without creating any exceptions along the road. The content of the <expression> is a hornets' nest, and you should never poke into it, because it will only create a lot of trouble.

The simple rule then is that an <expression> is an <expression> is an <expression>, and the content of it is only limited by the imagination of the programmer. This is very vivid (as it should be) and your code seems to be a very good test bed for this venture.

The first step is to find a clean break, so that the parsing of the line starts with the HLL token, and not with a label. So if the ugly hack inserted to break the label: macro()/.HLL works, as it seems to do, then we are on to a good start.

It is also important that the labels starts with the expansion, and not the evaluation. Labels could be public, so jumps to .HLL sections must also be correct.
Code: [Select]
label: .break .if func(foo)currently expands to
Code: [Select]
call foo
label:
.break .if eax

The clean break fixes all these cases, but the labels used inside the HLL section must also follow this logic, so it’s a slow burning fuse.

The warnings from the last compile also include text macros, so this will also generate a warning:
Code: [Select]
ax? equ eax
.while ax?

The version 2.06 works well on my end, so that’s the reason why I use this one.
Title: Re: Resource compiler for console applications
Post by: nidud on November 05, 2012, 10:13:43 AM
A brief test for .ELSEIF <expression> and .WHILE <expression> using JWasm 2.08a

The hookup currently assumes token[0] is the .HLL:
expans.c
Code: [Select]
ret_code ExpandLine( char *string, struct asm_tok tokenarray[] )
/**************************************************************/
...
#ifdef __EXPANDHLL
    if (stricmp(tokenarray[0].string_ptr, ".elseif") &&
    stricmp(tokenarray[0].string_ptr, ".while"))
#endif
while ( count < Token_Count ) {

hll.c
Added flags to hll_flags:
Code: [Select]
enum hll_flags {
    HLLF_ELSEOCCURED = 0x01,
#ifdef __EXPANDHLL
    HLLF_ELSEIF = 0x02,
    HLLF_WHILE = 0x04,
    HLLF_EXPRESSION = 0x08,
#endif

Allocate <expression> to hll->condlines:
Code: [Select]
    DebugMsg1(("EvaluateHllExpression enter\n"));

#ifdef __EXPANDHLL
    if (hll->flags & HLLF_ELSEIF || hll->flags & HLLF_WHILE) {
if (!(hll->flags & HLLF_EXPRESSION)) {
    if ((hll->condlines = LclAlloc(strlen(tokenarray[0].tokpos) + 1)) != NULL) {
    strcpy(hll->condlines, tokenarray[0].tokpos);
hll->flags |= HLLF_EXPRESSION;
return NOT_ERROR;
        }
}
return ERROR;
    } else {
    buffer[0] = NULLC;
    if (ERROR == GetExpression(hll, i, tokenarray, ilabel, is_true, buffer, &hllop, &opndx))
    return( ERROR );
    if (buffer[0])
    WriteExprSrc(hll, buffer);
    }
#else
...
#endif

Start .WHILE and .ELSEIF <expression>:

Code: [Select]
/* Start a .IF, .WHILE, .REPEAT item */

ret_code HllStartDir( int i, struct asm_tok tokenarray[] )
/********************************************************/
...
#ifdef __EXPANDHLL
    hll->flags = 0;
#endif
...
    case T_DOT_WHILE:
    case T_DOT_REPEAT:
/* create the label to loop start */
hll->labels[LSTART] = GetHllLabel();
hll->labels[LEXIT] = GetHllLabel();
if ( cmd == T_DOT_WHILE ) {
    hll->cmd = HLL_WHILE;
    if ( tokenarray[i].token != T_FINAL ) {
#ifdef __EXPANDHLL /* optimisation: ... */
hll->flags |= HLLF_WHILE;
if (tokenarray[i+1].token == T_FINAL &&
    tokenarray[i].string_ptr[0] == '1' &&
    tokenarray[i].string_ptr[1] == 0)
    hll->flags = 0;

#endif

Expand .ELSEIF and .WHILE <expression>:

Code: [Select]
/* Exit current .IF, .WHILE, .REPEAT item
 * that is: .ELSE, .ELSEIF, .CONTINUE and .BREAK are handled here
 */
ret_code HllExitDir( int i, struct asm_tok tokenarray[] )
/*******************************************************/
...
#ifdef __WATCOMC__
    enum hll_flags      savedflags;  /* for .BREAK/.CONTINUE .IF */
#else
    char savedflags;
#endif
...
    case T_DOT_ELSEIF:
#ifdef __EXPANDHLL
hll->flags |= HLLF_ELSEIF;
#endif
    case T_DOT_ELSE:
...
if ( cmd == T_DOT_ELSEIF ) {
    /* create new labels[LTEST] label */
    hll->labels[LTEST] = GetHllLabel();
    if ( ERROR == EvaluateHllExpression( hll, &i, tokenarray, LTEST, FALSE ) ) {
rc = ERROR;
break;
    }
#ifdef __EXPANDHLL
    if (HllPushLines() == ERROR)
rc = ERROR;
#else
    HllPushLines();
#endif
...
/* End a .IF, .WHILE, .REPEAT item
 * that is: .ENDIF, .ENDW, .UNTIL and .UNTILCXZ are handled here
 */
ret_code HllEndDir( int i, struct asm_tok tokenarray[] )
/******************************************************/

And testing an actual expansion of <expression>:

Code: [Select]
#ifdef __EXPANDHLL
 #define HllPushLines() HllPushTestLines( hll, tokenarray )
 extern ret_code ExpandToken(char *, int *, struct asm_tok tokenarray[], int, int, int);
#else
 #define HllPushLines() HllPushTestLines( hll )
#endif
...
#ifdef __EXPANDHLL
static ret_code HllPushTestLines( struct hll_item *hll, struct asm_tok tokenarray[])
#else
static ret_code HllPushTestLines( struct hll_item *hll )
#endif
/******************************************************/
...
#ifdef __EXPANDHLL
    if (hll->flags & HLLF_EXPRESSION) {
int result,q,i,x;
if (hll->flags & HLLF_WHILE) {
    x = 1;
    i = LSTART;
} else if (hll->flags & HLLF_ELSEIF) {
    x = 0;
    i = LTEST;
} else {
    return ERROR;
}
strcpy(buffer, tokenarray[0].string_ptr);
hll->flags &= ~(HLLF_ELSEIF | HLLF_WHILE | HLLF_EXPRESSION);
if (ModuleInfo.list)
    LstWrite(LSTTYPE_DIRECTIVE, GetCurrOffset(), NULL);
if (is_linequeue_populated()) {
    RunLineQueue();
#if FASTPASS /* listing is destroyed ...?? */
    if (ModuleInfo.list)
LstWrite(LSTTYPE_DIRECTIVE, GetCurrOffset(), NULL);
#endif
}
strcpy(CurrSource, hll->condlines);
Token_Count = Tokenize(CurrSource, 0, tokenarray, TOK_DEFAULT);
for (q = 1; q < Token_Count; q++) {
    result = ExpandToken(CurrSource, &q, tokenarray, Token_Count, 0, 0);
    if (result == STRING_EXPANDED) {
Token_Count = Tokenize(CurrSource, 0, tokenarray, TOK_DEFAULT);
    } else if (result == ERROR) {
    return ERROR;
    }
}
#if FASTPASS /* add a pending line on first pass ...?? */
if (Parse_Pass == PASS_1 && result)
    LineStoreCurr->line[0] = ';';
#endif
LclFree(hll->condlines);
hll->condlines = NULL;
q = 1;
if (ERROR == EvaluateHllExpression(hll, &q, tokenarray, i, x))
    return(ERROR);
p = hll->condlines;
strcpy(CurrSource, buffer);
Token_Count = Tokenize(CurrSource, 0, tokenarray, TOK_DEFAULT);
    }
#endif
...
}

This code actually pass the regression test in v2.08a, but using it creates problems. It will normally generate an error if the macros are too clever, but expands simple func(proc) macros correctly.

If FASTPASS is defined (default), a hack will be needed to kill the current line, else invoke func(proc) will be added again.

I also tested the label hack, but this currently don't pass:
Code: [Select]
EXPANS10.ASM(17) : Error A2209: Syntax error: m1
open error file 'EXPANS10.BIN' [2]
MACRO8.ASM(22) : Error A2209: Syntax error: m1x
 m1(6)[MACRO8.ASM]: Macro called from
  MACRO8.ASM(22): Main line code
open error file 'MACRO8.BIN' [2]
open error file 'LABEL3.ERR' [2]
Title: Re: Resource compiler for console applications
Post by: hfheatherfox07 on February 19, 2013, 11:29:47 AM
Hi all

One of the first programs I wrote was a 16-bit resource editor, and most of the programs I have made after that has been based on using this tool. It is very simplistic and hard to handle in some cases, but it still works.

The programs I made are still used (mostly by old farts), but the main problem with them is the lack of DOS support in newer hardware, especially printers. I also have a small baby project online, which I have been nursing for some time, but now MS is blocking the use of such applications even in XP.

Most of these programs are written in C/C++, so the plan was to convert the resource compiler to 32-bit instead of rewriting all this code. My knowledge of assembly is from 16-bit TASM, so I’m a bit rusty with regards to 32-bit MASM.

The learning curve will be to grind through the console functions first, using kernel32.lib and a few functions from user32.lib (clipboard functions).

The first problem I run into was the color setup, and here is some of the code used for manipulating colors used in 16-bit code:

Code: [Select]
include clib.inc
include conio.inc
include mouse.inc

.code

setpal proc _CType public uses bx? palid:size_t, clid:size_t
test console,CON_COLOR
jz setpal_end
ifndef __f__
mov ax,palid
mov dx,clid
mov     ch,al
mov     bx,dx
mov     ax,0040h
mov     es,ax
mov     dx,es:[0063h]
cmp dx,03D4h
jne setpal_end
cli
mov dx,03DAh
in al,dx
mov dx,03C0h
mov     al,bl
out     dx,al
mov     al,ch
out     dx,al
mov dx,03DAh
in      al,dx
mov dx,03C0h
mov     al,20h
out     dx,al
sti
else
; missing 32-bit code
endif
    setpal_end:
ret
setpal endp

resetpal proc _CType public
push si?
xor si?,si?
.repeat
    invoke setpal,si?,si?
    inc si?
.until si? == 8
mov si?,56
.repeat
    mov ax?,si?
    add ax?,-48
    invoke setpal,si?,ax?
    inc si?
.until si? == 64
invoke setpal,0014h,0006h
pop si?
ret
resetpal endp

getxya proc _CType public x:size_t, y:size_t
ifndef __f__
invoke getxyw,x,y
mov al,ah
mov ah,0
else
    local lpCharacter:dword, lpNumberOfAttributesRead:dword
mov eax,y
shl eax,16
add eax,x
mov ecx,eax
invoke ReadConsoleOutputAttribute,
    OFSH_OUTPUT,addr lpCharacter,1,ecx,addr lpNumberOfAttributesRead
mov eax,lpCharacter
and eax,00FFh
endif
ret
getxya endp

scputa proc _CType public uses ax? dx? x:size_t, y:size_t, l:size_t, a:size_t
 ifndef __f__
mov al,byte ptr x
mov ah,byte ptr y
call __getxypm
invoke wcputa,dx::ax,l,a
ShowMouseCursor
 else
local pcx:dword
push ecx
movzx ecx,byte ptr a
movzx eax,byte ptr x
movzx edx,byte ptr y
shl edx,16
mov dx,ax
invoke FillConsoleOutputAttribute,OFSH_OUTPUT,ecx,l,edx,addr pcx
pop ecx
 endif
ret
scputa endp

end

The code assign value [0..255] to index [0..15]

So, to my first question: is there a simple way to rearrange the 256 palettes like this in 32-bit, or do I have to apply a table of some sort for that?

The library used for this code could be downloaded from this site: https://sourceforge.net/projects/doszip/files/

hello ,
any chance of the source code for this attachment ?
Like to see the 16bit
Title: Re: Resource compiler for console applications
Post by: hfheatherfox07 on February 21, 2013, 10:04:14 AM
Actually I am just looking for an example source for text mode
That 16bit is before my time ,
I did find the interrupts , what a mess LOL

http://www.ziplib.com/emu8086/interrupts.html