;**************************************************************************
; FLASH.ASM - routine to make user code bootable from a flash eeprom
;
; The FLASH program should be assembled separately. Load your routine,
; then load FLASH, set the register R1 to indicate the end of your code
; (the last address) and run FLASH from program address $7FE0.
;
;
; 3 Nov. 1994 : version 1.0 rlr/ljd
; 13 Apr. 1995 : 1.1 rlr - force write to low byte (enable_prot)
; 25 Oct. 1995 : 1.2 rlr - correct conversion to sector count
; 29 Mar. 1996 : 1.3 mnw - added user discription
; 06 Feb. 1997 : 1.4 wtb - added comments from Johan Forrer
; 04 Apr. 1997 :
1.5 updated with variable end_address by F.Kuenle & M.Maier
;
:
so you no longer have to manually set R1. the code just
;
sets it to the highest legal address
;
for you - d.r.
;
; copyright (C) Motorola 1994
;
; execute with: R1 containing last address to store
; Comments from Johan Forrer KC7WW
; 1) Assemble your aplication program with the "-l" option. Check the
; LAST address in P. Remember ONLY P code will be saved into EEPROM,
; this means that coefficients or other constants need to be transferred
; from P->X/Y as part of the user's code.
; 2) Load this user program into EVM's memory using the debugger.
; 3) Load FLASH.CLD into the EVM's memory.
; 4) Modify register R1 to contain the LAST address as in (1). Remember that
; the EVM only accepts the value AFTER the register contents is
; displayed in HIGHLIGHED text.
; 5) "GO 7F00" or simply "GO" and wait till the debugger returns to diplaying
; "DEBUG" - it may take a few seconds.
; 6) Power down or RESET and the application will now restart from
; FLASH EEPROM.
; 7) Reminder that the maximum address range for the FLASH EEPROM on the
; EVM is from 8000 - FFFFh. However, the ROM bootstrap on the 56002 will
; load 512 words starting at C000h at boot time. This then means that
; you may only utilize the FLASH EEPROM space corresponding from
; 8000-BFFFh, a mere 4000h bytes, or 1555h 24-bit words. This will
; be equal to saving the address range P:0000 - 1554h. The program
; "FLASH.ASM" will write code in 64 word blocks, that means that the
; highest P-address may only be >>>1540h<<<. This is the highest value
; that may be entered safely into R1 before programming the EEPROM.
;**************************************************************************
BCR equ $FFFE ;Bus Control Register
PLL_CTRL equ $FFFD ;PLL Control Register
begin_address equ $7FE0 ;The loader will be copied to p:$7fe0
end_address equ $153f ;feste Userprg.endadresse
org p:$7F00
main
;---------------------------------------------------------------------------
; An external boot-ROM must have the lowest byte of data at the lowest
; address. (i.e., ROM Address $C000 --- P:0000 low byte
; ROM Address $C001 --- P:0000 middle byte
; ROM Address $C002 --- P:0000 high byte
; ROM Address $C003 --- P:0001 low byte ....)
;---------------------------------------------------------------------------
movep #$261009,x:PLL_CTRL ;set PLL for MF=10, 40 MHz VCO out
movep #$B0B0,x:BCR ;at 40MHz, T=25ns, 11 wait states in P:
;------ move the bootstrap loader into FLASH at P:$C000
move #end_address,r1 ;set end-address of userprg !!!
move r1,P:boot+$E ;modify boot for length
move #boot,r0 ;first DSP address to save
move #$C000,r2 ;flash starting address
jsr WR_FLASH ;save 64 words
move r1,A ;convert word cnt to sector cnt.
rep #6
asr A
move A1,r1
nop
move (r1)+
move #$8000,r2 ;address of initial FLASH address
move #$0000,r0 ;r0 points to input code
do r1,loop ;write sectors
jsr WR_FLASH
loop
movep #$0000,x:BCR
debug
jmp *
;************************************************************************
; WR_FLASH
; This routine writes 64 (24-bit) words from DSP RAM to FLASH EEPROM
;
; enter with: r2 pointing to starting EEPROM Byte Address
; r0 pointing to first DSP word to save
;
;-------------------------------------------------------------------------
; first, move 64 bytes - this includes 21 words + low byte of 22nd
;-------------------------------------------------------------------------
WR_FLASH
jsr disable_protect
do #21,move_codeA ;move 63 bytes
move P:(r0)+,A ;get 3 byte word
move A1,x:(r2)+ ;move low byte to FLASH EEPROM
rep #8
lsr A
move A1,x:(r2)+ ;move mid byte to FLASH EEPROM
rep #8
lsr A
move A1,x:(r2)+ ;move high byte
move_codeA
;*** 64th byte
move P:(r0)+,A ;get next 3 byte word
move A1,x:(r2)+ ;move low byte
jsr delay_200u ;wait 200 microseconds to enter
;...program cycle
jsr program_complete ;wait for programming cycle to
;...finish
;-------------------------------------------------------------------------
; then, move another 64 bytes - mid and high bytes of 22nd word followed
; by 20 words and then the low and mid
; bytes of the next word
;-------------------------------------------------------------------------
jsr disable_protect
rep #8
lsr A
move A1,x:(r2)+ ;move mid byte to FLASH EEPROM
rep #8
lsr A
move A1,x:(r2)+ ;move high byte
do #20,move_codeB ;move 60 bytes
move P:(r0)+,A ;get 3 byte word
move A1,x:(r2)+ ;move low byte to FLASH EEPROM
rep #8
lsr A
move A1,x:(r2)+ ;move mid byte to FLASH EEPROM
rep #8
lsr A
move A1,x:(r2)+ ;move high byte
move_codeB
;*** 63rd byte ***
move P:(r0)+,A ;get next 3 byte word
move A1,x:(r2)+ ;move low byte
rep #8
lsr A ;*** 64th byte ***
move A1,x:(r2)+ ;move mid byte to FLASH EEPROM
jsr delay_200u ;wait 200 microseconds to enter
;...program cycle
jsr program_complete ;wait for programming cycle to
;-------------------------------------------------------------------------
; lastly, move another 64 bytes - high bytes of last word followed
; by 21 words
;-------------------------------------------------------------------------
jsr disable_protect
rep #8
lsr A
move A1,x:(r2)+ ;move high byte of last word
do #21,move_codeC ;move 63 bytes
move P:(r0)+,A ;get 3 byte word
move A1,x:(r2)+ ;move low byte to FLASH EEPROM
rep #8
lsr A
move A1,x:(r2)+ ;move mid byte to FLASH EEPROM
rep #8
lsr A
move A1,x:(r2)+ ;move high byte
move_codeC
jsr delay_200u ;wait 200 microseconds to enter
;...program cycle
jsr program_complete ;wait for programming cycle to
;...finish
jsr enable_protect
rts
;***************************************************************************
;----------------------------------------------------------------------------
; enable_protect - Software data Protection routine
;
;----------------------------------------------------------------------------
enable_protect
move #>$AA,x0
move x0,x:$D555 ;Atmel needs $5555
move #>$55,x0
move x0,x:$AAAA ;Atmel needs $2AAA
move #>$A0,x0
move x0,x:$D555 ;writes are now enabled
rts
;---------------------------------------------------------------------------
; disable_protect - Disables Software Data protection
;
; This code writes the appropriate data to the FLASH part that disables
; the write protection from the FLASH and allows the part to be loaded.
;
;---------------------------------------------------------------------------
disable_protect
move #>$AA,x0
move x0,x:$D555
move #>$55,x0
move x0,x:$AAAA
move #>$80,x0
move x0,x:$D555
move #>$AA,x0
move x0,x:$D555
move #>$55,x0
move x0,x:$AAAA
move #>$20,x0
move x0,x:$D555 ;exit data protect state
rts
;---------------------------------------------------------------------------
; delay routine to be used to satisfy tBLC time requirement which is
; a minimum of 150 microseconds.
; Write Pulse Width, Write Pulse Width High requires a minimum of
; 3000 Icycles for 40MHz clock. (50ns/Icycle)
;---------------------------------------------------------------------------
delay_200u
rep #4000 ; delay of 200 micro seconds.
nop
rts
;---------------------------------------------------------------------------
; program_complete - routine to poll for the end of the programming cycle
;
; The AT29C256 will toggle bit 6 on successive reads until the program
; cycle completes. When bit 6 stabilizes, the device is no longer in
; a programming cycle.
;---------------------------------------------------------------------------
program_complete
btst #6,x:$8000 ;check the initial status of bit 6
jcs check_set
check_clr ;---go here if bit 6 is clear---
jsr delay_200u ;no need to hurry, give it a rest
btst #6,x:$8000 ;test bit 6...it was clear
jcs check_set ;if it is now set, continue...
rts
check_set ;---go here if bit 6 is set---
jsr delay_200u
btst #6,x:$8000 ;test bit 6...it was set
jcc check_clr ;if it is now clear, continue...
rts
;**************************************************************************
; this is the bootstrap loader
; it is loaded into the memory at boot time and then moves the
; application code into DSP RAM
;
boot
org p:0,p:*
;----------------------------------------------------------------------------
;The following code moves the loader code from the P:RAM.
;----------------------------------------------------------------------------
begin
move #reloc,r0 ; R0 points to loader code.
move #begin_address,r1 ; R1 points to runtime loader loc.
do #load_length,_move_code ; Move loader code to runtime loc.
move p:(r0)+,x0 ; Read loader code from load loc.
move x0,p:(r1)+ ; Write loader code to runtime loc.
_move_code
;----------------------------------------------------------------------------
;The following code moves the user's code from the flash to P:RAM.
;----------------------------------------------------------------------------
jmp load
reloc
org p:begin_address,p:
load move #$0000,r0 ; copy EEPROM into P:RAM @ $0000
move #$8000,r1 ; R1 points to the code in flash
move #1000,r2 ; R2 contains the length of code
; in words.
do r2,_ld_loop1 ; Loop once for each word of code.
do #3,_ld_loop2 ; Loop 3 times for each word.
movem p:(r1)+,a2 ; Load byte from flash.
rep #8 ; Shift eight times to move
asr a ; byte into correct position.
_ld_loop2
movem a1,p:(r0)+ ; Stores 24-bit word.
_ld_loop1
jmp 0 ; Jump to the reset vector.
load_length equ *-load
end