• Please review our updated Terms and Rules here

8051/8052 SBC

That is what I am working on at the moment too: a 8052AH Basic (or equivalent) with an external EEPROM which holds not only the extra Basic commands but also is used as a storage system. I made up a simple file system with 255 directory entries and a simple FAT table which holds which pages in the EEPROM are in use and such.
So far I added LOAD, SAVE, DIR, DISPLAY, HDUMP and ECALL commands. The EEPROM is connected and mapped into the space available so that the first 32 kB is always read from EEPROM (albeit the first 8 kB being masked by the internal ROM) and the rest of the (256kB!) EEPROM is available in 16 kB chunks at 8000-BFFF. Main memory is 32 kB SRAM space from 0000-7FFF and a small 8 kB SRAM chunk is also available from E000-FFFF in both program and data space.
This gives plenty of room to experiment with both fixed additional ROM code and Basic space and allows to fiddle with small assembler code experiments in the top memory area.

BTW the ECALL command can be used with an expression instead of a fixed address.
 
I'm very, very late to the 8051 party and have just bought the Kenneth J Ayala 8051 book. I never expected the 8051 instruction set to be so rich - I've got accustomed to the minimal PIC instrucion set and absent-mindedly expected something similar. How wrong could I have been! For Z80 assembler I always kept my Zilog "programmers reference card" handy - still have it - still use it, though its very tatty! - but even my few remaining neurons can remember all the PIC mnemonics without a cheat-sheet. This book is going to be an essential reference as the 8051 is way more comprehensive than I expected! I had to read the 'bit addressing ' section a few times but its clicked now. Pretty much handled by the assembler anyway, but nice to know whats happening under the bonnet. Lots of "nice to have's" too like 4 register banks, decimal adjust, 8-bit multiply & divide, exhanges, a better DJNZ than the Z80's 'B only' and a proper stack (though upside-down!)(SC/MP has no stack). Lots to learn 🙂
 
For loading intel hex files, the HEX2RAM.BAS file listed in Jan Axelson's book works well. I typed it in and have attached it here. I changed the file extension to .txt, so that it's one of the file types the forum allows me to attach. If you download it, you'll likely want to change it to .bas or .b52 or whatever you normally use.
Jan Axelson's book about BASIC-52 is recommended, and is available as a free .pdf download from her site: http://janaxelson.com/microc.htm
 

Attachments

With the 89S52 onboard I succesfully replaced the 11.0592 MHz crystal by a 25 MHz version I had lying around, had to adjust the baudrate parameters in my EEPROM but it runs fine. The datasheet states you can go up to 33 MHz.
 
I've programmed an Arduino to act as a very fast SPI uploader for the Atmel AT89S52, so you can do ICSP with it. You just do an XMODEM transfer of your Intel hex file to the Arduino's serial port, and it then decodes the XMODEM and Intel Hex encoding, and flashes the chip for you. I use an Arduino pro micro because it's small and neat, but my sketch works with most of the common Arduino variants, including the Uno and Nano. If you're on Windows, Teraterm has XMODEM transfers built-in, and on Linux, I just use a small shell script, which is included in the zip archive. You can see a video of it working on my YouTube channel (search for ceptimus). Arduino sketch attached.
 

Attachments

I'm interested, its exactly what the Densetsu board needs! 🙂
I have combined the basic extension code and the storage in the same EEPROM but is is entirely possible to split this up so that you can have two seperate (EP/EE)ROMS. One with the extension code in program space (from 2000h-7FFFh for example) and a large(ish) EEPROM for storage in banks of 8 or 16 kB from 8000h-BFFFh. That way you can set the banks simply with four PORT1 bits without having to deal with my 'complex' mapping. By splitting up the extension ROM and storage you can keep the EEPROM page write routine in the Basic extension ROM.

Some 'features' of this simple filesystem:

  1. 12 character filenames, you may include an extension just as long as the total length of the name does not exceed 12 characters
  2. The filenames are case sensitive and need to be put in double quotes to be accepted
  3. The directory can contain a maximum of 255 entries (the null-th entry is the occupied by the three byte baudrate setting and the storage system name)
  4. Each directry entry is 16 bytes in size where the first two bytes contain the page number of the first page used by the file, the second two bytes contains a representation of the file size (the number of pages used multiplied by the page size: 128 byte) The remaining 12 bytes contain the file name.
  5. The FAT table is as large as the number of EEPROM pages (each 128 bytes) divided by 8, each bit represents one page.
  6. The FAT table and directory are stored at the beginning (bank 0) of the EEPROM and simply protected against overwriting by having their page bits already set in the FAT table.
  7. Each 128 byte page used by a file has the next page number in the first two bytes (or zero if no next page / last page use by this file) and 126 bytes of file data.
 
In my case it would be only for storing a few small basic or even smaller m/c programs so even 128k or 256k storage would be fine.
If the extensions and the storage can exist in the one chip, all the better!
 
In my case it would be only for storing a few small basic or even smaller m/c programs so even 128k or 256k storage would be fine.
If the extensions and the storage can exist in the one chip, all the better!
The one problem with having both functions in the same chip is that during programming the EEPROM it is not available for some time to the processor. I circumvent that problem by having the programming routine in a small piece of SRAM (also mapped in program space) where it waits until the EEPROM is finished writing. It can then safely RETurn to the code in the EEPROM :-)
 
I've been working on a Conway's Game of Life for my 'Dennou' board. You can see it running in the YouTube video

I'm looking at making it also run on boards that don't have XRAM also mapped as CODE in the 7E00H - 7FFFH. Do many boards have a shared XRAM/CODE area and, if so, what addresses are typically used? Is it normal to map such XRAM so that the two address are the same, or might the same RAM appear at, say C000H in XRAM space, but F000H or similar in CODE space? Once I know, I can test it out on my old veroboard rig, which I mainly use to run FORTH - that has 128K of RAM.

BASIC-52 doesn't allow you to put CALL A where A is a variable containing an address, so I need to make the BASIC program modify itself to change the CALL addresses it will compute at runtime, once it's asked you where you want to put the code. That should be fun!
 
I've been working on a Conway's Game of Life for my 'Dennou' board. You can see it running in the YouTube video
Looks great!
I'm looking at making it also run on boards that don't have XRAM also mapped as CODE in the 7E00H - 7FFFH. Do many boards have a shared XRAM/CODE area and, if so, what addresses are typically used? Is it normal to map such XRAM so that the two address are the same, or might the same RAM appear at, say C000H in XRAM space, but F000H or similar in CODE space? Once I know, I can test it out on my old veroboard rig, which I mainly use to run FORTH - that has 128K of RAM.
Program code (aka 805x code) can not be run from data memory and you can not write to program memory unless... you map them on top of each other.
With some tricks you could map some part of SRAM (data memory) so it will appear at another address in program space.
With my EEPROM system I do it the other way around: I can map any 16 kB block of EEPROM space at 8000h-BFFFh which is at this moment only used to access every page of EEPROM space for storage. The bottom 32 kB of the EEPROM space is always mapped to 0000h-7FFFh so I have a fixed area for the Basic extensions and such. (note that the first 8 kB from 0000h-1FFFh of program space is masked by the internal ROM of the 8052)
BASIC-52 doesn't allow you to put CALL A where A is a variable containing an address, so I need to make the BASIC program modify itself to change the CALL addresses it will compute at runtime, once it's asked you where you want to put the code. That should be fun!
Yes this is the exact problem Phil had, take a look at his BASYS program, with a few bytes of code somewhere in program space (or in the internal ROM space if you can alter that) you can make it execute from a variable address.

In my Basic extension I added a command called ECALL which evaluates an expression following the ECALL command:

Code:
;
; CALL replacement so it can handle expressions
;
ecall:
        MOV        A,#39h    ; evalute expression from basic text
        LCALL    30H   

        MOV        A,#01h    ; get value from argument stack in R3:R1
        LCALL    30h
        
        MOV        DPL,R1    ; get low byte from R1
        MOV        DPH,R3    ; and high byte from R3
        CLR        A
        JMP        @A+DPTR
 
A bonus: This assembler is written in Turbo pascal and what I didn't notice so far is that it is capable of producing HEX files. That will easy my task to write my own routines.
That didn't work out. The assembler, which can handle several processors, is hard to understand. I thought the conversion part would be simpler. Wrong. In the end I just went to the "Intel Hex" page of Wikipedia and wrote the whole thing myself.
FYI: all software I write is free, including the sources. Just ask.
 
That didn't work out. The assembler, which can handle several processors, is hard to understand. I thought the conversion part would be simpler. Wrong. In the end I just went to the "Intel Hex" page of Wikipedia and wrote the whole thing myself.
FYI: all software I write is free, including the sources. Just ask.
I did program some Intel HEX stuff once with my CY7C264 programmer on the STM32F104 so I feel your pain :)
 
I found this board in my collection of STC dev boards.

20251125_092411.jpg

Most of my STC89s are PDIP 40 packages, and are the 90C versions that can't address external code space, and I've never found a seller for the datasheet-mentioned PDIP 40 "HC" (or "HD"?) parts that are supposed to have a working /PSEN pin.

But this surface mount one has a code that ends in H9C, so I wondered...

Initial tests with a memory display program that displays the last part of the built-in Flash memory and the first part (if present) of external code memory looked promising. The data from the external code memory was displaying part of the address (which is what normally happens with multiplexed address/data buses when no actual memory is present). I dabbed some pull down resistors onto the P0 pins (data bus and multiplexed address lines for external memory) and was able to change the displayed values.

So it looks like it will work for running MCS-BASIC with some shared code space/data space and also FORTH. I'll build up a 'shield' with RAM and latch chip Etc. to plug onto the board to try it. Unfortunately, not all the holes in the board are on a 0.1" grid - a stupid feature it shares with many Arduino boards.

If it works, it's a nice option. These boards are available cheap on Ali Express, and Amazon. They can run at 6T (double speed) and have a built-in USB serial adapter and a serial bootloader for updating the Flash memory quickly and easily. The chip information you see when uploading to it says it has 8kB of EEPROM, as well as 8kB of FLASH - I'm not sure how the EEPROM part works - something I need to investigate.
 
Alas! Further testing revealed that the /PSEN pin doesn't work on this chip either. It's a GPIO output, P4_4. So I'm not sure what will happen if I try jumping to code in an area that doesn't really exist in the chip's memory map - does the 8K internal flash memory get aliased every 8K, or does it run code that's in the XDATA memory at the same address, or will it just crash? I'll test it and report back with my findings.
 
My guess is that the internal ROM is either EEPROM or FLASH, a bit like the AT89C52 versus the AT89S52
Too bad they didn't put out the /PSEN or have it programmable like the EXTRAM option.

The AT89S52-24AU seems like a drop-in/solder-in replacement for the STC on your board and it has the /PSEN pin.
 
Last edited:
BTW I am running my 89S52-24DP @ 32 MHz now (just found out there are two speed variants, oops.) Runs rock solid though.
 
It seems it does have two types (or maybe two distinct blocks) of non-volatile memory. When I run stcgal (the ICSP tool) it reports the current state of the chip before uploading a program - like this:

Code:
Cycling power: done
Waiting for MCU: done
Protocol detected: stc89
Target model:
  Name: STC89C52RC/LE52RC
  Magic: F002
  Code flash: 8.0 KB
  EEPROM flash: 6.0 KB
Target frequency: 22.190 MHz
Target BSL version: 6.6C
Target options:
  cpu_6t_enabled=True
  bsl_pindetect_enabled=False
  eeprom_erase_enabled=False
  clock_gain=high
  ale_enabled=True
  xram_enabled=False
  watchdog_por_enabled=False
Loading flash: 1194 bytes (Intel HEX)
Switching to 115200 baud: checking setting testing done
Erasing 6 blocks: done
Writing flash: 1664 Bytes [00:00, 4247.72 Bytes/s]                             
Setting options: done
Disconnected!

That's with an "old fashioned" PDIP 40 chip. The LQFP44 chip is pretty similar, except that it says EEPROM flash: 8.0 KB instead of 6.0 KB

Anyway, my tests writing to xdata memory, and then reading back code memory, showed that the code memory (outside the range of the internal flash) is not really present, nor even consistent. I tried it with the /PSEN line (which is IO bit P4_4 on the 90C version) both high and low - and the values read back just seem to float around - different on each run of the test.

Maybe I'm doing something stupid, and there is a way to get it to work by "manually" driving the /PSEN output, but if so, I've not been able to work it out.
 
Back
Top