*****************************************************************************
*                     MONITOR PROGRAM FOR THE M68HC11                       *
*                               version 1.0                                 *
*****************************************************************************
* Description:    This program provides a controlled testing environment    *
*               for software development on a target 68HC11 microprocessor  *
*               It eliminates the need to reprogram the program under       *
*               testing into the eprom after minor changes.                 *
*               It allows the user to alter the contents of a memory        *
*               location or the contents of the microprocessor's            *
*               accumulators and registers.                                 *
*                 The monitor adds no extra cost to the target system other *
*               than the memory it occupies.  The main portion of the       *
*               monitor resides in the memory location specified by ROMS.   *
*               The variables used by the monitor is located in the memory  *
*               location specified by RAMS.  The values of RAMS and ROMS    *
*               can be alter to suit the user perference.                   *
*                 The monitor communicates through the target system's      *
*               serial port to an external host computer (via RS-232).      *
*                                                                           *
* Features Available:   1) Load - Loads user's test program into specified  *
*                                 memory location.                          *
*                       2) Run  - Run test program in memory.               *
*                       3) Call - Execute a JSR.                            *
*                       4) Help - Display list of commands available.       *
*                       5) Break- Add/delete Breakpoints                    *
*                       6) MD   - Display a block of memory.                *
*                       7) SS   - Single Step test program using interrupt. *
*                       8) SS2  - Single Step test program using breakpoints*
*                       9) Reg  - Display/modify CPU's registers.           *
*                      10) Fill - Alter the contents of a memory location.  *
*                                                                           *
* Memory Requirements:  4 kilobytes                                         *
*                                                                           *
* Other Requirements:     This monitor program does not require any external*
*                       host program.  However, it requires a communication *                     
*                       software program that could interface with the      *
*                       serial port of the host computer.  The monitor      *
*                       program configures the SCI port of the target       *
*                       system to a 9800 baud at a 8 MHz crystal (4800 baud *
*                       for 4 MHz).  Also, the SCI character length is      *
*                       configure to:                                       *
*                               Start Bit:       1                          *
*                               Data Bit :       8                          *
*                               Parity   :       None                       *
*                               Stop bit :       1                          *
*                                                                           *
*                                                                           *
* PROGRAMMED BY:  KIN-HUNG LEUNG                                            *
*****************************************************************************

*****************************************************************************
*                            PROGRAM EQUATES                                *
*****************************************************************************
* RAM and ROM specifications                                                *
*****************************************************************************
*RAMS            equ     $7000           Start of RAM
*IntRamEnd       equ     RAMS+$00FF      End Of internal RAM of M68HC11
*ROMS            equ     $7100           Start of ROM
RAMS            equ     $0000           Start of RAM
IntRamEnd       equ     RAMS+$00FF      End Of internal RAM of M68HC11
ROMS            equ     $E100           Start of ROM

*****************************************************************************
* Port Addresses, Peripheral Devices                                        *
*****************************************************************************
BaseReg         equ     $1000           Base Address of CPU Registers
Baud            equ     BaseReg+$2B     Baud register for SCI
SCCR1           equ     BaseReg+$2C     Control register 1 for SCI
SCCR2           equ     BaseReg+$2D     Control register 2 for SCI
SCSR            equ     BaseReg+$2E     Status register for SCI
SCDR            equ     BaseReg+$2F     Data register for SCI
TCNT            equ     BaseReg+$0E     Free running counter
TOC5            equ     BaseReg+$1E     Output compare register 5
TMSK1           equ     BaseReg+$22     Timer mask 1
TFLG1           equ     BaseReg+$23     Timer flag 1

*****************************************************************************
* Stack Size of User and Monitor                                            *
*****************************************************************************
UserStackSize   equ     50              User stack size
MonStackSize    equ     30              Monitor stack size

*****************************************************************************
* Buffer Size of for the SCI                                                *
*****************************************************************************
MaxBufSize      equ     50              Size of input character buffer

*****************************************************************************
* Maximum breakpoints available                                             *
*****************************************************************************
MaxBreak        equ     4               Maximum break point available

*****************************************************************************
* Offsets to user's registers pointed by UserRegs                           *
*****************************************************************************
PC_OffSet       equ     0
Y_OffSet        equ     2
X_OffSet        equ     4
A_OffSet        equ     6
B_OffSet        equ     7
CCR_OffSet      equ     8
SP_OffSet       equ     9

*****************************************************************************
* Miscellaneous equates                                                     *
*****************************************************************************
Null            equ     $00             Null character
CR              equ     $0D             Hex code for carriage return code
LF              equ     $0A             Hex code for new line
Space           equ     $20             Hex code for space
BackSpace       equ     $08             Hex code for backspace
EOT             equ     $04             Hex code for end of Text code
CTRLC           equ     $03             Hex code for control-c
*JSWI            equ     $00F4           Jump vector for SWI interrupt
*JTOC5           equ     $00D3           Jump vector for output compare 5
*                                        interrupt.
*JSCI            equ     $00C4           Jump vecotr for SCI interrupt.                               
*****************************************************************************
*                             RAM ALLOCATIONS                               *    
*****************************************************************************
                org RAMS
                
*****************************************************************************
* User Stack Area                                                           *                
*****************************************************************************
                rmb     UserStackSize   User stack area
UserStack       rmb     1               Point to the top of user stack

*****************************************************************************
* Monitor Stack Area                                                        *                
*****************************************************************************
                rmb     MonStackSize    Monitor stack area
MonStack        rmb     1               Point to the top of Monitor stack

*****************************************************************************
* Temporary storage for user registers and accumulators                     *
*****************************************************************************
UserRegs        rmb     11              User registers:  PC,Y,X,A,B,CCR,SP

*****************************************************************************
* Flags, Counters and Temporary storage area for the monitor program        *
*****************************************************************************
St_Length       rmb     1               Counter for counting the number of 
*                                       characters in St_Buffer
Ok              rmb     1               Flag to indicate a condition
Flag            rmb     1               Flag to indicate a condition
Flag2           rmb     1               Flag to indicate a condition
Error           rmb     1               Flag to indicate a condition
Counter         rmb     1               Number Counting
Temp            rmb     2               Temporary storage for monitor vars
Temp2           rmb     2               Temporary storage for address
Temp3           rmb     2               Temporary storage for address

*****************************************************************************
* Pointers used by the monitor                                              *
*****************************************************************************
Command         rmb     2               Storage for command address.
Ptr             rmb     2               String pointer.

*****************************************************************************
* Miscellaneous variables used by the monitor                               *
*****************************************************************************
OffSet          rmb     2               Loading Offset.
CheckSum        rmb     1               Check sum counter.
FillValue       rmb     1               The value to be filled in memory.
CtrlC_On        rmb     1               Flag to indicate if the user want
*                                       to enable control break during
*                                       execution. 1=on 0=off

*****************************************************************************
* Starting and ending address for memory dump                               *
*****************************************************************************
MDAddr1         rmb     2               Starting address used by memory dump
*                                       routine.
MDAddr2         rmb     2               Ending address used by memory dump.

*****************************************************************************
* Breakpoint table                                                          *
*****************************************************************************
BreakTable      rmb     3*MaxBreak      User break point table
SS2Break        rmb     3*2             Break point table for single stepping

*****************************************************************************
* The size of buffer used for holding characters comming from the SCI       *
*****************************************************************************
BufferSize      rmb     1               Input buffer size.
St_Buffer       rmb     MaxBufSize      Input character buffer.

*****************************************************************************
* Vector Jump Table                                                         *
*****************************************************************************
                org   RAMS+$C4
JSCI            RMB   3
JSPI            RMB   3
JPAIE           RMB   3
JPAO            RMB   3
JTOF            RMB   3
JTOC5           RMB   3
JTOC4           RMB   3
JTOC3           RMB   3
JTOC2           RMB   3
JTOC1           RMB   3
JTIC3           RMB   3
JTIC2           RMB   3
JTIC1           RMB   3
JRTI            RMB   3
JIRQ            RMB   3
JXIRQ           RMB   3
JSWI            RMB   3
JILLOP          RMB   3
JCOP            RMB   3
JCLM            RMB   3

*****************************************************************************
* The Start of Monitor Program                                              *    
*****************************************************************************
* Description:  This is the main portion of the monitor program.  It consist*
*               of a loop that constantly reads in the command from the host*
*               and compare it with that in the command table.  If the      *
*               command exists, then it will execute the command.           *
*---------------------------------------------------------------------------*
                org     ROMS

Monitor         sei                     Disable all maskable interrupts.
                lds     #MonStack       Set Stack pointer to top of Monitor
*                                       stack area.
                LDAA #$00               CLEAR OUTPUT PORT
                STAA $1100
*****************************************************************************
* SET UP LCD
*****************************************************************************
        LDX     #$FFFF          ;GIVE LCD TIME TO RESET
JKD     DEX                     ;
        BNE     JKD             ;
        JSR     CLRLCD          ;CLEAR AND SETUP LCD
        LDX     #RESMES         ;PRINT -POWER ON RESET-
        JSR     LCDTEXT         ;
        LDX     #$FFFF          ;DELAY
JKD1    DEX                     ;
        BNE     JKD1            ;
        LDAA     #$01            ;CLEAR LCD
        JSR     WCTRL           ;
        LDX     #HELLO          ;PRINT -KMON V1.0-
        JSR     LCDTEXT         ;
        LDAA     #$C0            ;ADDRESS SECOND LINE OF LCD
        JSR     WCTRL           ;
        LDX     #HELLO1         ;PRINT SECOND LINE
        JSR     LCDTEXT         ;
        JMP     JKSTART         ;START MONITOR PROGRAM
****************************************************************************
* LCD SET UP
****************************************************************************
CLRLCD  PSHA
        LDAA    #$01            ;
        JSR     WCTRL           ;CLEAR LCD
        LDAA    #$02            ;
        JSR     WCTRL           ;HOME CURSOR
        LDAA    #$38            ;
        JSR     WCTRL           ;SET 8 BIT, 2 LINE, 5X7
        LDAA    #$0C            ;
        JSR     WCTRL           ;DISPLAY ON, CURSOR OFF
        LDAA    #$06            ;
        JSR     WCTRL           ;ENTRY MODE-INC ADDRESS, NO SHIFT
        PULA                    ;
        RTS                     ;
*****************************************************************************
* SEND A LINE OF TEXT TO LCD
* PASS START ADDRESS OF TEXT IN X
* TEXT STRING TERMINATED BY $00 OR $04
* TEXT SHOULD NOT EXCEED DISPLAY LINE WIDTH
*****************************************************************************
LCDTEXT PSHA
LCD     LDAA    0,X             ;GET BYTE FROM TEXT STRING
        CMPA    #$00            ;CHECK FOR END OF STRING
        BEQ DLCD                ;
        CMPA    #$04            ;
        BEQ DLCD                ;
        JSR WDAT                ;SEND CHARACTER TO LCD
        INX                     ;GET NEXT
        BRA LCD                 ;
DLCD    PULA                    ;
        RTS                     ;     
*****************************************************************************        
* OUTPUT CONTROL BYTE TO LCD
* CONTROL BYTE PASSED IN A
*****************************************************************************
WCTRL   PSHB                    ;
        STAA    $1400           ;WRITE BYTE TO LCD CONTROL REG
WCTRLL  LDAB    $1400           ;TEST BUSY FLAG
        ANDB    #$80            ;
        BNE     WCTRLL          ;
        PULB                    ;
        RTS                     ;
*****************************************************************************
* OUTPUT DATA BYTE TO LCD
* DATA BYTE PASSED IN A
*****************************************************************************
WDAT    PSHB                    ;
        STAA    $1401           ;WRITE BYTE TO LCD DATA REG
WDATL   LDAB    $1400           ;TEST BUSY FLAG
        ANDB    #$80            ;
        BNE     WDATL           ;
        PULB                    ;
        RTS                     ;        
*****************************************************************************        
* MESSAGES
*****************************************************************************
RESMES  FCC     'POWER ON RESET'
        FCB $00
HELLO   FCC     'KMON V1.0'
        FCB $00
HELLO1  FCC     'HC11 MPP (C)1996'
        FCB $00
*****************************************************************************

* Initialize Target System's SCI and monitor program variables.
JKSTART         jsr     Init_SCI
                jsr     Init_UserVar
                jsr     Init_MonVar
                jsr     Init_Host

Main            jsr     Prompt          'Command> '
                jsr     GetString       Get string of characters from host.
                tst     St_Length
                beq     Main            Branch if string is empty.
                jsr     SearchCom       Find command in command table.
                tst     Ok
                beq     Main            Branch if command not in table.
                ldx     Command
                jsr     ,x              Execute command.
                bra     Main

*****************************************************************************
* Init_SCI()                                                                *
*****************************************************************************
* Description:  This routine sets up the SCI for 9800 baud @ 8 Mhz or       *
*               4800 baud @ 4 Mhz crystal.  All interrupts relating to the  *
*               SCI are disabled.                                           *
*                                                                           *
* Entry Condition:  None                                                    *
*                                                                           *
* Exit Condition:  SCI setup for 9600 baud @ 8Mhz or 4800 baud @ 4Mhz       *
*                  cyrstal.                                                 *    
*                                                                           *
* Register(s) Changed:  Register A                                          *
*---------------------------------------------------------------------------*
Init_SCI        ldaa    #%00110000
                sta     Baud
                ldaa    #%00000000
                sta     SCCR1
                ldaa    #%00001100
                sta     SCCR2
                rts

*****************************************************************************
* Init_Host()                                                               *
*****************************************************************************
* Description:  This routine initialize the host by sending a string of     *
*               characters.                                                 *
*                                                                           *
* Entry Condition:  None                                                    *
*                                                                           *
* Exit Condition:  Initialization string sent to host.                      *
*                                                                           *
* Register(s) Changed:  Register X                                          *
*---------------------------------------------------------------------------*
Init_Host       ldx     #MSG1           '68HC11 Monitor Program'
                jsr     OutString3
                rts

*****************************************************************************
* Prompt()                                                                  *
*****************************************************************************
* Description:  Routine to display the command prompt on the host.          *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       The prompt string sent to host                      *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
Prompt          pshx
                jsr     NewLine;
                ldx     #MSG2           'Command> '
                jsr     OutString
                pulx
                rts

*****************************************************************************
* Init_UserVar()                                                            *
*****************************************************************************
* Description:  Routine to initialize the user registers (A,B,X,Y,PC,CCR,SP)*
*               to a known state.  The accumulators A and B will be set to  *
*               zero.  Accumulators X, Y and SP will be pointing to the     *
*               top of the user stack area.  PC will hold the value of      *
*               $6000 and the CCR will contain the value of %11010000.      *
*                                                                           *
* Entry Condition:  None                                                    *
*                                                                           *
* Exit Condition:  The Memory location containing the user registers is set *
*                  to a known preset value.                                 *
*                                                                           *
* Register(s) changed:  Register D and X                                    *
*---------------------------------------------------------------------------*
Init_UserVar    ldx     #UserRegs
                ldd     #UserStack
                std     X_OffSet,X      Set the user's x register value.
                std     Y_OffSet,X      Set the user's y register value.
                std     SP_OffSet,X     Set the user's stack pointer point
*                                       to the top the user's stack area.
                ldd     #$6000
                std     PC_OffSet,X     Set the user's PC to start at $6000.
                ldd     #$D000
                stb     A_OffSet,X      Set the user's A accumulator value.
                stb     B_OffSet,X      Set the user's B accumulator value.
                sta     CCR_OffSet,X    Set the user's CCR to $D000
*                                               I bit set
*                                               S bit set
*                                               X bit set
                rts

*****************************************************************************
* Init_MonVar()                                                             *
*****************************************************************************
* Description:  Routine to initialize the variables used by the Monitor     *
*               program.                                                    *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       The variables used by the Monitor is set to a known *
*                       value.                                              *
*                               BufferSize = MaxBufSize.                    *
*                               FillValue  = $FF                            *
*                               MDAddr1    = $0000                          *
*                               MDAddr2    = $0080                          *
*                       The address value of the user and the monitor       *
*                       break point table are set to $FFFF (no entry)       *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
Init_MonVar     pshx
                pshb
                psha

* Setting maximum character buffer size to MaxBufSize
                ldab    #MaxBufSize
                stab    BufferSize

* Predefine value for fill routine
                ldaa    #$FF
                staa    FillValue

* Predefine the value for CtrlC_On to 0.
                clr     CtrlC_On

* Predefine the starting and ending address for the memory dump routine
                ldd     #$0000
                std     MDAddr1
                addb    #$80
                std     MDAddr2
                
* Clear Break point table for single stepping.  The value $FFFF indicate
* no entry.
                ldx     #SS2Break
                ldd     #$FFFF
                std     ,x
                std     3,x

* Clear the user's break point table.  The value $FFFF indicate no entry.
                ldx     #BreakTable
                ldaa    #MaxBreak
Loop1           beq     EndLoop1
                psha
                ldd     #$FFFF
                std     ,x
                ldab    #3
                abx
                pula
                deca
                bra     Loop1

EndLoop1        pula
                pulb
                pulx
                rts

*****************************************************************************
* GetString                                                                 *
*****************************************************************************
* Description:  Routine to get a string of characters from the host.  The   *
*               carriage return sent from the host indicates the end of     *
*               the string.                                                 *
*                                                                           *
* Entry Condition:  None                                                    *
*                                                                           *
* Exit Condition:  The St_Buffer contains a string of characters of         *
*                  St_Length long.  The string is terminated with a carriage* 
*                  return.                                                  *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
GetString       pshx
                pshy
                psha
                pshb
                ldx     #St_Buffer      Points to the start of string buffer.
                clrb                    Clear character counter.
StringLoop      jsr     GetChar2        Get character from host.
                cmpb    BufferSize      
                bhs     StringError     Branch if character counter exceed
*                                       character buffer size.
                cmpa    #BackSpace
                bne     IncPointer      Branch if not backspace character.
DecPointer      tstb
                beq     StringLoop      Branch if character counter is zero.
                decb                    Decrement character counter.
                dex                     Decrement string pointer.
                jsr     OutChar
                ldaa    #Space
                jsr     OutChar         Delete character on host screen.
                ldaa    #BackSpace
                bra     SendCharOut
IncPointer      staa    ,x              
                cmpa    #$0D
                beq     EndString       Branch if carriage return.
                incb                    Increment character counter.
                inx                     Increment string pointer.
SendCharOut     jsr     OutChar
                bra     StringLoop
StringError     ldx     #MSG3           'Command Too Long'
                jsr     OutString3
                clrb                    Reset character counter to zero.
EndString       stb     St_Length
                pulb
                pula
                puly
                pulx
                rts

*****************************************************************************
* SearchCom                                                                 *
*****************************************************************************
* Description:  Routine to parse the command from the input string          *
*               buffer.  Any spaces in front of the command ill be          *
*               ignored.  The command will then be compared with the        *
*               commands in the command table.  If the command is not in    *
*               the command table the flag indicated by Ok is cleared.      *
*               Otherwise is set and the variable 'Command' contains the    *
*               starting address of the command routine.                    *    
*                                                                           *
* Entry Condition:      St_Buffer contains a carriage return terminated     *
*                       string.                                             *
*                                                                           *
* Exit Condition:       Variables:  Ok      - Cleared if command not found  *
*                                             otherwise set.                *
*                                   Command - Starting address of command   *
*                                             routine.                      *
*                                   Ptr     - Address of the next field in  *       
*                                             St_Buffer.                    *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
SearchCom       pshx
                pshy
                psha
                clr     Ok              Clear Ok flag.
                ldy     #ComTable       Points to the start of the Command
*                                       table.
                ldx     #St_Buffer      Points to the start of the String
*                                       Buffer.
                jsr     SkipSpace       Remove leading spaces.
                beq     SearchComEnd    Branch if only carriage return.
                stx     Temp            
SearchCom1      ldaa    ,x
                jsr     UpCase          Convert to upper case.
                cmpa    #' '
                beq     SearchCom3      Branch if space.
                cmpa    #CR
                beq     SearchCom3      Branch if carriage return.
SearchCom2      cmpa    ,y
                bne     SearchCom4      Branch if characters pointed by
*                                       x and y do not match.
                iny     
                inx     
                bra     SearchCom1      Compare next characters.
SearchCom3      jsr     FindNull        Advance y pointer to a Null character
                iny
                ldy     ,y              
                sty     Command         Store command address.
                inc     Ok
                bra     SearchComEnd
SearchCom4      jsr     NextCom         Advance y pointer to next command in
*                                       command table.
                bne     SearchError     Branch if end of table.
                ldx     Temp            Reset x to beginning of command field.
                bra     SearchCom1
SearchError     ldx     #MSG4           'Bad Command'
                jsr     OutString3
SearchComEnd    stx     Ptr
                pula
                puly
                pulx
                rts

*****************************************************************************
* GetChar(var a: char)                                                      *
*****************************************************************************
* Description:  Routine to get a character from the SCI.  It first checks   *
*               the RDRF bit of the SCSR.  If it is not set then it loops   *
*               until it is set.  When a character is received, the MSB of  *
*               the character is removed.                                   *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       Accumulator A contains the ASCII character sent by  *
*                       the host.                                           *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
GetChar         pshb
GetCharLoop     Ldab    SCSR
                bitb    #%00100000      
                beq     GetCharLoop     Branch if received data register full
                ldaa    SCDR
                anda    #$7F            Remove MSB
                pulb
                rts

*****************************************************************************
* GetChar2(var a: char)                                                     *
*****************************************************************************
* Description:  This routine is an extension to the GetChar routine.  In    *
*               this routine, the escape sequence character for the arrow   *
*               keys sent by the host is removed.  The function key <F7>    *
*               is enabled as a shortkey for single stepping.               *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       Accumulator A contains the ASCII character sent by  *
*                       the host.                                           *
*                                                                           *
* Register(s) Changed:  Accumulator A and B.                                *
*---------------------------------------------------------------------------*
GetChar2        jsr     GetChar
                cmpa    #$1B            Escape Char
                bne     GetCharEnd      Branch if not an escape character
GetCharLoop2    jsr     GetChar

* Disabling all cursor keys
                cmpa    #$5B            
                beq     GetCharLoop2
                cmpa    #$5D
                beq     GetCharLoop2    Disable Cursor Keys

* Enabling the <F7> key to activate single stepping using interrupts.
                cmpa    #$71
                bne     GetCharLoop3    Branch if not one of the escape 
*                                       sequence character for <F7>.
                ldx     #St_Buffer      Set pointer to point to the start
*                                       of the string buffer.
                ldaa    SingleStep
                staa    ,x              writes the first character 's' to
*                                       the string buffer.
                inx
                ldaa    #CR             Indicate a carriage return has been
*                                       pressed.
                incb                    Increment character counter.
                jmp     GetCharEnd
GetCharLoop3    cmpa    #$4F            
                beq     GetCharLoop2    Branch if one of the escape sequence
*                                       character of <F7>.

* Enabling the <F8> key to activate single stepping using breakpoints.
                cmpa    #$72
                bne     GetCharLoop4    Branch if not one of the escape 
*                                       sequence character for <F8>.
                ldx     #St_Buffer      Reset string pointer pointing to the
*                                       start of the string buffer.
                pshb
                ldd     SingleStep2
                std     ,x              Store the 'S2' in string buffer.
                pulb
                inx
                inx
                incb
                incb                    Increment the character counter by 2.
                ldaa    #CR             Indicate a carriage return has been
*                                       pressed.
                jmp     GetCharEnd
GetCharLoop4    cmpa    #$4F
                beq     GetCharLoop2    Branch if one of the escape sequence
*                                       character for <F8>.

                bra     GetChar2
GetCharEnd      rts

*****************************************************************************
* KeyPressed(var b: char)                                                   *
*****************************************************************************
* Description:  Routine to detect if a key was pressed on the host terminal.*
*               If a key is pressed, the Z bit in the CCR is cleared and    *
*               the ASCII hex character of the key is stored in accumulator *
*               B.                                                          *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       Z bit in CCR is set if no key was pressed.          *
*                       Otherwise is cleared.  If a key is pressed, the     *
*                       ASCII hex character of the key is stored in         *
*                       accumulator B.                                      *
*                                                                           *
* Register(s) Changed:  Accumulator B                                       *
*---------------------------------------------------------------------------*
KeyPressed      Ldab    SCSR
                bitb    #%00100000      
                beq     KeyPressedEnd   Branch if received data register empty
                ldab    SCDR
                andb    #$7F            Remove MSB
KeyPressedEnd   rts

*****************************************************************************
* OutChar(a: char)                                                          *
*****************************************************************************
* Description:  Routine to send a character in accumulator A to the host    *
*               through the SCI.                                            *
*                                                                           *
* Entry Condition:      Accumulator A contains the ASCII character to be    *
*                       sent through the SCI.                               *
*                                                                           *
* Exit Condition:       Character sent through the SCI.                     *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
OutChar         pshb
OutCharLoop     ldab    SCSR
                bitb    #%10000000
                beq     OutCharLoop     Branch if transmit data register is
*                                       not empty.
                sta     SCDR            
                pulb
                rts

*****************************************************************************
* OutSpace                                                                  *
*****************************************************************************
* Description:  Routine to send 'n' space characters to the host through    *
*               the SCI.                                                    *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       None.                                               *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
OutSpace        psha
                tsta
OutSpaceLoop    beq     EndOutSpace
                psha
                ldaa    #Space
                jsr     OutChar
                pula
                deca
                bra     OutSpaceLoop
EndOutSpace     pula
                rts

*****************************************************************************
* Out1Space, Out2Space                                                      *
*****************************************************************************
* Description:  Routine to send a space character (either 1,2 or n space) to*
*               the host through the SCI.                                   *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       None.                                               *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
Out1Space       psha
                ldaa    #1
                jsr     OutSpace
                pula
                rts
Out2Space       jsr     Out1Space
                jsr     Out1Space
                rts

*****************************************************************************
* OutString  (x: Pointer) -> Sends string of characters only.               *
* OutString2 (x: Pointer) -> Sends the string and the CR+LF.                *
* OutString3 (x: Pointer) -> Sends a CR+LF, String, CR+LF.                  *
* OutString4 (x: Pointer) -> Sends a CR+LF and the string.                  *
*****************************************************************************
* Description:  Routine to send a string of characters pointed by register  *
*               X through the SCI.  The string of characters must be        *
*               terminated by a Null ($00) character.                       *
*                                                                           *
* Entry Condition:      Register X contains the starting address of the     *
*                       string.                                             *
*                                                                           *
* Exit Condition:       The string of characters sent to through the SCI.   *
*                                                                           *
* Register(s) Changed:  Register X points to the end of the string plus 1.  *
*---------------------------------------------------------------------------*
OutString       psha
OutStringLoop   ldaa    ,x              Load character into accumulator A.
                beq     OutStringEnd    Branch if Null character.
                jsr     OutChar
                inx                     Next character.
                bra     OutStringLoop
OutStringEnd    inx
                pula
                rts
OutString2      jsr     OutString       Send string through SCI
                jsr     NewLine         Send CR+NL through SCI
                rts
OutString3      jsr     NewLine         Send CR+NL through SCI
                jsr     OutString2      Send string through SCI
                rts
OutString4      jsr     NewLine         Send CR+NL through SCI
                jsr     OutString
                rts

*****************************************************************************
* NewLine()                                                                 *
*****************************************************************************
* Description:  Routine to send a carriage return and line feed code through* 
*               the SCI.                                                    *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       Host performs a carriage return and line feed.      *
*                                                                           *
* Register(s) Changed:  None                                                *
*---------------------------------------------------------------------------*
NewLine         psha
                ldaa    #CR
                jsr     OutChar
                ldaa    #LF
                jsr     OutChar
                pula
                rts

*****************************************************************************
* SkipSpace (x : Pointer)                                                   *
*****************************************************************************
* Description:  Routine to move the character pointer (register x) through  *
*               the a string of characters until a non space ($20) character*
*               is reached.  If a carriage return is reached, the Z bit in  *
*               the CCR is set.                                             *
*                                                                           *
* Entry Condition:      Register x contains the address of the string.      *
*                                                                           *
* Exit Condition:       Register x contains the address of a non space      *
*                       character within the string.  The Z bit in the CCR  *
*                       is set if a carriage return character is reached.   *
*                                                                           *
* Register(s) Changed:  None.                                               *
*---------------------------------------------------------------------------*
SkipSpace       psha
SkipSpaceLoop   ldaa    ,x
                cmpa    #Space
                bne     SkipSpaceEnd    Branch if not space ($20)
                inx
                bra     SkipSpaceLoop
SkipSpaceEnd    cmpa    #CR             Carriage return?
                pula
                rts
*****************************************************************************
* NextWord (x : Pointer)                                                    *
*****************************************************************************
* Description:  Routine to move the word pointer (register x) to the next   *
*               word.  The next word is determine if a character is followed*
*               after a space. If a carriage return is reached, the Z bit in*
*               the CCR is set.                                             *
*                                                                           *
* Entry Condition:      Register x contains the address of the string.      *
*                                                                           *
* Exit Condition:       Register x contains the address of a the next word  *
*                       within the string.  The Z bit in the CCR            *
*                       is set if a carriage return character is reached.   *
*                                                                           *
* Register(s) Changed:  None.                                               *
*---------------------------------------------------------------------------*
NextWord        psha
NextWordLoop    ldaa    ,x
                cmpa    #Space
                beq     NextWordStart   Searching of a space character.
                cmpa    #CR
                beq     NextWordStart
                inx                     Increment to next character.
                bra     NextWordLoop
NextWordStart   jsr     SkipSpace       Point to next word.
                pula
                rts

*****************************************************************************
* FindNull (y: Pointer)                                                     *
*****************************************************************************
* Description:  Routine to find a Null character pointed by register y.     *
*               The register y will increment to the next character if it   *
*               can't find a Null character.  However, if it finds a EOT    *
*               character the routine will terminate and an 'Error' flag is *
*               set.                                                        *
*                                                                           *
* Entry Condition:      Register y pointing to a Null terminated string.    *
*                                                                           *
* Exit Condition:       Register y points to the Null character.            *
*                       Variable Error is set if a EOT character is reached.*
*                                                                           *
* Register(s) Changed:  None.                                               *
*---------------------------------------------------------------------------*
FindNull        psha
FindNullLoop    ldaa    ,y
                cmpa    #EOT
                beq     FoundEOT        Branch if EOT character
                cmpa    #Null
                beq     FindNullEnd     Branch if Null character
                iny                     Next character
                bra     FindNullLoop
FindNullEnd     pula
                rts
FoundEOT        inc     Error           Set error flag
                pula
                rts

*****************************************************************************
* NextCom                                                                   *
*****************************************************************************
* Description:  Routine to increment the pointer (register y) to the next   *
*               command string in the command table.  If the end of table,  *
*               is reached the Z bit in the CCR is cleared.  Otherwise set. *
*                                                                           *
* Entry Condition:      Register y is pointing to the command string in the *
*                       command table.                                      *
*                                                                           *
* Exit Condition:       Register y points to the next command string in the *
*                       command table.  If end of table is reached, the     *
*                       Z-bit in the CCR is cleared.  Otherwise is set.     *
*                                                                           *
* Register(s) Changed:  The value in register y.                            *
*---------------------------------------------------------------------------*
NextCom         pshb
                ldab    #3
                clr     Error
                jsr     FindNull
                tst     Error
                bne     NextComEnd      Branch if EOT
                aby
NextComEnd      pulb
                rts

*****************************************************************************
* Get2HexBin                                                                *
*****************************************************************************
* Description:  Routine to extract two hex characters pointed by Ptr and    *
*               convert it to its binary equivalent.                        *
*               example,  Hex characters -> 2A                              *
*                         binary equivalent -> 00101010                     *
*                                                                           *
* Entry Condition:      Memory location pointed by 'Ptr' contains the       *
*                       address of the first hex characters to be converted.*
*                                                                           *
* Exit Condition:       Register A contains the binary equivalent of the    *
*                       two hex characters.  If the characters are not in   *
*                       the range of 0..9,A..F the error flag 'Flag'        *
*                       will be set.  Otherwise is cleared.                 *
*                                                                           *
* Register(s) Changed:  Register A and B                                    *
*---------------------------------------------------------------------------*
Get2HexBin      pshx
                clr     Counter         Clear Hex counter
                ldx     Ptr             Point to first hex character
                ldaa    ,x
                jsr     UpCase          
                inc     Counter         Increment hex counter
                inx                     Point to next hex character
                psha
                ldaa    ,x
                jsr     UpCase
                tab
                pula
                inc     Counter         Increment hex counter
                inx                     Point to next hex character
                stx     Ptr
                jsr     TwoHex2Bin      Convert to binary
                tst     Flag            
                bne     Get2HexBinEnd   Branch if conversion error
                ldab    ,x
                cmpb    #Space
                beq     Get2HexBinEnd
                cmpb    #CR
                beq     Get2HexBinEnd
                inc     Counter         Increment hex counter
Get2HexBinEnd   pulx
                rts

*****************************************************************************
* Get4HexBin                                                                *
*****************************************************************************
* Description:  Routine to extract four hex characters pointed by Ptr and   *
*               convert it to its binary equivalent.                        *
*               example,  Hex characters -> 2A8F                            *
*                         binary equivalent -> 00101010 10001111            *
*                                                                           *
* Entry Condition:      Memory location pointed by 'Ptr' contains the       *
*                       address of the first hex characters to be converted.*
*                                                                           *
* Exit Condition:       Register A contains the binary equivalent of the    *
*                       first two hex characters.                           *
*                       Register B contains the binary equivalent of the    *
*                       last two hex characters.                            *
*                       If the characters are not in the range of 0..9,A..F *
*                       the error flag 'Flag' will be set.  Otherwise is    *
*                       cleared.                                            *
*                                                                           *
* Register(s) Changed:  Register A and B                                    *
*---------------------------------------------------------------------------*
Get4HexBin      pshx
                jsr     Get2HexBin      Convert first two hex characters to 
*                                       binary.
                tst     Flag
                bne     Get4HexBinError Branch if conversion error.
                ldab    Counter
                cmpb    #3
                bne     Get4HexBinError Branch if no more hex character.
                psha
                jsr     Get2HexBin      Convert last two hex characters to
*                                       binary.
                tab
                pula
                tst     Flag
                bne     Get4HexBinError Branch if conversion error.
                psha
                ldaa    Counter
                cmpa    #3
                pula   
                bne     Get4HexBinEnd   Branch if no more character.
Get4HexBinError inc     Flag            Set error flag.
Get4HexBinEnd   pulx
                rts

*****************************************************************************
* Hex2Bin                                                                   *
*****************************************************************************
* Description:  Routine to convert an ASCII hex character to binary.  The   *
*               variable 'Flag' is set if an invalid hex character is       *
*               encounter.  Otherwise is cleared.                           *
*                                                                           *
* Entry Condition:      Accumulator A contains an ASCII hex character.      *
*                                                                           *
* Exit Condition:       Accumulator A the binary equivalent of the hex      *
*                       character.  Flag is set if encounter an invalid hex.*
*                       Otherwise is cleared.                               *
*                                                                           *
* Register(s) Changed:  Accumulator A                                       *
*---------------------------------------------------------------------------*
Hex2Bin         clr     Flag            Clear Flag
                cmpa    #'0'
                blo     Hex2BinError    Branch if lower
                cmpa    #'9'
                bls     UnderA          Branch if in '0'..'9'
                cmpa    #'F'
                bhi     Hex2BinError    Branch if higher
                suba    #7              
UnderA          suba    #'0'
                clc
                rts
Hex2BinError    inc     Flag            Set Flag
                sec
                rts

*****************************************************************************
* TwoHex2Bin                                                                *
*****************************************************************************
* Description:  Routine to convert a two ASCII hex character stored in      *
*               accumulator D to binary.  If an error occurs, the variable  *
*               Flag is set.  Otherwise is cleared.                         *
*                                                                           *
* Entry Condition:      Accumulator D contains the hex character.           *
*                                                                           *
* Exit Condition:       Accumulator A contains the binary equivalent of the *
*                       hex characters.                                     *
*                       If error, Flag is set.  Otherwise is cleared.       *
*                                                                           *
* Register(s) Changed:  Register A and B.                                   *
*---------------------------------------------------------------------------*
TwoHex2Bin      jsr     Hex2Bin         Convert first character.
                tst     Flag
                bne     HexError        Branch if conversion error.
                lsla
                lsla
                lsla
                lsla
                sta     Temp            
                tba
                jsr     Hex2Bin         Convert second character.
                tst     Flag
                bne     HexError        Branch if conversion error.
                adda    Temp            Add the two character together.
                clc
                rts
HexError        sec
                rts

*****************************************************************************
* FourHex2TwoBin                                                            *
*****************************************************************************
* Description:  Routine to convert four ASCII hex character stored in       *
*               register x and y to two binary number.  If an error occurs, *
*               the variable Flag is set.  Otherwise is cleared.            *
*                                                                           *
* Entry Condition:      Register X contains the first two hex characters.   *
*                       Register Y contains the last two hex characters.    *
*                                                                           *
* Exit Condition:       Accumulator D contains the binary equivalent of the *
*                       hex characters.                                     *
*                       If error, Flag is set.  Otherwise is cleared.       *
*                                                                           *
* Register(s) Changed:  Register A and B.                                   *
*---------------------------------------------------------------------------*
FourHex2TwoBin  xgdy
                jsr     TwoHex2Bin      Convert the last two hex character.
                tst     Flag
                bne     FourHexEnd      Branch if conversion error.
                tab     
                pshb
                xgdx
                jsr     TwoHex2Bin      Convert the first two hex character.
                pulb    
FourHexEnd      rts

*****************************************************************************
* ReadByte                                                                  *
*****************************************************************************
* Description:  Routine to read two ASCII hex from the SCI and convert it to*
*               its binary equivalent.  If and error occurs, the 'Flag'     *
*               variable is set.  Otherwise is cleared.                     *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       Accumulator A contains the binary equivalent of the *
*                       two hex characters.                                 *
*                                                                           *
* Register(s) Changed:  Accumulator A and B.                                *
*---------------------------------------------------------------------------*
ReadByte        jsr     GetChar         Get first character.
                psha
                jsr     GetChar         Get second character.
                tab
                pula
                jsr     TwoHex2Bin      Convert the two characters.
                rts

*****************************************************************************
* Read2Byte                                                                 *
*****************************************************************************
* Description:  Routine to read four ASCII hex from the SCI and convert it  *
*               to its binary equivalent.  If and error occurs, the 'Flag'  *
*               variable is set.  Otherwise is cleared.                     *
*                                                                           *
* Entry Condition:      None                                                *
*                                                                           *
* Exit Condition:       Accumulator D contains the binary equivalent of the *
*                       four hex characters.                                *
*                                                                           *
* Register(s) Changed:  Accumulator A and B.                                *
*---------------------------------------------------------------------------*
Read2Byte       jsr     ReadByte        Get binary equivalent of the first
*                                       two characters.
                psha
                jsr     ReadByte        Get binary equivalent of the last
*                                       two characters.
                tab
                pula
                rts

*****************************************************************************
* FourBin2Hex                                                               *
*****************************************************************************
* Description:  Routine to convert a 4-bit binary number to an ASCII hex    *
*               character.                                                  *
*                                                                           *
* Entry Condition:      Accumulator A contains a 4-bit binary number to be  *
*                       converted.                                          *
*                                                                           *
* Exit Condition:       Accumulator A contains a 8-bit ASCII hex character. *
*                                                                           *
* Register(s) Changed:  Accumulator A.                                      *
*---------------------------------------------------------------------------*
FourBin2Hex     anda    #$0F            Mask out the higher 4 bit.
                oraa    #$30            Convert to ASCII character.
                cmpa    #$39
                bls     BinHexEnd       If ASCII character is not within
*                                          A..F then branch.
                adda    #$07            Else need an adjustment of 7. 
BinHexEnd       rts

*****************************************************************************
* EightBin2Hex                                                              *
*****************************************************************************
* Description:  Routine to convert an 8-bit binary number to an ASCII hex   *
*               character.                                                  *
*                                                                           *
* Entry Condition:      Accumulator A contains a 8-bit binary number to be  *
*                       converted.                                          *
*                                                                           *
* Exit Condition:       Accumulator D contains the ASCII hex character of   *
*                       the 8-bit binary number.                            *
*                                                                           *
* Register(s) Changed:  Accumulator A & B                                   *
*---------------------------------------------------------------------------*
EightBin2Hex    psha
                jsr     FourBin2Hex     Convert lower four bits.
                tab
                pula
                lsra
                lsra
                lsra
                lsra
                jsr     FourBin2Hex     Convert upper four bits.
                rts

*****************************************************************************
* Out8Bin2Hex                                                               *
*****************************************************************************
* Description:  Routine to send an 8-bit binary number to the host.         *
*                                                                           *
* Entry Condition:      Accumulator A contains the binary number to be sent *
*                       to the host.                                        *
*                                                                           *
* Exit Condition:       The 8-bit binary number got converted to 2 byte     *
*                       ASCII hex character and got sent to the host.       *
*                                                                           *
* Register(s) Changed:  None.                                               *
*---------------------------------------------------------------------------*
Out8Bin2Hex     psha
                pshb
                jsr     EightBin2Hex
                jsr     OutChar       Display the higher 4 bit binary number.
                tba    
                jsr     OutChar       Display the lower 4 bit binary number.
                pulb
                pula
                rts

*****************************************************************************
* Out16Bin2Hex                                                              *
*****************************************************************************
* Description:  Routine to send a 16-bit binary number to the host.         *
*                                                                           *
* Entry Condition:      Accumulator D contains the binary number to be sent *
*                       to the host.                                        *
*                                                                           *
* Exit Condition:       The 16-bit binary number got converted to 4 byte    *
*                       ASCII hex character and got sent to the host.       *
*                                                                           *
* Register(s) Changed:  Accumulator D.                                      *
*---------------------------------------------------------------------------*
Out16Bin2Hex    pshb
                jsr     Out8Bin2Hex     Output the higher 8 bits.
                pula
                jsr     Out8Bin2Hex     Output the lower 8 bits.
                rts

*****************************************************************************
* UpCase(a:char)                                                            *
*****************************************************************************
* Description:  Routine to conver the hex value in accumulator to its upper *
*               case value.                                                 *
*                                                                           *
* Entry Condition:      Accumulator A contains the ASCII hex character.     *
*                                                                           *
* Exit Condition:       Accumulator A contains the upper case value of a    *
*                       lower case ASCII hex character.                     *
*                                                                           *
* Register(s) Changed:  Register A                                          *
*---------------------------------------------------------------------------*
UpCase          cmpa    #'a'
                blt     UpCase1         Branch if < 'a'.
                cmpa    #'z'
                bgt     UpCase1         Branch if > 'z'.
                suba    #$20            Convert to upper case.
UpCase1         rts

*****************************************************************************
* BadArgument                                                               *
*****************************************************************************
* Description:  Routine to display the string 'Bad Argument' on the host    *
*               terminal.                                                   *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       Message sent to host.                               *
*                                                                           *
* Register(s) Changed:  Register X                                          *
*---------------------------------------------------------------------------*
BadArgument     ldx     #MSG7           'Bad Argument'
                jsr     OutString3
                rts

*****************************************************************************
* Command Table used by the Monitor program.                                *
*****************************************************************************
* Description:  This is a look up table used by the Monitor Program.  In    *
*               this look up table, the address location of the routine is  *
*               given after the Null character.  The string given in front  *
*               of the Null character is used by the monitor program to     *
*               search for the command.  The end of the look up table is    *
*               determined by the EOT character.                            *
*                                                                           *
* Table format:                                                             *
*               String                                                      *
*               Null character                                              *
*               Memory location of routine                                  *
*               .                                                           *
*               .                                                           *
*               String                                                      *
*               Null character                                              *
*               Memory location of routine                                  *
*               EOT                                                         *
*---------------------------------------------------------------------------*
ComTable        fcc     'BREAK'                
                fcb     Null
                fdb     #Break

                fcc     'CALL'
                fcb     Null
                fdb     #Call

                fcc     'FILL'
                fcb     Null
                fdb     #Fill

                fcc     'GO'
                fcb     Null
                fdb     #Go

                fcc     'HELP'
                fcb     Null
                fdb     #Help

                fcc     '?'
                fcb     Null
                fdb     #Help
                
                fcc     'LOAD'
                fcb     Null
                fdb     #Load

                fcc     'MD'
                fcb     Null
                fdb     #MD

                fcc     'PB'
                fcb     Null
                fdb     #PB

                fcc     'REG'
                fcb     Null
                fdb     #Reg

SingleStep      fcc     'SS'
                fcb     Null
                fdb     #SS

SingleStep2     fcc     'S2'
                fcb     Null
                fdb     #SS2

                fcb     EOT

*****************************************************************************
* Load(Ptr)                                                                 *
*****************************************************************************
* Usage:  Load <cr>          <-- loads the S-records from the host.         *
*                                                                           *
*         Load [+/-]<NUM> <cr>   <-- loads the S-records and offset it with *
*                                    the value specified by <NUM>.          *
*                                                                           *
*         where <NUM> is any two byte hex number.                           *
*...........................................................................*
* Description:  Routine to load an S-record from the host to the specified  *
*               memory location of the target system.  The routine will     *
*               continuously read from the SCI until a valid S-record is    *
*               found.  The S-record must end with S9.  If not, it will     *
*               assume that more S-record is coming.  At the end of each    *
*               line of S-record is sent, a checksum is performed.  If the  *
*               resulting checksum does not equal FF, then the routine will *
*               send an error message to the host.                          *
*                                                                           *
* Entry Condition:      Variable Ptr points to the argument in St_Buffer.   *
*                                                                           *
* Exit Condition:       S-record load to target memory.                     *
*                                                                           *
* Register(s) Changed:  Accumulator A,B                                     *
*                       Register X,Y                                        *
*---------------------------------------------------------------------------*
Load            ldx     Ptr
                clrb
                clr     Ok
                clr     OffSet
                clr     OffSet+1        Initialize offset variable no offset.
                jsr     SkipSpace
                beq     NoArgument      Branch if no argument.
                ldaa    ,x
                cmpa    #'-'
                beq     MinusOffSet     Branch if '-'
                cmpa    #'+'
                beq     PlusOffSet      Branch if '+'
                jmp     BadArgument   
MinusOffSet     incb                    Flag to indicate minus offset.
PlusOffSet      inx
                jsr     SkipSpace       
                bne     NoLoadError1    Branch if there is an argument.
                jmp     BadArgument     Oops.  Invalid argument.
NoLoadError1    stx     Ptr
                pshb
                jsr     Get4HexBin      Get offset
                std     OffSet
                pulb
                tst     Flag
                beq     NoLoadError2    Branch if no invalid argument.
                jmp     BadArgument     Oops.  Invalid argument.
NoLoadError2    tstb
                beq     NoArgument      Branch if it is a positive offset.
                ldd     #$0000
                subd    OffSet
                std     OffSet          Make offset negative.
NoArgument      jsr     NewLine
                clr     Error
LoadLoop1       jsr     GetChar
                cmpa    #'S'
                bne     LoadLoop1       Branch if not S-record.
                jsr     GetChar
                cmpa    #'9'            
                beq     LoadS9          Branch if S9-record.
                cmpa    #'1'
                bne     LoadLoop1       Branch if not S1-record.
                clr     CheckSum
                jsr     ReadByte        Read the number of data bytes.
                staa    CheckSum        Add number to checksum.
                suba    #2
                tab     
                pshb
                jsr     Read2Byte       Read the address.
                psha
                aba
                adda    CheckSum
                staa    CheckSum        Update checksum
                pula
                addd    OffSet
                xgdx                    Offset memory pointer.
                pulb
                dex
LoadData        pshb
                jsr     ReadByte        Read data.
                pulb
                psha
                adda    CheckSum
                staa    CheckSum        Update checksum.
                pula
                decb
                beq     TestCheckSum    Branch if end of line.
                inx                     Increment memory pointer.
                sta     ,x              Store data to memory.
                sta     Temp
                ldaa    ,x
                cmpa    Temp            Check if written correctly.
                beq     LoadData
                tst     Error
                bne     LoadData
                stx     Temp2
                inc     Error           Not written correctly.  Must of 
*                                       written into a ROM area.
                bra     LoadData
LoadS9          jsr     ReadByte        Read the number of data bytes.
LoadS9Loop      psha
                jsr     ReadByte        Read data.
                pula
                deca
                bne     LoadS9Loop      Branch if not end of line.
                tst     Error
                beq     NoError
                ldx     #MSG11          'Memory Violation: '
                jsr     OutString
                jsr     Out2Space
                ldd     Temp2
                jsr     Out16Bin2Hex    Display the address where the memory
*                                       violation first occurs.
                jsr     NewLine
NoError         ldx     #MSG5           'Transmit Complete'
                jsr     OutString2
LoadEnd         rts

TestCheckSum    inc     CheckSum        Increment checksum.
                bne     TestCheckSum1
                jmp     LoadLoop1       Branch if chechsum is 0
TestCheckSum1   tst     Ok
                beq     TestCheckSum2
                jmp     LoadLoop1       Branch if not the first checksum 
*                                       error.
TestCheckSum2   inc     Ok
                pshx
                ldx     #MSG6           'Warning: Checksum Error'
                jsr     OutString2
                pulx
                jmp     LoadLoop1

*****************************************************************************
* Break                                                                     *
*****************************************************************************
* Usage:    Break <cr>           <----  Display breakpoint table.           *
*                                                                           *
*           Break <address> <cr> <----  Set/clear breakpoint specified by   *
*                                       <address>.  Also, display breakpoint*
*                                       table.                              *
*                                                                           *
*       where <address> is a 2 byte hex address.                            *
*...........................................................................*
* Description:  Routine to set or clear the breakpoint table and display    *
*               it to the host's monitor.  If no argument is given, then    *
*               only the breakpoint table is displayed.  The number of      *
*               breakpoints available is defined by MaxBreak.  If attempt   *
*               to add another breakpoint when the breakpoint table is full,* 
*               the new breakpoint will be ignored.  The format of the      *
*               breakpoint table is as follow,                              *
*                                                                           *
*               BreakTable      <address>                                   *
*                               <data>                                      *
*                               <address>                                   *
*                               <data>                                      *
*                               <address>                                   *
*                               <data>                                      *
*                               <address>                                   *
*                               <data>                                      *
*                                                                           *
*               where <address> is the location in memory to place the      *
*                               breakpoint.                                 *
*                     <data>    is the value stored in <address>.           *
*                                                                           *
* Entry Condition:      Variable Ptr points to the argument in St_Buffer.   *
*                                                                           *
* Exit Condition:       Breakpoint table modified and sent through the SCI  *
*                                                                           *
* Register(s) Changed:  Accumulators A,B                                    *
*                       Registers X,Y                                       *
*---------------------------------------------------------------------------*
Break           ldx     Ptr             
                jsr     SkipSpace
                beq     ShowTable       Branch if no argument.
                stx     Ptr
                jsr     Get4HexBin      Get argument (4 hex number)
                tst     Flag            
                beq     NoBreakError    Branch if valid argument.
                jmp     BadArgument     Oops, invalid argument.
NoBreakError    xgdy                    
                ldx     #BreakTable     Locate the top of breakpoint table.
                ldaa    #MaxBreak
BreakLoop       beq     NoBreak         Branch if end of breakpoint table.
                cpy     ,x
                beq     FoundBreak      Branch if break address already
*                                       exists.
                ldab    #3
                abx                     Point to next breakpoint entry.
                deca
                bra     BreakLoop

NoBreak         ldx     #BreakTable     Locate the top of breakpoint table.
                ldaa    #MaxBreak
BreakLoop2      beq     BreakFull       Branch if end of breakpoint table.
                psha
                ldd     ,x
                cpd     #$FFFF
                pula
                beq     FoundEmpty      Branch if found an empty slot ($FFFF) 
*                                       in the breakpoint table
                ldab    #3
                abx                     Point to next breakpoint entry.
                deca
                bra     BreakLoop2
FoundEmpty      sty     ,x              Store argument (<address>) into table
                bra     BreakEnd
BreakFull       ldx     #MSG8           'Break Table Full'
                jsr     OutString3
                bra     BreakEnd
FoundBreak      ldd     #$FFFF
                std     ,x              Clear breakpoint specified by argument
                ldx     #MSG9           'Breakpoint removed'
                jsr     OutString3
                bra     BreakEnd
BreakEnd        Nop
* Display break point table.
ShowTable       ldx     #MSG10          'Breakpoint Table'
                jsr     OutString3
                ldx     #BreakTable     X points to top of breakpoint table.
                ldaa    #MaxBreak
ShowLoop        beq     EndShow         Branch if end of table.
                psha
                ldd     ,x
                cpd     #$FFFF
                beq     Empty           Branch if empty slot.
                jsr     Out16Bin2Hex    Output the breakpoint address.
                jsr     NewLine
Empty           ldab    #3
                abx                     Point to next breakpoint.
                pula
                deca
                bra     ShowLoop
EndShow         rts

*****************************************************************************
* Fill                                                                      *
*****************************************************************************
* Usage:   Fill <addr1>                  <- Content specified by <addr1>    *
*                                           gets replace by previous <data> * 
*          Fill <addr1> <data>           <- Content specified by <addr1>    *
*                                           gets replace by <data>          *
*          Fill <addr1> <addr2>          <- Contents bounded by <addr1> to  *
*                                           <addr2> gets replace by previous*
*                                           <data>                          *
*          Fill <addr1> <addr2> <data>   <- Contents bounded by <addr1> to  *
*                                           <addr2> gets                    *
*                                                                           *
*       where <addr1>, <addr2> - memory location (four ascii hex characters)*
*             <data>           - value to replace with (two ascii hex       *
*                                                       characters)         *
*...........................................................................*
* Description:  Routine to modify the content in the specified memory       *
*               location.  If two address argument is given, then a block   *
*               of memory content from <addr1> to <addr2> will be replace   *
*               by <value> or from the previous used value.  Otherwise, if  *
*               one address is given as an argument, only that address      *
*               content is modify.  The main fill routine uses two smaller  *
*               routine, "ByteFill" and "BlockFill".  This routine calls the*
*               other two routine by performing a 'jmp'.  This is not a     *
*               practical way of calling the routine, but it eliminate the  *
*               extra branching.                                            *
*                                                                           *
* Entry Condition:      Ptr pointing to the start of the argument stored in *
*                       memory.                                             *
*                                                                           *
* Exit Condition:       Ptr pointing to the end of the argument.            *
*                       Memory content specified by <addr1> to <addr2> got  *
*                       replaced by a valid hex <value>                     *
*                                                                           *
* Register changed:     All register value is changed.                      *
*---------------------------------------------------------------------------*
Fill            ldx     Ptr             
                jsr     SkipSpace
                bne     CheckArgument   Branch if valid argument.
                jmp     BadArgument     Invalid argument.
CheckArgument   stx     Ptr
                jsr     Get4HexBin      Get first memory address.
                tst     Flag
                beq     Continue1       Branch if valid hex address.
                jmp     BadArgument
Continue1       std     Temp2
                ldx     Ptr
                jsr     SkipSpace
                bne     MoreArgument    Branch if more argument.
                ldx     Temp2
                ldaa    FillValue       Load value to be fill in ACC. A
                jmp     ByteFill        Fill one address location.
MoreArgument    stx     Ptr
                stx     Temp3
                jsr     Get4HexBin      Get second memory address.
                tst     Flag
                beq     GetData1        Branch if valid hex.
                ldx     Temp3
                stx     Ptr             Point back to start of second
*                                       argument.
                ldd     Temp2
GetData1        std     Temp3
                ldx     Ptr
                jsr     SkipSpace
                beq     NoDataValue     Branch if no more argument.
                stx     Ptr
                jsr     Get2HexBin      Get data.
                tst     Flag
                beq     Continue2       Branch if valid data.
                jmp     BadArgument
Continue2       ldab    Counter
                cmpb    #3
                bne     Continue3       Branch if only 2 hex number.
                jmp     BadArgument
Continue3       staa    FillValue       Store <data> to FillValue.
NoDataValue     ldx     Temp2           X points to <addr1>
                ldy     Temp3           Y points to <addr2>
                jmp     BlockFill

*****************************************************************************
* BlockFill                                                                 *
*****************************************************************************
* Description:  Routine to fill a block of memory location with the value   *
*               in accumulator A.  The memory block is specified by the     *
*               registers X and Y.  The fill routine terminates if the value* 
*               in register Y is greater than the value in register X.      *
*                                                                           *
* Entry Condition:      Accumulator A contains the value to be fill.        *
*                       Register X points to the start of the block.        *
*                       Register Y points to the end of the block.          *
*                                                                           *
* Exit Condition:       Register X points to the end of the block.          *
*                       The value in the other registers does not change.   *
*                                                                           *
* Register Charged:     Register X                                          *
*---------------------------------------------------------------------------*
BlockFill       ldaa    FillValue
                sty     Temp2
BlockFillLoop   cpx     Temp2
                bhi     EndBlockFill    Branch if end of block.
                jsr     ByteFill
                inx
                bra     BlockFillLoop
EndBlockFill    rts

*****************************************************************************
* ByteFill                                                                  *
*****************************************************************************
* Description:  Routine to fill a memory location with the value in         *
*               accumulator A.  The memory to be fill is specified by the   *
*               register X.                                                 *
*                                                                           *
* Entry Condition:      Accumulator A contains the value to be fill.        *
*                       Register X points to the start of the block.        *
*                                                                           *
* Exit Condition:       Content in accumulator A is stored in memory        *
*                       location pointed by register X.                     *
*                                                                           *
* Register Changed:     None.                                               *
*---------------------------------------------------------------------------*
ByteFill        staa    ,x
                rts

*****************************************************************************
* Reg                                                                       *
*****************************************************************************
* Usage :   Reg                              <- Display User Registers      *
*           Reg <User Register> <data>       <- Replace the content         *
*                                               of the User Register        *
*                                               with the new value <data>   *
*                                                                           *
*       where <User Register> - X            <- X register                  *
*                               Y            <- Y register                  *
*                               A            <- A accumulator               *
*                               B            <- B accumulator               *
*                               C            <- CCR                         *
*                               S            <- SP                          *
*                               P            <- PC                          *
*             <data> - is a 1 byte or 2 byte hex value.                     *
*                      (depends on the <User Register> specified.)          *    
*...........................................................................*
* Description:  Routine to display and alter the content of the user        *
*               registers.  Bad argument occurs when a 2 byte data is given *
*               to a 1 byte register, or vice versa.                        *
*                                                                           *    
* Entry Condition:      Ptr pointing to the start of the argument stored in *
*                       memory.                                             *
*                                                                           *
* Exit Condition:       If there is no invalid argument then, the content   *
*                       of the user registers is either modified or not     *
*                       (depending on the choice of argument).  The whole   *
*                       list of user register is also sent to the terminal  *
*                       of the host.                                        *
*                                                                           *
* Register Changed:     All registers and accumulators.                     *
*---------------------------------------------------------------------------*
Reg             ldx     Ptr
                jsr     SkipSpace
                beq     DisplayReg      If no argument then display registers
                stx     Ptr
                jsr     GetReg          Get type of register.
                tst     Flag
                beq     ValidReg        Branch if valid register.
                jmp     BadArgument     Bad argument.  Terminate reg routine.
ValidReg        jsr     SkipSpace
                beq     DisplayReg      Branch if no data for register.
                stx     Ptr
                stab    Temp3
                cmpb    #SP_OffSet
                beq     Read4Hex        Branch, it is a 4 hex character.
                cmpb    #A_OffSet
                blo     Read4Hex        Branch, it is a 4 hex character.
                jsr     Get2HexBin      Need a two hex character.
                tst     Flag
                beq     Valid2Hex       Branch if valid argument.
                jmp     BadArgument     Oops.  Invalid argument.
Valid2Hex       ldab    Temp3
                ldx     #UserRegs
                abx                     Point to user register.
                staa    ,x              Replace old value with new value.
                bra     DisplayReg
Read4Hex        jsr     Get4HexBin
                tst     Flag
                beq     Valid4Hex       Branch if it is a valid 4 character
*                                       hex.
                jmp     BadArgument     Oops.  Invalid argument.
Valid4Hex       pshb
                ldab    Temp3
                ldx     #UserRegs
                abx                     Point to user register.
                pulb
                std     ,x              Replace old value with new value.
DisplayReg      jsr     PrintReg
                rts

*****************************************************************************
* GetReg (Ptr)                                                              *
*****************************************************************************
* Description:  This routine is used by the routine 'Reg'.  It determines   *
*               the user register to be modified.  It checks for the first  *
*               letter in the argument string and compares it with its      *
*               constant.  If there is no match then the Flag is set.       *
*               Otherwise is cleared.                                       *
*                                                                           *
* Entry Condition:      Ptr pointing to the first character to the word.    *
*                                                                           *
* Exit Condition:       Accumulator B contains the offset to the user       *
*                       register.  The Flag is set if the first character   *
*                       is an invalid character.  Otherwise is clear.       *
*                                                                           *
* Register Changed:     Accumulator B.                                      *
*---------------------------------------------------------------------------*
GetReg          clr     Flag            Clear valid register flag.                                            
                clrb
                ldx     Ptr
                ldaa    ,x
                jsr     UpCase
AccA            cmpa    #'A'            Is it accumulator A?
                bne     AccB
                ldab    #A_OffSet
AccB            cmpa    #'B'            Is it accumulator B?
                bne     RegX
                ldab    #B_OffSet
RegX            cmpa    #'X'            Is it register X?
                bne     RegY     
                ldab    #X_OffSet
RegY            cmpa    #'Y'            Is it register Y?
                bne     RegCCR
                ldab    #Y_OffSet
RegCCR          cmpa    #'C'            Is it CCR?
                bne     RegSP
                ldab    #CCR_OffSet
RegSP           cmpa    #'S'            Is it stack pointer?
                bne     RegPC
                ldab    #SP_OffSet
RegPC           cmpa    #'P'            How about program counter?
                bne     InvalidReg
                ldab    #PC_OffSet
                bra     EndGetReg
InvalidReg      tstb                    
                bne     EndGetReg
                inc     Flag            Oops.  It is not a register or
*                                       accumulator.
EndGetReg       jsr     NextWord
                stx     Ptr             Advance to next argument.
                rts

*****************************************************************************
* MD - Memory Dump                                                          *
*****************************************************************************
* Usage:        MD                    <- Performs a memory dump (128 bytes) *
*                                        starting at the PREVIOUS           *
*                                        <addr1>.                           *
*               MD <addr1>            <- Performs a memory dump (128 bytes) *
*                                        starting at <addr1>.               *
*               MD <addr1> <addr2>    <- Performs a memory dump starting at *
*                                        <addr1> to <addr2>.                *
*       where <addr1> and <addr2> are 2 bytes address. (4 ascii hex char.)  *
*...........................................................................*
* Description:  Routine to display the content of the specified memory      *
*               location.  If no starting address is specified, it will     *
*               display the first 128 bytes starting at the previous        *
*               address specified.  If two address is specified, the block  *
*               of memory bounded by <addr1> to <addr2> will be displayed.  *
*               If the value of <addr1> is greater than the value of        *
*               <addr2>, the values of the two address will be swapped.     *
*                                                                           *
* Entry Condition:      Ptr pointing to the start of the argument.          *
*                                                                           *
* Exit Condition:       128 bytes of memory or block of memory bounded by   *
*                       <addr1> to <addr2> is sent to the host terminal     *
*                                                                           *
* Register Changed:     All registers and accumulators.                     *
*---------------------------------------------------------------------------*
MD              jsr     NewLine
                ldx     Ptr
                jsr     SkipSpace
                beq     MD1             Branch if no argument.
                stx     Ptr
                jsr     Get4HexBin      Get the first address argument.
                tst     Flag
                beq     SetUpStartAddr  Branch if valid argument (Flag = 0)
                jmp     BadArgument     Oops.  Invalid argument.
SetUpStartAddr  andb    #$F0
                std     MDAddr1         Mask out the lower four bit.
                ldx     Ptr
                jsr     SkipSpace
                beq     MD1             Branch if no more argument.
                stx     Ptr
                jsr     Get4HexBin      Get the ending address argument.
                tst     Flag
                beq     SetUpEndAddr    Branch if valid address (Flag = 0).
                jmp     BadArgument     Oops.  Invalid argument.
SetUpEndAddr    andb    #$F0            Mask out the lower four bit.
* Set the starting and ending address in order.
                cpd     MDAddr1
                bhi     MDAddrOK
                ldx     MDAddr1
                xgdx
                stx     MDAddr1
MDAddrOK        std     MDAddr2
                bra     MD2
* Calculate the ending address for one or no argument value.
MD1             ldx     MDAddr1
                ldab    #$80
                abx     
                stx     MDAddr2
* The core portion of memory dump.
MD2             ldx     MDAddr1
                jsr     DisplayHeader   Display header across the top.
                jsr     NewLine
MDLoop          stx     Temp2
                jsr     KeyPressed
                beq     NoKeyPressed
                cmpb    #CTRLC
                beq     EndMD           If the user pressed <ctrl-C> then
*                                       branch.
NoKeyPressed    xgdx
                jsr     Out16Bin2Hex    Output the address.
                jsr     Out2Space
                ldx     Temp2
                jsr     MDBytes         Output 16 bytes of memory content.
                jsr     Out2Space
                jsr     MDChar          Output the character representation
*                                       of the 16 bytes of memory content.
                jsr     NewLine
                cpx     #$FFF0
                beq     EndMD           Is it top of memory?  Is so, branch.
                cpx     MDAddr2
                beq     EndMD           Is it end of memory dump.  Is so 
*                                       branch.
                ldab    #$10
                abx                     Increment address by 16 bytes.
                bra     MDLoop
EndMD           rts

*****************************************************************************
* DisplayHeader()                                                           *
*****************************************************************************
* Description:  This routine is used by the MD routine.  It is used to      *
*               the header at the beginning of the memory dump.  This allows*
*               easy reading of the content in the memory.                  *
*                                                                           *
* Entry Condition:  None.                                                   *
*                                                                           *
* Exit Condition:   Hex value from 0 to F is sent to the host terminal      *
*                                                                           *
* Register(s) Changed:  Accumulator A.                                      *
*---------------------------------------------------------------------------*
DisplayHeader   ldaa    #6
                jsr     OutSpace        Output 6 space to the host terminal.
                ldaa    #$00            Set initial number to Zero.
DisplayHeaderL  jsr     Out8Bin2Hex     Output number to host terminal.
                jsr     Out1Space
                inca                    Increment number.
                cmpa    #$10
                bne     DisplayHeaderL  Sent $0F ? If not branch.
                rts

*****************************************************************************
* MDBytes (X:ptr)                                                           *
*****************************************************************************
* Description:  Routine to display the first 16 bytes of memory content to  *
*               the host terminal pointed by register X.                    *
*                                                                           *
* Entry Condition:  Register X points to the start of the 16 bytes of memory*
*                   to by display.                                          *
*                                                                           *
* Exit Condition:   The first 16 bytes of memory content pointed by X sent  *
*                   to the host.                                            *
*                                                                           *
* Register Changed:  Accumulator B.                                         *
*---------------------------------------------------------------------------*
MDBytes         pshx
                psha
                ldab    #$10
MDBytesLoop     ldaa    ,x
                jsr     Out8Bin2Hex     Display the memory content pointed
*                                       by X.
                jsr     Out1Space
                inx                     Increment to next memory location.
                decb
                bne     MDBytesLoop     If 16 bytes of memory had been display
*                                       then branch.
                pula
                pulx
                rts

*****************************************************************************
* MDChar
*****************************************************************************
* Description:  Routine to display the first 16 bytes of printable          *
*               character in memory to the host terminal pointed by         *
*               register X.                                                 *
*                                                                           *
* Entry Condition:  Register X points to the start of the 16 bytes of memory*
*                   to by display.                                          *
*                                                                           *
* Exit Condition:   The first 16 bytes of memory content pointed by X sent  *
*                   to the host.                                            *
*                                                                           *
* Register Changed:  Accumulator B.                                         *
*---------------------------------------------------------------------------*
MDChar          pshx
                psha
                ldab    #$10
MDCharLoop      ldaa    ,x
                cmpa    #Space
                bhs     Test1
                ldaa    #Space          Oops.  Not a printable character.
*                                       Replace it with a space.
Test1           cmpa    #'~'
                bls     PrintableChar
                ldaa    #Space          Oops.  Not a printable character.
*                                       Replace it with a space.
PrintableChar   jsr     OutChar
                inx                     Increment to next memory location.
                decb
                bne     MDCharLoop      16 bytes of memory displayed?  If not
*                                       branch.
                pula
                pulx
                rts

*****************************************************************************
* Call                                                                      *
*****************************************************************************
* Usage         Call          <-- Run test program starting at address      *
*                                 specified by user's program counter.      *
*               Call <Addr>   <-- Run test program starting at address      *
*                                 specified by <Addr>.                      *
*                                                                           *
*    where <Addr> is 2 byte ASCII hex value.                                *
*...........................................................................*
* Description:  Routine to run the test program in memory at full speed.    *
*               Note that this routine is different from the RUN routine.   *
*               In the RUN routine, termination of the test program is done *
*               by SWI.  However, in this routine the RTS and the SWI opcode*
*               will terminate the test program.  When the RTS is           *
*               encountered, control is handed back to the monitor program. *
*               The I bit in the condition code register is not affected.   *
*               If an interrupt occurs the interrupt will be served by the  *
*               user's interrupt service routine.                           *
*               The method of setting up the user's stack is the same as    *
*               the RUN routine.  The user's registers and accumulators are *
*               all pushed onto the stack before the call for RTI.  However,*
*               before any pushing is done, the address of the CALLRTS is   *
*               placed onto the user's stack first.  So, when RTS is        *
*               encountered the monitor can regain control.                 *
*               WARNING:  The interrupt vector for the SWI is used by this  *
*                         routine.  Any attempt to alter the vector by      *
*                         the test program will inhibit this monitor program*
*                         from regaining control after SWI.  Therefore, a   *
*                         reset is needed to restart the monitor program.   *
*                                                                           *
* Entry Condition:      Ptr is pointing to the first argument in memory.    *
*                                                                           *
* Exit Condition:       Termination of the user's test program.             *
*                                                                           *
* Register(s) Changed:  All registers and accumulators.                     *
*---------------------------------------------------------------------------*
Call            ldx     Ptr
                jsr     SkipSpace
                beq     Call1
                stx     Ptr
                jsr     Get4HexBin      Get address.
                tst     Flag
                beq     CallArgOk
                jmp     BadArgument     Invalid address
CallArgOk       std     UserRegs+PC_OffSet      Place address into user PC.
Call1           ldx     UserRegs+SP_OffSet
                ldd     #CallRTS
                dex
                std     ,x                      Place address of CallRTS 
*                                               routine into user stack.
                dex
                stx     UserRegs+SP_OffSet
                jsr     SetUpBreak              Setup breakpoints
                ldx     #SWI_ISR                
                jsr     SetUpSWI                Setup softvector for the 
*                                               SWI interrupt.
                jsr     RunUser                 Execute user program.
                rts

*****************************************************************************
* CALLRTS()                                                                 *
*****************************************************************************
* Description:  This routine is a portion of the CALL routine.  When the    *
*               opcode RTS is encountered in the running program, control   *
*               is handed to this routine.  The user's registers and        *
*               accumulators are all saved and printed to the host's        *
*               terminal.  However, the user program counter is not saved.  *
*                                                                           *
* Entry Condition:      Called by the RTS instruction.                      *
*                                                                           *
* Exit Condition:       User's registers and accumulators are all saved and *
*                       sent to the host computer.                          *
*                                                                           *
* Register(s) Changed:  All registers and accumulators.                     *
*---------------------------------------------------------------------------*
CallRTS         psha
                tpa
                staa    UserRegs+CCR_OffSet     Save CCR.
                pula
                staa    UserRegs+A_OffSet       Save acc. A.
                stb     UserRegs+B_OffSet       Save acc. B.
                sts     UserRegs+SP_OffSet      Save SP.
                ldx     Ptr
                txs                             Set Stack pointer to point
*                                               monitor stack area.
                jsr     RemoveBreak
                jsr     PrintReg
                rts

*****************************************************************************
* SS()                                                                      *
*****************************************************************************
* Usage:        SS              Performs single stepping starting at user   *
*                               program counter.                            *
*               SS <addr>       Performs single stepping starting at the    *
*                               address specified by <addr>.                *       
*                                                                           *
*       where <addr> is a 2 byte ASCII hex value                            *
*...........................................................................*
* Description:  Routine to single step through a test program in memory.    *
*               This routine uses the interrupt method to perform the       *
*               single stepping process.  It uses the output compare 5      *
*               of the M68HC11 processor.  The value of the output compare  *
*               is set in a way that the interrupt occurs after one         *
*               instruction.  After each instruction, the user registers    *
*               and accumulators are displayed to the host terminal.        *
*               WARNING:  The interrupt vectors for the SWI and the OC5 is  *
*                         used by this routine.  Any attempt in altering    *
*                         the content of these vectors by the running       *
*                         program will inhibit the monitor program from     *
*                         regaining control.  Therefore a reset in required *
*                         to restart the monitor program.                   *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       Termination of one instruction from the running     *
*                       program.                                            *
*                                                                           *
* Register Changed:     All registers and Accumulators.                     *
*                                                                           *
*---------------------------------------------------------------------------*
SS              ldx     Ptr
                jsr     SkipSpace
                beq     NoSSArgument
                stx     Ptr
                jsr     Get4HexBin      Get start address if any.
                tst     Flag
                beq     NoSSError       
                jmp     BadArgument     Invalid address.
NoSSError       std     UserRegs        Saves argument in user PC
NoSSArgument    jsr     SetUpSoftVector
                jsr     SetUpUserInt    Clear I bit in user CCR.
                jsr     SetUpTimer      Initialize the output compare of the
*                                       free running counter.
                jsr     RunUser
                rts

*****************************************************************************
* SeUpUserInt()                                                             *
*****************************************************************************
* Description:  Used by SS routine to clear the I bit in the User's         *
*               Condition Code Register to allow interrupt for the output   *
*               compare.                                                    *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       I bit in User's CCR is cleared.                     *
*                       If bit is already cleared, the Flag variable is set.*
*                       Otherwise is cleared.                               *
*                                                                           *
* Register(s) Changed:  Accumulator A.                                      *
*---------------------------------------------------------------------------*
SetUpUserInt    clr     Flag2                   Clear flag to indicate that
*                                               the I bit in user CCR is set.
                ldaa    UserRegs+CCR_OffSet
                bita    #%00010000
                bne     NotSet  
                inc     Flag2                   I bit in user CCR is already
*                                               set.
NotSet          anda    #%11101111
                staa    UserRegs+CCR_OffSet
                rts

*****************************************************************************
* SetUpSoftVector()                                                         *
*****************************************************************************
* Description:  Used by the SS routine to setup the interrupt vector for the*
*               output compare and the SWI.                                 *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       Address of the service routine for the output       *
*                       compare and the SWI is stored into their appropriate*
*                       location in the interrupt vector table.             *
*                                                                           *
* Register(s) Changed:  Register X and Accumulator A                        *
*---------------------------------------------------------------------------*
SetUpSoftVector ldaa    #$7E            JMP opcode.
                staa    JTOC5
                ldx     JTOC5+1
                stx     Temp2
                ldx     #SS_ISR         
                stx     JTOC5+1         Setup jmp vector for output compare 5
                ldx     #SS_ISR         
                jsr     SetUpSWI        Setup jmp vector for swi.
EndSoftVector   rts

*****************************************************************************
* SetUpTimer()                                                              *
*****************************************************************************
* Description:  Used by the SS routine to setup and enable the output       *
*               compare 5 to interrupt.  The value added to the output      *
*               compare register 5 is determined by adding all the cycles   *
*               required the execution of the program being run.  In this   *
*               case, it requires 126 cycles from the start of SetUpTimer   *
*               to the execution of the program being run.                  *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       Output Compare 5 is set to interrupt.               *
*                                                                           *
* Register(s) Changed:  Accumulators A and B.                               *
*---------------------------------------------------------------------------*
SetUpTimer      ldd     TCNT            
                addD    #126
                std     TOC5
                ldaa    #%00001000
                staa    TFLG1           Clear output compare 5 flag.
                staa    TMSK1           Enable interrupt from TOC5.
                rts

*****************************************************************************
* SS_ISR()                                                                  *
*****************************************************************************
* Description:  Interrupt Service Routine for the SS routine.  This routine *
*               is invoke by the interrupt from the output compare register *
*               5.  Control is handed back to the monitor program and all   *
*               user's registers and accumulators are saved and printed     *
*               to the host terminal.                                       *
*                                                                           *
* Entry Condition:      Interrupt from the Output Compare 5.                *
*                                                                           *
* Exit Condition:       Monitor program regains control.                    *
*                       User's registers and accumulators are saved and     *
*                       displayed to the host.                              *
*---------------------------------------------------------------------------*
SS_ISR          anda    #%11110111      
                staa    TMSK1           Inhibit output compare interrupt.
                ldaa    #%00001000      
                staa    TFLG1           Clear OC5F flag.
                tsx
                ldy     Ptr
                tys                     Set stack point to point to monitor
*                                       stack area.
                ldaa    TMSK1           
                ldd     Temp2
                std     JTOC5+1                 Restore vector for output 
*                                               compare 5.
                ldd     Temp
                std     JSWI+1                  Restore vector for swi.
                jsr     SaveUserStack
                ldd     UserRegs+PC_OffSet
                AddD    #1                      
                std     UserRegs+PC_OffSet      Locate the next opcode in
*                                               memory.
                tst     Flag2
                bne     PrintUserReg
                ldaa    UserRegs+CCR_OffSet     
                oraa    #%00010000              Restore I bit in user CCR.
                staa    UserRegs+CCR_OffSet
PrintUserReg    jsr     PrintReg
                rts

*****************************************************************************
* SS2()                                                                     *
*****************************************************************************
* Usage:        S2         <--  Performs single stepping starting at user   *
*                               program counter.                            *
*               S2 <addr>  <--  Performs single stepping starting at the    *
*                               address specified by <addr>.                *       
*                                                                           *
*       where <addr> is a 2 byte ASCII hex value.                           *
*...........................................................................*
* Description:  This routine performs a similar task as the SS routine.     *
*               Instead, this routine uses SWI breakpoints rather than      *
*               interrupt from the output compare.  The advantage of this   *
*               routine is that it allows the user to use all the output    *
*               compare.  If this routine is used to single step, all the   *
*               break points set by the user are inhibited.                 *
*                                                                           *
* Entry Condition:      Ptr points to the argument (in any).                *
*                                                                           *
* Exit Condition:       Termination of one instruction of the running       *
*                       program.                                            *
*                                                                           *
* Register(s) Change:   All registers and accumulators.                     *
*---------------------------------------------------------------------------*
SS2             ldx     Ptr
                jsr     SkipSpace
                beq     NoSS2Argument
                stx     Ptr
                jsr     Get4HexBin      Get starting address.
                tst     Flag
                beq     NoSS2Error
                jmp     BadArgument     Invalid address.
NoSS2Error      std     UserRegs        Saves address in user PC
NoSS2Argument   ldx     #SS2_ISR         
                jsr     SetUpSWI        Setup softvector to SS2_ISR.
                jsr     SetUpSS2Break   Setup SWI in the appropriate location.
                jsr     SWI_at_start    
                jsr     RunUser
                rts
                
*****************************************************************************
* SetUpSS2Break ()                                                          *
*****************************************************************************
* Description:  This routine is used by the SS2 routine.  It setup the      *
*               breakpoints at a specific location in memory defined by the *
*               addressing mode of the next opcode.                         *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       The opcode SWI is place in memory where only one    *
*                       instruction is allowed to execute.                  *
*                                                                           *
* Register(s) Changed:  All registers and accumulators.                     *
*---------------------------------------------------------------------------*
SetUpSS2Break   ldx     UserRegs+PC_OffSet
                jsr     RegY_Adjustment
                stx     Temp3                   Make a copy of the user PC.
                ldaa    ,x                      Opcode at user PC.
Not_Y           jsr     LinearBreakAddr         
                jsr     GetBranchBreak
                jsr     SetSS2Break             Place SWI in appropriate
*                                               location.
                rts

*****************************************************************************
* RegY_Adjustment()                                                         *
*****************************************************************************
* Description:  This routine is used by the SetUpSS2Break.  It increment    *
*               the value in X (user PC.) if the opcode pointed by X is a   *
*               y indexing opcode.  In the y indexing mode, there is an     *
*               extra byte at the beginning, say $18.  This enables the CPU *
*               to distinguish between x or y indexing mode.                *
*                                                                           *
* Entry Condition:      Register X contains the user PC value.              *
*                                                                           *
* Exit Condition:       If it is a y indexing mode the user PC in register  *
*                       x is incremented by 1.                              *
*                                                                           *
* Register(s) Changed:  All registers and accumulators.                     *
*---------------------------------------------------------------------------*
RegY_Adjustment psha    
                clr     Flag            Assume not y indexing mode.
                ldaa    ,x
                cmpa    #$18            Is it $18 ?
                beq     NeedAdjustment  
                cmpa    #$CD            Is it $CD ?
                beq     NeedAdjustment
                cmpa    #$1A            Is it $1A ?
                beq     NeedAdjustment
                bra     NoAdjustment    Not y indexing mode.
NeedAdjustment  inx
                inc     Flag            Ok, it is y indexing mode.
NoAdjustment    pula    
                rts

*****************************************************************************
* SS2_ISR()                                                                 *
*****************************************************************************
* Description:  This is the interrupt service routine used by the SS2       *
*               routine.  Control is handed back to the monitor program     *
*               after exiting this routine.                                 *
*               The user's registers and accumulators are saved and printed *
*               to the host terminal.                                       *
*                                                                           *
* Entry Condition:      Interrupt due to SWI.                               *
*                                                                           *
* Exit Condition:       Control is handed back to the monitor program.      *
*                       User's registers and accumulators are saved and     *
*                       printed to the host terminal.                       *
*---------------------------------------------------------------------------*
SS2_ISR         tsx
                ldy     Ptr
                tys                     Set stack pointer to monitor stack
*                                       area.
                ldd     Temp
                std     JSWI+1          Restore softvector.
                jsr     SaveUserStack
                jsr     RemoveSS2Break
                jsr     PrintReg
                rts

*****************************************************************************
* LinearBreakAddr()                                                         *
*****************************************************************************
* Description:  This routine is used by the SetUpSS2Break to determine      *
*               where to place the SWI.  This routine is not responsible    *
*               for any branching or jumping.  It is responsible for        *
*               locating the next opcode linearly down the program.         *
*               The way this routine knows how many byte to skip is         *
*               determined by the lookup tables.                            *
*                                                                           *
* Entry Condition:      Accumulator A contains the opcode of the current    *
*                       instruction.                                        *
*                                                                           *
* Exit Condition:       Address of the next instruction is placed into      *
*                       the breakpoint table.                               *
*                                                                           *
* Register(s) Changed:  All registers and accululators.                     *
*---------------------------------------------------------------------------*
LinearBreakAddr staa    Temp2           Saves a copy of the opcode in memory.    
                lsra
                lsra
                lsra
                lsra                    Mask Lower 4 bits
                psha
                ldx     #Higher4Bit     Use main lookup table.
                tab
                abx
                ldab    ,x              Get offset to next opcode address.
                pula
* Checking odd cases of opcode.
                cmpa    #$01
                bne     CheckNext
                ldy     #OffSetTable1   Use lookup table 1.
                jmp     AddressAdjust
CheckNext       cmpa    #$08
                bne     CheckNext2
                ldy     #OffSetTable8   Use lookup table 8.
                jmp     AddressAdjust
CheckNext2      ldy     #OffSetTableC   Use lookup table C.
                cmpa    #$0C
                beq     AddressAdjust
                jmp     EndGetLinear
AddressAdjust   ldaa    Temp2
                anda    #$0F
                staa    Temp2           Mask out higher 4 bit of opcode.
* Adjustment loop for odd cases of opcode.
AdjustLoop      ldaa    ,y
                cmpa    #$00
                beq     EndGetLinear
                cmpa    Temp2
                beq     FoundAdjustment
                iny
                iny
                bra     AdjustLoop
* Read Adjustment value for odd cases of opcode.
FoundAdjustment iny
                ldaa    ,y
                aba
                tab
* Save address value to breakpoint table.
EndGetLinear    ldx     UserRegs+PC_OffSet
                jsr     RegY_Adjustment
                abx     
                ldy     #SS2Break
                stx     ,y
                rts

*****************************************************************************
* GetBranchBreak()                                                          *
*****************************************************************************
* Description:  This routine is used by the SetUpSS2Break routine.  It      *
*               determines where to place the breakpoints for the jumping,  *
*               branching, RTS and RTI instruction.  When the address is    *
*               found, it stores it in the second entry of the breakpoint   *
*               table.                                                      *
*                                                                           *
* Entry Condition:      Registers X contains the user PC.                   *
*                                                                           *
* Exit Condition:       Predicted address is stored in the second entry     *
*                       of the breakpoint table.                            *
*                                                                           *
* Register(s) Changed:  All registers and accumulators.                     *
*---------------------------------------------------------------------------*
GetBranchBreak  ldx     Temp3
                ldaa    ,x
                jsr     CheckBranchOp   Checking Branch opcode.
                bcs     StoreAddress
                jsr     CheckJmpOpcode  Checking Jmp opcode.
                bcs     StoreAddress
                jsr     CheckRTSOpcode  Checking RTS opcode.
                bcs     StoreAddress
                jsr     CheckBrclrOp    Checking Brclr opcode.
                bcs     StoreAddress
                jsr     CheckBrsetOp    Checking Brset opcode.
                bcs     StoreAddress
                jsr     CheckJsrOpcode  Checking JSR opcode.
                bcs     StoreAddress
                jsr     CheckRtiOpcode  Checking RTI opcode.
                bcs     StoreAddress
                bra     EndBranchBreak
StoreAddress    ldy     #SS2Break
                stx     3,y             Save address in table.
EndBranchBreak  rts

*****************************************************************************
* CheckBranchOp()                                                           *
*****************************************************************************
* Description:  This routine is used by the GetBranchBreak routine.  It     *
*               is responsible for checking the branch opcode.  If a branch *
*               opcode is encountered, it will determine where it will      *
*               branch.                                                     *
*                                                                           *
* Entry Condition:      Accumulator A contains the current opcode.          *
*                                                                           *
* Exit Condition:       If a branch opcode is encountered, the predicted    *
*                       branch address is saved in register X.  The C-bit   *
*                       in the CCR is set.  Otherwise is cleared.           *
*                                                                           *
* Register(s) Changed:  Register X and accumulator A                        *
*---------------------------------------------------------------------------*
CheckBranchOp   cmpa    #$80            BSR opcode
                beq     BSR_Opcode      
                cmpa    #$20
                blo     NotBranchOpcode         If opcode is below $20 then
*                                               it is not a branch opcode.
                cmpa    #$2F
                bhi     NotBranchOpcode         If opcode is above $2F then
*                                               it is not a branch opcode.
BSR_Opcode      ldd     Temp3
                addb    1,x
                addb    #$02            
                xgdx                    Determining the branching address.
                sec
                bra     EndCheckBranch
NotBranchOpcode clc
EndCheckBranch  rts

*****************************************************************************
* CheckJmpOpcode()                                                          *
*****************************************************************************
* Description:  This routine is used by the GetBranchBreak routine.  It     *
*               is responsible for checking the jmp opcode.  If a jmp       *
*               opcode is encountered, it will determine where it will      *
*               jump.                                                       *
*                                                                           *
* Entry Condition:      Accumulator A contains the current opcode.          *
*                                                                           *
* Exit Condition:       If a jmp opcode is encountered, the predicted       *
*                       address is saved in register X.  The C-bit          *
*                       in the CCR is set.  Otherwise is cleared.           *
*                                                                           *
* Register(s) Changed:  Register X and accumulator A                        *
*---------------------------------------------------------------------------*
CheckJmpOpcode  cmpa    #$7E            Extended mode opcode.
                bne     CheckJmpIndex   If not extended mode, then check
*                                       index mode.
                ldx     1,x
                sec
                bra     EndCheckJmpOp
CheckJmpIndex   cmpa    #$6E            Index mode opcode.
                bne     NotJmpOpcode
                ldab    1,x
                tst     Flag
                bne     Y_Index
                ldx     UserRegs+X_OffSet       X indexing mode.
                bra     AdjustJmpAddr
Y_Index         ldx     UserRegs+Y_OffSet       Y indexing mode.
AdjustJmpAddr   abx
                sec
                bra     EndCheckJmpOp
NotJmpOpcode    clc
EndCheckJmpOp   rts

*****************************************************************************
* CheckRTSOpcode()                                                          *
*****************************************************************************
* Description:  This routine is used by the GetBranchBreak routine.  It     *
*               is responsible for checking the RTS opcode.  If the RTS     *
*               opcode is encountered, it will determine where it will      *
*               branch.                                                     *
*                                                                           *
* Entry Condition:      Accumulator A contains the current opcode.          *
*                                                                           *
* Exit Condition:       If the RTS opcode is encountered, the predicted     *
*                       return address is saved in register X.  The C-bit   *
*                       in the CCR is set.  Otherwise is cleared.           *
*                                                                           *
* Register(s) Changed:  Register X and accumulator A                        *
*---------------------------------------------------------------------------*
CheckRTSOpcode  cmpa    #$39                    Opcode for RTS
                bne     NotRTSOpcode
                ldd     UserRegs+SP_OffSet
                addd    #1
                xgdx
                ldx     ,x                      Get return address.
                sec
                bra     EndRTSCheck
NotRTSOpcode    clc
EndRTSCheck     rts

*****************************************************************************
* CheckBrclrOp()                                                            *
*****************************************************************************
* Description:  This routine is used by the GetBranchBreak routine.  It     *
*               is responsible for checking the BRCLR opcode.  If the BRCLR *
*               opcode is encountered, it will determine where it will      *
*               branch.                                                     *
*                                                                           *
* Entry Condition:      Accumulator A contains the current opcode.          *
*                                                                           *
* Exit Condition:       If the BRCLR opcode is encountered, the predicted   *
*                       branch address is saved in register X.  The C-bit   *
*                       in the CCR is set.  Otherwise is cleared.           *
*                                                                           *
* Register(s) Changed:  Register X and accumulator A                        *
*---------------------------------------------------------------------------*
CheckBrclrOp    cmpa    #$13            Direct mode for BRCLR.
                beq     BrclrOpcode
                cmpa    #$1F            Index mode for BRCLR.
                bne     NotBrclrOpcode
BrclrOpcode     ldd     Temp3
                addb    3,x
                addb    #4
                xgdx                    Determining the branch address.
                sec
                bra     EndBrclrOpcode
NotBrclrOpcode  clc
EndBrclrOpcode  rts

*****************************************************************************
* CheckBrsetOp()                                                            *
*****************************************************************************
* Description:  This routine is used by the GetBranchBreak routine.  It     *
*               is responsible for checking the BRSET opcode.  If the BRSET *
*               opcode is encountered, it will determine where it will      *
*               branch.                                                     *
*                                                                           *
* Entry Condition:      Accumulator A contains the current opcode.          *
*                                                                           *
* Exit Condition:       If a BRSET opcode is encountered, the predicted     *
*                       branch address is saved in register X.  The C-bit   *
*                       in the CCR is set.  Otherwise is cleared.           *
*                                                                           *
* Register(s) Changed:  Register X and accumulator A                        *
*---------------------------------------------------------------------------*
CheckBrsetOp    cmpa    #$12            Direct mode for BRSET.
                beq     BrsetDirect
                cmpa    #$1E            Index mode for BRSET.
                bne     NotBrset
BrsetDirect     ldd     Temp3
                addb    3,x
                addb    #4
                xgdx                    Determining the branch address.
                sec
                bra     EndBrsetOpcode
NotBrset        clc
EndBrsetOpcode  rts

*****************************************************************************
* CheckJsrOpcode()                                                          *
*****************************************************************************
* Description:  This routine is used by the GetBranchBreak routine.  It     *
*               is responsible for checking the JSR opcode.  If the JSR     *
*               opcode is encountered, it will determine where it will      *
*               jump.                                                       *
*                                                                           *
* Entry Condition:      Accumulator A contains the current opcode.          *
*                                                                           *
* Exit Condition:       If the JSR opcode is encountered, the predicted     *
*                       address is saved in register X.  The C-bit          *
*                       in the CCR is set.  Otherwise is cleared.           *
*                                                                           *
* Register(s) Changed:  Register X and accumulator A                        *
*---------------------------------------------------------------------------*
CheckJsrOpcode  cmpa    #$9D                    Direct mode for JSR.
                beq     JsrDirect
                cmpa    #$BD                    Extended mode for JSR.
                beq     JsrExtended
                cmpa    #$AD                    Index mode for JSR.
                bne     NotJsrOpcode
                ldab    1,x
                tst     Flag
                bne     JsrY_Index
                ldx     UserRegs+X_OffSet       X indexing mode.
                bra     JsrIndexAdjust
JsrY_Index      ldx     UserRegs+Y_OffSet       Y indexing mode.
JsrIndexAdjust  abx                             Address for indexing mode.
                bra     SetCBit
JsrExtended     ldx     1,x                     Address for Extended mode.
                bra     SetCBit
JsrDirect       ldd     Temp3
                addb    1,x
                xgdx                            Address for Direct mode.
SetCBit         sec
                bra     EndJsrOpcode
NotJsrOpcode    clc
EndJsrOpcode    rts

*****************************************************************************
* CheckRtiOpcode()                                                          *
*****************************************************************************
* Description:  This routine is used by the GetBranchBreak routine.  It     *
*               is responsible for checking the RTI opcode.  If the RTI     *
*               opcode is encountered, it will determine the return address.*
*                                                                           *
* Entry Condition:      Accumulator A contains the current opcode.          *
*                                                                           *
* Exit Condition:       If the RTI opcode is encountered, the predicted     *
*                       address is saved in register X.  The C-bit          *
*                       in the CCR is set.  Otherwise is cleared.           *
*                                                                           *
* Register(s) Changed:  Register X and accumulator A                        *
*---------------------------------------------------------------------------*
CheckRtiOpcode  cmpa    #$3B                    Opcode for the RTI.
                bne     NotRtiOpcode
                ldx     UserRegs+SP_OffSet
                ldx     8,x                     Get return address from user
*                                               stack area.
                sec
                bra     EndRtiOpcode
NotRtiOpcode    clc
EndRtiOpcode    rts

*****************************************************************************
* SetSS2Break()                                                             *
*****************************************************************************
* Description:  This routine is used by the SetUpSS2Break.  This routine    *
*               sets up the breakpoint in the user program.  It goes through*
*               the breakpoint table for the SS2.  If an entry is found,    *
*               i.e. address is not $FFFF, then the SWI opcode is swapped   *
*               with the current opcode pointed by the address in the table.*
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       The SWI opcode is placed in the user program.       *
*                                                                           *
* Register(s) Changed:  Register Y ,accumulator A and B                     *
*---------------------------------------------------------------------------*
SetSS2Break     ldy     #SS2Break
                ldaa    #2
SS2BreakLoop    beq     EndSS2Break
                ldx     ,y
                cpx     #$FFFF
                beq     NoSS2Break      Branch if no entry. (i.e. $FFFF)
                ldab    ,x
                stab    2,y             Make a copy of the opcode.
                ldab    #$3F           
                stab    ,x              Replace opcode with SWI opcode.
NoSS2Break      ldab    #3
                aby                     Next breakpoint entry.
                deca    
                bra     SS2BreakLoop
EndSS2Break     rts

*****************************************************************************
* RemoveSS2Break()                                                          *
*****************************************************************************
* Description:  This routine is used by the SS2_ISR.  It is responsible for *
*               removing all the breakpoints setup in the user program by   *
*               SetSS2Break routine.                                        *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       All breakpoints are removed.                        *
*                                                                           *
* Register(s) Changed:  All registers and accumulators.                     *
*---------------------------------------------------------------------------*
RemoveSS2Break  ldy     #SS2Break
                ldaa    #2
RemoveBreakL    beq     EndRemoveSS2B
                ldx     ,y
                cpx     #$FFFF          
                beq     SkipBreak
                ldab    2,y             Get saved opcode.
                stab    ,x              Store saved opcode back into program.
                ldx     #$FFFF
                stx     ,y
SkipBreak       ldab    #3
                aby                     Next breakpoint entry.
                deca    
                bra     RemoveBreakL
EndRemoveSS2B   rts

*****************************************************************************
* Higher4Bit                                                                *
*****************************************************************************
* Description:  This is a lookup table for the upper 4 bit of all opcode.   *
*               It gives the base offset of the predicted address.          *
*               For opcode with a upper 4 bit of 1, 8, and C requires an    *
*               additional lookup table.                                    *
*---------------------------------------------------------------------------*
Higher4Bit      fcb     1          for  0
                fcb     1               1
                fcb     2               2
                fcb     1               3
                fcb     1               4
                fcb     1               5
                fcb     2               6
                fcb     3               7
                fcb     2               8
                fcb     2               9
                fcb     2               A
                fcb     3               B
                fcb     2               C
                fcb     2               D
                fcb     2               E
                fcb     3               F

*****************************************************************************
* OffSetTable1                                                              *
*****************************************************************************
* Desription:   This lookup table is for the odd cases where the upper 4    *
*               bit is 1.  The first value is the value of the lower 4 bit. *
*               The second value is the additional offset required.         *
*               The end of this table is indicated by a Null Character.     *
*---------------------------------------------------------------------------*
OffSetTable1    fcb     2               Lower 4 Bit Value.
                fcb     3               Additional offset.
                fcb     3               Lower 4 Bit Value.
                fcb     3               Additional offset.
                fcb     4               Lower 4 Bit Value.
                fcb     2               Additional offset.
                fcb     5               .
                fcb     2               .
                fcb     $C              .
                fcb     2               .
                fcb     $D
                fcb     2
                fcb     $E
                fcb     3
                fcb     $F
                fcb     3
                fcb     0                End of table.

*****************************************************************************
* OffsetTable8                                                              *
*****************************************************************************
* Desription:   This lookup table is for the odd cases where the upper 4    *
*               bit is 8.  The first value is the value of the lower 4 bit. *
*               The second value is the additional offset required.         *
*               The end of this table is indicated by a Null Character.     *
*---------------------------------------------------------------------------*
OffSetTable8    fcb     3               Lower 4 Bit Value.
                fcb     1               Additional offset.
                fcb     $C              Lower 4 Bit Value.
                fcb     1               Additional offset.
                fcb     $D              .
                fcb     -1              .
                fcb     $E              .
                fcb     1               .
                fcb     $F
                fcb     -1
                fcb     0               End of table.

*****************************************************************************
* OffSetTableC                                                              *
*****************************************************************************
* Desription:   This lookup table is for the odd cases where the upper 4    *
*               bit is C.  The first value is the value of the lower 4 bit. *
*               The second value is the additional offset required.         *
*               The end of this table is indicated by a Null Character.     *
*---------------------------------------------------------------------------*
OffSetTableC    fcb     3               Lower 4 Bit Value.
                fcb     1               Additional offset.
                fcb     $C              Lower 4 Bit Value.
                fcb     1               Additional offset.
                fcb     $E              .
                fcb     1               .
                fcb     $F              .
                fcb     -1              .
                fcb     0               End of Table.

*****************************************************************************
* Help()                                                                    *
*                                                                           *
* Usage:   Help  <-- Displays the list of commands available and usage.     *
*          ?     <-- Same as Help.                                          *
* ..........................................................................*
* Description:  Routine to display the help string to the host terminal.    *
*               The help string contains all the commands available and     *
*               what are the arguments required.                            *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       A string of characters terminated by a null         *
*                       character is sent to the host terminal.             *
*                                                                           *
* Register(s) Changed:  All registers and Accumulators.                     *
*---------------------------------------------------------------------------*
Help            ldx     #HelpString
                jsr     OutString
                rts

*****************************************************************************
* Go(ptr)    
*
* Usage:    Go <cr>           <----  Run test program starting at address
*                                    specified by the user PC.
*
*           Go <address> <cr> <----  Run test program starting at the 
*                                    specified <address>.
*
*       where <address> is a 2 byte hex address.
*
* Description:  Routine to run the test program in memory at full speed.
*               The user's registers and accumulators are all pushed onto 
*               the stack before the call for RTI.  Termination of the test
*               program is done by a reset or by break points, ie. SWI.
*               Once a SWI is encountered, the monitor regains control.
*               WARNING:  The interrupt vector for the SWI is used by this
*                         routine.  Any attempt to alter the vector by
*                         the test program will inhibit this monitor program
*                         from regaining control after SWI.  Therefore, a
*                         reset is needed to restart the monitor program.
*
* Entry Condition:      Ptr is pointing to the first argument in memory.
*
* Exit Condition:       Termination of the user's test program.
*
* Register(s) Changed:  All registers and accumulators.
*
*----------------------------------------------------------------------------
Go              ldx     Ptr
                jsr     SkipSpace
                beq     NoGoArgument
                stx     Ptr
                jsr     Get4HexBin      Get starting address.
                tst     Flag
                beq     NoGoError
                jmp     BadArgument     Oops.  Bad starting address.
NoGoError       std     UserRegs        Saves address in user PC
NoGoArgument    jsr     SWI_at_start
                jsr     SetUpBreak
                ldx     #SWI_ISR
                jsr     SetUpSWI
                jsr     SetCtrlC
                jsr     RunUser
                rts

*****************************************************************************
* SetCtrlC                                                                  *
*****************************************************************************
* Description:  Routine to enable the SCI interrupt of reveiving mode.      *
*               It also clear the I-bit in the user CCR and set the SCI     *
*               softvector.                                                 *
* Entry Condition:      None.                                               *
* Exit Condition:       The above described in the description is performed.*
* Register Changed:     All registers, accumulators, and I-bit in user CCR. *
*---------------------------------------------------------------------------*
SetCtrlC        tst     CtrlC_On
                beq     EndCtrlC
                clr     Temp3
                ldaa    SCCR2
                bita    #%00100000
                beq     NotEnable
                inc     Temp3
NotEnable       ora     #%00100000
                staa    SCCR2           Enable receive interrupt.
                jsr     SetSCIVector
                jsr     SetUpUserInt
EndCtrlC        rts

*****************************************************************************
* SetSCIVector                                                              *
*****************************************************************************
* Description:  Routine to setup the SCI vector in the RAM.
* Entry Condition:      None.
* Exit Condition:       SCI vector points the SCI_ISR.
*----------------------------------------------------------------------------
SetSCIVector    ldaa    #$7E
                staa    JSCI
                ldd     JSCI+1
                std     Temp2
                ldd     #SCI_ISR
                std     JSCI+1
                rts

*****************************************************************************
* SCI_ISR                                                                   *
*****************************************************************************
* Description:  This is an interrupt service routine for the SCI interrupt.
*               It checks if the user pressed the Ctrl-C key.  If not, it 
*               continues on with the user program.  If so, the user program
*               is terminated.  The SCI interrupt is disabled and the user
*               CCR is return to normal.  The user registers are displayed 
*               on the host terminal.
* Entry Condition:      Interrupt from the SCI.
* Exit Condition:       If Ctrl-C is pressed, user CCR is return to original,
*                       SCI interrupt is disabled and user registers are sent
*                       to the host.
*                       If no Ctrl-C is pressed, the above is not perform.
*----------------------------------------------------------------------------
SCI_ISR         ldaa    SCSR
                ldaa    SCDR
                cmpa    #CTRLC
                bne     NotCtrlC
                ldd     Temp2
                std     JSCI+1                  Restore SCI interrupt vector.
                tst     Flag2
                bne     DisableSCI
                ldaa    UserRegs+CCR_OffSet     
                oraa    #%00010000              Restore I bit in user CCR.
                staa    UserRegs+CCR_OffSet
DisableSCI      tst     Temp3
                bne     RIE_Enable
                ldaa    SCCR2
                anda    #%11011111
                staa    SCCR2                   Disable SCI interrupt.
* Adjust user program counter to next opcode.
                tsx
                ldd     7,x
                addd    #1                      Increment user PC.
                std     7,x
                txs
RIE_Enable      jmp     SWI_ISR
NotCtrlC        rti

*****************************************************************************
* SWI_at_start                                                              *
*****************************************************************************
* Description:  This routine is used by the Go routine.  It is responsible  *
*               for checking if the starting opcode is a SWI.  If it is,    *
*               then it will advance to the next opcode.                    *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       The user PC is advanced to the next opcode if the   *
*                       PC is pointing a SWI instruction.                   *
*---------------------------------------------------------------------------*
SWI_at_start    ldx     UserRegs+PC_OffSet
                ldaa    ,x                      Get current opcode.
                cmpa    #$3F                    SWI opcode ?
                bne     NotSWI_at_start
                inx                             Yes.  Advance to next opcode.
                stx     UserRegs+PC_OffSet
NotSWI_at_start rts

*****************************************************************************
* SetUpBreak                                                                *
*****************************************************************************
* Description:  This routine is used by the Go routine.  This routine       *
*               sets up the breakpoint in the user program.  It goes through*
*               the user breakpoint table.  If an entry is found, i.e.      *
*               address is not $FFFF, then the SWI opcode is swapped        *
*               with the current opcode pointed by the address in the table.*
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       The SWI opcode is placed in the user program.       *
*                                                                           *
* Register(s) Changed:  Register Y ,accumulator A and B                     *
*---------------------------------------------------------------------------*
SetUpBreak      ldx     #BreakTable             Locate beginning of table.
                ldab    #3
                ldaa    #MaxBreak
SetUpBreakLoop  tsta
                beq     EndSetBreak
                ldy     ,x
                cpy     #$FFFF                  Check for entry in table.
                beq     NextBreak
                psha
                ldaa    ,y                      
                staa    2,x                     Make a copy of user opcode.
                cpy     UserRegs+PC_OffSet
                beq     CannotReplace
                ldaa    #$3F                    SWI opcode.
                staa    ,y                      Replace user opcode with SWI.
CannotReplace   pula
NextBreak       abx
                deca
                bra     SetUpBreakLoop
EndSetBreak     rts

*****************************************************************************
* SetUpSWI()
*
* Description:  Routine to setup the soft vector for the SWI vector.  The
*               previous value of the vector is stored in the variable
*               TEMP.
*
* Entry Condition:      X points to the interrupt service routine for SWI.
* 
* Exit Condition:       The address of the interrupt service routine
*                       pointed by register X is placed in the soft vector.
*
* Register(s) Changed:  Register X and Accumulator A.
*---------------------------------------------------------------------------*
SetUpSWI        ldaa    #$7E            
                staa    JSWI            Write a JMP instruction into vector.
                ldd     JSWI+1
                std     Temp
                stx     JSWI+1          Write the address of the serivce
*                                       routine into vector.
                rts

*****************************************************************************
* RunUser                                                                   *
*****************************************************************************
* Description:  This routine is used by the Go routine.  It is responsible  *
*               for stacking all the user accumulators and registers into   *
*               the user stack.  It then performs an RTI instruction to     *
*               run the user program.                                       *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       Control is given to the user program.               *
*---------------------------------------------------------------------------*
RunUser         tsx     
                stx     Ptr             Make of copy of the monitor SP.
                ldy     #UserRegs
                ldd     SP_OffSet,y
                addd    #1
                xgdx
                txs                     SP now points to user stack area.
* Pushing all necessary registers and accumulators into the user stack.
                ldx     PC_OffSet,y
                pshx                    
                ldx     Y_OffSet,y
                pshx
                ldx     X_OffSet,y
                pshx
                ldaa    A_OffSet,y
                psha
                ldaa    B_OffSet,y
                psha
                ldaa    CCR_OffSet,y
                psha
* Run the user program.
                rti

*****************************************************************************
* SWI_ISR                                                                   *
*****************************************************************************
* Description:  This is a interrupt service routine for the SWI interrupt.  *
*               Control is handed back to the monitor program.  All user    *
*               registers and accumulators are saved into memory.           *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       Control is handed back to the monitor.  SP is       *
*                       pointing back to the monitor stack area.            *
*---------------------------------------------------------------------------*
SWI_ISR         tsx
                ldy     Ptr     
                tys                     Restore SP to monitor stack area.
                ldd     Temp
                std     JSWI+1          Restore softvector for SWI.
                jsr     SaveUserStack
                jsr     RemoveBreak
                jsr     PrintReg
                rts

*****************************************************************************
* SaveUserStack                                                             *
*****************************************************************************
* Description:  This routine saves all user registers and accumulators into *
*               memory.  It gets the value out of the user stack.           *
* Entry Condition:      Must return from the interrupt.                     *
*---------------------------------------------------------------------------*
SaveUserStack   ldaa    ,x
                staa    UserRegs+CCR_OffSet
                ldaa    1,x
                staa    UserRegs+B_OffSet
                ldaa    2,x
                staa    UserRegs+A_OffSet
                ldd     3,x
                std     UserRegs+X_OffSet
                ldd     5,x
                std     UserRegs+Y_OffSet
                ldd     7,x
                subD    #1
                std     UserRegs+PC_OffSet
                ldab    #8
                abx
                stx     UserRegs+SP_OffSet
                rts

*****************************************************************************
* RemoveBreak                                                               *
*****************************************************************************
* Description:  This routine removes all the breakpoint from the user       *
*               program.  The SWI in the user program gets replaced with    *
*               the original opcode.                                        *
*                                                                           *
* Entry Condition:      None.                                               *
*                                                                           *
* Exit Condition:       All breakpoints in the user program is removed.     *
*                                                                           *
* Register(s) Changed:  All.                                                *
*---------------------------------------------------------------------------*
RemoveBreak     ldx     #BreakTable     Locate top of breakpoint table.
                ldab    #3
                ldaa    #MaxBreak
Re_Loop         tsta    
                beq     EndRemoveBreak          At the end of table?
                ldy     ,x
                cpy     #$FFFF                  Checking for valid entry.
                beq     NextRemoveBreak
                psha    
                ldaa    2,x
                staa    ,y                      Restoring original opcode.
                pula
NextRemoveBreak abx
                deca
                bra     Re_Loop
EndRemoveBreak  rts

*****************************************************************************
* PrintReg                                                                  *
*****************************************************************************
* Description:  This routine prints the content of the user's registers and *
*               accumulators onto the host terminal.                        *
* Register(s) Changed:  All.
*---------------------------------------------------------------------------*
PrintReg        ldx     #Labels
                jsr     OutString4              'A: '
                ldaa    UserRegs+A_OffSet
                jsr     Out8Bin2Hex
                jsr     OutString4              'B: '
                ldaa    UserRegs+B_OffSet
                jsr     Out8Bin2Hex
                jsr     OutString4              'X: '
                ldd     UserRegs+X_OffSet
                jsr     Out16Bin2Hex
                jsr     OutString4              'Y: '
                ldd     UserRegs+Y_OffSet
                jsr     Out16Bin2Hex
                jsr     OutString4              'PC: '
                ldd     UserRegs+PC_OffSet
                jsr     Out16Bin2Hex
                jsr     OutString4              'CCR: '
                ldaa    UserRegs+CCR_OffSet
                jsr     Out8Bin2Hex
                jsr     OutString4              'SP: '
                ldd     UserRegs+SP_OffSet
                jsr     Out16Bin2Hex
                rts

*****************************************************************************
* The following is a lookup table of the labels needed for the printing of  *
* the user's registers and accumulators.                                    *
*****************************************************************************
Labels          fcc     'A: '
                fcb     Null
                fcc     'B: '
                fcb     Null
                fcc     'X: '
                fcb     Null
                fcc     'Y: '
                fcb     Null
                fcc     'PC: '
                fcb     Null
                fcc     'CCR: '
                fcb     Null
                fcc     'SP: '
                fcb     Null
                fcb     EOT                 

*****************************************************************************
* The following string of characters are used by the Help routine.  It is 
* composed of all the commands available and the required arguments.
* The string is supposed to help the user in using this monitor program.
*****************************************************************************
HelpString      fcb     CR
                fcb     LF
                fcc     'BREAK [<addr>]  : Add/Delete breakpoints'
                fcb     CR
                fcb     LF
                fcc     'CALL [<addr>]  : Call subroutine'
                fcb     CR
                fcb     LF
                fcc     'FILL <addr1> [<addr2>] [<data>]  : Block/Byte fill'
                fcb     CR
                fcb     LF
                fcc     'GO [<addr>]  : Run program' 
                fcb     CR
                fcb     LF
                fcc     'HELP or ?  : Display help'
                fcb     CR
                fcb     LF
                fcc     'LOAD [<OffSet>]  : Load Program'
                fcb     CR
                fcb     LF
                fcc     'MD [<addr1>] [<addr2>]  : Memory dump'
                fcb     CR
                fcb     LF
                fcc     '   Key Stroke:  <Ctrl-C> terminates MD'
                fcb     CR
                fcb     LF
                fcc     'PB <on/off>  : Enable <Ctrl-C>'
                fcb     CR
                fcb     LF
                fcc     'REG [<A/B/X/Y/CCR/PC/SP> <data>] : Display/modify Registers'
                fcb     CR
                fcb     LF
                fcc     'SS [<addr>]  : Single Step (using interrupt)'
                fcb     CR
                fcb     LF
                fcc     '   HotKey:  <F7>'
                fcb     CR
                fcb     LF
                fcc     'S2 [<addr>]  : Single Step (using breakpoints)'
                fcb     CR
                fcb     LF
                fcc     '   HotKey:  <F8>'
                fcb     Null

*****************************************************************************
* PB()                                                                      *
*****************************************************************************
* Description:  This Routine toggles the user's break on/off.  This enable
*               the user to terminate the program during execution.  It
*               is useful when the program is stuck in a continuous loop.
*               The default value is Off because this command uses the 
*               interrupt vector of the SCI.  If the user program uses this
*               interrupt vector, then this command would not work properly.
*
* Entry Condition:      String pointer is pointing to the argument of the
*                       string.
*
* Exit Condition:       Toggles the value stored in CtrlC_On.
*                       1 = Enable, 0 = Disable.
*
* Register(s) Changed:  All registers and accumulators.
*---------------------------------------------------------------------------*
PB              ldx     Ptr
                jsr     SkipSpace
                beq     NoPB_argument
                stx     Ptr
                jsr     GetPB_argument          Get on/off argument.
                bcs     ArgumentOk
                jmp     BadArgument             Invalid argument.
ArgumentOk      Nop
NoPB_argument   jsr     NewLine
                ldx     #PBLabel1
                jsr     OutString               
                ldaa    #3
                ldab    CtrlC_On
                mul
                ldx     #PBLabel2
                abx
                jsr     OutString               Display status of PB.
                rts

*****************************************************************************
* String labels for PB routine.                                             *
*****************************************************************************
PBLabel1        fcc     'Break O'
                fcb     Null
PBLabel2        fcc     'ff'
                fcb     Null
                fcc     'n '
                fcb     Null

*****************************************************************************
* GetPB_argument                                                            *
*****************************************************************************
* Description:  This routine determines the argument for the PB command.
*               If an invalid argument is encountered, the C bit is cleared.
*               Otherwise is set.  If the argument <on> is encountered, the
*               variable CtrlC_On is set.  Otherwise is cleared.
*
* Entry Condition:      Register X contains the address of the PB argument.
*
* Exit Condition:       CtrlC_On variable is set accordingly.
*
* Register Changed:     Register A, accumulator X and C-bit in the CCR.
*----------------------------------------------------------------------------
GetPB_argument  ldaa    ,x
                jsr     UpCase
                cmpa    #'O'
                bne     InvalidPB       
                inx     
                ldaa    ,x
                jsr     UpCase
                cmpa    #'N'
                bne     CheckOff        Is the argument 'On'?
                ldaa    #1              
                staa    CtrlC_On        Yes, set CtrlC_On.
                bra     ValidPB
CheckOff        cmpa    #'F'            Is the argument 'Off'?
                bne     InvalidPB
                clr     CtrlC_On        Yes, clr CtrlC_On.
ValidPB         sec
                bra     EndGetPB_arg
InvalidPB       clc
EndGetPB_arg    rts

*****************************************************************************
* Messages used by the Monitor Program                                      *
*****************************************************************************
MSG1            fcc     '68HC11 Monitor Program v(1.0) by Kin-Hung Leung'
                fcb     Null
MSG2            fcc     'Command> '
                fcb     Null
MSG3            fcc     'Command Too Long'
                fcb     Null
MSG4            fcc     'Bad Command'
                fcb     Null
MSG5            fcc     'Transmit Complete'
                fcb     Null
MSG6            fcc     'Warning: Checksum Error'
                fcb     Null
MSG7            fcc     'Bad Argument'
                fcb     Null
MSG8            fcc     'Break Table Full'
                fcb     Null
MSG9            fcc     'Breakpoint removed'
                fcb     Null
MSG10           fcc     'Breakpoint Table'
                fcb     Null
MSG11           fcc     'Memory Violation:'
                fcb     Null
         
*****************************************************************************
* Jump Table of Subroutine in Monitor Program                               *
*****************************************************************************
                ORG     $E000
                jmp     GetChar
                jmp     OutChar
                jmp     OutString
                jmp     NewLine
                jmp     Hex2Bin
                jmp     TwoHex2Bin
                jmp     FourBin2Hex
                jmp     EightBin2Hex
                jmp     UpCase

*****************************************************************************
* Interrupt Vector table in ROM                                             *
*****************************************************************************
*                ORG    ROMBS+$1FD6
                ORG     $FFD6
*** Vectors ***
VSCI            FDB    JSCI
VSPI            FDB    JSPI
VPAIE           FDB    JPAIE
VPAO            FDB    JPAO
VTOF            FDB    JTOF
VTOC5           FDB    JTOC5
VTOC4           FDB    JTOC4
VTOC3           FDB    JTOC3
VTOC2           FDB    JTOC2
VTOC1           FDB    JTOC1
VTIC3           FDB    JTIC3
VTIC2           FDB    JTIC2
VTIC1           FDB    JTIC1
VRTI            FDB    JRTI
VIRQ            FDB    JIRQ
VXIRQ           FDB    JXIRQ
VSWI            FDB    JSWI
VILLOP          FDB    JILLOP
VCOP            FDB    JCOP
VCLM            FDB    JCLM
VRST            FDB    Monitor

