kake26
asked on
TP7 and interrupts
Hi,
Okay, here is a good question. Here is the info of a interrupt I want to use from the FreeDOS interuppt list, the MKDIR interrupt, see the info below. I've tinkered and mess with this stuff several days and have gotten to a point were I can call some of the simpler ones. Like oh say figure out how many bytes per sector.
This is what I try to use:
INT 21 - DOS 2+ - "MKDIR" - CREATE SUBDIRECTORY
AH = 39h
DS:DX -> ASCIZ pathname
Return: CF clear if successful
AX destroyed
CF set on error
AX = error code (03h,05h) (see #1545 at AH=59h/BX=0000h)
Notes: all directories in the given path except the last must exist
fails if the parent directory is the root and is full
DOS 2.x-3.3 allow the creation of a directory sufficiently deep that
it is not possible to make that directory the current directory
because the path would exceed 64 characters
under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
SeeAlso: AH=3Ah,AH=3Bh,AH=6Dh,AX=71 39h,AH=E2h /SF=0Ah,AX =43FFh/BP= 5053h
SeeAlso: INT 2F/AX=1103h,INT 60/DI=0511h
Here is the current attempt and more info. I know DS:DX means I have to put the Segment(longint), which points to a pchar that holds the name of the dir I want to create. See cod epost below.
Program Interrupter;
uses Dos;
var
ecode:string;
dir:pchar;
regs: Registers; { For Windows: TRegisters }
i:integer;
begin
regs.ah := $39;
dir := 'C:\test';
regs.dx := Seg(dir); {seems to work creates a dir name @ in the current dir, some how it doesn't get the name right}
writeln(Seg(dir),' ',Ofs(dir)); {I figure one of the two is right}
with regs do
intr($21,regs);
with regs do
str(ax ,ecode);
writeln(ecode);
end.
Anyone have a clue? Or better yet and answer?
Okay, here is a good question. Here is the info of a interrupt I want to use from the FreeDOS interuppt list, the MKDIR interrupt, see the info below. I've tinkered and mess with this stuff several days and have gotten to a point were I can call some of the simpler ones. Like oh say figure out how many bytes per sector.
This is what I try to use:
INT 21 - DOS 2+ - "MKDIR" - CREATE SUBDIRECTORY
AH = 39h
DS:DX -> ASCIZ pathname
Return: CF clear if successful
AX destroyed
CF set on error
AX = error code (03h,05h) (see #1545 at AH=59h/BX=0000h)
Notes: all directories in the given path except the last must exist
fails if the parent directory is the root and is full
DOS 2.x-3.3 allow the creation of a directory sufficiently deep that
it is not possible to make that directory the current directory
because the path would exceed 64 characters
under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
SeeAlso: AH=3Ah,AH=3Bh,AH=6Dh,AX=71
SeeAlso: INT 2F/AX=1103h,INT 60/DI=0511h
Here is the current attempt and more info. I know DS:DX means I have to put the Segment(longint), which points to a pchar that holds the name of the dir I want to create. See cod epost below.
Program Interrupter;
uses Dos;
var
ecode:string;
dir:pchar;
regs: Registers; { For Windows: TRegisters }
i:integer;
begin
regs.ah := $39;
dir := 'C:\test';
regs.dx := Seg(dir); {seems to work creates a dir name @ in the current dir, some how it doesn't get the name right}
writeln(Seg(dir),' ',Ofs(dir)); {I figure one of the two is right}
with regs do
intr($21,regs);
with regs do
str(ax ,ecode);
writeln(ecode);
end.
Anyone have a clue? Or better yet and answer?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks, but didn't work. I tried and made it a pchar which should have solved it and and use Ofs like you suggested. It still doesn't work. I know a asciz string is null terminated with #0, is that the same as char(0)? Could you give me a example. I've been on this for days and get no firther still. Tnx for the help sp far.
Yep, Null terminated string.
ASKER
Okay, trying more stuff. It turns out I over locked something. Alright here is my current code.
Program Interrupter;
uses Dos,Strings;
var
ecode:string;
dir:pchar;
regs: Registers; { For Windows: TRegisters }
i:string;
begin
regs.ah := $39;
dir := 'C:\test';
writeln(dir);
regs.dx := Ofs(dir);
inc(regs.dx);
writeln(Seg(dir),' ',Ofs(dir));
with regs do
intr($21,regs);
with regs do
str(ax ,ecode); {err code, in the current state it returns the number 5 }
writeln(ecode);
end.
Now as far as I think I'm doing it right if anyone sees a flub let me know. Its odd AX seems to contain and error code. Or at least the docs say so. I still don't get why it doesn't work.
Program Interrupter;
uses Dos,Strings;
var
ecode:string;
dir:pchar;
regs: Registers; { For Windows: TRegisters }
i:string;
begin
regs.ah := $39;
dir := 'C:\test';
writeln(dir);
regs.dx := Ofs(dir);
inc(regs.dx);
writeln(Seg(dir),' ',Ofs(dir));
with regs do
intr($21,regs);
with regs do
str(ax ,ecode); {err code, in the current state it returns the number 5 }
writeln(ecode);
end.
Now as far as I think I'm doing it right if anyone sees a flub let me know. Its odd AX seems to contain and error code. Or at least the docs say so. I still don't get why it doesn't work.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh, I just noticed that dir is a PCHAR and not STRING type. Before you can assign a value to a PCHAR you need to allocate some memory for it. It's probably easier to switch to a STRING instead, and then you can use the code from my previous post.
ASKER
Hi,
Yes and no about the pchar. You're a few days to late, I've figured it out all by now through lots of research and digging through code examples. You can closest to a real answer so I give you the points. Incase you want to see the ANSWER I've bothered to paste my findings
Program Interrupter;
uses Dos;
type
varstring:string[80];
var
ecode:string;
dir:varstring;
regs: Registers; { For Windows: TRegisters }
begin
regs.ah := $39;
dir := 'C:\test'+#0;
regs.ds := Seg(dir);
regs.dx := Ofs(dir);
inc(regs.dx);
with regs do
intr($21,regs);
with regs do
str(ax ,ecode);
writeln(ecode);
end.
PRESTO and enough said.
Yes and no about the pchar. You're a few days to late, I've figured it out all by now through lots of research and digging through code examples. You can closest to a real answer so I give you the points. Incase you want to see the ANSWER I've bothered to paste my findings
Program Interrupter;
uses Dos;
type
varstring:string[80];
var
ecode:string;
dir:varstring;
regs: Registers; { For Windows: TRegisters }
begin
regs.ah := $39;
dir := 'C:\test'+#0;
regs.ds := Seg(dir);
regs.dx := Ofs(dir);
inc(regs.dx);
with regs do
intr($21,regs);
with regs do
str(ax ,ecode);
writeln(ecode);
end.
PRESTO and enough said.
There shouldn't be the need to create and use the varstring type. Making dir a plain old string should work as well, but if that's what's working, that's all that matters.
dir := 'C:\test';
regs.dx := Seg(dir)
There are problems here.
dir is a Pascal string. It is not an ASCIZ string. A Pascal string starts with a number that tells the Pascal routines how long it is.
An ASCIZ string is a string that is finished when it encounters the zero char, that is a char that has the byte value of 0.
So you have to add another byte to the end of the dir string. And this byte must contain the 0 byte. That's your ASCIZ string.
Now DS:DX is a segment:offset pointer. DS needs to point to the data segment you are using in Pascal. I think it is initialised for you. DX points to the offset within the data segment.
So it is
regs.dx := ofs(dir);
inc(regs.dx); { increment it by 1 because regs.dx points to the number part of a Pascal string. After you increment it you point it at the start of the letters }