⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
com_wild_loop:  mov     al, bios_port_num
                xor     ah, ah
                call    set_port_ser
                inc     bios_port_num
                loop    com_wild_loop

                jmp     short c_get_port_ret

com_not_wild:   call    hex_number
                call    set_port_ser
                jmp     short c_get_port_ret

com_bad:        pmsg    m_com_bad

c_get_port_ret: ret

set_com_port    ENDP


set_lpt_port    PROC    NEAR

                call    find_port_arg
                jc      lpt_bad

                cmp     al, ' '
                jbe     lpt_wild

                cmp     al, '*'
                jne     lpt_not_wild

lpt_wild:       mov     cl, num_lpt
                xor     ch, ch
                jcxz    l_get_port_ret

                mov     bios_port_num, 1

lpt_wild_loop:  mov     al, bios_port_num
                xor     ah, ah
                call    set_port_par
                inc     bios_port_num
                loop    lpt_wild_loop

                jmp     short l_get_port_ret

lpt_not_wild:   call    hex_number
                call    set_port_par
                jmp     short l_get_port_ret

lpt_bad:        pmsg    m_lpt_bad

l_get_port_ret: ret

set_lpt_port    ENDP


hex_number      PROC    NEAR

; Input:
;   ES:SI pointing at hexadecimal string
;
; Output:
;   AX = binary value
;

                xor     ax, ax          ; Clear accumulator
                mov     cl, 4

hex_loop:       mov     bl, es:[si]     ; Get the next digit
                cmp     bl, '0'         ; Check range
                jb      hex_done

                cmp     bl, 'a'
                jb      check_hex

                sub     bl, 'a' - 'A'   ; Convert to upper case

check_hex:      cmp     bl, '9'
                jbe     is_digit

                cmp     bl, 'F'
                ja      hex_done

                cmp     bl, 'A'
                jb      hex_done

                sub     bl, '7'
                jmp     short add_digit

is_digit:       sub     bl, '0'

add_digit:      shl     ax, cl
                or      al, bl

                inc     si
                jmp     hex_loop

hex_done:       ret

hex_number      ENDP


decimal_number  PROC    NEAR

; Input:
;   ES:SI pointing at decimal string
;
; Output:
;   DX:AX = decimal value
;
; NOTE:  This routine stops scanning after it overflows into DX.  It can
; handle numbers as big as 655350 before it stops scanning.
;

                xor     ax, ax          ; Clear accumulator
                xor     bx, bx
                xor     dx, dx
                mov     di, 10          ; Base 10 multiplier

decimal_loop:   mov     bl, es:[si]     ; Get the next digit
                cmp     bl, '0'         ; Check range
                jb      decimal_ret

                cmp     bl, '9'
                ja      decimal_ret

                sub     bl, '0'         ; It's a digit, so normalize it
                or      dx, dx
                jnz     dec_overflow

                mul     di              ; Multiply previous value by 10
                add     ax, bx          ; Add in new 'ones' value
                adc     dx, 0
                inc     si
                jmp     decimal_loop

decimal_ret:    clc
                ret

dec_overflow:   stc
                ret

decimal_number  ENDP


validate_port   PROC    NEAR

                test    ax, 3
                jnz     bad_port

                cmp     ax, 200H
                jb      bad_port

                cmp     ax, 8000H
                jae     bad_port

                clc
                jmp     short vp_ret

bad_port:       stc

vp_ret:         ret

validate_port   ENDP

set_port_ser    PROC    NEAR

                push    cx
                or      ax, ax
                jz      bad_ser_addr

                cmp     ax, 4
                ja      ser_do_set

                cmp     al, num_com
                ja      bad_bios_ser

                mov     bios_port_num, al
                push    es
                mov     bx, 40H
                mov     es, bx
                dec     ax
                mov     di, ax
                shl     di, 1               ; Serial table at 40:0
                mov     ax, es:[di]
                pop     es

ser_do_set:     call    validate_port
                jc      bad_ser_addr

                xor     bx, bx
                mov     cl, 0

walk_ser:       cmp     cl, num_ser_ports
                jae     new_ser

                cmp     ax, serial_ports[bx].SERIAL_PORT_DEF.sp_address
                je      set_port_ret                ; Ignore duplicate address

                inc     cl
                add     bx, TYPE SERIAL_PORT_DEF
                jmp     walk_ser

new_ser:        cmp     num_ser_ports, MAX_SERIAL_PORTS
                jae     too_many_ser

                mov     serial_ports[bx].SERIAL_PORT_DEF.sp_address, ax
                push    es
                push    di
                xor     di, di
                mov     cx, 40H
                mov     es, cx
                mov     cl, num_com
                xor     ch, ch
        repne   scasw
                mov     ax, di
                pop     di
                pop     es
                je      save_ser_bios

                xor     ax, ax

save_ser_bios:  shr     al, 1
                mov     serial_ports[bx].SERIAL_PORT_DEF.sp_biosnum, al
                inc     num_ser_ports
                inc     num_ports
                jmp     short set_port_ret

bad_ser_addr:   push    ax
                pmsg    m_bad_ser_addr
                jmp     short show_hex_addr

bad_bios_ser:   push    ax
                pmsg    m_bad_bios_ser
                jmp     short show_hex_addr

too_many_ser:   push    ax
                pmsg    m_too_many_ser

show_hex_addr:  pop     ax
                call    show_hex
                call    show_crlf

set_port_ret:   pop     cx
                ret

set_port_ser    ENDP

set_port_par    PROC    NEAR

                push    cx
                or      ax, ax
                jz      bad_par_addr

                cmp     ax, 3
                ja      par_do_set

                cmp     al, num_lpt
                ja      bad_bios_par

                mov     bios_port_num, al
                push    es
                mov     bx, 40H
                mov     es, bx
                dec     ax
                mov     di, ax
                shl     di, 1               ; Serial table at 40:0
                add     di, 8               ; Parallel table at 40:8
                mov     ax, es:[di]
                pop     es

par_do_set:     call    validate_port
                jc      bad_par_addr

                xor     bx, bx
                mov     cl, 0

walk_par:       cmp     cl, num_par_ports
                jae     new_par

                cmp     ax, parallel_ports[bx].PARALLEL_PORT_DEF.pp_address
                je      par_sp_ret          ; Ignore duplicate address

                inc     cl
                add     bx, TYPE PARALLEL_PORT_DEF
                jmp     walk_par

new_par:        cmp     num_par_ports, MAX_PARALLEL_PORTS
                jae     too_many_par

                mov     parallel_ports[bx].PARALLEL_PORT_DEF.pp_address, ax
                push    es
                push    di
                mov     di, 8
                mov     cx, 40H
                mov     es, cx
                mov     cl, num_lpt
                xor     ch, ch
        repne   scasw
                mov     ax, di
                pop     di
                pop     es
                je      save_par_bios

                mov     al, 8

save_par_bios:  sub     al, 8
                shr     al, 1
                mov     parallel_ports[bx].PARALLEL_PORT_DEF.pp_biosnum, al
                inc     num_par_ports
                inc     num_ports
                jmp     short par_sp_ret

bad_par_addr:   push    ax
                pmsg    m_bad_par_addr
                jmp     short show_hex_par

bad_bios_par:   push    ax
                pmsg    m_bad_bios_par
                jmp     short show_hex_par

too_many_par:   push    ax
                pmsg    m_too_many_par

show_hex_par:   pop     ax
                call    show_hex
                call    show_crlf

par_sp_ret:     pop     cx
                ret

set_port_par    ENDP

show_crlf       PROC    NEAR

                pmsg    cr_lf
                ret

show_crlf       ENDP

show_hex        PROC    NEAR

                push    bx
                push    cx
                mov     bx, 3
                mov     cl, 4

skip_zero_loop: test    ah, 0F0H
                jnz     show_digits

                rol     ax, cl
                dec     bx
                jnz     skip_zero_loop

show_digits:    inc     bx

show_dig_loop:  rol     ax, cl
                mov     dl, al
                and     dl, 0FH
                add     dl, '0'
                cmp     dl, '9'
                jbe     show_dig

                add     dl, 7

show_dig:       call    show_char
                dec     bx
                jnz     show_dig_loop

                pop     cx
                pop     bx
                ret

show_hex        ENDP

show_address    PROC    NEAR

                mov     dl, '('
                call    show_char
                call    show_hex
                mov     dl, ')'
                call    show_char
                ret

show_address    ENDP

show_char       PROC    NEAR
                PUBLIC  show_char

                push    ax
                mov     ah, 2
                int     21H
                pop     ax
                ret

show_char       ENDP

IFDEF   DEBUG
wait_message    db      LF, "Hit any key to continue. . .$"

wait_for_key    PROC    NEAR

                pmsg    wait_message

                mov     ah, 08H         ; Wait for any key
                int     21H

                call    show_crlf

                ret

wait_for_key    ENDP
ENDIF

; get_max_secsize finds the largest allowable sector size on the MASTER
; system.  Any device that has a sector size larger that max_secsize on the
; slave system cannot be used!  This subroutine also determines the first
; unit number!
; 
get_max_secsize PROC    NEAR

                mov     ah, 52H         ; Get DOS's list of lists
                int     21H

                ; Use DOS 3.0+ offsets

                mov     ax, es:[bx + 10H]   ; Max sector size
                mov     cl, es:[bx + 20H]   ; First unit

                mov     max_secsize, ax
                mov     first_unit, cl

                ret

get_max_secsize ENDP

read_timer      PROC    NEAR

                pushf
                cli
                mov     al, TIMER_0_LATCH
                out     TIMER_CTL, al   ;Latch current count in 8253
                jmp     short $+2       ;Insure 5 clocks for 8253 recovery time
                in      al, TIMER_0     ;Get low order byte
                mov     ah, al          ;Save it in AH
                jmp     short $+2       ;Insure 5 clocks for 8253 recovery time
                in      al, TIMER_0     ;Get high order byte
                popf
                ret

read_timer      ENDP

; make_client_id gets an arbitrary non-zero number and places it in
; client_id.  This value is used to identify this image of the device driver
; to the server system.  If the ID's don't match in a SERVER_INFO exchange,
; the initialized flag will be cleared to force a re-initialization.
;
make_client_id  PROC    NEAR

                push    bx
                push    cx
                push    dx
                push    si
                push    es
                mov     si, 40H
                mov     es, si
                xor     si, si
                mov     cx, 64

; Build a 32-bit machine ID by XORing the first 64 DWORDS in the BIOS data
; area into DX:BX.  Let DX:BX start with whatever happens to be in them at
; the time.

build_loop:     lodsw
                xor     bx, ax
                lodsw
                xor     dx, ax
                loop    build_loop

                call    read_timer      ; Now XOR timer value into high word
                xor     bx, ax
                call    read_timer      ; and again into low word
                xor     dx, ax

                or      bx, dx
                jnz     @F

                inc     bx              ; insure != 0

@@:             mov     word ptr client_id, bx
                mov     word ptr client_id + 2, dx
                pop     es
                pop     si
                pop     dx
                pop     cx
                pop     bx
                ret

make_client_id ENDP

init_end        LABEL   BYTE

INIT            ENDS

                END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -