*
*       c_lmul  long signed multiply
*
*       multiplies two long operands on the stack and returns the
*       result on the stack with no garbage.
*
*       Translated from the Unix version by J.A.Lydiatt 01Oct87.
*
        xdef    _c%lmul
_c%lmul:
        movem.l d0-d3,-(a7)     ;save registers
        move.l  20(a7),d0       ;get parameter 1
        move.w  d0,d2
        move.w  d0,d1
        ext.l   d1
        swap    d1
        swap    d0
        sub.w   d0,d1
        move.w  26(a7),d0       ;get msw of parameter 2
        move.w  d0,d3
        ext.l   d3
        swap    d3
        sub.l   24(a7),d3       ;subtract lsw of parameter 2
        muls    d0,d1
        muls    d2,d3
        add.w   d1,d3
        muls    d2,d0
        swap    d0
        sub.w   d3,d0
        swap    d0
        move.l  d0,24(a7)
        move.l  16(a7),20(a7)   ;move return address
        movem.l (a7)+,d0-d3     ;restore registers
        addq.w  #4,a7           ;adjust stack
        rts
*
*       _c%switch - execute c switch statement
*
*       the switch table is encoded as follows:
*
*               long    label1,case1
*               long    label2,case2
*               long    label3,case3
*               ... for all cases
*               long    0,defaultcase
*
*       the case variable is passed in d0
*
        xdef    _c%switch
_c%switch:
        move.l  (a7)+,a0        ;get table address
c_sw1:
        move.l  (a0)+,a1        ;get a label
        move.l  a1,d1           ;test it for default
        beq.s   c_sw2           ;jump if default case
        cmp.l   (a0)+,d0        ;see if this case
        bne.s   c_sw1           ;next case if not
        jmp     (a1)            ;jump to case
c_sw2:
        move.l  (a0),a0         ;get default address
        jmp     (a0)            ;jump to default case
 
        end
