• Please review our updated Terms and Rules here

8051/8052 SBC

First DIY kit with memory expansion is running. Ik hooked up 64 kB of SRAM and an even more ridiculous amount of Flash/EEPROM (256 kB) to the header connectors. With a simple USB to RS232 adapter it connects happily to the host computer and after pressing the space bar it shows:

*MCS-BASIC-52 V1.31*
READY

(I programmed an AT89S52 with version 1.31)

It seems like the Basic defaults to a maximum of 32 kB RAM but you can move MTOP to higher values. The Flash/EEPROM is occupying all available ROM space (2000-FFFF) and is readable also just by connecting the chip enable to /PSEN, the SRAM is connected to /RD and /WR and occupies all data space (0000-FFFF)
The carrier board just has three chips, the SRAM, the Flash/EEPROM and the 74HC573 latch. I will add some more intelligent logic for the extra banks of Flash/EEPROM. Probably by adding a GAL chip
 
Some photos
 

Attachments

  • 2025-10-23 21.35.50.jpg
    2025-10-23 21.35.50.jpg
    1.6 MB · Views: 14
  • 2025-10-23 21.35.26.jpg
    2025-10-23 21.35.26.jpg
    1.7 MB · Views: 14
Thank you for the pointer. My start was "The 8051 Microcontroller and Embedded Systems Using Assembly and C" that I was able to download and it uses the same set. Very helpful. But this PDF also mentions registers in the 0Cxh area, like T2CON, on page 114. Having found two sources I will only support these ones unless someone comes with a good reason to support other names.
Best would be some original Intel documentation to confirm the use of these names.
 
I'd intended hardwiring this on stripboard as I didnt realise there was a PCB available - I got the .BRD file from Nick's link above
and Mark1960 from the VRRRF forum kindly converted the .BRD to gerbers for JLC. I'll have a few spares if anyone in the UK wasnts one.
A friend of mine ordered a set from JLCPCP. His idea: use it as a piggyback on the kit I mentioned before. If that won't work, I always can use it stand-alone.
 
Thank you for the pointer. My start was "The 8051 Microcontroller and Embedded Systems Using Assembly and C" that I was able to download and it uses the same set. Very helpful. But this PDF also mentions registers in the 0Cxh area, like T2CON, on page 114. Having found two sources I will only support these ones unless someone comes with a good reason to support other names.
Best would be some original Intel documentation to confirm the use of these names.
Example: TCON as a whole register can be address as a single byte at internal address 88H
The single bit IT0 can be addressed by the SETB or CLR commands also at 88H
IE0 is one bit further so it will be bit addressable at 89H, IT1 will be at bit address 8AH etc etc.

T2CON is adressed the same:
Whole register is byte addressable at internal address C8H and all the single bits are bit addressable from C8H to CFH

From the datasheet:
TCON_T2CON.png
 
While writing my assembler I ran into the so called "Symbolic addresses". For example, TCON = 88h and TMOD = 89h. But then I found an assembler that supported IT0 and IE0 as well, for the same addresses.

My question: what are the official ones and which ones are supported in general as well?

Thank you in advance!
What I did in my assembler was in contexts where a bit address was legit, if there was a "." then get the bit number and compute its address. I made a Get_8051_Bit_Reg() which verifies that an address can be a bit, then returns the base value. I also did a custom version of EQU that checked for the "." so you could do "FOO EQU 22H.3" and it computes the bit address.

In the message above, you could do "IT0 EQU 88H.0" and "TF1 EQU 88H.7".
 
The datasheets I found so far didn't mention the opcodes or above. I found the opcodes in the book I mentioned above but it didn't mentioned the above. Could you be so kind to point me to this datasheet, please?

FYI: it seems I have finished my assembler, I created a file that contains all possible instructions/opcodes except 0A5h. The binary of this file is the same as produced by the assembler I mentioned above, ASM51, so I think I succeeded.
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.

In the message above, you could do "IT0 EQU 88H.0" and "TF1 EQU 88H.7".
I have given it a good thought and I prefer "TF1 EQU 8FH". Thank you anyway for the advice.
 
I have reworked the memory mapping of my DIY kit so that SRAM is from 0000h-7FFFh and an extra 8 kB at the top at E000h to FFFFh
That 8 kB is also mapped as program space. The large EEPROM is mapped in from 2000h-7FFFh (program space) and the remaining 14 banks of 16kB can be mapped at 8000h-BFFFh in program and data space. The mapping is done with a GAL chip and (for now) four PORT1 bits (3-6). This mapping leaves a space from C000h-DFFFh for other expansion.
Now trying to make some routines to write to that SST29EE020 EEPROM, it can only write in pages of 128 bytes and you have to unlock it before writing.
To write a single byte you need to read the page it is in into RAM and update the byte you want to write and the write the whole page back. (the write function inside the EEPROM accepts single bytes but wipes the whole page and then just writes the single byte you are trying to insert...)
 
Well the Densetsu PCBs arrived, made one up and of course it worked first time, first impressions I'm quite impressed with MCS BASIC-52, for 8k it seems very complete. I need to peruse the manual now 🙂
 

Attachments

  • IMG_20251031_141106317.jpg
    IMG_20251031_141106317.jpg
    1.2 MB · Views: 7
Well the Densetsu PCBs arrived, made one up and of course it worked first time, first impressions I'm quite impressed with MCS BASIC-52, for 8k it seems very complete. I need to peruse the manual now 🙂
Nice! By using VT100/ANSI terminal codes you can even produce color if you'd like.
I see that there are provisions for pin-headers/sockets so you can expand that board also.

Currently I am fiddling with some 'large' EEPROM/Flash chips to use it as both an extension to the standard Basic commands and also as storage.
 
I've been reading the (huge) manual whilst playing with BASIC-52 and frankly I'm bowled over, its astonishing how many features they've crammed into 8k :)
For a benchtop control computer its really quick to rattle something together as a programmable item of test gear... easy port bit control, RTC for timing, interrupts etc...
One thing caught my attention was the PWM command, so easy to drive a servo or ESC speed controller. The μs timing is spot on. Last night I started
converting my BASYS monitor, I got maybe halfway through, probably finish it tonight, the -52 syntax is a little quirky in places (eg strings) but it seems theres nothing you cant do.

 
ok I have done the conversion of my BASYS monitor to BASIC-52 and everything works except the 'E' command which runs a machine-code program at the address specified.
In a nutshell it needs to do:
INPUT"Address? ", A: rem get the address to go to
CALL A
but apparently the call paramater cant be a variable, it has to be a hard coded address like CALL 7400H (?)
One idea is to copy a LJMP xxxx into RAM at a fixed address, then have the 'E' command change the jump operand before calling the fixed address (?)
Even so, if I insert a 22h (RET) into memory and CALL that address, I expect it to immediately return but instead it locks up, even in immediate mode from the command prompt.
I think its a data memory/program memory thing that I've misunderstood - maybe we cant 'run' code in data memory, which is to be expected (?)

Meanwhile I've added the bare bones of an 8052 page to my stash (including BASYS so-far): https://philg.uk
 
ok I have done the conversion of my BASYS monitor to BASIC-52 and everything works except the 'E' command which runs a machine-code program at the address specified.
In a nutshell it needs to do:
INPUT"Address? ", A: rem get the address to go to
CALL A
but apparently the call paramater cant be a variable, it has to be a hard coded address like CALL 7400H (?)
One idea is to copy a LJMP xxxx into RAM at a fixed address, then have the 'E' command change the jump operand before calling the fixed address (?)
Even so, if I insert a 22h (RET) into memory and CALL that address, I expect it to immediately return but instead it locks up, even in immediate mode from the command prompt.
I think its a data memory/program memory thing that I've misunderstood - maybe we cant 'run' code in data memory, which is to be expected (?)

Meanwhile I've added the bare bones of an 8052 page to my stash (including BASYS so-far): https://philg.uk
It seems that you can only enter an integer and not an expression.

From the manual:
4.2 CALL
MODE: command and/or run
TYPE: control
The CALL [integer] statement is used to call an assembly language program. The integer fol-
lowing CALL is the address where the user must provide the assembly language routine. To return
to BASIC the user must execute an assembly language RET instruction. Examples of how to use the
CALL [integer] instruction are given in the Assembly Language Linkage section of this manual.
EXAMPLE:
CALL 9000H
Will cause the 8052AH to execute the assembly language program beginning at location 9000H
(i.e. the program counter will be loaded with 9000H).
Variations: (Version 1.1 only) If the integer following the CALL statement is between 0 and 127
(7FH), Version 1.1 of MCS BASIC-52 will multiply the user integer by two, then add 4100H and
vector to that location. This means that CALL 0 will call location 4100H, CALL 1 will call 4102H,
CALL 2—4104H and so on. This permits the user to generate a simple table of assembly language
routines without having to enter 4 digit hex integers after the CALL statement from the user sup-
plied Reset routine.
And there is a separation between data and code memory (selected by the /PSEN and /RD pins)
I have explicitly selected the memory regions so that there is 32k SRAM data memory from 0000-7FFF and my external ROM lives in code memory from 2000-7FFF with selectable 16k banks from 8000-BFFF which are accesible from both code and data space. At the top I have 8 kB of shared code and data space E000-FFFF.
You can only execute code from the memory regions which are output enabled by /PSEN

You could try and combine the signals from /PSEN en /RD on the lower part (so it would be possible to execute code from there) but the Basic has provisions for extending and replacing certain functions by placing certain values and code at 2000... and 4000... so that may create a conflict.

For testing you could combine the /PSEN and /RD with two diodes: one cathode to /PSEN and other cathode to /RD and anodes connected together to /OE of your SRAM and a pullup resistor from /OE to +5V

BTW: not resolving your CALL [expr] problem but for specific functions you could create a jump table at the beginning of your machine code so they are at fixed places.
 
Last edited:
but apparently the call paramater cant be a variable, it has to be a hard coded address like CALL 7400H (?)
One idea is to copy a LJMP xxxx into RAM at a fixed address, then have the 'E' command change the jump operand before calling the fixed address (?)
One possible solution for this might be to write the start address of your LJMP at internal locations 20h and 21h (these are free to use) and then have a small assembler routine use these as jump location.

Something like this:

Code:
MOV DPH,20h
MOV DPL,21h
CLR A
JMP @A+DPTR
 
First I need to work out how best to overlay prog & data memory - Ron Dekker's page has lots of detail to digest :)
I have been chatting with Gemini about a simple memory mapper which would make it possible to test some machine code programs and it gave me some clues but alas not the exact right answer. Still together we came up with this:
Screenshot from 2025-11-03 15-14-26.png

With just a single 74LS00 IC it maps the 32 kB SRAM into the standard data region 0000h-7FFFh but the last 8 kByte from 6000h-7FFFh is also accessible as program/code memory from 6000h-7FFFh (so no conflicts with the program/code 2000/4000 area) You can lower MTOP to protect this region from Basic overwriting it.

You just have to disconnect the /OE line of the SRAM and connect it to /OE of this circuit. Inputs are /PSEN, /RD, A13 and A14 (and power of course).
I tested the circuit in the Logic Simulator at logic.ly But no warranty:p
 
Small update: I created a files that contains all instructions and assembled it. Next I used my disassembler to disassemble it and I used my assembler to assemble the created source. The resulting binary was the same the as the first one. So it seems both assembler and disassembler work.
The only thing I have to to is to convert known addresses of special function registers into their named like 0E0h into "A".
 
Back
Top