Jump to content
Sign in to follow this  
dhe

Trying to read the directory file.....

Recommended Posts

 

I'm trying to rewrite the basic catalog routine published in PHP1240 in Turbo Pasc99.

 

At the core of the first part is:

100 OPEN #1:"DSK1.",INPUT, RELATIVE,INTERNAL

220 INPUT #1:A$,J,J,K

 

* Record Length is suppose to be 38.

 

Digging deeper in to TI's software specification for the disk controller softspec.pdf {in the cyc}, TI says:

   A$       Diskname - 10 Characters [up to]

   J         Record type - always 0 for record #1

   J         Total number of sectors

   K         Number of sectors used

 

   TI says - these records consist of

    10 bytes of text                            - Diskname

      8 bytes in floating point format    - Record Type

      8 bytes in floating point format    - Total number of sectors

      8 bytes in floating point format    - Number of sectors used

  

That gives me 34 bytes, not 38...

 

I think I have good open...

I get a good disk name, but no matter how I define j,k,l; I end up with garbage.

 

{ dir 06.14.2021 }
{$S+}
 
PROGRAM dir;
 
LABEL done;
 
CONST
  fn1="DSK1.";
 
VAR File1:RELATIVE[38];  { must match dv80 }
 
    f_type: ARRAY[5] OF STRING[7];
    disk_name: STRING[10];
    j: REAL[8];  { record type always 0}
    k: REAL[8];  { total # OF sec }
    l: REAL[8];  { # OF available sec}
 
BEGIN                  {main PROGRAM }
 
  f_type[0] := "DIS/FIX";
  f_type[1] := "DIS/VAR";
  f_type[2] := "INT/FIX";
  f_type[3] := "INT/VAR";
  f_type[4] := "PROGRAM";
 
  disk_name := "";
  j         := 0.0;
  k         := 0.0;
  l         := 0.0;
 
  open(File1,fn1,input); {type, filename, in OR out }
  get(File1, disk_name, j,k,l);
  writeln("             Disk name:", disk_name);
  writeln("           Record type:", j);
  writeln("       Total # sectors:", k);
  writeln("# of available sectors:", l);
 
  close(File1);
  done:
 
END.

Results:

results.thumb.png.4f1367d1dc22f05cb02478d1bde3deaa.png

 

 

Wolfgang who is way better at tp99 then I, also had problems working with relative files.

 

Does someone know of a trick to make this work, or maybe I hit a buggy patch of code?

 

 

Share this post


Link to post
Share on other sites
19 minutes ago, dhe said:

That gives me 34 bytes, not 38...

 

Each field is preceded by a length byte, giving the extra 4 bytes of record length. The first field is a string, padded on the end with spaces. I do not remember whether the length byte is always 10 or counts the length up to the first space. Nonetheless, the first field is always 11 bytes. The last three fields are floating point numbers always preceded with an ‘8’ because floating point numbers are always 8 bytes long, so each of those fields is 9 bytes wide.

 

...lee

  • Like 1

Share this post


Link to post
Share on other sites

So I use the CYC a lot, like all the time. The CYC has 3.38GB or books/articles/newsletters/manuals etc....

 

I thought, that there would be a literal ton of information on Internal Format vs Display Format - the only really good explanation was from an article by Dr. Good of the Lima users group.

 

I thought, surely in the mass of disks which includes specs for basic, specs for file management and the specs for disk controllers, as well as tech drives disassembly of the TI disk controller ROMS and Winfried Winklers - "Disk Information" - there would be a clear explanation of the unnamed file that gets opened when doing a disk catalog. Nope, Nada, Nothing. I still don't know for example if the file is constructed in memory when the open is called, or if the DSR just interprets information it finds in the diskettes bitmap.

 

So, it's been a long battle without much progress, I can, from TP99, get the drive name and sectors available as well as all the file names.

 

I need to re-implement TI's Disk Managers trick, to pause a listing by pressing the space bar.

 

I can discuss an undocumented aspect of TI directory program as listed in php1240, with a complaint. TI did the same thing I see in lots of examples from that time period; picking a random letter, and using it as a variable. Yes, I get it, in large program it takes up space, but in a ten line EXAMPLE program, instead of J, please help the new guy and call it REC-TYPE!

 

The directory program from php1240.

100 CALL CLEAR
110 DIM TYPE$(5)
120 TYPE$(1)="DIS/FIX"
130 TYPE$(2)="DIS/VAR"
140 TYPE$(3)="TNT/FIX"
150 TYPE$(4)="INT/VAR"
160 TYPE$(5)="PROGRAM"
170 INPUT "MASTER DISK(1-3)? ":A
180 A=INT(A)
190 IF A<1 THEN 170
200 IF A>3 THEN 170
  
210 OPEN #1:"DSK"&STR$(A)&".",INPUT, RELATIVE,INTERNAL
220 INPUT #1:A$,J,J,K
230 DISPLAY "DSK";STR$(A); " - DISKNAME = ";
A$:"AVAILABLE = ";K;"USED = ";J-K
  
240 DISPLAY:"FILENAME SIZE TYPE P":
"---------- ---- ---------- -"
250 FOR LOOP=1 TO 127
260 INPUT #1:A$,A,J,K
270 IF LEN(A$)=0 THEN 350
280 DISPLAY:A$;TAB(12);J;TAB(17);
TYPE$(ABS(A));
290 IF ABS(A)=5 THEN 320
300 B$=" "&STR$(K)
310 DISPLAY SEG$(B$,LEN(B$)-2,3);
320 IF A>0 THEN 340
330 DISPLAY TAB(28);"Y";
340 NEXT LOOP
350 CLOSE #1

 

In one TI document, it is mentioned, if bit so and so is set in the record type, then the file is protected. Then you have to dig a bit deeper in to what protected actually means. Protected means: 1) Can't be deleted, 2) can't be written to and 3) can't be renamed. That will be on the test later.

 

One thing I found from experimentation, is the whole thing with ABS, is because the bit mentioned earlier makes the value returned negative. So if you have a program file, it comes back as type 5, if you have a program file AND it's protected, the value returned for type will be negative 5.

 

Also, feel free to up the diskette number from 3 to say 9! 😃

 

Let's get back to internal files, it appears there isn't a mechanism to set how many bytes you want to read, when you get(pascal) or input(basic) so magic is supposed to happen with the calling variables.

 

That appears to always work in basic and works for display in pascal.

 

I'm still not able to figure out how to get numbers reliably on an internal file with tp99. It would have been helpful if tp99 had logical operators like Shift Right/Left or even if the CH data type had been included, then I could just pick off the correct number of bytes (38) and worried about dealing with the data after the data had been retrieved from the disk.

 

If only I could call WiPoSoft technical support! 😃

 

Share this post


Link to post
Share on other sites
11 minutes ago, dhe said:

 It would have been helpful if tp99 had logical operators like Shift Right/Left

Can you use multiply and div to simulate shift operators?

x/2 is 1 bit right

x/4 is 2 bits

x/8 is 3 bits

x/16 is 4 bits 

 

x*2 is 1 bit left

etc.

 

Share this post


Link to post
Share on other sites

Not that I've found, I'm working from the original German documentation, Larry Conner's documentation and Wolfgang's grand unified documentation, so far I've not seen a way to do bitwise operations.

Share this post


Link to post
Share on other sites

I have not written a line of Pascal for 30 years so apologies for syntax errors and who knows what other errors, but something like this is what I am thinking.

 

(* shift functions  *)

function RSHIFT(num1, num2: integer): integer;
var
    i,bits,result: integer;
    bits:=1;
    begin
      for i:=0 to num2 do
      begin
        bits:= bits*2;
      end;
      result:= num1/bits;
   end;

function LSHIFT(num1, num2: integer): integer;
var
    i,bits,result: integer;
    bits:=1;
    begin
      for i:=0 to num2 do
      begin
        bits:= bits*2;
      end;
      result:= num1*bits;
   end;

 

 

Share this post


Link to post
Share on other sites
3 hours ago, dhe said:

In one TI document, it is mentioned, if bit so and so is set in the record type, then the file is protected.

 

Saying that “bit so and so is set in the record type” is misleading because the bit is not explicitly set by the DSR catalog routine, but rather (as you discovered) the Floating Point Number (FPN) that represents the record type is negated, which, of course, results in the MSb having a value of 1. Once it is determined that the FPN is negative, i.e., the file is protected, the absolute value of the FPN must be taken to get the value for the record type.

 

The only places where a bit is actually explicitly set to indicate file protection is

  • Bit #3 of the FDR’s File Status Flags byte (byte #12) on the disk and
  • Bit #1 of the PAB’s status (screen offset!) byte (byte #8) after calling the DSR’s Status subroutine with opcode 9.

...lee

Share this post


Link to post
Share on other sites

I know basic uses radix-100 for representing floating point numbers, I never really thought much about what a radix-100 would actually look like as a record stored on a disk. Of course I really don't think much about how every part of my car works either. i guess I should pull out disk fixer and look at a disk.

Share this post


Link to post
Share on other sites

Yep, you aren't supposed to be required to know how this is stored on the media. In fact, the FDR encodes these file type numbers in a single byte composed a a few single bit flags. 

 

The DSR manufactures in memory the 38 (edited) byte record it is going to return from various traditional bytes and words in the FDR. 

 

I think traditionally we've made float to integer conversion more difficult than it needed to be. Although TI didn't really document it clearly, in my opinion. .. The console ROM routine for float to int does not require XMLLNK, unless you want to be compatible with non-4A machines that nobody has... 

 

turn interrupts off ( limi 0 )

copy the 8 bytes into the FAC ( >834A )

set the workspace pointer to the GPL WS ( lwpi >83E0 )

call the console rom routine for float to int conversion ( bl @>12b8 )

restore your workspace pointer to whatever it used to be ( lwpi >???? )

 

The signed integer value you wanted from the float is now the first word of the FAC... ( mov @>834A, @dst )

 

I don't know anything about tp99... if you aren't allowed to extend it with embedded assembly, then you might translate the following C code to pascal, this does not use the console routine, but uses the knowledge Lee shared with me recently to convert these floats so I could fix reading them from the IDE controller catalog records:

 

Spoiler
int ti_floatToInt(unsigned char* bytes) {
  int signbit = bytes[0] & 0x80;

  if (signbit) {
    twosComplement(bytes);
  }

  int exp = *(bytes);
  exp = exp & 0x7f;
  exp -= 64;
  int result = bytes[1];
  int idx = 2;

  while(exp > 0) {
    result = result * 100;
    result += (unsigned int) bytes[idx];
    idx++;
    exp--;
  }

  if (signbit) {
    return -result;
  } else {
    return result;
  }
}

 

 

I just noticed I reference a twosComplement function that I wrote, that is grotesque, due to my code having to work with non-word-aligned buffers.  but you are just taking the two's complement of the first word in the bytes (the first 2 bytes cast to an signed integer. 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
1 hour ago, jedimatt42 said:

The DSR manufactures in memory the 36 byte record

 

... 38 byte record 🙂

 

...lee

  • Like 2
  • Thanks 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...