• Please review our updated Terms and Rules here

8051/8052 SBC

I realise its just a throwaway basic52 demo but the Mandelbrot example on Dennou Densetsu's page had me baffled.
When I first built the board it worked perfectly and I posted a photo of my screen. Today it wouldnt display correctly at all.
I'd built another Densetsu so I tried that - same problem. Maybe its Teraterm, tried the Arduino terminal window, same problem.
Tried the program on one of my Grant Searle Z80's and it was the same so I knew the program was wrong!
Turns out that its Googles fault!
Dennou's page (vintagechips) initially displays in Japanese Kanji, if you copy & paste the mandelbrot program from there it works fine.
If you click " translate to English" then copy & paste the mandelbrot program, it misses out a minus sign in line 80
Literally lost in translation!!!
However, thats wasted an entire evening so i havent done my code memory mod yet. Maybe tomorrow!
Cheers
Phil

10 FOR Y=-12 TO 12
20 FOR X=-39 TO 39
30 CA=X*0.0458
40 CB=Y*0.08333
50 A=CA
60 B=CB
70 I=0
80 T=A*A-B*B+CA
90 B=2*A*B+CB
100 A=T
110 IF (A*A+B*B)>4 THEN GOTO 150
120 I=I+1:IF I<=15 THEN GOTO 80
130 PRINT " ",
140 GOTO 170
150 IF I>9 THEN I=I+7
160 PRINT CHR(48+I),
170 NEXT X
180 PRINT
190 NEXT Y
 
If your terminal is in color you can try this one also:

Code:
5      REM 8052 color Mandelbrot (VT100/ANSI)
7      PRINT CHR(27),"[0m",
10     FOR Y=-12 TO 12
20     FOR X=-39 TO 39
30    CA=X*0.0458
40    CB=Y*0.08333
50    A=CA
60    B=CB
70    I=0
80    T=A*A-B*B+CA
90    B=2*A*B+CB
100   A=T
110    IF (A*A+B*B)>4 THEN 150
120   I=I+1 :  IF I<=15 THEN 80
130    PRINT " ",
140    GOTO 170
150    PRINT CHR(27),"[",
160    IF I<8 THEN  PRINT "3",CHR(48+I),"m#",
165    IF I>7 THEN  PRINT "9",CHR(40+I),"m#",
170    NEXT X
180    PRINT
190    NEXT Y
195    PRINT CHR(27),"[0m",
200    END
 
My 'Dennou' BASIC-52 Executor board, kindly given to me by Phil_G, has a 32k static ram mapped from 0000H to 7FFFH in the xdata space and uses the Atmel AT89C52's own flash memory for its code space (8k from 0000H to 1FFFH). To make 24k of the RAM from 2000H to 7FFFH also appear in the code space at those same addresses, I made a simple modification using two 1N4148 diodes, and one 10k resistor - forming a diode-resistor AND gate.

Cut the track from pin 17 (/RD) of the microcontroller to the /OE pin of the ram (pin 22 for the RAM on the Dennou board). Two diodes to pins 17 (/RD) and pin 29 (/PSEN) of the microcontroller with their cathodes (barred ends) facing the micro. The anodes of the diodes both connect to the (/OE) pin of the RAM, along with one leg of the 10k pull-up resistor.
Seems to work reliably, even with a 22.1184 MHz crystal fitted for "double speed" operation of *MCS BASIC-52 V1.31* and now allows me to load and execute machine code from a BASIC program.
 
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".
It seems I have covered that as well. Now I have to write some programs, real programs, to run on the SBC I bought.
 
My 'Dennou' BASIC-52 Executor board, kindly given to me by Phil_G, has a 32k static ram mapped from 0000H to 7FFFH in the xdata space and uses the Atmel AT89C52's own flash memory for its code space (8k from 0000H to 1FFFH). To make 24k of the RAM from 2000H to 7FFFH also appear in the code space at those same addresses, I made a simple modification using two 1N4148 diodes, and one 10k resistor - forming a diode-resistor AND gate.

Cut the track from pin 17 (/RD) of the microcontroller to the /OE pin of the ram (pin 22 for the RAM on the Dennou board). Two diodes to pins 17 (/RD) and pin 29 (/PSEN) of the microcontroller with their cathodes (barred ends) facing the micro. The anodes of the diodes both connect to the (/OE) pin of the RAM, along with one leg of the 10k pull-up resistor.
Seems to work reliably, even with a 22.1184 MHz crystal fitted for "double speed" operation of *MCS BASIC-52 V1.31* and now allows me to load and execute machine code from a BASIC program.
Martins mod works fine -sorry I called it an OR as its inverted logic, if /PSEN or /RD are low /OE is enabled, just the way I was thinking:
Also Gert's mod to the BASYS 'E'xecute command now works great! Thanks both

diode_or_psen_rd.jpg
 
It seems I have covered that as well. Now I have to write some programs, real programs, to run on the SBC I bought.
As a torture test you could try and assemble my preliminary code for my 8052AH Basic Extended project. It is already over 1500 lines :eek:
Lots of comments inside and it uses different origins and offset calculations.
 
I've now got my Dennou board running with an STC 89C52. It's better than the Atmel AT89C52 or AT89S52 in several ways:

* cheaper - there are lots of sellers on Ali Express.
* has the option to run at 6T as well as 12T, so twice as fast on the same crystal (and runs happily with a 22.1184 crystal, so four times as fast as a vanilla 8052).
* has a built-in serial bootloader, that works over the same serial connection you normally use to talk to the board.

The last one is perfect for trying out different firmware. You don't need any extra hardware. You just use the free stcgal utility (available for Windows, Mac, and Linux) to flash the chip - much faster than levering chips in and out, and using an external programmer. I've also been using an ICSP tool (SPI) with the Atmel 'S' chip, but even that requires a second serial port on the PC - and it's slower than the STC chip to flash anyway. Now you can easily swap between, say, MCS BASIC-52 V1.31, and Brad Rodriguez's CamelForth, in just a few seconds.

I struggled for a while to get it working, but it was just a couple of chip settings - easily altered by stcgal. You only need to do these once.
stcgal -p (comport) -o xram_enabled=False hexfile.hex
stcgal -p (comport) -o cpu_6t_enabled=True hexfile.hex

The important one for this board is the xram_enabled=False. The STC chips have a small amount of internal xram, which is enabled by default. But when you're fitting a big external ram, you need to disable the internal xram to make BASIC work properly. The 6T thing you might as well do, seeing as BASIC auto-detects the baud (which otherwise would need to be set twice as fast in 6T mode).
 
In my excitement at getting the STC chip running BASIC, I overlooked its flaw. It can't execute code in external memory. So it can run BASIC programs fine - reading from the external RAM and interpreting the instructions. But it can't jump to machine code poked into that RAM: it doesn't have a working /PSEN pin, so can't do the trick of having RAM also appear in its Harvard architecture code space. This makes it pretty useless for most FORTHs, including CamelForth.

There is supposed to be a version of the STC 89C52 available that does have a working /PSEN pin, but I've never been able to find one: all the common versions have the /PSEN pin repurposed as an extra GPIO pin.
 
Well that is a bummer that there are STC chips which do not have the /PSEN pin.
The datasheet mentions that the HD versions should have them with this cryptic text:

How to identify 90C and HD version:
See the the last few letters of the bottom
line of MCU surface text


I have used de Atmel 89S52 and the 89C52 and they seem to work, in the past I have used some Dallas chips like the DS5000 and the Siemens 80535.
NXP/Philips made lots of the 805x variants.
 
Hallo Gert
Circuit above tested and works OK.
Do you have a ML program that I can use to test the stand alone DIY board, please? Preferably something that can communicate with a terminal but something simple as lighting up the LEDs in a fancy way is fine as well.
Alvast bedankt / TIA!
 
Do you have a ML program that I can use to test the stand alone DIY board, please? Preferably something that can communicate with a terminal but something simple as lighting up the LEDs in a fancy way is fine as well.
My very first 8052 program, works for me if I use CALL 6000H directly from BASIC-52, but not if I use the BASYS Execute command (?)

hello_world.jpg
 

Attachments

Last edited:
Hallo Gert

Do you have a ML program that I can use to test the stand alone DIY board, please? Preferably something that can communicate with a terminal but something simple as lighting up the LEDs in a fancy way is fine as well.
Alvast bedankt / TIA!
Hi Ruud,

Just made a very simple test program which toggles PORT1 bit 7.
You can write it directly into the 89C52 or 89S52, it does not use the stack or other features. The hex and binary files are here also.

I also included the demo program that came with W.W. Heinz's assembler (ASEM-51)
 

Attachments

My very first 8052 program, works for me if I use CALL 6000H directly from BASIC-52, but not if I use the BASYS Execute command (?)
Yeah I found the 'oops' High and Low byte are swapped... 20h is the High byte and 21h is the low byte.
Line 3010 should read like this:

Code:
3010 DBY(21H)=H.AND.0FFH:DBY(20H)=INT(H/256):CALL 07FF0H

Give it a try
 
Yep the BASYS Exeute command works perfectly now, thanks Gert

basys52_hello.jpg

Since theres no loader, after manually typing the hello world program in twice I did a very quick converter to make a keyfile from the assemblers hex file.
You just enter the BASYS 'M' command, give it the address 6000H, then in Teraterm do file, send, out.dat (with char & line delays)
I use PC Basic as an 'awk-like' tool for simple quickies like this:
Code:
10 INPUT "Input hexfile";H$
50 OPEN H$ FOR INPUT AS 1
60 OPEN "OUT.DAT" FOR OUTPUT AS 2
70 WHILE NOT EOF(1)
100 LINE INPUT #1,L$:L=L+1
105 N=VAL("&H"+MID$(L$,2,2))
130 FOR B=10 TO (2*N+8) STEP 2
140 D$=MID$(L$,B,2):PRINT #2,"0";D$;"h"
160 NEXT:WEND
190 PRINT #2,"-1"
200 CLOSE #1:CLOSE #2
210 PRINT "SET CHARACTER DELAY TO 50MS, LINE TO 200MS"
220 PRINT "TYPE M COMMAND IN BASYS, THEN SEND FILE OUT.DAT"
 
Last edited:
For embedding machine code within a BASIC-52 program, is there a 'standard' method?
I've been using naive DATA statements, beginning with an address, then a list of bytes, terminated by -1. And a simple loop to XBY() (poke) the data to memory.
I've written a little Lua program that converts an intel hex file to that format.

Interestingly, you can pack more data on each line using decimal numbers than hex. That's because, in BASIC-52, a number literal must begin with a digit, 0 to 9 inclusive, so 102 (I think) of the 256 possible bytes take up 4 characters - e.g. 0A1H, whereas, using decimal, at most three digits suffice.

print aah -> 0 (unless you've already allocated a non-zero value to the variable: aah)
print 0aah -> 170 (the hex literal AA)

We could get more data per line, and in a nicer hex format, by doing something like:

10 REM 7000 A1 0A 33 7C 30 ...

... but then we would need a much bigger, more complicated, and slower BASIC-52 routine to find the data and transfer bytes to memory.
 
I put together an 8031-based kit for VCF Southwest. The following year I put together a Camel Forth expansion with dual-mapped RAM.

You can use an 8031, 8032, 8051, or 8052 in it using an external EPROM for BASIC. If your 8052 has BASIC built-in, you'll need to modify the grounded EA pin (pin 31) on the PCB which disables the internal ROM.


Gerbers are there for you to use with your favorite PCB fab.

Raymond
 
For embedding machine code within a BASIC-52 program, is there a 'standard' method?
This doesnt really answer the question but around 1982 when I'd had enough of my Nascom-1's tantrums, I bought the nearest affordable commercial equivalent, an EACA Genie. As supplied it was a BASIC-only machine and since at the time no machine-code utilities were available, I came up with BASYS, a 'trad' monitor in BASIC. Loading machine code from REM lines full of hex was ok but slow, needing range tests for 0-9 vs A-F and different adjustments to suit. Consequently I did my own 'version' of hex, which I called PEX as in Phil's hex. PEX is one character per nibble like trad hex, but uses the characters @ to letter O. The reading software needs no range tests, just one simple OR 0x0F. This was much quicker and since then I've continued to use PEX in BASIC programs (mostly NIBL) without really thinking much about it. I find its significantly quicker than converting intel hex and poking it to memory.
I've one of my usual crappy basic programs to generate the REM lines from an Intel hex file, and the PEX reader has been recycled through many computers since then.
Code:
HEX:    PEX:
0    @ $40  64d
1    A $41  65d
2    B $42  66d
3    C $43  67d
4    D $44  68d
5    E $45  69d
6    F $46  70d
7    G $47  71d
8    H $48  72d
9    I $49  73d
A    J $4A  74d
B    K $4B  75d
C    L $4C  76d
D    M $4D  77d
E    N $4E  78d
F    O $4F  79d

Here's an example that shows how NIBL loads my serial fast-loader code into high memory on the SC/MP:
Code:
10 REM @HLBCACELBC@CALD@HLJNJ@FMDB@ILOKLDDCHO@@@FMDB@ILOBLDHNHO@@@FMDB@
20 REM IL@BIH@BLD@AAO@AAM@AKJNJILNKD@LM@ALDKMHO@@@FMDB@ILLM@FMDB@IHOKCO
30 PR"Installing serial fast-loader to 0x7F00 ...":M=#7F00:S=#000A
40 P=@#1012:@#1041=P*16:IF P=1 S=#1128
50 FOR L=0 TO 1:FOR B=0 TO 62 STEP 2:A=S+B+L*73
60 X=(@A) AND 15:Y=(@(A+1)) AND 15:Z=(16*X)+Y:@M=Z:M=M+1:NEXT B:NEXT L
70 PR"Set Y=address, set binary, LINK#7800. Alt-B to exit."
 
Last edited:
For embedding machine code within a BASIC-52 program, is there a 'standard' method?

One thing you can do on BASIC-52 is put your code on an EPROM, set a few bits, and add a command for it in BASIC. BASIC-52 allows you to define your own keywords and extend the instruction set.

; .command -ai ; output Intel hex format
; ===============================================
; Add command table entry to start CamelForth on 8031
; Show Computer for VCF Southwest
;
;
.ORG 2002H
.DB 5AH ;Tell BASIC expansion options available
;
.ORG 2048H
SETB 2DH ;Set bit 45 to enable expansion
RET ;command lookups in BASIC
;
.ORG 2070H
MOV DPTR, #VECTOR_TABLE ;LOCATION BASIC CALLS TO GET
RET ;USER VECTOR_TABLE LOOKUP ADDRESS
;

.ORG 2078H
MOV DPTR, #USER_TABLE ;LOCATION BASIC CALLS TO GET
RET ;COMMAND TOKEN LOOKUP TABLE
;
USER_TABLE: .ORG 2200H
.DB 10H ;FIRST TOKEN
.DB "CAMEL" ;CAMEL KEYWORD
.DB 0FFH ;END OF USER TABLE
;
VECTOR_TABLE: .ORG 2300H
.DW RUN_CAMEL
;
RUN_CAMEL: .ORG 2400H
LJMP H'A000
RET
;

It adds the key word "CAMEL" to launch Camel Forth. You can't use "FORTH" because it conflicts with "FOR"

BASIC-52 looks at $2002h for a 5A value which specifies that extensions for BASIC are available. Then you set bit 45 to enable it. Set up a vector table, user table, put in your command key words, then the code the command key word executes. It's all documented in the manual and quite easy to do, even for this absolute n00b on machine coding.
 
Back
Top