⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nios2_germs_monitor.s

📁 一款基于FPGA的对于VGA实现全彩控制的程序
💻 S
📖 第 1 页 / 共 3 页
字号:
    MOVUI   r7, 31
    BR      getHexEntry1            # dive in with user's r6 and 31 char limit
    
GetHex:

    MOVUI   r7, 31                  # maximum character count


GetHexBytes:                        # entry point to use r3 to signifiy byte count
    MOVUI   r6, CR                  # default return-break char 

getHexEntry1:
    ADD     r7, r7, r7              # double for chars
    MOV     r23, ra                 # save return address
    MOV     r5, r0                  # result

getNextHex:
    MOV     r3, r5                  # come here after a hyphen, too
    MOV     r5, r0                  # result

getHexLoop:
    CALL    GetChar
    ADDI    r18, r18, 1             # bump char count

    CMPEQI  r15, r4, '-'            # hyphen separated pair...
    BNE     r0, r15, getNextHex

    BEQ     r4, r6, getHexDone      # user-passed return character? then we're done!
    CMPEQI  r15, r4, CR             # if carriage return, we're done, yay!
    BNE     r0, r15, getHexDone
    
    ADDI    r7, r7, -1              # decrement char count
    ANDI    r15, r4, 0b1000000      # bit 6 indicates alpha char
    BEQ     r0, r15, NoAlphaChar
    ADDI    r4, r4, 9               # if so, move up to 10-15
    
NoAlphaChar:
    ANDI    r4, r4, LOW_NIBBLE_MASK # mask out low nibble
    SLLI    r5, r5, 4
    ADD     r5, r5, r4              # last or not, add in the last nibble
    BNE     r0, r7, getHexLoop      # loop if this was not the last character
    
getHexDone:
    SRLI    r18, r18, 1             # turn char count to byte count
    JMP     r23                     # return

# End GetHexUntil/GetHex

###############################################################################

.if GM_WIDTHS
#----------------------------
# Stash16 -- either
# do a sthio
# or pass it off to flashwrite

Stash16:
    .ifdef GM_FlashTop
    MOV     r3, ra           # stash return address, deeper than usual!
    CALL    InFlashRange
    BNE     r0, r15, FlashWrite16
    STHIO   r5, 0(r21)
    JMP     r3
    .else
    STHIO   r5, 0(r21)
    RET
    .endif
.endif

#-----------------------------------
# Stash byte routine shared
# by S-records and 'W' command
#
# Store byte r5 into address r21
# and don't corrupt anything important
#
StashByte:
    MOV     r3, ra      # stash return address, deepter than usual!
    
.ifdef  GM_FlashTop

    CALL    InFlashRange
    BEQ     r0, r15, stashByteRAM

    #-------------------------------
    # We're storing to flash here...

    ANDI    r5, r5, 0xFF             # always clear out the high bits
    BR1     r15, r21, 0, FlashWrite  # odd address? then
                                     # do the the Flash Write routine        

    MOV     r11, r5                  # save the low byte
    JMP     r3                       # return

FlashWrite:
    SLLI    r5, r5, 8                   
    OR      r5, r5, r11              # r5 is word to write, r21 is address+1

FlashWrite16:                        # r3 must have return address already...

    #
    # At this point, r5, has a halfword to write,
    # r21 is the halfword address+1
    #

    # call C routine to write a word to flash

    # At this point, r5 has a word to write,
    # r21 is the word address 
    MOV     r6, r5

        # 
        # When doM calls us, the address is definitely even
        # When doS (S-record) calls us, the address is always on the
        # odd phase, as it goes byte-by-byte.
        #
        # clear the low bit to force it to be the next-lowest even.
        #

    ANDHI   r15, r21, 0xffff
    ANDI    r5, r21, 0xfffe
    OR      r5, r5, r15
    CALL    germs_write16

    BNE     r0, r2, flashWriteFail      # succeeded?
    JMP     r3

flashWriteFail:
    MOVUI   r4, '!'
    CALL    PutChar
    JMP     r3

stashByteRAM:

.endif                                  # if not handling flash case...

    STBIO   r5, 0(r21)                  # actualy stash the byte
    JMP     r3                          # return   
    
# +------------------------------------
# | For systems with flash memory only
# |

.ifdef GM_FlashTop

# +-------------------------------------
# | InFlashRange(address in r21)
# |
# | Return r15 nonzero if r21 in flash range.
# |  else zero.
# |

InFlashRange:

    MOVIK32 r15, GM_FlashBase           # checking to see if below flash base
    BLTU    r21, r15, OutofRange
    MOVIK32 r15, GM_FlashTop            # checking to see if above flash top
    BLTU    r21, r15, InRange
OutofRange:
    MOV     r15, r0                     # out of range: return 0
InRange:
    RET                                 # in range: return (nonzero) flashtop
    



.if 1

# ========================================
# | Asm versions of flash routines,
# | for a particular chip: amd29lv065d
# |


# +------------------------------
# | germs_erase_sector(address within flash in r5)
# |
# | use r15 for flash base
# | use r16 for temp bytes
# |

    .macro  _flash_put_byte _offset,_value
    MOVI    r16,\_value
    STBIO   r16,\_offset(r15)
    .endm

germs_erase_sector:
    MOVIK32 r15,GM_FlashBase

    # | magic dance for erase sector
    _flash_put_byte 0x555,0xAA
    _flash_put_byte 0x333,0x55
    _flash_put_byte 0x555,0x80
    _flash_put_byte 0x555,0xAA
    _flash_put_byte 0x333,0x55

    # | tell chip the address to erase by
    # | writing 0x30 to that address

    MOVI    r16,0x30
    STBIO   r16,0(r5)

    # | wait for 0xff to show up at that address,
    # | but only check approximately a zillion times

    MOVI    r15,0       # watchdog counter 4 billion
wait_for_erase:
    ADDI    r15,r15,1
    BEQ     r15,r0,erase_done  # watchdog hit zero again

    LDBIO   r16,0(r5)   # sign extends the single byte...
    ADDI    r16,r16,1   # will be 0x00000000 if we got 0xff
    BNE     r16,r0,wait_for_erase

erase_done:
    MOV     r2,r16      # return code: 0 is OK, anything else bad
    RET


# +--------------------------------
# | germs_write16(address within flash:r5, 16-bit value:r6)
# |

germs_write16:
    MOV     r9,ra      # stash return address to r2
    CALL    germs_write8
    BNE     r0,r2,germs_write16_done
    ADDI    r5,r5,1
    SRLI    r6,r6,8
    CALL    germs_write8
germs_write16_done:
    JMP     r9
 
# +---------------------------------
# | germs_write8(address within flash:r5, 8-bit value:r6)
germs_write8:
    MOVIK32 r15,GM_FlashBase
    ANDI    r17,r6,0x000000ff    # r17 has just the 8 bits

    _flash_put_byte 0x555,0xAA
    _flash_put_byte 0x333,0x55
    _flash_put_byte 0x555,0xa0
    STBIO r17,0(r5)

    # reuse r15 now...

    MOVHI   r15,20              # watchdog counter
wait_for_write8_done:
    LDBUIO  r16,0(r5)           # read byte back out of flash
    BEQ     r17,r16,write8_done # stopped changing?

    ADDI    r15,r15,-1
    BNE     r15,r0,wait_for_write8_done # watchdog hit zero again

write8_done:
    CMPNE   r2,r16,r17           # return 0 for ok, or 1 for bad
    RET
    
    




.else

# ========================================
# | Invoke C versions of flash routines


# +------------------------------
# | germs_erase_sector(address within flash in r5)
# |

germs_erase_sector:
    MOVI    r4,-1
    MOVI32  r15,nr_flash_erase_sector
    BR      call_c_routine

# +--------------------------------
# | germs_write16(address within flash:r5, 16-bit value:r6
# |

germs_write16:
    MOVI    r4,-1
    MOVI32  r15,nr_flash_write
    BR      call_c_routine


# +----------------------------------
# | handy means to call C routine from
# | germs. Note: the full C environment
# | is *far* from complete here. You get
# | a stack and that's it. No globals,
# | no printf or device drivers, &c.
# |

call_c_routine:

    #
    # r15 should have the address to call and
    # arguments in r5 and r6.  All flash routines
    # want nasys_main_flash in r4, with -1 indicating
    # default, so we put that into r4 every time.
    #

    ADDI    sp, sp, -124  # save all the registers. we are like that.
 
    STWIO  r1,  0(sp)
    STWIO  r2,  4(sp)
    STWIO  r3,  8(sp)
    STWIO  r4, 12(sp)
    STWIO  r5, 16(sp)
    STWIO  r6, 20(sp)
    STWIO  r7, 24(sp)
    STWIO  r8, 28(sp)
    STWIO  r9, 32(sp)
    STWIO r10, 36(sp)
    STWIO r11, 40(sp)
    STWIO r12, 44(sp)
    STWIO r13, 48(sp)
    STWIO r14, 52(sp)
    STWIO r15, 56(sp)
    STWIO r16, 60(sp)
    STWIO r17, 64(sp)
    STWIO r18, 68(sp)
    STWIO r19, 72(sp)
    STWIO r20, 76(sp)
    STWIO r21, 80(sp)
    STWIO r22, 84(sp)
    STWIO r23, 88(sp)
    STWIO r24, 92(sp)
    STWIO r25, 96(sp)
    STWIO r26,100(sp)
    STWIO r27,104(sp)
    STWIO r28,108(sp)
    STWIO r29,112(sp)
    STWIO r30,116(sp)
    STWIO r31,120(sp)

    # |
    # | call the C routine
    # |

    CALLR   r15
    
    # |
    # | Restore registers and clean up stackframe
    # |
    # | All these registers are yours, except
    # | r2. Attempt no landings there. r2 is for
    # | the return value.
    # |

    LDWIO  r1,  0(sp)

    # LDWIO  r2,  4(sp) It's the return value, leave intact.

    LDWIO  r3,  8(sp)               
    LDWIO  r4, 12(sp)
    LDWIO  r5, 16(sp)       
    LDWIO  r6, 20(sp)       
    LDWIO  r7, 24(sp)       
    LDWIO  r8, 28(sp)       
    LDWIO  r9, 32(sp)       
    LDWIO r10, 36(sp)       
    LDWIO r11, 40(sp)       
    LDWIO r12, 44(sp)       
    LDWIO r13, 48(sp)       
    LDWIO r14, 52(sp)       
    LDWIO r15, 56(sp)       
    LDWIO r16, 60(sp)       
    LDWIO r17, 64(sp)       
    LDWIO r18, 68(sp)       
    LDWIO r19, 72(sp)
    LDWIO r20, 76(sp)
    LDWIO r21, 80(sp)
    LDWIO r22, 84(sp)
    LDWIO r23, 88(sp)
    LDWIO r24, 92(sp)
    LDWIO r25, 96(sp)
    LDWIO r26,100(sp)
    LDWIO r27,104(sp)
    LDWIO r28,108(sp)
    LDWIO r29,112(sp)
    LDWIO r30,116(sp)
    LDWIO r31,120(sp)
    ADDI sp, sp, 124

    RET

.endif  # use_asm_routines or c routines

.endif  # GM_FlashTop


# |
# | This used to be tucked within the code up above.
# | It's down here, now, for two reasons, one good
# | and one bad.
# |
# | The good reason: we no longer have to branch
# | over it! this saves us a branch instruction.
# |
# | The bad reason: due to an assembler bug
# | in the first release of the Nios II tool
# | chain, we cannot have arbitrary .align
# | directives in a .text section. (data
# | sections are ok, though.)
# |

systemNameString:
    nm_monitor_string                       # include monitor name string

.else
# GM_UARTBase -- no uart, the monitor is empty
# There is no monitor here, since the system has no uart
# Here's an infinite loop for your cpu to enjoy.
NoUART:
    BR      NoUART
    .asciz  "There is no monitor here."
.endif

# End of file    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -