;flash subroutine               
;      *** Program AMD Am295010 Sector Erase Flash Memory ***
;
;       this will program the data in 8051 external RAM at
;       location 6000h (hopper memory) into flash memory location 4000h.
;       8051 internal RAM is used as a buffer and external memories
;       are switched between functioning as ROM and RAM depending on 
;       the setting of 8051 port 1
;       the flash memory is erased (non-protected sectors) before
;       programming begins
;
;               5/6/97  M. A. Kelley - BNL - Instrumentation
;
       name     flash
       org      3800h         
;
flash   nop
        setb     psw.3        ;select reg bank 1
        clr     psw.4
;at entry, data count in 8051 hopper memory
        mov     dptr,#05ffeh
        movx    a,@dptr        ;hi count
        mov     r4,a
        inc     dptr
        movx    a,@dptr        ;low count
        mov     r5,a
;initialize "partial buffer" flag
        mov     07dh,#00h
        clr     p3.4           ;flip memory for erase function 
                               ;flash memory = RAM
;erase non protected part of flash memory
        mov     dptr,#05555h   ;cycle 1 of erase function
        mov     a,#0aah
        movx    @dptr,a     
        mov     dptr,#02aaah   ;cycle 2
        mov     a,#055h
        movx    @dptr,a
        mov     dptr,#05555h   ;cycle 3
        mov     a,#080h
        movx    @dptr,a
        mov     a,#0aah
        movx    @dptr,a        ;cycle 4
        mov     dptr,#02aaah   ;cycle 5
        mov     a,#055h
        movx    @dptr,a
        mov     dptr,#05555h   ;cycle 6
        mov     a,#010h
        movx     @dptr,a
;test for erase finished or time out
erasfn  mov     dptr,#06000h   ;read any address
        movx    a,@dptr
        anl     a,#080h        ;test dq7  
        jnz     trasfn         ;if not = 0, finished
        movx    a,@dptr        ;if not finished, test
        anl     a,#020h        ;dq5 for time-out
        jnz     moret          ;=1 for time out
        sjmp    erasfn         ;otherwise, test again
moret   movx    a,@dptr        ;test for time-out at
        anl     a,#080h        ;same time as finish
        jnz     trasfn         ;finish - if not
        clr     psw.3          ;back to reg bank 0
        mov     r0,#077h       ;for error return
        setb    p3.4
        ret       
;erase algorithm finished successfully - start programming
;flash memory
;flip memory back - hopper memory = ram
;
trasfn  setb     p3.4
;initialize pointers
;                
start   inc     r4              ;takes care of last decrement
        mov     dptr,#04000h    ;pointer to flash memory
        mov     07fh,#060h      ;keep a copy of what is in p2
        mov     p2,#060h
        mov     r0,#00h         ;hopper mem pointer in r0/p2
upp2    mov     r6,#02          ;counter for p2 increment        
start1  mov     r1,#080h        ;iram buffer pointer
nxbuf   mov     r7,#080h        ;iram buffer counter
loadbf  movx    a,@r0           ;from hopper (ram)
        mov     @r1,a           ;to internal (iram)
        inc     r0              ;data pointer
        inc     r1              ;buffer poin
        mov     a,r5            ;in a to test
        jnz     okr4            ;if a not 0, branc
        mov     r5,#0ffh        ;if 0, set to 255 and
        dec     r4              ;decrement hi order        
        mov     a,r4            ;if hi order 0, data finished
        jnz     okr5
        sjmp    flashwr
okr4    dec     r5              ;if r4 wasn't 0
okr5    djnz    r7,loadbf       ;if r5 wasn't 0
; at this point, 128 bytes have been transferred to iram
; decrement p2 counter (after 256 transfers, p2 must be changed
        djnz    r6,flashwr
        inc     p2              ;adjust hi order part of hopper ptr
        inc     07fh            ;and its copy !!
        mov     r0,#0           ;reset lo order par
        mov     r6,#02          ; and p2 counter
;transfer from iram to flash memory - use AMD programming algorithm
;to write each byte
;flip memories - flash becomes ram
flashwr clr     p3.4
;dptr holds pointer to flash memory
;save hi pointer to hopper (in p2) and p2 counter (in r6)
        mov     a,r7
        jz      nopart
;partial buffer - indicating last data has been loaded into iram
        mov     7dh,#055h       ;set flag in iram absolute location
        mov     a,r7
        cpl     a               ;get 128 - r7 for new counter 
        inc     a
        add     a,#080h      
        mov     r7,a
        mov     r0,#080h        ;iram pointer     
        sjmp    bytewr          ; program last (partial) buffer
; for "not last buffer", save hi pointer to hopper and p2 counter
; just because these registers are needed!
nopart  mov     7eh,r0          ; hopper low pointer saved in iram
;init iram pointer and counter for transfer out
        mov     r0,#080h        ;iram pointer
        mov     r7,#080h        ;counter
;byte writing AMD algorithm follows
bytewr  mov     p2,#055h        ;hi order of register address
        mov     r1,#055h        ;lo order  "   "        "
        mov     a,#0aah         ;data for cycle 1 of write algorithm
        movx    @r1,a
        mov     p2,#02ah        ;same for cycle 2
        mov     r1,#0aah
        mov     a,#055h
        movx    @r1,a
        mov     p2,#055h         ;same for cycle 3
        mov     r1,#055h
        mov     a,#0a0h
        movx    @r1,a
        mov     a,@r0           ;get data byte from iram
        movx    @dptr,a         ;and write it to flash memory
;now test by data-polling if algorithm finished
polld   movx    a,@dptr         ;read byte just written
        anl     a,#080h         ;get bit 7
        mov     r1,a
        mov     a,@r0           ;compare with bit 7 of byte in
        anl     a,#080h         ;iram 
        xrl     a,r1            ;if the same, algorithm finished
        jz      algok
;if not finished, test for time-ou
        movx    a,@dptr         ;read byte once again
        anl     a,#020h         ;test bit 5 this time
        jnz     mrtes           ;timed out - test for simultaneous w/ finish
        sjmp    polld           ;no time out - test again          
mrtes   movx    a,@dptr         ;same read, test, etc
        anl     a,#080h
        mov     r1,a
        mov     a,@r0
        anl     a,#080h
        xrl     a,r1
        jz      algok
        clr     psw.3            ;back to reg bank 0 for
        mov     r0,#077h         ;error - flag - time out
        setb    p3.4
        ret
;end of data-polling - program next byte
algok: inc     dptr              ;bump pointers
       inc     r0                ;iram pointer
       djnz    r7,bytewr         ;do for 128 bytes (or partial buffer)
;buffer has been written to flash memory
;flip memories and bump to next buffer-full
;test "partial buffer" flag for finish
       mov     a,7dh             ;flag in iram
       jz      nxbuff            ;not set - transfer next buffer
;if "partial buffer" flag set
       sjmp    finish
nxbuff setb     p3.4
;restore saved values from iram
        mov     r0,07eh          ;hopper lo pointer saved
        mov     p2,07fh          ;and copy of p2 restores p2
;go to init iram pointer + counter
        ajmp    start1
;loop until r4/r5 data count is finished
;
;at end of programming flash memory, write pgb flag (77h)
;to location feffh in flash memory
finish  clr     p3.4
        mov     dptr,#05555h
        mov     a,#0aah           ;cycle 1
        movx    @dptr,a
        mov     dptr,#02aaah
        mov     a,#055h           ;cycle 2
        movx    @dptr,a
        mov     dptr,#05555h
        mov     a,#0a0h           ;cycle 3
        movx    @dptr,a
        mov     dptr,#0feffh
        mov     a,#077h           ;cycle 4 - write value to address
        movx    @dptr,a
;test for programming finished
pollf   movx    a,@dptr           ;read byte
        anl     a,#080h
        mov     r1,a              ;compare bit 7
        mov     a,#077h           ;with data bit 7
        anl     a,#080h
        xrl     a,r1
        jz      al2ok
;if not finished, test for time out
        movx    a,@dptr           ;read byte again
        anl     a,#020h           ;test bit 5
        jnz     m2tes             ;timed out - still test
        sjmp    pollf
m2tes   movx    a,@dptr           ;for case of simultaneous
        anl     a,#080h           ;finish and time out
        mov     r1,a
        mov     a,#077h
        anl     a,#080h
        xrl     a,r1
        jz      al2ok
        clr     psw.3              ;back to reg bank 0 for     
        mov     r0,#077h           ;error ret
        setb    p3.4               ;flip memories 
        ret
;good finish
al2ok   setb    p3.4
        clr     psw.3              ;back to reg bank 0      
        mov     r0,#0              ;clear error flag for success
        ret
;
; 
        end



