Page 1 of 1

Ever try to catch a fly with tweezers?

Posted: November 24, 2003, 3:31 pm
by Adex_Xeda
That's what I feel like every time I use Assembly to program a com port!

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'




Posted: November 24, 2003, 3:36 pm
by noel
First post!

Posted: November 24, 2003, 3:39 pm
by Skogen
If I had that job...I'd shoot myself.

Posted: November 24, 2003, 3:39 pm
by Pahreyia
That looks like fun... And by fun I mean like root canal work.

Posted: November 24, 2003, 4:09 pm
by Seebs
This is exactly why I'm a people person and not a paste-eater.

I like paying you people to deal with that hell.

Posted: November 24, 2003, 4:14 pm
by Xouqoa
I had to take an Assembly class at UNT once.

Worst. Class. Ever.

Posted: November 24, 2003, 4:47 pm
by Ebumar
I like assembly language. I think it's fun. I'm telling the truth. It isn't simple I'll tell you that, but it is fun. To get all that code, go through it all, fix what isn't working. Flesh out whole documents of it. I don't know, it is just fun for me.

Posted: November 24, 2003, 5:35 pm
by Kylere
Why repeat code a call that has been made millions of times before??

Posted: November 24, 2003, 10:50 pm
by Canelek
I used to program Assembly on the C64 a long ass time ago... I still am not sure why...except for 1337 1 day warez, hah! /shame

Posted: November 25, 2003, 11:46 am
by vn_Tanc
Dealing with interfaces to the real world is the suck even when not doing it with assembler.
WHY you would want to do it with assembler is also beyond me :)

Posted: November 25, 2003, 12:14 pm
by Drolgin Steingrinder
i can lol at you for this.

Why, you ask?

Because I know, deep in my heart, with a conviction as firm as the most dedicated papist:

I will never, ever, have to do shit like that.

Isn't life great? :)

Posted: November 25, 2003, 12:19 pm
by Sargeras
JFC, and I thought Actionscript was bad.

Posted: November 25, 2003, 12:24 pm
by Kelshara
And this is why I transfered from CS to CIS back in the day..

Posted: November 25, 2003, 12:46 pm
by Adex_Xeda
Compare the above code to this visual basic code that has similar functionality:

Code: Select all

Private Sub Form_Load ()
   Dim Instring As String
   MSComm1.CommPort = 1
   MSComm1.Settings = "9600,N,8,1"
   MSComm1.InputLen = 0
   MSComm1.PortOpen = True
   MSComm1.Output = "ATV1Q0" & Chr$(13) ' Ensure that 
   Do
      DoEvents
   Buffer$ = Buffer$ & MSComm1.Input
   Loop Until InStr(Buffer$, "OK" & vbCRLF)
   MSComm1.PortOpen = False
End Sub
To say assembly is verbose is a profane understatement.

Posted: November 25, 2003, 1:04 pm
by Shaerra
Assembly is verbose

Posted: November 25, 2003, 1:12 pm
by Sabek
Adex_Xeda wrote:Compare the above code to this visual basic code that has similar functionality:

Code: Select all

Private Sub Form_Load ()
   Dim Instring As String
   MSComm1.CommPort = 1
   MSComm1.Settings = "9600,N,8,1"
   MSComm1.InputLen = 0
   MSComm1.PortOpen = True
   MSComm1.Output = "ATV1Q0" & Chr$(13) ' Ensure that 
   Do
      DoEvents
   Buffer$ = Buffer$ & MSComm1.Input
   Loop Until InStr(Buffer$, "OK" & vbCRLF)
   MSComm1.PortOpen = False
End Sub
To say assembly is verbose is a profane understatement.
But assembly is faster than VB. You have to make the choice between ease of use, and speed of running.

Posted: November 25, 2003, 1:26 pm
by vn_Tanc
Its a COM port! The fastest code in teh west will spend 99% of its time waiting :)

Posted: November 25, 2003, 1:44 pm
by noel
Kylere wrote:Why repeat code a call that has been made millions of times before??
Tell you what, genius. We'll give you some time to think about this, and then you can get back to us...

Posted: November 25, 2003, 6:39 pm
by Lohrno
Out of curiosity, what is it you are trying to accomplish in general? (I mean what's the project you are working on supposed to do?)

-=Lohrno

Posted: November 26, 2003, 4:00 am
by Adex_Xeda
I have a police car at work that's decked out with a bunch of wireless equipment and artifacts from earlier research projects. Inside the car, is a set of 6 motorola M68332 microprocessors daisy chained together via high speed serial ports.

My current job is to investigate if those microprocessors are worth saving. One way to find out if they're worth keeping is to learn how to program them and then convey what I learned to my coworkers who might use them.

In short I'm testing these chips out to see if they can be used to help support our research.

Posted: November 26, 2003, 4:12 am
by Lohrno
Adex_Xeda wrote:I have a police car at work that's decked out with a bunch of wireless equipment and artifacts from earlier research projects. Inside the car, is a set of 6 motorola M68332 microprocessors daisy chained together via high speed serial ports.

My current job is to investigate if those microprocessors are worth saving. One way to find out if they're worth keeping is to learn how to program them and then convey what I learned to my coworkers who might use them.

In short I'm testing these chips out to see if they can be used to help support our research.
Ahhhh...that sounds pretty cool. ;)

Painful...but cool anyways. ;)

-=Lohrno