288 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
|                 ;===============================================================
 | |
|                 ; Beamer control
 | |
|                 ;===============================================================
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; register definitions
 | |
|                 ;   s0, s1: used for INPUT and OUTPUT operations
 | |
|                 ;   S2: returns UART data byte
 | |
|                 ;   S3: uart protocol checksum
 | |
|                 ;   S4: uart protocol packet id
 | |
|                 ;   S5: uart protocol command id
 | |
|                 ;   S6: uart protocol address
 | |
|                 ;   S7: uart protocol data
 | |
|                 ;   S8: copy of UART data byte for debug
 | |
|                 ;---------------------------------------------------------------
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; GPIO definitions
 | |
|                 ;---------------------------------------------------------------
 | |
|                 CONSTANT  gpioBaseAddress,  0000
 | |
|                 CONSTANT  gpioDataOffset,   0000
 | |
|                 CONSTANT  gpioEnableOffset, 0001
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; UART definitions
 | |
|                 ;---------------------------------------------------------------
 | |
|                 CONSTANT  uartBaseAddress,  0010
 | |
|                 CONSTANT  uartBaudOffset,   0002
 | |
|                 CONSTANT  uartStatusOffset, 0001
 | |
|                 CONSTANT  uartDataReady,    0001
 | |
|                 CONSTANT  uartSending,      0002
 | |
| ;                CONSTANT  uartBaudCount,    023D        ; 66E6 / 115 200 = 573
 | |
|                 CONSTANT  uartBaudCount,    0042        ; 66E6 / 1E6 = 66
 | |
| ;                CONSTANT  uartpollDelay,    0100
 | |
|                 CONSTANT  uartpollDelay,    0040
 | |
|                 CONSTANT  commandNack,      0000
 | |
|                 CONSTANT  commandWriteMem,  0003
 | |
|                 CONSTANT  commandReadMem,   0004
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; beamer peripheral definitions
 | |
|                 ;---------------------------------------------------------------
 | |
|                 CONSTANT  beamerBaseAddress,0020
 | |
|                 CONSTANT  beamerCtlOffset,  0000
 | |
|                 CONSTANT  beamerSpeedOffset,0001
 | |
|                 CONSTANT  beamerCtlInit,    0401
 | |
| ;                CONSTANT  beamerCtlInit,    1001
 | |
|                 CONSTANT  beamerSpeedInit,  0004
 | |
| 
 | |
|                 ;===============================================================
 | |
|                 ; initializations
 | |
|                 ;===============================================================
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; initialize GPIO
 | |
|                 ;---------------------------------------------------------------
 | |
|                 LOAD      s0, gpioBaseAddress
 | |
|                 ADD       s0, gpioDataOffset
 | |
|                 LOAD      s1, AA
 | |
|                 OUTPUT    s1, (s0)
 | |
|                 LOAD      s0, gpioBaseAddress
 | |
|                 ADD       s0, gpioEnableOffset
 | |
|                 LOAD      s1, 0F
 | |
|                 OUTPUT    s1, (s0)
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; initialize UART
 | |
|                 ;---------------------------------------------------------------
 | |
|                 LOAD      s0, uartBaseAddress
 | |
|                 ADD       s0, uartBaudOffset
 | |
|                 LOAD      s1, uartBaudCount
 | |
|                 OUTPUT    s1, (s0)
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; initialize beamer peripheral
 | |
|                 ;---------------------------------------------------------------
 | |
|                 LOAD      s0, beamerBaseAddress
 | |
|                 ADD       s0, beamerCtlOffset
 | |
|                 LOAD      s1, beamerCtlInit
 | |
|                 OUTPUT    s1, (s0)
 | |
|                 LOAD      s0, beamerBaseAddress
 | |
|                 ADD       s0, beamerSpeedOffset
 | |
|                 LOAD      s1, beamerSpeedInit
 | |
|                 OUTPUT    s1, (s0)
 | |
| 
 | |
|                 ;===============================================================
 | |
|                 ; Main loop
 | |
|                 ;===============================================================
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; Process commands from serial port
 | |
|                 ;---------------------------------------------------------------
 | |
|           main: CALL      uartGetCmd            ; get command from UART
 | |
|                 COMPARE   s3, 0000              ; check function return
 | |
|                 JUMP      nz, commandAbort
 | |
|                 COMPARE   s5, commandWriteMem   ; check for WRITE_MEM command
 | |
|                 JUMP      nz, commandRead
 | |
|                 OUTPUT    s7, (s6)              ; write word to memory location
 | |
|                 CALL      sendWriteOk           ; send write acknowledge
 | |
|                 JUMP      main
 | |
|    commandRead: INPUT     s7, (s6)              ; write word in memory location
 | |
|                 CALL      sendReadData          ; send back read data
 | |
|                 JUMP      main
 | |
|   commandAbort: CALL      sendNAck
 | |
|                 JUMP      main
 | |
| 
 | |
|                 ;===============================================================
 | |
|                 ; Subroutines
 | |
|                 ;===============================================================
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; Get command from serial port
 | |
|                 ;---------------------------------------------------------------
 | |
|     uartGetCmd: CALL      uartGetByte           ; get command header
 | |
|                 COMPARE   s2, 00AA
 | |
|                 JUMP      nz, uartGetCmd        ; loop until byte is AAh
 | |
|                 LOAD      s3, s2                ; prepare checksum
 | |
|                 CALL      uartGetByte           ; get packet id
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 LOAD      s4, s2                ; store id for reply
 | |
|                 CALL      uartGetByte           ; get command
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 COMPARE   s2, commandWriteMem   ; check for WRITE_MEM command
 | |
|                 JUMP      z , commandOk
 | |
|                 COMPARE   s2, commandReadMem    ; check for READ_MEM command
 | |
|                 JUMP      z , commandOk
 | |
|                 JUMP      commandKo             ; no match
 | |
|      commandOk: LOAD      s5, s2                ; store command for action
 | |
|                 CALL      uartGetByte           ; get data length
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 COMPARE   s5, commandWriteMem   ; check for WRITE_MEM command
 | |
|                 JUMP      z , testWrLength      ; go to test write command length
 | |
|                 COMPARE   s2, 0002              ; verify READ_MEM length
 | |
|                 JUMP      nz, commandKo
 | |
|                 JUMP      getAddress
 | |
|   testWrLength: COMPARE   s2, 0004              ; verify WRITE_MEM length
 | |
|                 JUMP      nz, commandKo
 | |
|     getAddress: CALL      uartGetByte           ; get address low
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 LOAD      s6, s2                ; store address low
 | |
|                 CALL      uartGetByte           ; get address high
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      shiftS2L8
 | |
|                 ADD       s6, s2                ; build address from low and high
 | |
|                 COMPARE   s5, commandReadMem    ; check for READ_MEM command
 | |
|                 JUMP      z , getChecksum       ; skip reading data word
 | |
|                 CALL      uartGetByte           ; get data low
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 LOAD      s7, s2                ; store data low
 | |
|                 CALL      uartGetByte           ; get data high
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      shiftS2L8
 | |
|                 ADD       s7, s2                ; build data from low and high
 | |
|    getChecksum: CALL      uartGetByte           ; get checksum
 | |
|                 AND       s3, 00FF              ; limit calculated checksum to 8 bit
 | |
|                 COMPARE   s3, s2                ; test checksum
 | |
|                 JUMP      nz, commandKo
 | |
|                 LOAD      s3, 0000              ; return OK
 | |
|                 RETURN
 | |
|      commandKo: LOAD      s3, 0001              ; return KO
 | |
|                 RETURN
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; send NACK reply
 | |
|                 ;---------------------------------------------------------------
 | |
|       sendNAck: LOAD      s2, 00AA              ; send header
 | |
|                 LOAD      s3, s2                ; prepare checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s4                ; packet id
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, commandNack       ; negative Acknowledge
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, 0000              ; packet length: no data
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s3                ; checksum
 | |
|                 CALL      uartSendByte
 | |
|                 RETURN
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; send WRITE_MEM reply
 | |
|                 ;---------------------------------------------------------------
 | |
|    sendWriteOk: LOAD      s2, 00AA              ; send header
 | |
|                 LOAD      s3, s2                ; prepare checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s4                ; packet id
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s5                ; received command
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, 0000              ; packet length: no data
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s3                ; checksum
 | |
|                 CALL      uartSendByte
 | |
|                 RETURN
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; send READ_MEM reply
 | |
|                 ;---------------------------------------------------------------
 | |
|   sendReadData: LOAD      s2, 00AA              ; send header
 | |
|                 LOAD      s3, s2                ; prepare checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s4                ; packet id
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s5                ; received command
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, 0002              ; packet length: 2 bytes
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s7                ; data low
 | |
|                 AND       s2, 00FF              ; keep low byte only
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s7                ; data high
 | |
|                 CALL      shiftS2R8             ; shift MSBs down to LSBs
 | |
|                 ADD       s3, s2                ; calculate checksum
 | |
|                 CALL      uartSendByte
 | |
|                 LOAD      s2, s3                ; checksum
 | |
|                 CALL      uartSendByte
 | |
|                 RETURN
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; Get byte from serial port
 | |
|                 ;---------------------------------------------------------------
 | |
|    uartGetByte: LOAD      s0, uartBaseAddress   ; read UART satus register
 | |
|                 ADD       s0, 01
 | |
| ;load s8, 0100
 | |
|      checkStat: LOAD      s2, uartpollDelay     ; add delay between bus reads
 | |
|         delay0: SUB       s2, 0001
 | |
|                 JUMP      nz, delay0
 | |
| ;sub s8, 0001
 | |
| ;jump nz, continue
 | |
| ;load s2, 0035
 | |
| ;call uartSendByte
 | |
| ;load s8, 0100
 | |
| continue:       INPUT     s1, (s0)
 | |
|                 INPUT     s1, (s0)
 | |
|                 TEST      s1, uartDataReady     ; check "data ready" bit
 | |
|                 JUMP      z , checkStat         ; loop until bit is '1'
 | |
|                 LOAD      s0, uartBaseAddress   ; read UART data register
 | |
|                 INPUT     s2, (s0)
 | |
|                 INPUT     s2, (s0)
 | |
| ;LOAD s8, s2
 | |
|                 RETURN
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; Send byte to serial port
 | |
|                 ;---------------------------------------------------------------
 | |
|   uartSendByte: LOAD      s0, uartBaseAddress   ; read UART satus register
 | |
|                 ADD       s0, uartStatusOffset
 | |
|     readStatus: INPUT     s1, (s0)
 | |
|                 INPUT     s1, (s0)
 | |
|                 TEST      s1, uartSending       ; check "sending data" bit
 | |
|                 JUMP      z , sendByte          ; loop until bit is '1'
 | |
|                 LOAD      s1, uartpollDelay     ; add delay between bus reads
 | |
|         delay1: SUB       s1, 0001
 | |
|                 JUMP      nz, delay1
 | |
|                 JUMP      readStatus
 | |
|       sendByte: LOAD      s0, uartBaseAddress   ; write UART data register
 | |
|                 OUTPUT    s2, (s0)
 | |
|                 RETURN
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; shift s2 8 bits to the left
 | |
|                 ;---------------------------------------------------------------
 | |
|      shiftS2L8: LOAD      s0, 8                 ; loop count
 | |
|  shiftLeftLoop: SL0       s2
 | |
|                 SUB       s0, 0001
 | |
|                 JUMP      nz, shiftLeftLoop
 | |
|                 RETURN
 | |
| 
 | |
|                 ;---------------------------------------------------------------
 | |
|                 ; shift s2 8 bits to the right
 | |
|                 ;---------------------------------------------------------------
 | |
|      shiftS2R8: LOAD      s0, 8                 ; loop count
 | |
| shiftRightLoop: SR0       s2
 | |
|                 SUB       s0, 0001
 | |
|                 JUMP      nz, shiftRightLoop
 | |
|                 RETURN
 | |
| 
 | |
|                 ;===============================================================
 | |
|                 ; End of instruction memory
 | |
|                 ;===============================================================
 | |
| ADDRESS 3FF
 | |
|    endOfMemory: JUMP      endOfMemory
 |