home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
pc
/
source
/
ms_sh16.lzh
/
ms_sh.2
< prev
next >
Wrap
Text File
|
1990-05-06
|
39KB
|
1,817 lines
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file Patch1.6 continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file Patch1.6"
sed 's/^X//' << 'SHAR_EOF' >> Patch1.6
X
X ;
X ; Some addition variables
X--- 88,118 ----
X public _SW_fp
X public _SW_I0_V
X public _SW_I23_V
X public _SW_EMstart
X public _SW_Mode
X public _SW_EMSFrame
X public _SW_Int24
X+ public _SW_XMS_Driver
X+ public _SW_XMS_Gversion
X+ public _SW_XMS_Allocate
X+ public _SW_XMS_Free
X
X+
X _cmd_line db 129 dup (?) ; Command line
X _path_line db 80 dup (?) ; Path line
X _SW_Blocks dw 0 ; Number of blocks to read/write
X _SW_fp dw 0 ; File ID
X _SW_I0_V dd 0 ; Our Interrupt Zero address
X _SW_I23_V dd 0 ; Our Interrupt 23 address
X _SW_EMstart dd 0100000H ; Default Extended Mem start
X _SW_Mode dw 0 ; Type of swapping to do
X ; 1 - disk
X ; 2 - Extended memory
X! ; 3 - EMS driver
X! ; 4 - XMS driver
X _SW_EMSFrame dw 0 ; EMS Frame segment
X _SW_intr dw 0 ; Interrupt 23 detected.
X+ _SW_XMS_Driver dd 0 ; XMS Driver Interface
X
X ;
X ; Some addition variables
X***************
X*** 120,128 ****
X FCB2 dw 16 dup (?)
X
X ;
X! ; Extended Memory Global Descriptor tables
X ;
X
X GD_table equ $
X GDT_Dummy dw 4 dup (0) ; Dummy
X GDT_self dw 4 dup (0) ; For self
X--- 141,160 ----
X FCB2 dw 16 dup (?)
X
X ;
X! ; XMS Driver Move structure
X ;
X
X+ XMS_DIF equ $
X+ XMS_Length dd 0 ; Number of bytes
X+ XMS_SHandle dw 0 ; Source Handler
X+ XMS_Soffset dd 0 ; Source Offset
X+ XMS_DHandle dw 0 ; Destination Handler
X+ XMS_Doffset dd 0 ; Destination Offset
X+
X+ ;
X+ ; Extended Memory Global Descriptor tables
X+ ;
X+ org XMS_DIF
X GD_table equ $
X GDT_Dummy dw 4 dup (0) ; Dummy
X GDT_self dw 4 dup (0) ; For self
X***************
X*** 297,315 ****
X
X $Write_loop:
X or si, si
X! je $Write_Complete
X
X ; OK - Copy next 0x4000 bytes - switch on device
X
X mov ax, word ptr cs: _SW_Mode
X dec ax
X jz $Write_disk
X dec ax
X! jz $W_extend
X jmp $W_expand
X
X! ; Write to disk
X
X $Write_disk:
X mov ax, 04000H ; Set up to write
X mov cx, ax ; Load count
X--- 329,396 ----
X
X $Write_loop:
X or si, si
X! jnz $Write_L1
X! jmp $Write_Complete
X
X ; OK - Copy next 0x4000 bytes - switch on device
X
X+ $Write_L1:
X mov ax, word ptr cs: _SW_Mode
X dec ax
X jz $Write_disk
X dec ax
X! jnz $Write_L2
X! jmp $W_extend
X! $Write_L2:
X! dec ax
X! jnz $W_xms
X jmp $W_expand
X
X! ;
X! ; Write to XMS driver. In this case, we do one write and let the driver
X! ; sort out the blocking
X! ;
X! $W_xms:
X! xor ax, ax
X! mov word ptr cs:XMS_SHandle, ax ; Source - normal memory
X! mov word ptr cs:XMS_DHandle, bx ; Dest - XMS
X
X+ mov word ptr cs:XMS_Doffset, ax ; Dest offset - zero
X+ mov word ptr cs:XMS_Doffset + 2, ax
X+
X+ mov word ptr cs:XMS_Soffset, ax ; Source offset DS:0
X+ mov ax, ds
X+ mov word ptr cs:XMS_Soffset + 2, ax
X+
X+ ;
X+ ; Set up number of bytes SW_Block * 16 * 1024
X+ ;
X+
X+ mov ax, si
X+ mov dx, si
X+ mov cl, 14
X+ shl ax, cl
X+ mov cl, 2
X+ shr dx, cl
X+ mov word ptr cs:XMS_Length, ax ; Load number of bytes
X+ mov word ptr cs:XMS_Length + 2, dx
X+
X+ mov ah, 0BH ; Set up parameters
X+ mov dx, cs
X+ mov ds, dx
X+ mov si, offset XMS_DIF
X+ call cs:[_SW_XMS_Driver]
X+ or ax, ax
X+ jnz $Write_Complete
X+
X+ ; XMS error - abort
X+
X+ mov ah, bl
X+ jmp $Write_error
X+
X+ ;
X+ ; Write to disk
X+ ;
X $Write_disk:
X mov ax, 04000H ; Set up to write
X mov cx, ax ; Load count
X***************
X*** 321,328 ****
X
X pop si ; Restore Regs
X pop bx
X! jc $Write_error ; NO - abort
X
X $Write_Incr:
X dec si ; Decrement block count
X mov ax, ds ; Increment offset
X--- 402,425 ----
X
X pop si ; Restore Regs
X pop bx
X! jnc $Write_disk1 ; NO error - continue
X
X+ ;
X+ ; Error - abort
X+ ;
X+ mov ds, word ptr cs:S_ds ; Restore DS
X+ mov ah, al
X+ call far ptr __maperror ; Map the error
X+ jmp $Write_Error1
X+
X+ ; Check for 16K write
X+
X+ $Write_disk1:
X+ cmp ax, 04000H
X+ jz $Write_Incr
X+ mov ax,01c1cH ; Set disk full
X+ jmp $Write_error ; NO - abort
X+
X $Write_Incr:
X dec si ; Decrement block count
X mov ax, ds ; Increment offset
X***************
X*** 372,377 ****
X--- 469,475 ----
X mov al, ah
X xor ah, ah
X mov word ptr ds:_errno, ax ; Save error code
X+ $Write_Error1:
X mov ax, 0FFFEH
X jmp $SA_spawn_Exit ; Exit
X
X***************
X*** 642,651 ****
X jz $R_disk
X dec ax
X jz $R_extend
X! jmp $R_expand
X
X! ; Read from disk
X
X $R_disk:
X call $Read_disk
X jmp $Read_loop
X--- 740,757 ----
X jz $R_disk
X dec ax
X jz $R_extend
X! dec ax
X! jz $R_expand
X
X! ;
X! ; Read from XMS driver. In this case, we do one read and let the driver
X! ; sort out the blocking
X! ;
X! call $Read_XMS
X! jmp $Read_Complete
X
X+ ; Read from disk
X+
X $R_disk:
X call $Read_disk
X jmp $Read_loop
X***************
X*** 676,681 ****
X--- 782,788 ----
X ; Save exit code
X
X push word ptr cs:Result ; Save response
X+ push word ptr cs:_SW_intr ; and interrupt flag
X
X ;
X ; Read in the first block - BX - File Handler
X***************
X*** 702,709 ****
X jz $R1_Disk
X dec ax
X jz $R1_Extend
X! jmp $R1_Expand
X
X $R1_Disk:
X call $Read_disk
X jmp $Read1_OK
X--- 809,821 ----
X jz $R1_Disk
X dec ax
X jz $R1_Extend
X! dec ax
X! jz $R1_Expand
X
X+ mov si, 1 ; Read one block
X+ call $Read_XMS
X+ jmp $Read1_OK
X+
X $R1_Disk:
X call $Read_disk
X jmp $Read1_OK
X***************
X*** 721,726 ****
X--- 833,839 ----
X ;
X
X $Read1_OK:
X+ pop word ptr cs:_SW_intr ; Restore interrupt flag
X pop ax
X
X ;
X***************
X*** 757,776 ****
X
X $SA_Exit1:
X pop ax ; Restore result
X! mov sp,bp
X pop bp
X ret
X
X _SA_spawn endp
X
X ;
X! ; READ DISK FUNCTION
X ;
X ; BX - file handler
X ; SI - Block count
X ; DS - Output data segement
X ;
X
X $Read_disk proc near
X
X mov ax, 03f00H ; Set up to read
X--- 870,941 ----
X
X $SA_Exit1:
X pop ax ; Restore result
X! mov sp, bp
X pop bp
X ret
X
X _SA_spawn endp
X
X ;
X! ; READ XMS DRIVER FUNCTION
X ;
X ; BX - file handler
X ; SI - Block count
X ; DS - Output data segement
X ;
X+ $Read_XMS proc near
X+ xor ax, ax
X+ mov word ptr cs:XMS_SHandle, bx ; Source - XMS
X+ mov word ptr cs:XMS_DHandle, ax ; Dest - normal memory
X
X+ mov word ptr cs:XMS_Soffset, ax ; Source offset - zero
X+ mov word ptr cs:XMS_Soffset + 2, ax
X+
X+ mov word ptr cs:XMS_Doffset, ax ; Dest offset DS:0
X+ mov ax, ds
X+ mov word ptr cs:XMS_Doffset + 2, ax
X+
X+ cmp si, 1 ; If first block, the
X+ jz $Read_X1 ; source offset is
X+ ; 4000H
X+ mov word ptr cs:XMS_Soffset, 04000H
X+
X+ ;
X+ ; Set up number of bytes: si * 16 * 1024
X+ ;
X+
X+ $Read_X1:
X+ mov ax, si
X+ mov dx, si
X+ mov cl, 14
X+ shl ax, cl
X+ mov cl, 2
X+ shr dx, cl
X+ mov word ptr cs:XMS_Length, ax ; Load number of bytes
X+ mov word ptr cs:XMS_Length + 2, dx
X+
X+ mov ah, 0BH ; Set up parameters
X+ mov dx, cs
X+ mov ds, dx
X+ mov si, offset XMS_DIF
X+ call cs:[_SW_XMS_Driver]
X+ or ax, ax
X+ jnz $Read_XMS1
X+ jmp Load_Error ; XMS error - abort
X+
X+ $Read_XMS1:
X+ ret
X+
X+ $Read_XMS endp
X+
X+ ;
X+ ; READ DISK FUNCTION
X+ ;
X+ ; BX - file handler
X+ ; SI - Block count
X+ ; DS - Output data segement
X+ ;
X+
X $Read_disk proc near
X
X mov ax, 03f00H ; Set up to read
X***************
X*** 872,882 ****
X
X Load_Error proc near
X
X! mov ax, 00900H
X! mov dx, offset Swap_PANIC
X mov bx, cs
X mov ds, bx
X! int 021H
X $Wait_L:
X sti
X hlt
X--- 1037,1046 ----
X
X Load_Error proc near
X
X! mov di, offset Swap_PANIC
X mov bx, cs
X mov ds, bx
X! call I24_Display
X $Wait_L:
X sti
X hlt
X***************
X*** 1021,1059 ****
X ;
X ; INTERRUPT 24 - ERROR HANDLER - Output message
X ;
X
X! _SW_Int24 proc far
X! pushf ; Save flags
X! call dword ptr cs:_SW_I24_V
X
X! cmp byte ptr cs:InShell, 0 ; Are we in the shell ?
X! jnz $SW_int24c ; No - no processing
X
X! test ah, 010h
X! jnz $SW_int24a
X! test ah, 008h
X! jnz $SW_int24b
X
X! mov al, 003h ; Fail system call
X
X- $SW_int24c:
X- iret
X-
X ;
X! $SW_int24a:
X! xor al, al ; Ignore error
X! iret
X!
X ;
X! $SW_int24b:
X! mov al, 001h ; Retry error
X iret
X _SW_Int24 endp
X
X ;
X! ; Start of overwrite area for environment. Align on a paragraph
X ;
X ALIGN 16
X Env_OWrite:
X SH0_TEXT ends
X end
X--- 1185,1690 ----
X ;
X ; INTERRUPT 24 - ERROR HANDLER - Output message
X ;
X+ ; AH - Bit 7 = 0 Disk error
X+ ; = 1 FAT error if block device
X+ ; Error code in DI if character device
X+ ; Bit 6 UNUSED
X+ ; Bit 5 = 1 Ignore allowed
X+ ; Bit 4 = 1 Retry allowed
X+ ; Bit 3 = 1 Fail allowed
X+ ; Bits 2 & 1 = Disk Area
X+ ; Bit 0 = 1 Writing error
X+ ; AL = Disk drive number
X+ ; DI = Error code
X+ ; BP:SI = Header of device driver for which error occured
X+ ;
X+ ;
X+ ; Return
X+ ; AL = 0 Ignore Error
X+ ; = 1 Retry operation
X+ ; = 2 Abort program
X+ ; = 3 Fail system call
X+ ;
X
X! I24_Errors equ $
X! I24_EC00: db 'Write protect error$'
X! I24_EC01: db 'Unknown unit$'
X! I24_EC02: db 'Drive not ready$'
X! I24_EC03: db 'Unknown command$'
X! I24_EC04: db 'Data error$'
X! I24_EC05: db 'Bad request$'
X! I24_EC06: db 'Seek error$'
X! I24_EC07: db 'Unknown media type$'
X! I24_EC08: db 'Sector not found$'
X! I24_EC09: db 'Paper out$'
X! I24_EC0A: db 'Write fault$'
X! I24_EC0B: db 'Read fault$'
X! I24_EC0C: db 'General failure$'
X! I24_EC0D: db 'Unknown code$'
X! I24_EC0F: db 'Invalid disk change$'
X! I24_EC10: db 'FCB unavailable$'
X! I24_EC11: db 'Sharing buffer overflow$'
X
X! ;
X! ; Error message address table
X! ;
X
X! I24_ECTABLE: dw offset I24_EC00
X! dw offset I24_EC01
X! dw offset I24_EC02
X! dw offset I24_EC03
X! dw offset I24_EC04
X! dw offset I24_EC05
X! dw offset I24_EC06
X! dw offset I24_EC07
X! dw offset I24_EC08
X! dw offset I24_EC09
X! dw offset I24_EC0A
X! dw offset I24_EC0B
X! dw offset I24_EC0C
X! dw offset I24_EC0D
X! dw offset I24_EC0D ; 0E - no message
X! dw offset I24_EC0F
X! dw offset I24_EC10
X! dw offset I24_EC11
X
X! I24_ECON: db ' when $'
X! I24_ECREAD: db 'reading $'
X! I24_ECWRITE: db 'writing $'
X! I24_ECDEVICE: db 'device $'
X! I24_ECDISK: db 'disk $'
X! I24_EABORT: db 'Abort$'
X! I24_EFAIL: db ', Fail$'
X! I24_EIGNORE: db ', Ignore$'
X! I24_ERETRY: db ', Retry$'
X! I24_EDRIVE: db '?$'
X! I24_EQUESTION db '? $'
X! I24_RESPONSE: db ' '
X! I24_ENL: db 0dH, 0aH, '$'
X! I24_EBELL: db 07H, '$'
X! I24_EDNAME: db '12345678$'
X! I24_EXTECODE: db 0dH, 0aH, '(Extended Code: '
X! I24_E_AL: db ' '
X! db ' Class: '
X! I24_E_BH: db ' '
X! db ' Action: '
X! I24_E_BL: db ' '
X! db ' Locus: '
X! I24_E_CH: db ' )', 0dH, 0aH, '$'
X
X ;
X! ; Save DS, ES, BX, CX, DX
X ;
X! _SW_Int24 proc far
X! push ds ; Save registers
X! push es
X! push bx
X! push cx
X! push dx
X!
X! push cs ; Set up data segment
X! pop ds
X!
X! mov cx, ax ; Save the error information in CX
X!
X! push di
X! mov di, offset I24_ENL
X! call I24_Display
X! pop di
X!
X! ;
X! ; Check inside message range
X! ;
X! cmp di, 012H
X! jb SWI24a
X! mov di, 0dH
X!
X! ;
X! ; Write the error message
X! ;
X!
X! SWI24a:
X! add di, di
X!
X! mov di, word ptr ds:I24_ECTABLE[di]
X! call I24_Display
X!
X! ;
X! ; Output on message
X! ;
X!
X! mov di, offset I24_ECON
X! call I24_Display
X!
X! ;
X! ; Output reading or write message
X! ;
X!
X! mov di, offset I24_ECWRITE
X! test ch, 01H
X! jnz SWI24b
X! mov di, offset I24_ECREAD
X!
X! SWI24b:
X! call I24_Display
X!
X! ;
X! ; Output device message
X! ;
X!
X! test ch, 080H
X! jz SWI24c
X!
X! mov di, offset I24_ECDEVICE
X! call I24_Display
X!
X! ;
X! ; Output device name - up to eight characters
X! ;
X!
X! add si, 0aH ; Move to device name
X! push ds
X! mov ds, bp
X! xor di, di ; Set counter
X!
X! SWI24b1:
X! mov dl, byte ptr ds:[si] ; Get next character in name
X! cmp dl, ' '
X! jz SWI24d
X!
X! mov byte ptr cs:[I24_EDNAME + di], dl
X!
X! inc si
X! inc di
X! cmp di, 8
X! jnz SWI24b1
X! ;
X! ; Append a $
X! ;
X!
X! SWI24d:
X! pop ds
X! mov byte ptr cs:[I24_EDNAME + di], '$'
X! mov di, offset I24_EDNAME
X! jmp SWI24e
X!
X! ;
X! ; Write disk error
X! ;
X! SWI24c:
X! mov di, offset I24_ECDISK
X! call I24_Display
X!
X! mov dl, cl
X! add dl, 'A'
X! mov byte ptr cs:I24_EDRIVE, dl
X!
X! mov di, offset I24_EDRIVE
X! SWI24e:
X! call I24_Display
X!
X! ;
X! ; Get extended error codes
X! ;
X! push cx
X! push ds
X! mov ah, 059H
X! xor bx, bx
X! int 021H
X!
X! ;
X! ; Save responses
X! ;
X!
X! mov byte ptr cs:I24_E_AL, al
X! mov byte ptr cs:I24_E_BL, bl
X! mov byte ptr cs:I24_E_BH, bh
X! mov byte ptr cs:I24_E_CH, ch
X! pop ds
X! pop cx
X!
X! ; Convert to display Hex.
X!
X! mov di, offset I24_E_AL
X! call I24_Convert
X! mov di, offset I24_E_BL
X! call I24_Convert
X! mov di, offset I24_E_BH
X! call I24_Convert
X! mov di, offset I24_E_CH
X! call I24_Convert
X! mov di, offset I24_EXTECODE
X! call I24_Display
X! ;
X! ; Output Options
X! ;
X! mov di, offset I24_EABORT
X! call I24_Display
X!
X! test ch, 020H ; Ignore allowed ?
X! jz SWI24f
X! mov di, offset I24_EIGNORE
X! call I24_Display
X!
X! SWI24f:
X! test ch, 010H ; Retry allowed ?
X! jz SWI24g
X! mov di, offset I24_ERETRY
X! call I24_Display
X!
X! SWI24g:
X! test ch, 08H ; Fail allowed ?
X! jz SWI24h
X! mov di, offset I24_EFAIL
X! call I24_Display
X!
X! ;
X! ; Append a question mark.
X! ;
X!
X! SWI24h:
X! mov di, offset I24_EQUESTION
X! call I24_Display
X!
X! ;
X! ; Get the valid key codes
X! ;
X! SWI24j:
X! xor ax, ax ; Read a keyboard character
X! int 16H
X! and al, 05fH ; Upper case
X!
X! xor ah, ah ; Clear counter
X! cmp al, 'I' ; Ignore ?
X! jnz SWI24k
X! test ch, 020H
X! jnz SWI24n
X! SWI24k:
X! inc ah
X! cmp al, 'R' ; Retry ?
X! jnz SWI24l
X! test ch, 010H
X! jnz SWI24n
X! SWI24l:
X! inc ah
X! cmp al, 'A' ; Abort ?
X! jz SWI24n
X!
X! inc ah
X! cmp al, 'F' ; Fail ?
X! jnz SWI24m
X! test ch, 08H
X! jnz SWI24n
X! SWI24m:
X! mov di, offset I24_EBELL
X! call I24_Display
X! jmp SWI24j
X!
X! ;
X! ; OK - got code
X! ;
X! SWI24n:
X! mov cl, ah
X! mov byte ptr ds:I24_RESPONSE, al
X! mov di, offset I24_RESPONSE
X! call I24_Display
X! mov ax, cx
X!
X! ;
X! ; Are we in the shell ?
X! ;
X! cmp byte ptr cs:InShell, 0 ; Are we in the shell ?
X! jnz $SW_int24a ; No - no processing
X!
X! cmp al, 02H ; Abort?
X! jnz $SW_int24a ; No - exit
X!
X! test ah, 008h ; If fail allowed - convert to fail
X! jz $SW_int24a
X!
X! mov al, 003h ; Fail system call
X!
X! $SW_int24a:
X! pop dx ; Restore registers
X! pop cx
X! pop bx
X! pop es
X! pop ds
X iret
X _SW_Int24 endp
X
X ;
X! ; Convert Hex code to display code
X ;
X+ ; ds:di Offset of code to replace
X+ ; ax is available
X+ ;
X+ I24_Convert proc near
X+ push cx
X+ mov al, byte ptr ds:[di] ; Get the code
X+ mov ah, al
X+ mov cl, 4
X+ shr ah, cl
X+ and ah, 0fh
X+
X+ cmp ah, 10
X+ jb I24_C1
X+ add ah, 'A' - 10
X+ jmp I24_C2
X+ I24_C1:
X+ add ah, '0'
X+ I24_C2:
X+ mov byte ptr ds:[di], ah
X+
X+ ; Now LSB
X+
X+ and al, 0fh
X+ cmp al, 10
X+ jb I24_C3
X+ add al, 'A' - 10
X+ jmp I24_C4
X+ I24_C3:
X+ add al, '0'
X+ I24_C4:
X+ mov byte ptr ds:[di + 1], al
X+ pop cx
X+ ret
X+ I24_Convert endp
X+ ;
X+ ; Display message function for Interrupt 24 processing
X+ ;
X+ ; DS:DI message
X+ ; AX is available
X+ ;
X+
X+ I24_Display proc near
X+ mov ah, 08H ; Get foreground colour
X+ xor bx, bx
X+ int 10H
X+ mov bl, ah
X+ and bl, 07h
X+
X+ ;
X+ ; Loop until a $ is hit, outputting the characters
X+ ;
X+ I24D:
X+ mov al, byte ptr ds:[di]
X+ cmp al, '$'
X+ jnz I24Da
X+ ret
X+
X+ I24Da:
X+ push di
X+ mov ah, 0EH
X+ int 10H
X+ pop di
X+ inc di
X+ jmp I24D
X+
X+ I24_Display endp
X+
X+ ;
X+ ; Start of overwrite area for environment. Align on a paragraph
X+ ;
X+ ; Also the XMS driver functions used by SH3.C live here
X+ ;
X ALIGN 16
X Env_OWrite:
X+
X+ ;
X+ ; XMS INTERFACE
X+ ;
X+ ; Get Version number. Return the release number in AX
X+ ;
X+
X+ _SW_XMS_Gversion proc far
X+
X+ push bp ; Save stack info
X+ mov bp, sp
X+
X+ xor ax, ax
X+ call cs:[_SW_XMS_Driver]
X+
X+ mov sp, bp
X+ pop bp
X+ ret
X+
X+ _SW_XMS_Gversion endp
X+
X+ ;
X+ ; Allocate N kbytes. Return the Handler in AX or -1 and error code in
X+ ; errno.
X+ ;
X+ ; Size will be in bp + 6.
X+ ;
X+
X+ _SW_XMS_Allocate proc far
X+
X+ push bp ; Save stack info
X+ mov bp, sp
X+
X+ mov dx, word ptr ss:[bp + 6]
X+ mov ah, 09H
X+ call cs:[_SW_XMS_Driver]
X+ or ax, ax
X+ jnz $SW_A1
X+
X+ ;
X+ ; Allocate Failed - return error code
X+ ;
X+ xor ax, ax
X+ neg ax
X+ xor bh, bh
X+ mov word ptr ds:_errno, bx ; Save error code
X+ jmp $SW_F2
X+
X+ ;
X+ ; Allocate OK - return handler
X+ ;
X+
X+ $SW_A1:
X+ mov ax, dx
X+
X+ $SW_A2:
X+ mov sp, bp
X+ pop bp
X+ ret
X+
X+ _SW_XMS_Allocate endp
X+
X+ ;
X+ ; Release handler. Return 0 or error code.
X+ ;
X+ ; Handler will be in bp + 6.
X+ ;
X+
X+ _SW_XMS_Free proc far
X+
X+ push bp ; Save stack info
X+ mov bp, sp
X+
X+ mov dx, word ptr ss:[bp + 6]
X+ mov ah, 0AH
X+ call cs:[_SW_XMS_Driver]
X+ or ax, ax
X+ jnz $SW_F1
X+ ;
X+ ; Free Failed - return error code
X+ ;
X+ mov al, bl
X+ jmp $SW_F2
X+
X+ ;
X+ ; Free OK - return zero
X+ ;
X+ $SW_F1:
X+ xor ax, ax
X+
X+ $SW_F2:
X+ mov sp, bp
X+ pop bp
X+ ret
X+
X+ _SW_XMS_Free endp
X SH0_TEXT ends
X end
XIndex: shell/sh2.c
XPrereq: 1.1
X*** ../sh15/shell/sh2.c Fri Feb 16 19:22:55 1990
X--- shell/sh2.c Tue May 1 19:48:35 1990
X***************
X*** 13,21 ****
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
X! * $Header: sh2.c 1.1 90/01/25 13:41:12 MS_user Exp $
X *
X * $Log: sh2.c $
X * Revision 1.1 90/01/25 13:41:12 MS_user
X * Initial revision
X *
X--- 13,34 ----
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
X! * $Header: sh2.c 1.5 90/04/25 09:18:38 MS_user Exp $
X *
X * $Log: sh2.c $
X+ * Revision 1.5 90/04/25 09:18:38 MS_user
X+ * Fix for ... do to not require terminating colon
X+ *
X+ * Revision 1.4 90/03/14 19:30:06 MS_user
X+ * Make collect a global for here document processing.
X+ * Add IOTHERE support to detect <<- redirection
X+ *
X+ * Revision 1.3 90/03/06 16:49:42 MS_user
X+ * Add disable history option
X+ *
X+ * Revision 1.2 90/03/05 13:49:41 MS_user
X+ * Change talking checks
X+ *
X * Revision 1.1 90/01/25 13:41:12 MS_user
X * Initial revision
X *
X***************
X*** 98,104 ****
X static IO_Actions *io (int, int, char *);
X static void yyerror (char *);
X static int yylex (int);
X- static int collect (int, int);
X static int dual (int);
X static void diag (int);
X static char *tree (unsigned int);
X--- 111,116 ----
X***************
X*** 339,347 ****
X multiline++;
X t->words = wordlist ();
X
X! if (((c = yylex (0)) != NL) && (c != ';'))
X! yyerror (syntax_err);
X
X t->left = dogroup (0);
X multiline--;
X break;
X--- 351,366 ----
X multiline++;
X t->words = wordlist ();
X
X! /* CHeck for "for word in word...; do" versus "for word do" */
X
X+ c = yylex (0);
X+
X+ if ((t->words == (char **)NULL) && (c != NL))
X+ peeksym = c;
X+
X+ else if ((t->words != (char **)NULL) && (c != NL) && (c != ';'))
X+ yyerror (syntax_err);
X+
X t->left = dogroup (0);
X multiline--;
X break;
X***************
X*** 353,359 ****
X t->type = (c == WHILE) ? TWHILE : TUNTIL;
X t->left = c_list (FALSE);
X t->right = dogroup (1);
X! t->words = NULL;
X multiline--;
X break;
X
X--- 372,378 ----
X t->type = (c == WHILE) ? TWHILE : TUNTIL;
X t->left = c_list (FALSE);
X t->right = dogroup (1);
X! t->words = (char **)NULL;
X multiline--;
X break;
X
X***************
X*** 531,537 ****
X
X static C_Op *block (type, t1, t2, wp)
X C_Op *t1, *t2;
X! char **wp;
X {
X register C_Op *t = (C_Op *)tree (sizeof (C_Op));
X
X--- 550,556 ----
X
X static C_Op *block (type, t1, t2, wp)
X C_Op *t1, *t2;
X! char **wp;
X {
X register C_Op *t = (C_Op *)tree (sizeof (C_Op));
X
X***************
X*** 643,649 ****
X {
X yynerrs++;
X
X! if (talking && e.iop <= iostack)
X {
X multiline = 0;
X
X--- 662,668 ----
X {
X yynerrs++;
X
X! if (Interactive ())
X {
X multiline = 0;
X
X***************
X*** 759,767 ****
X
X if (multiline || (cf & CONTIN))
X {
X! if (talking && e.iop <= iostack)
X {
X Add_History (FALSE);
X put_prompt (ps2->value);
X }
X
X--- 778,788 ----
X
X if (multiline || (cf & CONTIN))
X {
X! if (Interactive ())
X {
X+ #ifndef NO_HISTORY
X Add_History (FALSE);
X+ #endif
X put_prompt (ps2->value);
X }
X
X***************
X*** 801,816 ****
X return WORD;
X }
X
X! static int collect (c, c1)
X register int c, c1;
X {
X char *s = "x\n";
X
X! *e.linep++ = (char)c;
X
X while ((c = Getc (c1)) != c1)
X {
X! if (c == 0)
X {
X unget (c);
X *s = (char)c1;
X--- 822,839 ----
X return WORD;
X }
X
X! /* Read input until we read the specified end character */
X!
X! int collect (c, c1)
X register int c, c1;
X {
X char *s = "x\n";
X
X! *e.linep++ = (char)c; /* Save the current character */
X
X while ((c = Getc (c1)) != c1)
X {
X! if (c == 0) /* End of file - abort */
X {
X unget (c);
X *s = (char)c1;
X***************
X*** 819,827 ****
X return YYERRCODE;
X }
X
X! if (talking && (c == NL) && (e.iop <= iostack))
X {
X Add_History (FALSE);
X put_prompt (ps2->value);
X }
X
X--- 842,852 ----
X return YYERRCODE;
X }
X
X! if (Interactive () && (c == NL))
X {
X+ #ifndef NO_HISTORY
X Add_History (FALSE);
X+ #endif
X put_prompt (ps2->value);
X }
X
X***************
X*** 873,879 ****
X else
X yylval.i = (ec == '>') ? IOWRITE : IOREAD;
X
X! if ((c != '&') || (yylval.i == IOHERE))
X unget (c);
X
X else
X--- 898,909 ----
X else
X yylval.i = (ec == '>') ? IOWRITE : IOREAD;
X
X! /* Check for >&, <& and <<- */
X!
X! if ((c == '-') && (yylval.i == IOHERE))
X! yylval.i |= IOTHERE;
X!
X! else if ((c != '&') || (yylval.i == IOHERE))
X unget (c);
X
X else
XIndex: shell/sh3.c
XPrereq: 1.2
X*** ../sh15/shell/sh3.c Fri Feb 16 19:10:04 1990
X--- shell/sh3.c Tue May 1 19:48:50 1990
X***************
X*** 13,21 ****
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
X! * $Header: sh3.c 1.2 90/02/14 04:47:06 MS_user Exp $
X *
X * $Log: sh3.c $
X * Revision 1.2 90/02/14 04:47:06 MS_user
X * Clean up Interrupt 23 and 0 processing, change EMS version error message
X *
X--- 13,67 ----
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
X! * $Header: sh3.c 1.15 90/04/30 19:50:11 MS_user Exp $
X *
X * $Log: sh3.c $
X+ * Revision 1.15 90/04/30 19:50:11 MS_user
X+ * Stop search path if second character of name is colon
X+ *
X+ * Revision 1.14 90/04/26 17:27:52 MS_user
X+ * Fix problem with Picnix Utilities - full path name of executable required
X+ *
X+ * Revision 1.13 90/04/25 22:34:39 MS_user
X+ * Fix case in TELIF where then and else parts are not defined
X+ * Fix rsh check for execution path declared
X+ *
X+ * Revision 1.12 90/04/11 19:49:35 MS_user
X+ * Another problem with new command line processing
X+ *
X+ * Revision 1.11 90/04/11 12:55:49 MS_user
X+ * Change command line to look exactly like COMMAND.COM
X+ *
X+ * Revision 1.10 90/03/27 20:33:10 MS_user
X+ * Clear extended file name on interrupt
X+ *
X+ * Revision 1.9 90/03/27 20:09:21 MS_user
X+ * Clear_Extended_File required in SH1 for interrupt clean up
X+ *
X+ * Revision 1.8 90/03/26 20:57:14 MS_user
X+ * Change I/O restore so that "exec >filename" works
X+ *
X+ * Revision 1.7 90/03/22 13:47:24 MS_user
X+ * MSDOS does not handle /dev/ files after find_first correctly
X+ *
X+ * Revision 1.6 90/03/14 16:44:49 MS_user
X+ * Add quoting of arguments with white space on command line
X+ * Add IOTHERE processing to iosetup
X+ *
X+ * Revision 1.5 90/03/06 15:10:28 MS_user
X+ * Get doeval, dodot and runtrap working correctly in run so that a sub-shell
X+ * is not created and environment variables can be changed.
X+ *
X+ * Revision 1.4 90/03/05 13:50:04 MS_user
X+ * Add XMS driver
X+ * Fix bug with extended line file not being deleted
X+ * Get run to support eval and dot functionality correctly
X+ * Get trap processing to work
X+ * Add COMMAND.COM support for .bat files
X+ *
X+ * Revision 1.3 90/02/22 16:38:20 MS_user
X+ * Add XMS support
X+ *
X * Revision 1.2 90/02/14 04:47:06 MS_user
X * Clean up Interrupt 23 and 0 processing, change EMS version error message
X *
X***************
X*** 38,43 ****
X--- 84,91 ----
X #include <stdlib.h>
X #include <fcntl.h>
X #include <limits.h>
X+ #include <dirent.h>
X+ #include <ctype.h>
X
X #include "sh.h"
X
X***************
X*** 48,69 ****
X static C_Op **find1case (C_Op *, char *);
X static C_Op *findcase (C_Op *, char *);
X static void echo (char **);
X- static void setsig (int, int (*)());
X static int rexecve (char *, char **, char **, bool);
X static int Execute_program (char *, char **, char **, bool);
X static int S_spawnve (char *, char **, char **);
X! static void get_sys_info (void);
X! static void EMS_error (char *, int);
X static int EMS_Close (void);
X static int build_command_line (char *, char **, char **);
X- static void Clear_Extended_File (void);
X static int setstatus (int);
X
X static char *AE2big = "arg/env list too big";
X static char *EMS_emsg = "Warning: EMS Error (%x)\n";
X /* Extended Command line processing file name */
X static char *Extend_file = (char *)NULL;
X- static unsigned int SW_EMsize; /* Number of extend memory blks */
X
X /*
X * execute tree recursively
X--- 96,121 ----
X static C_Op **find1case (C_Op *, char *);
X static C_Op *findcase (C_Op *, char *);
X static void echo (char **);
X static int rexecve (char *, char **, char **, bool);
X static int Execute_program (char *, char **, char **, bool);
X static int S_spawnve (char *, char **, char **);
X! static bool Get_EMS_Driver (void);
X! static bool Get_XMS_Driver (void);
X! static bool EMS_error (char *, int);
X static int EMS_Close (void);
X+ static bool XMS_error (char *, int);
X+ static int XMS_Close (void);
X static int build_command_line (char *, char **, char **);
X static int setstatus (int);
X+ static bool Check_for_bat_file (char *);
X+ static size_t white_space_len (char *, bool *);
X+ static char *Gen_Full_Path_Name (char *);
X
X static char *AE2big = "arg/env list too big";
X static char *EMS_emsg = "Warning: EMS Error (%x)\n";
X+ static char *XMS_emsg = "Warning: XMS Error (%x)\n";
X /* Extended Command line processing file name */
X static char *Extend_file = (char *)NULL;
X
X /*
X * execute tree recursively
X***************
X*** 301,307 ****
X
X case TIF: /* IF and ELSE IF functions */
X case TELIF:
X! rv = !execute (t->left, pin, pout, 0)
X ? execute (t->right->left, pin, pout, 0)
X : execute (t->right->right, pin, pout, 0);
X break;
X--- 353,360 ----
X
X case TIF: /* IF and ELSE IF functions */
X case TELIF:
X! if (t->right != (C_Op *)NULL)
X! rv = !execute (t->left, pin, pout, 0)
X ? execute (t->right->left, pin, pout, 0)
X : execute (t->right->right, pin, pout, 0);
X break;
X***************
X*** 334,347 ****
X
X areanum = Local_areanum;
X
X- /* Check for interrupts */
X-
X- if (talking && SW_intr)
X- {
X- closeall ();
X- fail ();
X- }
X-
X /* Check for traps */
X
X if ((i = trapset) != 0)
X--- 387,392 ----
X***************
X*** 350,355 ****
X--- 395,408 ----
X runtrap (i);
X }
X
X+ /* Check for interrupts */
X+
X+ if (Interactive () && SW_intr)
X+ {
X+ closeall ();
X+ fail ();
X+ }
X+
X return rv;
X }
X
X***************
X*** 387,392 ****
X--- 440,446 ----
X char *cp;
X IO_Actions **iopp;
X int resetsig = 0;
X+ void (*sig_int)();
X char **owp = wp;
X bool spawn = FALSE;
X Fun_Ops *fop;
X***************
X*** 426,437 ****
X {
X spawn = TRUE;
X
X! if (talking)
X {
X #ifdef SIGQUIT
X signal (SIGQUIT, SIG_IGN);
X #endif
X! signal (SIGINT, SIG_IGN);
X resetsig = 1;
X }
X }
X--- 480,491 ----
X {
X spawn = TRUE;
X
X! if (Interactive ())
X {
X #ifdef SIGQUIT
X signal (SIGQUIT, SIG_IGN);
X #endif
X! sig_int = signal (SIGINT, SIG_IGN);
X resetsig = 1;
X }
X }
X***************
X*** 472,478 ****
X }
X
X if (shcom)
X! return restore_std (setstatus ((*shcom)(t)));
X
X /* All fids above 10 are autoclosed in the exec file because we have used
X * the O_NOINHERIT flag. Note I patched open.obj to pass this flag to the
X--- 526,532 ----
X }
X
X if (shcom)
X! return restore_std (setstatus ((*shcom)(t)), TRUE);
X
X /* All fids above 10 are autoclosed in the exec file because we have used
X * the O_NOINHERIT flag. Note I patched open.obj to pass this flag to the
X***************
X*** 484,501 ****
X #ifdef SIGQUIT
X signal (SIGQUIT, SIG_IGN);
X #endif
X! signal (SIGINT, onintr);
X }
X
X if (t->type == TPAREN)
X! return restore_std (execute (t->left, NOPIPE, NOPIPE, FEXEC));
X
X /* Are we just changing the I/O re-direction for the shell ? */
X
X if (wp[0] == NULL)
X {
X if (spawn)
X! restore_std (0);
X
X return 0;
X }
X--- 538,555 ----
X #ifdef SIGQUIT
X signal (SIGQUIT, SIG_IGN);
X #endif
X! signal (SIGINT, sig_int);
X }
X
X if (t->type == TPAREN)
X! return restore_std (execute (t->left, NOPIPE, NOPIPE, FEXEC), TRUE);
X
X /* Are we just changing the I/O re-direction for the shell ? */
X
X if (wp[0] == NULL)
X {
X if (spawn)
X! restore_std (0, TRUE);
X
X return 0;
X }
X***************
X*** 548,556 ****
X return rv;
X }
X
X! /* Ok - execute the program */
X
X! return restore_std (rexecve (wp[0], wp, makenv (), spawn));
X }
X
X /*
X--- 602,615 ----
X return rv;
X }
X
X! /* Check for another drive or directory in the restricted shell */
X
X! if (anys (":/\\", wp[0]) && check_rsh (wp[0]))
X! return restore_std (-1, TRUE);
X!
X! /* Ok - execute the program */
X!
X! return restore_std (rexecve (wp[0], wp, makenv (), spawn), TRUE);
X }
X
X /*
X***************
X*** 564,570 ****
X Execute_stack_depth = stack;
X Delete_G_VL ();
X Restore_Dir ();
X! restore_std (setstatus (retval));
X }
X
X /*
X--- 623,629 ----
X Execute_stack_depth = stack;
X Delete_G_VL ();
X Restore_Dir ();
X! restore_std (setstatus (retval), TRUE);
X }
X
X /*
X***************
X*** 613,628 ****
X iop->io_flag &= ~(IOREAD | IOWRITE);
X }
X
X! /* Open the file in the appropriate mode */
X
X! switch (iop->io_flag)
X {
X case IOREAD: /* < */
X u = S_open (FALSE, cp, O_RDONLY);
X break;
X
X case IOHERE: /* << */
X- case IOHERE | IOXHERE:
X u = herein (iop->io_name, iop->io_flag & IOXHERE);
X cp = "here file";
X break;
X--- 672,695 ----
X iop->io_flag &= ~(IOREAD | IOWRITE);
X }
X
X! /*
X! * When writing to /dev/???, we have to cheat because MSDOS appears to
X! * have a problem with /dev/ files after find_first/find_next.
X! */
X
X! if (((iop->io_flag & ~(IOXHERE | IOTHERE)) == IOWRITE) &&
X! (strnicmp (cp, "/dev/", 5) == 0))
X! iop->io_flag |= IOCAT;
X!
X! /* Open the file in the appropriate mode */
X!
X! switch (iop->io_flag & ~(IOXHERE | IOTHERE))
X {
X case IOREAD: /* < */
X u = S_open (FALSE, cp, O_RDONLY);
X break;
X
X case IOHERE: /* << */
X u = herein (iop->io_name, iop->io_flag & IOXHERE);
X cp = "here file";
X break;
X***************
X*** 748,755 ****
X }
X
X /*
X! * PATH-searching interface to execve. If getenv ("PATH") were kept
X! * up-to-date, execvp might be used.
X */
X
X static int rexecve (c, v, envp, d_flag)
X--- 815,821 ----
X }
X
X /*
X! * PATH-searching interface to execve.
X */
X
X static int rexecve (c, v, envp, d_flag)
X***************
X*** 759,782 ****
X bool d_flag;
X {
X register char *sp;
X! int res;
X! char *em;
X! bool eloop;
X
X /* If the environment is null - It is too big - error */
X
X if (envp == (char **)NULL)
X em = AE2big;
X
X else
X {
X- sp = any ('/', c) ? null : path->value;
X
X do
X {
X! sp = path_append (sp, c, e.linep);
X
X! if ((res = Execute_program (e.linep, v, envp, d_flag)) != -1)
X return res;
X
X eloop = TRUE;
X--- 825,869 ----
X bool d_flag;
X {
X register char *sp;
X! int res; /* Result */
X! char *em; /* Exit error message */
X! bool eloop; /* Re-try flag */
X! char **new_argv;
X! int batfile; /* .bat file flag */
X! int argc = 0; /* Original # of argcs */
X! char *params; /* Script parameters */
X! int nargc = 0; /* # script args */
X! char *p_name; /* Program name */
X! int i;
X
X /* If the environment is null - It is too big - error */
X
X if (envp == (char **)NULL)
X em = AE2big;
X
X+ else if ((p_name = getcell (FFNAME_MAX)) == (char *)NULL)
X+ em = strerror (ENOMEM);
X+
X else
X {
X
X+ /* Count the number of arguments to the program in case of shell script or
X+ * bat file
X+ */
X+
X+ while (v[argc++] != (char *)NULL);
X+
X+ ++argc; /* Including the null */
X+
X+ /* Start off on the search path for the executable file */
X+
X+ sp = (any ('/', c) || (*(c + 1) == ':')) ? null : path->value;
X+
X do
X {
X! sp = path_append (sp, c, p_name);
X
X! if ((res = Execute_program (p_name, v, envp, d_flag)) != -1)
X return res;
X
X eloop = TRUE;
X***************
X*** 788,812 ****
X * script
X */
X case ENOENT:
X! if ((res = O_for_execute (e.linep)) >= 0)
X {
X S_close (res, TRUE);
X- *v = e.linep;
X- em = *--v;
X- *v = e.linep;
X- res = Execute_program (lookup (shell, FALSE)->value,
X- v, envp, d_flag);
X- *v = em;
X-
X- if (res != -1)
X- return res;
X-
X- em = "no Shell";
X }
X
X! else
X em = "not found";
X
X eloop = FALSE;
X break;
X
X--- 875,963 ----
X * script
X */
X case ENOENT:
X! if ((res = O_for_execute (p_name, ¶ms, &nargc)) >= 0)
X {
X+ batfile = 1;
X S_close (res, TRUE);
X }
X
X! else if (!Check_for_bat_file (p_name))
X! {
X em = "not found";
X+ eloop = FALSE;
X+ break;
X+ }
X
X+ else
X+ {
X+ Convert_Slashes (p_name);
X+ batfile = 0;
X+ nargc = 0;
X+ }
X+
X+ /* Ok - either a shell script or a bat file (batfile = 0) */
X+
X+ nargc = (nargc < 2) ? 0 : nargc - 1;
X+ if ((new_argv = (char **)getcell (sizeof (char *) *
X+ (argc + nargc + 2)))
X+ == (char **)NULL)
X+ {
X+ em = strerror (ENOMEM);
X+ break;
X+ }
X+
X+ memcpy (&new_argv[2 + nargc], &v[0], sizeof(char *) * argc);
X+
X+ /* If BAT file, use command.com else use sh */
X+
X+ if (!batfile)
X+ {
X+ new_argv[0] = lookup ("COMSPEC", FALSE)->value;
X+ new_argv[1] = "/c";
X+ }
X+
X+ /* Stick in the pre-fix arguments */
X+
X+ else if (nargc)
X+ {
X+ i = 1;
X+ em = params;
X+
X+ while (*em)
X+ {
X+ while (isspace (*em))
X+ *(em++) = 0;
X+
X+ if (*em)
X+ new_argv[i++] = em;
X+
X+ while (!isspace (*em) && *em)
X+ ++em;
X+ }
X+ }
X+
X+ else if (params != null)
X+ new_argv[1] = params;
X+
X+ else
X+ new_argv[1] = lookup (shell, FALSE)->value;
X+
X+ new_argv[2 + nargc] = p_name;
X+
X+ res = rexecve (new_argv[batfile], &new_argv[batfile],
X+ envp, d_flag);
X+ /* Release allocated space */
X+
X+ DELETE (new_argv);
X+
X+ if (params != null)
X+ DELETE (params);
X+
X+ if (res != -1)
X+ return res;
X+ /* No - shell */
X+
X+ em = "no Shell";
X eloop = FALSE;
X break;
X
X***************
X*** 838,850 ****
X return -1;
X }
X
X /*
X * Run the command produced by generator `f' applied to stream `arg'.
X */
X
X! int run (argp, f)
X IO_Args *argp;
X int (*f)(IO_State *);
X {
X Word_B *swdlist = wdlist;
X Word_B *siolist = iolist;
X--- 989,1036 ----
X return -1;
X }
X
X+ /* Check to see if this is a bat file */
X+
X+ static bool Check_for_bat_file (name)
X+ char *name;
X+ {
X+ char *local_path;
X+ char *cp;
X+ bool res;
X+
X+ if ((local_path = getcell (strlen (name) + 5)) == (char *)NULL)
X+ return FALSE;
X+
X+ /* Work on a copy of the path */
X+
X+ if ((cp = strrchr (strcpy (local_path, name), '/')) == (char *)NULL)
X+ cp = local_path;
X+
X+ else
X+ ++cp;
X+
X+ if ((cp = strrchr (cp, '.')) == (char *)NULL)
X+ strcat (local_path, ".bat");
X+
X+ else if (stricmp (cp, ".bat") != 0)
X+ {
SHAR_EOF
echo "End of part 2"
echo "File Patch1.6 is continued in part 3"
echo "3" > s2_seq_.tmp
exit 0