options.asm
来自「比dos下的debug更好的debug程序源码」· 汇编 代码 · 共 505 行
ASM
505 行
;
; GRDP
;
; Copyright(c) LADsoft
;
; David Lindauer, camille@bluegrass.net
;
;
; OPTIONS.ASM.ASM
;
; Function: Option input and display
;
;MASM MODE
.MODEL SMALL
.386p
NUMOPTS = 11
include iversion.inc
include eprints.inc
include einput.inc
include emtrap.inc
include ebreaks.inc
include eints.inc
include elogging.inc
; define the symbol RAWA20 to run flat real mode with XMS
;
PUBLIC doopt,optdword, optdwordcommand,optpure,opthist, optflat0, optsignedimm
PUBLIC Disassemble32Bit, optdiv0, winshellchk
PUBLIC initflatreal, rundownflatreal, optdosio
PUBLIC ReadOptions, WriteOptions
.data
;
; gdt for flat real mode
;
gdt db 8 DUP (0) ;null entry SEL 0
db 0ffh,0ffh,0,0,0,92h,0cfh,0 ;32-bit dseg SEL 8h
db 0ffh,0ffh,0,0,0,92h,0,0 ;16-bit dseg SEL 10h
gdtp dw 3 DUP (17h) ;sice of gdt and its pointer
oldgdt db 6 DUP (?) ;their GDT
;
; optlist, optvals, and optvect MUST be kept in sync
;
optlst db "wrfr32zrbknvfif0sohimd"
oldflat0 db 0 ; echoes flat0 option so we can leave segs alone
; on successive ?o if they change them
;
writeopts db 0 ;true if options have changed
;
optmark dw verid ; MUST preced optvals
optvals label BYTE
optdword db 1 ;flag if user selected 32-bit registers (WR)
optdwordcommand db 0 ;flag if user wants flat real mode (FR)
Disassemble32Bit db 1 ;32-bit instructions enabled
TRUE equ 1
FALSE equ 0
optdiv0 db 1 ; these two options DEPEND on VECTLIST
optbrk db 1 ; having the upper bits of the ints set right
; on a no-param file start
optpure db 1 ;native video
optflatinit db 1 ;causes init for flat real mode
optflat0 db 0 ; flat real mode - default segs to zero
optsignedimm db 0 ; set if want to see signed immediates on u command
opthist db 1 ;flag if user enabled history
optdosio db 0 ; flag if using dos for command I/O
;
optvect dw vsetopt,vsetopt,vsetopt
dw voptdiv0,voptbrk1b,vsetopt,vsetopt,vsetopt,vsetopt,vsetopt
dw vsetopt
optname db "grdb.opt",0
.CODE
;
; for display of states
;
optmsgs label BYTE
db 13,10,"WR - wide registers ",0
db 13,10,"FR - flat real commands ",0
db 13,10,"32 - 32 bit disassembly ",0
db 13,10,"ZR - divide by zero trap",0
db 13,10,"BK - ctrl-break trap ",0
db 13,10,"NV - native video ",0
db 13,10,"FI - flat real autoinit ",0
db 13,10,"F0 - flat real 0 default",0
db 13,10,"SO - signed immediates ",0
db 13,10,"HI - command history ",0
db 13,10,"MD - msdos I/O ",0
;
; check for windows shell
;
winshellchk PROC
push si
mov ax,1600h ; check for windows func
int 2fh ; multiplex int
pop si
cmp al,00h ; windows not installed if = 0
je nowin
cmp al,80h ; xms (but no windows) if = 80 h
je nowin
pop ax ; anything else is windowsxx, drop ret addr
PRINT_MESSAGE <10,13,"Feature inactive in windows shells">
clc
nowin:
ret
winshellchk ENDP
ifdef RAWA20
;
; Routine to wait till KB controller not busy
;
kb_busy proc
xor cx,cx ; Loop 65536 times
kb_bs2:
in al,64h ; Get status
jmp $+2
jmp $+2
test al,2 ; See if busy
jz kb_busy_done ; Not busy any more
loop kb_bs2
stc
ret
kb_busy_done:
clc
ret
kb_busy endp
;
; Routine to wait till KB data buffer empty
;
kb_writewait proc
xor cx,cx ; Loop 65536 times
kb_rd2:
in al,64h ; Get port status
test al,2 ;
jz short kb_writewait_done ; Quit if buffer empty
loop kb_rd2 ; Wait a while
stc ; Error
ret
kb_writewait_done:
clc
ret
kb_writewait endp
;
; Routine to wait till KB data buffer fll
;
kb_readwait proc
xor cx,cx ; Loop 65536 times
kb_rdrd2:
in al,64h ; Get port status
test al,1 ;
jnz short kb_readwait_done ; Quit if buffer empty
loop kb_rdrd2 ; Wait a while
stc ; Error
ret
kb_readwait_done:
mov cx,32 ; Wait for controller to set data
delay:
jmp $+2
jmp $+2
loop delay ;
clc
ret
kb_readwait endp
;
; Routine to turn on A20 line
;
seta20 proc
cli ; Don't want a keypress now!
call kb_busy ; Wait while busy
jc short error ;
mov al,0d0h ; Command to get port status
out 64h,al ;
call kb_busy ; Wait while busy
jc short error
call kb_readwait ; Wait for it to put the char there
jc short error
in al,60h ; Get the data
or al,2 ; Set the A20 bit
xchg al,ah ; Data to ah
call kb_busy ; Wait while busy
jc short error
mov al,0d1h ; Command to put port status
out 64h,al ;
call kb_busy ; Wait while busy
jc short error
call kb_writewait ; Wait for buffer to empty
jc short error
mov al,ah ; Write the data
out 60h,al ;
clc ; No erros
error:
sti ; Keys allowed now
ret
seta20 endp
endif ; RAWA20
;
;
; init flat real mode
;
initflatreal PROC
test [optdwordcommand],1 ;check if can init
jz ifrx
test [optflatinit],1
jz ifrx
smsw ax ; test if in a shell
test ax,1
jnz ifr_err ; err if so
ifdef RAWA20
call seta20 ; same as XMS global alloc
else
mov ax,4300h ; now see if XMS loaded
int 2fh
cmp al,80h
jnz ifr_err ; err if not
push es
mov ax,4310h ; get xms driver address
int 2fh
push es ; put on stack
push bx
mov ax,300h ; now global enable HMA
call dword ptr [esp] ;
pop eax ; clear stack
pop es
; at this point we don't check XMS
; return stat as it always works :)
endif
sub eax,eax
mov ax,ds
shl eax,4
mov bx,offset gdt
movzx ebx,bx
add eax,ebx
mov dword ptr [gdtp+2],eax ;save old gdt
push ds
push es
sgdt fword ptr [oldgdt] ;get our gdt
lgdt fword ptr [gdtp] ;flat real mode in FS
mov eax,CR0
inc eax
mov CR0,EAX
mov bx,8
mov ds,bx
mov es,bx
mov fs,bx
dec eax ; back to real mode
mov CR0,eax
lgdt fword ptr [oldgdt] ;reload their GDT
pop es
pop ds
test [optflat0],1
jz ifrx2
test [oldflat0],1
jnz ifrx2
mov [RegdumpDS],0
mov [RegdumpES],0
mov [RegdumpFS],0
mov [RegdumpGS],0
; leaves SS and CS alone so we can run programs :).
ifrx2:
mov al,[optflat0]
mov [oldflat0],al
ifrx:
ret
ifr_err:
PRINT_MESSAGE <13,10,"Error: in DOS shell or XMS not available">
mov [optflatinit],0
ret
initflatreal ENDP
;
; reset descriptors for real mode
;
rundownflatreal PROC
test [optdwordcommand],1 ;check if can init
jz rfrx
test [optflatinit],1
jz rfrx
;
; we don't have to do lots of checking as the flatinit flag would have
; been cleared if we couldn't make the first transition...
;
push ds
push es
sgdt fword ptr [oldgdt] ;get our gdt
lgdt fword ptr [gdtp] ;flat real mode in FS
mov eax,CR0
inc eax
mov CR0,EAX
mov bx,16
mov ds,bx
mov es,bx
mov fs,bx
dec eax ; back to real mode
mov CR0,eax
lgdt fword ptr [oldgdt] ;reload their GDT
pop es
pop ds
rfrx:
ret
rundownflatreal ENDP
;
; option command
;
doopt PROC
Call WadeSpace ; Wade till address
jnz optlp
mov si,offset _text : optmsgs ; no args, print all options
mov di,offset optvals
mov cx,NUMOPTS
polp:
call PrintOption
loop polp
call LoggingStat
call initflatreal
optxit:
clc
ret
;
; subroutine to print an option and its enabled/disabled value
;
PrintOption:
mov bx,si
call olMessage
test byte ptr [di],-1
jnz dotype
PRINT_MESSAGE <9,"disabled">
jmp dojoin
dotype:
PRINT_MESSAGE <9,"enabled">
dojoin:
inc di
frs_lp:
lods byte ptr cs:[si]
or al,al
jnz frs_lp
ret
;
; comes here to set/reset an option
;
optlp:
cmp al,13
je doopt ; go back and show vals after the set
cmp al,'-' ; check for off command
pushf
jz incpos
cmp al,'+'
jne noinc
incpos:
inc si
noinc:
call WadeSpace ; now get the option letters
jz opterr
lodsw
cmp ah,13
je opterr
mov cx,NUMOPTS ; search for them
mov di,offset optlst
cmplp:
scasw
jz dovect
loop cmplp
opterr:
add sp,2 ; bad opt, exit with no display
clc
ret
dovect:
mov [writeopts],1 ; changing, need disk update
neg cx
add cx,NUMOPTS
movzx ebx,cx
popf
lahf
and ah,40h
xor ah,40h
shr ah,6 ; ah = opt new val
call [optvect + ebx*2] ; call handler
call WadeSpace
jmp optlp ; get another
doopt ENDP
;
; option routines
;
; this one is for basic bools
;
vsetopt PROC
mov [bx + optvals],ah
ret
vsetopt ENDP
;
; following this we have interrupt enables/disables.
; they run through VECLIST and set the high bit to match the
; bool value
;
voptbrk1b PROC
mov al,1bh
jmp vopttraps
voptbrk1b ENDP
voptdiv0 PROC
mov al,0
voptdiv0 ENDP
vopttraps PROC
mov [bx + optvals],ah
mov bl,ah
vopttraps ENDP
voptrefresh PROC
push si
mov si,offset veclist
call SetVectAttrib
pop si
ret
voptrefresh ENDP
;
; write options to disk file
;
WriteOptions PROC
IFDEF OPTION_EN
mov [optmark],verid
test [writeopts],0ffh
jz wo_x
call optcreat
jc wo_x
mov dx,offset optmark
mov cx,NUMOPTS+2
mov ah,40h
int 21h
jc wo_x2
mov [writeopts],0
wo_x2:
call optclose
wo_x:
ENDIF
ret
WriteOptions ENDP
;
; read options from disk file
;
ReadOptions PROC
IFDEF OPTION_EN
mov [writeopts],1
mov [optmark],-1
call optopen
jc ro_x
mov dx,offset optmark
mov cx,2
mov ah,3fh
int 21h
jc ro_x2
cmp [optmark],verid
jne ro_x2
mov dx,offset optmark+2
mov cx,NUMOPTS
mov ah,3fh
int 21h
jc ro_x2
cmp ax,NUMOPTS
jne ro_x2
push bx
mov [writeopts],0 ; the option file is read
mov bl,[optdiv0] ; now set the attrib bits in veclist
mov al,0
call voptRefresh
mov bl,[optbrk]
mov al,1bh
call voptRefresh
call initflatreal
pop bx
nd1bfix:
ro_x2:
call optclose
ro_x:
ENDIF
ret
ReadOptions ENDP
IFDEF OPTION_EN
;
; generi disk file stuff. Should probably merge with loader and logger
; routines...
;
OptOpen PROC
mov ax,3d02h
mov dx,offset optname
int 21h
mov bx,ax
ret
OptOpen ENDP
OptCreat PROC
mov ax,3c00h
mov cx,0
mov dx,offset optname
int 21h
mov bx,ax
ret
OptCreat ENDP
OptClose PROC
mov ah,3eh
int 21h
ret
OptClose ENDP
ENDIF
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?