Author Topic: Resource compiler for console applications  (Read 17657 times)

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: Resource compiler for console applications
« Reply #45 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.

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: Resource compiler for console applications
« Reply #46 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

jj2007

  • Member
  • *****
  • Posts: 7542
  • Assembler is fun ;-)
    • MasmBasic
Re: Resource compiler for console applications
« Reply #47 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...

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

jj

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: Resource compiler for console applications
« Reply #48 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.

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: Resource compiler for console applications
« Reply #49 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]

hfheatherfox07

  • Member
  • ***
  • Posts: 464
Re: Resource compiler for console applications
« Reply #50 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
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

hfheatherfox07

  • Member
  • ***
  • Posts: 464
Re: Resource compiler for console applications
« Reply #51 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
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.