Atari BadSector "A" Project Diary
I used a plug in breadboard to connect up the
for the first time. The intention was to try out the Atmel
programmer software. This software was found after searching the web
and emailing the author of the programmer and asking him to restore the
web page! A minimal set of components were wired up. A 7805 voltage regulator
was used to generate the 5V for the circuit. It was powered by the 12V
line of a PC power supply. The use of a regulator makes the circuit more
flexible with respect to which power sources can be used. A 16MHz crystal
and two 33pF capacitors were connected to make the clock circuit. A set
of 5 wires were connected up to an already existing parallel port cable.
The programming pins: Reset; MISO; MOSI; and Sck together with a ground
wire were connected up. I didn't even bother with the 100ohm resistors,
but they were intended to be inserted at the PC end of the cable, which
was impossible for me since I was using a printer port cable which I had
already put together for my PIC programmer. The circuit didn't originally
work and the following software <binary,source>
was used to debug the printer port connections. After examination of the
programmer source code it was discovered that the documentation had the
reset pin connected to the wrong pin on the parallel port cable. Once this
was fixed the circuit partially worked. When the logic probe used to check
for signal activity was held on the sck pin the circuit appeared to work
correctly allowing a small amount of data to be programmed and verified.
The fix was to load the reset pin with a 2200pF capacitor. I really should
use a scope at some point to properly understand why this allows the circuit
to work. A suspicion is ringing on the Sck signal.
I visited Maplin
Electronics and bought some IDC cable connectors. One 2x20 way for
the IDE drive connector and one 13x2 way to match the connector at the
end of my parallel port cable.
Nowadays the local Maplin shop is a joke. The
number of electronics components they have in stock is laughable. They
seem to be moving more into the mainstream, selling PC parts, radio control,
disco lights, tools and the like. They sadly remind me of Tandy shops.
Each time a new Maplin catalogue is released, the smaller the number of
real electronics components becomes. I guess this is only a reflection
on the demise of the electronics hobbyist in the UK :-(.
I continued to draw schematic using a demo version
of Orcad for Windows. The chip count
is now four. I think that it should be possible to code this application
only using internal RAM. The AT89S53 only has 256 bytes, but this should
be more than enough. There isn't space to buffer the data coming from the
IDE drive, so it is hoped that grabbing the data from the drive isn't time
critical, however to make sure that the development board is flexible enough
I decided to add 8k bytes of static RAM as I have plenty available. I use
the 74HCT573 octal latch rather than the more normal 74HCT373 since the
pinout is far better organised. All the inputs are on one side and the
outputs on the other. This matches up with the AT89S53 databus pins rather
Made more progress with the schematic. Added
the MAX232 RS232 interface chip and connections. Added the printer in-circuit
programmer connector. Time to start construction. The intention was to
build a circuit with just the AT89S53, crystal, and MAX232 in order to
test the in-circuit programming circuit and perhaps run a small program
to send data out of the RS232 port. Once the circuit was built and tested
with the programming software, the interface was failing intermittently.
I checked the signals using a scope and tried several things to try to
clean up the signals (although they looked OK). I decided to go back to
the plug in board. When I tried the programming software it ran reliably.
The crystal used on the circuit board was 11MHz, whereas the one used on
the breadboard was 16MHz (a random selection from my crystal drawer). I
tried a number of crystals on the breadboard and found that anything 11MHz
and lower would not work. I therefore suspected a timing problem in the
programming software. The author of the programming software included full
source code and from previous inspection I knew that there was code to
slow down the interface. So I loaded up Visual C for the first time and
loaded the programming source code. I uncommented a #define to
slow the interface down, and had a play around in the send0()
and send1() functions. I recompiled, copied over to my other PC,
and tried out again. To cut a long story short, I eventually got the programmer
to work reliably with the processor clocked by the 11MHz crystal. I went
back to the circuit board, re-soldered a wire which I had disconnected
as part of my experiments, and the circuit board started to work reliably.
A quick note about my setup. On my main computer
(alma) I am running Windows 95. I use gvim to edit my code (it has colour
syntax highlighting). My second PC (electro) runs Windows 98. It is a less
powerful PC and has a small Nec 3D monitor. It holds my EPROM programmer
ISA card and has the printer port dedicated for use for my PIC programmer
or EPROM emulator (both home made). It now is used for the Atmel in-circuit
programmer. They are networked together using cheap 100Mb/s PCI ethernet
cards and a hub. The in-circuit programming software is installed on electro.
I use the TELIX DOS program as comms software running on electro.
At some time in the dim and distant past I downloaded
a freeware C compiler for the 8051 family called SDCC. A more recent search
on the web brought to light the existance of a much newer version of this
program. I downloaded the binaries which had been compiled using Borland
C to run in a DOS window. Following a link from the main SDCC
page on Sorceforge brought me to the "SDCC
Open Knowledge Web Site" which contained sample code. Of interest was
the code to operate the 8051 comms port using interrupts.
I only spent an hour or so late Sunday evening
having a play with SDCC. The sample program vs5.c looks like a
good candidate to try. It is a very short program which performs some serial
comms. This is exactly what I need to check out the hardware. When I try
to compile it with the SDCC compiler I get a couple of linker warnings.
Two library routines are not been found. I suspect that I am missing some
libraries. I have no documentation. The ZIP file which I downloaded contained
only the Borland C compiled binaries and no documentation and no other
support files (such as libraries). Despite these warnings an Intelhex file
has been created. I surf the web to find an Intel
hex to binary converter, as the in-circuit programmer software only
supports binary files. I fire up electro and power up the development board.
I copy the vs5.bin binary file over to electro and then program
the AT89S53. I hit the reset button to reset the processor, but monitoring
the tx pin with a logic probe see no activity at all. Time to go to bed!
I had a very frustrating time messing around with
SDCC. I downloaded the SDCC sources from Sourceforge as I now know that
they contain the missing libraries. I tried several ways to get around
the linker warnings which I was getting. I suspect that the library files
have to be found in a specific directory. I found that if the .c
program was compiled one of the temporary files created was a .lnk
file which appeared to be used by the linker. I edited this file to change
the directory string to the one where my library files were. I could then
successfully run the linker. I also found that if the -L option of the
SDCC compiler is used to point to the library then this also works. It
makes the command line a little long. There must be a better way.
I surfed the web at work today and found useful information
about the installation of SDCC. I also tried to compile the SDCC sources
at work on a Sun workstation with mixed success. I eventually got SDCC
itself to compile. I now have a good idea why the installation on my PC
isn't working. I moved some directories around on my PC. I grepped some
of the SDCC sources to try to determine where the program was trying to
find the default libraries and include files. Looking at some C sources
and the makefile all became clear. I created the following directories
on my C: drive (it must be this drive).
Also note that any .c programs you compile
must also be on the C: drive. I compiled
an example serial comms program called vs5.c. This time there
were no error messages. This program does simple interrupt driven serial
IO at 19200 baud. It prints out an ASCII message then echoes everything
received on the rx input back to the tx output. The at8252.h include file
was correctly found in the /sdcc/share/include directory and the
small model library files were also correctly located. I used a program
called hex2bin to convert the .ihx Intel hex file into
pure binary. On electro I opened the directory on alma where the vs5.bin
binary was found and (copied it into the clipboard). I then pasted it into
the local directory where the in-circuit programming software is. I then
entered the name in the software (shame there is no file selector) and
hit the program button. The device programmed successfully. The device
was then verified. All OK. I loaded up an old DOS comms program called
TELIX on electro and connected the RS232 connector to the MAX232 on the
development circuit board. After messing around with wires and working
out which pin on the DB9 connector needed to be connected to the Tx pin
on the MAX232, the reset button on the in-circuit programming software
was pressed which toggles the AT89S53 reset pin. The expected ASCII message
appeared in the TELIX window. Success!
/sdcc/bin - this is where the Borland compiled
binaries are (this particular directory is not important).
/sdcc/share/include - this is where the
.h include files must be.
/sdcc/share/lib/src - this is where the
source .c files for the libraries are. I created a small.bat and
large.bat batch file to compile all the sources, one for the small model
(sdcc -c --model-small file.c) and one for the large model (sdcc
-c --model-large file.c). One file was compiled on every line. I couldn't
get the supplied makefile to work.
/sdcc/share/lib/small - this is where the
compiled small model library files must be.
/sdcc/share/lib/small - this is where the
compiled large model library files must be.
I fired up Orcad and wired up the IDE connector.
I am only using the bottom 8 bits of a 16 bit bus. This should be OK. The
commands are only 8 bits wide, and the intention is to "waste" the upper
8 bits of data. So each 512 byte (256 x 16bits) sector will only hold 256
bytes. This fits in fine with the way Atari drives are formatted for double
density. For reference single density Atari floppy disk drive sectors can
only hold 128 bytes. I then fired up my soldering iron and wired up the
remaining chips and IDE connector. Only the address bus of the RAM chip
remains to be connected. The IDE connector is fully wired up, so in theory
I can now play around with accessing an IDE drive itself.
I created my own program called ide.c
based on vs5.c with only some very minor changes. Imagine my surprise
when the program didn't work correctly and the text string printed to the
RS232 terminal was garbled. After much frustration in tracking this problem
down I decided to try some other serial port driver code from the SDCC
library. This new code worked. So the presumption is that the vs5.c
code is buggy in some way. I then played around with separate C file compilation
and linking (ide.c & ser_ir.c). This in turn led
to the creation of a makefile. I then incorporated the printf_small library
code. I tried a simple "printf", but it didn't work. Again I played around
with the printf code, but eventually gave up for the day. Oh the frustration
of free software!
I started adding debugging code (i.e. puts()
and putchar() calls) into the printf_small library code which
I suspected was the cause of the problems. After doing this the program
appeared to work. I added a routine which accessed the RAM and one of the
registers of the IDE drive. I soldered around 20 more wires in order
to complete the board and wire in the RAM chip. I then connected a real
IDE drive to the development board. I was soon able to write and read from
RAM and more excitingly write and read from one of the IDE drive registers.
In fact it read back and printed the correct IDE register values expected
after resetting the drive! Flushed with success I added more code to the
program to allow me to write and read from any IDE register using the RS232
terminal program. When I reset the processor the title string was printed
but then the screen just continued scrolling. At this point I gave up.
For some reason the SDCC executable runs really really
slow. It takes around 10 seconds even to print the "usage" information
if no parameters are given. This is really frustrating. So I spent a few
hours trying to re-compile the source C using my Borland C++ V4.5 compiler
(which was free on a magazine cover disk). There are Borland makefiles
in the SDCC source tree, but needless to say they need a lot of editing
to work properly. I booted up Linux and copied the SDCC source tarfile
over and installed it under Linux. It installed like a dream. The Borland
compile had failed since there were no lex or yacc binaries running under
DOS. The Linux make had created these files so I copied them to floppy
disk and re-booted into Windows. I continued to try to get SDCC to compile.
I then discovered that I hadn't copied all the necessary files over from
Linux. So rather than re-boot I searched the net and finally found some
tools which allowed Linux disk partitions to be accessed from Windows/DOS.
They worked successfully and proved quite useful. I eventually got SDCC
to compile my program.
I then set about debugging the sluggishness problem.
I tracked the problem down from routine to routine using printfs to see
where the big delay was. It was revealed at a place at which files appear
to be created in a temporary directory using the TMP or TEMP
environmental variables. I went to the TMP directory and saw it
was full of files beginning with the string "sdcc". I deleted them and
re-ran sdcc. It ran in a flash. The number of files in the temporary
directory slowed down the creation of new files in this directory, and
the problem was that they were never getting flushed. Now I knew this,
the fix was simple. I added commands to delete these files in my AUTOEXEC.BAT
file and also in my Makefile. In the SETUP.BAT file which
I have created to run to setup the sdcc environment I re-assign
away from the normal place and then in the Makefile clear the
temporary files. So at last the SDCC executable runs at a sensible speed.
Shame I had to waste so much time tracking this down.
I suspected that the "crash" problem was due to memory
problems. When the small model is used only 128 (or 256) bytes of RAM are
available for storage. The AT89S53 (and the 8031 and similar variants)
have an extra 128 bytes of RAM available (over the 8031) either for stack
expansion or for indirectly accessed variables. I changed the Makefile
to use the large model. This requires external RAM, but this is OK as the
HM6264 chip gives 8k bytes of storage. Having done this, the problem program
sprung back into life.
I then developed the program to have a simple
single character menu selection system which allows any IDE register to
be written to or read from. There was a strange problem that sometimes
when printing no number appeared. This led me into another debugging session.
Eventually I discovered a problem in the printf_small library routines.
If the number to be printed was 0, then nothing at all would get printed!
Both hex and decimal print routines were affected. I made the necessary
simple changes to the library C source code and re-compiled. As the code
expanded I wrote some code to get a string of characters and convert them
to integer using the library atoi() routine, however when the
number entered was printed out it was always completely wrong. After yet
another session of debugging, the problem appeared to be the use of multiplication
in atoi(). I copied the atoi() library code into my own
source and changed the code to use shifts and adds to achieve the required
multiplication by 10. The number reading code now appeared to be working
and I could write to and read back values from any IDE register.
I started to use the menu system to play with the
registers. All the registers read back the expected post reset values.
By the end of the evening I had the IDENTIFY command working and I was
able to dump and print out the drive serial number. Since only the lower
8 bits of the IDE drive data port are read back then every other byte of
the IDENTIFY is missing, however the ASCII data is aligned to the lower
byte of each 16 bit word.
In order to understand the IDENTIFY instruction better
a binary dump of the data was coded. In order to format the data correctly
I modified the printf_small() code to understand more complicated
format strings (e.g. %02x). As often the case the data displayed
on the screen wasn't as expected and I spent time trying to work out what
was wrong in the code which I had added to the printf code.
I finally discovered the printf problem. I needed
to code the format string as %02hx, where the "h" means short
or char data. The problem was that the unsigned char parameter was been
interpreted as an int and hence extra digits were being printed.
A new problem has started happening. The RS232
data printed to the RS232 terminal emulator is corrupted every so often.
The title string which is the first thing to be printed always gets corrupted
in the same place - in the middle of my name! I wondered if the data is
being sent to the PC is too quick for the PC software to cope (since the
DOS window is running under Windows) and some kind of data over-run is
A new bug has come to light with SDCC, although
this one has already been reported in the Sorceforge SDCC bug list page.
There is a for loop to move the data from the IDE drive to the sector buffer.
The assembly code generated reverses the direction of the for loop with
very strange results. I found there was a compiler directive to switch
off for loop optimisation and this cures the problem. Pressing the "i"
key now prints out the hard disk drive serial number and other text information.
Since only the bottom 8 bits of the IDE interface can be read the drive
parameters cannot be properly determined unless they are less than 256
in size. Before finishing some code was written to dump a selected sector.
This code was extended to write test data to the same sector before reading
it back. The program sometimes works but more usually hangs, so in the
next session I need to add timeout code and better status and error checking.
Return to Atari Projects home page