diff --git a/plat/msdos386/build-pkg.lua b/plat/msdos386/build-pkg.lua index 4b92b5619..8b3195afb 100644 --- a/plat/msdos386/build-pkg.lua +++ b/plat/msdos386/build-pkg.lua @@ -9,6 +9,7 @@ ackfile { ackfile { name = "stub", srcs = { "./stub.s" }, + deps = { "plat/msdos386/libsys+headers" }, vars = { plat = "msdos386" } } diff --git a/plat/msdos386/libsys/_hol0.s b/plat/msdos386/libsys/_hol0.s index f01566fe8..ad666d56f 100644 --- a/plat/msdos386/libsys/_hol0.s +++ b/plat/msdos386/libsys/_hol0.s @@ -3,12 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss +#include "libsysasm.h" .sect .bss diff --git a/plat/msdos386/libsys/brk.s b/plat/msdos386/libsys/brk.s index 3032bc929..ed2dcc6a1 100644 --- a/plat/msdos386/libsys/brk.s +++ b/plat/msdos386/libsys/brk.s @@ -1,11 +1,9 @@ -! Declare segments (the order is important). +# +! $Source$ +! $State$ +! $Revision$ -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" .define _brk _brk: diff --git a/plat/msdos386/libsys/build.lua b/plat/msdos386/libsys/build.lua index 71ac521b8..e972365e6 100644 --- a/plat/msdos386/libsys/build.lua +++ b/plat/msdos386/libsys/build.lua @@ -1,6 +1,13 @@ +bundle { + name = "headers", + srcs = { + "./libsysasm.h" + } +} + acklibrary { - name = "lib", - srcs = { + name = "lib", + srcs = { "./_hol0.s", "./brk.s", "./close.s", @@ -9,6 +16,9 @@ acklibrary { "./isatty.s", "./rename.s", "./sbrk.c", + "./sys_cpyin.s", + "./sys_cpyout.s", + "./sys_dpmidos.s", "./sys_exists.s", "./sys_getdate.s", "./sys_gettime.s", @@ -19,17 +29,16 @@ acklibrary { "./sys_rawopen.s", "./sys_rawread.s", "./sys_rawwrite.s", + "./sys_scpyout.s", "./sys_xret.s", "./unlink.s", "plat/msdos/libsys+srcs", - }, - deps = { - "lang/cem/libcc.ansi/headers+headers", - "plat/msdos386/include+headers", - "plat/msdos/libsys+headers", }, - vars = { - plat = "msdos386" - } + deps = { + "plat/msdos/libsys+headers", + "+headers" + }, + vars = { + plat = "msdos386" + } } - diff --git a/plat/msdos386/libsys/close.s b/plat/msdos386/libsys/close.s index 412307b62..936509894 100644 --- a/plat/msdos386/libsys/close.s +++ b/plat/msdos386/libsys/close.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Close a file. diff --git a/plat/msdos386/libsys/errno.s b/plat/msdos386/libsys/errno.s index 9858d2640..4126b8349 100644 --- a/plat/msdos386/libsys/errno.s +++ b/plat/msdos386/libsys/errno.s @@ -3,12 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss +#include "libsysasm.h" #define D(e) .define e; e diff --git a/plat/msdos386/libsys/getpid.s b/plat/msdos386/libsys/getpid.s index fd8706379..077674c50 100644 --- a/plat/msdos386/libsys/getpid.s +++ b/plat/msdos386/libsys/getpid.s @@ -15,14 +15,7 @@ ! the new terms are clearly indicated on the first page of each file where ! they apply. -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Get the current process identifier. For MS-DOS, use the Program Segment ! Prefix (PSP) segment as the PID, unless the system supports an actual diff --git a/plat/msdos386/libsys/isatty.s b/plat/msdos386/libsys/isatty.s index 794274bfa..e4d02617a 100644 --- a/plat/msdos386/libsys/isatty.s +++ b/plat/msdos386/libsys/isatty.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Say whether a given file descriptor number refers to a terminal. diff --git a/plat/msdos386/libsys/libsysasm.h b/plat/msdos386/libsys/libsysasm.h new file mode 100644 index 000000000..3c758f099 --- /dev/null +++ b/plat/msdos386/libsys/libsysasm.h @@ -0,0 +1,24 @@ +/* + * © 2013 David Given + * © 2022 TK Chia + * This file is redistributable under the terms of the 3-clause BSD license. + * See the file 'Copying' in the root of the distribution for the full text. + */ + +#ifndef LIBSYSASM_H +#define LIBSYSASM_H + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! Size of transfer buffer, for 32-bit DPMI mode. + +TRANSFER_BUFFER_SIZE = 32 * 1024 + +#endif diff --git a/plat/msdos386/libsys/rename.s b/plat/msdos386/libsys/rename.s index cfde5305e..ab181d0c7 100644 --- a/plat/msdos386/libsys/rename.s +++ b/plat/msdos386/libsys/rename.s @@ -3,54 +3,40 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Rename a file. .define _rename _rename: - mov ebx, esp - push esi push edi - ! Source filename. - - mov esi, 4(ebx) - movzx edi, (transfer_buffer_ptr) - mov es, (pmode_ds) - cld -1: - lodsb - stosb - testb al, al - jnz 1b - ! Destination filename. - mov eax, edi - mov esi, 8(ebx) -1: - lodsb - stosb - testb al, al - jnz 1b + mov eax, 4+8(esp) +#define DEST_NAME_OFFSET (TRANSFER_BUFFER_SIZE / 2) + mov edx, DEST_NAME_OFFSET + mov ecx, edx + call .sys_sncpyout + jc 9f + xchg edi, eax + ! Source filename. + + mov eax, 4+4(esp) + xor edx, edx + call .sys_sncpyout + jc 9f + xchg edx, eax + ! Make the DOS call. - o16 mov dx, (transfer_buffer_ptr) - o16 mov di, ax movb ah, 0x56 - mov ebx, 0x210000 - callf (interrupt_ptr) + call .sys_dpmidos + pop edi - pop esi - push ss - pop es jmp .sys_zret + +9: + pop edi + jmp .sys_toolongret diff --git a/plat/msdos386/libsys/sys_cpyin.s b/plat/msdos386/libsys/sys_cpyin.s new file mode 100644 index 000000000..873c75536 --- /dev/null +++ b/plat/msdos386/libsys/sys_cpyin.s @@ -0,0 +1,32 @@ +# +! $Source$ +! $State$ +! $Revision$ + +#include "libsysasm.h" + +! .sys_cpyin: copy ecx bytes from the transfer buffer to es:eax (= ds:eax). +! Preserve all registers, except the flags. + +.extern .sys_cpyin +.sys_cpyin: + push eax + push ecx + push esi + push edi + movzx esi, (transfer_buffer_ptr) + xchg edi, eax + mov ds, (pmode_ds) + mov eax, ecx + shr ecx, 2 + rep movs + andb al, 3 + movb cl, al + rep movsb + mov eax, ss + mov ds, eax + pop edi + pop esi + pop ecx + pop eax + ret diff --git a/plat/msdos386/libsys/sys_cpyout.s b/plat/msdos386/libsys/sys_cpyout.s new file mode 100644 index 000000000..b905904a3 --- /dev/null +++ b/plat/msdos386/libsys/sys_cpyout.s @@ -0,0 +1,34 @@ +# +! $Source$ +! $State$ +! $Revision$ + +#include "libsysasm.h" + +! .sys_cpyout: copy ecx bytes starting from ds:eax to the transfer +! buffer. Return eax := offset of transfer buffer in the real mode data +! segment. Preserve all other registers, except the flags. + +.extern .sys_cpyout +.sys_cpyout: + push ecx + push edx + push esi + push edi + xchg esi, eax + movzx edi, (transfer_buffer_ptr) + mov eax, edi + mov es, (pmode_ds) + mov edx, ecx + shr ecx, 2 + rep movs + movb cl, dl + andb cl, 3 + rep movsb + mov ecx, ss + mov es, ecx + pop edi + pop esi + pop edx + pop ecx + ret diff --git a/plat/msdos386/libsys/sys_dpmidos.s b/plat/msdos386/libsys/sys_dpmidos.s new file mode 100644 index 000000000..4900b1980 --- /dev/null +++ b/plat/msdos386/libsys/sys_dpmidos.s @@ -0,0 +1,16 @@ +# +! $Source$ +! $State$ +! $Revision$ + +#include "libsysasm.h" + +! .sys_dpmidos: simulate a call to real-mode int 0x21 with the current +! 16-bit register values. + +.extern .sys_dpmidos +.sys_dpmidos: + movzx ebx, bx + or ebx, 0x210000 + callf (interrupt_ptr) + ret diff --git a/plat/msdos386/libsys/sys_exists.s b/plat/msdos386/libsys/sys_exists.s index 8dc1dc18c..77bec119d 100644 --- a/plat/msdos386/libsys/sys_exists.s +++ b/plat/msdos386/libsys/sys_exists.s @@ -3,35 +3,19 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Say whether a file exists with the given name. .define __sys_exists __sys_exists: - push esi - mov esi, 4+4(esp) - movzx edi, (transfer_buffer_ptr) - mov edx, edi - mov es, (pmode_ds) - cld -1: - lodsb - stosb - testb al, al - jnz 1b + mov eax, 4(esp) + call .sys_scpyout + jc 9f + xchg edx, eax mov eax, 0x4300 - mov ebx, 0x210000 - callf (interrupt_ptr) - push ss - pop es + call .sys_dpmidos +9: sbb eax, eax inc eax ret diff --git a/plat/msdos386/libsys/sys_getdate.s b/plat/msdos386/libsys/sys_getdate.s index 981253b93..d220dd418 100644 --- a/plat/msdos386/libsys/sys_getdate.s +++ b/plat/msdos386/libsys/sys_getdate.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Get the current system date from MS-DOS. diff --git a/plat/msdos386/libsys/sys_gettime.s b/plat/msdos386/libsys/sys_gettime.s index 1d43d5f46..ce1614c5a 100644 --- a/plat/msdos386/libsys/sys_gettime.s +++ b/plat/msdos386/libsys/sys_gettime.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Get the current system time from MS-DOS. diff --git a/plat/msdos386/libsys/sys_isopen.s b/plat/msdos386/libsys/sys_isopen.s index 5f990f1c1..f0493587f 100644 --- a/plat/msdos386/libsys/sys_isopen.s +++ b/plat/msdos386/libsys/sys_isopen.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Say whether a given file descriptor number refers to a valid open file ! descriptor. diff --git a/plat/msdos386/libsys/sys_isreadyr.s b/plat/msdos386/libsys/sys_isreadyr.s index 9a646adc8..8beda6366 100644 --- a/plat/msdos386/libsys/sys_isreadyr.s +++ b/plat/msdos386/libsys/sys_isreadyr.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Say whether a file descriptor is ready for input, i.e. reading from the ! fd will immediately return something. diff --git a/plat/msdos386/libsys/sys_rawcreat.s b/plat/msdos386/libsys/sys_rawcreat.s index ce48d9d7c..f2db1b35c 100644 --- a/plat/msdos386/libsys/sys_rawcreat.s +++ b/plat/msdos386/libsys/sys_rawcreat.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Create or truncate a file. @@ -18,30 +11,18 @@ __sys_rawcreat: ! Copy filename to transfer buffer. - mov ebx, esp - push esi - push edi - mov esi, 4(ebx) - movzx edi, (transfer_buffer_ptr) - mov es, (pmode_ds) - cld -1: - lodsb - stosb - testb al, al - jnz 1b + mov eax, 4(esp) + call .sys_scpyout + jc 9f ! Make the DOS call. + xchg edx, eax movb ah, 0x3c - movzx edx, (transfer_buffer_ptr) - movb al, 8(ebx) - mov ebx, 0x210000 - callf (interrupt_ptr) + movb al, 8(esp) + call .sys_dpmidos - pop edi - pop esi - push ss - pop es jmp .sys_axret +9: + jmp .sys_toolongret diff --git a/plat/msdos386/libsys/sys_rawlseek.s b/plat/msdos386/libsys/sys_rawlseek.s index 8ff4bc1db..71e17de3d 100644 --- a/plat/msdos386/libsys/sys_rawlseek.s +++ b/plat/msdos386/libsys/sys_rawlseek.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Move the current file position for a file descriptor. diff --git a/plat/msdos386/libsys/sys_rawopen.s b/plat/msdos386/libsys/sys_rawopen.s index 3c8f2bf17..e8130d25b 100644 --- a/plat/msdos386/libsys/sys_rawopen.s +++ b/plat/msdos386/libsys/sys_rawopen.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Open an existing file. @@ -18,30 +11,14 @@ __sys_rawopen: ! Copy filename to transfer buffer. - mov ebx, esp - push esi - push edi - - mov esi, 4(ebx) - movzx edi, (transfer_buffer_ptr) - mov es, (pmode_ds) - cld -1: - lodsb - stosb - testb al, al - jnz 1b + mov eax, 4(esp) + call .sys_scpyout ! Make the DOS call. + xchg edx, eax movb ah, 0x3d - o16 mov dx, (transfer_buffer_ptr) - movb al, 8(ebx) - mov ebx, 0x210000 - callf (interrupt_ptr) + movb al, 8(esp) + call .sys_dpmidos - pop edi - pop esi - push ss - pop es jmp .sys_axret diff --git a/plat/msdos386/libsys/sys_rawread.s b/plat/msdos386/libsys/sys_rawread.s index ef71bf915..0c17307ff 100644 --- a/plat/msdos386/libsys/sys_rawread.s +++ b/plat/msdos386/libsys/sys_rawread.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Read bytes from a file descriptor. These routines do not do any ! translation between CRLF and LF line endings. @@ -20,15 +13,12 @@ .define __sys_rawread __sys_rawread: - enter 0, 0 - push esi - push edi -file_handle = 2*4 -write_buffer = 3*4 -amount_to_read = 4*4 +file_handle = 1*4 +write_buffer = 2*4 +amount_to_read = 3*4 - mov eax, amount_to_read(ebp) - mov ecx, 32*1024 + mov eax, amount_to_read(esp) + mov ecx, TRANSFER_BUFFER_SIZE cmp eax, ecx jge 2f mov ecx, eax @@ -38,41 +28,23 @@ amount_to_read = 4*4 movb ah, 0x3f o16 mov dx, (transfer_buffer_ptr) - movzx esi, dx - mov ebx, 0x210000 - o16 mov bx, file_handle(ebp) - callf (interrupt_ptr) - jnc success + o16 mov bx, file_handle(esp) + call .sys_dpmidos + jc 3f + ! Copy eax bytes out of the transfer buffer. + + movzx ecx, ax + mov eax, write_buffer(esp) + call .sys_cpyin + + xchg eax, ecx + ret + +3: ! Process errors. push eax call __sys_seterrno pop ecx - jmp exit -success: - - ! Copy eax bytes out of the transfer buffer. - - movzx eax, ax - mov ecx, eax - jcxz exit - push eax - mov edi, write_buffer(ebp) - mov es, (pmode_ds) - cld -1: - eseg lodsb - movb (edi), al - inc edi - loop 1b - pop eax - -exit: - pop edi - pop esi - push ss - pop es - leave ret - diff --git a/plat/msdos386/libsys/sys_rawwrite.s b/plat/msdos386/libsys/sys_rawwrite.s index 56976b53b..28219f14c 100644 --- a/plat/msdos386/libsys/sys_rawwrite.s +++ b/plat/msdos386/libsys/sys_rawwrite.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Write bytes to/to a file descriptor. These routines do not do any ! translation between CRLF and LF line endings. @@ -20,15 +13,12 @@ .define __sys_rawwrite __sys_rawwrite: - enter 0, 0 - push esi - push edi -file_handle = 2*4 -read_buffer = 3*4 -amount_to_write = 4*4 +file_handle = 1*4 +read_buffer = 2*4 +amount_to_write = 3*4 - mov eax, amount_to_write(ebp) - mov ecx, 32*1024 ! size of transfer buffer + mov eax, amount_to_write(esp) + mov ecx, TRANSFER_BUFFER_SIZE cmp eax, ecx jge 2f mov ecx, eax @@ -36,32 +26,22 @@ amount_to_write = 4*4 ! Copy ecx bytes into the transfer buffer. - push ecx - mov esi, read_buffer(ebp) - movzx edi, (transfer_buffer_ptr) - mov es, (pmode_ds) - cld - rep movsb - pop ecx + mov eax, read_buffer(esp) + call .sys_cpyout ! Write from the transfer buffer to DOS. + xchg edx, eax movb ah, 0x40 - o16 mov dx, (transfer_buffer_ptr) - mov ebx, 0x210000 - o16 mov bx, file_handle(ebp) - callf (interrupt_ptr) + o16 mov bx, file_handle(esp) + call .sys_dpmidos + movzx eax, ax jnc exit push eax call __sys_seterrno pop ecx exit: - pop edi - pop esi - push ss - pop es - leave ret ! vim: sw=4 ts=4 et diff --git a/plat/msdos386/libsys/sys_scpyout.s b/plat/msdos386/libsys/sys_scpyout.s new file mode 100644 index 000000000..9491e3c20 --- /dev/null +++ b/plat/msdos386/libsys/sys_scpyout.s @@ -0,0 +1,58 @@ +# +! $Source$ +! $State$ +! $Revision$ + +#include "libsysasm.h" + +! .sys_scpyout: copy the ASCIIZ string starting from ds:eax to the +! transfer buffer. The resulting ASCIIZ string, including the final null, +! should fit into the entire transfer buffer. Return eax := offset of +! transfer buffer in real mode data segment. Return CF = 1 if and only if +! the ASCIIZ string is too long to fit. Preserve all other registers, +! except the flags. +! +! .sys_sncpyout: copy the ASCIIZ string starting from ds:eax to offset +! edx into the transfer buffer. The resulting ASCIIZ string should occupy +! at most ecx bytes, including the final null. Return eax : offset of +! string in real mode data segment. Return CF = 1 if and only if the ASCIIZ +! string is too long to fit. Preserve all other registers, except the +! flags. + +.extern .sys_scpyout +.extern .sys_sncpyout +.sys_scpyout: + push ecx + push edx + mov ecx, TRANSFER_BUFFER_SIZE + xor edx, edx + jmp .cont +.sys_sncpyout: + push ecx + push edx +.cont: + push esi + push edi + mov esi, eax + movzx edi, (transfer_buffer_ptr) + add edi, edx + mov edx, edi + mov es, (pmode_ds) + jcxz .error +.loop: + lodsb + stosb + testb al, al + loopnz .loop + jz .ok +.error: + stc +.ok: + xchg edx, eax + mov edx, ss + mov es, edx + pop edi + pop esi + pop edx + pop ecx + ret diff --git a/plat/msdos386/libsys/sys_xret.s b/plat/msdos386/libsys/sys_xret.s index e9b9017c9..3b376051d 100644 --- a/plat/msdos386/libsys/sys_xret.s +++ b/plat/msdos386/libsys/sys_xret.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! .sys_zret: if the carry flag is set, then set `errno' from the DOS error ! code in ax, and return an int -1. If the carry flag is clear, just @@ -18,14 +11,18 @@ ! ! .sys_axret: if the carry flag is set, then set `errno' from the DOS error ! code in ax, and return a shortword -1. If the carry flag is clear, just -! return ax as a return value. +! return eax := ax as a return value. ! ! .sys_dxaxret: same as .sys_axret, but return -1 or eax := dx:ax as a ! return value. +! +! .sys_toolongret: a file name is too long: set `errno' to E2BIG, and return +! -1. .extern .sys_zret .extern .sys_axret .extern .sys_dxaxret +.extern .sys_toolongret .sys_zret: jc error xor eax, eax @@ -34,6 +31,7 @@ no_error: .sys_axret: jc error + movzx eax, ax ret .sys_dxaxret: @@ -43,6 +41,11 @@ no_error: mov eax, edx ret +.sys_toolongret: + mov (_errno), 7 ! E2BIG + or eax, -1 + ret + error: movzx eax, ax push eax diff --git a/plat/msdos386/libsys/unlink.s b/plat/msdos386/libsys/unlink.s index d2289e3c4..0695f511d 100644 --- a/plat/msdos386/libsys/unlink.s +++ b/plat/msdos386/libsys/unlink.s @@ -3,14 +3,7 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -.sect .text +#include "libsysasm.h" ! Remove a file. @@ -18,29 +11,13 @@ _unlink: ! Copy filename to transfer buffer. - mov ebx, esp - push esi - push edi - - mov esi, 4(ebx) - movzx edi, (transfer_buffer_ptr) - mov es, (pmode_ds) - cld -1: - lodsb - stosb - testb al, al - jnz 1b + mov eax, 4(esp) + call .sys_scpyout ! Make the DOS call. - mov dx, (transfer_buffer_ptr) + xchg edx, eax movb ah, 0x41 - or ebx, 0x210000 - callf (interrupt_ptr) + call .sys_dpmidos - pop edi - pop esi - push ss - pop es jmp .sys_zret