I have more gray hair now.
Bleh,,
Code: Select all
*******************************************************************************
* CONSTANT DECLARATIONS
*
QSMCR equ $FFFC00 ; D-18 Set stop/freeze mode
QILR equ $FFFC04 ; D-19 Set interrupt level
SCCR0 equ $FFFC08 ; D-20 baud rate selection
SCCR1 equ $FFFC0A ; D-20 SCI configuration
SCSR equ $FFFC0C ; D-22 SCI status flags
SCDR equ $FFFC0E ; D-23 SCI Data Register (RDR/TDR)
RDR equ SCDR+1
TDR equ RDR
vExitSCSR equ $4000
vExitSCDR equ $4002
vNewByte equ $4004
vCurSCDR equ $4006
vTargetStr equ $4020
vFoundCmdStr equ $4024
vStrTypeFND equ $4028
org $4010
vByteBuff ds.b $C ;12-byte input buffer $4010->$401B
*******************************************************************************
* SCI Interrupt Service Routine - write to the SCI data register
*
org $6000
srISR bsr srRead ; Received byte stored in vCurSCDR
bsr srWrite ; Transmit vCurSCDR value
bsr srAddBuffer ; Add new character to input buffer
cmp.b #$0D,$401b ; Is newest FIFO input a <return> character?
bne mkExitISR ; Avoid unnecessary String searching
bsr srChk4Cmds ; Check FIFO input buffer for user commands
mkExitISR rte
*******************************************************************************
* MAIN
*
srMain org $5000
move.w #$2400,SR ;Switch to Supervisor Mode.
bsr srInit
mkMainloop bra mkMainloop
*******************************************************************************
* INITIALIZATION
*
* d0- Temporary variable used for clearing the SCSR
*
srInit
mkQSM_Setup move.w #$008F,QSMCR ; STOP = 0, SUPV = 1, IARB = b1111 Enable QSM (D-18)
move.w #$0540,QILR ; QSM priority = 5, Interrupt vector # = $40
move.l #$6000,$0100 ; Direct any 100 vector calls to address $6000
mkSCI_Setup move.w #$0000,SCCR1 ; disable txd, rxd
move.w SCSR,d0 ; clear rxd flags
move.w #$0037,SCCR0 ; 9600baud = 2^24 / (32 * $37)
ori.w #$002C,SCCR1 ; Enable, TE = RE = 1
clr vNewByte
bsr srClrBuff ; Fill the byte input buffer with zeros
clr d0
clr d1
clr d4
clr d5
clr d6
rts
*******************************************************************************
* Clear Buffer - This subroutine fills the input buffer
* - "vByteBuff" full of zeros
*
*
srClrBuff move.l #0,$4010
move.l #0,$4014
move.l #0,$4018
rts
*******************************************************************************
* SCI WRITE - write to the SCI data register
*
* d1- Used to check TC bit, and store to TDR
*
srWrite movem.l d1,-(SP)
mkTCbusy move.w SCSR,d1 ; prepare transmit complete test
and.w #$180,d1 ; Is TC idle? (bit 7 = 1)?
cmp.w #$180,d1
bne mkTCbusy ; Transmitter busy ignore interrupt
* ; TC = 0 -> Z = 1 -> Exit; or beq->Z=0 bne->Z=1
move.w vCurSCDR,d1 ; Load received byte to SCDR
move.b d1,TDR
movem.l (SP)+,d1
rts
*******************************************************************************
* SCI READ - read from SCI data register
* - the program operates fine without error checking.
*
srRead move.w SCSR,vNewByte ;temp store SCSR value
move.w SCDR,vCurSCDR ; Read from the RDR to get the new byte.
mkReadExit move.w SCSR,vExitSCSR ; Clear the interrupt causing registers
move.w SCDR,vExitSCDR ; before leaving the ISR.
rts
*******************************************************************************
* srAddBuffer - Add a character to a FIFO Read Buffer
*
* d0 - load new data to buffer
*
* a1 - Head boundary of FIFO buffer
* a2 - Tail boundary of FIFO buffer
* a3 - Previous value
* a4 - Next value
srAddBuffer movem.l d0-d7/a0-a7,-(SP)
movea.l #$4010,a1 ;Head Boundary of FIFO buffer ($4010) vByteBuff
movea.l #$401C,a2 ;Tail Boundary of FIFO buffer ($401C) 12 bytes
movea.l a1,a3 ;Move a3 to the front boundary byte
movea.l a1,a4 ;Move a4 to the next byte from the front
adda.l #1,a4 ;Move a4 to the next byte from the front
mkTestEnd cmp.l a2,a4 ;Exit Loop if a4 has reached the tail boundary
beq mkEndBuf
move.b (a4)+,(a3)+ ;Shift the right byte left one byte.
bra mkTestEnd ;then shift both pointeres right one byte
mkEndBuf move.w vCurSCDR,d0 ;after shifting all bytes in the FIFO left, insert..
move.b d0,-(a4) ;..the new byte from vCurSCDR into FIFO buffer
movem.l (sp)+,d0-d7/a0-a7
rts
*******************************************************************************
* srChangeBaud
*
* Change the baud rate generator to reflect the detected target string.
*
*
* The variable vStrTypeFND contains a number that references the desired
* baud change. This subroutine looks at that value and then changes the
* SCCR0 (baud)
*
*
* d0- Temporary variable used for clearing the SCSR
*
*
*
srChangeBaud movem.l d0,-(SP)
move.w #$0000,SCCR1 ; disable txd, rxd
move.w SCSR,d0 ; clear flags
cmp.l #$01,vStrTypeFND
bne mkCngBd1
move.w #$129e,SCCR0 ; 110baud = 2^24 / (32 * $129e)
mkCngBd1 cmp.l #$02,vStrTypeFND
bne mkCngBd2
move.w #$06d4,SCCR0 ; 300baud = 2^24 / (32 * $6d4)
mkCngBd2 cmp.l #$03,vStrTypeFND
bne mkCngBd3
move.w #$01b5,SCCR0 ; 1200baud = 2^24 / (32 * $1b5)
mkCngBd3 cmp.l #$04,vStrTypeFND
bne mkCngBd4
move.w #$00da,SCCR0 ; 2400baud = 2^24 / (32 * $da)
mkCngBd4 cmp.l #$05,vStrTypeFND
bne mkCngBd5
move.w #$006d,SCCR0 ; 4800baud = 2^24 / (32 * $6d)
mkCngBd5 cmp.l #$06,vStrTypeFND
bne mkCngBd6
move.w #$0037,SCCR0 ; 9600baud = 2^24 / (32 * $37)
mkCngBd6 cmp.l #$07,vStrTypeFND
bne mkCngBd7
move.w #$001b,SCCR0 ; 19200baud = 2^24 / (32 * $1b)
mkCngBd7 cmp.l #$08,vStrTypeFND
bne mkCngBd8
move.w #$000e,SCCR0 ; 38400baud = 2^24 / (32 * $0e)
mkCngBd8 cmp.l #$09,vStrTypeFND
bne mkCngBd9
move.w #$0009,SCCR0 ; 57600baud = 2^24 / (32 * $09)
mkCngBd9 cmp.l #$0a,vStrTypeFND
bne mkCngFIN
move.w #$0005,SCCR0 ; 115200baud = 2^24 / (32 * $05)
mkCngFIN ori.w #$002C,SCCR1 ; Re-enable, TE = RE = 1
movem.l (SP)+,d0
rts
*******************************************************************************
*srChk4Cmds
*
*Check the Input Buffer ($4010->401B) for potiential command strings
*
*<<<<<<TARGET STRINGS and MEMORY LOCATIONS>>>>>>
*CPU32Bug>md 7000 70b0
*00007000 0465 7869 7400 0000 0000 0000 0000 0000 .exit...........
*00007010 0862 6175 6420 3131 3000 0000 0000 0000 .baud 110.......
*00007020 0862 6175 6420 3330 3000 0000 0000 0000 .baud 300.......
*00007030 0962 6175 6420 3132 3030 0000 0000 0000 .baud 1200......
*00007040 0962 6175 6420 3234 3030 0000 0000 0000 .baud 2400......
*00007050 0962 6175 6420 3438 3030 0000 0000 0000 .baud 4800......
*00007060 0962 6175 6420 3936 3030 0000 0000 0000 .baud 9600......
*00007070 0A62 6175 6420 3139 3230 3000 0000 0000 .baud 19200.....
*00007080 0A62 6175 6420 3338 3430 3000 0000 0000 .baud 38400.....
*00007090 0A62 6175 6420 3537 3630 3000 0000 0000 .baud 57600.....
*000070A0 0B62 6175 6420 3131 3532 3030 0000 0000 .baud 115200....
*
*<<<<<<Example of what the Input FIFO buffer might look like>>>>>>>>
*CPU32Bug>md 4010 401b
*00004010 2020 2062 6175 6420 3330 300D baud 300.
*
*
*<<<<<<Variables>>>>>>>>
*
* a0- Address of the Current Target String
* d0- Keep count of how many strings have been searched.
*
srChk4Cmds movem.l d0/a0,-(SP)
move.l #$7000,a0 ;Point a0 at first target string 'See botton for string list'
move.l #0,d0 ;d0 tracks the number of searched target strings.
mkChk4L1 cmp.l #$70a0,a0 ;Check for all command strings
bgt mkChk4END ;No command strings detected exit sr
move.l a0,vTargetStr ;Load Target string for srChk4Str
bsr srChk4Str
cmp.l #1,vFoundCmdStr ;Did srChk4Str match up a target string?
beq mkChk4BChg ;Target string was found by srChk4Str
add.l #1,d0 ;Target string not found, check for another target string
add.l #$10,a0
bra mkChk4L1
mkChk4BChg cmp.l #0,d0 ;Is the matched target string the exit command?
beq srExit ;Exit command detected, Exit Program
move.l d0,vStrTypeFND ;Load up which target string was found for use by srChangBaud
bsr srChangeBaud
mkChk4END movem.l (sp)+,d0/a0
rts
*******************************************************************************
*srChk4Str
*
*Check the Input Buffer ($4010->401B) for a desired target string
*
*
* a0 - Pointer to the target string
* a1 - Pointer to the input buffer
*
* d0 - Temporary holder for comparison values
* d1 - End position for searching the target string.
* - d1 serves as a boundary for the decrementing search loop.
* d2 - Target String Size
*
srChk4Str movem.l d0-d2/a0-a1,-(SP)
move.l #$401B,a1 ;Load a1 with the Tail position of the Input FIFO Buffer
cmp.b #$0D,(a1) ;Has a <return> character been recorded in the newest FIFO buffer position?
bne mkStrNOFnd ;If <return> isn't at the first FIFO slot ($401B), don't bother searching any further.
sub.l #1,a1 ;Move the focus onto the next oldest Input FIFO Buffer character.
move.l (vTargetStr),a0 ;Load a0 Target String start position.
clr d2
move.b (a0),d2 ;Give d2 the lenght of the targetstring, length found at the start of the string constant
add.l d2,a0 ;a0 = target string start position + string size = tail position
move.l #$401b,d1 ;Calculate the Oldest FIFO value that might contain the first targetstring value.
sub.l d2,d1 ;d1 also doubles as the main search loop stop value. (buffer tail - TString width)
mk4StrL1 cmp.l d1,a1 ;Begin the single loop for this subroutine
blt mkStrFound ;If the two values are equal, the target string was matched.
move.b (a0),d0 ;Compare a character from the FIFO buffer to a character in the target string.
cmp.b (a1),d0 ;If they don't match, the target string wasn't found for this ...
bne mkStrNOFnd ;...calling of the subroutine.
sub.l #1,a0 ;The two string characters matched, decrement both string pointers ...
sub.l #1,a1 ;... and check the next oldest character pair.
bra mk4StrL1
mkStrFound move.l #1,vFoundCmdStr ;Target String Found, Send a postive Flag out of subroutine
bra mkExit4Str
mkStrNOFnd move.l #0,vFoundCmdStr ;Target String not Found, Send a negative flag out of Subroutine
mkExit4Str movem.l (sp)+,d0-d2/a0-a1 ;Restore previous register values before leaving.
rts
*********************************************************************************************
* EXIT - exit the program
*
srExit move.w #$0000,QILR ; Shut Down the SCI to reduce debbugging errors
bclr #2,SCCR1 ; disable, TE = RE = 1
bclr #3,SCCR1
bclr #5,SCCR1
bclr #6,SCCR1
trap #15
dc.w $0063
end
***********************************************************************************************
* Reference
*
*mkTCbusy move.w SCSR,d1 ; prepare transmit complete test
* btst #7,d1 ; Is TC idle? (bit 7 = 1)?
* beq mkTCbusy ; Transmitter busy ignore interrupt
* ; TC = 0 -> Z = 1 -> Exit; or beq->Z=0 bne->Z=1
*
* $40XX 1011 1213 1415 1617 1819 1A1B
* 0000 0000 0000 0032 3430 300D" = "2400<enter>"
*
* 0000 0000 0031 3135 3230 300D" = "115200<enter>"
* 0000 0000 0000 0031 3230 300D" = "1200<enter>"
* 0000 0000 0000 3139 3230 300D" = "19200<enter>"
* 0000 0000 0000 3338 3430 300D" = "38400<enter>"
* 0000 0000 0000 0034 3830 300D" = "4800<enter>"
* 0000 0000 0000 3537 3630 300D" = "57600<enter>"
* 0000 0000 0000 0039 3630 300D" = "9600<enter>"
*
org $7000
exitstring dc.b 4, 'exit'
org $7010
BaudStr1 dc.b 8, 'baud 110'
org $7020
BaudStr2 dc.b 8, 'baud 300'
org $7030
BaudStr3 dc.b 9, 'baud 1200'
org $7040
BaudStr4 dc.b 9, 'baud 2400'
org $7050
BaudStr5 dc.b 9, 'baud 4800'
org $7060
BaudStr6 dc.b 9, 'baud 9600'
org $7070
BaudStr7 dc.b 10, 'baud 19200'
org $7080
BaudStr8 dc.b 10, 'baud 38400'
org $7090
BaudStr9 dc.b 10, 'baud 57600'
org $70a0
BaudStrA dc.b 11, 'baud 115200'



