Close

VIC1541 fast loader

A project log for Unlimited tile world on a Commodore 64

Unfinished childhood project

lion-mclionheadlion mclionhead 07/22/2024 at 17:520 Comments

The biggest need was decidedly speeding up ACPTR.  This entails running a loader inside the 1541 at runtime.  You can't overwrite the 1541 ROM with a shadow RAM like the C64 itself.  You have to upload an executable to RAM & call into the 1541 ROM from it.  The mane problem is the stock fastloaders are very focused on loading a program in 1 shot, blanking the screen & taking full control.  Concurrency would require a scratch built fast loader.

Reviewing the 1541 ROM source code from 50 years ago, it's clear that they were working just as hard as the current generation.  They optimized complex algorithms down to every single byte, writing in unintelligible opcodes.  They didn't have it any easier than the current generation but faced equally difficult problems.  The current problems are the massive size of modern API's, massive numbers of steps required to do the simplest thing.  Each generation worked at the limit of what was possible with a certain amount of capital.  The limiting factor is the amount of human decisions which can be made in a certain amount of time.

The only 1541 source code is a disassembly with absolute addresses:

https://g3sl.github.io/c1541rom.html

The byte for ACPTR is clocked out at 0xe958.  The only delay is 0xe97b, a call to 0xfef3.  The only other delays are many debounce routines.  They had induction problems.  It uses address 0x23 as a speed flag.  Some tests with u+, u-, ui+, ui- didn't do anything useful. 

The most useful resource was this presentation.  The same guy wrote a fast loader using these methods in 2011.  His video was in 2021.

https://www.pagetable.com/?p=568

The FCODE segment runs on the drive.  The PART2 segment runs on the host.  He handles the badlines.  All it does is load a sequence of hard coded sectors & sends them using custom bit banging.  It doesn't use TALK or LISTEN.  It just bit bangs data out of the drive after the OPEN call.  There's no debounce code.  Lions thus need to add a function which bit bangs a track & sector number to the drive & transitions between reading & writing.  The drive would become a simple sector reader.

The mane problem is uploading the program to the drive.  He uses some heroic methods to load the firmware directly from disk to the drive's execution space.  The trick with this is if the world map is a separate disk in a separate drive, it would entail loading a 3rd disk containing the fast loader or using some world space for the fast loader.  The easiest system is to load the firmware from drive 8 & run it in drive 9.

You have to use the M-W command to write drive memory.  page 38

https://www.commodore.ca/wp-content/uploads/2018/11/commodore_vic_1541_floppy_drive_users_manual.pdf

Then you have to use the M-E command to run it.  page 39

He doesn't use the data channel.  All the data is transferred over the control channel.  The port registers have separate out & in bits implying full duplex communication, but the host & the drive share just 1 data & 1 clock line. 

------------------------------------------------------------------------------------------------------------------------------

Debugging 1541 firmware

There's no monitor for the 1541 CPU in VICE.  It's quite difficult with emulation.  At least real hardware could bit bang a UART on the LED & have real serial port lines to probe.

It's well known that 1 peripheral can transmit to another peripheral because they were all daisychained on 1 bus, so practical debugging depends on the 1541 printing to the printer directly. 

--------------------------------------------------------------------------------------------------

For historic re-enactment, there are no more real 1541's.  The heads have all perished.  The SD2IEC dongle doesn't work with a fast loader.  1 current replica is the ultimate II cartridge.

https://ultimate64.com/Main_products

It can run without plugging into a C64.  It doesn't have the internal logic signals but emulates the original ROM.

https://cbm-pi1541.firebaseapp.com/

A much cheaper solution is a raspberry pi 1541 emulator.  This only works on pi's below the 4 but it could be a use for the zillions of zero W's with broken wifi chips.  It requires fabricating a level shifter.  It seems any hardware re-enactment is going to be largely home made.  Since lions only need the I/O port signals, 1 possible future is a C64 emulator on a raspberry pi communicating with all the peripherals on other raspberry pi's through an I/O board.  There should really be microcontroller peripheral emulations.

---------------------------------------------------------------------------------------------------------------------------

Some general traps for young players are: $dd00 is the data port register on the host & $1800 is the data port register on the drive.  The GPIO bits are different bits on each side.

The 1541 user manual specified m-w: as the command but the bios expects it to not have a :.  It stores the command at $0200 & reads the 1st byte of payload from $0205. 

The CLK_OUT, DAT_OUT bits are the inverse of the wire voltage on both sides.  The CLK_IN, DAT_IN are the inverse of the line voltage on the drive & the direct line voltage on the host.

Also noted the originalSteil fast loader doesn't handle TALK/LISTEN anymore.   It takes a 1 way trip to load a program & crash.  It needs major changes to continuously read sector addresses & send data.  Implementing TALK, LISTEN in the fast loader would be really hard so attempt 1 was using ATN to select the peripheral.  Low ATN would communicate with the disk.  High ATN would communicate with the printer.

Debugging using CIOUT should work inside the fastloader since all peripherals share the same serial lines.  Noted CIOUT buffers the argument & sends the previous character.  It flushes the buffer in the TALK/LISTEN command.  This could have been to avoid waiting for the listener to start listening.  Efforts to clone CIOUT in the fastloader didn't work.  A more likely system was bit banging debug text to the host & printing from the host.

--------------------------------------------------------------------------------------------------------------

Helas, after much effort, the new fastloader was erratically crashing or locking up. A verify operation would also randomly lock up, depending on random placement of nops anywhere in & after the end of the mane program.  Printing to the screen or printer made no difference.  Fixing the DATA segment made no difference.  Uploading random data instead of the fastloader failed the same way.  Started noticing behavior like this when simultaneously scrolling & loading sectors.  There seems to be a dependency on program size when sending disk commands from inside the program.  It's been the closest sign so far of an emulator bug, but GEOS & all it's I/O functions still work. 

Lions aren't inclined to burn $500 on a hardware replica to further test the problem.  It's extremely expensive when the same money would buy a 1st rate modern confuser.

Noted after calling LISTEN on the drive, you can still print to the screen by calling CHROUT & write characters to the drive by calling CIOUT.  That narrowed the problem down to just the disk I/O.

Discussions