The MASM Forum

Miscellaneous => 16 bit DOS Programming => Topic started by: jejump on January 21, 2022, 01:27:08 PM

Title: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jejump on January 21, 2022, 01:27:08 PM

Hello all!

I am working on a new 16-bit masm project that, in short, opens a user selected binary file (varying input file sizes), makes slight modifications to it, and saves it as a similarly named output file, but with a different file extension.  I'm reading the input file using DOS int 21h, service AH=3Fh.  I'd like to tell DOS to open up (or reserve) RAM enough to accommodate a maximum size file 65536 bytes in size.  If I do this in the data segment of my code like this:

dseg            segment 'DATA'


Input_File                      db              "88888888.333",0
Bin_File_Handle             dw              0000h
Bin_File_Size                 dw              0000h
Bin_File_Data                db              0FFFFh    DUP(?)

   dseg    ends


This causes overflow warnings in the assembly PLUS makes the .exe file unnecessarily huge.  If I sacrifice about 4096 bytes and make the Bin_File_Data array E000h, I don't get the overflow problems anymore, but the .exe file is still really big.  I know this is NOT the right way to do this, but I'm not sure what the right way is.  Any time I've ever needed to work with files on the machine language level in the past, they've been relatively small files (under 2KB) and I could use a single 16KB segment to handle code, data, stack with room to spare, in most cases.  This is new territory for me and I haven't found any good examples searching the internet.

Hopefully, I've made that all understandable.  Thanks for the help!  :thumbsup:

John


Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 21, 2022, 01:38:24 PM
Hi John,
I haven't done 16-bit stuff for a while, but can't you create a buffer on the stack? Something like

sub sp, 0FFFFh
mov di, sp   ; your buffer
...
add sp, 0FFFFh
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jejump on January 21, 2022, 02:26:58 PM

Oh, that's an interesting approach...  I'll look into that a little closer.  I was thinking there was someway to have DOS "assign" a section of memory, but maybe that's not how it works.  Thanks for the suggestion!
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 21, 2022, 04:01:55 PM
John,

I've attached the archive fcopy.zip to this post. There it is shown how to proceed with files under DOS. The archive contains the following files:
I used JWASM for DOS, but other assemblers like MASM or TASM should also work. However, the BATCH file must then be modified. MYFILE.TXT is hard coded in the source, but can be easily adapted and does not change the principle.

The FCOPY routine has some interesting aspects:
If you have any questions, don't hesitate to ask. Best regards to Nashville, TN.

Quote from: jj2007 on January 21, 2022, 01:38:24 PM
I haven't done 16-bit stuff for a while, but can't you create a buffer on the stack? Something like

sub sp, 0FFFFh
mov di, sp   ; your buffer
...
add sp, 0FFFFh
Do you really think this is a good idea? DOS programs usually have 1 or 2 KB stack. This is more than sufficient in most cases.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 21, 2022, 08:52:10 PM
Quote from: Gunther on January 21, 2022, 04:01:55 PM
Quote from: jj2007 on January 21, 2022, 01:38:24 PM
I haven't done 16-bit stuff for a while, but can't you create a buffer on the stack? Something like

sub sp, 0FFFFh
mov di, sp   ; your buffer
...
add sp, 0FFFFh
Do you really think this is a good idea? DOS programs usually have 1 or 2 KB stack. This is more than sufficient in most cases.

.nolist
.Model small
.stack 65536
.386
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: _japheth on January 21, 2022, 10:30:44 PM
Quote from: jj2007 on January 21, 2022, 08:52:10 PM
Quote from: Gunther on January 21, 2022, 04:01:55 PM
Quote from: jj2007 on January 21, 2022, 01:38:24 PM
I haven't done 16-bit stuff for a while, but can't you create a buffer on the stack? Something like

sub sp, 0FFFFh
mov di, sp   ; your buffer
...
add sp, 0FFFFh
Do you really think this is a good idea? DOS programs usually have 1 or 2 KB stack. This is more than sufficient in most cases.

.nolist
.Model small
.stack 65536
.386


IIRC ( :biggrin:) register SP is 16 bit, so ".stack 65536" might actually be a synonyme for ".stack 0"; but I hope the assembler will detect this condition and emit a warning?
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jejump on January 21, 2022, 10:44:19 PM

Thanks, Gunther, and everyone else helping.  I'm going to download FCOPY right now and scan through it and see what it reveals.

Jj
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 21, 2022, 10:47:52 PM
Quote from: _japheth on January 21, 2022, 10:30:44 PMIIRC ( :biggrin:) register SP is 16 bit, so ".stack 65536" might actually be a synonyme for ".stack 0"; but I hope the assembler will detect this condition and emit a warning?

You are perfectly right, but 1. no warning and 2. this works without problems, so I assume the assembler (UAsm64) handles the problem somehow:
  sub sp, 60000
  mov di, sp
  mov al, "x"
  mov cx, 60000
  rep stosb
  add sp, 60000


I don't have a 16-bit debugger on this machine, unfortunately. I am curious, too, why this works:
  tolerance=500 ; 500 is ok, 400 is not
  sub sp, 65536-tolerance
  mov di, sp
  mov cx, (65536-tolerance)/68
  .Repeat
mov si, Chr$("This 67-byte string was copied to the buffer created on the stack", 13, 10)
.Repeat
lodsb
stosb
.Until !al
dec di
dec cx
  .Until Sign?
  mov al, "$"
  stosb
  mov dx, sp
  mov ah, 9 ; the traditional DOS way,
  int 21h ; ending with the $ delimiter
  add sp, 65536-tolerance
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: _japheth on January 22, 2022, 01:19:11 AM
Quote from: jj2007 on January 21, 2022, 10:47:52 PM
You are perfectly right, but 1. no warning and 2. this works without problems, so I assume the assembler (UAsm64) handles the problem somehow:

I guess the assembler doesn't care. Neither does the MS 16-bit linker - but old Borland's tlink emits an error "invalid stack offset".
It "works" nevertheless, because the DOS memory "management" is somewhat "forgiving" - on most cases it allows a program to run with an initial value of 0000 for SP.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 22, 2022, 01:43:29 AM
UAsm chokes if I put 1 byte more, i.e. 65537, so the assembler is aware of the problem. 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.

Btw I use the MS-DOS Player for Win32-x64 (http://takeda-toshiya.my.coocan.jp/msdos/index.html) for running my 16-bit executables (msdos\binary\i486_x64\msdos.exe); no idea whether "real" DOS makes any difference :cool:
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: FORTRANS on January 22, 2022, 02:09:23 AM
Hi,

   How do you have the segment registers set up?  LODS defaults
to using DS.  (It can be overridden with a segment prefix.}  STOS
must use ES.

Regards,

Steve N.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 22, 2022, 02:43:55 AM
Hi Steve,
See the Init macro in DosBasic.inc:
  push @DATA ; set the DS register to DGROUP
  pop ds ; for ds:si (lods)
  push ds
  pop es ; for es:di (scas, stos)
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 02:52:21 AM
Quote from: jj2007 on January 22, 2022, 01:43:29 AM
Btw I use the MS-DOS Player for Win32-x64 (http://takeda-toshiya.my.coocan.jp/msdos/index.html) for running my 16-bit executables (msdos\binary\i486_x64\msdos.exe); no idea whether "real" DOS makes any difference :cool:

Your application simply crashes in DOSBox 0.74-3. And by the way: The naming convention for DOS is 8.3. Moreover, UASM is not exactly the classic DOS assembler.

But apart from that. The EXE cannot be re-assembled in the form you have attached it. DosBasic.inc is included via the masm32 path. After correcting that, JWASM says:

DosBasic.inc(2) : Warning A4095: Multiple .MODEL directives, .MODEL ignored
DosBasic.inc(2): Included by
  stack16.asm(1): Main line code

TLINK brings the following errors:

Turbo Link  Version 7.00 Copyright (c) 1987, 1994 Borland International
Error: Group DGROUP exceeds 64K
Error: Invalid initial stack offset

The MAP file looks like this:

Error: Group DGROUP exceeds 64K
Error: Invalid initial stack offset

Start  Stop   Length Name               Class

00000H 00000H 00000H STACK16_TEXT       CODE
00000H 0025FH 00260H _TEXT              CODE
00260H 00413H 001B4H _DATA              DATA
00414H 0EF7BH 0EB68H _BSS               BSS
0EF7CH 0EF7CH 00000H CONST              CONST
0EF80H 1EF7FH 10000H STACK              STACK

Since you don't have a 16-bit debugger, I've remedied that. I have attached the archive debug.zip to this post. It contains the very good debugger debug.com maintained by Japheth and a
quick and dirty tutorial for it by Michael Webster.

Finally, as a reminder: Your original proposal was
Quote from: jj2007 on January 21, 2022, 01:38:24 PM
sub sp, 0FFFFh
mov di, sp   ; your buffer
...
add sp, 0FFFFh
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: TimoVJL on January 22, 2022, 03:01:55 AM
msdos.exe + cv.exe might work for debugging :thumbsup:
td.exe had problems.

Under vDOSPlus td.exe works.

http://www.vdosplus.org/
https://sourceforge.net/projects/vdosplus/


Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 03:08:51 AM
Quote from: TimoVJL on January 22, 2022, 03:01:55 AM
td.exe had problems.

I believe that immediately!
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: _japheth on January 22, 2022, 03:42:55 AM
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.



Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 22, 2022, 05:03:41 AM
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.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: nidud on January 22, 2022, 05:45:10 AM
deleted
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 06:57:16 AM
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.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: TimoVJL on January 22, 2022, 06:58:36 AM
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
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 07:03:10 AM
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.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: 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.  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
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 22, 2022, 08:12:04 AM
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?
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 08:18:05 AM
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 (http://masm32.com/board/index.php?topic=9771.msg107102#msg107102). It'll assemble with JWASM for DOS but also with MASM, which is described here (http://masm32.com/board/index.php?topic=9771.msg107142#msg107142).
For more details have a look into the source, please.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: 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.  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
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 08:25:57 AM
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 (http://masm32.com/board/index.php?topic=9778.msg107221#msg107221).
There I have documented all error messages and warnings during assembling and linking. What else should I do?
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 08:34:28 AM
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 (http://masm32.com/board/index.php?topic=9771.msg107102#msg107102).
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 22, 2022, 08:37:58 AM
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.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 10:33:09 AM
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 (http://masm32.com/board/index.php?topic=9778.msg107210#msg107210) 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.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 22, 2022, 12:00:52 PM
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.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 22, 2022, 04:38:56 PM
Quote from: jj2007 on January 22, 2022, 12:00:52 PM
Can you occasionally make a post without insulting those who don't agree with you?

Uhh, touched a nerve?

But please, allow me the following question: Was it your buggy code or mine that caused the assembly problems (http://masm32.com/board/index.php?topic=9778.msg107247#msg107247)?
This just shows you're quarrelsome, opinionated, and incapable of self-criticism. That's not a personal attack, but a fact.

Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jj2007 on January 22, 2022, 11:25:42 PM
Quote from: Gunther on January 22, 2022, 04:38:56 PMWas it your buggy code or mine that caused the assembly problems (http://masm32.com/board/index.php?topic=9778.msg107247#msg107247)?
This just shows you're quarrelsome, opinionated, and incapable of self-criticism. That's not a personal attack, but a fact.

An absolute n00b would have understood immediately that the file wasn't where the source expected it. Strange that an experienced programmer like you isn't able to either change the include line, or copy the *.inc to the folder where the assembler expects it :cool:

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
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: Gunther on January 23, 2022, 01:10:58 AM
Quote from: jj2007 on January 22, 2022, 11:25:42 PM
An absolute n00b would have understood immediately that the file wasn't where the source expected it. Strange that an experienced programmer like you isn't able to either change the include line, or copy the *.inc to the folder where the assembler expects it :cool:

Tell it to the marines! Only you are responsible for your sloppy sources. 
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jejump on January 26, 2022, 02:22:16 AM

So, the code below produces an .exe file that produces this image:

https://drive.google.com/file/d/1Owctyj0LxRtwGguA9WeZkVaMNZ-rX-nU/view

on my Windows 7 computer by double-clicking the executable.  I wanted to see if in fact, DEBUG.exe was "hogging" most of the available memory.  Turns out, the real hog (I suppose) is Windows.  I get the same results in the working registers with or without working inside of DEBUG.  Segment registers will obviously differ.  I then opened FCOPY.exe inside of DEBUG and saw the same thing.  That program creates MYFILE.BAK literally at 70h bytes per data transfer.  I guess these are the limits. 

The challenge for me is that I want to open a file of max size 65535 bytes.  I want to then scan that data for an opening byte sequence that might be about 10 bytes long (actually, it's user defined) and then identify a closing byte sequence as well.  How to code that seems obvious if I could have the entire file available to me all at once.  At 112 bytes of file at once, I know there will surely be times when my available memory will cut off right in the middle of that signature byte sequence, so I'm gonna have to get clever about how to identify it when I have only 112 bytes of playground (or sometimes, maybe less).  Anyway, thought I'd share my findings.

Jj




    .386

xfrsize equ 0fff0h              ; # bytes per I/O access
                                ; (always multiple of 16)

bufsize equ 80                  ; length local buffer on stack

DGROUP group _DATA, STAK        ; automatic data group

_TEXT  segment word public use16 'CODE'
       assume  cs:_TEXT, ds:DGROUP, ss:STAK

Start:

    mov      ax, DGROUP         ; make data segment addressable
    mov      ds, ax


push CS
pop DS
push SS
pop ES
mov AX, 4800h
mov BX, 0FFFFh ; Not possible mem segment reserve
int 21h
push DX
push CX
push AX
lea AX, CS:[Reg_AX_Val]
pop DX
call Convert_DX_To_Ascii
lea AX, CS:[Reg_BX_Val]
mov DX, BX
call Convert_DX_To_Ascii
lea AX, CS:[Reg_CX_Val]
pop DX
call Convert_DX_To_Ascii
lea AX, CS:[Reg_DX_Val]
pop DX
call Convert_DX_To_Ascii

mov DX, CS
lea AX, CS:[Reg_CS_Val]
call Convert_DX_To_Ascii
mov DX, DS
lea AX, CS:[Reg_DS_Val]
call Convert_DX_To_Ascii
mov DX, ES
lea AX, CS:[Reg_ES_Val]
call Convert_DX_To_Ascii
mov DX, SS
lea AX, CS:[Reg_SS_Val]
call Convert_DX_To_Ascii

call Write_Reg_Status
mov AH, 0
call Wait_Esc
mov AX, 4C00h
int 21h


Wait_Esc:
int 16h
cmp AH, 1
jne Wait_Esc
ret


Convert_DX_To_Ascii:
push AX ; AX = address to store ASCII representation of DX
pop BP
push BX
mov SI, 3
mov AX, DX ; DX = 16-bit value to convert to ASCII
and AX, 0Fh
or AX, 30h
mov BX, AX
sub AX, 3Ah ; ASCII "9"+1
mov AX, BX
jc Zero_To_Nine_3
add AX, 7 ; Add 7 if > 9 (A to F)
Zero_To_Nine_3:
mov AH, 0
mov BX, AX
mov BYTE PTR CS:[BP+SI], BL
mov AX, DX
mov CL, 4
shr AX, CL
dec SI
and AX, 0Fh
or AX, 30h
mov BX, AX
sub AX, 3Ah ; ASCII "9"+1
mov AX, BX
jc Zero_To_Nine_2
add AX, 7 ; Add 7 if > 9 (A to F)
Zero_To_Nine_2:
mov AH, 0
mov BX, AX
mov BYTE PTR CS:[BP+SI], BL
mov AX, DX
mov CL, 8
shr AX, CL
dec SI
and AX, 0Fh
or AX, 30h
mov BX, AX
sub AX, 3Ah ; ASCII "9"+1
mov AX, BX
jc Zero_To_Nine_1
add AX, 7 ; Add 7 if > 9 (A to F)
Zero_To_Nine_1:
mov AH, 0
mov BX, AX
mov BYTE PTR CS:[BP+SI], BL
mov AX, DX
mov CL, 12
shr AX, CL
dec SI
and AX, 0Fh
or AX, 30h
mov BX, AX
sub AX, 3Ah ; ASCII "9"+1
mov AX, BX
jc Zero_To_Nine_0
add AX, 7 ; Add 7 if > 9 (A to F)
Zero_To_Nine_0:
mov AH, 0
mov BX, AX
mov BYTE PTR CS:[BP+SI], BL
pop BX
ret


Write_Reg_Status:
lea DX, CS:[Intro]
mov AH, 9
mov AL, 0
int 21h
ret




Intro db      0Dh,0Ah, "Int 21h call",0Dh
db 0Ah,0Ah,"Input AH = 48h"
db 0Dh,0Ah,"      BX = FFFFh (Impossible Paragraph Memory Request)"
db 0Dh,0Ah,0Ah
db "After call:  ",0Dh,0Ah,0Ah

Reg_AX_Def db "    AX = "
Reg_AX_Val db 4 DUP ("?")
db 0Dh,0Ah
Reg_BX_Def db "    BX = "
Reg_BX_Val db 4 DUP ("?")
db 0Dh,0Ah
Reg_CX_Def db "    CX = "
Reg_CX_Val db 4 DUP ("?")
db 0Dh,0Ah
Reg_DX_Def db "    DX = "
Reg_DX_Val db 4 DUP ("?")
db 0Dh,0Ah
Reg_CS_Def db "    CS = "
Reg_CS_Val db 4 DUP ("?")
db 0Dh,0Ah
Reg_DS_Def db "    DS = "
Reg_DS_Val db 4 DUP ("?")
db 0Dh,0Ah
Reg_ES_Def db "    ES = "
Reg_ES_Val db 4 DUP ("?")
db 0Dh,0Ah
Reg_SS_Def db "    SS = "
Reg_SS_Val db 4 DUP ("?")
db 0Dh,0Ah
db 0Dh,0Ah
db "Press 'Esc' to Exit!"
db 0Dh,0Ah,"$"

_TEXT  ends

_DATA segment word public use16 'DATA'


_DATA ends

STAK segment para stack use16 'STAK'

    db 2048 dup (?)             ; 2 KB stack

STAK ends

     end Start




(https://drive.google.com/file/d/1Owctyj0LxRtwGguA9WeZkVaMNZ-rX-nU/view)
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: _japheth on January 26, 2022, 02:36:27 AM

Haven't actually tried your program, but a quick look at your code


    mov      ax, DGROUP         ; make data segment addressable
    mov      ds, ax
push CS
pop DS


shows that you carefully set up the DS register ( mov ds,ax), but then destroy its content just 2 instructions later (pop ds). That probably won't work as expected.
Title: Re: File manipulation in good 'ole 16-bit DOS 6.22
Post by: jejump on January 26, 2022, 02:40:38 AM

Oh.. Sorry, that's actually leftover junk.  I originally had this as a TINY code-segment-only model.  I was trying different approaches and wasn't really trying to setup DS as anything other than a copy of CS.