In my last post, I discussed how I used Metal to render the PET screen instead of the higher level Cocoa APIs. I did the minimal amount of work to make the changes, so the program actually worked very inefficiently.
The 6502 has no separate IO space so all peripheral control registers are mapped into the main memory. In my emulation, when the CPU reads or writes memory there is a hook that a device can register for that means the device is called just before a read or just after a write. This gives the device the opportunity to modify the bytes that the CPU will read for device input registers and it can use the byte written to cause the device mapped to perform some action. In the case of the screen, the write hook was implemented to write the byte written into a separate array that the VDU controller would use to tell the renderer (Metal or Cocoa) what to render at each pixel. This works pretty well, but it can add quite a large overhead to writing a byte to the screen memory.
Now I’ve changed the code so that the CPU copies the screen memory directly into the Metal buffer. By itself, this does not make much difference, but it means I can delete the device memory mapping for the screen. The overall speed gain in a graphics intensive application is about 12% in a release build.
Unfortunately, I am now seeing some artefacts on the PET display. If you watch the recording above, you’ll see that, occasionally there is a line of @
s at the bottom of the screen. This is caused by the way the PET scrolls the screen, it moves each line up by 40 bytes and then sets the bottom line to spaces. If the bottom line was zeros, it displays the @
character because that is character 0 in PET display characters. I think I can solve this by properly syncing the render.
As an aside, the program executing above is this:
10 x = 0 20 print x 30 x = x + 1 40 goto 20
The code is here.