• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

Mac SE ADB Controller

tony359

Active member
Can confirm the 87 and 88 both work - I have used a 88 in a SE and a 87 in a IIcx (using a little QFN to PLCC adapter board I made) both of which worked perfectly
Amazing thanks! I think my SE just needs a VIA but I will socket the ADB as well so I can test the programmed PIC as well.
Thanks for now!
 

Snial

Well-known member
For my own interest I've done a bit of analysis on the flow control for the original PIC code. As per all PIC16C5x type MCUs, timing ends up using a lot of cycle counting, because there are no interrupts and the clock is too slow (2MHz => 500KIPs on these PICs) to use the TMR value accurately enough. Here's the flow diagram:

PicAdbExecutionPath.png

Undoubtably, it contains a few mistakes, but this gives you a feel for how it behaves. Function_002 dispatches to Function_052 to _060; Function_066 to _069 grabs AdbBytes and uses _029 to _051 to get each bit. Function_021 to _028 sends a byte (or bytes). Function_009 to _012 is VIA code and Function_013 to _015 fills memory.

Although the code involves a lot of cycle counting, nevertheless, bit timing isn't always exact. For example, if we look at _068 to _069, which gets an AdbByte:

function_068: ; address: 0x1d2 1d2: 9c5 call function_029[/FONT][/SIZE] [COLOR=rgb(65, 168, 95)][SIZE=3][FONT=courier new][B]1d3: bd4 goto function_069[/B][/FONT][/SIZE][/COLOR] [SIZE=3][FONT=courier new] function_069: ; address: 0x1d4 ; 1d4: 060 clrf INDF ; reg: 0x000 1d5: 9c5 call function_029 1d6: 120 iorwf INDF, F ; reg: 0x000 1d7: 360 rlf INDF, F ; reg: 0x000 1d8: 9c5 call function_029 1d9: 120 iorwf INDF, F ; reg: 0x000 1da: 360 rlf INDF, F ; reg: 0x000 1db: 9c5 call function_029 1dc: 120 iorwf INDF, F ; reg: 0x000 1dd: 360 rlf INDF, F ; reg: 0x000 1de: 9c5 call function_029 1df: 120 iorwf INDF, F ; reg: 0x000 1e0: 360 rlf INDF, F ; reg: 0x000 1e1: 9c5 call function_029 1e2: 120 iorwf INDF, F ; reg: 0x000 1e3: 360 rlf INDF, F ; reg: 0x000 1e4: 9c5 call function_029 1e5: 120 iorwf INDF, F ; reg: 0x000 1e6: 360 rlf INDF, F ; reg: 0x000 1e7: 9c5 call function_029 1e8: 120 iorwf INDF, F ; reg: 0x000 1e9: 360 rlf INDF, F ; reg: 0x000 1ea: 9c5 call function_029[/FONT][/SIZE] [COLOR=rgb(184, 49, 47)][SIZE=3][FONT=courier new][B]1eb: 120 iorwf INDF, F ; reg: 0x000 1ec: 3e4 incfsz FSR, F ; reg: 0x004 1ed: bd4 goto function_069[/B][/FONT][/SIZE][/COLOR] [SIZE=3][FONT=courier new]1ee: b37 goto function_050

The goto at 0x1db to the next line is a 2 cycle delay for timing purposes, but actually it adds 3 cycles including the clrf INDF. So, there's 3 cycles at the beginning of reading a byte. Yet there are only 2 cycles between each bit read. After reading a whole byte the code from 0x1eb to 0x1ed means there are 5 cycles between bytes (including the clrf INDF as before).

As it happens, I too have a Mac SE. However, it has a bust flyback transformer. I kinda want to interface my Mac SE to a VGA based LCD without having to use the flyback at all any more, but I also want to do it with a relatively simple MCU which generates VGA timings at CRT Macintosh frame rates at 1024 x 768 if that's possible. That is, each CRT scan from the SE is pixel-doubled to get 1024 pixels and similarly, the MCU would repeat that scan as well as adding a 21 scan margin at the top and bottom. If the MCU ends the Mac SE's frame at the bottom of the VGA scan, this would minimise how many scans need to be buffered at the top of the VGA frame (and a similar principle would work if a Mac SE's scan is faster than 2 VGA scan periods at 1024x768x60Hz). And I know there's a Raspberry PI + Expansion board CRT to VGA LCD converter, but these seems overkill to me, to use a computer a thousand x faster to convert a display for the SE.

Going back to the Adb PIC. What I'm thinking is that it might be useful to figure out a portable version, one that could work on an AVR or other MCU.
 

tashtari

PIC Whisperer
Going back to the Adb PIC. What I'm thinking is that it might be useful to figure out a portable version, one that could work on an AVR or other MCU.
My code (well, it's not exactly mine, it's a butchered version of Apple's) runs on a PIC16F87 or 88 - what purposes are you thinking of that would justify a port to another microcontroller? Don't let me stop you if you're looking for a project, mind, I'm just curious.
 

Snial

Well-known member
My code (well, it's not exactly mine, it's a butchered version of Apple's) runs on a PIC16F87 or 88 - what purposes are you thinking of that would justify a port to another microcontroller? Don't let me stop you if you're looking for a project, mind, I'm just curious.
Ha - you might do well to discourage me from another pointless project! OK, why port it to another MCU?
1. I'd love to claim some high-minded principle, but I'm afraid some of my motivation is that I don't like PICs much ;-) !
2. Having said that, I think there's something to be gained from transcribing the algorithm in more abstract and cleaner terms. e.g. the PIC16F87 could probably implement a much cleaner version as it's a far superior MCU. Or e.g. in the original version the memory fill routines just store W in IND and keep incrementing FSR until it gets to 0. But that only works on the '54, because FSR is a 5-bit reg + bits 5..7 =111₂. So, incrementing FSR when it's set to 0x1111111 => 0, so it doesn't trample on any of the other SFRs in a different reg bank. Also, I've seen some specs which imply ADB timing isn't that critical, though it might be on a PIC with no interrupts (aaah, see later, timing is +/-3% for host, +/-30% for devices).
3. Digital preservation. I guess this project exists, because some of the PICs are now failing, or have been overloaded by live-plugging ADB devices? The future might not have PIC16F87's to hand (or a Mac enthusiast might not), so it'd be handy to use whatever's to hand, e.g. an Arduino with an adapter board.
4. Apple used different ADB MCUs from the start. The Apple ||gs used an M50740AL.

1673046395709.png

Which was a Mitsubishi 8-bit device a lot like a 6502, but not exactly the same!


You can see on the data sheet, section 3, about 15% down that the ADB pin is connected to P27 and CNTR - a counter reg? Given all the other functions the chip handles, it must use interrupts and so can't be 100% cycle compatible with the Mac SE's PIC version.

Finally, I found a couple of useful articles for the protocol itself:



But primarily, this is simply interesting to me, so I've no idea if I'd take it any further.

-cheers from Julz
 

demik

Well-known member
3. Digital preservation. I guess this project exists, because some of the PICs are now failing, or have been overloaded by live-plugging ADB devices? The future might not have PIC16F87's to hand (or a Mac enthusiast might not), so it'd be handy to use whatever's to hand, e.g. an Arduino with an adapter board.

More like battery bombed.

IIRC the ||gs ADB controller is closer to the Portable / early PowerBooks ones. It's suspected to be a M50740 as well.
 

tashtari

PIC Whisperer
After remembering that the perfect is the enemy of the good-enough, I have released the current state of my annotation of the SE ADB controller firmware (along with the binary that is known to work).


Anyone willing to pick up the work of annotating the code where I left off is more than welcome to send me a PR. =)
 
Top