📄 0cd.asm
字号:
mov bx,[@@Handle] ; Filehandle in bx
int 21h ; Call DOS interrupt
mov [cs:Quiet],00h ; Turn of quiet mode
call LStrWrite, offset DataTooBig ; Write error msg
call CleanUp ; Clean up
ExitCode 0001h ; Exit to DOS
@@OkSize:
mov [@@Size],ax ; Save size of file
shr ax,4 ; Divide by 16
inc ax ; And add 1
mov bx,ax ; Number of segments in bx
mov ah,48h ; Dos Fn 48h = AllocMem
int 21h ; Call DOS interrupt
jc @@NoMem ; Error --> @@NoMem
mov es,ax ; Segment in es
mov [@@NewSeg],ax ; Store new segment
mov ax,4200h ; Dos Fn 42 = LSeek
mov bx,[@@Handle] ; Filehandle in bx
xor cx,cx ; High 16 bits of position
xor dx,dx ; Low 16 bits of position
int 21h ; Call DOS interrupt
mov ah,3fh ; Dos Fn 3fh = Read file
mov bx,[@@Handle] ; Filehandle in bx
push ds ; Save ds
push es ; Put ds ...
pop ds ; ... in es
xor dx,dx ; High 16 bits of size in dx
mov cx,[@@Size] ; Low 16 bits of size in cx
int 21h ; Call DOS interrupt
pop ds ; Restore ds
mov al,[byte ptr @@DriveID] ; Get driveletter
mov [ReadData2],al ; Update message text
call LStrWrite, offset ReadData1 ; Write text
call LStrWrite, offset DataName ; Write filename
call LStrWrite, offset CRLF ; Newline
mov bx,[@@Handle] ; Filehandle in bx
mov ah,3eh ; Dos Fn 3eh = Close file
int 21h ; Call DOS interrupt
jmp @@Exit ; Exit
@@NoMem:
mov bx,[@@Handle] ; Filehandle in bx
mov ah,3eh ; Dos Fn 3eh = Close file
int 21h ; Call DOS interrupt
mov [cs:Quiet],00h ; Turn off quiet mode
call LStrWrite, offset DataNoMem ; Write error msg
call CleanUp ; Clean up
ExitCode 0001h ; Exit to dos
@@Exit:
lea si,[Datas] ; ds:si point to Datas
mov cx,[@@DriveID] ; Get drive letter
sub cl,[cs:FirstID] ; Make 0-based
cmp cl,0 ; First drive ?
je @@DoExit ; Yes --> @@DoExit
@@Loop:
add si,2 ; Next data index
dec cl ; One less to skip
jnz @@Loop ; More --> @@Loop
@@DoExit:
mov es,[@@NewSeg] ; Return segment in es
mov [ds:si],es ; Save segment in Datas
ret ; Return to caller
endp
; Report procedure
proc Report
cmp [cs:CoMSCDEX],01h ; MSCDEX co-existance ?
jne @@NoCoEXIST
call LStrWrite, offset CoMsg ; Write message
@@NoCoExist:
cmp [cs:AudioTru],00h ; Audio throughput ?
je @@NoTru ; No --> @@NoTru
call LStrWrite, offset TruMsg ; Write message
@@NoTru:
cmp [cs:AltSimul],00h ; Alternate simulation ?
je @@NoAlt ; No --> @@NoAlt
call LStrWrite, offset AltMsg ; Write message
@@NoAlt:
cmp [cs:DoFailure],00h ; Failure or success ?
je @@Success
call LStrWrite, offset FailMsg ; Write message
jmp @@OkFail
@@Success:
call LStrWrite, offset SuccessMsg ; Write message
@@OkFail:
cmp [cs:WriteProt],00h ; Write-protected ?
je @@NotProt ; No --> @@NotProt
call LStrWrite, offset IsProt ; Write message
jmp @@Size ; --> @@Size
@@NotProt:
call LStrWrite, offset NotProt ; Write message
@@Size:
cmp [cs:RetZero],00h ; Zero disk free ?
je @@NotZero ; No --> @@NotZero
call LStrWrite, offset CD0 ; Write message
jmp @@Exit ; Exit
@@NotZero:
call LStrWrite, offset CDSize ; Write message
@@Exit:
call LStrWrite, offset CRLF ; Write an empty line
ret ; Return to caller
endp
; SaveDir procedure
proc SaveDir
uses ax, si, dx
mov ah,47h ; Dos Fn 47h = GetCurDir
lea si,[OldDir+1] ; Destination in ds:si
push ds
push cs
pop ds
mov [byte ptr ds:si-1],'\' ; Make \ relative
mov dl,00h ; Set to current drive
int 21h ; Call DOS interrupt
pop ds
mov ah,19h ; Dos Fn 19h = GetCurDrive
int 21h ; Call DOS interrupt
mov [cs:OldDrive],al ; Save drive
ret ; Return to caller
endp
; ReturnDir procedure
proc ReturnDir
uses ax, dx
mov ah,0eh ; Dos Fn 0eh = SetCurDrive
mov dl,[cs:OldDrive] ; Drive no in dl
int 21h ; Call DOS interrupt
mov ah,3bh ; Dos Fn 3bh = SetCurDir
lea dx,[OldDir] ; Directory in ds:dx
push ds
push cs
pop ds
int 21h ; Call DOS interrupt
pop ds
ret ; Return to caller
endp
; LStrWrite procedure
proc LStrWrite
arg @@Str:word
cmp [cs:Quiet],1 ; Quiet mode ?
je @@Exit ; Yes --> @@Exit
cmp [cs:Inited],0 ; Already shown version ?
jne @@Ok ; Yes --> @@Ok
mov [cs:Inited],1 ; Set version shown flag
call StrWrite, cs offset InitMsg ; Show version message
@@Ok:
call StrWrite, [@@Str] ; Write text
@@Exit:
ret ; Return to caller
endp
; Init procedure
proc Init
call GetFirstDrive
call ReadDescription
call Needed
call CheckMSCDEX
ret
endp
; GetCOMSPEC procedure
proc GetCOMSPEC
uses ax, si, di, es, ds
mov ah,62h ; Dos Fn 62h = Get PSP
int 21h ; Call DOS interrupt
mov es,bx ; Segment of PSP in es
mov es,[es:002ch] ; Get environment segment
xor si,si ; Start of environment
@@Loop:
call StrLIComp, es si, ds offset CSEnv, 8 ; COMSPEC=xxx ?
jc @@Next ; No --> @@Next
add si,8 ; Skip to xxx
call StrCopy, cs offset ProgName, es si ; Save program name
jmp @@Exit ; Exit
@@Next:
inc si ; Next character
cmp [byte ptr es:si],0 ; At end of string ?
jne @@Next ; No --> @@Next
inc si ; Skip end-of-string char
cmp [byte ptr es:si],0 ; End of environment ?
jne @@Loop ; No --> @@Loop
@@Exit:
ret ; Return to caller
endp
; Needed procedure
proc Needed
cmp [AnyRedir],1 ; Any redirections at all ?
je @@Exit ; Yes --> @@Exit
call LStrWrite, offset NoRedirs ; Write error message
call CleanUp ; Clean up
ExitCode 0001h ; Exit to dos
@@Exit:
call CheckFile ; Check for program to run
ret ; Return to caller
endp
; CheckFile procedure
proc CheckFile
mov ax,3d00h ; Dos Fn 3d = Open file
push ds
push cs
pop ds
lea dx,[RunName] ; Filename in ds:dx
int 21h ; Call DOS interrupt
pop ds
jc @@NoFile ; Error --> @@NoFile
mov bx,ax ; Filehandle in bx
mov ah,3eh ; Dos Fn 3eh = Close file
int 21h ; Call DOS interrupt
call LStrWrite, offset RunProg ; Show run message
push ds cs ; Save ds and put cs ...
pop ds ; ... into ds
call LStrWrite, offset RunName ; Show name of program
pop ds ; Restore ds
call LStrWrite, offset CRLF ; Newline
jmp @@Exit ; Exit
@@NoFile:
mov [byte ptr cs:Params],0 ; No parameters to COMSPEC
@@Exit:
ret ; Return to caller
endp
; GetCDS procedure
; Returns pointer in es:bx, and carry set if success, or 0:0 in es:bx and
; carry clear if failure
proc GetCDS
arg @@DriveID:word
uses ax
call UpCase, [@@DriveID] ; Make letter uppercase
mov [@@DriveID],ax ; Store in @@DriveID
mov ah,52h ; Dos Fn 52h = Get DosSysVars
int 21h ; Call DOS interrupt
add bx,16h ; Skip to CDS entry
les bx,[dword ptr es:bx] ; Get pointer to CDS in es:bx
mov al,'A' ; First drive letter in CDS
@@Loop:
cmp al,[byte ptr @@DriveID] ; Correct CDS record ?
je @@Found ; Yes --> @@Found
add bx,88 ; Skip record
inc al ; Next drive letter
cmp al,'[' ; Beyond end of CDS ?
jb @@Loop ; No --> @@Loop
xor bx,bx ; Zero offset
mov es,bx ; Zero segment
clc ; Signal failure via carry
jmp @@Exit ; Exit
@@Found:
stc ; Signal success via carry
@@Exit:
ret ; Return
endp
; GetFirstDrive procedure
proc GetFirstDrive
local @@DriveID:word
uses ax
mov [@@DriveID],'D' ; First available drive letter
@@Loop:
call GetCDS, [@@DriveID] ; Get CDS entry for drive
jnc @@Exit ; Failure --> @@Exit
cmp [word ptr es:bx+67],0000h ; Drive available ?
jne @@Next ; No --> @@Next
cmp [word ptr es:bx+69],0000h ; Drive available ?
jne @@Next ; No --> @@Next
cmp [word ptr es:bx+71],0000h ; Drive available ?
jne @@Next ; No --> @@Next
mov al,[byte ptr @@DriveID] ; Get drive ID
mov [DriveID],al ; Store ID
jmp @@Exit ; Exit
@@Next:
inc [@@DriveID] ; Next ID
cmp [@@DriveID],'[' ; Beyond available IDs?
je @@Err ; Yes --> @@Err
jmp @@Loop ; Loop
@@Exit:
mov al,[DriveID] ; Get drive ID
mov [cs:FirstID],al ; Save as first ID
ret ; Return to caller
@@Err:
mov [cs:Quiet],0 ; Turn off quiet mode
call LStrWrite, offset NoDrives ; Write error message
call CleanUp ; Clean up
ExitCode 0001h ; Exit to dos
endp
; CheckMSCDEX procedure
proc CheckMSCDEX
push 0dadah ; Put 0dadah on stack
mov ax,1100h ; Multiplex Fn 1100h = MSCDEX
mov si,'0C' ; si:ds = '0CD6' ...
mov di,'D7' ; ...
int 2fh ; Call multiplex interrupt
pop bx ; Get stack entry
cmp al,0ffh ; MSCDEX installed ?
jne @@NoMSCDEX ; No --> @@NoMSCDEX
cmp bx,0adadh ; Correct entry on stack ?
jne @@NoMSCDEX ; No --> @@NoMSCDEX
@@Installed:
cmp [cs:AudioTru],01h ; Audio throughput ?
je @@ExitInstalled ; Yes --> @@ExitInstalled
cmp si,'7D' ; 0cd signature ?
jne @@MSC ; No --> @@MSC
cmp di,'C0' ; ...
jne @@MSC ; ...
call LStrWrite, offset Installed ; Show installed message
jmp @@Quit ; Exit to dos
@@NoMSCDEX:
cmp [cs:AudioTru],01h ; Audio through-put enabled ?
jne @@Exit ; No --> @@Exit
call LStrWrite, offset NoMSCDEX ; Write warning message
mov [cs:AudioTru],00h ; Disable audio throughput
jmp @@Exit ; Exit
@@MSC:
mov [cs:AltSimul],00h ; Disable alternate simulation
cmp [cs:CoMSCDEX],01h ; MSCDEX co-existance ?
je @@Exit ; Yes --> @@Exit
call LStrWrite, offset MSCDEX ; Show MSCDEX message
@@Quit:
call CleanUp ; Clean up
ExitCode 0001h ; Exit to dos
@@ExitInstalled:
mov [cs:AltSimul],00h ; Disable alternate simulation
mov ax,1500h ; Get number of drives
int 2fh ; Call old driver
mov [cs:FirstRealCD],cl ; Store first unit
@@Exit:
ret ; Return to caller
endp
; ReadDescription procedure
proc ReadDescription
local @@File:word
mov ah,62h ; Dos Fn 62h = Get PSP
int 21h ; Call DOS interrupt
mov es,bx ; Segment of PSP in es
mov si,81h ; Offset 81h = Parameters
lea di,[Line] ; Point ds:di to Line
mov [byte ptr ds:di],0 ; Terminate Line variable
mov cl,[es:si-1] ; Get number of characters
cmp cl,0 ; Any at all ?
je @@Exit ; No --> @@Exit
@@Loop:
mov al,[es:si] ; Get character
inc si ; Skip character
cmp al,09h ; Tab character ?
je @@Space ; Yes --> @@Space
cmp al,20h ; Space character
je @@Space ; Yes --> @@Space
cmp al,0dh ; End of parameters ?
je @@Space ; Yes --> @@Space
mov [ds:di],al ; Store character in Line
inc di ; Skip character in Line
mov [byte ptr ds:di],0 ; Terminate Line variable
@@Next:
dec cl ; One less character to process
jnz @@Loop ; More --> @@Loop
call Parse ; Parse current parameter
jmp @@Exit ; Exit
@@Space:
cmp [byte ptr Line],0 ; Parameter ?
je @@NoLine ; No --> @@NoLine
call Parse ; Parse current parameter
@@NoLine:
mov [byte ptr Line],0 ; Empty Line variable
lea di,[Line] ; Rewind pointer to Line
jmp @@Next ; Next character
@@Exit:
ret ; Return to caller
endp
; Parse procedure
proc Parse
uses si, ax, cx, bx, ds, es
cmp [byte ptr ds:Line],'/' ; Option character ?
je @@Option ; Yes --> @@Option
cmp [byte ptr ds:Line],'-' ; Option character ?
je @@Option ; Yes --> @@Option
call Redirect ; Redirect new drive
jmp @@Exit ; Exit
@@Option:
mov al,[byte ptr ds:Line+1] ; Get option character
call UpCase, ax ; Convert to uppercase
cmp al,'V' ; Revision option ?
je @@ShowRev
cmp al,'M' ; MSCDEX option ?
je @@MSCDEX ; Yes --> @@MSCDEX
cmp al,'A' ; Alternate option ?
je @@Alt ; Yes --> @@Alt
cmp al,'F' ; Failure option ?
je @@Failure ; Yes --> @@Failure
cmp al,'I' ; Simulation option ?
je @@Simulate ; Yes --> @@Simulate
cmp al,'R' ; Run option ?
je @@SetRun ; Yes --> @@SetRun
cmp al,'D' ; DataFile option ?
je @@Data ; Yes --> @@Data
cmp al,'0' ; 0-free option ?
je @@ZeroRet ; Yes --> @@ZeroRet
cmp al,'L' ; Letter option ?
je @@NewLetter ; Yes --> @@NewLetter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -