How to run BASIC-52 on an 8032 from external eprom: Any 8052 or 8032, with timer 0, 1 and 2, which is required by Basic-52, can run Intel's Basic-52 interpreter. Connect everything as suggested for a usual setup with the 8052-AH Basic device, except: pin 31 of the processor has to be kept at a low level to execute from external eprom. The processor has to find eprom from address 0 on up to any address you like. For Basic-52 you will need 8K. The /OE of the eprom which holds the Basic-52 code has to be driven by the processor's /PSEN line. This means you cannot tie /PSEN and /RD together through an LS08 as is done in the usual 8052-AH setup. The 8052-AH only activates the /PSEN line when accessing more than it's internal 8K of rom. Pin 31 of the processor being low means the internal rom is disabled and code is expected from external memory. Since you then have ram end eprom at the same addresses, they will be distinguished only by different output enable signals (/RD for ram and /PSEN for code memory). This also means that you can't run assembler programs from ram, because the ram is read with /RD and not with /PSEN. It's easiest to test the board with a normal 8052-AH BASIC device and when it works, just change pin 31 from high to low, reset and with the code in external eprom it should run just the same. Then replace the 8052-AH by a faster 80C32S and enjoy. One other thing I changed is the user eprom. When running from external eprom, the buildt in programming routines can't work any more because the same bus can't be used for reading instructions (of the programming routine) and the data to be programmed into eprom at the same time. I use an eeprom which is in the same address space as the user eprom, but the eeprom can be written to by using the normal /WR line. So I do not use the processors pin 5 and 6 (/PROGRAM PULSE and /PROGRAM ENABLE) at all, but instead connect the eeprom just like a normal ram. This frees 2 port lines you can use for something else. For the programming to work I patched the source code a little, so the 'prog' command will write the current Basic program to eeprom. I assume you have the Basic-52 source code (I got it from nic.funet.fi, but it's also here as basic52.arj) and an assembler for it (I use Intel's asm51). Just replace the original eprom programming routines with the patch, assemble, burn into eprom and it should work. If you should have problems with this, I can send you the hex code for the eprom programmer. When you use an eeprom from adress 32768 on and you have ram up to 32767, then at every reset Basic-52 tries to determine the available ram by writing to it and reading back. If it finds ram at 32767 it will normally also try 32768, which means writing to the first eeprom location. To avoid this, I set the value for mtop to 32767 and type 'prog4'. So Basic-52 will sign on without having to hit the space bar and it will not write to the first eeprom location either. If you don't need the eeprom programming capability you could just read out the 8052-AH device and burn the code unaltered to eprom. Good luck Rolf Here is the patch: This altered section of code writes the ram resident Basic program to eeprom just like the ROM resident Basic interpreter writes to uv eproms. The eeprom is connected like ram, i.e. it uses /wr on pin 27 and gets it's adresses from the real address lines. So the only change from the original setup is the connection of /wr. In PG7: the byte is written to eeprom, in PG9: it is read back. I introduced the label pg9a: which is called from PG7:, because I needed space to load the data pointer. At one instance I moved the ZRO: -label by one byte and the floating point package did not work anymore, although at that point where this label was referenced (apparently as a constant), I had replaced this reference by the constant, so I was careful not to move any of the original labels. The assembler I used was ASM51. You can recognize my changes by the common letters as opposed to the original capital letters, which I commented out. The patch could probably be optimised, but right now it works for me. I did not notice any side effects yet but don't hold me responsible for any malfunction either. If someone improves this routine I'd like to hear about it. ;*************************************************************** ; ; CIPROG AND CPROG - Program a prom ; ;*************************************************************** ; ;$INCLUDE(:F2:BAS52.PGM) ;BEGINNING PG8: MOV R7,#00H ;PROGRAM ONE BYTE AT A TIME MOV R6,#01H MOV R2,#HIGH ROMADR-1 MOV R0,#LOW ROMADR-1;LOAD PROM ADDRESS ACALL PG1+3 INC R6 DB 0E5H ;MOV A DIRECT OP CODE DB 0CBH ;ADDRESS OF R2CAP HIGH ACALL PG1+3 DB 0E5H ;MOV A, DIRECT OP CODE DB 0CAH ;R2CAP LOW MOV R6,#3 MOV R1,#LOW MEMTOP-1 MOV R3,#HIGH MEMTOP ACALL PG1+3 ;SAVE MEMTOP SJMP PGR ; CIPROG: MOV DPTR,#IPROGS ;LOAD IPROG LOCATION SETB INTELB SJMP $+7 ;GO DO PROG ; CPROG: MOV DPTR,#PROGS ;LOAD PROG LOCATION CLR INTELB ; ACALL LD_T ;LOAD THE TIMER ; CLR PROMV ;TURN ON THE PROM VOLTAGE nop nop CALL DELTST ;SEE IF A CR JNZ PG8 ;SAVE TIMER IF SO MOV R4,#0FEH SETB INBIT ACALL ROMFD ;GET THE ROM ADDRESS OF THE LAST LOCATION CALL TEMPD ;SAVE THE ADDRESS MOV A,R4 ;GET COUNT CPL A CALL TWO_R2 ;PUT IT ON THE STACK CALL FP_BASE+14 ;OUTPUT IT ACALL CCAL ;GET THE PROGRAM ACALL CRLF ;DO CRLF MOV R0,TEMP4 ;GET ADDRESS MOV R2,TEMP5 MOV A,#55H ;LOAD SIGNIFIER INC R6 ;LOAD LEN + 1 CJNE R6,#00,$+4 INC R7 ACALL PG2-2 ; $EJECT PGR: ;SETB PROMV nop nop AJMP C_K ; PG1: MOV P2,R3 ;GET THE BYTE TO PROGRAM MOVX A,@R1 LCALL INC3210 ;BUMP POINTERS MOV R5,#1 ;SET UP INTELLIGENT COUMTER ; PG2: MOV R4,A ;SAVE THE BYTE IN R4 ACALL PG7 ;PROGRAM THE BYTE ACALL PG9 JB INTELB,PG4 ;SEE IF INTELLIGENT PROGRAMMING ; PG3: XRL A,R4 JNZ PG6 ;ERROR IF NOT THE SAME CALL DEC76 ;BUMP THE COUNTERS JNZ PG1 ;LOOP IF NOT DONE ANL PSW,#11100111B ;INSURE RB0 RET ; PG4: XRL A,R4 ;SEE IF PROGRAMMED JNZ PG5 ;JUMP IF NOT MOV A,R4 ;GET THE DATA BACK ACALL PG7 ;PROGRAM THE LOCATION ACALL ZRO ;AGAIN ACALL ZRO ;AND AGAIN ACALL ZRO ;AND AGAIN DJNZ R5,$-6 ;KEEP DOING IT ACALL PG9 ;RESET PROG SJMP PG3 ;FINISH THE LOOP ; PG5: INC R5 ;BUMP THE COUNTER MOV A,R4 ;GET THE BYTE CJNE R5,#25,PG2 ;SEE IF TRIED 25 TIMES ; PG6: ;SETB PROMV ;TURN OFF PROM VOLTAGE nop nop MOV PSW,#0 ;INSURE RB0 JNB DIRF,PG4-1 ;EXIT IF IN RUN MODE MOV DPTR,#E16X ;PROGRAMMING ERROR ; ERRLK: LJMP ERROR ;PROCESS THE ERROR ; $EJECT PG7: mov 19h,dph ;temporary save for data pointer mov 18h,dpl acall pg9a movx @dptr,a ;write the byte nop ; MOV P0,R0 ;SET UP THE PORTS ; MOV P2,R2 ;LATCH LOW ORDER ADDRESS ; ACALL PG11 ;DELAY FOR 8748/9 ; CLR ALED ; MOV P0,A ;PUT DATA ON THE PORT ; ZRO: NOP ;SETTLEING TIME + FP ZERO NOP NOP NOP NOP NOP ACALL PG11 ;DELAY A WHILE ; CLR PROMP ;START PROGRAMMING nop nop ACALL TIMER_LOAD ;START THE TIMER JNB TF1,$ ;WAIT FOR PART TO PROGRAM RET ;EXIT ; PG9: movx a,@dptr ;keep reading until correct xrl a,r4 ;data is returned jz $+6 inc r5 cjne r5,#255,pg9 movx a,@dptr mov dpl,18h mov dph,19h ret pg9a: mov dph,r2 ;load data pointer with eeprom address mov dpl,r0 ret ; SETB PROMP ; ACALL PG11 ;DELAY FOR A WHILE ; JNB P3.2,$ ;LOOP FOR EEPROMS ; MOV P0,#0FFH ; CLR P3.7 ;LOWER READ ; ACALL PG11 ; MOV A,P0 ;READ THE PORT ; SETB P3.7 ; SETB ALED ; RET ; PG11: MOV TEMP5,#12 ;DELAY 30uS AT 12 MHZ DJNZ TEMP5,$ RET ; ;END ;$INCLUDE(:F2:BAS52.PGM) $EJECT ;************************************************************** ; PGU: ;PROGRAM A PROM FOR THE USER ; ;************************************************************** ; ; CLR PROMV ;TURN ON THE VOLTAGE nop nop MOV PSW,#00011000B ;SELECT RB3 ACALL PG1 ;DO IT ; SETB PROMV ;TURN IT OFF nop nop RET ;