mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-14 01:14:27 +02:00
commit Bart's patch to fix CP/M call psp:05h compatibility call along with some comments to explain the call trampoline
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1372 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
497a2337ef
commit
240bcc30e2
@ -65,14 +65,22 @@ typedef struct {
|
|||||||
UWORD ps_exit; /* 00 CP/M-like exit point: int 20 */
|
UWORD ps_exit; /* 00 CP/M-like exit point: int 20 */
|
||||||
UWORD ps_size; /* 02 segment of first byte beyond */
|
UWORD ps_size; /* 02 segment of first byte beyond */
|
||||||
/* memory allocated to program */
|
/* memory allocated to program */
|
||||||
BYTE ps_fill1; /* 04 single char fill */
|
BYTE ps_fill1; /* 04 single char fill=0 */
|
||||||
|
|
||||||
/* CP/M-like entry point */
|
/* CP/M-like entry point */
|
||||||
UBYTE ps_farcall; /* 05 far call opcode */
|
/* offsets 5-9 are a far call to absolute address 0:000Ch
|
||||||
|
coded so that CP/M apps can do a near call to psp:5, does a
|
||||||
|
far call but ensures word at offset 6 is size of COM file
|
||||||
|
e.g. FEF0h by using 1MB wrap around address 0F01D:FEF0
|
||||||
|
(jmp code stored at 0:000C should be duplicated in HMA FFFF:00D0)
|
||||||
|
Note: MS-DOS has value as FEEE which wraps to 0:00BEh */
|
||||||
|
UBYTE ps_farcall; /* 05 far call opcode */
|
||||||
VOID(FAR ASMCFUNC * ps_reentry) (void); /* 06 re-entry point */
|
VOID(FAR ASMCFUNC * ps_reentry) (void); /* 06 re-entry point */
|
||||||
intvec ps_isv22, /* 0a terminate address */
|
|
||||||
ps_isv23, /* 0e break address */
|
|
||||||
ps_isv24; /* 12 critical error address */
|
intvec ps_isv22, /* 0a terminate address */
|
||||||
|
ps_isv23, /* 0e break address */
|
||||||
|
ps_isv24; /* 12 critical error address */
|
||||||
UWORD ps_parent; /* 16 parent psp segment */
|
UWORD ps_parent; /* 16 parent psp segment */
|
||||||
UBYTE ps_files[20]; /* 18 file table - 0xff is unused */
|
UBYTE ps_files[20]; /* 18 file table - 0xff is unused */
|
||||||
UWORD ps_environ; /* 2c environment paragraph */
|
UWORD ps_environ; /* 2c environment paragraph */
|
||||||
|
106
kernel/entry.asm
106
kernel/entry.asm
@ -28,10 +28,10 @@
|
|||||||
; $Id$
|
; $Id$
|
||||||
;
|
;
|
||||||
|
|
||||||
%include "segs.inc"
|
%include "segs.inc"
|
||||||
%include "stacks.inc"
|
%include "stacks.inc"
|
||||||
|
|
||||||
segment HMA_TEXT
|
segment HMA_TEXT
|
||||||
extern _int21_syscall
|
extern _int21_syscall
|
||||||
extern _int21_service
|
extern _int21_service
|
||||||
extern _int2526_handler
|
extern _int2526_handler
|
||||||
@ -50,7 +50,7 @@ segment HMA_TEXT
|
|||||||
|
|
||||||
extern _Int21AX:wrt DGROUP
|
extern _Int21AX:wrt DGROUP
|
||||||
|
|
||||||
extern _DGROUP_
|
extern _DGROUP_
|
||||||
|
|
||||||
global reloc_call_cpm_entry
|
global reloc_call_cpm_entry
|
||||||
global reloc_call_int20_handler
|
global reloc_call_int20_handler
|
||||||
@ -65,9 +65,14 @@ segment HMA_TEXT
|
|||||||
; VOID FAR
|
; VOID FAR
|
||||||
; cpm_entry(iregs UserRegs)
|
; cpm_entry(iregs UserRegs)
|
||||||
;
|
;
|
||||||
; This one is a strange one. The call is to psp:0005h but it returns to the
|
; For CP/M compatibility allow a program to invoke any DOS API function
|
||||||
; function after the call. What we do is convert it to a normal call and
|
; between 0 and 24h by doing a near call to psp:0005h which embeds a far call
|
||||||
; fudge the stack to look like an int 21h call.
|
; to absolute address 0:00C0h (int vector 30h & 31h) or FFFF:00D0 (hma).
|
||||||
|
; Note: int 31h is also used for DPMI
|
||||||
|
; Upon entry the stack has a near return offset (desired return address) and
|
||||||
|
; far return seg:offset (useless return to data at offset 0ah after far call
|
||||||
|
; in psp). We convert it to a normal call and correct the stack to appear same
|
||||||
|
; as if invoked via an int 21h call including proper return address.
|
||||||
;
|
;
|
||||||
reloc_call_cpm_entry:
|
reloc_call_cpm_entry:
|
||||||
; Stack is:
|
; Stack is:
|
||||||
@ -75,10 +80,7 @@ reloc_call_cpm_entry:
|
|||||||
; psp seg
|
; psp seg
|
||||||
; 000ah
|
; 000ah
|
||||||
;
|
;
|
||||||
push bp ; trash old return address
|
add sp, 2 ; remove unneeded far return offset 0ah
|
||||||
mov bp,sp
|
|
||||||
xchg bp,[2+bp]
|
|
||||||
pop bp
|
|
||||||
pushf ; start setting up int 21h stack
|
pushf ; start setting up int 21h stack
|
||||||
;
|
;
|
||||||
; now stack is
|
; now stack is
|
||||||
@ -107,12 +109,12 @@ reloc_call_cpm_entry:
|
|||||||
; psp seg (alias .COM cs)
|
; psp seg (alias .COM cs)
|
||||||
; return offset
|
; return offset
|
||||||
;
|
;
|
||||||
cmp cl,024h
|
cmp cl,024h ; restrict calls to functions 0-24h
|
||||||
jbe cpm_error
|
ja cpm_error
|
||||||
mov ah,cl ; get the call # from cl to ah
|
mov ah,cl ; get the call # from cl to ah
|
||||||
jmp reloc_call_int21_handler ; do the system call
|
jmp reloc_call_int21_handler ; do the system call
|
||||||
cpm_error: mov al,0
|
cpm_error: mov al,0
|
||||||
iret
|
iret ; cleanup stack and return to caller
|
||||||
|
|
||||||
;
|
;
|
||||||
; interrupt zero divide handler:
|
; interrupt zero divide handler:
|
||||||
@ -123,20 +125,20 @@ cpm_error: mov al,0
|
|||||||
; int20_handler(iregs UserRegs)
|
; int20_handler(iregs UserRegs)
|
||||||
;
|
;
|
||||||
|
|
||||||
print_hex: mov cl, 12
|
print_hex: mov cl, 12
|
||||||
hex_loop:
|
hex_loop:
|
||||||
mov ax, dx
|
mov ax, dx
|
||||||
shr ax, cl
|
shr ax, cl
|
||||||
and al, 0fh
|
and al, 0fh
|
||||||
cmp al, 10
|
cmp al, 10
|
||||||
sbb al, 69h
|
sbb al, 69h
|
||||||
das
|
das
|
||||||
mov bx, 0070h
|
mov bx, 0070h
|
||||||
mov ah, 0eh
|
mov ah, 0eh
|
||||||
int 10h
|
int 10h
|
||||||
sub cl, 4
|
sub cl, 4
|
||||||
jae hex_loop
|
jae hex_loop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
divide_by_zero_message db 0dh,0ah,'Interrupt divide by zero, stack:',0dh,0ah,0
|
divide_by_zero_message db 0dh,0ah,'Interrupt divide by zero, stack:',0dh,0ah,0
|
||||||
|
|
||||||
@ -159,27 +161,27 @@ zero_message_loop:
|
|||||||
jmp short zero_message_loop
|
jmp short zero_message_loop
|
||||||
|
|
||||||
zero_done:
|
zero_done:
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
xor si, si ; print 13 words of stack for debugging LUDIV etc.
|
xor si, si ; print 13 words of stack for debugging LUDIV etc.
|
||||||
stack_loop:
|
stack_loop:
|
||||||
mov dx, [bp+si]
|
mov dx, [bp+si]
|
||||||
call print_hex
|
call print_hex
|
||||||
mov al, ' '
|
mov al, ' '
|
||||||
int 10h
|
int 10h
|
||||||
inc si
|
inc si
|
||||||
inc si
|
inc si
|
||||||
cmp si, 13*2
|
cmp si, 13*2
|
||||||
jb stack_loop
|
jb stack_loop
|
||||||
mov al, 0dh
|
mov al, 0dh
|
||||||
int 10h
|
int 10h
|
||||||
mov al, 0ah
|
mov al, 0ah
|
||||||
int 10h
|
int 10h
|
||||||
|
|
||||||
mov ax,04c7fh ; terminate with errorlevel 127
|
mov ax,04c7fh ; terminate with errorlevel 127
|
||||||
int 21h
|
int 21h
|
||||||
sti
|
sti
|
||||||
thats_it: hlt
|
thats_it: hlt
|
||||||
jmp short thats_it ; it might be command.com that nukes
|
jmp short thats_it ; it might be command.com that nukes
|
||||||
|
|
||||||
invalid_opcode_message db 0dh,0ah,'Invalid Opcode at ',0
|
invalid_opcode_message db 0dh,0ah,'Invalid Opcode at ',0
|
||||||
|
|
||||||
@ -299,7 +301,7 @@ int21_1:
|
|||||||
; I don't know who needs that, but ... (TE)
|
; I don't know who needs that, but ... (TE)
|
||||||
;
|
;
|
||||||
mov word [_user_r+2],ss
|
mov word [_user_r+2],ss
|
||||||
mov word [_user_r],bp ; store and init
|
mov word [_user_r],bp ; store and init
|
||||||
|
|
||||||
;
|
;
|
||||||
; Decide which stack to run on.
|
; Decide which stack to run on.
|
||||||
@ -377,9 +379,9 @@ int21_exit_nodec:
|
|||||||
%ifdef WATCOM
|
%ifdef WATCOM
|
||||||
sub bp, 4 ; for fs and gs only
|
sub bp, 4 ; for fs and gs only
|
||||||
%else
|
%else
|
||||||
sub bp, 6 ; high parts of eax, ebx or ecx, edx
|
sub bp, 6 ; high parts of eax, ebx or ecx, edx
|
||||||
%endif
|
%endif
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
cli
|
cli
|
||||||
mov ss,si
|
mov ss,si
|
||||||
@ -387,7 +389,7 @@ int21_exit_nodec:
|
|||||||
|
|
||||||
int21_ret:
|
int21_ret:
|
||||||
Restore386Registers
|
Restore386Registers
|
||||||
POP$ALL
|
POP$ALL
|
||||||
|
|
||||||
;
|
;
|
||||||
; ... and return.
|
; ... and return.
|
||||||
@ -466,8 +468,8 @@ int2526:
|
|||||||
|
|
||||||
Protect386Registers
|
Protect386Registers
|
||||||
|
|
||||||
push dx
|
push dx
|
||||||
push cx ; save user stack
|
push cx ; save user stack
|
||||||
|
|
||||||
push dx ; SS:SP -> user stack
|
push dx ; SS:SP -> user stack
|
||||||
push cx
|
push cx
|
||||||
@ -475,8 +477,8 @@ int2526:
|
|||||||
call _int2526_handler
|
call _int2526_handler
|
||||||
add sp, byte 6
|
add sp, byte 6
|
||||||
|
|
||||||
pop cx
|
pop cx
|
||||||
pop dx ; restore user stack
|
pop dx ; restore user stack
|
||||||
|
|
||||||
Restore386Registers
|
Restore386Registers
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user