• 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.

SE/30 (and others) RTC Replacement / Emulator with ATTiny85

trickydee

Member
I'm happy to have a play around here.
I actually have two IIGS' I purchased the second to replace the one with the faulty clock chip, and then found it had its own problems ;-).
I must admit I don't full understand the relationship between the settings (pram?) store part of the chip and clock 1sec logic. When my IIGS was faulty The settings store continued to work but I could see no signals on the clock circuit (pins 1 or 2 or 3) - the IIGS was still happy to run.
With the tiny85 in place I get no clock pulse or settings being stored.

I've achieved my aim getting the IIGS working but I can see that other people have had similar issues (there is a specific error in the IIGS selftest that is clock related) - so I am more than happy to do some further testing/debugging here - I can purchase an Arduino if needed. That's if you have the time as well Phil.

In the meantime I will also try one of the other clock projects to see if SE aligned timing is better.


One final thing - I haven't ruled out that the issue is my inexperience with the tiny85's, I tried programming the the micronucleus Bootloader and use the USB adapter - but the tiny was still not recognised.
 
Last edited:

pgreenland

Well-known member
Awesome!

PRAM and clock pulse wise. The PRAM is used to store and maintain the system time/date, along with a load of other basic settings, like volume, mouse speed, keyboard repeat delay. Usual sort of OS things. I'm sure others could confirm but the one second pulse line would likely be used by the mac to update its internal copy of the time. A typical approach would be to read the RTC at startup and then continue incrementing a copy in the system's RAM in response to the one second pulse. It might be fun to try disabling the pulse and seeing if the clock in the status bar is still updating.

Giving the other solutions a go sounds like a plan. Try to rule out whether the software is to blame (wouldn't rule it out) or something went wrong when programming / configuring the chip.

Bootloader wise, the code in my repo is prepared to be programmed directly to the AtTiny without a bootloader. It almost certainly wouldn't play nicely being loaded through a bootloader....not that I've tried. The T48 should happily program the hex file, overwriting a bootloader if there was one present.

Arduino wise, any 5v Atmega based one would be fine. I've been using an uno as its what I had lying around: https://store.arduino.cc/products/arduino-uno-rev3 - The genuine ones are quite pricey. While its nice to support the creator.....the clones are quite a bit cheaper and they're all pretty much the same. If you grabbed one, the only other thing you'd need would be 3 x 1k (any highish value) resistors and some jumper leads or similar to connect the ATTiny to the Arduino.

Let me know if you order one and I'll prepare some notes and tidy up the test code for you. The test code may be useful to others too, its not specially testing my code, it quite happily tests a genuine clock chip too :)
 

trickydee

Member
@pgreenland
Sorry for the tardy response. Its been a while but tonight I managed to find some free time to investigate the AtTinyRTC in my Apple IIGS. And I now know the cause of the issue.

I connected up my logic analyser to the Tinys pin 1 - for the '1Sec' signal. With the original apple RTC I could see that each tick is exactly 1Second as it should be, with the Tiny I could see the 1Sec signal was 3.88 Seconds.

I tried some of the other firmwares to see if they improved things, but in most cases they didn't work at all. After switching back to your code I also found the Tiny didn't work !.

But then I removed the IIGS 3.6v clock battery, and powered on with it removed - the AtTiny then worked perfectly!, as did the saving to slots.
I verified multiple times, whenever the IIGS clock is in place the Tiny either doesn't work or has very strange clock intervals.
I tried inserting the Battery after a battery less boot and the machine worked fine - once power was removed and then reconnected the Tiny was again not working.

Could It be the IIGS battery circuit doesn't have enough juice to run the Tiny when the powers removed?
 

pgreenland

Well-known member
@pgreenland
Sorry for the tardy response. Its been a while but tonight I managed to find some free time to investigate the AtTinyRTC in my Apple IIGS. And I now know the cause of the issue.

I connected up my logic analyser to the Tinys pin 1 - for the '1Sec' signal. With the original apple RTC I could see that each tick is exactly 1Second as it should be, with the Tiny I could see the 1Sec signal was 3.88 Seconds.

I tried some of the other firmwares to see if they improved things, but in most cases they didn't work at all. After switching back to your code I also found the Tiny didn't work !.

But then I removed the IIGS 3.6v clock battery, and powered on with it removed - the AtTiny then worked perfectly!, as did the saving to slots.
I verified multiple times, whenever the IIGS clock is in place the Tiny either doesn't work or has very strange clock intervals.
I tried inserting the Battery after a battery less boot and the machine worked fine - once power was removed and then reconnected the Tiny was again not working.

Could It be the IIGS battery circuit doesn't have enough juice to run the Tiny when the powers removed?
Hey,

Good to heard that you're making progress of sorts.

I've not tried it with a battery myself. All of my machines are battery bombed unfortunately (oh to have a working battery holder :p ), which is partly why I was interested in a microcontroller replacement.

Looking at the datasheet: https://ww1.microchip.com/downloads...ller-attiny25-attiny45-attiny85_datasheet.pdf

Specifically "Speed Grade", "ATtiny25/45/85: 0 – 10 MHz @ 2.7 - 5.5V, 0 - 20 MHz @ 4.5 - 5.5V". There's a larger diagram on page 163.

The AtTiny85 is having to run at 16Mhz to keep up with the faster signalling in the SE/30. I'm assuming it's the same on the IIGS. If you fancy playing with your logic analyser again, possibly capture a sample of the data and clock lines?

At 3.6v on battery power we're going to be below the voltage range for operation at 16Mhz.

As the config is set by fuses rather than software, I don't think there's a way to switch clock source during sleep. Although this site hints that theres enough range in the internal oscillator calibration to slow it down quite a bit: http://www.technoblogy.com/show?1ZIY

When I get a moment I'll drop my little test tiny on a bench power supply and see how it behaves at different voltages + what sort of current it draws.

Thanks,

Phil
 

trickydee

Member
Hi Phil,
Sure I can capture some traces on the IIGS, my analyser is a cheap USB dongle so it's not high speed. Do you want me to capture the data and clock for both mains powered and battery ?
Also I compiled a build with EEPROM store enabled, but I noticed that although it allowed changing the IIGS' slot settings while powered on, it didn't store the values after a power cycle. I need to do some investigation to see what capacity the IIGS clock chip had for params, I would imagine its more aligned with the original Mac than the SE/30 due to it age.

Thanks again for your help.

Rich
 

pgreenland

Well-known member
Hey Rich,

Yep that would be perfect. If you've got enough channels, capturing the clock, data, select line and one second line would be good.

If you've got one of the Saleae Logic clones, the Saleae file would be easiest. If its a sigrok supported one, that works too :)

I've just had a go running my poor tortured AtTiny85 at 3v (in fact all the way down to 2.5v). It seems to keep producing the one second interrupt ok. Although operating outside the official specs it's a little on the edge.

It does however use quite a bit of power (for an RTC anyway).

At 5v its pulling an average of 6mA which is looking about right according to the datasheet.

At 3v (aka battery power), it drops to 3mA which is going to drain any RTC battery....even the big old barrel ones that the macs have pretty quickly.

I can't see many other options to reduce the power, other than running it slower. The closest I've come is tweaking the way the one second timer is handled to reduce how often the chip wakes up.

I took a look for more modern / efficient chips but couldn't find anything else with the right pinout.

It may turn out that a battery backed RTC with the ATTiny isn't all that possible.

Thanks,

Phil
 

Snial

Well-known member
I haven't looked at the code yet, but it's worth remembering that if this is still an Arduino sketch running on at ATTINY85, then I suspect the millisecond interrupt will cause significant interrupt latencies from time to time. This is because it's non-trivial on arduino, the timer interrupt for the 16MHz clock is prescaled to give a 1024Hz interrupt and some fractional math is then applied to skip 24 interrupts in every 1024 interrupts. You ought to turn the millisecond timer off and use a different method to measure those kinds of time periods.

The second thing to note is that when compiling an interrupt using gcc, if your interrupt code calls any other function, then the interrupt handler will push pretty much every register rather than just the registers used in the function: that's roughly 30-odd registers, which adds about 4µs to the handler. How fast did you say the clock speed was... 250kHz (==4µs cycle time) right? Oops!

I wrote a tool for my DIY computer FIGnition which does a proper analysis of AVR interrupt function dependancies so that only the necessary registers get pushed and popped: basically, you compile to assembler along with any dependent functions; put it though my tool, which adjusts the registers pushed in the interrupt routine; then you compile the assembler code to object code.
 

pgreenland

Well-known member
I haven't looked at the code yet, but it's worth remembering that if this is still an Arduino sketch running on at ATTINY85, then I suspect the millisecond interrupt will cause significant interrupt latencies from time to time. This is because it's non-trivial on arduino, the timer interrupt for the 16MHz clock is prescaled to give a 1024Hz interrupt and some fractional math is then applied to skip 24 interrupts in every 1024 interrupts. You ought to turn the millisecond timer off and use a different method to measure those kinds of time periods.

The second thing to note is that when compiling an interrupt using gcc, if your interrupt code calls any other function, then the interrupt handler will push pretty much every register rather than just the registers used in the function: that's roughly 30-odd registers, which adds about 4µs to the handler. How fast did you say the clock speed was... 250kHz (==4µs cycle time) right? Oops!

I wrote a tool for my DIY computer FIGnition which does a proper analysis of AVR interrupt function dependancies so that only the necessary registers get pushed and popped: basically, you compile to assembler along with any dependent functions; put it though my tool, which adjusts the registers pushed in the interrupt routine; then you compile the assembler code to object code.
Thanks for the tips....might want to take a look at the code though. FIGnition looks cool.....rather than writing your own optimiser did you consider asking GCC to optimise for you?....compilers tend to be good at that sort of thing if you twiddle the right switches.
 

Bolle

Well-known member
From the readme on github... what does this exactly mean?
"An effort has been made to limit the EEPROM writes. With only updates being written, and update only being considered when the RTC is marked as read-only by the host."
Is it possible the IIfx does something different than the SE/30, because I can't seem to get it to remember the PRAM settings without a battery.
The same module does it just fine when I stick it into an SE/30.
 

pgreenland

Well-known member
From the readme on github... what does this exactly mean?
"An effort has been made to limit the EEPROM writes. With only updates being written, and update only being considered when the RTC is marked as read-only by the host."
Is it possible the IIfx does something different than the SE/30, because I can't seem to get it to remember the PRAM settings without a battery.
The same module does it just fine when I stick it into an SE/30.
Hey,

It may well work differently on the different families. I've only been able to test on SE/30's myself (only machines in my collection....so far).

Inside Macintosh Volume III, page 37 https://vintageapple.org/inside_o/pdf/Inside_Macintosh_Volume_III_1985.pdf contains a description of the RTC protocol and registers. There's a write-protect register listed.

Monitoring the comms on the SE/30, it appeared that more often than not the RTC would be marked as writable before a bunch of transfers, then write-protected after. The RTC would seemingly always be marked as write protected at shutdown.

All of the emulated registers exist in a shadow copy in RAM, primarily for speed. When write-protect is asserted, the module writes any updates back to the EEPROM (if enabled).

The theory being that a few writes to the EEPROM may be saved, whether that works in practice is hard to tell.

You may well be right that the IIfx does something different.

In terms of battery powered, I've not used this myself, I was quite happy with just the parameters being stored and clock pausing when powered down. All the SE/30's I've got have battery damage around the RTC. Did a little testing above and suspect the ATTiny's current draw is too high to run for long with a battery. I've got one real Apple RTC kicking around somewhere, so may check its standby current when I get a mo.

If you've got access to a logic analyser, drop me a copy of the comms (clock, data and enable). Ideally from boot, change a setting and shutdown. Happy to take a look.

Alternatively I could do a build with that feature disabled?. Have the EEPROM written ASAP when the RTC's registers are written to for now.

Thanks,

Phil
 

trickydee

Member
Hi Phil,

Sorry for the delay in getting back to you. I've created a number of pulseview captures of the Apple IIgs' interactions with the attiny (8Mhz sample rate), I've only captured the clock, data and enable pins - I hope that's enough?, lmk if you need more info.
The captures show machine boot, enter setup, setup slot config for both original RTC and attiny.
Reading your response to Bolle above I wonder if the IIgs is also using the chip in a different manner? To me it looks like it accessed the data pins irrespective of config changing.

Regards

Rich
 

Attachments

  • Apple IIgs - attiny replacement rtc debug.zip
    135.1 KB · Views: 5

pgreenland

Well-known member
Hi Phil,

Sorry for the delay in getting back to you. I've created a number of pulseview captures of the Apple IIgs' interactions with the attiny (8Mhz sample rate), I've only captured the clock, data and enable pins - I hope that's enough?, lmk if you need more info.
The captures show machine boot, enter setup, setup slot config for both original RTC and attiny.
Reading your response to Bolle above I wonder if the IIgs is also using the chip in a different manner? To me it looks like it accessed the data pins irrespective of config changing.

Regards

Rich
Thanks Rich, captures look good. Will let you know if I spot anything. As soon as a find a the time to look at them.

Thanks,

Phil
 

pgreenland

Well-known member
Have taken an initial look.

The behaviour appears to be quite different to the SE/30 when it comes to the write protect register.

The SE/30 was seemingly writing to the register all the time, which is why I chose to use it as a means of attempting to save on EEPROM wear and tear. The IIGS appears to barely touch it.

I compared the original vs attiny startup's and settings changes. During startup the registers accessed appear to be largely the same, however in the case of the attiny it performs a read followed by a lot of writes. It looks like it decides the rtc ram is not initialised and so attempts to clear it all.

It doesn't access the write protection register before doing this, so I'd assume (will check on my one working SE/30 RTC that the protection is disabled at startup....when I find it).

Right at the end of the startup sequence the value 0x55 is written to the write protection register, which I don't believe I've seen the SE/30 do.

The inside macintosh manual says:
If the high-order bit (bit 7) of the write-protect register is set, this prevents writing into any other register on the clock chip (including parameter RAM). Clearing the bit allows you to change any values in any registers on the chip. Don't try to read from this register; it's a write-only register.
Which is what the code currently follows, in which case 0x55 wouldn't have bit 7 set and so be read-write mode.

Your captures showing changing of settings didn't appear to touch the write protection register.

If your capture setup was easy to hook up, a capture of the two chips when the system is shutdown would be good. I'd be interested to see if the write protect register is every written to.

I've had a go tweaking the code to operate on a timeout, rather than the write-protection register. Whenever the emulated PRAM inside the attiny is written, 3 seconds later the EEPROM will be updated with any changes.

I've also tweaked the default write protection status to be off rather than on based on what I've seen in the traces.

Along with the main two, there's a few other tweaks I was trialing for someone else, a small delay at startup hoping to avoid any power on glitches. Along with writing the time back to the EEPROM once per minute. The latter I expect would be useful when running without a battery in the IIGS.

If you'd like to try it I've pushed it to https://github.com/pgreenland/attinyrtc/tree/write_on_timeout - let me know if you'd like me to build / make a binary available somewhere.

I've not had a chance to test it on my SE/30 yet but will when I start playing with it next.

Thanks,

Phil
 

Bolle

Well-known member
Could you implement the same changes in the AttinyRTCmodule code as well so I can try if that helps with the problems I've got with it in the IIfx

because:
I compared the original vs attiny startup's and settings changes. During startup the registers accessed appear to be largely the same, however in the case of the attiny it performs a read followed by a lot of writes. It looks like it decides the rtc ram is not initialised and so attempts to clear it all.
...sounds a lot like what the IIfx is doing as well. Even if I take a module over from the SE/30 and plug it into the IIfx all settings will revert to their defaults.
 

pgreenland

Well-known member
Could you implement the same changes in the AttinyRTCmodule code as well so I can try if that helps with the problems I've got with it in the IIfx

because:

...sounds a lot like what the IIfx is doing as well. Even if I take a module over from the SE/30 and plug it into the IIfx all settings will revert to their defaults.
Sure thing, didn't realise you were using the other module:


I've applied exactly the same changes as with the single chip solution.

Will test on my SE/30 when I'm tinkering with it next, in the meantime let me know how you get on!
 
Top