From 80d7296cabf85779a08a9ae735ea66bc0809e375 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 10 Dec 2019 18:40:26 +0100 Subject: [PATCH] configuration tweaks and documentation updates --- .gitignore | 1 + STATUS.md | 41 ++++++------ bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_mega65.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_mega65.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/newc65.rom | Bin 131072 -> 131072 bytes c64/,,config_ultimate64.s | 2 +- c64/aliases/,aliases_config.s | 14 +++-- c64/kernal/iec_fast/iec_rx_byte_jiffydos.s | 2 +- c64/kernal/iec_fast/jiffydos_bittable.s | 2 +- c64/kernal/iec_fast/jiffydos_detect.s | 2 +- doc/Protocol-JiffyDOS.md | 70 +++++++++++++++++++++ 17 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 doc/Protocol-JiffyDOS.md diff --git a/.gitignore b/.gitignore index 41758c3a..e4515487 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ build/* # Various IDE project files, temporary files, etc. +dump.mem *project .*swp diff --git a/STATUS.md b/STATUS.md index 9f11bc40..110815b5 100644 --- a/STATUS.md +++ b/STATUS.md @@ -42,36 +42,35 @@ The following ROM features are currently missing: ## Keyboard -| Driver | Status | Remarks | -| :-----------------: | :------: | :------------------------------------------------: | -| C64 | DONE | | -| C128 | DONE | | -| C65 / Mega65 | NOT DONE | code should be complete, but is not tested yet | +| Driver | Status | Remarks | +| :-----------: | :------: | :------------------------------------------------: | +| C64 | DONE | | +| C128 | DONE | | +| C65 / Mega65 | NOT DONE | code should be complete, but is not tested yet | ## Tape storage (LOAD only!) -| Driver | Status | Remarks | -| :-----------------: | :------: | :------------------------------------------------: | -| normal | NOT DONE | | -| turbo | PARTIAL | works, to do: use sync to calibrate read speed | +| Driver | Status | Remarks | +| :-----------: | :------: | :------------------------------------------------: | +| normal | NOT DONE | | +| turbo | PARTIAL | works, to do: use sync to calibrate read speed | ## IEC bus (disk drives, etc.) -| Driver | Status | Remarks | -| :-----------------: | :------: | :------------------------------------------------: | -| standard protocol | DONE | | -| JiffyDOS | PARTIAL | not fully tested yet | -| DolphinDOS serial | NOT DONE | | -| DolphinDOS parallel | NOT DONE | | -| CIA burst mod | NOT DONE | | +| Driver | Status | Remarks | +| :-----------: | :------: | :------------------------------------------------: | +| standard | DONE | | +| JiffyDOS | DONE | | +| DolphinDOS | NOT DONE | | +| CIA burst mod | NOT DONE | | ## RS-232 -| Driver | Status | Remarks | -| :-----------------: | :------: | :------------------------------------------------: | -| UP2400 | NOT DONE | | -| UP9600 | NOT DONE | work in progress, not functional yet | -| ACIA 6551 | NOT DONE | | +| Driver | Status | Remarks | +| :-----------: | :------: | :------------------------------------------------: | +| UP2400 | NOT DONE | | +| UP9600 | NOT DONE | work in progress, not functional yet | +| ACIA 6551 | NOT DONE | | # API status diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index f35100af88e2d6c7313311859012e95170594896..a9f1c86991c2c338f5374342a260abfcc2d8ea51 100644 GIT binary patch delta 14 VcmZp0XmHpNE6-$TFgad+Apj(o1i}CS delta 14 VcmZp0XmHpNE6-$LIXPZ_Apj)41j+ya diff --git a/bin/basic_mega65.rom b/bin/basic_mega65.rom index 9a9d73279714d63f6770e646a437fed2d7f34625..7e056475e4e8963856a4ece71e30e717ba32a4ea 100644 GIT binary patch delta 14 VcmZp0XmHpNE6-$TFgad+Apj(o1i}CS delta 14 VcmZp0XmHpNE6-$LIXPZ_Apj)41j+ya diff --git a/bin/basic_testing.rom b/bin/basic_testing.rom index 301bcb53164445d2df007398fcfb7ddc466c14d6..7d402da212eda477ea13273e2fd4f25d77e87050 100644 GIT binary patch delta 14 VcmZp0XmHpNE6-$TFgad+Apj(o1i}CS delta 14 VcmZp0XmHpNE6-$LIXPZ_Apj)41j+ya diff --git a/bin/basic_ultimate64.rom b/bin/basic_ultimate64.rom index 6583b51e0fa07e6096664b8ea1558fc2522fec70..c16ce9f8a381371663806543052290cccba74f2c 100644 GIT binary patch delta 14 VcmZp0XmHpNE6-$TFgad+Apj(o1i}CS delta 14 VcmZp0XmHpNE6-$LIXPZ_Apj)41j+ya diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index 458494d42ff2c2b34b24f2a0dd45c63bedd2340d..1abd7c23cdb35dcfe642cc0bc84dff6105b57d71 100644 GIT binary patch delta 15 WcmZp0XmHqYgoVk_VDm8+D`@~Nqy;Vj delta 15 WcmZp0XmHqYgoVk#a`Q13D`@~N(*-sF diff --git a/bin/kernal_mega65.rom b/bin/kernal_mega65.rom index 93049ede3ff43df09dccfa95bfdd44c098673862..bcaa4aedd64e13bc32fbb879089b41e1ef7bcc23 100644 GIT binary patch delta 15 WcmZp0XmHqYgoVk_VDm8+D`@~Nqy;Vj delta 15 WcmZp0XmHqYgoVk#a`Q13D`@~N(*-sF diff --git a/bin/kernal_testing.rom b/bin/kernal_testing.rom index fc7df33b984c6010b7048ca8c011d290d326abca..0fff0fe8cb7a152451f39838dbddcc459a8a154a 100644 GIT binary patch delta 15 WcmZp0XmHqYgoVk_VDm8+D`@~Nqy;Vj delta 15 WcmZp0XmHqYgoVk#a`Q13D`@~N(*-sF diff --git a/bin/kernal_ultimate64.rom b/bin/kernal_ultimate64.rom index cc82b2e144ce8593d5e35634244e7d7ca93aa7d7..88de508d41b0b9dabe1dd4225d5dcabfe05a7504 100644 GIT binary patch delta 27 jcmZp0XmHqYgoVk_VDd4RpNwpi53ufKWZPWF)+7l4jmrtA delta 27 jcmZp0XmHqYgoVk#a`G{jpNtHX53ufK= 3.4 + +## Timing information + +When sending/receiving a byte, the JiffyDOS protocol timing is much more strict than the standard IEC. It is not enough to mask the interrupts - one has to make sure nothing will steal the CPU cycles. There are two ways to achieve this: + +- disable the screen completely for the duration of transmission; since VIC-II checks the bit in SCROLY register once per frame only, the code has to wait till the beginning of the next frame +- disable the sprites for the duration of transmission and synchronize with VIC-II RASTER/SCROLY registers to avoid badlines. Current implementation simply avoids transmission two lines before the badline; I suspect it can be reduced to one line, but it would need even more careful timing and would definitely mean inlining some subroutines - probably not worth the effort and increased code size, especially that 1541 JiffyDOS is not too fast sending bytes nevertheless + +Timing details are omitted by purpose - they are already described in [2], besides most of the time it was determined by observing VICE IEC logs and (for example) adding NOPs when necessary. The protocool is not cycle-exact, so our implementation probably behaves slightly differently than the original one. + +## Protocol detection + +Protocol detection happens when the IEC bus controller sends a command (under ATN) - first 7 bits of the commnad code is sent normally, detection is performed before sending the last bit: +- after releasing DATA, controller delays releasing the CLK +- if within about 400 usec (probably less time is needed, I took the value from a comment in the SD2IEC source code) the device pulls DATA line, it talks the JiffyDOS protocol +- in such case the controller waits till DATA is released again and continues the command transmission + +## Sending a command + +IEC commands are sent from the normally (with the additional protocol detection flow before the last bit). Althought it would be enough to perform detection within the TALK and LISTEN commands only, the original JiffyDOS ROMs tries to detect it every time. Omitting the detection is definitely not safe (depending on the command, it migh even cause the communication with device to fail, at least the 1541 JiffyDOS ROM shows such behavior). Moreover, it seems that only TALK/LISTEN commands cause the device to respond by pulling DATA; the controller side implementation has to be prepared for this. + +## Turnover + +Turnover (both to listener and to back to talker) is performed as usual. + +## Sending a byte + +Receiver releases DATA line once it is ready to receive a byte. When the bus controller is ready too (after possible 'badline synchronization' - this wasn't tested, but artificial delay might be needed when maintaining synchronization by screen blanking) it releases the CLK on his side. + +What happens now has to be carefully synchronized between bus controller and receiver, there is not much margin in terms of CPU cycles - see the source code and [2] for details. Basically, we are sending 2 bits a time (using CLK and DATA lines), without any sort of confirmation, and the only synchronization is done via instruction timing: + +- bits 4 (CLK out) and 5 (DATA out) +- bits 6 (CLK out) and 7 (DATA out) +- 2x two bits of the encoded low nibble + +Encoding the low nibble is done via lookup table, reverse engineered by observing the IEC logs from the original JiffyDOS ROMs in action. Unfortunately, IEC registers of the C64 and 1541 do not have the same layout - some bits are reversed and the bit layout is different (see [3]). Thus every single fast IEC protocol has to perform some kind of encoding/decoding; when sending byte using the JiffyDOS protocol the drive handles the high nibble and the controller - the lower one. + +Afterwards the controller either pulls the CLK quickly, or signals EOI by delaying this action. In our implementation the acceptable timing was adjusted by experimentation (pre-existing delay subroutine was used to reduce code size, also note that NTSC machines have slightly higher CPU frequency) - but it's important not to wait too long, 1541 JiffyDOS ROM can handle it, but SD2IEC implementation can not! + + +## Receiving a byte + +Device ready to send a byte signals it by releasing CLK, bus controller performs the 'badline synchronization' (note: if screen blanking method was choosen, artificial delay has to be inserted, otherwise communication with 1541 fails; also note the slightly faster CPU frequency on NTSC machines!). Controller releases the DATA line to signal it is ready to accept bits. + +Again, what happens now has to be carefully synchronized between bus controller and receiver, see [2]. Bits are received in the order shown below (using CLK and DATA lines), without any sort of confirmation, and the only synchronization is done via instruction timing: + +- bits 0 (CLK in) and 1 (DATA in) +- bits 2 (CLK in) and 3 (DATA in) +- bits 4 (CLK in) and 5 (DATA in) +- bits 6 (CLK in) and 7 (DATA in) + +No decoding is necessary (we just need to put received bits on proper positions by bit shifting and EOR manipulation to cancel the effect of non-IEC bits of the CIA register). I had to insert some delays (again - watch out for PAL/NTSC clock difference!) to make the protocol work. + +At the end the controller fetches the CLK/DATA bits and pulls DATA. If CLK is set at certain point, it means EOI (I'm not 100% sure about that, but such an implementation seems to work correctly).