Jump to content
Sign in to follow this  
Kchula-Rrit

Question about PABs in assembly.

Recommended Posts

Some DSRs already allow the use of CPU RAM buffers. But you can only use that feature in your own assembly programs, since no "normal" programs would expect data to end up in CPU RAM directly.

 

Yes, the UCSD p-system has an entirely own file handling structure. The directories are completely different, compared to the TI's normal files. The p-system uses only the sector read/write subprogram, to access the data its own file handling system needs.

 

If you need to read a normal file, sector by sector, but don't want to use the normal file based I/O, then you have to read the disk catalog (by reading the sectors it's in), find the file name, read the file catalog sector, find out where the file is stored and then read that file from these sectors. I've done that, when I wanted to read a DIS/VAR 80 text file on a disk with "normal" files from within the p-system, to convert these DIS/VAR 80 files to the p-system's text files.

 

The p-system, already on the normal Pascal language level, supports three different abstraction levels of disk access:

  1. Reading files with a defined content, where a stored real becomes a real value in a real variable etc. Commands like put, get, seek, read and write are used.
  2. Reading files block by block (the p-system uses 512 byte blocks, i.e. two sectors at a time), disregarding the content of the file. Blockread and blockwrite are used for this.
  3. Reading disks block by block, disregarding the file structure on the disk. Unitread and unitwrite gives access to this functionality.

 

I've done a  program, in Pascal, which reads MS-DOS disks too. It works fine with the old 360 kbyte disks, as they can be read with my drives I use with the CorComp controller. I don't have the hardware to read the 1.2 Megabyte disks in the TI.

 

The normal operating system has these capabilities too, but you can't just like that access them from BASIC. But among the "hidden" subprograms on the disk controller are not only the physical sector read/write program, but also support for formatting a disk and accessing files by sector, not by content. This is used by disk manager software to copy files, for example. Then the content isn't interesting in itself.

Share this post


Link to post
Share on other sites
7 hours ago, TheBF said:

Has anyone every written an alternate DOS that uses raw sectors? 

 

Sorta, MDOS for the Geneve has its master DSR.

 

One can read sectors by "Device" or one can read sectors of a file by "Device/:Filename".  I wrote a fairly extensive program back in the early 2000's that had just shy of 65K records (Bible verses).  As each verse was of a different length, one file had an index with the sector and sector/byte offset for each verse.  The total file size was just shy of 18,000 sectors that I had to split into 7 files.

 

Also, for what it's worth, MDOS can read/write and load/save to either VDP or CPU memory.  At this point in time, only TCP socket access is available under MDOS mode.  Under the TI-99/4A mode (GPL mode we call it), one can access the full features of the TIPI.  At this point in time, there is no support in MAME for the TIPI.  Not sure what all that would entail to wrap up a TI emulated system talking to an emulated Raspberry PI through an emulated TIPI.

 

Anyways, if you are doing something for your own personal interest, you have a lot of capability and it is much easier to program under MDOS on the Geneve than it is on the TI-99/4A.  If you are wanting to distribute something for others, then it is obvious the TI-99/4A is your route to go as there are so few Geneve users out there.

 

Beery

 

 

  • Like 2

Share this post


Link to post
Share on other sites
47 minutes ago, Kchula-Rrit said:

While investigating my runaway light show problem, I think I found a bug in TI's VMBW routine!  Here's a disassembly of the VMBW routine:

VMBW_START                                                                2200
       BL   @VDP_SET_WRITE_ADDR         >06A0,>223A        '..":'         2200

VMBW_LOOP                                                                 2204
* Get data from caller's buffer,
*  pointed-to by R1 MS byte,
*  and send to VDP.
       MOVB *R1+,@VDPWD                 >D831,>8C00        '.1..'         2204

* Done?
       DEC  R2                          >0602              '..'           2208

* If not, send another byte.
       JNE  BW                          >16FC              '..'           220A

* Return to caller.
       RTWP                             >0380              '..'           220C

If R2 is zero (writing zero bytes to VDP) it will decrement before the check, sending 65536 bytes to the VDP, causing the "lights show," and trashing any PABs and other stuff.  VMBR has the same "problem."

 

Maybe not necessarily a bug; TI probably did not expect someone to send "nothing" to the VDP.

 

K-R.

I ended up putting a protection jump around mine, but your idea is better. I will re-organize the loop.

Thanks

 

Share this post


Link to post
Share on other sites
55 minutes ago, Kchula-Rrit said:

If it recall correctly, I read on Thierry Nouspikel's site that Sectors 0 and 1 have the file-names.  I assume you would have to look up the list of sectors for the particular file-name and read them one-by-one.

If we are talking about the usual file system, things are more complicated.

 

Sector 0 is the disk name, some metadata, and the allocation map. Sector 1 is the list of sector numbers, referring to the sectors that contain file descriptor records, sorted alphabetically. Those file descriptor records may reside on any sector from 2 to the end and contain the respective file name, type, and the sector intervals (more than one if the file is fragmented). So you have to find those FDRs, check for the file name, and get the file intervals. The first sector is the start of the first interval etc. Information can also be found on Ninerpedia.

Share this post


Link to post
Share on other sites
6 hours ago, Asmusr said:

What is the best approach if you want to read from a named file sector by sector? I mean, how do you know which sectors to read?

 

You can read the sectors of a file without knowing where on the disk they reside by using DSR Level 2 Subprogram >014. As long as you have reserved enough space in VRAM, One call to the DSR can read into the VRAM buffer the desired number of consecutive file sectors beginning at any desired zero-based, file-sector number. If you ask Subprogram >014 to transfer 0 sectors, it will return status information about the file that can guide your read requests—notably, the actual number of sectors allocated to the file.

 

...lee

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites
4 hours ago, Kchula-Rrit said:

While investigating my runaway light show problem, I think I found a bug in TI's VMBW routine!  Here's a disassembly of the VMBW routine:

 

If R2 is zero (writing zero bytes to VDP) it will decrement before the check, sending 65536 bytes to the VDP, causing the "lights show," and trashing any PABs and other stuff.  VMBR has the same "problem."

 

Maybe not necessarily a bug; TI probably did not expect someone to send "nothing" to the VDP.

 

K-R.

Thanks for mentioning this. :)

 

After reviewing my own version of this I was able to take some bytes out it by using your observation.

My original version used a jump around the routine if the the count was zero.

It's pretty much free to protect from 0 count arguments by using the the carry flag to exit the loop when the count transitions from 0 to -1.

Here it is in Forth Assembler:

CODE: VWRITE  ( RAM-addr VDP-addr cnt -- )
             R0 POP,             \ vaddr to R0
             R1 POP,             \ cpu addr to R1
             WMODE @@ BL,
             R3 VDPWD LI,        \ vdp addr. in a reg. makes this 12.9% faster
             BEGIN,
                TOS DEC,         \ decr count in R4
             OC WHILE,           \ while carry=true
                 *R1+ *R3 MOVB,  \ write byte to vdp write port
             REPEAT,
             TOS POP,            \ refill top of stack cache register
             NEXT,               \ return to Forth
             END-CODE

 

And it assembles to this:

* VWRITE (VMBW)
   A7D8  C036  mov  *R6+,R0
   A7DA  C076  mov  *R6+,R1
   A7DC  06A0  bl   @>a754    \ set write address
   A7E0  0203  li   R3,>8c00
   A7E4  0604  dec  R4
   A7E6  1702  jnc  >a7ec
   A7E8  D4F1  movb *R1+,*R3
   A7EA  10FC  jmp  >a7e4
   A7EC  C136  mov  *R6+,R4
   A7EE  045A  b    *R10     \ return to Forth
  

I set R3 to the VDP write port address because I have found it is almost 13% faster on large memory block moves.

 

Share this post


Link to post
Share on other sites
2 hours ago, Lee Stewart said:

 

You can read the sectors of a file without knowing where on the disk they reside by using DSR Level 2 Subprogram >014. As long as you have reserved enough space in VRAM, One call to the DSR can read into the VRAM buffer the desired number of consecutive file sectors beginning at any desired zero-based, file-sector number. If you ask Subprogram >014 to transfer 0 sectors, it will return status information about the file that can guide your read requests—notably, the actual number of sectors allocated to the file.

 

...lee

Thanks. That's a much better approach than messing around with FDRs. And I have actually implemented this in my custom disk controller in js99er.net - I just forgot about it.

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

I can add that the p-system, which has its own file system, still need to combine that with how to access these files on the TI hardware. So they implement something they call PCB, Peripheral Control Block. It contains information that links the file control variable, visible in Pascal, to the file information block. A part of the PCB consists of the PAB, as we know it from the native system, since that's the layer where the p-system's file abstraction meets the hardware's storage device abstraction.

 

The p-system is heavily layered, in order to be as portable as possible. At the highest levels, you can't tell anything about the hardware, but the lower you come, more and more things become visible, until you hit the lowest level, the actual hardware.

  • Like 1

Share this post


Link to post
Share on other sites
On 4/22/2020 at 6:33 PM, adamantyr said:

You're absolutely right Rich. So much potential for a DSR is lost because it needs a VDP PAB and buffer space.

 

The Corcomp disk controller had subroutines that would let you read and write directly to CPU addresses. I think it still had the hard requirement of a PAB in VDP though. And since it wasn't nearly common enough it didn't get used.

...

 

 

Also still requires a VDP PAB, but HDR ROS has the same buffer capability, and it is not too late to start using it with the new HRD4000b being released in the near future.

 

It is something I sure want to give a try. Thierry’s page says:

  • If you add >40 to the opcode, VDP memory will not be used as a data buffer. Instead, the address specified in PAB bytes 2-3 is considered as a cpu RAM address. This allows for much faster data transfer. Of course, your program has to be written so as to take advantage of this feature, which is therefore only available to assembly programmers.

    http://www.unige.ch/medecine/nouspikel/ti99/horizon.htm

 

There are so many hidden gems in that beautiful device and its DSR.

 

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.

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