ralphb Posted April 14, 2019 Share Posted April 14, 2019 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? 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted April 14, 2019 Share Posted April 14, 2019 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 1 Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 14, 2019 Author Share Posted April 14, 2019 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. Quote Link to comment Share on other sites More sharing options...
F.G. Kaal Posted April 14, 2019 Share Posted April 14, 2019 (edited) 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 April 14, 2019 by F.G. Kaal Quote Link to comment Share on other sites More sharing options...
F.G. Kaal Posted April 14, 2019 Share Posted April 14, 2019 (edited) 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 April 14, 2019 by F.G. Kaal Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 14, 2019 Author Share Posted April 14, 2019 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. Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 14, 2019 Author Share Posted April 14, 2019 Sorry, I also have to unlike the first example, since it's also just a DSRLNK call in a roundabout way. Quote Link to comment Share on other sites More sharing options...
F.G. Kaal Posted April 14, 2019 Share Posted April 14, 2019 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 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted April 14, 2019 Share Posted April 14, 2019 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 1 Quote Link to comment Share on other sites More sharing options...
F.G. Kaal Posted April 14, 2019 Share Posted April 14, 2019 (edited) 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 fdsr4w.a99 Edited April 14, 2019 by F.G. Kaal Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 14, 2019 Author Share Posted April 14, 2019 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 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. Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 14, 2019 Author Share Posted April 14, 2019 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. Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 14, 2019 Author Share Posted April 14, 2019 (edited) 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 April 14, 2019 by ralphb Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted April 14, 2019 Share Posted April 14, 2019 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@ 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted April 14, 2019 Share Posted April 14, 2019 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 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted April 14, 2019 Share Posted April 14, 2019 RXB 2019 has CALL FILES(0) and up to CALL FILES(16) https://www.youtube.com/watch?v=vCeqV5TpE24 Quote Link to comment Share on other sites More sharing options...
Tursi Posted April 15, 2019 Share Posted April 15, 2019 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. 1 Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 15, 2019 Author Share Posted April 15, 2019 Thanks for all the info. 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. 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. Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 15, 2019 Author Share Posted April 15, 2019 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). 2 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted April 15, 2019 Share Posted April 15, 2019 Well, better be cautious now than sorry later. (Sounds like a typical German thing, but I hope that is just common sense. ) 1 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted April 15, 2019 Share Posted April 15, 2019 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@ 3 Quote Link to comment Share on other sites More sharing options...
Tursi Posted April 15, 2019 Share Posted April 15, 2019 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. 1 Quote Link to comment Share on other sites More sharing options...
ralphb Posted April 16, 2019 Author Share Posted April 16, 2019 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 ... 2 Quote Link to comment Share on other sites More sharing options...
Tursi Posted April 16, 2019 Share Posted April 16, 2019 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. 3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.