initial commit
This commit is contained in:
commit
60db522e87
107 changed files with 36924 additions and 0 deletions
805
lib/rommon.s
Normal file
805
lib/rommon.s
Normal file
|
|
@ -0,0 +1,805 @@
|
|||
.EQU CR 13
|
||||
.EQU LF 10
|
||||
.EQU EOT 4
|
||||
.EQU ACK 6
|
||||
.EQU NAK 21
|
||||
.EQU STX 2
|
||||
.EQU UART_REG 2048
|
||||
.EQU MON_ADDR 64512
|
||||
|
||||
BRANCH 2 ; the very first instruction is not
|
||||
; executed correctly
|
||||
LOADCP 65020 ; initialise FP and RP registers
|
||||
STOREREG FP
|
||||
LOADCP 65024
|
||||
STOREREG RP
|
||||
|
||||
LOADCP MON_ADDR
|
||||
LOADCP 4096
|
||||
STOREI
|
||||
DROP
|
||||
CMDLOOP0:
|
||||
LOADC MESSAGE
|
||||
LOADC PRINTLINE
|
||||
CALL
|
||||
|
||||
CMDLOOP:
|
||||
LOADC NEWLINE
|
||||
CALL
|
||||
LOADC PROMPT
|
||||
CALL
|
||||
CMDLOOP1:
|
||||
LOADC CONIN
|
||||
CALL
|
||||
LOADC TOUPPER
|
||||
CALL
|
||||
|
||||
DUP
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
|
||||
LOADC 'A'
|
||||
CMP.S0 EQ
|
||||
CBRANCH.Z CMD1
|
||||
LOADC CMD_A
|
||||
CALL
|
||||
BRANCH CMDLOOP2
|
||||
CMD1:
|
||||
LOADC 'X'
|
||||
CMP.S0 EQ
|
||||
CBRANCH.Z CMD2
|
||||
LOADC CMD_X
|
||||
CALL
|
||||
BRANCH CMDLOOP2
|
||||
CMD2:
|
||||
LOADC 'D'
|
||||
CMP.S0 EQ
|
||||
CBRANCH.Z CMD3
|
||||
LOADC CMD_D
|
||||
CALL
|
||||
BRANCH CMDLOOP2
|
||||
CMD3:
|
||||
LOADC 'G'
|
||||
CMP.S0 EQ
|
||||
CBRANCH.Z CMD4
|
||||
LOADC CMD_G
|
||||
CALL
|
||||
BRANCH CMDLOOP2
|
||||
CMD4:
|
||||
LOADC 'L'
|
||||
CMP.S0 EQ
|
||||
CBRANCH.Z CMD5
|
||||
LOADC CMD_L
|
||||
CALL
|
||||
BRANCH CMDLOOP2
|
||||
CMD5:
|
||||
LOADC 'B'
|
||||
CMP.S0 EQ
|
||||
CBRANCH.Z CMD6
|
||||
LOADC CMD_B
|
||||
CALL
|
||||
BRANCH CMDLOOP2
|
||||
CMD6:
|
||||
DROP
|
||||
BRANCH CMDLOOP0
|
||||
CMDLOOP2:
|
||||
DROP
|
||||
BRANCH CMDLOOP
|
||||
|
||||
; ---- Command 'A': set current address
|
||||
CMD_A:
|
||||
LOADC 32
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
LOADC READHEX
|
||||
CALL
|
||||
CBRANCH.Z CMD_A_INVALID ; 0 if not valid input
|
||||
LOADCP MON_ADDR
|
||||
SWAP
|
||||
STOREI
|
||||
DROP ; drop STOREI address
|
||||
RET
|
||||
CMD_A_INVALID:
|
||||
DROP
|
||||
LOADC '.'
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
RET
|
||||
|
||||
; ---- Command 'X': examine current address
|
||||
CMD_X:
|
||||
FPADJ -8 ; reserve space for 4 bytes of local variables
|
||||
LOADCP MON_ADDR
|
||||
LOADI
|
||||
STORE 0 ; current memory address
|
||||
LOADC 4 ; print 8 words
|
||||
STORE 4 ; Loop counter
|
||||
CMD_X_LOOP:
|
||||
LOADC 32 ; print a a space
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
LOAD 0 ; load word via current address
|
||||
LOADI
|
||||
LOADC PRINTHEXW ; print it
|
||||
CALL
|
||||
LOAD 0
|
||||
INC 4 ; increment current address
|
||||
STORE 0
|
||||
LOAD 4
|
||||
DEC 1
|
||||
DUP
|
||||
STORE 4
|
||||
CBRANCH.NZ CMD_X_LOOP
|
||||
LOADCP MON_ADDR
|
||||
LOAD 0
|
||||
STOREI
|
||||
DROP
|
||||
FPADJ 8
|
||||
RET
|
||||
|
||||
; ---- Command 'D': deposit words at current address
|
||||
CMD_D:
|
||||
FPADJ -4
|
||||
LOADC 4 ; max number of words
|
||||
STORE 0
|
||||
CMD_D_LOOP:
|
||||
LOADC 32 ; print a space
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
LOADC READHEX
|
||||
CALL
|
||||
DUP
|
||||
CBRANCH.Z CMD_D_EXIT ; check for invalid input
|
||||
SWAP ; swap return code and value
|
||||
LOADCP MON_ADDR
|
||||
LOADI ; get current address
|
||||
SWAP ; swap address and value for STOREI
|
||||
STOREI 4 ; store the value with post-increment of address
|
||||
LOADCP MON_ADDR
|
||||
SWAP ; swap destination address and value for STOREI
|
||||
STOREI ; store the new address
|
||||
DROP
|
||||
LOADC 2 ; compare return code (swapped above) to 2
|
||||
CMP EQ ; check for valid input and return key
|
||||
CBRANCH CMD_D_EXIT
|
||||
LOAD 0
|
||||
DEC 1
|
||||
DUP
|
||||
STORE 0
|
||||
CBRANCH.NZ CMD_D_LOOP
|
||||
CMD_D_EXIT:
|
||||
FPADJ 4
|
||||
RET
|
||||
|
||||
CMD_G:
|
||||
DROP ; remove input char
|
||||
LOADCP NEWLINE
|
||||
CALL
|
||||
LOADCP MON_ADDR
|
||||
LOADI
|
||||
JUMP
|
||||
|
||||
CMD_L:
|
||||
LOADCP NEWLINE
|
||||
CALL
|
||||
LOADCP RCVBLOCKS
|
||||
CALL
|
||||
LOADCP NEWLINE
|
||||
CALL
|
||||
RET
|
||||
|
||||
PROMPT:
|
||||
LOADC '['
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
LOADCP MON_ADDR
|
||||
LOADI
|
||||
LOADC PRINTHEXW
|
||||
CALL
|
||||
LOADC PROMPT2
|
||||
LOADC PRINTLINE
|
||||
CALL
|
||||
RET
|
||||
|
||||
NEWLINE:
|
||||
LOADC CR
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
LOADC LF
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
RET
|
||||
|
||||
; print string of byte characters
|
||||
; takes pointer to string on eval stack
|
||||
PRINTLINE:
|
||||
DUP ; duplicate address as arg to printchar
|
||||
LOADC PRINTCHAR
|
||||
CALL
|
||||
CBRANCH.Z PRINTLINE_EXIT ; if char is zero, exit
|
||||
INC 1 ; increment address
|
||||
BRANCH PRINTLINE
|
||||
PRINTLINE_EXIT:
|
||||
DROP ; remove address from stack
|
||||
RET
|
||||
|
||||
; print a single character
|
||||
; takes a byte pointer on eval stack
|
||||
; returns character on eval stack
|
||||
PRINTCHAR:
|
||||
LOADI.S1.X2Y ; load word, keep address on stack
|
||||
BSEL ; select byte of a word via address
|
||||
DUP ; check for null byte
|
||||
CBRANCH.Z PRINTCHAR_XT
|
||||
DUP
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
PRINTCHAR_XT:
|
||||
RET
|
||||
|
||||
; print a 32-bit hexadecimal number
|
||||
; takes the value on the stack
|
||||
|
||||
PRINTHEXW:
|
||||
BROT
|
||||
DUP
|
||||
LOADC PRINTHEXB
|
||||
CALL
|
||||
BROT
|
||||
DUP
|
||||
LOADC PRINTHEXB
|
||||
CALL
|
||||
BROT
|
||||
DUP
|
||||
LOADC PRINTHEXB
|
||||
CALL
|
||||
BROT
|
||||
LOADC PRINTHEXB
|
||||
CALL
|
||||
RET
|
||||
|
||||
PRINTHEXB:
|
||||
DUP
|
||||
SHR
|
||||
SHR
|
||||
SHR
|
||||
SHR
|
||||
LOADC PRINTNIBBLE
|
||||
CALL
|
||||
LOADC PRINTNIBBLE
|
||||
CALL
|
||||
RET
|
||||
|
||||
PRINTNIBBLE:
|
||||
LOADC 15
|
||||
AND ; isolate nibble
|
||||
LOADC 10
|
||||
CMPU.S0 GE ; nibble >= 10 ?
|
||||
CBRANCH.NZ PRINTNIBBLE_1 ; then print a-f
|
||||
LOADC '0' ; else print 0-9
|
||||
BRANCH PRINTNIBBLE_2
|
||||
PRINTNIBBLE_1:
|
||||
LOADC 55 ; 55 + 10 == 'A'
|
||||
PRINTNIBBLE_2:
|
||||
ADD
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
RET
|
||||
|
||||
; ------ read a 8-digit hexadecimal number from the console
|
||||
; stores variables on the user stack, so the FP register must be
|
||||
; inizialized.
|
||||
; returns two values on the eval stack:
|
||||
; - return code (topmost)
|
||||
; 0 - no valid number
|
||||
; 1 - valid number
|
||||
; 2 - valid number and enter was pressed
|
||||
; - result value
|
||||
|
||||
READHEX:
|
||||
FPADJ -8
|
||||
LOADC 0 ; current value
|
||||
STORE 0
|
||||
LOADC 8 ; max number of digits
|
||||
STORE 4 ; remaining digits counter
|
||||
READHEX_1:
|
||||
LOADC CONIN
|
||||
CALL
|
||||
LOADC CR ; RETURN pressed?
|
||||
CMP.S0 EQ
|
||||
CBRANCH READHEX_RT
|
||||
DUP
|
||||
LOADC CONOUT ; echo character
|
||||
CALL
|
||||
LOADC CONVHEXDIGIT
|
||||
CALL
|
||||
LOADC -1
|
||||
CMP.S0 EQ ; invalid character?
|
||||
CBRANCH.NZ READHEX_XT
|
||||
LOAD 0
|
||||
SHL 2 ; shift previous nibble
|
||||
SHL 2
|
||||
OR ; combine with last digit
|
||||
STORE 0
|
||||
LOAD 4
|
||||
DEC 1
|
||||
DUP
|
||||
STORE 4
|
||||
CBRANCH.NZ READHEX_1
|
||||
BRANCH READHEX_XT1
|
||||
READHEX_RT: ; if no digits were entered, set return code
|
||||
DROP ; drop read character
|
||||
LOAD 4 ;remaining digits counter
|
||||
LOADC 8
|
||||
CMP NE
|
||||
CBRANCH READHEX_RT2
|
||||
LOADC 0 ; no valid input
|
||||
BRANCH READHEX_XT3
|
||||
READHEX_RT2:
|
||||
LOADC 2 ; valid input and return pressed
|
||||
BRANCH READHEX_XT3
|
||||
READHEX_XT:
|
||||
DROP
|
||||
LOAD 4
|
||||
LOADC 8
|
||||
CMP EQ ; if no digits were entered
|
||||
CBRANCH READHEX_XT0
|
||||
READHEX_XT1:
|
||||
LOADC 1 ; valid input flag
|
||||
BRANCH READHEX_XT3
|
||||
READHEX_XT0:
|
||||
LOADC 0
|
||||
READHEX_XT3:
|
||||
LOAD 0
|
||||
SWAP
|
||||
FPADJ 8
|
||||
RET
|
||||
|
||||
; ------ convert character on the eval stack to upper case
|
||||
TOUPPER:
|
||||
LOADC 'a'
|
||||
CMP.S0 LT
|
||||
CBRANCH TOUPPER_XT
|
||||
LOADC 'z'
|
||||
CMP.S0 GT
|
||||
CBRANCH TOUPPER_XT
|
||||
LOADC 32
|
||||
SUB
|
||||
TOUPPER_XT:
|
||||
RET
|
||||
|
||||
; ------ convert hexadecimal digit to integer
|
||||
; ------ takes an ascii character as parameter on the eval stack
|
||||
; ------ returns an integer value from 0-15 on the eval stack,
|
||||
; ------ or -1 if the character was not a valid hexadecimal digit
|
||||
|
||||
CONVHEXDIGIT:
|
||||
LOADC TOUPPER
|
||||
CALL
|
||||
LOADC '0'
|
||||
CMP.S0 LT ; character < '0'?
|
||||
CBRANCH.NZ CONVHEXDIGIT_ERR
|
||||
LOADC '9'
|
||||
CMP.S0 GT ; character > '9'?
|
||||
CBRANCH.NZ CONVHEXDIGIT_ISALPHA
|
||||
LOADC '0' ; character is between '0' and '9', subtract '0'
|
||||
SUB
|
||||
BRANCH CONVHEXDIGIT_NBL
|
||||
CONVHEXDIGIT_ISALPHA:
|
||||
LOADC 'A'
|
||||
CMP.S0 LT ; character < 'A'?
|
||||
CBRANCH.NZ CONVHEXDIGIT_ERR
|
||||
LOADC 'F'
|
||||
CMP.S0 GT ; character > 'F'?
|
||||
CBRANCH.NZ CONVHEXDIGIT_ERR
|
||||
LOADC 55 ; character is between 'A' and 'F', subtract ('A' - 10)
|
||||
SUB
|
||||
CONVHEXDIGIT_NBL:
|
||||
RET
|
||||
CONVHEXDIGIT_ERR:
|
||||
DROP ; remove character from stack
|
||||
LOADC -1 ; error
|
||||
RET
|
||||
|
||||
; --------- output a character on serial console
|
||||
; --------- takes a character (padded to a word) on the eval stack
|
||||
CONOUT:
|
||||
LOADC UART_REG ; address of UART register
|
||||
LOADI ; load status
|
||||
LOADC 256 ; check bit 8 (tx_busy)
|
||||
AND
|
||||
CBRANCH.NZ CONOUT ; loop if bit 8 is not zero
|
||||
|
||||
; transmitter is idle now, write character
|
||||
LOADC UART_REG ; address of UART register
|
||||
SWAP ; swap character and address for STOREI
|
||||
LOADC 1024 ; TX enable bit
|
||||
OR ; OR in the character
|
||||
STOREI
|
||||
DROP
|
||||
RET
|
||||
|
||||
; ---- wait until a character is received and return it on eval stack
|
||||
CONIN:
|
||||
LOADC WAITFORBYTE
|
||||
CALL
|
||||
LOADC -1 ; -1 means timeout
|
||||
CMP.S0 NE
|
||||
CBRANCH CONIN_XT ; exit if no timeout
|
||||
DROP ; remove last result
|
||||
BRANCH CONIN
|
||||
CONIN_XT:
|
||||
RET
|
||||
|
||||
|
||||
.EQU L_BLOCKSIZE 32
|
||||
.EQU L_WORDSIZE 4
|
||||
.EQU CKSUM_PATTERN $AFFECAFE
|
||||
RCVBLOCKS:
|
||||
LOADCP MON_ADDR ; pointer to current write position,
|
||||
LOADI ; kept on stack
|
||||
RCVBLOCKS_L:
|
||||
LOADC WAITFORBYTE ; read header byte
|
||||
CALL
|
||||
LOADC -1
|
||||
CMP.S0 EQ
|
||||
CBRANCH RCVBLOCKS_XT ; exit on timeout
|
||||
|
||||
; check for EOT -> end
|
||||
LOADC EOT
|
||||
CMP.S0 EQ
|
||||
CBRANCH RCVBLOCKS_XT
|
||||
|
||||
; check for STX -> read block
|
||||
LOADC STX
|
||||
CMP.S0 EQ
|
||||
CBRANCH RCVBLOCKS_CONT
|
||||
|
||||
; anything else -> send NAK
|
||||
BRANCH RCVBLOCKS_RETRY
|
||||
|
||||
RCVBLOCKS_CONT:
|
||||
DROP ; remove header byte
|
||||
DUP ; duplicate pointer
|
||||
LOADC READBLOCK
|
||||
CALL
|
||||
LOADC -1
|
||||
CMP.S0 EQ ; check for timeout
|
||||
CBRANCH RCVBLOCKS_XT ; exit on timeout
|
||||
|
||||
LOADC -2
|
||||
CMP.S0 EQ ; check for checksum error
|
||||
CBRANCH RCVBLOCKS_RETRY
|
||||
|
||||
DROP ; remove return code
|
||||
LOADC L_BLOCKSIZE ; advance pointer
|
||||
ADD
|
||||
|
||||
LOADC ACK ; send ACK
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
|
||||
; next block
|
||||
BRANCH RCVBLOCKS_L
|
||||
|
||||
RCVBLOCKS_RETRY:
|
||||
DROP ; remove read byte
|
||||
; send NAK
|
||||
LOADC NAK
|
||||
LOADC CONOUT
|
||||
CALL
|
||||
|
||||
; next block
|
||||
BRANCH RCVBLOCKS_L
|
||||
|
||||
RCVBLOCKS_XT:
|
||||
DROP ; remove pointer
|
||||
DROP ; remove read byte
|
||||
RET
|
||||
|
||||
|
||||
; ---- read a sequence of binary words and store into memory
|
||||
; - arguments: pointer to memory area
|
||||
READBLOCK:
|
||||
FPADJ -12
|
||||
STORE 0 ; buffer pointer
|
||||
LOADCP L_BLOCKSIZE
|
||||
STORE 4 ; remaining bytes
|
||||
LOADC 0
|
||||
STORE 8 ; checksum
|
||||
READBLOCK_L:
|
||||
LOADCP READWORD ; read a word
|
||||
CALL
|
||||
LOADC -1 ; check for timeout
|
||||
CMP EQ
|
||||
CBRANCH.NZ READBLOCK_ERR
|
||||
|
||||
; DUP ; debug
|
||||
; LOADC PRINTHEXW
|
||||
; CALL
|
||||
|
||||
|
||||
DUP ; duplicate read word
|
||||
LOAD 8 ; load checksum
|
||||
ADD ; checksum = ((checksum + data) ^ pattern) << 1
|
||||
LOADCP CKSUM_PATTERN
|
||||
XOR
|
||||
SHL
|
||||
STORE 8 ; store new checkcsum
|
||||
|
||||
LOAD 0 ; load buffer pointer
|
||||
SWAP ; swap value and pointer for STOREI
|
||||
STOREI 4 ; store word and increment pointer
|
||||
STORE 0 ; store pointer
|
||||
|
||||
LOAD 4 ; load remaining bytes
|
||||
DEC L_WORDSIZE ; decrement by word size
|
||||
DUP
|
||||
STORE 4 ; store
|
||||
CBRANCH.NZ READBLOCK_L ; loop if remaining words not zero
|
||||
|
||||
|
||||
LOADCP READWORD ; read checksum
|
||||
CALL
|
||||
LOADC -1 ; check for timeout
|
||||
CMP EQ
|
||||
CBRANCH READBLOCK_ERR
|
||||
|
||||
LOAD 8 ; load checksum
|
||||
CMP EQ
|
||||
CBRANCH READBLOCK_OK
|
||||
LOADC -2 ; return code for checksum error
|
||||
BRANCH READBLOCK_XT
|
||||
READBLOCK_OK:
|
||||
LOADC 0 ; return 0
|
||||
READBLOCK_XT:
|
||||
FPADJ 12
|
||||
RET
|
||||
|
||||
READBLOCK_ERR:
|
||||
DROP ; remove result
|
||||
LOAD 4 ; return number of missing bytes
|
||||
FPADJ 8
|
||||
RET
|
||||
|
||||
; --- read four bytes (msb to lsb) and return as word
|
||||
; returns: word, error code (-1 for error, 0 otherwise)
|
||||
|
||||
READWORD:
|
||||
LOADCP WAITFORBYTE
|
||||
CALL
|
||||
DUP
|
||||
LOADC -1 ; check for error
|
||||
CMP EQ
|
||||
CBRANCH.NZ READWORD_ERR
|
||||
; first byte is now on stack
|
||||
BROT ; rotate byte left
|
||||
|
||||
LOADCP WAITFORBYTE
|
||||
CALL
|
||||
DUP
|
||||
LOADC -1 ; check for error
|
||||
CMP EQ
|
||||
CBRANCH.NZ READWORD_ERR
|
||||
; second byte is now on stack
|
||||
OR ; OR last byte with this byte
|
||||
BROT ; rotate bytes left
|
||||
|
||||
LOADCP WAITFORBYTE
|
||||
CALL
|
||||
DUP
|
||||
LOADC -1 ; check for error
|
||||
CMP EQ
|
||||
CBRANCH.NZ READWORD_ERR
|
||||
; third byte is now on stack
|
||||
OR ; OR last byte with this byte
|
||||
BROT
|
||||
|
||||
LOADCP WAITFORBYTE
|
||||
CALL
|
||||
DUP
|
||||
LOADC -1 ; check for error
|
||||
CMP EQ
|
||||
CBRANCH.NZ READWORD_ERR
|
||||
; fourth byte is now on stack
|
||||
OR ; OR last byte with this byte
|
||||
|
||||
LOADC 0 ; error code (0: no error)
|
||||
RET
|
||||
|
||||
READWORD_ERR:
|
||||
LOADC -1 ; error code
|
||||
RET
|
||||
|
||||
;---- wait a fixed amount of cycles for a character to be
|
||||
; received on the UART.
|
||||
; returns character or -1 on timeout
|
||||
|
||||
.EQU MAX_WAIT 20000000
|
||||
WAITFORBYTE:
|
||||
LOADCP MAX_WAIT ; maximum wait loops
|
||||
WAITFORBYTE_L:
|
||||
LOADC UART_REG ; address of UART register
|
||||
LOADI ; load status
|
||||
LOADC 512 ; check bit 9 (rx_avail)
|
||||
AND
|
||||
CBRANCH WAITFORBYTE_RX ; if bit 9 is one, a character is available
|
||||
DEC 1
|
||||
DUP
|
||||
CBRANCH.NZ WAITFORBYTE_L
|
||||
DROP ; remove wait counter from stack
|
||||
LOADC -1 ; error code
|
||||
RET
|
||||
WAITFORBYTE_RX:
|
||||
DROP ; remove wait counter from stack
|
||||
LOADC UART_REG
|
||||
LOADI ; read register again
|
||||
LOADC 255 ; mask status bits
|
||||
AND
|
||||
LOADC UART_REG ; I/O address
|
||||
LOADC 512 ; set bit 9 (rx_clear)
|
||||
STOREI ; write register
|
||||
DROP ; remove address left by STOREI
|
||||
RET
|
||||
|
||||
.CPOOL
|
||||
|
||||
;---- boot from SD-card
|
||||
|
||||
; declare buffer addresses used by sdcardlib.s
|
||||
.EQU CSD_BUF 63984
|
||||
.EQU CARD_BUF 64000
|
||||
CMD_B:
|
||||
DROP ; remove input char
|
||||
LOADCP NEWLINE
|
||||
CALL
|
||||
|
||||
FPADJ -4
|
||||
; initialize card
|
||||
LOADC INITSDCARD
|
||||
CALL
|
||||
|
||||
; read partition block
|
||||
LOADC 0
|
||||
LOADC CARDREADBLK
|
||||
CALL
|
||||
|
||||
DUP ; non-zero return code means error
|
||||
CBRANCH.Z CMD_B_1
|
||||
CMD_B_ERR:
|
||||
LOADC PRINTHEXW ; print error code
|
||||
CALL
|
||||
LOADC NEWLINE
|
||||
CALL
|
||||
LOADC 0 ; if we return, we need to
|
||||
; put a fake input char back on the
|
||||
; stack because the main loop will
|
||||
; try to remove it
|
||||
FPADJ 4
|
||||
RET
|
||||
|
||||
CMD_B_1:
|
||||
DROP ; remove error code
|
||||
; check boot partition slot (boot flag)
|
||||
LOADCP CARD_BUF,104 ; offset partition flags second part slot
|
||||
LOADI
|
||||
LOADC 2 ; PartFlags [PartBoot]
|
||||
CMP EQ
|
||||
CBRANCH CMD_B_C
|
||||
|
||||
; no boot partition
|
||||
LOADC $B0
|
||||
BRANCH CMD_B_ERR
|
||||
|
||||
CMD_B_C:
|
||||
; get start block
|
||||
LOADCP CARD_BUF,108 ; offset startBlock
|
||||
LOADI
|
||||
; get block count
|
||||
LOADCP CARD_BUF,124 ; offset bootBlocks
|
||||
LOADI
|
||||
|
||||
FPADJ -4 ; allocate space for address var
|
||||
LOADCP MON_ADDR
|
||||
LOADI
|
||||
STORE 0 ; initialize dest addr
|
||||
CMD_B_L:
|
||||
; read block
|
||||
OVER ; duplicate block no
|
||||
LOADC CARDREADBLK
|
||||
CALL
|
||||
|
||||
DUP ; check for error
|
||||
CBRANCH.Z CMD_B_C2 ; continue if zero (no error)
|
||||
|
||||
NIP ; remove start and count, keep error code
|
||||
NIP
|
||||
BRANCH CMD_B_ERR
|
||||
CMD_B_C2: DROP ; remove error code
|
||||
CMD_B_2:
|
||||
; copy to destination
|
||||
LOAD 0 ; dest addr
|
||||
LOADC COPY_BLK
|
||||
CALL
|
||||
|
||||
; decrement count and loop
|
||||
LOAD 0 ; increment dest addr
|
||||
LOADC 512
|
||||
ADD
|
||||
STORE 0
|
||||
|
||||
SWAP ; swap block no/count, blockno is now ToS
|
||||
INC 1
|
||||
SWAP ; count is now ToS
|
||||
DEC 1
|
||||
DUP
|
||||
CBRANCH.NZ CMD_B_L ; if not zero, loop
|
||||
|
||||
; jump to coreloader
|
||||
DROP
|
||||
DROP
|
||||
FPADJ 4
|
||||
LOADCP MON_ADDR
|
||||
LOADI
|
||||
JUMP
|
||||
|
||||
CMD_B_XT:
|
||||
FPADJ 4
|
||||
RET
|
||||
|
||||
; copy a sdcard block to destination address
|
||||
; block size is always 512 byte, source
|
||||
; is always CARD_BUF
|
||||
; parameters: dest addr
|
||||
COPY_BLK:
|
||||
FPADJ -4
|
||||
LOADC 128 ; word count
|
||||
STORE 0
|
||||
|
||||
LOADCP CARD_BUF ; src addr
|
||||
COPY_BLK1:
|
||||
SWAP
|
||||
; [ src addr, dest addr ]
|
||||
OVER ; [ saddr, daddr, saddr ]
|
||||
LOADI ; [ saddr, daddr, sword ]
|
||||
STOREI 4 ; [ saddr, daddr + 4 ]
|
||||
SWAP ; [ daddr + 4, saddr ]
|
||||
INC 4 ; [ daddr + 4, saddr + 4]
|
||||
|
||||
LOAD 0 ; load and decrement counter
|
||||
DEC 1
|
||||
DUP
|
||||
STORE 0 ; store it again
|
||||
CBRANCH.NZ COPY_BLK1 ; if not zero, loop
|
||||
|
||||
DROP ; remove saddr and daddr
|
||||
DROP
|
||||
|
||||
FPADJ 4
|
||||
RET
|
||||
|
||||
.CPOOL
|
||||
|
||||
; wait approx. 1 millisecond
|
||||
;
|
||||
; 83.333 MHz Clock, three instructions a 4 cycles
|
||||
; 83333 / 12 = 6944.4166
|
||||
; works only if executed without wait states (i.e.
|
||||
; from BRAM/SRAM)
|
||||
WAIT1MSEC:
|
||||
LOADCP 6944
|
||||
WAIT1LOOP:
|
||||
DEC 1
|
||||
DUP
|
||||
CBRANCH.NZ WAIT1LOOP
|
||||
DROP
|
||||
RET
|
||||
|
||||
%include "sdcardboot.s"
|
||||
.CPOOL
|
||||
MESSAGE:
|
||||
.BYTE 13,10,"ROM Monitor v3.0.3", 13, 10,
|
||||
"Set A)ddress D)eposit eX)amine L)oad G)o B)oot",13,10,0
|
||||
PROMPT2:
|
||||
.BYTE "]> ",0
|
||||
END:
|
||||
Loading…
Add table
Add a link
Reference in a new issue