📄 core.asm
字号:
server_multitasker db ?
seq_num db ?
num_ports db 0
num_ser_ports db 0
num_par_ports db 0
serial_ports db TYPE SERIAL_PORT_DEF * MAX_SERIAL_PORTS DUP (?)
parallel_ports db TYPE PARALLEL_PORT_DEF * MAX_PARALLEL_PORTS DUP (?)
save_area db 5 DUP (?) ; Save area for port state info
timeout db 0
code_list_ptr dw ?
code_save dw (2 + MAX_FIXUPS) dup (?)
ticks_remaining dw ? ; Number of ticks until timeout occurs
alarm_vector dw ?
set_alarm_time dw ?
bios_tab_ptr dw ?
bios_port_save dw ?
EVEN
par_timer_save dd 0 ; Old timer vector
;--- The serial_id byte must immediately precede the serial jump vectors ---
db ?
serial_id db 1 ; Gets copied into is_serial
;========================= Offsets into serial segment ====================
;=================== Must be fixed up if serial code moved ================
send_pack_svec DW DVR:send_pack_serial
recv_pack_svec DW DVR:recv_pack_serial
;--- The parallel_id byte must immediately precede the parallel jump vectors ---
db ?
parallel_id db 0 ; Gets copied into is_serial
par_fixup_start LABEL WORD
;========================= Offsets into parallel segment ====================
;=================== Must be fixed up if parallel code moved ================
send_pack_pvec DW DVR:send_pack_parallel
recv_pack_pvec DW DVR:recv_pack_parallel
send_sync_pvec DW DVR:send_sync_parallel
save_par_vec DW DVR:save_parallel
restore_par_vec DW DVR:restore_parallel
;******************************************************************************
;* IMPORTANT NOTE: There must not be more than MAX_FIXUPS entries in any of
;* the lists below (not counting the initial fail address and trailing null).
;*
;* Also, each jump must be within short jump distance (128 bytes) of the fail
;* address, or of the the next jump that follows it.
;******************************************************************************
send_sync_list dw DVR:ss_timeout, DVR:ssp1, DVR:ssp2, DVR:ssp3, 0
send_word_list dw DVR:sw_timeout, DVR:swp1, DVR:swp2, 0
send_pack_list2 dw DVR:sp_timeout, DVR:spp2, DVR:spp3, DVR:spp4, 0
sp_normal_list dw DVR:spn_timeout, DVR:spn2, DVR:spn3, DVR:spn4, 0
recv_word_list dw DVR:rw_timeout, DVR:rwp1, DVR:rwp2, 0
recv_pack_list dw DVR:rp_timeout, DVR:rpp1, DVR:rpp2, DVR:rpp3, 0
rp_normal_list dw DVR:rpn_timeout, DVR:rpn1, DVR:rpn2, DVR:rpn3, 0
wait_send_list dw DVR:wsa_timeout, DVR:wsa1, 0
par_fixup_end LABEL WORD
timer_jmp dw ?
;----------------------------------------------------------------------------
;--- Data for printer code -------------------------------------------------
request dw ? ; request (save area for al)
port db ? ; port number
old_int17 dd ? ; Old interrupt 17H vector
;----------------------------------------------------------------------------
device_high db 0 ; Set to 1 if DEVICEHIGH was used
init_size dw ? ; Size to tell INIT
low_memory db 1 ; TRUE if loaded in low memory
driver_size dw ? ; Device driver size in bytes
num_com db ?
num_lpt db ?
display_scan db 0
fx_force_variable db 0
packet_buf db MAX_PACKET DUP (?) ; buffer for packets
end_core_data LABEL BYTE
PUBLIC strat
strat PROC FAR ; device driver "Strategy" routine
; called from MS-DOS driver with
; ES:BX = address of request header
mov WORD PTR cs:rhptr, bx
mov WORD PTR cs:rhptr + 2, es
ret ; Save pointer and return to MS-DOS
strat ENDP
intr_error PROC FAR
push es
push bx
les bx, cs:rhptr
mov es:[bx].static_rhp.rhp_status, STATUS_ERROR OR STATUS_DONE OR \
ERR_UNK_COMMAND
pop bx
pop es
ret
intr_error ENDP
far_call PROC FAR
call ax
ret
far_call ENDP
port_num db 90H
error_proc LABEL NEAR
stc ; Indicate error
null_proc LABEL NEAR
ret
show_dot PROC NEAR
cmp display_scan, 0
je show_dot_ret
push ax
push dx
mov dl, '.'
mov ah, 2
int 21H
pop dx
pop ax
show_dot_ret: ret
show_dot ENDP
start_vxd PROC NEAR
pushf
cmp win_386_api_ok, 0
je start_done
push ax
mov ax, SET_VMSTAT_HIGH_PRI_BACK
call dword ptr win_386_api
pop ax
start_done: popf
ret
start_vxd ENDP
end_vxd PROC NEAR
pushf
cmp win_386_api_ok, 0
je done
push ax
mov ax, RESET_VMSTAT_HIGH_PRI_BACK
call dword ptr win_386_api
pop ax
done: popf
ret
end_vxd ENDP
zero_bios_table PROC NEAR
mov bios_tab_ptr, 0FFFFH
cmp port_address, 0
je zero_done
cld
mov ax, 40H
mov es, ax
mov ax, port_address
mov bios_port_save, ax
mov cx, 4
xor di, di
cmp is_serial, 0
jne scan_table
mov cx, 3
mov di, 8
scan_table: repne scasw
jne zero_done
sub di, 2
mov bios_tab_ptr, di
mov word ptr es:[di], 0
zero_done: ret
zero_bios_table ENDP
;************************************************************************
;* Interlnk 2FH interface:
;*
;* Input:
;* AH = 56H (for all functions)
;* AL = function number
;* (0 = install check, 1 = drive check, 2 = port address check)
;* BL = logical Interlnk driver number (0 = any, 1 = 1st, 2 = 2nd, etc.)
;* BH = drive number (subfunction 1 only, 0 = drive A, 1 = B, etc.)
;* CX = port address (used only for subfunction 2)
;* DX = FFFF
;* Return values:
;* AL = FF on success, 0 on failure (or unchanged if no responding driver)
;* BL = logical Interlnk driver number of responding driver
;* CL = major version number of responding Interlnk driver
;* CH = minor version number of responding Interlnk driver
;* DX = segment address of responding Interlnk driver
;************************************************************************
int2f_handler PROC FAR
cmp ah, INTERLNK_MULTIPLEX_ID
jne check_win
cmp dx, 0FFFFH
jne int2f_done
cmp bl, 0
je check_function
cmp bl, cs:driver_id
jne int2f_done
check_function: cmp al, 0
je ok
cmp al, 1 ; Check drive letter
je check_drive
cmp al, 2
jne int2f_done
cmp cx, cs:port_address
jne fail
jmp ok
check_drive: cmp bh, 25
ja int2f_done ; Pass on if bad drive number
cmp bh, cs:first_unit
jb fail
push ax
mov ah, cs:first_unit
add ah, cs:units
cmp bh, ah
pop ax
jae fail
jmp short ok
fail: or bl, bl ; If any driver, pass it on
jz int2f_done
mov al, 0
jmp short answer
ok: mov al, 0FFH ; Return AL = 0FFH for installed
answer: mov bl, cs:driver_id ; Return BL = logical driver number
mov cx, WORD PTR cs:major_version ; CL = major, CH = minor version #
mov dx, cs ; Return DX = segment of driver
iret
check_win: cmp ah, 16h
jne int2f_done ; Not windows API interrupt
cmp al, 5
je windows_init
cmp al, 6
je windows_exit
cmp al, 8
je win_init_done
cmp al, 9
je win_begin_exit
jmp int2f_done
windows_init: test dl, 1
jnz win_std_init ; Non-zero = standard mode init
.386
pusha
push ds
push es
mov ax, cs
mov ds, ax
mov win386_enh_mode, 1
call zero_bios_table
pop es
pop ds
popa
.8086
pushf
call dword ptr cs:old_int2f_vec
mov word ptr cs:Win386_Startup_Info.SIS_Next_Dev_Ptr, bx
mov word ptr cs:Win386_Startup_Info.SIS_Next_Dev_Ptr[2], es
push cs
pop es
mov bx, DVR:Win386_Startup_Info
jmp short int2f_ret
win_std_init: mov cs:win386_std_mode, 1
jmp short int2f_done
windows_exit: test dl, 1
jnz win_std_exit ; Non-zero = standard mode exit
mov cs:win386_enh_mode, 0
jmp short int2f_done
win_std_exit: mov cs:win386_std_mode, 0
jmp short int2f_done
win_init_done: push ax
push bx
push di
push es
;--- Restore the port we zeroed in the BIOS table (if there was one).
cmp cs:bios_tab_ptr, 0FFFFH
je restore_done
mov ax, 40H
mov es, ax
mov ax, cs:bios_port_save
mov di, cs:bios_tab_ptr
mov word ptr es:[di], ax
restore_done: xor di, di
mov es, di ; Zero ES:DI
mov ax, 1684h
mov bx, VFXD_Device_ID
int 2Fh
mov word ptr cs:win_386_api, di
mov ax, es
mov word ptr cs:win_386_api[2], ax
or ax, di
pop es
pop di
pop bx
pop ax
jz no_api
push ax
push ds
push di
mov di, cs
mov ds, di
lea di, win_386_api_ok
mov al, -1
call dword ptr win_386_api
pop di
pop ds
pop ax
no_api: jmp short int2f_done
win_begin_exit: mov cs:win_386_api_ok, 0
;### jmp short int2f_done
;--- Pass on the INT 2F to the previous handler
int2f_done: cmp cs:int2f_ok, 0
jne pass_int2f
int2f_ret: iret
pass_int2f: jmp dword ptr cs:old_int2f_vec
int2f_handler ENDP
int25_handler PROC FAR
cmp al, cs:first_unit
jb int25_pass
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -