2

I wanted to have a calculator program be able to save a set of answers on a floppy disk or tape but I have no idea what I should do.

I am aware that the "cbm.h" library can be used to load and save data but I have no idea how to use the instructions (I can barely code in C as it is).

I honestly have no idea how to go about this and I failed to find any resources about this topic. Any info would help. Thanks!

5
  • 1
    The CC65 library style appears to be to try to provide as much of a POSIX-style interface as possible, within the limitations of the target platform. The C64 port exposes the normal C stdio functions for disk files: open(), read(), etc.
    – RETRAC
    Commented Sep 22, 2022 at 22:14
  • For reading/writing the Commodore specific functions cbm_k_open, cbm_k_setlfs, etc. need to be used. The question is a partial duplicate to How to read disk files using CBM specific functions in cc65 with proper error checking.
    – Raffzahn
    Commented Sep 22, 2022 at 23:32
  • So this is a question about a modern, supported piece of software?
    – Tommy
    Commented Sep 23, 2022 at 13:13
  • @Tommy My reading is that the questioner is seeking to write their own software, to run on old hardware.
    – Kaz
    Commented Sep 25, 2022 at 10:07
  • 1
    @Kaz that may be the motivation, but to my mind there’s no distinction between this question and e.g. asking how to use the debugger in whatever the C64 emulator du jour is.
    – Tommy
    Commented Sep 25, 2022 at 15:51

2 Answers 2

3

Here is an example of using (mostly) the C library functions to write and read data to/from a file. The _filetype is an addition to select the file type. For data storage on the CBM machines, sequential files are common, as in the example:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int main (void) {
  FILE *fp;
  char data_out[] = "This is my data to save.";
  char c;
  
  //Saving
  _filetype = 's';
  if ((fp = fopen ("filename", "w")) == 0) {
    printf ("File could not be opened\n\r");
    exit (1);
  }
  fwrite (data_out, 1, sizeof (data_out), fp);
  fclose (fp);

  //Reading
  _filetype = 's';
  if ((fp = fopen ("filename", "r")) == 0) {
    printf ("File could not be opened\n\r");
    exit (1);
  }

  while (1) {
    c = fgetc (fp);
    if (feof (fp)) {
      break;
    }
    printf ("%c", c);
  }
  fclose (fp);
}

Compile the program with cl65 progname.c -o progname.prg and run it on a C64 with disk drive. It saves the string and then reads it back. Note that this approach links a lot of code to the program, if you want a smaller solution, you should look into directly calling the Kernal functions, see CBM-specific functions in the cc65 documentation.

4
  • You might want to add the way to select a drive.
    – Raffzahn
    Commented Sep 23, 2022 at 13:00
  • Thank you, one question I am left with though is how would I go about generating a file, do I have to create a blank one (if so how?) or does the program do it if there is no file present? Commented Sep 23, 2022 at 14:04
  • 1
    The part marked with "//Saving" generates a file.
    – Peter B.
    Commented Sep 23, 2022 at 14:31
  • 1
    Since Raffzahn made the suggestion to add a way to select a drive - to my knowledge, this cannot be done from C because the current version of cc65 initializes the memory address curunit (current device unit) by first reading address $BA (containing the last used device address) and, if the value is 0, replacing it with 8 as default. After this initialization, there is no C function to overwrite curunit. There is a getter function called getcurrentdevice(), but no respective setter function. So this would require an assembler function being linked to the C program.
    – Peter B.
    Commented Sep 23, 2022 at 18:57
2

The previous answer is probably sufficient. But in case you need more examples, in DestinyHunter I wrote a level-editor that compiled with cc65. The specific source is in: https://github.com/voidstar78/DestinyHunter/blob/main/src/source/editor.c

I didn't do a binary file (could have, but just didn't need to in this application). I used sprintf. But I used a PET2SD card, and it just wrote/read to the root of that card as expected. If I had multiple drives, I'm not sure what else I would have needed to do.

To modify D64 files or extract file content in a way readable under Windows, I used the very excellent utility called DirMaster v3.1.5

Not the answer you're looking for? Browse other questions tagged .