For my current assignment, I need to write a small app, which uses int21 0Ah function, for buffered input.
The Program should take the input, check if it is a valid filename (with optional path+wildcards) and if so display some information (access times etc. to that file).
Now in case you may not remember (which is of course highly unlikely...) I'm the guy 'stuck' with having to write 16bit dos apps, when my system is a 64bit linux type of beast. I was having 'compatibility' problems when using Dosbox seemingly due to a different implementation within dosbox for certain functions.
Since last posting here, I've since switched to using DosEmu, configured to load a 'real' MS-DOS 6.22 for me. Its slow, but up until now its gotten me through.
Now back to my current assignment. I of course had it working (sort of using Dosbox), but it no longer behaved well when using DosEmu (or Win32's cmd-box, which ironically is the 'target-system', as its that what they have installed in their labs at my uni).
So I started to sift through the mess, and finally ended up just rewriting it.
So the first task was to get input, using 0Ah (buffered input). And no matter what I do, it seemingly will not behave.
So my question is: I've searched for this wide and far, I need to see a *working example* of how to use buffered input.
How does my buffer need to be defined? How should I pass the 0Ah function it's offset? And should I be able to 'see' my input when using cv and 'watching' string?
Below is what I've been messing with.The actual functionality within 'find' is of course not present.
.MODEL small
.STACK 100h
.DATA
string DB 20,20 dup(0) ; c:\8.3\8.3\8.3\8.3\8.3
.CODE
find proc
mov ah,0Ah
;mov dx,offset string ; same as below!?
lea dx,string
int 21h
ret
find endp
MAIN:
mov dx,@data
mov ds,dx
call find
mov ah,4Ch
int 21h
END MAIN
The buffer's format is
db 20 ;in - maximum length
db ? ;out - actual length
db ? ;buffer start
Don't forget that DOS terminates the buffer with 0dh, not 00.
Hi,
Here is something I put together to answer a question or debug
function 0A calls. I don't use CV but it works nicely in DEBUG. You
can zero out the InBuff if that is clearer to you. I filled it with
numbers and so forth to see it in debug.
HTH,
Steve N.
PAGE ,132
TITLE Test DOS Input String
NAME TESTFN0A
COMMENT *
2 October 2008, example for MASM Forum question. (Oops, not for the forum...)
SRN as FORTRANS.
MASM TestFn0A;
LINK TestFn0A;
EXE2BIN TestFn0A.exe TestFn0A.com
*
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CODE SEGMENT
ORG 100H ; COM file opening
ASSUME CS:CODE,DS:CODE
Start PROC FAR
; Initialization
MOV AX,CS ; Save someone from foot shooting if they
MOV DS,AX ; don't EXE2BIN and run the EXE.
; Enter the text
MOV DX,OFFSET InBuff; Point to input buffer
MOV AH,0AH ; Input String Function Number
INT 21H
; Print a message
MOV DX,OFFSET Msg1 ; Point to message.
MOV AH,9 ; Output String Function Number
INT 21H
MOV DL,InBuff[1] ; And get the input's length.
ADD DL,48 ; Convert to ASCII
MOV AH,2 ; Console Output Character Function Number
INT 21H
XOR BH,BH
MOV BL,InBuff[1] ; Get the input's length.
MOV InBuff[BX+2],'<' ; Change the carriage return to printable char.
MOV DX,OFFSET Msg2
MOV AH,9
INT 21H
MOV DX,OFFSET InBuff[2] ; Point to start of input + debug
MOV AH,9 ; Output String Function Number
INT 21H
MOV AX,04C00H ; Exit
INT 21H
Start ENDP
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Msg1 DB 13,10,' The length of the input was $'
Msg2 DB ' characters,',13,10,' and the input text looks like: ', 13, 10, '$'
InBuff DB 9, 0, 13, '23456789$' ; Input buffer filled with debug stuff.
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CODE ENDS
END Start
Thanks for the replies.
I'm still not 'getting it' though.
I used parts of your example and got it to work, but my understanding is not really clear yet.
Neither has the example translated into working within my app, and I'm still quite certain its down to my incorrect understanding of declaring that input buffer variable.
InBuff DB 9, 0, 13, '23456789$' ; Input buffer filled with debug stuff.
Would mean:
Quote9 ;maximum length
0 ;out - actual length
13 ;buffer start
According to your posts. I just don't get that. The '9' is clear, and I assume the '0' gets filled during runtime, but what with the '13'. No matter what I set it to, the example will work. As far as I understand it, this is the third byte, from where on my input should get stored. So why 13 in the example, and why doesn't changing it matter(seemingly) ?
I realise I'm being a dork here, but I've just hit a brick wall which is starting to question my understanding of other things... :(
The questions in my above post are still valid, but I've now cornered where my actual problem lies.
As my InputBuffer will hold a filepath of an obviously unknown length, it is important not to have garbage in it, so it needs to be correctly initialized.
This is what I've currently got, and when outputting it, I get no 'unprintables', but its not clean this way either. I think.
string DB 50,0,50 dup(' '),'$'
What am I doing wrong.
To make myself more clear. The string would have the CR removed(replaced) and then it would get passed to int21's function 4Eh.
For the function to work, the 'string' would have to be clean, obviously.
The first byte of the buffer must specify the maximum number of characters, including the carriage return, to be copied to the buffer. This allows the function to avoid writing past the end of the buffer. The second byte receives the actual number of characters that the function copied to the buffer, not including the carriage return. The actual buffer starts at the third byte. The function will read characters, echo them to standard output, and copy them to the buffer until a carriage return is read. If the number of characters reaches one less than the maximum, the function will send a beep character to standard output and ignore any further characters, other than a carriage return. As zooba pointed out, the buffer will be terminated with a carriage return. As I see you already realized, if you structure your buffer like this:
buff db 20, 0, 21 dup('$')
Then you can use the Display String function (AH = 9) to display the contents of the buffer on return:
mov ah, 9
mov dx, OFFSET buff+2
int 21h
And to prevent it from displaying over the top of the echoed input, you can define a carriage return / line feed string like this:
crlf db 13, 10, '$'
And display it before you display the contents of the buffer.
I'm not sure what you mean by "clean". From the third byte to the carriage return the buffer will contain what the user entered, less any characters that were ignored. So you replace the carriage return with a zero byte and pass the address of the third byte of the buffer, and any remaining problems are bad input.
Hi,
Sorry for the confusion, the example posted was for
my use and experimentation.
QuoteAccording to your posts. I just don't get that. The '9' is clear, and I assume the '0' gets filled during runtime, but what with the '13'. No matter what I set it to, the example will work. As far as I understand it, this is the third byte, from where on my input should get stored. So why 13 in the example, and why doesn't changing it matter(seemingly) ?
The buffer is overwritten with the input, its initial contents
do not matter in that respect. The 13 is the carriage return
that would occur it there was no additional text entered, and
was for debugging the rest of the code. For a time I just had
the numbers 1 through 9, and that may have been clearer.
QuoteWhat am I doing wrong.
To make myself more clear. The string would have the CR removed(replaced) and then it would get passed to int21's function 4Eh.
For the function to work, the 'string' would have to be clean, obviously.
Yes, 4Eh is "Find First File" and requires an ASCIIZ string.
Use the actual length byte (the second byte in the input buffer)
to locate the carriage return, and replace it with a zero. See
in my example were I "Change the carriage return to printable
char." for something close.
HTH,
Steve N.
Ok, after looking long and hard at what you wrote, an playing with the code some more, I finally got it working.
With 'clean' I meant that I wanted my input buffer to *only* contain what the input function gives it. No stray printables or worse non-printables, because obviously the 4Eh function would not produce the desired results.
This:
buff db 20, 0, 21 dup('$')
saved me, the ' $ ', to be more precise :lol
Thanks alot for all your help! :bg