Introduce popargs and arg macros to distinguish PASCAL/STDCALL conventions.

GCC has -mrtd but the args are pushed in reverse versus PASCAL. So asm
routines have to use macros to obtain the stack arguments.
For the complex call_nls assembly, revert the arguments in C using a
preprocessor macro.
This commit is contained in:
Bart Oldeman 2017-12-19 13:30:59 -05:00 committed by Kenneth J Davis
parent f6d62165e0
commit 97003a8aca
11 changed files with 178 additions and 104 deletions

View File

@ -29,6 +29,7 @@
;
%include "../kernel/segs.inc"
%include "../hdr/stacks.inc"
segment HMA_TEXT
;
@ -112,7 +113,8 @@ fl_common:
push bp ; setup stack frame
mov bp,sp
mov cx,[bp+0Ch] ; cylinder number
arg drive, head, track, sector, count, {buffer,4}
mov cx,[.track] ; cylinder number
mov al,1 ; this should be an error code
cmp ch,3 ; this code can't write above 3FFh=1023
@ -121,13 +123,13 @@ fl_common:
xchg ch,cl ; ch=low 8 bits of cyl number
ror cl,1 ; bits 8-9 of cylinder number...
ror cl,1 ; ...to bits 6-7 in CL
or cl,[bp+0Ah] ; or in the sector number (bits 0-5)
or cl,[.sector] ; or in the sector number (bits 0-5)
mov al,[bp+08h] ; count of sectors to read/write/...
les bx,[bp+04h] ; Load 32 bit buffer ptr into ES:BX
mov al,[.count] ; count of sectors to read/write/...
les bx,[.buffer] ; Load 32 bit buffer ptr into ES:BX
mov dl,[bp+10h] ; drive (if or'ed 80h its a hard drive)
mov dh,[bp+0Eh] ; get the head number
mov dl,[.drive] ; drive (if or'ed 80h its a hard drive)
mov dh,[.head] ; get the head number
int 13h ; process sectors
@ -152,9 +154,10 @@ FL_LBA_READWRITE:
push ds
push si ; wasn't in kernel < KE2024Bo6!!
mov dl,[bp+10] ; drive (if or'ed with 80h a hard drive)
mov ax,[bp+8] ; get the command
lds si,[bp+4] ; get far dap pointer
arg drive, mode, {dap_p,4}
mov dl,[.drive] ; drive (if or'ed with 80h a hard drive)
mov ax,[.mode] ; get the command
lds si,[.dap_p] ; get far dap pointer
int 13h ; read from/write to drive
pop si
@ -182,8 +185,7 @@ FL_READKEY: xor ah, ah
global FL_SETDISKTYPE
FL_SETDISKTYPE:
pop bx ; return address
pop ax ; disk format type (al)
pop dx ; drive number (dl)
popargs dx,ax ; drive number(dl),disk format type(al)
push bx ; restore stack
mov ah,17h ; floppy set disk type for format
int 13h
@ -198,9 +200,7 @@ ret_AH:
global FL_SETMEDIATYPE
FL_SETMEDIATYPE:
pop ax ; return address
pop bx ; sectors/track
pop cx ; number of tracks
pop dx ; drive number
popargs dx,cx,bx ; drive number,#tracks,sectors/track
push ax ; restore stack
push di

View File

@ -29,6 +29,7 @@
;
%include "../kernel/segs.inc"
%include "../hdr/stacks.inc"
segment HMA_TEXT
@ -47,13 +48,14 @@ WRITEATCLOCK:
; bcdMinutes = 6
; bcdHours = 8
; bcdDays = 10
mov ch,byte [bp+8] ;bcdHours
mov cl,byte [bp+6] ;bcdMinutes
mov dh,byte [bp+4] ;bcdSeconds
arg bcdDays, bcdHours, bcdMinutes, bcdSeconds
mov ch,byte [.bcdHours]
mov cl,byte [.bcdMinutes]
mov dh,byte [.bcdSeconds]
mov dl,0
mov ah,3
int 1ah
mov bx,word [bp+10] ;bcdDays
mov bx,word [.bcdDays]
mov dx,word [bx]
mov cx,word [bx+2]
mov ah,5

View File

@ -28,6 +28,7 @@
; $Header$
;
%include "../kernel/segs.inc"
%include "../hdr/stacks.inc"
segment HMA_TEXT
@ -40,8 +41,7 @@ segment HMA_TEXT
WRITEPCCLOCK:
; Ticks = 4
pop ax ; return address
pop dx
pop cx ; Ticks
popargs {dx,cx} ; Ticks
push ax ; restore stack
mov ah,1
int 1ah

View File

@ -196,3 +196,57 @@ irp_hi equ 26
%endif
%ENDIF
; macros to define stack arguments
; arg a, {b,4}, c
; defines a and c as "word" arguments and b as a "dword" argument
; for STDCALL defines .a as [bp+4], .b as [bp+6] and .c as [bp+10]
; for PASCAL defines .a as [bp+10], .b as [bp+6] and .c as [bp+4]
;
; popargs bx, {dx,ax}, cx pops these arguments of the stack (for PASCAL
; in reverse order). Here dx,ax is a dword argument dx:ax where dx is
; the high word. The caller is responsible for dealing with instruction
; pointer (ip) on the stack.
%ifdef gcc
%define STDCALL
%else
%define PASCAL
%endif
%macro definearg 1-2 2
%xdefine .%1 bp+.argloc
%assign .argloc .argloc+%2
%endmacro
%macro arg 1-*
%assign .argloc 4
%rep %0
%ifdef PASCAL
%rotate -1
%endif
definearg %1
%ifdef STDCALL
%rotate 1
%endif
%endrep
%endmacro
%macro multipop 1-*
%rep %0
%rotate -1
pop %1
%endrep
%endmacro
%macro popargs 1-*
%rep %0
%ifdef PASCAL
%rotate -1
%endif
multipop %1
%ifdef STDCALL
%rotate 1
%endif
%endrep
%endmacro

View File

@ -48,6 +48,7 @@
%ifndef WATCOM_INIT
%include "segs.inc"
%include "stacks.inc"
%ifdef _INIT
@ -134,9 +135,10 @@ pascal_setup:
cld
mov bl,6 ; majority (4) wants that
mov cx,[4+bp] ; majority (8) wants that (near and far)
mov si,[6+bp] ; majority (3) wants that (near)
mov di,[8+bp] ; majority (3) wants that (near)
arg arg1, arg2, arg3
mov cx,[.arg3] ; majority (8) wants that (near and far)
mov si,[.arg2] ; majority (3) wants that (near)
mov di,[.arg1] ; majority (3) wants that (near)
jmp ax
@ -192,14 +194,17 @@ FMEMCPYBACK:
FMEMCPY:
call pascal_setup
arg {d,4}, {s,4}, n
; Get the repetition count, n preset above
; mov cx,[bp+4]
%ifdef STDCALL
mov cx,[.n]
%endif
; Get the far source pointer, s
lds si,[bp+6]
lds si,[.s]
; Get the far destination pointer d
les di,[bp+10]
les di,[.d]
mov bl,10
jmp short domemcpy
@ -212,14 +217,17 @@ FMEMCPY:
FMEMSET:
call pascal_setup
arg {d,4}, ch, n
; Get the repetition count, n - preset above
; mov cx,[bp+4]
%ifdef STDCALL
mov cx,[.n]
%endif
; Get the fill byte ch
mov ax,[bp+6]
mov ax,[.ch]
; Get the far source pointer, s
les di,[bp+8]
les di,[.d]
mov bl,8
domemset:
@ -240,11 +248,12 @@ domemset:
MEMSET:
call pascal_setup
arg d, ch, n
; Get the repitition count, n - preset above
; mov cx,[bp+4]
; Get the char ch
mov ax, [bp+6]
mov ax, [.ch]
; Get the far source pointer, d - preset above
; mov di,[bp+8]
@ -282,11 +291,12 @@ pascal_return:
FSTRCPY:
call pascal_setup
arg {dest,4}, {src,4}
; Get the source pointer, ss
lds si,[bp+4]
lds si,[.src]
; and the destination pointer, d
les di,[bp+8]
les di,[.dest]
mov bl,8
@ -299,11 +309,13 @@ STRCPY:
call pascal_setup
%ifdef PASCAL
; Get the source pointer, ss
mov si,[bp+4]
; and the destination pointer, d
mov di,[bp+6]
%endif
mov bl,4
dostrcpy:
@ -334,7 +346,9 @@ FSTRLEN:
STRLEN:
call pascal_setup
; Get the source pointer, ss
%ifdef PASCAL
mov di,[bp+4]
%endif
mov bl,2
dostrlen:
@ -356,8 +370,11 @@ STRCHR:
call pascal_setup
; Get the source pointer, ss
; mov cx,[bp+4] - preset above
; mov si,[bp+6] - preset above
arg src, ch
%ifdef STDCALL ; preset above for PASCAL
mov cx,[.ch]
mov si,[.src]
%endif
mov bl,4
strchr_loop:
@ -388,11 +405,12 @@ strchr_found1:
FSTRCHR:
call pascal_setup
arg {src,4}, ch
; Get ch (preset above)
;mov cx, [bp+4]
;and the source pointer, src
lds si, [bp+6]
lds si, [.src]
;mov bl, 6 - preset above
@ -403,14 +421,17 @@ FSTRCHR:
FMEMCHR:
call pascal_setup
arg {src,4}, ch, n
; Get the length - preset above
; mov cx, [bp+4]
%ifdef STDCALL
mov cx, [.n]
%endif
; and the search value
mov ax, [bp+6]
mov ax, [.ch]
; and the source pointer, ss
les di, [bp+8]
les di, [.src]
mov bl, 8
@ -426,11 +447,12 @@ FMEMCHR:
FSTRCMP:
call pascal_setup
arg {dest,4}, {src,4}
; Get the source pointer, ss
lds si,[bp+4]
lds si,[.src]
; and the destination pointer, d
les di,[bp+8]
les di,[.dest]
mov bl,8
@ -507,14 +529,17 @@ strncmp_loop:
FMEMCMP:
call pascal_setup
arg {dest,4}, {src,4}, n
; the length - preset above
; mov cx, [bp+4]
%ifdef STDCALL
mov cx, [.n]
%endif
; Get the source pointer, ss
les di,[bp+6]
les di,[.src]
; and the destination pointer, d
lds si,[bp+10]
lds si,[.dest]
mov bl,10

View File

@ -51,17 +51,18 @@ segment HMA_TEXT
push si
push ds ; sp=bp-8
lds si,[bp+4] ; ds:si = device header
les bx,[bp+8] ; es:bx = request header
arg {rhp,4}, {dhp,4}
lds si,[.dhp] ; ds:si = device header
les bx,[.rhp] ; es:bx = request header
mov ax, [si+6] ; construct strategy address
mov [bp+4], ax
mov [.dhp], ax
push si ; the bloody fucking RTSND.DOS
push di ; driver destroys SI,DI (tom 14.2.03)
call far[bp+4] ; call far the strategy
call far[.dhp] ; call far the strategy
pop di
pop si
@ -69,8 +70,8 @@ segment HMA_TEXT
; Protect386Registers ; old free-EMM386 versions destroy regs in their INIT method
mov ax,[si+8] ; construct 'interrupt' address
mov [bp+4],ax ; construct interrupt address
call far[bp+4] ; call far the interrupt
mov [.dhp],ax ; construct interrupt address
call far[.dhp] ; call far the interrupt
; Restore386Registers ; less stack load and better performance...

View File

@ -213,10 +213,7 @@ SHARE_CHECK:
SHARE_OPEN_CHECK:
mov es, si ; save si
pop ax ; return address
pop dx ; sharemode;
pop cx ; openmode;
pop bx ; pspseg;
pop si ; filename
popargs si,bx,cx,dx ; filename,pspseg,openmode,sharemode;
push ax ; return address
mov ax, 0x10a0
int 0x2f ; returns ax
@ -261,12 +258,13 @@ share_common:
mov bp, sp
push si
push di
mov bx, [bp + 16] ; pspseg
mov cx, [bp + 14] ; fileno
mov si, [bp + 12] ; high word of ofs
mov di, [bp + 10] ; low word of ofs
les dx, [bp + 6] ; len
or ax, [bp + 4] ; allowcriter/unlock
arg pspseg, fileno, {ofs,4}, {len,4}, allowcriter
mov bx, [.pspseg] ; pspseg
mov cx, [.fileno] ; fileno
mov si, [.ofs+2] ; high word of ofs
mov di, [.ofs] ; low word of ofs
les dx, [.len] ; len
or ax, [.allowcriter] ; allowcriter/unlock
int 0x2f
pop di
pop si
@ -323,10 +321,8 @@ remote_lock_unlock:
global NETWORK_REDIRECTOR_MX
NETWORK_REDIRECTOR_MX:
pop bx ; ret address
pop cx ; stack value (arg); cx in remote_rw
pop dx ; off s
pop es ; seg s
pop ax ; cmd (ax)
popargs ax,{es,dx},cx ; cmd (ax), seg:off s
; stack value (arg); cx in remote_rw
push bx ; ret address
call_int2f:
push bp
@ -497,7 +493,8 @@ FLOPPY_CHANGE:
segment INIT_TEXT
; int ASMPASCAL UMB_get_largest(void FAR * driverAddress,
; UCOUNT * seg, UCOUNT * size);
global UMB_GET_LARGEST
arg {driverAddress,4}, argseg, size
global UMB_GET_LARGEST
UMB_GET_LARGEST:
push bp
@ -505,7 +502,7 @@ UMB_GET_LARGEST:
mov dx,0xffff ; go for broke!
mov ax,1000h ; get the UMBs
call far [bp+8] ; Call the driver
call far [.driverAddress] ; Call the driver
;
; bl = 0xB0 and ax = 0 so do it again.
@ -517,7 +514,7 @@ UMB_GET_LARGEST:
je umbt_error
mov ax,1000h ; dx set with largest size
call far [bp+8] ; Call the driver
call far [.driverAddress] ; Call the driver
cmp ax,1
jne umbt_error
@ -525,10 +522,10 @@ UMB_GET_LARGEST:
; and the size
mov cx,bx ; *seg = segment
mov bx, [bp+6]
mov bx, [.argseg]
mov [bx],cx
mov bx, [bp+4] ; *size = size
mov bx, [.size] ; *size = size
mov [bx],dx
umbt_ret:

View File

@ -26,6 +26,7 @@
;
%include "segs.inc"
%include "stacks.inc"
%macro INTR 0
@ -41,10 +42,11 @@
%endif
push ds
mov ax, [bp+6] ; interrupt number
arg nr, rp
mov ax, [.nr] ; interrupt number
mov [cs:%%intr_1-1], al
jmp short %%intr_2 ; flush the instruction cache
%%intr_2 mov bx, [bp+4] ; regpack structure
%%intr_2 mov bx, [.rp] ; regpack structure
mov ax, [bx]
mov cx, [bx+4]
mov dx, [bx+6]
@ -66,7 +68,7 @@
%ifdef WATCOM
mov bx, [ss:bx+24] ; address of REGPACK
%else
mov bx, [ss:bx+16] ; address of REGPACK
mov bx, [ss:bx+12+.rp-bp] ; address of REGPACK
%endif
mov [bx], ax
pop word [bx+2]
@ -98,9 +100,7 @@ segment HMA_TEXT
global RES_DOSEXEC
RES_DOSEXEC:
pop es ; ret address
pop dx ; filename
pop bx ; exec block
pop ax ; mode
popargs ax,bx,dx ; mode, exec block, filename
push es ; ret address
mov ah, 4bh
push ds
@ -115,9 +115,7 @@ no_exec_error:
global RES_READ
RES_READ:
pop ax ; ret address
pop cx ; count
pop dx ; buf
pop bx ; fd
popargs bx,dx,cx ; fd, buf, count
push ax ; ret address
mov ah, 3fh
int 21h
@ -144,10 +142,7 @@ INIT_CALL_INTR:
global INIT_CALL_XMSCALL
INIT_CALL_XMSCALL:
pop bx ; ret address
pop dx
pop ax
pop cx ; driver address
pop es
popargs {es,cx},ax,dx
push cs ; ret address
push bx
@ -190,8 +185,7 @@ KEYCHECK:
INIT_DOSOPEN:
;; init calling DOS through ints:
pop bx ; ret address
pop ax ; flags
pop dx ; pathname
popargs dx,ax ; pathname, flags
push bx ; ret address
mov ah, 3dh
;; AX will have the file handle
@ -216,9 +210,7 @@ CLOSE:
global READ
READ:
pop ax ; ret address
pop cx ; count
pop dx ; buf
pop bx ; fd
popargs bx,dx,cx ; fd,buf,count
push ax ; ret address
mov ah, 3fh
jmp short common_int21
@ -227,8 +219,7 @@ READ:
global DUP2
DUP2:
pop ax ; ret address
pop cx ; newfd
pop bx ; oldfd
popargs bx,cx ; oldfd,newfd
push ax ; ret address
mov ah, 46h
jmp short common_int21
@ -239,9 +230,7 @@ DUP2:
global LSEEK
LSEEK:
pop ax ; ret address
pop dx ; position low
pop cx ; position high
pop bx ; fd
popargs bx,{cx,dx} ; fd, position high:low
push ax ; ret address
mov ax,4200h ; origin: start of file
int 21h
@ -265,9 +254,7 @@ INIT_PSPSET:
global INIT_DOSEXEC
INIT_DOSEXEC:
pop es ; ret address
pop dx ; filename
pop bx ; exec block
pop ax ; mode
popargs ax,bx,dx ; mode, exec block, filename
push es ; ret address
mov ah, 4bh
push ds
@ -313,8 +300,7 @@ ALLOCMEM:
global SET_DTA
SET_DTA:
pop ax ; ret address
pop dx ; off(dta)
pop bx ; seg(dta)
popargs {bx,dx} ; seg:off(dta)
push ax ; ret address
mov ah, 1ah
push ds

View File

@ -29,6 +29,7 @@
;
%include "segs.inc"
%include "stacks.inc"
%include "ludivmul.inc"

View File

@ -51,6 +51,15 @@
; destroys:
; flags
;
%ifdef STDCALL
push bp
mov bp, sp
mov ax, [bp+6]
mov dx, [bp+8]
mov bx, [bp+10]
mov cx, [bp+12]
pop bp
%endif
test cx, cx ; divisor > 2^32-1 ?
jnz %%big_divisor ; yes, divisor > 32^32-1
@ -113,12 +122,10 @@
%macro LSHLU 0
pop bx
pop ax
pop dx
pop cx
popargs {dx,ax},cx
push bx
jcxz %%ret
%%loop: shl ax, 1
%%loop: shl ax, 1
rcl dx, 1
loop %%loop
%%ret: ret 6
@ -126,12 +133,10 @@
%macro LSHRU 0
pop bx
pop ax
pop dx
pop cx
popargs {dx,ax},cx
push bx
jcxz %%ret
%%loop: shr dx, 1
%%loop: shr dx, 1
rcr ax, 1
loop %%loop
%%ret: ret 6

View File

@ -98,6 +98,9 @@ struct nlsInfoBlock ASM nlsInfo = {
***** MUX calling functions ****************************************
********************************************************************/
#ifdef __GNUC__
#define call_nls(a,b,c,d,e,f) call_nls(f,e,d,c,b,a)
#endif
extern long ASMPASCAL call_nls(UWORD, VOID FAR *, UWORD, UWORD, UWORD, UWORD);
/*== DS:SI _always_ points to global NLS info structure <-> no
* subfct can use these registers for anything different. ==ska*/