todd@ivucsb.sba.ca.us (Todd Day) (10/09/89)
Building a DSP board, Part Seven: Serial Loader Bootstrap --------------------------------------------------------- This is the seventh in a series on how I went about building a dual Motorola DSP56000 sampling board. Okay, first off, how did I make this board two channel in, four channel out? Well, I told you how to make a single DSP board (two in, two out). All you have to do is hook the second DSP to same input section you made for the first one, and make another completely new output section for the second one. Now we have to make the board boot. Since I'm using two DSPs, I'll have to burn two EPROMs. First, let's find out how the built-in bootstrap ROM on the 56000 works. When the 56000 boots, it loads its original operating mode from some external pins. There are four different modes. We want to set the chip up for a mode 1 initialization. Mode 1 loads an external program into internal program RAM (PRAM) and then switches to mode 2 and starts executing from internal PRAM. Mode 2 is the standard operating mode. Mode 1 is a fairly whacked out operating mode. The 56000 executes from internal PROM, reads from external PROM, and then writes to internal PRAM. The first thing the 56000 does is decide whether to load from an external byte-wide PROM or load from the byte-wide host port. It does this by checking the MSBit of P:$C000 (the P: prefix means a reference to the program memory, as opposed to the X: and Y: memories). We set this bit high (we want it to boot from EPROM) by tying D23 to +5V through a 10k resistor. The 56000 then selects 15 wait states (more than enough for our slow 250ns EPROM) and begins loading the PRAM from the EPROM. Now, how does the 56000 map 8 bit-wide bytes into 24 bit-wide words? Let's have a look: EPROM PRAM $C000 $0000 low byte $C001 $0000 middle byte $C002 $0000 high byte . . $C5FD $01FF low byte $C5FE $01FF middle byte $C5FF $01FF high byte Note that the PRAM loading is the Intel bassackwards method of LSB MSB instead of the awesome Motorola method of MSB LSB. Go figure... Now, I didn't feel like dealing with the $C000 decoding, so I just hooked up the lower address bits to the EPROM (I used a 2716) plus the P address bank selector. So, after the 56000 is done loading from the EPROM, it switches to operating mode 2 (maps PRAM to program fetching as well as P: writing) and boots the program it just loaded from P:$0000. Here is the program that I blasted into my EPROM. I think it is documented fairly okay, so I won't say anything else. Next time: initializing all of your hardware ---------------------------------------------------------------------- ; sloader.asm ; Wed Aug 2 23:56:14 PDT 1989 ; This file originally came from Motorola's Dr. BuB DSP board. ; Slightly modified by Todd Day (todd@ivucsb.sba.ca.us) ; to echo characters received. ; Serial Loader for the DSP56000. ; This loader initializes the serial communications interface (SCI) ; on the DSP56001 for 9600 baud and then loads OMF records (output ; by the DSP56000 assembler) into internal memory. The loader takes ; the upper 128 bytes of P memory allowing the lower memory from ; $0000-(LDRMEM-1) to be used by the user. The following records are ; interpreted: ; _DATA X ADDR ; _DATA Y ADDR ; _DATA P ADDR ; _END ADDR ; After the END record is encountered, the loader jumps to the address ; in the END record. Note that an address MUST be present in the ; END record (the program must contain at least one P segment). ; ; To generate a EPROM of this loader (8Kx8), perform the following: ; $ asm56000 -b -l -a sloader ; $ srec sloader ; ; The EPROM is in file SLOADER.P. To program the EPROM, set the ; programmer to MOTOROLA S record format, download the file with ; a zero address offset and program the part. ; ; BTW, S record format is LSB MidSB MSB (what! Intel format? :-) ; Took me a few hours to figure this one out! ; ; If you don't have the program srec (where can I get this?), ; you have to do some gnarly contortions on the .LOD file. ; ; So, if your .LOD file resulting from compiling this program ; looks like this: ; ; _START SLOADER 0000 0000 ; ; _DATA P 0020 ; 010203 040506 070809 ; _END 0020 ; ; then, program your PROM with this sequence: ; $0020 0302 0106 0504 0908 07..... etc. (Fun, eh? :) ; ; ; The loader loads the following memory spaces: ; X - 0 to FF ; Y - 0 to FF ; P - 0 to LDRMEM-1 ; PAGE 68,66,1,1 SCR EQU $FFF0 ;SCI CONTROL REGISTER SCCR EQU $FFF2 ;SCI CLOCK CONTROL REGISTER PCC EQU $FFE1 ;PORT C CONTROL REGISTER RDRF EQU $2 ;RECEIVE DATA REGISTER FULL FLAG SSR EQU $FFF1 ;SCI STATUS REGISTER SRXH EQU $FFF6 ;SCI RECEIVE IN HIGH BYTE LDRMEM EQU $19D ;START OF LOADER IN P MEMORY ORG P:$0000 ;RESET VECTOR FOR BOOTING RVEC JMP LOAD ;GO EXECUTE LOADER ORG P:LDRMEM,P:3*LDRMEM LOAD MOVEP #$0302,X:SCR ;ENABLE TX,RX: 8 BIT 1 START, 1 STOP ; *** You will probably have to ; *** change the line below! MOVEP #$0020,X:SCCR ;CD=32 (/33), INT CLK @ 9600 BAUD MOVEP #$0007,X:PCC ;ENABLE SCI WTUS JSR GETCH ;INPUT CHARACTER MOVE #'_',X0 ;GET UNDERSCORE CHARACTER CMP X0,A ;SEE IF "_" YET JNE WTUS ;NO GOTUS JSR GETCH ;GET A CHARACTER MOVE #'D',X0 ;GET A D FOR DATA CMP X0,A #'E',X0 ;COMPARE TO D, GET E JEQ DATAREC ;IF "D", THEN DATA RECORD CMP X0,A ;SEE IF END RECORD JNE WTUS ;NO, GO WAIT FOR ANOTHER UNDERSCORE _WTSPC JSR GETCH ;GET CHARACTER MOVE #$20,X0 ;GET SPACE CMP X0,A ;WAIT FOR SPACE AFTER "END" JNE _WTSPC ;WAIT FOR SPACE JSR IN4 ;GET TRANSFER ADDRESS MOVE B1,R0 ;MOVE TRANSFER ADDRESS NOP ;CLEAR ADDRESS PIPE JMP (R0) ;GO EXECUTE USER CODE DATAREC JSR GETCH ;GET CHARACTER MOVE #$20,X0 ;GET SPACE CMP X0,A ;SEE IF SPACE JNE DATAREC ;NO JSR GETCH ;GET [P,X,Y] MOVE A1,Y0 ;SAVE CHARACTER JSR IN4 ;GET ADDRESS OF DATA RECORD MOVE B1,R0 ;SAVE ADDRESS MOVE #'X',A ;GET X CMP Y0,A #'Y',A ;SEE IF X, GET Y JEQ _LDX ;LOAD DATA INTO X MEMORY CMP Y0,A ;SEE IF Y JEQ _LDY ;LOAD DATA INTO Y MEMORY _LDP JSR IN6 ;GET DATA MOVE B1,P:(R0)+ ;LOAD P MEMORY JMP _LDP _LDX JSR IN4 ;GET DATA MOVE B1,X:(R0)+ ;LOAD X MEMORY JMP _LDX _LDY JSR IN4 ;GET DATA MOVE B1,Y:(R0)+ ;LOAD Y MEMORY JMP _LDY GETCH JCLR #RDRF,X:SSR,* ;WAIT FOR DATA IN SCI MOVEP X:SRXH,A ;GET SCI DATA IN HIGH BYTE LSL A ;SHIFT OUT PARITY LSR A ;PUT 0 IN PARITY BIT MOVE A1,A ;SIGN EXTEND AND ZERO MOVEP A,X:SRXH ;put sci data in high byte RTS IN4 CLR B #>4,X0 ;CLEAR VALUE, GET 4 JMP READHEX ;READ 4 HEX CHARACTERS IN6 CLR B #>6,X0 ;CLEAR VALUE, GET 6 READHEX DO X0,_READHEX ;READ ASCII HEX AND CONVERT TO BINARY _GET JSR GETCH ;GET A CHARACTER MOVE #'_',X0 ;GET UNDERSCORE CMP X0,A #'F',X0 ;SEE IF UNDERSCORE JNE _NOTUS ;NO ENDDO ;EXIT LOOP MOVE SSH,X0 ;POP RETURN ADDRESS JMP GOTUS ;GO PROCESS NEW INPUT RECORD _NOTUS CMP X0,A #'0',X0 ;SEE IF GREATER THAN F JGT _GET ;YES, IGNORE CMP X0,A ;SEE IF LESS THAN 0 JLT _GET ;YES, IGNORE SUB X0,A #10,X0 ;ADJUST FOR ASCII TO BINARY CMP X0,A #7,X0 ;SEE IF A-F JLT _NOTALPHA ;NO SUB X0,A ;ADJUST FOR 1-F _NOTALPHA REP #4 ;SHIFT OLD VALUE LEFT 1 NIBBLE LSL B REP #16 ;SHIFT NEW NIBBLE DOWN TO LSB LSR A ADD A,B ;ADD NEW NIBBLE IN _READHEX RTS END -- Todd Day | todd@ivucsb.sba.ca.us | ivucsb!todd@anise.acc.com "Time to eat all your words, swallow your pride, open your eyes." -- Tears for Fears