📄 genercfg.a86
字号:
mov byte ptr [si],al ; command line string and update
; the count
mov ax,offset envstart ; env buffer is para aligned
mov cl,4
shr ax,cl ; convert offset to paras
mov cx,ds
add ax,cx ; segment of env variables
mov exec_envseg,ax
mov exec_lineoff,si
mov exec_lineseg,ds
mov exec_fcb1off,0FFFEh ; Force PCMODE to generate
mov exec_fcb2off,0FFFEh ; correct FCB References
mov system_ss,ss
mov system_sp,sp
mov dx,offset dev_name ; Get ASCIIZ Command
mov bx,offset exec_envseg ; and Parameter Block Offset
mov ax,4B00h ; Load and Execute Program with Handle
int DOS_INT ; EXEC the application
cli ; Swap back to the original stack
mov ss,cs:system_ss ; again with interrupts disabled
mov sp,cs:system_sp
sti
mov ah,MS_X_WAIT ; if all went well return the
jnc func_i20 ; termination code
mov ah,MS_F_ERROR ; if we had an error from EXEC
xor bx,bx ; get extended error
func_i20:
int DOS_INT ; retrieve error value
mov cs:error_level,ax ; and save for testing
pop es ; recover the seg we protected
mov ah, MS_M_FREE ; so we can free that memory up
int 21h
mov ah,MS_M_ALLOC ; try and allocate as much as possible
mov bx, 0FFFFh ; ASSUME this will cover CONFIG
int 21h ; bx = No. of paras available
mov ah, MS_M_ALLOC ; give me bx paras please
int 21h ; ax:0 -> my memory
pop es ! pop ds
mov mem_current_base,ax ; save memory base
mov mem_current,ax ; for future allocations
ret
func_hidos: ; HIDOS ON/OFF
call check_onoff ; Check for ON or OFF
jc f_hidos10 ; Return on error
mov hidos,al ; update hidos flag
f_hidos10:
ret
func_dos: ; DOS=HIGH - relocate BIOS/BDOS/Buffer etc to FFFF
call separator ; Deblank Command
mov di,offset high_opt ; es:di -> "HIGH"
call compare ; do we have an "HIGH"?
jc func_dos10
push si
call func_dos_high ; execute HIGH
pop si
jmps func_dos
func_dos10:
mov di,offset low_opt ; es:di -> "LOW"
call compare
jc func_dos20
push si
call func_dos_low ; execute LOW
pop si
jmps func_dos
func_dos20:
mov di,offset umb_opt ; es:di -> "UMB"
call compare
jc func_dos30
push si
call func_dos_umb ; execute UMB
pop si
jmps func_dos
func_dos30:
mov di,offset noumb_opt ; es:di -> "NOUMB"
call compare
jc func_dos40
push si
call func_dos_noumb ; execute NOUMB
pop si
jmps func_dos
func_dos40:
ret
func_dos_high:
;-------------
; Move DOS into the HMA and allocate buffers etc. high too.
;
mov dos_target_seg,0FFFFh
mov bios_target_seg,0FFFFh
mov hidos,TRUE ; update hidos flag to be ON
or buffersIn,BUFFERS_IN_HMA; buffers at seg FFFF too
ret
func_dos_low:
;------------
; force all allocation to be low
;
mov dos_target_seg,0
mov bios_target_seg,0
mov hidos,FALSE ; system allocation from low memory
mov buffersIn,0 ; buffers from low memory
ret
func_dos_umb:
;------------
; allocate Upper Memory Blocks and link them to the DMD chain
;
mov hidos,TRUE ; update hidos flag to be ON
call initialise_dmd_upper ; build initial upper memory DMD
jc func_dos_umb30
func_dos_umb10:
call alloc_xms_umb ; allocate XMS upper memory
jc func_dos_umb20
call add_dmd_upper ; add to upper memory DMD's
jmps func_dos_umb10 ; go around again
func_dos_umb20:
call remove_last_dmd ; get rid of useless last DMD
func_dos_umb30:
mov ax,(MS_M_STRATEGY*256)+3
mov bx,1 ; link in upper memory region
int 21h
ret
func_dos_noumb:
;--------------
; Unlink Upper Memory blocks from the DMD chain
;
mov ax,(MS_M_STRATEGY*256)+3
xor bx,bx ; unlink upper memory region
int 21h
ret
alloc_xms_umb:
; On Entry:
; None
; On Exit:
; CY set is no upper memory available
; else
; BX = para base address
; DX = para size
;
; Try to allocate the largest possible block of XMS memory
; so we can link it to the upper memory chain
;
push es
mov ax,4300h ; check for XMS installation
int 2fh
cmp al,80h
jne alloc_xms10
mov ax,4310h ; get address of XMS driver
int 2fh
mov word ptr xms_driver,bx
mov word ptr xms_driver+2,es
mov ah,10h ; allocate upper memory block
mov dx,0FFFFh ; DX set to find largest block
callf xms_driver
cmp dx,3 ; we need at least 3 para's
jb alloc_xms10 ; before we contruct a DMD
mov ah,10h ; now allocate largest block
callf xms_driver
cmp ax,1 ; did we succeed ?
je alloc_xms20
alloc_xms10:
stc ; return CY set indicating failure
alloc_xms20:
pop es
ret
xms_driver rd 0
dw 0,0
initialise_dmd_upper:
; On Entry:
; None
; On Exit:
; CY set if chain already exists
; (BX/DX preserved)
;
; build initial upper memory DMD
; we rely on the fact the last para in memory is unused
; (but BIOSINIT makes sure that is true)
;
push es
push bx
push dx
if DOS5
les bx,func52_ptr ; ES:BX -> list of lists
cmp es:F52_DMD_UPPER[bx],0FFFFh
else
les bx,drdos_ptr
cmp es:DRDOS_DMD_UPPER[bx],0
les bx,funv52_ptr ; ES:BX -> list of lists
endif
stc ; assume error return required
jne initialise_dmd_upper30 ; bail out if chain already established
mov es,es:F52_DMDROOT ; ES -> 1st DMD
initialise_dmd_upper10:
cmp es:DMD_ID,IDZ ; end of DMD chain ?
je initialise_dmd_upper20
cmp es:DMD_ID,IDM ; do we have any more DMD's ?
stc
jne initialise_dmd_upper30 ; woops, chain must be bad
mov ax,es ; better point to it
inc ax
add ax,es:DMD_LEN ; AX:0 -> next DMD
mov es,ax
jmps initialise_dmd_upper10
initialise_dmd_upper20:
mov ax,es
add ax,es:DMD_LEN ; AX:0 -> will be upper memory chain
cmp ax,0A000h ; if the DMD chain is already into
cmc ; upper memory, lets make sure we
jb initialise_dmd_upper30 ; stop before we fall apart
mov es:DMD_ID,IDM ; no longer the last entry
dec es:DMD_LEN ; shorten last DMD to make room
mov es,ax ; point to new DMD
mov es:DMD_ID,IDZ ; there is only one entry in the chain
mov es:DMD_PSP,8 ; its' owned by "system"
xchg ax,cx ; CX = DMD
mov ax,0FFFFh
sub ax,cx ; it's this big
mov es:DMD_LEN,ax
if DOS5
les bx,func52_ptr
mov es:F52_DMD_UPPER[bx],cx
else
les bx,drdos_ptr
mov es:DRDOS_DMD_UPPER[bx],cx
endif
clc
initialise_dmd_upper30:
pop dx
pop bx
pop es
ret
remove_last_dmd:
; On Entry:
; None
; On Exit:
; None
;
; We have build an upper memory DMD chain, but we have left an extra
; DMD around covering the ROMs at the top of memory. Remove it if
; it's not required.
;
push es
les bx,func52_ptr ; ES:BX -> list of lists
mov es,es:F52_DMDROOT[bx] ; ES -> 1st DMD
remove_last_dmd10:
cmp es:DMD_ID,IDM ; do we have any more DMD's ?
jne remove_last_dmd20 ; bail out if we don't
mov ax,es ; remember previous DMD
mov dx,es
inc dx
add dx,es:DMD_LEN ; DX:0 -> next DMD
mov es,dx
cmp es:DMD_ID,IDZ ; end of DMD chain ?
jne remove_last_dmd10
cmp es:DMD_PSP,8 ; is it owned by "system" ?
jne remove_last_dmd20 ; if so we can ditch this entry
mov es,ax ; ES = next to last DMD
mov es:DMD_ID,IDZ ; new end of chain
inc es:DMD_LEN ; include last para
if DOS5
les bx,func52_ptr ; ES:BX -> list of lists
cmp dx,es:F52_DMD_UPPER[bx]
jne remove_last_dmd20 ; remove upper memory link if none left
mov es:F52_DMD_UPPER[bx],0FFFFh
else
les bx,drdos_ptr
cmp dx,es:DRDOS_DMD_UPPER[bx]
jne remove_last_dmd20 ; remove upper memory link if none left
mov es:DRDOS_DMD_UPPER[bx],0
endif
remove_last_dmd20:
pop es
ret
add_dmd_upper:
; On Entry:
; BX = base address of DMD
; DX = size of DMD
; On Exit:
; None
;
; Add this block into the upper memory chain.
; To do this we find the DMD containing the block and link it into place
;
push es
push bx ; save base address
les bx,func52_ptr ; ES:BX -> list of lists
mov ax,es:F52_DMDROOT[bx] ; AX -> 1st DMD
pop bx ; 1st DMD is always below XMS
cmp ax,bx ; memory, so bomb out if not
jae add_dmd_upper40 ; as our DMD's must be corrupt
add_dmd_upper10:
mov es,ax
add ax,es:DMD_LEN ; AX:0 -> end of this block
cmp ax,bx ; is the next block above us ?
ja add_dmd_upper20 ; if not try the next block
inc ax ; AX:0 -> next DMD
cmp es:DMD_ID,IDM ; do we have any more DMD's ?
je add_dmd_upper10 ; we should have......
jmps add_dmd_upper40 ; stop, DMD's are screwed up
add_dmd_upper20:
; We have found the block we wish to insert a new free block into
cmp es:DMD_PSP,8 ; it must be owned by "system"
jne add_dmd_upper40
; Shorten existing DMD to point to new block
mov ax,bx ; work out how far to new DMD
mov cx,es
sub ax,cx ; it's this many para's
dec ax ; forget the header
xchg ax,es:DMD_LEN ; set new length
; now we need to work out how much is left above the new DMD
sub ax,dx ; subtract length of new block
sub ax,es:DMD_LEN ; subtract the portion below
; Create DMD covering new block
mov cl,IDM ; create a new entry
xchg cl,es:DMD_ID ; CL = existing ID (M/Z)
mov es,bx ; ES -> base of new DMD
mov es:DMD_ID,IDM ; it's a link field
mov es:DMD_PSP,0 ; it's free
dec dx ; forget the header
add bx,dx ; last para is here
dec dx ; forget the next link
mov es:DMD_LEN,dx ; it's this long
; Build a new DMD at the top if the new block for anything above it
mov es,bx
mov es:DMD_ID,cl ; inherit the ID field
mov es:DMD_LEN,ax ; and it's this long
test ax,ax ; if zero length then
jz add_dmd_upper30 ; it's free
mov ax,8 ; else it's system
add_dmd_upper30:
mov es:DMD_PSP,ax ; set owner
add_dmd_upper40:
pop es
ret
func_set: ; SET envar=string
call whitespace ; deblank the command
mov di,offset envstart-1 ; point to our environment area
func_set5:
inc di
cmp es:word ptr [di],0 ; are we at the end yet
jne func_set5
cmp di,offset envstart ; if nothing is there yet start
je func_set10 ; at the NUL, else skip the NUL
inc di ; to leave a seperator
func_set10:
lodsb ; get a character
cmp al,CR ; end of the line yet ?
je func_set20
cmp di,offset envend ; have we room ?
jae func_set30 ; bail out if not
stosb ; save the character
jmps func_set10
func_set20:
xor ax,ax ; terminate with NULL
stosb
func_set30:
ret
endif ;not ADDDRV
func_echo: ; ECHO "string"
call whitespace ; Scan off all white space
lodsb ; before the optional
cmp al,'=' ; '=' character.
je func_echo10
dec si ; point at char
func_echo10:
mov dx,offset msg_dollar ; NUL error message
mov al,CR ; SI -> config line anyway
jmp config_error ; use error reporting routine
func_yeschar: ; yeschar "string"
call whitespace ; Scan off all white space
lodsb ; before the optional
cmp al,'=' ; '=' character.
je func_yeschar10
dec si ; point at char
func_yeschar10:
call whitespace
lodsb
mov yes_char,al ; update YES character
ret
func_chain: ; CHAIN="filename" - use as new CONFIG.SYS
mov di,offset dev_name ; Copy the Device Filename into a
mov byte ptr [di],0 ; local buffer and zero terminate
call copy_file
jc func_chain10 ; ignore if any problems
mov ax,(MS_X_OPEN*256)+80h ; Try to open the file
mov dx,offset dev_name ; as a new config file
int DOS_INT ; if we can't ignore it
jc func_chain10
mov bx,ax
mov ah,MS_X_CLOSE
int DOS_INT ; close the new file
mov si,offset dev_name
mov di,offset cfg_file
call copy_asciiz ; copy the new name
mov cfg_seeklo,0 ; start at begining of it
mov cfg_seekhi,0
mov cfg_tail,0 ; force a read
func_chain10:
ret
func_switch: ; SWITCH=option0, option1
; GOSUB to appropriate label
call wait_for_key ; wait until a key is pressed
jc func_switch01 ; ignore if timeout
mov ah,MS_C_RAWIN
int DOS_INT ; read a char
cmp al,CR
jne func_switch02
func_switch01:
mov al,default_switch_char ; use default character
func_switch02:
cmp al,'0' ; ignore if < '0'
jb func_switch
cmp al,'9' ; or > '9'
ja func_switch
sub al,'1' ; convert from ASCII
jns func_switch05
mov al,10 ; make '0' into 10
func_switch05:
cbw ; AX = lines to skip
xchg ax,cx ; make CX the loop count
jcxz func_switch30
mov bx,si ; BX -> saved command line start
func_switch10:
push bx
push cx
mov di,offset dev_name ; copy and discard a label
call copy_file
pop cx
pop bx
jc func_switch40 ; ignore if any problems
push bx
push cx
call separator ; look for ','
pop cx
pop bx
jc func_switch40 ; stop at end of line
loop func_switch10
func_switch30:
jmp func_gosub ; execute a GOSUB
func_switch40:
mov si,bx ; retract to start of line
jmps func_switch ; then back to sleep again
func_gosub: ; GOSUB="label"
;----------
pop ax ; get return address
mov bx,cfg_seeklo ; get existing offset
mov cx,cfg_seekhi ; in CONFIG file
sub bx,cfg_tail ; work out begining of buffer
sbb cx,0
add bx,cfg_head ; add in current offset in buffer
adc cx,0
push bx ; save as position to RETURN to
push cx
push ax ; save return address again
call func_goto ; try to GOTO label
jc func_return
ret ; RET, with old offset on stack
func_return: ; RETURN [n]
;-----------
pop bx ; get return address
cmp sp,save_sp ; is anything on stack ?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -