Link to home
Start Free TrialLog in
Avatar of kake26
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=7139h,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?
Avatar of dbrunton
dbrunton
Flag of New Zealand image

DS:DX -> ASCIZ pathname

 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 }
ASKER CERTIFIED SOLUTION
Avatar of dbrunton
dbrunton
Flag of New Zealand image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of kake26
kake26

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.
Avatar of kake26

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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
Avatar of kake26

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.
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.