DOSIF.ASM
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:61k
源码类别:
操作系统开发
开发平台:
Asm
- ; File : $Workfile: DOSIF.ASM$
- ;
- ; Description :
- ;
- ; Original Author :
- ;
- ; Last Edited By : $Author: RGROSS$
- ;
- ; Copyright : (C) 1992 Digital Research (UK), Ltd.
- ; Charnham Park
- ; Hungerford, Berks.
- ; U.K.
- ;
- ; *** Current Edit History ***
- ; *** End of Current Edit History ***
- ;
- ; $Log: $
- ; DOSIF.ASM 1.1 94/06/28 16:01:14 RGROSS
- ; Initial PUT
- ; DOSIF.ASM 1.16 94/06/28 16:01:28 IJACK
- ; ms_x_expand returns error codes (for benefit of TRUENAME)
- ; DOSIF.ASM 1.15 93/11/29 19:57:24 IJACK
- ;
- ; --------
- ;
- ; DOSIF.ASM 1.13 93/09/09 10:24:50 RFREEBOR
- ; call_novell() now returns all allowed error codes.
- ;
- ; DOSIF.ASM 1.12 93/02/24 17:42:49 EHILL
- ; _get_scr_width() function added.
- ;
- ; DOSIF.ASM 1.11 93/01/21 16:19:31 EHILL
- ;
- ; DOSIF.ASM 1.10 93/01/21 14:32:32 EHILL
- ;
- ; DOSIF.ASM 1.8 92/09/11 10:46:28 EHILL
- ;
- ; DOSIF.ASM 1.7 92/08/06 09:56:07 EHILL
- ; Added DOS 5 calls to get and set memory allocation strategy and
- ; upper memory link.
- ;
- ; DOSIF.ASM 1.6 92/07/10 17:47:13 EHILL
- ; No comment
- ;
- ; ENDLOG
- ;
- ; This file provides all the assembler level interfaces to the
- ; underlying operating system that are required by COMMAND.COM.
- ; The type of functions calls that will be made is controlled
- ; by a Assemble time flag.
- ;
- ; Currently the Operating System Interfaces that are supported
- ; are MS-DOS and Concurrent DOS 6.0.
- ;
- ;
- ; Command Line Flags
- ; ==================
- ;
- ; MSDOS If defined then USE MSDOS function Calls
- ; CDOS If defined then Use Concurrent DOS Calls
- ;
- ;
- ; 2/Sep/87 jc Convert the Concurrent IOCTL function to use the FDOS
- ; command.
- ; 19/Oct/87 jc Handle Fail on Get current directory correctly
- ; 23/Feb/88 jc Use Text substitution function to get the path assigned
- ; to floating drives (ms_x_subst).
- ; 3/Mar/88 jc Support Server Password Error
- ; 9/Mar/88 jc Return a NULL terminated string when an error occurs on the
- ; ms_x_subst function.
- ; 15/Mar/88 jc Correct ms_x_subst register corruption bug
- ; 13/Apr/88 jc Support the FAR_READ and FAR_WRITE routines as well as external
- ; copy buffer allocation via MEM_ALLOC and MEM_FREE
- ; 20/May/88 jc Return the current country code to the calling application
- ; 25/May/88 jc Missing dataOFFSET causing garbage offset to be passed
- ; ms_x_subst.
- ; 18/Jul/88 jc Modify LOGICAL_DRV test to detect substituted physical drives
- ; 17/Aug/88 jc Return the current Break Status using DL not AL
- ; 22/Sep/88 jc Replace MS_X_SUBST with more general MS_X_EXPAND routine
- ; 25/Jan/89 ij If new DRDOS internal data layout get DPHTBL the new way
- ; 07/Feb/89 jc Add the Get and Set Global Codepage MS_X_GETCP/MS_X_SETCP
- ; 25/Jan/89 ij Get DPHTBL using DRDOS_DPHTBL_OFFSET equate
- ; 14/Apr/89 jjs Add ms_x_setdev
- ; 31/May/89 ij Get SYSDAT for DPHTBL using new f4458 function
- ; 19/May/89 jc Remove "Alternative" techniques of getting SYSDAT:DPHTABLE
- ; 20/Jun/89 js ms_f_parse, ms_f_delete, for DEL cmd
- ; 30/Aug/89 js ms_idle_ptr
- ; 6/Sep/89 ij network_drvs really does something on DRDOS
- ; 16/Oct/89 ach Added double byte character set support routines: dbcs_init,
- ; dbcs_expected and dbcs_lead.
- ; 18/Jan/90 ij HILOAD interfaces added
- ; 4/Apr/90 ij dbcs_init moved to cstart, use system table, then we can throw
- ; away the init code
- ; 24-May-90 ij ms_x_expand sets up ES....
- ; 17 Sep 90 ij TMP Control Break kludge echo's ^C to console
- ; 4 Oct 90 ij Use P_CAT, not P_HDS
- ; 15 Mar 91 jc DRDOS_DPHTBL is now called SYSDAT_DPHTBL cos thats where it lives
- ; 28 May 91 ejh No longer use SYSDAT to determine if drives are physical,
- ; logical or networked. See _physical_drive, _logical_drive and
- ; _network_drive.
- ; 23 Jun 91 ejh SUBST and ASSIGN are now external commands, so the following
- ; are no longer required:
- ; _physical_drvs, _logical_drvs, _network_drvs
- ; _physical_drive,_logical_drive,_network_drive
- ; 3 jul 91 ij except for NETDRIVE in MDOS
- ;
- ; 18 Jun 92 ejh Added get_lines_page() function.
- ; 24 Jun 92 ejh Added novell_copy() function.
- CGROUP group _TEXT
- DGROUP group _DATA
- codeOFFSET equ offset CGROUP:
- dataOFFSET equ offset DGROUP:
- EXT_SUBST equ 1 ; External Subst and Assign commands
- CRET MACRO num
- ret
- ENDM
- ifndef ??Version ;; Turbo Assembler always knows RETF
- ifndef retf ;; some versions of MASM do as well
- retf macro ;; define far return macro for others
- db 0cbh
- endm
- endif
- endif
- ifndef CDOSTMP
- include msdos.equ
- endif
- ifndef DOSPLUS
- include system.def
- include pd.def
- include ccpm.equ
- ;include udaa.def
- include net.def
- include mserror.equ
- else
- include f52data.def
- endif
- ;
- ifdef CDOSTMP
- OK_RIF equ 00111000b ; All Responsese are Valid
- OK_RI equ 00110000b ; Retry and Ignore are Valid
- OK_RF equ 00011000b ; Retry and Fail are Valid
- ;
- ; Structure of DOS DPB
- ; --------------------
- ; The layout of this structure is a guess based on
- ; examples. It is returned by PC MODE on functions 1Fh and
- ; 32h and is required by various disk-related utilities
- ; like disk editors and CHKDSK.
- DDSC_UNIT equ es:byte ptr 0 ; absolute drive number
- DDSC_RUNIT equ es:byte ptr 1 ; relative unit number
- DDSC_SECSIZE equ es:word ptr 2 ; sector size in bytes
- DDSC_CLMSK equ es:byte ptr 4 ; sectors/cluster - 1
- DDSC_CLSHF equ es:byte ptr 5 ; log2 (sectors/cluster)
- DDSC_FATADDR equ es:word ptr 6 ; sector address of FAT
- DDSC_NFATS equ es:byte ptr 8 ; # of FAT copies
- DDSC_DIRENT equ es:word ptr 9 ; size of root directory
- DDSC_DATADDR equ es:word ptr 11 ; sector address of cluster #2
- DDSC_NCLSTRS equ es:word ptr 13 ; # of clusters on disk
- DDSC_NFATRECS equ es:byte ptr 15 ; # of sectors per FAT
- DDSC_DIRADDR equ es:word ptr 16 ; sector address of root dir
- DDSC_DEVHEAD equ es:dword ptr 18 ; device driver header
- DDSC_MEDIA equ es:byte ptr 22 ; current media byte
- DDSC_FIRST equ es:byte ptr 23 ; "drive never accessed" flag
- DDSC_LINK equ es:dword ptr 24 ; next drive's DDSC
- DDSC_BLOCK equ es:word ptr 28 ; next block to allocate
- DDSC_FREE equ es:word ptr 30 ; total free clusters on drive
- DDSC_MAP equ es:word ptr 32 ; free blocks/FAT sector
- endif
- BDOS_INT equ 224 ; ##jc##
- _DATA SEGMENT byte public 'DATA'
- extrn __psp:word
- ifndef DOSPLUS
- extrn _pd:dword ; Process Descriptor Pointer
- endif
- extrn _country:WORD
- ifdef DOSPLUS
- extrn dbcs_table_ptr:dword ; points to system DBCS table
- endif
- ifdef CDOSTMP
- ;
- ; The following buffer is used by the P_PATH function.
- ; FINDFILE uses the first three fields to get the full path and
- ; filename of the command.
- ;
- exec_block label byte
- exec_pathoff dw ? ; Offset of ASCIIZ Load file
- exec_pathseg dw ? ; Segment of ASCIIZ Load File
- exec_filetype db ? ; File Type Index
- fdos_data dw 7 dup(0) ; FDOS parameter Block
- mpb_start dw ? ; Memory parameter Block
- mpb_min dw ?
- mpb_max dw ?
- mpb_pdadr dw ?
- mpb_flags dw ?
- mfpb_start dw ? ; Memory Free Parameter Block
- mfpb_res dw ?
- country_data label word ; GET country data
- cd_country dw ? ; Requested Country Code
- cd_codepage dw ? ; Requested Code Page
- cd_table dw ? ; Table Number
- cd_offset dw ? ; Buffer Offset
- cd_segment dw ? ; Buffer Segment
- valid dw 0 ; Valid Error Responses
- retry_ip dw 0 ; Critical Error Retry IP
- retry_sp dw 0 ; Critical Error Retry SP
- crit_flg db FALSE ; Critical Section of Error Handler
- include fdos.def
- endif
- ifdef NETWARE
- ipx label dword
- ipx_offset dw 0
- ipx_segment dw 0
- ;
- ; Socket Allocation by Novell
- ;
- ; Socket Nos 4000 and 4001 appear to be used by the IPX internally
- ; and these are NOT closed by the NET_WARE routine. All other USER
- ; sockets are closed.
- ;
- ; List of sockets to be closed on shutdown
- ; Start Count
- socket label word
- ;; dw 0001h, 0BB8h
- dw 4002h, 3FFFh - 2 ; User Socket Numbers
- dw 0, 0
- aes label byte ; Event Control Block
- aes_link label dword ; Link Field
- aes_linkoff dw 0
- aes_linkseg dw 0
- aes_esr label dword ; Service Routine Address
- aes_esroff dw codeOFFSET aes_retf
- aes_esrseg dw 0000
- aes_inuse db 0 ; Flag Field
- aes_workspc db 5 dup(?) ; AES WorkSpace
- endif
- _DATA ENDS
- _TEXT SEGMENT byte public 'CODE'
- assume cs:CGROUP, ds:DGROUP, es:DGROUP
- extrn _int_break:near ; Control-C Break Handler
- ifdef CDOSTMP
- ifdef MWC
- extrn _critical_error:near ; Default Critical Error Handler
- CRITICAL_ERR equ _critical_error
- else
- extrn CRITICAL_ERROR:near ; Default Critical Error Handler
- CRITICAL_ERR equ CRITICAL_ERROR
- endif
- endif
- ;
- ; UWORD psp_poke(WORD handle, BYTE ifn);
- ;
- Public _psp_poke
- _psp_poke:
- push bp
- mov bp,sp
- push es
- ifdef CDOSTMP
- mov es,__psp ; ES:0 -> our PSP
- else
- mov ah,MS_P_GETPSP
- int DOS_INT ; for software carousel
- mov es,bx
- endif
- les bx,es:[0034h] ; ES:BX -> external file table
- add bx,4[bp] ; ES:BX -> XFT entry for our handle
- mov al,6[bp] ; get new value to use
- xchg al,es:[bx] ; get old value, set new value
- xor ah,ah
- pop es
- pop bp
- ret
- ifndef CDOSTMP
- Public _ms_drv_set
- ;-----------
- _ms_drv_set:
- ;-----------
- push bp
- mov bp,sp
- mov dl,04[bp]
- mov ah,MS_DRV_SET ; Select the Specified Disk Drive
- int DOS_INT ; Nothing Returned to caller
- pop bp
- ret
- Public _ms_drv_get
- ;-----------
- _ms_drv_get:
- ;-----------
- mov ah,MS_DRV_GET ; Return the Currently selected
- int DOS_INT ; disk drive
- cbw
- ret
- Public _ms_drv_space
- ;------------
- _ms_drv_space:
- ;------------
- ;
- ; ret = _ms_drv_space (drive, &free, &secsiz, &nclust);
- ; where: drive = 0, 1-16 is drive to use
- ; free = free cluster count
- ; secsiz = bytes/sector
- ; nclust = clusters/disk
- ; ret = sectors/cluster -or- (0xFFFFh)
- push bp
- mov bp,sp
- mov dx,4[bp]
- mov ah,MS_DRV_SPACE
- int DOS_INT
- push bx
- mov bx,6[bp] ; get free cluster count
- pop word ptr [bx]
- mov bx,8[bp]
- mov [bx],cx ; bytes/sector
- mov bx,10[bp]
- mov [bx],dx ; clusters/disk
- cbw
- pop bp
- ret
- Public _ms_s_country
- ;------------
- _ms_s_country:
- ;------------
- push bp
- mov bp,sp
- mov ax,MS_S_COUNTRY shl 8 ; Get the curremt country information
- mov dx,4[bp] ; and return the current country code
- int DOS_INT ; to the calling application.
- mov ax,bx
- pop bp
- ret
- Public _ms_x_mkdir
- ;----------
- _ms_x_mkdir:
- ;----------
- mov ah,MS_X_MKDIR
- jmp ms_dx_call
- Public _ms_x_rmdir
- ;----------
- _ms_x_rmdir:
- ;----------
- mov ah,MS_X_RMDIR
- jmp ms_dx_call
- Public _ms_x_chdir
- ;----------
- _ms_x_chdir:
- ;----------
- mov ah,MS_X_CHDIR
- jmp ms_dx_call
- Public _ms_x_creat
- ;----------
- _ms_x_creat:
- ;----------
- mov ah,MS_X_CREAT
- jmp ms_open_creat
- Public _ms_x_open
- ;---------
- _ms_x_open:
- ;---------
- mov ah,MS_X_OPEN
- ms_open_creat:
- push bp
- mov bp,sp
- mov dx,4[bp]
- mov cx,6[bp] ; get mode for new file (CREAT)
- mov al,cl ; or open mode (OPEN)
- int DOS_INT
- jnc ms_open_ret ; AX = handle if no error
- neg ax ; else mark as error code
- ms_open_ret:
- pop bp
- ret
- Public _ms_x_close
- ;----------
- _ms_x_close:
- ;----------
- push bp
- mov bp,sp
- mov bx,4[bp] ; get the open handle
- mov ah,MS_X_CLOSE ; get the function
- jmp ms_call_dos ; call DOS, handle errors
- Public _ms_x_unique
- ;----------
- _ms_x_unique:
- ;----------
- mov ah,MS_X_MKTEMP
- jmp ms_open_creat
- Public _ms_x_fdup
- ;----------
- _ms_x_fdup:
- ;----------
- push bp
- mov bp,sp
- mov cx,4[bp] ; get the destination handle
- mov bx,6[bp] ; Get the current handle
- mov ah,MS_X_DUP2 ; get the function
- jmp ms_call_dos ; call DOS, handle errors
- Public _far_read
- ;---------
- _far_read:
- ;---------
- mov ah,MS_X_READ
- jmp far_read_write
- Public _far_write
- ;----------
- _far_write:
- ;----------
- mov ah,MS_X_WRITE
- far_read_write:
- push bp
- mov bp,sp
- push ds
- mov bx,4[bp] ; get file handle
- lds dx,dword ptr 6[bp] ; get buffer address
- mov cx,10[bp] ; get byte count
- int DOS_INT ; call the DOS
- jnc far_rw_ok ; skip if no error
- neg ax ; else make it negative error code
- far_rw_ok:
- pop ds
- pop bp
- ret
- Public _ms_x_read
- ;---------
- _ms_x_read:
- ;---------
- mov ah,MS_X_READ
- jmp ms_read_write
- Public _ms_x_write
- ;----------
- _ms_x_write:
- ;----------
- mov ah,MS_X_WRITE
- ms_read_write:
- push bp
- mov bp,sp
- mov bx,4[bp] ; get file handle
- mov dx,6[bp] ; get buffer address
- mov cx,8[bp] ; get byte count
- int DOS_INT ; call the DOS
- jnc ms_rw_ok ; skip if no error
- neg ax ; else make it negative error code
- ms_rw_ok:
- pop bp
- ret
- Public _ms_x_unlink
- ;-----------
- _ms_x_unlink:
- ;-----------
- mov ah,MS_X_UNLINK
- jmp ms_dx_call
- Public _ms_x_lseek
- ;----------
- _ms_x_lseek:
- ;----------
- push bp
- mov bp,sp
- mov ah,MS_X_LSEEK ; get the function
- mov bx,4[bp] ; get the file handle
- mov dx,6[bp] ; get the offset
- mov cx,8[bp]
- mov al,10[bp] ; get the seek mode
- int DOS_INT
- jnc ms_lseek_ok ; skip if no errors
- neg ax ; make error code negative
- cwd ; sign extend to long
- ms_lseek_ok:
- mov bx,dx ; AX:BX = DRC long return
- pop bp
- ret
- Public _ms_x_ioctl
- ;----------
- _ms_x_ioctl:
- ;----------
- push bp
- mov bp,sp
- mov bx,4[bp] ; get our handle
- mov ah,MS_X_IOCTL ; get IO Control function
- mov al,0 ; get file/device status
- int DOS_INT ; do INT 21h
- jnc ms_x_i10
- neg ax
- ms_x_i10:
- pop bp ;
- ret
- Public _ms_x_setdev
- ;------------
- _ms_x_setdev:
- ;------------
- push bp
- mov bp, sp
- mov bx, 4[bp] ; handle
- mov dx, 6[bp] ; byte value to set
- sub dh, dh
- mov ah, MS_X_IOCTL
- mov al, 1
- int DOS_INT
- jnc ms_x_sd10
- neg ax
- ms_x_sd10:
- pop bp
- ret
- Public _ms_x_chmod
- ;----------
- _ms_x_chmod:
- ;----------
- push bp
- mov bp,sp
- mov ah,MS_X_CHMOD
- mov dx,4[bp]
- mov cx,6[bp]
- mov al,8[bp]
- int DOS_INT
- jnc ms_chmod_ok
- neg ax ; make error code negative
- jmp ms_chmod_ret
- ms_chmod_ok:
- sub ax,ax ; assume no error
- cmp byte ptr 8[bp],0 ; getting attributes
- jne ms_chmod_ret ; return ax = 0 if setting & no error
- xchg ax,cx ; return ax = attrib otherwise
- ms_chmod_ret:
- pop bp
- ret
- Public _ms_x_curdir
- ;-----------
- _ms_x_curdir:
- ;-----------
- push bp
- mov bp,sp
- push si
- mov si,6[bp] ; Get the buffer address and
- mov byte ptr [si],0 ; put a zero in the first byte in
- mov ah,MS_X_CURDIR ; the command is FAILED
- push word ptr 4[bp]
- call ms_dx_call
- pop dx
- pop si
- pop bp
- ret
- Public _ms_x_exit
- ;---------
- _ms_x_exit:
- ;---------
- push bp
- mov bp,sp
- ifdef NETWARE
- push es ; If this is Novell Netware and
- mov ax,__psp ; the command processor is terminating
- mov es,ax ; ie PSP_PARENT == PSP then do the
- cmp ax,es:word ptr 16h ; special Novell Close down sequence
- pop es
- jnz ms_x_exit10
- mov ax,7A00h ; Check for IPX being present using
- int 2Fh ; the Multi-Plex Interrupt.
- cmp al,0FFh
- jz net_ware
- ms_x_exit10:
- endif
- mov al,04[bp] ; Get the Return Code
- mov ah,MS_X_EXIT ; terminate process function
- int DOS_INT ; call the DOS
- pop bp
- ret
- ifdef NETWARE
- ;
- ; The following routine attempts to clean-up after a Novell
- ; session. It does so in the following manner:-
- ;
- ; 1) Close all file handles (May be Networked !!)
- ; 2) Close all User Sockets
- ; 3) Remove all User Events from Internal lists
- ; 4) Use CDOS terminate function
- ;
- net_ware:
- mov ipx_offset,di
- mov ipx_segment,es
- mov cx,20 ; Close all the possible handles
- mov bx,0 ; used by the command processor
- net_w05: ; in case any have been redirected
- mov ah,MS_X_CLOSE ; accross the Network
- int DOS_INT
- inc bx
- loop net_w05
- mov si,dataOFFSET socket
- net_w10:
- mov cx,word ptr 02[si] ; Get the number of sockets to close
- mov dx,word ptr 00[si] ; starting at Socket No.
- jcxz net_w30 ; Terminate on a 0 Count
- push si
- net_w20:
- push cx
- push dx ; Save Count and Socket No.
- xchg dl,dh ; Swap socket no to High/Low
- mov bx,1 ; Close Socket Function
- call ipx ; Close Socket.
- pop dx
- pop cx
- inc dx ; Increment Socket No
- loop net_w20 ; and Loop
- pop si
- add si,4 ; Point to next entry in the array
- jmp net_w10 ; and repeat till count is 0
- net_w30: ; All sockets have been closed
- mov aes_esrseg,cs
- mov ax,0FFFFh ; Create Special event with the
- mov bx,7 ; maximum time delay
- push ds
- pop es ; Pass the address of the Special
- mov si,dataOFFSET aes ; Event control block call the IPX
- call ipx
- net_w40:
- les si,aes_link ; Remove all entries from the Link
- ; Which are not owned by the IPX
- net_w50:
- mov bx,es ; get the AES segment
- cmp bx,ipx_segment ; and check for a match
- jnz net_w60 ; Remove this entry
- les si,es:dword ptr [si] ; get the next entry and try again
- jmp short net_w50
- net_w60:
- or bx,si ; End of List
- jz net_w70 ; Yes terminate our entry
- mov bx,0006h ; Cancel this event
- call ipx
- jmp short net_w40
- net_w70:
- mov bx,0006h ; Cancel our event
- push ds
- pop es
- mov si,dataOFFSET aes
- call ipx
- net_exit:
- mov dh,0 ; Standard Exit
- mov dl,04[bp] ; With the supplied ExitCode
- mov cx,P_EXITCODE ; Set the ExitCode for the Parent
- int BDOS_INT
- mov cx,P_TERMCPM ; Use a Concurrent Terminate Call
- int BDOS_INT ; because Novell has taken over 4Ch
- aes_retf: ; Dummy AES routine
- retf
- endif
- ;
- ; ms_x_expand(dstbuf, srcbuf) returns the full path of SRCBUF
- ;
- Public _ms_x_expand
- ;-----------
- _ms_x_expand:
- ;-----------
- push bp
- mov bp,sp
- push si
- push di
- mov si,06[bp] ; Get the source String Address
- mov di,04[bp] ; Get the destination string
- mov byte ptr [di],0 ; address and force it to be a NULL
- push ds
- pop es ; ES:DI -> destination
- mov ah,60h ; terminated string in case of errors
- int DOS_INT
- jc ms_exp_ret ; skip if error
- xor ax,ax ; signal no errors
- ms_exp_ret:
- neg ax ; make error negative, 0 = 0
- pop di
- pop si
- pop bp
- CRET 4
- Public _ms_x_wait
- ;---------
- _ms_x_wait: ; retrieve child return code
- ;---------
- mov ah,MS_X_WAIT ; Top byte is abort code ie ^C
- int DOS_INT ; Bottom byte is return code
- ret
- Public _ms_x_first
- ;----------
- _ms_x_first:
- ;----------
- push bp
- mov bp,sp
- mov dx,8[bp] ; get DMA buffer address
- mov ah,MS_F_DMAOFF
- int DOS_INT
- mov dx,4[bp] ; get ASCII string
- mov cx,6[bp] ; get attribute
- mov ah,MS_X_FIRST ; get search function
- jmp ms_call_dos ; call DOS, check for errors
- Public _ms_x_next
- ;---------
- _ms_x_next:
- ;---------
- push bp
- mov bp,sp
- mov dx,4[bp] ; get DMA buffer address
- mov ah,MS_F_DMAOFF
- int DOS_INT
- mov ah,MS_X_NEXT ; get the function
- jmp ms_call_dos ; get DX, call DOS, handle errors
- ms_dx_call: ; call DOS with parameter in DX
- push bp
- mov bp,sp
- mov dx,4[bp]
- ms_call_dos:
- int DOS_INT
- jnc ms_dos_ok ; no carry = no error
- neg ax ; else make it negative
- jmp ms_dos_ret ; and return with error
- ms_dos_ok:
- sub ax,ax ; return 0 if no error
- ms_dos_ret:
- pop bp ; return 0 or negative error code
- ret
- Public _ms_x_rename
- ;-----------
- _ms_x_rename:
- ;-----------
- push bp
- mov bp,sp
- push di
- push ds
- pop es
- mov ah,MS_X_RENAME
- mov di,6[bp] ; ES:DI = new name
- push word ptr 4[bp] ; make it look like DRC call
- call ms_dx_call ; DX = 4[bp], call DOS, handle errors
- pop di ; remove parameter
- pop di
- pop bp
- ret
- Public _ms_x_datetime
- ; ret = _ms_x_datetime (gsflag, h, &time, &date);
- ;-------------
- _ms_x_datetime:
- ;-------------
- push bp
- mov bp,sp
- mov ah,MS_X_DATETIME ; set/get time stamp function
- mov al,4[bp] ; get/set subfunction (0/1)
- mov bx,8[bp] ; get address of time
- mov cx,[bx] ; get time
- mov bx,10[bp] ; get address of date
- mov dx,[bx] ; get date
- mov bx,6[bp] ; get handle
- int DOS_INT ; call the DOS
- jc ms_dt_ret ; skip if error
- sub ax,ax ; signal no errors
- cmp byte ptr 4[bp],0 ; geting time/date?
- jne ms_dt_ret ; skip if setting
- mov bx,8[bp] ; get time address
- mov [bx],cx ; update time
- mov bx,10[bp] ; get date address
- mov [bx],dx ; update date
- ms_dt_ret:
- neg ax ; make error negative, 0 = 0
- pop bp
- ret
- ;
- ; The following routines allow COMMAND.COM to manipulate
- ; the system time and date. Four functions are provided and
- ; these are MS_GETDATE, MS_SETDATE, MS_GETTIME and MS_SETTIME
- ;
- ; Date information is passed and return in a structure which
- ; has the following format.
- ;
- ; WORD Year (1980 - 2099)
- ; BYTE Month
- ; BYTE Day
- ; BYTE Day of the Week (Ignored on SET DATE)
- Public _ms_getdate
- _ms_getdate:
- push bp
- mov bp,sp
- mov ah,MS_T_GETDATE ; get the current date from DOS
- int DOS_INT
- mov bx,4[bp] ; and get the structure address
- mov [bx],cx ; save the year
- xchg dh,dl ; swap month and day
- mov 2[bx],dx ; and save
- mov 4[bx],al ; and finally save the day number
- pop bp ; and exit
- ret
- Public _ms_setdate
- _ms_setdate:
- push bp
- mov bp,sp
- mov bx,4[bp] ; and get the structure address
- mov cx,0[bx] ; det the year
- mov dx,2[bx] ; get the month and day
- xchg dh,dl ; swap month and day
- mov ah,MS_T_SETDATE ; set the current date
- int DOS_INT
- cbw ; 0000 = Ok and FFFF = Bad
- pop bp ; and exit
- ret
- ; Time information is passed and return in a structure which
- ; has the following format.
- ;
- ; BYTE Hours (0 - 23)
- ; BYTE Minutes (0 - 59)
- ; BYTE Seconds (0 - 59)
- ; BYTE Hundredths of a second (0 - 99)
- Public _ms_gettime
- _ms_gettime:
- push bp
- mov bp,sp
- mov ah,MS_T_GETTIME ; get the current date from DOS
- int DOS_INT
- mov bx,4[bp] ; and get the structure address
- xchg cl,ch
- mov [bx],cx ; save the hours and minutes
- xchg dh,dl
- mov 2[bx],dx ; save seconds and hundredths
- pop bp ; and exit
- ret
- Public _ms_settime
- _ms_settime:
- push bp
- mov bp,sp
- mov bx,4[bp] ; and get the structure address
- mov cx,[bx] ; get the hours and minutes
- xchg cl,ch
- mov dx,2[bx] ; get seconds and hundredths
- xchg dh,dl
- mov ah,MS_T_SETTIME ; get the current date from DOS
- int DOS_INT
- cbw ; 0000 = Ok and FFFF = Bad
- pop bp ; and exit
- ret
- Public _ms_idle_ptr
- ;------------
- _ms_idle_ptr:
- ;------------
- push es
- push si
- push di
- mov ax, 4458h
- int DOS_INT ; ptr in ES:AX
- mov dx, es
- pop di
- pop si
- pop es
- ret
- Public _ms_switchar
- ;-----------
- _ms_switchar:
- ;-----------
- mov ax,3700h
- int DOS_INT
- sub ah,ah
- mov al,dl
- ret
- if 0
- Public _ms_p_getpsp
- ;-----------
- _ms_p_getpsp:
- ;-----------
- mov ah,51h ; Note: SeCRET DOS 2.x entry
- int DOS_INT
- xchg ax,bx
- ret
- endif
- Public _ms_f_verify
- ;-----------
- _ms_f_verify:
- ;-----------
- push bp
- mov bp,sp
- mov ah,MS_F_VERIFY
- mov al,4[bp] ;get 0/1 al parameter
- int DOS_INT
- pop bp
- ret
- Public _ms_f_getverify
- ;--------------
- _ms_f_getverify:
- ;--------------
- mov ah,MS_F_GETVERIFY
- int DOS_INT
- cbw
- ret
- ifndef CDOSTMP
- Public _ms_f_parse
- ;-----------
- _ms_f_parse:
- ;-----------
- push bp
- mov bp, sp
- push es
- push si
- push di
- push ds
- pop es
- mov di, 4[bp] ; fcb
- mov si, 6[bp] ; filename
- mov al, 8[bp] ; flags
- mov ah, MS_F_PARSE
- int DOS_INT
- cbw ; return code in ax
- pop di
- pop si
- pop es
- pop bp
- ret
- Public _ms_f_delete
- ;------------
- _ms_f_delete:
- ;------------
- push bp
- mov bp, sp
- mov dx, 4[bp] ; fcb
- mov ah, MS_F_DELETE
- int DOS_INT
- cbw ; return code
- pop bp
- ret
- endif
- ;
- ; The SET BREAK function returns the previous Break Flag Status
- ;
- Public _ms_set_break
- ;------------
- _ms_set_break:
- ;------------
- push bp
- mov bp,sp
- mov dl,04[bp]
- mov ax,(MS_S_BREAK SHL 8) + 2
- int DOS_INT
- pop bp
- mov al,dl
- cbw
- ret
- if 0
- Public _ms_get_break
- ;------------
- _ms_get_break:
- ;------------
- mov ax,MS_S_BREAK SHL 8
- int DOS_INT
- mov al,dl
- cbw
- ret
- endif
- ;
- ; mem_alloc(BYTE FAR * NEAR * bufaddr, UWORD * bufsize, UWORD min, UWORD max);
- ;
- ; max 10[bp]
- ; min 08[bp]
- ; bufsize 06[bp]
- ; buffadr 04[bp]
- ;
- Public _mem_alloc
- ;---------
- _mem_alloc:
- ;---------
- push bp
- mov bp,sp
- mov bx,10[bp] ; Start with request maximum size
- mem_all10:
- mov ah,MS_M_ALLOC ; Attempt to allocate the maximum
- int DOS_INT ; memory requested by the user.
- jnc mem_all20 ; Allocation OK
- cmp bx,08[bp] ; Is this less than the requested
- jae mem_all10 ; No then allocate this amount
- xor ax,ax ; Force the Buffer address and Buffer
- mov bx,ax ; Size to Zero
- mem_all20:
- mov cx,bx ; Save the Buffer Size
- mov bx,04[bp] ; Update the Buffer Address
- mov word ptr 00[bx],0 ; Offset 0
- mov word ptr 02[bx],ax ; Segment AX
- mov bx,06[bp] ; Now Update the Buffer Size
- mov word ptr 00[bx],cx ; and return to the caller
- pop bp
- ret
- ;
- ; mem_free(BYTE FAR * NEAR * bufaddr);
- ;
- ; buffadr 04[bp]
- ;
- Public _mem_free
- ;---------
- _mem_free:
- ;---------
- push bp
- mov bp,sp
- xor ax,ax
- mov bx,04[bp] ; Get the Buffer Pointer address
- xchg ax,word ptr 02[bx] ; and from this the segment of the
- cmp ax,0 ; allocated memory. If the memory
- jz mem_free10 ; has already been freed the quit
- push es ; Otherwise Free the Memory
- mov es,ax
- mov ah,MS_M_FREE
- int DOS_INT
- pop es
- mem_free10:
- pop bp
- ret
- Public _msdos
- ;-------
- _msdos:
- ;-------
- push bp
- mov bp,sp
- push si
- push di
- mov ah,4[bp]
- mov dx,6[bp]
- int DOS_INT
- pop di
- pop si
- pop bp
- ret
- Public _ioctl_ver
- ;---------
- _ioctl_ver:
- ;---------
- ifdef DOSPLUS
- mov ax,4452h ; Get DOS Plus BDOS version Number
- else
- mov ax,4451h ; Get Concurrent BDOS Version
- endif
- int DOS_INT ; Real DOS returns with Carry Set
- jc cdos_v10
- and ax,not 0200h ; Reset the Networking Bit
- ret
- cdos_v10:
- xor ax,ax
- ret
- ifdef DOSPLUS
- ;
- ; Get CodePage information form the system. Return both the currently
- ; active CodePage and the System CodePage.
- ;
- ; ms_x_getcp(&globalcp, &systemcp);
- ;
- Public _ms_x_getcp
- ;-----------
- _ms_x_getcp:
- ;-----------
- push bp
- mov bp,sp
- mov ax,MS_X_GETCP ; Get the CodePage Information
- int DOS_INT ; and return an error if not
- jc ms_x_getcp10 ; supported.
- mov ax,bx ; Now update the callers
- mov bx,04[bp] ; Global and System Codepage
- mov word ptr [bx],ax ; variables
- mov bx,06[bp]
- mov word ptr [bx],dx
- xor ax,ax
- ms_x_getcp10:
- neg ax ; Negate the error code has
- pop bp ; no effect on 0
- ret
- ;
- ; Change the current CodePage
- ;
- ; ms_x_setcp(globalcp);
- ;
- Public _ms_x_setcp
- ;-----------
- _ms_x_setcp:
- ;-----------
- push bp
- mov bp,sp
- mov bx,04[bp] ; Get the requested CodePage
- mov ax,MS_X_SETCP ; and make this the default
- int DOS_INT
- jc ms_x_getcp10
- xor ax,ax
- pop bp
- ret
- endif
- endif
- ifdef CDOSTMP
- Public _ms_drv_set
- ;-----------
- _ms_drv_set:
- ;-----------
- push bp
- mov bp,sp
- mov dl,04[bp] ; Get the Specified drive
- or dl,80h ; Prevent any Select Errors
- mov cl,DRV_SET ; and go select the bugger
- int BDOS_INT
- pop bp
- ret
- Public _ms_drv_get
- ;-----------
- _ms_drv_get:
- ;-----------
- mov cl,DRV_GET ; Return the Currently selected
- int BDOS_INT ; disk drive
- cbw
- ret
- Public _ms_drv_space
- ;------------
- _ms_drv_space:
- ;------------
- ;
- ; ret = _ms_drv_space (drive, &free, &secsiz, &nclust);
- ; where: drive = 0, 1-16 is drive to use
- ; free = free cluster count
- ; secsiz = bytes/sector
- ; nclust = clusters/disk
- ; ret = sectors/cluster -or- (0xFFFFh)
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC, FD_DISKINFO
- mov ax,04[bp]
- mov FD_DRIVE,ax
- call fdos_entry
- or ax,ax ; Check for Errors
- mov ax,0FFFFh
- jnz ms_drv_exit ; Error Exit
- push es ; Save ES
- push di
- les di,FD_DPB ; Get the DPB Address
- mov ax,es:DDSC_FREE[di] ; Get the number of free
- mov bx,06[bp] ; clusters on the drive
- mov [bx],ax
- mov ax,es:DDSC_SECSIZE[di] ; Get the Physical Sector Size
- mov bx,08[bp] ; in bytes
- mov [bx],ax
- mov ax,es:DDSC_NCLSTRS[di] ; Get the disk size in
- mov bx,10[bp] ; clusters and save in DX
- mov [bx],ax
- mov al,es:DDSC_CLMSK[di] ; Get the sectors per Cluster -1
- cbw ; and save in AX
- inc ax
- pop di
- pop es
- ms_drv_exit:
- pop bp
- CRET 8
- Public _ms_s_country
- ;------------
- _ms_s_country:
- ;------------
- push bp
- mov bp,sp
- mov ax,04[bp] ; Get the data Block Offset
- mov cd_country,0 ; Get the Current Country
- mov cd_codepage,0 ; Current CodePage
- mov cd_table,0 ; Country Information
- mov cd_offset,ax ; Save the Buffer Offset
- mov cd_segment,ds ; and the Buffer Segment
- mov dx,dataOFFSET country_data
- mov cl,S_GETCOUNTRY ; Get the country information
- int BDOS_INT ; and return the current country
- pop bp ; code to the caller
- CRET 2
- Public _ms_x_mkdir
- ;----------
- _ms_x_mkdir:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_MKDIR ; Make Directory
- mkdir_10:
- mov ax,04[bp]
- mov FD_NAMEOFF,ax
- mov FD_NAMESEG,ds
- call fdos_entry
- pop bp
- CRET 2
- Public _ms_x_rmdir
- ;----------
- _ms_x_rmdir:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_RMDIR
- jmp mkdir_10
- Public _ms_x_chdir
- ;----------
- _ms_x_chdir:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_CHDIR
- jmp mkdir_10
- Public _ms_x_creat
- ;----------
- _ms_x_creat:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_CREAT
- jmp ms_open_creat
- Public _ms_x_open
- ;---------
- _ms_x_open:
- ;---------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_OPEN
- ms_open_creat:
- mov ax,4[bp]
- mov FD_NAMEOFF,ax
- mov FD_NAMESEG,ds
- mov ax,6[bp] ; get mode for new file (CREAT)
- mov FD_MODE,ax ; or the OPEN mode
- call fdos_entry ; Call the FDOS and return either
- pop bp ; a handle or error code
- CRET 4
- Public _ms_x_close
- ;----------
- _ms_x_close:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov ax,4[bp] ; get the open handle
- mov FD_FUNC,FD_CLOSE
- mov FD_HANDLE,ax
- call fdos_entry
- pop bp
- CRET 2
- Public _ms_x_unique
- ;----------
- _ms_x_unique:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_MKTEMP
- jmp ms_open_creat
- Public _ms_x_fdup
- ;----------
- _ms_x_fdup:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_FDUP
- mov ax,4[bp] ; get the destination handle
- mov FD_NEWHND,ax
- mov ax,6[bp] ; Get the current handle
- mov FD_HANDLE,ax
- call fdos_entry
- pop bp
- CRET 4
- Public _far_read
- ;---------
- _far_read:
- ;---------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_READ
- jmp far_read_write
- Public _far_write
- ;----------
- _far_write:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_WRITE
- far_read_write:
- mov ax,4[bp] ; get file handle
- mov FD_HANDLE,ax
- mov ax,6[bp] ; get buffer offset address
- mov FD_BUFOFF,ax
- mov ax,8[bp] ; get buffer Segment address
- mov FD_BUFSEG,ax
- mov ax,10[bp] ; get byte count
- mov FD_COUNT,ax
- call fdos_entry
- or ax,ax
- jnz far_rw_fail
- mov ax,FD_COUNT ; Get the Byte Count
- far_rw_fail:
- pop bp
- CRET 6
- Public _ms_x_read
- ;---------
- _ms_x_read:
- ;---------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_READ
- jmp ms_read_write
- Public _ms_x_write
- ;----------
- _ms_x_write:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_WRITE
- ms_read_write:
- mov ax,4[bp] ; get file handle
- mov FD_HANDLE,ax
- mov ax,6[bp] ; get buffer address
- mov FD_BUFOFF,ax
- mov FD_BUFSEG,ds
- mov ax,8[bp] ; get byte count
- mov FD_COUNT,ax
- call fdos_entry
- or ax,ax
- jnz ms_rw_fail
- mov ax,FD_COUNT ; Get the Byte Count
- ms_rw_fail:
- pop bp
- CRET 6
- Public _ms_x_unlink
- ;-----------
- _ms_x_unlink:
- ;-----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_UNLINK
- jmp mkdir_10
- Public _ms_x_lseek
- ;----------
- _ms_x_lseek:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_LSEEK ; get the function
- mov ax,4[bp] ; get the file handle
- mov FD_HANDLE,ax
- mov ax,6[bp] ; get the offset
- mov word ptr FD_OFFSET+0,ax
- mov ax,8[bp]
- mov word ptr FD_OFFSET+2,ax
- mov ax,10[bp] ; get the seek mode
- mov FD_METHOD,ax
- call fdos_entry
- cwd
- or ax,ax
- jnz ms_lseek_fail ; skip if errors
- mov ax,word ptr FD_OFFSET+0 ; Return the New Location
- mov dx,word ptr FD_OFFSET+2
- ms_lseek_fail:
- mov bx,dx ; AX:BX = DRC long return
- pop bp
- CRET 8
- Public _ms_x_ioctl
- ;----------
- _ms_x_ioctl:
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov ax,4[bp] ; get Enquiry Handle
- mov FD_FUNC,FD_IOCTL ; Use the IOCTL function
- mov FD_HANDLE,ax ; For Handle AX
- mov FD_CTLFUNC,0000 ; Get the Handle Status
- mov FD_CTLSTAT,0 ; Invalidate CTLSTAT
- call fdos_entry ; Call the FDOS
- mov ax,FD_CTLSTAT ; and return the STATUS
- pop bp
- CRET 2
- Public _ms_x_setdev
- ;------------
- _ms_x_setdev:
- ;------------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov ax,4[bp] ; get Handle
- mov FD_HANDLE,ax
- mov FD_FUNC,FD_IOCTL ; Use the IOCTL function
- mov FD_CTLFUNC,1 ; Set device info
- mov ax, 6[bp] ; status to set
- sub ah, ah
- mov FD_CTLSTAT,ax
- call fdos_entry ; Call the FDOS
- mov ax,FD_CTLSTAT ; and return the STATUS
- pop bp
- CRET 2
- Public _ms_x_chmod
- ;----------
- _ms_x_chmod: ; ms_x_chmod(path, attrib, get/set)
- ;----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_CHMOD
- mov ax,4[bp] ; Get the FileName
- mov FD_NAMEOFF,ax
- mov FD_NAMESEG,ds
- mov ax,6[bp] ; Get the Required Attributes
- mov FD_ATTRIB,ax
- mov ax,8[bp] ; Finally Get the GET/SET flag
- mov FD_FLAG,ax
- call fdos_entry ; Returns with AX equal to the
- or ax,ax ; error code or with the file
- js chmod10 ; attributes.
- mov ax,FD_ATTRIB
- chmod10:
- pop bp
- CRET 6
- Public _ms_x_curdir
- ;-----------
- _ms_x_curdir:
- ;-----------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_GETDIR
- mov ax,04[bp] ; Get the drive
- mov FD_DRIVE,ax
- mov bx,06[bp] ; and then the path
- mov byte ptr [bx],0 ; Put a Zero byte in the buffer in
- mov FD_PATHOFF,bx ; case the command fails and the
- mov FD_PATHSEG,ds ; user selects the FAIL Option
- call fdos_entry
- pop bp
- CRET 4
- ;
- ; ms_x_expand(dstbuf, srcbuf) returns the full path of SRCBUF
- ;
- Public _ms_x_expand
- ;-----------
- _ms_x_expand:
- ;-----------
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_EXPAND
- mov ax,06[bp] ; Get Source Buffer Offset
- mov FD_ONAMEOFF,ax
- mov FD_ONAMESEG,ds
- mov bx,04[bp] ; Get the destination string
- mov byte ptr [bx],0 ; address and force it to be a NULL
- mov FD_NNAMEOFF,bx ; terminated string in case of errors
- mov FD_NNAMESEG,ds
- call fdos_entry
- pop bp
- CRET 4
- Public _ms_x_wait
- ;---------
- _ms_x_wait: ; retrieve child return code
- ;---------
- mov cl,P_EXITCODE ; Return the Exit Code
- mov dx,0FFFFh ; Get the Exit Code
- int BDOS_INT
- CRET 0
- Public _ms_x_first
- ;----------
- _ms_x_first:
- ;----------
- push bp
- mov bp,sp
- mov dx,8[bp] ; get DMA buffer address
- mov cl,F_DMAOFF
- call bdos_entry
- mov dx,ds ;##jc##
- mov cl,F_DMASEG ;##jc##
- call bdos_entry ;##jc##
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_FFIRST ; Search First
- mov ax,04[bp] ; Get the FileName
- mov FD_NAMEOFF,ax
- mov FD_NAMESEG,ds
- mov ax,06[bp] ; Get the Attributes
- mov FD_ATTRIB,ax
- mov FD_COUNT, 0 ; Search for a File at a time
- call fdos_entry
- cmp ax,1 ; Did we match 1 entry
- jnz ms_x_f10 ; No so return Error Code
- mov ax,0 ; Return Zero on sucess
- ms_x_f10:
- pop bp
- CRET 6
- Public _ms_x_next
- ;---------
- _ms_x_next:
- ;---------
- push bp
- mov bp,sp
- mov dx,4[bp] ; get DMA buffer address
- mov cl,F_DMAOFF
- call bdos_entry
- mov dx,ds ;##jc##
- mov cl,F_DMASEG ;##jc##
- call bdos_entry ;##jc##
- mov al,OK_RF ; Retry or Fail
- call fdos_retry
- mov FD_FUNC,FD_FNEXT ; Search Next
- mov FD_NEXTCNT, 0 ; Search for a File at a time
- call fdos_entry
- cmp ax,1 ; Did we match 1 entry
- jnz ms_x_n0 ; No so return Error Code
- mov ax,0 ; Return Zero on sucess
- ms_x_n0:
- pop bp
- CRET 2
- Public _ms_x_rename
- ;-----------
- _ms_x_rename:
- ;-----------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_RENAME
- mov ax,04[bp] ; Get the Old Name
- mov FD_ONAMEOFF,ax
- mov FD_ONAMESEG,ds
- mov ax,06[bp] ; Get the New Name
- mov FD_NNAMEOFF,ax
- mov FD_NNAMESEG,ds
- call fdos_entry
- pop bp
- CRET 4
- Public _ms_x_datetime
- ;-------------
- _ms_x_datetime: ; ms_x_datetime (gsflag, h, &time, &date);
- ;-------------
- push bp
- mov bp,sp
- mov al,OK_RIF ; Retry, Ignore or Fail
- call fdos_retry
- mov FD_FUNC,FD_DATETIME ; set/get Time Stamp
- mov ax,4[bp] ; get/set subfunction (0/1)
- mov FD_SFLAG,ax
- mov ax,6[bp] ; get handle
- mov FD_HANDLE,ax
- mov bx,8[bp] ; get address of time
- mov ax,[bx] ; get time
- mov FD_TIME,ax ; and Save
- mov bx,10[bp] ; get address of date
- mov ax,[bx] ; get date
- mov FD_DATE,ax
- call fdos_entry
- or ax,ax ; Skip if Failed
- jnz ms_dt_ret
- mov ax,FD_TIME
- mov bx,8[bp] ; get time address
- mov [bx],ax ; update time
- mov ax,FD_DATE
- mov bx,10[bp] ; get date address
- mov [bx],ax ; update date
- xor ax,ax
- ms_dt_ret:
- pop bp
- CRET 8
- ;
- ; The following routines allow COMMAND.COM to manipulate
- ; the system time and date. Four functions are provided and
- ; these are GETDATE, SETDATE, GETTIME and SETTIME
- ;
- ; Date information is passed and return in a structure which
- ; has the following format.
- ;
- ; WORD Year (1980 - 2099)
- ; BYTE Month
- ; BYTE Day
- ; BYTE Day of the Week (Ignored on SET DATE)
- Public _ms_getdate
- ;-----------
- _ms_getdate:
- ;-----------
- push bp
- mov bp,sp
- mov dx,04[bp] ; Get the structure address
- mov cl,T_GETDATE ; and call the BDOS
- call bdos_entry
- pop bp
- CRET 2
- Public _ms_setdate
- ;----------
- _ms_setdate:
- ;----------
- push bp
- mov bp,sp
- mov dx,4[bp] ; and get the structure address
- mov cl,T_SETDATE ; and call the BDOS to do the work
- call bdos_entry ; Return 0 Good and FFFF Bad
- pop bp
- CRET 2
- ; Time information is passed and return in a structure which
- ; has the following format.
- ;
- ; BYTE Hours (0 - 23)
- ; BYTE Minutes (0 - 59)
- ; BYTE Seconds (0 - 59)
- ; BYTE Hundredths of a second (0 - 99)
- Public _ms_gettime
- ;----------
- _ms_gettime:
- ;----------
- push bp
- mov bp,sp
- mov dx,04[bp] ; Get the Time Structure address
- mov cl,T_GETTIME ; and call the OS
- call bdos_entry
- pop bp
- CRET 2
- Public _ms_settime
- ;----------
- _ms_settime:
- ;----------
- push bp
- mov bp,sp
- mov dx,4[bp] ; and get the structure address
- mov cl,T_SETTIME ; and call the BDOS SET Time Function
- call bdos_entry ; Return 0 Good and FFFF Bad
- pop bp
- CRET 2
- Public _ms_f_verify
- ;-----------
- _ms_f_verify:
- ;-----------
- push bp
- mov bp,sp
- push es
- mov ax,04[bp] ; Get the required state
- les bx,_pd ; Update the Verify flag in
- and es:P_SFLAG[bx],not PSF_VERIFY ; current PD
- or ax,ax ; Set the Flag
- jz ms_fv10 ; No
- or es:P_SFLAG[bx],PSF_VERIFY ; Flag set in PD
- ms_fv10:
- pop es
- pop bp
- ret
- Public _ms_f_getverify
- ;--------------
- _ms_f_getverify:
- ;--------------
- push es
- xor ax,ax ; Assume the flag is RESET
- les bx,_pd ; now test the state of the
- test es:P_SFLAG[bx],PSF_VERIFY ; flag in the current PD
- jz ms_fgv10 ; Verify = OFF
- inc ax ; Verify = ON
- ms_fgv10:
- pop es
- ret
- ;
- ; mem_alloc(BYTE FAR * NEAR * bufaddr, UWORD * bufsize, UWORD min, UWORD max);
- ;
- ; max 10[bp]
- ; min 08[bp]
- ; bufsize 06[bp]
- ; buffadr 04[bp]
- ;
- Public _mem_alloc
- ;---------
- _mem_alloc:
- ;---------
- push bp
- mov bp,sp
- mov mpb_start,0
- mov ax,08[bp] ; Get the Minimum and Maximum values
- mov mpb_min,ax ; and fill in the parameter block
- mov ax,10[bp]
- mov mpb_max,ax
- mov mpb_pdadr,0
- mov mpb_flags,0
- mov cx,M_ALLOC ; Call the Concurrent Allocate function
- mov dx,dataOFFSET mpb_start ;
- call bdos_entry
- xor cx,cx ; Assume that the function fails
- mov dx,cx ; and zero the start and size fields
- cmp ax,0
- jnz mem_all10
- mov cx,mpb_min ; Get the Allocation Size
- mov dx,mpb_start ; and the starting segment
- mem_all10:
- mov bx,04[bp] ; Update the Buffer Address
- mov word ptr 00[bx],0 ; Offset 0
- mov word ptr 02[bx],dx ; Segment DX
- mov bx,06[bp] ; Now Update the Buffer Size
- mov word ptr 00[bx],cx ; and return to the caller
- pop bp
- ret
- ;
- ; mem_free(BYTE FAR * NEAR * bufaddr);
- ;
- ; buffadr 04[bp]
- ;
- Public _mem_free
- ;---------
- _mem_free:
- ;---------
- push bp
- mov bp,sp
- xor ax,ax
- mov bx,04[bp] ; Get the Buffer Pointer address
- xchg ax,word ptr 02[bx] ; and from this the segment of the
- cmp ax,0 ; allocated memory. If the memory
- jz mem_free10 ; has already been freed the quit
- mov mfpb_start,ax ; Otherwise Free the Memory
- mov mfpb_res,0
- mov cx,M_FREE
- mov dx,dataOFFSET mfpb_start
- call bdos_entry
- mem_free10:
- pop bp
- ret
- ;
- ; findfile(BYTE *loadpath, UWORD *loadtype)
- ;
- Public _findfile
- _findfile:
- push bp
- mov bp,sp
- mov al,OK_RF ; Retry, Ignore or Fail
- call fdos_retry
- mov ax,word ptr 04[bp]
- mov exec_pathoff,ax
- mov exec_pathseg,ds
- mov cx,P_PATH
- mov dx,dataOFFSET exec_block
- call ppath_entry
- or ax,ax
- jnz ff_error
- mov al,exec_filetype
- cbw
- mov bx,word ptr 06[bp]
- mov word ptr [bx],ax
- xor ax,ax
- ff_error:
- pop bp
- ret
- ;
- fdos_retry:
- xor ah,ah
- mov valid,ax ; Save the Valid Error responses
- pop retry_ip ; Get the return Address
- mov retry_sp,sp ; and Stack Pointer
- jmp retry_ip
- ;
- ; FDOS_ENTRY is an internal function entry point which makes the
- ; F_DOS function call. As the F_DOS data area used by COMMAND.COM
- ; is always FDOS_DATA.
- ;
- ; WORD PASCAL critical_error(error, valid, drive, mode, server);
- ;
- ; critical_error will return an WORD response which (R,I,A,F)
- ; after displaying the appropriate error message and get the
- ; correct response from the user.
- ;
- fdos_entry:
- mov cl,F_DOS
- mov dx,dataOFFSET fdos_data
- ppath_entry:
- call bdos_entry
- cmp ax,ED_LASTERROR ; Did an Error Occur
- jb fdos_exit ; No So Exit OK
- cmp crit_flg,TRUE ; Already in handler
- jz fdos_exit ; Yes Skip Critical Error
- cmp ax,ED_PROTECT ; Is this a Physical Error
- jg fdos_exit ; if so then simulate a
- cmp ax,ED_GENFAIL ; Critical Error by calling
- jge fdos_e05 ; the COMMAND routine Critical
- ; error
- cmp ax,ED_NETPWD ; Now check for DR-NET errors
- jg fdos_exit ; if so then simulate a
- cmp ax,ED_NETLOG ; Critical Error by calling
- jge fdos_e05 ; the COMMAND routine Critical
- ; error
- fdos_exit:
- ret
- fdos_e05:
- push retry_ip ; Save Retry IP and SP and valid
- push retry_sp ; responses
- push valid
- mov crit_flg,TRUE ; Start Critical Section
- mov cx,es ; Save the Segment Regsiter
- push ax ; Save the Error Code
- push valid ; Save the Valid Responses (R,I,F)
- les bx,_pd ; Get the PD address
- mov es,es:P_UDA[bx] ; and then the UDA address
- xor ah,ah ; Zero the top byte of AX and
- mov al,es:byte ptr 15h ;;U_ERR_DRV ; Get the Failing Drive
- push ax ; Save on the Stack
- mov al,es:byte ptr 14h ;;U_ERR_RW ; Get the Error Mode
- push ax ; and Save
- mov ax,00FFH ; Default Server NO is (INVALID)
- les bx,_pd ; Get the PD address Again
- mov bx,es:P_NDA[bx] ; and then the NDA address
- cmp bx,0 ; Are we attached to DR-NET
- jz fdos_e08 ; NO
- mov es,bx ; ES -> DR-Net NDA
- mov al,es:byte ptr 0Ch ;; NDA_CXRTN
- fdos_e08:
- push ax ; Pass the DR-NET Server No.
- mov es,cx ; Restore ES
- call CRITICAL_ERR ; Handle the Critical Error. Parameters
- ; are removed by the CALLEE
- mov crit_flg,FALSE ; Critical Section complete
- pop valid ; Restore our original RETRY IP
- pop retry_sp ; and SP values which have been
- pop retry_ip ; corrupted by the "CRITICAL_ERROR"
- ; routine during message printing
- cmp ax,0 ; Ignore the Error
- jz fdos_exit ; Then Exit with no Error
- cmp ax,1 ; Retry the Operation
- jnz fdos_e10 ; using information saved by FDOS_RETRY
- mov sp,retry_sp ; Reset the Stack Pointer
- jmp retry_ip ; and retry the Operation
- fdos_e10:
- cmp ax,3 ; FAIL this function
- mov ax,ED_FAIL ; Fail the function
- jz fdos_exit ; Yes otherwise ABORT
- call _int_break ; Simulate a Control C to terminate
- ; We are never coming back
- ;
- ; BDOS_ENTRY is the usual method of calling the Operating System.
- ; In order to provide a DOS compatible environment this function.
- ; does Control-C checking on function exit.
- ;
- bdos_entry:
- int BDOS_INT
- push es
- les bx,_pd ; Get our process descriptor address
- test es:P_SFLAG[bx],PSF_CTLC ; Check if a Control-C has been typed
- jnz bdos_e10 ; Jump to Abort Handler
- mov bx,ax ; Restore BX and Return.
- pop es
- ret
- bdos_e10:
- and es:P_SFLAG[bx],not PSF_CTLC
- pop es
- bdos_e20:
- mov cl,C_RAWIO ; Flush the Character buffer until
- mov dl,0FFh ; Return the character or 00 if queue
- int BDOS_INT ; is empty. Repeat till the Keyboard
- or al,al ; Buffer has been flushed
- jnz bdos_e20
- push ds
- push cs
- pop ds
- mov cl,C_WRITESTR
- mov dx,offset break_str ; echo ^C to screen
- int BDOS_INT
- pop ds
- call _int_break ; Place the Control Break Code on the
- ; Stack and the call the error handler
- ; ** We will never return **
- break_str db '^C$'
- endif
- ifndef DOSPLUS
- Public __BDOS
- ;-------
- __BDOS:
- ;-------
- push bp
- mov bp,sp
- push si
- push di
- mov cl,4[bp]
- mov dx,6[bp]
- int BDOS_INT
- pop di
- pop si
- pop bp
- ret
- ;
- endif
- ifdef DOSPLUS
- ifndef EXT_SUBST
- Public _physical_drvs ; Physical Drives returns a LONG
- _physical_drvs: ; Vector with bits set for every drive
- mov ax,0 ; start with drive A:
- mov cx,16 ; check the first 16 drives
- mov bx,0
- p_d10:
- push ax ; pass drive no. to _physical_drive
- call _physical_drive ; call it
- cmp ax,0 ; check return value
- pop ax ; restore ax
- jz p_d20 ; if zero skip setting the bit in
- or bx,1 ; the bitmap
- p_d20:
- ror bx,1 ; shift bitmap right
- inc ax ; next drive
- loop p_d10 ; Loop 16 Times
- mov cx,10 ; Finally check the last 10 drives
- mov dx,0
- p_d30:
- push ax ; pass drive no. to _physical_drive
- call _physical_drive ; call it
- cmp ax,0 ; check return val
- pop ax ; restore ax
- jz p_d40 ; id zero skip setting the bit in
- or dx,1 ; the bitmap
- p_d40:
- ror dx,1 ; shift bitmap right
- inc ax ; next drive
- loop p_d30 ; Loop 10 Times
- mov cl,6 ; Now rotate the contents of
- ror dx,cl ; DX 6 more times for correct
- ; alignment of the Physical Drive Vector
- mov ax,bx
- mov bx,dx ; Return the long value in both
- ; AX:BX and AX:DX
- ret
- Public _logical_drvs ; Logical Drives returns a LONG
- _logical_drvs: ; vector with bits set for every
- mov cx,16 ; check the first 16 drives
- mov ax,0 ; start with drive A:
- mov bx,ax
- l_d10:
- push ax ; pass the drive to _logical_drive
- call _logical_drive ; call it
- cmp ax,0 ; check return value
- pop ax ; restore ax
- jz l_d20 ; skip if zero return
- or bx,1 ; set bit in bitmap
- l_d20:
- ror bx,1 ; shift bitmap right
- inc ax ; next drive
- loop l_d10 ; Loop 16 Times
- mov cx,10 ; Finally check the last 10 drives
- mov dx,0
- l_d30:
- push ax ; pass the drive to _logical_drive
- call _logical_drive ; call it
- cmp ax,0 ; check return value
- pop ax ; restore ax
- jz l_d40 ; skip if zero return
- or dx,1 ; set bit in bitmap
- l_d40:
- ror dx,1 ; shift bitmap right
- inc ax ; next drive
- loop l_d30 ; Loop 10 Times
- mov cl,6 ; Now rotate the contents of
- ror dx,cl ; DX 6 more times for correct
- ; alignment of bits
- mov ax,bx
- mov bx,dx ; Return the long value in both
- ret ; AX:BX and AX:DX
- Public _network_drvs ; Network Drives returns a LONG
- _network_drvs: ; vector with bits set for every drive
- xor ax,ax ; Start with BX:AX as
- mov bx,ax ; zeros.
- mov cx,'Z'-'A' ; We look at drives A-Z
- n_d10:
- add ax,ax ; we move the dword vector
- adc bx,bx ; one place left
- push ax
- push bx ; save the vector
- mov ah,MS_X_IOCTL
- mov al,9 ; is device local ?
- mov bl,cl ; drive number in BL
- int DOS_INT
- pop bx
- pop ax ; recover the vector
- jc n_d20 ; if an error skip network bit
- test dx,1000h ; is device local ?
- jz n_d20 ; if not then
- or ax,1 ; set bit for this drive
- n_d20:
- loop n_d10
- mov dx,bx ; long value in both AX:BX and AX:DX
- ret
- public _physical_drive
- _physical_drive PROC NEAR
- ; BOOLEAN physical_drive(WORD);
- ; returns true if given drive (0-25) is physical.
- ;
- push bp
- mov bp,sp
- push ds
- push es
- push si
- push di
- push dx
- push cx
- push bx
- mov bx,4[bp] ; get the drive number
- inc bx ; A=1, B=2, etc
- mov ax,4409h ; IOCTL Network/Local
- int 21h ; do it
- jc not_phys ; carry means invalid drive
- and dx,1000h ;
- cmp dx,0
- jne not_phys ; its a network drive
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov si,offset func60_in
- mov di,offset func60_out
- mov ax,4[bp] ; insert drive letter in input string
- add al,'A'
- mov [si],al ;
- mov ah,60h ; Expand Path string
- int 21h ; do it
- jc not_phys ; carry set means invalid drive
- mov ax,4[bp] ; if drive letter changes then drive is
- add al,'A' ; substed
- cmp al,cs:[func60_out]
- jne not_phys
- mov ax,-1
- jmp phys_exit
- not_phys:
- mov ax,0
- phys_exit:
- pop bx
- pop cx
- pop dx
- pop di
- pop si
- pop es
- pop ds
- pop bp
- ret
- func60_in db "d:con",0
- func60_out db 0,0,0,0,0,0,0,0,0,0
- _physical_drive ENDP
- ;
- ; This function translates a logical to physical drive.
- ;
- Public _pdrive
- ;------
- _pdrive:
- ;------
- push bp
- mov bp,sp
- push ds
- push es
- push si
- push di
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov si,offset func60_in
- mov di,offset func60_out
- mov ax,4[bp] ; insert drive letter in input string
- add al,'A'
- mov [si],al
- mov ah,60h ; Expand Path string
- int 21h ; do it
- mov ax,4[bp] ; assume invalid, hence no change
- jc pdrive_exit ; carry set means invalid drive
- mov al,cs:[func60_out]
- sub al,'A'
- pdrive_exit:
- pop di
- pop si
- pop es
- pop ds
- pop bp
- CRET 2
- public _logical_drive
- _logical_drive PROC NEAR
- ; BOOLEAN logical_drive(WORD);
- ; returns TRUE if given drive (0-25) is logical
- ;
- push bp
- mov bp,sp
- push ds
- push es
- push si
- push di
- push dx
- push cx
- push bx
- mov bx,4[bp] ; get the drive number
- inc bx ; A=1, B=2, etc
- mov ax,4409h ; IOCTL Network/Local
- int 21h ; do it
- jc not_logical ; carry means invalid drive
- and dx,1000h ;
- cmp dx,0
- jne not_logical ; its a network drive
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov si,offset func60_in
- mov di,offset func60_out
- mov ax,4[bp] ; insert drive letter in input string
- add al,'A'
- mov [si],al ;
- mov ah,60h ; Expand Path string
- int 21h ; do it
- jc not_logical ; carry set means invalid drive
- mov ax,4[bp] ; if drive letter changes then drive is
- add al,'A' ; substed
- cmp al,cs:[func60_out]
- je not_logical
- mov ax,-1
- jmp logical_exit
- not_logical:
- mov ax,0
- logical_exit:
- pop bx
- pop cx
- pop dx
- pop di
- pop si
- pop es
- pop ds
- pop bp
- ret
- _logical_drive ENDP
- public _network_drive
- _network_drive PROC NEAR
- ; BOOLEAN network_drive(WORD);
- ; returns TRUE if given drive (0-25) is networked
- ;
- push bp
- mov bp,sp
- push dx
- push cx
- push bx
- mov bx,4[bp] ; get the drive number
- inc bx ; A=1, B=2, etc
- mov ax,4409h ; IOCTL Network/Local
- int 21h ; do it
- jc not_networked ; carry means invalid drive
- and dx,1000h ;
- cmp dx,0
- jne not_networked ; its a network drive
- mov ax,-1
- jmp network_exit
- not_networked:
- mov ax,0
- network_exit:
- pop bx
- pop cx
- pop dx
- pop bp
- ret
- _network_drive ENDP
- endif ;EXT_SUBST
- else ;!DOSPLUS
- Public _physical_drvs ; Physical Drives returns a LONG
- _physical_drvs: ; Vector with bits set for every
- mov cx,DRV_LOGINVEC ; Physical or Networked Drive
- int BDOS_INT ; attached to the system
- xor dx,dx ; Return the LONG value in both
- mov bx,dx ; AX:DX and AX:BX for maximum
- ret ; compatibility
- Public _network_drvs ; Network Drives returns a LONG
- _network_drvs: ; vector with bits set for every
- push es ; physical drive which has been
- mov ax,0 ; mapped to a remote DRNET server
- mov dx,ax
- les bx,_pd ; Get Our Process Descriptor
- mov cx,es:P_NDA[bx] ; and then the NDA Segment
- jcxz n_d20 ; Skip Drive Test if no NDA
- mov es,cx ; Get the RCT Address
- les bx,es:dword ptr 04h ;; NDA_RCT ; From the NDA
- mov cx,16
- n_d10:
- test es:RCT_DSK[bx],080h ; Is this a Remote drive
- jz n_d15 ; No
- or ax,1 ; Set Drive Bit
- n_d15:
- ror ax,1 ; Rotate Drive Bit Vector
- add bx,2 ; Update the Drive Pointer
- loop n_d10 ; Loop Till Done
- n_d20:
- mov bx,dx ; Return the long value in both
- pop es ; AX:BX and AX:DX
- ret
- ifndef EXT_SUBST
- Public _logical_drvs ; Logical Drives returns a LONG
- _logical_drvs: ; vector with bits set for every
- push es
- push si
- push di
- les si,_pd ; Get Our Process Descriptor
- mov si,es:P_CAT[si] ; and then the address of the
- mov cx,16 ; first HDS and check the first
- mov ax,0 ; 16 Drives
- mov bx,ax
- l_d10:
- mov di,es:word ptr [si] ; Has this drive got an HDS
- test di,di ; then skip setting the bit in
- jz l_d20 ; the vector register
- cmp es:byte ptr [di],bl ; Is the HDS pointing to same drive
- jz l_d20 ; Yes then this is a Physical Drive
- or ax,1
- l_d20:
- ror ax,1
- add si,2
- inc bx
- loop l_d10 ; Loop 16 Tines
- mov cx,10 ; Finally check the last 10 HDS
- mov dx,0
- l_d30:
- mov di,es:word ptr [si] ; Has this drive got an HDS
- test di,di ; then skip setting the bit in
- jz l_d40 ; the vector register
- cmp es:byte ptr [di],bl ; Is the HDS pointing to same drive
- jz l_d40 ; Yes then this is a Physical Drive
- or dx,1
- l_d40:
- ror dx,1
- add si,2
- inc bx
- loop l_d30 ; Loop 10 Tines
- mov cl,6 ; Now rotate the contents of
- ror dx,cl ; DX 6 more times for correct
- ; alignment of bits
- pop di
- pop si
- pop es
- mov bx,dx ; Return the long value in both
- ret ; AX:BX and AX:DX
- ;
- ; This function use the CONCURRENT 5.xx CP/M function to translate
- ; a logical to physical drive.
- ;
- Public _pdrive
- ;------
- _pdrive:
- ;------
- push bp
- mov bp,sp
- mov dl,4[bp] ; get the logical drive
- mov cl,175 ; Logical to Physical Xlat
- int BDOS_INT
- cbw
- pop bp
- CRET 2
- endif ;!EXT_SUBST
- endif ;!DOSPLUS
- Public _toupper
- UCASE equ 18 ; offset of dword ptr to uppercase func
- ;-------
- _toupper proc near
- ;-------
- ; Return the uppercase equivilant of the given character.
- ; The uppercase function defined in the international info block is
- ; called for characters above 80h.
- ;
- ; char ch; char to be converted
- ; char result; uppercase equivilant of ch
- ;
- ; result = toupper(ch);
- push bp
- mov bp, sp
- mov ax, 4[bp]
- mov ah, 0 ; al = character to be converted
- cmp al, 'a' ; al < 'a'?
- jb exit_toupper ; yes - done (char unchanged)
- cmp al, 'z' ; al <= 'z'?
- jbe a_z ; yes - do ASCII conversion
- cmp al, 80h ; international char?
- jb exit_toupper ; no - done (char unchanged)
- ; ch >= 80h -- call international routine
- call dword ptr [_country+UCASE]
- jmp exit_toupper
- a_z:
- ; 'a' <= ch <= 'z' -- convert to uppercase ASCII equivilant
- and al, 0DFh
- exit_toupper:
- pop bp
- ret
- _toupper endp
- ifdef DOSPLUS
- if 0
- Public _hiload_status
- ;----------
- _hiload_status:
- ;----------
- push bp
- mov bp,sp
- mov dx,100h ; get hiload state
- mov ax,(MS_X_IOCTL*256)+57h ; IO Control function
- int DOS_INT ; do INT 21h
- pop bp ;
- ret
- Public _hiload_set
- ;----------
- _hiload_set:
- ;----------
- push bp
- mov bp,sp
- mov dx,4[bp] ; get state
- mov dh,2 ; set hiload state
- mov ax,(MS_X_IOCTL*256)+57h ; IO Control function
- int DOS_INT ; do INT 21h
- pop bp ;
- ret
- endif
- Public _get_upper_memory_link
- _get_upper_memory_link:
- mov ax,5802h
- int 21h
- cbw
- ret
- Public _set_upper_memory_link
- _set_upper_memory_link:
- push bp
- mov bp,sp
- mov bx,4[bp]
- mov ax,5803h
- int 21h
- pop bp
- ret
- Public _get_alloc_strategy
- _get_alloc_strategy:
- mov ax,5800h
- int 21h
- ret
- Public _set_alloc_strategy
- _set_alloc_strategy:
- push bp
- mov bp,sp
- mov bx,4[bp]
- mov ax,5801h
- int 21h
- pop bp
- ret
- Public _alloc_region
- _alloc_region:
- push es
- xor ax,ax
- mov es,ax ; assume no block allocated
- mov ah,MS_M_ALLOC
- mov bx,1
- int 21h ; allocate a small block
- jc _alloc_region10
- mov es,ax
- mov ah,MS_M_SETBLOCK
- mov bx,0FFFFh
- int 21h ; find out how big the block is
- mov ah,MS_M_SETBLOCK
- int 21h ; now grow to take up the block
- _alloc_region10:
- mov ax,es ; return address of block
- pop es
- ret
- Public _free_region
- _free_region:
- push bp
- mov bp,sp
- push es
- mov es,4[bp]
- mov ah,MS_M_FREE
- int 21h ; free the block
- pop es
- pop bp
- ret
- endif
- ; The Double Byte Character Set lead byte table.
- ; Each entry in the table except the last specifies a valid lead byte range.
- ;
- ; 0 +---------------+---------------+
- ; | start of | end of | DBCS table entry 0
- ; | range 0 | range 0 |
- ; 2 +---------------+---------------+
- ; | start of | end of | DBCS table entry 1
- ; | range 1 | range 1 |
- ; +---------------+---------------+
- ; :
- ; n +---------------+---------------+
- ; | 0 | 0 | end of DBCS table
- ; | | |
- ; +---------------+---------------+
- Public _dbcs_expected
- _dbcs_expected proc near
- ;-------------
- ; Returns true if double byte characters are to be expected.
- ; A call to dbcs_init() MUST have been made.
- ; Entry
- ; none
- ; Exit
- ; ax = 1 - double byte characters are currently possible
- ; 0 - double byte characters are not currently possible
- ifdef DOSPLUS
- push ds
- push si
- lds si, dbcs_table_ptr ; DS:SI -> system DBCS table
- lodsw ; ax = first entry in DBCS table
- test ax, ax ; empty table?
- jz de_exit ; yes - return 0 (not expected)
- mov ax, 1 ; return 1 (yes you can expect DBCS)
- de_exit:
- pop si
- pop ds
- else
- xor ax,ax ; CDOS doesn't support them
- endif
- ret
- _dbcs_expected endp
- Public _dbcs_lead
- _dbcs_lead proc near
- ;---------
- ; Returns true if given byte is a valid lead byte of a 16 bit character.
- ; A call to init_dbcs() MUST have been made.
- ; Entry
- ; 2[bp] = possible lead byte
- ; Exit
- ; ax = 1 - is a valid lead byte
- ; 0 - is not a valid lead byte
- ifdef DOSPLUS
- push bp
- mov bp, sp
- push ds
- push si
- mov bx, 4[bp] ; bl = byte to be tested
- lds si,dbcs_table_ptr ; ds:si -> system DBCS table
- lodsw ; any entries ?
- test ax,ax
- jz dl_not_valid ; no DBC entries
- dl_loop:
- lodsw ; al/ah = start/end of range
- test ax, ax ; end of table?
- jz dl_not_valid ; yes - exit (not in table)
- cmp al, bl ; start <= bl?
- ja dl_loop ; no - try next range
- cmp ah, bl ; bl <= end?
- jb dl_loop ; no - try next range
- mov ax, 1 ; return 1 - valid lead byte
- dl_not_valid:
- pop si
- pop ds
- pop bp
- else
- xor ax,ax ; CDOS doesn't support them
- endif
- ret
- _dbcs_lead endp
- PUBLIC _extended_error
- _extended_error PROC NEAR
- mov ah,59h
- mov bx,0
- int 21h
- neg ax
- ret
- _extended_error ENDP
- PUBLIC _get_lines_page
- _get_lines_page PROC NEAR
- push bp
- push es
- mov ax,1130h
- mov bx,0
- mov dx,24 ; preset dx to 24 in case function not supported
- int 10h
- mov ax,dx ; returns (no. rows)-1 in dx
- inc ax
- pop es
- pop bp
- ret
- _get_lines_page ENDP
- PUBLIC _get_scr_width
- _get_scr_width PROC NEAR
- push bp
- mov ah,0fh
- int 10h
- xor al,al
- xchg ah,al
- pop bp
- ret
- _get_scr_width ENDP
- PUBLIC _novell_copy
- _novell_copy PROC NEAR
- push bp
- mov bp,sp
- push si
- push di
- mov ax,11f0h
- mov si,4[bp] ; si = source handle
- mov di,6[bp] ; di = destination handle
- mov dx,8[bp] ; lo word of source length
- mov cx,10[bp] ; hi word of source length
- clc ; start with carry cleared
- int 2fh ; do it
- jc novcop_failure ; carry set means novell couldn't handle it
- cmp ax,11f0h
- je novcop_failure ; ax hasn't changed, so novell isn't there
- mov ax,1 ; success !
- jmp novcop_exit
- novcop_failure:
- mov ax,0
- novcop_exit:
- pop di
- pop si
- pop bp
- ret
- _novell_copy ENDP
- PUBLIC _call_novell
- _call_novell PROC NEAR
- push bp
- mov bp,sp
- push es
- push si
- push di
- mov ah,8[bp]
- mov al,0ffh
- push ds
- pop es
- mov si,4[bp]
- mov di,6[bp]
- int 21h
- cmp al,0
- jne call_nov_err
- jc call_nov_err
- mov ax,0
- jmp call_nov_exit
- call_nov_err:
- mov ah,0 ;; clear ah, BUT allow all ret' values in al
- call_nov_exit:
- pop di
- pop si
- pop es
- pop bp
- ret
- _call_novell ENDP
- PUBLIC _nov_station
- _nov_station PROC NEAR
- push bp
- mov bp,sp
- push si
- mov ax,0eeffh
- int 21h
- cmp ax,0ee00h
- je ns_err
- mov si,4[bp]
- mov [si],cx
- mov 2[si],bx
- mov 4[si],ax
- mov ax,0
- jmp ns_exit
- ns_err:
- mov ax,-1
- ns_exit:
- pop si
- pop bp
- ret
- _nov_station ENDP
- public _nov_connection
- _nov_connection PROC NEAR
- push es
- push si
- if 0
- mov ax,0
- mov es,ax
- mov si,0
- mov ax,0ef03h
- int 21h
- mov ax,es
- cmp ax,0
- jne nc_ok
- cmp si,0
- jne nc_ok
- mov ax,-1
- jmp nc_exit
- nc_ok:
- mov al,es:23[si]
- mov ah,0
- endif
- mov ax,0dc00h
- int 21h
- jc nc_err
- sub ah,ah
- jmp nc_exit
- nc_err:
- mov al,-1;
- nc_exit:
- pop si
- pop es
- ret
- _nov_connection ENDP
- _TEXT ENDS
- END