Category : Files from Magazines
Archive   : PJ95.ZIP
Filename : IOISR.ASM

 
Output of file : IOISR.ASM contained in archive : PJ95.ZIP
;---------------------------------------------------------------
;ioisr - Interrupt Service Routines for I/O Monitor |
;--------------------------------------------------------------|
;Copyright 1991 ASMicro Co. |
;--------------------------------------------------------------|
; 5/25/91 Rick Knoblaugh |
;--------------------------------------------------------------|
;include files |
;---------------------------------------------------------------
.386P
include ioequ.inc
include iomac.inc
include iostruc.inc


data segment para public 'data16' use16
extrn start_port:WORD
extrn end_port:WORD
extrn old_int1:DWORD
extrn old_user_int:DWORD
extrn io_table:BYTE
extrn IO_TAB_ENTRIES:ABS
extrn access_port:word
extrn access_info:byte
extrn store_buf:byte
extrn store_buf_end:ABS
extrn store_ptr:word
extrn display_loc:word
extrn trap_status:byte
data ends

gdt_seg segment para public 'data16' use16
extrn sel_databs:byte
extrn sel_video:byte
extrn sel_data:byte
extrn sel_tss_alias:byte
gdt_seg ends

tss_seg segment para public 'data16' use16
tss_seg ends


isrcode segment para public 'icode16' use16
assume cs:isrcode, ds:nothing, es:nothing
;--------------------------------------------------------------
;PUBLICS |
;--------------------------------------------------------------
public int1_isr
public user_int_isr
public int_0
public int_2
public int_3
public int_4
public int_5
public int_6
public int_7
public except_8
public except_9
public except_0ah
public except_0bh
public except_0ch
public except_0dh
public except_0eh
public except_0fh
public int_20h
public int_21h
public int_22h
public int_23h
public int_24h
public int_25h
public int_26h
public int_27h

public int_70h
public int_71h
public int_72h
public int_73h
public int_74h
public int_75h
public int_76h
public int_77h

irp z, <0, 2, 3, 4, 5, 6, 7>
DOINT &z
endm

irp z, <8, 9, 0ah, 0bh, 0ch, 0dh, 0eh, 0fh>
DOEXCP &z
endm

irp z, <20h, 21h, 22h, 23h, 24h, 25h, 26h, 27h>
DOEXCPH &z
endm

irp z, <70h, 71h, 72h, 73h, 74h, 75h, 76h, 77h>
DOINT &z
endm

;--------------------------------------------------------------
;int1_isr - ISR for single step interrupt. If trap_status |
; has EXPECT_INT1 bit set, this is the trap |
; that occurs just after the I/O instruction |
; we are monitoring executes. Store the I/O data |
; from ax into our buffer. |
;--------------------------------------------------------------
int1_isr proc far
push bp
mov bp, sp
push bx
push ds
mov bx, offset gdt_seg:sel_data
mov ds, bx
assume ds:data
test trap_status, EXPECT_INT1 ;expecting an int 1?
jnz int1_050
pop ds
pop bx
push 1
jmp pass_thru ;if not, do old int 1
int1_050:
push ax
push cx
push dx
mov trap_status, 0
and [bp].s_eflags, NOT TRAP_FLAG ;no more single step
mov bx, store_ptr
mov cl, access_info
or cl, CONTAINS_DATA ;indicate data stored
mov [bx].buf_info, cl ;store info re i/o
mov dx, access_port
mov [bx].buf_port, dx ;store port number
test cl, AWORD ;word access?
jnz int1_100
sub ah, ah ;if not, clear half
int1_100:
mov [bx].buf_data, ax
add bx, size buf_record ;advance buf ptr
cmp bx, store_buf_end - size buf_record ;at end?
jb int1_200
mov bx, offset store_buf
int1_200:
mov store_ptr, bx ;save new ptr
and cx, (AWORD OR ABYTE) ;number of bits
mov ah, 1 ;indicate set
mov dx, access_port
call do_bit_map ;set the bits again
pop dx
pop cx
pop ax
pop ds
pop bx
pop bp
iretd
int1_isr endp

;--------------------------------------------------------------
;except_handler - Process as follows: |
; |
; Int 0dh - Go look for software int or |
; I/O instruction. |
; Any other |
; exception - go display exception number |
; and halt. |
;--------------------------------------------------------------
except_handler proc near
mov bp, sp
cmp [bp].e_pushed_int , GEN_PROT_EXCEP
je gen_prot_isr
mov ax, [bp].e_pushed_int ;int in ax, go display
jmp short fatal_error
except_handler endp

fatal_error proc near
call display_it
jmp $
fatal_error endp

;--------------------------------------------------------------
;display_it - Display hex number on screen at next display |
; offset. |
; |
; Enter: number in AX |
; processor in protected mode |
; |
; All registers saved |
;--------------------------------------------------------------
display_it proc near
pusha
push ds
push es

mov dx, offset gdt_seg:sel_data
mov ds, dx ;get our data segment
assume ds:data
mov dx, offset gdt_seg:sel_video
mov es, dx ;and video segment
mov di, display_loc
xchg al, ah ;print MSB first
call put_hex_digit
xchg al, ah ;get LSB
call put_hex_digit
add di, 2 ;past space and attribute
cmp di, VID_PAGE_SIZE
jb display_i100
xor di, di ;back to start of page
display_i100:
mov display_loc, di
pop es
pop ds
popa
ret
display_it endp

put_hex_digit proc near
push ax
mov cx, 2 ;2 digits in al
mov ah, al
put_hex_100:
shr al, 4
cmp al, 9
ja put_hex_200
add al, '0'
jmp short put_hex_300
put_hex_200:
add al, 'A' - 10
put_hex_300:
cld
stosb
inc di ;past attrib
mov al, ah
shl al, 4
loop put_hex_100
pop ax
ret
put_hex_digit endp

;--------------------------------------------------------------
;pass_thru - This procedure is JMPed to by any interrupt |
; handler which wishes to pass control to the |
; original ISR per the interrupt vector table. |
; |
; Entry: |
; See stack_area struc for stack layout |
; Any error code has been removed from stack.|
; EIP on stack has been adjusted if |
; necessary. |
;--------------------------------------------------------------
pass_thru proc near
mov bp, sp
pushad
push ds
mov ax, offset gdt_seg:sel_databs
mov ds, ax ;address all base memory
movzx ebx, [bp].s_ss ;user stack
shl ebx, 4 ;make linear
mov edx, [bp].s_esp ;user stack pointer
sub edx, 6 ;flags, cs, ip
mov [bp].s_esp, edx ;adjust it
mov eax, [bp].s_eflags ;put on flags
mov [ebx][edx].user_flags, ax
;
;change flags on stack so that original ISR will be entered with
;interrupts cleared and trap flag cleared to be consistent with their
;state upon entering an ISR (the normal way).
;
and ax, not (TRAP_FLAG + INT_FLAG)
mov [bp].s_eflags, eax ;put back flags
mov ax, [bp].s_cs ;put on user cs
mov [ebx][edx].user_cs, ax
mov eax, [bp].s_eip ;put on ip
mov [ebx][edx].user_ip, ax
movzx ebx, [bp].s_pushed_int ;get int number
movzx eax, [ebx * 4].d_offset ;offset portion
mov [bp].s_eip, eax
mov ax, [ebx * 4].d_segment ;segment portion
mov [bp].s_cs, ax
pop ds
popad
add sp, 2 ;get rid of int number
pop bp
iretd
pass_thru endp

;--------------------------------------------------------------
;gen_prot_isr - JMP here if int 0dh. Process as follows: |
; |
; Look for software int. If found, go route to |
; appropriate ISR. |
; |
; Look for I/O instructions we currently |
; support. If found, store port, size and |
; direction of I/O. Also, set trap flag and |
; return (we will get control at int 1 to |
; inspect data). |
; |
; If other than software int or I/O, go |
; display 0dh and halt. |
; |
;--------------------------------------------------------------
gen_prot_isr proc near
push ds
pushad
mov bx, offset gdt_seg:sel_databs
mov ds, bx
movzx ebx, [bp].e_cs ;get cs of user instruction
shl ebx, 4 ;make linear
add ebx, [bp].e_eip ;add ip
mov ax, [ebx] ;get bytes at cs:ip
cmp al, INT_OPCODE
jne get_prot100
inc [bp].e_eip ;get past the 0cdh
get_prot050:
inc [bp].e_eip
;
;Adjust stack so that error code goes away and int number retrieved from
;instruction goes in spot on stack where pushed int number is (for stacks
;with no error code). Stack will be the way pass_thru routine likes it.
;
mov bx, [bp].e_pushed_bp
shl ebx, 16 ;get into high word
mov bl, ah ;interrupt number
mov [bp].e_errcode, ebx
popad
pop ds
add sp, 4 ;error code gone
jmp pass_thru
get_prot100:
cmp al, INT3_OPCODE
jne get_prot150
mov ah, 3 ;interrupt 3
jmp short get_prot050
get_prot150:

mov bx, offset gdt_seg:sel_data
mov ds, bx
mov bx, offset io_table
mov cx, IO_TAB_ENTRIES
get_prot200:
cmp al, [bx].io_opcode
jne get_prot300
mov trap_status, EXPECT_INT1
mov cl, [bx].io_info ;get info about instruction
mov access_info, cl
mov access_port, dx ;save port
test cl, CONSTANT ;is port number in instruction?
jz get_prot250 ;if not, we have it
xchg ah, al ;ah = 2nd byte of instruction
sub ah, ah
mov access_port, ax ;save port
mov dx, ax
get_prot250:
and cx, (AWORD OR ABYTE) ;number of bits
sub ah, ah ;indicate clear
call do_bit_map

popad
pop ds
or [bp].e_eflags, TRAP_FLAG ;single step i/o

add sp, 2 ;int number pushed
pop bp
add sp, 4 ;error code
iretd

get_prot300:
add bx, size io_struc ;advance to next table entry
loop get_prot200
mov ax, [bp].e_cs ;get cs of user instruction
call display_it
mov eax, [bp].e_eip ;add ip
call display_it
popad
pop ds
mov ax, [bp].e_pushed_int
jmp fatal_error
gen_prot_isr endp

;--------------------------------------------------------------
;do_bit_map - For the number of ports specified, clear/set |
; corresponding I/O permission map bits. |
; |
; Enter: Ah = 0 clear, ah = 1 set |
; dx = starting port |
; cx = number of ports |
; |
; All registers saved. |
;--------------------------------------------------------------
do_bit_map proc near
push ax
push bx
push cx
push dx
push ds
mov bx, offset gdt_seg:sel_tss_alias
mov ds, bx
assume ds:tss_seg
mov bx, t_iomap
push cx
mov cx, dx ;port
and cl, 7 ;get non byte boundary
mov al, 1 ;first bit position
shl al, cl ;get out corresponding bit
shr dx, 3 ;start_port/8
pop cx
add bx, dx ;starting offset in map
do_bit100:
or ah, ah
jnz do_bit200
mov dl, al
not dl
and byte ptr [bx], dl ;turn off permission bit
jmp short do_bit250
do_bit200:
or byte ptr [bx], al ;turn on permission bit
do_bit250:
rcl al, 1 ;next bit position
jnc do_bit300
inc bx
rcl al, 1
do_bit300:
loop do_bit100
pop ds
pop dx
pop cx
pop bx
pop ax
ret
do_bit_map endp

;--------------------------------------------------------------
;user_int_isr - return buffer address to caller. |
; |
; Exit: dx:bx= far ptr to store_buf |
;--------------------------------------------------------------
user_int_isr proc near
mov dx, data
mov bx, offset data:store_buf
iret
user_int_isr endp
isrcode ends
end


  3 Responses to “Category : Files from Magazines
Archive   : PJ95.ZIP
Filename : IOISR.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/