************************ TALKER51.ASC 9/8/89 *****************************
*   Written by R.Soja, Motorola, East Kilbride                           *
*   Motorola Copyright 1989                                              *
*   MCU resident, Interrupt driven Communication routines for HC11JC     *
*   monitor. Provides low level memory and stack read/write operations.  *
*   Works with Host user interface program PCBUG11.EXE and 65C51 ACIA.   *
*   Includes subroutine to boot up DSP56001 with code to simulate SPI2.  *
*
* CONSTANTS
TALKBASE  equ $6000
TALKVECT  equ $FFF4       Start address of vectors used by TALKER51
ACIA      equ $9000
uS500     equ 1000/7      500uS delay with DEY/BNE loop
BRKCODE   equ $4A         Break point signal code to host.
BRKACK    equ $B5         Break point acknowledge code from host.
*
* ACIA MASKS
TDRE      equ $10
RDRF      equ $08
FE        equ $02
*
* PROGRAM
          org TALKBASE
*
TALKSTART EQU *
          LDS #$1FF
          LDD #$C91E    Init ACIA to 9600 baud, 8 bit, no parity, Rx intr.
          STD ACIA+2    Note: Control reg set up for 1.843MHz xtal.
          JSR LOADSPI2  Load DSP and start it.
*
USERSTART EQU *         This is entry point of user defined reset.
          TPA           XIRQ must be enabled (Clear X bit in CCR)
          ANDA #$BF
          TAP
IDLE      JMP IDLE      Now hang around for interruption from host.
* A RESET from host changes above jump destination to start of user code.
*
XIRQSRV   EQU *
          LDAA ACIA+1   If ACIA has generated interrupt, then
          BMI TXIRQ     Talker code processes received data
          JMP >TXIRQEX
* Above 3 bytes are replaced by JMP USERXIRQ instruction from host monitor, if
* user specified XIRQ vector is detected during download of user code.
*
XIRQUJMP  EQU *-2       Label equates to JMP operand.
*
TXIRQ     EQU *
          LDAA ACIA     Read command byte, & echo it as acknowledge
          BSR OUTACIA   to host.
          BMI INH1      If command bit 7 set, then process inherent command
          BSR INACIA    else read byte count from host into ACCB.(0=256)
          XGDX          Save command and byte count.
          BSR INACIA    Read high address byte
          TBA           into ACCA
          BSR INACIA    then low address byte into ACCB
          XGDX          Restore command in ACCA,count in ACCB,address in X
          CMPA #$01
          BNE TXIRQ1    If command is memory read, then
*
TREADMEM  EQU *         REPEAT
          LDAA ,X       read required address
          BSR OUTACIA   send it to host
          TBA           (save byte count)
          BSR INACIA    and wait for acknowledge
          TAB           (restore byte count)
          INX           Increment address
          DECB          Decrement byte count
          BNE TREADMEM  UNTIL all done
          RTI           and return to idle loop or user code.
*
TXIRQ1    EQU *
          CMPA #$41
          BNE TXIRQEX   If command is memory write then
*
          TBA           move byte count to ACCA
TWRITMEM  EQU *         REPEAT
          BSR INACIA    Read next byte from host into ACCB,
          STAB ,X       and store at required address.
          LDY #20000/14 Set up timeout count of ~10mS
*
WAITPOLL  CMPB ,X       Wait until read back data matches written data
          BEQ WAITEND
          DEY           or timeout reached,
          BNE WAITPOLL
          BRA USERSTART in which case, restart without reloading DSP.
*
WAITEND   LDAB ,X       Read stored byte and
          STAB ACIA     echo it back to host,
          INX
          DECA          Decrement byte count
          BNE TWRITMEM  UNTIL all done
*
          LDY #4000/7   Wait ~2mS to permit PCBUG11 to enable write protect
TXWAITEX  DEY
          BNE TXWAITEX
TXIRQEX   RTI           and return
*
INACIA    EQU *
          LDAB ACIA+1
          BITB #FE      If break detected then
          BEQ INACIA1   clean up stack and
          LDS #$1FF     restart from user start,
          BRA USERSTART
*
INACIA1   ANDB #RDRF    else if new data received from host
          BEQ INACIA
          LDAB ACIA     then read it
          RTS           and return with data in ACCB
*
OUTACIA   EQU *         Only register Y modified.
          XGDY          Enter with data to send in ACCA, saved in Y
OUTACIA1  LDAA ACIA+1
          ANDA #TDRE
          BEQ OUTACIA1
          XGDY          Restore ACCA
          LDY #$180
OUTDELAY  DEY           Wait until transmission complete (@ 9600 baud)
          BNE OUTDELAY  (to fix spurious loss of transmitted character!)
          STAA ACIA     Important - Updates CCR!
          RTS
*
INH1      EQU *
          CMPA #$81     If command is read MCU registers then
          BNE INH2
*
INH1A     TSX           Move stack pointer to X
          XGDX          then to ACCD
          BSR OUTACIA   send stack pointer to host (high byte first)
          TBA
          BSR OUTACIA   then low byte
          TSX           Restore X (=stack pointer)
          LDAB #9       then return 9 bytes on stack
          BRA TREADMEM  i.e. CCR,ACCB,ACCA,IXH,IXL,IYH,IYL,PCH,PCL
*
INH2      EQU *
          CMPA #$C1     If command is write MCU registers then
          BNE SWISRV1
*
          BSR INACIA    get stack pointer from host (High byte first)
          TBA
          BSR INACIA
          XGDX          Move to X reg
          TXS           and copy to stack pointer
          LDAA #9       Then put next 9 bytes from host on to stack
          BRA TWRITMEM
*
SWISRV    EQU *         Breakpoints generated by host-placed SWI instruction.
          LDAA #BRKCODE Force host to process breakpoints
          BSR OUTACIA   by sending it the break signal
SWIIDLE   BRA SWIIDLE   then wait for response from host. (Ibit=1,Xbit=0)
*
SWISRV1   EQU *
          CMPA #BRKACK  If host has acknowledged breakpoint state then
          BNE TXIRQEX
          TSX           move stack pointer to SWI stack frame and
          LDAB #9
          ABX
          TXS
          LDD 7,X       Send user code breakpoint return address to host
          BSR OUTACIA   (high byte first)
          TBA
          BSR OUTACIA   (low byte next)
          LDD #IDLE     force idle loop on return from breakpoint processing
          STD 7,X
          BRA INH1A     but first return all MCU registers to host
*
ILLOPSRV  equ *
          STOP
          BRA ILLOPSRV
*
***************************************************************************
*             Loader for LME HC11FCCSIC SPI2 code.                        *
*     SPI2 is simulated by the DSP56001 running in bootstrap mode.        *
*                                                                         *
*                                                                         *
LOADSPI2  LDX #SPI2CODE
*
LOADINIT  LDY #$8005       Set up pointers to load DSP code into its host
          LDAB #3          receive registers.
LOADBYTE  LDAA ,X
          STAA ,Y
          INY
          INX
          DECB
          BNE LOADBYTE
          CPX #SPI2END
          BLS LOADINIT
 
*
          LDX #$8000       Now start execution of DSP code in internal RAM
          BSET 0,X,#8      by setting HF0 bit in ICR register.
          RTS
*
SPI2CODE  EQU *
          FCB $08,$F4,$AC,$00,$00,$01,$08,$F4,$AD,$00,$3E,$3F,$08,$F4,$A1,$00
          FCB $01,$F8,$08,$F4,$A0,$00,$00,$01,$65,$F4,$00,$00,$FF,$E8,$67,$F4
          FCB $00,$00,$FF,$EB,$66,$F4,$00,$00,$FF,$EF,$30,$08,$00,$31,$18,$00
          FCB $0A,$65,$23,$0A,$65,$04,$46,$F4,$00,$00,$80,$00,$47,$F4,$00,$00
          FCB $00,$80,$25,$00,$00,$0A,$A9,$80,$00,$00,$17,$45,$65,$00,$44,$E7
          FCB $00,$20,$00,$D0,$50,$66,$00,$0A,$AE,$87,$00,$00,$1D,$44,$E6,$00
          FCB $20,$00,$C0,$54,$67,$00,$60,$65,$00,$0A,$A9,$80,$00,$00,$17,$61
          FCB $65,$00,$44,$E7,$00,$0C,$00,$17
SPI2END   EQU *
*
          org TALKVECT
          FDB XIRQSRV
          FDB TXIRQEX   SWI (Changed by Break and Trace monitor cmds)
          FDB ILLOPSRV
          FDB TXIRQEX   COP Software fail (Unused)
          FDB TXIRQEX   COP Clock Monitor fail (Reassigned by PCBUG11 Reset)
          FDB TALKSTART
*
          END
 