Jump to content
IGNORED

Toward a Better (and Better-Documented) DSRLNK


Lee Stewart

Recommended Posts

I have decided to take this DSRLNK discussion out of my fbForth thread so that I can get more non-Forth eyes on it.

 

One of the changes I am seriously considering for fbForth 3.0 is revamping the file management system—especially, how DSRLNK works. I will likely replace the MG DSRLNK currently in place. I am looking  into an implementation of Paolo Bagnaresi’s version as modified by Bill R. Sullivan (@Bill R Sullivan & @FDOS). I do not want to include Bill’s optional use of CPU RAM PABs and buffers, but I definitely want to use the 5 saved parameters after the first call to DSRLNK so CRU and device/program searches can be minimized with subsequent DSRLNK calls. Whereas Bill suggests a stack for multiple open files, I am thinking of adding those parameters to the head of each PAB. 

 

Though others have addressed some or all of my issues, trying to follow the logic of the various DSRLNKs, especially with some (several?) misleading comments, has been unsettling, to say the least.

 

I am also considering using a linked list of PABs, much as TI Basic does—we’ll see.

 

My Current Version of the Bagnaresi-Sullivan-Stewart DSRLNK:  DSRLNK_LES02.a99

 

My Current Version of the Miller-Warren-Stewart DSRLNK:     DSRLNK_fbForth03.a99

 

 

[Note:  I should mention that the Warren referenced above is our own @FALCOR4 (Doug C. Warren)]

 

...lee

Edited by Lee Stewart
FILE UPDATE, etc.
  • Like 6
Link to comment
Share on other sites

On 9/16/2023 at 6:01 PM, TheBF said:

I am not sure which 5 parameters you are referring to but the one that seems to be missing in a standard PAB is the address of the "." character.

I call that the "real PAB address" since it is used to reference the PAB if I recall correctly. 

 

The five parameters are 

 

SAVCRU DATA 0    CRU Address of the Peripheral
SAVENT DATA 0    Entry Address of DSR or Subprogram
SAVLEN DATA 0    Device or Subprogram name length
SAVPAB DATA 0    Pointer to Device or Subprogram in the PAB
SAVVER DATA 0    Version # of DSR

 

from the files in this WHTech directory, which are various versions of Paolo’s DSRLNK routine. Of course, they are also present in the DSRLNK from TI Forth (pretty much identical to the E/A version), but I am not sure if they are actually reused anywhere (I will check).

 

I need to parse one of them very carefully to make more descriptive comments as a starting point for fleshing out what I want to do. With “DSK1.FBLOCKS” as an example, SAVLEN seems to be correctly described in that “DSK1” would have a length of 4. However, SAVPAB appears to point to the position after the ‘.’ following the device name (not relevant for subprogram name), which is the actual filename of “FBLOCKS” following “DSK1.” in my example. Just before the DSR/subprogram is called >8356 also has that filename pointer. I guess that is what the DSR needs for level 3 calls. Of course, it would be irrelevant for level 1 and level 2 calls. I have work to do!

 

...lee

  • Like 2
Link to comment
Share on other sites

On 9/16/2023 at 8:43 PM, Lee Stewart said:

I need to parse one of them very carefully to make more descriptive comments as a starting point for fleshing out what I want to do.

 

FLGPTR is a prime example of what I intend to clarify in this commented code:

 

 

FLGPTR DATA 0    Pointer to Flag in PAB (Byte 1 in PAB)              

*  ⋮

       MOV  @SCNAME,R0  Fetch pointer into PAB                       
       MOV  R0,R9       Save pointer                                 
       MOV  R0,@FLGPTR  Save again pointer to PAB+1                  
*                       for DSRLNK DATA 8                            
       AI   R9,-8       Adjust pointer to flag byte                  

*  ⋮

* NOW CHECK IF ANY DSR ERROR OCCURRED                                
       LWPI DLNKWS       Load back LOADER workspace                  
       MOV  @FLGPTR,R0   Get back pointer to PAB+1                   
       JMP  FRMDSR      - 2008.8.15 - Keep on as                     
*                       - 2008.8.15 - with a Normal DSRLNK           

 

As far as I can tell, nowhere is FLGPTR updated to point to the flag byte (PAB+1). It actually, always points to the file-descriptor length byte (PAB+9). The only pointer to the flag byte is R9 in the DSRLNK workspace. In fact the last move above from FLGPTR to R0 cannot possibly work when the branch to FRMDSR is taken. I definitely have work to do!

 

...lee

  • Like 3
Link to comment
Share on other sites

Just a quick comment: there were a few iterations of the dsrlnk that made their way through the list server long ago. Some of the participants are still active in this forum.   If the conversations were preserved, they may be of some value as well.  I do not recall if the final iteration was well documented. 

  • Like 2
  • Thanks 2
Link to comment
Share on other sites

In Sweden, we had a version of DSRLNK that was modified so the same DSRLNK could be used to find DSR in GROM as well. Particularily useful if you wanted to be able to use disk files or cassette recorder in the same program. No need to do any special checking, just call that DSRLNK and it will sort it out.

 

You can find that DSRLNK on page 23 of this newsletter Programbiten. Note that the listing was printed with a daisy wheel printer, which replaced @ with '. So CLR 'HERE should be read as CLR @HERE.

 

The p-system is designed a bit according to the same ideas. It scans for devices it wants to use at startup, then store CRU and entry address in a PCB (Peripheral Control Block). It's like you envision here, a PAB with some added information. Then that information is used to accomplish a quicker access when the device is really used.

Edited by apersson850
  • Like 2
  • Thanks 2
Link to comment
Share on other sites

1 hour ago, apersson850 said:

In Sweden, we had a version of DSRLNK that was modified so the same DSRLNK could be used to find DSR in GROM as well. Particularly useful if you wanted to be able to use disk files or cassette recorder in the same program. No need to do any special checking, just call that DSRLNK and it will sort it out.

 

Yeah, the MG DSRLNK I am currently using uses the GPL version in GROM 0, but I see no way to use either of these for direct, repeat calls to a specific DSR/subprogram. My plan is to provide separate instructions for cassette tape access and to work here on a DSRLNK for ROM (>4000 – >5FFF) access to DSRs/subprograms—unless, of course, there arises a compelling reason to do otherwise.

 

...lee

  • Like 4
Link to comment
Share on other sites

No, it's probably less well aimed for such secondary quick access functions. I never bothered to sort that out, since the p-system does it from scratch and that was the only thing I used for any serious work.

But you did write you want this better documented, and then a reference to this method should be included, in my opinion.

Edited by apersson850
  • Like 3
Link to comment
Share on other sites

The spoiler below has the working copy of the ALC of the DSRLNK I am editing:

Spoiler
* ----------------------------------------------------------------------------                         
*                                                                    
*               NEW DSRLNK                                           
*                                                                    
* --- DIRECT ACCESS TO THE FDC DEVICES ---                           
*
* This code came from Paolo Bagnaresi, who started with the standard TI DSRLNK.
* It was subsequently edited by Bill R. Sullivan in cooperation with Paolo.
*
* I (Lee Stewart) am in the process of editing this ALC further. This current
* version already has extenxive edits.
*
*
                                                                     
SCLEN  EQU >8354  Device Name Length                                 
SCNAME EQU >8356  Pointer to Device Name Length in PAB               
CRULST EQU >83D0  Save last used CRU address                         
SADDR  EQU >83D2  Save last used Devicew Name pointer                
GPLWS  EQU >83E0  GPL Workspace                                      

*++ GPLWS Registers (for clarity)...
GR0    EQU  R0
GR1    EQU  R1
GR2    EQU  R2
GR3    EQU  R3
GR4    EQU  R4
GR5    EQU  R5
GR6    EQU  R6
GR7    EQU  R7
GR8    EQU  R8
GR9    EQU  R9
GR10   EQU  R10
GR11   EQU  R11
GR12   EQU  R12
GR13   EQU  R13
GR14   EQU  R14
GR15   EQU  R15
                                                                     
MSCRU  DATA >1100        Start searching DSR from this address       
                                                                     
DLNKWS DATA 0,0,0,0,0    DSRLNK workspace. TIPE is R5 of this        
TIPE   DATA 0,0,0,0,0    workspace                                   
       DATA 0,0,0,0,0,0                                              
                                                                     
NAMBUF BYTE 0,0,0,0,0,0,0,0,0,0,0                                    
                                                                     
                                                                     
                                                                     
C100   DATA 100                                                      
H20                                                                  
       EVEN                                                          
H2000  DATA >2000                                                    
DECMAL TEXT '.'                                                      
HAA    BYTE >AA                                                      
       EVEN                                                          
DATA8  DATA >8       - 8 is the normal DATA that                     
*                      follows a BLWP @DSRLNK                        
* Save parameters here                                               
SAV8A  DATA 0    Save data following BLWP @DSRLNK (8 or >A)          
                                                                     
SAVCRU DATA 0     CRU Address of the Peripheral
SAVENT DATA 0     Entry Address of DSR or Subprogram
SAVLEN DATA 0     Device or Subprogram name length 
SAVPAB DATA 0     PAB address of filename following device name (level 3)..
*                 ..not relevant for subprogram (levels 1 & 2)
SAVVER DATA 0     Version # of DSR
                                                                  
FLGPTR DATA 0     Pointer to Flag byte in PAB (PAB+1)              
                                                                     
*                                                                    
* Utility Vectors                                                    
*                                                                    
*========================================                            
*       DSRLNK                                                       
*========================================                            
DSRLNK DATA DLNKWS,DLENTR                                            
*** Link to device service routine                                   
*                                                                    
                                                                     
DLENTR MOV  *R14+,R5       Fetch program type for link                  
       MOV  R5,@SAV8A      Save data after BLWP @DSRLNK (8 or >A)       
       LI   R8,>0F00       Starting point for new search                
       SZCB @H20,R15       Reset equal bit                              
       MOV  @SCNAME,R0     Fetch pointer to PAB+9 (pathname length)
       MOV  R0,R9          Save pointer                                 
       AI   R9,-8          Adjust saved pointer to flag byte                  
       MOV  R9,@FLGPTR     Save pointer to PAB+1 for DSRLNK DATA 8
       BLWP @VSBR          Read device name length                      
       MOVB R1,R3          Store it elsewhere                           
       SRL  R3,8           Make it a word value                         
       SETO R4             Initialize a counter                         
       LI   R2,NAMBUF      Point to NAMBUF                              
LNK$LP INC  R0             Point to next char of name                   
       INC  R4             Increment character counter                  
       CI   R4,7           Is name length >7?                           
       JGT  LNKERR         Yes, error                                   
       C    R4,R3          End of name?                                 
       JEQ  LNK$LN         Yes                                          
       BLWP @VSBR          Read current character                       
       MOVB R1,*R2+        Move it to NAMBUF                            
       CB   R1,@DECMAL     Is it a decimal point?                       
       JNE  LNK$LP         No                                           
LNK$LN MOV  R4,R4          Is name length zero?                         
       JEQ  LNKERR         Yes, error                                   
       CLR  @CRULST                                                  
       MOV  R4,@SCLEN      Store device name length for DSR search 
       MOV  R4,@SAVLEN     Save device name length
       INC  R4             Adjust it to point..
       A    R4,@SCNAME     ..to start of filename after '.' (level 3 use only)
       MOV  @SCNAME,@SAVPAB   Save pointer to filename after device name '.'
*                                                                    
*** Search ROMs at >4000 for DSR                                     
*                                                                    
                                                                     
SROM   LWPI GPLWS          Use GPL workspace to search                  
       CLR  GR1            Version found of DSR etc.                    
       MOV  @MSCRU,GR12    Starting CRU address is in MSCRU from Forth  
       JMP  NOOFF2         CRU selected                                 
NOROM  SBZ  0              Yes, turn it off
       CLR  @CRULST        Reset in case we are finished  (label NOOFF removed)
       AI   GR12,>0100     No, point to next ROM
NOOFF1 C    GR12,@MSCRU    Did we cycle back to the original CRU?
       JEQ  NODSR          Yes, end the scan

       CI   GR12,>2000     At the end
       JNE  NOOFF2         no
       LI   GR12,>1000     Yes, restart * Paolo 15.2.2010  Save a few CPU cycles
       JMP  NOOFF1         restart properly - don't fall through         
NOOFF2 MOV  GR12,@CRULST   Save address of current CRU                  
       SBO  0              Turn on ROM                                  
       LI   GR2,>4000      Start at beginning                           
       CB   *GR2,@HAA      Is it a valid ROM?                           
       JNE  NOROM          No                                           
       A    @TIPE,GR2      Go to first pointer (TYPE already used - BRS)
       JMP  SGO2                                                     
SGO    MOV  @SADDR,GR2     Continue where we left off                   
       SBO  0              Turn ROM back on                             
SGO2   MOV  *GR2,GR2       Is address a zero                            
       JEQ  NOROM          Yes, no program to look at                   
       MOV  GR2,@SADDR     Remember where we go next                    
       INCT GR2            Go to entry point                            
       MOV  *GR2+,GR9      Get entry address                            
*                                                                    
*** See if name matches                                              
*                                                                    
       MOVB @SCLEN+1,GR5   Get devicename/subprogram length to GR5 MSB
       JEQ  NAME2          Zero length, don't do match                  
       CB   GR5,*GR2+      Does length match next device/subprogram in DSR?                           
       JNE  SGO            No                                           
       SRL  GR5,8          Yes..move to LSB for counting
       LI   GR6,NAMBUF     Point to NAMBUF                              
NAME1  CB   *GR6+,*GR2+    Is character correct?                        
       JNE  SGO            No                                           
       DEC  GR5            More to look at?                             
       JNE  NAME1          Yes                                          
NAME2  INC  GR1            Next version found
       MOV  GR1,@SAVVER    Save version number                          
       MOV  GR9,@SAVENT    Save entry address                           
       MOV  GR12,@SAVCRU   Save CRU address                             
       BL   *GR9           Match, call subroutine                       

* This jump executes only if no DSR to advance return vector past it.
       JMP  SGO            Not right version                            

       SBZ  0              Turn off ROM                                 
                        
       LWPI DLNKWS         Select DSRLNK workspace                      
       MOV  R9,R0          Point to flag byte in level-3 PAB                    
FRMDSR MOV  @SAV8A,R1      Get back data after BLWP @DSRLNK (8 or >A)
       CI   R1,8           Was it 8?                                    
       JEQ  DSRDT8         Yes, jump: Normal DSRLNK                     
       MOVB @>8350,R1      No, we have a DATA >A. Get Error byte from >8350
       JMP  DSRDTA         Go and return error byte to the caller                           
                                                                        
DSRDT8 BLWP @VSBR          Read flag byte                               

*++ Error codes for both DSRs and subprograms are in high 3 bits
DSRDTA SRL  R1,13          Just want the error flags
       JNE  IOERR          Error!                                       
       RTWP                                                          
*                                                                    
*** Error handling                                                   
*                                                                    
                                                                     
NODSR  LWPI DLNKWS      Select DSRLNK workspace                      
LNKERR CLR  R1          Clear the error flags                        
IOERR  SWPB R1                                                       
       MOVB R1,*R13     Store error flags in calling R0              
       SOCB @H20,R15    Indicate an error occured                    
       RTWP             Return to caller                             
                                                                     
*----------------*                                                   
* ACCESS ONCE AGAIN THE SAME DSRLNK                                  
*----------------*                                                   
DSRAGN EQU  $                                                        
       DATA DLNKWS                                                   
       DATA LDGETR                                                   
LDGETR SZCB @H20,R15     Reset Equal Bit in STATUS (V2)              

       LWPI GPLWS                                                    

* Paolo 15.2.2010 - Use GR11 instead of GR0 of GPLWS. We will be using GR11
*		              anyway later on with the BL *GR9
       LI   GR11,SAVCRU       pointer to last used CRU address
       MOV  *GR11+,GR12       SAVCRU..CRU address
       MOV  *GR11+,GR9        SAVENT..DSR entry address
       MOV  *GR11+,@SCLEN     SAVLEN..device name/subprogram namelength
       MOV  *GR11+,@SCNAME    SAVPAB..PAB filename addr after dev name..lvl 3
       MOV  *GR11+,GR1        SAVVER..DSR version Number 
       SBO  0              Open CARD
       CB   @>4000,@HAA    Valid Indentifier?
       JNE  NODSR          No, Error Code 0 = Bad Device Name..
*                          ..The above jump to NODSR may happen only in case
*                          ..of either card hardware malfunctioning or if
*                          ..there are 2 cards opened at the same time                           
                                                                     
       BL   *GR9           Execute DSR

* This jump executes only if no DSR to advance return vector past it.
       JMP  NODSR          issue Error Code 0 = Bad Device Name                             

       SBZ  0              Otherwise, close CARD                       
                                                                     
* NOW CHECK IF ANY DSR ERROR OCCURRED                                
       LWPI DLNKWS         Load back LOADER workspace                  
       MOV  @FLGPTR,R0     Get back pointer to PAB+1                   
       JMP  FRMDSR         - 2008.8.15 - continue as with a normal DSRLNK           
                                                                     
* DSRLNK code ends here!                                             

 

 

I have fixed the FLGPTR issue (never pointing to the PAB flag byte, PAB+1) mentioned in a previous post.

 

I was thinking of changing the use in the routine of the term, “version”, because it has nothing to do with the version of the DSR listed in the second byte at >4001. It has, rather, to do with how many successful matches have been made of the device/subprogram name in the course of finding a routine associated with that name that actually works. That is to say, if a particular routine for, say, DSK1.FILENAME, that runs without error, has a version number of 3, it means that two previous routines with the same name (DSK1) were found, but errored out before this one succeeded. If we cannot find a better descriptor, I will just clarify it in the comments.

 

While we are discussing “version”, I noticed that the code five instructions above NAME1, jumps to NAME2 if the device/subprogram name-length byte (at >8355) is zero. That increments the version number without there having actually been a name match in the DSR. I should think it would be better to send it to LNKERR, where a similar test, at the beginning, sends it. It is probably a moot point, because the name length should never be zero at that spot in the routine. If the byte at >8355 is zero, it will exit the routine at the beginning. It seems to me that the test is superfluous and could be removed. I’ll stop talking now...

 

...lee

  • Like 1
  • Haha 2
Link to comment
Share on other sites

 Considering

 

23 hours ago, Vorticon said:

<snip>

One thing I want to test as well is disabling the RS232 card prior to saving the image. My program uses that card to receive outside info from a camera via the parallel port, and I only disable the card just prior to exiting the program. I wonder if that might make a difference...

22 hours ago, InsaneMultitasker said:

If the RS232's ROM is enabled and visible at the >4000 space, then yes, it could definitely interfere with other DSR operations.  The DSRLNK routine scans the peripherals by turning each card on and off to find the requested device name or subroutine.  Perhaps the DSRLNK is turning off the RS232 during the first save operation, which sets up the second save operation for success (since the RS232 is now off).  You may have found the answer :)  <fingers crossed>

 

8 hours ago, apersson850 said:

Vary probable.

A "standard" DSRLNK call will turn each card in the CRU address range first on, then off, in the search for the correct DSR. If you are looking for a disk controller DSR, which normally is at >1100, it will not be found if the card at >1300 is enabled at the same time. Two data buffers will try to overdrive each other. Scanning will continue and soon enable the card at >1300 (which doesn't change anything, since it already is enabled), find the RS232 card, realize it's not the card searched for, disable the card and continue the search. But the disk controller at >1100 will not be found, because looking for that has already passed.

Next time the DSRLNK is called, provided nothing turned that RS 232 card on again in between, all cards are off and the disk controller will be found at >1100.

 

from another thread, I wonder whether it might not be a good idea for DSRLNK to turn off all peripheral cards before doing any DSR checking, just to be certain there are no conflicts.

 

...lee

  • Like 2
Link to comment
Share on other sites

36 minutes ago, Lee Stewart said:

from another thread, I wonder whether it might not be a good idea for DSRLNK to turn off all peripheral cards before doing any DSR checking, just to be certain there are no conflicts.

This may be a good idea in hindsight, but the premise would be to assume that assembly language programmers mess with the CRU bits, which they should not. I suppose TI's vision was that there are these nice DSRs, so there would be no need to use CRU bits directly. In systems like the 99xxx, access to CRU bits can be limited to privileged mode.

 

But more importantly, you don't know whether bit 0 is the only bit to reset.

  • Like 3
Link to comment
Share on other sites

48 minutes ago, Lee Stewart said:

from another thread, I wonder whether it might not be a good idea for DSRLNK to turn off all peripheral cards before doing any DSR checking, just to be certain there are no conflicts.

This seems like it might be a case of a good, cautious DSRLNK approach that isn't needed for most programs, provided the programmer follows existing device access conventions.  Turning off all of the cards each time would also add some overhead and execution time, especially during heavy record-based IO.  (As an aside, the Geneve OS and boot eprom start by turning off all cards prior to executing the standard ROM powerups, to ensure that any cards that were not turned off by a hardware reset, e.g., the TIPI card, are in a known state. DSRLNK operates in the same standard manner as the /4a.)

  • Like 3
Link to comment
Share on other sites

55 minutes ago, mizapf said:

This may be a good idea in hindsight, but the premise would be to assume that assembly language programmers mess with the CRU bits, which they should not. I suppose TI's vision was that there are these nice DSRs, so there would be no need to use CRU bits directly. In systems like the 99xxx, access to CRU bits can be limited to privileged mode.

 

But more importantly, you don't know whether bit 0 is the only bit to reset.

Messing with the CRU bits is necessary to activate and access the parallel port at the low level for interfacing purposes. One just has to remember to clean up afterwards :) 

  • Like 3
Link to comment
Share on other sites

On 9/27/2023 at 7:02 PM, mizapf said:

But more importantly, you don't know whether bit 0 is the only bit to reset.

Well, that you should know, since the specification says that cards with a DSR should be enabled/disabled by the first bit in the CRU address space for the card. Which is bit 0 relative to the base address, of course.

If other bits are left on, they should not make the DSR program visible in the memory address range >4000-5FFF.

 

The parallel port is a hybrid, since the 8 data bits are read/written with a memory access, but the additional handshake bits are implemented as CRU bits.

 

I use CRU bits to enable/disable banks in my internal 16-bit wide RAM expansion. But then that wasn't anticipated by TI either.

Edited by apersson850
  • Like 4
Link to comment
Share on other sites

27 minutes ago, InsaneMultitasker said:

A neat feature of the TI RS232 is that the serial port can be used without turning on bit 0 to enable the ROM.  I debugged a few of the nasty Horizon ROS bugs from 'within' the ROS/DSR, by sending debug & trace information to the serial port.  I'm sure TI wouldn't have blessed this either. :)

 

LOL.  

 

I had to do a double check to confirm that my RS232 driver never turns on the "card", only the LED. :) 

Once I saw signals on the connector it never occurred to me to  "turn on" the card. 

Does  turning on the card just put the ROM on CPU buss?

 

I push R12 before using the UART and POP it back when I am done using it so I play nice in the sandbox ... kind of. 

Link to comment
Share on other sites

On 9/20/2023 at 10:44 AM, Lee Stewart said:

The only pointer to the flag byte is R9 in the DSRLNK workspace. In fact the last move above from FLGPTR to R0 cannot possibly work when the branch to FRMDSR is taken. I definitely have work to do!

I believe the last move was intended to restore R0 for the upcoming VSBR, when the 'quick' routine DSRAGN is called.  Should FLGPTR store the value of R9 (not R0) after it is adjusted to point to the flag byte? 

       MOV  R0,R9       Save pointer                                 
       MOV  R0,@FLGPTR  Save again pointer to PAB+1                  
*                       for DSRLNK DATA 8                            
       AI   R9,-8       Adjust pointer to flag byte   
       MOV R9,@FLGPTR Save again pointer to PAB+1                
       BLWP @VSBR       Read device name length  

Maybe R9 could be used in place of FLGPTR, regardless of entry, if the jump to FRMDSR was changed to the MOV R9,R0 statement. I didn't trace the entire routine to verify whether this would work.

       MOV  R9,R0       Point to flag byte in PAB                    
FRMDSR MOV  @SAV8A,R1   Get back data                                
*                       following BLWP @DSRLNK (8 or >A)
  • Like 2
Link to comment
Share on other sites

 

3 hours ago, InsaneMultitasker said:

I believe the last move was intended to restore R0 for the upcoming VSBR, when the 'quick' routine DSRAGN is called.  Should FLGPTR store the value of R9 (not R0) after it is adjusted to point to the flag byte? 

       MOV  R0,R9       Save pointer                                 
       MOV  R0,@FLGPTR  Save again pointer to PAB+1                  
*                       for DSRLNK DATA 8                            
       AI   R9,-8       Adjust pointer to flag byte   
       MOV R9,@FLGPTR Save again pointer to PAB+1                
       BLWP @VSBR       Read device name length  

 

Yeah—that is what I did in my subsequent post.

 

3 hours ago, InsaneMultitasker said:

Maybe R9 could be used in place of FLGPTR, regardless of entry, if the jump to FRMDSR was changed to the MOV R9,R0 statement. I didn't trace the entire routine to verify whether this would work.

       MOV  R9,R0       Point to flag byte in PAB                    
FRMDSR MOV  @SAV8A,R1   Get back data                                
*                       following BLWP @DSRLNK (8 or >A)

 

I did think of that and it should work because the DSR workspace is not used by any other routine. Even in the E/A DSRLNK, where the DSR WS overlaps a utility WS, R9 is safe between calls to DSRLNK. Ultimately, however, I want to be able to deal with more than one PAB. For example, copying records from one file to another. This would require storing DSR calling information with the PABs or, per Bill Sullivan’s suggestion, on a stack. I think it will work better stored with the PABs, even though that involves VRAM access. Of course, I could always do something in RAM.

 

...lee

  • Like 2
Link to comment
Share on other sites

1 hour ago, Lee Stewart said:

Ultimately, however, I want to be able to deal with more than one PAB. For example, copying records from one file to another.

This would require storing DSR calling information with the PABs or, per Bill Sullivan’s suggestion, on a stack.

I think it will work better stored with the PABs, even though that involves VRAM access. Of course, I could always do something in RAM.

 

...lee

Not sure if it helps your work, but I took the approach of making a VDP stack that allocates PAB+buffer descending from system reported end of VDP RAM.

Buffers are always maximum size for simplicity and speed of access.

 

I found it advantageous in a Forth environment to use VDP memory operators to read/write the VDP PAB directly rather that duplicating anything in RAM.

Block read/write with VDP ram is as fast as RAM-to-RAM move on the 8 bit buss, from what I can see.

Word-wide fetch store operators are about 50% slower than the RAM equivalent in Forth, but you don't do many of those.

These tradeoffs might not make any sense in an assembler environment. 

Edited by TheBF
typo
  • Like 2
Link to comment
Share on other sites

In dissecting the various DSRLNK incarnations before the Bagnaresi/Sullivan DSRLNK, I am wondering why all of them, including the E/A version from which they were all derived (as far as I can tell) save the following (labels vary), even though they are not used within the routine or elsewhere (that I can find—maybe someone knows?):

 

SAVCRU DATA 0           CRU Address of the Peripheral
SAVENT DATA 0           Entry Address of DSR or Subprogram
SAVLEN DATA 0           Device or Subprogram name length
SAVPAB DATA 0           Pointer to Device or Subprogram in the PAB
SAVVER DATA 0           Version # of DSR

 

Most or all of these persist long enough to be captured after return to the calling routine without the need to save them in the above manner—even in the console DSRLNK, which does not save them elsewhere. The only one that surely does not survive is SAVVER (GPLWS R1)—and I am not sure it is necessary. Perhaps these saved values were intended for debugging.

 

I am even considering keeping the MG DSRLNK and trying to manage reruns of the various DSRs/subprograms in its shadow. The only feature I would like to have that will likely not be possible is starting the DSR search at a particular CRU address and circling around back to it to complete the search. Folks are probably used to managing CRU addresses in hardware to manage search order, but starting the DSR search at any desired CRU address from >1000 to >1F00 and circling back around to the starting address is a nifty feature of the Bagnaresi/Sullivan DSRLNK, which I kind of hate to give up.

 

Just thinking out loud here....

 

...lee

 

Edited by Lee Stewart
correction
  • Like 2
Link to comment
Share on other sites

16 hours ago, Lee Stewart said:

In dissecting the various DSRLNK incarnations before the Bagnaresi/Sullivan DSRLNK, I am wondering why all of them, including the E/A version from which they were all derived (as far as I can tell) save the following (labels vary), even though they are not used within the routine or elsewhere (that I can find—maybe someone knows?):

 

SAVCRU DATA 0           CRU Address of the Peripheral
SAVENT DATA 0           Entry Address of DSR or Subprogram
SAVLEN DATA 0           Device or Subprogram name length
SAVPAB DATA 0           Pointer to Device or Subprogram in the PAB
SAVVER DATA 0           Version # of DSR

This looks like the authors had plans to allow re-entering the DSR code without searching through everything every time but it was never completed.  ?

 

  • Like 2
Link to comment
Share on other sites

The re-entry routine (at least in the latest version that I am aware of) populates registers using the SAVCRU "structure", in order to bypass the scanning and setup of a standard DSRLNK call.  As I recall, R11 is set to the address of SAVCRU and the registers are populated via moves, e.g., MOV *R11+,<target>.

  • Like 3
Link to comment
Share on other sites

1 hour ago, InsaneMultitasker said:

The re-entry routine (at least in the latest version that I am aware of) populates registers using the SAVCRU "structure", in order to bypass the scanning and setup of a standard DSRLNK call.  As I recall, R11 is set to the address of SAVCRU and the registers are populated via moves, e.g., MOV *R11+,<target>.

 

I do understand that. That is what I was referencing with my opening phrase. It is all the others that save those same values and addresses and never use them that puzzles me. What @TheBF said above about possible intentions for re-entry down the road (as the Bagnaresi/Sullivan version actually does, per your post) is a good guess. I think it is even possible it was used by TI programmers on the 990 computers (@FarmerPotato?), but just not passed on to us in the E/A manual.

 

...lee

  • Like 2
Link to comment
Share on other sites

2 hours ago, Lee Stewart said:

I do understand that. That is what I was referencing with my opening phrase

Ah hah!  I read your post a few more times before I figured out that the orangish font (on this particular monitor of mine) doesn't play nicely with my eyes. I will return to lurking and learning :) 

 

  • Like 1
Link to comment
Share on other sites

3 hours ago, InsaneMultitasker said:

Ah hah!  I read your post a few more times before I figured out that the orangish font (on this particular monitor of mine) doesn't play nicely with my eyes. I will return to lurking and learning :) 

 

Yeah...I should try another font. It works fine on a black background, but not so well on white.

 

And...I have learned far more from you over the years than you have likely learned from me!

 

...lee

 

Link to comment
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...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...