Retro Apple ][c Restoration

Reposted from blue forum.

I recently bought an Apple ][c off eBay. Been looking to get one of the old Apple systems for a while now. I guess this will be a blog of my misadventures with it. Either it will be toast or I will have a nice like new system and a bunch of games that I used to play. Do I know what I am doing? Who knows. Is this going to be a good blog? Probably not, I skip over quite a few things and probably wont document absolutely everything.

s-l1600

This one came working with no power supply, the original set of disks and manuals which was a surprise. The listing had a link to a youtube video which showed the system working, which was a neat idea.

Not having an CRT, i initially used an composite to HDMI converter and ran the video into a monitor. This only gives a black and white display however, something to do with how the Apple ][c generates the colours.
Good enough for now though. I also had a small LCD TV with RCA inputs, same result.

Step 1: Destroy it.
First point of call was to try and make a power supply for it. These computers have an internal DC-DC converter, and can take in from 9 to 20VDC. This is pretty nifty. They seemed to design it as a portable unit that can run from a battery.

I butchered an old universal laptop power supply, which can put out either 16 or 19v. I bought some cheap and nasty power plugs, 7 pin female DIN style and wired it up. Something went wrong though, and after initially having a play with one of the disks, it fails to boot up correctly, and sits at a screen of random characters. It appears you can reset it, but the system is not operating correctly.
Also, it was working quite strangely. When powering it off, the power would seem to surge and then the laptop power supply would switch off.

Time to open it up and investigate the power supply. Assuming caps might be dead, bugs in it or something else.

20190325_141443

Connected this up to my bench supply, and tested each output. It seems to be working fine. It outputs 12v, 5v and -12v, and can be switched on and off.
Worth noting I found a service manual for the Apple ][c, and it has some basic schematics for the main-board, and the pin-outs for the power supply.
Replaced the paste on the component at the back, and plonked it back in.
From now on I have been powering the unit straight from the bench supply. There is a handy reverse polarity protection diode, and I have been putting the supply voltage on that for now until I can make a decent supply.
The unit seems to be drawing quite a bit more power than it should, and still isn’t working. More than 2amps at 20v it seems.
The 5v rail is sitting just under 5v, and is used to supply all the chips. Some may have died during the power issues? Some felt a bit warm.
I tried reseating all the socketed ones to no avail.
Next I sprayed some isopropyl on them while running to see which ones are getting hot. And wouldn’t you know it.
MRD1, MRD7, ARD4 and ARD7 are quite toasty. They haven’t dragged the 5v rail down, but are boiling off the isopropyl much faster than other chips on the board. In a couple of seconds.

Step 2: Fix it.
I de-soldered each of these RAM chips using a combination of a solder sucker, wick and a lot of flux. I borrowed ARD5 and ARD6, to put down in MRD1 & MRD7. All without destroying the board, pads or the chips. I also ordered a bunch of new chips, as some others might be bad. I also ordered a new ROM, as I thought that might be bad before doing the moist test.

20190325_112840_res

So, after all that, I am happy to report it is booting again! It will even boot a disk, but programs tend to crash now. Perhaps due to bad ram, or lack of a few RAM chips.
You can initiate a Built-In Test (BIT) by holding open & close apple while booting. This flashes a few random screens up and them reports the following info:

20190325_130036_res

Step 3: Clean keyboard.

The keyboard, while functional, has some sticky keys and is a bit grubby. Also like the 8 Bit guy’s Apple ][c, the rubber sheet is falling to bits.

20190326_083255_res

I used a pair of small angled pliers to pry off all the keys, removed the rubber sheets, and scrubbed it down with isopropyl.

I scrubbed the keys down in a bowl with dish soap, removed the English sticker on the space bar.

20190326_092824

They came up not too bad. Had to let them dry for a while before re-assembling the keyboard. All of the switches work pretty well, and are usable. I may look at trying to replace some, or at least remove, open up and clean out internally. The enter key was a bit sticky, same with the Dvorak and 80 col toggle switches at the top.

20190326_131400_res

Put all the keys back on and tested by writing a small program. Of course I forgot to put this plastic sheet back under the keys, so will remove them all again at some stage.

Found a source for some floppy disks, out of the states. A pack of 50 should keep me going for a while.

Screen
Looking into the whole video output situation. This information might not be totally accurate, but is my understanding at this moment in time. Apple 2 did some funny stuff to generate colours. Some kind of wizardry from the Wizard of Woz. Pixels are stored 7 at a time in a byte in RAM. The remaining bit specifies which pallet. Odd pixels and even pixels are the different colours for the specified pallet. Two lit next to each other make both white. Not to mention the 64:1 interlacing. This is all without getting into the double high res.
It seems they designed the Apple 2 to output NTSC. It generates the colours by doing some kind of trickery that doesn’t conform well enough to standards. The PAL versions of the computer only output black & white through the composite port. However, this model has an additional video out port, that exposes a bunch of digital lines. Some people have made their own hardware to convert this output to component yCbCr, but that wont work for me. I am thinking I can make my own adapter to output VGA. There were adapters made back in the day to output proper PAL, but they are probably rare as hens teeth now.
VGA sounds complex, but it is pretty easy to understand. You have two sync lines, one vertical for each page refresh, and one horizontal for each line refresh. Then independent RGB lines containing the colour and intensity information. This would be much easier to generate than some kind of component colour space, where they store intensity and colour information separately to cut down on information.
I already have access to line sync pulses, and intensity pulses for each pixel. Might even be page sync pulses, need to wait for my cheap $10 logic analyser to arrive. Once i find the info I need, need to translate the sync pulses to the right levels/polarity/duration, and see what happens!
Maybe a monitor will display it, maybe it wont because it doesn’t conform to a predetermined resolution.

RAM:
My replacement RAM chips, sockets and some other stuff finally come in. I spent some time de-soldering all of the current chips and installing IC sockets in their places. This should make it relatively easy to swap chips out in the future.
Although, the sockets I got were really cheap and nasty ones off eBay. They still have clips that contact the IC legs from the inside and outside, just very thin and prone to breaking.

20190425_122046_res

This finally solved the RAM BIT failure. As it turns out, the errors it was reporting was on the aux bank. It seems to test the main bank first, than the aux bank putting the asterix there for any errors. So it was telling my AR5 and AR7, as well as AR0 were bad. You kind of keep replacing the chips until the errors go away, due to the interlaced nature of ram addressing.

The bits came in for the serial cable also. A standard USB-RS232 serial cable. I hacked up a RS232 extension cable, got a 5 pin DIN 180 degree plug and wired it up. Now I can use the amazing ATDPro (http://www.adtpro.com/) to copy disk images from a computer directly to the computer, to a blank disk. This solves the major problem of how does I use it. Once the cable is connected, you sort of redirect the serial input to main PC, and the program takes over writing a small boot-loader directly into the computer memory.

20190425_131859_res

I also downloaded and ran an Apple II service disk, and did another RAM, ROM and disk drive test. All checks out.

  • Joystick / Gamepad
    Pretty easy to make, just a 150k potentiometer joystick module and some buttons + resistors. 150k potentiometer joysticks are really rare, but some clever people (http://quinndunki.com/blondihacks/?p=2225) have looked at the Apple IIc schematics, and figured out you can use different sized potentiometer as long as you add capacitors to balance out the flipflop discharge timing. Yes this was before you had micro-controllers with nice easy to use ADC built in. The apple uses a monostable flipflop to measure the joystick positions. Must be annoying for game programmers, having to burn all that time waiting for the joystick.
    Knocked up a prototype, seems to work fine. It is hard to get the right amount of capacitance to offset the resistance of the joysticks. You want the center position and the limit of the axis to be roughly right. Luckily the games don’t care too much, and close enough is good enough.

Prototype:
20190713_113628%20(2)

Schematic & Board:
sch
brd
I have no idea which was the axis go, so I added the links which can be bridged with solder in-case I need to invert an axis. If somehow I mix the axis up, I just just swap the wires going into the board.

When I fix 3d printer (again) I can make a case, and then design and etch a proper PCB.

Next Steps:

  • Colour Output
    Have some bits for this. The model I have is the PAL one, which only outputs black & white on the video port. All colour was generated by messing with NTSC signals anyway, wouldn’t work on PAL. However there is a video expander port, which outputs information in a digital form. I figure it may be possible to build a VGA output from this. I have ordered a tinyFPGA board, will play with this. See if it can handle the job.

  • New power supply, again.
    It seems to draw a bit more than the rated power. Might try and use a beefier one than last time. I have a bunch of old laptop universal supplies lying around. Will probably try and canabalise another one. Also need to find a nice female DIN style plug that won’t immediately fall to bits as soon as I try and use it. I got some cheap ones off eBay, which fall to bits as soon as you try and use them. The plug is a tight fit.
    Since the computer was sort of designed to be portable, it can handle a wide input range of like 12-20VDC or so.

6 Likes

reserved

1 Like

One day

Playing with an tinyFPGA BX to try and make a video converter.
I think I stuffed up, they come with a 16MHZ clock. I should see if I can swap this out for a 25Mhz one, which will be nicer for producing 640x480 VGA resolution, since it is a close match to the pixel clock.

Since I am running 16Mhz, I should still be able to generate good enough sync pulses, I just won’t have a 1:1 pixel resolution at 640x480. Maybe I can invent a new resolution, will depend on how tolerant my monitors/TVs are.

So, for 16Mhz, I will have a H sync of 30Khz and a V sync of 60Hz. This gives me total 533.33 pixels per line, 500 lines per frame if I calculated everything right. Hopefully this will be close enough for a screen to try and display it. If not, I can tweak it until I get something. For now, looking at the output on a scope.

I looked at some tutorials, and followed their lead a bit. I am a bit stuck because I don’t know this language at all, and am just blundering through it. The Hsync pulses are happening like I want, but I get no Vsync pulses. Not even sure if the CounterY is counting, I don’t think it is. :thinking:

20190727_114853
The picture is a little blurry, I am just measuring the period of the Hsync pulse, which is 4us. Going for a near enough is good enough here, that’s the way with electronics.

module VGA(
  input CLK,
  output vga_h_sync,
  output vga_v_sync,
  output vga_R,
  output vga_G,
  output vga_B
);

reg [9:0] CounterX; //Counter for lines, in "pixels".
reg [9:0] CounterY; //Counter for frame, in lines.
reg vga_HS; // Store the state of the Hsync
reg vga_VS; // Store the state of the Vsync
wire CounterXmaxed = (CounterX==533); //Flag for the end of the line
wire CounterYmaxed = (CounterY==500); //flag for the end of the frame

//Now do stuff
always @(posedge CLK)
if(CounterXmaxed)
  CounterX <= 0;  //reset pixel counter when hit the end
else
  CounterX <= CounterX + 1; //increment pixel count

always @(posedge CLK)
if(CounterXmaxed)
  CounterY <= CounterY + 1; //Hit end of line, increment line counter

always @(posedge CLK)
if(CounterYmaxed) 
  CounterY <= 0; //hit end of frame, reset line counter

always @(posedge CLK)
begin
  vga_HS <= (CounterX[9:6]==0);   //Generate sync pulse for 4us
  vga_VS <= (CounterY[9:1]==0);   //Supposed to generate v sync pulse for 2 lines, does nothing?
end

assign vga_h_sync = ~vga_HS;  //Output invert of pulse
assign vga_v_sync = ~vga_VS;

//Generate some RGB values, not important right now.
assign vga_R = CounterY[3] | (CounterX==256);
assign vga_G = (CounterX[5] ^ CounterX[6]) | (CounterX==256);
assign vga_B = CounterX[4] | (CounterX==256);

endmodule
1 Like

Well fixed the above issues and am now getting up a test pattern. It’s a start.
Well, it works on a monitor, but not on a small tv. Guess it is pretty custom.

I threw away some more code I found in the tutorial and did it my own way a bit. No way optimised.
I dumped the CounterY var, and just run CounterX right up until horizontal pixels * v lines.
Then used divide and modulus to find the H and V sync pulses, and now they both show up. I had to tweak the timing a bit, turns out I was trying to drive 500fps!

So, now, 512x512 pixels at ~61 Hz. Seems stable!

16MHz pixel clock.
512x512 total resolution, including porches etc.
This gives 31.25KHz x 61.04Hz H & V refresh rates.

I manually tweaked the display bounds, it seems we have about 412x490 viewable pixels? I may need more pixels horizontally, so will refine this further over time.

VGA

The top yellow line is the H sync pulse, bottom is a vertical sync pulse.

I know I should dump the modulus operators into a variable or something, but it’s an FPGA, how much does it matter?

module VGA(
  input CLK,
  output vga_h_sync,
  output vga_v_sync,
  output vga_R,
  output vga_G,
  output vga_B
);

reg [20:0] CounterX; //Counter for lines, in "pixels".
reg vga_HS; // Store the state of the Hsync
reg vga_VS; // Store the state of the Vsync
wire CounterXmaxed = (CounterX == 262144); //Flag for the end of the line
reg inDisplayArea;
//Now do stuff

always @(posedge CLK)
if(CounterXmaxed)
	CounterX <= 0;
else
	CounterX <= CounterX + 1;

always @(posedge CLK)
begin
  vga_HS <= ((CounterX % 512) <= 64);   //Generate sync pulse for 4us
  vga_VS <= ((CounterX / 512) == 0);   //Supposed to generate v sync pulse for 2 lines, does nothing?
end

always @(posedge CLK)
  inDisplayArea <= (((CounterX % 512) >= 100) && ((CounterX % 512) <= 500)) && (((CounterX / 512) >= 20) && ((CounterX / 512) <= 510));

assign vga_h_sync = ~vga_HS;  //Output invert of pulse
assign vga_v_sync = ~vga_VS;

//Generate some RGB values, not important right now.
assign vga_R = inDisplayArea && ((CounterX % 512) % 8) && ((CounterX / 512) % 8);
assign vga_G = inDisplayArea && ((CounterX % 512) % 8) && ((CounterX / 512) % 8);
assign vga_B = inDisplayArea && ((CounterX % 512) % 8) && ((CounterX / 512) % 8);

endmodule
3 Likes

> blu forum bange

otherwise :+1: nice read

fucking love FPGA stuff, can you give me the full name for that FPGA? @ArgGrr

3 Likes

Well not knowing anything about it all, I saw these mentioned some place:
https://tinyfpga.com/
I grabbed a couple of the bx ones from the store further down the page. It seemed like it might suit my purposes.

I followed some tutorials here, esp the pong one to get started on VGA out:
https://www.fpga4fun.com/PongGame.html

Not used to programming them, I still try and write computer programs rather than design hardware in code, if that makes sense.

They are 3.3v logic, so I have ordered a logic level converter to drop the mostly 5v logic output from the apple down to 3.3v for the FPGA. Things are a bit fast to use voltage dividers, esp the 14Mhz clock. Actually the 14M signal is like 6v peak to peak, so I will try and run that through a buffer xor gate to get it down to nice 5v square wave first.

Hmm I could do a new logo… L1 was an age ago it seems now.

1 Like

Ah yeah those are those Lattice based Open-Sauce ones? Great!

They chips are lettuce ones, but I can’t tell you much more than that. I don’t really know. The boards are open source, all on github and hackaday.

Playing around trying to get the data from the expansion port down to 3.3v logic levels.
I am having trouble with the 14MHz clock signal though, it doesn’t translate cleanly. Firstly, it is a bit more than 5v and swings negative about a volt, which is interesting. I can’t run it through a signal diode, that just trashes it for reasons unknown to me. It shouldn’t be too fast for the old 1n4148, according to the datasheet. Would drop it .7v and cut the negative part, if it worked. :confounded:
Also tried feed it through a NOR gate as a way to buffer it, but it also seems to give poor results. Probably because signal coming in swings higher than VCC, and goes negative.

I need to go and find another way to deal with this.
The 5-3.3v logic level converter seems to be working ok for the other signals.

I intend to use the 14Mhz as the clock in the FPGA, and convert the 4bit serial pixel data into RGB data out, hopefully the monitor will display something. I mean I can feed it all in and pick and choose what I want.
There is also a blanking signal which I can use, save me trying to calculate it on the fly.

2 Likes

I think the clock is ok, on the board at least. I could always replace the quartz resonator if needed, but once I set the scope up properly, calibrated the probe capacitance using the test point on the meter, set them to x10, and measure close to the clock, I get a clock that would be usable.

clock

It just isn’t usable at the end of the cable I made. The manual mentions you need to buffer it within 10cm of the plug, due to the added impedance messing with it. I have ordered one of these, will see if I can wire up something closer.
image

2 Likes