dosstart.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 278 行
ASM
278 行
extrn SaveSave_ : far
extrn StringIn_ : near
extrn InitRetrieve_ : near
extrn _edata : byte ; end of DATA (start of BSS)
extrn _end : byte ; end of BSS (start of STACK)
fard segment para public 'far_data'
fard ends
_TEXT segment para public 'code'
_data segment para public 'data'
stk db 512 dup(?)
top db 0
l_in db 0,0
l_out db 0,0
alias_file db "\ALIAS.DOS",0
_data ends
const segment para public 'data'
const ends
stack segment para stack 'stack'
db 512 dup (?)
stack ends
dgroup group _data,const,stack
assume cs:_TEXT,ds:_TEXT,ss:_TEXT,es:_TEXT
dosedit proc far
jmp start
canfind db "Program is already loaded$"
cantfind db "Cannot locate previous version$"
savesp dw 0
savess dw 0
string_in dw 5
SIGNATURE equ 0CED1H
NEWSIGOFF equ -14H
newsig dw SIGNATURE
SAVESAVEOFF equ -12H
savesave dd SaveSave_
MYDSOFF equ -0EH
saveds dw 0
ALIASOFF equ -0CH
public _AliasList
_AliasList dw 0,0
INT21OFFOFF equ -08H
int21off dw 0
INT21SEGOFF equ -06H
int21seg dw 0
MYPSPOFF equ -04H
mypsp dw 0
SIGOFF equ -02H
sig dw SIGNATURE
int21 proc near
cmp ah,0AH ; is Buffered kbd input call?
jne short old ; no ... bop off to old 21 hdlr
push ax ; save regs
push dx ; ...
push bx ; ...
push cx ; ...
mov bx,0 ; handle is stdin
mov ax,4400H ; get handle information
int 21H ; ...
test dx,80H ; see if this is console input
pop cx ; restore regs
pop bx ; ...
pop dx ; ...
pop ax ; ...
je short old ; don't bother if not console
sti ; interrupts back on
push di ; save some regs
mov di,sp ; point at parms
push bp
push es
push si ; ...
push ax ; ...
push bx ; ...
push cx ; ...
push dx ; ...
push ds ; ...
push ds ; save pointer at buffer
push dx ; ...
mov ah,051H ; - get psp of current process
int 021H ; - ...
; mov ds,bx ; - point at processes psp
; cmp bx,ds:[02CH] ; - if environment area < psp
cmp bx,cs:mypsp ; - if running psp >= cmdedit psp
jb short else1 ; - - ...
mov di,0 ; - - no aliases
jmp short endif1 ; - else
else1: mov di,1 ; - - do aliases
endif1: ; - endif
pop si ; restore buffer pointer
pop ds ; ...
lea ax,2[si] ; point at buffer + 2
mov dx,ds ; ...
mov cl,[si] ; set input length to stringin
mov byte ptr cs:l_in,cl ; ...
mov cx,dgroup ; point at length struct
mov bx,offset dgroup:l_in ; ...
push si ; save buffer pointer
mov bp,sp ; ...
mov si,ss ; ...
mov ss,cx ; ...
mov sp,offset dgroup:top ; ...
push ds ; save ds
mov es,cs:string_in ; push requested routine num
push es ; ...
mov ds,cx ; point it at our data segment
push di ; do aliasing?
call StringIn_ ; command line edit
pop ds ; reset ds
mov ss,si ; point to old stack
mov sp,bp ; ...
pop si ; restore buffer pointer
mov cl,cs:l_out ; set length gotten in buffer
mov byte ptr 1[si],cl ; put length gotten in buffer
done: pop ds ; restore some regs
pop dx ; restore some regs
pop cx ; ...
pop bx ; ...
pop ax ; ...
pop si ; ...
pop es
pop bp
pop di ; ...
mov al,0 ; Why? I dunno
iret
old: jmp dword ptr cs:int21off
int21 endp
main proc near
notin: lea dx,cantfind
jmp short putmsg
alreadyin: lea dx,canfind
putmsg:
push cs
pop ds
mov ah,9
int 21H
jmp exit
start:
mov dx,es ; save pointer to PSP
mov ax,0 ; point to interrupt tables
mov ds,ax ; ...
mov di,080H ; ...
mov cl,es:[di] ; pick up parm length
xor ch,ch ; do
again: inc di ; - ++parm
dec cx ; - --length
cmp byte ptr es:[di],' ' ; while( *parm == ' ' )
je short again ; ...
inc cx ; ++length
cmp byte ptr es:[di],'-' ; if - option
jne short install ; - then
not_a: cmp byte ptr es:1[di],'q' ; - ...
je short kickout ; - ...
cmp byte ptr es:1[di],'Q' ; - ...
jne short install
kickout:
cli ; interrupt off for a second
mov dx,es ; save the command line
mov ax,di ; ...
les bx,ds:[84h] ; pick up old int21 hdlr
push es ; - ...
cmp word ptr es:SIGOFF[bx],SIGNATURE; if already in memory
jne short notin ; - then
mov di,es:INT21OFFOFF[bx] ; - restore int21
mov ds:[84h],di ; - ...
mov di,es:INT21SEGOFF[bx] ; - restore int21
mov ds:[86h],di ; - ...
cmp word ptr es:NEWSIGOFF[bx],SIGNATURE; if not old style
jne short oldstyle ; - - then
mov ds,es:MYDSOFF[bx] ; - - set up ds
mov si,ss ; - - save stack
mov di,sp ; - - ...
mov ss,es:MYDSOFF[bx] ; - - set new stack
mov sp,offset dgroup:top ; - - ...
call dword ptr es:SAVESAVEOFF[bx]; save saved commands
mov ss,si ; - - restore stack
mov sp,di ; - - ...
oldstyle: sti
pop ds ; - ...
cmp word ptr ds:ALIASOFF+2[bx],0; if there are aliases
je short noalias ; - - then
mov es,ds:ALIASOFF+2[bx] ; - - free up aliases
mov ah,49H ; - -
int 21H ; - - ...
noalias: mov es,ds:MYPSPOFF[bx] ; - free up code
mov ah,49H ; - prepare to free up memory
int 21H ; - ...
exit: ; - endif
mov al,0 ; - terminate
mov ah,4CH ; - ...
int 21H ; - ...
; endif
install:
cli ; interrupt off for a second
les bx,ds:[84h] ; pick up old int21 hdlr
cmp word ptr es:SIGOFF[bx],SIGNATURE; if already in memory
jne notalready ; - then
jmp alreadyin ; - then
notalready:
mov cs:int21off,bx ; save old handler
mov cs:int21seg,es ; ...
mov word ptr ds:[84h],offset _TEXT:int21; set new handler
mov ds:[86h],cs ; ...
sti ; interrupts back on
mov cs:mypsp,dx ; save our PSP
mov es,dx ; restore pointer to PSP
mov bx,di ; get pointer to end of parm
add bx,cx ; ...
mov byte ptr es:[bx],0 ; store a null character
mov bx,dgroup ; set up stack
mov cs:saveds,bx
mov ss,bx ; ...
mov sp,offset dgroup:top ; ...
;
; initialize bss to 0
;
push di
push ax
push es
mov ax,DGROUP
mov es,ax
mov cx,offset DGROUP:_end
mov di,offset DGROUP:_edata
sub cx,di
mov al,0
rep stosb
pop es
pop ax
pop di
mov ds,bx ; point ds to PSP
mov bx,offset dgroup:_end ; calculate memory size needed
mov cl,4 ; ...
shr bx,cl ; ...
add bx,dgroup ; ...
mov cx,es ; ...
sub bx,cx ; ...
mov cl,4 ; ...
inc bx ; ...
mov ah,4AH ; setblock
int 21H ; ...
mov ax,di ; ...
call InitRetrieve_ ; initialize
mov al,0 ; terminate and stay resident
mov ah,31H ; ...
mov dx,bx ; ...
int 21H ; ...
main endp
dosedit endp
_TEXT ends
end dosedit
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?