Sorted by Squirrels.

Tuesday, 1 July 2008

He's at it again!

I'm getting back into the Atom swing! After a fruitless hour measuring incorrect logic levels at the Atom's expansion port I was on the verge of giving up. I had been prodding the VIA, according to available documentation, and getting nowhere. All I wanted was a toggly bit. Was that too much to ask for? That's when I decided to do some chip swapping.

It takes me longer than most people to get to this point as I'm a software person at heart and so blame that first ;)

I just happened to have a vintage 6522 VIA lying on my desk so I swapped the chips over. Joy! I was flipping bits like a demon. Naturally my thoughts turned to MMC...

10@=0
20!#208=!#208+3
30V=#B800
40W=#FFF4
50T=#80
60DIM LL(13),C(6)
70F.N=0TO13;LL(N)=#FFFF;N.N
80F.N=1TO2; DIM P(-1)
90P."PASS "N',$21
100[
110\ main
120:LL0 LDA @#0
130STA C+1; STA C+2; STA C+3; STA C+4
140LDA @#95; STA C+0
150JSR LL3
160LDA @#40+#0; JSR LL7
170LDA @CH"1"; SBC @0; JMP W
180\ select card
190:LL1 LDA @0; STA V; RTS
200\ deselect card
210:LL2 LDA @#20; STA V; RTS
220\ init hw and go spi
230:LL3 LDA @0; STA V+#C
240LDA @#FE; STA V+2
250LDA @#20; STA V
260LDY @10
270:LL4 LDA @#FF; JSR LL5; DEY; BNE LL4
280RTS
290\ xferbyte
300:LL5 STX T+0; STY T+1; LDY @8
310:LL6 PHA; AND @#80; STA V
320ORA @#40; STA V
330LDX V; AND @#BF; STA V
340TXA; ROR A
350PLA; ROL A
360DEY; BNE LL6
370PHA; JSR #F7FA; PLA
380LDY T+1; LDX T+0;
390RTS
400\ command
410:LL7 STA C+5; LDY @5
420:LL8 LDA C,Y; JSR LL5; DEY; BPL LL8
430:LL9 LDA @#FF; JSR LL5; AND @#FF; CLC; BPL LL10
440DEY; BNE LL9;
450SEC
460:LL10 RTS
470]
480P.$6
490NE.N
500END



If you're an ex-atommer or you've been around BBC micros you might recognise this. If you don't then I can tell you it's some Atom basic with inline assembler. The Atom's Basic dialect was hard on the eyes but lightning fast. By the standards of the day, naturally ;)

The built-in assembler gave the user of this machine an instant boost when learning to program. No fussing with 3rd party apps, loading the assembler or machine code, or the attendant problems with cassettes. Turn on. Assemble. Bam! (Which is as it happens almost quite literally what happened to my 1st Atom over 20 years ago...) Now if only it was that easy for the kids of today - it was much better in the old days - I remember when all this was fields etc. etc.

The above listing is code to bit-bang SPI to an MMC card attached via the simplest of hardware harnesses to the rear expansion connector of the Atom. I'm looking at making a ROM based solution that hooks into the OS's filing system vectors. It's all quite primitive at the moment but I'm hoping it'll solidify. Get in touch if you have any experience of developing this kind of Atom program. I'd love to talk to you.

Saturday, 28 June 2008

It's gone all doubley-spaced!

(edit)
The listings are back!

Apologies about the listings, esteemed reader, they appear to have lost their formatting and become double-spaced. I'm looking into it but in the mean time, please bear with me!

Thursday, 26 June 2008

Atom Power!



She's arrived! After many years of fussing and prevaricating I've finally taken the plunge and bought myself an Atom. The prices were rocketing in the bay of E, and I reckoned on the time being nigh. This one was advertised as having a broken key and otherwise with little hope of receiving a working box I decided on taking a punt and fixing it up if necessary. I've always loved this machine. I owned one as a boy although it was only a half-populated board without a case. It still did the business though!

I must admit to being a little saddened when I opened the wrapping. It was grubby and half of the keys appeared to be smashed in, sitting a good 6-7mm lower than their neighbours. The 1st thing was to open it up and check the power supply status. The Atom was infamous for overheating and many owners bypassed the internal regulators in favour of feeding it a regulated 5v diet. As was indeed the case with this one. It had received some tweaks in its time, but I was really happy to see the work was all of a high standard. These were all what I call 'magazine hacks' - the electronic equivalent of a one-liner joke. Single wire patches for enabling an eighth bit on the printer port, joining some lines to an external socket for wiring a joystick, nothing major. I was chuffed to see that it was fully expanded memory and support-chip wise. 12K RAM & 12K ROM plus a utility kit that I'm still having trouble finding any info about. I'll have to resort to a disassembler I think. No colour board but then I wouldn't ever have even contemplated that. Too rare.

The mother and key boards were in a real state. I think it had been stored on top of kitchen cupboards at some point in its life and it had received a good layering of yellow grease and fibres. Some keys were sticking and this was the main reason. I've since scrubbed it with a toothbrush and plenty of warm soapy water and now you'd never know! I was shy of putting it in the dishwasher as some people recommend, this may be ok for generic PC keyboards but rare vintage '80s hardware...

At some point in its history the three keys in the lower left had been replaced. They were replaced with high quality keyswitches, which - well I never - made the keycaps sit higher. What had happened was that the previous owner had raised the original keycaps with superglue to match the height of the replacements. The original mechanism is a cheap spring-based creation which I've only ever seen in Atoms ... and a keypad that I was given recently! That was handy, wasn't it! So I hacked the keypad and replaced the switches with something contemporary and far more suitable. And the same height! The caps all came off and were cleaned and repaired where necessary.

The machine is now clean and tidy, ready for work.

One tough trick was finding a plug to fit the odd power socket dimensions. It's some olde fashioned imperial jack size. Eventually located with the assistance of an Atom owning colleague I was able to juice the old girl. To my immense surprise it eventually reset and presented me with the very comforting words:

ACORN ATOM
>

Joy!

A computer's no good without software, right? Like all good '80s machines this one needs some square-wave goodness. I couldn't locate any software to generate the required signals that worked on a modern PC, so being handy with a compiler I got to work. I'm pleased I did all the work on ACE - the techniques transferred instantly and I had a program to translate raw program dumps into WAVS. And text files into raw dumps. And vice versa.

I'll be happy to pass these on to anyone that wants them. The source can be found here. It's vanilla C++. I'll be happy to help with porting, compiling or whatever.

There looks to be a new site emerging that could eventually be a must-see for any Atom fans. I'm speaking in the future tense as it's not there yet but I've spoken with the masters and they're promising big things. Watch this space.

If you're an Atom fan, get in touch.

Thursday, 15 May 2008

IO, IO it's off to work we go!


This is my 1st attempt at getting a PCB made. It was rushed so please excuse any glaring stupidity :)

A colleague was having some PCBs manufactured and had a little space left on the plate so I knocked this together during a lunch hour. I'm pretty pleased so far - the boards have come back and, despite being less than optimally packed, they're quite neat.



This is a ZX81 IO board. As I'm sure you've already worked out, esteemed reader! The 8255 is a general purpose IO controller and it's mapped to the Z80 IO space at ports 0x07 and 0x17. I'll be attaching the MMC card to it later :)

I've included links to the schematic and board files in case you want to fire up Eagle and have a play. This is a package with a very steep learning curve. I've been playing with it for about a year and I can only now say that I'm beginning to become confident. Version 5 has just been released which adds some polish to the mix. It wouldn't be uncharitable to say that the package weas a little rough around the edges before..! I haven't pushed V5 much - and it's likely I never will :) - but you can just tell that there's been some love and attention lavished. Hurrah for CadSoft!

Click the schematic for a very high res version. Or get the binaries from HERE.

I'll let you know how it works out when the SMT 74s arrive!

Friday, 2 May 2008

Average bits 10.2



May I present some of my non-human babies. Continued thanks go to my employers - you know who you are - for allowing the museum to exist on my desk.

The C128 rear-left has a proto-board built SD2IEC card installed inside the tape drive. I shaped the PCB like a cassette. Press eject and you can insert an SD card into the presented slot. Cheesy but fun :)

The Apple //e front left is my latest baby. I'm awaiting a prototype board from the states so I can build an IDE card. They're ridiculously simple to build, it seems.

The centre column contains a QL, an STe, a Spectrum 128 and a BBC Master 128 with MMBeeb interface. They're nice, but not my favourites. Especially as the Sinclair machines require attention due to defective membranes. A pathology known around these parts as the curse of Clive.

No, the favourite machine honour belongs to the Atari 800. This is another machine with a SD card interface secreted away in a hacked tape drive. I dreamed.. no.. seriously fantasised about this machine when I was pecking away at my ZX81. (Not pictured - it's on the bench at the moment having an SD card and keyboard upgrade, natch)

One thing tends to be common amongst these machines and that's the addition of SD card interfaces.. My hat goes off to the engineers linked in this post. MMBeeb was my first exposure to the practice, which gave me enough of a kick-start to design my own interface for the zx81. Monster maze loads in 6 seconds. Bliss!

I guess it remains to be said - I AM 8-BIT

And proud :)

Sunday, 27 April 2008

Like a record baby!

I've been inspired by someone or other's homebuilt spinner. I probably saw it on Make or Hack-a-day, I forget. If you aren't familiar with the aforementioned input device it's like, well you know, like an arcade game control that could be found on such classics as Tempest, Arkanoid, Cameltry and many many more. You spin it. Hence the name.

I had to have a go. I have a project stack 100 deep at the moment and no time to do anything, so I needed a quick fix, a micro-project if you will. And this seemed like the perfect candidate.

So the obligatory VCR head was pulled from a dead Matsui. This particular model had a wonderful head motor mechanism that came apart very easily and cleanly, leaving no random sprue like some I've been near. It also furnished me with convenient screw holes. The motor shaft has a metal disk at the end which was just the right size for some idle tweaking. There's something very relaxing and .. zen I suppose .. about VCR head motor mechanisms. I suggest everyone try hefting one and idly spinning away a few minutes :)

An old USB mouse was inspected and found to be of the correct vintage - ball era. The optical encoder disks were removed and the pcb ritually prepared. The left/right encoder was severed and the traces replaced with kynar wire. Did I already say that this stuff has changed my life? I did have to modify my wire strippers to nip away that micro-fine insulation and I must admit the very act made me feel quite hardcore!

So with the emitter/receiver pair free to do their thing I started to try and mount the encoder disk on the base of the motor. What a nightmare. I tried different adhesives and when the little black brolly wasn't teetering drunkenly on the shaft or resolutely embracing my fingers it was wholly and utterly eccentric. In the end I liberated one of the tiny rare earth magnets from a sneakily swiped Magnetix stick. To this I super-glued the encoder on its truncated shaft. This could then be pinged onto the end of the shaft and repositioned easily whilst still holding position. When it was rotating as centrally as I thought it could, out came the hot glue. One quick spin draged a glistening thread of glue from the gun like silk from a spider's arse. And there was the disk in place, semi-permanently fixed. Result!

To mount the spinner I chose a CD 'cake box'. I'll leave the details of mounting the motor to your imagination as I am wont to do. All I will say is knife and screws were involved, but not my friend the rocket scientist.

So with the motor mounted all that needed to be achieved was the solid mounting of the transceiver pair. Tip #2: Don't use stiff wire. I thought that this would be simple, quick and give me plenty lattitide to position the payload precisely in space with little play. Wrong. It bounced around like Katie Price on a trampoline. So I did what I always do at moments like this - reach for the Lego. A small 1x2 hinge, a 1x8 plate and some more hot glue later I had the PCB shard mounted in the right position. More hot glue saw it fixed and locked. Game on!

[Click for a much, much bigger view! Erk!]


Cuts on your fingertips are painful. Rough-edged spinning steel disks attached to a momentum powerhouse cause cuts. Thinks needed :) The rubber 'tyre' that encased the middle mouse wheel was promptly repurposed. An almost perfect fit! I was understandably quite chuffed. While in the heightened state of chuff I figured some buttons might be useful too, in order to save splitting control between the keyboard and spinner when necessary. So off to the bits box and one feisty rummage later we have control! And the old BBC Master computer has 2 less keys.

One leisurely wiring of these buttons to the mouse PCB switch pads and there we have it. One spinner. It may not be pretty, but it was a project! And it works great with Tempest :D

[Click for a much, much bigger view! Zoinks!]

Sunday, 13 April 2008

u-Fat filesystem

Not a truncated attempt at a verbal slight, but a solution to PC compatible file access for micro-controllers!

Many FAT file system implementations are, by necessity, too large to take a place in micro-controller applications. Long file names, fragmented files, the FAT tables - no wonder a 'proper' solution weighs in at many K of code and buffers. One solution is to carry out raw access to the card, but this then involves compromises when getting the data off the card onto the desktop.

My solution is to reduce weight of code by applying stringent use restrictions:

Only 16 files (potentially), named in 8.3 format, pre-allocated and contiguous.

This enables us to locate the start sector of the file and read/write to it as we wish. The files can be freely swapped between PC and micro controller application using standard operating system commands. To reach this state of nirvana all that needs to be done is format the card before copying the pre-allocated files to it.

The only external requirement for servicing the code is a function that reads sectors, using logical block addressing, from your chosen FAT device. If you look in the ACE post previously the code zip there includes a complete MMC solution.

I found a schematic on the arduino site that is almost identical to my own and comes very highly recommended. If you haven't got a card reader that you can cannibalise then edge connector works well too. It's a common way of doing it and there are many good examples around - you can find one here.

Here's the header which shows just how micro micro can be!

 /*
/ Microfat.
/
/ Developed by Charlie Robson in 2008.
/
/ This is the bare minimum* functionality required to read and write data
/ to a FAT formatted device. In this case, an MMC card.
/
/ Rather than build a fully-featured FAT implimentation this will allow
/ the user to locate sectors associated with a file on the device, and
/ read and write to them in a brute force manner. No error checking, no
/ long filenames, not even any support for fragmented files :) This is
/ raw access, we only deal with existing files.
/
/ What you do get is a very lightweight module for extremely limited
/ environments. Arduino has 2k of SRAM. Holding the sector of FAT data
/ needed to traverse a fragged file would instantly gobble up 1/4
/ of that. Enough said. Another benefit to not using the FAT is that
/ there's no need to worry about whether a device is FAT12 or 16.
/
/ To use:
/ Format a card.
/ Make a file big enough to hold all the data you expect to write.
/ Copy to the card.
/
/ With the MMC module started up, call initialise. This will cache some
/ relevant information about the card such as the sector location of the
/ root directory and data area.
/
/ Call locateFileStart, passing the name of the file which is providing
/ the backing store for your transfers, and assuming the file is found
/ in the directory you'll receive its start sector and file size.
/
/ Now feel free to read and write data to and from the sectors allocated
/ to the file. Code carefully though - stray writes can twat your card!
/
/ Enjoy :)
/
/ *Massive understatement!
*/

#ifndef __MICROFAT_H__
#define __MICROFAT_H__

// some data structures we'll be encountering on our travels.

typedef struct
{
byte bootable;
byte chsAddrOfFirstSector[3];
byte partitionType;
byte chsAddrOfLastSector[3];
uint32_t lbaAddrOfFirstSector;
uint32_t partitionLengthSectors;
}
partition_record;

typedef struct
{
byte jump[3];
char oemName[8];
uint16_t bytesPerSector;
byte sectorsPerCluster;
uint16_t reservedSectors;
byte fatCopies;
uint16_t rootDirectoryEntries;
uint16_t totalFilesystemSectors;
byte mediaDescriptor;
uint16_t sectorsPerFAT;
uint16_t sectorsPerTrack;
uint16_t headCount;

uint32_t hiddenSectors;
uint32_t totalFilesystemSectors2;
byte logicalDriveNum;
byte reserved;
byte extendedSignature;
uint32_t partitionSerialNum;
char volumeLabel[11];
char fsType[8];
byte bootstrapCode[447];
byte signature[2];
}
boot_sector;

typedef struct
{
char filespec[11];
byte attributes;
byte reserved[10];
uint16_t time;
uint16_t date;
uint16_t startCluster;
uint32_t fileSize;
}
directory_entry;


namespace microfat
{
// Cache some relevant info about the card.
//
bool initialise(byte* buffer);

// Get start sector, file size for given filename. Returns false if the file
// is not found in the directory.
//
bool locateFileStart(const char* filename, unsigned long& sector, unsigned long& size);
};


#endif // __MICROFAT_H__



Now for the meat:

#include <wprogram.h>
#include "microfat.h"
#include "mmc.h"

// Data which remains constant over one session. Re-initialise if
// the card is changed.
//
static struct
{
uint16_t sectorsPerCluster;

uint32_t rootDirSect, cluster2;

byte* buffer;
}
vars;


bool microfat::initialise(byte* buffer)
{
vars.buffer = buffer;

if (RES_OK != mmc::readSectors(vars.buffer, 0, 1))
{
return false;
}

partition_record* p = (partition_record*)&vars.buffer[0x1be];
long bootSector = p->lbaAddrOfFirstSector;

if (RES_OK != mmc::readSectors(vars.buffer, bootSector, 1))
{
return false;
}

boot_sector* b = (boot_sector*)vars.buffer;

if (BYTESPERSECTOR != b->bytesPerSector)
{
return false;
}

vars.sectorsPerCluster = b->sectorsPerCluster;
vars.rootDirSect = bootSector + b->reservedSectors + (b->fatCopies * b->sectorsPerFAT);

long dirBytes = b->rootDirectoryEntries * 32;
long dirSects = dirBytes / BYTESPERSECTOR;

if (dirBytes % BYTESPERSECTOR != 0)
{
++dirSects;
}

vars.cluster2 = vars.rootDirSect + dirSects;

return true;
}



// Get start sector for given filename.
//
// Returns false if the specified file wasn't found in the directory.
// Short filenames only. Be aware that the directory fills up with 'deleted'
// filenames. Rather than deleting too many files try a quick reformat.
//
bool microfat::locateFileStart(const char* filename, uint32_t& sector, uint32_t& size)
{
if (RES_OK == mmc::readSectors(vars.buffer, vars.rootDirSect, 1))
{
// The filenames are stored in [8][3] format. No dot, all upper case.
// Names shorter than 8 chars are padded with spaces.
//
// Cook the supplied name. fred.txt -> FRED----TXT
//
char cookedName[11];
for(int i = 0; i < 12; ++i)
{
cookedName[i] = 0x20;
}

for (int i = 0, j = 0; i < 12 && filename[i]; ++i)
{
if (filename[i] != '.')
{
// Force char to uppercase. Cheesy I know :)
//
cookedName[j] = filename[i] >= 96 ? filename[i] - 32 : filename[i];
++j;
}
else
{
// Continue cooking chars at the extension position
//
j = 8;
}
}

for (int i = 0; i < BYTESPERSECTOR; i += 32)
{
directory_entry* de = (directory_entry*)&vars.buffer[i];

// Don't match with deleted or system/volname/subdir/hidden files
//
if (de->filespec[0] != 0xe5 && (de->attributes & 0x1e) == 0 && memcmp(cookedName, de->filespec, 11) == 0)
{
sector = vars.cluster2 + ((de->startCluster-2) * vars.sectorsPerCluster);
size = de->fileSize;
return true;
}
}
}

return false;
}




Which as you can see is smaller than the header - due in no small measure to the size of the FAT structure definitions.

As it stands this code could be improved by using non-static file info structures - only one is supported right now but the change would be trivial. Also allowing the filename search to traverse the entire root directory space would allow access to more files. However I don't really see the utility in ths -wherever I've used this code I've never needed more than one file :)

As usual any Qs are welcome.

Contact Form

Name

Email *

Message *

This is how we do it

MMC (9) acorn atom (7) sord m5 (7) zx81 (7) multicart (6) arduino (5) Sord (4) tatung einstein (4) Atari 800 (3) Chuckie egg (3) M5 (3) M5Multi (3) c128 (3) sd card (3) sd2iec (3) sio2sd (3) 6502 (2) Max6956 (2) QL (2) RCM (2) assembler (2) avr (2) c64 (2) cadsoft eagle (2) eeprom (2) einSDein (2) mmbeeb (2) multi-cart (2) spi (2) system 80 (2) ufat2 (2) vic20 (2) video genie (2) 6502 second processor (1) 6522 (1) 8255 (1) Acorn BBC Micro (1) Apple 2e (1) Apple ][ 2 two (1) BBC 6502 second processor (1) BBC micro (1) DevicePrint (1) Double Choc Chip Muffins (1) FAT (1) IO (1) Jupiter Ace (1) LED (1) Master 128 (1) PCB (1) PIC (1) POV (1) PROGMEM (1) Pineapple (1) ST (1) Spectrum 128 (1) antex (1) arcade spinner (1) arduino shield (1) atari (1) atmel (1) bakewell tart (1) beer (1) bird's nest (1) bitbucket (1) brokenated XC special (1) cake (1) cassette (1) cassette interface (1) colecovision (1) compact flash (1) convert (1) dac (1) de-yellowing (1) dev cart (1) development tool (1) eaca (1) efficient (1) einsdein. z80 (1) esp32 (1) esp8266 (1) eye strain (1) failosophy (1) filesystem (1) finally (1) fram (1) french polishing (1) fuse (1) fuses (1) game development (1) games (1) gaming (1) github (1) glue (1) google chrome (1) heroic failure (1) high voltage programming (1) hot irons (1) if (1) jiffydos (1) joey beltram (1) lego robot (1) library (1) lying (1) machine code (1) matron (1) microcode (1) mmc interface (1) mmc2iec (1) mmm (1) mouse guts (1) oscilloscopes (1) pcm (1) pic32mx (1) porn (1) proto shield (1) purple (1) repo (1) retro computer museum (1) retro hard-on (1) rom box (1) sd (1) sd-x (1) sd2mmc (1) seadragon (1) silliness (1) small (1) software master (1) soldering (1) spi software master (1) stray capacitance (1) string (1) techadventure (1) test equipment porn (1) ts1000 (1) turtle cheesecake (1) tweaking (1) vc20 (1) video head (1) video ram replacement (1) weewee (1) wingasm (1) wire library (1) wodges of IO (1) xilinx cpld (1) yellowing (1) z80 (1) zx spectrum (1) zxpander (1)
Unless otherwise stated all of the original work presented here is:

Creative Commons License
Licensed under a Creative Commons Attribution-Noncommercial 2.5 Generic License.

The work of others where referenced will be attributed appropriately. If I've failed to do this please let me know.