Close

Concurrent bitmap scrolling & disk reads

A project log for Unlimited tile world on a Commodore 64

Unfinished childhood project

lion-mclionheadlion mclionhead 07/20/2024 at 22:570 Comments

The next step was making a scrolling demo which performs sector reads while simultaneously scrolling.

Despite all their busy waits & sleep commands, the LISTEN, UNLSN, CIOUT commands are actually fast enough to run without noticeably affecting scrolling.  The busters are TALK & ACPTR.   Sadly, there is no way to poll the serial port for data like there is for the keyboard. 

For the ACPTR operation, there are notes saying the drive releases CLK at T0 when it's ready to send

https://ia902702.us.archive.org/11/items/Commodore_1541_Troubleshooting_and_Repair_Guide/Commodore_1541_Troubleshooting_and_Repair_Guide.pdf

page 165.  Then the host releases data at T1 when it's ready to receive. The document has a typo: ""clear to send" by releasing the clock line to a logic high" The kernal waits only 256us between T1 & T2 before it times out.

The drive lowers CLK at T2 to send the 1st byte & the host has to be polling to receive it.  There's no more timeout code after T2.  It might be easier with physical hardware to probe.   It big bangs all the serial port reads.  The drive is driving CLK.  The host has to be fast enough to catch the clock transitions.

Profiling the read operation is difficult because the jiffy clock doesn't run during I/O operations & the CIA time of day doesn't seem to work at all in emulation.  An external hardware timer could do the job, but that's another job for physical hardware.  The only way was to setup the only unused CIA timer

    lda #$ff   ; reset CIA 2 timer A
    sta d2t1h
    sta d2t2l  ; reset CIA 2 timer B
    lda #$11
    sta d2cra  ; start timer A
    lda #$51
    sta d2crb  ; run timer B off of timer A

Then extract a 16 bit time value.  It decrements every 256 us.  The value has to be complimented to get a positive number.

    lda #$ff
    sbc d2t1h ; get CIA 2 timer A
    sta dst
    lda #$ff
    sbc d2t2l ; get CIA 2 timer B
    sta dst + 1
    lda #$ff ; reset the clock
    sta d2t1h
    sta d2t2l
    lda #$11
    sta d2cra
    lda #$51
    sta d2crb

 

Some extensive profiling revealed the TALK after sending "u1 2 0 1 0" has the long delay for the sector read.  The TALK takes around .4 seconds in a test of reading multiple tracks.  The trick with profiling is you can't print anything until after all the disk I/O is done, otherwise the LISTEN for printing steps on the TALK for the disk.

After copying bits of kernal source code & bodging in random delays, got it to poll the TALK state while scrolling.  There's no documentation for the TALK operation, but it seems to rely on driving the attention line & waiting for a pulse in the data line.  There's a chance it could miss the data pulse so it has to poll fast enough.  After polling just enough signal transitions, it can call the native TALK function without blocking.  The demo prints the time spent polling the TALK state, the time spent running the actual TALK function, & the time spent reading the 1st byte.

Sadly, scrolling still slows down during the ACPTR operations, even though it's not as bad as a .4 second delay.

Polling the CLK pin before calling ACPTR was useless.  The polling function spins just as long as ACPTR & ACPTR is limited by the baud rate.

A fast loader would speed up ACPTR.  The only other ways are to fix the scrolling frame rate with some kind of timer & spread out the serial port commands.  Experiments with the jiffy clock accuracy during sector reads would be required.  Raster interrupts are unlikely to work with constant I/O.

Depending on how I/O servicing is divided between bitmap operations, the single sector reads are 1.8 seconds at 4fps & 2.4 seconds at 6fps.  Quite a bit slower than the 400 byte/second rating, because of the serial port handshaking, seeking, & multitasking.  Reduce the scrolling speed & the I/O could be concealed.  There could be a case for just letting the scrolling stutter.

Discussions