;;****************************************************************************
;;                      bridge.asm          bridge.asm
;;****************************************************************************
;;
;;  Copyright (C) 1989 Northwestern University, Vance Morrison
;;
;;
;; Permission to view, compile, and modify for LOCAL (intra-organization) 
;; USE ONLY is hereby granted, provided that this copyright and permission 
;; notice appear on all copies.  Any other use by permission only.
;;
;; Northwestern University makes no representations about the suitability 
;; of this software for any purpose.  It is provided "as is" without expressed 
;; or implied warranty.  See the copywrite notice file for complete details.
;;
;;*************************************************************************
;;
;; bridge.asm implemtents a simple two interface ethernet bridge
;;
;; AUTHOR: Vance Morrison
;; DATE:   5/24/89
;; ADDRESS: morrison@accuvax.nwu.edu
;;****************************************************************************

    dosseg
    .model small
    .stack 500h  
    JUMPS                       ;; deal with long displacement
                                ;; jumps automaticly

;; small helper macro
MY_SET_MTU MACRO name, mtu
    if_&name&_mtu = mtu
ENDM

	include declare.inc

       .data
    db  'Copywrite (c) 1989, Vance Morrison, Northwestern University', 13,10, 0
    db  'VERSION 1.21 ', 0

        ; a place to put the command line
comline_count db 0 
comline       db 127 dup (0)        

baud_rate_div dw 0                      ;; used for remote bridging


;;************************************************************************
;; This routine converts the ASCII base ten number pointed to by SI and
;; returns the number in AX.  It also updates SI to point to the next
;; char in the string.  This routine skips preceeding space and stops
;; conversion at the first non-digit.  Clearly this routine can' handle
;; numbers up to 64K

ASCII_TO_BINARY_in_SI_out_AX_SI_const_BP_DI_ES MACRO
    local top_loop, next_char, conv_string, space_loop, done

    space_loop:
        mov CL, [SI]
        cmp CL, ' '         ; skip space
        jnz conv_string
        inc SI
        jmp space_loop
    conv_string:

    xor AX, AX
    xor CH, CH
    top_loop:
        sub CL, '0'         ; is it a digit
        jl done
        cmp CL, 9
        jg done

        mov DX, AX          ; AX = AX * 10
        shl AX, 1
        shl AX, 1
        add AX, DX
        shl AX, 1
        
        add AX, CX
    next_char:
        inc SI
    mov CL, [SI]
    jmp top_loop

    done:
ENDM


;;************************************************************************
    .code

    ;; insert code for all interfaces
    IRP idx,<1,2,3,4,5,6,7,8>
       WDE_REAL_DEFINE idx     
       I8250_REAL_DEFINE idx
       PKT_REAL_DEFINE idx     
       C507_REAL_DEFINE idx     
    endm

    DB_DEFINE           

bridge_start:
    ;; save the command line
    mov SI, 80h
    mov AX, @DATA 
    mov ES, AX
    mov DI, offset comline_count
    mov CX, 40h
    rep
    movsw

    mov AX, @DATA       ;; initialize data segment
    mov DS, AX
    cld                 ;; direction forward

        ; if this is a remote bridge
    ifdef i8250_declared
        mov SI, offset comline
        ASCII_TO_BINARY_in_SI_out_AX_SI_const_BP_DI_ES      ;; get the baud rate
        cmp AX, 0
        jnz not_default
            mov AX, 19200                   ;; 19.2 is the default
        not_default:
        shr AX, 1                           ;; compute the baud rate div
        mov BX, AX
        mov AX, 57600
        xor DX, DX
        div BX
        mov baud_rate_div, AX
    endif

    IRP idx,<1,2,3,4,5,6,7,8>       ;; call definition code
    if idx le num_dls
        WDE_DEFINE idx     

        BUFF_DEFINE %(idx*10+1)
        QUEUE_DEFINE %(idx*10+2)
        BUFF_DEFINE %(idx*10+3)
        QUEUE_DEFINE %(idx*10+4)
        Q_IF_DEFINE idx     
        SLIP_DEFINE idx     
        mov BX, baud_rate_div 
        I8250_DEFINE_in_BX idx, serial_fail

        PKT_DEFINE idx, packet_fail

        C507_DEFINE_out_AX idx, card_fail
    endif
    endm

    BDG_DEFINE %mybridge

    ;; start looking for packets
    big_loop:
    IRP idx,<1,2,3,4,5,6,7,8>
    local next
    if idx le num_dls
        BDG_IF_R_ACCESS_out_BX_CX_ES idx, next
        BDG_IF_R_FREE_const_BX_CX_BP_SI_DI_ES idx    ;; throw it away
        next:
    endif
    endm
    jmp big_loop

    card_fail:
        print_reg <error configuring ethernet card.  Code = >, AX
        jmp terminate

    packet_fail:
        print <error configuring packet driver>
        jmp terminate

    serial_fail:
        print <error configuring serial port>
    terminate:
        mov AH, 4CH
        int 21H
END bridge_start


