JIFFYDOS C64-IECIN = 1541-IECOUT C64-IECIN ( = 1541-IECOUT) (for JD-databytes) first letter = data out A - second letter = clock out I- DC ee13 *jmp $fbaa AI- -------------------- AI- -------------------- AI- fb97 *pha saves sprite register to stack AI- fb98 *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- fb9b *jsr $fbb4 JD-IECIN AI- fb9e *pla AI- fb9f *sta $d015 restores sprite register AI- fba2 *lda $a4 IECIN byte AI- fba4 *rts AI- -------------------- AI- fba5 *lda #$00 AI- fba7 *jmp $ee16 to CBM-IECIN AI- -------------------- AI- fbaa *sei prevent IRQs AI- fbad *bit $a3 JD-IEC status byte (and flag for EOI) AI- fbad *bvc $fba5 b.i. bit 6 = 0 =CBM routines AI- fbaf *lda $d015 sprite register (=JD-IECIN-routines) AI- fbb2 *bne $fb97 b.i. not all sprites are off AI- fbb4 *lda $dd00 4 reads bus (41:ff8b) lda $dd00 AI- - AI- - AI- - (1) put 1541 paper arrow here ----AI) fbb7 *cmp #$40 2 %01000000 cmp #$40 AI- - AI- fbb9 *bcc $fbb4 2/3 waits until 1541 sets clock = inactive bcc $fbb4 AI- - AI- fbbb *and #$07 2 mascs bit 0-2 (pin M & VIC-bank) and #$07 AI- - AI- fbbd *pha 3 saves pin M & VIC-bank to stack pha AI- - AI- - AI- fbbe *lda $d012 4 VIC rasterbar (carry is set) lda $d012 AI- - AI- - AI- - AI- fbc1 *sbc $d011 4 bit 2-0 = vertical softscroll register sbc $d011 AI- - AI- - AI- - AI- fbc4 *and #$07 2 mascs bit 2-0, that 8 rasterbars remain and #$07 AI- - (data=inactive,clock=inactive,ATN=inactive) AI- fbc6 *cmp #$07 2 cmp #$07 AI- - AI- fbc8 *bcs $fbbe 2/3 b.i. too few time until next badline bcs $fbbe AI- - AI- + + + (7 uS only that timing fits, if + + C64 doesn't wait at badline-loop + + and 1541 doesn't make waiting-loop + + at ffb8 at all) + + + + + fbca *pla 4 restores pin M and VIC-bank pla AI- - AI- - AI- - AI- fbcb *sta $dd00 4 data=inactive,clock=inactive,ATN=inactive sta $dd00 AI- - (41:ffb8) AI- - AI- - (2) put 1541 paper arrow here (late/ealy) ----II) fbce *sta $a4 3 saves it (to IECIN byte) sta $a4 II- - II- - II- fbd0 *ora #$20 2 (data=active) ora #$20 II- - II- fbd2 *pha 3 saves to stack pha II- - II- - II- fbd3 *nop 2 nop II- - II- fbd4 *nop 2 nop II- - II- fbd5 *ora $dd00 4 reads bus (41:ffbd) ora $dd00 II- - II- - 1541 C64 1541 C64 II- - bit1=data-)bit7 bit0=clock-)bit6 ----II) fbd8 *lsr 2 bit7-)bit6 bit6-)bit5 lsr II- - II- fbd9 *lsr 2 bit6-)bit5 bit5-)bit4 lsr II- - II- fbda *nop 2 nop II- - II- fbdb *ora $dd00 4 reads bus (41:ffc4) ora $dd00 II- - II- - 1541 C64 1541 C64 II- - bit3=data-)bit7 bit2=clock-)bit6 ----II) fbde *lsr 2 bit7-)bit6 bit6-)bit5 5-)4 4-)3 lsr II- - II- fbdf *lsr 2 bit6-)bit5 bit5-)bit4 4-)3 4-)2 lsr II- - II- fbe0 *eor $a4 3 inverts bit 2-0 pin M & VIC-bank eor $a4 II- - II- - II- fbe2 *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) fbe5 *lsr 2 bit7-)bit6 6-)5 5-)4 4-)3 3-)2 2-)1 lsr II- - II- fbe6 *lsr 2 bit6-)bit5 5-)4 4-)3 4-)2 2-)1 1-)0 lsr II- - II- fbe7 *eor $a4 3 inverts bit 2-0 pin M & VIC-bank eor $a4 II- - II- - II- fbe9 *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) fbec *sta $a4 3 stores IECIN byte sta $a4 II- - II- - II- fbee *pla 4 (restores D=A, pin M, VIC-bank) pla II- - II- - II- - II- fbef *bit $dd00 4 data-)plus/minus-, clock-)overflow-flag bit dd00 II- - (41:ffdb) II- - II- - II- fbf2 *sta $dd00 4 sets data = active (41:ffde) sta $dd00 II- - II- - II- - ----AI) fbf5 *bvc $fc22 b.i.bit6=low=b.i.1541 sets clock=active(=ok) bvc $fc22 AI- fbf7 *bpl $fc1d b.i.bit7=low=b.i.1541 sets data=active(=EOI) bpl $fc1d AI- fbf9 *lda #$42 bit6=end- bit1=error-at-read-bit in $90 (=1541 makes AI- fbfb *jmp $edb2 sets error bits in $90 all lines =inactive) AI- -------------------- AI- fc1d *lda #$40 bit6=end = EOI AI- fc1f *jsr $fe1c sets end-bit in $90 AI- fc22 *lda $a4 IECIN byte AI- fc23 *cli allows IRQs AI- fc24 *clc sets flag for no error AI- fc25 *rts end of IECIN AI- DC ============================================================================== ============================================================================== 1541-IECOUT ( = C64-IECIN) (for JD-databytes) DC -I first letter=data-out - A second letter=clock-out -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? -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 fb18 several test? -IA .... -IA fb2c takes next byte in JD-IECOUT-loop -IA .... -IA fb58 (at the end after EOI?) -IA .... -IA fb5a *lda $1800 reads bus -IA fb5d *bmi $fbd0 b.i. C64 sets ATN=active -IA fb5f *and #$6d %01101101 (data=I, (clock stays A), ATNack=I) -IA fb61 *sta $44 -IA fb63 *and #$61 %01100001 (data=I, clock=I, ATNack=I) -IA fb65 *sta $7a $7a = %0xx00001 -IA fb67 *lda $f2,x status of actual channel if C64=present -IA fb69 *bpl $faee b.i.status is not talk or after EOI $7a = %0xx00000 -IA fb6b *and #$08 mascs bit 3 = EOI-bit if C64=not prsnt -IA fb6d *jsr $ff79 -IA -------------------- -IA ff76 *jmp $e85b routine after ATN from C64 comes -IA -------------------- -IA ff79 *bne $ff81 b.i. no EOI (->e935) -IA ff7b *lda $7a =EOI if C64=present: -IA ff7d *ora #$03 (data=active) noEOI:$44 = %0xx01101 -IA ff7d *sta $44 (D=A (EOI), D=I (noEOI)) EOI: $44 = %0xx00011 -IA ff81 *lda $023e,x acttual byte of channel x if C64=not present: -IA ff84 *ldx $7a noEOI:$44 = %0xx01100 -IA ff86 *ldy #$ff flag for transfer only one byte EOI: $44 = %0xx00011 -IA ff88 *stx $1800 4 sets clock = inactive (64:fbb4) -IA =flag to C64 that 1541 is ready to -IA send nexte byte (II---- (1) put C64 paper arrow here -II ff8b *bne ffa5 3 branches allways -II -II -------------------- -II ffa5 *tax 2 IECOUT byte -II -II ffa6 *lsr 2 -II -II ffa7 *lsr 2 -II -II ffa8 *lsr 2 -II -II ffa9 *lsr 2 highnibble-)lownibble -II -II ffaa *sta $4b 3 stores highnibble -II -II -II ffac *txa 2 IECOUT byte -II -II ffad *and #$0f 2 mascs lownibble -II -II ffaf *tax 2 -II -II ffb0 *lda $ea1d,x 4 nibble table (inverted, because C64 inputs are not -II loads low nibble inverted) -II -II -II ffb3 *ldx $7a 3 0xx00001 0xx00000 -II C64=present C64=not present -II -II ffb5 *stx $1800 4 no function at IECOUT (only at LOAD) -II -II (II---- -II ffb8 *cpx $1800 4 (64:fbcb) -II -II (II---- (2) put C64 paper arrow here (late) 0us -II ffbb *beq $ffb8 3 waits until -C64 sets data = inactive -II or -C64 sets ATN = active -II -II ffb8 *cpx $1800 4 (64:fbcb) -II -II (II---- (2) put C64 paper arrow here (early) 0us -II ffbb *beq $ffb8 2 waits until C64 sets data = inactive -II -II ffbd *sta $1800 4 bit1 -) data bit0 -) clock (64:fbd5) -II -II (10---- 06-13us -10 ffc0 *asl 2 06-0d -10 -10 ffc1 *and #$0f 2 clears bit 4 (ATNack=inactive) -10 -10 ffc3 *nop 2 -10 -10 ffc4 *sta $1800 4 bit3 -) data bit2 -) clock (64:fbdb) -10 -10 (32---- 16-23us -32 ffc7 *ldx $4b 3 highnibble 10-17 -32 -32 -32 ffc9 *lda $ea1d,x 4 nibble table -32 -32 -32 -32 ffcc *sta $1800 4 bit5 -) data bit4 -) clock (64:fbe2) -32 -32 (54---- 27-34us -54 ffcf *asl 2 1b-22 -54 -54 ffd0 *and #$0f 2 clears bit 4 (ATNack=inactive) -54 -54 ffd2 *iny 2 #$ff-)#$00 -54 -54 ffd3 *sta $1800 4 bit7 -) data bit6 -) clock (64:fbe9) -54 -54 (76---- 37-44us -76 ffd6 *bne $ffa3 2/3 never branches at IECOUT (only for LOAD) 25-2c -76 -76 ffd8 *nop 2 -76 if C64=present: -76 ffd9 *lda $44 3 noEOI: data=inactive,clock=active %0xx01101 -76 EOI: data=active,clock=inactive %0xx00011 -76 -76 ffdb *sta $1800 4 noEOI: sets D=I, C=A (64:fbef) -76 (EOI: D=A, C=I) -76 48-55us (IA---- 30-37 -IA ffde *cmp $1800 4 (64:fbf2) -IA noEOI: waits until C64 sets data = active -IA EOI: doesn't wait because C64-clock = inactive (IA---- -IA ffe1 *bcc $ff76 2/3 b.i.C64 sets ATN = active -IA -IA ffe3 *bne $ffde 2/3 -IA -IA ffe5 *rts 6 -IA ------------------- -IA -IA -IA -IA -IA fb70 *and #$02 2 mascs data-out bit -IA -IA fb72 *beq $fb2c 2/3 b.i. no EOI -) (loads from disk) & transfers next byte -IA/AI (noEOI: D=I, C=A) C64=present / C64=not prsnt -AI fb74 *lda $7a (=EOI: D=A, C=I) 7a=%0xx00001 / %0xx00000 fb76 *ora #$0d %0xx01101 (data=inactive, clock=active) at EOI from ffdb to fb78 1541 makes data = active and clock = inactive for 33us (or 42us if bus isn't constant within 4us from ffdb to ffde) fb78 *jsr $ffdb then 1541 makes data = inactive and clock = active (=>C64 badline must come later than fb78???) ------------------- ff76 *jmp $e85b service routine for bus after C64 sets ATN=active ------------------- ffdb *sta $1800 data=inactive clock=active ffde *cmp $1800 compares with bus ffe1 *bcc $ff76 b.i. C64 sets ATN = active ffe3 *bne $ffde doesn't wait because C64 sets data=active ffe5 *rts ------------------- fb7b *cli fb7c *jsr $d3aa takes next data byte (after EOI: stores #$00-)$f2,x) fb7f *sei fb80 *jmp $fb58 transfers next byte (after EOI: $f2,x=#$00 DC =) branches at fb69 to 'rts') ------------------------------------------------------------------------------ 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 waiting-loop. 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. The 1541 waiting loop at fbbb (for C64 is ready) is 7uS long. =) The tolerance must be greater than 7uS (it is minimum 10uS). (1) The C64 doesn't branch in the badline-loop at fbc8: The C64 is from fbb4 to fbcb faster (31uS) than the 1541 from ff8b to ffb8 (37uS). So the 1541 doesn't branch at all at ffbb. For the timing at the paper there are the 7 empty lines at the C64 to compensate the (not existing) 7uS 1541 branching loop at ffbb. Put the arrows (1) together: C64-paper-sheet (1) ----XY) (XY---- (1) 1541-paper-sheet. (2) The C64 branches in the badline-loop at fbc8: Put the C64-arrow at fbcb to one of the two 1541-arrows (late/early) at ffb8. 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. 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 bit 1 and 0 when the 1541 allready sets bit 3 and 2 (same with bits 5,4 and 7,6). 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 microprcessor 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. There are 48 cycles from fbcb to fbe9. A PAL-C64 needs 48/0.9852=48.72us. While 48 cycles the PAL-C64 is 0.72us slower than the 1541. At a C128D and the internal 1571 there are exactly the same routines. Here the serial cable from C128 to internal 1571 is very short. So the delay of the signals is very short, too. The C128 should read at fbe9 bit 7&6. But the PAL-C128 is as slow that it doesn't read bit 7&6 but that it reads the buslevels which the 1571 had made for EOI (or noEOI at the last byte). So there are sometimes wrong bytes at the PAL-C128 and internal 1571 when you f.e. display the directory. When many additional devices are connected to the serial bus, then the capacity of the serial bus is as much increased that there is no more problem. (Because the NTSC-C128 is faster, there is no problem there at all) 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 wrong. C64-time from load-VIC-rasterbar-register to last-action-at-bus: 81uS ---------------------------------------------------------------------- 2005/01/30 Near Letter Quantity Jochen Adler NLQ@gmx.de http://home.t-online.de/home/dadler/ ---------------------------------------------------------------------- Home