Saturday, April 5, 2014

Progress towards making the 1581 DOS work

Today I have been working on implementing enough of the F011 floppy controller to make the internal DOS work.

The idea is that it will point to a portion of the SD card storage corresponding with a 1581 image.

The floppy controller is reasonably well described in the C65 specifications manual, so a while back I set about implementing most of the registers.

The more recent work has focussed on tying those registers to the existing sd card controller.

First, I added some registers to select the starting sector on the SD card for the 1581 image, and some flags to tell the FDC whether it thinks it has a disk inserted, and whether it is write-protected.  I already knew that the C65 startup checks the disk inserted bit when it decides whether or not to try booting from the floppy drive.

I also implemented an on-screen-display facility for the drive led, so that a square of pixels in the top left of the video display go red if the FDC is active, or blink red if an error has occurred.  This was fairly simple, because the FDC has dedicated LED control bits used by the C65 ROM to turn the drive led on or make it blink, with the same indications as a 1541 disk drive.  This works differently to a real 1581 where the LED interpretation is different.

Here you can see the drive led on-screen display as I cycle it through error indication, on solid for activity, and off a couple of times:


This got me to the point where I could lie to the C65 by making the FDC indicate a disk was present, and see what it did.

It turns out it went into an infinite loop.  Some digging revealed that it was trying to step the head to track 0, and the track0 indicator bit was not being set.  That's not surprising, since I hadn't implemented it.  Here is the relevant bit of code from the C65 ROM.  It uses LSR $D082 to push the TRACK0 flag into the processor's carry flag as an easy way to test the status of this flag:

9B85  A9 10      LDA #$10
9B87  4E 82 D0   LSR $D082                      ;  put bit 0 (TRACK0 flag) of $D082 into C flag
9B8A  B0 05      BCS $9B91
9B8C  20 91 9A   JSR $9A91                      ; Execute FDC command from A, and wait for completion.
9B8F  80 F6      BRA $9B87

9B91  A9 00      LDA #$00
9B93  9D 0F 01   STA $010F,X
9B96  18         CLC 
9B97  60         RTS 

Once that was fixed, it got a bit further, but hit another infinite loop when a sector read succeeded, because the RDREQ bit was not being set to indicate that the sector was successfully read.  Here is the routine.  Basically the ROM checks if the RNF (sector not found) or RDREQ (sector found and read) flags are asserted, and loops otherwise:

; Read a sector?
975B  20 2C 9A   JSR $9A2C                      ; Set FDC track, sector and side register from $1FB4?
975E  B3 12 01   BCS $9872
9761  A9 40      LDA #$40                       ;  command byte: read sector from disk.
9763  8D 81 D0   STA $D081                      ;  FDC Command register
9766  AD 82 D0   LDA $D082                      ;  FDC Status byte 1
9769  29 10      AND #$10
976B  D0 28      BNE $9795                      ;  Take branch and abort if RNF (read not found) bit set
976D  AD 83 D0   LDA $D083                      ;  FDC Status byte 2
9770  10 F4      BPL $9766                      ;  Take branch and keep waiting if sector not yet found (RDREQ bit clear)

This is the sort of thing that comes up when specifications for a system are only mostly incomplete: integration testing is needed to discover and resolve the remaining ambiguities.

What is nice is that the drive light stays on on the screen, so that is working.

I have updated the FDC/sd card controller behaviour to attempt to fix this, by not clearing the RDREQ line after the sector has been read.  The FPGA code is rebuilding, so hopefully it will get a step further tomorrow.  Of course, I still haven't implemented actually reading out the bytes of the sector when they are read, so there will still be more work to do even if this fix is successful.

And that is as far as I have got today.

1 comment:

  1. This comment has been removed by a blog administrator.