Does the DOS-ROM of the 1541-II drive recognise 1541 mechanics supported with a track 0 light barrier to make the drive "rattle free"? A little writeup by Wolfgang Moser, 2003-03-01 2nd corrected edition, 2003-03-03 3rd corrected edition, 2003-06-06 As I checked with a 1541C drive hardware, the 1541II ROM doesn't contain the proper routines for recognising the track 0 sensor. I first suspected the 1541-II ROM, that it does contain the routines needed, because of the nearly identical serial numbers of the both ROMs: 1541C - 251968-02 1541-II - 251968-03 But it doesn't. So what are the differencies of the ROMs regarding the track 0 light barrier sensor. Disassembling the ROMs for the 1541C and 1541-II drives and checking mainly for the differencies regarding port A of the VIA at 0x1800...0x180F (port A means: 0x1801, 0x1803 and 0x180F): egrep '180(1|3|F)' *.d65dis.asm 1541-II.251968-03.d65dis.asm: L1801 = $1801 1541-II.251968-03.d65dis.asm: L1803 = $1803 1541-II.251968-03.d65dis.asm:E853 AD 01 18 LDA L1801 1541-II.251968-03.d65dis.asm:FF10 8E 03 18 STX L1803 1541-II.251968-03.d65dis.asm:FF50 2C 01 18 BIT L1801 1541C_.251968-02.d65dis.asm: L1801 = $1801 1541C_.251968-02.d65dis.asm: L1803 = $1803 1541C_.251968-02.d65dis.asm: L180F = $180F 1541C_.251968-02.d65dis.asm:E853 AD 01 18 LDA L1801 1541C_.251968-02.d65dis.asm:FF10 8E 03 18 STX L1803 1541C_.251968-02.d65dis.asm:FF3E AD 0F 18 LDA L180F 1541C_.251968-02.d65dis.asm:FF41 CD 0F 18 CMP L180F 1541C_.251968-02.d65dis.asm:FFA6 2C 01 18 BIT L1801 At 0xE853 and 0xFF10 both ROMs are identical: ; Clear IRQ-Flag for port A, ATN_In at CA1 E853 AD 01 18 LDA L1801 E856 A9 01 LDA #$1 E858 85 7C STA L7C E85A 60 RTS ; VIA port initialisation, called from EAA0 FF10 8E 03 18 STX L1803 FF13 A9 02 LDA #$2 FF15 8D 00 18 STA L1800 FF18 A9 1A LDA #$1A FF1A 8D 02 18 STA L1802 FF1D 4C A7 EA JMP LEAA7 There's a little difference with the Reset routine, which calls the port initialisation above: ; Reset routine, calls port initialisation EAA0 78 SEI EAA1 D8 CLD .if __1541C__ EAA2 A2 FE LDX #$FE ; set PA0 as input, PA1.7 output .else EAA2 A2 FF LDX #$FF ; set PAx as output .endif EAA4 4C 10 FF JMP LFF10 ; init VIA ports The "BIT L1801" can be found on both ROMs, they are a patch for correctly clearing the IRQ-Flag for port A, that signals an ATN_In at the handshake input CA1 of port A: 1541C: FFA6 2C 01 18 BIT L1801 FFA9 4C 5B E8 JMP LE85B 1541II: FF50 2C 01 18 BIT L1801 FF53 4C 5B E8 JMP LE85B But there are two remaining calls ("LDA L180F" and "CMP L180F") in the 1541C-ROM, that cannot be found within the 1541-II ROM: ; routine, which calls the following one: FA2E A5 4A LDA L4A ; move inwards FA30 10 31 BPL LFA63 ; if yes, jump FA32 LFA32: ; no, move towards track 0 FA32 4C 36 FF JMP LFF36 ; check track 0 sensor FA35 LFA35: FA35 EA NOP FA36 EA NOP FA37 EA NOP FA38 LFA38: FA38 4C 69 FA JMP LFA69 ; move track ; added patch just before the actual "move head" routine, which first ; checks the track 0 light barrier and prevents moves to the outer ; tracks, if a stable track-0-condition is reached FF36 8A TXA FF37 48 PHA FF38 98 TYA FF39 48 PHA FF3A A2 01 LDX #$1 FF3C LFF3C: FF3C A0 64 LDY #$64 ; wait 100 loops at maximum FF3E LFF3E: FF3E AD 0F 18 LDA L180F ; load port A FF41 CD 0F 18 CMP L180F ; check if bits are stable FF44 D0 20 BNE LFF66 ; if unstable, jump (do move) FF46 LFF46: FF46 88 DEY ; loop down FF47 D0 F5 BNE LFF3E ; and check again FF49 LFF49: FF49 CA DEX ; loop down FF4A D0 F0 BNE LFF3C ; and check again FF4C LFF4C: FF4C 29 01 AND #$1 ; isolate bit 0/PA0 FF4E F0 16 BEQ LFF66 ; if low (tracks 1..4x), jump FF50 LFF50: FF50 AD 00 1C LDA L1C00 FF53 29 03 AND #$3 FF55 D0 0F BNE LFF66 ; move head FF57 LFF57: FF57 A5 7B LDA L7B FF59 D0 0B BNE LFF66 ; move head FF5B LFF5B: FF5B 68 PLA FF5C A8 TAY FF5D 68 PLA FF5E AA TAX FF5F A9 00 LDA #$0 ; don't move the head one step FF61 85 4A STA L4A ; more outerwards, jump behind FF63 4C BE FA JMP LFABE ; the "move head" routine FF66 LFF66: FF66 68 PLA FF67 A8 TAY FF68 68 PLA FF69 AA TAX FF6A E6 4A INC L4A FF6C AE 00 1C LDX L1C00 FF6F CA DEX FF70 4C 38 FA JMP LFA38 ; jump to "move head" routine Comparing the ROM of the 1541C additionally with the ROM of the 1571 drive shows, that the "1541 DOS ROM compatibility part" (0xC000...0xFFFF) contains another, slightly changed routine for a proper track 0 light barrier check: FF45 98 TYA FF46 48 PHA FF47 A0 64 LDY #$64 ; wait 100 loops at maximum FF49 LFF49: FF49 AD 0F 18 LDA L180F ; load port A FF4C 6A ROR A ; put Bit 0 into the Carry FF4D 08 PHP ; save status FF4E AD 0F 18 LDA L180F ; load part A again FF51 6A ROR A ; and move Bit 0 FF52 6A ROR A ; as sign (bit 7) FF53 28 PLP ; get old status FF54 29 80 AND #$80 ; isolate sign FF56 90 04 BCC LFF5C ; jump, if first read =0 FF58 LFF58: FF58 10 1D BPL LFF77 ; move head (track != 0) FF5A LFF5A: ; if both bits were 1, FF5A 30 02 BMI LFF5E ; signal is stable FF5C LFF5C: FF5C 30 19 BMI LFF77 ; move head, if second read =1 FF5E LFF5E: FF5E 88 DEY ; loop down and check again FF5F D0 E8 BNE LFF49 ; PA0 for stability FF61 LFF61: FF61 B0 14 BCS LFF77 ; move head, if PA0 is stable 1 FF63 LFF63: FF63 AD 00 1C LDA L1C00 ; probably prevent head move FF66 29 03 AND #$3 FF68 D0 0D BNE LFF77 ; move head FF6A LFF6A: FF6A A5 7B LDA L7B FF6C D0 09 BNE LFF77 ; move head FF6E LFF6E: FF6E 68 PLA ; PA0 is stable low, further FF6F A8 TAY ; checks were done. FF70 A9 00 LDA #$0 ; don't move the head one step FF72 85 4A STA L4A ; more outerwards, jump behind FF74 4C BE FA JMP LFABE ; the "move head" routine FF77 LFF77: ; FF77 68 PLA FF78 A8 TAY FF79 E6 4A INC L4A FF7B AE 00 1C LDX L1C00 FF7E CA DEX FF7F 4C 38 FA JMP LFA38 ; jump to "move head" routine Take note, that the 1571 routine prevents an outerwards head move, if PA0 is at a stable low state. The 1541C routine in contrast prevents the head move, if PA0 is at a stable high. You can find the reason for this behaviour at the electronics level. The light barrier signal is inverted twice (2x 74LS04 inverter gates) on the board of the 1541C, while it is only inverted once (1x 74LS14) with the 1571. Both routines are not optimal in my personal opinion, because they don't work, if there's no light barrier connected to the port pin PA0. That's the reason, why there's an extra jumper on most of the 1541C boards (JP3), which has to be opened to get the track 0 light barrier go work. That may also be the reason, why pin 2 of port A of the VIA is mostly connected to ground on most of the 1541-II mainboards. Perhaps early versions were equipped with a 1541C DOS ROM, so that this "fix" would be needed. But _why_ does the ROM not work, if the light barrier is unconneced? Let's look at the electronics first, figure 1 shows the significant parts out of the schematics of the 1541C mainboard. You can see, that the photoactive transistor of the light barrier is mounted externally, while the pullup and the inverters are on the 1541C board itself. +5V | | +++ | | 47kOhm | | ~~~~~ | | | +++ | | +---+ +---+ | +--------| 1 |O-----| 1 |O-------| PA0 | +---+ +---+ | ~~~~~ | ~|~~~ ~~~~~ | \\> | / \> |/ > |\ | \ | | ===== Fig. 1: Signal preparation of the 1541C's track 0 light barrier The photoactive transistor is connected "Open Collector", that means, it can only produce an active low signal. Whenever light falls onto the transistor, it pulls the ouput line to low. If the light beam is broken (the head reached track 0), the outputs becomes something like an open state like beeing unconnected. To get the inverter input signal high in this situation we need the pullup resitor. You can see now, what happens, if the light barrier is not connected to the board. The desired input line is simply open, the same as if the transistor becomes open, because the light beam is broken. The pullup resistor now puts the input signal to a high, which "says" to PA0, that track 0 is reached by the head. Regardless if the light beam is broken (track 0 reached) or the whole light barrier is not mounted or not connected to the board, it both means the same: "Track 0 reached". And if this condition becomes true, the ROM routines prevents head moves to the outermost tracks. That's the reason, why the head moves inwards only, if you switch a 1541C on and want to access it. A solution may be a more intelligent track 0 check routine, that also makes a proof, that the track 0 light barrier is working correctly. That means, that such a routine has to check, that the PA0 input signal becomes low some time, especially, when the head is moved some tracks inwards. This test could be done with the reset routine, but it would be better to also integrate this test into the stepper routine. Here are some more goals, that should be reached for a fix of all modern 1541 drives, namely the 1541C and 1541-II drives. 1. The input signal should be connected to the VIA input pin CB2 instead of PA0, so that standard parallel cables can freely use port A (until know it is untested, if CB2 is "free" in a manner, so that it can be used for this purpose). 2. Additionally needed electronics must be as simple as possible, so that people can even add a light barrier to their 1541-II drives. 3. The ROM replacement should be a patched 1541-II ROM and the patch must be as compatible as possible to existing software. It would be better, the drive "rattles" with bad written software instead of not working in general. 4. The ROM replacements should work in every case, even if there's no light barrier connected at all. This would be fine, because everyone could use this ROM as a base for own patches, improvements or addons like speeder systems. 5. It may be another goal to produce a more compatible 1541 ROM part for the 1571 drive, which bases on the 1541-II ROM. To be done somewhere in the future, Womo