News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

File manipulation in good 'ole 16-bit DOS 6.22

Started by jejump, January 21, 2022, 01:27:08 PM

Previous topic - Next topic

_japheth

Quote from: jj2007 on January 22, 2022, 01:43:29 AM
And the demo works fine, which it wouldn't if no extra stack was allocated. So apparently .stack 65536 does indeed allocate a 64k stack.

I checked this. It depends on the link step - not all tools work correctly.

This is my test case:

.model small
.stack 65536

.code
start:
mov ax,4c00h
int 21h
end start


First, this is a valid DOS program, and it's also absolutely correct if DOS initializes SP to 0000.

Background: in the small model, all logical data segments ( _DATA, _BSS, CONST and STACK ) are put into one physical segment named DGROUP, and this segment's size must not exceed 64 KB.
DGROUP will be located behind the code segments when loaded into memory.

So if DOS loads the program's code at, say, address 0500:0000, DGROUP starts at 0501:0000 ( since code size is just 5 bytes here ), and SS:SP is initialized to 0501:0000.
In the executable's header, the minimum memory size requirement should be 1001h paragraphs, so DOS wilt refuse to load it if there's not enough free mem available.

However, MS OMF link sets the minumum memory size to 0001 paragraphs:

                     Display of File SMALL.EXE

DOS File Size                                        205h  (   517. )
Load Image Size                                        5h  (     5. )
Relocation Table entry count                          0000h  (     0. )
Relocation Table address                              001Eh  (    30. )
Size of header record      (in paragraphs)            0020h  (    32. )
Minimum Memory Requirement (in paragraphs)            0001h  (     1. )
Maximum Memory Requirement (in paragraphs)            FFFFh  ( 65535. )
File load checksum                                    0000h  (     0. )
Overlay Number                                        0000h  (     0. )

Initial Stack Segment  (SS:SP)   0001:0000
Program Entry Point    (CS:IP)   0000:0000


That's a bug, but it often has no consequences, since DOS allocates all available memory to a program when it is launched.

jwasm with option -mz does this job better, minimum memory requirement is indeed correctly set to 1001h paragraphs. But is also has quirks, it warns about DGROUP being larger than 64k ( which is simply wrong ).
tlink, as well as  jwlink, also have problems with this test case.



Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

jj2007

QuoteSince you don't have a 16-bit debugger, I've remedied that. I have attached the archive debug.zip to this post.

Thanks

Quote from: Gunther on January 22, 2022, 02:52:21 AMYour application simply crashes in DOSBox 0.74-3

See below, here it works.

nidud

#17
deleted

Gunther

Quote from: jj2007 on January 22, 2022, 05:03:41 AM
See below, here it works.

Yes, I have to apologize. It works. The cause of the crash was a version of DOSBox in which I had changed the variable cputype.

However, this does not change the fact that your program cannot be re-assembled in this way. You should write as simple a test bed as possible. This should be able to be assembled and linked with the usual tools
and demonstrate your idea. Andreas has shown how to do this. I can reproduce his results on my machine. Either your idea works or it doesn't.
You have to know the facts before you can distort them.

TimoVJL

Quote from: nidud on January 22, 2022, 05:45:10 AM
Quote from: TimoVJL on January 22, 2022, 03:01:55 AM
msdos.exe + cv.exe might work for debugging :thumbsup:
td.exe had problems.

msdos -x td.exe works fine on my end for Turbo Debugger Version 2.3
msdos -x cv.exe hangs.
msdos -x cv.exe hang with -x, not without it.
td version 4.0 and 5.0 won't load example exe even with -x
May the source be with you

Gunther

nidud,

Quote from: nidud on January 22, 2022, 05:45:10 AM
msdos -x td.exe works fine on my end for Turbo Debugger Version 2.3
msdos -x cv.exe hangs.

that may be so. But TurboDebugger was always a part of commercial Borland products (Borlan C, TurboPascal, TASM). For a simple test program in real mode DEBUG should be sufficient.
You have to know the facts before you can distort them.

jejump


After reading through FCOPY.asm, one of my big takeaways from it is that INT 21H, service AH=48h is my friend.  This attempts to allocate memory referenced in paragraphs by BX.  I didn't know about this call.  However, I tried it on Win7 and WinXP Command Prompts within DEBUG, and it returns that only 7 paragraphs are available on both machines.  I used the "Impossible Value" of 0FFFFh and got a return in CX of 7 and AX of 8.  Any idea why this behaves that way in Windows?  Would it be larger if I weren't in the DEBUG environment, you suppose?

-John

jj2007

Quote from: Gunther on January 22, 2022, 06:57:16 AMthis does not change the fact that your program cannot be re-assembled in this way.

Sorry, what do you mean? It does not assemble? The DosBasic.inc does not contain any libs or includes, so the source should build fine. At least, it does with UAsm64 and link16. What's the problem?

Gunther

John,

Quote from: jejump on January 22, 2022, 07:42:16 AM
After reading through FCOPY.asm, one of my big takeaways from it is that INT 21H, service AH=48h is my friend.  This attempts to allocate memory referenced in paragraphs by BX.  I didn't know about this call.  However, I tried it on Win7 and WinXP Command Prompts within DEBUG, and it returns that only 7 paragraphs are available on both machines.

this may have to do with the fact that many DOS programs occupy all available memory. Therefore, it is a good idea to reduce the application's memory beforehand.
Here is a simple example of how to do it:

; ResMem
; Purpose:   Resize the program's memory block for later allocation.
; Input:     None
; Output:    cf = 0 ===> success, memory block resized
;            cf = 1 ===> failure
; Uses:      DOS Dispatcher 21h, FUNCTION 4ah
; To Call:   call ResMem
ResMem proc near
    mov      ax, sp             ; ss:sp -> end of program
    shr      ax, 4
    mov      bx, ss
    add      bx, ax
    inc      bx                 ; bx = first paragraph beyond program
    mov      ax, es             ; es:0000 -> first program paragraph
    sub      bx, ax             ; bx = program size in paragraphs
    mov      ah, 4ah            ; FUNCTION: resize memory block
    int      21h                ; transfer to DOS
    retn
ResMem endp


The code snippet is part of this application. It'll assemble with JWASM for DOS but also with MASM, which is described here.
For more details have a look into the source, please.
You have to know the facts before you can distort them.

jejump

I don't think there's a problem, necessarily...  I just think there's a behavior within the two Windows systems that's causing only 7 paragraphs available when I run this code in DEBUG.  Maybe because I'm trying to run this 16-bit code in protected mode:

mov AX, 4800h
mov BX, FFFFh
int   21h

Then command in DEBUG:

G108 to run just those three code lines.  This results in CX being 0007 and AX having a value of 0008.  As I understand it, AX having 8 is saying the requested allocation amount is not available (also CY will be set) and CX is showing what actually IS available.  Maybe I'm missing something, but isn't 7 paragraphs available the same as saying there's 70h bytes available for allocation?  I would like for that value to be 1000h minimum, right?

Jj

Gunther

Quote from: jj2007 on January 22, 2022, 08:12:04 AM
Sorry, what do you mean? It does not assemble? The DosBasic.inc does not contain any libs or includes, so the source should build fine. At least, it does with UAsm64 and link16. What's the problem?

The problems with your applications are described in this post.
There I have documented all error messages and warnings during assembling and linking. What else should I do?
You have to know the facts before you can distort them.

Gunther

John,

Quote from: jejump on January 22, 2022, 08:22:22 AM
I don't think there's a problem, necessarily...  I just think there's a behavior within the two Windows systems that's causing only 7 paragraphs available when I run this code in DEBUG. 

that may be so. It's of course possible that the debugger occupies all available RAM.

Quote from: jejump on January 22, 2022, 08:22:22 AM
Maybe because I'm trying to run this 16-bit code in protected mode:

This is not so simple. You should have a look at PMSHELL.ASM from here.
You have to know the facts before you can distort them.

jj2007

Quote from: Gunther on January 22, 2022, 08:25:57 AMWhat else should I do?

Use tools that work? UAsm and link16? Btw ML 6.15, latest AsmC and JWasm 2.13 also work fine here.

Gunther

Quote from: jj2007 on January 22, 2022, 08:37:58 AM
Use tools that work?

It is very likely that the tools will work on your computer. Unfortunately I can't come by your place when I want to create the EXE. But it doesn't work here. There are reasons why I did not install UASM.
But of course I have the other tools you mentioned:
Quote from: jj2007 on January 22, 2022, 08:37:58 AM
Btw ML 6.15, latest AsmC and JWasm 2.13 also work fine here.

Good for you. I have assembled your original source from this post under FreeDOS with JWASM 2.13. Here is the result:

stack1~1.asm(1) : Error A2106: Cannot open file: "\masm32\MasmBasic\DosBasic.inc" [ENOENT]
stack1~1.asm(2) : Error A2209: Syntax error: Init
stack1~1.asm(3) : Error A2209: Syntax error: Print
stack1~1.asm(4) : Error A2209: Syntax error: Print
stack1~1.asm(6) : Error A2082: Must be in segment block
stack1~1.asm(7) : Error A2082: Must be in segment block
stack1~1.asm(8) : Error A2082: Must be in segment block
stack1~1.asm(9) : Error A2082: Must be in segment block
stack1~1.asm(10) : Error A2082: Must be in segment block
stack1~1.asm(11) : Error A2082: Must be in segment block
stack1~1.asm(12) : Error A2082: Must be in segment block
stack1~1.asm(13) : Error A2082: Must be in segment block
stack1~1.asm(14) : Error A2082: Must be in segment block
stack1~1.asm(14) : Error A2082: Must be in segment block
stack1~1.asm(15) : Error A2082: Must be in segment block
stack1~1.asm(16) : Error A2082: Must be in segment block
stack1~1.asm(17) : Error A2082: Must be in segment block
stack1~1.asm(18) : Error A2082: Must be in segment block
stack1~1.asm(19) : Error A2082: Must be in segment block
stack1~1.asm(20) : Error A2082: Must be in segment block
stack1~1.asm(21) : Error A2082: Must be in segment block
stack1~1.asm(22) : Error A2082: Must be in segment block
stack1~1.asm(23) : Error A2082: Must be in segment block
stack1~1.asm(24) : Error A2082: Must be in segment block
stack1~1.asm(25) : Error A2082: Must be in segment block
stack1~1.asm(26) : Error A2082: Must be in segment block
stack1~1.asm(27) : Error A2082: Must be in segment block
stack1~1.asm(28) : Error A2209: Syntax error: Print
stack1~1.asm(29) : Error A2082: Must be in segment block
stack1~1.asm(30) : Error A2082: Must be in segment block
stack1~1.asm(31) : Error A2082: Must be in segment block
stack1~1.asm(32) : Error A2082: Must be in segment block
stack1~1.asm(33) : Error A2082: Must be in segment block
stack1~1.asm(34) : Error A2209: Syntax error: Print
stack1~1.asm(35) : Error A2209: Syntax error: Print
stack1~1.asm(36) : Error A2209: Syntax error: Print
stack1~1.asm(37) : Error A2209: Syntax error: Print
stack1~1.asm(38) : Error A2082: Must be in segment block
stack1~1.asm(39) : Error A2209: Syntax error: Open
stack1~1.asm(40) : Error A2209: Syntax error: Print
stack1~1.asm(41) : Error A2209: Syntax error: Close
stack1~1.asm(42) : Error A2209: Syntax error: Print
stack1~1.asm(43) : Error A2209: Syntax error: Make$
stack1~1.asm(44) : Error A2209: Syntax error: FileRead
stack1~1.asm(45) : Error A2082: Must be in segment block
stack1~1.asm(46) : Error A2209: Syntax error: Print
stack1~1.asm(47) : Error A2082: Must be in segment block
stack1~1.asm(47) : Error A2082: Must be in segment block
stack1~1.asm(48) : Error A2209: Syntax error: Print
stack1~1.asm(49) : Error A2209: Syntax error: Print
stack1~1.asm(50) : Error A2082: Must be in segment block
stack1~1.asm(50) : Fatal error A1113: Too many errors


If you look into your code, you will see that your program simply crashes on an 80286. It's not tested on which CPU the application runs. The program also crashes on my old 80386,
which I've used as a printer spooler for many years. The machine simply hasn't a FPU. Should I list more?

And you have the chutzpah to tell me this:
Quote from: jj2007 on January 22, 2022, 08:37:58 AM
Use tools that work?
Like a thief yelling to catch the thief.
You have to know the facts before you can distort them.

jj2007

Quote from: Gunther on January 22, 2022, 10:33:09 AM
Quote from: jj2007 on January 22, 2022, 08:37:58 AM
Use tools that work?
Like a thief yelling to catch the thief.

Can you occasionally make a post without insulting those who don't agree with you?

I just tested my original code (attached) with a virgin Masm32 SDK. No MasmBasic folder, no advanced assembler, just ML 6.14 and link16.exe. It assembles and links ok, and runs just fine in DOSBox-0.74-3 provided you give it an 8.3 name. You have problems.

Second attachment is a demo showing that you can use a 60kB buffer on the stack.