home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
utils
/
easyun.zip
/
DE-JET2.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-10-23
|
49KB
|
980 lines
page 50,132
;*******************************************************************************
; Program DE-JET
;
; version 2.00
;
; Brought to you by the friends of George P. Burdell , Georgia Tech. 10/22/86
;
; Function: Read 'Jet' program from protected disk, put in 'exe' file format
; with several extensions including exit to dos and inclusion of
; extra options sectors while maintaining the ability to load a
; scenery disk and accept command line parameters.
;
; All terminates are type 4ch with errorlevel = 2 (hard error) while
; clean exit is errorlevel = 0 and CTRL-C is errorlevel = 1
;
; All calls are Dos type except int 13h (bios disk access) and
; int 11h (bios installed equipment).
;
; This version of De-Jet fixes DMA boundary error over ver 1.00 and
; retry on loading of extended situations sectors over ver 1.00 also.
;
; This version (v 2.00) fixes an print string error which occurs when
; 'error_3' is to be printed. It also happens to do JET v1.3 now.
; The loader checksum will distinguish between the two versions and
; will set the version flag to signal the proper changes for the
; 'mod_jet' procedure to make. The major changes were relocation of
; the stack from 1dee to 0090. Change of address of the print
; graphic string subroutine. Change of the load address of the extra
; situations sectors.
;
; This program should assemble on MASM 4.0 with no errors. Empty
; segment warning error may occur on other assemblers however this is
; a warning and is inconsequential.
;
;*******************************************************************************
;
;
;
stackseg segment para stack 'stack'
;
db 32 dup('STACK ') ;reserve 100h bytes for the stack
;
stack_top label word ;top of stack = stack_top
stackseg ends
;
;
;
dataseg segment para public 'data'
;EQUATES follow
chk_sum_10 equ 0ad62h ;loader checksum for ver 1.0
chk_sum_13 equ 07b84h ;loader checksum for ver 1.3
copy_c_sum equ 05c72h ;copyright checksum
cr equ 0dh ;carriage return character
lf equ 0ah ;line feed character
eom equ '$' ;print string terminator
;
;MISC VARIABLES follow
sec_buff db 400h dup(00h) ;1K sector buffer at beginning of ds seg
int_1e dw 2 dup(0000h) ;storage for proper int 1eh
spec_case db 00h ;floppy flag, for De-Jet to single floppy sys.
retry db 05h ;retry counter
seg dw 0000h ;Jet construction segment
version db 00h ;version storage byte (10 or 13)
;
;GENERAL MESSAGES follow
hello db 'De-Jet v2.00',cr,lf,eom
mesg_1 db 'Insert JET disk in drive A:, "JET.EXE" will be written to drive '
prt_drive db 00h,cr,lf,eom
strk_key db '...strike a key when ready or CTRL-C to stop.',cr,lf,lf,eom
mesg_2 db '...insert destination disk for JET.EXE in drive ',eom
mesg_3 db 'Conversion complete.',cr,lf,eom
;
;ERROR MESSAGES follow
error_1 db '*** bios sector read failure - ABORT',cr,lf,eom
error_2 db '*** unidentified Jet loader version - ABORT',cr,lf,eom
error_3 db '*** unidentified Jet version, "OPCODE" not present - ABORT',cr,lf,eom
error_4 db '*** file write error.',cr,lf,eom
error_5 db '*** you forgot the drive specification.',cr,lf,eom
error_6 db '*** invalid drive specification.',cr,lf,eom
error_7 db '*** not enough space available on specified drive.',cr,lf,eom
error_8 db '*** sector buffer on DMA boundary - see instructions.',cr,lf,eom
;
;MISC TABLES AND STRINGS follow
copyright db 'L|yqr~*~y*ây*lâ*,^ro*p|soxn}*yp*Qoy|qo*Z8*L|novv,6*Qoy|qsk*^omr*;:9<=9B@*.'
copylen equ $-copyright
;this parameter table is of non-dos format, used by the Jet loader
parmtable db 0cfh,02h,25h,03h,05h,2ah,0ffh,50h,83h,13h,04h,0c0h,50h,8bh,46h,0feh
;standard link header
link_head db 4dh,5ah,00,00,0a8h,00,00,00,20h,00,00,00,0ffh,0ffh,00,00
link_stack db 0eeh,1dh
link_len equ $-link_head
;filename in ascii-z string format, leading zero is for drive spec.
writefile db 00h,':JET.EXE',00h
;
;FIXUPS follow
; These fixups are for the version 1.0 of Jet and represent many hours of
; debugging. Some of the code has been coded with the 'db' directive because
; the assembler will not assemble these instructions outside the code segment.
; All 'db' instructions have the asm equivalent in the trailing comment field.
;
; The fixups are in the format 'FIXUP_??' where ?? represents the offset from
; the first byte of Jet data past the link header. They were done like this
; so that I could remember where they went in the original debugged binary
; file.
;
; An explanation of each fixup should precede the fixup and comments of the
; fixup code are included.
fixup_00 label byte ;jump to our initialization code
jmp $+(347h) ;at offset 347h in the current segment
length_00 equ $-fixup_00
;
;FIXUP_347 contains all of our hooks out of this segment. Jet takes up almost
; 64K of data and I do not know how close it comes to the end of the
; segment, so a new segment appended to the end of the Jet segment was
; created to allow room for some of our code. I have determined that
; location 347h has unwanted code and is over-written with our code
; up to 3abh where their code is required again.
fixup_347 label byte
mov ax,cs ;init. is at cs+10000 : offset 00h
add ax,1000h ;point to new segment (old + 64K), called post seg
push ax ;push seg onto stack
sub ax,ax ;point ax to offset zero
push ax ;push offset into post seg onto the stack
db 0cbh ;(retf) far return as the jump to seg : offset
;
prt_calls label byte
call $+(6e9ah-351h) ;location 351h : call to prt graphics at 6e9ah
mov si,35bh ;point to string EXIT TO DOS
call $+(6e9ah-357h) ;location 357h : call to prt graphics at 6e9ah
ret ;return back to their menu routine
;
;this is the 'EXIT TO DOS' string, screen position precedes it, terminates with a 00h
EXIT_string db 2ah,1ch,'<6> EXIT TO DOS',00h ;2a1c is position on screen
;
cmp al,02h ;test if select less than 1
jl $+(385h-36fh) ;location 36fh : jl 385h if bad input char
cmp al,07h ;check if select 6 or greater
jg $+(385h-373h) ;373 : jg 385 if bad input char
jnz $+(382h-375h) ;375 : jnz 382 if good but not exit dos
mov ax,cs ;prep do exit to DOS
add ax,1000h ;point to the post seg
push ax ;push seg
mov ax,40h ;offset of our exit to dos routine in post seg
push ax ;push the offset
db 0cbh ;(retf) far return to cs +10000 : offset 40h
jmp $+(55ch-382h) ;382 : jmp 55c do the selected option (their code)
jmp $+(551h-385h) ;385 : jmp 551 get another char code (their code)
;
mov ax,cs ;prep mov in extended situation sects.
add ax,1000h ;point to post seg
push ax ;push the seg
mov ax,66h ;point to ofset of our routine in post seg
push ax ;push offset
db 0cbh ;(retf) far return to cs +10000 : offset 66h
ret ;ret from calling load at 684h or 68ah where they called from
;
mov ax,cs ;prep mov in more extended situation sectors
add ax,1000h ;point to post seg
push ax ;push the segment
mov ax,8eh ;point to offset of our code in post seg
push ax ;push the offset
db 0cbh ;(retf) far return to cs +10000 : offset 8eh
ret ;ret from calling load at 6b4h where they called from
;
mov ax,cs ;extra hook for future use
add ax,1000h
push ax
mov ax,0b6h
push ax
db 0cbh ;(retf) far return to cs +10000 : offset b6h
length_347 equ $-fixup_347
option_calls label byte ;replacement calls for version 1.3 moved in by mod_jet
call $+(6c86h-351h) ;location 351h : call to prt graphics at 6e9ah
mov si,35bh ;point to string EXIT TO DOS
call $+(6c86h-357h) ;location 357h : call to prt graphics at 6e9ah
ret ;return back to their menu routine
len_opt_calls equ $-option_calls
;
;
;
;POSTSEG contains all of the required code to perform the command line
; parameter functions. It performs initialization functions which
; currently consist of saving the first 20h interupt vectors. It's
; easier to do this than selectively restore those which have been
; destroyed as I am uncertain of which vectors will be destroyed.
; However I do know that if you do a load scenery disk, the disk parm
; pointer gets wiped out again so we need to catch that one.
;
; Postseg has the 'exit to dos' code which puts back the old vector
; table and does a clear screen reset to 80 column mode and dos
; terminate function.
;
; Postseg also has the two routines which copy in the required
; extended situations sectors when called upon. There are two sections
; for this purpose because there are two different sets of sectors
; to be copied in place.
postseg label byte
db 80h,3eh,80h,00h,02h ;(cmp byte ptr [80h],02) are there command line parameters ?
jnz $+(1bh-5h) ;offset 5h : jnz to 1bh if no command line parms present
db 0a0h,82h,00h ;(mov al,[82h]) otherwise load parm letter into al
and al,0f0h ;take high nibble
cmp al,40h ;is it a capital letter
jz $+(15h-0eh) ;ofset eh : jz 15h if already upper case
db 80h,2eh,82h,00h,20h ;(sub byte ptr [82h],20h) otherwise subtract 20h to make upper case
db 0a0h,82h,00h ;(mov al,[82h]) put parm in al
db 0a2h,22h,08h ;(mov [822],al) put parm where jet looks for it
sub ax,ax ;prep mov 20 int vectors at seg 0000h
mov ds,ax ;load ds with source seg
mov si,ax ;set source index to beginning of table
mov di,1000h ;put at offset 1000h in post seg
mov ax,cs ;set destination segment up
mov es,ax
mov cx,40h ;move 40h words, vectors 00h - 1fh
cld ;increment through memory
cli ;allow no maskable int's and pray for no NMI
repz movsw ;move 'em out
sti ;allow interrupts now
mov ax,cs ;prepare to leave post seg
sub ax,1000h ;point to Jet seg
push ax ;push segment
mov ds,ax ;reset ds and es segments
mov es,ax
mov ax,3abh ;return to cs - 10000h : offset 3abh
push ax ;push offset of return
db 0cbh ;(retf) back to Jet
nop ;why not take a breather ?
sub ax,ax ;entry for exit to dos code
mov es,ax ;point destination segment to low vector table
mov di,ax ;point di to beginning of the table
mov si,1000h ;point source to old saved table in post seg
mov ax,cs ;prep restore 20 int's to low mem
mov ds,ax ;point source segment to post seg
mov cx,40h ;move 40h words, vectors 00h - 1fh
cld ;increment through memory
cli ;turn off maskable int's, pray for no MNI
repz movsw ;move 'em back where they belong
sti ;allow int's
sub ax,1010h ;set es and ds segs to point to link header
mov ds,ax ;set them both
mov es,ax
mov ax,03h ;restore video, clear screen and set 80x25 color
int 10h ;call bios
mov ax,4c00h ;terminate process function errorlevel = 0
int 21h ;call to dos
;
push ds ;entry for mov mem sectors e67-f67
push es ;save the es and ds regs
mov ax,cs ;point source seg to post seg
mov ds,ax
sub ax,1000h ;point es to Jet seg
mov es,ax ;track E sec. 67-69,track F 65-67
mov si,2000h ;sectors currently reside at offset 2000h in post seg
mov di,0dfd7h ;put them here in Jet seg unless version 1.3 then de6ah
copy_pt_1 equ $-2
mov cx,0c00h ;6K bytes to move
cld ;increment through memory
cli
repz movsw ;move' em out
sti
pop es ;restore old segments
pop ds
push ax ;push Jet segment
mov ax,393h ;return here in the HOOKS code
push ax ;push offset of return
db 0c6h,06h,0b1h,1bh,00h ;(mov byte ptr [1bb1h],00h) for Jet, they do it so I will too
sub ax,ax ;clear the ax for the hell of it
db 0cbh ;(retf) far return to cs -10000 : offset 393h
;
mov ax,cs ;this is the other set of extra sectors to be moved
push ds ;this is just like the above routine except for the
push es ;offset where the sectors are found in the post seg
mov ds,ax ;and the length to be moved, so you can figure it out
sub ax,1000h ;on your own !
mov es,ax ;track 10 sec. 65-69
mov si,3800h ;sectors are currently 3800
mov di,0dfd7h ;put them here except for v1.3 will change to de6ah
copy_pt_2 equ $-2
mov cx,0a00h ;5K bytes to move
cld
cli
repz movsw ;move 'em out
sti
pop es
pop ds
push ax ;time to leave this place again
mov ax,39fh
push ax
db 0c6h,06h,0b1h,1bh,00h ;(mov byte ptr [1bb1h],00h) for Jet
sub ax,ax
db 0cbh ;(retf) far return to cs -10000 : offset 39fh
length_post equ $-postseg
;
fixup_6f0d label byte
jmp $-(6f0dh-351h) ;6f0d : jmp to 351 print exit to dos v1.3
length_6f0d equ $-fixup_6f0d
;
fixup_712a label byte
jmp $-(712ah-351h) ;712a : jmp to 351 print exit to dos v1.0
length_712a equ $-fixup_712a
;
fixup_554 label byte
jmp $-(554h-36dh) ;554 : jmp to 36d to check selection
nop ;nop out some old stuff
nop
nop
nop
nop
length_554 equ $-fixup_554
;
fixup_684 label byte
call $-(684h-388h) ;684 : call 388 load sectors
length_684 equ $-fixup_684
;
fixup_68a label byte
call $-(68ah-388h) ;68a : call 388 load sectors
length_68a equ $-fixup_68a
;
fixup_6b4 label byte
call $-(6b4h-394h) ;6b4 : call 394 load sectors
length_6b4 equ $-fixup_6b4
;
dataseg ends
;
;
;
codeseg segment para public 'code'
;
begin proc far
assume cs:codeseg,ds:dataseg,ss:stackseg,es:dataseg
push ds ;used by dos for return to dos
sub ax,ax ;ds:0000h points to dos int 20
push ax ;at PSP
;
mov ax,dataseg ;iniatialize the ds segment
mov ds,ax ;register for our program
;
push ax ;save ds segment value for es later
mov bx,ax ;test to see if sector buffer is on a DMA boundary
add bx,40h ;add 1K, the size of the sector buffer, to the segment value
and bx,0f000h ;mask all but top nibble
and ax,0f000h ;same for ax
cmp ax,bx ;test upper nibble for change of seg
jz get_spec ;if zero then not on 64K boundary, continue
pop ax ;save stack integrity by dumping old ax
lea dx,error_8 ;point to error message 8
mov ah,09h ;dos function to print string
int 21h ;call to dos
mov ax,4c01h ;function to terminate process with errorlevel = 2, 'hard error'
int 21h ;call to dos
;
get_spec: pop ax ;restore segment relocatable value
mov bl,es:[80h] ;get parm length
cmp bl,00h ;if less than one then do error_5
jg parse ;
lea dx,error_5 ;print error_5 and terminate
mov ah,09h ;print string function
int 21h ;call to dos
ret ;terminate
;
parse: mov cl,byte ptr es:[82h] ;get drive spec from command line
and cl,0dfh ;force it to upper case
mov byte ptr ds:writefile,cl ;put it at beginning of filename string
sub cx,cx ;clear the used registers
mov es,ax ;put proper value in es now
;
lea dx,hello ;print the prog hello message
mov ah,09h ;dos print string function
int 21h ;call to dos
lea bx,copyright ;decrypt the copyright
mov cx,copylen
cld
decrypt: sub byte ptr [bx],0ah
inc bx
loop decrypt
lea dx,copyright ;print the copyright
mov ah,09h
int 21h
lea bx,copyright ;encrypt the copyright
mov cx,copylen
cld
encrypt: add byte ptr [bx],0ah
inc bx
loop encrypt ;end copyright code
;
mov al,writefile ;move drive spec to message string
mov prt_drive,al
;
call save_int_1e ;save old disk parm table pointer
;
call test_drive ;test for drive and drive space avail.
;
mov ah,09h ;ask insert jet disk
lea dx,mesg_1 ;
int 21h
lea dx,strk_key ;ask strike a key
mov ah,09h ;print string function
int 21h ;call dos
mov ah,08h ;wait for a key or ctrl-c break but do not echo
int 21h ;call dos
;
mov cx,0165h ;loader sector on Jet disk
call new_int_1e ;point to new parm table
;
call load_sector ;load initial loader into the sector buffer in the ds
;
call check_sum ;make sure the loader is the same as mine
;
call set_seg ;set up construction segment in es and variable seg
;
mov cx,8000h ;prep to clear 64K segment to zeros
mov ax,0000h
mov di,ax ;beginning of the segment
cld ;increment through memory
rep stosw ;store cx ax's into es:di
mov ax,es ;point to next segment
add ax,1000h
mov es,ax ;put new seg back in es
mov cx,2800h ;number of words to clear in this seg
mov ax,0000h ;store zeros
mov di,ax ;beginning of the segment
cld ;increment through memory
rep stosw ;store cx ax's into es:di
mov es,seg ;put seg back in es
;
call link_header ;create link header
;
add seg,20h ;set new segment to point to first byte past link header
mov es,seg ;put new
mov bx,0000h ;where to put the sector within construction segment
call move_sector ;put loader in proper place in construction segment
;
mov cx,0166h ;first sector in the long group to come
add bx,400h ;point to next sector location for move_sector
group_load: call load_sector ;load the sector
call move_sector ;move it to proper place in memory
add bx,400h ;point to next sector move position
inc cl ;the next sector on the track
cmp cl,6ah ;is sector header nember above 69h
jz next_track ;if so then increment the track count
jmp group_load ;load next sector in the string
next_track: sub cl,05h ;point to first sector on the track
inc ch ;point to the next track
cmp ch,0dh ;is it track 0dh ?
jnz group_load ;if not continue group load
;if it is 0dh then thru with the group load
mov cx,0e67h ;point to first of extended situations sectors
mov bx,es ;need to change es to post segment = construction seg + 64K
add bx,1000h ;add the 64K
mov es,bx ;put it into the es again
mov bx,2000h ;put them at offset 2000h in the post seg
load_extra: call load_sector ;load the sector in cx into sector buffer
call move_sector ;move it to place pointed to be es:bx
add bx,400h ;next sector position in post seg
inc cl ;next sector on the track
cmp cx,0f68h ;is it the end of this 6 sector string
jne check_done ;if not then check if done loading
inc cl ;if last in this string of sectors then
inc cl ;set cx so that next sector read will be 1065h
check_done: cmp cx,106ah ;if this value then leave this load section
je do_mods ;and go to modify code call
track_test: cmp cl,6ah ;is it time to step tracks
je step_track ;if so then new track
jmp load_extra ;read the sector
step_track: sub cl,05h ;first sector on the new track
inc ch ;the new track
jmp load_extra ;load the next sector
;
;
do_mods: mov es,seg ;put construction segment back in the es
call mod_jet
;
call old_int_1e ;put old int 1e back
;
call write_file
;
lea dx,mesg_3 ;print done message
mov ah,09h
int 21h
;
ret
begin endp
;
test_drive proc near
mov dl,writefile ;get drive spec
sub dl,40h ;convert to dos drive num A=1,B=2,...
push dx
cmp dl,02h ;is it greater than B
jg continue ;if so continue
int 11h ;get system switch stats
test al,01h ;test if any floppys attached
jz not_valid
and al,11000000b ;mask bits
rol al,1
rol al,1 ;al has num disk drives minus one
sub dl,01h
and al,dl ;if more than one floppy and drive B
jnz continue ;then continue
mov spec_case,0ffh ;set special case flag
lea dx,mesg_2 ;print insert the right disk message
mov ah,09h
int 21h
lea dx,prt_drive ;tag on the drive spec
mov ah,09h
int 21h
lea dx,strk_key ;ask strike a key
mov ah,09h
int 21h
mov ah,08h ;wait for a key or ctrl-c to break
int 21h
;
continue: mov ah,36h
pop dx ;put dos drive back in dx
int 21h ;dos drive test
cmp ax,0ffffh ;ffff if drive invalid
je not_valid
mul cx ;bytes per cluster in dx:ax, dx probably 0
mul bx ;bytes avail in dx:ax
cmp dx,0001h ;over 64K bytes ?
jb no_room ;if not do no_room
ja test_exit ;if greater then plenty of room so exit
cmp ax,5000h ;over 5000 bytes on drive (plus dx) ?
jna no_room ;if not do no room
test_exit: ret
not_valid: lea dx,error_6 ;print error and return to dos
mov ah,09h
int 21h
;
call old_int_1e
;
mov ax,4c01h ;function to terminate process with errorlevel = 2, 'hard error'
int 21h ;call to dos
no_room: lea dx,error_7 ;print error and return to dos
mov ah,09h
int 21h
mov ax,4c01h ;function to terminate process with errorlevel = 2, 'hard error'
int 21h ;call to dos
test_drive endp
;
save_int_1e proc near
push es ;save the es
push bx ;save the bx
push ax ;save the ax
mov al,1eh ;interrupt # in al
mov ah,35h ;get interrupt address in es:bx
int 21h
mov int_1e,bx ;save the interupt in int_1e
mov int_1e +2,es ;save the high part in int_1e +2
pop ax ;bring back those saved registers
pop bx
pop es
ret ;get the hell out of here
save_int_1e endp
;
new_int_1e proc near
push dx ;save the dx, remember the ds is already set
push ax ;save the ax
lea dx,parmtable ;new parm table offset in dx
mov al,1eh ;do interrupt 1eh
mov ah,25h ;put int al offset dx, segment ds in place
int 21h ;dos replace vector call
pop ax ;restore the ax
pop dx ;bring the dx back to original value
ret ;leave this place
new_int_1e endp
;
load_sector proc near
;
push es ;save es and bx
push bx
push ds ;mov ds to es
pop es
;
mov retry,05h ;five tries to read the sector
;
read_sector: lea bx,sec_buff ;load offset of buffer in the ds
mov al,01h ;one sector
mov ah,02h ;read
mov dl,00h ;drive A
mov dh,00h ;side zero
;track and sector already in cx
int 13h ;bios disk read
jnc good_read ;if ok then continue
dec retry ;if bad read then decrement the retry count
jnz read_sector
lea dx,error_1 ;point to the error message
mov ah,09h ;dos print string function
int 21h ;call to dos
;
call old_int_1e
;
mov ax,4c01h ;function to terminate process with errorlevel = 2, 'hard error'
int 21h ;call to dos
;
good_read: pop bx ;restore bx
pop es ;bring back the original es which contains contruction segment
ret ;leave this place now
load_sector endp
;
;
;
move_sector proc near
push cx ;save the cx
push di ;save the di
lea si,sec_buff ;point source to sector buffer
mov di,bx ;point di to destination in construction seg
mov cx,400h ;mov 1K bytes
cld ;increment through memory
rep movsb ;mov cx bytes from ds:si to es:di
pop di ;restore the di
pop cx ;restore the cx
ret ;exit to calling procedure
move_sector endp
;
;
;
mod_jet proc near
lea si,fixup_00 ;put in first jmp into our code
mov di,00h ;put at offset 00h
cmp byte ptr es:[di],90h ;check th opcode first
je go_on ;make sure its a nop
jmp bad_opcode ;had to be done this way because bad_opcode out of range for jnz
go_on: mov cx,length_00 ;put the length of the fix in the cx for the move
cld ;increment through memory
rep movsb ;move from ds:si to es:di
;
;
cmp byte ptr version,13h ;check for version 1.3
jne cont_347 ;if not continue with fixup_347
lea si,option_calls ;prep to move in optional calls for ver 1.3
lea di,prt_calls ;here's where they go
push es ;set es up to point in ds
push ds
pop es
mov cx,len_opt_calls ;num bytes to move
cld ;increment the si,di
repz movsb ;move'em
pop es ;restore es to point to construct seg
cont_347: lea si,fixup_347 ;move in hooks
mov di,347h ;put at offset 347h
mov cx,length_347 ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
;
;
mov di,722h ;put in command line required
mov word ptr es:[di],2020h ;put at offset 722h
;
;
lea si,fixup_554 ;key board hook to exit to dos
mov di,554h ;put at offset 554h
mov cx,length_554 ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
;
;
lea si,fixup_684 ;load extra sectors hook
mov di,684h ;put at offset 684h
cmp byte ptr es:[di],0e8h ;make sure its a call
je more_684 ;if it is continue
jmp bad_opcode ;otherwise do bad opcode error
more_684: mov cx,length_684 ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
;
;
lea si,fixup_68a ;another load extra sectors hook
mov di,68ah ;put t offset 68ah
cmp byte ptr es:[di],0e8h ;make sure its a call
jnz bad_opcode ;if bad opcode then error
mov cx,length_68a ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
;
;
lea si,fixup_6b4 ;the last load extra sectors hook
mov di,6b4h ;put at offset 6b4
cmp byte ptr es:[di],0e8h ;make sure its a call
jnz bad_opcode ;if bad opcode then error
mov cx,length_6b4 ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
;
;
cmp byte ptr version,13h ;check for version 1.3
jz other_pg ;if so do the other print graphics hook mod
lea si,fixup_712a ;prt graphics hook
mov di,712ah ;put at offset 712ah
cmp byte ptr es:[di],0e8h ;make sure its a call
jnz bad_opcode ;if not right opcode then error
mov cx,length_712a ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
jmp put_postseg ;continue on skipping next mod
other_pg: lea si,fixup_6f0d ;prt graphics hook
mov di,6f0dh ;put at offset 6f0dh
cmp byte ptr es:[di],0e8h ;make sure its a call
jnz bad_opcode ;if not right opcode then error
mov cx,length_6f0d ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
;
;
put_postseg: cmp byte ptr version,13h ;is it version 1.3
jne cont_postseg ;if not then continue on
mov word ptr copy_pt_1,0de6ah ;need to change address of point where extra sector
mov word ptr copy_pt_2,0de6ah ;info is copied into code segment
;then continue
cont_postseg: lea si,postseg ;move in post segment code
push es ;save this segment
mov bx,es ;point to the new segment
add bx,1000h ;which is 10000h past the old
mov es,bx ;load the new segment
mov di,00h ;point to beginning of new segment
mov cx,length_post ;length of the fix
cld ;increment through memory
rep movsb ;move from ds:si to es:di
pop es ;restore the es
;
ret ;return to calling procedure
;
bad_opcode: lea dx,error_3 ;print error 3 message
mov ah,09h
int 21h
;
call old_int_1e
;
mov ax,4c01h ;function to terminate process with errorlevel = 2, 'hard error'
int 21h ;call to dos
mod_jet endp
;
;
;
link_header proc near
push si ;save si and si
push di
cmp byte ptr version,13h ;is this version 1.3
jne cont_link ;if not continue on
mov byte ptr link_stack,90h ;change initial stack to 0090 from 1dee
mov byte ptr link_stack+1,00h
cont_link: lea si,link_head ;point to link header info
mov di,00h ;point to beginning of consruction seg
mov cx,link_len ;load length of link header info
cld ;increment through memory
rep movsb ;move link header into construction seg
pop di ;restore si and di
pop si
ret ;return to calling procedure
link_header endp
;
write_file proc near
push ds ;save the ds
cmp spec_case,0ffh ;is this a special drive case
jnz do_write
lea dx,mesg_2 ;ask insert right disk
mov ah,09h
int 21h
lea dx,prt_drive ;print the drive spec
mov ah,09h
int 21h
lea dx,strk_key ;ask srike a ket to continue
mov ah,09h
int 21h
mov ah,08h ;wait for a key or ctrl-c to break
int 21h
;
do_write: lea bx,copyright ;load address of copyright string
sub ax,ax ;clear the ax
mov cx,(copylen/2h) ;add this many words
copy_chk: add ax,[bx] ;add to ax
inc bx ;point to next word
inc bx
loop copy_chk ;loop until all words done
cmp ax,copy_c_sum ;is it correct ?
jne bad_write ;if not then don't write the Jet.exe file
;
lea dx,writefile ;point to file and path ascii-z string
mov cx,20h ;attribute of file to be created
mov ah,3ch ;dos create file function
int 21h ;call to dos
jc bad_write ;carry set then handle the error
;
mov dx,seg ;load segment of Jet info
sub dx,20h ;relocate to link header
mov ds,dx ;put the segment in ds
sub dx,dx ;point to the beginning of the file in memory
mov cx,0ffffh ;write this many bytes, this is max allowed
mov bx,ax ;put the file handle in the bx for this function call
mov ah,40h ;write to file function
int 21h ;call to dos
jc bad_write ;carry set then handle the error
cmp ax,0ffffh ;was correct number of bytes written ?
jnz bad_write ;if not then handle the error
;
mov cx,0h ;move pointer past the end of the file
mov dx,01h ;this many bytes (1)
mov ah,42h ;function to move pointer
mov al,02h ;method of pointer movement
int 21h ;call to dos
jc bad_write ;carry set then handle the error
;
mov dx,ds ;point to the next segment to write from
add dx,1000h ;add 64K
mov ds,dx ;put the new segment back in the ds
sub dx,dx ;point to the beginning of the segment
mov cx,5000h ;write this many bytes
mov ah,40h ;write to file function
int 21h ;call to dos
jc bad_write ;if carry set then handle error
cmp ax,5000h ;was correct number of bytes written ?
jnz bad_write ;if not then do error
;
mov ah,3eh ;close file function, handle in bx
int 21h ;call to dos
jc bad_write ;if carry set then handle the error
pop ds ;restore the ds segment
ret ;return to calling procedure
;
bad_write: pop ds ;error handling here, restore the ds
lea dx,error_4 ;point to error message
mov ah,09h ;print string function
int 21h ;call to dos
mov ax,4c01h ;function to terminate process with errorlevel = 2, 'hard error'
int 21h ;call to dos
;
write_file endp
;
;
;
check_sum proc near
mov cx,200h ;sum 512 words
lea bx,sec_buff ;they are in the sector buffer
sub ax,ax ;clear the ax to hold the sum
sum: add ax,[bx] ;add this word to the ax
inc bx ;point to next word
inc bx
loop sum ;do 200h words
mov bx,chk_sum_10 ;load correct v1.0 value into bx
cmp ax,bx ;is it Jet ver 1.0 ?
je exit_10 ;if so do the proper exit routine
mov bx,chk_sum_13 ;load correct v1.3 value into bx
cmp ax,bx ;is it Jet ver 1.3 ?
je exit_13 ;if so do the proper exit routine
;if not drop thru to error code
bad_chksum: lea dx,error_2 ;unidentified loader message
mov ah,09h ;print function
int 21h ;call dos function
call old_int_1e ;put the old parameter table pointer back
mov ax,4c01h ;function to terminate process with errorlevel = 2, 'hard error'
int 21h ;call dos function
exit_10: mov version,10h ;put 10 hex into version
ret ;and leave procedure
exit_13: mov version,13h ;put 13 hex into version
ret ;and leave procedure
check_sum endp
;
;
;
old_int_1e proc near
push ds ;save the ds register
push dx ;save the dx register
mov dx,word ptr int_1e ;get old offset value
mov ax,word ptr int_1e +2 ;get old segment value
mov ds,ax ;put segment value in ds
mov ah,25h ;dos change interrupt function
mov al,1eh ;interrupt number
int 21h ;call dos function
pop dx ;restore the dx
pop ds ;restore the ds
ret ;return from procedure
old_int_1e endp
;
;
;
set_seg proc near
push ax ;save the ax
mov ax,construct ;load segment after the code segment
mov es,ax ;put it in the es
mov seg,ax ;and in the proper variable for future reference
pop ax ;restore ax
ret ;return to calling procedure
set_seg endp
;
;
;
codeseg ends ;end of code
;
construct segment para ;define Jet construction segment
construct ends
;
end begin ;end of program