Jump to content
IGNORED

CALL FILES/subprogram >16 code


ralphb

Recommended Posts

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?

 

  • Like 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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:

 

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

 

...lee

  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

Here is how I implemented it:

 

CALL FILES:

https://github.com/jedimatt42/tipi/blob/aafc1aa3eb549b0484b4b9ec178658b9d5fa6899/hardware/dsr/basic.a99#L68

 

CALL >16:

https://github.com/jedimatt42/tipi/blob/aafc1aa3eb549b0484b4b9ec178658b9d5fa6899/hardware/dsr/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@

  • Like 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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:

  • Like 2
Link to comment
Share on other sites

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@

  • Like 3
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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

  • Like 2
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...