home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / source / kiss.asm < prev    next >
Encoding:
Assembly Source File  |  1991-08-31  |  11.3 KB  |  483 lines

  1.     page    132,63,1,1
  2.     opt    rc
  3.     title    'KISS protocol handling'
  4.  
  5. ;***************************************************************
  6. ;* KISS.ASM -- KISS protocol interface and SCI drivers           *
  7. ;*                                   *
  8. ;* Provides interrupt based SCI handling, data buffering       *
  9. ;* and KISS protocol handling.                       *
  10. ;*                                   *
  11. ;* KISS protocol handling is based on article               *
  12. ;*    Chepponis, M., Karn, P.:                   *
  13. ;*    "The KISS TNC: A simple Host-to-TNC communications     *
  14. ;*     protocol",                                            *
  15. ;*    Proc. of the sixth ARRL computer networking cnf., 1988 *
  16. ;*                                   *
  17. ;* This module uses registers as follows:               *
  18. ;*  r1 - read queue tail ptr                       *
  19. ;*  r4 - general purpose                       *
  20. ;*  r5 - write queue head ptr                       *
  21. ;*                                   *
  22. ;* Copyright (C) 1990, 1991 by Alef Null. All rights reserved. *
  23. ;* Author(s): Jarkko Vuori, OH2LNS                   *
  24. ;* Modification(s):                           *
  25. ;*  1991-Jun: corrected FEND TFEND, FEND TFESC bug           *
  26. ;***************************************************************
  27.  
  28.     nolist
  29.     include 'ioequlc'
  30.     list
  31.  
  32.     section Kiss
  33.     xdef    baud
  34.     xdef    sci_ini,sci_rec,sci_err,sci_xmt
  35.     xdef    rdhost,tsthost
  36.     xdef    wrhost,endfrm,rejfrm
  37.     xref    kickx
  38.     xref    m_scr,m_sccr,m_srxl,m_ssr,m_tie,m_stxl
  39.  
  40.     org    p:
  41.  
  42.     nolist
  43.     include 'macros'
  44.     list
  45.  
  46. ; Serial interface parameters
  47. baud    equ    9600
  48.  
  49. ; KISS special characters
  50. fend    equ    $c0
  51. fesc    equ    $db
  52. tfend    equ    $dc
  53. tfesc    equ    $dd
  54.  
  55. ; Xmitter status flags
  56. idle    equ    0
  57.  
  58.  
  59. ;****************************
  60. ;*    SCI initialization    *
  61. ;****************************
  62. sci_ini
  63. ; initialize SCI
  64.     IF    !DEBUG
  65.     movep            #$2b02,x:m_scr        ; async 8,n,1
  66.     movep            #20736000/(2*2*16*baud),x:m_sccr
  67.     ELSE
  68.     movep            #$2b02,x:m_scr        ; async 8,n,1
  69.     movep            #20736000/(10*2*2*16*baud),x:m_sccr
  70.     ENDIF
  71. ; initialize receiving queue handling
  72.     movi    str0,x:<rstate
  73.     movi    0,x:<rfrmcnt
  74.     movi    inbuf,x:<rhead
  75.     move            #inbuf,r1
  76.     move            #inqlen-1,m1
  77.     movi    $1,x:<rstatus                ; receiver idling
  78. ; initialize sending queue handling
  79.     movi    stx0,x:<xstate
  80.     movi    0,x:<xfrmcnt
  81.     move            #outbuf,r5
  82.     move            #outqlen-1,m5
  83.     move            r5,x:<xohead
  84.     movi    outbuf,x:<xtail
  85.     movi    $1,x:<xstatus                ; xmitter idling
  86.  
  87.     rts
  88.  
  89.  
  90. ;****************************
  91. ;*   SCI receive interrupt  *
  92. ;****************************
  93. sci_rec
  94. ; save registers to be used
  95.     enter    scir
  96.     stor    scirr,4
  97. ; read received character
  98.     movep            x:m_srxl,x0
  99.     clr    a        x:<rstate,r4
  100.     clr    b        #fend,a1
  101.     jmp    (r4)                    ; determine what to do for it
  102.  
  103. ; --- State 0, waiting for FEND
  104. str0    cmp    x0,a        #str1,b1
  105.     jne    <scr_end                ; we didn't see FEND, keep looking
  106.     move    b1,x:<rstate                ; FEND found, change state
  107.     jmp    <scr_end
  108.  
  109. ; --- State 1, we have seen FEND, look for the command byte
  110. str1    cmp    x0,a
  111.     jeq    <scr_end                ; just another FEND, keep looking for cmd
  112. ; analyze command byte
  113.     clr    a
  114.     cmp    x0,a        #str2,b1
  115.     jeq    <str1c                    ; cmd 0, data will follow
  116. ; check for command 1,2,3,4,5,6
  117. str1a    move            #parcnt,a1
  118.     cmp    x0,a        #str4,b1
  119.     jlt    <str1b
  120. ; valid cmd, store it and change state
  121.     move            b1,x:<rstate
  122.     move            x0,x:<cmd
  123.     jmp    <scr_end
  124. ; invalid cmd, look for FEND
  125. str1b    move            #str0,b1
  126.     move            b1,x:<rstate
  127.     jmp    <scr_end
  128. ; start a new frame
  129. str1c    move            b1,x:<rstate
  130.     move            x:<rhead,b1         ; backup current rhead
  131.     move            b1,x:<rohead
  132.     jmp    <scr_end
  133.  
  134. ; --- State 2, data to follow
  135. str2    cmp    x0,a        #fesc,b1            ; check if end of frame
  136.     jeq    <strend
  137.     cmp    x0,b                    ; check if escape
  138.     jeq    <stresc
  139. ; store the character to the queue
  140. store    move            #inqlen-1,m4
  141.     move            x:<rhead,r4
  142.     move            r1,b1
  143.     move            x0,p:(r4)+
  144.     move            r4,x1            ; check buffer full
  145.     cmp    x1,b        x0,a
  146.     jeq    <strful
  147. ; check if end of frame
  148.     move            r4,x:<rhead
  149.     tst    a
  150.     jpl    <scr_end
  151.     ori    #$02,mr
  152.     nop
  153.     nop
  154.     nop
  155.     nop
  156.     move            x:<rfrmcnt,r4
  157.     andi    #$fe,mr                 ; do not allow SCI interrupts yet
  158.     clr    a        (r4)+            ; yeah, increment frame counter
  159.     move            r4,x:<rfrmcnt
  160. ; check if receiver sleeping
  161.     bclr    #idle,x:<rstatus
  162.     jcc    <scr_st0
  163.     jsr    <kickx                    ; yup, kick receiver
  164.     jmp            <scr_st0
  165. ; queue full, discard the current frame
  166. strful    move            x:<rohead,b1        ; restore rhead
  167.     move            b1,x:<rhead
  168.     jmp    <scr_st0                ; enter FEND hunt
  169. ; end of frame, store negative value and increment frame counter
  170. strend
  171.     move            #-1,x0
  172.     jmp    <store
  173. ; escape character found
  174. stresc    move            #str3,b1            ; enter FESC found state
  175.     move            b1,x:<rstate
  176.     jmp    <scr_end
  177.  
  178. ; --- State 3, saw FESC, expecting TFESC or TFEND
  179. str3    move            #tfesc,b1            ; check if TFESC
  180.     cmp    x0,b        #tfend,a1
  181.     jeq    <str3esc
  182.     cmp    x0,a        #str2,b1            ; check if TFEND
  183.     jeq    <str3end
  184.     move            b1,x:<rstate        ; something wrong has happened,
  185.     jmp    <scr_end                ; go back to the data receiving mode
  186. ; we have seen TFESC after an FESC, write an FESC
  187. str3esc move            #str2,b1
  188.     move            b1,x:<rstate
  189.     move            #>fesc,x0
  190.     jmp    <store
  191. ; we have seen TFEND after an FESC, write an FEND
  192. str3end move            #str2,b1
  193.     move            b1,x:<rstate
  194.     move            #>fend,x0
  195.     jmp    <store
  196.  
  197. ; --- State 4, get command data
  198. str4    move            x:<cmd,n4            ; enter byte to its place in parameter area
  199.     move            #params-1,r4
  200. ; check if we need special scaling
  201.     clr    a        x:<cmd,x1
  202.     move            #<(txdly-params+1),a1
  203.     cmp    x1,a        #<(slotime-params+1),a1
  204.     jeq    <str4a
  205.     cmp    x1,a        #<(txtail-params+1),a1
  206.     jeq    <str4a
  207.     cmp    x1,a        #<(gain-params+1),a1
  208.     jeq    <str4a
  209.     cmp    x1,a        #>@cvi(@pow(2,15-1)),x1
  210.     jne    <str4b
  211. ; yes, gain scaling (shift left 15 bits)
  212.     mpy    x0,x1,a
  213.     move            a0,x:(r4+n4)
  214.     jmp    <scr_st0
  215. ; yes, time scaling
  216. str4a    move            #>baud/100,x1
  217.     mpy    x0,x1,a
  218.     asr    a                    ; interger multiply correction
  219.     move            a0,x:(r4+n4)        ; product in low order word
  220.     jmp    <scr_st0
  221. ; no scaling needed, just store the value
  222. str4b    move            x0,x:(r4+n4)
  223.  
  224. ; go back to FEND hunt state
  225. scr_st0 movi    str0,x:<rstate
  226.  
  227. ; restore registers
  228. scr_end rclr    scirr,4
  229.     leave    scir
  230.  
  231.  
  232. ;****************************
  233. ;*  SCI receive with errors *
  234. ;*      interrupt        *
  235. ;****************************
  236. sci_err
  237. ; save registers to be used (b1)
  238.     move            b1,y:<scir
  239. ; clear SCI interrupts
  240.     movep            x:m_ssr,b1
  241.     movep            x:m_srxl,b1
  242. ; restore frame
  243.     move            x:<rohead,b1        ; restore rhead
  244.     move            b1,x:<rohead
  245. ; restore registers (b1)
  246.     move            y:<scir,b1
  247.  
  248.     rti
  249.  
  250.  
  251. ;****************************
  252. ;*   SCI xmitter interrupt  *
  253. ;****************************
  254. sci_xmt
  255. ; save registers to be used
  256.     enter     scix
  257.     stor    scixr,4
  258. ; jump to the current state
  259.     move            x:<xstate,r4
  260.     nop
  261.     jmp    (r4)
  262.  
  263. ; --- State 0, start sending KISS-packet
  264. stx0    move            x:<xfrmcnt,a
  265.     tst    a
  266.     jeq    <stx0no
  267. ; there is data in the queue, begin a new frame
  268.     movi    stx1,x:<xstate
  269.     move            #>fend,x0
  270.     jmp    <xbyte
  271. ; there are no data left in the queue, stop xmitter
  272. stx0no    bset    #idle,x:<xstatus
  273.     bclr    #m_tie,x:m_scr
  274.     jmp    <scx_end
  275.  
  276. ; --- State 1, send KISS command byte (always data command)
  277. stx1    movi    stx2,x:<xstate
  278.     move            #>0,x0
  279.     jmp    <xbyte
  280.  
  281. ; --- State 2, send KISS data
  282. stx2
  283. ; get a new character from the queue
  284.     move            x:<xtail,r4
  285.     move            #outqlen-1,m4
  286.     nop
  287.     move            p:(r4)+,a
  288.     tst    a        r4,x:<xtail
  289.     jpl    <stx2dat
  290. ; end of frame, decrement frame counter
  291.     ori    #$02,mr
  292.     nop
  293.     nop
  294.     nop
  295.     nop
  296.     move            x:<xfrmcnt,r4
  297.     andi    #$fe,mr                 ; do not allow SCI interrupts yet
  298.     move            (r4)-
  299.     move            r4,x:<xfrmcnt
  300. ; and then send frame end flag
  301.     movi    stx0,x:<xstate
  302.     move            #>fend,x0
  303.     jmp    <xbyte
  304. ; new data found, check for special characters
  305. stx2dat move            #>fesc,x0
  306.     cmp    x0,a        #>tfesc,x0            ; check if FESC
  307.     jeq    <stx2spe
  308.     move            #>fend,x0
  309.     cmp    x0,a        #>tfend,x0            ; check if FEND
  310.     jeq    <stx2spe
  311.     move            a,x0
  312.     jmp    <xbyte                    ; normal character out
  313. ; special character, enter escaped mode
  314. stx2spe movi    stx3,x:<xstate
  315.     move            x0,x:<xtmp
  316.     move            #>fesc,x0
  317.     jmp    <xbyte
  318.  
  319. ; --- State 3, escaped mode
  320. stx3    movi    stx2,x:<xstate
  321.     move            x:<xtmp,x0
  322.     jmp    <xbyte
  323.  
  324. ; send x0 to SCI
  325. xbyte    movep            x0,x:m_stxl
  326.  
  327. ; restore registers
  328. scx_end rclr    scixr,4
  329.     leave    scix
  330.  
  331.  
  332. ;****************************
  333. ;*   Read from host buffer  *
  334. ;****************************
  335. ;   x0 byte read from the queue
  336. ; returns with N bit set when frame end detected
  337. ; Note! this routine must not be called when you
  338. ;    are not sure if there are data left
  339. rdhost    move            p:(r1)+,a            ; get next byte from the queue
  340.     tst    a        x:<rfrmcnt,r0        ; decrement byte counter
  341.     jpl    <rdhend
  342. ; end of frame, decrement frame counter
  343.     move            (r0)-
  344.     move            r0,x:<rfrmcnt
  345.  
  346. rdhend    move            a,x0
  347.     rts
  348.  
  349.  
  350. ;****************************
  351. ;*   Test if data in queue  *
  352. ;****************************
  353. ; returns with Zero if there are no data available
  354. tsthost move            x:<rfrmcnt,a
  355.     tst    a
  356.     jne    <tstend
  357. ; no data, receiver idling
  358.     bset    #idle,x:<rstatus
  359. tstend    rts
  360.  
  361.  
  362. ;****************************
  363. ;* Write to the host buffer *
  364. ;****************************
  365. ;   x0 byte written to the queue
  366. wrhost    move            x0,p:(r5)+
  367. ; check if buffer full
  368.     move            x:<xtail,a
  369.     move            r5,x1
  370.     cmp    x1,a
  371.     move            x0,a            ; &&&&&
  372.     jeq    <wrfull
  373. ; no, check if this was an end of frame
  374.     tst    a        x:<xfrmcnt,r0
  375.     jpl    <wrend
  376. ; yes, store a new frame beginning
  377.     move            r5,x:<xohead
  378. ; increment frame counter
  379.     move            (r0)+
  380.     move            r0,x:<xfrmcnt
  381. ; check for idling xmitter
  382.     bclr    #idle,x:<xstatus
  383.     jcc    <wrend
  384. ; xmitter was idling, kick it up
  385.     movi    stx1,x:<xstate
  386.     movep            #fend,x:m_stxl
  387.     bset    #m_tie,x:m_scr
  388.     rts
  389. ; queue full, discard the current frame
  390. wrfull    move            x:<xohead,r5
  391.  
  392. wrend    rts
  393.  
  394.  
  395. ;****************************
  396. ;*  End the current frame   *
  397. ;****************************
  398. endfrm    move            #-1,x0
  399.     jmp    <wrhost
  400.  
  401.  
  402. ;****************************
  403. ;* Reject the current frame *
  404. ;****************************
  405. rejfrm    jmp    <wrfull
  406.  
  407.  
  408. ;****************************
  409. ;*     DATA - AREA        *
  410. ;****************************
  411.  
  412.     org    x:
  413.  
  414. ; KISS-to-data queue
  415. rfrmcnt ds    1                    ; how many frames in the queue
  416. rohead    ds    1                    ; start of the current frame
  417. rhead    ds    1
  418. rstatus ds    1
  419.  
  420. ; KISS decoder data
  421. rstate    ds    1                    ; KISS decoder state
  422. cmd    ds    1                    ; current KISS command
  423.  
  424. ; data-to-KISS queue
  425. xfrmcnt ds    1                    ; how many frames in the queue
  426. xohead    ds    1                    ; start of the current frame
  427. xtail    ds    1
  428. xstatus ds    1                    ; xmitter status
  429.  
  430. ; KISS coder data
  431. xstate    ds    1                    ; KISS coder state
  432. xtmp    ds    1                    ; temporary store
  433.  
  434.     endsec
  435.  
  436. ;****************************
  437. ;*     MODEM PARAMETERS     *
  438. ;****************************
  439.     section ModemPar
  440.     xdef    params,parcnt,txdly,P,slotime,txtail,fuldplx,gain
  441.  
  442.     org    x:
  443.  
  444. ;  every time delay is in 1/baud s
  445. params    equ    *
  446.     IF    !DEBUG
  447. txdly    dc    baud/100*50                ; 500 mS
  448. P    dc    63
  449. slotime dc    baud/100*1                ;  10 mS
  450. txtail    dc    baud/100*1                ;  10 mS
  451. fuldplx ds    1
  452. gain    dc    0.05
  453.     ELSE
  454. txdly    dc    10
  455. P    dc    63
  456. slotime dc    10
  457. txtail    dc    10
  458. fuldplx ds    1
  459. gain    dc    0.1
  460.     ENDIF
  461. parcnt    equ    *-params
  462.  
  463.     endsec
  464.  
  465. ;****************************
  466. ;*    DATA QUEUE BUFFERS    *
  467. ;****************************
  468.     section KissQue
  469.     xdef    inqlen,outqlen
  470.     xdef    outbuf,inbuf
  471.  
  472.     org    p:
  473.  
  474. inqlen    equ    2048
  475. outqlen equ    1024
  476.  
  477. outbuf    ds    outqlen
  478. inbuf    ds    inqlen
  479.  
  480.     endsec
  481.  
  482.     end
  483.