home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / src / ctrondni.asm < prev    next >
Assembly Source File  |  1995-06-25  |  17KB  |  820 lines

  1. version    equ    1
  2.  
  3.     include    defs.asm
  4.  
  5. ; Packet driver for Cabletron DNI Exxxx series cards.
  6. ; Portions Copyright 1992-1993 Kai Getrost.
  7. ;
  8. ; Since I have no official programming info on the DNI cards, nor do I
  9. ; have a Microchannel version of the card, this driver doesn't work on
  10. ; an MCA bus (to my knowledge).  There's code in here to do stuff when
  11. ; running on an MCA bus, but most of it is guesswork.  To enable it,
  12. ; uncomment the MCA_STUFF define below, and move the 6 lines of code
  13. ; before "include 8390.asm" to the head of recv in 8390.asm.
  14. ; -KNG 930924
  15. ;
  16. ; Define for MCA code:
  17. ;MCA_STUFF    equ    1
  18.  
  19. ;For brain-dead assemblers:
  20. REP_INSB    equ    db    0f3h, 06ch
  21. REP_INSW    equ    db    0f3h, 06dh
  22. REP_OUTSB    equ    db    0f3h, 06eh
  23. REP_OUTSW    equ    db    0f3h, 06fh
  24.  
  25.  
  26. EN_OFF        equ    0
  27. CT_DATAPORT    equ    10h        ; data transfer port
  28. SM_TSTART_PG    equ    1
  29. SM_RSTART_PG    equ    9
  30. SM_RSTOP_PG    equ    20h        ; 40h on MCA cards
  31. TEST_VAL    equ    1234h
  32.  
  33.     include    8390.inc
  34.  
  35. ;This used to be in 8390.asm:
  36. pause_    macro
  37.     push    ax
  38.     in    al, 61h        ;use al, not ax!
  39.     pop    ax
  40. endm
  41.  
  42. reset_8390    macro
  43. local    foo
  44.     loadport
  45.     setport    EN_CCMD
  46.     mov    al, ENC_STOP
  47.     pause_
  48.     out    dx, al
  49.     mov    cx, 80h
  50. foo:
  51.     pause_
  52.     loop    foo
  53. endm
  54.  
  55. terminate_board    macro
  56.     mov    dh, CANT_TERMINATE
  57.     stc
  58. endm
  59.  
  60.  
  61. code    segment word public
  62.     assume cs:code, ds:code
  63.  
  64.     public    int_no, io_addr
  65. int_no        db    3, 0, 0, 0    ;IRQ #; must be dword for get_number
  66. io_addr        dw    300h, 0        ;IO port to use
  67.  
  68.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  69. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  70. driver_type    db    51        ;from Cabletron's driver
  71. driver_name    db    "Cabletron DNI", 0    ;name of the driver.
  72. driver_function    db    2        ;2 = basic/extended
  73. parameter_list    label    byte
  74.     db    1    ;major rev of packet driver
  75.     db    9    ;minor rev of packet driver
  76.     db    14    ;length of parameter list
  77.     db    EADDR_LEN    ;length of MAC-layer address
  78.     dw    GIANT    ;MTU, including MAC headers
  79.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  80.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  81.     dw    0    ;(# of successive xmits) - 1
  82. int_num    dw    0    ;Interrupt # to hook for post-EOI
  83.             ;processing, 0 == none
  84.  
  85. is_16bit    db    0        ;set to 1 if 16 bit card
  86. out_jmp        dw      out_88        ;block_output method
  87. in_jmp        dw    in_88        ;block_input method
  88. shmem_seg    dw    ?        ;shared memory segment
  89.  
  90.  
  91.     extrn    sys_features: byte
  92.     extrn    is_186: byte
  93.  
  94.     public    block_input
  95. ;enter with AX = board address, CX = count, ES:DI -> buffer to copy to
  96. ;buffer-wraparound added 920901 -kng
  97. block_input:
  98.     assume    ds:nothing    ; force CS overrides for data refs
  99.  
  100. ;First check for buffer wraparound:
  101.     mov    si, ax                ;save start page
  102.     add    ax, cx                ;compute end of this frame
  103.     mov    dh, cs:sm_rstop_ptr
  104.     or    dh, dh
  105.     jz    in_okcpy            ;no mem, ok to copy (?)
  106.     xor    dl, dl
  107.     cmp    ax, dx                ;is it beyond end of buffer?
  108.     jbe    in_okcpy            ;jump if not
  109.  
  110. ;Frame is wrapped around; do copy in 2 parts:
  111.     push    cx                ;save total length
  112.     mov    cx, dx
  113.     sub    cx, si                ;get length of first part
  114.     push    cx                ;save it
  115.     call    get_block
  116.     pop    bx
  117.     pop    cx
  118.     sub    cx, bx                ;get length of second part
  119.     mov    si, SM_RSTART_PG*256 + 0
  120. in_okcpy:
  121.     call    get_block
  122.     ret
  123.  
  124. ;Copy contiguous block of data.  SI = page, CX = len, ES:DI = buffer
  125. ;From ne1000.asm, modified (shared mem added for MCA cards).
  126. get_block:
  127.     cld            ; set right direction
  128.   ifdef MCA_STUFF
  129.     test    sys_features, SYS_MCA
  130.     jnz    in_mem
  131.   endif
  132.     loadport
  133.     setport EN_CCMD
  134.     pause_
  135.     mov    al, ENC_NODMA + ENC_PAGE0 + ENC_START
  136.     out    dx, al
  137.  
  138.     mov    ax, cx        ;get the count to be output.
  139.     setport    EN0_RCNTLO    ; remote byte count 0
  140.     pause_
  141.     out    dx, al
  142.     setport    EN0_RCNTHI
  143.     pause_
  144.     mov    al, ah
  145.     out    dx, al
  146.  
  147.     mov    ax, si        ; get our page back
  148.     setport    EN0_RSARLO
  149.     pause_
  150.     out    dx, al        ; set as hi address
  151.     setport    EN0_RSARHI
  152.     pause_
  153.     mov    al, ah
  154.     out    dx, al
  155.  
  156.     setport EN_CCMD
  157.     pause_
  158.     mov    al, ENC_RREAD + ENC_START    ; read and start
  159.     out    dx, al
  160.     setport    CT_DATAPORT
  161.     pause_
  162.  
  163.     jmp    [in_jmp]    ; do the copy
  164.  
  165. in_88:                ; Default, use 8088 I/O
  166.     in    al, dx        ; get a byte
  167.     stosb            ; save it
  168.     loop    in_88
  169.     ret
  170.  
  171. in_186:                ; Use 80[123]86 I/O
  172.     REP_INSB
  173.     ret
  174.  
  175. in_16bit:            ; Use 16 bit I/O
  176.     inc    cx
  177.     shr    cx, 1        ; round up to nearest word count
  178.     REP_INSW
  179.     ret
  180.  
  181.   ifdef MCA_STUFF
  182. in_mem:                ; Copy from shared memory
  183.     push    ds
  184.     mov    ds, shmem_seg
  185.     inc    cx
  186.     shr    cx, 1
  187.     rep    movsw
  188.     pop    ds
  189.   endif
  190.  
  191.     ret
  192.  
  193.  
  194.     public    block_output
  195. ;enter with AX = board address, CX = length, DS:SI -> buffer
  196. ;From ne1000.asm, modified for shared mem.
  197. block_output:
  198.     assume    ds:nothing
  199.  
  200.     cld
  201.   ifdef MCA_STUFF
  202.     test    sys_features, SYS_MCA
  203.     jnz    out_mem
  204.   endif
  205.     push    ax        ; save buffer address
  206.     inc    cx        ; make even
  207.     and    cx, 0fffeh
  208.     loadport
  209.     setport EN_CCMD
  210.     pause_
  211.     mov    al, ENC_NODMA + ENC_START
  212.     out    dx, al        ; stop & clear the chip
  213.  
  214. ;There's some funkiness to remote DMA writes under certain conditions,
  215. ;according to the National DP8390 Datasheet Addendum and comments in
  216. ;the hppclan driver.  A description and solution to the problem, from
  217. ;Glenn Talbott's additions to hppclan.asm, are reproduced here.  -KNG
  218.  
  219. ;; To quote from the National DP8390 Datasheet Addendum, June 1990
  220. ;;
  221. ;;   11.0 Remote DMA Write
  222. ;;
  223. ;;   Under certain conditions the NIC may issue /MWR and /PRD before
  224. ;;   PRQ for the first DMA transfer. This causes an extraneous byte to be
  225. ;;   written inot memory at the first Remote DMA Write location. [...]
  226. ;;
  227. ;;   To prevent this condition, write a non-zero value into RBCR0 and
  228. ;;   issued [sic] the Remote Read DMA command to the NIC (CR=0AH), but
  229. ;;   do not give any Read Acknowledges (/RACK). (This causes PRQ to go high.)
  230. ;;   Then write the desired byte count into RBCR0 and RBCR1 and give the
  231. ;;   Remote Write DMA command (CR=12H). The Remote Write DMA will operate as
  232. ;;   normal.
  233. ;;
  234. ;; My interpretation of the above is          - gft - 910603
  235.  
  236.     setport    EN0_RCNTLO    ; remote byte count 0
  237.     pause_
  238.     mov    al,0ffh        ; a non-zero value
  239.     out    dx,al
  240.     setport EN_CCMD
  241.     pause_
  242.     mov     al,ENC_RREAD+ENC_START ; read and start
  243.     out     dx,al        ; starts the read setting PRQ for the first
  244.                 ; DMA transfer, now reprogram everything
  245.                 ; and start a write instead.
  246.  
  247. ;; BUT WHAT THE NATIONAL DOCUMENTATION DOESN'T TELL YOU ...
  248. ;;
  249. ;;  When the read is started, the remote byte count register is decremented
  250. ;;  (in this case from 0ffh to 0feh). This takes a finite amount of time.
  251. ;;  IF you are TOO QUICK in re-programming the remote byte count 0 register
  252. ;;  to the correct value, the NEW VALUE GETS DECREMENTED INSTEAD! Then when
  253. ;;  you reach the last byte of the buffer and you output it to the IO port,
  254. ;;  the NIC has already reached a count of zero and WON'T HANDSHAKE THE LAST
  255. ;;  BYTE!. Result, computer HUNG, powercycle to recover. Therefore a stall is
  256. ;;  required here, I use at least 1.5uS
  257. ;;                                      - gft - 910603
  258. ;;
  259.     in    al,61h        ; read from NMI Status register for IO delay
  260.     in    al,61h        ; ~ 0.5uS on Microchannel and ~ 1.0 on ISA
  261.     in    al,61h        ; for a total of ~1.5uS or 3.0uS.
  262.  
  263. ;Now the rest of block_output:   -KNG 921208
  264.  
  265.     setport    EN0_RCNTLO    ; remote byte count 0
  266.     pause_
  267.     mov    al, cl
  268.     out    dx, al
  269.     setport    EN0_RCNTHI
  270.     pause_
  271.     mov    al, ch
  272.     out    dx, al
  273.  
  274.     pop    ax        ; get our page back
  275.     setport    EN0_RSARLO
  276.     pause_
  277.     out    dx, al        ; set as lo address
  278.     setport    EN0_RSARHI
  279.     pause_
  280.     mov    al, ah
  281.     out    dx, al
  282.  
  283.     setport EN_CCMD
  284.     pause_
  285.     mov    al, ENC_RWRITE + ENC_START    ; write and start
  286.     out    dx, al
  287.     setport    CT_DATAPORT
  288.     pause_
  289.  
  290.     jmp    [out_jmp]    ; do the copy
  291.  
  292. out_88:                ; Default:  loop for 8088/8086
  293.     lodsb
  294.     out    dx, al
  295.     loop    out_88
  296.     jmp    short block_out_1
  297.  
  298. out_186:            ; Use 80[123]86 I/O
  299.     REP_OUTSB
  300.     jmp    short block_out_1
  301.  
  302. out_16bit:            ; Use 16 bit I/O
  303.     inc    cx
  304.     shr    cx, 1        ; convert to word count
  305.     REP_OUTSW
  306.     jmp    short block_out_1
  307.  
  308.   ifdef MCA_STUFF
  309. out_mem:            ; Copy to shared mem
  310.     push    es
  311.     mov    es, shmem_seg
  312.     inc    cx
  313.     shr    cx, 1
  314.     rep    movsw
  315.     pop    es
  316.   endif
  317.  
  318. block_out_1:
  319.     mov    cx, 0
  320.     setport    EN0_ISR
  321. tx_check_rdc:
  322.     in    al, dx
  323.     test    al, ENISR_RDC    ; dma done ?
  324.     jnz    tx_start    ; jump if so
  325.     loop    tx_check_rdc    ; otherwise loop
  326.     stc
  327.     ret
  328. tx_start:
  329.     clc
  330.     ret
  331.  
  332.  
  333. ; The following 6 lines seem to be needed at the start of the recv
  334. ; routine in 8390.asm, for PS/2s.  -KNG 930924
  335. ifdef MCA_STUFF
  336. xxxxxx  Move to start of recv in 8390.asm:  xxxxxx
  337.     test    sys_features, SYS_MCA
  338.     jz    check_isr
  339.     loadport
  340.     setport    23h
  341.     mov    al, 4
  342.     out    dx, al
  343. endif
  344.  
  345.     include    8390.asm
  346.  
  347.  
  348. int_no_list    db    3, 7, 9            ; IRQ list for MCA
  349. out_jmp_list    dw    out_88, out_186, out_16bit
  350. in_jmp_list    dw    in_88, in_186, in_16bit
  351. slot_no        db    0            ; BIOS slot number
  352. tmp_pag        db    0            ; used in do_test
  353. testbyte    db    0            ; used in test_mem
  354.  
  355. BUF_SIZ        equ    100h
  356. buf        db    BUF_SIZ dup(?)        ; used for diags in test_mem
  357.  
  358. EOM        equ    CR, LF, '$'
  359.     public    usage_msg
  360. usage_msg    db    "Usage:  ctrondni [options] <packet_int_no> <hardware_irq> <io_addr>", EOM
  361.  
  362.     public    copyright_msg
  363. copyright_msg    db    "Packet driver for Cabletron DNI cards, version "
  364.         db    '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF
  365.         db    "Portions Copyright 1992-1993, Kai Getrost", EOM
  366.  
  367. cant_find_msg    db    "** Can't find Ethernet controller **", EOM
  368. mem_failed_msg    db    "** Board memory test failed **", EOM
  369. mem_msg        db    "; mem size in kb is ", '$'
  370. bus_msg        db    "Bus is ", '$'
  371. bus_8_msg    db      "8 bit", '$'
  372. bus_16_msg    db    "16 bit", '$'
  373.   ifdef MCA_STUFF
  374. bus_MCA_msg    db    "microchannel", '$'
  375.   else
  376. no_MCA_msg    db    "Microchannel bus unsupported", EOM
  377.   endif
  378. int_no_msg    db    "Interrupt number ", '$'
  379. ioaddr_msg    db    "I/O address ", '$'
  380.  
  381.  
  382.     extrn    set_recv_isr: near
  383.     extrn    get_number: near
  384.     extrn    print_number: near
  385.     extrn    decout: near
  386.  
  387.     public    parse_args
  388. parse_args:
  389. ;Exit with cy if error, nc if OK.  Reads IRQ, IO port numbers.
  390.  
  391.     mov    di, offset int_no
  392.     call    get_number        ;read IRQ number
  393.     jc    parse_err        ;jump if error
  394.     mov    di, offset io_addr
  395.     call    get_number        ;read I/O address
  396.     jc    parse_err
  397.     clc                ;no error
  398.     ret
  399. parse_err:
  400.     stc                ;error
  401.     ret
  402.  
  403.  
  404.     public    init_card
  405. init_card:
  406. ;Returns with nc if ok; cy if error.  Determines bus/mem size, tests mem,
  407. ;reads Ethernet address, etc.
  408.  
  409.     test    sys_features, SYS_MCA
  410.     jz    init_1                ;jump if not MCA
  411.   ifdef MCA_STUFF
  412.     call    do_MCA_stuff
  413.     jb    init_err
  414.     jmp    init_2
  415.   else
  416. ; Microchannel bus detected, but no MCA code:
  417.     mov    dx, offset no_MCA_msg
  418.     stc
  419.     jmp    init_err
  420.   endif
  421.  
  422. init_1:
  423.     call    get_bus_size            ;get bus size (if not MCA)
  424. init_2:
  425.  
  426. init_3:
  427. ;Set block_input/output mode (8-bit loop, 8-bit 80186 I/O, 16-bit 80186)
  428. ;MCA is not checked since block_output/input checks it
  429.     xor    bx, bx
  430.     cmp    is_186, 0
  431.     jz    init_cont
  432.     inc    bx
  433.     cmp    is_16bit, 0
  434.     jz    init_cont
  435.     inc    bx
  436. init_cont:
  437.     shl    bx, 1                ;offsets are words
  438.     mov    ax, out_jmp_list[bx]
  439.     mov    out_jmp, ax
  440.     mov    ax, in_jmp_list[bx]
  441.     mov    in_jmp, ax
  442.  
  443.     call    read_address            ;get Ethernet address
  444.   ifdef MCA_STUFF
  445.     test    sys_features, SYS_MCA
  446.     jnz    init_5                ;jump if MCA; we know mem size
  447.   endif
  448.     call    get_mem_size
  449. init_5:
  450.     call    test_mem            ;test board memory
  451.     jb    init_err
  452.  
  453.     clc                    ;no error return
  454.     ret
  455. init_err:
  456.     mov    ah, 9
  457.     int    21h                ;print error msg
  458.     stc                    ;error return
  459.     ret
  460.  
  461.  
  462.     public    print_parameters
  463. ;Prints command line parameters, bus/mem info.
  464. print_parameters:
  465.  
  466.     mov    ah, 9
  467.     mov    dx, offset bus_msg
  468.     int    21h
  469.  
  470. ;print bus size:
  471.     mov    dx, offset bus_8_msg
  472.   ifdef MCA_STUFF
  473.     test    sys_features, SYS_MCA
  474.     jz    pr_not_MCA
  475.     mov    dx, offset bus_MCA_msg
  476.     jmp    pr_bus
  477.   endif
  478. pr_not_MCA:
  479.     cmp    is_16bit, 0
  480.     jz    pr_bus
  481.     mov    dx, offset bus_16_msg
  482. pr_bus:
  483.     mov    ah, 9
  484.     int    21h
  485.  
  486.     mov    al, cs:sm_rstop_ptr    ;
  487.     add    al, 3            ;
  488.     shr    al, 1            ; calculate memory size in Kb =
  489.     shr    al, 1            ;    (sm_rstop_ptr + 3) / 4
  490.     xor    ah, ah            ;
  491.     mov    word ptr buf, ax    ;
  492.     mov    dx, offset mem_msg
  493.     mov    di, offset buf
  494.     call    print_number        ;print mem size
  495.  
  496.     mov    dx, offset int_no_msg
  497.     mov    di, offset int_no
  498.     call    print_number        ;print int_no
  499.     mov    dx, offset ioaddr_msg
  500.     mov    di, offset io_addr
  501.     call    print_number        ; and IO port
  502.  
  503.     ret
  504.  
  505.  
  506. read_address:
  507. ;Gets board address into rom_address. From ne1000.asm init_card,
  508. ;modified.  Board data is 16 bytes starting at remote dma address 0.
  509. ;Put it in a buffer called board_data.
  510.     assume    ds:code
  511.  
  512.     mov    cx, 10h            ; get 16 bytes,
  513.     push    ds
  514.     pop    es            ; set es to ds
  515.     mov    di, offset board_data
  516.     mov    si, 0            ; from address 0
  517.     call    get_block
  518.  
  519.     push    ds                  ; Copy to current address:
  520.     pop     es
  521.     mov    si, offset board_data    ; address is at start of board_data
  522.     mov    di, offset rom_address
  523.     mov    cx, EADDR_LEN        ; one address length
  524.     cld
  525.     rep     movsb
  526.  
  527.     ret    ;Cabletron checks if address starts w/00:00:1D; we don't care
  528.  
  529.  
  530. ifdef MCA_STUFF
  531. do_MCA_stuff:
  532. ;Called only if microchannel card.  Returns CY, DX = error msg if error.
  533. ;I don't really know what this does...
  534.  
  535.     cli
  536.     mov    dx, 100h
  537.     mov    al, slot_no
  538.     or    al, al
  539.     jz    dm_check
  540.     dec    al
  541.     or    al, 8
  542.     out    96h, al        ;select MCA channel ?
  543.     inc    dx
  544.     pause_
  545.     in    al, dx
  546.     mov    ah, al
  547.     dec    dx
  548.     pause_
  549.     in    al, dx
  550.     cmp    ah, 56h
  551.     je    dm_cont
  552.     jmp    dm_cantfind
  553.  
  554. dm_check:
  555.     mov    cx, 8
  556.     mov    bl, 8
  557. dm_loop:
  558.     mov    al, bl
  559.     out    96h, al
  560.     inc    dx
  561.     pause_
  562.     in    al, dx
  563.     mov    ah, al
  564.     dec    dx
  565.     pause_
  566.     in    al, dx
  567.     cmp    ah, 56h
  568.     je    dm_cont
  569.     inc    bl
  570.     loop    dm_loop
  571.  
  572. dm_cantfind:
  573.     xor    al, al
  574.     out    96h, al
  575.     sti
  576.     mov    dx, offset cant_find_msg
  577.     stc                    ;error
  578.     ret
  579.  
  580. dm_cont:
  581.     mov    sm_rstop_ptr, 0
  582.     test    al, 1
  583.     jnz    dm_1
  584.     mov    sm_rstop_ptr, 40h        ;16K board mem
  585. dm_1:
  586.     mov    dx, 102h
  587.     mov    al, 81h
  588.     out    dx, al
  589.     inc    dx
  590.     in    al, dx
  591.     mov    bl, al
  592.     inc    dx
  593.     in    al, dx
  594.     mov    bh, al
  595.     xor    al, al
  596.     out    96h, al
  597.     sti
  598.  
  599.     mov    endcfg, ENDCFG_FT10 + ENDCFG_BMS + ENDCFG_WTS    ;word transfer
  600.     mov    ah, bl
  601.     and    ah, 0f0h
  602.     mov    cl, 2
  603.     shr    ah, cl
  604.     or    ax, 0c000h
  605.     mov    shmem_seg, ax
  606.     mov    ah, bl
  607.     and    ah, 0eh
  608.     mov    cl, 3
  609.     shl    ax, cl
  610.     or    ax, 300h
  611.     mov    io_addr, ax        ;set IO address
  612.  
  613.     loadport
  614.     setport    EN0_IMR
  615.     xor    al, al
  616.     pause_
  617.     out    dx, al
  618.     setport    EN0_ISR
  619.     pause_
  620.     out    dx, al
  621.     mov    bl, bh
  622.     and    bx, 3
  623.     mov    al, int_no_list[bx]
  624.     mov    int_no, al        ;set IRQ
  625.  
  626. ;PIC stuff was here
  627.  
  628.     setport    20h
  629.     mov    al, 12h
  630.     out    dx, al
  631.     setport    23h
  632.     mov    al, 7ch
  633.     out    dx, al
  634.     setport    22h
  635.     mov    al, 4
  636.     out    dx, al
  637.     clc
  638.     ret
  639. endif
  640.  
  641.  
  642. get_bus_size:
  643. ;Determines bus size.  Not called on MCA cards; they use shared mem.
  644. ;If 16 bit bus, sets endcfg to ENDCFG_WTS (word transfer mode), is_16bit to 1
  645.  
  646.     loadport
  647.     setport    EN0_RSARLO
  648.     mov    ax, 100h
  649.     pause_
  650.     out    dx, al
  651.     setport    EN0_RSARHI
  652.     pause_
  653.     mov    al, ah        ;Cabletron bug: does AL -> DX, not AH
  654.     out    dx, al
  655.  
  656.     setport    EN0_RCNTLO
  657.     mov    ax, 40h
  658.     pause_
  659.     out    dx, al
  660.     setport    EN0_RCNTHI
  661.     mov    al, ah
  662.     pause_
  663.     out    dx, al
  664.  
  665.     setport    EN_CCMD
  666.     mov    al, ENC_RWRITE + ENC_START
  667.     pause_
  668.     out    dx, al
  669.  
  670.     xor    cx, cx
  671.     setport    EN0_CRDALO
  672.     pause_
  673.     in    al, dx
  674.     or    al, al
  675.     jnz    gbs_1
  676.  
  677. gbs_2:
  678.     loadport
  679.     setport    CT_DATAPORT
  680.     pause_
  681.     out    dx, ax        ;should this be AL instead of AX?
  682.  
  683. gbs_1:
  684.     inc    cx
  685.     loadport
  686.     setport    EN0_CRDALO
  687.     pause_
  688.     in    al, dx
  689.     cmp    al, 40h
  690.     jne    gbs_2
  691.  
  692.     setport    EN_CCMD
  693.     mov    al, ENC_NODMA + ENC_START
  694.     pause_
  695.     out    dx, al
  696.     setport    EN0_ISR
  697.     mov    al, 0ffh
  698.     out    dx, al
  699.  
  700.     cmp     cx, 30h
  701.     jb    gbs_ret            ; jump if 8-bit bus
  702.     or    endcfg, ENDCFG_WTS    ; use word transfer
  703.     mov    is_16bit, 1
  704.  
  705. gbs_ret:
  706.     ret
  707.  
  708.  
  709. get_mem_size:
  710. ;Determines size of on-board memory.
  711. ;Call only if not MCA (do_MCA_stuff determines mem size on MCA).
  712.  
  713. ;Write 0's to first word of all possible pages (1-255):
  714.     mov    tmp_pag, 1
  715.     mov    word ptr buf, 0
  716. gms_2:
  717.     mov    si, offset buf
  718.     mov    ah, tmp_pag
  719.     xor    al, al
  720.     mov    cx, 2
  721.     call    block_output
  722.     inc    tmp_pag
  723.     jnz    gms_2
  724.  
  725. ;Write TEST_VAL to first word of page 1:
  726.     mov    si, offset buf
  727.     mov    [si], TEST_VAL
  728.     mov    ax, 100h
  729.     mov    cx, 2
  730.     call    block_output
  731.  
  732. ;Starting at page 11h, look for TEST_VAL every 10h pages (4kb).  Page found
  733. ;(rounded to 4kb) is on-board mem size:
  734.     mov    tmp_pag, 11h
  735. gms_3:
  736.     mov    ah, tmp_pag
  737.     xor    al, al
  738.     mov    si, ax
  739.     mov    di, offset buf
  740.     mov    cx, 2
  741.     call    get_block
  742.     cmp    word ptr buf, TEST_VAL
  743.     je    gms_1
  744.     add    tmp_pag, 10h
  745.     jnb    gms_3
  746.  
  747. gms_1:
  748.     mov    al, tmp_pag
  749.     and    al, 0f0h            ;trunc mem size to nearest 4Kb
  750.     mov    sm_rstop_ptr, al
  751.  
  752.     ret
  753.  
  754.  
  755. test_mem:
  756. ;Returns CY, DX = msg if failed.
  757. ;Tests board memory by writing and reading bit patterns.
  758.  
  759.     mov    testbyte, 0ffh
  760.     call    do_test
  761.     jb    tm_err
  762.     mov    testbyte, 0
  763.     call    do_test
  764.     jb    tm_err
  765.  
  766.     clc
  767.     ret
  768. tm_err:
  769.     mov    dx, offset mem_failed_msg
  770.     stc
  771.     ret
  772.  
  773.  
  774. do_test:
  775. ;Writes `testbyte' to board memory and reads it back.
  776. ;Returns CY if failure.
  777.  
  778.     mov    tmp_pag, SM_TSTART_PG        ;? probably
  779. dt_loop:
  780.     mov    al, testbyte
  781.     mov    di, offset buf
  782.     mov    cx, BUF_SIZ
  783.     cld
  784.     rep    stosb                ;set buf = testbyte
  785.  
  786.     mov    si, offset buf
  787.     mov    ah, tmp_pag
  788.     xor    al, al
  789.     mov    cx, BUF_SIZ
  790.     call    block_output            ;write pattern to page
  791.  
  792.     mov    ah, tmp_pag
  793.     xor    al, al
  794.     mov    si, ax
  795.     mov    di, offset buf
  796.     mov    cx, BUF_SIZ
  797.     call    get_block            ;read it back
  798.  
  799.     mov    al, testbyte
  800.     mov    di, offset buf
  801.     mov    cx, BUF_SIZ
  802.     cld
  803.     rep    scasb                ;check mem we read
  804.     jne    dt_failed            ;jump if != testbyte
  805.  
  806.     inc    tmp_pag                ;go to next page
  807.     mov    al, tmp_pag
  808.     cmp    al, sm_rstop_ptr        ;have we done all pages?
  809.     jne     dt_loop                ;jump if not
  810.  
  811.     clc                    ;no error
  812.     ret
  813. dt_failed:
  814.     stc                    ;error
  815.     ret
  816.  
  817.  
  818. code    ends
  819.     end
  820.