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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -51,6 +51,15 @@
; destroys: ; destroys:
; flags ; 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 ? test cx, cx ; divisor > 2^32-1 ?
jnz %%big_divisor ; yes, divisor > 32^32-1 jnz %%big_divisor ; yes, divisor > 32^32-1
@ -113,12 +122,10 @@
%macro LSHLU 0 %macro LSHLU 0
pop bx pop bx
pop ax popargs {dx,ax},cx
pop dx
pop cx
push bx push bx
jcxz %%ret jcxz %%ret
%%loop: shl ax, 1 %%loop: shl ax, 1
rcl dx, 1 rcl dx, 1
loop %%loop loop %%loop
%%ret: ret 6 %%ret: ret 6
@ -126,12 +133,10 @@
%macro LSHRU 0 %macro LSHRU 0
pop bx pop bx
pop ax popargs {dx,ax},cx
pop dx
pop cx
push bx push bx
jcxz %%ret jcxz %%ret
%%loop: shr dx, 1 %%loop: shr dx, 1
rcr ax, 1 rcr ax, 1
loop %%loop loop %%loop
%%ret: ret 6 %%ret: ret 6

View File

@ -98,6 +98,9 @@ struct nlsInfoBlock ASM nlsInfo = {
***** MUX calling functions **************************************** ***** 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); extern long ASMPASCAL call_nls(UWORD, VOID FAR *, UWORD, UWORD, UWORD, UWORD);
/*== DS:SI _always_ points to global NLS info structure <-> no /*== DS:SI _always_ points to global NLS info structure <-> no
* subfct can use these registers for anything different. ==ska*/ * subfct can use these registers for anything different. ==ska*/