From 48398b072a5e9e756a777e02712114ecb9fa832a Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 17 Aug 2022 22:34:06 +0200 Subject: [PATCH] write() system calls work; start going through the libsys. --- plat/msdos386/boot.s | 34 ++++++--- plat/msdos386/descr | 1 - plat/msdos386/libsys/build.lua | 3 +- plat/msdos386/libsys/close.s | 4 +- plat/msdos386/libsys/getpid.s | 4 +- plat/msdos386/libsys/isatty.s | 14 ++-- plat/msdos386/libsys/rename.s | 1 + plat/msdos386/libsys/sys_exists.s | 1 + plat/msdos386/libsys/sys_getdate.s | 1 + plat/msdos386/libsys/sys_gettime.s | 1 + plat/msdos386/libsys/sys_isopen.s | 1 + plat/msdos386/libsys/sys_isreadyr.s | 1 + plat/msdos386/libsys/sys_rawcreat.s | 1 + plat/msdos386/libsys/sys_rawlseek.s | 1 + plat/msdos386/libsys/sys_rawopen.s | 1 + .../libsys/{sys_rawrw.s => sys_rawread.s} | 21 +++--- plat/msdos386/libsys/sys_rawwrite.s | 70 +++++++++++++++++++ plat/msdos386/libsys/sys_xret.s | 31 +++++--- plat/msdos386/stub.s | 30 ++++++-- 19 files changed, 172 insertions(+), 49 deletions(-) rename plat/msdos386/libsys/{sys_rawrw.s => sys_rawread.s} (56%) create mode 100644 plat/msdos386/libsys/sys_rawwrite.s diff --git a/plat/msdos386/boot.s b/plat/msdos386/boot.s index 618e17163..282dcb866 100644 --- a/plat/msdos386/boot.s +++ b/plat/msdos386/boot.s @@ -18,15 +18,24 @@ begtext: ! On entry, the stub has cs and ds pointing at the 32-bit ! segment, but ss is still pointing at the 16-bit segment. ! - ! si:di memory handle of linear block ! ax: pmode code segment of stub - ! dx: pointer to realloc routine - ! fs: data segment (just a clone of the code segment) + ! bx: pmode data segment of stub + ! cx: rmode segment of stub + ! dx: pointer to realloc routine (in stub)e + ! si: pointer to interrupt routine (in stub) + ! di: pointer to transfer buffer (in stub) ! Resize the segment to include the BSS. o16 cseg mov (realloc_ptr+4), ax cseg mov (realloc_ptr+0), edx + cseg o16 mov (pmode_cs), ax + cseg o16 mov (pmode_ds), bx + cseg o16 mov (rmode), cx + cseg o16 mov (interrupt_ptr+4), ax + cseg mov (interrupt_ptr+0), esi + cseg o16 mov (transfer_buffer_ptr), di + mov eax, endbss cseg callf (realloc_ptr) @@ -180,10 +189,19 @@ al_exit: movb ah, 0x4c int 0x21 - ! This must be in the code segment due to bootstrap issues. -realloc_ptr: - .data2 0 - .data4 0 + ! These must be in the code segment due to bootstrap issues. +realloc_ptr: .space 6 ! far +interrupt_ptr: .space 6 ! far +transfer_buffer_ptr: .space 2 ! near +rmode: .space 2 +pmode_cs: .space 2 +pmode_ds: .space 2 + +.define interrupt_ptr +.define rmode +.define pmode_cs +.define pmode_ds +.define transfer_buffer_ptr ! Define symbols at the beginning of our various segments, so that we can find ! them. (Except .text, which has already been done.) @@ -210,7 +228,7 @@ no_room_msg: .ascii 'No room$' .comm _psp, 256 .sect .bss - .space 512 + .space 32*1024 .stack: ! vim: ts=4 sw=4 et ft=asm diff --git a/plat/msdos386/descr b/plat/msdos386/descr index 718424e21..d7be3eb1e 100644 --- a/plat/msdos386/descr +++ b/plat/msdos386/descr @@ -39,7 +39,6 @@ name as program {EM}/lib/ack/{PLATFORM}/as args - -o > < prep cond - end name led from .o.a diff --git a/plat/msdos386/libsys/build.lua b/plat/msdos386/libsys/build.lua index 70c7eaa17..4d349eb0f 100644 --- a/plat/msdos386/libsys/build.lua +++ b/plat/msdos386/libsys/build.lua @@ -16,7 +16,8 @@ acklibrary { "./sys_rawcreat.s", "./sys_rawlseek.s", "./sys_rawopen.s", - "./sys_rawrw.s", + "./sys_rawread.s", + "./sys_rawwrite.s", "./sys_xret.s", "./unlink.s", "plat/msdos/libsys+srcs", diff --git a/plat/msdos386/libsys/close.s b/plat/msdos386/libsys/close.s index b8c2f8a15..5e52a638b 100644 --- a/plat/msdos386/libsys/close.s +++ b/plat/msdos386/libsys/close.s @@ -16,8 +16,8 @@ .define _close _close: - mov bx, sp - mov bx, 2(bx) + mov ebx, sp + mov ebx, 4(ebx) movb ah, 0x3E int 0x21 jmp .sys_zret diff --git a/plat/msdos386/libsys/getpid.s b/plat/msdos386/libsys/getpid.s index 5aa80638b..d2a250491 100644 --- a/plat/msdos386/libsys/getpid.s +++ b/plat/msdos386/libsys/getpid.s @@ -39,7 +39,7 @@ _getpid: jnc .eur_dos movb ah, 0x51 int 0x21 - xchg bx, ax + xchg ebx, eax .eur_dos: - xor dx, dx + xor edx, edx ret diff --git a/plat/msdos386/libsys/isatty.s b/plat/msdos386/libsys/isatty.s index bd2e195e6..7ed92fffd 100644 --- a/plat/msdos386/libsys/isatty.s +++ b/plat/msdos386/libsys/isatty.s @@ -16,22 +16,22 @@ .define _isatty _isatty: - mov bx, sp - mov bx, 2(bx) - mov ax, 0x4400 + mov ebx, sp + mov ebx, 4(ebx) + o16 mov ax, 0x4400 int 0x21 jc error testb dl, dl jz not_tty - mov ax, 1 + mov eax, 1 ret not_tty: mov (_errno), 25 ! ENOTTY not_tty_2: - xor ax, ax + xor eax, eax ret error: - push ax + push eax call __sys_seterrno - pop cx + pop ecx jmp not_tty_2 diff --git a/plat/msdos386/libsys/rename.s b/plat/msdos386/libsys/rename.s index edb14266b..1550b73db 100644 --- a/plat/msdos386/libsys/rename.s +++ b/plat/msdos386/libsys/rename.s @@ -16,6 +16,7 @@ .define _rename _rename: + int 3 mov bx, sp push di mov dx, 2(bx) diff --git a/plat/msdos386/libsys/sys_exists.s b/plat/msdos386/libsys/sys_exists.s index e282ef687..8786f4c2a 100644 --- a/plat/msdos386/libsys/sys_exists.s +++ b/plat/msdos386/libsys/sys_exists.s @@ -16,6 +16,7 @@ .define __sys_exists __sys_exists: + int 3 mov bx, sp mov dx, 2(bx) mov ax, 0x4300 diff --git a/plat/msdos386/libsys/sys_getdate.s b/plat/msdos386/libsys/sys_getdate.s index 41d69fc85..eeb118923 100644 --- a/plat/msdos386/libsys/sys_getdate.s +++ b/plat/msdos386/libsys/sys_getdate.s @@ -16,6 +16,7 @@ .define __sys_getdate __sys_getdate: + int 3 movb ah, 0x2a int 0x21 mov bx, sp diff --git a/plat/msdos386/libsys/sys_gettime.s b/plat/msdos386/libsys/sys_gettime.s index d062fad8d..d3ea65847 100644 --- a/plat/msdos386/libsys/sys_gettime.s +++ b/plat/msdos386/libsys/sys_gettime.s @@ -16,6 +16,7 @@ .define __sys_gettime __sys_gettime: + int 3 movb ah, 0x2c int 0x21 mov bx, sp diff --git a/plat/msdos386/libsys/sys_isopen.s b/plat/msdos386/libsys/sys_isopen.s index 5ce49ed45..5da95a44e 100644 --- a/plat/msdos386/libsys/sys_isopen.s +++ b/plat/msdos386/libsys/sys_isopen.s @@ -17,6 +17,7 @@ .define __sys_isopen __sys_isopen: + int 3 mov bx, sp mov bx, 2(bx) mov ax, 0x4400 diff --git a/plat/msdos386/libsys/sys_isreadyr.s b/plat/msdos386/libsys/sys_isreadyr.s index b5d0800ee..9a400859d 100644 --- a/plat/msdos386/libsys/sys_isreadyr.s +++ b/plat/msdos386/libsys/sys_isreadyr.s @@ -17,6 +17,7 @@ .define __sys_isreadyr __sys_isreadyr: + int 3 mov bx, sp mov ax, 0x4406 mov bx, 2(bx) diff --git a/plat/msdos386/libsys/sys_rawcreat.s b/plat/msdos386/libsys/sys_rawcreat.s index 67bc34e59..0d765a27d 100644 --- a/plat/msdos386/libsys/sys_rawcreat.s +++ b/plat/msdos386/libsys/sys_rawcreat.s @@ -16,6 +16,7 @@ .define __sys_rawcreat __sys_rawcreat: + int 3 movb ah, 0x3c mov bx, sp mov dx, 2(bx) diff --git a/plat/msdos386/libsys/sys_rawlseek.s b/plat/msdos386/libsys/sys_rawlseek.s index 992c4c655..06a7783a7 100644 --- a/plat/msdos386/libsys/sys_rawlseek.s +++ b/plat/msdos386/libsys/sys_rawlseek.s @@ -16,6 +16,7 @@ .define __sys_rawlseek __sys_rawlseek: + int 3 movb ah, 0x42 mov bx, sp mov dx, 4(bx) diff --git a/plat/msdos386/libsys/sys_rawopen.s b/plat/msdos386/libsys/sys_rawopen.s index 301e2fded..5fae1bba4 100644 --- a/plat/msdos386/libsys/sys_rawopen.s +++ b/plat/msdos386/libsys/sys_rawopen.s @@ -16,6 +16,7 @@ .define __sys_rawopen __sys_rawopen: + int 3 movb ah, 0x3d mov bx, sp mov dx, 2(bx) diff --git a/plat/msdos386/libsys/sys_rawrw.s b/plat/msdos386/libsys/sys_rawread.s similarity index 56% rename from plat/msdos386/libsys/sys_rawrw.s rename to plat/msdos386/libsys/sys_rawread.s index a306d6528..d7c14aa54 100644 --- a/plat/msdos386/libsys/sys_rawrw.s +++ b/plat/msdos386/libsys/sys_rawread.s @@ -12,7 +12,13 @@ .sect .text -! Read/write bytes to/to a file descriptor. These routines do not do any +.extern pmode_ds +.extern pmode_cs +.extern rmode +.extern transfer_buffer_ptr +.extern interrupt_ptr + +! Read bytes from a file descriptor. These routines do not do any ! translation between CRLF and LF line endings. ! ! Note that, for MS-DOS, a raw "write" request of zero bytes will truncate @@ -20,14 +26,5 @@ .define __sys_rawread __sys_rawread: - movb ah, 0x3f - .data1 0x3d ! eat up the next instruction -.define __sys_rawwrite -__sys_rawwrite: - movb ah, 0x40 - mov bx, sp - mov dx, 4(bx) - mov cx, 6(bx) - mov bx, 2(bx) - int 0x21 - jmp .sys_axret + int 3 + diff --git a/plat/msdos386/libsys/sys_rawwrite.s b/plat/msdos386/libsys/sys_rawwrite.s new file mode 100644 index 000000000..e13e5e52c --- /dev/null +++ b/plat/msdos386/libsys/sys_rawwrite.s @@ -0,0 +1,70 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +.extern pmode_ds +.extern pmode_cs +.extern rmode +.extern transfer_buffer_ptr +.extern interrupt_ptr + +! Write bytes to/to a file descriptor. These routines do not do any +! translation between CRLF and LF line endings. +! +! Note that, for MS-DOS, a raw "write" request of zero bytes will truncate +! (or extend) the file to the current file position. + +.define __sys_rawwrite +__sys_rawwrite: + enter 4, 0 +amount_transferred = -1*4 +file_handle = 2*4 +read_buffer = 3*4 +amount_to_write = 4*4 + + mov es, (pmode_ds) + mov amount_transferred(ebp), 0 + +mainloop: + mov ecx, 32*1024 + cmp amount_to_write(ebp), ecx + jge 2f + mov ecx, amount_to_write(ebp) + test ecx, ecx + jz exit +2: + ! Copy ecx bytes into the transfer buffer. + + push ecx + mov esi, read_buffer(ebp) + movzx edi, (transfer_buffer_ptr) + rep movsb + pop ecx + + movb ah, 0x40 + o16 mov dx, (transfer_buffer_ptr) + o16 mov bx, file_handle(ebp) + or ebx, 0x210000 + callf (interrupt_ptr) + movzx eax, ax + + add read_buffer(ebp), eax + add amount_transferred(ebp), eax + sub amount_to_write(ebp), eax + jmp mainloop + +exit: + mov eax, amount_to_write(ebp) + leave + ret + diff --git a/plat/msdos386/libsys/sys_xret.s b/plat/msdos386/libsys/sys_xret.s index 57f407ef4..20c2b454b 100644 --- a/plat/msdos386/libsys/sys_xret.s +++ b/plat/msdos386/libsys/sys_xret.s @@ -13,29 +13,38 @@ .sect .text ! .sys_zret: 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 a shortword zero. +! code in ax, and return an int -1. If the carry flag is clear, just +! return an int zero. ! ! .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. ! -! .sys_dxaxret: same as .sys_axret, but return a longword -1 or dx:ax as a -! return value. +! .sys_dxaxret: same as .sys_axret, but return -1 or dx:ax as a return value. .extern .sys_zret .extern .sys_axret .extern .sys_dxaxret .sys_zret: jc error - xor ax, ax + xor eax, eax no_error: ret + .sys_axret: -.sys_dxaxret: - jnc no_error -error: - push ax - call __sys_seterrno - pop cx + jc error + ret + +.sys_dxaxret: + jc error + shl edx, 16 + o16 mov dx, ax + mov eax, edx + ret + +error: + movzx eax, ax + push eax + call __sys_seterrno + pop ecx ret diff --git a/plat/msdos386/stub.s b/plat/msdos386/stub.s index 863d5d8f7..03887ec5d 100644 --- a/plat/msdos386/stub.s +++ b/plat/msdos386/stub.s @@ -210,15 +210,17 @@ exe_start: ! Jump to the new segment and enter 32-bit mode! - mov ax, (psegcs) - mov bx, (psegds) - mov cx, (rseg) + o32 movzx eax, (psegcs) + o32 movzx ebx, (psegds) + o32 movzx ecx, (rseg) o32 mov edx, realloc + o32 mov esi, interruptf + o32 mov edi, transfer_buffer push es pop ds push es push 0 - retf + retf ! 19b ! ALL CODE ABOVE THIS POINT DISCARDED ON ENTRY TO 32-BIT CODE ! (it's reused as the 16-bit stack) @@ -271,6 +273,7 @@ realloc: jc bad_dpmi popa + o32 mov eax, (pmemlen) cli ! atomically switch stacks back mov ss, (dpmi_ss) o32 mov esp, (dpmi_ebp) @@ -309,10 +312,15 @@ exit_with_error: ! Simulate DOS interrupt. int21: + o32 or ebx, 0x210000 + ! Simulate interrupt in the high half of ebx. +interrupt: mov (dpmi_eax), ax mov (dpmi_ebx), bx mov (dpmi_ecx), cx mov (dpmi_edx), dx + mov (dpmi_esi), si + mov (dpmi_edi), di mov ax, (rseg) mov (dpmi_ds), ax push es @@ -324,16 +332,28 @@ int21: pop es mov di, dpmi_edi mov ax, 0x300 - mov bx, 0x21 + o32 shr ebx, 16 int 0x31 ! simulate DOS interrupt pop ds pop es + pushf mov ax, (dpmi_eax) mov bx, (dpmi_ebx) mov cx, (dpmi_ecx) mov dx, (dpmi_edx) + mov si, (dpmi_esi) + mov di, (dpmi_edi) + popf ret +! Far call wrapper around interrupt. +interruptf: + push ds + cseg mov ds, (psegds) + call interrupt + pop ds + o32 retf + bad_dpmi_msg: .asciz "DPMI error during setup" no_file_msg: