Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/18/20 in all areas

  1. I couldn't find any resources on how to create and change directories on the SD card using assembly, so I wrote some helper functions based off the code in "x16-rom/basic/x16additions.s". These functions show how to use the KERNAL API to send commands and get file/directory names from CMDR-DOS. I wrote the functions to be simple, so error & SD card checking will be left up to the reader. The code itself was written using the ACME assembler, but it should be easy to convert it to other assemblers. Code: https://gist.github.com/DavidSM64/a036a622f4b7a2d8364c355e72766eb7 The 3 functions are: execute_dos_command Takes in a string pointer that contains a channel 15 command and executes it. A table of commands can be found here: https://github.com/commanderx16/x16-rom/tree/master/dos (It is the large table that starts with "BLOCK-ALLOCATE") Examples: "MD:FOO" = Creates a new directory called FOO "CD:FOO" = Enters the FOO directory "CD:.." = Enters the parent directory "RD:FOO" = Deletes the FOO directory get_dos_directory Takes in a string pointer that contains valid directory syntax (see examples), the length of that input string, and an output pointer where the result will be written to. This function isn't particularly useful, since it also outputs the formatting used in BASIC. Examples: "$" = List out everything in the current directory "$:*=P" = Only list out files "$:*=D" = Only list out directories "$:FOO*=D" = Only list out directories that start with FOO (FOO, FOO2, FOOBAR, etc.) The output will look like this: The first 4 bytes can be ignored For each line: 2 bytes at the start for the block count Then follows a certain number of bytes (might be a variable amount, the line ends with $00) get_dos_dir_entries Same inputs as get_dos_directory This function only outputs the file / directory names, separated by a $00. Returns the number of entries in the current directory into the accumulator. The output will look like this: This will not show the file type, but files typically have an extension while directories do not.
    2 points
  2. I can vouch for Bloodstained: Ritual of the Night. I know some people were put off by the odd-looking 3D, but honestly I got used to it after about 20 minutes, and the game is a blast. Castle-not-legally-Vania is fun to explore and the level design and enemy placement are excellent and encourage creative use of the different weapon types. And, of interest in this forum, their little retro game Bloodstained: Curse of the Moon was surprisingly well put together as well. Retro fans should check that out. Would love to see a platformer like that on the X16.
    1 point
  3. I forgot to mention the Kernal function READST in my post from yesterday. To sum it up, this is what I think you should do to handle I/O errors when reading a file: Call SETNAM to set the file name. This function does not throw I/O errors. Call SETLFS to set file no, device no and command. As I understand, neither this function throws I/O errors Call OPEN to open the file Check carry bit, if set there was an I/O error, and the error number is in A register Call READST to get I/O status returned in A register. I not zero, there was an error. This should not happen on opening a file for reading, but could occur in other I/O operations. Call CHKIN to open a channel for input Check carry bit, as after calling OPEN Call READST as after calling OPEN Call CHRIN to read one character from the device Carry set does not indicate error after calling this function Call READST after every invocation to get I/O status returned in A register. It not zero there was an error or you reached end of file Call CHRIN in a loop until READST returns end of file or an error My experience is that the above mentioned Kernal errors only occur if there is a problem communicating with the device. For instance Kernal I/O error no 5 - Device not present - will be thrown if a SD card is not mounted. But the Kernal will say nothing if the error occurs on what used to be the disk drive side in the old days. For example, a file not found error must be checked by reading the disk status. So the last step is to do that, which requires opening another I/O channel: Call SETNAM (name may be empty) Call SETLFS (like OPEN 15,8,15) Call OPEN. Check carry bit and READST for errors as above Call CHKIN to open channel for input. Check carry bit and READST for errors as above Call CHRIN to read status string Call READST and loop back and call CHRIN until READST returns end of file or an error There are small variances on how to handle errors depending on the type of I/O channel, for instance if it's a RS232 channel instead of a disk file. One good source for the functioning of the Kernal is here: https://www.pagetable.com/c64ref/kernal/ It puts the comments on each Kernal function from a handful different books, including the C64 PRG, side by side. Or in more simple terms. Use the Kernal functions. Even if you find some memory addresses that return the I/O status they might be subject to change.
    1 point
×
×
  • Create New...

Important Information

Please review our Terms of Use