PCMIF.A86
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:32k
源码类别:
操作系统开发
开发平台:
Asm
- ; File : $PCMIF.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: $
- ; PCMIF.A86 1.21 93/09/09 22:36:50
- ; Int 21/59 uses error stack
- ; PCMIF.A86 1.20 93/08/27 18:56:30
- ; Int 25/26 32 bit sector detection
- ; PCMIF.A86 1.19 93/07/22 19:30:54
- ; chnage int 25/26 support for NDD
- ; PCMIF.A86 1.18 93/07/20 22:47:54
- ; Even fewer checks on int 25/26
- ; PCMIF.A86 1.14 93/05/06 19:28:31
- ; Move int 23/28 support to CIO.
- ; PCMIF.A86 1.13 93/05/05 23:31:0
- ; int 2A/84 is now only generated on input-and-wait functions
- ; PCMIF.A86 1.12 93/03/25 15:06:48
- ; tweak int21 entry
- ; ENDLOG
- ;
- ; 24 Aug 87 The CARRY flag is now preserved for all DOS functions below
- ; 038h Get/Set Country Code.
- ; 04 Sep 87 Display the Interrupt Number and Registers when an illegal
- ; software interrupt is executed by an application. This
- ; is disabled by DBG OFF.
- ; 09 Sep 87 DDIO interface changed to support a Double Word sector
- ; number.
- ; 05 Oct 87 Critical Error abort routine now uses the correct
- ; terminate code.
- ; 14 Oct 87 INT2F responds like a Network Redirector
- ; 28 Oct 87 Preserve the state of the INDOS_INTERNAL flag during multiple
- ; calls through DOS_ENTRY
- ; 29 Oct 87 DS now points at the IBM PC ROS during an INT1B and INT1B
- ; moved into IBMROS.
- ; 7 Nov 87 Removal of development flags
- ; 5 Jan 88 Terminate CP/M applications making DOS Calls in Concurrent DOS
- ; 26 Feb 88 Terminate DOS applications making CP/M calls in DOSPLUS
- ; 26 Apr 88 INT25/26 error codes only translated for Concurrent
- ; 18 May 88 Prevent corruption of the EXIT_CODE by INT23 and INT24
- ; when the application does not return.
- ; 23 May 88 Prevent termination during CONFIG.SYS processing in DOSPLUS
- ; 26 May 88 Force INDOS and ERROR flags to ZERO on terminate
- ; 1 Jun 88 Modify INT28 to execute delays and work with SideKick.
- ; 15 Jul 88 Support the IDLECNT field in the Process Descriptor and
- ; CCB BUSY bit.
- ; 07 Sep 88 PolyTron PolyWindows make DOS functions calls whenever
- ; CS < SS. Therefore during the INT21 Entry and Exit code
- ; interrupts must be disabled untill the stack swap occurs
- ; even though the INDOS_FLAG is non-zero.
- ; 24 Oct 88 File Lock/Unlock is now treated as an INACTIVE function.
- ; 4 Nov 88 Correct the INT25/26 Error Translation Code
- ; 21 Nov 88 Make INt25/26 Error Translation even better.
- ; 29 Nov 88 Command Line Editor Insert on by default.
- ; 21 Dec 88 IJs IDLE detection improvement only DELAY if someone else is
- ; ready to run.
- ; 11 Jan 89 Inc/Dec INTERNAL_FLAG to support DOS_ENTRY reentrancy.
- ; 30 Jan 89 Inc/Dec INDOS_FLAG to INT25/26 Direct Disk I/O (CHKDSK/PRINT)
- ; 19 Feb 89 Check the SHARE_FLAG for SHARING status in DR DOS
- ; 9 Mar 89 Save/Restore PSP_USERSP/SS round int28's (SKPLUS/LINK/CTRL-C)
- ; 18 Apr 89 ij Maintain the INDOS_FLAG correctly while processing INT 24
- ; 18 Apr 89 Only take over INTs 5B and 5C for Debug Systems
- ; 22 May 89 Setup DS before testing the state of the Share Flag.
- ; 25 May 89 Support INT28_FLAG for functions 01 to 0C inclusive
- ; 31 May 89 Move break_sp into DOS internal data area
- ; 1 Jun 89 Save PSP_USERSS and SP during a critival Error (INT 24)
- ; 05 Jun 89 Return NOT present for ASSIGN command and TRUE state for APPEND
- ; 29 Jun 89 Save/restore retry_sp & retry_off around INT 24
- ; 10 Jul 89 INT27 corrected to handle memory size of XXX1 (INFORM)
- ; 31 Jul 89 Move stacks to DATA.PCM (CDROM support under way...)
- ; 11 Aug 89 Create INT2F.PCM to support real INT 2F functions
- ; 6 Sep 89 INT2A/84 keyboard busy loop added to do_int28
- ; 23 Oct 89 MON_PERM removed from func5D/func5E/func5F (pain with MSNET..)
- ; 9 Nov 89 Int 5B & 5C no longer taken over in DRDOS Debug versions
- ; (Conflicts with PC-Net)
- ; 15 Jan 90 pcmode_swapin/pcmode_swapout added for paged isr support
- ; 25/Jan/90 Support Idle Data Area
- ; 25/Jan/90 Add forth stack to support Japanese FEP and PTHOT.
- ; 29/Jan/90 keep int21 CS/IP/FLAGS on local stack
- ; 13/Feb/90 Added func63.
- ; 20/Feb/90 CDOS checks caller is DOS process and aborts if not.
- ; 22/Feb/90 Int25/26 checks disk label for passwords
- ; Also swaps to normal stack like others DOS's
- ; 7 Mar 90 Convert to register preserved function calls
- ; 16 Mar 90 Int25/26 checks out for Leopard Beta 2
- ; 4 Jun 90 Int21/25&35 don't swap stacks-ANSI.SYS Framework DOS window bug
- ; 7 Jun 90 Print Rite fix moves to init.pcm
- ; 29 Jun 90 CDOS idle detection uses timer info
- ; 9 Aug 90 Int 8 tick count packed in P_CMOD
- ; 19 Sep 90 load current_psp before checking PSP_PIDF (thanks Datapac)
- ; 4 Oct 90 improved control break handling
- ; 11 Oct 90 dev_map now supported to set LPTn/COMn mapping
- ; 1 Nov 90 default Int 24 handler returns "Fail"
- ; 19 feb 91 do_int28 calls read_time_and_date (BIOS CLOCK needs a call
- ; every day)
- ; 14 jun 91 copy user regs to local copy after int24 for pcshell
- ; 8 aug 91 SI preserved on Int25/26 for SCAN 7.7
- include pcmode.equ
- include fdos.def
- include vectors.def
- include i:msdos.equ
- include i:mserror.equ
- include i:psp.def
- include i:fdos.equ
- PCM_CODE CSEG BYTE
- extrn pcmode_dseg:word
- extrn break_check:near ; Control-C Check
- extrn error_exit:near
- extrn fdos_nocrit:near
- extrn get_ddsc:near
- eject
- ;
- ; This entry point is used when a CALLF PSP:0005 has been executed
- ; Here the function number is passed in CL and not AH and only
- ; functions 0 to 24 inclusive can be executed.
- ;
- ; Entry Stack -> INT 21 Stack
- ;
- ; SP + 04 Return Offset Current Flags
- ; SP + 02 PSP Segment PSP Segment
- ; SP + 00 000Ah Return Offset
- ;
- Public call5_entry
- call5_entry:
- pop ax ; Remove 000Ah return Offset
- pushf ; Save the Flags
- push bp ! mov bp,sp ; Get Stack Frame Pointer
- mov ax,02[bp] ; Get the FLAGS
- xchg ax,06[bp] ; Swap with the return offset
- mov 02[bp],ax ; and then save the return offset
- pop bp ; Restore the BP register
- mov ah,cl ; Make it look like an INT 21
- cmp ah,024h ; Check for a valid function for this
- jbe int21_entry ; entry technique if not return
- illegal_iret:
- mov al,0
- iret
- int21_e01:
- mov ds,word ptr .INT31_SEGMENT
- jmps int21_e02
- eject
- ; ++++++++++++++++++++++++++
- ; Int 20 - Program Terminate
- ; ++++++++++++++++++++++++++
- ;
- Public int20_entry
- int20_entry:
- mov ah,00h
- ; jmps int21_entry ; and jump to the standard entry point
- eject
- ; +++++++++++++++++++++++++
- ; Int 21 - Function Request
- ; +++++++++++++++++++++++++
- ;
- Public int21_entry
- int21_entry:
- cmp ah,pcmode_ftl ; is it in range ?
- ja illegal_iret ; no, return BEFORE enabling ints
- cld ; Clear the direction flag
- PUSH$DOS ; Save User Registers
- mov ds,pcmode_dseg ; get CS relative Data Segment
- test pcmode_dseg,0FFFFh ; if Data Segment is zero then get
- jz int21_e01 ; the Data segment address from
- int21_e02: ; the segment portion of INT 31
- ;
- ; The following routines execute on the users stack without
- ; modifing the INDOS_FLAG etc. These routines should only read
- ; or update BASIC system variables.
- ;
- cmp ah,33h ; Func 33h - Control Break
- je int21_e10
- cmp ah,50h ; Func 50h - Set PSP
- jb int21_e20
- cmp ah,51h ; Func 51h - Get PSP
- jbe int21_e10
- cmp ah,62h ; Func 62h - Get PSP
- jne int21_e20
- int21_e10:
- mov bp,sp ; Calculate the Stack Frame address
- call internal_func ; "jump" to appropriate routine
- jmp int21_exit
- int21_e20:
- inc indos_flag ; Increment the INDOS Flag
- mov int21AX,ax ; save function number
- if DOS5
- cmp WindowsHandleCheck,26h ; is windows active ?
- jne int21_e30
- mov ax,LocalMachineID ; get local machine ID (zero unless
- mov machine_id,ax ; we are multi-tasking)
- else
- callf win386_local_machine
- cmp machine_id,0 ; did it nobble the machine ID
- jnz int21_e30 ; if so leave it alone
- mov ax,LocalMachineID ; get local machine ID (zero unless
- mov machine_id,ax ; we are multi-tasking)
- endif
- int21_e30:
- mov ax,current_psp
- mov owning_psp,ax
- mov es,ax ; Get the PSP
- mov ax,sp
- mov PSP_USERSP,ax ; Save the SS:SP pointer to
- mov PSP_USERSS,ss ; the register image ready for any
- ; Critical errors that might occur
- xchg ax,int21regs_off ; point to callers registers
- mov prev_int21regs_off,ax ; while saving current
- mov ax,ss ; pointer to cater for
- xchg ax,int21regs_seg ; re-entrancy
- mov prev_int21regs_seg,ax
- xor ax,ax
- mov remote_call,ax ; indicate we are a local call
- mov int28_flag,al ; Do NOT Generate INT 28s
- mov ax,ds
- mov ss,ax ; swap initially to the error
- mov sp,offset error_stack ; stack until we know better
- mov ax,int21AX ; reload AX
- sti
- cmp ah,59h ; Func 59h - Return Extended Error
- je int21_e50 ; use the error stack
- cmp ah,0Ch ; are we a character function
- ja int21_e40 ; in range 01-0C ?
- cmp ah,00h
- je int21_e40
- cmp error_flag,0 ; Use the "ERROR" Stack for the above
- jnz int21_e50 ; functions 01-0C if error_flag set
- mov sp,offset indos_stack ; else use the "INDOS" stack for these
- mov int28_flag,TRUE ; functions and generate INT 28s
- jmps int21_e50
- int21_e40:
- mov error_flag,0 ; clear the error flag in case someone
- ; hasn't returned from an Int 24
- push ax ; save function on stack
- mov ah,82h ; magic number in AH
- int 2ah ; call server hook
- pop ax ; recover function number
- mov sp,offset normal_stack ; switch to the NORMAL stack
- test break_flag,0FFh ; is the Break Flag ON
- jz int21_e50 ; NO - So continue
- call break_check ; Handle the Control-C
- int21_e50:
- if IDLE_DETECT
- test idle_flags,IDLE_DISABLE ; don't break the pipeline unless
- jz int21_idle ; IDLE checking enabled
- int21_e60:
- endif
- call int21_func ; Execute the function
- cli ; Stop anybody interfering
- les bp,int21regs_ptr ; point to user stack
- mov es:reg_AL[bp],al ; always return AL
- mov ax,prev_int21regs_off
- mov int21regs_off,ax
- mov ax,prev_int21regs_seg
- mov int21regs_seg,ax
- mov ax,es
- mov ss,ax ; back to users stack
- mov sp,bp
- dec indos_flag ; Decrement the INDOS_FLAG
- ; jmp int21_exit
- Public int21_exit
- int21_exit:
- POP$DOS ; Restore Registers
- iret
- eject
- if IDLE_DETECT
- ; Only called if Idle detection is enabled
- ; AH,DL as on Int 21 Entry
- ; Decide if function is active/inactive
- int21_idle:
- ;----------
- if IDLE_DETECT
- mov bx,int28_reload ; reset the INT28 delay counter
- mov int28_delay,bx ; with the Reload value
- endif
- cmp ah,5Ch ! je int21_inactive ; Treat Lock/Unlock as inactive some
- ; applications poll locked record.
- cmp ah,44h ! je int21_inactive ; IO Control Treated as Inactive
- cmp ah,2Ch ! ja int21_active ; > Get Current Time all active
- je int21_inactive ; Get Current Time inactive
- cmp ah,2Ah ! je int21_inactive ; Get Current Date inactive
- cmp ah,0Bh ! je int21_inactive ; Console Status
- cmp ah,0Ch ! je int21_inactive ; Flush and Invoke Treated as Inactive
- cmp ah,19h ! je int21_inactive ; Get Current Disk
- cmp ah,06h ! jne int21_active ; Treat RAW_IO Status as Inactive
- cmp dl,0FFh ! je int21_inactive ;
- int21_active: ; Active function Executed
- or idle_flags,IDLE_DOSFUNC ; set DOSFUNC flag for BIOS
- call active ; remember we were active
- jmps int21_e60 ; continue execution
- int21_inactive:
- call inactive ; Process this INACTIVE function
- jmps int21_e60
- Public inactive
- inactive:
- push es ! push ax
- dec active_cnt ; Decrement the count
- jnz inactive_10 ; Return if Non-Zero
- mov ax,idle_max ; Get the default count value
- mov active_cnt,ax ; and reset the internal count
- test idle_flags,IDLE_DISABLE ; Has Idle Checking been enabled
- jnz inactive_10 ; Skip if NO.
- mov ax,PROC_IDLE ; Process is IDLE
- callf idle_vec ; Call the IDLE Handler
- inactive_10:
- pop ax ! pop es
- ret
- ;
- ; This routine will reset the active count for functions which
- ; are treated as INACTIVE but which have active sub-functions.
- ;
- Public active
- active:
- push ax
- mov ax,idle_max ; Get the default count value
- mov active_cnt,ax ; and reset the internal count
- pop ax
- ret
- endif
- ;
- ;
- ; This function is invoked for functions number above the last
- ; supported function number. It forces AL to zero and returns.
- ; Just that and nothing more.
- ;
- ms_zero_AL:
- xor ax,ax ; AL = 0 for return
- ret
- eject
- ; DOS_ENTRY is used to call DOS functions internally.
- ; eg. Func4B (exec) calls MS_X_OPEN, MS_X_READ, MS_X_CLOSE etc.
- ; It is the responsibilty of the caller to make sure that no side
- ; effects exist if this entry point is used.
- ; eg. critical error handling
- ;
- ;
- Public dos_entry
- dos_entry:
- clc
- cld
- pushf ; look like Int21 registers
- pushf ! pushf ; fake CS/IP positions
- push ds ! push es ; Save registers on the USER stack
- push bp ; no Stack Swap is executed and DS
- push di ! push si ; and ES are swapped.
- push dx ! push cx
- push bx ! push ax
- mov bp,sp ; Initialise Stack Frame
- call get_dseg ; Get our Data Area
- inc internal_flag
- push fdos_data+0*WORD ; save fdos pblk so we can
- push fdos_data+1*WORD ; be re-entrant(ish)
- push fdos_data+2*WORD
- push fdos_data+3*WORD
- push fdos_data+4*WORD
- push fdos_data+5*WORD
- push fdos_data+6*WORD
- push int21regs_off
- push int21regs_seg
- mov int21regs_off,bp
- mov int21regs_seg,ss
- call internal_func ; Execute the function
- mov reg_AL[bp],al ; always return AL to caller
- pop int21regs_seg
- pop int21regs_off ; restore previous pointer user REGS
- pop fdos_data+6*WORD
- pop fdos_data+5*WORD
- pop fdos_data+4*WORD
- pop fdos_data+3*WORD
- pop fdos_data+2*WORD
- pop fdos_data+1*WORD
- pop fdos_data+0*WORD ; restore fdos_pb for nested calls
- dec internal_flag
- pop ax ! pop bx ; Update the registers then
- pop cx ! pop dx ; set the flags and return
- pop si ! pop di ; to the user
- pop bp
- pop es ! pop ds
- popf ; discard dos_IP
- popf ; and dos_CS
- popf ; get result
- jnc dos_entry10
- neg ax ; return using our negative error
- stc ; conventions
- dos_entry10:
- ret
- Public int21_func
- int21_func:
- ;----------
- ; On Entry:
- ; AX, CX, DX, SI, DI as per Int 21
- ; BX = ??
- ; BP = ??
- ; DS = pcmode data
- ; ES = ??
- ; On Exit:
- ; (to client function)
- ; All general purpose registers as per Int 21 entry
- ; ES = dos_DS
- ;
- xor bx,bx ; BH = 0
- mov bl,ah ; BX = function number
- shl bx,1 ; make it a word offset
- push pcmode_ft[bx] ; save address of Function
- les bp,int21regs_ptr
- mov bx,es:reg_BX[bp] ; reload from dos_BX,dos_BP,and dos_DS
- les bp,es:dword ptr reg_BP[bp]
- ret
- internal_func:
- ;-------------
- ; On Entry:
- ; All registers as per Int 21 EXCEPT
- ; DS = pcmode data
- ; BP = dos_REGS stack frame
- ; On Exit:
- ; (to client function)
- ; ES = dos_DS
- ;
- mov al,ah ; function number in AL
- cbw ; AH = 0
- xchg ax,bx ; get subfunction in BX
- shl bx,1 ; make offset in the internal table
- push pcmode_ft[bx] ; save address of Function
- xchg ax,bx ; restore BX
- mov ax,reg_AX[bp] ; recover function number
- mov es,reg_DS[bp] ; ES = callers DS
- ret ; "jump" to handler
- eject
- ; INT25 and INT26 direct disk I/O interface
- ;
- ;Standard DOS 1.xx - 3.30 INT25/26 Interface
- ;===========================================
- ;
- ; entry: al = drive number
- ; ds = DMA segment
- ; bx = DMA offset
- ; cx = number of sectors
- ; dx = beginning relative sector
- ;
- ;
- ;Enhanced DOS 3.31 INT25/26 Interface
- ;====================================
- ;
- ; If CX == 0FFFFh then the application is using the enhanced
- ; INT25/INT26 interface which allows access to more than 64K
- ; sectors.
- ;
- ; entry: al = drive number
- ; bx = Parameter block Offset
- ; ds = Parameter block Segment
- ;
- ; Parameter Block Format
- ;DS:BX -> DD Starting Sector No.
- ; DW Number of Sectors
- ; DD Transfer Address
- ;
- ;
- ; exit: C flag = 0 if successful
- ; = 1 if unsuccessful
- ; ax = error code(if CF = 1)
- ; ah physical error
- ; al logical error
- ; Users orginal flags left on stack
- ;
- ;
- eject
- DDIO_INT13 equ 0
- DDIO_READ_OP equ 1
- DDIO_WRITE_OP equ 2
- ; ++++++++++++++++++++++++++++
- ; Int 26 - Absolute Disk Write
- ; ++++++++++++++++++++++++++++
- ;
- Public int26_entry
- int26_entry:
- mov ah,DDIO_WRITE_OP ; This is a WRITE operation
- jmps int26_10
- ; +++++++++++++++++++++++++++
- ; Int 25 - Absolute Disk Read
- ; +++++++++++++++++++++++++++
- ;
- Public int25_entry
- int25_entry:
- mov ah,DDIO_READ_OP ; This is a READ operation
- int26_10: ; Common Direct Disk I/O code
- cld
- push ds ! push es
- push dx ; save DX for FLASHCARD
- push ds ! pop es ; ES = callers DS
- call get_dseg ; Get PCMODE Data Segment
- inc indos_flag ; Update the INDOS_FLAG
- mov normal_stack+2,ss ; save users SS:SP
- mov normal_stack,sp
- cli
- push ds ! pop ss ; use normal stack when in here
- mov sp,offset normal_stack
- sti
- inc cx ; CX = FFFF indicates this is
- jz int26_30
- ; CHECK FOR PARITIONS > 32 MBytes...
- dec cx ; CX restored
- push es
- push ax
- push bx
- push dx
- call get_ddsc ; ES:BX -> DDSC_
- mov di,0201h ; assume bad drive
- jc int26_20
- mov di,0207h ; assume large media, and this error
- if 0
- ; This code works out the total number of sectors on a drive
- mov ax,es:DDSC_NCLSTRS[bx] ; get last cluster #
- dec ax ; make it # data clusters
- xor dx,dx
- mov dl,es:DDSC_CLMSK[bx] ; get sec/cluster -1
- inc dx ; DX = sec/cluster
- mul dx ; DX:AX = # data sectors
- add ax,es:DDSC_DATADDR[bx] ; add in address of 1st data sector
- adc dx,0
- else
- mov ax,es:DDSC_NCLSTRS[bx] ; get last cluster #
- xor dx,dx
- mov dl,es:DDSC_CLMSK[bx] ; get sec/cluster -1
- inc dx ; DX = sec/cluster
- mul dx ; DX:AX is vaguely the # sectors
- test dx,dx ; close enough for bill
- endif
- stc ; assume an error
- jnz int26_20
- xor di,di ; DI = zero, no error
- int26_20:
- pop dx
- pop bx
- pop ax
- pop es
- jnc int26_40
- xchg ax,di ; AX = error code
- jmps int26_60 ; return it
- int26_30:
- mov dx,es:word ptr 0[bx] ; Get Starting Sector Low
- mov di,es:word ptr 2[bx] ; Get Starting Sector High
- mov cx,es:word ptr 4[bx] ; Get No. of sectors to transfer
- les bx,es:dword ptr 6[bx] ; Tranfer Address Offset
- int26_40:
- mov FD_DDIO_DRV_OP,ax ; save drive and operation
- mov FD_DDIO_NSECTORS,cx ; No. of Sectors
- mov FD_DDIO_STARTLOW,dx ; Starting Sector No.
- mov FD_DDIO_STARTHIGH,di ; High Word of Sector Number
- mov FD_DDIO_DMAOFF,bx ; DMA Offset
- mov FD_DDIO_DMASEG,es ; DMA Segment
- mov FD_FUNC,FD_DDIO
- call fdos_nocrit ; let the FDOS do the work
- neg ax ; AX is DOS extended error
- jz int26_exit
- sub al,-ED_PROTECT ; get AL to Int24 error format
- cmp al,-(ED_GENFAIL-ED_PROTECT)
- jbe int26_50
- mov al,-(ED_GENFAIL-ED_PROTECT)
- int26_50: ; no, make it general failure
- mov ah,al ; save error in AH
- mov bx,offset int13_error
- xlat int13_error ; convert error to int13 format
- xchg al,ah ; get errors in correct registers
- int26_60:
- stc ; Set the Carry Flag when an error
- int26_exit: ; Occurs and return to the calling app.
- cli
- mov ss,normal_stack+2 ; back to user stack
- mov sp,normal_stack
- sti
- dec indos_flag ; Update the INDOS_FLAG
- sti
- pop dx
- pop es ! pop ds ; restore callers registers
- retf ; leave flags on stack
- int13_error db 03h,02h,80h,01h,10h,02h,40h,02h,04h,02h,02h,02h,02h
- eject
- ; ++++++++++++++++++++++++++++++++++++
- ; Int 27 - Terminate but Stay Resident
- ; ++++++++++++++++++++++++++++++++++++
- ;
- Public int27_entry
- int27_entry:
- mov ax,3100h ; Convert this to a DOS 'Terminate and
- add dx,15 ; Stay Resident' function by converting the
- rcr dx,1 ; memory size in bytes to paragraphs.
- shr dx,1 ; On entry DX == memsize + 1 bytes therefore
- shr dx,1 ; round upto a paragraph boundary by adding
- shr dx,1 ; 15 then divide by 16
- jmp int21_entry
- eject
- ;
- ; DO_INT24:
- ; On Entry:-
- ; AH Set for INT 24
- ; AL Drive Number (0 = A:)
- ; DI Error Code
- ; ES:SI Device Header Control Block
- ;
- ; On Exit:-
- ; AL Error Response Retry/Ignore/Fail
- ;
- ; INT 24 Critical Error:-
- ; On Entry:- AH/7 0 = Disk Device
- ; AH/5 0 = IGNORE is an Invalid Response
- ; AH/4 0 = RETRY in an Invalid Response
- ; AH/3 0 = FAIL is an Invalid Response
- ; AH/2-1 00= DOS Area
- ; 01= File Allocation Table
- ; 10= Directory
- ; 11= Data
- ; AH/0 0 = Read, 1 = Write
- ;
- ; AL 1 Retry the Operation
- ; BP:SI Device Header Control Block
- ; DI High Byte Undefined, Low Byte Error Code
- ;
- ; On Exit:- AL 0 = IGNORE Error
- ; 1 = RETRY the Operation
- ; 2 = TERMINATE using INT 23
- ; 3 = FAIL the current DOS function
- ;
- Public do_int24
- do_int24:
- cmp error_flag,0 ; Skip the critical error routine
- jz di24_05 ; if the handler is active
- mov al,ERR_FAIL ; Then return the FAIL condition
- ret ; to the calling routine
- di24_05:
- push ax ! push bp ; Save our Base Pointer and then the
- cli ; Disable Interupts
- mov bp,es ; BP:SI points to dev header
- mov es,current_psp ; Get the current PSP and USER Stack
- push PSP_USERSS ; Save the Users Real SS and SP
- push PSP_USERSP ; on the internal Stack
- push retry_sp ; also the retry info
- push retry_off
- push remote_call
- push machine_id
- mov critical_sp,sp ; Internal Stack Pointer Offset
- inc error_flag ; Entering Critical Error Handler
- dec indos_flag ; I may be gone some time....
- ; (an application error handler need
- ; never return so tidy up first)
- mov ss,PSP_USERSS ; Switch to the Users Stack
- mov sp,PSP_USERSP
- int 24h ; Call the Critical Error Handler
- cld
- cli ; paranioa.....
- call get_dseg ; Reload DS just in case someone at
- ; A-T or Lotus cannot read
- push ds ! pop ss ; Swap back to the Internal stack
- mov sp,critical_sp ; and process the returned info.
- pop machine_id
- pop remote_call
- pop retry_off ; restore retry info
- pop retry_sp
- mov es,current_psp ; Restore the Users original SS and
- pop PSP_USERSP ; SP registers from the Stack
- pop PSP_USERSS
- pop bp ! pop bx ; Restore BP and original AX
- sti
- mov error_flag,0
- inc indos_flag
- cmp al,ERR_IGNORE ! jnz di24_10 ; Check for IGNORE and force
- test bh,OK_IGNORE ! jnz di24_10 ; to become a FAIL if its an
- mov al,ERR_FAIL ; invalid response.
- di24_10:
- cmp al,ERR_RETRY ! jnz di24_20 ; Check for RETRY and force
- test bh,OK_RETRY ! jnz di24_20 ; to become a FAIL if its an
- mov al,ERR_FAIL ; invalid response.
- di24_20:
- cmp al,ERR_FAIL ! jnz di24_30 ; Check for FAIL and force
- test bh,OK_FAIL ! jnz di24_30 ; to become a ABORT if its an
- mov al,ERR_ABORT ; invalid response.
- di24_30:
- cmp al,ERR_ABORT ; Do not return if the ABORT option
- jz di24_abort ; has been selected but execute
- ; INT 23 directly
- cmp al,ERR_FAIL ; All invalid reponses are converted
- ja di24_abort ; to ABORT
- di24_40:
- ret
- di24_abort: ; Abort this Process
- mov ax,current_psp ; check not root application because
- mov es,ax ; it must not be terminated so force
- cmp ax,PSP_PARENT ; Is this the root Process
- mov al,ERR_FAIL ; convert the error to FAIL
- je di24_40 ; if not we terminate
- mov exit_type,TERM_ERROR ; Set the correct exit Type
- mov ax,04C00h ; and return code.
- mov int21AX,ax
- jmp func4C ; Then terminate
- eject
- ;
- ; Get the PCMODE Emulator data Segment from the PD
- ;
- Public get_dseg
- get_dseg:
- mov ds,pcmode_dseg ; get CS relative Data Segment
- test pcmode_dseg,0FFFFh ; If Data Segment is zero then get
- jz get_d10 ; the Data segment address from
- ret ; the segment portion of INT 31
- get_d10:
- mov ds,word ptr .INT31_SEGMENT
- ret
- ;
- ;INVALID_FUNCTION is called when any unsupported function has been executed
- ;
- Public invalid_function
- invalid_function:
- mov ax,ED_FUNCTION ; Mark as Invalid Function
- jmp error_exit ; and Exit
- eject
- Public reload_registers
- reload_registers:
- ;----------------
- ; This routine is called to reload the registers we expect to have correct
- ; at the start of a PCMODE function.
- push ds
- lds bp,int21regs_ptr
- mov ax,ds:reg_AX[bp]
- mov bx,ds:reg_BX[bp]
- mov cx,ds:reg_CX[bp]
- mov dx,ds:reg_DX[bp]
- mov si,ds:reg_SI[bp]
- mov di,ds:reg_DI[bp]
- les bp,ds:dword ptr reg_BP[bp]
- pop ds
- ret
- PCMODE_DATA DSEG WORD
- extrn retry_sp:word
- extrn retry_off:word
- extrn break_flag:byte
- extrn current_psp:word
- extrn current_dsk:byte
- extrn dma_offset:word
- extrn dma_segment:word
- extrn error_flag:byte
- extrn error_stack:word
- extrn exit_type:byte
- extrn int21regs_ptr:dword
- extrn int21regs_off:word
- extrn int21regs_seg:word
- extrn prev_int21regs_ptr:dword
- extrn prev_int21regs_off:word
- extrn prev_int21regs_seg:word
- extrn indos_flag:byte
- extrn indos_stack:word
- extrn LocalMachineID:word
- extrn machine_id:word
- extrn int21AX:word
- extrn normal_stack:word
- extrn owning_psp:word
- extrn remote_call:word
- if DOS5
- extrn WindowsHandleCheck:byte
- else
- extrn win386_local_machine:dword
- endif
- if IDLE_DETECT
- extrn active_cnt:word
- extrn idle_max:word
- extrn idle_flags:word
- extrn idle_vec:dword
- extrn int28_delay:word
- extrn int28_reload:word
- endif
- extrn critical_sp:word
- extrn internal_flag:byte
- extrn int28_flag:byte
- PCM_CODE CSEG BYTE
- ;
- ; The following Function tables are forced onto a word boundary
- ; because of the word alignment of the PCMODE_RODATE segment.
- ; Only word based Read Only data is held in this segment.
- ;
- extrn func00:near, func01:near, func02:near, func03:near
- extrn func04:near, func05:near, func06:near, func07:near
- extrn func08:near, func09:near, func0A:near, func0B:near
- extrn func0C:near, func0D:near, func0E:near, func0F:near
- extrn func10:near, func11:near, func12:near, func13:near
- extrn func14:near, func15:near, func16:near, func17:near
- extrn func19:near, func1A:near, func1B:near, func1C:near
- extrn func1F:near, func21:near, func22:near, func23:near
- extrn func24:near, func25:near, func26:near, func27:near
- extrn func28:near, func29:near, func2A:near, func2B:near
- extrn func2C:near, func2D:near, func2E:near, func2F:near
- extrn func30:near, func31:near, func32:near, func33:near
- extrn func34:near, func35:near, func36:near, func37:near
- extrn func38:near, func39:near, func3A:near, func3B:near
- extrn func3C:near, func3D:near, func3E:near, func3F:near
- extrn func40:near, func41:near, func42:near, func43:near
- extrn func44:near, func45:near, func46:near, func47:near
- extrn func48:near, func49:near, func4A:near, func4B:near
- extrn func4C:near, func4D:near, func4E:near, func4F:near
- extrn func50:near, func51:near, func52:near, func53:near
- extrn func54:near, func55:near, func56:near, func57:near
- extrn func58:near, func59:near, func5A:near, func5B:near
- extrn func5C:near, func5D:near, func5E:near, func5F:near
- extrn func60:near, func62:near, func63:near, func65:near
- extrn func66:near, func67:near, func68:near, func69:near
- extrn func6C:near
- PCM_RODATA CSEG WORD
- Public pcmode_ft, pcmode_ftl
- pcmode_ft rw 0
- dw func00 ; (00) Terminate Program
- dw func01 ; (01) Read Keyboard and Echo
- dw func02 ; (02) Display Character
- dw func03 ; (03) Auxilary Input
- dw func04 ; (04) Auxilary Output
- dw func05 ; (05) Print Character
- dw func06 ; (06) Direct Console I/O
- dw func07 ; (07) Direct Console Input
- dw func08 ; (08) Read Keyboard
- dw func09 ; (09) Display String
- dw func0A ; (0A) Buffered Keyboard Input
- dw func0B ; (0B) Check Keyboard Status
- dw func0C ; (0C) Flush Buffer, Read Keyboard
- dw func0D ; (0D) Reset Disk
- dw func0E ; (0E) Select Disk
- dw func0F ; (0F) Open File
- dw func10 ; (10) Close File
- dw func11 ; (11) Search for First
- dw func12 ; (12) Search for Next
- dw func13 ; (13) Delete File
- dw func14 ; (14) Sequential Read
- dw func15 ; (15) Sequential Write
- dw func16 ; (16) Create File
- dw func17 ; (17) Rename File
- dw ms_zero_AL ; (18) Unused DOS function (AL = 0)
- dw func19 ; (19) Current Disk
- dw func1A ; (1A) Set Disk Transfer Address
- dw func1B ; (1B) *Get Default Drive Data
- dw func1C ; (1C) *Get Drive Data
- dw ms_zero_AL ; (1D) Unused DOS function (AL = 0)
- dw ms_zero_AL ; (1E) Unused DOS function (AL = 0)
- dw func1F ; (1F) Get Default DPB
- dw ms_zero_AL ; (20) Unused DOS function (AL = 0)
- dw func21 ; (21) Random Read
- dw func22 ; (22) Random Write
- dw func23 ; (23) File Size
- dw func24 ; (24) Set Relative Record
- dw func25 ; (25) Set Interrupt Vector
- dw func26 ; (26) Duplicate PSP
- dw func27 ; (27) Random Block Read
- dw func28 ; (28) Random Block Write
- dw func29 ; (29) Parse File Name
- dw func2A ; (2A) Get Date
- dw func2B ; (2B) Set Date
- dw func2C ; (2C) Get Time
- dw func2D ; (2D) Set Time
- dw func2E ; (2E) Set/Reset Verify Flag
- dw func2F ; (2F) Get Disk Transfer Address
- dw func30 ; (30) Get Version Number
- dw func31 ; (31) Keep Process
- dw func32 ; (32) Get DPB
- dw func33 ; (33) CONTROL-C Check
- dw func34 ; (34) Get the Indos Flag
- dw func35 ; (35) Get Interrupt Vector
- dw func36 ; (36) Get Disk Free Space
- dw func37 ; (37) Get/Set Switch Character
- dw func38 ; (38) Return Country Dependant Info
- dw func39 ; (39) Create Sub-directory
- dw func3A ; (3A) Remove Sub-directory
- dw func3B ; (3B) Change Sub-directory
- dw func3C ; (3C) Create a File
- dw func3D ; (3D) Open a File Handle
- dw func3E ; (3E) Close a File Handle
- dw func3F ; (3F) Read from a File/Device
- dw func40 ; (40) Write to a File/Device
- dw func41 ; (41) Delete a Directory Entry
- dw func42 ; (42) Move a File Pointer
- dw func43 ; (43) Change Attributes
- dw func44 ; (44) I/O Control
- dw func45 ; (45) Duplicate File Handle
- dw func46 ; (46) Force a Duplicate File Handle
- dw func47 ; (47) Return Text of Current Directory
- dw func48 ; (48) Allocate Memory
- dw func49 ; (49) Free Allocated Memory
- dw func4A ; (4A) Modify Allocated Memory
- dw func4B ; (4B) Load and Execute Program
- dw func4C ; (4C) Terminate a Process
- dw func4D ; (4D) Get Return Code
- dw func4E ; (4E) Find Matching File
- dw func4F ; (4F) Find Next Matching File
- dw func50 ; (50) Set Current PSP
- dw func51 ; (51) Get Current PSP
- dw func52 ; (52) *Get In Vars
- dw func53 ; (53) *Build DPB from BPB
- dw func54 ; (54) Return Verify State
- dw func55 ; (55) Create a New PSP
- dw func56 ; (56) Move a Directory Entry
- dw func57 ; (57) Get/Set File Date and Time
- dw func58 ; (58) Memory Allocation Strategy
- dw func59 ; (59) Get Extended Error
- dw func5A ; (5A) Create Temporary File
- dw func5B ; (5B) Create New File
- dw func5C ; (5C) File Lock Control
- dw func5D ; (5D) Internal DOS Function
- dw func5E ; (5E) Control Local Machine Data
- dw func5F ; (5F) Get Network Assignments
- dw func60 ; (60) Perform Name Processing
- dw ms_zero_AL ; (61) ?? Parse Path (AL = 0)
- dw func62 ; (62) Get Current PSP
- dw func63 ; (63) Get Lead Byte Table
- dw invalid_function ; (64) *Saves AL and Returns
- dw func65 ; (65) Get Extended Country Information
- dw func66 ; (66) Get/Set Global Code Page
- dw func67 ; (67) Set Handle Count
- dw func68 ; (68) Commit File
- dw func69 ; (69) Get Serial number
- dw func68 ; (6A) Commit File (again)
- dw invalid_function ; (6B) Unknown DOS 4
- dw func6C ; (6C) Extended Open/Create
- pcmode_ftl equ (offset $ - offset pcmode_ft)/2
- ;**************************
- ;* Do Not Move This Entry *
- ;**************************
- dw ms_zero_AL ; Illegal Function Handler
- end