JIFFYDOS LOAD 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, UNLISTEN) 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- DC ============================================================================== ============================================================================== 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/76 -AI/76 -AI/76 -AI/76 -AI ffa5 *tax 2 LOAD-byte -AI/76 -AI ffa6 *lsr 2 -AI/76 -AI ffa7 *lsr 2 -AI/76 -AI ffa8 *lsr 2 -AI/76 -AI ffa9 *lsr 2 highnibble-)lownibble -AI/76 -AI ffaa *sta $4b 3 stores highnibble -AI/76 -AI/76 -AI ffac *txa 2 LOAD-byte -AI/76 -AI ffad *and #$0f 2 mascs lownibble -AI/76 -AI ffaf *tax 2 -AI/76 -AI ffb0 *lda $ea1d,x 4 nibble table (inverted, because C64 inputs are not -AI/76 loads low nibble inverted) -AI/76 -AI/76 -AI ffb3 *ldx $7a 3 %0xx00000 -AI/76 -AI/76 -AI ffb5 *stx $1800 4 sets data=inactive clock=inactive (64:fb3e) -AI/76 -AI/76 (II---- -II ffb8 *cpx $1800 4 (64:fb51) -II -II (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 -II ffb8 *cpx $1800 4 (64:fb51) -II -II (II---- put C64 paper arrow here (early) -II ffbb *beq $ffb8 2 waits until C64 sets data = active -II -II ffbd *sta $1800 4 bit1 -) data bit0 -) clock (64:fb5d) -II -II (10 -10 ffc0 *asl 2 -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:fb63) -10 -10 (32---- -32 ffc7 *ldx $4b 3 highnibble -32 -32 -32 ffc9 *lda $ea1d,x 4 nibble table -32 -32 -32 -32 ffcc *sta $1800 4 bit5 -) data bit4 -) clock (64:fb6a) -32 -32 (54---- -54 ffcf *asl 2 -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:fb71) -54 -54 (76---- -76 ffd6 *bne $ffa3 2/3 b.i. still bytes in buffer to transfer -76 -76 ffd8 *nop 2 -76 -76 ffd9 *lda $44 3 (clock=active) %0xx01101 -76 -76 -76 ffdb *sta $1800 4 sets data=inactive, clock=active (64:fb54) -76 -76 -IA -IA ffde *cmp $1800 4 waits until -C64 sets data = active (64:fb51) -IA or -C64 makes ATN = active -IA (IA---- -IA ffe1 *bcc $ff76 2/3 b.i.C64 sets ATN = active -IA -IA ffe3 *bne $ffde 2/3 waits until C64 sets data=active (64:fb51) -IA -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) DC ------------------------------------------------------------------------------ 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. 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 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 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 wrong. 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 faf0. (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 ---------------------------------------------------------------------- 2000/01/30 Near Letter Quantity Jochen Adler NLQ@gmx.de http://home.t-online.de/home/dadler/ ---------------------------------------------------------------------- Home