Category : Network Files
Archive   : PKTD11A.ZIP
Filename : EXOS205.ASM

 
Output of file : EXOS205.ASM contained in archive : PKTD11A.ZIP
version equ 1

include defs.asm

; a driver for the EXOS 205 Ethernet controller by Dirk Koeppen ([email protected])

; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, version 1.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


public int_no
public driver_class, driver_type, driver_name, driver_function
public parameter_list
public usage_msg
public copyright_msg
public parse_args
public print_parameters

; inform 82586.asm that we have a larger amount of memory
SEG586 equ 0fh

; equates for controlling EXOS 205 i/o ports
P_INTR EQU 0 ; interrupt EXOS 205
P_CTRL1 EQU 2 ; control port 1
P1_186 EQU 00000001b ; enable 80186
P1_586 EQU 00000010b ; enable 82586
P1_A12 EQU 00000100b ; address bit 12 of EXOS memory
P1_NET EQU 00001000b ; enable net (disable loopback)
P1_A13 EQU 00010000b ; address bit 13 of EXOS memory
P1_CA EQU 00100000b ; do a channel attention by host
P1_A14 EQU 01000000b ; address bit 14 of EXOS memory
P1_A15 EQU 10000000b ; address bit 15 of EXOS memory
P_CTRL2 EQU 3 ; control port 2
P2_A16 EQU 00000001b ; address bit 16 of EXOS memory
P2_SHM EQU 01111110b ; EXOS shared memory address on host
P2_ACC EQU 10000000b ; enable access to EXOS memory
P_ACK EQU 4 ; acknowledge interrupt


; here are some equates to syncronise the i186 and the host via a semaphore
S_INST EQU 0aah ; a fancy value to flag installed code
S_EXEC EQU 0a5h ; .. code is executing
S_FAILED EQU 05ah ; .. i186 has failed to execute code
S_STOP EQU 055h ; .. code was successfully executed


code segment word public
assume cs:code, ds:code

int_no db 2, 0, 0, 0 ; interrupt number
io_addr dw 310h, 0 ; I/O address for card
base_addr dw 0cc00h, 0 ; base segment for board

ex_eaddr db 6 dup (0) ; boards Ethernet address
ex_ctrl1 db 0 ; copy of control port 1
ex_ctrl2 db 0 ; .. port2

driver_class db BLUEBOOK, IEEE8023, 0 ; from the packet spec
driver_type db 13 ; from the packet spec
driver_name db "EXOS205", 0 ; name of the driver
driver_function db 2
parameter_list label byte
db 1 ; major rev of packet driver
db 9 ; minor rev of packet driver
db 14 ; length of parameter list
db EADDR_LEN ; length of MAC-layer address
dw GIANT ; MTU, including MAC headers
dw MAX_MULTICAST * EADDR_LEN ; buffer size of multicast addrs
dw 0 ; (# of back-to-back MTU rcvs) - 1
dw 0 ; (# of successive xmits) - 1
int_num dw 0 ; interrupt # to hook for post-EOI
; processing, 0 == none

usage_msg db "usage: exos205 [options] [int_no] [io_addr] [base_addr]",CR,LF,'$'

copyright_msg db "Packet driver for the EXOS 205, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+i82586_version,CR,LF
db "Portions Copyright 1988 The Board of Trustees of the University of Illinois.",CR,LF
db "Portions Copyright 1992 Dirk Koeppen ([email protected]).",CR,LF,'$'

no_exos205 db "Unable to initialize the EXOS 205 adapter.",CR,LF,'$'

int_no_name db "Interrupt number ",'$'
io_addr_name db "I/O port ",'$'
base_addr_name db "Shared memory address ",'$'


; ENABLE_NETWORK - switch on the transceiver
enable_network:
ret ; is on all the time


; RESET_586 - reset the network controller
reset_586:
push ds ; could be called from different segment
push ax
mov ax, cs
mov ds, ax

loadport
setport P_CTRL1 ; load the i/o control register
mov al, ex_ctrl1
or al, P1_CA ; set CA
and al, NOT P1_586 ; disable i82586
out dx, al ; trigger the port
jmp $+2 ; let the signal dry
or al, NOT P1_586 ; enable i82586
out dx, al
mov ex_ctrl1, al ; save a copy
pop ax
pop ds
ret


; DOCA - do a channel attention
doca:
push ds ; could be called from different segment
push ax
mov ax, cs
mov ds, ax

loadport
setport P_CTRL1 ; load the i/o control register
mov al, ex_ctrl1
and al, NOT P1_CA ; clear CA
or al, P1_586 ; enable i82586 if not already enabled
out dx, al ; trigger the port
jmp $+2 ; let the signal dry
jmp $+2
or al, P1_CA ; set CA
out dx, al
mov ex_ctrl1, al ; save a copy

setport P_ACK ; acknowledge intr (placed here because
out dx, ax ; .. recv_isr calls doca each time)

pop ax
pop ds
ret


; EX_INIT - initialize the EXOS205
ex_init:
loadport ; base of device
mov ex_ctrl1, P1_NET+P1_A12+P1_A13+P1_A14+P1_A15 ; highest mem page

mov ax, base_addr ; where the shared memory should get to
shr ah, 1 ; shift it to the right place
and ah, P2_SHM ; zero all other bits
or ah, P2_A16 ; set address bit 16
mov ex_ctrl2, ah

setport P_CTRL1 ; set the EXOS memory address
mov al, ex_ctrl1
out dx, al

setport P_CTRL2
mov al, ex_ctrl2
out dx, al
jmp $+2 ; let it dry
jmp $+2
or ex_ctrl2, P2_ACC ; enable the memory
mov al, ex_ctrl2
out dx, al

init_i186:
push es ; save 'C' register type loop-counters
push si
push di
push ds
mov es, base_addr ; ES:DI -> EXOS205 memory (end of last 16K page)
mov di, 03fffh
mov ax, cs ; DS:SI -> code to be downloaded (end of code)
mov ds, ax
mov si, offset i186_end
mov cx, (offset i186_end-offset i186_code) ; amount to be downloaded
inc cx ; one more because loops end at 0
std ; copy backwards

rep movsb ; copy the code

cld
pop ds ; restore original DS
mov di, 03fffh ; where the semaphore is located
sub di, (offset i186_end-offset i186_sema)
mov al, es:[di] ; get semaphore
cmp al, S_INST ; check if code is installed
jne init_failed ; failed to init board

setport P_CTRL1
mov al, ex_ctrl1 ; release the i186, let it execute the code
or al, P1_186
mov ex_ctrl1, al ; .. and let it run forever
out dx, al

mov ax, (36*2) ; give it 2 seconds to start execution
call set_timeout

init_loop1:
mov al, es:[di] ; get semaphore
cmp al, S_EXEC ; does it execute ?
je init_i186exec

call do_timeout ; loop until timeout
jne init_loop1

jmp init_failed ; failed to init board

init_i186exec:
mov ax, (36*5) ; give it 5 seconds to initialize
call set_timeout

init_loop2:
mov al, es:[di] ; get semaphore
cmp al, S_STOP ; did it stop ?
je init_i186stop

call do_timeout ; loop until timeout
jne init_loop2

jmp init_failed ; failed to init board

init_i186stop:
xor ax, ax ; flag that everything worked all right
push ax
mov di, 03fffh ; where the Ethernet address is located
sub di, (offset i186_end-offset i186_addr)
mov bx, offset ex_eaddr
mov cx, 6 ; 6 bytes to move

init_acpy:
mov al, es:[di] ; copy address
mov ds:[bx], al
inc di ; next byte
inc bx
loop init_acpy ; loop for all byte

init_end:
pop ax

setport P_ACK ; acknowledge intr to reset hardware logic
out dx, ax

pop di ; restore saved registers
pop si
pop es
or ax, ax ; setup zero flag
ret

init_failed:
setport P_CTRL1 ; stop the i186
mov al, ex_ctrl1
and al, NOT P1_186 ; .. forever
mov ex_ctrl1, al
out dx, al
mov ax, -1 ; failed to init board
push ax
jmp init_end


; I186_CODE - this code is downloaded to the EXOS205 to be executed by the i186
i186_code:
i186_addr:
db 08h, 00h, 14h ; unique EXOS Ethernet address (byte 5-3)
db 0, 0, 0 ; .. byte 2-0 of the boards Ethernet address

i186_sema:
db S_INST ; semaphore will be S_STOP if code was executed

i186_ipl: ; i186 bootstrap
cli ; disable interrupts
xor ax, ax ; zero relocation register
mov dx, 0fffeh
out dx, ax
mov ax, 0fff8h ; setup UMCS register
out 0a0h, ax
mov ax, 0007ch ; .. PACS register
out 0a4h, ax
mov ax, 080bch ; .. MPCS register
out 0a8h, ax

mov ax, cs ; DS -> CS
mov ds, ax

; flag code execution
mov bx, 00fffh - (offset i186_end-offset i186_sema)
mov byte ptr ds:[bx], S_EXEC
xor cx, cx

i186_wait: ; spend some time to let host read the semaphore
jmp $+2
jmp $+2
jmp $+2
loop i186_wait

; where to write the boards Ethernet addr to (starts 3 bytes after code)
mov si, 00fffh - (offset i186_end-offset i186_addr) + 3

mov dx, 0502h ; low order nibble of byte 2 Ethernet address
xor bx, bx ; zero checksum
mov cx, 3 ; 3 bytes of Ethernet address are to be read

i186_acpy:
in al, dx ; read one nibble
and al, 00001111b ; .. mask valid bits (just to get shure !)
mov ah, al ; .. store it
add bl, al ; .. add to checksum
inc dx ; go to high order nibble
inc dx
in al, dx ; .. read it
add bl, al ; .. add to checksum
shl al, 1 ; .. shift it to be high order nibble
shl al, 1
shl al, 1
shl al, 1
or al, ah ; pack those two nibbles into one byte
mov ds:[si], al ; .. and store the byte

inc dx ; go to next nibble of Ethernet address
inc dx
inc si
loop i186_acpy ; loop until all 3 bytes are read

mov ah, bl ; add bottom to top nibble
shr ah, 1 ; top nibble
shr ah, 1
shr ah, 1
shr ah, 1
and bl, 00001111b ; bottom nibble
add ah, bl ; add them
xor ah, 5 ; is x-ored by 5 to avoid 0x00 or 0xff problem

in al, dx ; DX -> checksum
cmp ah, al
je i186_ok

mov byte ptr ds:[si], S_FAILED; flag that checksum failed

jmp $ ; stop execution (i186 will be stopped by host)

i186_ok:
mov byte ptr ds:[si], S_STOP ; flag that we have stopped execution
xor ax, ax ; set the interrupt vector
mov ds, ax ; .. i82586 is connected to INT2
mov si, 4*14 ; INT2 has vector type 14
mov word ptr ds:[si], 00fffh - (offset i186_end-offset i186_intr)
inc si
inc si
mov word ptr ds:[si], 0ff00h

sti ; enable interrupts

mov dx, 3ch ; INT2 control register
mov ax, 3 ; level triggered, unmasked and prio 3
out dx, ax

xor bx, bx ; zero counters
xor cx, cx
mov bp, 00fffh - (offset i186_end-offset i186_lcnt)

i186_loop: ; endless loop to keep i186 doing something
nop
nop
nop
nop
loop i186_loop

inc bx ; count
mov cs:[bp], bx ; .. and store for debugging
jmp i186_loop ; cycle endless while waiting for interrupts

i186_intr: ; interrupt routine called by 82586 intr
push dx
mov dx, 00600h ; interrupt host first
out dx, ax

push ax
push bx
push bp

mov bp, 00fffh - (offset i186_end-offset i186_icnt)
mov bx, cs:[bp]
inc bx ; increment interrupt counter
mov cs:[bp], bx ; .. and store for debugging

mov dx, 22h ; acknowledge interrupt
mov ax, 8000h
out dx, ax

pop bp
pop bx
pop ax
pop dx
iret

db 'INTR cnt->' ; some debugging variables
i186_icnt:
dw 0 ; counts 82586 interrupts
db 'LOOP cnt->'
i186_lcnt:
dw 0 ; loops to flag execution

i586_reset_vector:
db 0eah dup (0) ; reserved for the i82586 reset vector

i186_reset_vector:
db 0eah ; opcode 'jmp far'
dw 00fffh - (offset i186_end-offset i186_ipl)
dw 0ff00h
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; fill patterns

i186_end:
db 0 ; one more fill pattern


; here we include the code that is common between 82586 implementations.
; everything above this is resident.
include 82586.asm
; everything below this is discarded upon installation.

; CHECK_BOARD - check if there really is a EXOS 205 installed
check_board:
mov SCP, 0 ; 16 bit bus type in scb.

call ex_init ; setup the board
je check_ok

mov dx, offset no_exos205 ; failed to init board
jmp error

check_ok:
xor ax, ax ; have a return value
ret


; PARSE_ARGS - read the command line option and overwrite defaults
parse_args:
mov di, offset int_no
call get_number
mov di, offset io_addr
call get_number
mov di, offset base_addr
call get_number
clc
ret

; PRINT_PARAMETERS - print out the boards configuration parameters
print_parameters:
mov di, offset int_no
mov dx, offset int_no_name
call print_number
mov di, offset io_addr
mov dx, offset io_addr_name
call print_number
mov ax, memory_begin
mov cl, 4
shr ax, cl
add base_addr, ax
push ax
mov di, offset base_addr
mov dx, offset base_addr_name
call print_number
pop ax
sub base_addr, ax
ret

; GET_ADDRESS - get boards Ethernet address
; enter with es:di -> place to get the address,
; cx = size of address buffer.
; exit with nc, cx = actual size of address,
; or cy if buffer not big enough.
get_address:
assume ds: code
mov bx, offset ex_eaddr ; where to copy is located
get_address_1:
mov al, ds:[bx] ; copy a byte of the address
stosb ; put it away
inc bx ; next address byte
loop get_address_1 ; go back for rest
ret

include memtest.asm

code ends
end


  3 Responses to “Category : Network Files
Archive   : PKTD11A.ZIP
Filename : EXOS205.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/