Jump to content

Photo

CALL FILES/subprogram >16 code

DSR

23 replies to this topic

#1 ralphb OFFLINE  

ralphb

    Dragonstomper

  • 654 posts
  • Location:Germany

Posted Sun Apr 14, 2019 3:16 AM

Does anybody have an implementation for CALL FILES/subprogram >16?

 

From my understanding of BASIC, I assume that this routine decreases or increases >8370 (by >26x bytes?), updates the PAB links, and possibly sets some additional values.  I've looked at the TI Floppy Disk controller code for CALL FILES, but the code is really spread around and uses general purpose functions that obscure what really needs to be done.

 

Now before I embark on re-creating this on my own, are there already implementations for this?

 



#2 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,966 posts
  • Location:Silver Run, Maryland

Posted Sun Apr 14, 2019 5:46 AM

Does anybody have an implementation for CALL FILES/subprogram >16?

 

From my understanding of BASIC, I assume that this routine decreases or increases >8370 (by >26x bytes?), updates the PAB links, and possibly sets some additional values.  I've looked at the TI Floppy Disk controller code for CALL FILES, but the code is really spread around and uses general purpose functions that obscure what really needs to be done.

 

Now before I embark on re-creating this on my own, are there already implementations for this?

 

I am not sure what exactly you are trying to do, but subprogram >16 for the TI disk controller (and all others that strictly adhere to its example) reserves >206 (51810) bytes in upper VRAM for space for each additional file you anticipate adding to the maximum number of files that can be open simultaneously.  The DSR (not Basic) updates >8370 as necessary.  This is a DSR function that works the same regardless of the programming language that calls it.  To my knowledge, TI Basic implementations do not do anything with PAB links until a file is actually opened.  Pointers affecting available memory in VRAM for Basic are surely updated, but I do not think additional space is reserved until files are actually opened.

 

...lee



#3 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Sun Apr 14, 2019 5:57 AM

Thanks Lee, I do need this for SDD 99.  I'm not necessarily looking for code, a description is fine.

 

But looking at the CALL FILES code of the TI disk controller, it seems that updating >8370 is not enough.  I think it also extends (or shrinks) the linked list of the BASIC PABs, and maybe updates pointers in the scratchpad RAM, as you wrote.  For example, I would assume that there is a pointer to the first PAB somewhere.

 

But as I said, I don't know everything that needs to be done.  



#4 F.G. Kaal ONLINE  

F.G. Kaal

    Star Raider

  • 50 posts

Posted Sun Apr 14, 2019 6:49 AM

I use this code in DM2K to do a (call) FILES(1). It looks like a lot but it is assembler code to be used with the C99 compiler from C. Pulley. You don't need everything but this is the idea.

 

Fred

PABL2  EQU >1580
SAVEG  BSS  2
PABCOD BSS  2
PABCD2 BSS  2
CRUSRC BSS  2
CRUDST BSS  2
THSCRU BSS  2
LSTCRU BSS  2

* files(nof) int nof;
* - allocate bufferspace for number of files
* nof: number of files 1-16
* if error returns -1
*
FILES  MOV  @2(14),0     Get nof
       SWPB 0
       MOV  0,@H834C
       CLR  @PABCOD
       CLR  0
       CLR  7
       LI   8,>0116      CALL FILES() opcode
       JMP  FMT#2        Search all DSR's

* fmtdsk(device, mode, sides, tracks, density, interleave)
* char *device; int  mode, sides, tracks, density, interleave;
* - format a floppy disk
*
* device:  devicenam e.g. "DSK1"
* mode  :  search mode   0= search all DSR's
*                       >0= CRUSRC contains CRU address
* sides :  number of sides 0,1= single 2=double sided
* tracks:  number of tracks 40 or 80
* density: disk density 0,1 single density FM  125Kbits/sec
*                       2   double density MFM 250Kbits/sec
*                       3   double density MFM 500Kbits/sec
* interleave: 1..sectors-1
*             default 4 for single density, 5 for double density
*
* returns: @>8350 number of sectors per disk
*
FMTDSK BL   @GETU#C
       LI   8,FORFD      Format FD
       CLR  0            Number of sectors
       MOV  0,@>834A
       LI   0,BUFL2      VDP buffer
       MOV  0,@H834E
       MOV  @8(14),0     Sides
       SWPB 0
       MOVB 0,@H8351
       MOV  @6(14),7     Tracks
       MOV  @2(14),0     Interleave
       SLA  0,2
       A    @4(14),0     Density
       MOV  @10(14),2    Search mode?
       JEQ  FMT#2        All DSR's
*
* differences in Dm2k and Du2k
* Du2k allready knows CRU address by calling FCRU
* Dm2k doesn't know CRU address and must search
*
FMT#1  MOV  @CRUSRC,@THSCRU      after fcru()
       MOV  @CRUSRC,@LSTCRU
       JMP  FMT#3
FMT#2  MOV  @FMTCRU+0,@THSCRU    search all DSR's
       MOV  @FMTCRU+2,@LSTCRU
FMT#3  BL   @L2BUF1
       MOV  @>83D0,@THSCRU
       MOV  @>83D0,@LSTCRU
       B    *13

* Base Level1 routines
*
* L2BUF0,L2BUF1,L2BUF2
*
* Input : R8 Level1 routine code
*         R7 Byte for @>834D
*         R0 Byte for @>8350
* Output: -
* Uses  : R0,R1,R2,R8

L2BUF0 CLR  0           Error code/Aditional info
L2BUF1 SWPB 0
       MOVB 0,@H8350
L2BUF2 SWPB 7
       MOVB 7,@H834D    Code/Tracks
       MOVB @GRMRA,@SAVEG
       NOP
       MOVB @GRMRA,@SAVEG+1
       DEC  @SAVEG
       A    8,@PABCOD   Add L2 function code
       LI   0,PABL2     VDP pab
       LI   1,PABCOD    L2 code
       LI   2,2
       BLWP @VMBW
L0X    LI   0,PABL2     VDP pab
       MOV  0,@>8356
L2BUF3 LI   1,H834C
       LI   2,>834C
       MOV  *1+,*2+
       MOV  *1+,*2+
       MOV  *1+,*2+
       MOV  *1,*2
       BLWP @DSRL10
       DATA 10
**     JEQ  L4X          Error: Bad name and bad idea (05/07/2007)
**			 because Dm2k can now do setpath for DSKx
**			 and is it conform TI spec?
       MOVB @>8350,8     Error code
       SRL  8,8
       CI   8,>30
       JEQ  L4X          not altered
       CI   8,7          SCSI
       JLE  L1X          yes
       SRL  8,5
L1X    CI   8,6          Err 6,7
       JNE  L2X          No
       C    @THSCRU,@LSTCRU
       JEQ  L2X          check one controller
       MOV  @CRULST,2    CRU address
       CI   2,>1100      TI-controller
       JEQ  L0X          Yes
L2X    MOV  8,@ERRNO
       JEQ  L7X
L4X    SETO 8            Error
L7X    MOVB @SAVEG,@GRMWA
       NOP
       MOVB @SAVEG+1,@GRMWA
       MOV  8,8
       JNE  L8X
       B    *11
L8X    B    *13


* T-SHELL SOURCE CODE BY TRAVIS WATFORD
* excerpt taken by B. Harrison - MODIFIED
*                  F.G.Kaal - MODIFIED
*----------------------------------------
*  Device service routine for DATA >000A
*
DSRL10 DATA DSRWS,DSR#10
DSRWS  BSS  32
DSRWS5 EQU  DSRWS+10

H834C  BYTE 0   Buffer for ram locations
H834D  BYTE 0
H834E  BYTE 0
H834F  BYTE 0
H8350  BYTE 0
H8351  BYTE 0
H8352  BYTE 0
H8353  BYTE 0

NPNTR  EQU  >8356
NLEN   EQU  >8354
CRULST EQU  >83D0
SAVADD EQU  >83D2
VDPWA  EQU  >8C02
VDPRD  EQU  >8800
H20    BYTE >20
HAA    BYTE >AA
       EVEN
DSR#10 MOV  *R14+,R5     Get DSR offset (>A)
       SZCB @H20,R15
       LI   R4,1         Pabcod is >01xx
DSR2   MOV  R4,@NLEN     Save name length
       INC  R4
       A    R4,@NPNTR    Adjust name pointer
       LWPI GPLWS
       CLR  R1           Dsr version etc
       MOV  @THSCRU,R12  This Cru

CRUOK  MOV  R12,@CRULST  Save cru address
       SBO  0            Card on
       LI   R2,>4000     See if a card is present
       CB   *R2,@HAA
       JNE  DSR8A
DSR4B  A    @DSRWS5,R2   Add DSR offset
       JMP  DSR5
DSR4   MOV  @SAVADD,R2   Get DSR routine address
DSR5   MOV  *R2,R2       Any routines?
       JEQ  DSR8A        No
       MOV  R2,@SAVADD   Save link to next DSR routine address
       INCT R2
       MOV  *R2+,R9      Get DSR routine address
       LI   R5,PABCOD    The DSR code
       CB   *R5+,*R2+    Name length matches
       JNE  DSR4         No
       CB   *R5+,*R2+    DSR code matches
       JNE  DSR4         No
DSR7   INC  R1           Next version
       BL   *R9          Call DSR routine
       JMP  DSR4         Error? Try next
       SBZ  0            Card off
       LWPI DSRWS
       RTWP

DSR8A  SBZ  0            Card off
       AI   R12,>0100    Next
       C    R12,@LSTCRU
       JL   CRUOK
DSR8   LWPI DSRWS
DSR9   CLR  R1           Error 0=bad name
       MOVB R1,*R13      Error code to R0 of calling program
       SOCB @H20,R15     Set equal bit for error
       RTWP



Edited by F.G. Kaal, Sun Apr 14, 2019 7:03 AM.


#5 F.G. Kaal ONLINE  

F.G. Kaal

    Star Raider

  • 50 posts

Posted Sun Apr 14, 2019 7:05 AM

And to keep it short it can be done like this (I leaf the optimisation to you):

PABL2  EQU >1580              Level2 PAB in VDP RAM

NOF    DATA 1                 Number of files 1-16
PABCOD DATA >0116
SAVEG  BSS  2

FILES  MOV  @NOF,R0	      Number of files
       SWPB R0
       MOVB R0,@>834C         Number of files
       SWPB R0
       MOVB R0,@>834D         Must be 0
       MOVB R0,@>8350         DSR Returned error code

       MOVB @GRMRA,@SAVEG     Save GROM address
       NOP
       MOVB @GRMRA,@SAVEG+1
       DEC  @SAVEG

       LI   R0,PABL2          VDP pab
       LI   R1,PABCOD         L2 code
       LI   R2,2
       BLWP @VMBW
       
       LI   R0,PABL2          VDP pab
       MOV  R0,@>8356

       BLWP @DSRLNK
       DATA 10

       MOVB @>8350,8          Get Error code
       etc etc


       MOVB @SAVEG,@GRMWA     Restore GROM address
       NOP
       MOVB @SAVEG+1,@GRMWA


Fred ;-)


Edited by F.G. Kaal, Sun Apr 14, 2019 7:09 AM.


#6 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Sun Apr 14, 2019 7:10 AM

Thanks, but the second program won't do, because there is no DSR.  In fact, I'm trying to put together a DSR and CALL FILES should be part of it.  :)



#7 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Sun Apr 14, 2019 7:13 AM

Sorry, I also have to unlike the first example, since it's also just a DSRLNK call in a roundabout way.  ;)



#8 F.G. Kaal ONLINE  

F.G. Kaal

    Star Raider

  • 50 posts

Posted Sun Apr 14, 2019 7:14 AM

Thanks, but the second program won't do, because there is no DSR.  In fact, I'm trying to put together a DSR and CALL FILES should be part of it.  :)

 

After I had read your question again a few seconds ago I uderstand what you are looking for and this is not it,  sorry my mistake. You need the implementation of CALL FILES itself. I had the same problem with my facke DSR in my TI994w emulator. The best thing I could come up with was to add bits and pieces of the TI diskcontroller DSR to make it work.

 

Fred



#9 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,966 posts
  • Location:Silver Run, Maryland

Posted Sun Apr 14, 2019 7:21 AM

Thanks, but the second program won't do, because there is no DSR.  In fact, I'm trying to put together a DSR and CALL FILES should be part of it.  :)

 

I do not mean to strain at gnats here, but the DSR knows nothing about Basic.  Anything done to the PAB chain or pointers needed by Basic are handled by Basic’s CALL FILES() function, not the DSR.  CALL FILES() ultimately calls DSR subprogram >16, but it does other things that the DSR does not.  Perhaps the attached documents will help.  I think I retrieved them from WHTech’s site:

 

Attached File  TI99 TI Software Specs for Disk Peripheral.pdf   754KB   2 downloads Attached File  TI99 TI GPL Interface Specs for Disk Peripheral_+_Functional Specs.pdf   750.22KB   3 downloads

 

...lee



#10 F.G. Kaal ONLINE  

F.G. Kaal

    Star Raider

  • 50 posts

Posted Sun Apr 14, 2019 7:22 AM

Does it help if I supply the code I use in my Ti994w emulator? Only the nescesarry FILES stuf is used. It is from the documented DSR code from T. Nouspickel's website btw.

 

Fred ;-)

Attached Files


Edited by F.G. Kaal, Sun Apr 14, 2019 7:24 AM.


#11 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Sun Apr 14, 2019 8:01 AM

I do not mean to strain at gnats here, but the DSR knows nothing about Basic.  Anything done to the PAB chain or pointers needed by Basic are handled by Basic’s CALL FILES() function, not the DSR.  CALL FILES() ultimately calls DSR subprogram >16, but it does other things that the DSR does not.  Perhaps the attached documents will help.  I think I retrieved them from WHTech’s site:

 

attachicon.gifTI99 TI Software Specs for Disk Peripheral.pdf attachicon.gifTI99 TI GPL Interface Specs for Disk Peripheral_+_Functional Specs.pdf

 

...lee

 

Sorry, I didn't know there's much of a difference between both functions.  These documents are exactly what I've been missing!   :)   I think I should be able to write something, although it's not 100 percent clear to me yet where to draw the boundary between FILES and >16.



#12 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Sun Apr 14, 2019 8:06 AM

Does it help if I supply the code I use in my Ti994w emulator?

 

Thanks Fred, that looks very much like the TIFC disassembly from Thierry.  I already have this, but I'm too obtuse/impatient to understand this. 

 

But thanks for removing the fat from that code, I may have to make use of it.



#13 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Sun Apr 14, 2019 9:21 AM

Lee, I wrote some code for updating the file buffers at the top of the VDP RAM that I erroneously called PABs.  But now where are these "linked PABs" of BASIC that >833C should point to?  That address contains 0 after entering BASIC.  EDIT: Is the OPEN command in the DSR handling this?

 

I also had another look at the TIFC, and for that device at least >16 and FILES are identical in function.


Edited by ralphb, Sun Apr 14, 2019 9:22 AM.


#14 jedimatt42 OFFLINE  

jedimatt42

    Stargunner

  • 1,964 posts
  • Location:Beaverton, OR

Posted Sun Apr 14, 2019 12:08 PM

Here is how I implemented it: 

 

CALL FILES:

https://github.com/j...r/basic.a99#L68

 

CALL >16:

https://github.com/j...level2.a99#L283

 

I recall it being very much the same, except that for CALL FILES the buffer count comes from parsing command line arguments from VDP RAM, and >16 expects parameters stuffed into scratchpad

 

-M@



#15 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,966 posts
  • Location:Silver Run, Maryland

Posted Sun Apr 14, 2019 1:09 PM

Lee, I wrote some code for updating the file buffers at the top of the VDP RAM that I erroneously called PABs.  But now where are these "linked PABs" of BASIC that >833C should point to?  That address contains 0 after entering BASIC.  EDIT: Is the OPEN command in the DSR handling this?

 

I also had another look at the TIFC, and for that device at least >16 and FILES are identical in function.

 

Again, the DSR knows nothing about a linked PAB list.  The PAB that TIB or XB sets up for a given file has all the information the DSR needs for OPEN or any other file-dependent opcode.

 

When TIB or XB start up, there are no PABs, so >833C contains 0, signalling that such is the case.  This (0) is the same value as contained in the list-link-pointer address (first two bytes) of the last PAB in the chain, signalling the end of the chain.  The PAB chain starts after the space allotted to the Value Stack, whose base pointer is >8324 and top-of-stack pointer is >836E.  TIB and XB probably have a hard-coded start address for the start of the PAB list.  On page 302 of the E/A Manual, there is a suggestion that this address for TIB is >0FAB.  Based on the different sizes of the first two PABs, I would guess TIB and XB reserve space for a file’s data buffer immediately following its PAB.

 

...lee



#16 RXB OFFLINE  

RXB

    River Patroller

  • 3,583 posts
  • Location:Vancouver, Washington, USA

Posted Sun Apr 14, 2019 3:46 PM

RXB 2019 has CALL FILES(0) and up to CALL FILES(16)

 

https://www.youtube....h?v=vCeqV5TpE24



#17 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,638 posts
  • HarmlessLion
  • Location:BUR

Posted Sun Apr 14, 2019 10:30 PM

CALL FILES only exists for the benefit of the DSR... if you don't have a DSR, why do you care about CALL FILES?

Classic99 does a bare bones implementation solely for the sake of compatibility with programs that expect the TI disk controller, maybe that's what you are asking for?

In that case, it does the following:

First, it calculates a new top of video RAM. There are 518 bytes per buffer requested, a base starting point of 0x3DEF (below the disk controller's own management structure), and 5 more bytes for a small header. Then, subtract one more because it's the last free byte stored, not the byte above it.

So, in short: newTop = 0x3DEF - (n * 518) - 6
Write newTop to scratchpad at 0x8370

After that, it creates a new disk buffer header starting at newTop+1:
		VDP[++nNewTop] = 0xaa;		// valid header
		VDP[++nNewTop] = 0x3f;		// top of VRAM, MSB
		VDP[++nNewTop] = 0xff;		// top of VRAM, LSB (TODO: CF7 will change top of VRAM value by 6 bytes)
		VDP[++nNewTop] = 0x11;		// CRU of this disk controller
		VDP[++nNewTop] = n;		// number of files
That's enough to be compatible with most software, and it's all that CALL FILES itself does. Classic99 itself doesn't use the reserved space for anything, mind...

This header is used for searching VRAM for the correct disk controller's buffer block, if multiple controllers are installed. ISTR most add-on controllers end up using the TI disk controllers buffers rather than reserving more blocks, though.
  • RXB likes this

#18 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Mon Apr 15, 2019 1:12 AM

Thanks for all the info.  :thumbsup:   I knew about the 518 bytes part (although I couldn't remember the number), but not the 6 bytes before the whole thing.

 

I wrote my own code now, and in fact I found an earlier attempt to convert the TIFC functions to SDD99 again.  The TIFC code isn't actually complicated at all, with the exception of their function to read and write VDP memory.

 

The linked DSR thing was once and for all cleared up by Lee.  :idea:

 

And yes, I do have a DSR for which I need CALL FILES, but I cannot simply call another DSR with DSRLNK as a shortcut.  :)



#19 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Mon Apr 15, 2019 12:12 PM

It seems that I was too hasty: Based on my tests, it appears that those buffers are used only by the TIFC, and not at all by BASIC.  This implies that for SDD99, I need neither buffers nor CALL FILES (except for compatibility, but FILES/>16 will just be a NOP).  :dunce:



#20 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,607 posts
  • Location:Germany

Posted Mon Apr 15, 2019 2:11 PM

Well, better be cautious now than sorry later. (Sounds like a typical German thing, but I hope that is just common sense. ;) )



#21 jedimatt42 OFFLINE  

jedimatt42

    Stargunner

  • 1,964 posts
  • Location:Beaverton, OR

Posted Mon Apr 15, 2019 5:00 PM

I implemented them for TIPI if it is using same crubase as TIFDC, for compatibility reasons. TIPI also has no need to cache a sector in VDP.

We found that the-missing-link complained if the routines couldn't be called. I don't remember if a dummy was sufficient. I think it tested for the expected result.

I haven't heard of anything else that cares.

Someone also fear-mongered having 'disk' with more space than normal. Without these buffers you can load from your device those files that used to only exist on cassette... This could actually be a good thing.

-M@

#22 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,638 posts
  • HarmlessLion
  • Location:BUR

Posted Mon Apr 15, 2019 5:50 PM

Someone also fear-mongered having 'disk' with more space than normal. Without these buffers you can load from your device those files that used to only exist on cassette... This could actually be a good thing.


Classic99 outright ran into it... loading didn't seem like a problem to me, but the issue that finally convinced me to implement the reduced memory size was saving from Extended BASIC. You could end up with PROGRAM images too large to load on a console with disk, even if you had the 32k memory expansion, and someone was actually running into that case.

Of course, you could work around it by just making the program slightly larger, but I wanted Classic99 to be a little kinder than that. ;)

#23 ralphb OFFLINE  

ralphb

    Dragonstomper

  • Topic Starter
  • 654 posts
  • Location:Germany

Posted Tue Apr 16, 2019 12:25 AM

Classic99 outright ran into it... loading didn't seem like a problem to me, but the issue that finally convinced me to implement the reduced memory size was saving from Extended BASIC. You could end up with PROGRAM images too large to load on a console with disk, even if you had the 32k memory expansion, and someone was actually running into that case.

Of course, you could work around it by just making the program slightly larger, but I wanted Classic99 to be a little kinder than that. ;)

 

Oh, I hadn't thought about this case ... But I guess keeping just the buffers equal to a CALL FILES(1) would be safe?  Anyway, I'll put the code back in, also in light of what Matt said ...



#24 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,638 posts
  • HarmlessLion
  • Location:BUR

Posted Tue Apr 16, 2019 12:17 PM

That, or tell people to use RXB, since Rich implemented always saving in the IF254 format for that one. That way VDP memory size doesn't matter.





Also tagged with one or more of these keywords: DSR

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users