home *** CD-ROM | disk | FTP | other *** search
- ;--------------------------------------------------
- ;
- ; JX
- ;
- ;--------------------------------------------------
-
- comment #
-
- keywords: CXI API POPUP ASM
-
- SAMPLE asm source code for a popup interface between a
- pc user and a mainframe coax-connected host, via the CXI API.
- This allows a program to process screens and keys before
- passing them through. Uploaded as a self-extracting EXE.
-
- Unlike simpler programs, this type of program in active thoughout
- the session, and must continually keep the screen updated while
- passing along translated keystrokes to the host when the host
- is not busy. A reset can be sent while the host is busy.
-
- This is not a working program. Code which was specific to the
- original application has been removed. The original program
- provided allowed a mainframe reporting program to print directly
- on the pc using specially formatted screens.
-
- The current hotkey is both shift keys together.
-
- The 'outkb' routine is untested on 8088 machines...
-
- See the cautions marked by double-semi flags (';;')
-
- #
- ;-------------------------------------------------
-
- ;bios seg
- bios_seg segment at 40h
- org 17h
- kbflag db ?
- org 1Ah
- kbhead dw ? ;buffer head
- kbtail dw ? ;buffer tail
- kbbuf dw 16 dup (?) ;orig\only buf
- org 63h
- addr_crtc dw ? ;crtc base
- org 87h
- ega_info db ? ;ega info byte
- bios_seg ends
- ;-------------------------------------------------
-
- code segment para public 'code'
- assume cs:code, ds:code
- org 100h
- begin: jmp install
- db 'JX 01- cxi screen capture'
- ;--------------------------------------------------
-
- adapter db 0
- apicall equ <int 111> ;"saves only cs,ds,es,bp,ss,sp"
- areasw db 0
- bioseg dw 40h
- busy10 db 0
- busy13 db 0
- critaddr dw 0
- crtc dw 0
- cseg dw 0
- curloc dw 0
- curloc2 dw 0
- curpos2 dw 0
- curtyp2 dw 0
- dataloc dw 0 ;bufloc for data start
- dos_seg dw 0 ;seg of internal dos flags
- dos_version dw 0 ;dos version number
- indosaddr dw 0 ;offset of indos flag
- jxactive db 0
- kbstart dw 0
- kbend dw 0
- muxid equ 44
- mypsp dw 0
- my_style dw 0
- oldint8 dw 0,0 ;tik
- oldint9 dw 0,0 ;kb
- oldint28 dw 0,0 ;idle
- oldint2f dw 0,0 ;mux
- pop_request db 0
- popped db 0
- popoutsw db 0
- prevscan db 0,0
- resetsw db 0
- savess dw 0 ;must be in cs:
- savesp dw 0 ;"
- tmodd dw 0,0
- uninsw db 0
- unloadsw db 0
- vid_page db 0
- vidseg dw 0
- ;..................................................
-
- ;aid keys
- aidlist db 105, 112, 113 ;clr, pa1, pa2
- ;pf1-24
- db 120,121,122,123,124,126,126,127,128,129,130,131
- db 133,134,135,136,137,138,139,140,141,142,143,144
- aidlistlen equ $-aidlist
- ;------------------------------------------------------------
-
- ;bug on some 286s:
- ;if ints are disabled and the flags on the stack are also
- ;disabled, a popf may allow one int after the popf
- ;Use this macro instead
-
- popff macro
- push cs
- call iiret ;any iret
- endm
- ;..................................................
-
- ;long 'jmp if equal'
- jmpe macro x
- local tt
- jne tt
- jmp &x
- tt:
- endm
- ;..................................................
-
- jmpne macro x
- local tt
- je tt
- jmp &x
- tt:
- endm
- ;..................................................
-
- mypusha macro
- irp x, <ax, bx, cx, dx, di, si, ds, es, bp>
- push x
- endm
- endm
- ;.............................................................
- mypopa macro
- irp x, <bp, es, ds, si, di, dx, cx, bx, ax>
- pop x
- endm
- endm
- ;..........................................................
-
- esds macro
- push ds
- pop es
- endm
- ;..........................................................
-
- ;load literal addr with inline constant
- laddr macro r, l
- local tt
- mov &r, offset $ +5
- jmp short tt
- db &l
- tt:
- endm
- ;--------------------------------------------------
- ;--------------------------------------------------
-
- restart:
- ;popup entry point- after lo-level activation
- esds ;set es=ds
- call pushscr2 ;save screen
- call clrscr ;clear screen
- mywait:
- ;idle loop entry point
- int 28h ;idle call dos
-
- cmp popoutsw, 0 ;hotkey back to dos
- je @f ;no
- mov popoutsw, 0
- jmp popout
- @@:
- call paint ;updt display buffer or print
-
- ;process reset key, without testing for busy host
- cmp resetsw, 0
- je ss40 ;none
- mov resetsw, 0
- mov ax, resetkey ;send
- call emit
- call clr_kb ;clear all pending keystrokes
- jmp mywait
- ss40:
- ;process non-aid keys, without testing for busy host
- call tstkey ;see next key waiting
- jz mywait ;none
- cmp al, 13 ;enter
- je ss60 ;yes- aid
- or al, al ;extended
- jnz @f ;no- not aid
- mov di, offset aidlist ;search for key in aid list
- xchg ah, al
- mov cx, aidlistlen
- esds
- repne scasb ;scan
- xchg ah, al ;restore
- je ss60 ;is aid - wait for unlock
- @@:
- ;not aid
- call getkey ;dequeue the key
- cmp al, '~' ;uninstall
- je @f ;yes
- call emit ;send to buffer
- jmp ss40 ;get next key
- @@:
- ;uninstall
- call ckvec ;are we last on all vectors
- jnc @f ;yes
- mov al, 7 ;beep
- int 29h
- jmp mywait
- @@:
- mov unloadsw, 1
- mov popped, 0 ;allow recursive pop
- jmp popout
- ss60:
- ;aid key pending
- ;if we are busy, trash the key
-
- call tstlok ;kb locked
- jc ss66 ;yes
- mov ax, 3 ;wait n/18ths second to be sure
- call delayx
- mov ax, 11 ;updt buffer
- apicall
- call tstlok ;still unlocked
- jc ss66 ;no
-
- call getkey ;dequeue aid key
- call emit ;send it
- jmp mywait
- ss66:
- call getkey ;get aid key
- jmp mywait ;ignore it
- ;--------------------------------------------------
-
- paint:
- ;updt buffer
-
- ;updt 3278 buffer
- mov ax, 11 ;updt buffer
- apicall
-
- ;paint screen
- mov ax, 10 ;paint screen
- apicall
-
- ;set cursor
- call tstlok ;unless locked
- jnc @f
- ret ;locked
- @@:
- mov ax, 4 ;get cursor addr
- apicall
- mov curloc2, ax ;painted cursor abs loc
- mov dx, ax ;convert to row,col
- mov ax, 26
- apicall
- cmp ax, 26 ;no cxi connection
- jne @f
- mov ax, 0101h ;true
- @@:
- mov dx, ax ;row,col
- dec dh ;relative
- dec dl ;relative
- call curpos
- ret
- ;--------------------------------------------------
-
- tstlok:
- ;stc if kb is locked
- ;busy indicator is statline pos 9 = X
-
- mov ax, 5 ;read buf char
- mov dx, 8 ;pos 9
- apicall
- cmp al, 'X'
- je lokt
- clc ;unlocked
- ret
- lokt:
- stc ;locked
- ret
- ;--------------------------------------------------
-
- emit:
- ;send al char to interface
- mov dx, ax
- xor dh, dh ;assume non-extended
- or al, al
- jnz @f ;true
- inc dh
- mov dl, ah
- @@:
- mov ax, 6 ;emit key
- apicall
- ret
- ;--------------------------------------------------
-
- get_kb:
- call getkey
- jz get_kb ;no key avail
- ret
- ;..................................................
-
- clr_kb:
- call getkey
- jnz clr_kb
- ret
- ;..................................................
-
- tstkey:
- mov ah, 1 ;any key waiting
- int 16h
- jne @f ;yes
- xor ax, ax ;zr
- @@: ret
- ;..................................................
-
- getkey:
- ;return key or zr
- mov ah, 1 ;any key waiting
- int 16h
- jne @f ;yes
- ret
- @@:
- mov ah, 0 ;get key
- int 16h
- cmp ax, 1515h ;special prefix
- jne gk20 ;no
- mov ah, 1 ;2nd key waiting
- int 16h
- je getkey ;no- discard
-
- mov ah, 0 ;get 2nd key
- int 16h
- xchg ah, al ;reformat it
- gk20:
- cmp al, 0e0h ;ext key
- je getkey ;yes- ignore
- or ax, ax ;nz
- ret
- ;--------------------------------------------------
-
- pushscr2:
- ;save user's screen in alternate page ;;
- xor si, si
- mov di, si
- add di, 4096 ;store in page 2
- mov cx, 4096/2
- mov es, vidseg
- push ds
- mov ds, vidseg
- rep movsw
- pop ds
- esds
-
- mov ah, 3 ;get pos and style
- mov bh, vid_page
- int 10h
- mov curpos2, dx
-
- cmp cl, 0 ;style with emulation disabled
- je @f ;yes
- cmp cl, 7
- ja @f ;yes
- or cx, 80h ;flag to reset with emulation
- @@:
- cmp adapter, 0 ;mono
- jne @f ;no
- mov cx, 0b0ch
- @@:
- mov curtyp2, cx
- ret
- ;..................................................
-
- popscr2:
- mov es, vidseg
- xor di, di
- mov si, di
- add si, 4096
- mov cx, 4096/2
- push ds
- mov ds, vidseg
- rep movsw
- pop ds
- esds
-
- mov dx, curpos2
- call curpos
-
- mov cx, curtyp2
- call show_cx_cursor
- ret
- ;--------------------------------------------------
- ;--------------------------------------------------
-
- ;KEYBOARD INTERRUPT HANDLER
- ;remap keys for 3270 functions
-
- ;f1-12 --> pf1-12
- ;alt 1-= pf1-12
- ;ctl f1-12 pf13-24
- ;ctl 1-= pf13-24
- ;alt f9 pa1
- ;alt f10 pa2
- ;alt f11 pa3
- ;esc clear
- ;bsp,enter,tab,up,down,left,right,ins,del == same
- ;end reset
- ;home deleof
- ;shift tab backtab
- ;ctl tab backtab
- ;ctl enter newline
- ;.................................................
-
- ;0= transparent
- ;1= ignore
- plaintbl:
- dw 6900h ;1 esc -> clear
- dw 58-2+1 dup(0) ;2-58 are transparent
- dw 7800h, 7900h ;59-68 f1-f10
- dw 7a00h, 7b00h ;f3-4
- dw 7c00h, 7d00h ;f5-6
- dw 7e00h, 7f00h ;f7-8
- dw 8000h, 8100h ;f9-10
- dw 70-69+1 dup(0) ;69-70 transparent
- dw 4000h ;71 home -> deleof
- dw 0 ;72 up
- dw 1 ;73 pgup null
- dw 0 ;74 -
- dw 0 ;75 left
- dw 1 ;76 center -> null
- dw 0 ;77 right
- dw 0 ;78 +
- resetkey dw 4f00h ;79 end -> reset
- dw 0 ;80 down
- dw 1 ;81 pgdn -> null
- dw 0 ;82 ins
- dw 0 ;83 del
- dw 86-84+1 dup(1) ;84-86 -> null
- dw 8200h, 8300h ;87-88 f11,12
- ;.................................................
-
- ctltbl:
- dw 0 ;1=esc (Windows)
- dw 8500h, 8600h ;2-13 (digits-=) -> pf13-24
- dw 8700h, 8800h
- dw 8900h, 8a00h
- dw 8b00h, 8c00h
- dw 8d00h, 8e00h
- dw 8f00h, 9000h
- dw 0 ;14 bsp
- backtab dw 0f00h ;15 ^tab -> backtab
- dw 27-16+1 dup(0) ;16-27
- dw 4e00h ;28 enter -> newline
- dw 58-29+1 dup(0) ;29-58
- dw 8500h, 8600h ;59-68 f1-10 -> pf13-22
- dw 8700h, 8800h ;
- dw 8900h, 8a00h ;
- dw 8b00h, 8c00h ;
- dw 8d00h, 8e00h ;
- dw 86-69+1 dup(1) ;69-86
- dw 8f00h, 9000h ;87-88 f11,12 -> pf23,24
- ;.................................................
-
- alttbl:
- dw 1 ;1 esc -> null
- dw 7800h, 7900h ;2-13 (digits-=) -> pf1-12
- dw 7a00h, 7b00h
- dw 7c00h, 7d00h
- dw 7e00h, 7f00h
- dw 8000h, 8100h
- dw 8200h, 8300h
- dw 27-14+1 dup(0) ;14-27
- dw 4e00h ;28 enter -> newline
- dw 66-29+1 dup(0) ;29-66
- dw 7000h ;67-69 f9 pa1
- dw 7100h ; f10 pa2
- dw 7200h ; f11 pa3
- dw 88-70+1 dup(1) ;70+
- ;-------------------------------------------------
-
- ;check table len
- if ($-plaintbl) / 2 - (3*88)
- .err
- endif
- ;--------------------------------------------------
- ;--------------------------------------------------
-
- newint9:
- ;kb int handler
- cli
- pushf
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
- push bp
- mov ds, cs:cseg
-
- ;fix bios bug
- mov al, 0adh ;disable kb
- call outkb
-
- sti ;enable higher ints
- in al, 60h ;get scancode
- jmp $+2
-
- mov ah, prevscan +1 ;prev key
- mov prevscan, ah
- mov prevscan+1, al ;this key
- xor ah, ah
-
- test al, 80h ;break etc.
- jmpne jbios ;yes- ignore
-
- ;get shift state
- mov es, bioseg
- mov cl, es:kbflag
-
- ;test for hotkey
- cmp al, 42 ;left-shift
- jne @f ;no
- test cl, 1 ;right-shift pending
- jnz hotyes ;yes
- jmp short jbios
- @@:
- cmp al, 54 ;right-shift
- jne nothot ;no
- test cl, 2 ;left shift pending
- jz jbios ;no
- hotyes:
- ;hotkey pressed
- cmp jxactive, 0 ;active
- jne @f ;yes
- mov pop_request, 18 ;pop
- jmp done9
- @@:
- inc popoutsw
- jmp done9
- nothot:
- cmp jxactive, 0 ;are we active
- je jbios ;no- done
-
- ;passthru if numlok+ keypad (digit)
- test cl, 20h ;numlok on
- jz @f ;no
- cmp prevscan, 0e0h ;extended (negates numlok)
- je @f ;yes
- cmp al, 71 ;keypad
- jb @f ;no
- cmp al, 83
- jna jbios ;yes- transparent
- @@:
- ;the only shift translation is shift-tab to backtab.
- test cl, 3 ;shifted
- jz noshift ;no
- cmp al, 15 ;tab
- jne jbios ;no
- mov bx, backtab
- jmp short stuff_bx
- noshift:
- ;set bx to correct shift-state lookup tbl
- mov bx, offset plaintbl ;assume no state
- test cl, 8 ;alt mask
- jz noalt ;no
- mov bx, offset alttbl
- noalt:
- test cl, 4 ;ctl mask
- jz @f ;no
- mov bx, offset ctltbl
- @@:
- ;get replacement char
- mov si, ax
- shl si, 1
- mov bx, [bx] [si] -2 ;fetch replacement
- cmp bx, 1 ; 0=transparent (pass to bios)
- je done9 ; 1=nul
- ja stuff_bx ; else replace
- jbios:
- ;pass to bios
- pop bp
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- call dword ptr cs:oldint9
- push ax
- mov al, 0aeh ;enable kb
- call outkb
- pop ax
- iret
- stuff_bx:
- cmp bx, resetkey ;reset key
- jne @f ;no
- inc resetsw ;set priority switch
- jmp short done9 ;ignore key
- @@:
- mov ax, bx
- cmp bh, 83h ;bios max
- jna @f
- push bx
- mov ax, 1515h ;special prefix code (see getkey)
- call stuffchar ;(does sti)
- pop ax
- xchg ah, al ;reversed extended code
- @@:
- call stuffchar ;(does sti)
- done9:
- pop bp
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- cli
-
- ;enable kb
- mov al, 0aeh ;enable kb
- call outkb
-
- ;clear kb int
- in al, 61h
- jmp $+2
- or al, 80h
- out 61h, al ;set hi
- jmp $+2
- and al, not 80h
- out 61h, al ;set lo
- jmp $+2
-
- ;eoi
- mov al, 20h
- out 20h, al
- jmp $+2
-
- pop ax
- popf
- iret
- ;--------------------------------------------------
-
- outkb:
- ;this helps avoid a bios bug
- push ax
- @@: in al, 64h
- jmp $+2
- test al, 2
- jnz @b
- pop ax
- out 64h, al
- jmp $+2
- ret
- ;--------------------------------------------------
-
- stuffchar:
- ;stuff ax into kbbuf
- ;es = bios
- cli
- mov bx, es:kbtail ;next open loc
- add bx, 2 ;new tail
- cmp bx, kbend ;wrap
- jne @f ;no
- mov bx, kbstart
- @@: cmp bx, es:kbhead ;new tail = head
- je @f ;yes- no room for more- abandon
- xchg es:kbtail, bx ;new tail
- mov es:[bx], ax ;add char
- @@:
- sti
- ret
- ;-----------------------------------------------------------
-
- delayx:
- ;delay ax tiks. (55ms, 18.2 tiks per second)
- call start_tmo
- @@: call tst_tmo
- jnc @b
- ret
- ;------------------------------------------------------------
-
- start_tmo:
- ;initialize tmo counter
- push ax
- push es
- mov es, bioseg
- mov ax, es:[6ch] ;timer lo
- mov tmodd, ax
- mov ax, es:[6eh] ;timer hi
- mov tmodd +2, ax
- pop es
- pop ax
- ret
- ;------------------------------------------------------------
-
- tst_tmo:
- ;stc if ax tiks have elapsed since last call to start-tmo
- push ax
- push bx
- push cx
- push dx
-
- mov bx, ax
-
- push es
- mov es, bioseg
- mov cx, es:[6ch] ;timer lo
- mov ax, es:[6eh] ;timer hi
- pop es
-
- ;get init-val plus interval
- mov dx, tmodd +2 ;hi
- add bx, tmodd
- jnc @f ;no lo wrap
- add dx, 1 ;(don't inc)
- jnc @f ;no num wrap
-
- ;deadline is a wrap.
- cmp dx, ax ;deadline, current hi
- jne timex ;no timeout
- cmp bx, cx ;deadline, current lo
- ja timex
- jmp short timeout ;timeout
- @@: cmp dx, ax ;deadline, current hi
- ja timex ;no timeout
- cmp bx, cx ;lo
- ja timex ;no timeout
- timeout:
- stc
- jmp short timez
- timex:
- clc
- timez:
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- ;--------------------------------------------------
- clrscr:
- xor dx, dx
- call curpos
- mov cx, 25*80
- jmp short clr_area
- ;.....................................
- clr_area:
- ;write cx blanks at dx
- push es
- push cx
- call get_dxaddr
- pop cx
- mov al, ' '
- inc areasw
- call vidchar
- pop es
- ret
- ;--------------------------------------------------
-
- show_cx_cursor:
- cmp adapter, 2 ;ega active
- jne @f ;no
- test cx, 80h ;use ega emulation
- jnz @f ;yes
- push es
- mov es, bioseg
- push word ptr es:ega_info ;save ega info byte
- or byte ptr es:ega_info, 1 ;disable ega cursor emulation
- mov ah, 1 ;set cx cursor style
- int 10h
- pop word ptr es:ega_info ;restore ega info byte
- pop es
- ret
- @@:
- and cx, not 80h
- mov ah, 1 ;set cx cursor style
- int 10h
- ret
- ;--------------------------------------------------
-
- curpos:
- ;set real and virtual cursor pos from dx
- mov curloc, dx
- push ax
- push bx
- mov ah, 2 ;set dx pos
- mov bh, vid_page
- int 10h
- pop bx
- pop ax
- ret
- ;--------------------------------------------------
-
- tty2:
- ;write al char at curloc. bump curloc.
- ;preserve all regs
-
- push ax
- push cx
- push di
- push si
- push es
-
- ;compute buffer offset
- push ax ;char
- call get_vidaddr
- pop ax
-
- call vidchar ;store
- inc curloc
- cmp byte ptr curloc, 80
- jb @f
- mov byte ptr curloc, 0
- inc byte ptr curloc+1
- @@: pop es
- pop si
- pop di
- pop cx
- pop ax
- ret
- ;--------------------------------------------------
-
- get_dxaddr:
- mov curloc, dx
- get_vidaddr:
- ;curloc to es:di
- push ax
- push cx
- mov al, byte ptr curloc+1 ;line x 160
- mov cx, 160
- mul cl
- mov cl, byte ptr curloc ;col x 2
- shl cl, 1
- add ax, cx ;offset in page
- xor di, di
- cmp ax, 25*160 ;4,000
- ja @f
- mov di, ax ;to
- @@: mov cl, vid_page
- jcxz @f ;save time
- mov ax, 1000h ;4k pages in 80 col mode
- mul cl ;page offset
- add di, ax ;total offset
- @@: mov es, vidseg
- pop cx
- pop ax
- ret
- ;--------------------------------------------------
-
- vidchar:
- stosb
- inc di
- cmp areasw, 0
- je @f
- dec cx
- jnz vidchar
- mov areasw, cl
- @@: ret
- ;--------------------------------------------------
- ;--------------------------------------------------
-
- ;timer and popup
-
- assume ds:nothing ;for ints and popup
- newint8:
- ;timer int
- cli
- pushf
- call dword ptr oldint8 ;also does eoi
-
- cmp popped, 0 ;is anybody pending or popped
- je @f ;no
- iret
- @@: inc popped ;busy now
- sti
- cld
-
- ;regs have not been saved
-
- cmp unloadsw, 2 ;unloading
- je @f ;yes
- cmp pop_request, 0 ;pop requested
- je exit8 ;no
- @@:
- cmp busy10, 0 ;video busy
- jne bad8 ;yes- exit with prejudice
- cmp busy13, 0 ;disk busy
- jne bad8 ;yes- exit with prejudice
-
- push es
- push di
- mov es, dos_seg ;indos seg (usually)
- mov di, indosaddr
- cmp byte ptr es:[di], 0 ;dos busy
- jne xp ;yes- exit with prejudice
- mov di, critaddr ;in critical error
- cmp byte ptr es:[di], 0
- jne xp ;yes- exit with prejudice
- mov pop_request, 0
- call popup
- mov pop_request, 1 ;going to 0
- xp:
- pop di
- pop es
- bad8:
- dec pop_request
- exit8:
- cli
- mov popped, 0
- iret
- ;-----------------------------------------------------------------------
-
- ;assume ds:nothing ..cont
- newint28:
- ;idle int
- ;note regs are not saved until popup
-
- cli
- pushf
- call dword ptr oldint28
-
- cmp popped, 0 ;is anybody popped
- je @f ;no
- iret
- @@: inc popped ;busy now
- sti
- cld
-
- cmp pop_request, 0 ;pop requested
- je exit28 ;no- exit
- cmp busy10, 0 ;video busy
- jne exit28 ;yes- exit
- cmp busy13, 0 ;disk busy
- jne exit28 ;yes- exit
-
- push es
- push di
- mov es, dos_seg ;in critical error
- mov di, critaddr
- cmp byte ptr es:[di], 0
- pop di
- pop es
- mov pop_request, 0
- jne exit28 ;yes
- call popup
- exit28:
- cli
- mov popped, 0
- iret
- ;-----------------------------------------------------------
-
- ;assume ds:nothing ..cont
- popup:
- mov savess, ss ;save caller's stack
- mov savesp, sp
- cli ;new stack
- push cs
- pop ss
- mov sp, offset stackend
- sti
- mypusha
- ;.........................................................
-
- mov ds, cs:cseg
- assume ds:code ; es is not set
- ;.........................................................
-
- ;test for uninstall
- cmp unloadsw, 2
- jne @f ;no
- esds
- call remove ;disable and unvector
- mov es, mypsp
- mov cx, es:[2ch] ;envir blok
- push cx ;save
- mov ah, 49h ;release pgm
- mov es, mypsp
- int 21h
- pop es ;envir
- mov ah, 49h ;release envir
- int 21h
- jmp short popexit
- @@:
- call ck_vid ;mode ok to pop
- jnc pop20 ;yes
- ;................
- popexit:
- ;return to interrupted application
- cmp unloadsw, 1
- jne @f
- inc unloadsw
- @@:
- mypopa
- mov ss, cs:savess
- mov sp, cs:savesp
- ret ;back to int8,int28
- ;................
- pop20:
- ;we are active
- inc jxactive ;we're active
- esds
- jmp restart
- ;.....................................................
- popout:
- ;return to interrupted pgm (jumped-to)
-
- call popscr2 ;restore as when called
- call clr_kb
-
- mov jxactive, 0
- jmp popexit
- ;-----------------------------------------------------------
-
- newint2f:
- ; entry: ah - device id
- pushf
- cmp ah, muxid
- je @f ;its us
- popff
- jmp dword ptr cs:oldint2f
- @@:
- push ds
- push cs
- pop ds
- mov al, -1 ;indicate installed
- cmp bx, 0202h ;called to pop (nu)
- jne @f ;no
- mov pop_request, 26
- @@:
- cmp bx, 0303h ;called to uninstall
- jne fx ;no
- call ckvec ;are we last on all vectors
- jnc @f ;yes
- mov al, 7 ;beep
- int 29h
- jmp short fx
- @@: mov unloadsw, 2
- fx:
- push cs ;returns es = installed segment
- pop es
- pop ds
- popff
- iiret: iret
- ;---------------------------------------------------------
-
- ckvec:
- ;stc if any ints have been intercepted since we loaded
- mov al, 8
- call cksub
- jne @f
- mov al, 9
- call cksub
- jne @f
- mov al, 28h
- call cksub
- jne @f
- mov al, 2fh
- call cksub
- jne @f
- clc
- ret
- @@:
- stc
- ret
- ;.........................................................
-
- cksub:
- push es
- mov ah, 35h
- int 21h
- mov ax, es
- cmp ax, cseg
- pop es
- ret
- ;---------------------------------------------------------
-
- remove:
- push ds
- assume ds:nothing
- lds dx, dword ptr oldint8
- mov ax, 2508h
- int 21h
-
- lds dx, dword ptr oldint9
- mov ax, 2509h
- int 21h
-
- lds dx, dword ptr oldint28
- mov ax, 2528h
- int 21h
-
- lds dx, dword ptr oldint2f
- mov ax, 252fh
- int 21h
-
- pop ds
- assume ds:code
- ret
- ;------------------------------------------------------------
-
- ck_vid:
- mov ah, 0fh
- int 10h ;get cols,mode,page
- cmp al, 2 ;2,3,7 ok (all are 80 col)
- je @f
- cmp al, 3
- je @f
- cmp al, 7
- je @f
- stc ;no
- ret
- @@: mov vid_page, bh
- clc
- ret
- ;------------------------------------------------------------
- ;------------------------------------------------------------
-
- ;final section of resident code
- ;this allocation method minimizes the .com size
-
- even
- mystack equ $ ;stack 512
- stackend equ mystack +512 -2
- progend equ mystack +512
- ;------------------------------------------------------------
-
- install:
- ;end of resident code
- ;one-time init code
-
- mov ax, cs
- mov ds, ax
- mov mypsp, es
- mov es, ax
- mov ss, ax
- mov sp, offset stackend
- mov cseg, ax
- cld
-
- call getcmd ;get cmdline parms
- cmp uninsw, 0 ;request to uninstall
- je @f ;no
- mov ah, muxid
- xor al, al
- mov bx, 0303h
- int 2fh
- mov ax, 4c00h ;eoj
- int 21h
- @@:
- call getvid ;get display info
- call revec ;setup intercepts
-
- ;get dos version
- mov ah, 30h
- xor al, al
- int 21h
- xchg ah, al
- mov dos_version, ax
-
- ;set kbstart,end
- mov ax, offset kbbuf
- mov bx, offset kbbuf+32
- mov kbstart, ax
- mov kbend, bx
-
- ;get cursor offset for 2,2
- ;(first char of each line is an attrib char)
- mov ax, 25 ;convert row,col to offset
- mov dh, 2
- mov dl, 2
- apicall
- mov dataloc, ax ;save
-
- ;display msg
- mov ah, 9
- laddr dx, <'JX Installed.$'>
- int 21h
-
- ;adj pgm size
- mov ax, 4a00h
- mov bx, (progend-code +15) shr 4
- mov es, mypsp
- int 21h
-
- ;go resident
- mov ax, 3100h ;tsr
- mov dx, (progend-code +15) shr 4
- int 21h
- ;--------------------------------------------------
-
- getvid:
- ;get video segment addr
- ;set adapter type
-
- mov es, bioseg
- mov ax, es:addr_crtc
- mov crtc, ax
-
- mov ah, 12h ;get ega,vga info
- mov bl, 10h
- int 10h
- cmp bl, 10h ;did bl return unchanged
- je vid20 ;yes- no ega,vga
- mov es, bioseg
- test es:ega_info, 8 ;ega currently active
- jnz vid20 ;no
- mov adapter, 2 ;active ega
- mov vidseg, 0b800h ;color
- push bx
- mov ax, 1130h ;get nof scan lines per char
- int 10h ;to create new shape
- dec cl
- mov ch, cl
- sub ch, 2
- mov my_style, cx
- pop bx
- or bh, bh ;ega attached to color monitor
- je vid40 ;yes
- mov vidseg, 0b000h ;mono
- jmp short vid40
-
- ;cga or mda.
- vid20: test crtc, 40h ;mono
- jz @f ;yes
- mov adapter, 1 ;cga
- mov my_style, 0607h
- mov vidseg, 0b800h ;color
- jmp short vid40
- @@: mov adapter, 0 ;mda
- mov my_style, 0b0ch
- mov vidseg, 0b000h ;mono
- vid40:
- esds
- ret
- ;--------------------------------------------------
-
- revec:
- ;see if already resident in memory. dos 3.0+ only
- not word ptr [begin] ;no match on this copy
- mov ah, muxid
- xor al, al
- int 2fh ;sets es = installed seg
- or al, al
- jz nodup ;not found
- mov si, offset begin ;tst signature also
- mov di, si
- mov cx, 16
- repe cmpsb
- jne nodup
-
- laddr dx, <'Already installed$'>
- mov ah, 9
- int 21h
- mov ax, 4c01h ;eoj
- int 21h
- ;.....................
- nodup:
- ;get dos-seg and indos addr at es:bx
- mov ah, 34h
- int 21h
- mov dos_seg, es
- mov indosaddr, bx
-
- ;get critical err addr
- mov ax, 3e80h ;cmp opcode
- mov cx, 2000h ;max search length
- mov di, bx ;start at indos address
- @@: repne scasw ;do the search
- jcxz @f ;branch if search failed
- cmp byte ptr es:[di+5], 0bch ;verify this is it
- je found ;yes
- jmp @b
- @@: mov cx, 2000h ;search again
- inc bx ;search odd addresses this time
- mov di, bx
- @@: repne scasw ;look for the opcode
- jcxz @f ;not found
- cmp byte ptr es:[di+5], 0bch ;verify
- je found
- jmp @b
- @@:
- laddr dx, <'DOS flag not found$'>
- mov ah, 9
- int 21h
- mov ax, 4c01h
- int 21h
- nop
- found: mov ax, es:[di] ;get flag offset address
- mov critaddr, ax
-
- ;.....................
- mov ax, 3508h ;timer tik
- int 21h
- mov oldint8, bx
- mov oldint8 +2, es
- mov ax, 2508h
- mov dx, offset newint8
- int 21h
-
- mov ax, 3509h ;kb int
- int 21h
- mov oldint9, bx
- mov oldint9 +2, es
- mov ax, 2509h
- mov dx, offset newint9
- int 21h
-
- mov ax, 3528h ;idle
- int 21h
- mov oldint28, bx
- mov oldint28 +2, es
- mov ax, 2528h
- mov dx, offset newint28
- int 21h
-
- mov ax, 352fh ;multiplex
- int 21h
- mov oldint2f, bx
- mov oldint2f +2, es
- mov ax, 252fh
- mov dx, offset newint2f
- int 21h
-
- esds
- ret
- ;----------------------------------------------------------
-
- ;..revector
- getcmd:
- ;cmd tail tests
- assume ds:nothing
- mov ds, mypsp
- ;.............
- ;test for cmdline /U to uninstall
- mov si, 81h
- @@: lodsb
- cmp al, 13
- je @f
- or al, 20h
- cmp al, 'u'
- jne @b
- cmp byte ptr [si-2], '/'
- jne @b
- inc uninsw
- @@:
- ;.............
- mov ds, cs:cseg
- assume ds:code
- ret
- ;------------------------------------------------------------
-
- code ends
- end begin
-