         page  Semantic Routines
*******************************************************************************
*        Debug Semantic Routines
*******************************************************************************
Redisplayno
         rts

RedisplayifOpen ; (X) contains new display mode
         stx   DisplayMode
         tst   CellOpenFlag
         beq   Redisplayno
DisplayLocation ; Display location last opened
         jmp   [DisplayMode]

DisplayInstructionMode ; Display instruction at location
         ldx   OpenCellAddress    get address of cell
         lbsr  ListInstruction    go list an instruction
         rts

DisplayHexMode ; Display byte at location as hex byte
         lda   #1                 = actual number of bytes to display
DisplayOpenCellforCount ; Display (A) bytes at OpenCellAddress
         ldx   OpenCellAddress    get address of cell again
DisplayMultiplebytesLoop ; (a)=count, (X)=where; show bytes from user space
         pshs  x,a                save address and length count
         jsr   fetchuserbyte      get a byte from the user space
         jsr   printhexbyte       output hex value of byte
         puls  x,a                get address and length count back
         inx                      bump pointer to next byte
         deca                     = remaining count
         bne   DisplayMultiplebytesloop
PrintBlank ; Print blank and then return
         lbsr  PrintInLineCharacter
         fcc   " "
         rts

DisplayWordMode ; Display byte at location as 16 bit word
**** shouldn't this try to look things up ins the symbol table?
         lda   #2                 = # bytes to display
         bra   DisplayOpenCellforCount

DisplayCharacterMode ; Display byte at location as a character
         ldx   OpenCellAddress    go fetch the byte to display
         jsr   FetchUserByte
         anda  #$7f               mask off "parity" bit
         cmpa  #Ascii:Rubout      unprintable character ?
         beq   DisplayUnprintableCharacter b/ yes
         cmpa  #Ascii:blank       control character ?
         blo   DisplayUnprintableCharacter b/ yes
         psha                     save the character
         lbsr  PrintInlineCharacter
         fcc   "'"
         pula                     restore the character
         lbsr  PrintCharacter
         lbsr  PrintInlineCharacter
         fcc   "'"
         bra   PrintBlank         output the required trailing blank

DisplayUnprintableCharacter ; character is unprintable
         lbsr  PrintHex           output the character as a hex byte
         bra   PrintBlank

PrintInlineCharacter ; Print character coded inline at point of subroutine call
         pulx                     = return address
         lda   ,x+                get the inline character
         pshx                     push standard return address on stack
         bra   PrintCharacter
PrintCharacter ; Print character in (A) on user console
         ???
         page
SetRegisterBranchTable ; Branch table used to get to register setting routines
         #SetRegisterA
         #SetRegisterB
         #SetRegisterC
         #SetRegisterD
         #SetGPRegister           Register E
         #SetGPRegister           Register F
         #SetGPRegister           Register G
         #SetGPRegister           Register H
         #SetGPRegister           Register I
         #SetGPRegister           Register J
         #SetGPRegister           Register K
         #SetGPRegister           Register L
         #SetRegisterM
         #SetGPRegister           Register N
         #SetGPRegister           Register O
         #SetRegisterP
         #SetGPRegister           Register Q
         #SetGPRegister           Register R
         #SetRegisterS
         #SetRegisterT
         #SetRegisterU
         #SetGPRegister           Register V
         #SetGPRegister           Register W
         #SetRegisterX
         #SetRegisterY
         #SetRegisterZ
         page
Verify8BitSignificance ; check that (D) has only 8 bits of significance
         tsta            is 0<=(D)<=255 ?
         beq   VerifySignificanceOK
         inca            no, check for -256<=(D)<=-1
         bne   SemanticError b/ too negative
         tstb            msb should be set...
         bpl   SemanticError b/ not 8 bit significance
VerifySignificanceOK
         rts

SetRegisterA ; (D) contains new value
         bsr   Verify8bitSignificance
         stb   UserRegisterA
         rts

SetRegisterB ; (D) contains new value
         bsr   Verify8bitSignificance
         stb   UserRegisterB
         rts

SetRegisterC ; (D) contains new value
         bsr   Verify8bitSignificance
         stb   UserRegisterCC
         rts

SetRegisterD ; (D) contains new value
         std   UserRegisterD
         rts

SetRegisterM ; (D) contains new value
         std   SearchMask    save search mask value
         rts

SetRegisterP ; (D) contains new value
         std   UserRegisterPC
         rts

SetRegisterS ; (D) contains new value
         std   UserRegisterS
         rts

SetRegisterT ; (D) contains new value
         std   SearchTarget  save search target value
         rts

SetRegisterU ; (D) contains new value
         std   UserRegisterU
         rts

SetRegisterX ; (D) contains new value
         std   UserRegisterX
         rts

SetRegisterY ; (D) contains new value
         std   UserRegisterY
         rts

SetRegisterZ ; (D) contains new value
         tstb            must be on page boundary !
         bne   SemanticError
         sta   UserRegisterDP
         rts

SetGPRegister ; Set GP Register to value in (D)
         std   0,x
         rts
         page
GetRegisterBranchTable ; Branch table used to get to register fetching routines
         #GetRegisterA
         #GetRegisterB
         #GetRegisterC
         #GetRegisterD
         #GetGPRegister           Register E doesn't exist
         #GetGPRegister           Register F doesn't exist
         #GetGPRegister           Register G doesn't exist
         #GetGPRegister           Register H doesn't exist
         #GetGPRegister           Register I doesn't exist
         #GetGPRegister           Register J doesn't exist
         #GetGPRegister           Register K doesn't exist
         #GetGPRegister           Register L doesn't exist
         #GetRegisterM
         #GetGPRegister           Register N doesn't exist
         #GetGPRegister           Register O doesn't exist
         #GetRegisterP
         #GetGPRegister           Register Q doesn't exist
         #GetGPRegister           Register R doesn't exist
         #GetRegisterS
         #GetRegisterT
         #GetRegisterU
         #GetGPRegister           Register V doesn't exist
         #GetGPRegister           Register W doesn't exist
         #GetRegisterX
         #GetRegisterY
         #GetRegisterZ

GetRegisterA ; Get contents of specified register
         ldb   UserRegisterA
         clra                extend to 16 bits
         rts

GetRegisterB ; Get contents of specified register
         ldb   UserRegisterB
         clra                extend to 16 bits
         rts

GetRegisterC ; Get contents of specified register
         ldb   UserRegisterCC
         clra                extend to 16 bits
         rts

GetRegisterD ; Get contents of specified register
         ldd   UserRegisterD
         rts

GetRegisterM ; Get contents of specified register
         ldd   SearchMask
         rts

GetRegisterP ; Get contents of specified register
         ldd   UserRegisterPC
         rts

GetRegisterS ; Get contents of specified register
         ldd   UserRegisterS
         rts

GetRegisterT ; Get contents of specified register
         ldd   SearchTarget
         rts

GetRegisterU ; Get contents of specified register
         ldd   UserRegisterU
         rts

GetRegisterX ; Get contents of specified register
         ldd   UserRegisterX
         rts

GetRegisterY ; Get contents of specified register
         ldd   UserRegisterY
         rts

GetRegisterZ ; Get contents of specified register
         ldb   UserRegisterDP
         clra           extend to 16 bits
         rts

GetGPRegister ; Set GP Register to value in (D)
         ldd   0,x
         rts
         page
*
*        This section of the debugger contains semantic actions for the rules
*        When a rule is invoked, (X) points to the state stack
*        The state stack contains 4 byte entries,
*        one for each item in the right hand side of a rule.
*        The first pair of bytes of each item are used by the parser only.
*        The second pair of bytes contain semantic information only.
*        Typical use of a semantic values is as follows:
*              Assume a rule of form   EXP =  PRODUCT '+' TERM ;
*              Then there will be 3 items on the stack when the semantic
*              routine for this rule is called.  The "leftmost" (...2,x)
*              could contain the semantic (arithmetic) value of the PRODUCT.
*              The middle value (...6,x) is simply garbage, no "value"
*              is associated with the "+" syntactic item.  The "rightmost"
*              (...10,x) would contain the semantic (arithmetic) value
*              of the TERM.
*        The semantic routine must perform whatever action is required,
*        and return a new semantic value in the D register (in the example
*        above, the new semantic value would the sum of the values of the
*        PRODUCT and the TERM).  Of course, if no semantic value results,
*        garbage can be returned; parser will faithfully attach the new
*        value as the semantic value of the reduced-to token (i.e., EXP).
*
Semantic1stValue equ 2  Index offset of semantic value of 1st token
Semantic2ndValue equ 6  Index offset of semantic value of 2nd token
Semantic3rdValue equ 10 Index offset of semantic value of 3rd token
Semantic4thValue equ 14 Index offset of semantic value of 4th token
Semantic5thValue equ 18 Index offset of semantic value of 5th token
Semantic6thValue equ 22 Index offset of semantic value of 6th token

SemanticError ; Syntax is ok, but can't perform the desired operation
         ????

         page
SemanticDisplayInstructionMode ; COMMAND = ';I' ;
****could do BSR to common point here?
         ldx   #DisplayInstructionMode
         bra   Redisplayifopen

SemanticDisplayCharacterMode ; COMMAND = ';A' ;
         ldx   #DisplayCharacterMode
         bra   Redisplayifopen

SemanticDisplayHexMode ; COMMAND = ';H' ;
         ldx   #DisplayHexMode
         bra   Redisplayifopen

SemanticDisplayWordMode ; COMMAND = ';W' ;
         ldx   #DisplayWordMode
         bra   Redisplayifopen

SemanticSetRegister ; COMMAND = REGISTERNAME ':' '=' EXP ;
         ldd   Semantic1stValue,x fetch register number
         asld                convert to word index
         ldy   #SetRegisterBranchTable
         leay  d,x           get address of register-setting routine
         ldd   Semantic4thValue,x value to set register to
         jmp   0,y           go to register setting routine

SemanticGetRegister ; TERM = REGISTERNAME ;
         ldd   Semantic1stValue,x fetch register number
         asld                convert to word index
         ldy   #GetRegisterBranchTable
         jmp   [d,x]         go to proper routine to fetch value
         page
SearchMask   rmb 8                storage holding search-for mask
SearchTarget rmb 8                storage holding search-for target string
SearchTargetLength rmb 1          holds length of search target

SemanticSetTarget ; COMMAND = LONGHEX ';T' ;
**** what about target of 8 or 16 bits ?
         ldx   Semantic1stValue,x fetch pointer to hex string to search for
         ldb   0,x                fetch length of value
         cmpb  #SearchTargetLength-SearchTarget too long ?
         bhi   SemanticError      b/ yes, abort!
         cmpb  SearchTargetLength different length ?
         beq   SemanticSetTarget1 b/ no, leave SearchMask alone
         stb   SearchTargetLength
         ldy   #SearchMask        yes, reset SearchMask to "Match all bits"
         lda   #$ff               set mask to "all"
SemanticSetTargetResetMask
         sta   ,y+
         decb
         bne   SemanticSetTargetResetMask
SemanticSetTarget1 ; actually copy the target
         ldy   #SearchTarget      = where to put value
         ldb   SearchTargetLength
SemanticSetTargetLoop ; copy bytes into target buffer
         lda   ,x+                boy, this is easy!!
         sta   ,y+
         rts

SemanticSetMask ; COMMAND = LONGHEX ';M' ;
*** what about mask of 8 or 16 bits??
         ldx   Semantic1stValue,x fetch pointer to hex string to search for
         ldb   0,x                fetch length of mask
         cmpb  SearchTargetLength match size of target ?
         bne   SemanticError      b/ no, give up!
         ldy   #SearchMask        = where to put mask bytes
SemanticSetMaskLoop ; copy bytes into mask buffer
         lda   ,x+                fetch mask byte
         coma                     this is most convenient internal form
         sta   ,y+                save byte away
         decb
         bne   SemanticSetMaskLoop
         rts

SemanticSearchMemory ; COMMAND = EXP ',' EXP ';S' ; search range
         jsr   PrintNewLine       move to next line
         clr   CellOpenFlag       close any open location
         ldx   Semantic1stValue,s fetch starting search address
         dex                      to offset INX that follows
         stx   OpenCellAddress    save location address
SemanticSearchMemoryNext ; try next location
         jsr   CheckAttention     abort if operator wants attention
         ldx   OpenCellAddress    bump location
         inx
         stx   OpenCellAddress    save location address
         cmpx  Semantic3rdValue,s limit exceeded ?
         beq   PrintNewLine       b/ yes, exit
         ldy   #SearchTarget      = source of bytes to compare against
         ldb   SearchTargetLength # bytes to compare before match occurs
         beq   SemanticError      b/ search target not set
SemanticSearchMemoryLoop ; compare next byte
         lda   ,x+                fetch byte to compare against
         anda  SearchMask-SearchTarget,y drop undesired bits
         cmpa  ,y+                compare to target
         bne   SemanticSearchMemoryNext b/ failed to match
         decb                     down count length required to match
         bne   SemanticSearchMemoryLoop b/ more bytes to compare
         jsr   DisplayNext1       display the address and value found
         jsr   PrintNewLine       move to next line
         bra   SemanticSearchMemoryNext search for more!
         page
??? the serach/fill command should allow arbitrary target to be speciifiied,
??? iincluding an instrution!!!
SemanticFillMemory ; COMMAND = EXP ',' EXP ',' LONGHEX ';Z' ;
SemanticFillMemory ; COMMAND = EXP ',' EXP ',' EXP ';Z' ;
SemanticZeroMemory ; COMMAND = EXP ',' EXP ';Z' ;
         clr   FillSource         put a zero into the source
         lda   #1                 = size of source
         sta   FillLength
         jsr   PrintNewLine       move to next line
         clr   CellOpenFlag       close any open location
         ldx   Semantic1stValue,s fetch starting search address
         ldy   #FillSource        = source
         ldb   FillLength         = size of source
         beq   SemanticError      b/ source not set!
SemanticZeroMemoryNext ; try next location
         cmpx  Semantic3rdValue,s limit exceeded ?
         beq   PrintNewLine       b/ yes, exit
         jsr   CheckAttention     abort if operator wants attention
         lda   ,y+                fetch byte from source
         decb                     down count source size
         bne   SemanticZeroMemory1 b/ more source bytes available
         ldy   #FillSource        = source of more bytes
         ldb   FillLength         = size of source
SemanticZeroMemory1
         pshs  x,y,b              save loop parameters
         jsr   storeuserbyte      into user space
         puls  x,y,b              restore loop parameters
         inx                      advance target pointer
         bra   SemanticZeroMemoryNext
         page
SemanticChecksumMemory ; COMMAND = EXP ',' EXP ';C' ;
*** this should be a function, so it can be used in a breakpoint!
*** allow bkpt if cksum over a region has changed?
         ldx   Semantic1stValue,s fetch bottom address of region
         ldd   #0                 zero the checksum over the region
SemanticChecksumMemoryLoop ; add next byte to checksum
         cmpx  Semantic3rdValue,x checksum over region complete ?
         bhs   SemanticCheckSumRts b/ yes
         pshs  d,x                save checksum and location
         jsr   fetchuserbyte      from user space
         tab                      make 16 bit number
         clra
         addd  ,s++               add to checksum total
         puls  x                  restore location
         inx                      advance pointer
         bra   SemanticChecksumMemoryLoop
SemanticCheckSumRts
         rts
         page
SemanticKillABreakPoint ; COMMAND = EXP ';K' ;
SemanticKillAllBkpts ; COMMAND = ';K' ;

SemanticSetPCandGo ; COMMAND = EXP ';G' ;
         ldd   Semantic1stValue,x  Fetch new P counter value
         bsr   SetRegisterP  set the P counter to specified value
SemanticGoUsingPC ; COMMAND = ';G'
         bsr   InstallRealTimeBreakPoints
         bsr   SetUserRegisterstolocalcopy
         ldx   #TaskCapability
         lda   #StartTask
         jsr   DoOperation
         rts
         page
SemanticSingleStepTillAddr ; COMMAND = EXP ';I' ;
         ldd    Semantic1stValue,x fetch target PC
         std    TargetPC
SemanticSingleStepLoop ; Single step till Target PC reached
         lbsr  ExecuteInstruction Execute one instruction
         jsr   CheckAttention     see if operator wants out!
         bcs   RegisterDisplay    b/ yes, abort single stepping
         ldd   UserRegisterPC     arrive at desired location ?
         cmpd  TargetPC           ...?
         bne   SemanticSingleStepLoop
         bra   SemanticDisplayRegisters

SemanticSingleStep ; COMMAND = ',' ;
         jsr   ExecuteInstruction execute one instruction, display results
SemanticDisplayRegisters ; COMMAND = '?';
*        Display register contents
*        Register display format (80 characters):
* D=aabb X=xxxx Y=yyyy U=uuuu S=ssss Z=xx efhinzvc pppp/ instruction (efa)
*        Register display format (40 characters):
*               D=aabb X=xxxx Y=yyyy U=uuuu S=ssss Z=xx
*               efhinzvc pppp/ instruction  (addr)
*
???
PrintBlank ; prints a single blank character
         lda   #ascii:blank
         bra   PrintCharacter
????
         lbsr   PrintBlank
         ldd    UserRegisterD display D register contents
         bsr    DisplayRegister
         fcc    "D"
         ldd    UserRegisterX display X register contents
         bsr    DisplayRegister
         fcc    "X"
         ldd    UserRegisterY display Y register contents
         bsr    DisplayRegister
         fcc    "Y"
         ldd    UserRegisterU display U register contents
         bsr    DisplayRegister
         fcc    "U"
         ldd    UserRegisterS display S register contents
         bsr    DisplayRegister
         fcc    "S"
         lbsr   PrintBlank
         lbsr   DisplayInlineCharacter  display DPR contents
         fcc    "Z"
         lbsr   DisplayInlineCharacter
         fcc    "="
         lda    UserRegisterDP
         bsr    printhexbyte
         lda    NarrowScreenFlag       40 character wide display ?
         beq    SemanticDisplayRegisters1 b/ no
         lbsr   PrintNewLine           yes, go to new line
SemanticDisplayRegisters1
         lbsr   DisplayInLineCharacter
         fcc    " "
         bsr    DisplayCCR             display Condition code bits
         lbsr   PrintBlank
         ldd    UserRegisterPC display the PC ??? as a symbolic value???
         bsr    PrintHexWord
         bsr    PrintSlant
         ldx    UserRegisterPC display the instruction
         lbsr   ListInstruction
         lbsr   PrintBlank   output blank to seperate from register display
         ldd    EffectiveAddress  does instruction have an effective address ?
         cmpd   #$FFFF            ...?
         lbeq   PrintNewLine      b/ no, don't display anything
         bsr    PrintHexWord      yes, show effective address ??? symbolic mode
         lbra   PrintNewLine
         page
DisplayRegister ; Display (D) as contents of in-line register name
         tdx                 rearrange registers to make things convenient
         puls   y            pull return address
         lda    ,y+          = name of register
         pshs   y,x          push return address followed by value to print
         lbsr   PrintCharacter print name of register
         lbsr   PrintInlineCharacter
         fcc    "="
         puld                = value to display
         bsr    PrintHexWord output value to display
         lbra   PrintBlank   output a blank

PrintHexWord ; Print out hexadecimal for (D)
         pshb                   save 2nd byte
         bsr    PrintHexByte    output first byte
         pula                   restore 2nd byte for printing
PrintHexByte ; Print out hexadecimal for (A)
         tfr    a,b             split (A) into 2 hex nibbles
         lsra                   shift upper nibble to lower 4 bits
         lsra
         lsra
         lsra
         andb   #$F             mask off upper nibble on 2nd nibble
         pshb
         bsr    PrintHexDigit   output the 1st hex digit
         pula                   fetch 2nd hex digit and output
PrintHexDigit ; Print out hex digit for nibble in (A)
         adda   #$90            convert to ascii digit
         daa                    carry set --> digit >= 'A'
         adca   #$40            propogate carry (is $ sposed to be here?)
         daa                    (A) contains final digit!
         lbra   PrintCharacter  and go output that instead!

         page
SemanticDisplayLocation ; COMMAND = EXP '?' ;
         ldx    Semantic1stValue,x Fetch memory location to open
         stx    OpenCelladdress  remember it
         lda    #1               remember that we remembered it
         sta    OpenCellFlag
         bra    SemanticDisplayNext1

SemanticDisplayNext ; COMMAND = <LF> ;
         jsr    PrintInlineCharacter
         fcb    Ascii:cr        <LF> has been echoed, output <CR>
         tst    CellOpenFlag    is a cell open ?
         beq    Illegal         b/ no!
         ldd    OpenCellAddress yes, get address of last opened location
         addb   DisplayedCount  = # bytes displayed
         adca   #0
SemanticDepositandDisplayNext ; COMMAND = DEPOSIT <LF> ;
*        semantic value is address of next location to deposit into
SemanticSetCellandDisplay
         std    OpenCellAddress Remember new location
         bsr    printsymbolicaddress
         lbsr   PrintInlineCharacter
         fcc    "/"
SemanticDisplayNext1
         lbsr   PrintBlank
         bra    Displaylocation go display the address

SemanticOpenLocation ; COMMAND = EXP ':' ;
         std    Opencelladdress remember address of open cell
         lda    #1              remember that a cell is open
         sta    CellisOpenFlag
         rts

SemanticDepositandClose ; COMMAND = DEPOSIT <CR> ;
SemanticCloseLocation ; COMMAND = <CR> ;
         clr    CellisOpenFlag  Remember that no cell is open
         rts

SemanticDisplayPrevious ; COMMAND = '^' ;
         tst    CellisOpenFlag  only legal if cell is open
         beq    SemanticError   b/ not legal now.
         ldd    OpenCellAddress Back up one location
         subd   #1
         bra    SemanticSetCellandDisplay

PrintNewLine ; output <CR> and implied <LF>
         bsr    PrintInLineCharacter
         fcb    Ascii:CR
         rts

PrintSlant ; print "/<blank>"
         bsr    PrintInlineCharacter
         fcc    "/"
         bra    PrintBlank

SemanticPrintText ; COMMAND = TEXT '?' ;
SemanticLoad ; COMMAND = ';L' ;
SemanticLoadFile ; COMMAND = TEXT ';L' ;
SemanticPunchtoFile ; COMMAND = EXP ',' EXP ';P' ;
SemanticOpenSaveFile ; COMMAND = TEXT ';P' ;
         page
SemanticSetFancyBkpt ; COMMAND = '[' COMMANDS ']' EXP '!' ;
SemanticSetSimpleBkpt ; COMMAND = EXP '!' ;
SemanticShowBkpts ; COMMAND = '!' ;
SemanticRemoveBkpt ; COMMAND = EXP '\' ;
SemanticSetCursor ; '@' '(' EXP ',' EXP ')' ;

SemanticPrintValue ; EXP '=' '?' ;
         bsr    PrintHexWord     display the value
         ldx    Semantic1stValue,x use value of expression as result
         rts

         page  Arithmetic Semantic execution routines
SemanticNOP ; LEFTHANDSIDE = RIGHTHANDSIDE ... ;
         rts                     use value of RIGHTHANDSIDE as result

SemanticTrue ; Result of relational compare is 'True'
         ldd    #1
         rts

SemanticFalse ; Result of relational compare is 'False'
         ldd    #0
         rts

SemanticEqual ; RELATIONALOP = '=' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         beq    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticNotEqual ; RELATIONALOP = '#' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bne    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticSignedLess ; RELATIONALOP = '<' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         blt    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticSignedGreater ; RELATIONALOP = '>' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bgt    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticSignedLessEqual ; RELATIONALOP = '<=' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         ble    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticSignedGreaterEqual ; RELATIONALOP = '>=' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bge    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticUnsignedLess ; RELATIONALOP = '<' '<' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         blo    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticUnsignedGreater ; RELATIONALOP = '>' '>' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bhi    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticUnsignedLessEqual ; RELATIONALOP = '<' '/' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bls    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticUnsignedGreaterEqual ; RELATIONALOP = '>' '/' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bhs    SemanticTrue     b/ relationship is true
         bra    SemanticFalse    b/ relationship is false

SemanticRelation ; RELATION = SUM RELATIONALOP SUM ;
         cmpd   Semantic3rdValue compare to 2nd operand (ignored by ...Sum and ...Product)
SemanticSum ; SUM = SUM ADDOP PRODUCT ;
SemanticProduct ; PRODUCT = PRODUCT MULTOP TERM ;
         jmp    [Semantic2ndValue,x]  Invoke relational test routine
         page
SemanticSaveOperatorAddress ; push return address as result
         puld                    = result of semantic function
         rts

SemanticOrValues ; EXP = EXP '!' CONJUNCTION ;
         ora    Semantic3rdValue,x
         orb    Semantic3rdValue+1,x
         rts

SemanticAndValues; CONJUNCTION = CONJUNCTION '&' RELATION ;
         anda   Semantic3rdValue,x
         andb   Semantic3rdValue+1,x
         rts

SemanticAdd ; ADDOP = '+' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         addd   Semantic3rdValue,x compute sum
         rts

SemanticSubtract ; ADDOP = '-' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         subd   Semantic3rdValue,x compute difference
         rts

SemanticExclusiveOr ; ADDOP = '!!' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         eord   Semantic3rdValue,x compute logical exclusive 'or'
         rts
         page
SemanticMultiply ; MULTOP = '*' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bra    Notimplemented

SemanticQuotient ; MULTOP = '/' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bra    Notimplemented

SemanticRemainder ; MULTOP = '\' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bra    Notimplemented

SemanticCoveredQuotient ; MULTOP = '/' '/' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bra    Notimplemented

SemanticShift ; MULTOP = '#' '#' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         bra    Notimplemented

NotImplemented
         jmp   SemanticError
         page
SemanticNegate ; UNARYOP = '-' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         negd                    and do it
         rts

SemanticComplementValue ; UNARYOP = '\' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         comd
         rts

SemanticWordIndirect ; UNARYOP = '@' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         jsr    fetchword     then get desired word from user space
         rts

SemanticRelocate ; UNARYOP = '.' ;
         bsr    SemanticSaveOperatorAddress push return address as result
         jsr    IDB:getcurrentmodulebaseaddresstoD
         addd   Semantic2ndValue,x add value of OPERAND
         rts

SemanticUnaryTerm ; TERM = UNARYOP TERM ;
         ldd    Semantic2ndvalue,x get value to operate on
         jmp    [Semantic1stvalue,x] invoke operator routine


SemanticByteIndirect ; TERM = OPERAND '->' ;
         jmp   fetchByte      then get byte that is selected
         tfr    a,b
         clra                 extend to 16 bits
         rts

SemanticInvokeAssyWithParameter ; TERM = OPERAND '(' EXP ')' ;
         ldd    Semantic3rdValue,x   get value of argument for Assy routine
SemanticInvokeAssy ; TERM = OPERAND '(' ')' ;
         jmp    [Semantic1stArg,x] invoke user assembly routine
*        User assembly code returns via RTS with value in (D)
*??? should this trigger a routine in the space being debugged or the
*** the space in which the debugger lives? I think the former, so this is wrong
         page
SemanticSymbolValue ; OPERAND = SYMBOL ;
         ldx    CurrentSymbolTable specify the currently selected symbol table
         jsr    IDB:FindSymbolValue go get value from symbol table
         rts

SemanticOtherModuleSymbolValue ; OPERAND = MODULESELECTOR '.' SYMBOL ;
         ldx    Semantic1stValue,x get symbol table selector
         ldd    Semantic3rdValue,x and pointer to symbol name
         jsr    IDB:FindSymbolValue go get value from selected symbol table

*** These routines don't belong here!
SemanticModuleSelector ; MODULESELECTOR = SYMBOL ;
         jsr    IDB:FindSymbolTable using Symbol @ D to specify which one
**** returns symbol table selector in (D)
         rts

SemanticSelectSymbolTable ; COMMAND = MODULESELECTOR ';S' ;
         std    CurrentSymbolTable save moduleselector value
         rts

***** Note: parser mechanism can:
***** a) implement 'don't do semantics' (i.e., syntax check only!)
*****    by simply not calling the semantic routines
***** b) can always pick up Semantic1stValue and pass in (D)
*****    the semantic routine can ignore it if not needed!
***** The code in this section assumes both of these have taken place!
**** end DONTBELONG

SemanticValueLocationCounter ; OPERAND = '*' ;
         ldd   OpenCellLocaton
         rts

SemanticIterationCount ; OPERAND = '%' ;
         ldx    LastBreakPoint   Get pointer to last breakpoint hit
         beq    SemanticError    b/ no breakpoint hit recently
         ldd    Break:IterationCount,x
         rts

SemanticModuleBaseValue ; OPERAND = '.' ;
         jmp    IDB:getcurrentmodulebaseaddresstoD

SemanticParenthesizedExp ; OPERAND = '(' EXP ')' ;
         ldd    Semantic2ndValue,x use value of 2nd token as result
         rts

************************ ;P if no most recent bkpt = ;G
LIst of semantic routines required for debugger
SemanticProcessCommands ; COMMAND = UNSAVABLECOMMAND
*        Command is syntactically correct, rescan and process!
         com   DoSemanticsFlag         did we process the semantics this time ?
         beq   GetNewInput             Scan new input w/o doing semantics
         jmp   ParseInputStream        go rescan input; this time do semantics

SemanticDisplayInstruction ; COMMAND = INSTRUCTION '=?' ;
*        Display an assembled instruction

SemanticDisplayFloatMode ; COMMAND = ';F' ;

SemanticListDisplacedRange ; COMMAND = EXP ',' ',' EXP ;
SemanticListRange ; COMMAND = EXP ',' EXP '?' ;

SemanticLongOpcode ; INSTRUCTION = OPLONG ;

SemanticLongIndexReqd ; INDEXMODE = '>' INDIRECTINDEX ;

SemanticInherentOpcode ; INSTRUCTION = OPWITHINHERENTOPERAND ;

SemanticRelocateSymbol ; OPERAND = '.' SYMBOL ;

SemanticRelocateValue ; OPERAND = '.' NUMBER ;

SemanticIndirect ; TERM = '@' TERM ;

SemanticCloseLocation ; UNSAVEABLECOMMAND = <CR> ;

SemanticIndexedExamine ; COMMAND = EXP ',' REGISTER '?' ;

SemanticSetBreakPoint ; COMMAND = EXP ';B' ;

SemanticSetCondBkpt ; COMMAND = EXP COMMANDSELECTOR ';B' ;

SemanticShowBkpts ; COMMAND = ';B' ;

SemanticProceed ; COMMAND = ';P' ;

SemanticProceedIf ; COMMAND = EXP ';P' ;

SemanticSetReadBkpt ; COMMAND = EXP ';R' ;

SemanticSetCondReadBkpt ; COMMAND = EXP COMMANDSELECTOR ';R' ;

SemanticSetWriteBkpt ; COMMAND = EXP ';W' ;

SemanticSetCondWriteBkpt ; COMMAND = EXP COMMANDSELECTOR ';W' ;

SemanticSetExecRangeBkpt ; COMMAND = EXP ',' EXP ';B' ;

SemanticSetExecRangeCondBkpt ; COMMAND = EXP ',' EXP COMMANDSELECTOR ';B' ;

SemanticSetReadRangeBkpt ; COMMAND = EXP ',' EXP ';R' ;

SemanticSetReadRangeCondBkpt ; COMMAND = EXP ',' EXP COMMANDSELECTOR ';R' ;

SemanticSetWriteRangeBkpt ; COMMAND = EXP ',' EXP ';W' ;

SemanticSetWriteRangeCondBkpt ; COMMAND = EXP ',' EXP COMMANDSELECTOR ';W' ;

SemanticShowTraceHistory ; COMMAND = ';T' ;

SemanticTraceInstructions ; COMMAND = EXP ';T' ;

SemanticPositionCursor ; COMMAND = '@' '(' EXP ',' EXP ')' ;

SemanticCallSubroutine ; COMMAND = EXP ';C' ;

SemanticMoveBlock ; COMMAND = EXP ',' EXP ',' EXP ';M' ;

SemanticOpenBinaryFile ; COMMAND = TEXT ';B' ;

SemanticOpenFile ; COMMAND = TEXT ';F' ;

SemanticSetBaseOffset ; COMMAND = EXP ';O' ;

SemanticSetBigOffset ; COMMAND = EXP ',' EXP ';O' ;

SemanticSetClusterOffset ; COMMAND = EXP ',' ';O' ;

SemanticOpenMemory ; COMMAND = ';M' ;

SemanticFetchSymbolTable ; COMMAND = TEXT ';S' ;

SemanticDeselectSymbolTable ; COMMAND = ';S' ;

SemanticSetSymbol ; COMMAND = SYMBOL ':=' EXP ;

SemanticSetSymbolInModule ; COMMAND = SYMBOL '.' SYMBOL ':=' EXP ;

SemanticForgetSymbol ; COMMAND = SYMBOL ';F' ;

SemanticShowMatches ; COMMAND = SYMBOL ';Q' ;

SemanticQuitDebugging ; COMMAND = ';Q' ;

SemanticCreateLogfile ; COMMAND = TEXT ';O' ;

