Copy Link
Add to Bookmark
Report

Commodore 64: 1541C to 1541-II

DrWatson's profile picture
Published in 
Commodore64
 · 22 May 2021
Commodore 1541C Disk Drive
Pin it
Commodore 1541C Disk Drive

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 <womo (at) d81 (dot) de>

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT