home *** CD-ROM | disk | FTP | other *** search
- ;*-------------------------------------------------------------------*;
- ;* FlashDOS Version 2.1 by P.E.Colla 1988 - COLLA @ MARVM1 *;
- ;* *;
- ;* This program start a secondary DOS command processor from *;
- ;* inside applications. *;
- ;* *;
- ;* Version 2.0 10-Jul-89 Virtual memory support added. *;
- ;* Version 2.1 25-Jul-89 Huge mode added. *;
- ;* *;
- ;*-------------------------------------------------------------------*;
-
-
- ;*-------------------------------------------------------------------*;
- ;* DOS Memory Control Block - Chain Record Format (Undocumented) *;
- ;*-------------------------------------------------------------------*;
-
- mem segment at 0FFFFh
-
- memtype db ?
- memid dw ?
- memsize dw ?
-
- mem ends
-
- ;*-------------------------------------------------------------------*;
- ;* Main Program Start *;
- ;*-------------------------------------------------------------------*;
- cseg segment para public 'code'
- org 100h
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
- ;*-------------------------------------------------------------------*;
- ;* Equates *;
- ;*-------------------------------------------------------------------*;
-
- cr equ 0dh
- lf equ 0ah
- bell equ 07h
- hotkey equ 0Eh
- shift_mask equ 08h
- ncol equ 80
- box_row equ 0
- box_col equ 0
- bw_attr equ 70h
- co_attr equ 17h
- id_len equ (id_end - id) - 1
- prog_len equ (initialize - main) / 10h
- env_var_len equ (env_var_end - env_var)
- video_len equ 315
-
- ;*-------------------------------------------------------------------*;
- ;* Control is given here at load time, jump to initialization code *;
- ;*-------------------------------------------------------------------*;
-
- main: jmp initialize
-
- ;*-------------------------------------------------------------------*;
- ;* Variable definition area *;
- ;*-------------------------------------------------------------------*;
- ;***---- COMMON AREA ---***;
-
- ;*--- Unique ID to detect multiple load
-
- id db "@#PonchiFlashDOS#@"
- id_unique db 10 dup (0)
- id_end db 0
-
- ;*--- External Swap File Area
-
- swapfile db "A:\FLASHDOS.SWP",0
- handle dw ?
-
- ;*--- Inter-Process Communication
-
- rc db 00h
-
- ;*--- DOS command to be passed to COMMAND.COM at start
-
- dos_command_def db 3," ",cr,0,0
- dos_command db 0,40 dup (" "),cr,0,0
- command_flag db 0
-
- ;*--- Status control area
-
- active db 0
- dormant db 0
- buffer_type db "I"
- huge_mode db 0
-
- ;*--- WorkSpace Address & Size
-
- ptr_area dw 0
- size_area dw 4096
-
- ;*--- Runtime error & messages
-
- merr01 db cr,lf
- db "FlashDOS: Invalid Function Code",cr,lf,"$"
- merr02 db cr,lf
- db "FlashDOS: File not found",cr,lf,"$"
- merr05 db cr,lf
- db "FlashDOS: Access Denied",cr,lf,"$"
- merr07 db cr,lf
- db "FlashDOS: Memory Blocks Destroyed",cr,lf,"$"
- merr08 db cr,lf
- db "FlashDOS: Insufficient memory",cr,lf,"$"
- merr09 db cr,lf
- db "FlashDOS: Invalid Memory Block Address",cr,lf,"$"
- merr10 db cr,lf
- db "FlashDOS: Invalid Media",cr,lf,"$"
- merr11 db cr,lf
- db "FlashDOS: Invalid Format",cr,lf,"$"
- merrff db cr,lf
- db "FlashDOS: Protection Exception",cr,lf,"$"
- merrot db cr,lf
- db "FlashDOS: Something wrong occurs",cr,lf,"$"
- now_inactive db cr,lf
- db "FlashDOS: Now Inactive",cr,lf,"$"
- StartUp db cr,lf
- db "╔═════════════════════════════════════════════════════════════════════════════╗",cr,lf
- db "║ FlashDOS Version 2.1 by P.E.Colla (COLLA @ MARVM1) ║",cr,lf
- db "║ Type EXIT to End "
- type_msg db "Real"
- db "║",cr,lf
- db "╚═════════════════════════════════════════════════════════════════════════════╝",cr,lf
- db "$"
- disk_msg db "Disk"
- huge_msg db "Huge"
- SwapMsg db cr,lf
- db "╔═════════════════════════════════╗",cr,lf
- db "║ FlashDOS V2.1 ║",cr,lf
- db "║Swapping to Drive "
- Drive db "A:"
- db ", Please wait║",cr,lf
- db "╚═════════════════════════════════╝",cr,lf
- db "$"
- db " ",cr,lf
-
- Finish db cr,lf
- db "FlashDOS Ended",cr,lf,"$"
- dos_error db cr,lf
- db "FlashDOS: Secondary COMMAND cann't start",cr,lf,"$"
- claim_error db cr,lf
- db "FlashDOS: Cann't claim memory",cr,lf,"$"
-
- ;*--- Errors associated with swap process
-
- emem_error db cr,lf
- db "FlashDOS: Memory mgmt error",cr,lf,"$"
- epsp_error db cr,lf
- db "FlashDOS: PSP do not belong to Usr Program",cr,lf,"$"
- edisk_error db cr,lf
- db "FlashDOS: Disk error, Can not swap out",cr,lf,"$"
- eno_space db cr,lf
- db "╔════════════════════════════════╗",cr,lf
- db "║ FlashDOS 2.0 ║",cr,lf
- db "║ Not enough space to swap ║",cr,lf
- db "║ Press any key to continue ║",cr,lf
- db "╚════════════════════════════════╝",cr,lf,"$"
- eusr_short db cr,lf
- db "╔════════════════════════════════╗",cr,lf
- db "║ FlashDOS 2.0 ║",cr,lf
- db "║ Insufficient User Memory ║",cr,lf
- db "║ Press any key to continue ║",cr,lf
- db "╚════════════════════════════════╝",cr,lf,"$"
- eno_open db cr,lf
- db "FlashDOS: Can not open swap file",cr,lf,"$"
- eno_swap db cr,lf
- db "FlashDOS: Can not swap to file",cr,lf,"$"
- eno_shrink db cr,lf
- db "FlashDOS: Can not shrink Usr memory",cr,lf,"$"
- eswap_ok db cr,lf
- db "FlashDOS: User program swapped OK",cr,lf,"$"
- eno_retrieve db cr,lf
- db "FlashDOS: Can not retrieve memory",cr,lf,"$"
- eno_close db cr,lf
- db "FlashDOS: Can not close swap file",cr,lf,"$"
- eno_erase db cr,lf
- db "FlashDOS: Can not erase swap file",cr,lf,"$"
-
-
- ;*--- Local Stack Definition
-
- Old_ss dw ?
- Old_sp dw ?
- Free_Space dw 512 dup (?)
- Loc_sp dw 10 dup (?)
-
- ;*--- Interrupt saving area
-
- Old_Int_Area dw 1200 dup (?)
- New_Int_Area dw 1200 dup (?)
-
- ;*--- EXEC control block
-
- env_segment dw ?
- command_ptr dw 2 dup (?)
- fcb1_ptr dw 2 dup (?)
- fcb2_ptr dw 2 dup (?)
-
- ;*--- COMMAND.COM path
-
- comspec_path db "A:\COMMAND.COM",0
- db 100 dup (0)
- env_var db "COMSPEC="
- env_var_end db ?
-
-
- ;*--- User memory block information
-
- usr_base dw ?
- usr_psp dw ?
- usr_size dw ?
- usr_last dw ?
-
- ;*--- Swap process auxiliary registers
-
- swp_len dw ?
- swp_par dw ?
- usr_ptr dw ?
- usr_len dw ?
-
- ;*--- Stack save area
-
- ss_save dw ?
- sp_save dw ?
-
- ;*--- Old Interrupt Address
-
- old_int_9 dd 0
- old_int_13 dd 0
- old_int_21 dd 0
-
- ;*--- Video Information
-
- cursor_pos dw 0
- display_page db 0
- attribute db 0
- nrow db 25
-
- ;*--- Flags & Status
-
- disk_status db 0
- load_flag db 0
- dos_flag dd 0
- info_ptr dd 00000487h
- lo_fn_flag db 0
- paragraph_size db 10h
- par_size dw 10h
-
-
- ;*-------------------------------------------------------------------*;
- ;* New BIOS Keyboard Interrupt *;
- ;*-------------------------------------------------------------------*;
-
- int_9 proc far
- assume cs:cseg,ds:nothing,es:nothing,ss:nothing
-
- ;*--- Check if Hot Key is pressed
-
- sti
- push ax
- mov ah,0ffh
- mov cs:rc,ah
- in al,60h
- cmp al,hotkey
- jne process_key
- mov ah,2
- int 16h
- and al,0Fh
- cmp al,shift_mask
- je our_key
-
- ;*--- No, continue with old keyboard interrupt handler
-
- process_key:
- pop ax
- jmp dword ptr cs:old_int_9
-
- ;*--- Yes,reset keyboard and see if it is possible to pop up
-
- our_key:
- in al,61h
- mov ah,al
- or al,80h
- out 61h,al
- jmp short $+2
- out 61h,al
- cli
- mov al,20h
- out 20h,al
- sti
-
- ;*--- Is FlashDOS already active
-
- cmp cs:active,0
- jne return_a
-
- ;*--- Is DOS in critical state
-
- push ds
- push bx
- lds bx,cs:dos_flag
- cmp byte ptr [bx],0
- jne return_b
-
- ;*--- Is DOS performing Int 21h greather than 0Ch
-
- cmp cs:lo_fn_flag,0
- jne return_b
-
- ;*--- Is any disk activity in progress
-
- check_b: cmp cs:disk_status,0
- jne return_b
-
- ;*--- Is active
-
- cmp cs:dormant,0
- je invoke
-
- return_b: pop bx
- pop ds
- return_a: pop ax
- iret
-
- ;*--- Condition OK to popup, video condition is saved
-
- invoke: lds bx,cs:info_ptr
- lds bx,[bx]
- test bl,08h
- jnz return_b
- mov attribute,co_attr
- mov ah,0Fh
- int 10h
- mov display_page,bh
- cmp al,3
- jbe mode_ok
- mov attribute,bw_attr
- cmp al,7
- jne return_b
-
- ;*--- Set active flag, FlashDOS is not re-entrant.
-
- mode_ok: inc cs:active
-
- ;*--- Signal with interprocess purposes that at least the condition for popup
- ;*--- was completed
-
- mov ah,80h
- mov cs:rc,ah
-
- ;*--- Put the stack on a safe place and Save everything
-
- cli
-
- mov cs:old_ss,ss
- mov cs:old_sp,sp
- push cs
- pop ss
- mov sp,offset cs:Loc_sp
-
- sti
-
- push cx
- push dx
- push di
- push si
- push es
- push bp
-
- push cs
- pop ds
-
- push cs
- pop es
-
- ;*--- IF External swap mode then preserve interrupt vector and restore the
- ;*--- vector that was at the FlashDos loading time.
- ;*--- This operation avoid any conflict if the current program have one or
- ;*--- more interrupt vectors trapped (pointing to nowhere if swapped).
-
- cmp cs:buffer_type,"E"
- jne txintend
-
- cli
-
- push es
-
- mov ax,0000h
- mov es,ax
-
-
- mov si,0000h
- lea di,new_int_area
- mov bx,1024
-
- txintold:
- mov ah,byte ptr es:[si]
- mov byte ptr cs:[di],ah
- inc di
- inc si
- dec bx
-
- mov ax,bx
- cmp ax,0000h
- jne txintold
-
- mov si,0000h
- lea di,old_int_area
- mov bx,1024
-
- txintnew:
- mov ah,byte ptr cs:[di]
- mov byte ptr es:[si],ah
- inc di
- inc si
- dec bx
-
- mov ax,bx
- cmp ax,0000h
- jne txintnew
-
- pop es
-
- sti
-
- txintend:
-
- assume ds:cseg,es:cseg
-
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov ah,3
- int 10h
- mov cursor_pos,dx
-
- ;*--- Save & clear screen
-
- mov di,offset initialize
- mov si,0FFFFh
- call screen
-
- ;*--- If a user program is selected to popup don't clear the screen
-
- cmp byte ptr cs:command_flag,00h
- jne dos_ldr
-
- ;*--- If external swap is specified don't clear the screen neither
-
- cmp byte ptr cs:buffer_type,"E"
- je dos_ldr
-
- call clr_box
-
- ;*--- Try to load COMMAND.COM
- dos_ldr:
- call dos_loader
-
- ;*--- Restore screen
-
- mov si,offset initialize
- call screen
- mov ah,2
- mov dx,cursor_pos
- int 10h
-
- ;*--- Reset active flag
-
- mov active,0
-
- ;*--- Restore registers
-
- pop bp
- pop es
- pop si
- pop di
- pop dx
- pop cx
-
- ;*--- Restore Stack
-
- cli
-
- mov ss,old_ss
- mov sp,old_sp
-
- sti
-
- ;*--- Check if storage mode is external or internal
- ;*--- If External restore Interrupt Vector area
-
- cmp cs:buffer_type,"E"
- jne endint9
-
- cli
-
- push es
-
- mov ax,0000h
- mov es,ax
-
- mov si,0000h
- lea di,new_int_area
- mov bx,1024
-
- reintold:
- mov ah,byte ptr cs:[di]
- mov byte ptr es:[si],ah
- inc di
- inc si
- dec bx
-
- mov ax,bx
- cmp ax,0000h
- jne reintold
-
- pop es
- sti
-
- ;*--- Signal with inter-process purposes that the program sucefully ended
-
- mov ah,00h
- mov cs:rc,ah
-
- endint9:
- pop bx
- pop ds
- pop ax
-
-
- iret
- int_9 endp
-
-
- ;*-------------------------------------------------------------------*;
- ;* Loader of secondary COMMAND.COM *;
- ;*-------------------------------------------------------------------*;
- dos_loader proc near
-
- ;*--- Set addresability
-
- mov ax,cs
- mov ds,ax
- mov es,ax
-
- ;*--- Get current video page
-
- mov ah,0Fh
- Int 10h
-
- ;*--- Position cursor at upper left corner (0,0)
-
- mov bl,00h
- mov dx,0000h
- mov ah,02h
- Int 10h
-
- ;*--- Check if Internal or External swap is selected
-
- cmp cs:buffer_type,"E"
- je external_swap
-
- ;*--- Get pointer to workspace area (If internal swap is active)
-
- internal_storage:
- mov ax,word ptr cs:ptr_area
-
- ;*--- Freed up reserved workspace area
-
- mov es,ax
- mov ah,49h
- Int 21h
-
- ;*--- OK, go to load command.com
-
- jc intsto01
- jmp load_command
-
- ;*--- Display error message (never should happen)
-
- intsto01:
- mov dx,offset claim_error
- call print
-
- jmp escape
-
- ;*--- External Swap procedure
-
- external_swap:
-
- ;*--- Get current (user program) PSP segment
-
- mov ah,62h
- Int 21h
-
- mov cs:usr_psp,bx
-
-
- ;*--- Based on PSP segment address the User's MCB is accesed
-
- push ds
-
- mov ax,cs:usr_psp
- dec ax
- mov ds,ax
-
- assume ds:mem
-
- ;*--- Verify is the MCB is one of the expected type
-
-
- cmp ds:memtype,"M"
- je eswap01
-
- cmp ds:memtype,"Z"
- je eswap01
-
- mov dx,offset emem_error
- call print
- call getkey
- pop ds
- jmp escape
-
- ;*--- Get the owner of the MCB (Should be the PSP just retrieved above)
-
- eswap01:
- mov ax,cs:usr_psp
- cmp ds:memid,ax
- je eswap02
-
- mov dx,offset epsp_error
- call print
- call getkey
- pop ds
- jmp escape
-
- ;*--- Get the memory size of the block owned by the PSP (in paragraphs)
-
- eswap02:
- mov ax,ds:memsize
- mov cs:usr_size,ax
-
- ;*--- If huge mode is in place the swappable area is set to the user size
- ;*--- minus one.
- cmp byte ptr cs:huge_mode,01h
- jnz eswap02b
-
- ;*--- The reason to let at least one user block in memory is really to avoid
- ;*--- the mess to completely erase the user MCB and after the operation
- ;*--- restore it.
- mov ax,word ptr cs:usr_size
- sub ax,10h
- mov word ptr cs:size_area,ax
-
- assume ds:cseg
-
- eswap02b:
- pop ds
-
- ;*--- The User PSP size is checked against the size of the area required
-
- cmp ax,size_area
- jnb eswap09
-
- mov dx,offset eusr_short
- call print
- call getkey
- jmp escape
-
- ;*--- The actual segment from wich the memory will be swapped to disk
- ;*--- is computed.
- ;*--- First, the last allocated paragraph is computed
-
- eswap09:
-
- mov ax,cs:usr_psp
- dec ax
- mov bx,cs:usr_size
- add ax,bx
- dec ax
- mov cs:usr_last,ax
-
- ;*--- Now the paragraph in which the swap will start is computed
-
- inc ax
- sub ax,cs:size_area
- mov cs:usr_base,ax
-
-
- ;*--- All the memory dirty work is already done, now all the user's files
- ;*--- are closed (if any).
-
- push bx
- push cx
- mov cx,0Fh
- mov bx,05h
-
- eswap03:
- mov ah,3Eh
- Int 21h
-
- inc bx
- loop eswap03
-
- pop cx
- pop bx
-
-
- ;*--- Now take a look around to found space enough to swap out the memory
- ;*--- Scan drive F: thru A:
-
- mov dl,05h
- mov dh,00h
-
- ;*--- Try to get disk status for the selected drive
-
- eswap04:
-
- clc
-
- mov di,dx
- mov al,00h
- mov ah,36h
- Int 21h
-
- jnc eswap05
-
- mov dx,offset edisk_error
- call print
- call getkey
- jmp escape
-
- ;*--- If AX=FFFFh there are no drive available to check
-
- eswap05:
-
- cmp ax,0FFFFh
- jne eswap06
-
- ;*--- Decrement drive to next available and check again
-
- eswap08:
- mov dx,di
- dec dl
- jnz eswap04
-
- ;*--- If drive count reach 0 no one of the drive have enough space to swap
-
- mov dx,offset eno_space
- call print
- call getkey
- jmp escape
-
- eswap06:
-
- ;*--- Check if the space available is really huge, otherwise a
- ;*--- free amount of paragraphs could be greater than FFFFh and
- ;*--- the space computation could end on error
-
- push ax
- mov ax,bx
- cmp ax,1000
- jge eswap16
- jmp eswap17
-
- eswap16:
- pop ax
- jmp eswap07
-
- ;*--- Get free space on drive
- ;*--- First get bytes on each cluster
-
- eswap17:
- pop ax
- mul cx
-
-
- ;*--- Then convert to paragraphs by cluster
-
- idiv paragraph_size
-
- mov ah,00h
-
- ;*--- Now get total number of paragraphs available on drive
-
- mul bx
-
- ;*--- Compare with amount needed, if not enough continue to cycle
-
- cmp ax,size_area
- jnb eswap07
- jmp eswap08
-
- eswap07:
-
- ;*--- Now the drive with sufficient space is on DI, transfer to DX
-
- mov dx,di
-
- ;*--- Convert the drive number to a useful form
-
- add dl,40h
- mov cs:swapfile,dl
- mov cs:drive,dl
-
- ;*--- Print swap in progress message
-
- mov ax,cs
- mov ds,ax
- mov dx,offset SwapMsg
- call print
-
- ;*--- Create and open the swapfile (hidden file)
-
- push cs
- pop ds
- mov dx,offset swapfile
- mov cx,02h
- mov ah,03cH
- Int 21h
-
- jnc eswap10
-
- mov dx,offset eno_open
- call print
- call getkey
- jmp escape
-
- ;*--- Store the handle number returned by DOS
-
- eswap10:
- mov cs:handle,ax
-
- ;*--- Now the swap is actually done
- ;*--- Set the address FROM
-
- mov ax,cs:usr_base
- mov cs:usr_ptr,ax
-
- ;*--- Set the size to swap
-
- mov ax,size_area
- mov usr_len,ax
-
- ;*--- Cycle thru the swapable area swapping on 64K chunks
-
- eswap11:
- mov bx,usr_len
- mov ax,0fffh
-
- cmp ax,bx
- jb more_64K
-
- mov ax,usr_len
- mul par_size
- mov swp_len,ax
- mov swp_par,bx
- jmp swap_in
-
- more_64K:
- mov ax,0FFF0h
- mov swp_len,ax
- mov ax,0fffh
- mov swp_par,ax
- swap_in:
- clc
- mov bx,handle
- mov cx,swp_len
- mov dx,0000h
- push ds
- mov ax,usr_ptr
- mov ds,ax
- mov ah,40h
- mov al,00h
- Int 21h
- pop ds
-
- jnc eswap12
-
- ;*--- Check if the amount of bytes wrote is equal than expected
-
- mov dx,offset eno_swap
- call print
- call getkey
- jmp escape
-
- ;*--- Increment pointer (next paragraph) decrement remaining size
-
- eswap12:
-
- mov ax,usr_ptr
- add ax,swp_par
- mov usr_ptr,ax
-
- mov ax,usr_len
- sub ax,swp_par
- mov usr_len,ax
-
-
- ;*--- When remainder is equal to zero the swap is finished
-
- cmp ax,0000h
- jne eswap11
-
- cmp byte ptr cs:command_flag,00h
- jne eswap18
-
- ;*--- Clear Screen & Position cursor at upper left corner (0,0)
-
- push ds
- push es
- call clr_box
-
- mov bl,00h
- mov dx,0000h
- mov ah,02h
- Int 10h
- pop es
- pop ds
-
- ;*--- To complete the swap the swapfile is closed
-
- eswap18:
- clc
-
- mov bx,cs:handle
- mov ah,3Eh
- Int 21h
-
- jnc eswap15
-
- mov dx,offset eno_close
- call print
- call getkey
- jmp escape
-
- ;*--- When the swap is complete the piece of the user program swaped is
- ;*--- shrinked down to allow free space to be used.
-
- eswap15:
-
- mov ax,usr_size
- sub ax,size_area
- mov bx,ax
- mov ax,usr_psp
- mov es,ax
- mov ah,4ah
- mov al,00h
- Int 21h
-
- jnc load_command
-
- mov dx,offset eno_shrink
- call print
- call getkey
- jmp escape
-
- load_command:
-
- ;*--- Set contents of EXEC Control Block
-
- mov ax,word ptr cs:2Ch
- mov env_segment,ax
- mov word ptr cs:env_segment + 4,cs
-
- ;*--- Select between default or specified DOS Command
-
- cmp command_flag,00h
- je default_com
- mov word ptr cs:env_segment + 2,offset dos_command
- jmp start_load
-
- default_com:
-
- mov word ptr cs:env_segment + 2,offset dos_command_def
-
- ;*--- Save main registers on stack
-
- start_load:
- push es
- push ds
- push bp
-
- ;*--- Save stack itself
-
- mov ss_save,ss
- mov sp_save,sp
-
- ;*--- Display PopUp message
-
- cmp byte ptr cs:command_flag,00h
- jne cont_load
-
- mov ax,cs
- mov ds,ax
- mov dx,offset StartUp
- call print
-
- ;*--- Load & Exec a Secondary DOS Command Processor
- cont_load:
- mov ax,cs
- mov ds,ax
- mov es,ax
- lea dx,comspec_path
- lea bx,env_segment
- mov ah,4bh
- mov al,00h
- Int 21h
-
- ;*--- Restore stack & registers
-
- mov ss,ss_save
- mov sp,sp_save
-
- pop bp
- pop ds
- pop es
-
- ;*--- Something wrong? , Display message.
-
- jc load_error
-
- end_load:
- cmp byte ptr cs:command_flag,00h
- jne end_ldb
-
- ;*--- Display End Session message
-
- mov dx,offset Finish
- call print
-
- end_ldb:
-
- cmp cs:buffer_type,"E"
- je external_retrieve
-
- ;*--- If internal swap done Allocate workspace again to preserve it.
-
- internal_retrieve:
-
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov bx,size_area
- mov ah,48h
- Int 21h
-
- ;*--- Cann't, display message.
-
- jc prt_mem_err
-
- ;*--- Workspace is under ownership of the interrupted program
- ;*--- Access DOS Memory Control Block of allocated space and change
- ;*--- ID to point to PSP of FlashDOS.
-
- mov word ptr cs:ptr_area,ax
- dec ax
- mov ds,ax
-
- assume ds:mem
-
- cmp ds:memtype,"M"
- jne chg_mem_err
-
- mov ax,cs
- mov ds:memid,ax
-
- ;*--- Restablish addresability
-
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
- mov ax,cs
- mov ds,ax
- jmp escape
-
- ;*--- Error handling & display messages
-
- chg_mem_err:
- mov ax,0ffh
- prt_mem_err:
- call memory_error
-
- ;*--- Cann't claim back its memory, became inactive
-
- mov dormant,01h
- mov dx,offset now_inactive
- call print
-
- jmp escape
-
- ;*--- If load error is found after the message the workarea is claimed again
-
- load_error:
- call memory_error
- call getkey
- jmp end_load
-
- ;*--- If external retrieve is active the memory is swapped back
-
- external_retrieve:
-
- ;*--- Last, the Usr program is restored as a main PSP for DOS
-
- push cs
- pop ax
- mov es,ax
- mov ds,ax
-
- ;*--- The user memory block is restored to his original size
-
- clc
-
- mov ax,usr_size
- mov bx,ax
- mov ax,usr_psp
- mov es,ax
- mov ah,4ah
- mov al,00h
- Int 21h
-
- jnc eretr01
-
- mov dx,offset eno_retrieve
- call print
- call getkey
- jmp escape
-
- eretr01:
-
- ;*--- Now the swapfile is open for read
-
- clc
-
- push cs
- pop ds
- mov dx,offset swapfile
- mov ax,3D00h
- Int 21h
-
- jnc eretr02
-
- mov dx,offset eno_open
- call print
- call getkey
- jmp escape
-
- ;*--- If the file was sucefully open the swaped part of the memory is restored
-
- eretr02:
- mov cs:handle,ax
-
- push cs
- pop ax
- mov es,ax
- mov ds,ax
-
- mov ax,usr_base
- mov usr_ptr,ax
- mov ax,size_area
- mov usr_len,ax
-
- eretr03:
- mov bx,usr_len
- mov ax,0fffh
-
-
- cmp ax,bx
- jb more_64Kb
-
- mov ax,usr_len
- mul par_size
- mov swp_len,ax
- mov swp_par,bx
- jmp swap_out
-
- more_64Kb:
- mov ax,0FFF0h
- mov swp_len,ax
- mov ax,0fffh
- mov swp_par,ax
-
- swap_out:
- clc
-
- mov bx,handle
- mov cx,swp_len
- mov dx,0000h
-
- push ds
- mov ax,usr_ptr
- mov ds,ax
- mov al,00h
- mov ah,3Fh
- Int 21h
- pop ds
-
- jnc eretr04
-
- mov dx,offset eno_swap
- call print
- call getkey
- jmp escape
-
- eretr04:
-
- mov ax,usr_ptr
- add ax,swp_par
- mov usr_ptr,ax
-
- mov ax,usr_len
- sub ax,swp_par
- mov usr_len,ax
-
- cmp ax,0000h
- je eretr04b
- jmp eretr03
-
- ;*--- If the swap back ends sucefully the swapfile is closed
-
- eretr04b:
- mov bx,handle
- mov ah,3Eh
- Int 21h
-
- jnc eretr05
-
- mov dx,offset eno_close
- call print
- call getkey
- jmp escape
-
- eretr05:
-
- ;*--- Just to be clean the swapfile is erased from the disk
-
- clc
-
- push cs
- pop ds
- mov dx,offset swapfile
- mov ah,41h
- Int 21h
-
- jnc escape
-
- mov dx,offset eno_erase
- call print
- call getkey
- jmp escape
-
- escape:
- ret
-
- dos_loader endp
-
- ;*-------------------------------------------------------------------*;
- ;* Wait for any key to be pressed *;
- ;*-------------------------------------------------------------------*;
-
- getkey proc near
-
- mov ah,1
- int 16h
- jne getkey1
- jmp getkey
-
- getkey1: mov ah,0
- int 16h
-
- ret
- getkey endp
-
-
- ;*-------------------------------------------------------------------*;
- ;* Save/Restore Screen *;
- ;*-------------------------------------------------------------------*;
-
- screen proc near
- cld
- mov bh,display_page
- mov ch,00
- mov cl,nrow
- mov dh,box_row
- row_loop:
- push cx
- mov cx,ncol
- mov dl,box_col
- col_loop:
- push cx
- mov ah,2
- int 10h
- cmp si,0FFFFh
- je do_save
- lodsw
- mov bl,ah
- mov ah,9
- mov cx,01
- int 10h
- jmp short do_loop
- do_save:
- mov ah,8
- int 10h
- stosw
-
- do_loop:
- inc dl
- pop cx
- loop col_loop
- pop cx
- inc dh
- loop row_loop
- ret
- screen endp
-
-
- ;*-------------------------------------------------------------------*;
- ;* Clear Screen and Set Color *;
- ;*-------------------------------------------------------------------*;
-
- clr_box proc near
- mov ax,0600h
- mov ch,box_row
- mov cl,box_col
- mov dh,box_row - 1
- add dh,nrow
- mov dl,box_col + ncol - 1
- mov bh,attribute
- int 10h
- ret
- clr_box endp
-
- ;*-------------------------------------------------------------------*;
- ;* New Disk BIOS Interrupt Handler *;
- ;*-------------------------------------------------------------------*;
-
- int_13 proc far
- assume ds:nothing,es:nothing
- mov cs:disk_status,1
- pushf
- call dword ptr cs:old_int_13
- mov cs:disk_status,0
- sti
- ret 2
- int_13 endp
-
- ;*-------------------------------------------------------------------*;
- ;* New Main DOS Interrupt Handler *;
- ;*-------------------------------------------------------------------*;
-
- int_21 proc far
- mov cs:lo_fn_flag,0
- cmp ah,0
- jne check
- mov ah,4Ch
- go_direct:
- jmp dword ptr cs:old_int_21
- check:
- cmp ah,0ch
- ja go_direct
- inc cs:lo_fn_flag
- pushf
- call dword ptr cs:old_int_21
- mov cs:lo_fn_flag,0
- ret 2
- int_21 endp
-
-
-
- ;*-------------------------------------------------------------------*;
- ;* Handler of process errors *;
- ;*-------------------------------------------------------------------*;
-
- memory_error proc near
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
- push ds
- push ax
-
- mov ax,cs
- mov ds,ax
-
- pop ax
-
- cmp ax,01h
- je err_mem_01h
- cmp ax,02h
- je err_mem_02h
- cmp ax,05h
- je err_mem_05h
- cmp ax,10
- je err_mem_10h
- cmp ax,11
- je err_mem_11h
- cmp ax,07h
- je err_mem_07h
- cmp ax,08h
- je err_mem_08h
- cmp ax,09h
- je err_mem_09h
- cmp ax,0ffh
- je err_mem_ffh
- err_mem_oth:
- mov dx,offset merrot
- call print
- jmp end_memory
-
- err_mem_07h:
- mov dx,offset merr07
- call print
- jmp end_memory
- err_mem_01h:
- mov dx,offset merr01
- call print
- jmp end_memory
- err_mem_02h:
- mov dx,offset merr02
- call print
- jmp end_memory
- err_mem_05h:
- mov dx,offset merr05
- call print
- jmp end_memory
- err_mem_10h:
- mov dx,offset merr10
- call print
- jmp end_memory
- err_mem_11h:
- mov dx,offset merr11
- call print
- jmp end_memory
-
- err_mem_08h:
- mov dx,offset merr08
- call print
- jmp end_memory
-
- err_mem_09h:
- mov dx,offset merr09
- call print
- jmp end_memory
-
- err_mem_ffh:
- mov dx,offset merrff
- call print
- jmp end_memory
-
- end_memory:
- call getkey ;Version 2.0
- pop ds
- ret
- memory_error endp
-
- ;*-------------------------------------------------------------------*;
- ;* Routine to convert from binary to ASCII (Hex Format) *;
- ;*-------------------------------------------------------------------*;
-
- L0154 proc near
-
- push cx
- mov cx,4
- mov ah,0
- rol ax,cl
- ror al,cl
-
- L015E: add al,30h;'0'
- cmp al,39h;'9'
- jle L0166
- add al,7
-
- L0166: cmp ch,0
- je L016D
- xchg al,ah
- pop cx
- ret
-
-
- L016D: mov ch,1
- xchg al,ah
- jmp L015E
-
- L0154 endp
-
- ;*-------------------------------------------------------------------*;
- ;* Print String - BIOS based version of Int 21h Fn=09h *;
- ;*-------------------------------------------------------------------*;
-
- print proc near
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
- push es
- push ds
- push ax
- push dx
- push si
- push bx
- push cx
- mov ax,dx
- mov si,ax
- mov ax,cs
- mov ds,ax
-
- print_loop:
- cmp byte ptr cs:[si],"$"
- je eprint
-
- mov ah,0Fh
- Push si
- Int 10h
- Pop si
-
- mov bl,00h
- mov al,byte ptr cs:[si]
- mov ah,0eh
-
- Push si
- Int 10h
- Pop si
-
- inc si
-
- jmp print_loop
- eprint:
- pop cx
- pop bx
- pop si
- pop dx
- pop ax
- pop ds
- pop es
- ret
- print endp
-
-
- ;*-------------------------------------------------------------------*;
- ;* Main Initialization code *;
- ;*-------------------------------------------------------------------*;
-
- initialize proc near
- assume cs:cseg,ds:cseg,es:nothing,ss:cseg
-
- ;*--- Set addresability & Display Copyright notice
-
- mov ax,cs
- mov ds,ax
- mov es,ax
-
- mov dx,offset copyright
- call print
-
- ;*--- Check if DOS version is greater than 2.00
-
- push es
- push ds
- mov ah,30h
- Int 21h
-
- cmp al,02h
- jge next_init
-
- ;*--- No, message error and terminate
-
- mov load_flag,0
- mov dx,offset wrong_dos
- call print
- pop ds
- pop es
- jmp no_load
-
- next_init:
- pop ds
- pop es
- mov word ptr [main+0],0
- mov word ptr [main+2],0
-
- ;*--- Search for copies of itself on DOS memory chain
-
- xor bx,bx
- mov ax,cs
- next_para:
- inc bx
- cmp ax,bx
- mov es,bx
- je end_search
- mov si,offset id
- mov di,si
- mov cx,id_len
- rep cmpsb
- or cx,cx
- jnz next_para
-
- ;*--- Another copy was founded, send message and prevent to load again
- ;*--- also, the segment in wich the previous copy was founded is saved
-
- mov load_flag,0
- mov ax,es
- mov curr_segm,ax
-
- mov dx,offset yet_loaded
- call print
- jmp get_parm
-
- end_search:
-
- ;*--- No another copy can be founded, prosecute installation
-
- mov load_flag,1
-
- ;*--- In ES is stored the current CS segment , save it
-
- mov ax,es
- mov curr_segm,ax
-
- ;*--- Now command parameters are inspected
-
-
- get_parm:
-
- ;*--- Point to first character of parameter area in the PSP
-
- mov si,81h
- push cs
- pop ds
-
- ;*--- Throw away if blank
-
- parse:
- cmp ds:byte ptr [si],32
- jne parse1
- inc si
- jmp parse
-
- ;*--- If first non-blank is carriage return the command area is empty
- ;*--- Load with default memory size of 4096 paragraphs
-
- parse1:
- cmp ds:byte ptr [si],cr
- jne parseus
- jmp locate_com
-
- ;*--- First non-blank is "/" or is an error
-
- parseus:
-
- cmp ds:byte ptr [si],2Fh
- je parnum
- jmp error_parm
-
- ;*--- Try to convert parameter from ASCII to binary
-
- parnum:
- push si
- inc si
- mov ax,si
- mov dx,ax
- mov ax,cs
- mov ds,ax
- call cnvd2h
- cmp ax,0000h
- je parsest
-
- ;*--- Sucefull conversion, the number is stored as a requested memory size
-
- lea di,size_area
- mov word ptr cs:[di],ax
- pop si
-
- ;*--- If there are another copy on memory try to change it workspace size
-
- cmp load_flag,1
- jne parsesi
-
- jmp locate_com
-
- ;*--- First check if it is inactive, this would ensure that there are no
- ;*--- workspace allocated to it
-
- parsesi:
- mov ax,curr_segm
- mov es,ax
- cmp es:dormant,01h
-
- je parses1
- jmp locate_com
- parses1:
-
- ;*--- The newest size area is stamped on the resident copy and the control
- ;*--- is transfered to the regular activation procedure
-
- mov ax,word ptr cs:size_area
- mov word ptr es:size_area,ax
- jmp activation
-
- ;*--- The parameter is in valid format but it is not a number
- ;*--- check if is one of /H,/U,/I,/E,/A or /?
-
- parsest:
-
- ;*--- Restore SI register just to clean up the stack
-
- pop si
-
- parse0:
-
- ;*--- Force UpperCase
-
- mov ah,ds:byte ptr [si+1]
- mov ar,ah
- and ds:byte ptr [si+1],0DFh
-
- ;*--- Is /E , Then is an External Swap indication
-
- cmp ds:word ptr [si],452Fh
- jne parse1b
- jmp set_ext
-
- ;*--- Is /H , Then is a Huge Mode indication
-
- parse1b:
- cmp ds:word ptr [si],482Fh
- jne parse1a
- jmp set_huge
-
- ;*--- Is /A , Then is an Activation Request
-
- parse1a:
- cmp ds:word ptr [si],412Fh
- jne parse2
- jmp activation
-
- ;*--- Is /U , Then is an UnInstall request
-
- parse2:
- cmp ds:word ptr [si],552Fh
- jne parse3
- jmp uninstall
-
- ;*--- Is /I , Then is an Inactivation request
-
- parse3:
- cmp ds:word ptr [si],492Fh
- jne parse4
- jmp inactivation
-
- ;*--- Is /? , Then display a help text
-
- parse4:
- mov ah,ar
- mov byte ptr ds:[si+1],ah
- cmp ds:word ptr [si],3F2Fh
- jne parse5
- jmp help
-
- ;*--- Is /C , Then search for filename
- parse5:
- and ds:byte ptr [si+1],0DFh
- cmp ds:word ptr [si],432Fh
- je user_spec
-
- mov dx,offset invalid_parm
- call print
- jmp locate_com
-
- ;*--- Establish huge mode (automatically set external swap mode)
-
- set_huge:
- mov byte ptr es:huge_mode,01h
-
- ;*--- Print message telling about the huge selection
-
- mov dx,offset huge_mode_msg
- call print
-
- ;*--- Save the position on the command line
-
- push si
-
- ;*--- Put a message telling about the Huge mode in the wakeup message
-
- lea di,es:type_msg
- lea si,es:huge_msg
- mov al,04h
- set_hugea:
- mov ah,byte ptr ds:[si]
- mov byte ptr ds:[di],ah
- inc si
- inc di
- dec al
-
- cmp al,00h
- jne set_hugea
-
- ;*--- Restore the position on the command line
-
- pop si
-
- jmp set_ext
-
-
- ;*--- get address of dos_command buffer & reset counter
-
- user_spec:
- mov di,offset dos_command
- mov byte ptr es:[di],00h
- push di
- xor ah,ah
- inc di
-
- ;*--- Transfer command line till the CR
-
- user_01:
- cmp byte ptr [si],cr
- je end_user
- mov al,byte ptr [si]
- mov es:byte ptr [di],al
- inc si
- inc di
- inc ah
- cmp byte ptr [si],"/"
- je end_user
- jmp user_01
-
- ;*--- Store correct values on flag,counter
-
- end_user:
- mov es:byte ptr [di],cr
- pop di
- mov es:byte ptr [di],ah
- mov ah,01h
- mov es:byte ptr command_flag,ah
- mov dx,offset user_file
- call print
- jmp parse
-
- ;*--- Display help text and exit without being resident
-
- help:
- mov dx,offset flash_help
- call print
- mov load_flag,0
- jmp no_load
-
- ;*--- Invalid parameter is given, display error and exit
-
- error_parm:
- mov dx,offset invalid_parm
- call print
- mov load_flag,0
- jmp no_load
-
- ;*--- Set external swap flag
-
- set_ext:
-
- mov ax,curr_segm
- mov es,ax
- mov byte ptr es:buffer_type,"E"
- mov dx,offset exter_stor
- call print
-
- inc si
- inc si
-
- push si
- push di
- push bx
-
- ;*--- If huge mode is active the message was already moved
-
- cmp byte ptr es:huge_mode,01h
- jz set_extb
-
- ;*--- Transfer the regular disk message
-
- lea di,es:type_msg
- lea si,es:disk_msg
- mov al,04h
- set_exta:
- mov ah,byte ptr ds:[si]
- mov byte ptr ds:[di],ah
- inc si
- inc di
- dec al
-
- cmp al,00h
- jne set_exta
-
- set_extb:
-
- ;*--- When the external mode is selected additional provisions must be taken
- ;*--- to ensure that any code in the swapped part IS NOT part of an
- ;*--- interruption.
- ;*--- The safest way is to save the interrupt status in this moment and
- ;*--- swap back and forth this one when Flashdos is invoked.
-
- push es
- mov ax,0000h
- mov es,ax
-
- mov si,0000h
- lea di,ds:old_int_area
- mov bx,1024
-
- reintnew:
- mov ah,byte ptr es:[si]
- mov byte ptr ds:[di],ah
- inc di
- inc si
- dec bx
-
- mov ax,bx
- cmp ax,0000h
- jne reintnew
-
- pop es
-
- pop bx
- pop di
- pop si
-
- jmp parse
-
- ;*--- Activation request
-
- activation:
- cmp load_flag,0
- je activ01
-
- ;*--- Cann't activate if it is not in memory
-
- mov dx,offset no_loaded
- call print
- mov load_flag,0
- jmp no_load
-
- ;*--- See if it is yet active
- activ01:
- mov ax,curr_segm
- mov es,ax
-
- cmp byte ptr es:dormant,0
- jne activ02
-
- ;*--- Is already active, you cann't active it again
-
- mov dx,offset yet_active
- call print
- mov load_flag,0
- jmp no_load
-
- ;*--- The program is resident and inactive, so active it
- ;*--- Program Owns all the memory, shrink it to a minimun if internal swap
-
- activ02:
-
- cmp es:buffer_type,"E"
- je activ05
-
- mov ax,cs
- mov bx,prog_len
- add bx,video_len
- push es
- mov es,ax
- mov ah,4Ah
- int 21h
- pop es
- jnc activ03
-
- call memory_error
- mov load_flag,1
- jmp no_load
-
- activ03:
-
- ;*--- Get workspace area, save the returned pointer for future use
-
- mov ax,cs
- mov ds,ax
- mov bx,es:size_area
- mov ah,48h
- push es
- Int 21h
- pop es
- jnc activ04
-
- call memory_error
- mov load_flag,1
- jmp no_load
-
- activ04:
-
- ;*--- The work memory was claimed suceffully store pointer
-
- mov word ptr es:ptr_area,ax
-
- ;*--- The memory claimed is under the property of the running FlashDOS and
- ;*--- not of the resident portion, some DOS memory block adjusting is in place
-
- push es
- push ds
-
- mov word ptr es:ptr_area,ax
- dec ax
- mov ds,ax
-
- assume ds:mem
-
- cmp ds:memtype,"M"
- jne act_mem_err
-
- mov ax,es
- mov ds:memid,ax
- pop ds
- pop es
-
- ;*--- Restablish addresability
-
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
-
- activ05:
-
- mov ax,cs
- mov ds,ax
-
- ;*--- Change active flag to active
-
- mov byte ptr es:dormant,0
-
- ;*--- Send message and exit
-
- mov dx,offset now_active
- call print
- mov load_flag,0
- jmp no_load
-
- ;*--- Display memory management problem and exit
-
- act_mem_err:
- mov ax,0ffh
- call memory_error
- mov load_flag,0
- jmp no_load
-
- ;*--- Inactivation Request
-
- inactivation:
- call set_inactive
- jmp no_load
-
- ;*--- UnInstall Request
-
- Uninstall:
- cmp load_flag,0
- je unins01
-
- ;*--- Cann't uninstall if it is not in memory
-
- mov dx,offset no_loaded
- call print
- mov load_flag,0
- jmp no_load
-
- ;*--- See if it is active or inactive
-
- unins01:
- mov ax,curr_segm
- mov es,ax
-
- cmp byte ptr es:dormant,0
-
- jne unins02
-
- ;*--- Cann't uninstall if it is not inactive
-
- push es
- call set_inactive
- pop es
-
- ;*--- Now, check if all interrupts trapped still pointing to myself
-
- unins02:
-
- ;*--- Interrupt 09h (Keyboard) is verified against resident segment
-
- push es
- mov ah,35h
- mov al,09h
- Int 21h
- mov bx,es
- pop es
- mov ax,es
- cmp bx,ax
- je int09_ok
-
- ;*--- Is different, cann't uninstall
-
- mov dx,offset wrong_int09
- call print
- mov load_flag,0
- jmp no_load
- int09_ok:
-
- ;*--- Interrupt 13h (BIOS Disk) is verified against resident segment
-
- push es
- mov ah,35h
- mov al,13h
- Int 21h
- mov bx,es
- pop es
- mov ax,es
- cmp bx,ax
- je int13_ok
-
- ;*--- Is different, cann't uninstall
-
- mov dx,offset wrong_int13
- call print
- mov load_flag,0
- jmp no_load
- int13_ok:
-
- ;*--- Interrupt 21h (DOS Function) is verified against resident segment
-
- push es
- mov ah,35h
- mov al,21h
- Int 21h
- mov bx,es
- pop es
- mov ax,es
- cmp bx,ax
- je int21_ok
-
- ;*--- Is different, cann't uninstall
-
- mov dx,offset wrong_int21
- call print
- mov load_flag,0
- jmp no_load
- int21_ok:
-
- ;*--- All trapped interrupts belong to FlashDOS so restore old values
-
- ;*--- Restore Int09h
-
- push es
- lds dx,es:old_int_9
- mov ah,25h
- mov al,09h
- Int 21h
- pop es
-
- ;*--- Restore Int13h
-
- push es
- lds dx,es:old_int_13
- mov ah,25h
- mov al,13h
- Int 21h
- pop es
-
- ;*--- Restore Int21h
-
- push es
- lds dx,es:old_int_21
- mov ah,25h
- mov al,21h
- Int 21h
- pop es
-
- ;*--- Corrupt the signature, otherwise another try to load FlashDOS would fail
-
- xor ax,ax
- mov es:id,al
-
- ;*--- Now resident FlashDOS is a dead memory zone, release environment
-
- push es
- mov ax,word ptr es:2Ch
- mov es,ax
- mov ah,49h
- Int 21h
- pop es
-
- ;*--- Release resident program itself
-
- push es
- mov ah,49h
- Int 21h
- pop es
-
- ;*--- Uninstallation complete, display a message
-
- mov dx,offset now_uninstall
- call print
- mov load_flag,0
- jmp no_load
-
- ;*--- Get the current COMMAND.COM path from the Environment Block
-
- locate_com:
-
- ;*--- Check if there are another copy in memory
-
- cmp load_flag,0
- jne loc_com
- jmp no_load
-
- ;*--- Inspect environment area
-
- loc_com:
- push es
- mov ax,word ptr cs:2Ch
- mov es,ax
- mov ax,offset env_var
- mov si,ax
- mov cx,env_var_len
-
- call Get_Env_Str
-
-
- cmp al,00h
- jne no_comm_found
- mov ax,offset comspec_path
- mov si,ax
-
- locate_loop:
-
- mov al,byte ptr es:[di]
- cmp al,00h
- je end_locate
-
- mov byte ptr cs:[si],al
- inc si
- inc di
- jmp locate_loop
-
-
- end_locate:
-
- mov byte ptr cs:[si],al
-
- ;*--- No 'COMSPEC' variable can be found in the environment
-
- no_comm_found:
-
- pop es
-
- continue:
-
- ;*--- Program Owns all the memory, shrink it to a minimun
-
-
- mov ax,cs
- mov es,ax
- mov bx,prog_len
- add bx,video_len
- mov ah,4Ah
- int 21h
- jnc cont01
-
- call memory_error
- mov load_flag,1
- jmp no_load
-
- cont01:
-
- ;*--- If internal get workspace area, save the returned pointer for future use
-
- cmp buffer_type,"E"
- je cont02b
-
- mov ax,cs
- mov ds,ax
- mov bx,size_area
- mov ah,48h
- Int 21h
- jnc cont02
-
- call memory_error
- mov load_flag,1
- jmp no_load
-
- cont02:
- mov word ptr cs:ptr_area,ax
-
- ;*--- Get the DOS Critical Flag Address (Undocumented)
-
- cont02b:
-
- mov ah,34h
- int 21h
- mov word ptr dos_flag[0],bx
- mov word ptr dos_flag[2],es
-
- ;*--- Trap Int 09h, 10h and 21h
-
- push ds
- pop es
-
- mov al,9
- mov di,offset old_int_9
- mov dx,offset int_9
- call set_int
-
- mov al,13h
- mov di,offset old_int_13
- mov dx,offset int_13
- call set_int
-
- mov al,21h
- mov di,offset old_int_21
- mov dx,offset int_21
- call set_int
-
- ;*--- Main initializacion job done, so print message
-
- mov dx,offset loaded_ok
- call print
-
- ;*--- Get pointer to workspace and convert binary to ASCII, print it.
-
- cmp buffer_type,"E"
- je cont03a
-
- mov ax,word ptr cs:ptr_area
- call L0154
- mov MSBH,ah
- mov MSBL,al
- mov ax,ptr_area
- mov al,ah
- call L0154
- mov LSBH,ah
- mov LSBL,al
-
- mov dx,offset mem_ptr
- call print
-
- ;*--- Get workspace size in paragraphs and convert binary to ASCII, print it.
-
- cont03a:
- ;*--- If it is on huge mode the workspace size doesn't matter.
-
- cmp byte ptr cs:huge_mode,01h
- jz tsr_pgm
-
- mov ax,word ptr cs:size_area
- call L0154
- mov MMSBH,ah
- mov MMSBL,al
- mov ax,size_area
- mov al,ah
- call L0154
- mov MLSBH,ah
- mov MLSBL,al
-
- mov dx,offset mem_size
- call print
-
-
- ;*--- Terminate and Stay Resident
-
- tsr_pgm:
- mov dx,prog_len
- add dx,video_len
- mov ax,3100h
- int 21h
-
- ;*--- Procedure to avoid to keep as a TSR
-
- no_load:
- mov dx,offset not_loaded
- call print
-
- mov al,04h
- mov ah,4ch
- Int 21h
-
- initialize endp
-
- ;*-------------------------------------------------------------------*;
- ;* Routine to Trap current interrupt and set the own one *;
- ;*-------------------------------------------------------------------*;
-
- set_int proc near
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
- push ax
- mov ah,35h
- int 21h
- mov word ptr [di+0],bx
- mov word ptr [di+2],es
- pop ax
- mov ah,25h
- int 21h
-
- ret
- set_int endp
-
- ;*-------------------------------------------------------------------*;
- ;*GET_ENV_STR procedure to find a string in the environment *;
- ;*Input: ES pointer to environment *;
- ;* SI pointer to variable to find plus equals sign *;
- ;* CX length of variable including equals sign *;
- ;*Output: DI pointer to start of value of variable, if AL=0 *;
- ;* AL 0 if string found, 1 if not *;
- ;* ES,SI,CX unchanged *;
- ;*Borrowed from ENVPTR Package by Jeff Urs from PCTOOLS *;
- ;*-------------------------------------------------------------------*;
-
- Get_Env_Str: Sub DI,DI
- Cld
-
- End_Check: Cmp Byte Ptr ES:[DI],00
- Jne Check_Str
- Mov AL,1
- Jmp Short Get_Env_End
-
- Check_Str: Push SI
- Push CX
- Repe Cmpsb
- Pop CX
- Pop SI
- Jne Next_Str
- Xor AL,AL
- Jmp Short Get_Env_End
-
- Next_Str: Xor AL,AL
- Push CX
- Mov CX,8000H
- Repne Scasb
- Pop CX
- Jmp End_Check
- ;
- Get_Env_End: Ret
-
- ;*-------------------------------------------------------------------*;
- ;* CNVD2H: This routine will convert a decimal string into a hex-*;
- ;* adecimal word value. The user passes a pointer to a string *;
- ;* containing a value between -32768 and 65535. *;
- ;* *;
- ;* INPUT: DS:DX - number string to convert *;
- ;* OUTPUT: AX - output value *;
- ;* *;
- ;* All registers are preserved except AX. *;
- ;* *;
- ;* Written by G. R. Ingalls - 4/29/87 *;
- ;*-------------------------------------------------------------------*;
-
- cnvd2h proc near
-
- ;*--- Save Registers
-
- push bx
- push cx
- push dx
- push es
- push di
- push si
-
- ;*--- Scan charater string to be converted
-
- mov si,dx
- mov bl,1
-
- get_sign:
-
- ;*--- Check for first non-blank character
-
- lodsb
- cmp al,' '
- je get_sign
-
- ;*--- If a sign is founded (+ or -) save it
-
- cmp al,'+'
- jne chk_minus_sign
- jmp got_sign
-
- chk_minus_sign:
-
- cmp al,'-'
- jne no_sign
- mov bl,-1
- jmp got_sign
-
- no_sign:
-
- ;*--- Restore character pointer
-
- dec si
-
- got_sign:
- push bx
-
- ;*--- For each numeric character add it to the result, stop at first non num
- ;*--- Clear CX to store results
-
- xor cx,cx
-
- next_character:
-
- lodsb
-
- ;*--- Check if it is numeric value
-
- cmp al,'0'
- jb not_numeric
- cmp al,'9'
- ja not_numeric
-
- ;*--- Convert to binary
-
- sub al,'0'
- cbw
- xchg ax,cx
- mov bx,10
- mul bx
-
- ;*--- Add to counter
-
- add ax,cx
- xchg ax,cx
- jmp next_character
-
- not_numeric:
-
- ;*--- Set the proper sign ;
-
- pop bx
- cmp bl,-1
- jne not_negative
- neg cx
-
- not_negative:
-
-
- ;*--- Put result in AX and exit ;
-
- mov ax,cx
-
- pop si
- pop di
- pop es
- pop dx
- pop cx
- pop bx
- ret
-
- cnvd2h endp
-
-
- ;*-------------------------------------------------------------------*;
- ;* Proc to inactivate the program, shared by inactive and uninstall *;
- ;*-------------------------------------------------------------------*;
-
- set_inactive proc near
-
- cmp load_flag,0
- je inact01
-
- ;*--- Cann't inactivate if it is not in memory
-
- mov dx,offset no_loaded
- call print
- mov load_flag,0
- ret
-
- ;*--- See if it is yet inactive
-
- Inact01:
- mov ax,curr_segm
- mov es,ax
-
- cmp byte ptr es:dormant,1
- jne Inact02
-
- ;*--- Is already inactive, you cann't inactive it again
-
- mov dx,offset yet_inactive
- call print
- mov load_flag,0
- ret
-
- ;*--- Is resident and active, inactive and freed memory buffer
-
- Inact02:
- mov byte ptr es:dormant,1
-
- ;*--- If external swap is required don't mess with the memory
-
- cmp es:buffer_type,"E"
- je inact03
-
- ;*--- Get pointer to workspace area
-
- mov ax,word ptr es:ptr_area
-
- ;*--- Freed up reserved workspace area
-
- mov es,ax
- mov ah,49h
- Int 21h
-
- ;*--- OK, display message and end
-
- jc cannt_inactive
-
- inact03:
-
- mov dx,offset now_inactive
- call print
- mov load_flag,0
- ret
-
- ;*--- Something wrongs occurs, FlashDOS cann't free up the memory
-
- cannt_inactive:
-
- call memory_error
- mov byte ptr es:dormant,0
- mov load_flag,0
- ret
-
- set_inactive endp
-
- ;*-------------------------------------------------------------------*;
- ;* Messages and variables used during initialization process only *;
- ;*-------------------------------------------------------------------*;
-
- curr_segm dw ?
- not_loaded db cr,lf
- db "FlashDOS: Not Loaded",cr,lf,"$"
- loaded_ok db cr,lf
- db "FlashDOS: Loaded sucefully",cr,lf,"$"
- yet_loaded db cr,lf
- db "FlashDOS: Already Loaded",cr,lf,"$"
- yet_active db cr,lf
- db "FlashDOS: Already Active",cr,lf,"$"
- yet_inactive db cr,lf
- db "FlashDOS: Already Inactive",cr,lf,"$"
- now_active db cr,lf
- db "FlashDOS: Now Active",cr,lf,"$"
- exter_stor db cr,lf
- db "FlashDOS: External Storage Selected",cr,lf,"$"
- now_uninstall db cr,lf
- db "FlashDOS: Uninstalled sucefully",cr,lf,"$"
- mem_ptr db cr,lf,"FlashDOS: Memory area allocated at "
- LSBH db "0"
- LSBL db "0"
- MSBH db "0"
- MSBL db "0"
- db ":0000h",cr,lf,"$"
-
- mem_size db cr,lf,"FlashDOS: Memory size "
- MLSBH db "0"
- MLSBL db "0"
- MMSBH db "0"
- MMSBL db "0"
- db "h Paragraphs",cr,lf,"$"
- copyright db cr,lf
- db "╔══════════════════════════╗",cr,lf
- db "║FlashDOS V2.1 by P.E.Colla║",cr,lf
- db "║ IBM Internal Use Only ║",cr,lf
- db "║ DOS Switch ║",cr,lf
- db "║ COLLA @ MARVM1 ║",cr,lf
- db "║Press Alt-Backspace to Pop║",cr,lf
- db "╚══════════════════════════╝",cr,lf
- db "$"
- huge_mode_msg db cr,lf
- db "FlashDOS: Huge Mode Selected",cr,lf,"$"
- user_file db cr,lf
- db "FlashDOS: User File Defined",cr,lf,"$"
- wrong_dos db cr,lf
- db "FlashDOS: Incorrect DOS Level",cr,lf,"$"
- wrong_int09 db cr,lf
- db "FlashDOS: Unable to restore Int 09h.",cr,lf,"$"
- wrong_int13 db cr,lf
- db "FlashDOS: Unable to restore Int 13h.",cr,lf,"$"
- wrong_int21 db cr,lf
- db "FlashDOS: Unable to restore Int 21h.",cr,lf,"$"
- must_inactive db cr,lf
- db "FlashDOS: Must be inactive to Uninstall",cr,lf,"$"
- no_loaded db cr,lf
- db "FlashDOS: Not previously loaded.",cr,lf,"$"
- invalid_parm db cr,lf
- db "FlashDOS: Incorrect parameter, type FlashDOS /?"
- db " for help.",cr,lf,"$"
- flash_help db cr,lf
- db " FlashDOS Version 2.1 by P.E.Colla 1988 ",cr,lf
- db "This program start a secondary DOS command",cr,lf
- db "processor from inside another application.",cr,lf
- db "Using it you can manage a limited kind of ",cr,lf
- db "multitasking. At loading time the user must",cr,lf
- db "specify if memory or disk swap is desired.",cr,lf
- db "To invoke them type: ",cr,lf
- db " FLASHDOS /{Switch} ",cr,lf
- db "Valid Switches values are: ",cr,lf
- db " /? Help ",cr,lf
- db " /E Swap to disk ",cr,lf
- db " /I Inactive Request (Shrink Memory)",cr,lf
- db " /A Active Request (Growth memory) ",cr,lf
- db " /U Un-Install (became /I if cann't)",cr,lf
- db " /H Active Huge Mode ",cr,lf
- db " /C Pgm Install Program as a TSR ",cr,lf
- db " /99999 Size in paragraphs of internal ",cr,lf
- db " memory area (default 64k bytes)",cr,lf
- db "The program will not PopUp when you are on",cr,lf
- db "graphics video mode or at DOS prompt. ",cr,lf
- db " COLLA @ MARVM1 ",cr,lf
- db "$"
-
- ar db ?
- free db "#"
- cseg ends
- end main
-
-