MISC.A86
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:48k
源码类别:
操作系统开发
开发平台:
Asm
- ; File : $MISC.A86$
- ;
- ; Description :
- ;
- ; Original Author : DIGITAL RESEARCH
- ;
- ; Last Edited By : $CALDERA$
- ;
- ;-----------------------------------------------------------------------;
- ; Copyright Work of Caldera, Inc. All Rights Reserved.
- ;
- ; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
- ; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
- ; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
- ; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
- ; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
- ; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
- ; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
- ; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
- ; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
- ; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
- ; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
- ; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
- ; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
- ; CIVIL LIABILITY.
- ;-----------------------------------------------------------------------;
- ;
- ; *** Current Edit History ***
- ; *** End of Current Edit History ***
- ; $Log$
- ; MISC.A86 1.29 94/11/30 14:40:17
- ; fixed error return for function 6602
- ; MISC.A86 1.28 94/07/13 15:31:04
- ; Pass name to share on Int21/5D02 (close file by name)
- ; MISC.A86 1.27 93/11/29 14:18:16
- ; Fix bug in get extended country info if not current country
- ; MISC.A86 1.25 93/11/19 17:00:14
- ; If 21/38 get country info fails for current codepage, try any codepage
- ; MISC.A86 1.24 93/11/16 15:57:08
- ; int 21/5D06 clears CY flag
- ; MISC.A86 1.23 93/10/21 19:31:16
- ; Move Int 21/5D03+5D04 support (close all files by machine/psp) into share
- ; MISC.A86 1.22 93/10/18 17:41:45
- ; fix for >255 open files (PNW Server)
- ; MISC.A86 1.21 93/09/03 20:28:57
- ; Add intl/dbcs support for int 21/6523 (query yes/no char)
- ; MISC.A86 1.20 93/07/26 20:42:13
- ; Seperate int21/3306
- ; MISC.A86 1.12 93/03/05 18:12:33
- ; Fix DS corruption for NLSFUNC calls
- ; ENDLOG
- ;
- VALID_SIG equ 0EDC1h
- include pcmode.equ
- include i:msdos.equ
- include i:mserror.equ
- include i:psp.def
- include i:driver.equ
- include i:char.def
- include i:country.def
- include i:doshndl.def
- include i:redir.equ
- include i:fdos.equ
- NLSFUNC equ TRUE
- ;
- GLOBAL_DATA DSEG WORD
- extrn default_country:byte
- extrn Ucasetbl:word
- extrn FileUcasetbl:word
- extrn FileCharstbl:word
- extrn Collatingtbl:word
- extrn DBCS_tbl:word
- extrn NoYesChars:byte
- extrn info1_len:abs
- extrn info2_len:abs
- extrn info4_len:abs
- extrn info5_len:abs
- extrn info6_len:abs
- extrn info7_len:abs
- extrn dos_version:word
- extrn country_filename:byte
- PCM_CODE CSEG BYTE
- extrn dbcs_lead:near
- extrn device_write:near ; Write to a Character Device
- extrn device_read:near ; Read from a Character Device
- extrn dos_entry:near
- extrn error_exit:near
- extrn error_ret:near
- extrn func5F_common:near
- extrn get_dseg:near
- extrn valid_drive:near
- extrn ifn2dhndl:near
- extrn int21_func:near
- extrn invalid_function:near
- extrn patch_version:word
- extrn reload_registers:near
- extrn reload_ES:near
- extrn return_AX_CLC:near
- extrn return_BX:near
- extrn return_CX:near
- extrn return_DX:near
- extrn toupper:near
- extrn xlat_xlat:word
- ;
- ; *****************************
- ; *** DOS Function 34 ***
- ; *** Get The Indos Flag ***
- ; *****************************
- Public func34
- func34:
- mov bx,offset indos_flag
- ; jmp return_DSBX_as_ESBX ; return ES:BX -> indos flag
- Public return_DSBX_as_ESBX
- return_DSBX_as_ESBX:
- ;-------------------
- ; On Entry:
- ; DS:BX to be returned to caller in ES:BX
- ; On Exit:
- ; ES/DI trashed
- ;
- les di,ss:int21regs_ptr
- mov es:reg_ES[di],ds
- mov es:reg_BX[di],bx
- ret
- ;
- ; *****************************
- ; *** DOS Function 52 ***
- ; *** Get Internal Data ***
- ; *****************************
- ;
- ;
- Public func52
- func52:
- mov bx,offset func52_data
- jmps return_DSBX_as_ESBX ; return ES:BX -> internal data
- ;
- ; *****************************
- ; *** DOS Function 5D ***
- ; *** Private DOS Func ***
- ; *****************************
- ;
- ;
- Public func5D
- func5D:
- if DOS5
- cmp al,7
- jae f5d_05
- mov si,dx ; ES:SI -> callers structure
- mov bx,es:word ptr 20[si]
- mov ss:owning_psp,bx ; update PSP from there
- cmp WindowsHandleCheck,26h
- jne f5D_05 ; check if Windows is running
- mov bx,es:word ptr 18[si]
- mov ss:machine_id,bx ; no, update machine_id
- f5D_05:
- else
- push ds
- push es ! pop ds ; restore users DS
- callf ss:win386_remote_machine
- pop ds
- endif
- cbw ; zero AH for valid functions
- xchg ax,bx ; sub function in BX
- cmp bx,func5D_ftl ; Assume Illegal Subfunction
- jb f5D_10 ; check that it is a valid
- mov bx,func5D_ftl ; subfunction
- f5D_10:
- shl bx,1
- push func5D_ft[bx] ; save function address
- shr bx,1
- xchg ax,bx ; restore BX
- ret ; go to function
- f5D_msnet:
- mov ax,I2F_REDIR_5D ; magic number to redirect
- jmp func5F_common ; calls to extentions
- ;
- ;
- ; The registers for some of the following sub-functions are passed
- ; in the following structure.
- ;
- RDC_AX equ es:word ptr 00[di] ; User AX
- RDC_BX equ es:word ptr 02[di] ; User BX
- RDC_CX equ es:word ptr 04[di] ; User CX
- RDC_DX equ es:word ptr 06[di] ; User DX
- RDC_SI equ es:word ptr 08[di] ; User SI
- RDC_DI equ es:word ptr 10[di] ; User DI
- RDC_DS equ es:word ptr 12[di] ; User DS
- RDC_ES equ es:word ptr 14[di] ; User ES
- RDC_RES equ es:word ptr 16[di] ; Remote Machine ID (High Word)
- RDC_UID equ es:word ptr 18[di] ; Remote Machine ID (Low Word)
- RDC_PID equ es:word ptr 20[di] ; Process ID
- ;
- ; *****************************
- ; *** DOS Function 5D00 ***
- ; *** Remote DOS Call ***
- ; *****************************
- ;
- ;
- f5D00:
- mov remote_call,0ffh ; set remote op flag
- push es
- les di,int21regs_ptr ; stack image the copy registers
- pop ds
- mov cx,6
- rep movsw ; Copy AX, BX, CX, DX, SI, DI
- inc di ! inc di ; Skip BP in the destination
- movsw ! movsw ; finally copy DS and ES
- push ss ! pop ds ; DS -> PCMDSEG
- call reload_registers ; load up the new registers
- jmp int21_func ; then execute that function
- ; *****************************
- ; *** DOS Function 5D01 ***
- ; *** Commit all files ***
- ; *****************************
- ;
- f5D01:
- ;-----
- ; We are being asked to commit all files to disk
- ; By pretending to be FCB's we force use of IFN's, and we commit all possible
- ; files in the range 0-255, ignoring errors from unopened handles.
- ;
- mov remote_call,DHM_FCB ; pretend to be FCB, forces use of IFN
- xor bx,bx ; start with handle zero
- f5D01_10:
- mov ah,MS_X_COMMIT
- call dos_entry ; commit this file
- inc bx ; onto next candidate
- cmp bx,0FFh ; runout yet ?
- jb f5D01_10 ;
- ret
- ; *****************************
- ; *** DOS Function 5D02 ***
- ; *** Close file by name ***
- ; *****************************
- ;
- f5D02:
- ;-----
- ; Close file by name. We do a search first to find out about the file.
- ; As long as it's local we call share with the directory cluster/index
- ; to close it if it's open.
- ;
- mov di,dx ; ES:DI -> register block
- mov dx,RDC_DX
- mov es,RDC_DS ; ES:DX -> filename to close
- push dma_offset
- push dma_segment
- mov dma_offset,offset fcb_search_buf
- mov dma_segment,ds
- mov cx,DA_RO+DA_SYSTEM+DA_HIDDEN
- mov ah,MS_X_FIRST ; look for this file
- call dos_entry ; to get dir entry info
- pop dma_segment
- pop dma_offset
- jc f5Dret
- mov al,fcb_search_buf ; get drive #
- test al,al ; reject networked drives
- js f5Dret
- dec ax ; make drive zero based
- mov cx,word ptr fcb_search_buf+0Dh
- ; CX = directory count
- mov dx,word ptr fcb_search_buf+0Eh
- ; DX = parent directory cluster
- lea bx,fcb_search_buf+1 ; DS:BX -> name
- mov di,S_CLOSE_IF_OPEN
- ; jmps f5D_common
- f5D_common:
- callf lock_tables ; protect SHARE with a critical section
- callf share_stub[di]
- callf unlock_tables ; safe again
- f5Dret:
- ret
- ; *****************************
- ; *** DOS Function 5D03 ***
- ; *** Close files by machine***
- ; *****************************
- ;
- ; *****************************
- ; *** DOS Function 5D04 ***
- ; *** Close by Machine/PSP ***
- ; *****************************
- f5D03:
- f5D04:
- ;-----
- ; Close all files for given PSP
- ;
- mov di,S_CLOSE_FILES
- jmps f5D_common
- ; *****************************
- ; *** DOS Function 5D05 ***
- ; *****************************
- ;
- f5D05:
- ; On Entry:
- ; RDC.BX = Share File # to look to
- ; RDC.CX = Share Record # to look for
- ; On Exit:
- ; AX = DOSHNDL Attribute Word
- ; BX = machine ID
- ; CX = locked blocks count
- ; ES:DI -> buffer containing full pathname
- ;
- ;
- callf lock_tables ; protect SHARE with a critical section
- callf share_stub+S_GET_LIST_ENTRY
- callf unlock_tables ; safe again
- jnc f5Dret ; just return if it went OK
- jmp error_ret ; else return error code in AX
- ; *****************************
- ; *** DOS Function 5D06 ***
- ; *** Get Internal Data ***
- ; *****************************
- ;
- f5D06:
- mov cx,offset swap_indos ; Calculate Size of Swap
- sub cx,offset internal_data ; Swap INDOS Array
- call return_CX ; CX = Swap Indos length
- mov dx,offset swap_always ; Calculate Size of Swap
- sub dx,offset internal_data ; Swap ALWAYS Array
- call return_DX ; DX = Swap Always length
- mov si,offset internal_data
- call return_DSSI
- mov ax,5D06h
- jmp return_AX_CLC
- ;
- ; *****************************
- ; *** DOS Function 5D0A ***
- ; ***Set Extended Error Info***
- ; *****************************
- ;
- f5D0A:
- mov si,dx ; ES:SI -> parameter block
- lods es:word ptr [si]
- mov error_code,ax ; copy the appropriate fields
- lods es:word ptr [si]
- mov error_class,ah
- mov error_action,al
- lods es:word ptr [si]
- mov error_locus,ah
- add si,2*WORD ; skip to device
- lods es:word ptr [si]
- mov error_dev,ax
- lods es:word ptr [si]
- mov error_dev+2,ax
- xor ax,ax ; return AL=0
- ret
- ;
- ; *****************************
- ; *** Get switch character ***
- ; *****************************
- ;
- ;
- Public func37
- func37:
- cmp al,1 ! jb f37_getswitch ; Get the current Switch Character
- je f37_setswitch ; Set the Switch Character
- cmp al,3 ! je f37_s03 ; Sub-Func 03 Return Unchanged
- mov dl,0ffh ! jb f37_return_DX ; Sub-Func 02 Return DL == 0FFh
- mov al,0FFh ; else invalid sub-function
- f37_s03:
- ret
- f37_getswitch:
- mov dl,switch_char
- f37_return_DX:
- jmp return_DX ; return current setting in DX
- f37_setswitch:
- mov switch_char,dl
- ret
- ;**************************************************
- ;**************************************************
- ;*** ***
- ;*** Miscellaneous Isolated Functions ***
- ;*** ***
- ;**************************************************
- ;**************************************************
- ;
- ; *****************************
- ; *** DOS Function 30 ***
- ; *** Get Version Number ***
- ; *****************************
- Public func30
- func30:
- if DOS5
- mov es,current_psp ; version is kept in the PSP
- mov ax,PSP_VERSION
- else
- mov ax,dos_version ; version returned in AX
- endif
- ReturnVersionNumber:
- xor bx,bx ; zero BX and CX
- xor cx,cx
- call return_BX
- call return_CX
- jmp return_AX_CLC
- ;
- ; *****************************
- ; *** DOS Function 33 ***
- ; *** Get/Set Cntl-Break ***
- ; *****************************
- Public func33
- ; WARNING - called on USER stack
- func33:
- cmp al,2 ; range check subfunction
- jbe f33_10
- mov dl,bootDrv ; assume we want boot drive
- cmp al,5 ; did we ?
- je f33_30
- if DOS5
- cmp al,6 ; get true version ?
- je f33_60
- endif
- mov reg_AL[bp],0FFh ; return AL = FF
- ret ; Illegal function request
- f33_10:
- and dl,01h ; force a valid value
- cmp al,1 ; check for get or set
- jae f33_20
- mov dl,break_flag ; it's a get, so use existing setting
- f33_20:
- xchg dl,break_flag ; replace current setting
- je f33_40
- f33_30:
- mov reg_DL[bp],dl ; return setting in DL
- f33_40:
- ret
- if DOS5
- f33_60:
- mov reg_BX[bp],TRUE_VERSION ; return version number
- mov ax,patch_version
- mov reg_DX[bp],ax ; return revision+HMA
- ret
- endif
- ;
- ; *****************************
- ; *** DOS Function 25 ***
- ; *** Set Interrupt Vector ***
- ; *****************************
- ;
- ; WARNING - use no stack as device drivers have called us re-entrantly
- Public func25
- func25:
- mov bx,es ; is really dos_DS - save for later
- xor di,di ; replace with the values in dos_DS:DX
- mov es,di ; es -> zero segment
- xor ah,ah ; the interrupt number
- mov di,ax ; 0:di -> vector
- shl di,1 ! shl di,1 ; 4 bytes per vector
- cli
- xchg ax,dx ; Get New Offset
- stosw ; and Save
- xchg ax,bx ; Get New Segment
- stosw ; and Save
- sti
- xchg ax,dx ; recover entry AL to (preserve it)
- ret
- ; *****************************
- ; *** DOS Function 35 ***
- ; *** Get Interrupt Vector ***
- ; *****************************
- ; WARNING - use no stack as device drivers have called us re-entrantly
- Public func35
- func35:
- xor bx,bx
- mov ds,bx ; DS:0 -> vector table
- mov bl,al ; BX = the interrupt number
- shl bx,1 ! shl bx,1 ; 4 bytes per vector
- lds bx,ds:dword ptr [bx] ; DS:BX -> vector
- les di,ss:int21regs_ptr
- mov es:reg_BX[di],bx
- mov es:reg_ES[di],ds
- jmp get_dseg ; restore DS for return
- ;PC-DOS Verify and Break Flags Support
- ;
- ; *****************************
- ; *** DOS Function 2E ***
- ; *** Set/Reset Verify ***
- ; *****************************
- Public func2E
- func2E:
- and al,1 ; only use bottom bit
- mov verify_flag,al ; store for use later
- ret
- ; *****************************
- ; *** DOS Function 54 ***
- ; *** Get Verify Setting ***
- ; *****************************
- Public func54
- func54:
- mov al,verify_flag ; return verify flag
- ret
- ; *****************************
- ; *** DOS Function 63 ***
- ; *** Get Lead Byte Table ***
- ; *****************************
- ;
- Public func63
- func63:
- cmp al, 1 ; subfunction #?
- jb f63_get_tbl ; subfunction 0
- je f63_set_flg ; subfunction 1
- cmp al, 2 ; subfunction 2?
- je f63_get_flg ; yes
- mov ax, ED_FUNCTION ; invalid subfunction number
- jmp error_exit ; so quit
- f63_get_flg:
- ; Get the current state of the DOS interim character console flag.
- ; If this flag is set int 21h functions 07h, 08h, 0Bh, 0Ch are supposed
- ; to return "interim character information" which I assume is incomplete
- ; characters. (In languages like Korean a given double byte character
- ; may be built by the user entering several keystrokes which form
- ; incomplete characters.)
- mov es, current_psp
- mov dl, PSP_RIC ; Return Interim Character flag
- jmp return_DX ; flag returned in dl
- f63_set_flg:
- ; Set the current state of the DOS interim character console flag.
- ; dos_DL = 0 - clear flag, dos_DL = 1 - set flag
- mov es, current_psp
- mov PSP_RIC, dl ; record flag
- ret
- f63_get_tbl:
- ; Get the current DBCS table address.
- mov si,offset DBCS_tbl+2; skip the table size entry
- ; jmp return_DSSI
- return_DSSI:
- ;-----------
- ; On Entry:
- ; DS:SI to be returned to caller
- ; On Exit:
- ; AX preserved
- ;
- les di,ss:int21regs_ptr
- mov es:reg_DS[di],ds
- mov es:reg_SI[di],si
- ret
- ;
- ; *****************************
- ; *** DOS Function 29 ***
- ; *** Parse String ***
- ; *****************************
- Public func29
- func29:
- ;
- ; Entry:
- ; DS:SI -> line to parse
- ; ES:DI -> resulting fcb
- ; Exit:
- ; DS:SI -> terminating delimeter past parsed filename
- ; ES:DI -> filled in fcb (Affects 16 bytes: DnnnnnnnnTTT0000)
- ;
- push ds
- push es
- call reload_ES
- pop ds
- call parse
- call return_DSSI ; return result of parse
- pop ds
- mov al,dh ; return result in AL
- ret
- ;-----
- parse: ; parse DOS filename delimited by TAB,SPACE,or .,+:;=|"/[]<> or ctrl
- ;-----
- ; Entry:
- ; DS:SI -> line to parse
- ; ES:DI -> fcb to parse into
- ; AL == bit options:
- ; Bit 0 == 1: scan off leading delimiters
- ; Bit 1 == 1: change drive only if specified
- ; Bit 2 == 1: change name " " "
- ; Bit 3 == 1: change type " " "
- ; Exit:
- ; DS:SI -> terminating delimeter past parsed filename
- ; ES:DI -> filled in fcb (Affects 16 bytes: DnnnnnnnnTTT0000)
- ; DH == 1 if wild, 0FFh if the drive is invalid, 0 otherwise
- ;
- push di ; (<--keep DI last on stack)
- cld ; ChSh
- xor dx,dx ; DH = default return value (0)
- xchg al,dl ; put flags into DL, AL = 0
- mov cx,1
- test dl,0010b ; should we initialize drive?
- call nz_store_al ; do conditional store
- mov al,' ' ; use spaces for filename & typ
- mov cl,8
- test dl,0100b ; should we initialize the name?
- call nz_store_al
- mov cl,3
- test dl,1000b ; should we initialize the typ?
- call nz_store_al
- xor ax,ax ; zero-out the 4 post-typ bytes
- stos ax
- stos ax
- pop di ! push di ; restore DI to start of FCB
- deblank_loop:
- lods al ; grab char
- cmp al,' ' ; is it a blank?
- je deblank_loop ; Y: keep looping
- cmp al,'I'-'@' ; is it a tab?
- je deblank_loop ; Y: keep looping
- test dl,0001b ; skip-delimiter-bit set?
- jz parse_drive ; N: go start parsing
- skip_delim_loop:
- call check_delimiters ; check AL for delimiterness
- jb parse_dec_ret ; found terminator, dec SI & leave
- mov dl,dh ; flag no-more-delimiter-skip (DL = 0)
- je deblank_loop ; found separator, go deblank after it
- parse_drive:
- dec si
- cmp byte ptr 1[si],':' ; is the drive specified?
- jne parse_name
- lods ax ; get drive, junk colon
- and al,01011111b ; upper case it
- sub al,'@' ; AL = 1-relative drive #
- push ax ! push ds ; Save the drive code and call
- call get_dseg ; Restore our Data Segment
- call valid_drive ; routine to validate drive ZR == OK
- pop ds ! pop ax ; Restore drive code and User DS
- jz parse_d10
- dec dh ; flag drive error (0FFh)
- parse_d10:
- mov es:[di],al ; insert drive in fcb
- parse_name:
- inc di ; DI -> fname
- mov cx,8
- call parse_item ; parse an up-to 8 char filename
- cmp dl,'.' ; was the delimeter a '.'?
- jne parse_dec_ret ; N: the parse is complete
- mov cl,3
- call parse_item ; parse an up-to 3 char filetype
- parse_dec_ret:
- dec si ; bump SI back to point to delimeter
- parse_ret:
- pop di
- ret
- ;-----------
- nz_store_al:
- ;-----------
- ; Entry:
- ; DI -> destination to conditionally initialize
- ; CX == length of destination
- ; AL == byte to initialize with
- ; ZF set: do not initialize destination
- ; Exit:
- ; DI -> past destination (initial DI+CX)
- ; Changed:
- ; CX,DI
- ;
- jnz skip_store ; should we initialize?
- rep stosb ; Y: store them bytes
- skip_store:
- add di,cx ; bump DI to post-dest position
- ret
- ;==========
- parse_item: ; Parses item into fcb if item is specified
- ;==========
- ;
- ; Entry:
- ; SI -> item to parse (name or type)
- ; DI -> fcb area to parse it into
- ; CX == length of item
- ; DH == parse_return
- ; Exit:
- ; SI -> past ending delimeter
- ; DI -> past fcb area (initial DI + CX)
- ; CH == If zero on enter zero on exit else 0-255
- ; DH == updated parse_return w/possible wild bit set
- ; DL == character delimiter @(SI-1)
- ; Changed:
- ; AX,CX,DX,SI,DI
- ;
- mov ah,FALSE ; specified item flag
- parse_item_loop:
- lods al ; get char
- call check_delimiters ; is it a delimiter?
- jbe pi_pad_ret ; Y: the parse is complete
- jcxz parse_item_loop ; if the name is full, skip the char
- mov ah,al ; flag name as present
- cmp al,'?' ; is it a single wild char?
- je pi_set_wild ; Y: set wild flag
- cmp al,'*' ; is it a multi-char wild card?
- jne pi_store ; N: store it
- mov al,'?' ; Y: fill with '?' to end of name
- rep stosb
- pi_set_wild:
- or dh,1 ; set wild flag
- jcxz parse_item_loop ; skip store if name is now filled
- pi_store:
- dec cx ; another char done
- call dbcs_lead ; is it the 1st byte of kanji ?
- jne pi_store10
- inc si ; skip 2nd byte
- jcxz parse_item_loop ; can I copy both ?
- dec cx ; yes, do so
- stosb
- dec si ; point at second byte
- lodsb ; so we can copy it too..
- pi_store10:
- stos al ; put the char in the fcb
- jmps parse_item_loop
- pi_pad_ret:
- mov dl,al ; DL = ending delimeter
- or ah,ah ; the the item specified?
- jz pi_ret ; N: skip padding
- mov al,' ' ; Y: pad to end with spaces
- rep stosb
- pi_ret:
- add di,cx ; bump DI out to end
- ret
- ;----------------
- check_delimiters:
- ;----------------
- ;
- ; Entry:
- ; AL == char to check in list of delimiters
- ; Exit:
- ; AL == char changed to uppercase
- ; CF set if it is one of the terminators: |"/[]<> & ctrl chars != TAB
- ; ZF set if it is one of the separators: .,+:;= SPACE & TAB
- ; OR one of the non-ctrl terminators
- ;
- cmp al,'a' ; check for lower case
- jb not_lower
- cmp al,'z'
- ja not_lower
- and al,01011111b ; uppercase it, CF clear, ZF clear
- ret
- not_lower:
- push cx ! push di ! push es
- push cs ! pop es ; ES = Code segment
- mov di,offset parse_separators
- mov cx,length parse_separators
- repne scasb ; is AL a separator?
- je cpd_pop_ret ; Y: return ZF set
- mov cl,length parse_terminators
- repne scasb ; is AL a terminator?
- stc ; (set CF if true)
- je cpd_pop_ret ; Y: return CF & ZF set
- cmp al,' ' ; (AL == ' ') ZF set, (AL < ' ') CF set
- cpd_pop_ret:
- pop es ! pop di ! pop cx
- ret
- ;
- ; *****************************
- ; *** DOS Function 2A ***
- ; *** Get Current Date ***
- ; *****************************
- Public func2A
- func2A:
- ;
- ; entry: None
- ;
- ; exit: cx = year (1980-2099)
- ; dh = month (1-12)
- ; dl = day (1-31)
- ; al = DOS returns day of week here
- ;
- call ReadTimeAndDate ; Get the current Time and Date
- mov cx,1980
- add cx,yearsSince1980
- ; mov dl,dayOfMonth
- ; mov ah,month
- mov dx,word ptr dayOfMonth
- mov al,dayOfWeek
- jmps f2C_10 ; exit via common routine
- ; *****************************
- ; *** DOS Function 2C ***
- ; *** Get Current Time ***
- ; *****************************
- Public func2C
- func2C:
- ;
- ; entry: None
- ;
- ; exit: ch = hours (0-23)
- ; cl = minutes (0-59)
- ; dh = seconds (0-59)
- ; dl = Hunredths seconds (0-99)
- ; al = 0
- ;
- call ReadTimeAndDate ; Get the current Time and Date
- mov cx,biosDate+2 ; Get the Hour and Minute
- mov dx,biosDate+4 ; Get the Seconds and Hundredths
- xor ax,ax ; return AL = 0
- f2C_10:
- call return_CX ; and return to caller
- jmp return_DX
- ; *****************************
- ; *** DOS Function 2B ***
- ; *** Set Current Date ***
- ; *****************************
- Public func2B
- func2B:
- ;
- ; entry: cx = year (1980-2099)
- ; dh = month (1-12)
- ; dl = day (1-31)
- ;
- ; exit: al = 00H success
- ; = FFH failure
- ;
- call ConvertDate ; Convert to BIOS date
- jc f2B_20 ; Abort on Error
- push cx ; save the converted date
- call ReadTimeAndDate ; Get the current Time and Date
- pop biosDate ; new date, existing time
- f2B_10: ; Set the current Time and Date
- call rw_clock_common ; make sure clock is there/setup regs
- call device_write ; Update the Date and Time
- xor ax,ax
- ret
- f2B_20:
- mov al,0FFh ; return FAILURE
- ret
- ; *****************************
- ; *** DOS Function 2D ***
- ; *** Set Current Time ***
- ; *****************************
- Public func2D
- func2D:
- ;
- ; entry: ch = hours (0-23)
- ; cl = minutes (0-59)
- ; dh = seconds (0-59)
- ; dl = hundredth seconds (0-99)
- ;
- ; exit: al = 00H success
- ; = FFH failure
- ;
- cmp ch,23 ; Range check hours
- ja f2B_20
- cmp cl,59 ; Range check minutes
- ja f2B_20
- cmp dh,59 ; Range check seconds
- ja f2B_20
- cmp dl,99 ; Range check hundredths
- ja f2B_20
- push cx ; save hours/mins
- push dx ; save secs/hundredths
- call ReadTimeAndDate ; Get the current Time and Date
- pop biosDate+4 ; leave the date alone
- pop biosDate+2 ; but update the time
- jmps f2B_10 ; Update the Date and Time
- Public ReadTimeAndDate
- ReadTimeAndDate: ; Get the current Time and Date
- call rw_clock_common ; make sure clock is there/setup regs
- call device_read ; read the Date and Time
- mov ax,biosDate ; get the BIOS date and convert
- cmp ax,daysSince1980 ; (but only if necessary)
- jne NewDate
- ret
- NewDate:
- mov daysSince1980,ax ; so we won't have to convert next time
- inc ax ; Day number starting 1 Jan 1980
- mov cx,ax ; save day count
- inc ax ; convert to a sunday as 1/1/80 is tues
- xor dx,dx
- mov bx,7
- div bx
- mov dayOfWeek,dl ; save day of week
- xor dx,dx
- mov ax,cx ; recover day count
- xor di,di ; assume zero leap days
- sub ax,60 ; less than 60 days
- jc no_leap_days ; means no leap days to subtract
- mov bx,1461 ; 1461 = days in four years
- div bx ; get number of leap years since 1980
- inc ax ; include 1980
- sub cx,ax ; normalize years to 365 days
- mov di,ax ; save proper leap day count
- no_leap_days:
- xor dx,dx
- xchg ax,cx ; DX:AX = years since 1980 * 365
- mov bx,365
- div bx ; get number of years since 1980
- or dx,dx ; check for zero days left
- jnz days_left
- dec ax ; dec year count
- mov dx,365 ; set day count to last day of last year
- days_left:
- mov yearsSince1980,ax ; save the year
- xchg ax,si ; save in SI
- xor bx,bx
- mov cx,12
- get_month: ; find the appropriate month
- cmp dx,totaldays[bx]
- jbe got_month
- inc bx ! inc bx
- loop get_month
- got_month:
- shr bx,1 ; BX = month
- mov month,bl
- dec bx
- shl bx,1 ; BX = index to previous months
- sub dx,totaldays[bx] ; get days into this month
- cmp bx,2 ; if it's FEB 29th we've lost a day
- jne not_leap_yr ; check it's FEB
- test si,3
- jnz not_leap_yr ; but is it a leap year ?
- shr si,1 ! shr si,1 ; divide years by 4
- inc si ; include this year
- cmp si,di ; compare against leap day adjustment
- jne not_leap_yr
- inc dx ; put 29th feb back again
- not_leap_yr:
- mov dayOfMonth,dl ; save the day of the month
- ret
- ConvertDate:
- sub cx,1980 ; Base year is 1980
- jc xset_date_error
- cmp cx,2100-1980 ; Year in valid range ?
- jnc xset_date_error
- mov bl,dh ; Month to BL
- xor bh,bh
- dec bx ; Adjust month to 0-11
- cmp bl,12 ; Month in valid range ?
- jnc xset_date_error
- mov al,dl ; Day of month
- cbw
- test cl,3 ; Leap year ?
- jnz not_leap_year ; Jump if not
- cmp dh,3 ; After February ?
- cmc
- adc al,ah ; Increment days in current year if so
- cmp dl,29 ; Day of month 29 ?
- jz day_valid ; Valid if so
- not_leap_year:
- dec dx
- cmp dl,monthdays[bx] ; Day of month within range for non-leap
- ; year ?
- jnc xset_date_error
- day_valid:
- shl bx,1
- add ax,totaldays[bx] ; Get total days in current year
- push ax
- mov ax,365
- mul cx ; Convert year to days since 1-1-1980
- mov cx,ax
- ; if total (ax) >= 60 (Feb 29 1980) then
- ; leap$days = (total - 60) / (365 * 4) + 1
- sub ax,60 ; Before first leap year date
- jc noleap ; Jump if so
- mov bx,365*4 ; 4 years worth of days (365 * 4)
- sub dx,dx
- div bx ; Get number of leap years - 1
- inc ax
- add cx,ax ; CX now has total days including leap
- ; days
- noleap:
- dec cx
- pop ax
- add cx,ax ; Get total days since 1-1-1980
- clc
- ret
- xset_date_error:
- stc
- ret
- rw_clock_common:
- mov cx,6 ; read/write 6 characters
- mov dx,offset biosDate ; DX -> 6 byte buffer
- les si,clk_device ; Get the address of the Clock Device
- cmp si,-1 ; Has a valid device been selected
- jne rw_clock_common10
- add sp,WORD ; discard near return address
- rw_clock_common10:
- ret
- ; *****************************
- ; *** DOS Function 38 ***
- ; *** Get/Set Country Data ***
- ; *****************************
- Public func38
- func38:
- xor ah,ah ; Generate 16 Bit country
- cmp al,0FFh ; FF means country code in BX
- jne f38_10
- xchg ax,bx ; AX = real country code
- f38_10:
- xchg ax,dx ; DX = country
- test dx,dx ; dos_AL = 0 get the current country
- jz f38_get
- inc ax ; now check for dos_DX = FFFF
- jz f38_set ; which means set country code
- dec ax ; no, return buffer to normal
- f38_get:
- test dx,dx ; Get current?
- jnz f38_g10 ; Yes
- mov dx,cur_country ; use current country
- f38_g10:
- ; look for (and if neccessary load) type 1 info into buffer
- xchg ax,di ; ES:DI -> buffer
- mov bx,cur_cp ; bx=codepage
- call f38_get_info ; get info in current codepage
- jnc f38_g20
- push ss ! pop ds
- xor bx,bx ; now try any codepage
- call f38_get_info ; if none for current codepage
- jc f38_error ; No Match Found
- f38_g20:
- lea si,EXCI_CI_DATAOFF[si] ; point at CI_, not EXCI_ data
- mov bx,CI_CODE[si] ; Return the selected country code
- mov cx,CI_STATICLEN/2
- rep movsw
- if NLSFUNC
- push ss
- pop ds
- ; call get_dseg ; DS back to PCMODE
- endif
- call return_BX ; return country code in BX
- xchg ax,bx
- jmp return_AX_CLC ; and in AX
- f38_get_info:
- push es ! push di ! push dx ; save pointer to buffer
- mov al,1 ; Get data list seperators etc...
- call f65_get_info ; DS:SI -> extended country info buffer
- pop dx ! pop di ! pop es ; ES:DI -> users buffer
- ret
- f38_set:
- mov bx,cur_cp ; bx=codepage
- and bx,f38_flag ; force CP to zero if 1st time here
- call f38_set_country ; Update the Internal Data Structures
- jc f38_error
- f38_s20:
- mov f38_flag,0FFFFh ; Country Code Set Successfully
- mov ax,cur_country ; and return the current country
- jmp return_AX_CLC ; to the user
- f38_error:
- if NLSFUNC
- push ss
- pop ds
- ; call get_dseg ; DS back to PCMODE
- endif
- mov ax,ED_FILE ; This is the Error to return
- jmp error_exit
- f38_set_country:
- ; On Entry:
- ; BX = codepage
- ; DX = country
- ; On Exit:
- ; AX = error code
- ; preserve codepage/country info if there is an error (ie do type 1 last!)
- ;
- mov al,2 ; Get uppercase & filename table
- mov di,offset Ucasetbl
- mov cx,info2_len
- call f38_update
- jc f38_seterr
- mov al,4 ; Get uppercase & filename table
- mov di,offset FileUcasetbl
- mov cx,info4_len
- call f38_update
- jc f38_seterr
- mov al,5 ; Get Legal file characters
- mov di,offset FileCharstbl
- mov cx,info5_len
- call f38_update
- jc f38_seterr
- mov al,6 ; Get Collating table
- mov di,offset Collatingtbl
- mov cx,info6_len
- call f38_update
- jc f38_seterr
- mov al,7 ; Get double byte character set table
- mov di,offset DBCS_tbl
- mov cx,info7_len
- call f38_update
- jc f38_seterr
- mov al,1 ; Get data list seperators etc...
- mov di,offset country_data ; do last since this updates
- mov cx,info1_len ; cur_country/cur_cp
- call f38_update
- ; jc f38_seterr
- ; clc
- ret
- f38_seterr:
- mov ax,ED_FILE ; return file not found error
- ret
- f38_update:
- push ds ; save important registers
- push bx ; codepage
- push cx ; count for move
- push dx ; country
- push di ; destination offset for move
- push ds ; destination segment
- call f65_get_info ; DS:SI -> buffer with country info
- pop es ; destination seg in ES
- pop di ; ES:DI -> destination of move
- pop dx ; country
- pop cx ; bytes to move
- pop bx ; codepage back again
- jc f38_update10 ; any problems ?
- rep movsb ; no, copy the data
- f38_update10:
- pop ds ; DS back to PCMDSEG
- ret
- ; *****************************
- ; *** DOS Function 65 ***
- ; *** Extended Country Data ***
- ; *****************************
- ;
- ;CODEPAGE equ 437 ; Return Standard Code Page
- ;
- ; Get Extended Country Code Sub-Functions
- ;
- func65_dt dw 0FFFFh ; 00 Illegal Sub-Function
- dw offset country_data ; 01 Extended Country Info
- dw offset Ucasetbl ; 02 UpperCase Table
- dw 0FFFFh ; 03 Invalid Subfunction
- dw offset FileUcasetbl ; 04 FileName Upper Case Table
- dw offset FileCharstbl ; 05 Valid Filename Characters
- dw offset Collatingtbl ; 06 Collating Sequence
- dw offset DBCS_tbl ; 07 DBCS Environment Vector
- func65_dtl equ (offset $ - offset func65_dt)/2
- Public func65
- func65:
- cmp al,func65_dtl ; is sub-function 0-7 ?
- jb func65_read_table
- sub al,20h ; now check for 20-22
- jb f65_invalid
- je func6520 ; it's upper case character
- sub al,2
- je func6522
- jb func6521
- sub al,1 ; how about 6523 ?
- jnz f65_invalid
- ; jmp func6523
- func6523:
- ;--------
- ; On Entry:
- ; DX = character to check
- ; On Exit:
- ; AX = 0, No
- ; AX = 1, Yes
- ; AX = 2, neither
- ;
- push ds
- pop es
- mov di,offset NoYesChars ; 'NnYy'
- cbw ; assume No (AX=0)
- xchg ax,dx ; AX = char, DX = answer
- call dbcs_lead ; is it 1st of a DBCS pair
- jne func6523_10
- scasw ; check 'N'
- je func6523_30
- inc dx ; assume Yes (DX=1)
- scasw ; check 'Y'
- jmps func6523_20
- func6523_10:
- scasb ; check 'N'
- je func6523_30
- scasb ; check 'n'
- je func6523_30
- inc dx ; assume Yes (DX=1)
- scasb ; check 'Y'
- je func6523_30
- scasb ; check 'y'
- func6523_20:
- je func6523_30
- inc dx ; it's neither (DX=2)
- func6523_30:
- xchg ax,dx ; return result in AX
- jmp return_AX_CLC ; Return the Code Page
- func6522:
- ;--------
- ; Upper case ASCIIZ string at ES:DX
- mov cx,0FFFFh ; calculate the length
- mov di,dx ; of the string
- ; mov al,0
- repne scasb
- not cx ; CX = length, including 0
- ; jmp func6521 ; now use upper case CX bytes
- func6521:
- ;--------
- ; Upper case string of CX bytes at ES:DX
- mov si,dx
- mov di,dx ; point SI & DI at string
- f6521_10:
- lods es:al ; read a character
- call dbcs_lead ; is it 1st of a DBCS pair
- jne f6521_20
- stosb ; store 1st byte of this pair
- movs es:byte ptr [di],es:byte ptr [si]
- ; copy 2nd byte
- dec cx ; 1st byte of pair
- loopnz f6521_10 ; go around for another one
- ret ; time to go...
- f6521_20:
- call toupper ; upper case the character
- stosb ;
- loop f6521_10 ; go and do another one
- ret
- func6520:
- ;--------
- ; Upper case character DL
- xchg ax,dx ; character in AX
- call toupper ; upper case it
- mov dl,al ; return in AL and DL
- jmp return_DX ; set return code
- f65_invalid:
- ;-----------
- ; short jump to invalid function
- jmp invalid_function
- func65_read_table:
- ;-----------------
- cmp cx,5 ; Check for valid buffer size
- jb f65_invalid
- cbw ; Get the request sub-function
- mov si,ax ; into SI
- shl si,1
- mov si,func65_dt[si]
- inc si ; is SI = 0FFFFh
- jz f65_invalid ; if so it's an invalid function
- dec si
- cmp dx,0ffffh
- jne f65_21 ; FFFF means
- mov dx,cur_country ; use default country
- f65_21:
- cmp bx,0ffffh
- jne f65_22 ; FFFF means
- mov bx,cur_cp ; use default codepage
- f65_22:
- call f65_get_info ; DS:SI -> extended info for this pair
- mov ax,ED_FILE ; On Error return File Not Found
- jnc f65_23 ; for any error
- push ss ! pop ds
- jmp error_exit ; so Quit
- f65_23:
- les bx,ss:int21regs_ptr ; point to callers registers
- mov ax,es:reg_AX[bx] ; get the subfunction number
- mov cx,es:reg_CX[bx] ; this much data is requested
- mov di,es:reg_DI[bx] ; Get the Parameter Block Offset
- mov es,es:reg_ES[bx] ; and Segment
- stosb ; fill in Info ID
- cmp al,1 ; 1 is special - the rest
- jne f65_30 ; want a DWORD ptr
- cmp cx,EXCI_MAXLEN ; Check CX against the sub-function 1
- jbe f65_25 ; maximum and force CX to this value
- mov cx,EXCI_MAXLEN ; if it is greater
- f65_25:
- call return_CX ; Return the number of bytes transfered
- sub cx,EXI_DATA_LEN ; Adjust count for 3 byte header
- mov ax,cx ! stosw ; fill in EXCI_LENGTH
- push cx ; Save the count and copy as much
- cmp cx,EXCI_STATLEN ; valid data a possible. IE at most
- jbe f65_27 ; EXCI_STATLEN bytes
- mov cx,EXCI_STATLEN
- f65_27:
- rep movsb ; just copy the data
- pop cx ; Zero the rest of the data
- sub cx,EXCI_STATLEN ; Skip if no space left in users
- jbe f65_40 ; buffer otherwise STOSB
- xor al,al ! rep stosb
- jmps f65_40
- ;
- ; All function 65 sub-functions apart from 01 (Extended Country Info.)
- ; pass use this code to update the users parameter block.
- ;
- f65_30:
- mov cx,5
- call return_CX
- mov ax,si ! stosw ; fill in the DWORD ptr to the data
- mov ax,ds ! stosw
- f65_40:
- push ss
- pop ds
- ; call get_dseg ; back to PCMDSEG
- mov ax,cur_cp ; ##jc## Is the Requested or Current
- jmp return_AX_CLC ; Return the Code Page
- ; *****************************
- ; *** DOS Function 66 ***
- ; ***Get/Set Global CodePage***
- ; *****************************
- ;
- Public func66
- func66:
- cbw
- dec ax ! jz f66_10 ; AL = 1, Get the Current CodePage
- dec ax ! jz f66_20 ; AL = 2, Set the Current CodePage
- jmp invalid_function ; Illegal Sub-Function return an Error
- f66_10: ; Get the Current Code Page Info
- mov bx,cur_cp ; Current CodePage
- call return_BX
- mov dx,SYS_CP ; System CodePage
- jmp return_DX
- f66_20: ; Set the Current CodePage
- mov dx,cur_country ; The Codepage has changed, so update
- call f38_set_country ; Country Info and tables
- jnc f66_30 ; Reset the Current CodePage if
- mov ax,ED_FILE ; and return the error
- jmp error_exit
- f66_30:
- mov bx,cur_cp ; select the new codepage
- call f66_select_cp ; Prepare CodePage Devices
- jnc f66_40 ; No Errors Skip Error Handler
- mov ax,-65 ; Update Error Status do not generate
- call error_ret ; a critical error but return
- ; "access denied" to the application
- f66_40:
- ret
- f65_get_info:
- ; On Entry:
- ; AL = info type
- ; BX = codepage (zero means any)
- ; DX = country
- ; On Exit:
- ; CY set if error
- ; DS:SI -> buffer with info in it
- ;
- ; NB. Remember to to Xlat fixups !
- ;
- cmp dx,cur_country ; is it default country ?
- jne f65_p30 ; have we already got correct country ?
- test bx,bx ; CP zero special case and we will
- jz f65_p20 ; accept anything for this country
- cmp bx,cur_cp ; otherwise is the codepage
- jne f65_p30 ; in the default system ?
- f65_p20:
- cbw ; make info type a word
- mov si,ax ; into index register
- shl si,1 ; now a word offset
- mov si,func65_dt[si] ; pick up offset of correct table
- jmps f65_p90
- f65_p30:
- push ax
- call f65_locate_and_read ; get info into a buffer at DS:SI
- pop ax
- jc f65_p_exit
- f65_p90:
- cmp al,1 ; was it country info ?
- jne f65_p95 ; no, skip the fixup
- mov CI_CASEOFF+EXCI_CI_DATAOFF[si],offset xlat_xlat
- mov CI_CASESEG+EXCI_CI_DATAOFF[si],ss
- f65_p95:
- clc
- f65_p_exit:
- ret
- ;
- ; **********************************************************************
- ; *** Function 65 support - routines for seeking a country/codepage ***
- ; *** and loading the required information into the temp data area ***
- ; **********************************************************************
- ;
- ; **************************************************
- ; *** Open country.sys and search for the ***
- ; *** table of offsets for the given country/ ***
- ; *** codepage, read it in and exit. ***
- ; **************************************************
- f65_locate_and_read:
- ; Locate and Read info AL for Country DX Codepage BX
- if NLSFUNC
- mov di,offset country_filename
- ; point at pathname to country.sys
- xchg ax,cx ; get info into CL
- mov ax,14feh ; then call magic backdoor
- nlsfunc_int2f:
- stc ; assume an error
- int 2fh ; to do the hard work
- ret
- else
- push ax
- call f65x_find_info ; Will need to load up the info
- pop ax
- jc f65_lr_exit ; so do it if we can.
- mov dx,offset f65xx_temp_area
- mov cx,256 ; read 256 bytes into local buffer
- push ax
- call f65x_load_info ; Load required info
- pop ax
- jc f65_lr_exit
- mov ah,MS_X_CLOSE ; All done so
- mov bx,c_handle ; Close the file first
- call dos_entry ; before leaving
- ; jc f65_lr_exit
- mov si,offset f65xx_temp_area ; Tell subroutines where info is
- f65_lr_exit:
- ret
- ;
- ; Entry: dx=country code, bx=codepage
- ; Exit : carry set, and country.sys closed if failure
- ; country.sys open ready for more reads if success
- ;
- f65x_find_info:
- push es ; Save es
- push ds
- pop es ; Make es=ds
- mov f65xx_country,dx
- mov f65xx_codepage,bx
- mov dx,offset country_filename
- mov ax,(MS_X_OPEN*256)+0 ; Attempt to open country.sys
- test dx,dx
- stc
- jz f65x_40
- call dos_entry ; Handle should come back in ax
- jc f65x_40
- f65x_10:
- mov c_handle,ax ; Save handle
- mov dx,f65xx_country
- cmp f65xx_code,dx ; do we already have the information?
- jne f65x_30 ; No - get it from country.sys
- f65x_20:
- cmp f65xx_cp,bx ; Does codepage agree too?
- je f65x_35 ; Yes so exit with no more ado
- f65x_30:
- mov dx,007Eh
- xor cx,cx ; Seek within country.sys
- mov bx,c_handle
- mov ax,(MS_X_LSEEK*256)+0 ; seek from begining
- call dos_entry
- jc f65x_err
- mov ah,MS_X_READ ; Now read the signature bytes and
- mov bx,c_handle ; check them
- mov cx,2
- mov dx,offset f65xx_sig
- call dos_entry
- jc f65x_err
- cmp f65xx_sig,VALID_SIG
- jne f65x_err ; If signature bad exit
- f65x_32:
- mov ah,MS_X_READ ; Read from country.sys header until
- mov bx,c_handle ; Country/codepage found or NULL
- mov cx,f65xx_ptable_len
- mov dx,offset f65xx_code
- call dos_entry
- jc f65x_err
- cmp f65xx_code,0 ; Found NULL so reqd combination
- je f65x_err ; was not found
- mov dx,f65xx_code ; Get the country/codepage values
- mov bx,f65xx_cp ; read from Country.SYS
- cmp dx,f65xx_country ; Check against the requested
- jne f65x_32 ; Country.
- cmp f65xx_codepage,0 ; If a codepage match is not
- jz f65x_35 ; then return success
- cmp bx,f65xx_codepage ; Check against the requested
- jne f65x_32 ; Codepage
- f65x_35:
- mov f65xx_country,dx ; Force the Search Country and
- mov f65xx_codepage,bx ; CodePage to be Updated
- f65x_40:
- pop es ; combination found so exit
- ret
- f65x_err:
- pop es
- mov ah,MS_X_CLOSE ; On error close country.sys
- mov bx,c_handle ; and set the carry flag before
- call dos_entry ; leaving
- stc
- ret
- ;
- ; **************************************************
- ; *** Load the type of information requested ***
- ; *** For the country currently active in the ***
- ; *** offset table ***
- ; **************************************************
- ;
- ; Entry: al=type of info, dx=offset of buffer to read info into cx=no of bytes
- ; Exit : carry set, and country.sys closed if failure
- ;
- f65x_load_info:
- push es
- push cx
- push dx
- push ds ; Make es=ds
- pop es
- dec al ; 1=Data , 2=uppercase, 4=fuppercase
- sub bh,bh ; 5=filechars, 6=Collating table
- mov bl,al ; 7=DBCS table
- shl bx,1 ; Retrieve relevant offset
- mov dx,f65xx_data[bx]
- xor cx,cx ; Seek within country.sys
- mov bx,c_handle
- mov ax,(MS_X_LSEEK*256)+0 ; seek from begining
- call dos_entry
- pop dx ; Get buffer address back
- pop cx ; and number of bytes to read
- jc f65x_err
- test ax,ax ; zero offset is a problem
- jz f65x_err ; (probably DBCS with old COUNTRY.SYS)
- mov ah,MS_X_READ ; Now read that info into our data area
- mov bx,c_handle
- call dos_entry ; Return when read is done
- jc f65x_err
- pop es
- ret
- endif
- ;
- ; This function scans the complete device list and prepares
- ; all devices which support codepage.
- ;
- ; On Entry:
- ; BX = codepage
- ; On Exit:
- ; AX = error code
- DA_CODEPAGE equ DA_CHARDEV+DA_IOCTL+DA_GETSET
- f66_select_cp:
- if NLSFUNC
- mov ax,14ffh ; then call magic backdoor
- jmps nlsfunc_int2f ; to do the hard work
- else
- push ds
- mov f66_cp,bx ; Save requested CodePage
- mov preperr,0000 ; Initialize Prepare Error
- push ds ! pop es
- mov bx,offset dev_root ; Get the Root of the Device List
- f66_p10: ; Skip the NUL Device and check
- lds bx,ds:DH_NEXT[bx] ; each character device for CodePage
- cmp bx,0FFFFh ! jz f66_p50 ; Support.
- mov ax,ds:DH_ATTRIB[bx]
- and ax,DA_CODEPAGE ; Check for a Character Device which
- cmp ax,DA_CODEPAGE ; supports IOCTL strings and GETSET
- jne f66_p10 ; otherwise skip the device
- push bx
- lea si,DH_NAME[bx] ; Found a matching device so
- mov di,offset prepname ; open the device and select the
- mov cx,8 ; requested codepage
- f66_p20:
- lodsb
- cmp al,' ' ! jz f66_p30
- stosb
- loop f66_p20
- f66_p30:
- xor al,al ! stosb
- mov ax,(MS_X_OPEN*256)+1 ; Open the device name for
- mov dx,offset prepname ; Write Access
- call dos_entry
- jc f66_perr
- mov bx,ax ; Save Device Handle in BX
- mov si,es:f66_cp ; Get Requested CodePage in SI
- mov dx,offset cp_packet ; Offset of CodePage Struct
- mov cx,006Ah ; Get Unknown CodePage
- mov ax,(MS_X_IOCTL*256)+0Ch ; Generic IOCTL function
- call dos_entry ; Make function Call
- jc f66_p32 ; Error so Select requested Code Page
- cmp si,es:cp_cpid ! jz f66_p35 ; If this the currently selected
- f66_p32: ; skip the select CodePage
- mov es:cp_cpid,si
- mov dx,offset cp_packet ; Offset of CodePage Struct
- mov cx,004Ah ; Select Unkown CodePage
- mov ax,(MS_X_IOCTL*256)+0Ch ; Generic IOCTL function
- call dos_entry ; Make function Call
- jnc f66_p35 ; No Error so skip the error
- f66_p33:
- mov es:preperr,ax ; save
- f66_p35:
- mov ah,MS_X_CLOSE ; Close the device and check
- call dos_entry ; for more devices to be prepared
- jmps f66_p40
- f66_perr:
- mov es:preperr,ax ; Save the error code and try the
- f66_p40: ; next device in the chain
- pop bx ; Restore the Device offset
- jmps f66_p10 ; and continue
- f66_p50: ; All device have been prepared
- pop ds ; now return the last error code
- mov ax,preperr ; in AX
- or ax,ax
- ret
- endif
- PCMODE_DSIZE DSEG PARA
- extrn swap_indos:word
- PCM_RODATA CSEG WORD
- ;
- ; Get Internal Data DOS function 5Dh
- ;
- func5D_ft dw f5D00
- dw f5D01 ; Commit All
- dw f5D02 ; Close File By Name
- dw f5D03 ; Close All Host Files
- dw f5D04 ; Close Process Host Files
- dw f5D05 ; Get Open File List
- dw f5D06 ; Get DOS Data Area
- dw f5D_msnet ; f5D07 ; Get Truncate Flag used
- ; with Redirected Dev I/O
- dw f5D_msnet ; f5D08 ; Set Truncate Flag with
- ; with Redirected Dev I/O
- dw f5D_msnet ; f5D09 ; Close All Spool Streams
- dw f5D0A ; Set Extended Error Info
- func5D_ftl equ (offset $ - offset func5D_ft)/2
- dw invalid_function
- ;
- ; Data used by the Binary format Time and Date routines
- ;
- totaldays dw 0,31,59,90,120,151,181,212,243,273,304,334,0ffffh
- monthdays db 31,28,31,30,31,30,31,31,30,31,30,31
- parse_separators db TAB,'.,+:;='
- parse_terminators db '|"/[]<>'
- PCMODE_DATA DSEG WORD
- extrn internal_data:word
- extrn error_code:word
- extrn error_class:byte
- extrn error_action:byte
- extrn error_locus:byte
- extrn error_dev:word
- extrn indos_flag:word
- extrn bootDrv:byte
- extrn current_psp:word
- extrn break_flag:byte
- extrn dma_offset:word
- extrn dma_segment:word
- extrn fcb_search_buf:byte
- extrn func52_data:byte ; Internal Data Table Area
- extrn int21regs_ptr:dword
- extrn lock_tables:dword
- extrn unlock_tables:dword
- extrn share_stub:dword
- extrn remote_call:word ; set to FF if remote machine operation
- extrn swap_always:word
- extrn switch_char:byte
- extrn owning_psp:word
- extrn machine_id:word
- extrn country_data:byte
- extrn cur_country:word
- extrn cur_cp:word
- extrn verify_flag:byte
- extrn clk_device:dword ; Clock Device Driver Address
- extrn biosDate:word
- extrn daysSince1980:word
- extrn yearsSince1980:word
- extrn month:byte
- extrn dayOfWeek:byte
- extrn dayOfMonth:byte
- extrn hour:byte
- extrn minute:byte
- extrn second:byte
- extrn hundredth:byte
- if DOS5
- extrn WindowsHandleCheck:byte
- else
- extrn win386_remote_machine:dword
- endif
- SYS_CP equ 437 ; System CodePage
- GLOBAL_DATA dseg word
- f38_flag dw 0 ; Country Code Selected Successfully
- if not NLSFUNC
- extrn dev_root:dword
- f66_cp rw 1 ; INT21/66 Local Variable
- cp_packet dw 2 ; Packet Size
- cp_cpid dw 0 ; Request CodePage
- db 0,0 ; Packet Terminators
- preperr rw 1 ; Prepare function Error Code
- prepname rb 9 ; Reserved for ASCIIZ Device Name
- ;
- ; Area for country.sys current pointer table
- ; (these are all offsets into country.sys)
- ;
- f65xx_code rw 1 ; Country code
- f65xx_cp rw 1 ; Code page
- rw 1 ; +1 reserved
- f65xx_data rw 1 ; Data area
- rw 1 ; Upper case table
- rw 1 ; +1 reserved
- rw 1 ; Filename upper case table
- rw 1 ; Legal file characters
- rw 1 ; Collating table
- rw 1 ; Double byte character set lead byte table
- f65xx_ptable_len equ offset $ - offset f65xx_code
- f65xx_temp_area rb 256 ; Data area for extended country info
- f65xx_codepage rw 1
- f65xx_country rw 1
- f65xx_sig rw 1 ; Signature
- c_handle rw 1
- endif ;not NLSFUNC
- end