- refactor code for transfer buffer reads/writes, real mode
int 0x21 calls, and assembler segment declarations
- define transfer buffer size in one place
- beef up error checking for transfer buffer operations
(prevent buffer overflows)
- also optimize such operations to transfer dword by dword
where feasible
- ensure es = ds = ss upon exit of each C runtime function
- clear upper 16 bits of ebx before setting them to 0x0021,
when invoking interrupt_ptr to simulate a RM int 0x21
- make _sys_exists use the transfer buffer (which it needs)
- make _sys_rawread properly handle an end-of-file read
(zero bytes read)
- make argument to _sys_seterrno short --- after a failed
int 0x21 call, only the lower 16 bits of eax hold the MS-DOs
error code
- _sys_rawlseek accepts only 3 longword arguments, not 4
(the offset is only 1 longword)
- other minor fixes
- correctly calculate size of BSS area to clear
- make realloc routine set both ds & es to point to new
data segment
- correctly initialize real mode flags when simulating real
mode interrupt via DPMI
- other minor fixes
- do not try to store data through code segment selectors
- set each segment limit to segment size - 1, not segment size
- get PSP segment while still in real/V86 mode (DPMI host
might choose to return PM selector for int 0x21, ah = 0x62)
- other minor fixes
The new .seek assembler pseudo-op advances the location
counter to a fixed offset within a section --- or to a fixed
address, if the section is a .base'd section. It works
somewhat like the GNU assembler's .org pseudo-op, though
with a hopefully less confusing name.
This pseudo-op lets us avoid having to manually compute the
needed boot sector padding in the pc86 start-up code
plat/pc86/boot.s .
bug caused by this instruction:
fmove.l fp0,d0
problem was caused by a conflict between the fpu emulator (softfloat) and the compiler.
the emulator implemented this as a purely arithmetic move & conversion,
but the compiler assumed that the result could be interpreted as a logical (ie unsigned) conversion.
rightly or wrongly.
for example, if fp0 contained the value 2576980377.0 which is unsigned integer -1717987328
the emulator would treat this as an integer overflow and move 0x7fffffff (INT_MAX) into d0.
The complier on the other hand would assume that d0 contained 2576980377 (the unsigned value).
I don't know which is correct, but this is my fix for the time being.