📄 init.asm
字号:
;***
;* $Workfile: init.asm $
;* $Revision: 1.5 $
;* $Author: Dave Sewell $
;* $Date: 08 Aug 1989 16:44:52 $
;***
TITLE Expansion Box Main Device Driver
PAGE 66, 132
INCLUDE drivers.mac
INCLUDE packets.mac
INCLUDE debug.mac
CORE SEGMENT WORD PUBLIC 'CODE'
EXTRN C int2f_handler:FAR
EXTRN C int25_handler:FAR
EXTRN C int26_handler:FAR
EXTRN header:BYTE
EXTRN lpt3_header:BYTE
EXTRN lpt2_header:BYTE
EXTRN lpt1_header:BYTE
EXTRN strat_seg:WORD
EXTRN intr0_seg:WORD
EXTRN intr1_seg:WORD
EXTRN intr2_seg:WORD
EXTRN intr3_off:WORD
EXTRN intr3_seg:WORD
EXTRN end_low_stub:BYTE
EXTRN finger_print:BYTE
EXTRN setup_ports_parallel:NEAR
EXTRN setup_ports_serial:NEAR
EXTRN reset_ports_parallel:NEAR
EXTRN reset_ports_serial:NEAR
EXTRN intr_error:FAR
IFDEF DEBUG
EXTRN debug_init:NEAR
EXTRN debug_msg:WORD
EXTRN hex_out:WORD
ENDIF
EXTRN gri_proc:NEAR
EXTRN send_sync_proc:NEAR
EXTRN driver_call:DWORD
EXTRN header_seg:WORD
EXTRN driver_id:BYTE
EXTRN client_id:DWORD
EXTRN max_baud:BYTE
EXTRN client_max_baud:BYTE
EXTRN idle_semaphore:BYTE
EXTRN max_secsize:WORD
EXTRN dos_version:WORD
EXTRN dos_major:BYTE
EXTRN rhptr:DWORD
EXTRN bios_port_num:BYTE
EXTRN is_serial:BYTE
EXTRN port_address:WORD
EXTRN port_index:WORD
EXTRN int2f_ok:BYTE
EXTRN old_int2f_vec:DWORD
EXTRN old_int25_vec:DWORD
EXTRN old_int26_vec:DWORD
EXTRN num_ports:BYTE
EXTRN num_ser_ports:BYTE
EXTRN num_par_ports:BYTE
EXTRN serial_ports:BYTE
EXTRN parallel_ports:BYTE
EXTRN printer_loaded:BYTE
EXTRN parallel_start:BYTE
EXTRN par_fixup_start:WORD
EXTRN par_fixup_end:WORD
EXTRN device_high:BYTE
EXTRN init_size:WORD
EXTRN low_memory:BYTE
EXTRN driver_size:WORD
EXTRN initialized:BYTE
EXTRN display_scan:BYTE
EXTRN fx_force_variable:BYTE
EXTRN Virt_Dev_File:BYTE
EXTRN Win386_Startup_Info:Win386_Startup_Info_Struc
CORE ENDS
BLOCK SEGMENT WORD PUBLIC 'CODE'
EXTRN intr_vector:WORD
EXTRN normal_intr:NEAR
EXTRN block_start:BYTE
EXTRN block_init_end:BYTE
EXTRN bpb_array:WORD
EXTRN units:BYTE
EXTRN default_units:BYTE
EXTRN first_unit:BYTE
EXTRN dd_attributes:WORD
EXTRN max_devices:BYTE
EXTRN dispatch:WORD
EXTRN bpb_pnt_array:WORD
EXTRN lpt_unused:NEAR
BLOCK ENDS
SERIAL SEGMENT WORD PUBLIC 'CODE'
SERIAL ENDS
PARALLEL SEGMENT WORD PUBLIC 'CODE'
EXTRN par_fixup1:WORD
EXTRN par_fixup2:WORD
EXTRN par_fixup3:WORD
EXTRN par_fixup4:WORD
PARALLEL ENDS
PRINTER SEGMENT WORD PUBLIC 'CODE'
EXTRN prn_fixup:WORD
PRINTER ENDS
EXTRN serial_start:BYTE
EXTRN printer_start:BYTE
EXTRN comma_space:BYTE
EXTRN invalid_switch:BYTE
EXTRN product_name:BYTE
EXTRN port_address_msg:BYTE
EXTRN port_address_loc:BYTE
EXTRN ser_port_name:BYTE
EXTRN ser_port_number:BYTE
EXTRN par_port_name:BYTE
EXTRN par_port_number:BYTE
EXTRN baud_msg:BYTE, baud_loc:BYTE
EXTRN irq_msg:BYTE, irq_loc:BYTE
EXTRN cr_lf:BYTE
EXTRN signon_default:BYTE, signon_dfirst:BYTE
EXTRN signon_paren:BYTE
EXTRN signon_dlast:BYTE, signon_ndrives:WORD
EXTRN printer_default:BYTE, printer_dfirst:BYTE
EXTRN printer_paren:BYTE
EXTRN printer_dlast:BYTE, printer_ndrives:BYTE
EXTRN msg_no_ports:BYTE
EXTRN msg_no_devices:BYTE
EXTRN too_big:BYTE
EXTRN m_bad_ser_addr:BYTE
EXTRN m_too_many_ser:BYTE
EXTRN m_bad_bios_ser:BYTE
EXTRN m_bad_par_addr:BYTE
EXTRN m_too_many_par:BYTE
EXTRN m_bad_bios_par:BYTE
EXTRN m_com_bad:BYTE
EXTRN m_lpt_bad:BYTE
EXTRN m_connect_try:BYTE
EXTRN m_connect_ok:BYTE
EXTRN m_connect_fail:BYTE
EXTRN m_baud_error:BYTE
EXTRN m_max_baud:BYTE
MAXCMD equ 16 ; Maximum allowed command code
; 12 for MS-DOS 2.x
; 16 for MS-DOS 3.0-3.1
; 24 for MS-DOS 3.2-3.3
TIMER_0 EQU 40H ;8253 counter 0 port
TIMER_CTL EQU 43H ;8253 control port
TIMER_0_LATCH EQU 00H ;8253 cmd to save channel 0 current count
DOS30 EQU (3 SHL 8) + 30 ; MS-DOS 3.30 word format version number
DOS331 EQU (3 SHL 8) + 31 ; MS-DOS 3.31 word format version number
DOS40 EQU (4 SHL 8) + 00 ; MS-DOS 4.00 word format version number
DOS50 EQU (5 SHL 8) + 00 ; MS-DOS 5.00 word format version number
INIT SEGMENT WORD PUBLIC 'CODE'
PUBLIC get_dos_version
PUBLIC show_crlf
PUBLIC init_end
EXTRN num_lpt:BYTE
EXTRN num_com:BYTE
EXTRN auto_str:BYTE
EXTRN spaces_str:BYTE
EXTRN none_str:BYTE
EXTRN printer_init:NEAR
EXTRN printer_signon:BYTE
EXTRN drives_error:BYTE
EXTRN no_drives:BYTE
EXTRN no_printers:BYTE
EXTRN m_prn_cl_letter:BYTE
EXTRN m_prn_se_letter:BYTE
EXTRN m_prn_map:BYTE
EXTRN m_lost_connect:BYTE
EXTRN actual_prn_map:BYTE
EXTRN packet_buf:BYTE
EXTRN m_map_header:BYTE
EXTRN m_drive_map:BYTE
EXTRN m_client_letter:BYTE
EXTRN m_server_letter:BYTE
EXTRN m_no_driver:BYTE
EXTRN send_pack:WORD
EXTRN recv_pack:WORD
EXTRN drive_mapping:BYTE
ORG 0
DB "Copyright (C) 1989-1991 by Sewell Development Corp."
force_low db 0 ; Set non-zero if forcing low memory
bpb_start dw ?
noscan db 0
auto db 0 ; TRUE if load only on connect
umb_allocated db 0 ; Set TRUE if high mem block allocated
initialize PROC NEAR ; function 0 = initialize driver
PUBLIC initialize
mov ax, cs
mov WORD PTR driver_call + 2, ax
mov header_seg, ax
IFDEF DEBUG
call debug_init
ENDIF
call signon
get_version: call get_dos_version ; Get DOS version number
call make_client_id ; Get an arbitrary client ID
les di, rhptr
call get_equipment
les si, es:[di].init_req.init_cmd ; es:si -> command line
call parse_args ; Parse and process command line args
jc init_no_install
call get_max_secsize ; Get the maximum sector size on MASTER
; Also get first unit number
mov al, 'Z' - 'A' + 1 ; Calculate max devices
sub al, first_unit
mov max_devices, al
mov al, default_units
cmp al, max_devices ; See if we can use all of the default
jbe save_units ; devices
mov al, max_devices ; If not enough device letters, use only
; those that are available
save_units: mov units, al ; Save the number of units
; Force NON_IBM format. This will avoid the initial read of the first
; sector of the FAT before a build BPB call. The slave system will perform
; this read if necessary.
;
; Force OCRM, HUGE, & GEN_IOCTL. We maintain count of the open files even
; if the
; slave driver doesn't. We will always use HUGE addressing, the read and
; write I/O routines, convert the 32-bit sector numbers into the appropriate
; format for the slave system. We must force HUGE because the other side
; may use HUGE addressing and we don't know about it (because communications
; couldn't be established above). If we didn't, we might start addressing
; a HUGE disk on the slave system with small sectors -- which would destroy
; the disk!!! On DOS versions before 3.31, this bit should be ignored!
mov header.device_header.attribute, ATT_NON_IBM OR ATT_OCRM OR ATT_HUGE OR ATT_GEN_IOCTL
;--- Load only those segments of code into memory which are really needed ---
push ds
pop es
mov di, DVR:block_init_end
mov ax, DVR:normal_intr
sub ax, DVR:intr_vector + 2
mov intr_vector, ax
mov di, DVR:serial_start
cmp num_ser_ports, 0
je copy_parallel
mov di, DVR:parallel_start
copy_parallel: cmp num_par_ports, 0
je copy_printer
mov si, DVR:parallel_start
mov cx, DVR:printer_start
call check_copy_code
jc copy_printer ; Carry set if no copy needed
sub par_fixup1, ax
sub par_fixup2, ax
sub par_fixup3, ax
sub par_fixup4, ax
rep movsw
mov si, DVR:par_fixup_start
mov cx, DVR:par_fixup_end
call fixup_table
copy_printer: cmp printer_loaded, 0
je fixup_bpbs
mov si, DVR:printer_start
mov cx, DVR:bpb_array
call check_copy_code
jc fixup_bpbs
rep movsw
sub WORD PTR prn_fixup, ax
fixup_bpbs: mov bpb_start, di
cmp units, 0
je check_size
mov si, DVR:bpb_array
cmp si, di
je check_size
mov cx, (MAX_DEVICES * TYPE bios_parameter_block) / 2
rep movsw
mov ax, bpb_start
mov cx, MAX_DEVICES
mov di, DVR:bpb_pnt_array
fix_bpb_pnt: stosw
add ax, TYPE bios_parameter_block
loop fix_bpb_pnt
check_size: mov al, units ; Now calculate length of BPB array
mov cl, TYPE bios_parameter_block
mul cl
add ax, bpb_start ; Calculate Driver length
mov cx, ax ; cx = break address offset
add ax, 000FH ; Include all of last paragraph in
and ax, 0FFF0H ; required space message
cmp dos_version, DOS50
jl save_size
; have determined that we are dos 5.0 or greater, so
; check end address to make sure we will not go past
; it with bpb array.
mov dx, cs
mov cl, 4
shr ax, cl
add dx, ax
; compare max address seg. to break seg (both
; normalized) to see if we will fit
les di, rhptr
mov bx, WORD PTR es:[di].init_ans.init_end
shr bx, cl
add bx, WORD PTR es:[di].init_ans.init_end + 2
cmp dx, bx
jbe load_size_ok
pmsg too_big
jmp init_no_install ; Not enough room!
load_size_ok: shl ax, cl ; restore ax to num bytes
save_size: mov driver_size, ax ; Save driver size in bytes
mov init_size, ax
cmp num_ports, 0
jne init_show_port
pmsg msg_no_ports
jmp init_no_install
init_show_port: cmp units, 0
jne @F
cmp printer_loaded, 0
jne @F
pmsg msg_no_devices
jmp init_no_install
@@: call show_max_baud
mov bx, cs
cmp bx, 0A000H
jb in_low
inc device_high
dec low_memory ; Set low_memory to 0
jmp short connect_scan
in_low: cmp force_low, 0
jne connect_scan
cmp dos_version, DOS50
jb connect_scan
mov bx, driver_size ; Get size (already rounded up)
mov cl, 4
shr bx, cl ; Convert size to paragraphs
mov ah, 48H ; Try to allocate UMB memory block
int 21H
jc connect_scan ; Failed - must be none available
inc umb_allocated
mov strat_seg, ax
mov intr0_seg, ax
mov intr1_seg, ax
mov intr2_seg, ax
mov intr3_seg, ax
mov WORD PTR driver_call + 2, ax
dec low_memory
mov init_size, (DVR:end_low_stub + 15)
and init_size, 0FFF0H
dec ax ; Point to MCB just in front
mov es, ax
inc ax ; Restore our segment
mov si, DVR:finger_print
mov di, 8
mov es:[di - 7], ax ; Point "owner" word to us
mov cx, 4
rep movsw
mov es, ax
xor si, si
xor di, di
mov cx, driver_size
shr cx, 1 ; Change to word count
rep movsw ; ===> Move the driver! <===
mov ds, ax ; Update DS with new driver seg
connect_scan: call setup_ports_parallel ; Parallel setup
call setup_ports_serial ; Serial setup
cmp cs:noscan, 0
jne init_show
call connect
jnc init_show ; Connection succeeded
cmp cs:auto, 0 ; Connection failed
je init_show
call reset_ports_parallel
call reset_ports_serial
jmp init_no_install
init_show: call printer_init ; Printer redirection setup
call show_units
call show_printers
cmp initialized, 0
je init_continue
call show_drive_map
jc init_continue
call show_prn_map
init_continue: call hook_int2f
call hook_int25_26
init_done: mov idle_semaphore, MINIMUM_TICKS + 1
les di, rhptr
;--- Unlink LPT drivers that aren't necessary.
mov ax, DVR:header
cmp units, 0
jne check_num_lpt
mov ax, -1 ; Cause block driver to be unlinked
check_num_lpt: cmp printer_loaded, 0
je load_only_one
cmp num_lpt, 0
je zero_lpts
cmp num_lpt, 1
je one_lpt
load_only_one: mov cs:lpt3_header.device_header.next_offset, ax
cmp printer_loaded, 0
je make_null
cmp num_lpt, 2
je init_ret_size
make_null: mov WORD PTR cs:lpt3_header.device_header.name_num, "UN"
mov WORD PTR cs:lpt3_header.device_header.name_num[2], "2L"
mov cs:intr3_off, DVR:lpt_unused
jmp short init_ret_size
zero_lpts: mov cs:lpt1_header.device_header.next_offset, ax
jmp short init_ret_size
one_lpt: mov cs:lpt2_header.device_header.next_offset, ax
init_ret_size: mov ax, init_size
mov WORD PTR es:[di].static_rhp.rhp_status, STATUS_DONE
mov WORD PTR es:[di].init_ans.init_end, ax
mov WORD PTR es:[di].init_ans.init_end + 2, cs ; Break address
cmp init_size, 0
jne init_ret
;--- We are not going to load, so unlink the other drivers.
mov cs:lpt3_header.device_header.next_offset, -1
cmp cs:umb_allocated, 0
je init_ret
mov es, strat_seg
mov ah, 49H
int 21H ; Return allocated block in UMB
init_ret: ret
init_no_install:mov units, 0 ; and do not install driver
mov printer_loaded, 0
mov init_size, 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -