Kchula-Rrit Posted May 28, 2020 Share Posted May 28, 2020 I'm trying to use the Level 2 I/O function to get file information, but cannot seem to make it work. Using Thierry Nouspikel's information, I placed the following values in scratch-pad RAM: 0x834C = 2 (DSK2) 0x834D = 0 (Get file info) 0x834E = 0x2000 (filename = TEST;C) 0x8350 = 0x30 (0x8330 for returned info) 0x8356 = 0x2010 (start address for "command") I placed the following in VDP RAM: 0x2000 = 'TEST;C ' 0x2010 = 1 ("Command" length) 0x2011 = 0x14 (Get file info) Here's the code I used. I've fiddled with it, and gotten bleary-eyed from trying to read about how to make this thing work. I assume I'm doing something wrong, but just cannot figure out what. The part between the ellipsis(es) are the code I'm using. ... #asm * Clear STATUS byte. CLR R8 MOVB R8,@>837C * File is in DSK2. LI R8,>200 MOVB R8,@>834C * Zero means "get file info". CLR R8 MOVB R8,@>834D * Copy name to VDP RAM. LI R0,2000 * Save file-name pointer for DSR access. MOV R0,@>834E LI R1,MYNAME * File-name. LI R2,14 * Name length. BLWP @VMBW * Copy "get file info" command to VDP. LI R0,GETNFO LI R1,2010 * Save PAB pointer for DSR access. MOV R1,@>8356 LI R2,2 * "Command" name length. BLWP @VMBW * Place results at 0x8330. * C99 doc said this is unused by C99. LI R8,>30 MOV R8,@8350 * Set return status. 0 = success. SETO @RESULT MOVB @GRMRA,@MYGROM NOP MOVB @GRMRA,@MYGROM+1 DEC @MYGROM * Call DSR. BLWP @DSRLNK DATA 10 * If error, skip next instruction. JEQ ERROR * Call succeeded; set status to 0. INC @RESULT ERROR * Save dsr return code. SRL R0,8 MOV R0,@DSRERR * Restore GROM address. MOVB @MYGROM,@GRMWA NOP MOVB @MYGROM+1,@GRMWA ... * Saved GROM address. MYGROM BSS 2 * Test file. MYNAME BYTE 10 * Name length. * BYTE 6 * Name length. * TEXT 'DSK2.' TEXT 'TEST;C ' TEXT ' ' BYTE 0 EVEN GETNFO BYTE 1 * "name" length. BYTE >14 * "Get file info" routine. ... Any advice would be appreciated. K-R. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 28, 2020 Share Posted May 28, 2020 (edited) 15 hours ago, Kchula-Rrit said: I'm trying to use the Level 2 I/O function to get file information, but cannot seem to make it work. ... Any advice would be appreciated. K-R. I remember working through this quite some time ago. At first glance, it looks like the only thing wrong is the filename pointer. It should be pointing at the filename, not the length byte as with Level 3 access: * Copy name to VDP RAM. LI R0,>2000 <----FORGOT '>' in front of 2000 * Save file-name pointer for DSR access. MOV R0,@>834E LI R1,MYNAME+1 * File-name. <----POINT TO FIRST CHARACTER OF FILENAME LI R2,11 * Name length. <----COPY 10 CHARACTERS + TERMINATING 0 BLWP @VMBW Also, insure that the 11th character is a null (0): * Test file. MYNAME BYTE 10 * Name length. TEXT 'TEST;C ' <----EXACTLY 10 CHARACTERS BYTE 0 EVEN I presume you are using the E/A cartridge’s DSRLNK. If so, I am not sure why you are saving and restoring the GROM location. I guess I should review Thierry’s information. ...lee Edited May 28, 2020 by Lee Stewart code correction 1 Quote Link to comment Share on other sites More sharing options...
GDMike Posted May 28, 2020 Share Posted May 28, 2020 I'm also following this, I think it might help me in the future. Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted May 28, 2020 Share Posted May 28, 2020 Quick glance also. Double check 8350 - I think you need to move a byte to >8350, not a word. LI R8,>3000; MOVB r8,@>8350. * Place results at 0x8330. * C99 doc said this is unused by C99. LI R8,>30 MOV R8,@8350 2 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 28, 2020 Share Posted May 28, 2020 1 hour ago, InsaneMultitasker said: Quick glance also. Double check 8350 - I think you need to move a byte to >8350, not a word. LI R8,>3000; MOVB r8,@>8350. * Place results at 0x8330. * C99 doc said this is unused by C99. LI R8,>30 MOV R8,@8350 Good eye! Sorry, I missed that one. Yes, indeed, that needs to be a byte because it is the low byte of the scratchpad address of the Additional Information block—in this case, >8330. ...lee Quote Link to comment Share on other sites More sharing options...
Kchula-Rrit Posted May 28, 2020 Author Share Posted May 28, 2020 First, thanks for your assistance and the "extra eyeballs". I did the following: Got rid of the length byte on the filename, then set it to ten bytes padded with spaces, with a NULL byte. Changed MOV R8,@8350 to a MOVB. Tried running it with and without saving the GROM address. I did it because Tom Bentley did so in TCIO.C, figuring that he knew more about calling DSRs than I do. Is it plagiarism if you admit it? 8-) I still got all zeroes in my return values. Then, thinking it might be a mismatch between C and assembly (I would not be surprised if it is) I plugged values into the return variables on the assembly side and they printed OK. While I was prettying-up the code to possibly post it, I noticed several places where I forgot to include the ">" to make values hex instead of decimal. One of many bonehead mistakes I seem to make a lot. It still returns all zeroes, but now, after answering "N" to the "re-run C99" prompt, the computer locks up. Last time that happened I "fixed" it by re-formatting the "disk" in the NanoPEB and recompiling. I'll try that tonight. I'm running this with the E/A cartridge, with v5.1 of C99 with a date of 1994. The C part just prints the results. I can post the whole test program, but it's 180 lines. How would I do the scrolling blu-ish window thing that people do for code? K-R. 1 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted May 28, 2020 Share Posted May 28, 2020 In this section, R0 is typically the VDP address and R1 is CPU ram address. Are the two reversed. The address moved to 8356 would be the VDP address now in R0. Also, I believe your address in R1 should be >2010 not 2010, i.e., hex value vs. decimal value. Maybe post your updated code for the group. ------------------------------------------------ * Copy "get file info" command to VDP. LI R0,GETNFO LI R1,2010 * Save PAB pointer for DSR access. MOV R1,@>8356 LI R2,2 * "Command" name length. BLWP @VMBW Edit: similar thing here. * Copy name to VDP RAM. LI R0,2000 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 28, 2020 Share Posted May 28, 2020 1 hour ago, Kchula-Rrit said: I'm running this with the E/A cartridge, with v5.1 of C99 with a date of 1994. The C part just prints the results. I can post the whole test program, but it's 180 lines. How would I do the scrolling blu-ish window thing that people do for code? If you mean what we oldies call a spoiler, I used to use the old BBCs (Bulletin Board Codes), which still seem to work, sort of. What you can do is to choose the spoiler icon (the eye) on the edit menu bar. Then, click inside the window and choose the code icon (“</>”). You can put your code into the window that pops up. That will give the code that folks see a monospaced appearance that preserves all of your proper spacing. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 28, 2020 Share Posted May 28, 2020 Also, as @InsaneMultitasker said, ALL multi-byte reads and writes must have the VRAM address in R0 and the CRAM address in R1. ...lee Quote Link to comment Share on other sites More sharing options...
Kchula-Rrit Posted May 30, 2020 Author Share Posted May 30, 2020 It works! I had the VDP and CPU RAM addresses reversed on the two-byte VMBW, and a few more missing ">"s on constants. If it works, here is the source for my test program. The good stuff is done in the assembly part; the C part is just for pretty-printing the results. /* test.c (TI-name "TEST;C") */ #include "dsk1.stdio;h" /* Definitions. */ #asm REF VMBR,VMBW REF GRMRA,GRMWA REF DSRLNK REF DUMPREGS #endasm int dsknum; /* Disk number. */ int sectr1; /* Sector 1 locatin. */ int filtyp; /* File-type flags. */ int recsec; /* Records-per-sector. */ int eofoff; /* EOF offset. */ int reclen; /* Record length. */ int recrds; /* Record count. */ int result; /* EQ flag after DSR exit. */ int dsrerr; /* DSR error code. */ int my8350; /* Whatever's returned in 0x8350. */ int outfile; /* Output file descriptor. */ extern putline(); /* Send string to file. */ extern dp4(); /* Print value as decimal to file. */ extern xp2(); /* Print 2 hex digits to file. */ extern xp4(); /* Print 4 hex digits to file. */ main () { dsknum = 2; diskinfo (); /* Use C to just print results. */ outfile = fopen ("SIO.BA=9600", "a"); putline ("File name is \"DSK", -1, outfile); dp4 (dsknum, outfile); putline (".", -1, outfile); putline (MYNAME, -1, outfile); putline ("\".\nSector 1 location = ", -1, outfile); xp4 (sectr1, outfile); putline (".\nFile flags = ", -1, outfile); xp2 (filtyp, outfile); putline (".\nRecords-per-sector = ", -1, outfile); xp2 (recsec, outfile); putline (".\nEOF offset = ", -1, outfile); xp2 (eofoff, outfile); putline (".\nRecord length = ", -1, outfile); xp2 (reclen, outfile); putline (".\nRecord count = ", -1, outfile); xp2 (recrds, outfile); putline (".\nDSR \"eq\" bit = ", -1, outfile); dp4 (result, outfile); putline (".\nDSR error = ", -1, outfile); xp2 (dsrerr, outfile); putline (".\nDSR return code = ", -1, outfile); xp2 (my8350, outfile); putline (".\n", -1, outfile); fclose (outfile); exit (0); } diskinfo () { #asm * Save caller's registers. MOV R0,@OLDR0 MOV R1,@OLDR1 MOV R2,@OLDR2 * Clear STATUS byte. CLR R8 MOVB R8,@>837C * File is in DSK2. MOV @DSKNUM,R8 SWPB R8 MOVB R8,@>834C * Zero means "get file info". CLR R8 MOVB R8,@>834D * Copy name to VDP RAM. LI R0,>2000 * Save file-name pointer for DSR access. MOV R0,@>834E LI R1,MYNAME * File-name. LI R2,11 * Name length. BLWP @VMBW * Copy "get file info" command to VDP. LI R0,>2010 LI R1,GETNFO * GETNFO-> 0x0114. * Save PAB pointer for DSR access. MOV R0,@>8356 LI R2,2 * "Command" name length. BLWP @VMBW * Place results at 0x8330. * C99 doc said this is unused by C99. LI R8,>3000 MOVB R8,@>8350 * Set return status. 0 = success. LI R8,1 MOV R8,@RESULT * Call DSR. BLWP @DSRLNK DATA 10 * If error, skip next instruction. JEQ ERROR * Call succeeded; set status to 0. DEC @RESULT ERROR * Save dsr return code. SRL R0,8 MOV R0,@DSRERR * Get first-sector location. MOV @>8332,@SECTR1 * Get file flags. MOVB @>8334,R8 SRL R8,8 MOV R8,@FILTYP * Get records-per-sector. MOVB @>8335,R8 SRL R8,8 MOV R8,@RECSEC * Get EOF offset. MOVB @>8336,R8 SRL R8,8 MOV R8,@EOFOFF * Get record length. MOVB @>8337,R8 SRL R8,8 MOV R8,@RECLEN * Get record count. MOVB @>8338,R8 SRL R8,8 MOV R8,@RECRDS * Get whatever's returned in 0x8350 MOVB @>8350,R8 SRL R8,8 MOV R8,@MY8350 * Restore caller's registers. MOV @OLDR0,R0 MOV @OLDR1,R1 MOV @OLDR2,R2 #endasm return; } #asm EVEN OLDR0 BSS 2 OLDR1 BSS 2 OLDR2 BSS 2 * Saved GROM address. MYGROM BSS 2 * Disk number. MYDISK DATA 2 MYNAME * Test file name. TEXT 'TEST;S ' BYTE 0 GETNFO * "Get file info" Level-2 command. BYTE 1 * "name" length. BYTE >14 * "Get file info" routine. BFRDSR TEXT 'Before dsrlink...' BYTE 0 AFTDSR TEXT 'After dsrlink...' BYTE 0 #endasm The blue-ish scrolling-window thingie works! I made some test runs with various types of files and will put the results in my next post. K-R. 1 Quote Link to comment Share on other sites More sharing options...
Kchula-Rrit Posted May 30, 2020 Author Share Posted May 30, 2020 Okay, the blue-ish thing worked, but the scrolling bit did not. I was hoping to not make the posts so big, but do not seem to have a choice. Anyway, here are the results: [Display/Variable File] File name is "DSK2.TEST;S ". Sector 1 location = 0023. (Not used for file-info command) ** Values here are hex ** These are from Fred Kaal's Web site. File flags = 80. (Bit 0 set = Variable-length records) 0x80 Set = Variable Clear = Fixed 0x08 Set = Protected Clear = Not Protected 0x02 Set = Binary Clear = ASCII 0x01 Set = Program Clear = Data Records-per-sector = 03. (makes sense; int(256 / 3) = 80) EOF offset = 93. (I'll have to trust it.) Record length = 50. (Correct 0x50 = 80 bytes) Record count = 23. (DM2K shows 36 records; count + 1 for heaer) DSR "eq" bit = 1. (DSR "eq" bit set upon return; not sure why) (E/A manual says that I/O sets this bit) DSR error = 01. (Not sure what this is) DSR return code = 00. (MS 3 bits = 0; means "success") [Display/Fixed File] File name is "DSK2.DISKDIR;C ". Sector 1 location = 000F. File flags = 00. Records-per-sector = 02. EOF offset = 00. Record length = 80. Record count = 1E. DSR "eq" bit = 1. DSR error = 02. DSR return code = 00. [Non-existent file.] File name is "DSK2.TEST;Q ". Sector 1 location = 0000. File flags = 00. Records-per-sector = 00. EOF offset = 00. Record length = 00. Record count = 00. DSR "eq" bit = 1. DSR error = 01. DSR return code = E0. [Write-protected file.] File name is "DSK2.DUMPREGS;S". Sector 1 location = 0026. File flags = 88. Records-per-sector = 03. EOF offset = 25. Record length = 50. Record count = 26. DSR "eq" bit = 1. DSR error = 01. DSR return code = 00. [XBASIC File] File name is "DSK3.LOAD-TELCN". Sector 1 location = 0005. File flags = 01. Records-per-sector = 00. EOF offset = 9B. Record length = 00. Record count = 00. DSR "eq" bit = 1. DSR error = 02. DSR return code = 00. [Program File] File name is "DSK3.TELCN ". Sector 1 location = 0001. File flags = 01. Records-per-sector = 00. EOF offset = DA. Record length = 00. Record count = 00. DSR "eq" bit = 1. DSR error = 01. DSR return code = 00. [Length-byte not equal to one] File name is "DSK2.TEST;S ". Sector 1 location = 0000. File flags = 00. Records-per-sector = 00. EOF offset = 00. Record length = 00. Record count = 00. DSR "eq" bit = 1. DSR error = 00. DSR return code = 30. [Non-existent DSR call ("command" = 0x34)] File name is "DSK2.TEST;S ". Sector 1 location = 0000. File flags = 00. Records-per-sector = 00. EOF offset = 00. Record length = 00. Record count = 00. DSR "eq" bit = 1. DSR error = 00. DSR return code = 30. [Non-existent Drive (Disk Number = 4)] Computer locked up. Since the computer locked up when I specified a nonexistent drive, and probably would do so with other errors, I figure I could use the Level-3 DSR call for STATUS (PAB Command 9) first to catch the "egregious" errors and not lock the computer. If the STATUS command works I could then use the Level-2 get-file-info command (0x114) to get further file information to complement what the STATUS command returns. K-R. 2 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.