News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

JWASM: ERROR A2030: Instruction or register not accepted in current CPU mode

Started by bugthis, March 29, 2025, 07:32:16 PM

Previous topic - Next topic

bugthis

This code
.MODEL SMALL, C, OS_DOS
.STACK 20
.DATA
  STRING DB "Hello World!", 13, 10, "$"
.CODE
.STARTUP
  LEA DX, STRING
  MOV AH, 09h
  INT 21h
  .EXIT
  END
produces the following error:
test.asm (10): ERROR A2030: Instruction or register not accepted in current CPU mode
test.asm: 11 lines, 1 passes, .. ms, 0 warnings, 1 errors
The asm code was compiled with:
jwasmr -mz test.asm

If i replace
.MODEL SMALL, C, OS_DOS
with
.MODEL SMALL, C
by removing OS_DOS the code compiles and runs without errors.

Why does this OS_DOS option have such a big impact?
And what is the reason for this?
Why does it fail after the first pass? The working version is made with 2 passes.
Could this be a bug in JWASM v2.14 from Dec 20 2020?

Vortex


_japheth

Quote from: bugthis on March 29, 2025, 07:32:16 PMWhy does this OS_DOS option have such a big impact?
And what is the reason for this?
Why does it fail after the first pass? The working version is made with 2 passes.
Could this be a bug in JWASM v2.14 from Dec 20 2020?

Sooo many questions! That's actually a full-time job to answer them...

Could this be a bug in JWASM v2.14 from Dec 20 2020? - No, it's still there in the current version.
Why does it fail after the first pass? The working version is made with 2 passes. I don't know. Is this important?
Why does this OS_DOS option have such a big impact? Well, define "big"!
And what is the reason for this? Instead of an answer, here's the relevant JWasm code ( cpumodel.c ) - or rather the data definitions:

#define INIT_LANG       0x1
#define INIT_STACK      0x2
#define INIT_OS         0x4

struct typeinfo {
    uint_8 value;  /* value assigned to the token */
    uint_8 init;   /* kind of token */
};

static const char * const ModelAttr[] = {
    "NEARSTACK", "FARSTACK", "OS_OS2", "OS_DOS" };

static const struct typeinfo ModelAttrValue[] = {
    { STACK_NEAR,     INIT_STACK      },
    { STACK_FAR,      INIT_STACK      },
    { OPSYS_DOS,      INIT_OS         },
    { OPSYS_OS2,      INIT_OS         },
};

A little riddle: can you see the bug just be examining that data?

I guess it's a bug that exists since the very beginning of jwasm - that is 03/2008, so it celebrates its 17th birthday these days.
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

bugthis

Quote from: _japheth on March 29, 2025, 09:26:24 PMCould this be a bug in JWASM v2.14 from Dec 20 2020? - No, it's still there in the current version.
Thanks for testing.

QuoteInstead of an answer, here's the relevant JWasm code ( cpumodel.c ) - or rather the data definitions:

#define INIT_LANG       0x1
#define INIT_STACK      0x2
#define INIT_OS         0x4

struct typeinfo {
    uint_8 value;  /* value assigned to the token */
    uint_8 init;   /* kind of token */
};

static const char * const ModelAttr[] = {
    "NEARSTACK", "FARSTACK", "OS_OS2", "OS_DOS" };

static const struct typeinfo ModelAttrValue[] = {
    { STACK_NEAR,     INIT_STACK      },
    { STACK_FAR,      INIT_STACK      },
    { OPSYS_DOS,      INIT_OS         },
    { OPSYS_OS2,      INIT_OS         },
};

A little riddle: can you see the bug just be examining that data?

Yes, either the names are wrong in:
static const struct typeinfo ModelAttrValue[] = {
    { STACK_NEAR,     INIT_STACK      },
    { STACK_FAR,      INIT_STACK      },
    { OPSYS_DOS,      INIT_OS         },
    { OPSYS_OS2,      INIT_OS         },
};
and it must be changed as follows:
static const struct typeinfo ModelAttrValue[] = {
    { NEARSTACK,     INIT_STACK      },
    { FARSTACK,      INIT_STACK      },
    { OS_DOS,        INIT_OS         },
    { OS_OS2,        INIT_OS         },
};
of the order of OPSYS_DOS and OPSYS_OS2 needs to be swapped.
static const struct typeinfo ModelAttrValue[] = {
    { STACK_NEAR,     INIT_STACK      },
    { STACK_FAR,      INIT_STACK      },
    { OPSYS_OS2,      INIT_OS         },
    { OPSYS_DOS,      INIT_OS         },
};
If STACK_NEAR, STACK_FAR, OPSYS_OS2, and OPSYS_DOS are defined somewhere outside of your code snippet, then I suspect the latter.
And ultimately, it could be a combination of both, in which case it would need to be changed as follows:
static const struct typeinfo ModelAttrValue[] = {
    { NEARSTACK,     INIT_STACK      },
    { FARSTACK,      INIT_STACK      },
    { OS_OS2,        INIT_OS         },
    { OS_DOS,        INIT_OS         },
};
It's also possible that the wrong values are being assigned. OPSYS_OS2 and OPSYS_DOS are given exactly the same value. Perhaps one of them should be INIT_LANG? INIT_LANG is not used anywhere and it may well be that the value in the struct is used later for differentiation and is therefore dependent on the correctly assigned value. On the other hand, OS/2 and DOS are both operating systems, so the value INIT_OS could also be correct. It just depends on what the rest of the code says.

QuoteI guess it's a bug that exists since the very beginning of jwasm - that is 03/2008, so it celebrates its 17th birthday these days.
Great, then I found a bug in JWASM, which can be fixed, and JWASM will have one less bug in future versions.
Unfortunately, I don't have a GitHub account and therefore can't create a bug report. If you could report the bug to the developers, that would be great.


_japheth

Quote from: bugthis on March 30, 2025, 09:30:04 AMYes, either the names are wrong in:
...
and it must be changed as follows:
...
of the order of OPSYS_DOS and OPSYS_OS2 needs to be swapped.

Yes, that's a cigar! This syntax is hardly used ever. Masm v6 knows "OS_DOS" only, since MS removed everything related to OS/2 from their tools in the early 1990s ( not even the -Zm switch to enable Masm v5 compatibility will change that ).

QuoteGreat, then I found a bug in JWASM, which can be fixed, and JWASM will have one less bug in future versions.
Unfortunately, I don't have a GitHub account and therefore can't create a bug report. If you could report the bug to the developers, that would be great.

Yes, will do that ASAP.
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

bugthis

Quote from: _japheth on March 30, 2025, 06:13:32 PMYes, that's a cigar! This syntax is hardly used ever. Masm v6 knows "OS_DOS" only, since MS removed everything related to OS/2 from their tools in the early 1990s ( not even the -Zm switch to enable Masm v5 compatibility will change that ).
That's good to know.
Quote
QuoteGreat, then I found a bug in JWASM, which can be fixed, and JWASM will have one less bug in future versions.
Unfortunately, I don't have a GitHub account and therefore can't create a bug report. If you could report the bug to the developers, that would be great.

Yes, will do that ASAP.

Thank you very much. I just compiled and tested it and it works perfectly with my above hellowld.asm file. However, there were some issues with compiling, see below.

In your commit log you wrote the following:
https://github.com/Baron-von-Riedesel/JWasm/commit/59e0bd32218609f145db17bcfd2eb7c9101f0637
Quote-  .model directive: os qualifier (OS_DOS,OS_OS2) never worked; see
      startup5.asm.
I couldn't find a file called startup5.asm in the code tree:
https://github.com/Baron-von-Riedesel/JWasm/tree/master

And then I noticed something else while unpacking on a FAT16 file system. The file
Samples/Win32DrvA.asm is too long for the 8.3 file system, so you're asked if you want to overwrite the previously unpacked file
Samples/Win32Drv.asm.
Since this is a file for Windows, hopefully not for Windows 3.x with the 32-bit Win32s extension installed, I'm assuming this is irrelevant for DOS if you overwrite the file and then don't need it in DOS anyway. But I'll mention it for the sake of completeness.
If this could also be important under Windows 3.x, I would suggest renaming the file to a short 8.3 filename.
Renaming
Samples/Win32DrvA.asm to
W32DrvA.asm did work for me.

I haven't compiled Win32DrvA, though. If that were necessary, the Makefiles and some other files in Samples would still need to be adapted, as the following output shows.
grep Win32DrvA.asm *
MAKE.BAT:if exist "\WinInc" JWasm -nologo -coff Win32DrvA.asm
Readme.txt:  Win32DrvA.asm Win32   coff   console  loads Win32Drv.sys
Win32DrvA.asm:;---  assemble: jwasm -coff Win32DrvA.asm
Win32Drv.asm:;--- to run the driver, assemble, link and run the Win32DrvA.asm service control program.
Win32Drv.asm:;--- define control code. this code must match the one in Win32DrvA.asm.

Now to the problems with compiling:

The Makefile OWDOS16.MAK for OpenWatcom had to be modified.
The Makefile states:
!else
OUTD=build\OWDOS16R
!endif
...
$(OUTD):
        @if not exist $(OUTD) mkdir $(OUTD)
...
When I ran
wmake -f OWDOS16.mak, the
BUILD\OWDOS16R directory couldn't be created, and make freezes. I had to reboot the computer.
MKDIR isn't able to create two-level directories in one step.
However, manually creating the build directory before running wmake worked.
mkdir build
The subdirectory OWDOS16R was then created automatically without errors using the Make script.
To fix the error, I would suggest changing the Makefile to first check if a build directory exists and then create it before continuing with the subdirectory.
Neither MKDIR from MS-DOS 6.22, nor DR-DOS 7.03 or FreeDOS 1.3 can create multilevel directories with subdirectories in one step.

But then I got another error message when running wmake -f OWDOS16.mak.
Error(E14): Cannot execute (\Watcom\binnt\wcc): Argument list too big
Error(E42): Last command making (build/owdos16r\apiemu.obj) returned a bad status
Error(E02): Make execution terminated
The build\owdos16r directory was still empty after that.

I don't know if this is helpful, but my environment variables look like this. The command "set" outputs this:
DOSDRV=C:
LANG=DE
TZ=UTC
PATH=C:\DEVEL\WATCOMC\BINW;C:\DEVEL\JWASM;C:\WORK\BIN;C:\FreeDOS\BIN;C:\FREEDOS\LINKS
WORKDIR=C:\WORK\BIN;
JWASMDIR=C:\DEVEL\JWASM;
NLSPATH=C:\FreeDOS\NLS
HELPPATH=C:\FreeDOS\HELP
TEMP=C:\FreeDOS\TEMP
TMP=C:\FreeDOS\TEMP
BLASTER=A220 I5 D1 H5 P330
DIRCMD=/OGN /Y
COPYCMD=/-Y
OS_NAME=FreeDOS
OS_VERSION=1.3
AUTOFILE=C:\FDAUTO.BAT
CFGFILE=C:\FDCONFIG.SYS
CDROMID=FDCDX001
CDROM=D:
INCLUDE=C:\DEVEL\WATCOMC\H
EDPATH=C:\DEVEL\WATCOMC\EDDAT
WATCOM=C:\DEVEL\WATCOMC

Since I wasn't able to build the 16-bit JWASM binary with OpenWatcom, I decided to use the GccDOS.mak makefile with DJGPP to build a 32-bit PM and DPMI enabled binary with GCC.
That worked, but the build directory had to be created manually too because MKDIR wasn't able to create a directory with subdirectories in one step.
Here the GccDOS.mak Makefile should also be adjusted to check if the build directory exists and if not, it should be created before subdirectories are created.

For setting the environment variables of OpenWatcom and GCC I have two separate batch files, which is why my environment variables for GCC change to the following values without the Watcom entries:
...  ; Entries as above without the Watcom stuff
PATH=C:\DEVEL\DJGPP\BIN;C:\DEVEL\JWASM;C:\WORK\BIN;C:\FreeDOS\BIN;C:\FREEDOS\LINKS
...  ; Entries as above without the Watcom stuff
DJGPP=C:\DEVEL\DJGPP\DJGPP.ENV

I would also recommend adding at the top of the Watcom Makefile OWDOS16.mak the following line, so that the users can read how to use it with OpenWatcom:
# 'wmake -f OWDOS16.mak'
The same applies to OWDOS32.mak. OWDOS32.mak does btw. have the same problem according creating the build directory and its subdirectory. mkdir just can't create multilevel directories in one go. Other Makefiles suitable for DOS may also be affected.

The Makefile GccDOS.mak for DJGCC contains such a tip, so you don't have to search for long:
# This makefile creates the JWasm 32-bit DOS binary with DJGPP.
#  'make -f GccDos.mak'


bugthis

To fix some of the above errors in the OWDOS16.mak and possibly also OWDOS32.mak Makefile, the following corrections must be made:
1. Using an editor with Search & Replace function, all strings named "BINNT" must be replaced with "BINW". The reason is that the Open Watcom compiler and linker are located in the BINW directory in DOS, not in the BINNT directory. This applies in particular to the OpenWatcom package from FreeDOS.

2. Next, at the very beginning of the Makefile, the entry
!ifndef WATCOM
must be replaced with
!ifndef %WATCOMOtherwise, the Makefile cannot access the DOS environment variable WATCOM. It's important that there is no % sign at the end of the entry; this would be different in a normal DOS batch file.

3. The same steps will likely need to be performed for the
!ifndef DEBUG entry directly below, replacing it with
!ifndef %DEBUG if you want to reference a DOS environment variable named DEBUG here.
The same applies to the !ifndef TRMEM entry.

If you do that, the E14 error will at least point to the correct directory where WCC.EXE, WLINK.EXE and WLIB.EXE is located.
Error(E14): Cannot execute (\binw\wcc): Argument list too big
Unfortunately, the argument list is still too long. I don't know how to fix this error. I'm not familiar enough with Watcom Makefiles and it could also be related to DOS and its maximum line length.


_japheth

Quote from: bugthis on March 31, 2025, 12:14:24 PMTo fix some of the above errors in the OWDOS16.mak and possibly also OWDOS32.mak Makefile, the following corrections must be made:

No, those makefiles all run fine in DOS, but need the HX DOS extender ( and the extender's HXLDR32 TSR loaded ). Additionally, I guess the DOSLFN TSR must be loaded to activate LFN support.

Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

bugthis

Quote from: _japheth on March 31, 2025, 01:31:48 PMNo, those makefiles all run fine in DOS, but need the HX DOS extender ( and the extender's HXLDR32 TSR loaded ). Additionally, I guess the DOSLFN TSR must be loaded to activate LFN support.
Couldn't you adapt the Makefile so that it can also be compiled on an 8086 or 286 on a FAT16 file system without LFN support? LFN support is also only available starting with MS-DOS 7.0, which is included with Windows 95b.
It would be a pity if you couldn't "bootstrap" the 16-bit Real Mode JWASM binary on a 16-bit x86 machine.

six_L

Hi,zedd151
QuoteThis is the 21st century. DOS is still stuck in 1980ish, imo. I just don't get it... at all.
Nowadays, most industrial automation control systems still use 16bit CPU.
Say you, Say me, Say the codes together for ever.

zedd151

Quote from: six_L on March 31, 2025, 02:22:38 PMHi,zedd151
QuoteThis is the 21st century. DOS is still stuck in 1980ish, imo. I just don't get it... at all.
Nowadays, most industrial automation control systems still use 16bit CPU.
I did not (obviously) know that. Thank you six_L.  :smiley:
I wouldn't think though, that they are conceivably running MS-DOS or a derivative. More likely a different proprietary OS, designed specifically for the task.
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

_japheth

Quote from: zedd151 on March 31, 2025, 02:13:30 PMI still don't understand though.

I like DOS. Not for nostalgic reasons, but since it allows hardware and PL0 access. So I can easily experiment with CPU "alignment checks" or MSR registers or mode switches between 16-bit and 64-bit, all things that are strictly forbidden for you "Windoze guys"  :biggrin: .
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

_japheth

Quote from: bugthis on March 31, 2025, 02:06:28 PMCouldn't you adapt the Makefile so that it can also be compiled on an 8086 or 286 on a FAT16 file system without LFN support? LFN support is also only available starting with MS-DOS 7.0, which is included with Windows 95b.

Yes, OWDOS16.MAK may be changed so it runs on a 8086. I'm prettty sure it will run without LFN even now.
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

sinsi

A mechanic I know still uses a 386 with MS-DOS 5 because his emissions program is from 1993 and he's not willing to spend $5000 per year for the latest version (which is no different in capabilities). Mind you, he is 88 years old and a bit set in his ways :biggrin: He is the guy that young revheads go to when their cars get defected and need a police inspection to be re-registered. The cops have given up giving him a hard time, as he has never failed an inspection.

Like _japheth said, there's something satisfying about booting from your floppy image and seeing "Hello 64-bit world" on the monitor :cool:


NoCforMe

I was going to write, contrary to what Zedd did, how gratifying it is to see such loving care tendered towards such "obsolete" software, which is obviously still much used, despite what all the future-fanbois tell us.
Assembly language programming should be fun. That's why I do it.