Wednesday 19 December 2018

Apple /// Drivers, and a new way of cross compiling them

This is a bit of a long lead in story, its been awhile since I have done a blog update..

It started out when I was thinking about the Apple /// bootup and wondering about a small file selector that could be used, something like Selector ///. I had some ideas that if we had a tiny one like ProDOS Bitsy Bye, then maybe we could build that into SOS. I don't think the source code is released yet for Bitsy Bye, maybe in the future it looks like this will happen. I did some looking around and came across a ProDOS one called Squirt.

I then started to 'port' this over to SOS for fun. One bigger change was the move for the screen output from  direct video memory manipulation and A2 rom calls to using the SOS .CONSOLE driver. Like everything, its always a lot more work. The other part was mapping the ProDOS calls to SOS calls. These have some differences, more than I was expecting as ProDOS's calls are based on the SOS calls. It has a lot more to go, so not much use yet. You can view volumes online, navigate folders, and view text files. I was next going to add viewing A3 fonts, and that's when the story runs off on a tangent...

I thought I would use the .GRAFIX driver for the graphics output. Well, this had me stuck. I kept getting a device error ($30) back when ever I tried to send commands to it. I can open the .GRAFIX driver ok, but nothing more. I spent quite some time searching for info on what this error might be, and trying other things. There is an invokable module called bgraf.inv that works fine with the .GRAFIX driver. I did a test in Business Basic with this and all works as expected. So it must be possible to get it to work.

After some searching through the aIII wap dvd again, I found some very useful driver disassemblies in the 3's company BBS files. In there was one for the .GRAFIX driver. This has some clues, it seems there is some SOS global flag for memory allocation that the .GRAFIX driver uses, but this needs to be set by the calling program. I still have not got back to this, but this seems the main reason it was not working.

I have put up a disk image and the current source code for Squirt3 on github here:
 robjustice/Squirt3
For anyone interested to have a look. I'm not sure when I will put some more time into this, but it was a great learning exercise with what I have done so far.

Somehow while looking at the .GRAFIX driver source, I rekindled an old thought on trying to get a relocatable file format converted for use as a Apple /// driver, to help with cross platform development. I had come across the o65 file format and this looked like a possibility, and the ca65 assembler supports this. I have been trying to learn Python more, so this looked like a good fit. I had also helped with some debugging of the Driv3rs program, and this also helped understand the driver file format. (thanks Guys)

The o65 file includes the code and relocation information to allow the file to be loaded and relocated, similar to the PCD file that the Pascal assembler creates. The Apple 3 System Utilities SCP program takes the PCD files and converts these to a raw format. The SOS 1.3 source code contains in file SOSLDR.C.SRC.TEXT a brief note on this:
                           
  * SOS.DRIVER FILE FORMAT
  *
  *  (8)  LABEL
  *         = "SOS DRVR"
  *
  *  (2)  HEADER COUNT
  *         = # OF FLOPPY DRIVES
  *         = CHARACTER SET TABLE
  *         = KEYBOARD TABLE
  *       ...
  *                                                 +---------------------------------------+
  *  (2)  DM #N TITLE COUNT  <---+                  !       RELOCATION FIELD FORMAT         !
  *             TITLE FIELD      !                  !       -----------------------         !
  *  (2)     DM #N CODE  COUNT   ! DRIVER MODULE #N ! CONSISTS OF A LIST OF 2 BYTE POINTERS !
  *             CODE  FIELD      !                  ! WHICH POINT TO THE LOW BYTE OF A TWO  !
  *  (2)     DM #N RELOC COUNT   !                  ! BYTE QUANTITY TO BE RELOCATED.        !
  *             RELOC FIELD  <---+                  +---------------------------------------+
  *       ...
  *
  *       $FFFF = THE END


Explaining this a little more, for each of the drivers, they have the following:
  word - length of the comment
  bytes - comment
  word - length of the code
  bytes - code
  word - length of the relocation table
  bytes - list of addresses that need relocating

The program I have written decodes the input o65 file and converts it to this Apple3 driver format consisting of the three parts.

The latest version of the program is available here:
 robjustice/a3driverutil

There is some more detail in the readme there of the various functions available and how to run it. I have added a few more than I initially thought, so it has a bit of SCP functions in there now to add/list/extract drivers.

This allows a driver to be assembled with the ca65 assembler and then added or updated to a SOS.DRIVER file. With the use of a disk image util, then this process can be automated in a script to allow one command to do driver assembly, updating in a SOS.DRIVER file and launching in an emulator.

One other function it includes that I wanted to talk about here, is extracting a driver from a SOS.DRIVER file. I have done some disassembly of a few drivers and wanted a nice easy way to get the code out. While doing this I found that without 'relocating' the code, the origin of the code is address 0000. I found that this causes confusion with zero page locations and instructions when disassembling. To get around this, I have added the option of extracting and relocating the code to base address $2000.

hope you enjoy this.