C64-LOAD (= 1541-LOAD)
                                                   first letter = data out A -
                                                 second letter = clock out  I-

f4b8  ldy $b7       length of filename
f4ba  bne $f4bf     b.i. there is a filename
f4bc  jmp $f659     "missing filename"
f4bf  ldx $b9       secundary address
f4c1  jsr $f5af     "searching for (filename)"
f4c4  lda #$60      sets SA = 0  (0=LOAD)
f4c6  sta $b9       sets SA
f4c8  jsr $f3d5     opens file at IEC bus: (LISTEN to device in $ba, SA after
                    LISTEN in $b9 (ora #$f0 for open), sends filename,
f4cb  lda $ba       device number
f4cd  jsr $ed09     sends TALK to floppy(if JD-C64&JD-floppy:sets bit6 in $a3)
f4d0  lda $b9       =#$60 secundary address
f4d2  jsr $edc7     sends SA to floppy
f4d5  jsr $ee13     IECIN, takes load-address-low-byte from floppy
f4d8  sta $ae       stores it to load-address-vector
f4da  lda $90       IEC-bus-status-byte
f4dc  lsr           bit 1 (= error at read) -) bit 0
f4dd  lsr           bit 0 -) carry
f4de  bcs $f530     b.i. error at read
f4e0 *jsr f179
f179 *jsr $fbaa     IECIN, takes load-address-high-byte from floppy
f17c *pha           stores it to stack
f17d *bit $a3       bit 6 of JD-status-byte (and EOI-flag) -) overflow-flag
f17f *bvc $f19c     b.i. CBM-IEC-bus routines
f181 *cpx #$00      X = SA
f183 *bne $f187     b.i. not 'load,d,0'
f185 *lda $c4       highbyte basic start
f187 *cmp #$04      A = highbyte start-load-address (relative & absolute load)
f189 *bcc $f19c     b.i. startaddress $0000-$03ff (no JD-LOAD because vectors
                    in $0300 - $0333 could be overwritten and some software-
                    fastloaders use them)
f18b *ldy #$00
f18d *lda ($bb),y   first letter of filename
f18f *cmp #$24      '$'
f191 *beq $f19c     b.i. 'load'$'' load directory
f193 *inc $b9       SA: #$60 -) #$61 (#$61 = SA for SAVE)
f195 *jsr $f38b                                                            DC
f38b *jsr $ffab     sends UNTALK to floppy    sends flag for JD-LOAD to floppy
f38e *lda $ba       device number             sends first TALK (=floppy must
f390 *jsr $ffb4     TALK (sets JD-IEC-flag)   TALK = bytes from floppy to C64)
f393 *lda $b9       SA = #$61                 sends then SA for SAVE (save =
f395 *jmp $ff96     sends SA after TALK       bytes from C64 to floppy)
====================                          illegal orders=flag for JD-LOAD
f198 *dec $b9       SA: #$61 -) #$60                                       AI-
f19a *asl $a3       JD-status-byte: bit6-)bit7 = sets bit 7 (=flag for     AI-
f19c *pla           load-address-high-byte                     JD-LOAD)    AI-
====================                                                       AI-
f4e3  sta $af       stores it to load-address-vector                       AI-
f4e5  txa           original SA from $b9 (-)f4bf)                          AI-
f4e6  bne $f4f0     b.i. 'load,d,1' = relative load                        AI-
f4e8  lda $c3       lowbyte basic start  = absolute load                   AI-
f4ea  sta $ae       load vector                                            AI-
f4ec  lda $c4       highbyte basic start                                   AI-
f4ee  sta $af       load vector                                            AI-
f4f0 *jmp $fac4                                                            AI-
====================                                                       AI-
fac4 *jsr f5d2      "loading"                                              AI-
      ...                                                                  AI-
fad7 *bit $a3       JD-status-byte (and EOI-flag): bit7-)plus/minus-flag   AI-
fad9 *bmi $fade     b.i. JD-LOAD                                           AI-
fadb *jmp $f4f3     to CBM-LOAD                                            AI-
--------------------                                                       AI-
fade *sei           prevents IRQs                                          AI-
fadf *ldy #$03                                                             AI-
fae1 *lda $00af,y                                                          AI-
fae4 *pha           saves b2,b1,b0 to stack                                AI-
fae5 *dey                                                                  AI-
fae6 *bne $fae1                                                            AI-
fae8 *lda $d015     VIC-sprite-register                                    AI-
faeb *sta $b0       saves it                                               AI-
faed *jsr $f0d8                                                            AI-
====================                                                       AI-
f0d8 *lda #$00                                                             AI-
f0da *sta $d015     switch off all sprites                                 AI-
f0dd *adc #$01    2                                                        AI-
f0df *bne f0dd    3 (2+3)*250=1250uS delay                                 AI-
f0e1 *rts                                                                  AI-
====================                                                       AI-
faf0 *jsr $f6bc     checks whether (STOP) key is pressed                   AI-
faf3 *bpl $fb27     b.i. (STOP) is pressed                                 AI-
faf5 *lda $d011     vertical softscroll register of VIC(normal=#%.....011) AI-
faf8 *and #$07      mascs theese bits (normal: #$03)                       AI-
fafa *clc                                                                  AI-
fafb *adc #$2f      normal:(3) + 47 = 50 =$32                              AI-
fafd *sta $b1       saves it                                               AI-
faff *lda $dd00     reads bus                                              AI-
fb02 *and #$07      mascs bit 2-0 (=pin M & VIC-bank)                      AI-
fb04 *sta $b2       stores it                                              AI-
fb06 *sta $dd00     data=inactive,clock=inactive,ATN=inactive              II-
fb09 *ora #$20      (data = active,  clock = inactive)                     II-
fb0b *tax                                                                  II-
fb0c *bit $dd00     datain-)plus/minus, clockin-)overflow                  II-
fb0f *bvc $fb0c     waits until 1541 sets clock=inactive   (41:ff9d/ff65)  II-
fb11 *bpl fb3e      b.i.41 sets data=active =transfer next block(41:ff98)  II-
fb13 *ldx #$64      (=end / 1541 sets data = inactive)     (41:ffdb)       II-
fb15 *bit $dd00     clock -) overflow                                      II-
fb18 *bvc $fb20     b.i. 1541 sets clock = active (ok-flag)     (41:ff6b)  II-
fb1a *dex                                                                  II-
fb1b *bne $fb15     checks 1100uS the bus                                  II-
fb1d *lda #$42      bit6=end- bit1=error-at-read-flags in $90              II-
fb1f *bit $....     skips to fb22                                          II-
fb20 *lda #$40      bit 6 = end-flag in $90                                II-
fb22 *jsr $fe1c     sets bits in $90                                       II-
fb25 *clc           flag for (STOP) not pressed                            II-
fb26 *bit $..       skips to fb28                                          II-
fb27 *sec           flag for (STOP) is pressed                             II-
fb28 *lda $b0                                                              II-
fb2a *sta $d015     restores sprite register                               II-
fb2d *pla                                                                  II-
fb2e *sta $b0       restores b0                                            II-
fb30 *pla                                                                  II-
fb31 *sta $b1       restores b1                                            II-
fb33 *pla                                                                  II-
fb34 *sta $b2       restores b2                                            II-
fb36 *bcs $fb3b     b.i. (STOP) is pressed                                 II-
fb38 *jmp $f528     =ok (-) UNTALK & CLOSE)                                II-
--------------------                                                       II-
fb3b *jmp $f633     = (STOP)                                               II-
fb3e *bit $dd00     data -) plus/minus                                     II-
fb41 *bpl $fb3e     waits until 1541 sets data = inactive        (41:ffb5) II-
fb43 *sec                                                                  II-
-                                                                          II-
fb44 *lda $d012   4 VIC rasterbar                                lda $d012 II-
-                                                                          II-
-                                                                          II-
-                                                                          II-
fb47 *sbc $b1     3 bit 2-0 = y softscroll register              sbc $b1   II-
-                                                                          II-
-                                                                          II-
fb49 *bcc $fb4f 2/3 b.i.in border (rasterbar 0-49 or 256-305, no badlines) II-
-                                                                          II-
fb4b *and #$07    2 mascs bit 2-0, that 8 rasterbars remain      and #$07  II-
-                   (data=inactive,clock=inactive,ATN=inactive)            II-
fb4d *beq $fb44 2/3 b.i. too few time until next badline         beq $fb4d II-
-                                                                          II-
fb4f *lda $b2     3 restores pin M and VIC-bank                  lda $b2   II-
-                   (data=inactive,clock=inactive)                         II-
-                                                                          II-
fb51 *stx $dd00   4 data=active,clock=inactive,ATN=inactive      stx $dd00 II-
-                                                      (41:ffb8)           II-
-                                                                          II-
-                                put 1541 paper arrow here (late/ealy) ----AI)
fb54 *bit $dd00   4 clock -) overflow                            bit $dd00 AI-
-                                                                          AI-
-                                                                          AI-
-                                                                      ----AI)
fb57 *bvc $faf0   2 b.i. 1541 sets clock = active      (41:ffdb) bvc $faf0 AI-
-                   =b.i. 1541 must load next block from disk              AI-
fb59 *nop         2                                              nop       AI-
-                                                                          AI-
fb5a *sta $dd00   4 sets data = inactive                         sta $dd00 AI-
-                                                                          AI-
-                                                                          AI-
-                                                                      ----II)
fb5d *ora $dd00   4 reads bus                          (41:ffbd) ora $dd00 II-
-                                                                          II-
-                   1541       C64   1541        C64                       II-
-                   bit1=data-)bit7  bit0=clock-)bit6                  ----II)
fb60 *lsr         2 bit7-)bit6  bit6-)bit5                       lsr       II-
-                                                                          II-
fb61 *lsr         2 bit6-)bit5  bit5-)bit4                       lsr       II-
-                                                                          II-
fb62 *nop         2                                              nop       II-
-                                                                          II-
fb63 *ora $dd00   4 reads bus                          (41:ffc4) ora $dd00 II-
-                                                                          II-
-                   1541       C64   1541        C64                       II-
-                   bit3=data-)bit7  bit2=clock-)bit6                  ----II)
fb66 *lsr         2 bit7-)bit6  bit6-)bit5  5-)4  4-)3           lsr       II-
-                                                                          II-
fb67 *lsr         2 bit6-)bit5  bit5-)bit4  4-)3  4-)2           lsr       II-
-                                                                          II-
fb68 *eor $b2     3 inverts bit 2-0 (pin M & VIC-bank)           eor $b2   II-
-                                                                          II-
-                                                                          II-
fb6a *eor $dd00   4 reads bus                          (41:ffcc) eor $dd00 II-
-                   (bit 2-0 is now double inverted = correct)             II-
-                   1541       C64   1541        C64                       II-
-                   bit5=data-)bit7  bit4=clock-)bit6                  ----II)
fb6d *lsr         2 bit7-)bit6  6-)5  5-)4  4-)3  3-)2 2-)1      lsr       II-
-                                                                          II-
fb6e *lsr         2 bit6-)bit5  5-)4  4-)3  4-)2  2-)1 1-)0      lsr       II-
-                                                                          II-
fb6f *eor $b2     3 inverts bit 2-0 (pin M & VIC-bank)           eor $b2   II-
-                                                                          II-
-                                                                          II-
fb71 *eor $dd00   4 reads bus                          (41:ffd3) eor $dd00 II-
-                   (bit 2-0 is now double inverted = correct)             II-
-                   1541       C64   1541        C64                       II-
-                   bit5=data-)bit7  bit4=clock-)bit6                  ----II)
fb74 *cpy $93       load/verify-flag                                       II-
fb76 *bne $fb83     b.i. verify                                            II-
fb78 *sta (ae),y    stores LOAD-byte                                       II-
fb7a *inc $ae       increments lowbyte-load-vector                         II-
fb7c *bne $fb44                                                            II-
fb7e *inc $af       increments highbyte-load-vector                        II-
fb80 *jmp $fb44     takes next byte from floppy                            II-
--------------------                                                       II-
fb83 *cmp ($ae),y   compares VERIFY-byte                                   II-
fb85 *beq $fb7a     b.i. ok                                                II-
fb87 *sec           (for subtraction at fb47)                              II-
fb88 *lda #$10                                                             II-
fb8a *sta $90       sets verify-error-flag                                 II-
fb8c *bne $fb7a     branches allways                                       II-


1541-LOAD (= C64-LOAD)

-I  first letter = data-out
- A second letter = clock-out
-   e858                routine when the C64 sends an command byte
    e87c *jsr $e9c9     takes command-IEC-bytes from C64 (sets JD-IEC-flag)
    ....                A=orderbyte  x=#$00  y=#$80              (64:f390)
    e88b *cmp $78       devicenumber for TALK of floppy
    e88d *bne           b.i. not TALK to this floppy
    e88f *sty $7a       #$80 -) $7a  sets flag for TALK
    e891 *stx $79       #$00 -) $79  clears flag for LISTEN
    e8c8 *bmi $e87c
    e87c *jsr $e9c9    takes order-byte from C64                 (64:f393)
    e89f *cmp #$61     checks whether secundary address for SAVE
    e8a1 *bne $e8ab    b.i. not SAVE-SA
    e8a3 *ldx $7a      flag for TALK
    e8a5 *beq $....    b.i. not TALK to this floppy
    e8a7 *lda #$60
    e8a9 *sta $98      sets bit 6 in $98 = JD-status-byte (=JD-LOAD-flag)
 DC e8e6 *jsr $e909    datas from disk-)buffer-)IEC-bus-)C64
-IA e909
-IA ....
-IA e90f *lda $98       JD-IEC-status byte
-IA e911 *beq $e918     b.i.CBM routines
-IA e913 *ldx #$46
-IA e915 *jmp $fb0f     JD-IECOUT routines
-IA --------------------
-IA e918  ...           CBM-IECOUT routines
-IA --------------------
-IA --------------------
-IA faee *rts
-IA --------------------
-IA fb0f *jsr $fef6     360uS delay? ($46=70*5=350+6+6)
-IA fb12 *asl           JD-IEC status byte: bit6-)bit7
-IA fb13 *bpl $fb18     b.i.bit6 of JD-status = low (=no LOAD)
-IA fb15 *jmp $ff2d     to JD-LOAD
-IA ====================
-IA ff2d *lda $31       highbyte of actual disc buffer
-IA ff2f *pha           stores it to stack
-IA ff30 *jsr $e977     waits until C64 sets data = inactive     (64:fb06)
-IA ff33 *lda #$04      transfer byte 4-? (without loadaddress)
-IA ff35 *pha           stores it to stack
-IA ff36 *ldy #$01
-IA ff38 *lda ($30),y   first byte of buffer = link to track of next block
-IA ff3a *sta $81
-IA ff3c *tax
-IA ff3d *dey           y=#$00
-IA ff3e *lda ($30),y   second byte of buffer = link to sector of next block
-IA ff40 *sta $80
-IA ff42 *bne $ff50     b.i. there is a next-block
-IA ff44 *pla           #$2/4   (=endblock)
-IA ff45 *clc
-IA ff46 *sbc $81       calculates y
-IA ff48 *inx           increments number of bytes in the endblock/second byte
-IA ff49 *stx $30       lowbyte buffer vector
-IA ff4b *beq $ff4f
-IA ff4d *dec $31       decrements highbyte buffer vector
-IA ff4f *pha           -)y = vector begin of transfer of block
-IA ff50 *pla         4
-IA ff51 *tay         2 vector begin of transfer of block
-IA ff52 *jsr $ff8d   6 send one buffer
-IA ff8a *lda $1800     reads bus
-IA ff90 *and #$60      %0110000 (data=I, clock=I, ATNack=I)
-IA ff92 *sta $7a                                              $7a = %0xx00000
-IA ff94 *ora #$0d      %00001101 (data=I, clock=A, ATNack=I)
-IA ff96 *sta $44                                              $44 = %0xx01101
-AA ff98 *jsr $e9a5     sets data = active                       (64:fb11)
-AA ff9b *eor #$0d      %00001101
-AI ff9d *sta $1800   4 sets clock = inactive                    (64:fb0c)
-AI ffa0 *jsr $fef3  42 42 uS delay
-AI ffa3 *lda ($30),y 5 loads actual byte from buffer
-AI ffa5 *tax         2  LOAD-byte
-AI ffa6 *lsr         2
-AI ffa7 *lsr         2
-AI ffa8 *lsr         2
-AI ffa9 *lsr         2 highnibble-)lownibble
-AI ffaa *sta $4b     3 stores highnibble
-AI ffac *txa         2 LOAD-byte
-AI ffad *and #$0f    2 mascs lownibble
-AI ffaf *tax         2
-AI ffb0 *lda $ea1d,x 4 nibble table (inverted, because C64 inputs are not
-AI/76                  loads low nibble                             inverted)
-AI ffb3 *ldx $7a     3 %0xx00000
-AI ffb5 *stx $1800   4 sets data=inactive clock=inactive        (64:fb3e)
-II ffb8 *cpx $1800   4                                          (64:fb51)
(II---- put C64 paper arrow here (late)
-II ffbb *beq $ffb8   3 waits until -C64 sets data = active
-II                              or -C64 makes ATN = active
-II ffb8 *cpx $1800   4                                          (64:fb51)
(II---- put C64 paper arrow here (early)
-II ffbb *beq $ffb8   2 waits until C64 sets data = active
-II ffbd *sta $1800   4 bit1 -) data  bit0 -) clock              (64:fb5d)
-10 ffc0 *asl         2
-10 ffc1 *and #$0f    2 clears bit 4 (ATNack=inactive)
-10 ffc3 *nop         2
-10 ffc4 *sta $1800   4 bit3 -) data  bit2 -) clock              (64:fb63)
-32 ffc7 *ldx $4b     3 highnibble
-32 ffc9 *lda $ea1d,x 4 nibble table
-32 ffcc *sta $1800   4 bit5 -) data  bit4 -) clock              (64:fb6a)
-54 ffcf *asl         2
-54 ffd0 *and #$0f    2 clears bit 4 (ATNack=inactive)
-54 ffd2 *iny         2 #$ff-)#$00
-54 ffd3 *sta $1800   4 bit7 -) data  bit6 -) clock              (64:fb71)
-76 ffd6 *bne $ffa3 2/3 b.i. still bytes in buffer to transfer
-76 ffd8 *nop         2
-76 ffd9 *lda $44     3 (clock=active) %0xx01101
-76 ffdb *sta $1800   4 sets data=inactive, clock=active         (64:fb54)
-IA ffde *cmp $1800   4 waits until -C64 sets data = active      (64:fb51)
-IA                              or -C64 makes ATN = active
-IA ffe1 *bcc $ff76 2/3 b.i.C64 sets ATN = active
-IA ffe3 *bne $ffde 2/3 waits until C64 sets data=active         (64:fb51)
-IA ffe5 *rts         6
-IA ====================
-IA ff55 *lda $80     3 follow track
-IA ff57 *beq $ff60 2/3 b.i. this was the endblock
-IA ff59 *jsr $fb83     reads follow-block from disk into buffer
-IA ff5c *lda #$02      start transmission from byte 2
-IA ff5e *bne $ff35     branches allways
-IA ff60 *sta $30       #$00-)lowbyte buffer vector
-IA ff62 *pla
-IA ff63 *sta $31       restores highbyte buffer vector
-II ff65 *jsr $ff6e     100uS delay, then sets clock=inactive    (64:fb0c)
-II ff68 *jsr $ff6e     100uS delay
-IA ff6b *jsr $e9ae     sets clock = active                      (64:fb15)
-IA ff6e *ldx #$14      20
-IA ff70 *dex
-IA ff71 *bne $ff70     20*5=100uS delay
-II ff73 *jmp $e9b7     sets clock = inactive (& rts to $e8e9)

ea1d    0f 07 0d 05 0b 03 09 01 0e 06 0c 04 0a 02 08 00

Put the right margin of the C64-paper-sheet to the left margin of the 1541-
paper-sheet, it fits and shows the timing.

You can move the sheets seven lines up and down, depending on the 7uS

The 1541 waiting loop at ffbb (for C64 is ready) is 7uS long. =) The tolerance
must be greater than 7uS (it is minimum 10uS).

Put the C64-arrow at fb51 to one of the two 1541-arrows (late/early) at ffb8
or between the two arrows.
C64-paper-sheet  ----XY)    (XY----  1541-paper-sheet

Late: When the 1541 reads the bus, the data line is still set to active by
the C64. The C64 sets the data line to inactive an extremely short time later
(f.e. 0.1uS), so the 1541 must wait one complete loop (7uS). So the 1541
leaves the loop 7uS later than the C64 inactivates data.

Early: The 1541 reads the bus exactly in the moment when the C64 sets the
data line to inactive. So the 1541 doesn't wait but continues at once. So the
1541 leaves the loop 0uS later than the C64 inactivates data.

Each line is 1uS.

In a line with a '-' there is no action at the bus.
In a line with a '(' or a ')' the C64 or the 1541 sets lines of the bus or
reads the bus.

If I made no error, then the timing is very short. The 1541 sets a bit for
only 10uS. The timing at the paper shows that the C64 reads in position 'late'
bit 1 and 0 when the 1541 allready sets bit 3 and 2 (same with bits 5,4 and
Possible solution: The C64 starts the transmission by setting data = inactive.
If the electric delay from the C64 microprocessor over the CIA, over the
output-inverter-chip, over the wire, over the input-inverter-chip and over the
VIA to the 1541 microprocessor is only 0.5uS (in each direction), then the
timing is ok. The 1541 receives the start-signal from the C64 0.5uS later than
the C64 sends it and the C64 receives the sended IEC-data-bits 0.5uS later
than the 1541 sends them.

Possible error: If bit 2 of $dd00 (pin M of the userport) is an input and this
input changes during the IECIN then bit 2 and 0 of the IECIN byte could be

The C64 checks the (STOP) key every 254 transmitted bytes.

Transfer of a block:
(1) the C64 waits at fb0c until the 1541 is ready to transfer a block (41:ff98
data=active ff9d clock=inactive).
(2) the C64 branches at fb11 to fb3e.
(3) the C64 waits at fb3e until the 1541 is ready to transfer the first byte
of the blok (41:ffb5 data=inactive).
(4) the C64 starts the transmission of one byte at fb51 (data=active).
(5) the 1541 transfers one byte (ffbd-ffd3) to the C64 (fb5d-fb71).
(6) the 1541 is from the end of the transmission to the beginning of the
transmission of the next byte (ffd6-ffa3-ffb5) faster than the C64
(fb74-fb80-fb44-fb51). =) the 1541 sets at ffb5 clock = inactive before the
C64 reads clock-in at fb54. The inactivated clock-line is the signal from the
1541 for the transmission of the next byte of the block.

Steps (4) (5) (6) continue until the last byte of the block is transmitted.

(7) when the 1541  transmits the last byte of the block (not of the file),
then the 1541 sets at ffdb clock = active and waits (until the C64 sets data =
active at fb51).
(8) the C64 wants to start at fb51 the transmission of the next byte, but sees
at fb54 that the 1541 activates the clock-line. =) the C64 branches at fb57 to
(9) the 1541 loads the next block from the disk into the buffer ( )))100uS).
The C64 checks the (STOP) key (100uS).
(10) the transmission continues with step (1).

The JD-LOAD routine relies that at step (9) the C64 (100uS) is faster than the
floppy (1541 ))100uS, must load block).
Error if the floppy is at step (9) faster than the C64:
The floppy starts the transmission of the next block before the C64 has
finished checking the (STOP) key. The floppy sets at ffb5 data = inactive. =)
the C64 thinks at fb11 that the end of the file comes and doesn't take the
next block.
=) at floppies with a track-cache-buffer there must be a delay-loop at step
(9). Another solution culd be: The track-cache-bufer-floppy waits at ff96
until the C64 sets data = inactive (at fb06), but perhaps it's not the same at
all conputers (C128, SCPU)?

End of file:
When the 1541 sees at ff57 that it has transmitted the last block, it waits
100uS, lets data = inactive (ffdb) and then sets clock = inactive (ff65).
The C64 waits at fb0c until the 1541 sets clock = inactive (ff65). Because the
data-in-line is inactivated, the C64 doesn't branch, but closes the file.

C64-time from load-VIC-rasterbar-register to last-action-at-bus: 64uS
Fasted time for 1 byte (C64 in border): 84us
Near Letter Quantity
Jochen Adler