; sloader.asm
; Wed Aug  2 23:56:14 PDT 1989
; This file originally came from Motorola's Dr. BuB DSP board.
; Slightly modified by Todd Day (todd@ivucsb.sba.ca.us)
;	to echo characters received.

;       Serial Loader for the DSP56000.
;       This loader initializes the serial communications interface (SCI)
;       on the DSP56001 for 9600 baud and then loads OMF records (output
;       by the DSP56000 assembler) into internal memory.  The loader takes
;       the upper 128 bytes of P memory allowing the lower memory from
;       $0000-(LDRMEM-1) to be used by the user.  The following records are
;       interpreted:
;           _DATA X ADDR
;           _DATA Y ADDR
;           _DATA P ADDR
;           _END ADDR
;       After the END record is encountered, the loader jumps to the address
;       in the END record.  Note that an address MUST be present in the
;       END record (the program must contain at least one P segment).
;
;       To generate a EPROM of this loader (8Kx8), perform the following:
;       $ asm56000 -b -l -a sloader
;       $ srec sloader
;
;       The EPROM is in file SLOADER.P.  To program the EPROM, set the
;       programmer to MOTOROLA S record format, download the file with
;       a zero address offset and program the part.
;
;	BTW, S record format is LSB MidSB MSB (what! Intel format? :-)
;	Took me a few hours to figure this one out!
;
;	If you don't have the program srec (where can I get this?),
;	you have to do some gnarly contortions on the .LOD file.
;
;	So, if your .LOD file resulting from compiling this program
;	looks like this:
;
;	_START SLOADER 0000 0000
;
;	_DATA P 0020
;	010203 040506 070809
;	_END 0020
;
;	then, program your PROM with this sequence:
;	$0020	0302  0106  0504  0908  07..... etc. (Fun, eh? :)
;
;
;       The loader loads the following memory spaces:
;           X - 0 to FF
;           Y - 0 to FF
;           P - 0 to LDRMEM-1
;
        PAGE    68,66,1,1

SCR     EQU     $FFF0           ;SCI CONTROL REGISTER
SCCR    EQU     $FFF2           ;SCI CLOCK CONTROL REGISTER
PCC     EQU     $FFE1           ;PORT C CONTROL REGISTER
RDRF    EQU     $2              ;RECEIVE DATA REGISTER FULL FLAG
SSR     EQU     $FFF1           ;SCI STATUS REGISTER
SRXH    EQU     $FFF6           ;SCI RECEIVE IN HIGH BYTE
LDRMEM  EQU     $19D            ;START OF LOADER IN P MEMORY

        ORG     P:$0000         ;RESET VECTOR FOR BOOTING
RVEC
        JMP     LOAD            ;GO EXECUTE LOADER

        ORG     P:LDRMEM,P:3*LDRMEM
LOAD
        MOVEP   #$0302,X:SCR    ;ENABLE TX,RX: 8 BIT 1 START, 1 STOP

				; *** You will probably have to
				; *** change the line below!
        MOVEP   #$0020,X:SCCR   ;CD=32 (/33), INT CLK @ 9600 BAUD
        MOVEP   #$0007,X:PCC    ;ENABLE SCI
WTUS
        JSR     GETCH           ;INPUT CHARACTER
        MOVE    #'_',X0         ;GET UNDERSCORE CHARACTER
        CMP     X0,A            ;SEE IF "_" YET
        JNE     WTUS            ;NO
GOTUS
        JSR     GETCH           ;GET A CHARACTER
        MOVE    #'D',X0         ;GET A D FOR DATA
        CMP     X0,A    #'E',X0 ;COMPARE TO D, GET E
        JEQ     DATAREC         ;IF "D", THEN DATA RECORD
        CMP     X0,A            ;SEE IF END RECORD
        JNE     WTUS            ;NO, GO WAIT FOR ANOTHER UNDERSCORE
_WTSPC
        JSR     GETCH           ;GET CHARACTER
        MOVE    #$20,X0         ;GET SPACE
        CMP     X0,A            ;WAIT FOR SPACE AFTER "END"
        JNE     _WTSPC          ;WAIT FOR SPACE
        JSR     IN4             ;GET TRANSFER ADDRESS
        MOVE    B1,R0           ;MOVE TRANSFER ADDRESS
        NOP                     ;CLEAR ADDRESS PIPE
        JMP     (R0)            ;GO EXECUTE USER CODE
DATAREC
        JSR     GETCH           ;GET CHARACTER
        MOVE    #$20,X0         ;GET SPACE
        CMP     X0,A            ;SEE IF SPACE
        JNE     DATAREC         ;NO
        JSR     GETCH           ;GET [P,X,Y]
        MOVE    A1,Y0           ;SAVE CHARACTER
        JSR     IN4             ;GET ADDRESS OF DATA RECORD
        MOVE    B1,R0           ;SAVE ADDRESS
        MOVE            #'X',A  ;GET X
        CMP     Y0,A    #'Y',A  ;SEE IF X, GET Y
        JEQ     _LDX            ;LOAD DATA INTO X MEMORY
        CMP     Y0,A            ;SEE IF Y
        JEQ     _LDY            ;LOAD DATA INTO Y MEMORY
_LDP
        JSR     IN6             ;GET DATA
        MOVE    B1,P:(R0)+      ;LOAD P MEMORY
        JMP     _LDP
_LDX
        JSR     IN4             ;GET DATA
        MOVE    B1,X:(R0)+      ;LOAD X MEMORY
        JMP     _LDX
_LDY
        JSR     IN4             ;GET DATA
        MOVE    B1,Y:(R0)+      ;LOAD Y MEMORY
        JMP     _LDY

GETCH
        JCLR    #RDRF,X:SSR,*   ;WAIT FOR DATA IN SCI
        MOVEP   X:SRXH,A        ;GET SCI DATA IN HIGH BYTE
        LSL     A               ;SHIFT OUT PARITY
        LSR     A               ;PUT 0 IN PARITY BIT
        MOVE    A1,A            ;SIGN EXTEND AND ZERO
	MOVEP	A,X:SRXH	;put sci data in high byte
        RTS

IN4
        CLR     B       #>4,X0  ;CLEAR VALUE, GET 4
        JMP     READHEX         ;READ 4 HEX CHARACTERS
IN6
        CLR     B       #>6,X0  ;CLEAR VALUE, GET 6
READHEX
        DO      X0,_READHEX     ;READ ASCII HEX AND CONVERT TO BINARY
_GET
        JSR     GETCH           ;GET A CHARACTER
        MOVE    #'_',X0         ;GET UNDERSCORE
        CMP     X0,A    #'F',X0 ;SEE IF UNDERSCORE
        JNE     _NOTUS          ;NO
        ENDDO                   ;EXIT LOOP
        MOVE    SSH,X0          ;POP RETURN ADDRESS
        JMP     GOTUS           ;GO PROCESS NEW INPUT RECORD
_NOTUS
        CMP     X0,A    #'0',X0 ;SEE IF GREATER THAN F
        JGT     _GET            ;YES, IGNORE
        CMP     X0,A            ;SEE IF LESS THAN 0
        JLT     _GET            ;YES, IGNORE
        SUB     X0,A    #10,X0  ;ADJUST FOR ASCII TO BINARY
        CMP     X0,A    #7,X0   ;SEE IF A-F
        JLT     _NOTALPHA       ;NO
        SUB     X0,A            ;ADJUST FOR 1-F
_NOTALPHA
        REP     #4              ;SHIFT OLD VALUE LEFT 1 NIBBLE
        LSL     B
        REP     #16             ;SHIFT NEW NIBBLE DOWN TO LSB
        LSR     A
        ADD     A,B             ;ADD NEW NIBBLE IN
_READHEX
        RTS

        END
