Email: Password: Remember Me | Create Account (Free)
Using the 8390 Code

 Using the 8390 Code

The code has been written to reduce the amount of overhead required to get the code working. The best way to see how easily the code intergrates into an application is to examine the ETHTEST.ASM code. Below is an overview of the code, and what the user variables etc are and how they affect the compilation and execution of the ethernet driver.

REQUIREMENTS
The minimum requirements for using the 8390 code are:

  1. 8390 chipset compatible network card configured in the XDATA address space on a page boundary
  2. 3.5k RAM configured on a page boundary (depends on size of Transmit and Receive Buffer)
  3. One spare interrupt, either INT0 or INT1

FUNCTIONS OF THE CODE
While the code is lengthly, there are only five (5) routines that should be called from the calling program. These routines are explained in greater detail below. In short, the routines are:

  • Int8390 - Interrupt portion of the driver
  • Probe8390 - Attempts to locate an 8390 compatible card at the IOAddr page boundary
  • NS8390_Init - Initializes the NIC
  • EIGetPacket - Retrieves a packet from the NIC
  • SendPacket - Sends a packet from the TXBUFFER on to the NIC and triggers a send

IMPLEMENTING THE CODE
To include support for the 8390 driver, Use the INCLUDE or similar directive to add the 8390.INC file to your source. An example is

INCL "8390.INC" ; Include 8390 Ethernet drivers

This will compile both the 8390.INC file, as well and use the NEEQUATE.TXT file which is also required for successful compilation.

A skeleton struction to get the code working would look like this:

ORG 0000h
ajmp Begin

ORG INT0 or INT1 address
ljmp Int8390

BEGIN:
<Start of initialization code>

lcall Probe8390
lcall NS8390_Init

<End of Initializtion code>

<Main program loop>

jnb EI_RXD, NoPktWait

lcall ProcessPacket
clr EI_RXD

NoPktWait:

sjmp MainLoop

INCL "8390.inc"
end


<---------- VARIABLES ---------->

This section describes the variables and there purpose. Listed here are both user variables, and system use variables. User variables determine run-time configurations. System use variables are used by the code to keep track of itself and various status flags. The only system user variable that should be modified by the application program is ei_RXD. Changing any other System Variable may cause unpredicable behaviour.

Type of variable

Name declared in file: Use
User Variables IOAddr
SAPROM
MultiByte
EIDebug
RXBuffer
TXBuffer
8390.inc
8390.inc
8390.inc
8390.inc
8390.inc
8390.inc
Page boundary setting of the NIC. (MSB)
Start of data area for SAPROM data
Byte to enter into Multicast array
TRUE to include debug information in code
Points to start of receive buffer
Points to start of transmit buffer
System Variables ei_Txing
ei_Rxd
dmaing
Next_Page
8390.inc
8390.inc
8390.inc
8390.inc
TRUE is card tranmitting data
TRUE is ReceiveBuffer contains valid data
TRUE is transferring data to NIC
Holds pointer to next page from NIC

User Variables:

IOAddr: The contains the Most Significant Byte of the word address of the NIC. For example. If the Address of the NIC was at 6300h, then IOAddr would contain the value 63h. This value, combined with the value stored in R1 addresses the correct register within the Network Card.

SAPROM: This array, which at most will be 32 bytes long, but should only use the first 16 bytes, contains the data stored on the PROM chip of the NIC. The most important data out of this PROM area is the MAC address that the card uses. The initialization routine uses the first 6 bytes at the start of array to program the NIC with the MAC address programmed on the card. You could, but not recommended is to program the NIC with your own MAC address. If you have multiple NICs on the network with the same MAC address, you will create communication problems - enough said.

Multibyte: Along with receiving normal packets addressed for the MAC address of the card, you can also program the card to accept Multicast packets. Normally, the value of this should be 00h. See the 8390 datasheet for an explanation of this feature. Normally, leave this value at 00h.

EIDebug: For production code, set this to FALSE (0). Leaving this active will display some diagnostic messages if certain conditions are met, i.e. unknown interrupt.

RXBuffer: This is the location of the start of the receive buffer. If the EI_RXD variable is true, then the data in this buffer is deemed to be valid and required to be processed. The maximum length of data in this buffer will not exceed 1540 bytes, which the standard MTU (Maximum Transmission Unit) used on ethernet. The length of the buffer can be shorter, but should a packet be received which is longer than the buffer it will overwrite other areas of memory! The data from the NIC is entered into the buffer with the following characteristics:

Representation

Function

Number of Bytes

Frame Status Status of the received frame. 1
Next Packet Pointer Pointer to pointer to the next received packet 1
Length Length of the frame 2, low byte first
Source Address MAC address of the card that the frame is destined for 6
Destination Address MAC Address of the card that sent the packet 6
Type of Service Type of packet, i.e 0800h = IP, 0806h = ARP 2
REST OF FRAME Remaining data within the frame. Will include other headers, i.e. IP. 1...1518 bytes
The length of the actual frame required for processing is calcutated with the following formula: LENGTH (Bytes 2 and 3) - 18. The Frame Status and Next Packet Pointer are copied for completeness, but are of no value to the programmer. The remaining bytes before the REST OF FRAME are required for transmit data formation and Type Of Service program branching.

TXBuffer: This points to the start of the transmit buffer. This buffer should be set the size of the largest transmitted packet + 14 bytes. The format of the transmit packet is as follows:

Description

Description

Number of Bytes

Destination Address MAC Address of the computer to send the packet too 6
Source Address MAC Address of this device, ie. of the NIC 6
Type of Service Type of information the packet contains, i.e. 0806 = ARP, 0800 = IP 2
REST OF FRAME Rest of the frame data, includes IP, ARP etc header and data. Note 1...
Note that no range checking of the size of the packet is performed. It is up to the programmer to make sure that the size of the packet exceeds 50 bytes, and is less than 1518 bytes. Should the packet be less than 50 bytes, some network cards will reject the packet, and not pass it up to the stack. This also happens if the length of the packet exceeds 1518 bytes.

System Variables:

ei_Txing: This flag is set to true if the NIC is sending data onto the network. It is used to prevent sending more than one packet at a time. This flag is cleared within the interrupt subroutine when an end of transmit interrupt occurs. If the program is transmitting multiple packets, it should check the status of this flag before beginning to assemble the next packet for transmittion and confirm that it is set to false.

ei_RXD: This flag is set to TRUE if the data in the Receive buffer should be processed. This is the only system variable that the programmer should modify. Once the packet has been processed, the programmer should clear this flag, otherwise no further packets will be transferred from the NIC to the receive buffer. After this flag is cleared, the subroutine EIGETPACKET should be called to retreive the next packet from the NIC should it exist. If you do not call the EIGETPACKET routine after clearing the flag, any packets waiting in the NIC will not retrieved until the next interrupt at which time only one packet will be retreived.

DMAING: This value is set to TRUE if data is being transferred to or from the NIC. DO NOT change the value of this variable, otherwise unpredictable results may occur.

Next_Page: Holds the page location of the next packet to be retreived from the NIC.

DO NOT CHANGE THIS VARIABLE. Doing so WILL cause packets to be lost within the NIC. It may even cause the NIC to stop responding.


<---------- SUBROUTINES ---------->

INT8390
ON EXTRY: NIL
ON EXIT: NIL
DESTROYS: NOTHING
As this code relies on an interrupt from the card to signal various states of the card, a branch to INT8390 is required either at the INT0 or INT1 interrupt address of the card. This routine contains a RETI instruction, so an LJMP or AJMP instruction is all that is required. The interrupt routine performs the following functions:

  1. Saves the Program status register and changes the Microprocessor to use register bank 1
  2. Saves working registers
  3. Changes P2 to the value of the IOADDR byte
  4. Get the interrupt value from the NIC
  5. If the NIC signals that it has received a packet, and the EI_RXD flag is false, then the interrupt routine will call the EIGETPACKET subroutine to load a packet from the NIC into the RXBuffer.
  6. repeats steps 3 and 4 until all interrupts have been serviced
  7. restore working registers
  8. Restores PSW thereby returning selected register bank to pre-interrupt state

NOTE: Do not under any cercumstances atttempt to send a packet while still in the interrupt routine. This will cause the NIC to stop. The only way to overcome this is to use the reset button.

PROBE8390
ON ENTRY: NIL
ON EXIT: Carry flag reports status of the operation. if CF set, Accumulator holds error value, otherwise Accumulator intederminate.
DESTROYS: R1, R2, R3, R4, P2
FUNCTION: To attempt to locate an 8390 compatible chipset NIC card located on the IOADDR page boundary. If the operation is successful, the CF is cleared, and the SAPROM contains valid information. If the search for the card is unsuccessful, the CF bit is set, and the accumulator holds the error code. Possible error codes are:

  • NoCardFound - Unable to locate, or communicate with a NIC. Chances are the IOADDR equate does not correspond to the page boundary that the NIC is on.
  • NoResetAck - Found a card, but did not get a return an acknowledgement to the reset function. Same symptons as for NoCardFound.
  • NoIRQFound - Found a card, can communicate with it, but no acknowlegement to an interrupt. Check to make sure that the IRQ number programmed into the NIC, and the line that you have attached to the microprocessor are the same. Also, make sure that the interrupt is active and enabled.

NS8390_INIT
ON ENTRY: The first 6 bytes of the SAPROM array MUST contain a the bytes for the MAC address.
ON EXIT: No status, it is assumed that this will finish with out error. MAKE SURE THAT PROBE8390 is executed before this for error detection, as well as to get the MAC address from the NIC.
DESTROYS: P2, R1, R2, Accumulator, DPTR
FUNCTION: Initializes the card, and turns on the Transmit and Receive buffers. When this call completes, packets can be sent and received. This routine can be called at any time to reset the NIC.

EIGETPACKET
ON ENTRY: EI_RXD flag set accordingly (see below)
ON EXIT: EI_RXD flag, if cleared upon entry will be set if a packet has been transferred from the NIC to the Receive buffer.
DESTROYS: P2
FUNCTION: To retrieve a packet from the NIC if one is waiting. If EI_RXD is set upon entry to this routine, the routine will exit as the receive buffer is flagged as containing valid data. If the EI_RXD flag is clear upon entry to this routine and a packet is waiting in the NIC for retrieval, then the packet is transferred to the ReceiveBuffer and this flag set. The interrupt to the NIC is switched off during the data transfer.

SENDPACKET
ON ENTRY: DPTR points to the data to be transmitted. R3/R4 contains the length of the data to be transferred.
ON EXIT: No exit code. Assume success.
DESTROYS: CF, Accumulator, P2, R1
FUNCTION: To send a packet pointed to by DPTR onto the ethernet network. No checks are performed on the data to confirm validity. To be a valid ethernet packet, the minimum size if the packet shall be no less than 60 bytes or greater than 1518 bytes. The NIC interrupt is turned off during the transmit to prevent any extraneous errors.

DO NOT call this routine from within an interrupt routine. Doing so will stop the network card.

Home