From 5329c98b81d7760e7934695de3e32abd8d2e8e8a Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 18 Aug 2022 21:21:33 +0200 Subject: [PATCH] Simplify and fix reading and writing so they seem to work. --- plat/msdos/libsys/read.c | 56 +++++++++++++------------ plat/msdos/libsys/write.c | 59 ++++++++++++++++---------- plat/msdos386/boot.s | 2 +- plat/msdos386/libsys/sys_rawread.s | 35 ++++++---------- plat/msdos386/libsys/sys_rawwrite.s | 65 ++++++++++++----------------- plat/msdos386/stub.s | 16 ++++--- 6 files changed, 113 insertions(+), 120 deletions(-) diff --git a/plat/msdos/libsys/read.c b/plat/msdos/libsys/read.c index 5075958bd..bed9fcd14 100644 --- a/plat/msdos/libsys/read.c +++ b/plat/msdos/libsys/read.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -16,9 +17,7 @@ ssize_t read(int fd, void* buffer, size_t count) ssize_t r, tot; size_t left; int eof = 0; - - if (!count || _sys_getmode(fd) == O_BINARY) - return _sys_rawread(fd, buffer, count); + bool text = _sys_getmode(fd) == O_TEXT; if (_sys_iseof(fd)) return 0; @@ -47,33 +46,36 @@ ssize_t read(int fd, void* buffer, size_t count) if (r <= 0) return tot ? tot : r; - q = memchr(p, 0x1a, (size_t)r); - if (q) + if (text) { - _sys_rawlseek(fd, (off_t)(q - p) - r, SEEK_CUR); - r = q - p; - eof = 1; - _sys_seteof(fd, 1); - } - - q = memchr(p, '\r', (size_t)r); - if (!q) - return tot + r; - - tot += q - p; - left = r - (q + 1 - p); - p = q; - ++q; - - while (left) - { - char c = *q++; - if (c != '\r') + q = memchr(p, 0x1a, (size_t)r); + if (q) { - *p++ = c; - ++tot; + _sys_rawlseek(fd, (off_t)(q - p) - r, SEEK_CUR); + r = q - p; + eof = 1; + _sys_seteof(fd, 1); + } + + q = memchr(p, '\r', (size_t)r); + if (!q) + return tot + r; + + tot += q - p; + left = r - (q + 1 - p); + p = q; + ++q; + + while (left) + { + char c = *q++; + if (c != '\r') + { + *p++ = c; + ++tot; + } + --left; } - --left; } } while (tot < count && !eof && _sys_isreadyr(fd)); diff --git a/plat/msdos/libsys/write.c b/plat/msdos/libsys/write.c index fc744b256..cfc764246 100644 --- a/plat/msdos/libsys/write.c +++ b/plat/msdos/libsys/write.c @@ -20,42 +20,55 @@ ssize_t write(int fd, void* buffer, size_t count) if (!count) return 0; - if (_sys_getmode(fd) == O_BINARY) - return _sys_rawwrite(fd, buffer, count); - - /* If the file descriptor is an O_TEXT fd, translate LFs to CRLFs. */ p = buffer; left = count; tot = 0; - while (left) - { - q = memchr(p, '\n', left); - if (!q) - return _sys_rawwrite(fd, p, left); - n = q - p; - if (n) + if (_sys_getmode(fd) == O_BINARY) + { + while (left) { - r = _sys_rawwrite(fd, p, n); + r = _sys_rawwrite(fd, p, left); if (r <= 0) return tot ? tot : r; tot += r; p += r; left -= r; - if (r != n) - break; } - - r = _sys_rawwrite(fd, crlf, sizeof crlf); - if (r != 2) + } + else + { + /* If the file descriptor is an O_TEXT fd, translate LFs to CRLFs. */ + while (left) { - if (r > 0) - r = 0; - return tot ? tot : r; + q = memchr(p, '\n', left); + if (!q) + return _sys_rawwrite(fd, p, left); + + n = q - p; + if (n) + { + r = _sys_rawwrite(fd, p, n); + if (r <= 0) + return tot ? tot : r; + tot += r; + p += r; + left -= r; + if (r != n) + break; + } + + r = _sys_rawwrite(fd, crlf, sizeof crlf); + if (r != 2) + { + if (r > 0) + r = 0; + return tot ? tot : r; + } + ++tot; + ++p; + --left; } - ++tot; - ++p; - --left; } return tot; } diff --git a/plat/msdos386/boot.s b/plat/msdos386/boot.s index b30b6594c..6e1b02add 100644 --- a/plat/msdos386/boot.s +++ b/plat/msdos386/boot.s @@ -166,7 +166,7 @@ empty_environment: ! argc, argv, and envp are now at the stack top. Now go. call __m_a_i_n - add sp, 6 + add sp, 3*4 push ax call _exit diff --git a/plat/msdos386/libsys/sys_rawread.s b/plat/msdos386/libsys/sys_rawread.s index c8ba4bea0..c54410347 100644 --- a/plat/msdos386/libsys/sys_rawread.s +++ b/plat/msdos386/libsys/sys_rawread.s @@ -26,19 +26,12 @@ .define __sys_rawread __sys_rawread: - enter 4, 0 -amount_transferred = -1*4 + enter 0, 0 file_handle = 2*4 write_buffer = 3*4 amount_to_read = 4*4 - mov amount_transferred(ebp), 0 - -mainloop: mov eax, amount_to_read(ebp) - test eax, eax - jz exit - mov ecx, 32*1024 cmp eax, ecx jge 2f @@ -53,33 +46,31 @@ mainloop: mov ecx, 0x80 or ebx, 0x210000 callf (interrupt_ptr) - jc exit - test eax, eax - jz exit + jnc success + + ! Process errors. + + push eax + call __sys_seterrno + leave + ret +success: ! Copy eax bytes out of the transfer buffer. - mov ecx, eax push eax + mov ecx, eax movzx esi, (transfer_buffer_ptr) mov edi, write_buffer(ebp) mov es, (pmode_ds) cld 1: - eseg lods + eseg lodsb movb (edi), al - add edi, 4 + inc edi loop 1b pop eax - add write_buffer(ebp), eax - add amount_transferred(ebp), eax - sub amount_to_read(ebp), eax - jmp mainloop - -exit: - mov eax, amount_transferred(ebp) leave ret - diff --git a/plat/msdos386/libsys/sys_rawwrite.s b/plat/msdos386/libsys/sys_rawwrite.s index bef6481b2..5451670fe 100644 --- a/plat/msdos386/libsys/sys_rawwrite.s +++ b/plat/msdos386/libsys/sys_rawwrite.s @@ -26,53 +26,42 @@ .define __sys_rawwrite __sys_rawwrite: - enter 4, 0 -amount_transferred = -1*4 + enter 0, 0 file_handle = 2*4 read_buffer = 3*4 amount_to_write = 4*4 - mov amount_transferred(ebp), 0 - -mainloop: - mov eax, amount_to_write(ebp) - test eax, eax - jz exit - - mov ecx, 32*1024 - cmp eax, ecx - jge 2f - mov ecx, eax + mov eax, amount_to_write(ebp) + mov ecx, 32*1024 ! size of transfer buffer + cmp eax, ecx + jge 2f + mov ecx, eax 2: - ! Copy ecx bytes into the transfer buffer. + ! 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 + push ecx + mov esi, read_buffer(ebp) + movzx edi, (transfer_buffer_ptr) + mov es, (pmode_ds) + cld + rep movsb + pop ecx - ! Write from the transfer buffer to DOS. + ! Write from the transfer buffer to DOS. - movb ah, 0x40 - o16 mov dx, (transfer_buffer_ptr) - o16 mov bx, file_handle(ebp) - or ebx, 0x210000 - callf (interrupt_ptr) - jc exit - - ! Update counters and go again. - - add read_buffer(ebp), eax - add amount_transferred(ebp), eax - sub amount_to_write(ebp), eax - jmp mainloop + movb ah, 0x40 + o16 mov dx, (transfer_buffer_ptr) + o16 mov bx, file_handle(ebp) + or ebx, 0x210000 + callf (interrupt_ptr) + jnc exit + push eax + call __sys_seterrno exit: - mov eax, amount_transferred(ebp) - leave - ret + leave + ret + +! vim: sw=4 ts=4 et diff --git a/plat/msdos386/stub.s b/plat/msdos386/stub.s index 725d3431e..35b9e8e40 100644 --- a/plat/msdos386/stub.s +++ b/plat/msdos386/stub.s @@ -116,7 +116,7 @@ exe_start: callf (pmode_switch) jc bad_dpmi - ! We're now in protected mode. (ae) + ! We're now in protected mode. mov (psegcs), cs mov (psegds), ds @@ -222,10 +222,6 @@ exe_start: push 0 retf ! 19b - ! ALL CODE ABOVE THIS POINT DISCARDED ON ENTRY TO 32-BIT CODE - ! (it's reused as the 16-bit stack) -stack16: - ! Helper routine which reallocates the linear block that the 32-bit code ! is running from. This can't happen from inside the 32-bit code itself ! because it might move. @@ -238,7 +234,7 @@ realloc: o32 mov (dpmi_ebp), esp ! yes, saving esp into the ebp field mov (dpmi_ss), ss mov ss, (psegds) - mov sp, stack16 + mov sp, dosstack sti pusha @@ -323,10 +319,10 @@ interrupt: mov (dpmi_edi), di mov ax, (rseg) mov (dpmi_ds), ax + mov (dpmi_ss), ax push es push ds - xor ax, ax - mov (dpmi_ss), ax ! zero stack: DPMI host allocates one. + mov ax, dosstack ! auto stack is too small mov (dpmi_sp), ax push ds pop es @@ -401,8 +397,10 @@ pmemhandle: .space 4 ! protected mode linear memory handle pmemlen: .space 4 ! protected mode linear memory length fh: .space 2 - .space 128 + .space 512 stack: + .space 512 +dosstack: TRANSFER_BUFFER_SIZE = 32*1024 transfer_buffer: