home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- comment * PARINT.COM - (C) 1984 by David G Hunter.
- This program may be freely copied but may not be sold for profit.
-
- (Necessary modifications for the early model (1981) IBM PC
- made by Lawrence B. Afrin, 12/30/84. These modifications
- are documented at the appropriate point in this program.
- Modifications are Copyright (c) 1984 by Lawrence B. Afrin.
- Along with Mr. Hunter's code, these modifications may be
- freely copied but may not be sold for profit.)
-
- PARINT.COM detects parity errors, logs them on the printer if
- possible, beeps, and returns to program execution. The system does
- not halt when this program is resident. Parity error checking is
- terminated after first error is detected. The error message
- includes the time of the event. If the printer is not available,
- errors are logged to the screen.
- *
- ;***************** Addresses of Interrupt handlers *******************
-
- Book segment at 0h ;this is where the interrupt address books is
- org 2h*4 ;
- Int_2 label dword ;address of NMI handler
- Book ends
-
- ;***************** Beginning of PARINT Instructions *******************
- cseg segment
- assume cs:cseg
- org 100h
-
- Start: jmp newvec ;install new NMI handler in RAM
-
-
- ;************************** NMI handler ********************************
-
- newint proc near ;new interrupt handler
- assume ds:cseg, es:cseg
- sti ;this flag was cleared when interrupt was issued
- jmp go ;jump over more data
-
- go: push cx
- push ds
- pushf
- push dx
- push bx
- push ax
- pushf
- mov al, 00h
- out 0A0h, al ;turn off parity checking for now
- xor cx, cx ;cx=error flag: cx=1 if parity OK
- in al,62h ;get data in port C
-
- ; - - find origin of NMI - - - - - -
- test al, 40h
- jz mother
- mov dx, offset par2 ;if bit 6 set, error is on expansion board
- jmp out ; print message and exit
-
- mother: test al, 80h
- jz other
- mov dx, offset par1 ;if bit 7 set, error is on main board
- jmp out ;print message and exit
-
- other: or cx, 1h ;If neither bit set, no parity error occurred,
- mov al, 80h ;so set parity OK flag
- out 0A0h, al ;turn parity checking back on
- jmp noprt ;Don't print message if not parity error
-
- ; - - print error message and exit. Type of exit depends on type of error --
- out: mov ax,cs ;establish proper data segment to
- mov ds,ax ; allow access to messages
- call whatime ;get time of error
- mov bx, device1
- cmp bx,0004 ;if output is to printer, make sure it's ready
- jne f1
- call testprt
- f1: call print
- mov dx, offset time ;"time of error" message
- call print
- mov dx, offset paroff
- call print
-
- noprt: popf
- pop ax
- pop bx
- pop dx
- popf
- pop ds
- test cx, 1h ;special exit if parity OK
- jnz oth
- pop cx
- iret ;message printed; let execution continue
-
- ; If no parity error, turn control over to pre-existing NMI handler.
- ; This is done by restoring DS and jumping to the instruction that
- ; specifies the address of the old interrupt routine. This unusual exit
- ; is necessary because otherwise, once DS was restored, the address of the
- ; old interrupt routine would not be accessible.
-
- oth: cli
- pop cx
- jmp GetOut
-
- newint endp
-
-
- ;**************************** SUBROUTINES ******************************
-
- Testprt proc near
- push dx
- push ax
- xor dx,dx ;print # 0
- mov ah,2
- int 17h ;read printer status
- test ah,00101001b ;error bits
- jz aok
- mov bx, device2 ;if not ok, try other device
- aok: pop ax
- pop dx
- ret
- testprt endp
-
- Print proc near ;output to file named in bx; if error try another file
- push cx
- mov cx,34 ;34 characters to print
- mov ah,40h ;DOS function call
- int 21h
- pop cx
- ret
- print endp
-
- Whatime proc near ;what time is it? put result in hour/min
- push cx
- push dx
- mov ah,2Ch ;DOS time
- int 21h
- mov al,ch ;hours (0-23)
- call convt ;put tens in ah, ones in al
- mov hour,"00"
- add hour,ax
- mov al,cl
- call convt ;do same for minutes (0-59)
- mov min,"00"
- add min,ax
- pop dx
- pop cx
- ret
- Whatime endp
-
- Convt proc near ;convert number (<100) to ASCII. Number is in
- ;al. result: tens in ah, ones in al.
- xor ah,ah ;input is less than 100 anyway, so clear it
- push cx
- mov cl,10
- div cl ;divide ax by 10
- pop cx
- little: ret
- Convt endp
-
- ;------------------------------- DATA ----------------------------------
-
- GetOut: nop
- Instruc db 0EAh ;this is the jump-immediate instruction!
- ;it jumps to the address stored in oldint
- Oldint dd ? ;address of old interrupt 2 routine -
- Device1 dw 0004 ;printer
- Device2 dw 0001 ;standard output device
- par1 db 0Dh,0Ah,"Parity Error: Main Board ",07h,0Dh,0Ah
- par2 db 0Dh,0Ah,"Parity Error: Expansion Board",07h,0Dh,0Ah
- time db " TIME: "
- hour dw "00"
- db ":"
- min dw "00"
- db " ",0Dh,0Ah
- paroff db "PARITY CHECKING NOW DISABLED ",0Dh,0Ah,0Ah
-
- ;---------------------------- MAIN PROGRAM -----------------------------
-
- ;************************* INSTALL NMI HANDLER **************************
-
- Newvec proc near
- jmp past
-
- loaded db 0Dh,0Ah,"PARITY ERROR INTERCEPTOR v2.00 by David Hunter IS NOW"
- db " INSTALLED",0Dh,0Ah,"$"
-
- past: mov dx, offset loaded
- mov ah,9
- int 21h
- assume ds:Book ;interrupt address book area
- push ds ;save old ds for future use
- mov ax,Book
- mov ds,ax
-
- ; NOTE: The following modifications and their associated documentation
- ; are Copyright (c) 1984 by Lawrence B. Afrin. Further copyright
- ; information is included in this program's header comment block.
- ;
- ; The following two instructions have been removed from David
- ; Hunter's version by Lawrence B. Afrin because Mr. Afrin found that
- ; on the original model of the IBM PC (and possibly later models, too),
- ; these instructions cause the machine to go into the Twilight Zone
- ; later on when NMI interrupts are re-enabled. For some reason in the
- ; early IBM PC models, when NMI interrupts are re-enabled after having
- ; been disabled, the reenabling operation causes the system to signal
- ; an NMI interrupt. At the point in this program at which that occurs,
- ; the program is not ready to handle that interrupt and consequently
- ; dies. Therefore, by preventing the initial disabling of NMI
- ; interrupts, the problem is take care of. -- LBA, 12/30/84
-
- ; mov al, 00h
- ; out 0A0h, al ;turn off parity checking
- mov ax,int_2 ;get the address
- mov oldint,ax ;save it for some future use
- mov ax,int_2[2] ;second part of double word
- mov oldint[2],ax
- mov int_2, offset newint ;now load the new address
- mov int_2[2],cs ;cs is ds in com program
- mov al, 80h
- ;
- ; NOTE: It is at the following instruction that the early model PC would
- ; ordinarily enter the Twilight Zone if the NMI-disabling instructions
- ; noted above were to be left in the program. Because those instructions
- ; were removed, the following instruction, which re-enables an already
- ; enabled NMI mask, has no effect on the machine and does not cause a
- ; spurious NMI interrupt.
- ;
- out 0A0h, al ;turn parity checking back on
- mov dx, offset newvec ;leave new interrupt routine resident
- int 27h ;don't need "newvec" or beyond
- newvec endp
- cseg ends
- end start
-