Jump to content

Recommended Posts

13 minutes ago, speccery said:

Mini Memory does implement DSRs, and it even does that in GPL code.

GPL has veered me away from that DSR, as well. I believe TERMINAL EMULATOR II, also uses a device DSR, "SPEECH".:grin:

  • Like 1

Share this post


Link to post
Share on other sites

The thing with GPL DSRs is that they only work from BASIC because assembly programs generally don't look for them.

  • Like 1

Share this post


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

The thing with GPL DSRs is that they only work from BASIC because assembly programs generally don't look for them.

Assembly sucks at DSR unless you have a GPL DSRLNK DSR from Miller Graphics.

 

This has been stated for over 20 years as a fact.

 

Assembly DSR only find ROM DSR and nothing else, hence why the suck.

  • Like 2

Share this post


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

The thing with GPL DSRs is that they only work from BASIC because assembly programs generally don't look for them.

I have written the SD card DSR for my ET-PEB board (and before that for the FPGA system). I suppose that has been the 'easy' part. The receiving end of a DSR is just parsing the PAB, and trying to do the right thing. My DSR does not properly deal with all the weird single character named DSR routines (named hex 10 to hex 16) for sector I/O.

But calling the DSRs is another matter.

A related matter is that I still don't know how to call machine code from GPL, or vice versa, and this is something I should learn at some point rather soon. If I have understood correctly, all the various DSRLNK routines are simple header walking routines, resolving a string to an address. If the address is in ROM, it's all good to go and ready for a branch to that address, but if it is a GROM address I suspect some setup is needed for scratchpad variables before jumping to somewhere in ROM to start the GPL interpreter. And I don't know how to return from there.

Share this post


Link to post
Share on other sites

I never found out where the DSRLNK that BASIC uses is located, and why we don't use that from assembly. Is it because it's written in GPL?

  • Like 1

Share this post


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

I never found out where the DSRLNK that BASIC uses is located, and why we don't use that from assembly. Is it because it's written in GPL?

 

I use it in fbForth 2.0 via the MG DSRLNK/GPLLNK. The trick is to get the GPL code to return to ALC, which is what the MG code does. The GPL DSRLNK is located in the console GROM 0 at >03D9 (see Heiner Martin’s TI99/4A Intern, p. 104). Not only does it check through all the DSRs in CRU space (>4000), but, if it exhausts CRU space, it drops through to GSRLNK, which checks every GROM (0 – 15?) at the GROM base address in GPLWS R13, which includes the cassette tape DSR in console GROM 0. I do not know whether it tries to check other GROM bases—I have not analyzed it that far.

 

FYI, here is the MG DSRLNK/GPLLNK I modified slightly to use in fbForth 2.0:

Spoiler
LLVSPT   ; <--This is the source copy location for the rest of this code.

$BUFF  EQU  >2010
 
* 4 I/O buffers below ($LO = >3020) 
* Change '4' to number of buffers needed and for which there is room.

$LO    EQU  4*>404+$BUFF      start of low-level routines after I/O buffers

*  EQUating labels below to $LO+$-LLVSPT insures those labels refer to the
*  addresses where they get copied.
*    .
*    .
*    .
*    ________  __   __   _  ____ __           __  ________
*   / ___/ _ \/ /  / /  / |/ / //_/          /  |/  / ___/
*  / (_ / ___/ /__/ /__/    / ,<      _ _ _ / /|_/ / (_ / 
*  \___/_/  /____/____/_/|_/_/|_|    (_|_|_)_/  /_/\___/  
* 
*-----------------------------------------------------------------------*
;[*== GPLLNK- A universal GPLLNK - 6/21/85 - MG =========================
* {LES NOTE: Some labels have been modified for fbForth compatibility.} *
*                                                                       *
* This routine will work with any GROM library slot since it is         *
* indexed off of R13 in the GPLWS.  (It does require Mem Expansion)     *
* This GPLLNK does NOT require a module to be plugged into the          *
* GROM port so it will work with the Editor/Assembler,                  *
* Mini Memory (with Mem Expansion), Extended Basic, the Myarc           *
* CALL LR("DSKx.xxx") or the CorComp Disk Manager Loaders.              *
* It saves and restores the current GROM Address in case you want       *
* to return back to GROM for Basic or Extended Basic CALL LINKs         *
* or to return to the loading module.                                   *
*                                                                       *
*    ENTER: The same way as the E/A GPLLNK, i.e., BLWP @GPLLNK          *
*                                                 DATA >34              *
*                                                                       *
*    NOTES: Do Not REF GPLLNK when using this routine in your code.     *
*                                                                       *
* 70 Bytes - including the GPLLNK Workspace                             *
*-----------------------------------------------------------------------*

GPLWS  EQU  >83E0                GPL workspace
G_R4   EQU  GPLWS+8              GPL workspace R4
G_R6   EQU  GPLWS+12             GPL workspace R6
SUBSTK EQU  >8373                GPL Subroutine stack pointer
LDGADR EQU  >60                  Load & Execute GROM address entry point
XTAB27 EQU  >200E                Low Mem XML table location 27
*                                ..Will contain XMLRTN at startup
GETSTK EQU  >166C              
 
*++------------------------------------------------------------------------++*
*++---ADDRESS: >3784 in fbForth 2.0:12-------------------------------------++*
*++------------------------------------------------------------------------++*
GPLLNK EQU  $LO+$-LLVSPT
       DATA GLNKWS      R7       Set up BLWP Vectors
       DATA GLINK1      R8     
* RTNADR EQU  $LO+$-LLVSPT    <---don't think we need this label
       DATA XMLRTN      R9       address where GPL XML returns to us...
*                                ...this address will already be in XTAB27,...
*                                ...>200E, so don't really need it here}
GXMLAD EQU  $LO+$-LLVSPT
       DATA >176C       R10      GROM Address for GPL 'XML >27' (>0F27 Opcode)
       DATA >50         R11      Initialized to >50 where PUTSTK address resides
*++------------------------------------------------------------------------++*
*++---ADDRESS: >3776 in fbForth 2.0:12-------------------------------------++*
*++------------------------------------------------------------------------++*
GLNKWS EQU  $LO+$-LLVSPT->18     GPLLNK's workspace of which only...
       BSS  >08         R12-R15  ...registers R7 through R15 are used

*++------------------------------------------------------------------------++*
*++---ADDRESS: >3796 in fbForth 2.0:12-------------------------------------++*
*++------------------------------------------------------------------------++*
GLINK1 EQU  $LO+$-LLVSPT
       MOV  *R11,@G_R4           Put PUTSTK Address into R4 of GPL WS
       MOV  *R14+,@G_R6          Put GPL Routine Address in R6 of GPL WS
       LWPI GPLWS                Load GPL WS
       BL   *R4                  Save current GROM Address on stack
       MOV  @GXMLAD,@>8302(R4)   Push GPL XML Address on stack for GPL Return
       INCT @SUBSTK              Adjust the stack pointer
       B    @LDGADR              Execute our GPL Routine

XMLRTN EQU  $LO+$-LLVSPT
       MOV  @GETSTK,R4           Get GETSTK pointer
       BL   *R4                  Restore GROM address off the stack
       LWPI GLNKWS               Load our WS
       RTWP                      All Done - Return to Caller
;]
*     ___  _______  __   _  ____ __           __  ________
*    / _ \/ __/ _ \/ /  / |/ / //_/          /  |/  / ___/
*   / // /\ \/ , _/ /__/    / ,<      _ _ _ / /|_/ / (_ / 
*  /____/___/_/|_/____/_/|_/_/|_|    (_|_|_)_/  /_/\___/  
* 
*-----------------------------------------------------------------------*
;[*== DSRLNK - A Universal Device Service Routine Link - MG =============
* {LES NOTE: Some labels have been modified for fbForth compatibility.} *
*                                                                       *
*      (Uses console GROM 0's DSRLNK routine)                           *
*      (Do not REF DSRLNK or GPLLNK when using these routines)          *
*      (This DSRLNK will also handle Subprograms and CS1, CS2)          *
*                                                                       *
*      ENTER: The same way as the E/A DSRLNK, i.e., BLWP @DSRLNK        *
*                                                   DATA 8              *
*                                                                       *
*      NOTES: Must be used with a GPLLNK routine                        *
*             Returns ERRORs the same as the E/A DSRLNK                 *
*             EQ bit set on return if error                             *
*             ERROR CODE in caller's MSB of Register 0 on return        *
*                                                                       *
* 186 Bytes total - including GPLLNK, DSRLNK and both Workspaces        *
*-----------------------------------------------------------------------*

PUTSTK EQU  >50                     Push GROM Address to stack pointer
TYPE$  EQU  >836D                   DSRLNK Type byte for GPL DSRLNK
NAMLEN EQU  >8356                   Device name length pointer in VDP PAB
VWA    EQU  >8C02                   VDP Write Address location
VRD    EQU  >8800                   VDP Read Data byte location
G_R4LB EQU  >83E9                   GPL Workspace R4 Lower byte
GSTAT  EQU  >837C                   GPL Status byte location
                                    
*++------------------------------------------------------------------------++*
*++---ADDRESS: >37BE in fbForth 2.0:12-------------------------------------++*
*++------------------------------------------------------------------------++*
DSRLNK EQU  $LO+$-LLVSPT
       DATA DSRWS,DLINK1            Set BLWP Vectors

*++------------------------------------------------------------------------++*
*++---ADDRESS: >37C2 in fbForth 2.0:12-------------------------------------++*
*++------------------------------------------------------------------------++*
DSRWS  EQU  $LO+$-LLVSPT            Start of DSRLNK workspace
DR3LB  EQU  DSRWS+7                 lower byte of DSRLNK workspace R3
*++------------------------------------------------------------------------++*
*++---ADDRESS: >37C2 in fbForth 2.0:12-------------------------------------++*
*++------------------------------------------------------------------------++*
DLINK1 EQU  $LO+$-LLVSPT
       MOV  R12,R12         R0      Have we already looked up the LINK address?
       JNE  DLINK3          R1      YES!  Skip lookup routine
*<<-------------------------------------------------------------------------->>*
* This section of code is only executed once to find the GROM address          *
* for the GPL DSRLNK - which is placed at DSRADR and R12 is set to >2000       *
* to indicate that the address is found and to be used as a mask for EQ & CND  *
*------------------------------------------------------------------------------*
       LWPI GPLWS           R2,R3   else load GPL workspace
       MOV  @PUTSTK,R4      R4,R5   Store current GROM address on the stack
       BL   *R4             R6
       LI   R4,>11          R7,R8   Load R4 with address of LINK routine vector
       MOVB R4,@>402(R13)   R9,R10  Set up GROM with address for vector

***les*** Note on above instruction:
***les***    1. R13 of GPLWS has >9800=GRMRD (GROM Read Data)
***les***    2. >402 added to GRMRD yields >9C02=GRMWA (GROM Write Address)

       JMP  DLINK2          R11     Jump around R12-R15
       DATA 0               R12     contains >2000 flag when set
       DATA 0,0,0           R13-R15 contains WS, PC & ST for RTWP
DLINK2 MOVB @G_R4LB,@>402(R13)      Finish setting up GROM address
       MOV  @GETSTK,R5              Take some time & set up GETSTK pointer
       MOVB *R13,@DSRAD1            Get the GPL DSR LINK vector
       INCT @DSRADR                 Adjust it to get past GPL FETCH instruction
       BL   *R5                     Restore the GROM address off the stack
       LWPI DSRWS                   Reload DSRLNK workspace
       LI   R12,>2000               Set flag to signify DSRLNK address is set
*<<-------------------------------------------------------------------------->>*
DLINK3 INC  R14                     Adjust R14 to point to caller's DSR Type byte
       MOVB *R14+,@TYPE$            Move it into >836D for GPL DSRLNK
       MOV  @NAMLEN,R3              Save VDP address of Name Length
       AI   R3,-8                   Adjust it to point to PAB Flag byte
       BLWP @GPLLNK                 Execute DSR LINK
*++------------------------------------------------------------------------++*
*++---ADDRESS: >3810 in fbForth 2.0:12-------------------------------------++*
*++------------------------------------------------------------------------++*
DSRADR EQU  $LO+$-LLVSPT
       BYTE >03                     High byte of GPL DSRLNK address
DSRAD1 EQU  $LO+$-LLVSPT
       BYTE >00                     Lower byte of GPL DSRLNK address
*----Error Check & Report to Caller's R0 and EQU bit-------------------------
       MOVB @DR3LB,@VWA             Set up LSB of VDP Address for Error Flag
       MOVB R3,@VWA                 Set up MSB of VDP Address for Error Flag
       SZCB R12,R15                 Clear EQ bit for Error Report
       MOVB @VRD,R3                 Get PAB Error Flag
       SRL  R3,5                    Adjust it to 0-7 error code
       MOVB R3,*R13                 Put it into Caller's R0 (msb)
       JNE  SETEQ                   If it's not zero, set EQ bit
       COC  @GSTAT,R12              Else, test CND bit for Link Error (00)
       JNE  DSREND                  No Error, Just return
SETEQ  SOCB R12,R15                 Error, so set Caller's EQ bit
DSREND RTWP                         All Done - Return to Caller

 

 

...lee

Edited by Lee Stewart
RESOLVED REFERENCES IN CODE SNIPPET...
  • Like 2

Share this post


Link to post
Share on other sites

Just in case anyone is interested, in a few minutes, I will edit the MG code snippet I posted above to resolve references. For fbForth 2.0, that code is copied from ROM to low expansion RAM at startup.

 

...lee

  • Like 2

Share this post


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

Just in case anyone is interested, in a few minutes, I will edit the MG code snippet I posted above to resolve references. For fbForth 2.0, that code is copied from ROM to low expansion RAM at startup.

 

...lee

Thanks Lee! Need to take a look at this, but not now as it is late here where I live.


And thanks to all the other responses by others as well! It is a shame that TI left this half baked on their part. Not that I like GPL, but it is part of what makes the 99/4A what it is, part of it’s character. One more thing to fix if we ever get to building the TI-99/4A Next 🙂

 

Share this post


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

It's because it returns into GPL. It would have been so easy for TI to do it properly, but no.

Thanks. Things like these make this machine hard to understand. Unnecessary one way streets.

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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...