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

📄 nios2_germs_monitor.s

📁 一款基于FPGA的对于VGA实现全彩控制的程序
💻 S
📖 第 1 页 / 共 3 页
字号:
# Contents: Nios II monitor, (modified from nios_germs_monitor.s)
#           this one with S-Record, I-Hex
#           records, and Flash Programming
#           for the Nios development board.
# 
# ex:tabstop=4:
# ex:shiftwidth=4:
# ex:expandtab:
#
# +-------------------------------------------
# | A Note About Caching
# |
# | To eliminate issues with caching, this Germs
# | monitor uses the following strategy:
# |
# |   1. Init the i- and d-caches at startup.
# |      So the caches are EMPTY when we begin.
# |   2. Use only IO reads and writes.
# |      So the d-cache stays empty, and the
# |      i-cache contains only parts of
# |      Germs itself.
# |
# | therefore
# |
# |   3. When you execute a G (go) command,
# |      or the s-record equivalent, there
# |      CANNOT be any stale i-cache data
# |      associated with that address. Only
# |      parts of Germs itself will be found
# |      in the i-cache.
# |
# | dvb2004.04.02
# +--------------------------------------------
#
# GermsMon is build-time configurable to
# support various Nios configurations.
# The following variables control
# how it's built:
#
#   GM_UARTBase -- base of the uart for output, presumed
#                  to be Nios compatible registers
# 
#   GM_FlashBase,
#   GM_FlashTop --
#           The flash to support, unless FlashTop is zero,
#           which means "no flash". The flash is presumed
#           to be AMD 29LV800, as on the Nios reference design.
#           Other AMD flashes might be compatible.
# 
#   GM_Flash --
#           The address in flash to check for the Nios 2
#           signature "N2". The boot loader generated by
#           nios2-srec2flash contains the signature at
#           offset 4.
#           If the signature is found, execution
#           is transferred to GM_Flash. If
#           GM_Flash is zero, the feature is disabled.
#   GM_PIO --
#           The pio to check bit zero of before executing
#           from flash.
#
#   GM_VectorTable --
#           Interrupt vector table base
#   
# To set a variable, include the directive 
#
#   --defsym GM_whatever=value
#
# on the assembler's command line. With nios-build, include
# the directive
#
#   -as "--defsym GM_whatever=value"
#
#

    .include "excalibur.s"

    .ifndef GM_UARTBase
     .ifdef nasys_printf_uart
      .equ GM_UARTBase,nasys_printf_uart
     .else
      #
      # If there's no UART defined, we'll compile
      # as IF the uart address is 0x0000.
      # This, of course, won't be a functioning
      # monitor, but, hey, there's no UART. What
      # were you expecting?
      # At least it puts some bytes in your
      # ROM, and you can see what code looks like.
      #
      #.equ GM_UARTBase,0
      # !!!
      # The above comment is obsolete, but is preserved here
      # for future generations to look upon, and marvel.
      # See the bottom of this file for the code that's generated
      # when no UART exists.
      # !!!
     .endif
    .endif

    .ifndef GM_FlashBase
     .ifdef nasys_main_flash
      .equ GM_FlashBase,nasys_main_flash
     .endif
    .endif

    .ifdef GM_FlashBase

     .ifndef GM_FlashTop
      .ifdef nasys_main_flash_end
       .equ GM_FlashTop,nasys_main_flash_end
      .else
       .equ GM_FlashTop,GM_FlashBase+0x100000
      .endif
     .endif

     .ifndef GM_Flash
      .equ GM_Flash,GM_FlashBase+0x40000
     .endif

    .endif

    .ifndef GM_StackTop
     .equ GM_StackTop,nasys_stack_top
    .endif

    .ifndef GM_VectorTable
     .equ GM_VectorTable,nasys_vector_table
    .endif

    .ifndef GM_PIO
     .ifdef na_button_pio
      .equ GM_PIO,na_button_pio
     .endif
    .endif

    .ifndef GM_WIDTHS
     .equ GM_WIDTHS,1
    .endif

# Constants used by nj germs monitor

    .equ CR,13              # carriage return
    .equ WORD, 4            # default word size, for 32-bit NJ, 4 bytes in a word
    .equ LOW_NIBBLE_MASK, 0x00000000f   # to mask out low nibble of a word
    #.equ ADDR_MASK, 0xFFFFFFFC         # for masking out low two bits of addresses
    .equ ADDR_LOBITS,2          # how many low bits to zap for rounding

# Useful Macros!
#
# A simple macro to branch if register bit is 0
#
    .macro BR0  rB, rA, bit, dest
        ANDI    \rB, \rA, (1<<\bit)
        BEQ     r0, \rB, \dest
    .endm

# +----------------------------
# | _CLRLOBITS reg,bits

    .macro  _CLRLOBITS _dst,_src,_bits
    SRLI    \_dst,\_src,\_bits
    SLLI    \_dst,\_dst,\_bits
    .endm

#--------------------------------------------------
#
# A simple macro to branch if register bit is 1
    .macro BR1  rB, rA, bit, dest
        ANDI    \rB, \rA, (1<<\bit)
        BNE     r0, \rB, \dest
    .endm

# Mostly, this is one big goto-tangle.
#
# No RAM used
#
# LOW_NIBBLE_MASK   : the value 0x0000000F
#
# Global Register Usage:
#
# r3                : number of bytes read by getHex routine
# r8                : UART Base Address
# r9                : return address temp for flash routines
# r11               : residual byte for writing to Flash in words
# rl2               : Upper bytes (or segment) for I-Hex records
# r13               : Force-to address for S-Records/I-Hex records
# r14               : Address to read next from <CR>
#                     This gets set by an R command
# r15,r16           : Any routine's scratch
# r17,r18           : Any routine's scratch
# r19               : record type for S-record
# r20               : record length in bytes for S-record
# r21               : address we're reading bytes into for S-record
#
# r22               : How many words to display on CR
# r23               : stashed return address
#
# r24               : stashed value-end during doMWrite
#
#
#
#
# --------------
#
#
# -------------------------------
# Commands:
# G<address>               Go at address
# E<address>               Erase flash at address
# R<address>-<address>     Relocate S-Records from-to
# M<address>               Display at address
# M<address>-<address>     Display range
# M<address>:val val...    Write at address
# M<address>-<address>:val Fill range with val
# S...                     S-record, no error checking
# :...                     Intel-Hex record, no error checking



.text

GFUNC _start

# +------------------------------------------------------
# | Cache flushing code
# |
# | Initialize caches if present.
# | All contents will be cleared without writing back dirty data to memory.
# | This is required since the caches start from an unknown state on reset.

.if nasys_has_icache
_start_icache_init:
    mov     r4, r0
    MOVIK32 r5, nasys_icache_size
_start_icache_loop:
    # This looped is unrolled by a factor of 2 to speed it up.
    # Further unrolling is not done because the end of the loop won't
    # fit in one icache line.
    initi   r4
    addi    r4, r4, nasys_icache_line_size
    initi   r4
    addi    r4, r4, nasys_icache_line_size
    bltu    r4, r5, _start_icache_loop
    flushp
.endif

.if nasys_has_dcache
_start_dcache_init:
    mov     r4, r0
    MOVIK32 r5, nasys_dcache_size
_start_dcache_loop:
    # This looped is unrolled by a factor of 8 to speed it up.
    # Further unrolling could be done as desired.
    initd   0*nasys_dcache_line_size(r4)
    initd   1*nasys_dcache_line_size(r4)
    initd   2*nasys_dcache_line_size(r4)
    initd   3*nasys_dcache_line_size(r4)
    initd   4*nasys_dcache_line_size(r4)
    initd   5*nasys_dcache_line_size(r4)
    initd   6*nasys_dcache_line_size(r4)
    initd   7*nasys_dcache_line_size(r4)
    addi    r4, r4, nasys_dcache_line_size * 8
    bltu    r4, r5, _start_dcache_loop
.endif
    

# | the caches are now flushed
# |
# +--------------------------------------------------


_start_post_cache_flush:

    WRCTL   status, r0       # Disabling interrupts

.ifdef GM_UARTBase

    # (previous germs monitors cleared the vector table
    # here, but it's more useful to be able to still
    # see it after you finish. Also, every byte is
    # precious, to keep it under 1k bytes! so its gone.)

    #
    # Reset UART, SwitchPIO, and Timers
    #
    MOVIK32 r8, GM_UARTBase
    STWIO   r0, WORD*np_uartcontrol(r8)           # control all 0's: no irq's

    .ifdef GM_PIO
    MOVIK32 r16, GM_PIO
    STWIO   r0, WORD*np_piointerruptmask(r16)
    .endif

    #
    # set the stack pointer
    #
    .ifdef GM_StackTop
    MOVIK32  sp, GM_StackTop
    .endif

    #
    # Look for Signature in flash, & jump there.
    #   
    .ifdef GM_PIO
    LDWIO   r15, WORD*np_piodata(r16)       # Unless the button is pressed
    BR0     r16, r15, 0, postFlash_start
    .endif

    .ifdef GM_FlashTop
    MOVIK32 r16, GM_Flash
    LDHIO   r15, 4(r16)
    CMPNEI  r15, r15, 'N'+(256*'2')
    BNE     r0, r15, postFlash_start

    CALLR   r16        # (if it wants to return, no problem!)
    .endif

GFUNC postFlash_start

        ##  We end up here upon exit of a user-program run with the 'G'
        ##  command.  User-programs can do -anything-, including exitng
        ##  with interrupts left running.  This is inconvenient when
        ##  using the monitor.  Disable CPU interrupts as a defensive measure.
        
    WRCTL   status, r0
    
    #
    # Registers which need certain
    # values for the rest of the monitor
    # to work.
    # (Other registers are used as
    # needed, although their reservations
    # for certain uses must be respected
    # while running.)

    MOVIK32  r8, GM_UARTBase

    CALL    PutHash
    
    MOV     r12, r0
    MOV     r13, r0
    MOV     r14, r0                         # address to show on <CR>
    MOVUI   r22, 16                         # words to show on <CR>

    .ifndef __timeStamp__
        .equ __timeStamp__,0
    .endif

    MOVIK32  r5, __timeStamp__
    CALL    PutHex

    # RDCTL   r5, cpuid     # uncomment once cpu id control register is defined
    MOVIK32  r5, 0x12171981  # for now put this, guess who's b-day?
    CALL    PutHex
    MOVUI    r4, CR
    CALL    PutChar
    
    # 
    # Print the system name GM_SystemName, if defined
    #

    MOVI32   r21, systemNameString

printSystemNameLoop:
    LDBIO   r4, 0(r21)
    BEQ     r0, r4, donePrintSystemNameLoop
    CALL    PutChar
    ADDI    r21, r21, 1
    BR      printSystemNameLoop

donePrintSystemNameLoop:

    # |
    # | print address of monitor
    # |
    MOVUI   r4, ' '
    CALL    PutChar
    MOVUI   r4, '@'
    CALL    PutChar
    MOVUI   r4, ' '
    CALL    PutChar
    MOVI32  r5,_start
    CALL    PutHex

    MOVUI   r4, CR
    CALL    PutChar

ReceiveCommand:
    MOVUI   r4, '+'
    CALL    PutChar

    CALL    GetChar

    CMPGEUI r15, r4, 0x0060                 # character from [60,7f]
    BEQ     r0, r15, RespondToInput

LowercaseChar:
    ANDI    r4, r4, 0xffdf
    #BR     RespondToInput

RespondToInput:
    ADDI    r4, r4, -CR
    BEQ     r0, r4, doCR

    ADDI    r4, r4, CR-'#'                  # '#' (hash) is for comments: ignore to EOL
    BEQ     r0, r4, happyWaitForEOL

    ADDI    r4, r4, '#'-':' 
    BEQ     r0, r4, doColon

    ADDI    r4, r4, ':'-'E'
    BEQ     r0, r4, doE

    ADDI    r4, r4, 'E'-'G'
    BEQ     r0, r4, doG

    ADDI    r4, r4, 'G'-'M'
    BEQ     r0, r4, doM
    
    ADDI    r4, r4, 'M'-'R'
    BEQ     r0, r4, doR

    ADDI    r4, r4, 'R'-'S'
    BEQ     r0, r4, doS

⌨️ 快捷键说明

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