| 1 | ;
|
|---|
| 2 | ; SYSCALL.ASM -- System calls (without BIOS and DOS calls)
|
|---|
| 3 | ;
|
|---|
| 4 | ; Copyright (c) 1991-1998 by Eberhard Mattes
|
|---|
| 5 | ;
|
|---|
| 6 | ; This file is part of emx.
|
|---|
| 7 | ;
|
|---|
| 8 | ; emx is free software; you can redistribute it and/or modify it
|
|---|
| 9 | ; under the terms of the GNU General Public License as published by
|
|---|
| 10 | ; the Free Software Foundation; either version 2, or (at your option)
|
|---|
| 11 | ; any later version.
|
|---|
| 12 | ;
|
|---|
| 13 | ; emx is distributed in the hope that it will be useful,
|
|---|
| 14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 16 | ; GNU General Public License for more details.
|
|---|
| 17 | ;
|
|---|
| 18 | ; You should have received a copy of the GNU General Public License
|
|---|
| 19 | ; along with emx; see the file COPYING. If not, write to
|
|---|
| 20 | ; the Free Software Foundation, 59 Temple Place - Suite 330,
|
|---|
| 21 | ; Boston, MA 02111-1307, USA.
|
|---|
| 22 | ;
|
|---|
| 23 | ; See emx.asm for a special exception.
|
|---|
| 24 | ;
|
|---|
| 25 |
|
|---|
| 26 | INCLUDE EMX.INC
|
|---|
| 27 | INCLUDE SIGNAL.INC
|
|---|
| 28 | INCLUDE PROCESS.INC
|
|---|
| 29 | INCLUDE PAGING.INC
|
|---|
| 30 | INCLUDE SEGMENTS.INC
|
|---|
| 31 | INCLUDE LOADER.INC
|
|---|
| 32 | INCLUDE FILEIO.INC
|
|---|
| 33 | INCLUDE TABLES.INC
|
|---|
| 34 | INCLUDE PMINT.INC
|
|---|
| 35 | INCLUDE SWAPPER.INC
|
|---|
| 36 | INCLUDE MEMORY.INC
|
|---|
| 37 | INCLUDE VCPI.INC
|
|---|
| 38 | INCLUDE MISC.INC
|
|---|
| 39 | INCLUDE XMS.INC
|
|---|
| 40 | INCLUDE CORE.INC
|
|---|
| 41 | INCLUDE PROFIL.INC
|
|---|
| 42 | INCLUDE VPRINT.INC
|
|---|
| 43 | INCLUDE UTILS.INC
|
|---|
| 44 | INCLUDE VERSION.INC
|
|---|
| 45 | INCLUDE TERMIO.INC
|
|---|
| 46 | INCLUDE STAT.INC
|
|---|
| 47 | INCLUDE TIMEB.INC
|
|---|
| 48 | INCLUDE ULIMIT.INC
|
|---|
| 49 | INCLUDE ERRORS.INC
|
|---|
| 50 |
|
|---|
| 51 | PUBLIC DO_SYSCALL
|
|---|
| 52 |
|
|---|
| 53 | FD_SETSIZE = 256
|
|---|
| 54 |
|
|---|
| 55 | MY_DATETIME STRUCT
|
|---|
| 56 | SECONDS DD ?
|
|---|
| 57 | MINUTES DD ?
|
|---|
| 58 | HOURS DD ?
|
|---|
| 59 | DAY DD ?
|
|---|
| 60 | MONTH DD ?
|
|---|
| 61 | YEAR DD ?
|
|---|
| 62 | MY_DATETIME ENDS
|
|---|
| 63 |
|
|---|
| 64 | SELECT_ARGS STRUCT
|
|---|
| 65 | SELA_NFDS DD ?
|
|---|
| 66 | SELA_READFDS DD ?
|
|---|
| 67 | SELA_WRITEFDS DD ?
|
|---|
| 68 | SELA_EXCEPTFDS DD ?
|
|---|
| 69 | SELA_TIMEOUT DD ?
|
|---|
| 70 | SELECT_ARGS ENDS
|
|---|
| 71 |
|
|---|
| 72 | TIMEVAL STRUCT
|
|---|
| 73 | TV_SEC DD ?
|
|---|
| 74 | TV_USEC DD ?
|
|---|
| 75 | TIMEVAL ENDS
|
|---|
| 76 |
|
|---|
| 77 | SV_DATA SEGMENT
|
|---|
| 78 |
|
|---|
| 79 | ;
|
|---|
| 80 | ; This structure is passed by spawnve() to NEW_PROCESS
|
|---|
| 81 | ;
|
|---|
| 82 | TALIGN 2
|
|---|
| 83 | NP2 NEW_PROC <>
|
|---|
| 84 |
|
|---|
| 85 | ;
|
|---|
| 86 | ; Variables for __select()
|
|---|
| 87 | ;
|
|---|
| 88 | SEL_COUNT WORD ?
|
|---|
| 89 | SEL_RBITS BYTE FD_SETSIZE/8 DUP (?)
|
|---|
| 90 |
|
|---|
| 91 | ;
|
|---|
| 92 | ;
|
|---|
| 93 | ;
|
|---|
| 94 | INO_NUMBER DWORD 100000H
|
|---|
| 95 |
|
|---|
| 96 | ;
|
|---|
| 97 | ; Number of days of a month
|
|---|
| 98 | ;
|
|---|
| 99 | MONTH_LEN DB 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|---|
| 100 |
|
|---|
| 101 | $FAT DB "FAT", 0
|
|---|
| 102 | $LAN DB "LAN", 0
|
|---|
| 103 |
|
|---|
| 104 | ;
|
|---|
| 105 | ; __open() maps "/dev/null" and "/dev/tty" to "nul" and "con",
|
|---|
| 106 | ; respectively.
|
|---|
| 107 | ;
|
|---|
| 108 | $DEVNULL BYTE "/dev/null", 0
|
|---|
| 109 | $DEVTTY BYTE "/dev/tty", 0
|
|---|
| 110 | $NUL BYTE "nul", 0
|
|---|
| 111 | $CON BYTE "con", 0
|
|---|
| 112 |
|
|---|
| 113 | ;
|
|---|
| 114 | ; Special program names
|
|---|
| 115 | ;
|
|---|
| 116 | $COMMAND BYTE "COMMAND.COM", 0
|
|---|
| 117 | $4DOS BYTE "4DOS.COM", 0
|
|---|
| 118 |
|
|---|
| 119 | ;
|
|---|
| 120 | ; DOS_COMMAND sets this flag to non-FALSE if command.com or 4dos.com
|
|---|
| 121 | ; is to be run.
|
|---|
| 122 | ;
|
|---|
| 123 | IS_COMMAND BYTE FALSE
|
|---|
| 124 |
|
|---|
| 125 | ;
|
|---|
| 126 | ; Parameter block for DOS function 4BH
|
|---|
| 127 | ;
|
|---|
| 128 | PAR_BLOCK LABEL BYTE
|
|---|
| 129 | PB_ENV DW 0
|
|---|
| 130 | DD CMD_LINE ; Command line
|
|---|
| 131 | DD FCB ; FCB1
|
|---|
| 132 | DD FCB ; FCB2
|
|---|
| 133 |
|
|---|
| 134 | ;
|
|---|
| 135 | ; He who uses FCBs loses
|
|---|
| 136 | ;
|
|---|
| 137 | FCB DB 0 ; Drive name
|
|---|
| 138 | DB 11 DUP (" ") ; File name
|
|---|
| 139 | DB 20 DUP (0) ; Fill to 32 bytes
|
|---|
| 140 |
|
|---|
| 141 | ;
|
|---|
| 142 | ; Program name and command line for DOS programs
|
|---|
| 143 | ;
|
|---|
| 144 | PGM_NAME_SIZE = 65
|
|---|
| 145 | CMD_LINE_SIZE = 128
|
|---|
| 146 |
|
|---|
| 147 | PGM_NAME DB PGM_NAME_SIZE DUP (0)
|
|---|
| 148 | CMD_LINE DB CMD_LINE_SIZE DUP (0)
|
|---|
| 149 |
|
|---|
| 150 | FIND_BUF STRUC
|
|---|
| 151 | FIND_RESERVED DB 15H DUP (?)
|
|---|
| 152 | FIND_ATTR DB ?
|
|---|
| 153 | FIND_TIME DW ?
|
|---|
| 154 | FIND_DATE DW ?
|
|---|
| 155 | FIND_SIZE DD ?
|
|---|
| 156 | FIND_NAME DB 13 DUP (?)
|
|---|
| 157 | FIND_BUF ENDS
|
|---|
| 158 |
|
|---|
| 159 | STAT_CWD DB "x:\"
|
|---|
| 160 | DB 65 DUP (?)
|
|---|
| 161 |
|
|---|
| 162 | ;
|
|---|
| 163 | ; Error message
|
|---|
| 164 | ;
|
|---|
| 165 | $SYSCALL DB "Invalid syscall function code: 7f", 0
|
|---|
| 166 |
|
|---|
| 167 | SV_DATA ENDS
|
|---|
| 168 |
|
|---|
| 169 | SV_CODE SEGMENT
|
|---|
| 170 |
|
|---|
| 171 | ASSUME CS:SV_CODE, DS:NOTHING
|
|---|
| 172 |
|
|---|
| 173 | TIME_2_UNIX PROTO PASCAL, MDT:PTR MY_DATETIME
|
|---|
| 174 | EXTRN PTRACE:NEAR
|
|---|
| 175 |
|
|---|
| 176 | ;
|
|---|
| 177 | ; Jump table for syscall functions
|
|---|
| 178 | ;
|
|---|
| 179 | TALIGN 2
|
|---|
| 180 | SYSCALL_JMP DW SYS00 ; __sbrk
|
|---|
| 181 | DW SYS01 ; __brk
|
|---|
| 182 | DW SYS02 ; __ulimit
|
|---|
| 183 | DW SYS03 ; __vmstat
|
|---|
| 184 | DW SYS04 ; __umask1
|
|---|
| 185 | DW SYS05 ; __getpid
|
|---|
| 186 | DW SYS06 ; __spawnve
|
|---|
| 187 | DW SYSCALL_ERROR ; (obsolete)
|
|---|
| 188 | DW PTRACE ; __ptrace
|
|---|
| 189 | DW SYS09 ; __wait
|
|---|
| 190 | DW SYS0A ; __version
|
|---|
| 191 | DW SYS0B ; __memavail
|
|---|
| 192 | DW SYS0C ; __signal
|
|---|
| 193 | DW SYS0D ; __kill
|
|---|
| 194 | DW SYS0E ; __raise
|
|---|
| 195 | DW SYS0F ; __uflags
|
|---|
| 196 | DW SYS10 ; __unwind
|
|---|
| 197 | DW SYS11 ; __core
|
|---|
| 198 | DW SYS12 ; __portaccess
|
|---|
| 199 | DW SYS13 ; __memaccess
|
|---|
| 200 | DW SYS14 ; __ioctl2
|
|---|
| 201 | DW SYS15 ; __alarm
|
|---|
| 202 | DW SYS16 ; Poll the keyboard
|
|---|
| 203 | DW SYS17 ; __sleep
|
|---|
| 204 | DW SYS18 ; __chsize
|
|---|
| 205 | DW SYS19 ; __fcntl
|
|---|
| 206 | DW SYS1A ; __pipe
|
|---|
| 207 | DW SYS1B ; __fsync
|
|---|
| 208 | DW SYS1C ; __fork
|
|---|
| 209 | DW SYS1D ; __scrsize
|
|---|
| 210 | DW SYS1E ; __select
|
|---|
| 211 | DW SYS1F ; __syserrno
|
|---|
| 212 | DW SYS20 ; __stat
|
|---|
| 213 | DW SYS21 ; __fstat
|
|---|
| 214 | DW SYSCALL_ERROR ; No longer used
|
|---|
| 215 | DW SYS23 ; __filesys
|
|---|
| 216 | DW SYS24 ; __utimes
|
|---|
| 217 | DW SYS25 ; __ftruncate
|
|---|
| 218 | DW SYS26 ; __clock
|
|---|
| 219 | DW SYS27 ; __ftime
|
|---|
| 220 | DW SYS28 ; __umask
|
|---|
| 221 | DW SYS29 ; __getppid
|
|---|
| 222 | DW SYS2A ; __nls_memupr
|
|---|
| 223 | DW SYS2B ; __open
|
|---|
| 224 | DW SYS2C ; __newthread
|
|---|
| 225 | DW SYS2D ; __endthread
|
|---|
| 226 | DW SYS2E ; __waitpid
|
|---|
| 227 | DW SYS2F ; __read_kbd
|
|---|
| 228 | DW SYS30 ; __sleep2
|
|---|
| 229 | DW SYS31 ; __unwind2
|
|---|
| 230 | DW SYS32 ; __pause
|
|---|
| 231 | DW SYS33 ; __execname
|
|---|
| 232 | DW SYS34 ; __initthread
|
|---|
| 233 | DW SYS35 ; __sigaction
|
|---|
| 234 | DW SYS36 ; __sigpending
|
|---|
| 235 | DW SYS37 ; __sigprocmask
|
|---|
| 236 | DW SYS38 ; __sigsuspend
|
|---|
| 237 | DW SYS39 ; __imphandle
|
|---|
| 238 | DW SYS3A ; __fpuemu
|
|---|
| 239 | DW SYSCALL_ERROR ; __getsockhandle
|
|---|
| 240 | DW SYSCALL_ERROR ; __socket
|
|---|
| 241 | DW SYSCALL_ERROR ; __bind
|
|---|
| 242 | DW SYSCALL_ERROR ; __listen
|
|---|
| 243 | DW SYSCALL_ERROR ; __recv
|
|---|
| 244 | DW SYSCALL_ERROR ; __send
|
|---|
| 245 | DW SYSCALL_ERROR ; __accept
|
|---|
| 246 | DW SYSCALL_ERROR ; __connect
|
|---|
| 247 | DW SYSCALL_ERROR ; __getsockopt
|
|---|
| 248 | DW SYSCALL_ERROR ; __setsockopt
|
|---|
| 249 | DW SYSCALL_ERROR ; __getsockname
|
|---|
| 250 | DW SYSCALL_ERROR ; __getpeername
|
|---|
| 251 | DW SYSCALL_ERROR ; __gethostbyname
|
|---|
| 252 | DW SYSCALL_ERROR ; __gethostbyaddr
|
|---|
| 253 | DW SYSCALL_ERROR ; __getservbyname
|
|---|
| 254 | DW SYSCALL_ERROR ; __getservbyport
|
|---|
| 255 | DW SYSCALL_ERROR ; __getprotobyname
|
|---|
| 256 | DW SYSCALL_ERROR ; __getprotobynumber
|
|---|
| 257 | DW SYSCALL_ERROR ; __getnetbyname
|
|---|
| 258 | DW SYSCALL_ERROR ; __getnetbyaddr
|
|---|
| 259 | DW SYSCALL_ERROR ; __gethostname
|
|---|
| 260 | DW SYSCALL_ERROR ; __gethostid
|
|---|
| 261 | DW SYSCALL_ERROR ; __shutdown
|
|---|
| 262 | DW SYSCALL_ERROR ; __recvfrom
|
|---|
| 263 | DW SYSCALL_ERROR ; __sendto
|
|---|
| 264 | DW SYSCALL_ERROR ; __impsockhandle
|
|---|
| 265 | DW SYSCALL_ERROR ; __recvmsg
|
|---|
| 266 | DW SYSCALL_ERROR ; __sendmsg
|
|---|
| 267 | DW SYSCALL_ERROR ; __ttyname
|
|---|
| 268 | DW SYS58 ; __settime
|
|---|
| 269 | DW SYS59 ; __profil
|
|---|
| 270 | DW SYS5A ; __nls_ctype
|
|---|
| 271 | DW SYSCALL_ENOSYS ; __setsyserrno
|
|---|
| 272 | SYSCALL_LAST = ($-SYSCALL_JMP)/2-1
|
|---|
| 273 |
|
|---|
| 274 | ;
|
|---|
| 275 | ; Syscall functions
|
|---|
| 276 | ;
|
|---|
| 277 | ; In: AH 7FH
|
|---|
| 278 | ; AL Function code
|
|---|
| 279 | ;
|
|---|
| 280 | ASSUME DS:SV_DATA
|
|---|
| 281 | ASSUME BP:PTR ISTACKFRAME
|
|---|
| 282 | TALIGN 4
|
|---|
| 283 | DO_SYSCALL: CMP AL, SYSCALL_LAST ; Valid function code?
|
|---|
| 284 | JA SHORT SYSCALL_ENOSYS ; Yes -> return ENOSYS
|
|---|
| 285 | MOV DI, PROCESS_PTR ; Process table entry
|
|---|
| 286 | MOVZX EAX, AL ; Keep only lower 8 bits
|
|---|
| 287 | JMP SYSCALL_JMP[EAX*2] ; Jump!
|
|---|
| 288 |
|
|---|
| 289 | SYSCALL_ERROR: LEA EDX, $SYSCALL ; Display error message
|
|---|
| 290 | MOV BL, AL ; (function code = AL)
|
|---|
| 291 | JMP DOSF_ERROR ; and abort
|
|---|
| 292 |
|
|---|
| 293 | SYSCALL_ENOSYS: MOV I_EAX, -1
|
|---|
| 294 | MOV I_ECX, ENOSYS
|
|---|
| 295 | RET
|
|---|
| 296 |
|
|---|
| 297 | ; ----------------------------------------------------------------------------
|
|---|
| 298 | ; AX=7F00H: EAX:=sbrk(EDX)
|
|---|
| 299 | ; AX=7F01H: EAX:=brk(EDX)
|
|---|
| 300 | ;
|
|---|
| 301 | ; Change data segment space allocation
|
|---|
| 302 | ;
|
|---|
| 303 | ; ----------------------------------------------------------------------------
|
|---|
| 304 | ;
|
|---|
| 305 | ; AX=7F00H: EAX:=sbrk(EDX)
|
|---|
| 306 | ;
|
|---|
| 307 | ; In: EDX Value to be added to current break value (address of
|
|---|
| 308 | ; first byte beyond the end of the data segment). Positive
|
|---|
| 309 | ; values grow the data segment, negative values shrink the
|
|---|
| 310 | ; data segment.
|
|---|
| 311 | ;
|
|---|
| 312 | ; Out: EAX Previous break value or -1 if error.
|
|---|
| 313 | ;
|
|---|
| 314 | ; ----------------------------------------------------------------------------
|
|---|
| 315 | ;
|
|---|
| 316 | ; AX=7F01H: EAX:=brk(EDX)
|
|---|
| 317 | ;
|
|---|
| 318 | ; In: EDX New break value.
|
|---|
| 319 | ;
|
|---|
| 320 | ; Out: EAX 0 if successful or -1 if error.
|
|---|
| 321 | ;
|
|---|
| 322 | ; ----------------------------------------------------------------------------
|
|---|
| 323 | ;
|
|---|
| 324 | ; Bug: doesn't fail if there isn't enough swap space
|
|---|
| 325 | ; Bug: Doesn't free pages with negative argument
|
|---|
| 326 | ; Bug: Doesn't work with stack above data/bss!!!
|
|---|
| 327 | ; Bug?: Doesn't zero-fill new memory
|
|---|
| 328 | ;
|
|---|
| 329 | ; ----------------------------------------------------------------------------
|
|---|
| 330 | ASSUME DI:PTR PROCESS
|
|---|
| 331 | SYS00: MOV EAX, [DI].P_BRK ; Get current break value
|
|---|
| 332 | PUSH EAX ; Save it
|
|---|
| 333 | MOV EDX, I_EDX ; Get argument
|
|---|
| 334 | CMP EDX, 0 ; No change?
|
|---|
| 335 | JE SHORT SYS00_OK ; Yes -> done
|
|---|
| 336 | JS SHORT SYS00_NEG
|
|---|
| 337 | ADD EAX, EDX
|
|---|
| 338 | JMP SHORT SYS00_1
|
|---|
| 339 | SYS00_NEG: NEG EDX
|
|---|
| 340 | SUB EAX, EDX
|
|---|
| 341 | SYS00_1: JC SHORT SYS00_ERR
|
|---|
| 342 | CALL BRK
|
|---|
| 343 | JNC SHORT SYS00_OK
|
|---|
| 344 | SYS00_ERR: POP EAX ; Throw away saved value
|
|---|
| 345 | MOV I_EAX, -1 ; Return -1
|
|---|
| 346 | RET
|
|---|
| 347 |
|
|---|
| 348 | SYS00_OK: POP I_EAX ; Return previous break value
|
|---|
| 349 | RET
|
|---|
| 350 |
|
|---|
| 351 | ASSUME DI:NOTHING
|
|---|
| 352 |
|
|---|
| 353 | SYS01: MOV EAX, I_EDX ; Argument
|
|---|
| 354 | CALL BRK
|
|---|
| 355 | SBB EAX, EAX ; ok -> 0, error -> -1
|
|---|
| 356 | MOV I_EAX, EAX
|
|---|
| 357 | RET
|
|---|
| 358 |
|
|---|
| 359 |
|
|---|
| 360 | ;
|
|---|
| 361 | ; Common code for brk and sbrk
|
|---|
| 362 | ;
|
|---|
| 363 | ; In: DS:DI Pointer to process table entry
|
|---|
| 364 | ; EAX New break value
|
|---|
| 365 | ;
|
|---|
| 366 | ; Out: CY Error
|
|---|
| 367 | ;
|
|---|
| 368 | ASSUME DI:PTR PROCESS
|
|---|
| 369 | BRK PROC NEAR
|
|---|
| 370 | CMP EAX, [DI].P_INIT_BRK
|
|---|
| 371 | JB BRK_ERR
|
|---|
| 372 | MOV EBX, [DI].P_STACK_ADDR
|
|---|
| 373 | CMP EBX, [DI].P_BRK ; Stack above data/bss ?
|
|---|
| 374 | JB SHORT BRK_1 ; No -> don't check stack
|
|---|
| 375 | SUB EBX, 4096 ; Leave at least one page
|
|---|
| 376 | CMP EAX, EBX ; of stack space (note 1)
|
|---|
| 377 | JA BRK_ERR ; Out of memory -> failure
|
|---|
| 378 | BRK_1: MOV ESI, EAX ; ESI := new break value
|
|---|
| 379 | CMP EAX, [DI].P_BRK
|
|---|
| 380 | JB SHORT BRK_SEG ; Set segment size
|
|---|
| 381 | MOV ECX, EAX
|
|---|
| 382 | DEC ECX ; New last byte
|
|---|
| 383 | SHR ECX, 12 ; New last page number
|
|---|
| 384 | MOV EAX, [DI].P_BRK
|
|---|
| 385 | DEC EAX
|
|---|
| 386 | JS SHORT BRK_2
|
|---|
| 387 | SHR EAX, 12 ; Old last page number
|
|---|
| 388 | BRK_2: SUB ECX, EAX ; Number of new pages
|
|---|
| 389 | JBE SHORT BRK_SEG
|
|---|
| 390 | INC EAX ; First new page number
|
|---|
| 391 | SHL EAX, 12 ; Byte address of new page
|
|---|
| 392 | ADD EAX, [DI].P_LINEAR ; Linear address
|
|---|
| 393 | ;
|
|---|
| 394 | ; Note 1: We must not change the attributes of stack pages!
|
|---|
| 395 | ; This is assured by leaving at least 4096 bytes between data
|
|---|
| 396 | ; and stack.
|
|---|
| 397 | ;
|
|---|
| 398 | CALL INIT_PAGES
|
|---|
| 399 | JC SHORT BRK_ERR ; Out of memory
|
|---|
| 400 | MOV EBX, PAGE_WRITE OR PAGE_USER
|
|---|
| 401 | MOV EDX, SRC_NONE
|
|---|
| 402 | TEST [DI].P_FLAGS, PF_DONT_ZERO
|
|---|
| 403 | JNZ SHORT BRK_3
|
|---|
| 404 | MOV EDX, SRC_ZERO
|
|---|
| 405 | BRK_3: MOV DL, [DI].P_PIDX
|
|---|
| 406 | CALL SET_COMMIT ; Set PAGE_ALLOC bit
|
|---|
| 407 | CALL SET_PAGES
|
|---|
| 408 | JC SHORT BRK_ERR ; Committing failed
|
|---|
| 409 | ;
|
|---|
| 410 | ; Adjust data segment size
|
|---|
| 411 | ;
|
|---|
| 412 | BRK_SEG: MOV EBX, [DI].P_STACK_ADDR
|
|---|
| 413 | CMP EBX, [DI].P_BRK ; Stack above data/bss ?
|
|---|
| 414 | JA BRK_DONE ; Yes -> skip
|
|---|
| 415 | MOV ECX, ESI
|
|---|
| 416 | PUSH ESI
|
|---|
| 417 | MOV SI, [DI].P_LDT_PTR
|
|---|
| 418 | ADD SI, L_DATA_SEL AND NOT 07H
|
|---|
| 419 | CALL SEG_SIZE
|
|---|
| 420 | POP ESI
|
|---|
| 421 | BRK_DONE: MOV [DI].P_BRK, ESI
|
|---|
| 422 | CLC
|
|---|
| 423 | RET
|
|---|
| 424 |
|
|---|
| 425 | BRK_ERR: STC
|
|---|
| 426 | RET
|
|---|
| 427 |
|
|---|
| 428 | ASSUME DI:NOTHING
|
|---|
| 429 | BRK ENDP
|
|---|
| 430 |
|
|---|
| 431 |
|
|---|
| 432 | ; ----------------------------------------------------------------------------
|
|---|
| 433 | ; AX=7F02H: EAX:=ulimit
|
|---|
| 434 | ;
|
|---|
| 435 | ; Get greatest possible break value
|
|---|
| 436 | ;
|
|---|
| 437 | ; ----------------------------------------------------------------------------
|
|---|
| 438 | ;
|
|---|
| 439 | ; In: ECX Command code (must be UL_GMEMLIM or UL_OBJREST)
|
|---|
| 440 | ; EDX New limit (currently ignored)
|
|---|
| 441 | ;
|
|---|
| 442 | ; Out: EAX Return value:
|
|---|
| 443 | ; greatest possible break value for UL_GMEMLIM
|
|---|
| 444 | ; remaining bytes in current heap object for UL_OBJREST
|
|---|
| 445 | ; ECX errno, if non-zero
|
|---|
| 446 | ;
|
|---|
| 447 | ; ----------------------------------------------------------------------------
|
|---|
| 448 |
|
|---|
| 449 | TALIGN 4
|
|---|
| 450 | ASSUME DI:PTR PROCESS
|
|---|
| 451 | SYS02: CMP I_ECX, UL_GMEMLIM
|
|---|
| 452 | JE ULIMIT_GMEMLIM
|
|---|
| 453 | CMP I_ECX, UL_OBJREST
|
|---|
| 454 | JE ULIMIT_OBJREST
|
|---|
| 455 | ULIMIT_ERR: MOV I_EAX, -1
|
|---|
| 456 | MOV I_ECX, EINVAL
|
|---|
| 457 | RET
|
|---|
| 458 |
|
|---|
| 459 | ULIMIT_OBJREST: CALL HEAP_LIMIT
|
|---|
| 460 | SUB EAX, [DI].P_BRK
|
|---|
| 461 | JMP SHORT ULIMIT_RET
|
|---|
| 462 |
|
|---|
| 463 | ULIMIT_GMEMLIM: CALL HEAP_LIMIT
|
|---|
| 464 | ULIMIT_RET: MOV I_EAX, EAX
|
|---|
| 465 | MOV I_ECX, 0
|
|---|
| 466 | RET
|
|---|
| 467 |
|
|---|
| 468 | HEAP_LIMIT PROC NEAR
|
|---|
| 469 | MOV EAX, [DI].P_BRK ; Return this on error
|
|---|
| 470 | MOV EDX, [DI].P_STACK_ADDR
|
|---|
| 471 | CMP EDX, [DI].P_BRK
|
|---|
| 472 | MOV EBX, 80000000H ; ...bad estimate
|
|---|
| 473 | JB SHORT HEAP_LIMIT_1
|
|---|
| 474 | MOV EBX, I_ESP
|
|---|
| 475 | SUB EBX, 4096 ; Leave at least on page
|
|---|
| 476 | JC SHORT HEAP_LIMIT_RET ; of stack space (note 1)
|
|---|
| 477 | HEAP_LIMIT_1: CMP EBX, [DI].P_BRK
|
|---|
| 478 | JB SHORT HEAP_LIMIT_RET
|
|---|
| 479 | MOV EAX, EBX
|
|---|
| 480 | HEAP_LIMIT_RET: RET
|
|---|
| 481 | HEAP_LIMIT ENDP
|
|---|
| 482 |
|
|---|
| 483 | ASSUME DI:NOTHING
|
|---|
| 484 |
|
|---|
| 485 | ; ----------------------------------------------------------------------------
|
|---|
| 486 | ; AX=7F03H: [EBX]:=statistics
|
|---|
| 487 | ;
|
|---|
| 488 | ; Virtual memory statistics
|
|---|
| 489 | ;
|
|---|
| 490 | ; In: DS:EBX Buffer
|
|---|
| 491 | ; ECX Size (in bytes) of buffer pointed to by DS:EBX
|
|---|
| 492 | ;
|
|---|
| 493 | ; Out: [EBX+0] Number of page faults caused by this process
|
|---|
| 494 | ; [EBX+4] Total number of page faults
|
|---|
| 495 | ;
|
|---|
| 496 | ; ----------------------------------------------------------------------------
|
|---|
| 497 | TALIGN 4
|
|---|
| 498 | ASSUME DI:PTR PROCESS
|
|---|
| 499 | SYS03: MOV EBX, I_EBX
|
|---|
| 500 | MOV ES, I_DS
|
|---|
| 501 | MOV ECX, I_ECX
|
|---|
| 502 | CMP ECX, 1*4
|
|---|
| 503 | JB SHORT SYS03_RET
|
|---|
| 504 | MOV EAX, [DI].P_PAGE_FAULTS
|
|---|
| 505 | MOV ES:[EBX+0], EAX
|
|---|
| 506 | CMP ECX, 2*4
|
|---|
| 507 | JB SHORT SYS03_RET
|
|---|
| 508 | MOV EAX, SWAP_FAULTS
|
|---|
| 509 | MOV ES:[EBX+4], EAX
|
|---|
| 510 | SYS03_RET: RET
|
|---|
| 511 |
|
|---|
| 512 | ASSUME DI:NOTHING
|
|---|
| 513 |
|
|---|
| 514 | ; ----------------------------------------------------------------------------
|
|---|
| 515 | ; AX=7F04H: EAX:=__umask1(EDX)
|
|---|
| 516 | ;
|
|---|
| 517 | ; Set file-permission mask
|
|---|
| 518 | ;
|
|---|
| 519 | ; ----------------------------------------------------------------------------
|
|---|
| 520 | TALIGN 4
|
|---|
| 521 | ASSUME DI:PTR PROCESS
|
|---|
| 522 | SYS04: MOVZX EAX, [DI].P_UMASK1
|
|---|
| 523 | MOV I_EAX, EAX
|
|---|
| 524 | MOV AX, WORD PTR I_EDX
|
|---|
| 525 | NOT AX
|
|---|
| 526 | AND [DI].P_UMASK1, AX
|
|---|
| 527 | RET
|
|---|
| 528 |
|
|---|
| 529 | ASSUME DI:NOTHING
|
|---|
| 530 |
|
|---|
| 531 | ; ----------------------------------------------------------------------------
|
|---|
| 532 | ; AX=7F05H: EAX:=getpid()
|
|---|
| 533 | ;
|
|---|
| 534 | ; Get process ID
|
|---|
| 535 | ;
|
|---|
| 536 | ; ----------------------------------------------------------------------------
|
|---|
| 537 | TALIGN 4
|
|---|
| 538 | ASSUME DI:PTR PROCESS
|
|---|
| 539 | SYS05: MOV EAX, [DI].P_PID
|
|---|
| 540 | MOV I_EAX, EAX
|
|---|
| 541 | RET
|
|---|
| 542 |
|
|---|
| 543 | ASSUME DI:NOTHING
|
|---|
| 544 |
|
|---|
| 545 | ; ----------------------------------------------------------------------------
|
|---|
| 546 | ; AX=7F06H: spawnve()
|
|---|
| 547 | ;
|
|---|
| 548 | ; Spawn child process
|
|---|
| 549 | ;
|
|---|
| 550 | ; In: DS:EDX Pointer to parameter table (NEW_PROC, see PROCESS.INC)
|
|---|
| 551 | ; NP_PARENT will be filled in by this function.
|
|---|
| 552 | ;
|
|---|
| 553 | ; Out: CY Error
|
|---|
| 554 | ; NC Success
|
|---|
| 555 | ; EAX Error code (CY)
|
|---|
| 556 | ; EAX Process id (NC, asynchronous process)
|
|---|
| 557 | ; EAX Return code (NC, synchronous process)
|
|---|
| 558 | ;
|
|---|
| 559 | ; Note: Not reentrant (uses global variable NP2!).
|
|---|
| 560 | ;
|
|---|
| 561 | ; ----------------------------------------------------------------------------
|
|---|
| 562 | TALIGN 4
|
|---|
| 563 | ASSUME DI:PTR PROCESS
|
|---|
| 564 | SYS06: MOV BX, DI
|
|---|
| 565 | CALL SAVE_PROCESS ; Save registers
|
|---|
| 566 | CALL MAKE_NP2 ; Copy param. table to NP2
|
|---|
| 567 | CALL SPAWN_FNAME ; Create program file name
|
|---|
| 568 | MOV NP2.NP_FNAME_SEL, DS
|
|---|
| 569 | MOV NP2.NP_FNAME_OFF, OFFSET PGM_NAME
|
|---|
| 570 | MOV DI, PROCESS_PTR ; Current process
|
|---|
| 571 | CMP BYTE PTR NP2.NP_MODE1, NP_EXEC ; exec?
|
|---|
| 572 | JNE SHORT SPAWN_2 ; No -> process is parent
|
|---|
| 573 | MOV EAX, [DI].P_PPID ; PID of parent process
|
|---|
| 574 | CALL FIND_PROCESS ; Find parent process
|
|---|
| 575 | CMP BX, NO_PROCESS ; Success?
|
|---|
| 576 | JNE SHORT SPAWN_2 ; Yes -> has real parent
|
|---|
| 577 | LEA BX, PROC0 ; No -> use dummy parent
|
|---|
| 578 | SPAWN_2: MOV NP2.NP_PARENT, BX ; Set NP_PARENT field
|
|---|
| 579 | MOV NP2.NP_FPROC, DI ; Set source of file handles
|
|---|
| 580 | LEA SI, NP2 ; Parameter table
|
|---|
| 581 | CALL NEW_PROCESS ; Create new process
|
|---|
| 582 | OR AX, AX ; Failure?
|
|---|
| 583 | JNZ SHORT SPAWN_FAIL ; Yes -> try DOS pgm or return
|
|---|
| 584 | MOV BX, PROCESS_PTR ; Outgoing process
|
|---|
| 585 | ASSUME BX:PTR PROCESS
|
|---|
| 586 | CMP BYTE PTR NP2.NP_MODE1, NP_DEBUG ; Debugging?
|
|---|
| 587 | JE SHORT SPAWN_ASYNC ; Yes -> return to parent
|
|---|
| 588 | CMP BYTE PTR NP2.NP_MODE1, NP_SPAWN_ASYNC ; Asynchronous?
|
|---|
| 589 | JNE SHORT SPAWN_3 ; No -> continue
|
|---|
| 590 | MOV EAX, [DI].P_PID ; Process ID of child
|
|---|
| 591 | MOV [BX].P_SPAWN_RC, EAX ; will be returned by spawn()
|
|---|
| 592 | OR [BX].P_FLAGS, PF_PSEUDO_ASYNC
|
|---|
| 593 | SPAWN_3: MOV [BX].P_STATUS, PS_WAIT_SPAWN
|
|---|
| 594 | ;
|
|---|
| 595 | ; Now run the new process synchronously
|
|---|
| 596 | ;
|
|---|
| 597 | MOV PROCESS_PTR, DI ; Switch to incoming process
|
|---|
| 598 | MOV PROCESS_SIG, DI
|
|---|
| 599 | CMP BYTE PTR NP2.NP_MODE1, NP_EXEC
|
|---|
| 600 | JNE SHORT SPAWN_4
|
|---|
| 601 | CALL REMOVE_PROCESS ; TODO: FPUEMU_ENDPROC
|
|---|
| 602 | SPAWN_4: MOV BX, DI
|
|---|
| 603 | CALL REST_PROCESS ; Start incoming process
|
|---|
| 604 | CALL BREAK_AFTER_IRET
|
|---|
| 605 | MOV EAX, [BX].P_NUMBER
|
|---|
| 606 | CALL FPUEMU_NEWPROC ; Notify FPU emulator
|
|---|
| 607 | SPAWN_RET: RET
|
|---|
| 608 |
|
|---|
| 609 | ;
|
|---|
| 610 | ; Return to the parent process after starting an asynchronous process.
|
|---|
| 611 | ; This is currently used for NP_DEBUG only.
|
|---|
| 612 | ;
|
|---|
| 613 | SPAWN_ASYNC: MOV EAX, [DI].P_PID ; Process ID of child
|
|---|
| 614 | MOV I_EAX, EAX ; Return process ID
|
|---|
| 615 | MOV EAX, [DI].P_NUMBER
|
|---|
| 616 | CALL FPUEMU_NEWPROC ; Notify FPU emulator
|
|---|
| 617 | JMP SHORT SPAWN_RET
|
|---|
| 618 |
|
|---|
| 619 | SPAWN_FAIL: CMP AX, ENOEXEC ; Not an emx program?
|
|---|
| 620 | JE SHORT SPAWN_DOS ; Yes -> try to run a DOS pgm
|
|---|
| 621 | SPAWN_ERROR: MOVZX EAX, AX
|
|---|
| 622 | MOV I_EAX, EAX ; Failure
|
|---|
| 623 | OR BYTE PTR I_EFLAGS, FLAG_C
|
|---|
| 624 | RET
|
|---|
| 625 |
|
|---|
| 626 | ASSUME BX:NOTHING
|
|---|
| 627 | ASSUME DI:NOTHING
|
|---|
| 628 | ;
|
|---|
| 629 | ; Try to run the program as ordinary DOS program
|
|---|
| 630 | ;
|
|---|
| 631 | SPAWN_DOS: CMP BYTE PTR NP2.NP_MODE1, NP_SPAWN_SYNC ; Synchronous?
|
|---|
| 632 | JE SHORT SPAWN_DOS_1 ; Yes -> continue
|
|---|
| 633 | CMP BYTE PTR NP2.NP_MODE1, NP_SPAWN_ASYNC ; Asynchronous?
|
|---|
| 634 | JNE SHORT SPAWN_ERROR ; No -> error
|
|---|
| 635 | SPAWN_DOS_1: CMP DISABLE_LOW_MEM, FALSE ; Low memory in use?
|
|---|
| 636 | JNE SHORT DOS_10 ; No -> ok
|
|---|
| 637 | MOV AX, ENOMEM ; Not enough memory
|
|---|
| 638 | JMP SHORT SPAWN_ERROR
|
|---|
| 639 | ;
|
|---|
| 640 | ; Build command line
|
|---|
| 641 | ;
|
|---|
| 642 | DOS_10: CALL DOS_COMMAND ; Look for COMMAND.COM
|
|---|
| 643 | CALL DOS_ARGS ; Build command line
|
|---|
| 644 | JC SHORT DOS_TOO_BIG
|
|---|
| 645 | CALL DOS_ENV ; Build environment
|
|---|
| 646 | OR AX, AX
|
|---|
| 647 | JNZ SHORT SPAWN_ERROR ; Error -> return errno
|
|---|
| 648 | CALL MAP_ALL_HANDLES ; Remap file handles
|
|---|
| 649 | JC SHORT SPAWN_ERROR ; Error -> return errno
|
|---|
| 650 | ;
|
|---|
| 651 | ; Try to run the program
|
|---|
| 652 | ;
|
|---|
| 653 | LEA DX, PGM_NAME
|
|---|
| 654 | LEA BX, PAR_BLOCK
|
|---|
| 655 | MOV AX, 4B00H ; Load and execute program
|
|---|
| 656 | INT 21H
|
|---|
| 657 | MOV I_EAX, EAX
|
|---|
| 658 | JNC SHORT DOS_OK
|
|---|
| 659 | OR BYTE PTR I_EFLAGS, FLAG_C
|
|---|
| 660 | JMP SPAWN_RET
|
|---|
| 661 |
|
|---|
| 662 | DOS_OK: MOV AH, 4DH ; Get ret code of child process
|
|---|
| 663 | INT 21H
|
|---|
| 664 | MOVZX EAX, AX ; Put it in EAX
|
|---|
| 665 | MOV BX, PROCESS_PTR ; Parent process
|
|---|
| 666 | ASSUME BX:PTR PROCESS
|
|---|
| 667 | CMP BYTE PTR NP2.NP_MODE1, NP_SPAWN_ASYNC ; Pseudo async?
|
|---|
| 668 | JNE SHORT DOS_SPAWN_RC ; No -> return return code
|
|---|
| 669 | MOV [BX].P_RC, AL ; Save the return code
|
|---|
| 670 | CALL CREATE_PID ; Return a process ID
|
|---|
| 671 | OR [BX].P_FLAGS, PF_PSEUDO_ASYNC
|
|---|
| 672 | CMP [BX].P_SIG_HANDLERS[4*SIGCLD], SIG_IGN
|
|---|
| 673 | JE SHORT DOS_SPAWN_RC
|
|---|
| 674 | CMP [BX].P_SIG_HANDLERS[4*SIGCLD], SIG_DFL
|
|---|
| 675 | JE SHORT DOS_SPAWN_RC
|
|---|
| 676 | BTS [BX].P_SIG_PENDING, SIGCLD ; Generate SIGCLD
|
|---|
| 677 | DOS_SPAWN_RC: MOV [BX].P_SPAWN_RC, EAX
|
|---|
| 678 | MOV I_EAX, EAX
|
|---|
| 679 | JMP SPAWN_RET
|
|---|
| 680 | ASSUME BX:NOTHING
|
|---|
| 681 |
|
|---|
| 682 | ;
|
|---|
| 683 | ; Arguments or environment too big
|
|---|
| 684 | ;
|
|---|
| 685 | DOS_TOO_BIG: MOV AX, E2BIG
|
|---|
| 686 | JMP SPAWN_ERROR
|
|---|
| 687 |
|
|---|
| 688 | ;
|
|---|
| 689 | ;
|
|---|
| 690 | ;
|
|---|
| 691 | TALIGN 4
|
|---|
| 692 | SPAWN_FNAME PROC NEAR
|
|---|
| 693 | PUSH ESI
|
|---|
| 694 | PUSH EDI
|
|---|
| 695 | PUSH DS
|
|---|
| 696 | LEA DI, PGM_NAME
|
|---|
| 697 | MOV_ES_DS
|
|---|
| 698 | MOV ESI, NP2.NP_FNAME_OFF
|
|---|
| 699 | MOV DS, NP2.NP_FNAME_SEL
|
|---|
| 700 | ASSUME DS:NOTHING
|
|---|
| 701 | MOV CX, PGM_NAME_SIZE - 1
|
|---|
| 702 | SPAWN_FNAME_1: LODS BYTE PTR DS:[ESI]
|
|---|
| 703 | OR AL, AL
|
|---|
| 704 | JZ SHORT SPAWN_FNAME_2
|
|---|
| 705 | STOS BYTE PTR ES:[DI]
|
|---|
| 706 | LOOP SPAWN_FNAME_1
|
|---|
| 707 | SPAWN_FNAME_2: XOR AL, AL
|
|---|
| 708 | STOS BYTE PTR ES:[DI]
|
|---|
| 709 | POP DS
|
|---|
| 710 | ASSUME DS:SV_DATA
|
|---|
| 711 | LEA EDI, PGM_NAME
|
|---|
| 712 | CALL TRUNCATE
|
|---|
| 713 | POP EDI
|
|---|
| 714 | POP ESI
|
|---|
| 715 | RET
|
|---|
| 716 | SPAWN_FNAME ENDP
|
|---|
| 717 |
|
|---|
| 718 | ;
|
|---|
| 719 | ; Check for COMMAND.COM and 4DOS.COM
|
|---|
| 720 | ;
|
|---|
| 721 |
|
|---|
| 722 | DOS_COMMAND PROC NEAR
|
|---|
| 723 | MOV IS_COMMAND, FALSE ; Standard quoting by default
|
|---|
| 724 | LEA SI, PGM_NAME ; Find base name
|
|---|
| 725 | MOV DI, SI
|
|---|
| 726 | DC_1: LODSB
|
|---|
| 727 | OR AL, AL
|
|---|
| 728 | JZ SHORT DC_3
|
|---|
| 729 | CMP AL, "/"
|
|---|
| 730 | JE SHORT DC_2
|
|---|
| 731 | CMP AL, "\"
|
|---|
| 732 | JE SHORT DC_2
|
|---|
| 733 | CMP AL, ":"
|
|---|
| 734 | JNE SHORT DC_1
|
|---|
| 735 | DC_2: MOV DI, SI
|
|---|
| 736 | JMP SHORT DC_1
|
|---|
| 737 |
|
|---|
| 738 | DC_3: MOV_ES_DS
|
|---|
| 739 | LEA SI, $COMMAND ; command.com?
|
|---|
| 740 | CALL STRICMP
|
|---|
| 741 | JE SHORT DC_4 ; Yes ->
|
|---|
| 742 | LEA SI, $4DOS ; 4dos.com?
|
|---|
| 743 | CALL STRICMP
|
|---|
| 744 | JNE SHORT DC_RET ; No -> skip
|
|---|
| 745 | DC_4: MOV IS_COMMAND, NOT FALSE ; Don't quote arguments
|
|---|
| 746 | DC_RET: RET
|
|---|
| 747 | DOS_COMMAND ENDP
|
|---|
| 748 |
|
|---|
| 749 | ;
|
|---|
| 750 | ; Build command line for DOS programs
|
|---|
| 751 | ;
|
|---|
| 752 | ; In: NP2 Parameter block
|
|---|
| 753 | ;
|
|---|
| 754 | ; Out: CY Command line too big
|
|---|
| 755 | ;
|
|---|
| 756 | DOS_ARGS PROC NEAR PASCAL
|
|---|
| 757 | LOCAL ARG_COUNTER:WORD
|
|---|
| 758 | LOCAL NO_QUOTE:BYTE
|
|---|
| 759 | LOCAL FORCE_QUOTE:BYTE
|
|---|
| 760 |
|
|---|
| 761 | PUSH DS ; Save DS
|
|---|
| 762 | MOV AL, IS_COMMAND ; No quoting if command.com
|
|---|
| 763 | MOV NO_QUOTE, AL ; Copy to stack segment
|
|---|
| 764 | MOV FORCE_QUOTE, FALSE
|
|---|
| 765 | TEST NP2.NP_MODE2, NP2_QUOTE
|
|---|
| 766 | JNZ SHORT DA_1
|
|---|
| 767 | MOV BX, PROCESS_PTR
|
|---|
| 768 | CMP BX, NO_PROCESS
|
|---|
| 769 | JE SHORT DA_2
|
|---|
| 770 | TEST (PROCESS PTR [BX]).P_FLAGS, PF_QUOTE
|
|---|
| 771 | JZ SHORT DA_2
|
|---|
| 772 | DA_1: NOT FORCE_QUOTE
|
|---|
| 773 | DA_2: MOV DX, 0 ; Size of command line
|
|---|
| 774 | MOV AX, NP2.NP_ARG_COUNT ; Number of arguments
|
|---|
| 775 | MOV_ES_DS
|
|---|
| 776 | LEA DI, CMD_LINE + 1
|
|---|
| 777 | MOV ESI, NP2.NP_ARG_OFF
|
|---|
| 778 | MOV DS, NP2.NP_ARG_SEL
|
|---|
| 779 | ASSUME DS:NOTHING
|
|---|
| 780 | CLD
|
|---|
| 781 | ;
|
|---|
| 782 | ; Skip argv[0]
|
|---|
| 783 | ;
|
|---|
| 784 | CMP AX, 2
|
|---|
| 785 | JB DONE ; No arguments -> done
|
|---|
| 786 | DEC AX ; argv[0] skipped
|
|---|
| 787 | MOV ARG_COUNTER, AX
|
|---|
| 788 | LODS BYTE PTR DS:[ESI] ; Get flags byte
|
|---|
| 789 | OR AL, AL ; End of arguments?
|
|---|
| 790 | JZ DONE ; Yes -> done
|
|---|
| 791 | SKIP_ARGV0: LODS BYTE PTR DS:[ESI] ; Fetch character
|
|---|
| 792 | OR AL, AL ; End of argument?
|
|---|
| 793 | JNZ SKIP_ARGV0 ; No -> repeat
|
|---|
| 794 | ;
|
|---|
| 795 | ; Next argument
|
|---|
| 796 | ;
|
|---|
| 797 | NEXT: LODS BYTE PTR DS:[ESI] ; Get flags byte
|
|---|
| 798 | OR DX, DX
|
|---|
| 799 | JZ SHORT ARG_SKIP_FLAG ; First argument -> skip
|
|---|
| 800 | INC DX
|
|---|
| 801 | CMP DX, CMD_LINE_SIZE - 2 ; Too long?
|
|---|
| 802 | JA DONE ; Yes -> end
|
|---|
| 803 | MOV AL, " " ; Delimit arguments
|
|---|
| 804 | STOS BYTE PTR ES:[DI]
|
|---|
| 805 | ;
|
|---|
| 806 | ; Look for blanks and tabs. Quote the entire argument if there is
|
|---|
| 807 | ; a blank or a tab.
|
|---|
| 808 | ;
|
|---|
| 809 | ARG_SKIP_FLAG: CMP NO_QUOTE, FALSE ; Quote?
|
|---|
| 810 | JNE SHORT ARG_CHECK_NO ; No -> skip
|
|---|
| 811 | CMP BYTE PTR DS:[ESI], 0 ; Empty argument?
|
|---|
| 812 | JE SHORT ARG_CHECK_YES ; Yes -> needs quoting
|
|---|
| 813 | PUSH ESI
|
|---|
| 814 | XOR AH, AH ; No quoting required
|
|---|
| 815 | ARG_CHECK: LODS BYTE PTR DS:[ESI] ; Fetch character
|
|---|
| 816 | TEST AL, AL ; End of argument?
|
|---|
| 817 | JZ SHORT ARG_CHECK_END ; Yes -> no quoting required
|
|---|
| 818 | CMP AL, " " ; Blank?
|
|---|
| 819 | JE SHORT ARG_CHECK_END ; Yes -> quote the argument
|
|---|
| 820 | CMP AL, TAB ; Tab?
|
|---|
| 821 | JNE SHORT ARG_CHECK ; No -> check next character
|
|---|
| 822 | ARG_CHECK_END: POP ESI
|
|---|
| 823 | TEST AL, AL
|
|---|
| 824 | JNZ SHORT ARG_CHECK_YES
|
|---|
| 825 | CMP FORCE_QUOTE, FALSE ; P_QUOTE or -q?
|
|---|
| 826 | JE SHORT ARG_CHECK_NO ; No -> don't quote
|
|---|
| 827 | ;
|
|---|
| 828 | ; Check for @, ? or *
|
|---|
| 829 | ;
|
|---|
| 830 | PUSH ESI
|
|---|
| 831 | MOV AL, 1
|
|---|
| 832 | CMP BYTE PTR DS:[ESI], "@" ; Argument starting with "@"?
|
|---|
| 833 | JNE SHORT AC_200
|
|---|
| 834 | CMP BYTE PTR DS:[ESI+1], 0
|
|---|
| 835 | JNE SHORT AC_299 ; Yes -> quote (AL non-zero)
|
|---|
| 836 | AC_200: LODS BYTE PTR DS:[ESI] ; Fetch character
|
|---|
| 837 | TEST AL, AL ; End of argument?
|
|---|
| 838 | JZ SHORT AC_299 ; Yes -> don't quote (AL=0)
|
|---|
| 839 | CMP AL, "?" ; Wildcard character?
|
|---|
| 840 | JE SHORT AC_299 ; Yes -> quote (AL non-zero)
|
|---|
| 841 | CMP AL, "*" ; Wildcard character?
|
|---|
| 842 | JNE SHORT AC_200 ; No -> check next character
|
|---|
| 843 | AC_299: POP ESI
|
|---|
| 844 | TEST AL, AL
|
|---|
| 845 | JZ SHORT ARG_CHECK_NO
|
|---|
| 846 | ARG_CHECK_YES: MOV AH, 1 ; Flag for closing quote
|
|---|
| 847 | INC DX
|
|---|
| 848 | CMP DX, CMD_LINE_SIZE - 2 ; Too long?
|
|---|
| 849 | JA SHORT DONE ; Yes -> end
|
|---|
| 850 | MOV AL, '"' ; Store opening quote
|
|---|
| 851 | STOS BYTE PTR ES:[DI]
|
|---|
| 852 | ARG_CHECK_NO: XOR CX, CX ; Clear backslash counter
|
|---|
| 853 | ;
|
|---|
| 854 | ; Copy argument
|
|---|
| 855 | ;
|
|---|
| 856 | ARG_COPY: LODS BYTE PTR DS:[ESI] ; Fetch character
|
|---|
| 857 | OR AL, AL ; End of argument?
|
|---|
| 858 | JZ SHORT ARG_END ; Yes -> next argument
|
|---|
| 859 | CMP NO_QUOTE, FALSE ; Quoting disabled?
|
|---|
| 860 | JNE SHORT ARG_STORE ; Yes -> simply store the char
|
|---|
| 861 | CMP AL, "\" ; Backslash?
|
|---|
| 862 | JE SHORT ARG_BACKSLASH ; Yes -> count
|
|---|
| 863 | CMP AL, '"' ; Quote?
|
|---|
| 864 | JE SHORT ARG_QUOTE ; Yes -> handle backslashes
|
|---|
| 865 | XOR CX, CX ; Clear backslash counter
|
|---|
| 866 | ARG_STORE: INC DX
|
|---|
| 867 | CMP DX, CMD_LINE_SIZE - 2 ; Too long?
|
|---|
| 868 | JA SHORT DONE ; Yes -> end
|
|---|
| 869 | STOS BYTE PTR ES:[DI]
|
|---|
| 870 | JMP SHORT ARG_COPY
|
|---|
| 871 |
|
|---|
| 872 | TALIGN 4
|
|---|
| 873 | ARG_BACKSLASH: INC CX ; Increment backslash counter
|
|---|
| 874 | JMP SHORT ARG_STORE ; Store character
|
|---|
| 875 |
|
|---|
| 876 | TALIGN 4
|
|---|
| 877 | ARG_QUOTE: INC CX ; 2n+1 backslashes
|
|---|
| 878 | ADD DX, CX
|
|---|
| 879 | CMP DX, CMD_LINE_SIZE - 2 ; Too long?
|
|---|
| 880 | JA SHORT DONE ; Yes -> end
|
|---|
| 881 | MOV AL, "\" ; Store backslashes
|
|---|
| 882 | ARG_QUOTE_1: STOSB
|
|---|
| 883 | LOOP ARG_QUOTE_1
|
|---|
| 884 | MOV AL, '"'
|
|---|
| 885 | JMP SHORT ARG_STORE
|
|---|
| 886 |
|
|---|
| 887 | ARG_END: OR AH, AH ; Closing quote required?
|
|---|
| 888 | JZ SHORT MORE ; No -> skip
|
|---|
| 889 | JCXZ ARG_END_2
|
|---|
| 890 | ADD DX, CX
|
|---|
| 891 | CMP DX, CMD_LINE_SIZE - 2 ; Too long?
|
|---|
| 892 | JA SHORT DONE ; Yes -> end
|
|---|
| 893 | MOV AL, "\"
|
|---|
| 894 | ARG_END_1: STOSB
|
|---|
| 895 | LOOP ARG_END_1
|
|---|
| 896 | ARG_END_2: MOV AL, '"'
|
|---|
| 897 | INC DX
|
|---|
| 898 | CMP DX, CMD_LINE_SIZE - 2 ; Too long?
|
|---|
| 899 | JA SHORT DONE ; Yes -> end
|
|---|
| 900 | STOSB
|
|---|
| 901 | MORE: DEC ARG_COUNTER
|
|---|
| 902 | JNZ NEXT
|
|---|
| 903 | DONE: POP DS ; Restore DS
|
|---|
| 904 | ASSUME DS:SV_DATA
|
|---|
| 905 | CMP DX, CMD_LINE_SIZE - 2
|
|---|
| 906 | JA SHORT TOO_BIG
|
|---|
| 907 | MOV CMD_LINE[0], DL ; Length = 0
|
|---|
| 908 | MOV AL, CR
|
|---|
| 909 | STOS BYTE PTR ES:[DI] ; End of command line
|
|---|
| 910 | CLC
|
|---|
| 911 | FIN: RET
|
|---|
| 912 |
|
|---|
| 913 | TOO_BIG: STC
|
|---|
| 914 | JMP SHORT FIN
|
|---|
| 915 | DOS_ARGS ENDP
|
|---|
| 916 |
|
|---|
| 917 |
|
|---|
| 918 | ; ----------------------------------------------------------------------------
|
|---|
| 919 | ;
|
|---|
| 920 | ; Build environment for DOS program
|
|---|
| 921 | ;
|
|---|
| 922 | ; Out: AX errno (0 if no error)
|
|---|
| 923 | ; PB_ENV Segment of environment
|
|---|
| 924 | ;
|
|---|
| 925 | ; ----------------------------------------------------------------------------
|
|---|
| 926 | DOS_ENV PROC NEAR
|
|---|
| 927 | CMP NP2.NP_ENV_SIZE, 8000H ; Fail with E2BIG if the
|
|---|
| 928 | MOV AX, E2BIG ; environment is too big
|
|---|
| 929 | JAE SHORT ERR
|
|---|
| 930 | ;
|
|---|
| 931 | ; Copy the environment to the real-mode buffer (that buffer is not used
|
|---|
| 932 | ; for INT 21H, AH=4BH).
|
|---|
| 933 | ;
|
|---|
| 934 | MOV AX, NP2.NP_ENV_SEL
|
|---|
| 935 | MOV ESI, NP2.NP_ENV_OFF
|
|---|
| 936 | MOV EDI, 0 ; OFFSET_1 is not zero!
|
|---|
| 937 | MOVZX ECX, NP2.NP_ENV_SIZE
|
|---|
| 938 | CALL MOVE_TO_RM
|
|---|
| 939 | MOV AX, BUF_SEG ; Set the environment pointer
|
|---|
| 940 | MOV PB_ENV, AX ; in the parameter block
|
|---|
| 941 | OK: XOR AX, AX ; No error
|
|---|
| 942 | ERR: RET
|
|---|
| 943 | DOS_ENV ENDP
|
|---|
| 944 |
|
|---|
| 945 |
|
|---|
| 946 | ; ----------------------------------------------------------------------------
|
|---|
| 947 | ; Copy NEW_PROC (_new_proc) structure from user process' data segment to
|
|---|
| 948 | ; supervisor data segment
|
|---|
| 949 | ;
|
|---|
| 950 | ; In: I_EDX Pointer to structure in user process' data segment
|
|---|
| 951 | ;
|
|---|
| 952 | ; ----------------------------------------------------------------------------
|
|---|
| 953 | TALIGN 4
|
|---|
| 954 | MAKE_NP2 PROC NEAR
|
|---|
| 955 | PUSH DS
|
|---|
| 956 | XOR EDI, EDI
|
|---|
| 957 | LEA DI, NP2
|
|---|
| 958 | MOV_ES_DS
|
|---|
| 959 | MOV ESI, I_EDX
|
|---|
| 960 | MOV DS, I_DS
|
|---|
| 961 | ASSUME DS:NOTHING
|
|---|
| 962 | MOV ECX, NP_USER_SIZE
|
|---|
| 963 | REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]
|
|---|
| 964 | POP DS
|
|---|
| 965 | ASSUME DS:SV_DATA
|
|---|
| 966 | MOV NP2.NP_MODE2, 0
|
|---|
| 967 | TEST NP2.NP_MODE1, 8000H
|
|---|
| 968 | JZ SHORT MNP2_1
|
|---|
| 969 | MOV ES, I_DS
|
|---|
| 970 | MOV ESI, I_EDX
|
|---|
| 971 | ASSUME ESI:NEAR32 PTR NEW_PROC
|
|---|
| 972 | MOV AX, ES:[ESI].NP_MODE2
|
|---|
| 973 | MOV NP2.NP_MODE2, AX
|
|---|
| 974 | ASSUME ESI:NOTHING
|
|---|
| 975 | MNP2_1: RET
|
|---|
| 976 | MAKE_NP2 ENDP
|
|---|
| 977 |
|
|---|
| 978 |
|
|---|
| 979 | ; ----------------------------------------------------------------------------
|
|---|
| 980 | ; AX=7F09H: __wait()
|
|---|
| 981 | ;
|
|---|
| 982 | ; Wait for child process
|
|---|
| 983 | ;
|
|---|
| 984 | ; In: --
|
|---|
| 985 | ;
|
|---|
| 986 | ; Out: EAX Process ID of child process (-1 if no children)
|
|---|
| 987 | ; ECX errno
|
|---|
| 988 | ; EDX Termination status
|
|---|
| 989 | ;
|
|---|
| 990 | ; ----------------------------------------------------------------------------
|
|---|
| 991 | TALIGN 4
|
|---|
| 992 | ASSUME DI:PTR PROCESS
|
|---|
| 993 | SYS09: TEST [DI].P_FLAGS, PF_PSEUDO_ASYNC ; Pseudo async child?
|
|---|
| 994 | JNZ SHORT WAIT_PSEUDO ; Yes -> return its status
|
|---|
| 995 | MOV EAX, [DI].P_PID ; Get process ID
|
|---|
| 996 | CALL WAIT_PROCESS ; Look for children
|
|---|
| 997 | CMP BX, NO_PROCESS ; Children?
|
|---|
| 998 | JE SHORT SYS09_ERROR ; No -> error
|
|---|
| 999 | CMP BX, NO_WPROCESS ; Stopped/terminated children?
|
|---|
| 1000 | JE SHORT SYS09_WAIT ; No -> wait
|
|---|
| 1001 | ASSUME BX:PTR PROCESS
|
|---|
| 1002 | AND [BX].P_FLAGS, NOT PF_WAIT_WAIT ; wait done
|
|---|
| 1003 | MOV EAX, [BX].P_PID ; Return process ID
|
|---|
| 1004 | MOV I_EAX, EAX
|
|---|
| 1005 | XOR EAX, EAX ; Termination status := 0
|
|---|
| 1006 | CMP [BX].P_STATUS, PS_STOP ; Stopped process?
|
|---|
| 1007 | JE SHORT SYS09_STOP ; Yes ->
|
|---|
| 1008 | MOV AH, [BX].P_RC ; Return code -> bits 8..15
|
|---|
| 1009 | JMP SHORT SYS09_OK
|
|---|
| 1010 | SYS09_STOP: MOV AL, 177Q
|
|---|
| 1011 | MOV AH, [BX].P_SIG_NO ; Signal number
|
|---|
| 1012 | SYS09_OK: MOV I_EDX, EAX ; Return status in EDX
|
|---|
| 1013 | MOV I_ECX, 0 ; No error
|
|---|
| 1014 | CMP [BX].P_STATUS, PS_DEFUNCT ; Zombie process?
|
|---|
| 1015 | JNE SHORT SYS09_RET ; No -> skip
|
|---|
| 1016 | CALL KILL_PROCESS ; Remove last vestiges
|
|---|
| 1017 | ASSUME BX:NOTHING
|
|---|
| 1018 | SYS09_RET: RET
|
|---|
| 1019 |
|
|---|
| 1020 |
|
|---|
| 1021 | ;
|
|---|
| 1022 | ; There are children, but no one stopped/terminated. Wait.
|
|---|
| 1023 | ; Not implemented, return error.
|
|---|
| 1024 | ;
|
|---|
| 1025 | SYS09_WAIT:
|
|---|
| 1026 | SYS09_ERROR: MOV I_ECX, ECHILD
|
|---|
| 1027 | MOV I_EAX, -1
|
|---|
| 1028 | RET
|
|---|
| 1029 |
|
|---|
| 1030 | ;
|
|---|
| 1031 | ; We had a pseudo asynchronous child process. Return its termination
|
|---|
| 1032 | ; status.
|
|---|
| 1033 | ;
|
|---|
| 1034 | WAIT_PSEUDO: AND [DI].P_FLAGS, NOT PF_PSEUDO_ASYNC ; Child is dead
|
|---|
| 1035 | XOR EAX, EAX
|
|---|
| 1036 | MOV AH, [DI].P_RC ; Get the return code
|
|---|
| 1037 | MOV I_EDX, EAX ; Set termination status
|
|---|
| 1038 | MOV EAX, [DI].P_SPAWN_RC ; Process ID
|
|---|
| 1039 | MOV I_EAX, EAX
|
|---|
| 1040 | MOV I_ECX, 0 ; No error
|
|---|
| 1041 | RET
|
|---|
| 1042 |
|
|---|
| 1043 | ASSUME DI:NOTHING
|
|---|
| 1044 |
|
|---|
| 1045 |
|
|---|
| 1046 | ; ----------------------------------------------------------------------------
|
|---|
| 1047 | ; AX=7F0AH: version
|
|---|
| 1048 | ;
|
|---|
| 1049 | ; Return emx version
|
|---|
| 1050 | ;
|
|---|
| 1051 | ; In: --
|
|---|
| 1052 | ;
|
|---|
| 1053 | ; Out: EAX Version number
|
|---|
| 1054 | ; Bits 0..7: version letter ("a".."z")
|
|---|
| 1055 | ; Bits 8..15: minor version number ("0".."9")
|
|---|
| 1056 | ; Bits 16..23: 2EH (".")
|
|---|
| 1057 | ; Bits 24..31: major version number ("0".."9")
|
|---|
| 1058 | ; EBX Environment:
|
|---|
| 1059 | ; Bit 0: VCPI
|
|---|
| 1060 | ; Bit 1: XMS
|
|---|
| 1061 | ; Bit 2: VDISK.SYS 3.3
|
|---|
| 1062 | ; Bit 3: DESQview
|
|---|
| 1063 | ; Bit 4: 287
|
|---|
| 1064 | ; Bit 5: 387
|
|---|
| 1065 | ; Bit 6: 486 (not implemented)
|
|---|
| 1066 | ; Bit 7: DPMI 0.9 (not implemented)
|
|---|
| 1067 | ; Bit 8: DPMI 1.0 (not implemented)
|
|---|
| 1068 | ; Bit 9: OS/2 2.0
|
|---|
| 1069 | ; Bit 10: -t option given
|
|---|
| 1070 | ; Bits 6..31: 0 (reserved for future expansion)
|
|---|
| 1071 | ; ECX Revision index
|
|---|
| 1072 | ; EDX 0 (reserved for future expansion)
|
|---|
| 1073 | ;
|
|---|
| 1074 | ; ----------------------------------------------------------------------------
|
|---|
| 1075 | TALIGN 4
|
|---|
| 1076 | ASSUME DI:PTR PROCESS
|
|---|
| 1077 | SYS0A: MOV I_EAX, VERSION ; Return version number in EAX
|
|---|
| 1078 | XOR EAX, EAX ; Clear all environment bits
|
|---|
| 1079 | CMP VCPI_FLAG, FALSE
|
|---|
| 1080 | JE SHORT SYS0A_1
|
|---|
| 1081 | OR AL, 01H ; Set VCPI bit
|
|---|
| 1082 | SYS0A_1: CMP XMS_FLAG, FALSE
|
|---|
| 1083 | JE SHORT SYS0A_2
|
|---|
| 1084 | OR AL, 02H ; Set XMS bit
|
|---|
| 1085 | SYS0A_2: CMP VDISK_FLAG, FALSE
|
|---|
| 1086 | JE SHORT SYS0A_3
|
|---|
| 1087 | OR AL, 04H ; Set VDISK bit
|
|---|
| 1088 | SYS0A_3: CMP DV_FLAG, FALSE
|
|---|
| 1089 | JE SHORT SYS0A_4
|
|---|
| 1090 | OR AL, 08H ; Set DESQview bit
|
|---|
| 1091 | SYS0A_4: CMP FP_FLAG, FP_287
|
|---|
| 1092 | JNE SHORT SYS0A_5
|
|---|
| 1093 | OR AL, 10H ; Set 287 bit
|
|---|
| 1094 | SYS0A_5: CMP FP_FLAG, FP_387
|
|---|
| 1095 | JNE SHORT SYS0A_6
|
|---|
| 1096 | OR AL, 20H ; Set 387 bit
|
|---|
| 1097 | SYS0A_6: CMP [DI].P_TRUNC, 0
|
|---|
| 1098 | JE SHORT SYS0A_7
|
|---|
| 1099 | OR AX, 400H ; Set -t bit
|
|---|
| 1100 | SYS0A_7: TEST [DI].P_HW_ACCESS, HW_ACCESS_CODE
|
|---|
| 1101 | JZ SHORT SYS0A_8
|
|---|
| 1102 | OR AX, 800H ; Set -ac bit
|
|---|
| 1103 | SYS0A_8: MOV I_EBX, EAX
|
|---|
| 1104 | MOV I_ECX, REV_INDEX_BIN ; Revision index
|
|---|
| 1105 | MOV I_EDX, 0 ; Reserved
|
|---|
| 1106 | RET
|
|---|
| 1107 |
|
|---|
| 1108 | ASSUME DI:NOTHING
|
|---|
| 1109 |
|
|---|
| 1110 | ; ----------------------------------------------------------------------------
|
|---|
| 1111 | ; AX=7F0BH: memavail
|
|---|
| 1112 | ;
|
|---|
| 1113 | ; Return number of available pages of memory (w/o swapping)
|
|---|
| 1114 | ;
|
|---|
| 1115 | ; In: --
|
|---|
| 1116 | ;
|
|---|
| 1117 | ; Out: EAX Number of available pages
|
|---|
| 1118 | ;
|
|---|
| 1119 | ; ----------------------------------------------------------------------------
|
|---|
| 1120 | TALIGN 4
|
|---|
| 1121 | SYS0B: CALL PM_AVAIL ; This call does all the work
|
|---|
| 1122 | MOV I_EAX, EAX ; Return the result in EAX
|
|---|
| 1123 | RET
|
|---|
| 1124 |
|
|---|
| 1125 | ; ----------------------------------------------------------------------------
|
|---|
| 1126 | ; AX=7F0CH: __signal()
|
|---|
| 1127 | ;
|
|---|
| 1128 | ; Set signal handler
|
|---|
| 1129 | ;
|
|---|
| 1130 | ; In: ECX Signal number
|
|---|
| 1131 | ; EDX Address of signal handler or SIG_ACK, SIG_DFL, SIG_IGN
|
|---|
| 1132 | ;
|
|---|
| 1133 | ; Out: EAX Previous value (success) or SIG_ERR (error)
|
|---|
| 1134 | ;
|
|---|
| 1135 | ; ----------------------------------------------------------------------------
|
|---|
| 1136 | TALIGN 4
|
|---|
| 1137 | ASSUME DI:PTR PROCESS
|
|---|
| 1138 | SYS0C: MOV EAX, I_ECX ; Signal number
|
|---|
| 1139 | MOV EDX, I_EDX ; Signal handler
|
|---|
| 1140 | CMP EDX, SIG_ACK ; Acknowledge?
|
|---|
| 1141 | JE SHORT SIGNAL_ACK ; Yes ->
|
|---|
| 1142 | CALL DO_SIGNAL
|
|---|
| 1143 | MOV I_EAX, EAX
|
|---|
| 1144 | RET
|
|---|
| 1145 |
|
|---|
| 1146 | ;
|
|---|
| 1147 | ; Unblock the signal EAX. If there is a pending signal, it will be
|
|---|
| 1148 | ; raised on return to the current process.
|
|---|
| 1149 | ;
|
|---|
| 1150 | SIGNAL_ACK: CMP EAX, SIGNALS ; Valid signal number?
|
|---|
| 1151 | JAE SHORT SIGNAL_ERROR ; No -> failure
|
|---|
| 1152 | CMP SIG_VALID[EAX], FALSE
|
|---|
| 1153 | JE SHORT SIGNAL_ERROR ; No -> failure
|
|---|
| 1154 | MOV BX, AX
|
|---|
| 1155 | SHL BX, 2
|
|---|
| 1156 | TEST [DI].P_SA_FLAGS[BX], SA_ACK ; SA_ACK set?
|
|---|
| 1157 | JZ SHORT SIGNAL_ERROR ; No -> failure
|
|---|
| 1158 | BTR [DI].P_SIG_BLOCKED, EAX ; Unblock the signal
|
|---|
| 1159 | MOV EAX, [DI].P_SIG_HANDLERS[BX] ; Get previous value
|
|---|
| 1160 | MOV I_EAX, EAX ; Return previous value
|
|---|
| 1161 | RET
|
|---|
| 1162 |
|
|---|
| 1163 | SIGNAL_ERROR: MOV I_EAX, SIG_ERR ; Return SIG_ERR
|
|---|
| 1164 | RET
|
|---|
| 1165 |
|
|---|
| 1166 | ASSUME DI:NOTHING
|
|---|
| 1167 |
|
|---|
| 1168 | ; ----------------------------------------------------------------------------
|
|---|
| 1169 | ; AX=7F0DH: __kill()
|
|---|
| 1170 | ;
|
|---|
| 1171 | ; Send a signal to a process
|
|---|
| 1172 | ;
|
|---|
| 1173 | ; In: ECX Signal number
|
|---|
| 1174 | ; EDX Process ID
|
|---|
| 1175 | ;
|
|---|
| 1176 | ; Out: EAX 0 if successful, -1 otherwise
|
|---|
| 1177 | ; ECX errno
|
|---|
| 1178 | ;
|
|---|
| 1179 | ; (As we don't have real multitasking, we should switch to the other
|
|---|
| 1180 | ; process.)
|
|---|
| 1181 | ;
|
|---|
| 1182 | ; ----------------------------------------------------------------------------
|
|---|
| 1183 | TALIGN 4
|
|---|
| 1184 | SYS0D: MOV EAX, I_EDX ; Get process ID
|
|---|
| 1185 | CALL FIND_PROCESS ; Find process for given ID
|
|---|
| 1186 | CMP BX, NO_PROCESS ; Found?
|
|---|
| 1187 | JE SHORT KILL_BAD_PID ; No -> error
|
|---|
| 1188 | CMP I_ECX, 0 ; Signal 0 (check PID)?
|
|---|
| 1189 | JE SHORT RAISE_OK ; Yes -> ok
|
|---|
| 1190 | MOV DI, BX ; Copy process pointer to DI
|
|---|
| 1191 | ;
|
|---|
| 1192 | ; Fall through to __raise() code
|
|---|
| 1193 | ;
|
|---|
| 1194 | ; ----------------------------------------------------------------------------
|
|---|
| 1195 | ; AX=7F0EH: __raise()
|
|---|
| 1196 | ;
|
|---|
| 1197 | ; Raise a signal (in current process)
|
|---|
| 1198 | ;
|
|---|
| 1199 | ; In: ECX Signal number
|
|---|
| 1200 | ;
|
|---|
| 1201 | ; Out: EAX 0 if successful, a non-zero value otherwise
|
|---|
| 1202 | ; ECX errno
|
|---|
| 1203 | ;
|
|---|
| 1204 | ; ----------------------------------------------------------------------------
|
|---|
| 1205 | TALIGN 4
|
|---|
| 1206 | ASSUME DI:PTR PROCESS
|
|---|
| 1207 | SYS0E: MOV EAX, I_ECX ; Get signal number
|
|---|
| 1208 | CMP EAX, SIGNALS ; Valid signal number?
|
|---|
| 1209 | JAE SHORT RAISE_ERROR ; No -> failure
|
|---|
| 1210 | CMP SIG_VALID[EAX], FALSE
|
|---|
| 1211 | JE SHORT RAISE_ERROR ; No -> failure
|
|---|
| 1212 | BTS [DI].P_SIG_PENDING, EAX ; Generate signal
|
|---|
| 1213 | RAISE_OK: MOV I_ECX, 0 ; No error
|
|---|
| 1214 | MOV I_EAX, 0 ; Success
|
|---|
| 1215 | RET
|
|---|
| 1216 |
|
|---|
| 1217 | RAISE_ERROR: MOV I_ECX, EINVAL
|
|---|
| 1218 | MOV I_EAX, -1 ; Error
|
|---|
| 1219 | RET
|
|---|
| 1220 |
|
|---|
| 1221 | KILL_BAD_PID: MOV I_ECX, ESRCH
|
|---|
| 1222 | MOV I_EAX, -1
|
|---|
| 1223 | RET
|
|---|
| 1224 |
|
|---|
| 1225 | ASSUME DI:NOTHING
|
|---|
| 1226 |
|
|---|
| 1227 | ; ----------------------------------------------------------------------------
|
|---|
| 1228 | ; AX=7F0FH: EAX:=uflags(ECX,EDX)
|
|---|
| 1229 | ;
|
|---|
| 1230 | ; Set user flags
|
|---|
| 1231 | ;
|
|---|
| 1232 | ; ----------------------------------------------------------------------------
|
|---|
| 1233 | TALIGN 4
|
|---|
| 1234 | ASSUME DI:PTR PROCESS
|
|---|
| 1235 | SYS0F: MOV EAX, [DI].P_UFLAGS
|
|---|
| 1236 | MOV I_EAX, EAX ; Return previous value
|
|---|
| 1237 | MOV ECX, I_ECX ; Get mask
|
|---|
| 1238 | MOV EDX, I_EDX ; Get new bits
|
|---|
| 1239 | AND EDX, ECX ; Clear unwanted bits
|
|---|
| 1240 | NOT ECX
|
|---|
| 1241 | AND EAX, ECX ; Clear bits to be changed
|
|---|
| 1242 | OR EAX, EDX ; Insert new bits
|
|---|
| 1243 | MOV [DI].P_UFLAGS, EAX ; Store new value
|
|---|
| 1244 | RET
|
|---|
| 1245 |
|
|---|
| 1246 | ASSUME DI:NOTHING
|
|---|
| 1247 |
|
|---|
| 1248 | ; ----------------------------------------------------------------------------
|
|---|
| 1249 | ; AX=7F10H: __unwind()
|
|---|
| 1250 | ;
|
|---|
| 1251 | ; Unwind signal handlers for longjmp()
|
|---|
| 1252 | ;
|
|---|
| 1253 | ; Currently not used by the DOS version of emx.
|
|---|
| 1254 | ;
|
|---|
| 1255 | ; ----------------------------------------------------------------------------
|
|---|
| 1256 |
|
|---|
| 1257 | TALIGN 4
|
|---|
| 1258 | SYS10: RET
|
|---|
| 1259 |
|
|---|
| 1260 | ; ----------------------------------------------------------------------------
|
|---|
| 1261 | ; AX=7F11H: __core()
|
|---|
| 1262 | ;
|
|---|
| 1263 | ; Write core image file
|
|---|
| 1264 | ;
|
|---|
| 1265 | ; In: EBX File handle
|
|---|
| 1266 | ;
|
|---|
| 1267 | ; Out: CY Error
|
|---|
| 1268 | ; EAX errno (CY)
|
|---|
| 1269 | ;
|
|---|
| 1270 | ; ----------------------------------------------------------------------------
|
|---|
| 1271 |
|
|---|
| 1272 | TALIGN 4
|
|---|
| 1273 | SYS11: MOV BX, DI ; Process table entry
|
|---|
| 1274 | CALL CORE_REGS_I
|
|---|
| 1275 | MOV EAX, I_EBX ; Get file handle
|
|---|
| 1276 | CALL CORE_MAIN ; Write core image file
|
|---|
| 1277 | JNC SHORT SYS11_RET
|
|---|
| 1278 | OR I_EFLAGS, FLAG_C
|
|---|
| 1279 | CALL DOS_ERROR_TO_ERRNO
|
|---|
| 1280 | MOV I_EAX, EAX
|
|---|
| 1281 | SYS11_RET: RET
|
|---|
| 1282 |
|
|---|
| 1283 | ; ----------------------------------------------------------------------------
|
|---|
| 1284 | ; AX=7F12H: _portaccess()
|
|---|
| 1285 | ;
|
|---|
| 1286 | ; Enable access to I/O ports
|
|---|
| 1287 | ;
|
|---|
| 1288 | ; In: ECX First port number
|
|---|
| 1289 | ; EDX Last port number
|
|---|
| 1290 | ;
|
|---|
| 1291 | ; Out: CY Failed
|
|---|
| 1292 | ; EAX errno (0 if successful)
|
|---|
| 1293 | ;
|
|---|
| 1294 | ; ----------------------------------------------------------------------------
|
|---|
| 1295 |
|
|---|
| 1296 | TALIGN 4
|
|---|
| 1297 | ASSUME DI:PTR PROCESS
|
|---|
| 1298 | SYS12: MOV EAX, I_ECX
|
|---|
| 1299 | CMP EAX, 10000H
|
|---|
| 1300 | JAE SHORT PORTACCESS_ERR
|
|---|
| 1301 | MOV ECX, I_EDX
|
|---|
| 1302 | CMP ECX, 10000H
|
|---|
| 1303 | JAE SHORT PORTACCESS_ERR
|
|---|
| 1304 | SUB ECX, EAX
|
|---|
| 1305 | JB SHORT PORTACCESS_ERR
|
|---|
| 1306 | INC ECX
|
|---|
| 1307 | TEST [DI].P_HW_ACCESS, HW_ACCESS_IO
|
|---|
| 1308 | JZ SHORT PORTACCESS_ERR
|
|---|
| 1309 | CMP NEW_TSS, FALSE
|
|---|
| 1310 | JE SHORT PORTACCESS_ERR
|
|---|
| 1311 | MOV DX, G_TSS_MEM_SEL
|
|---|
| 1312 | MOV FS, DX
|
|---|
| 1313 | MOVZX EBX, (TSS_STRUC PTR FS:[0]).TSS_BIT_MAP_OFF
|
|---|
| 1314 | PORTACCESS_1: BTR DWORD PTR FS:[EBX], EAX
|
|---|
| 1315 | INC EAX
|
|---|
| 1316 | LOOPD PORTACCESS_1
|
|---|
| 1317 | MOV I_EAX, 0
|
|---|
| 1318 | RET
|
|---|
| 1319 |
|
|---|
| 1320 | PORTACCESS_ERR: MOV I_EAX, EACCES
|
|---|
| 1321 | OR I_EFLAGS, FLAG_C
|
|---|
| 1322 | RET
|
|---|
| 1323 |
|
|---|
| 1324 | ASSUME DI:NOTHING
|
|---|
| 1325 |
|
|---|
| 1326 | ; ----------------------------------------------------------------------------
|
|---|
| 1327 | ; AX=7F13H: _memaccess()
|
|---|
| 1328 | ;
|
|---|
| 1329 | ; Enable access to memory
|
|---|
| 1330 | ;
|
|---|
| 1331 | ; In: EBX First address
|
|---|
| 1332 | ; ECX Last address
|
|---|
| 1333 | ; EDX 0: read access, 1:write access
|
|---|
| 1334 | ;
|
|---|
| 1335 | ; Out: CY Failed
|
|---|
| 1336 | ; EAX errno if failed (CY)
|
|---|
| 1337 | ; EAX Pointer to start of mapped memory area (NC)
|
|---|
| 1338 | ;
|
|---|
| 1339 | ; ----------------------------------------------------------------------------
|
|---|
| 1340 |
|
|---|
| 1341 | TALIGN 4
|
|---|
| 1342 | ASSUME DI:PTR PROCESS
|
|---|
| 1343 | SYS13: CMP I_EDX, 1
|
|---|
| 1344 | JA MEMACCESS_INV
|
|---|
| 1345 | MOV EAX, I_EBX
|
|---|
| 1346 | TEST EAX, 0FFFH
|
|---|
| 1347 | JNZ MEMACCESS_ACC
|
|---|
| 1348 | MOV ECX, I_ECX
|
|---|
| 1349 | INC ECX
|
|---|
| 1350 | JNZ SHORT MEMACCESS_01
|
|---|
| 1351 | OR EAX, EAX
|
|---|
| 1352 | JZ MEMACCESS_MEM
|
|---|
| 1353 | SUB ECX, EAX
|
|---|
| 1354 | JMP SHORT MEMACCESS_02
|
|---|
| 1355 | MEMACCESS_01: TEST ECX, 0FFFH
|
|---|
| 1356 | JNZ MEMACCESS_ACC
|
|---|
| 1357 | SUB ECX, EAX
|
|---|
| 1358 | JBE MEMACCESS_ACC
|
|---|
| 1359 | MEMACCESS_02: TEST [DI].P_HW_ACCESS, HW_ACCESS_MEM
|
|---|
| 1360 | JZ MEMACCESS_ACC
|
|---|
| 1361 | MOV EBX, I_EBX
|
|---|
| 1362 | OR EBX, PAGE_PRESENT OR PAGE_USER OR PAGE_LOCKED
|
|---|
| 1363 | CMP I_EDX, 0
|
|---|
| 1364 | JE SHORT MEMACCESS_RD
|
|---|
| 1365 | CMP I_EBX, 0A0000H
|
|---|
| 1366 | JB SHORT MEMACCESS_DNG ; Danger!
|
|---|
| 1367 | CMP I_ECX, 0BFFFFH
|
|---|
| 1368 | JBE SHORT MEMACCESS_WR
|
|---|
| 1369 | MEMACCESS_DNG: TEST [DI].P_HW_ACCESS, HW_ACCESS_WRITE
|
|---|
| 1370 | JZ SHORT MEMACCESS_ACC
|
|---|
| 1371 | MEMACCESS_WR: OR EBX, PAGE_WRITE
|
|---|
| 1372 | MEMACCESS_RD: MOV EDX, SRC_NONE
|
|---|
| 1373 | SHR ECX, 12
|
|---|
| 1374 | CALL MAP_PHYS
|
|---|
| 1375 | TEST EAX, EAX
|
|---|
| 1376 | JZ SHORT MEMACCESS_MEM
|
|---|
| 1377 | MOV I_EAX, EAX
|
|---|
| 1378 | RET
|
|---|
| 1379 |
|
|---|
| 1380 | MEMACCESS_INV: MOV I_EAX, EINVAL
|
|---|
| 1381 | OR I_EFLAGS, FLAG_C
|
|---|
| 1382 | RET
|
|---|
| 1383 |
|
|---|
| 1384 | MEMACCESS_ACC: MOV I_EAX, EACCES
|
|---|
| 1385 | OR I_EFLAGS, FLAG_C
|
|---|
| 1386 | RET
|
|---|
| 1387 |
|
|---|
| 1388 | MEMACCESS_MEM: MOV I_EAX, ENOMEM
|
|---|
| 1389 | OR I_EFLAGS, FLAG_C
|
|---|
| 1390 | RET
|
|---|
| 1391 |
|
|---|
| 1392 | ASSUME DI:NOTHING
|
|---|
| 1393 |
|
|---|
| 1394 | ; ----------------------------------------------------------------------------
|
|---|
| 1395 | ; AX=7F14H: __ioctl2()
|
|---|
| 1396 | ;
|
|---|
| 1397 | ; UNIX-like termio ioctl()
|
|---|
| 1398 | ;
|
|---|
| 1399 | ; In: EBX Handle
|
|---|
| 1400 | ; ECX Request code
|
|---|
| 1401 | ; EDX Argument
|
|---|
| 1402 | ;
|
|---|
| 1403 | ; Out: EAX Return value
|
|---|
| 1404 | ; ECX errno
|
|---|
| 1405 | ;
|
|---|
| 1406 | ; ----------------------------------------------------------------------------
|
|---|
| 1407 |
|
|---|
| 1408 | TALIGN 4
|
|---|
| 1409 | SYS14: CMP I_ECX, TCGETA
|
|---|
| 1410 | JE SHORT TC_GETA
|
|---|
| 1411 | CMP I_ECX, TCSETA
|
|---|
| 1412 | JE SHORT TC_SETA
|
|---|
| 1413 | CMP I_ECX, TCSETAW
|
|---|
| 1414 | JE SHORT TC_SETA
|
|---|
| 1415 | CMP I_ECX, TCSETAF
|
|---|
| 1416 | JE SHORT TC_SETAF
|
|---|
| 1417 | CMP I_ECX, TCFLSH
|
|---|
| 1418 | JE IOCTL_FLUSH
|
|---|
| 1419 | CMP I_ECX, TCXONC
|
|---|
| 1420 | JE IOCTL_XONC
|
|---|
| 1421 | CMP I_ECX, TCSBRK
|
|---|
| 1422 | JE IOCTL_SBRK
|
|---|
| 1423 | CMP I_ECX, _TCGA
|
|---|
| 1424 | JE SHORT TCS_GETA
|
|---|
| 1425 | CMP I_ECX, _TCSANOW
|
|---|
| 1426 | JE SHORT TCS_SETA
|
|---|
| 1427 | CMP I_ECX, _TCSADRAIN
|
|---|
| 1428 | JE SHORT TCS_SETA
|
|---|
| 1429 | CMP I_ECX, _TCSAFLUSH
|
|---|
| 1430 | JE SHORT TCS_SETAF
|
|---|
| 1431 | CMP I_ECX, FIONREAD
|
|---|
| 1432 | JE IOCTL_NREAD
|
|---|
| 1433 | CMP I_ECX, FGETHTYPE
|
|---|
| 1434 | JE IOCTL_HTYPE
|
|---|
| 1435 | JMP EMX_EINVAL
|
|---|
| 1436 |
|
|---|
| 1437 | TALIGN 4
|
|---|
| 1438 | TC_GETA: MOV EAX, I_EBX
|
|---|
| 1439 | MOV ES, I_DS
|
|---|
| 1440 | MOV EBX, I_EDX
|
|---|
| 1441 | CALL TERMIO_GET
|
|---|
| 1442 | TC_RET: MOV I_EAX, EAX
|
|---|
| 1443 | MOV I_ECX, ECX
|
|---|
| 1444 | RET
|
|---|
| 1445 |
|
|---|
| 1446 | TALIGN 4
|
|---|
| 1447 | TC_SETAF: MOV EAX, I_EBX
|
|---|
| 1448 | CALL TERMIO_FLUSH
|
|---|
| 1449 | OR EAX, EAX
|
|---|
| 1450 | JNZ SHORT TC_RET
|
|---|
| 1451 | TC_SETA: MOV EAX, I_EBX
|
|---|
| 1452 | MOV ES, I_DS
|
|---|
| 1453 | MOV EBX, I_EDX
|
|---|
| 1454 | CALL TERMIO_SET
|
|---|
| 1455 | JMP SHORT TC_RET
|
|---|
| 1456 |
|
|---|
| 1457 | TALIGN 4
|
|---|
| 1458 | TCS_GETA: MOV EAX, I_EBX
|
|---|
| 1459 | MOV ES, I_DS
|
|---|
| 1460 | MOV EBX, I_EDX
|
|---|
| 1461 | CALL TERMIOS_GET
|
|---|
| 1462 | JMP SHORT TC_RET
|
|---|
| 1463 |
|
|---|
| 1464 | TALIGN 4
|
|---|
| 1465 | TCS_SETAF: MOV EAX, I_EBX
|
|---|
| 1466 | CALL TERMIOS_FLUSH
|
|---|
| 1467 | OR EAX, EAX
|
|---|
| 1468 | JNZ SHORT TC_RET
|
|---|
| 1469 | TCS_SETA: MOV EAX, I_EBX
|
|---|
| 1470 | MOV ES, I_DS
|
|---|
| 1471 | MOV EBX, I_EDX
|
|---|
| 1472 | CALL TERMIOS_SET
|
|---|
| 1473 | JMP SHORT TC_RET
|
|---|
| 1474 |
|
|---|
| 1475 | ;
|
|---|
| 1476 | ; TCFLSH
|
|---|
| 1477 | ;
|
|---|
| 1478 | TALIGN 4
|
|---|
| 1479 | IOCTL_FLUSH: CMP I_EBX, 0 ; stdin?
|
|---|
| 1480 | JNE EMX_EBADF
|
|---|
| 1481 | CMP I_EDX, 0 ; Flush input queue
|
|---|
| 1482 | JE SHORT IOCTL_FLUSH_1
|
|---|
| 1483 | CMP I_EDX, 1 ; Flush output queue
|
|---|
| 1484 | JE EMX_OK ; Not implemented -- ignore
|
|---|
| 1485 | CMP I_EDX, 2 ; Flush input & output queues
|
|---|
| 1486 | JNE EMX_EINVAL ; No -> error
|
|---|
| 1487 | IOCTL_FLUSH_1: CALL KBD_FLUSH
|
|---|
| 1488 | JMP EMX_OK
|
|---|
| 1489 |
|
|---|
| 1490 | ;
|
|---|
| 1491 | ; TCSBRK (not implemented)
|
|---|
| 1492 | ;
|
|---|
| 1493 | TALIGN 4
|
|---|
| 1494 | IOCTL_SBRK: JMP EMX_OK
|
|---|
| 1495 |
|
|---|
| 1496 | ;
|
|---|
| 1497 | ; TCXCONC (not yet implemented)
|
|---|
| 1498 | ;
|
|---|
| 1499 | TALIGN 4
|
|---|
| 1500 | IOCTL_XONC: JMP EMX_OK
|
|---|
| 1501 |
|
|---|
| 1502 | TALIGN 4
|
|---|
| 1503 | IOCTL_NREAD: CMP I_EBX, 0 ; stdin?
|
|---|
| 1504 | JNE SHORT IOCTL_NREAD2 ; No -> check input status
|
|---|
| 1505 | TEST STDIN_TERMIO.C_LFLAG, IDEFAULT OR ICANON ; termio?
|
|---|
| 1506 | JNZ SHORT IOCTL_NREAD2 ; No -> check input status
|
|---|
| 1507 | CALL STDIN_AVAIL
|
|---|
| 1508 | IOCTL_NREAD1: MOV EBX, I_EDX
|
|---|
| 1509 | MOV ES, I_DS
|
|---|
| 1510 | MOV ES:[EBX], EAX
|
|---|
| 1511 | JMP EMX_OK
|
|---|
| 1512 |
|
|---|
| 1513 | IOCTL_NREAD2: MOV EBX, I_EBX ; Get file handle
|
|---|
| 1514 | MOV AX, 4406H ; IOCTL: Check input status
|
|---|
| 1515 | INT 21H
|
|---|
| 1516 | JC SHORT IOCTL_ERR ; Error -> done
|
|---|
| 1517 | OR AL, AL ; 00H=not ready, 0FFH=ready
|
|---|
| 1518 | MOV EAX, 0 ; No characters ready
|
|---|
| 1519 | JZ SHORT IOCTL_NREAD1 ; Not ready -> 0 characters
|
|---|
| 1520 | INC EAX ; Ready -> 1 character
|
|---|
| 1521 | JMP SHORT IOCTL_NREAD1
|
|---|
| 1522 |
|
|---|
| 1523 | IOCTL_ERR: MOV I_ECX, EAX
|
|---|
| 1524 | MOV I_EAX, -1
|
|---|
| 1525 | RET
|
|---|
| 1526 |
|
|---|
| 1527 | HT_FILE = 0
|
|---|
| 1528 | HT_UPIPE = 1
|
|---|
| 1529 | HT_NPIPE = 2
|
|---|
| 1530 | HT_DEV_OTHER = 3
|
|---|
| 1531 | HT_DEV_NUL = 4
|
|---|
| 1532 | HT_DEV_CON = 5
|
|---|
| 1533 | HT_DEV_CLK = 7
|
|---|
| 1534 |
|
|---|
| 1535 | TALIGN 4
|
|---|
| 1536 | IOCTL_HTYPE: MOV AX, 4400H
|
|---|
| 1537 | MOV EBX, I_EBX
|
|---|
| 1538 | INT 21H
|
|---|
| 1539 | JC SHORT HTYPE_ERR
|
|---|
| 1540 | MOV ECX, HT_FILE
|
|---|
| 1541 | TEST EDX, 80H
|
|---|
| 1542 | JZ SHORT HTYPE_RET
|
|---|
| 1543 | MOV ECX, HT_DEV_CON
|
|---|
| 1544 | TEST EDX, 03H
|
|---|
| 1545 | JNZ SHORT HTYPE_RET
|
|---|
| 1546 | MOV ECX, HT_DEV_NUL
|
|---|
| 1547 | TEST EDX, 04H
|
|---|
| 1548 | JNZ SHORT HTYPE_RET
|
|---|
| 1549 | MOV ECX, HT_DEV_CLK
|
|---|
| 1550 | TEST EDX, 08H
|
|---|
| 1551 | JNZ SHORT HTYPE_RET
|
|---|
| 1552 | MOV ECX, HT_DEV_OTHER
|
|---|
| 1553 | HTYPE_RET: MOV EBX, I_EDX
|
|---|
| 1554 | MOV ES, I_DS
|
|---|
| 1555 | MOV ES:[EBX], ECX
|
|---|
| 1556 | JMP EMX_OK
|
|---|
| 1557 |
|
|---|
| 1558 | HTYPE_ERR: MOV I_ECX, EAX
|
|---|
| 1559 | MOV I_EAX, -1
|
|---|
| 1560 | RET
|
|---|
| 1561 |
|
|---|
| 1562 |
|
|---|
| 1563 | ; ----------------------------------------------------------------------------
|
|---|
| 1564 | ; AX=7F15H: __alarm()
|
|---|
| 1565 | ;
|
|---|
| 1566 | ; Set alarm clock
|
|---|
| 1567 | ;
|
|---|
| 1568 | ; In: EDX Seconds
|
|---|
| 1569 | ;
|
|---|
| 1570 | ; Out: EAX Time remaining
|
|---|
| 1571 | ;
|
|---|
| 1572 | ; ----------------------------------------------------------------------------
|
|---|
| 1573 |
|
|---|
| 1574 | TALIGN 4
|
|---|
| 1575 | SYS15: MOV EAX, I_EDX
|
|---|
| 1576 | MOV ECX, 91
|
|---|
| 1577 | MUL ECX ; Multiply by 18.2
|
|---|
| 1578 | ADD EAX, 4
|
|---|
| 1579 | ADC EDX, 0
|
|---|
| 1580 | MOV ECX, 5
|
|---|
| 1581 | CMP EDX, ECX ; Overflow?
|
|---|
| 1582 | JAE SHORT ALARM_OV ; Yes -> use maximum value
|
|---|
| 1583 | DIV ECX
|
|---|
| 1584 | ALARM_SET: MOV BX, DI
|
|---|
| 1585 | MOV DX, TT_ALARM
|
|---|
| 1586 | CALL SET_TIMER
|
|---|
| 1587 | MOV I_EAX, 0
|
|---|
| 1588 | JC SHORT SYS15_RET
|
|---|
| 1589 | MOV ECX, 5
|
|---|
| 1590 | MUL ECX ; Divide by 18.2
|
|---|
| 1591 | MOV ECX, 91
|
|---|
| 1592 | DIV ECX
|
|---|
| 1593 | MOV I_EAX, EAX
|
|---|
| 1594 | SYS15_RET: RET
|
|---|
| 1595 |
|
|---|
| 1596 | ALARM_OV: MOV EAX, MAX_32 ; Use maximum value
|
|---|
| 1597 | JMP SHORT ALARM_SET
|
|---|
| 1598 |
|
|---|
| 1599 | ; ----------------------------------------------------------------------------
|
|---|
| 1600 | ; AX=7F16H: Used internally for polling the keyboard
|
|---|
| 1601 | ; ----------------------------------------------------------------------------
|
|---|
| 1602 |
|
|---|
| 1603 | TALIGN 4
|
|---|
| 1604 | SYS16: TEST I_CS, 3 ; Called from user code?
|
|---|
| 1605 | JNZ SYSCALL_ERROR ; Yes -> error
|
|---|
| 1606 | MOV RM_AX, 7F16H
|
|---|
| 1607 | CALL INT_RM
|
|---|
| 1608 | RET
|
|---|
| 1609 |
|
|---|
| 1610 | ; ----------------------------------------------------------------------------
|
|---|
| 1611 | ; AX=7F17H: __sleep()
|
|---|
| 1612 | ;
|
|---|
| 1613 | ; Suspend process
|
|---|
| 1614 | ;
|
|---|
| 1615 | ; In: EDX Seconds
|
|---|
| 1616 | ;
|
|---|
| 1617 | ; Out: EAX Remaining seconds
|
|---|
| 1618 | ;
|
|---|
| 1619 | ; ----------------------------------------------------------------------------
|
|---|
| 1620 |
|
|---|
| 1621 | TALIGN 4
|
|---|
| 1622 | SYS17: MOV EAX, I_EDX
|
|---|
| 1623 | TEST EAX, EAX
|
|---|
| 1624 | JZ SHORT SYS17_RET
|
|---|
| 1625 | MOV ECX, 91
|
|---|
| 1626 | MUL ECX ; Multiply by 18.2 = 91/5
|
|---|
| 1627 | ADD EAX, 4
|
|---|
| 1628 | ADC EDX, 0
|
|---|
| 1629 | MOV ECX, 5
|
|---|
| 1630 | CMP EDX, ECX ; Overflow?
|
|---|
| 1631 | JAE SHORT SLEEP_OV
|
|---|
| 1632 | DIV ECX
|
|---|
| 1633 | SLEEP_DO: MOV BX, DI
|
|---|
| 1634 | CALL SLEEP
|
|---|
| 1635 | MOV ECX, 5
|
|---|
| 1636 | MUL ECX ; Divide by 18.2
|
|---|
| 1637 | MOV ECX, 91
|
|---|
| 1638 | DIV ECX
|
|---|
| 1639 | SYS17_RET: MOV I_EAX, EAX
|
|---|
| 1640 | RET
|
|---|
| 1641 |
|
|---|
| 1642 | SLEEP_OV: MOV EAX, MAX_32 ; Use maximum value
|
|---|
| 1643 | JMP SHORT SLEEP_DO
|
|---|
| 1644 |
|
|---|
| 1645 | ; ----------------------------------------------------------------------------
|
|---|
| 1646 | ; AX=7F18H: __chsize()
|
|---|
| 1647 | ;
|
|---|
| 1648 | ; Change file size
|
|---|
| 1649 | ;
|
|---|
| 1650 | ; In: EBX File handle
|
|---|
| 1651 | ; EDX File size
|
|---|
| 1652 | ;
|
|---|
| 1653 | ; Out: CY Error
|
|---|
| 1654 | ; EAX errno (CY)
|
|---|
| 1655 | ;
|
|---|
| 1656 | ; ----------------------------------------------------------------------------
|
|---|
| 1657 |
|
|---|
| 1658 | TALIGN 4
|
|---|
| 1659 | SYS18: MOV EBX, I_EBX ; File handle
|
|---|
| 1660 | MOV EDX, I_EDX ; Distance
|
|---|
| 1661 | MOV AL, 0 ; SEEK_SET
|
|---|
| 1662 | MOV AH, 42H ; Move file pointer
|
|---|
| 1663 | INT 21H
|
|---|
| 1664 | JC SHORT SYS18_RET
|
|---|
| 1665 | MOV EBX, I_EBX ; File handle
|
|---|
| 1666 | MOV ECX, 0 ; Number of bytes
|
|---|
| 1667 | MOV EDX, 0 ; Buffer
|
|---|
| 1668 | MOV AH, 40H ; Write handle
|
|---|
| 1669 | INT 21H
|
|---|
| 1670 | JC SHORT SYS18_RET
|
|---|
| 1671 | XOR EAX, EAX
|
|---|
| 1672 | SYS18_RET: MOV I_EAX, EAX
|
|---|
| 1673 | RET
|
|---|
| 1674 |
|
|---|
| 1675 |
|
|---|
| 1676 | ; ----------------------------------------------------------------------------
|
|---|
| 1677 | ; AX=7F19H: __fcntl()
|
|---|
| 1678 | ;
|
|---|
| 1679 | ; Unix-like file control
|
|---|
| 1680 | ;
|
|---|
| 1681 | ; In: EBX File handle
|
|---|
| 1682 | ; ECX Request code
|
|---|
| 1683 | ; EDX Argument
|
|---|
| 1684 | ;
|
|---|
| 1685 | ; Out: EAX Return value
|
|---|
| 1686 | ; ECX errno
|
|---|
| 1687 | ;
|
|---|
| 1688 | ; ----------------------------------------------------------------------------
|
|---|
| 1689 |
|
|---|
| 1690 | TALIGN 4
|
|---|
| 1691 | ASSUME DI:PTR PROCESS
|
|---|
| 1692 | SYS19: CMP I_ECX, F_SETFL
|
|---|
| 1693 | JE SHORT FCNTL_SETFL
|
|---|
| 1694 | CMP I_ECX, F_SETFD
|
|---|
| 1695 | JE SHORT FCNTL_SETFD
|
|---|
| 1696 | CMP I_ECX, F_GETFD
|
|---|
| 1697 | JE SHORT FCNTL_GETFD
|
|---|
| 1698 | CMP I_ECX, F_GETFL
|
|---|
| 1699 | JE FCNTL_GETFL
|
|---|
| 1700 | EMX_EINVAL: MOV I_ECX, EINVAL
|
|---|
| 1701 | MOV I_EAX, -1
|
|---|
| 1702 | RET
|
|---|
| 1703 |
|
|---|
| 1704 | TALIGN 4
|
|---|
| 1705 | FCNTL_GETFD: MOV BX, WORD PTR I_EBX
|
|---|
| 1706 | CMP BX, MAX_FILES
|
|---|
| 1707 | JAE EMX_EBADF
|
|---|
| 1708 | XOR EAX, EAX
|
|---|
| 1709 | SHL BX, 1
|
|---|
| 1710 | TEST [DI].P_HFLAGS[BX], HF_NOINHERIT
|
|---|
| 1711 | JZ SHORT GETFD_1
|
|---|
| 1712 | OR EAX, 1 ; FD_CLOEXEC
|
|---|
| 1713 | GETFD_1: MOV I_EAX, EAX
|
|---|
| 1714 | MOV I_ECX, 0
|
|---|
| 1715 | RET
|
|---|
| 1716 |
|
|---|
| 1717 | TALIGN 4
|
|---|
| 1718 | FCNTL_SETFD: MOV BX, WORD PTR I_EBX
|
|---|
| 1719 | CMP BX, MAX_FILES
|
|---|
| 1720 | JAE EMX_EBADF
|
|---|
| 1721 | SHL BX, 1
|
|---|
| 1722 | AND [DI].P_HFLAGS[BX], NOT HF_NOINHERIT
|
|---|
| 1723 | TEST I_EDX, 1 ; FD_CLOEXEC
|
|---|
| 1724 | JZ SHORT SETFD_1
|
|---|
| 1725 | OR [DI].P_HFLAGS[BX], HF_NOINHERIT
|
|---|
| 1726 | SETFD_1: JMP SHORT EMX_OK
|
|---|
| 1727 |
|
|---|
| 1728 | TALIGN 4
|
|---|
| 1729 | FCNTL_SETFL: MOV BX, WORD PTR I_EBX
|
|---|
| 1730 | CMP BX, MAX_FILES
|
|---|
| 1731 | JAE SHORT EMX_EBADF
|
|---|
| 1732 | SHL BX, 1
|
|---|
| 1733 | MOV EAX, I_EDX
|
|---|
| 1734 | TEST EAX, NOT (O_NDELAY OR O_APPEND)
|
|---|
| 1735 | JNZ SHORT EMX_EINVAL
|
|---|
| 1736 | .ERRE O_NDELAY EQ HF_NDELAY
|
|---|
| 1737 | .ERRE O_APPEND EQ HF_APPEND
|
|---|
| 1738 | AND [DI].P_HFLAGS[BX], NOT (HF_NDELAY OR HF_APPEND)
|
|---|
| 1739 | OR [DI].P_HFLAGS[BX], AX
|
|---|
| 1740 | CMP I_EBX, 0 ; stdin?
|
|---|
| 1741 | JNE SHORT EMX_OK
|
|---|
| 1742 | MOV STDIN_FL, EAX
|
|---|
| 1743 | TALIGN 4
|
|---|
| 1744 | EMX_OK: MOV I_ECX, 0
|
|---|
| 1745 | MOV I_EAX, 0
|
|---|
| 1746 | RET
|
|---|
| 1747 |
|
|---|
| 1748 | TALIGN 4
|
|---|
| 1749 | FCNTL_GETFL: MOV BX, WORD PTR I_EBX
|
|---|
| 1750 | CMP BX, MAX_FILES
|
|---|
| 1751 | JAE SHORT EMX_EBADF
|
|---|
| 1752 | SHL BX, 1
|
|---|
| 1753 | XOR EAX, EAX
|
|---|
| 1754 | MOV AX, [DI].P_HFLAGS[BX]
|
|---|
| 1755 | .ERRE O_NDELAY EQ HF_NDELAY
|
|---|
| 1756 | .ERRE O_APPEND EQ HF_APPEND
|
|---|
| 1757 | AND AX, HF_NDELAY OR HF_APPEND
|
|---|
| 1758 | MOV I_EAX, EAX
|
|---|
| 1759 | MOV I_ECX, 0
|
|---|
| 1760 | RET
|
|---|
| 1761 |
|
|---|
| 1762 | TALIGN 4
|
|---|
| 1763 | EMX_EBADF: MOV I_ECX, EBADF
|
|---|
| 1764 | MOV I_EAX, -1
|
|---|
| 1765 | RET
|
|---|
| 1766 | ASSUME DI:NOTHING
|
|---|
| 1767 |
|
|---|
| 1768 | ; ----------------------------------------------------------------------------
|
|---|
| 1769 | ; AX=7F1AH: __pipe()
|
|---|
| 1770 | ;
|
|---|
| 1771 | ; Create unnamed pipe
|
|---|
| 1772 | ;
|
|---|
| 1773 | ; In: ECX Size of pipe
|
|---|
| 1774 | ; EDX Pointer to storage for two handles (two DWORDs)
|
|---|
| 1775 | ;
|
|---|
| 1776 | ; Out: EAX 0 (success) or -1 (failure)
|
|---|
| 1777 | ; ECX errno
|
|---|
| 1778 | ;
|
|---|
| 1779 | ; ----------------------------------------------------------------------------
|
|---|
| 1780 |
|
|---|
| 1781 | TALIGN 4
|
|---|
| 1782 | SYS1A: MOV I_ECX, ENOSYS
|
|---|
| 1783 | MOV I_EAX, -1
|
|---|
| 1784 | RET
|
|---|
| 1785 |
|
|---|
| 1786 | ; ----------------------------------------------------------------------------
|
|---|
| 1787 | ; AX=7F1BH: __fsync()
|
|---|
| 1788 | ;
|
|---|
| 1789 | ; Update file system
|
|---|
| 1790 | ;
|
|---|
| 1791 | ; In: EBX File handle
|
|---|
| 1792 | ;
|
|---|
| 1793 | ; Out: EAX 0 (success) or -1 (failure)
|
|---|
| 1794 | ; ECX errno
|
|---|
| 1795 | ;
|
|---|
| 1796 | ; ----------------------------------------------------------------------------
|
|---|
| 1797 |
|
|---|
| 1798 | TALIGN 4
|
|---|
| 1799 | SYS1B: MOV I_ECX, ENOSYS
|
|---|
| 1800 | MOV I_EAX, -1
|
|---|
| 1801 | RET
|
|---|
| 1802 |
|
|---|
| 1803 | ; ----------------------------------------------------------------------------
|
|---|
| 1804 | ; AX=7F1CH: __fork()
|
|---|
| 1805 | ;
|
|---|
| 1806 | ; Duplicate process
|
|---|
| 1807 | ;
|
|---|
| 1808 | ;
|
|---|
| 1809 | ; Out: EAX Process ID or 0 (in new process) or -1 (failure)
|
|---|
| 1810 | ; ECX errno (0 if successful)
|
|---|
| 1811 | ;
|
|---|
| 1812 | ; ----------------------------------------------------------------------------
|
|---|
| 1813 | TALIGN 4
|
|---|
| 1814 | SYS1C: MOV I_ECX, ENOSYS
|
|---|
| 1815 | MOV I_EAX, -1
|
|---|
| 1816 | RET
|
|---|
| 1817 |
|
|---|
| 1818 | ; ----------------------------------------------------------------------------
|
|---|
| 1819 | ; AX=7F1DH: __scrsize()
|
|---|
| 1820 | ;
|
|---|
| 1821 | ; Get number of rows and columns
|
|---|
| 1822 | ;
|
|---|
| 1823 | ; In: EDX Pointer to structure
|
|---|
| 1824 | ;
|
|---|
| 1825 | ; Out: --
|
|---|
| 1826 | ;
|
|---|
| 1827 | ; ----------------------------------------------------------------------------
|
|---|
| 1828 |
|
|---|
| 1829 | TALIGN 4
|
|---|
| 1830 | SYS1D: MOV EBX, I_EDX
|
|---|
| 1831 | MOV ES, I_DS
|
|---|
| 1832 | MOVZX EAX, VWIDTH
|
|---|
| 1833 | MOV DWORD PTR ES:[EBX+0], EAX
|
|---|
| 1834 | MOVZX EAX, VHEIGHT
|
|---|
| 1835 | MOV DWORD PTR ES:[EBX+4], EAX
|
|---|
| 1836 | RET
|
|---|
| 1837 |
|
|---|
| 1838 | ; ----------------------------------------------------------------------------
|
|---|
| 1839 | ; AX=7F1EH: __select()
|
|---|
| 1840 | ;
|
|---|
| 1841 | ; Synchronous I/O multiplexing
|
|---|
| 1842 | ;
|
|---|
| 1843 | ; In: EDX pointer to structure
|
|---|
| 1844 | ;
|
|---|
| 1845 | ; Out: EAX 0 (timeout), > 0 (ready) or -1 (failure)
|
|---|
| 1846 | ; ECX errno (0 if successful)
|
|---|
| 1847 | ;
|
|---|
| 1848 | ; ----------------------------------------------------------------------------
|
|---|
| 1849 |
|
|---|
| 1850 | TALIGN 4
|
|---|
| 1851 | ASSUME DI:PTR PROCESS
|
|---|
| 1852 | SYS1E: AND [DI].P_FLAGS, NOT PF_SLEEP_FLAG ; Clear counter flag
|
|---|
| 1853 | MOV SEL_COUNT, 0 ; No ready handles
|
|---|
| 1854 | MOV ESI, I_EDX ; Get pointer to structure
|
|---|
| 1855 | MOV ES, I_DS ; and segment register
|
|---|
| 1856 | ASSUME ESI:NEAR32 PTR SELECT_ARGS
|
|---|
| 1857 | MOV EBX, ES:[ESI].SELA_TIMEOUT ; Get timeout pointer
|
|---|
| 1858 | TEST EBX, EBX ; NULL pointer?
|
|---|
| 1859 | JZ SHORT SELECT_LOOP ; Yes -> indefinite wait
|
|---|
| 1860 | ASSUME EBX:NEAR32 PTR TIMEVAL
|
|---|
| 1861 | MOV EAX, ES:[EBX].TV_USEC ; Get microseconds
|
|---|
| 1862 | XOR EDX, EDX
|
|---|
| 1863 | MOV ECX, 54945
|
|---|
| 1864 | DIV ECX ; Convert to timer ticks
|
|---|
| 1865 | PUSH EAX ; Save ticks for microseconds
|
|---|
| 1866 | MOV EAX, ES:[EBX].TV_SEC ; Get seconds
|
|---|
| 1867 | ASSUME EBX:NOTHING
|
|---|
| 1868 | MOV ECX, 91
|
|---|
| 1869 | MUL ECX ; Multiply by 18.2 = 91/5
|
|---|
| 1870 | ADD EAX, 4
|
|---|
| 1871 | ADC EDX, 0
|
|---|
| 1872 | MOV ECX, 5
|
|---|
| 1873 | CMP EDX, ECX
|
|---|
| 1874 | JAE SHORT SELECT_OV1
|
|---|
| 1875 | DIV ECX
|
|---|
| 1876 | POP ECX ; Ticks for microseconds
|
|---|
| 1877 | ADD EAX, ECX ; Total number of ticks
|
|---|
| 1878 | JC EMX_EINVAL ; Overflow -> error
|
|---|
| 1879 | JZ SHORT SELECT_ONCE ; Zero -> return after one loop
|
|---|
| 1880 | MOV DX, TT_SLEEP ; Set `sleep' timer
|
|---|
| 1881 | MOV BX, DI ; Process table entry
|
|---|
| 1882 | CALL SET_TIMER
|
|---|
| 1883 | JC EMX_EINVAL ; Table overflow -> error
|
|---|
| 1884 | JMP SHORT SELECT_LOOP ; Start loop
|
|---|
| 1885 |
|
|---|
| 1886 | SELECT_OV1: POP ECX ; Ticks for microseconds
|
|---|
| 1887 | JMP EMX_EINVAL ; Error
|
|---|
| 1888 |
|
|---|
| 1889 | SELECT_ONCE: OR [DI].P_FLAGS, PF_SLEEP_FLAG ; Return after first loop
|
|---|
| 1890 | ASSUME DI:NOTHING
|
|---|
| 1891 | LEA DI, SEL_RBITS ; Clear all bits in the
|
|---|
| 1892 | MOV_ES_DS ; bitmap of ready handles
|
|---|
| 1893 | MOV CX, FD_SETSIZE/8
|
|---|
| 1894 | XOR AL, AL
|
|---|
| 1895 | REP STOSB
|
|---|
| 1896 | MOV ES, I_DS
|
|---|
| 1897 | ;
|
|---|
| 1898 | ; This is the main loop
|
|---|
| 1899 | ;
|
|---|
| 1900 | SELECT_LOOP: MOV BX, PROCESS_PTR
|
|---|
| 1901 | ASSUME BX:PTR PROCESS
|
|---|
| 1902 | MOV EAX, [BX].P_SIG_BLOCKED ; Compute set of pending,
|
|---|
| 1903 | NOT EAX ; unblocked signals
|
|---|
| 1904 | AND EAX, [BX].P_SIG_PENDING
|
|---|
| 1905 | ASSUME BX:NOTHING
|
|---|
| 1906 | ;
|
|---|
| 1907 | ; TODO: Deliver signals set to SIG_DFL now
|
|---|
| 1908 | ; TODO: Ignore signals set to SIG_IGN
|
|---|
| 1909 | ;
|
|---|
| 1910 | JNZ SELECT_INTR ; Signal -> return EINTR
|
|---|
| 1911 | MOV EDI, ES:[ESI].SELA_READFDS ; Get readfds pointer
|
|---|
| 1912 | TEST EDI, EDI ; NULL pointer?
|
|---|
| 1913 | JZ SELECT_TIME ; Yes -> wait until timeout
|
|---|
| 1914 | XOR EBX, EBX ; Start with handle 0
|
|---|
| 1915 | SELECT_POLL: CMP EBX, ES:[ESI].SELA_NFDS ; All handles checked?
|
|---|
| 1916 | JAE SELECT_CHECK ; Yes -> any ready handles?
|
|---|
| 1917 | BT DWORD PTR ES:[EDI], EBX ; Handle in readfds bitmap?
|
|---|
| 1918 | JNC SELECT_NEXT ; No -> next handle
|
|---|
| 1919 | CMP EBX, 0 ; stdin?
|
|---|
| 1920 | JNZ SHORT SELECT_TEST ; No -> check input status
|
|---|
| 1921 | TEST STDIN_TERMIO.C_LFLAG, IDEFAULT ; termio?
|
|---|
| 1922 | JNZ SHORT SELECT_TEST ; No -> check input status
|
|---|
| 1923 | CALL STDIN_AVAIL ; Get number of available chars
|
|---|
| 1924 | TEST EAX, EAX ; Any characters available?
|
|---|
| 1925 | JNZ SHORT SELECT_HIT ; Yes -> handle ready
|
|---|
| 1926 | JMP SHORT SELECT_NEXT ; Next handle
|
|---|
| 1927 |
|
|---|
| 1928 | SELECT_TEST: PUSH EBX
|
|---|
| 1929 | PUSH ESI
|
|---|
| 1930 | PUSH EDI
|
|---|
| 1931 | MOV AX, 4406H ; IOCTL: Check input status
|
|---|
| 1932 | INT 21H
|
|---|
| 1933 | POP EDI
|
|---|
| 1934 | POP ESI
|
|---|
| 1935 | POP EBX
|
|---|
| 1936 | JC SELECT_ERR ; Error -> done
|
|---|
| 1937 | TEST AL, AL ; 00H=not ready, 0FFH=ready
|
|---|
| 1938 | JZ SHORT SELECT_NEXT ; Not ready -> next handle
|
|---|
| 1939 | SELECT_HIT: INC SEL_COUNT ; Increment # of ready handles
|
|---|
| 1940 | BTS DWORD PTR SEL_RBITS, EBX ; Set bit in bitmap
|
|---|
| 1941 | SELECT_NEXT: INC EBX ; Next handle
|
|---|
| 1942 | JMP SELECT_POLL ; Check next handle
|
|---|
| 1943 |
|
|---|
| 1944 | ;
|
|---|
| 1945 | ; Having looped though the handles, check if a handle is ready
|
|---|
| 1946 | ;
|
|---|
| 1947 | SELECT_CHECK: CMP SEL_COUNT, 0 ; Are there ready handles?
|
|---|
| 1948 | JNE SHORT SELECT_READY ; Yes -> success
|
|---|
| 1949 | SELECT_TIME: MOV EBX, ES:[ESI].SELA_TIMEOUT ; Get pointer to timeout
|
|---|
| 1950 | TEST EBX, EBX ; NULL pointer?
|
|---|
| 1951 | JZ SELECT_LOOP ; Yes -> indefinite wait
|
|---|
| 1952 | MOV BX, PROCESS_PTR ; Process table entry
|
|---|
| 1953 | TEST (PROCESS PTR [BX]).P_FLAGS, PF_SLEEP_FLAG ; Timer down?
|
|---|
| 1954 | JZ SELECT_LOOP ; No -> check handles again
|
|---|
| 1955 | ;
|
|---|
| 1956 | ; Time out, clear all sets
|
|---|
| 1957 | ;
|
|---|
| 1958 | MOV EDI, ES:[ESI].SELA_READFDS
|
|---|
| 1959 | CALL CLEAR_FDSET
|
|---|
| 1960 | MOV EDI, ES:[ESI].SELA_WRITEFDS
|
|---|
| 1961 | CALL CLEAR_FDSET
|
|---|
| 1962 | MOV EDI, ES:[ESI].SELA_EXCEPTFDS
|
|---|
| 1963 | CALL CLEAR_FDSET
|
|---|
| 1964 | MOV I_EAX, 0 ; Time out
|
|---|
| 1965 | MOV I_ECX, 0 ; No error
|
|---|
| 1966 | JMP SELECT_RET ; Done
|
|---|
| 1967 |
|
|---|
| 1968 | ;
|
|---|
| 1969 | ; At least one handle is ready
|
|---|
| 1970 | ;
|
|---|
| 1971 | SELECT_READY: MOVZX EAX, SEL_COUNT ; Return number of ready
|
|---|
| 1972 | MOV I_EAX, EAX ; handles
|
|---|
| 1973 | MOV I_ECX, 0 ; No error
|
|---|
| 1974 | PUSH ESI ; Save pointer to structure
|
|---|
| 1975 | LEA ESI, SEL_RBITS ; Copy bitmap of ready handles
|
|---|
| 1976 | MOV ECX, FD_SETSIZE/8 ; to readfds
|
|---|
| 1977 | REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]
|
|---|
| 1978 | POP ESI ; Restore pointer to structure
|
|---|
| 1979 | MOV EDI, ES:[ESI].SELA_WRITEFDS ; Get writefds pointer
|
|---|
| 1980 | CALL CLEAR_FDSET
|
|---|
| 1981 | MOV EDI, ES:[ESI].SELA_EXCEPTFDS ; Get exceptfds pointer
|
|---|
| 1982 | CALL CLEAR_FDSET
|
|---|
| 1983 | SELECT_RET: RET ; Done
|
|---|
| 1984 |
|
|---|
| 1985 | ;
|
|---|
| 1986 | ; A signal occured while waiting in select(). Return EINTR and raise
|
|---|
| 1987 | ; the signal.
|
|---|
| 1988 | ;
|
|---|
| 1989 | SELECT_INTR: MOV EAX, EINTR
|
|---|
| 1990 |
|
|---|
| 1991 | SELECT_ERR: MOV I_ECX, EAX ; Return errno in ECX
|
|---|
| 1992 | MOV I_EAX, -1 ; Error
|
|---|
| 1993 | JMP SHORT SELECT_RET ; Done
|
|---|
| 1994 |
|
|---|
| 1995 | ;
|
|---|
| 1996 | ; Clear a fd_set object pointed to by ES:EDI if EDI is not NULL
|
|---|
| 1997 | ;
|
|---|
| 1998 | ALIGN 4
|
|---|
| 1999 | CLEAR_FDSET PROC NEAR
|
|---|
| 2000 | TEST EDI, EDI
|
|---|
| 2001 | JZ SHORT FIN
|
|---|
| 2002 | MOV ECX, FD_SETSIZE/8
|
|---|
| 2003 | XOR AL, AL
|
|---|
| 2004 | MOV ECX, FD_SETSIZE/8
|
|---|
| 2005 | REP STOS BYTE PTR ES:[EDI]
|
|---|
| 2006 | FIN: RET
|
|---|
| 2007 | CLEAR_FDSET ENDP
|
|---|
| 2008 |
|
|---|
| 2009 | ASSUME ESI:NOTHING
|
|---|
| 2010 |
|
|---|
| 2011 | ; ----------------------------------------------------------------------------
|
|---|
| 2012 | ; AX=7F1FH: __syserrno()
|
|---|
| 2013 | ;
|
|---|
| 2014 | ; Return DOS error number for last syscall
|
|---|
| 2015 | ;
|
|---|
| 2016 | ; Out: EAX error number
|
|---|
| 2017 | ;
|
|---|
| 2018 | ; ----------------------------------------------------------------------------
|
|---|
| 2019 |
|
|---|
| 2020 | TALIGN 4
|
|---|
| 2021 | SYS1F: MOV I_EAX, 0
|
|---|
| 2022 | RET
|
|---|
| 2023 |
|
|---|
| 2024 | ; ----------------------------------------------------------------------------
|
|---|
| 2025 | ; AX=7F20H __stat()
|
|---|
| 2026 | ;
|
|---|
| 2027 | ; Get information about a path name
|
|---|
| 2028 | ;
|
|---|
| 2029 | ; In: EDX path name
|
|---|
| 2030 | ; EDI pointer to structure
|
|---|
| 2031 | ;
|
|---|
| 2032 | ; Out: EAX 0 (ok), -1 (error)
|
|---|
| 2033 | ; ECX errno (0 if successful)
|
|---|
| 2034 | ;
|
|---|
| 2035 | ; ----------------------------------------------------------------------------
|
|---|
| 2036 | TALIGN 4
|
|---|
| 2037 | ASSUME EDI:NEAR32 PTR STAT
|
|---|
| 2038 | SYS20: MOV ESI, I_EDX ; Pointer to path name
|
|---|
| 2039 | MOV ES, I_DS
|
|---|
| 2040 | ;
|
|---|
| 2041 | ; Return ENOENT if the path name contains wildcard characters
|
|---|
| 2042 | ;
|
|---|
| 2043 | TALIGN 4
|
|---|
| 2044 | NSTAT_WILD: LODS BYTE PTR ES:[ESI]
|
|---|
| 2045 | TEST AL, AL
|
|---|
| 2046 | JZ SHORT NSTAT_NOWILD
|
|---|
| 2047 | CMP AL, "?"
|
|---|
| 2048 | JE SHORT NSTAT_FAILURE1
|
|---|
| 2049 | CMP AL, "*"
|
|---|
| 2050 | JNE SHORT NSTAT_WILD
|
|---|
| 2051 | NSTAT_FAILURE1: JMP NSTAT_FAILURE
|
|---|
| 2052 |
|
|---|
| 2053 | NSTAT_NOWILD: MOV EDX, I_EDX ; Pointer to path name
|
|---|
| 2054 | MOV ESI, I_ESP ; Allocate FIND_BUF in user
|
|---|
| 2055 | SUB ESI, SIZE FIND_BUF ; stack (same segment as path!)
|
|---|
| 2056 | ASSUME ESI:NEAR32 PTR FIND_BUF
|
|---|
| 2057 | PUSH DS
|
|---|
| 2058 | MOV DS, I_DS
|
|---|
| 2059 | MOV CX, 16H ; Dir & system & hidden
|
|---|
| 2060 | MOV AH, 4EH ; Find first file
|
|---|
| 2061 | INT 21H
|
|---|
| 2062 | POP DS
|
|---|
| 2063 | JC NSTAT_10 ; Error -> root directory?
|
|---|
| 2064 | MOV EDI, I_EDI ; Pointer to structure
|
|---|
| 2065 | MOV ES, I_DS ; Use ES for user data segment
|
|---|
| 2066 | MOV EAX, S_IFREG ; File
|
|---|
| 2067 | TEST ES:[ESI].FIND_ATTR, 10H ; Is it a directory?
|
|---|
| 2068 | JZ SHORT NSTAT_1 ; No -> it's a file
|
|---|
| 2069 | MOV ES:[ESI].FIND_SIZE, 0 ; The size of a directory is 0
|
|---|
| 2070 | MOV EAX, S_IFDIR OR ((S_IREAD+S_IWRITE+S_IEXEC) SHR 6) * 111Q
|
|---|
| 2071 | JMP SHORT NSTAT_2
|
|---|
| 2072 | TALIGN 4
|
|---|
| 2073 | NSTAT_1: OR EAX, (S_IREAD SHR 6) * 111Q ; Read-only access
|
|---|
| 2074 | TEST ES:[ESI].FIND_ATTR, 01H ; Ready-only attribute set?
|
|---|
| 2075 | JNZ SHORT NSTAT_2 ; Yes -> skip
|
|---|
| 2076 | OR EAX, (S_IWRITE SHR 6) * 111Q ; Read-write access
|
|---|
| 2077 | NSTAT_2: MOV ES:[EDI].ST_MODE, EAX ; Set mode
|
|---|
| 2078 | MOVZX EAX, ES:[ESI].FIND_ATTR ; Get attributes
|
|---|
| 2079 | MOV ES:[EDI].ST_ATTR, EAX ; and store them
|
|---|
| 2080 | MOV EAX, ES:[ESI].FIND_SIZE ; Get size
|
|---|
| 2081 | MOV ES:[EDI].ST_SIZE, EAX ; and store it
|
|---|
| 2082 | MOV CX, ES:[ESI].FIND_TIME ; Get time
|
|---|
| 2083 | MOV DX, ES:[ESI].FIND_DATE ; and date
|
|---|
| 2084 | CALL PACKED_2_UNIX ; and convert them to time_t
|
|---|
| 2085 | NSTAT_MORE: MOV ES:[EDI].ST_ATIME, EAX ; Time of last access
|
|---|
| 2086 | MOV ES:[EDI].ST_MTIME, EAX ; Time of last modification
|
|---|
| 2087 | MOV ES:[EDI].ST_CTIME, EAX ; Time of creation
|
|---|
| 2088 | MOV ES:[EDI].ST_NLINK, 1 ; One link
|
|---|
| 2089 | MOV ES:[EDI].ST_UID, 0 ; root
|
|---|
| 2090 | MOV ES:[EDI].ST_GID, 0 ; root
|
|---|
| 2091 | MOV ES:[EDI].ST_DEV, 0 ; Device numbers not supported
|
|---|
| 2092 | MOV ES:[EDI].ST_RDEV, 0 ; Device numbers not supported
|
|---|
| 2093 | MOV ES:[EDI].ST_RESERVED, 0 ; Nomen est omen
|
|---|
| 2094 | MOV EAX, INO_NUMBER ; Mock inode number
|
|---|
| 2095 | MOV ES:[EDI].ST_INO, EAX
|
|---|
| 2096 | INC INO_NUMBER
|
|---|
| 2097 | JNZ SHORT NSTAT_INO_1
|
|---|
| 2098 | INC INO_NUMBER
|
|---|
| 2099 | NSTAT_INO_1: JMP EMX_OK ; Done
|
|---|
| 2100 |
|
|---|
| 2101 | ;
|
|---|
| 2102 | ; Not found -- check for root directory
|
|---|
| 2103 | ;
|
|---|
| 2104 | ; Get current working directory and save it. Then try to change to the
|
|---|
| 2105 | ; "directory" given as argument to __stat(). If successful, it's the
|
|---|
| 2106 | ; root directory: set the structure appropriately and restore the
|
|---|
| 2107 | ; previous working directory. Otherwise, the file/directory does not
|
|---|
| 2108 | ; exist (or it's a device -- which is not supported by this implementation
|
|---|
| 2109 | ; of stat).
|
|---|
| 2110 | ;
|
|---|
| 2111 | TALIGN 4
|
|---|
| 2112 | NSTAT_10: MOV EBX, I_EDX
|
|---|
| 2113 | MOV ES, I_DS
|
|---|
| 2114 | MOV AL, ES:[EBX]
|
|---|
| 2115 | CALL UPPER
|
|---|
| 2116 | CMP AL, "A"
|
|---|
| 2117 | JB SHORT NSTAT_11
|
|---|
| 2118 | CMP AL, "Z"
|
|---|
| 2119 | JA SHORT NSTAT_11
|
|---|
| 2120 | CMP BYTE PTR ES:[EBX+1], ":"
|
|---|
| 2121 | JE SHORT NSTAT_12
|
|---|
| 2122 | NSTAT_11: MOV AH, 19H
|
|---|
| 2123 | INT 21H
|
|---|
| 2124 | ADD AL, "A"
|
|---|
| 2125 | NSTAT_12: MOV STAT_CWD, AL
|
|---|
| 2126 | SUB AL, "A" - 1
|
|---|
| 2127 | MOV DL, AL
|
|---|
| 2128 | LEA ESI, STAT_CWD + 3
|
|---|
| 2129 | MOV AH, 47H
|
|---|
| 2130 | INT 21H
|
|---|
| 2131 | JC SHORT NSTAT_FAILURE
|
|---|
| 2132 | PUSH DS
|
|---|
| 2133 | MOV EDX, I_EDX
|
|---|
| 2134 | MOV DS, I_DS
|
|---|
| 2135 | MOV AH, 3BH
|
|---|
| 2136 | INT 21H
|
|---|
| 2137 | POP DS
|
|---|
| 2138 | JC SHORT NSTAT_FAILURE
|
|---|
| 2139 | LEA EDX, STAT_CWD
|
|---|
| 2140 | MOV AH, 3BH
|
|---|
| 2141 | INT 21H
|
|---|
| 2142 | MOV EDI, I_EDI
|
|---|
| 2143 | MOV ES, I_DS
|
|---|
| 2144 | MOV ES:[EDI].ST_MODE, S_IFDIR+((S_IREAD+S_IWRITE+S_IEXEC) SHR 6)*111Q
|
|---|
| 2145 | MOV ES:[EDI].ST_ATTR, 0 ; Look here to find out about
|
|---|
| 2146 | ; root directory (not 10H!)
|
|---|
| 2147 | MOV ES:[EDI].ST_SIZE, 0
|
|---|
| 2148 | XOR EAX, EAX
|
|---|
| 2149 | JMP NSTAT_MORE
|
|---|
| 2150 |
|
|---|
| 2151 | TALIGN 4
|
|---|
| 2152 | NSTAT_FAILURE: MOV I_EAX, -1
|
|---|
| 2153 | MOV I_ECX, ENOENT
|
|---|
| 2154 | RET
|
|---|
| 2155 |
|
|---|
| 2156 | ASSUME ESI:NOTHING
|
|---|
| 2157 | ASSUME EDI:NOTHING
|
|---|
| 2158 |
|
|---|
| 2159 | ; ----------------------------------------------------------------------------
|
|---|
| 2160 | ; AX=7F21H __fstat()
|
|---|
| 2161 | ;
|
|---|
| 2162 | ; Get information about an open file
|
|---|
| 2163 | ;
|
|---|
| 2164 | ; In: EBX file handle
|
|---|
| 2165 | ; EDI pointer to structure
|
|---|
| 2166 | ;
|
|---|
| 2167 | ; Out: EAX 0 (ok), -1 (error)
|
|---|
| 2168 | ; ECX errno (0 if successful)
|
|---|
| 2169 | ;
|
|---|
| 2170 | ; ----------------------------------------------------------------------------
|
|---|
| 2171 | TALIGN 4
|
|---|
| 2172 | ASSUME EDI:NEAR32 PTR STAT
|
|---|
| 2173 | SYS21: MOV EBX, I_EBX
|
|---|
| 2174 | MOV AX, 4400H
|
|---|
| 2175 | INT 21H
|
|---|
| 2176 | JC FSTAT_ERROR
|
|---|
| 2177 | MOV EDI, I_EDI
|
|---|
| 2178 | MOV ES, I_DS
|
|---|
| 2179 | TEST DL, 80H ; Device?
|
|---|
| 2180 | JNZ FSTAT_DEV
|
|---|
| 2181 | MOV ES:[EDI].ST_MODE, S_IFREG
|
|---|
| 2182 | MOV ES:[EDI].ST_ATTR, 0
|
|---|
| 2183 | MOV ES:[EDI].ST_RESERVED, 0
|
|---|
| 2184 | MOV AX, 5700H
|
|---|
| 2185 | INT 21H
|
|---|
| 2186 | JC FSTAT_ERROR
|
|---|
| 2187 | CALL PACKED_2_UNIX
|
|---|
| 2188 | MOV ES:[EDI].ST_ATIME, EAX
|
|---|
| 2189 | MOV ES:[EDI].ST_MTIME, EAX
|
|---|
| 2190 | MOV ES:[EDI].ST_CTIME, EAX
|
|---|
| 2191 | MOV AX, 4201H
|
|---|
| 2192 | MOV EDX, 0
|
|---|
| 2193 | INT 21H
|
|---|
| 2194 | JC FSTAT_ERROR
|
|---|
| 2195 | MOV ESI, EAX
|
|---|
| 2196 | MOV AX, 4202H
|
|---|
| 2197 | MOV EDX, 0
|
|---|
| 2198 | INT 21H
|
|---|
| 2199 | JC FSTAT_ERROR
|
|---|
| 2200 | MOV ES:[EDI].ST_SIZE, EAX
|
|---|
| 2201 | MOV AX, 4200H
|
|---|
| 2202 | MOV EDX, ESI
|
|---|
| 2203 | INT 21H
|
|---|
| 2204 | JC FSTAT_ERROR
|
|---|
| 2205 | JMP SHORT FSTAT_MORE
|
|---|
| 2206 |
|
|---|
| 2207 | TALIGN 4
|
|---|
| 2208 | FSTAT_DEV: MOV ES:[EDI].ST_MODE, S_IFCHR
|
|---|
| 2209 | MOV ES:[EDI].ST_SIZE, 0
|
|---|
| 2210 | MOV ES:[EDI].ST_ATIME, 0
|
|---|
| 2211 | MOV ES:[EDI].ST_MTIME, 0
|
|---|
| 2212 | MOV ES:[EDI].ST_CTIME, 0
|
|---|
| 2213 | FSTAT_MORE: MOV EAX, INO_NUMBER
|
|---|
| 2214 | MOV ES:[EDI].ST_INO, EAX
|
|---|
| 2215 | INC INO_NUMBER
|
|---|
| 2216 | JNZ SHORT FSTAT_INO_1
|
|---|
| 2217 | INC INO_NUMBER
|
|---|
| 2218 | FSTAT_INO_1: MOV ES:[EDI].ST_UID, 0
|
|---|
| 2219 | MOV ES:[EDI].ST_GID, 0
|
|---|
| 2220 | MOV ES:[EDI].ST_NLINK, 1
|
|---|
| 2221 | MOV ES:[EDI].ST_DEV, 0
|
|---|
| 2222 | MOV ES:[EDI].ST_RDEV, 0
|
|---|
| 2223 | OR ES:[EDI].ST_MODE, ((S_IREAD+S_IWRITE) SHR 6) * 111Q
|
|---|
| 2224 | JMP EMX_OK
|
|---|
| 2225 |
|
|---|
| 2226 | FSTAT_ERROR: MOV I_EAX, -1
|
|---|
| 2227 | MOV I_ECX, EAX
|
|---|
| 2228 | RET
|
|---|
| 2229 |
|
|---|
| 2230 | ASSUME EDI:NOTHING
|
|---|
| 2231 |
|
|---|
| 2232 |
|
|---|
| 2233 | ; ----------------------------------------------------------------------------
|
|---|
| 2234 | ; AX=7F23H __filesys()
|
|---|
| 2235 | ;
|
|---|
| 2236 | ; Get name of file-system driver
|
|---|
| 2237 | ;
|
|---|
| 2238 | ; In: EDX pointer to drive name
|
|---|
| 2239 | ; EDI pointer to output buffer
|
|---|
| 2240 | ; ECX size of output buffer
|
|---|
| 2241 | ;
|
|---|
| 2242 | ; Out: EAX 0 (ok) or -1 (error)
|
|---|
| 2243 | ; ECX errno (0 if successful)
|
|---|
| 2244 | ;
|
|---|
| 2245 | ; ----------------------------------------------------------------------------
|
|---|
| 2246 | TALIGN 4
|
|---|
| 2247 | SYS23: MOV EBX, I_EDX
|
|---|
| 2248 | MOV ES, I_DS
|
|---|
| 2249 | MOV AL, ES:[EBX+0]
|
|---|
| 2250 | CALL UPPER
|
|---|
| 2251 | CMP AL, "A"
|
|---|
| 2252 | JB SHORT FILESYS_INVALID
|
|---|
| 2253 | CMP AL, "Z"
|
|---|
| 2254 | JA SHORT FILESYS_INVALID
|
|---|
| 2255 | CMP BYTE PTR ES:[EBX+1], ":"
|
|---|
| 2256 | JNE SHORT FILESYS_INVALID
|
|---|
| 2257 | CMP BYTE PTR ES:[EBX+2], 0
|
|---|
| 2258 | JNE SHORT FILESYS_INVALID
|
|---|
| 2259 | CMP I_ECX, 4
|
|---|
| 2260 | JB SHORT FILESYS_2BIG
|
|---|
| 2261 | SUB AL, "A"-1
|
|---|
| 2262 | MOV BL, AL
|
|---|
| 2263 | MOV AX, 4409H
|
|---|
| 2264 | INT 21H
|
|---|
| 2265 | JC SHORT FILESYS_ERROR
|
|---|
| 2266 | LEA ESI, $FAT
|
|---|
| 2267 | TEST DX, 1 SHL 12
|
|---|
| 2268 | JZ SHORT FILESYS_1
|
|---|
| 2269 | LEA ESI, $LAN
|
|---|
| 2270 | FILESYS_1: MOV ECX, 4
|
|---|
| 2271 | MOV EDI, I_EDI
|
|---|
| 2272 | REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]
|
|---|
| 2273 | JMP EMX_OK
|
|---|
| 2274 |
|
|---|
| 2275 | FILESYS_2BIG: MOV EAX, E2BIG
|
|---|
| 2276 | JMP SHORT FILESYS_ERROR
|
|---|
| 2277 |
|
|---|
| 2278 | FILESYS_INVALID:MOV EAX, EINVAL
|
|---|
| 2279 | FILESYS_ERROR: MOV I_EAX, -1
|
|---|
| 2280 | MOV I_ECX, EAX
|
|---|
| 2281 | RET
|
|---|
| 2282 |
|
|---|
| 2283 | ; ----------------------------------------------------------------------------
|
|---|
| 2284 | ; AX=7F24H __utimes()
|
|---|
| 2285 | ;
|
|---|
| 2286 | ; Set access and modification time of a file
|
|---|
| 2287 | ;
|
|---|
| 2288 | ; In: EDX pointer to path name
|
|---|
| 2289 | ; ESI pointer to array of structures
|
|---|
| 2290 | ;
|
|---|
| 2291 | ; Out: EAX 0 (ok) or -1 (error)
|
|---|
| 2292 | ; ECX errno (0 if successful)
|
|---|
| 2293 | ;
|
|---|
| 2294 | ; ----------------------------------------------------------------------------
|
|---|
| 2295 | TALIGN 4
|
|---|
| 2296 | SYS24: PUSH PROCESS_PTR
|
|---|
| 2297 | MOV PROCESS_PTR, NO_PROCESS
|
|---|
| 2298 | PUSH DS
|
|---|
| 2299 | MOV EDX, I_EDX
|
|---|
| 2300 | MOV DS, I_DS
|
|---|
| 2301 | ASSUME DS:NOTHING
|
|---|
| 2302 | MOV AX, 3D11H
|
|---|
| 2303 | INT 21H
|
|---|
| 2304 | POP DS
|
|---|
| 2305 | ASSUME DS:SV_DATA
|
|---|
| 2306 | JC SHORT UTIMES_ERROR
|
|---|
| 2307 | MOV EBX, EAX
|
|---|
| 2308 | MOV ESI, I_ESI
|
|---|
| 2309 | MOV ES, I_DS
|
|---|
| 2310 | MOV EAX, ES:[ESI+8] ; Modification time
|
|---|
| 2311 | CALL UNIX_2_PACKED
|
|---|
| 2312 | MOV AX, 5701H
|
|---|
| 2313 | INT 21H
|
|---|
| 2314 | JC SHORT UTIMES_1
|
|---|
| 2315 | MOV AH, 3EH
|
|---|
| 2316 | INT 21H
|
|---|
| 2317 | JC SHORT UTIMES_ERROR
|
|---|
| 2318 | MOV I_EAX, 0
|
|---|
| 2319 | MOV I_ECX, 0
|
|---|
| 2320 | UTIMES_RET: POP PROCESS_PTR
|
|---|
| 2321 | RET
|
|---|
| 2322 |
|
|---|
| 2323 | UTIMES_1: PUSH EAX
|
|---|
| 2324 | MOV AH, 3EH
|
|---|
| 2325 | INT 21H
|
|---|
| 2326 | POP EAX
|
|---|
| 2327 | UTIMES_ERROR: MOV I_EAX, -1
|
|---|
| 2328 | MOV I_ECX, EAX
|
|---|
| 2329 | JMP SHORT UTIMES_RET
|
|---|
| 2330 |
|
|---|
| 2331 |
|
|---|
| 2332 | ; ----------------------------------------------------------------------------
|
|---|
| 2333 | ; AX=7F25H: __ftruncate()
|
|---|
| 2334 | ;
|
|---|
| 2335 | ; Truncate a file
|
|---|
| 2336 | ;
|
|---|
| 2337 | ; In: EBX File handle
|
|---|
| 2338 | ; EDX File size
|
|---|
| 2339 | ;
|
|---|
| 2340 | ; Out: EAX 0 (ok), -1 (error)
|
|---|
| 2341 | ; ECX errno
|
|---|
| 2342 | ;
|
|---|
| 2343 | ; ----------------------------------------------------------------------------
|
|---|
| 2344 |
|
|---|
| 2345 | TALIGN 4
|
|---|
| 2346 | SYS25: MOV EBX, I_EBX ; File handle
|
|---|
| 2347 | MOV EDX, 0 ; Distance
|
|---|
| 2348 | MOV AL, 2 ; SEEK_END
|
|---|
| 2349 | MOV AH, 42H ; Move file pointer
|
|---|
| 2350 | INT 21H
|
|---|
| 2351 | JC SHORT SYS25_ERR ; Error ->
|
|---|
| 2352 | CMP I_EDX, EAX ; Truncating?
|
|---|
| 2353 | JNB EMX_OK ; No -> ignore request, OK
|
|---|
| 2354 | MOV EBX, I_EBX ; File handle
|
|---|
| 2355 | MOV EDX, I_EDX ; Distance
|
|---|
| 2356 | MOV AL, 0 ; SEEK_SET
|
|---|
| 2357 | MOV AH, 42H ; Move file pointer
|
|---|
| 2358 | INT 21H
|
|---|
| 2359 | JC SHORT SYS25_ERR ; Error ->
|
|---|
| 2360 | MOV EBX, I_EBX ; File handle
|
|---|
| 2361 | MOV ECX, 0 ; Number of bytes
|
|---|
| 2362 | MOV EDX, 0 ; Buffer
|
|---|
| 2363 | MOV AH, 40H ; Write handle
|
|---|
| 2364 | INT 21H
|
|---|
| 2365 | JNC EMX_OK
|
|---|
| 2366 | SYS25_ERR: MOV I_ECX, EAX
|
|---|
| 2367 | MOV I_EAX, -1
|
|---|
| 2368 | RET
|
|---|
| 2369 |
|
|---|
| 2370 | ; ----------------------------------------------------------------------------
|
|---|
| 2371 | ; AX=7F26H: __clock()
|
|---|
| 2372 | ;
|
|---|
| 2373 | ; Processor time
|
|---|
| 2374 | ;
|
|---|
| 2375 | ; Out: EAX timer ticks of processor time used, low-order 32 bits
|
|---|
| 2376 | ; EDX high-order 32 bits
|
|---|
| 2377 | ;
|
|---|
| 2378 | ; ----------------------------------------------------------------------------
|
|---|
| 2379 | TALIGN 4
|
|---|
| 2380 | SYS26: MOV EAX, CLOCK_HI
|
|---|
| 2381 | MOV EBX, CLOCK_LO
|
|---|
| 2382 | CMP EAX, CLOCK_HI
|
|---|
| 2383 | JNE SHORT SYS26
|
|---|
| 2384 | MOV ECX, 500
|
|---|
| 2385 | MUL ECX
|
|---|
| 2386 | XCHG EAX, EBX
|
|---|
| 2387 | MUL ECX ; Multiply by 100 / 18.2
|
|---|
| 2388 | ADD EDX, EBX
|
|---|
| 2389 | PUSH EAX
|
|---|
| 2390 | MOV EAX, EDX
|
|---|
| 2391 | XOR EDX, EDX
|
|---|
| 2392 | MOV ECX, 91
|
|---|
| 2393 | DIV ECX
|
|---|
| 2394 | MOV I_EDX, EAX
|
|---|
| 2395 | POP EAX
|
|---|
| 2396 | DIV ECX
|
|---|
| 2397 | MOV I_EAX, EAX
|
|---|
| 2398 | RET
|
|---|
| 2399 |
|
|---|
| 2400 | ; ----------------------------------------------------------------------------
|
|---|
| 2401 | ; AX=7F27H: __ftime()
|
|---|
| 2402 | ;
|
|---|
| 2403 | ; Get current time
|
|---|
| 2404 | ;
|
|---|
| 2405 | ; In: EDX pointer to structure
|
|---|
| 2406 | ;
|
|---|
| 2407 | ; ----------------------------------------------------------------------------
|
|---|
| 2408 | TALIGN 4
|
|---|
| 2409 | SYS27: MOV EDI, I_EDX
|
|---|
| 2410 | MOV ES, I_DS
|
|---|
| 2411 | CALL DO_FTIME
|
|---|
| 2412 | RET
|
|---|
| 2413 |
|
|---|
| 2414 |
|
|---|
| 2415 | ; ----------------------------------------------------------------------------
|
|---|
| 2416 | ; AX=7F28H: __umask()
|
|---|
| 2417 | ;
|
|---|
| 2418 | ; Set file permission mask
|
|---|
| 2419 | ;
|
|---|
| 2420 | ; In: EDX file permission mask
|
|---|
| 2421 | ;
|
|---|
| 2422 | ; Out: EAX previous file permission mask
|
|---|
| 2423 | ;
|
|---|
| 2424 | ; ----------------------------------------------------------------------------
|
|---|
| 2425 | TALIGN 4
|
|---|
| 2426 | ASSUME DI:PTR PROCESS
|
|---|
| 2427 | SYS28: MOV AX, WORD PTR I_EDX
|
|---|
| 2428 | XCHG AX, [DI].P_UMASK
|
|---|
| 2429 | MOVZX EAX, AX
|
|---|
| 2430 | MOV I_EAX, EAX
|
|---|
| 2431 | RET
|
|---|
| 2432 |
|
|---|
| 2433 | ASSUME DI:NOTHING
|
|---|
| 2434 |
|
|---|
| 2435 | ; ----------------------------------------------------------------------------
|
|---|
| 2436 | ; AX=7F29H: __getppid()
|
|---|
| 2437 | ;
|
|---|
| 2438 | ; Get parent process ID
|
|---|
| 2439 | ;
|
|---|
| 2440 | ; Out: EAX parent process ID
|
|---|
| 2441 | ;
|
|---|
| 2442 | ; ----------------------------------------------------------------------------
|
|---|
| 2443 | TALIGN 4
|
|---|
| 2444 | ASSUME DI:PTR PROCESS
|
|---|
| 2445 | SYS29: MOV EAX, [DI].P_PPID
|
|---|
| 2446 | MOV I_EAX, EAX
|
|---|
| 2447 | RET
|
|---|
| 2448 |
|
|---|
| 2449 | ASSUME DI:NOTHING
|
|---|
| 2450 |
|
|---|
| 2451 | ; ----------------------------------------------------------------------------
|
|---|
| 2452 | ; AX=7F2AH: __nls_memupr()
|
|---|
| 2453 | ;
|
|---|
| 2454 | ; Convert buffer to upper case
|
|---|
| 2455 | ;
|
|---|
| 2456 | ; In: EDX pointer to buffer
|
|---|
| 2457 | ; ECX size of buffer
|
|---|
| 2458 | ;
|
|---|
| 2459 | ; ----------------------------------------------------------------------------
|
|---|
| 2460 | TALIGN 4
|
|---|
| 2461 | SYS2A: MOV AX, I_DS
|
|---|
| 2462 | MOV ESI, I_EDX
|
|---|
| 2463 | MOV EDI, OFFSET_1
|
|---|
| 2464 | MOV ECX, I_ECX
|
|---|
| 2465 | MOV RM_DX, DI ; Offset of buffer
|
|---|
| 2466 | MOV RM_CX, CX
|
|---|
| 2467 | CALL MOVE_TO_RM
|
|---|
| 2468 | MOV RM_AX, 7F2AH
|
|---|
| 2469 | CALL INT_RM
|
|---|
| 2470 | MOV AX, I_DS
|
|---|
| 2471 | MOV EDI, I_EDX
|
|---|
| 2472 | MOV ECX, I_ECX
|
|---|
| 2473 | CALL MOVE_FROM_RM
|
|---|
| 2474 | RET
|
|---|
| 2475 |
|
|---|
| 2476 |
|
|---|
| 2477 |
|
|---|
| 2478 | ; ----------------------------------------------------------------------------
|
|---|
| 2479 | ; AX=7F2BH: __open
|
|---|
| 2480 | ;
|
|---|
| 2481 | ; Open file
|
|---|
| 2482 | ;
|
|---|
| 2483 | ; In: EDX pointer to file name
|
|---|
| 2484 | ; ECX flags
|
|---|
| 2485 | ;
|
|---|
| 2486 | ; Out: EAX handle or -1
|
|---|
| 2487 | ; ECX errno (0 if successful)
|
|---|
| 2488 | ;
|
|---|
| 2489 | ; ----------------------------------------------------------------------------
|
|---|
| 2490 | ;
|
|---|
| 2491 | ; Replace "/dev/null" with "nul"
|
|---|
| 2492 | ;
|
|---|
| 2493 | SYS2B_NUL: MOV I_EDX, OFFSET $NUL ; Use "nul" instead
|
|---|
| 2494 | MOV SI, DS
|
|---|
| 2495 | JMP SHORT SYS2B_1
|
|---|
| 2496 |
|
|---|
| 2497 | ;
|
|---|
| 2498 | ; Replace "/dev/tty" with "con"
|
|---|
| 2499 | ;
|
|---|
| 2500 | SYS2B_CON: MOV I_EDX, OFFSET $CON ; Use "con" instead
|
|---|
| 2501 | MOV SI, DS
|
|---|
| 2502 | JMP SHORT SYS2B_1
|
|---|
| 2503 |
|
|---|
| 2504 | ;
|
|---|
| 2505 | ; __open()
|
|---|
| 2506 | ;
|
|---|
| 2507 | TALIGN 4
|
|---|
| 2508 | SYS2B: LEA ESI, $DEVNULL
|
|---|
| 2509 | MOV EDI, I_EDX
|
|---|
| 2510 | MOV ES, I_DS
|
|---|
| 2511 | CALL STRCMP ; "/dev/null"?
|
|---|
| 2512 | JE SHORT SYS2B_NUL ; Yes -> use "nul"
|
|---|
| 2513 | LEA ESI, $DEVTTY
|
|---|
| 2514 | MOV EDI, I_EDX
|
|---|
| 2515 | CALL STRCMP ; "/dev/tty"?
|
|---|
| 2516 | JE SHORT SYS2B_CON ; Yes -> use "con"
|
|---|
| 2517 | MOV SI, I_DS
|
|---|
| 2518 | SYS2B_1: MOV EDX, I_EDX ; File name
|
|---|
| 2519 | MOV AL, BYTE PTR I_ECX[0] ; Open mode
|
|---|
| 2520 | MOV AH, 3DH
|
|---|
| 2521 | PUSH DS
|
|---|
| 2522 | MOV DS, SI
|
|---|
| 2523 | INT 21H
|
|---|
| 2524 | POP DS
|
|---|
| 2525 | JC SHORT SYS2B_FAILED
|
|---|
| 2526 | ;
|
|---|
| 2527 | ; File exists
|
|---|
| 2528 | ;
|
|---|
| 2529 | MOV EDX, I_ECX
|
|---|
| 2530 | AND EDX, 30000H ; O_CREAT|O_EXCL
|
|---|
| 2531 | CMP EDX, 30000H ; O_CREAT and O_EXCL set?
|
|---|
| 2532 | JE SYS2B_EXFAIL ; Yes -> fail
|
|---|
| 2533 | MOV I_EAX, EAX ; Save the handle
|
|---|
| 2534 | SYS2B_OK: TEST I_ECX, 40000H ; O_TRUNC set?
|
|---|
| 2535 | JZ SHORT SYS2B_SUCCESS ; No -> don't truncate file
|
|---|
| 2536 | MOV EBX, EAX ; File handle
|
|---|
| 2537 | XOR EDX, EDX ; Distance = 0
|
|---|
| 2538 | MOV AL, 0 ; SEEK_SET
|
|---|
| 2539 | MOV AH, 42H ; Move file pointer
|
|---|
| 2540 | INT 21H
|
|---|
| 2541 | JC SHORT SYS2B_SUCCESS ; Ignore error (device!)
|
|---|
| 2542 | MOV EBX, I_EAX ; File handle
|
|---|
| 2543 | MOV ECX, 0 ; Number of bytes
|
|---|
| 2544 | MOV EDX, 0 ; Buffer
|
|---|
| 2545 | MOV AH, 40H ; Write handle
|
|---|
| 2546 | INT 21H ; Ignore error (device!)
|
|---|
| 2547 | ;
|
|---|
| 2548 | ; Opening the file succeeded. Set the handle flags.
|
|---|
| 2549 | ;
|
|---|
| 2550 | SYS2B_SUCCESS: TEST I_ECX, 80000H ; O_NOINHERIT?
|
|---|
| 2551 | JZ SHORT SYS2B_RET
|
|---|
| 2552 | MOV BX, PROCESS_PTR
|
|---|
| 2553 | CMP BX, NO_PROCESS
|
|---|
| 2554 | JE SHORT SYS2B_RET
|
|---|
| 2555 | ASSUME BX:PTR PROCESS
|
|---|
| 2556 | MOV SI, WORD PTR I_EAX
|
|---|
| 2557 | SHL SI, 1
|
|---|
| 2558 | OR [BX].P_HFLAGS[SI], HF_NOINHERIT
|
|---|
| 2559 | ASSUME BX:NOTHING
|
|---|
| 2560 | SYS2B_RET: MOV I_ECX, 0 ; Success
|
|---|
| 2561 | RET
|
|---|
| 2562 |
|
|---|
| 2563 | ;
|
|---|
| 2564 | ; Opening an existing file failed.
|
|---|
| 2565 | ;
|
|---|
| 2566 | SYS2B_FAILED: CMP EAX, ENOENT ; No such file?
|
|---|
| 2567 | JNE SHORT SYS2B_ERR ; No -> fail
|
|---|
| 2568 | TEST I_ECX, 10000H ; O_CREAT?
|
|---|
| 2569 | JZ SHORT SYS2B_ERR ; No -> fail
|
|---|
| 2570 | ;
|
|---|
| 2571 | ; Try to create the file
|
|---|
| 2572 | ;
|
|---|
| 2573 | MOV EDX, I_EDX ; File name
|
|---|
| 2574 | MOVZX CX, BYTE PTR I_ECX[1]
|
|---|
| 2575 | MOV AH, 3CH ; umask is applied by
|
|---|
| 2576 | PUSH DS ; function 3CH
|
|---|
| 2577 | MOV DS, SI
|
|---|
| 2578 | INT 21H
|
|---|
| 2579 | POP DS
|
|---|
| 2580 | JC SHORT SYS2B_ERR
|
|---|
| 2581 | MOV I_EAX, EAX ; Save the handle
|
|---|
| 2582 | JMP SHORT SYS2B_SUCCESS ; Done
|
|---|
| 2583 |
|
|---|
| 2584 | SYS2B_ERR: MOV I_ECX, EAX
|
|---|
| 2585 | MOV I_EAX, -1
|
|---|
| 2586 | RET
|
|---|
| 2587 |
|
|---|
| 2588 | SYS2B_EXFAIL: MOV EBX, EAX ; File handle
|
|---|
| 2589 | MOV AH, 3EH ; Close handle
|
|---|
| 2590 | INT 21H
|
|---|
| 2591 | MOV EAX, EEXIST
|
|---|
| 2592 | JMP SHORT SYS2B_ERR
|
|---|
| 2593 |
|
|---|
| 2594 | ; ----------------------------------------------------------------------------
|
|---|
| 2595 | ; AX=7F2CH: __newthread
|
|---|
| 2596 | ;
|
|---|
| 2597 | ; Notify emx of new thread
|
|---|
| 2598 | ;
|
|---|
| 2599 | ; In: EDX Thread ID
|
|---|
| 2600 | ;
|
|---|
| 2601 | ; ----------------------------------------------------------------------------
|
|---|
| 2602 |
|
|---|
| 2603 | TALIGN 4
|
|---|
| 2604 | SYS2C: MOV I_ECX, ENOSYS
|
|---|
| 2605 | MOV I_EAX, -1
|
|---|
| 2606 | RET
|
|---|
| 2607 |
|
|---|
| 2608 | ; ----------------------------------------------------------------------------
|
|---|
| 2609 | ; AX=7F2DH: __endthread
|
|---|
| 2610 | ;
|
|---|
| 2611 | ; Notify emx of end of thread
|
|---|
| 2612 | ;
|
|---|
| 2613 | ; In: EDX Thread ID
|
|---|
| 2614 | ;
|
|---|
| 2615 | ; ----------------------------------------------------------------------------
|
|---|
| 2616 |
|
|---|
| 2617 | TALIGN 4
|
|---|
| 2618 | SYS2D: MOV I_ECX, ENOSYS
|
|---|
| 2619 | MOV I_EAX, -1
|
|---|
| 2620 | RET
|
|---|
| 2621 |
|
|---|
| 2622 | ; ----------------------------------------------------------------------------
|
|---|
| 2623 | ; AX=7F2EH: __waitpid()
|
|---|
| 2624 | ;
|
|---|
| 2625 | ; Wait for child process
|
|---|
| 2626 | ;
|
|---|
| 2627 | ; In: EDX Process ID
|
|---|
| 2628 | ; ECX Options
|
|---|
| 2629 | ;
|
|---|
| 2630 | ; Out: EAX Process ID of child process (-1 if no children)
|
|---|
| 2631 | ; ECX errno
|
|---|
| 2632 | ; EDX Termination status
|
|---|
| 2633 | ;
|
|---|
| 2634 | ; ----------------------------------------------------------------------------
|
|---|
| 2635 |
|
|---|
| 2636 | TALIGN 4
|
|---|
| 2637 | SYS2E: MOV I_ECX, ENOSYS
|
|---|
| 2638 | MOV I_EDX, 0
|
|---|
| 2639 | MOV I_EAX, -1
|
|---|
| 2640 | RET
|
|---|
| 2641 |
|
|---|
| 2642 | ; ----------------------------------------------------------------------------
|
|---|
| 2643 | ; AX=7F2FH: __read_kbd()
|
|---|
| 2644 | ;
|
|---|
| 2645 | ; Keyboard input
|
|---|
| 2646 | ;
|
|---|
| 2647 | ; In: EDX flags (bit 0: echo, bit 1: wait, bit 2:sig)
|
|---|
| 2648 | ;
|
|---|
| 2649 | ; Out: EAX Character (or -1)
|
|---|
| 2650 | ;
|
|---|
| 2651 | ; ----------------------------------------------------------------------------
|
|---|
| 2652 |
|
|---|
| 2653 | RK_ECHO = 1
|
|---|
| 2654 | RK_WAIT = 2
|
|---|
| 2655 | RK_SIG = 4
|
|---|
| 2656 |
|
|---|
| 2657 | TALIGN 4
|
|---|
| 2658 | SYS2F: TEST I_EDX, RK_SIG
|
|---|
| 2659 | JNZ SHORT RKBD_SIG
|
|---|
| 2660 | TEST I_EDX, RK_WAIT
|
|---|
| 2661 | JNZ SHORT RKBD_WAIT
|
|---|
| 2662 | MOV DL, 0FFH
|
|---|
| 2663 | MOV AH, 06H
|
|---|
| 2664 | INT 21H
|
|---|
| 2665 | JZ SHORT RKBD_NOTHING
|
|---|
| 2666 | MOVZX EAX, AL
|
|---|
| 2667 | RKBD_ECHO: TEST I_EDX, RK_ECHO
|
|---|
| 2668 | JZ RKBD_RET
|
|---|
| 2669 | PUSH EAX
|
|---|
| 2670 | MOV DL, AL
|
|---|
| 2671 | MOV AH, 06H
|
|---|
| 2672 | INT 21H
|
|---|
| 2673 | POP EAX
|
|---|
| 2674 | RKBD_RET: MOV I_EAX, EAX
|
|---|
| 2675 | RET
|
|---|
| 2676 |
|
|---|
| 2677 | RKBD_WAIT: MOV AH, 07H
|
|---|
| 2678 | INT 21H
|
|---|
| 2679 | MOVZX EAX, AL
|
|---|
| 2680 | JMP SHORT RKBD_ECHO
|
|---|
| 2681 |
|
|---|
| 2682 | RKBD_SIG: TEST I_EDX, RK_WAIT
|
|---|
| 2683 | JNZ SHORT RKBD_SIG_WAIT
|
|---|
| 2684 | MOV AH, 0BH
|
|---|
| 2685 | INT 21H
|
|---|
| 2686 | OR AL, AL
|
|---|
| 2687 | JZ SHORT RKBD_NOTHING
|
|---|
| 2688 | RKBD_SIG_WAIT: TEST I_EDX, RK_ECHO
|
|---|
| 2689 | JNZ SHORT RKBD_SIG_ECHO
|
|---|
| 2690 | MOV AH, 08H
|
|---|
| 2691 | INT 21H
|
|---|
| 2692 | MOVZX EAX, AL
|
|---|
| 2693 | JMP SHORT RKBD_RET
|
|---|
| 2694 |
|
|---|
| 2695 | RKBD_SIG_ECHO: MOV AH, 01H
|
|---|
| 2696 | INT 21H
|
|---|
| 2697 | MOVZX EAX, AL
|
|---|
| 2698 | JMP SHORT RKBD_RET
|
|---|
| 2699 |
|
|---|
| 2700 | RKBD_NOTHING: MOV EAX, -1
|
|---|
| 2701 | JMP SHORT RKBD_RET
|
|---|
| 2702 |
|
|---|
| 2703 |
|
|---|
| 2704 | ; ----------------------------------------------------------------------------
|
|---|
| 2705 | ; AX=7F30H: __sleep2()
|
|---|
| 2706 | ;
|
|---|
| 2707 | ; Suspend process
|
|---|
| 2708 | ;
|
|---|
| 2709 | ; In: EDX Milliseconds
|
|---|
| 2710 | ;
|
|---|
| 2711 | ; Out: EAX 0
|
|---|
| 2712 | ;
|
|---|
| 2713 | ; ----------------------------------------------------------------------------
|
|---|
| 2714 |
|
|---|
| 2715 | TALIGN 4
|
|---|
| 2716 | SYS30: MOV I_EAX, 0 ; Return value
|
|---|
| 2717 | MOV EAX, I_EDX
|
|---|
| 2718 | OR EAX, EAX
|
|---|
| 2719 | JZ SHORT SYS30_RET
|
|---|
| 2720 | MOV ECX, 91
|
|---|
| 2721 | MUL ECX ; Multiply by 0.0182 = 91/5000
|
|---|
| 2722 | ADD EAX, 4999
|
|---|
| 2723 | ADC EDX, 0
|
|---|
| 2724 | MOV ECX, 5000
|
|---|
| 2725 | DIV ECX
|
|---|
| 2726 | MOV BX, DI
|
|---|
| 2727 | CALL SLEEP ; Suspend process
|
|---|
| 2728 | SYS30_RET: RET
|
|---|
| 2729 |
|
|---|
| 2730 |
|
|---|
| 2731 | ; ----------------------------------------------------------------------------
|
|---|
| 2732 | ; AX=7F31H: __unwind2()
|
|---|
| 2733 | ;
|
|---|
| 2734 | ; Unwind signal handlers for longjmp()
|
|---|
| 2735 | ;
|
|---|
| 2736 | ; Currently not used by the DOS version of emx.
|
|---|
| 2737 | ;
|
|---|
| 2738 | ; ----------------------------------------------------------------------------
|
|---|
| 2739 |
|
|---|
| 2740 | TALIGN 4
|
|---|
| 2741 | SYS31: RET
|
|---|
| 2742 |
|
|---|
| 2743 |
|
|---|
| 2744 | ; ----------------------------------------------------------------------------
|
|---|
| 2745 | ; AX=7F32H: __pause()
|
|---|
| 2746 | ;
|
|---|
| 2747 | ; Wait for signal
|
|---|
| 2748 | ;
|
|---|
| 2749 | ; Currently not implemented
|
|---|
| 2750 | ;
|
|---|
| 2751 | ; ----------------------------------------------------------------------------
|
|---|
| 2752 |
|
|---|
| 2753 | TALIGN 4
|
|---|
| 2754 | SYS32: RET
|
|---|
| 2755 |
|
|---|
| 2756 |
|
|---|
| 2757 | ; ----------------------------------------------------------------------------
|
|---|
| 2758 | ; AX=7F33H: __execname()
|
|---|
| 2759 | ;
|
|---|
| 2760 | ; Get the name of the executable file
|
|---|
| 2761 | ;
|
|---|
| 2762 | ; In: EDX Buffer
|
|---|
| 2763 | ; ECX Buffer size
|
|---|
| 2764 | ;
|
|---|
| 2765 | ; Out: EAX 0 if successful, -1 otherwise
|
|---|
| 2766 | ;
|
|---|
| 2767 | ; ----------------------------------------------------------------------------
|
|---|
| 2768 | TALIGN 4
|
|---|
| 2769 | SYS33: MOV I_EAX, -1
|
|---|
| 2770 | RET
|
|---|
| 2771 |
|
|---|
| 2772 |
|
|---|
| 2773 | ; ----------------------------------------------------------------------------
|
|---|
| 2774 | ; AX=7F34H: __initthread()
|
|---|
| 2775 | ;
|
|---|
| 2776 | ; Install exception handler in new thread
|
|---|
| 2777 | ;
|
|---|
| 2778 | ; In: EDX Pointer to EXCEPTIONREGISTRATIONRECORD
|
|---|
| 2779 | ;
|
|---|
| 2780 | ; Out: EAX 0 if successful, -1 otherwise
|
|---|
| 2781 | ;
|
|---|
| 2782 | ; ----------------------------------------------------------------------------
|
|---|
| 2783 | TALIGN 4
|
|---|
| 2784 | SYS34: MOV I_EAX, -1
|
|---|
| 2785 | RET
|
|---|
| 2786 |
|
|---|
| 2787 |
|
|---|
| 2788 | ; ----------------------------------------------------------------------------
|
|---|
| 2789 | ; AX=7F35H: __sigaction()
|
|---|
| 2790 | ;
|
|---|
| 2791 | ; Examine or specify action for a signal
|
|---|
| 2792 | ;
|
|---|
| 2793 | ; In: ECX Signal number
|
|---|
| 2794 | ; EDX Pointer to sigaction structure (input)
|
|---|
| 2795 | ; EBX Pointer to sigaction structure (output)
|
|---|
| 2796 | ;
|
|---|
| 2797 | ; Out: EAX 0 if successful, -1 otherwise
|
|---|
| 2798 | ; ECX errno (0 if no error)
|
|---|
| 2799 | ;
|
|---|
| 2800 | ; ----------------------------------------------------------------------------
|
|---|
| 2801 | TALIGN 4
|
|---|
| 2802 | ASSUME DI:PTR PROCESS
|
|---|
| 2803 | SYS35: MOV EAX, I_ECX
|
|---|
| 2804 | MOV EDX, I_EDX
|
|---|
| 2805 | MOV EBX, I_EBX
|
|---|
| 2806 | MOV ES, I_DS
|
|---|
| 2807 | CALL DO_SIGACTION
|
|---|
| 2808 | MOV I_ECX, EAX
|
|---|
| 2809 | MOV I_EAX, 0
|
|---|
| 2810 | TEST EAX, EAX
|
|---|
| 2811 | JZ SHORT SYS35_RET
|
|---|
| 2812 | MOV I_EAX, -1
|
|---|
| 2813 | SYS35_RET: RET
|
|---|
| 2814 |
|
|---|
| 2815 |
|
|---|
| 2816 | ; ----------------------------------------------------------------------------
|
|---|
| 2817 | ; AX=7F36H: __sigpending()
|
|---|
| 2818 | ;
|
|---|
| 2819 | ; Query set of pending signals
|
|---|
| 2820 | ;
|
|---|
| 2821 | ; In: EDX Pointer to sigset_t (output)
|
|---|
| 2822 | ;
|
|---|
| 2823 | ; Out: EAX 0 if successful, -1 otherwise
|
|---|
| 2824 | ; ECX errno (0 if no error)
|
|---|
| 2825 | ;
|
|---|
| 2826 | ; ----------------------------------------------------------------------------
|
|---|
| 2827 | TALIGN 4
|
|---|
| 2828 | ASSUME DI:PTR PROCESS
|
|---|
| 2829 | SYS36: MOV EAX, [DI].P_SIG_BLOCKED
|
|---|
| 2830 | AND EAX, [DI].P_SIG_PENDING
|
|---|
| 2831 | SHR EAX, 1
|
|---|
| 2832 | MOV EBX, I_EDX
|
|---|
| 2833 | MOV ES, I_DS
|
|---|
| 2834 | MOV ES:[EBX], EAX
|
|---|
| 2835 | MOV I_EAX, 0
|
|---|
| 2836 | MOV I_ECX, 0
|
|---|
| 2837 | RET
|
|---|
| 2838 |
|
|---|
| 2839 |
|
|---|
| 2840 | ; ----------------------------------------------------------------------------
|
|---|
| 2841 | ; AX=7F37H: __sigprocmask()
|
|---|
| 2842 | ;
|
|---|
| 2843 | ; Examine or change the signal mask
|
|---|
| 2844 | ;
|
|---|
| 2845 | ; In: ECX Manner in which to set the mask
|
|---|
| 2846 | ; EDX Pointer to sigset_t (input)
|
|---|
| 2847 | ; EBX Pointer to sigset_t (output)
|
|---|
| 2848 | ;
|
|---|
| 2849 | ; Out: EAX 0 if successful, -1 otherwise
|
|---|
| 2850 | ; ECX errno (0 if no error)
|
|---|
| 2851 | ;
|
|---|
| 2852 | ; ----------------------------------------------------------------------------
|
|---|
| 2853 | TALIGN 4
|
|---|
| 2854 | ASSUME DI:PTR PROCESS
|
|---|
| 2855 | SYS37: PUSH [DI].P_SIG_BLOCKED
|
|---|
| 2856 | MOV EBX, I_EDX
|
|---|
| 2857 | TEST EBX, EBX
|
|---|
| 2858 | JZ SHORT SPM_NO_INPUT
|
|---|
| 2859 | MOV ES, I_DS
|
|---|
| 2860 | MOV EAX, ES:[EBX]
|
|---|
| 2861 | SHL EAX, 1
|
|---|
| 2862 | CMP I_ECX, SIG_BLOCK
|
|---|
| 2863 | JE SHORT SPM_BLOCK
|
|---|
| 2864 | CMP I_ECX, SIG_UNBLOCK
|
|---|
| 2865 | JE SHORT SPM_UNBLOCK
|
|---|
| 2866 | CMP I_ECX, SIG_SETMASK
|
|---|
| 2867 | JE SHORT SPM_SETMASK
|
|---|
| 2868 | POP EAX
|
|---|
| 2869 | MOV I_EAX, -1
|
|---|
| 2870 | MOV I_ECX, EINVAL
|
|---|
| 2871 | RET
|
|---|
| 2872 |
|
|---|
| 2873 | SPM_UNBLOCK: NOT EAX
|
|---|
| 2874 | AND EAX, [DI].P_SIG_BLOCKED
|
|---|
| 2875 | JMP SHORT SPM_SETMASK
|
|---|
| 2876 |
|
|---|
| 2877 | SPM_BLOCK: OR EAX, [DI].P_SIG_BLOCKED
|
|---|
| 2878 | SPM_SETMASK: AND EAX, SIG_BLOCK_MASK
|
|---|
| 2879 | MOV [DI].P_SIG_BLOCKED, EAX
|
|---|
| 2880 | SPM_NO_INPUT: POP EAX
|
|---|
| 2881 | MOV EBX, I_EBX
|
|---|
| 2882 | TEST EBX, EBX
|
|---|
| 2883 | JZ SHORT SPM_NO_OUTPUT
|
|---|
| 2884 | SHR EAX, 1
|
|---|
| 2885 | MOV ES:[EBX], EAX
|
|---|
| 2886 | SPM_NO_OUTPUT: MOV I_EAX, 0
|
|---|
| 2887 | MOV I_ECX, 0
|
|---|
| 2888 | RET
|
|---|
| 2889 |
|
|---|
| 2890 |
|
|---|
| 2891 | ; ----------------------------------------------------------------------------
|
|---|
| 2892 | ; AX=7F38H: __sigsuspend()
|
|---|
| 2893 | ;
|
|---|
| 2894 | ; Replace signal mask and wait for signal
|
|---|
| 2895 | ;
|
|---|
| 2896 | ; In: EDX Pointer to sigset_t (input)
|
|---|
| 2897 | ;
|
|---|
| 2898 | ; Out: EAX 0 if successful, -1 otherwise
|
|---|
| 2899 | ; ECX errno (0 if no error)
|
|---|
| 2900 | ;
|
|---|
| 2901 | ; Currently not implemented
|
|---|
| 2902 | ;
|
|---|
| 2903 | ; ----------------------------------------------------------------------------
|
|---|
| 2904 | TALIGN 4
|
|---|
| 2905 | ASSUME DI:PTR PROCESS
|
|---|
| 2906 | SYS38: MOV I_EAX, -1
|
|---|
| 2907 | MOV I_ECX, ENOSYS
|
|---|
| 2908 | RET
|
|---|
| 2909 |
|
|---|
| 2910 | ; ----------------------------------------------------------------------------
|
|---|
| 2911 | ; AX=7F39H: __imphandle()
|
|---|
| 2912 | ;
|
|---|
| 2913 | ; Import a file handle
|
|---|
| 2914 | ;
|
|---|
| 2915 | ; In: EDX File handle
|
|---|
| 2916 | ;
|
|---|
| 2917 | ; Out: EAX Relocated file handle (success) or -1 (failure)
|
|---|
| 2918 | ; ECX errno (0 if no error)
|
|---|
| 2919 | ;
|
|---|
| 2920 | ; ----------------------------------------------------------------------------
|
|---|
| 2921 |
|
|---|
| 2922 | TALIGN 4
|
|---|
| 2923 | SYS39: MOV I_ECX, ENOSYS
|
|---|
| 2924 | MOV I_EAX, -1
|
|---|
| 2925 | RET
|
|---|
| 2926 |
|
|---|
| 2927 | ; ----------------------------------------------------------------------------
|
|---|
| 2928 | ; AX=7F3AH: __fpuemu()
|
|---|
| 2929 | ;
|
|---|
| 2930 | ; Interface for floating point emulator
|
|---|
| 2931 | ;
|
|---|
| 2932 | ; In: ECX Command code
|
|---|
| 2933 | ; EDX Pointer to communication area
|
|---|
| 2934 | ;
|
|---|
| 2935 | ; Out: EAX Relocated file handle (success) or -1 (failure)
|
|---|
| 2936 | ; ECX errno (0 if no error)
|
|---|
| 2937 | ;
|
|---|
| 2938 | ; ----------------------------------------------------------------------------
|
|---|
| 2939 | TALIGN 4
|
|---|
| 2940 | ASSUME DI:PTR PROCESS
|
|---|
| 2941 | SYS3A: CMP I_ECX, FPUC_INIT
|
|---|
| 2942 | JE SHORT FPUEMU_INIT
|
|---|
| 2943 | CMP PROCESS_FPUEMU, DI ; Correct process?
|
|---|
| 2944 | JNE FPUEMU_FAIL ; No -> fail
|
|---|
| 2945 | CMP I_ECX, FPUC_NEXT
|
|---|
| 2946 | JE SHORT FPUEMU_NEXT ; Yes -> wait for notification
|
|---|
| 2947 | CMP I_ECX, FPUC_SIGNAL
|
|---|
| 2948 | JE FPUEMU_SIGNAL
|
|---|
| 2949 |
|
|---|
| 2950 | ;
|
|---|
| 2951 | ; The FP emulator waits for the next notification; switch back to the
|
|---|
| 2952 | ; interrupted process
|
|---|
| 2953 | ;
|
|---|
| 2954 | FPUEMU_NEXT: CMP FPUEMU_STATE, FES_ON
|
|---|
| 2955 | JNE SHORT FPUEMU_NEXT_1
|
|---|
| 2956 | MOV AX, 0
|
|---|
| 2957 | MOV FS, AX ; Avoid trap on POP FS
|
|---|
| 2958 | MOV [DI].P_STATUS, PS_FPUEMU_NEXT
|
|---|
| 2959 | MOV BX, DI
|
|---|
| 2960 | CALL SAVE_PROCESS
|
|---|
| 2961 | MOV DI, PROCESS_FPUCLIENT
|
|---|
| 2962 | ASSUME DI:PTR PROCESS
|
|---|
| 2963 | MOV PROCESS_PTR, DI
|
|---|
| 2964 | MOV ES, I_DS
|
|---|
| 2965 | MOV ESI, I_EDX
|
|---|
| 2966 | ASSUME ESI:NEAR32 PTR FPUEMU_COM
|
|---|
| 2967 | MOV CX, I_REG_DWORDS
|
|---|
| 2968 | XOR EBX, EBX
|
|---|
| 2969 | FEN_LOOP: MOV EAX, ES:[ESI].FEC_FRAME[EBX]
|
|---|
| 2970 | MOV DWORD PTR [DI].P_GS[BX], EAX
|
|---|
| 2971 | ADD BX, 4
|
|---|
| 2972 | LOOP FEN_LOOP
|
|---|
| 2973 | MOV BX, DI
|
|---|
| 2974 | CALL REST_PROCESS
|
|---|
| 2975 | ;;;; CALL BREAK_AFTER_IRET
|
|---|
| 2976 | ASSUME DI:NOTHING
|
|---|
| 2977 | RET
|
|---|
| 2978 |
|
|---|
| 2979 | FPUEMU_INIT: CMP PROCESS_FPUEMU, NO_PROCESS ; FPU emu already installed?
|
|---|
| 2980 | JNE FPUEMU_FAIL
|
|---|
| 2981 | CMP FPUEMU_STATE, FES_LOADING
|
|---|
| 2982 | JNE FPUEMU_FAIL
|
|---|
| 2983 | MOV PROCESS_FPUEMU, DI
|
|---|
| 2984 | MOV FPUEMU_STATE, FES_INIT1
|
|---|
| 2985 | JMP EMX_OK
|
|---|
| 2986 |
|
|---|
| 2987 | ASSUME DI:PTR PROCESS
|
|---|
| 2988 | FPUEMU_NEXT_1: CMP FPUEMU_STATE, FES_ENDPROC
|
|---|
| 2989 | JE FPUEMU_ENDPROC_1
|
|---|
| 2990 | CMP FPUEMU_STATE, FES_NEWPROC
|
|---|
| 2991 | JE SHORT FPUEMU_NEWPROC_1
|
|---|
| 2992 | CMP FPUEMU_STATE, FES_INIT1
|
|---|
| 2993 | JNE FPUEMU_EXIT ; TODO
|
|---|
| 2994 | ;
|
|---|
| 2995 | ; Send FPUN_NEWPROC notifications for all processes
|
|---|
| 2996 | ;
|
|---|
| 2997 | LEA BX, PROCESS_TABLE
|
|---|
| 2998 | ASSUME BX:PTR PROCESS
|
|---|
| 2999 | MOV CX, MAX_PROCESSES
|
|---|
| 3000 | NEWPROC_LOOP: TEST [BX].P_FLAGS, PF_FPUEMU_INIT
|
|---|
| 3001 | JNZ SHORT NEWPROC_NEXT
|
|---|
| 3002 | CMP [BX].P_STATUS, PS_NONE
|
|---|
| 3003 | JE SHORT NEWPROC_NEXT
|
|---|
| 3004 | CMP [BX].P_STATUS, PS_DEFUNCT
|
|---|
| 3005 | JE SHORT NEWPROC_NEXT
|
|---|
| 3006 | CMP [BX].P_STATUS, PS_INIT
|
|---|
| 3007 | JE SHORT NEWPROC_NEXT
|
|---|
| 3008 | CMP BX, PROCESS_FPUEMU
|
|---|
| 3009 | JNE SHORT NEWPROC_SEND
|
|---|
| 3010 | NEWPROC_NEXT: ADD BX, SIZE PROCESS
|
|---|
| 3011 | LOOP NEWPROC_LOOP
|
|---|
| 3012 | ASSUME BX:NOTHING
|
|---|
| 3013 | ;
|
|---|
| 3014 | ; All processes have been processed, send FPUN_EMU notification
|
|---|
| 3015 | ;
|
|---|
| 3016 | FPUEMU_NEXT_INIT2:
|
|---|
| 3017 | MOV FPUEMU_STATE, FES_ON
|
|---|
| 3018 | MOV BX, PROCESS_PTR
|
|---|
| 3019 | CALL SAVE_PROCESS
|
|---|
| 3020 | MOV BX, PROCESS_FPUCLIENT
|
|---|
| 3021 | MOV PROCESS_PTR, BX
|
|---|
| 3022 | CALL REST_PROCESS
|
|---|
| 3023 | CALL FPUEMU_CALL
|
|---|
| 3024 | JMP EMX_OK
|
|---|
| 3025 |
|
|---|
| 3026 | ;
|
|---|
| 3027 | ; Send a FPUN_NEWPROC notification
|
|---|
| 3028 | ;
|
|---|
| 3029 | ASSUME BX:PTR PROCESS
|
|---|
| 3030 | NEWPROC_SEND: OR [BX].P_FLAGS, PF_FPUEMU_INIT
|
|---|
| 3031 | MOV ES, I_DS
|
|---|
| 3032 | MOV EDI, I_EDX
|
|---|
| 3033 | ASSUME EDI:NEAR32 PTR FPUEMU_COM
|
|---|
| 3034 | MOV ES:[EDI].FEC_NOTIFY, FPUN_NEWPROC
|
|---|
| 3035 | MOV EAX, [BX].P_NUMBER
|
|---|
| 3036 | MOV ES:[EDI].FEC_PNUM, EAX
|
|---|
| 3037 | JMP EMX_OK
|
|---|
| 3038 |
|
|---|
| 3039 | ASSUME EDI:NOTHING
|
|---|
| 3040 | ASSUME BX:NOTHING
|
|---|
| 3041 |
|
|---|
| 3042 | ;
|
|---|
| 3043 | ; FPUN_ENDPROC and FPUN_NEWPROC handled
|
|---|
| 3044 | ;
|
|---|
| 3045 | ASSUME DI:PTR PROCESS
|
|---|
| 3046 | FPUEMU_ENDPROC_1:
|
|---|
| 3047 | FPUEMU_NEWPROC_1:
|
|---|
| 3048 | MOV FPUEMU_STATE, FES_ON
|
|---|
| 3049 | MOV [DI].P_STATUS, PS_FPUEMU_NEXT
|
|---|
| 3050 | MOV BX, DI
|
|---|
| 3051 | CALL SAVE_PROCESS
|
|---|
| 3052 | MOV BX, PROCESS_FPUCLIENT
|
|---|
| 3053 | MOV PROCESS_PTR, BX
|
|---|
| 3054 | CALL REST_PROCESS
|
|---|
| 3055 | RET
|
|---|
| 3056 |
|
|---|
| 3057 | ;
|
|---|
| 3058 | ; Generate a signal. Faking an exception would be better, but this
|
|---|
| 3059 | ; will do for now.
|
|---|
| 3060 | ;
|
|---|
| 3061 | FPUEMU_SIGNAL: MOV ES, I_DS
|
|---|
| 3062 | MOV ESI, I_EDX
|
|---|
| 3063 | ASSUME ESI:NEAR32 PTR FPUEMU_COM
|
|---|
| 3064 | MOV EAX, ES:[ESI].FEC_SIGNAL
|
|---|
| 3065 | MOV BX, PROCESS_FPUCLIENT
|
|---|
| 3066 | BTS (PROCESS PTR [BX]).P_SIG_PENDING, EAX ; Generate signal
|
|---|
| 3067 | JMP EMX_OK
|
|---|
| 3068 | ASSUME ESI:NOTHING
|
|---|
| 3069 |
|
|---|
| 3070 | ;
|
|---|
| 3071 | ; TODO: Error message
|
|---|
| 3072 | ;
|
|---|
| 3073 | FPUEMU_EXIT: MOV AX, 4CFFH
|
|---|
| 3074 | INT 21H
|
|---|
| 3075 |
|
|---|
| 3076 | FPUEMU_FAIL: MOV I_ECX, EINVAL
|
|---|
| 3077 | MOV I_EAX, -1
|
|---|
| 3078 | RET
|
|---|
| 3079 |
|
|---|
| 3080 | ASSUME DI:NOTHING
|
|---|
| 3081 |
|
|---|
| 3082 | ; ----------------------------------------------------------------------------
|
|---|
| 3083 | ; AX=7F58H: __settime()
|
|---|
| 3084 | ;
|
|---|
| 3085 | ; Set system time
|
|---|
| 3086 | ;
|
|---|
| 3087 | ; In: EDX Pointer to struct timeval
|
|---|
| 3088 | ;
|
|---|
| 3089 | ; Out: EAX 0 (success) or -1 (failure)
|
|---|
| 3090 | ; ECX errno (0 if no error)
|
|---|
| 3091 | ;
|
|---|
| 3092 | ; ----------------------------------------------------------------------------
|
|---|
| 3093 | TALIGN 4
|
|---|
| 3094 | SYS58: MOV ESI, I_EDX
|
|---|
| 3095 | MOV ES, I_DS
|
|---|
| 3096 | CALL DO_SETTIME
|
|---|
| 3097 | MOV I_ECX, EAX
|
|---|
| 3098 | MOV I_EAX, 0
|
|---|
| 3099 | TEST EAX, EAX
|
|---|
| 3100 | JZ SHORT SYS58_RET
|
|---|
| 3101 | MOV I_EAX, -1
|
|---|
| 3102 | SYS58_RET: RET
|
|---|
| 3103 |
|
|---|
| 3104 | ; ----------------------------------------------------------------------------
|
|---|
| 3105 | ; AX=7F59H: __profil()
|
|---|
| 3106 | ;
|
|---|
| 3107 | ; Sampling profiler
|
|---|
| 3108 | ;
|
|---|
| 3109 | ; In: EDX Pointer to struct _profil
|
|---|
| 3110 | ;
|
|---|
| 3111 | ; Out: EAX 0 (success) or -1 (failure)
|
|---|
| 3112 | ; ECX errno (0 if no error)
|
|---|
| 3113 | ;
|
|---|
| 3114 | ; ----------------------------------------------------------------------------
|
|---|
| 3115 | TALIGN 4
|
|---|
| 3116 | ASSUME DI:PTR PROCESS
|
|---|
| 3117 | SYS59: MOV ES, I_DS
|
|---|
| 3118 | MOV ESI, I_EDX
|
|---|
| 3119 | CALL DO_PROFIL
|
|---|
| 3120 | MOV I_ECX, EAX
|
|---|
| 3121 | TEST EAX, EAX
|
|---|
| 3122 | JZ SHORT SYS59_1
|
|---|
| 3123 | MOV EAX, -1
|
|---|
| 3124 | SYS59_1: MOV I_EAX, EAX
|
|---|
| 3125 | RET
|
|---|
| 3126 |
|
|---|
| 3127 | ; ----------------------------------------------------------------------------
|
|---|
| 3128 | ; AX=7F5AH: __nls_ctype()
|
|---|
| 3129 | ;
|
|---|
| 3130 | ; Mark DBCS lead bytes
|
|---|
| 3131 | ;
|
|---|
| 3132 | ; In: EDX pointer to buffer
|
|---|
| 3133 | ;
|
|---|
| 3134 | ; Out: EAX 0 (success) or -1 (failure)
|
|---|
| 3135 | ; ECX errno (0 if no error)
|
|---|
| 3136 | ;
|
|---|
| 3137 | ; ----------------------------------------------------------------------------
|
|---|
| 3138 | TALIGN 4
|
|---|
| 3139 | SYS5A: CALL GET_DBCS_LEAD
|
|---|
| 3140 | TEST AX, AX
|
|---|
| 3141 | JZ SHORT NLS_CT_COPY
|
|---|
| 3142 | JMP SYSCALL_ENOSYS
|
|---|
| 3143 |
|
|---|
| 3144 | ;
|
|---|
| 3145 | ; Copy the DBCS lead byte bits of our table to the target buffer
|
|---|
| 3146 | ;
|
|---|
| 3147 | NLS_CT_COPY: CMP I_DS, 0 ; See INIT_DBCS
|
|---|
| 3148 | JE SHORT NLS_CT_EFAULT
|
|---|
| 3149 | MOV ES, I_DS
|
|---|
| 3150 | MOV EDI, I_EDX
|
|---|
| 3151 | MOV ECX, 0
|
|---|
| 3152 | TALIGN 4
|
|---|
| 3153 | NLS_CT_COPY_BIT:BT DBCS_LEAD_TAB, CX
|
|---|
| 3154 | JC SHORT NLS_CT_COPY_SET
|
|---|
| 3155 | AND BYTE PTR ES:[EDI], 0FEH ; Clear _NLS_DBCS_LEAD
|
|---|
| 3156 | NLS_CT_COPY_NXT:INC EDI
|
|---|
| 3157 | INC CX
|
|---|
| 3158 | CMP CX, 256
|
|---|
| 3159 | JB SHORT NLS_CT_COPY_BIT
|
|---|
| 3160 | JMP EMX_OK
|
|---|
| 3161 |
|
|---|
| 3162 | TALIGN 4
|
|---|
| 3163 | NLS_CT_COPY_SET:OR BYTE PTR ES:[EDI], 01H ; Set _NLS_DBCS_LEAD
|
|---|
| 3164 | JMP SHORT NLS_CT_COPY_NXT
|
|---|
| 3165 |
|
|---|
| 3166 | NLS_CT_EFAULT: MOV I_EAX, -1
|
|---|
| 3167 | MOV I_ECX, EFAULT
|
|---|
| 3168 | RET
|
|---|
| 3169 |
|
|---|
| 3170 | ASSUME BP:NOTHING
|
|---|
| 3171 |
|
|---|
| 3172 | ; ----------------------------------------------------------------------------
|
|---|
| 3173 | ;
|
|---|
| 3174 | ; Convert a MY_DATETIME structure to Unix time format
|
|---|
| 3175 | ;
|
|---|
| 3176 | ; MDT must be in the stack!
|
|---|
| 3177 | ;
|
|---|
| 3178 | ; ----------------------------------------------------------------------------
|
|---|
| 3179 | TALIGN 4
|
|---|
| 3180 | TIME_2_UNIX PROC PASCAL USES EBX ESI, MDT:PTR MY_DATETIME
|
|---|
| 3181 | MOV BX, MDT
|
|---|
| 3182 | ASSUME BX:PTR MY_DATETIME
|
|---|
| 3183 | MOV EAX, SS:[BX].YEAR
|
|---|
| 3184 | MOV EDX, 365
|
|---|
| 3185 | MUL EDX
|
|---|
| 3186 | MOV ESI, EAX
|
|---|
| 3187 | MOV EAX, SS:[BX].MONTH
|
|---|
| 3188 | DEC EAX
|
|---|
| 3189 | MOV EDX, 31
|
|---|
| 3190 | MUL EDX
|
|---|
| 3191 | ADD ESI, EAX
|
|---|
| 3192 | ADD ESI, SS:[BX].DAY ; 365*year + day + 31*(month-1)
|
|---|
| 3193 | DEC SS:[BX].YEAR
|
|---|
| 3194 | CMP SS:[BX].MONTH, 2 ; Jan or Feb?
|
|---|
| 3195 | JBE SHORT T2U_1 ; Yes -> skip
|
|---|
| 3196 |
|
|---|
| 3197 | INC SS:[BX].YEAR
|
|---|
| 3198 | MOV EAX, SS:[BX].MONTH
|
|---|
| 3199 | SHL EAX, 2
|
|---|
| 3200 | ADD EAX, 23
|
|---|
| 3201 | XOR EDX, EDX
|
|---|
| 3202 | MOV ECX, 10
|
|---|
| 3203 | DIV ECX
|
|---|
| 3204 | SUB ESI, EAX ; - ((4*month)+23)/10
|
|---|
| 3205 |
|
|---|
| 3206 | TALIGN 4
|
|---|
| 3207 | T2U_1: MOV EAX, SS:[BX].YEAR
|
|---|
| 3208 | SHR EAX, 2
|
|---|
| 3209 | ADD ESI, EAX ; + (year{-1})/4
|
|---|
| 3210 | MOV EAX, SS:[BX].YEAR
|
|---|
| 3211 | XOR EDX, EDX
|
|---|
| 3212 | MOV ECX, 100
|
|---|
| 3213 | DIV ECX
|
|---|
| 3214 | INC EAX
|
|---|
| 3215 | MOV EDX, EAX
|
|---|
| 3216 | ADD EAX, EAX
|
|---|
| 3217 | ADD EAX, EDX
|
|---|
| 3218 | SHR EAX, 2
|
|---|
| 3219 | SUB ESI, EAX ; - (3*((year{-1})/100+1)) / 4
|
|---|
| 3220 | MOV EAX, ESI
|
|---|
| 3221 | SUB EAX, 719528 ; 01-Jan-1970
|
|---|
| 3222 | MOV EDX, 24*60*60
|
|---|
| 3223 | MUL EDX
|
|---|
| 3224 | ;
|
|---|
| 3225 | ; Add time of day
|
|---|
| 3226 | ;
|
|---|
| 3227 | ADD EAX, SS:[BX].SECONDS
|
|---|
| 3228 | MOV ESI, EAX
|
|---|
| 3229 | MOV EAX, SS:[BX].MINUTES
|
|---|
| 3230 | MOV EDX, 60
|
|---|
| 3231 | MUL EDX
|
|---|
| 3232 | ADD ESI, EAX
|
|---|
| 3233 | MOV EAX, SS:[BX].HOURS
|
|---|
| 3234 | MOV EDX, 60*60
|
|---|
| 3235 | MUL EDX
|
|---|
| 3236 | ADD EAX, ESI
|
|---|
| 3237 | RET
|
|---|
| 3238 | ASSUME BX:NOTHING
|
|---|
| 3239 | TIME_2_UNIX ENDP
|
|---|
| 3240 |
|
|---|
| 3241 | ; ----------------------------------------------------------------------------
|
|---|
| 3242 | ; Convert a packed time/date value to Unix time value (GMT)
|
|---|
| 3243 | ;
|
|---|
| 3244 | ; In: CX Time
|
|---|
| 3245 | ; DX Date
|
|---|
| 3246 | ;
|
|---|
| 3247 | ; Out: EAX Unix time
|
|---|
| 3248 | ;
|
|---|
| 3249 | ; ----------------------------------------------------------------------------
|
|---|
| 3250 | ;
|
|---|
| 3251 | TALIGN 4
|
|---|
| 3252 | PACKED_2_UNIX PROC
|
|---|
| 3253 | LOCAL MDT:MY_DATETIME
|
|---|
| 3254 | MOV AX, DX ; Day of month
|
|---|
| 3255 | AND EAX, 1FH
|
|---|
| 3256 | MOV MDT.DAY, EAX
|
|---|
| 3257 | MOV AX, DX ; Month
|
|---|
| 3258 | SHR AX, 5
|
|---|
| 3259 | AND EAX, 0FH
|
|---|
| 3260 | MOV MDT.MONTH, EAX
|
|---|
| 3261 | MOV AX, DX ; Year - 1980
|
|---|
| 3262 | SHR AX, 9
|
|---|
| 3263 | AND EAX, 7FH
|
|---|
| 3264 | ADD EAX, 1980
|
|---|
| 3265 | MOV MDT.YEAR, EAX
|
|---|
| 3266 | MOV AX, CX ; Seconds / 2
|
|---|
| 3267 | AND EAX, 1FH
|
|---|
| 3268 | SHL EAX, 1
|
|---|
| 3269 | MOV MDT.SECONDS, EAX
|
|---|
| 3270 | MOV AX, CX ; Minutes
|
|---|
| 3271 | SHR AX, 5
|
|---|
| 3272 | AND EAX, 3FH
|
|---|
| 3273 | MOV MDT.MINUTES, EAX
|
|---|
| 3274 | MOV AX, CX ; Hours
|
|---|
| 3275 | SHR AX, 11
|
|---|
| 3276 | AND EAX, 1FH
|
|---|
| 3277 | MOV MDT.HOURS, EAX
|
|---|
| 3278 | INVOKE TIME_2_UNIX, ADDR MDT
|
|---|
| 3279 | RET
|
|---|
| 3280 | PACKED_2_UNIX ENDP
|
|---|
| 3281 |
|
|---|
| 3282 |
|
|---|
| 3283 | ;
|
|---|
| 3284 | ; In: EAX Year
|
|---|
| 3285 | ;
|
|---|
| 3286 | ; Out: EAX 1 if leap year, 0 otherwise
|
|---|
| 3287 | ;
|
|---|
| 3288 | TALIGN 4
|
|---|
| 3289 | LEAP_YEAR PROC NEAR
|
|---|
| 3290 | PUSH ECX
|
|---|
| 3291 | PUSH EDX
|
|---|
| 3292 | TEST EAX, 3 ; year = 4n?
|
|---|
| 3293 | JNZ SHORT LEAP_NO ; No -> not a leap year
|
|---|
| 3294 | MOV ECX, 100
|
|---|
| 3295 | XOR EDX, EDX
|
|---|
| 3296 | DIV ECX
|
|---|
| 3297 | OR EDX, EDX ; year = 100n?
|
|---|
| 3298 | JNZ SHORT LEAP_YES ; No -> it's a leap year
|
|---|
| 3299 | TEST EAX, 3 ; year = 400n?
|
|---|
| 3300 | JNZ SHORT LEAP_NO ; No -> not a leap year
|
|---|
| 3301 | LEAP_YES: XOR EAX, EAX
|
|---|
| 3302 | INC EAX
|
|---|
| 3303 | JMP SHORT LEAP_RET
|
|---|
| 3304 |
|
|---|
| 3305 | TALIGN 4
|
|---|
| 3306 | LEAP_NO: XOR EAX, EAX
|
|---|
| 3307 | LEAP_RET: POP EDX
|
|---|
| 3308 | POP ECX
|
|---|
| 3309 | RET
|
|---|
| 3310 | LEAP_YEAR ENDP
|
|---|
| 3311 |
|
|---|
| 3312 | ; ----------------------------------------------------------------------------
|
|---|
| 3313 | ;
|
|---|
| 3314 | ; Convert a Unix time value to a MY_DATETIME structure
|
|---|
| 3315 | ;
|
|---|
| 3316 | ; MDT must be in the stack!
|
|---|
| 3317 | ;
|
|---|
| 3318 | ; ----------------------------------------------------------------------------
|
|---|
| 3319 | TALIGN 4
|
|---|
| 3320 | UNIX_2_TIME PROC PASCAL USES EBX ESI EDI,
|
|---|
| 3321 | TIME:DWORD, MDT:PTR MY_DATETIME
|
|---|
| 3322 | MOV BX, MDT
|
|---|
| 3323 | ASSUME BX:PTR MY_DATETIME
|
|---|
| 3324 | MOV EAX, TIME
|
|---|
| 3325 | MOV ECX, 60
|
|---|
| 3326 | XOR EDX, EDX
|
|---|
| 3327 | DIV ECX
|
|---|
| 3328 | MOV SS:[BX].SECONDS, EDX
|
|---|
| 3329 | XOR EDX, EDX
|
|---|
| 3330 | DIV ECX
|
|---|
| 3331 | MOV SS:[BX].MINUTES, EDX
|
|---|
| 3332 | MOV ECX, 24
|
|---|
| 3333 | XOR EDX, EDX
|
|---|
| 3334 | DIV ECX
|
|---|
| 3335 | MOV SS:[BX].HOURS, EDX
|
|---|
| 3336 | MOV ESI, 1970
|
|---|
| 3337 | MOV EDI, EAX
|
|---|
| 3338 | TALIGN 4
|
|---|
| 3339 | U2T_Y_LOOP: MOV EAX, ESI
|
|---|
| 3340 | CALL LEAP_YEAR
|
|---|
| 3341 | ADD EAX, 365
|
|---|
| 3342 | MOV ECX, EAX
|
|---|
| 3343 | INC ESI
|
|---|
| 3344 | SUB EDI, ECX
|
|---|
| 3345 | JNC SHORT U2T_Y_LOOP
|
|---|
| 3346 | ADD EDI, ECX
|
|---|
| 3347 | DEC ESI
|
|---|
| 3348 | MOV SS:[BX].YEAR, ESI
|
|---|
| 3349 | MOV ESI, 0
|
|---|
| 3350 | TALIGN 4
|
|---|
| 3351 | U2T_M_LOOP: CMP ESI, 1 ; February?
|
|---|
| 3352 | JE SHORT U2T_M_FEB
|
|---|
| 3353 | MOVZX ECX, MONTH_LEN[ESI]
|
|---|
| 3354 | JMP SHORT U2T_M_CONT
|
|---|
| 3355 | TALIGN 4
|
|---|
| 3356 | U2T_M_FEB: MOV EAX, SS:[BX].YEAR
|
|---|
| 3357 | CALL LEAP_YEAR
|
|---|
| 3358 | ADD EAX, 28
|
|---|
| 3359 | MOV ECX, EAX
|
|---|
| 3360 | TALIGN 4
|
|---|
| 3361 | U2T_M_CONT: INC ESI
|
|---|
| 3362 | SUB EDI, ECX
|
|---|
| 3363 | JNC SHORT U2T_M_LOOP
|
|---|
| 3364 | ADD EDI, ECX
|
|---|
| 3365 | MOV SS:[BX].MONTH, ESI
|
|---|
| 3366 | INC EDI
|
|---|
| 3367 | MOV SS:[BX].DAY, EDI
|
|---|
| 3368 | RET
|
|---|
| 3369 | UNIX_2_TIME ENDP
|
|---|
| 3370 |
|
|---|
| 3371 |
|
|---|
| 3372 | ;
|
|---|
| 3373 | ; Convert Unix time value (GMT) to a packed time/date value
|
|---|
| 3374 | ;
|
|---|
| 3375 | ; In: EAX Unix time
|
|---|
| 3376 | ;
|
|---|
| 3377 | ; Out: CX Time
|
|---|
| 3378 | ; DX Date
|
|---|
| 3379 | ;
|
|---|
| 3380 | UNIX_2_PACKED PROC
|
|---|
| 3381 | LOCAL MDT:MY_DATETIME
|
|---|
| 3382 | INVOKE UNIX_2_TIME, EAX, ADDR MDT
|
|---|
| 3383 |
|
|---|
| 3384 | MOV ECX, MDT.SECONDS
|
|---|
| 3385 | SHR ECX, 1
|
|---|
| 3386 | MOV EAX, MDT.MINUTES
|
|---|
| 3387 | SHL EAX, 5
|
|---|
| 3388 | OR ECX, EAX
|
|---|
| 3389 | MOV EAX, MDT.HOURS
|
|---|
| 3390 | SHL EAX, 11
|
|---|
| 3391 | OR ECX, EAX
|
|---|
| 3392 |
|
|---|
| 3393 | MOV EDX, MDT.DAY
|
|---|
| 3394 | MOV EAX, MDT.MONTH
|
|---|
| 3395 | SHL EAX, 5
|
|---|
| 3396 | OR EDX, EAX
|
|---|
| 3397 | MOV EAX, MDT.YEAR
|
|---|
| 3398 | SUB EAX, 1980
|
|---|
| 3399 | SHL EAX, 9
|
|---|
| 3400 | OR EDX, EAX
|
|---|
| 3401 | RET
|
|---|
| 3402 | UNIX_2_PACKED ENDP
|
|---|
| 3403 |
|
|---|
| 3404 |
|
|---|
| 3405 | ;
|
|---|
| 3406 | ; In: ES:EDI destination
|
|---|
| 3407 | ;
|
|---|
| 3408 | TALIGN 4
|
|---|
| 3409 | ASSUME EDI:NEAR32 PTR TIMEB
|
|---|
| 3410 | DO_FTIME PROC
|
|---|
| 3411 | LOCAL DATE_CX:WORD, DATE_DX:WORD
|
|---|
| 3412 | LOCAL TIME_CX:WORD, TIME_DX:WORD
|
|---|
| 3413 | LOCAL MDT:MY_DATETIME
|
|---|
| 3414 |
|
|---|
| 3415 | RETRY: MOV AH, 2AH
|
|---|
| 3416 | INT 21H
|
|---|
| 3417 | MOV DATE_CX, CX
|
|---|
| 3418 | MOV DATE_DX, DX
|
|---|
| 3419 | MOV AH, 2CH
|
|---|
| 3420 | INT 21H
|
|---|
| 3421 | MOV TIME_CX, CX
|
|---|
| 3422 | MOV TIME_DX, DX
|
|---|
| 3423 | MOV AH, 2AH
|
|---|
| 3424 | INT 21H
|
|---|
| 3425 | CMP CX, DATE_CX
|
|---|
| 3426 | JNE SHORT RETRY
|
|---|
| 3427 | CMP DX, DATE_DX
|
|---|
| 3428 | JNE SHORT RETRY
|
|---|
| 3429 |
|
|---|
| 3430 | MOVZX EAX, BYTE PTR TIME_DX[1]
|
|---|
| 3431 | MOV MDT.SECONDS, EAX
|
|---|
| 3432 | MOVZX EAX, BYTE PTR TIME_CX[0]
|
|---|
| 3433 | MOV MDT.MINUTES, EAX
|
|---|
| 3434 | MOVZX EAX, BYTE PTR TIME_CX[1]
|
|---|
| 3435 | MOV MDT.HOURS, EAX
|
|---|
| 3436 | MOVZX EAX, BYTE PTR DATE_DX[0]
|
|---|
| 3437 | MOV MDT.DAY, EAX
|
|---|
| 3438 | MOVZX EAX, BYTE PTR DATE_DX[1]
|
|---|
| 3439 | MOV MDT.MONTH, EAX
|
|---|
| 3440 | MOVZX EAX, DATE_CX
|
|---|
| 3441 | MOV MDT.YEAR, EAX
|
|---|
| 3442 |
|
|---|
| 3443 | INVOKE TIME_2_UNIX, ADDR MDT
|
|---|
| 3444 |
|
|---|
| 3445 | MOV ES:[EDI].DSTFLAG, 0
|
|---|
| 3446 | MOV ES:[EDI].TIME, EAX
|
|---|
| 3447 | MOVZX EAX, BYTE PTR TIME_DX[0]
|
|---|
| 3448 | MOV ECX, 10
|
|---|
| 3449 | MUL ECX
|
|---|
| 3450 | MOV ES:[EDI].MILLITM, EAX
|
|---|
| 3451 | MOV ES:[EDI].TIMEZONE, 0
|
|---|
| 3452 | ASSUME EDI:NOTHING
|
|---|
| 3453 | RET
|
|---|
| 3454 | DO_FTIME ENDP
|
|---|
| 3455 |
|
|---|
| 3456 |
|
|---|
| 3457 | ;
|
|---|
| 3458 | ; In: ES:ESI Source
|
|---|
| 3459 | ;
|
|---|
| 3460 | TALIGN 4
|
|---|
| 3461 | ASSUME ESI:NEAR32 PTR TIMEVAL
|
|---|
| 3462 | DO_SETTIME PROC
|
|---|
| 3463 | LOCAL MDT:MY_DATETIME
|
|---|
| 3464 | MOV EAX, ES:[ESI].TV_USEC
|
|---|
| 3465 | XOR EDX, EDX
|
|---|
| 3466 | MOV ECX, 1000000
|
|---|
| 3467 | DIV ECX
|
|---|
| 3468 | PUSH EDX ; Save microseconds
|
|---|
| 3469 | ADD EAX, ES:[ESI].TV_SEC
|
|---|
| 3470 | INVOKE UNIX_2_TIME, EAX, ADDR MDT
|
|---|
| 3471 | POP EAX ; Microseconds
|
|---|
| 3472 | XOR EDX, EDX
|
|---|
| 3473 | MOV ECX, 10000
|
|---|
| 3474 | DIV ECX ; 1/100 seconds
|
|---|
| 3475 | MOV DL, CL
|
|---|
| 3476 | MOV DH, BYTE PTR MDT.SECONDS
|
|---|
| 3477 | MOV CL, BYTE PTR MDT.MINUTES
|
|---|
| 3478 | MOV CH, BYTE PTR MDT.HOURS
|
|---|
| 3479 | MOV AH, 2DH ; Set system time
|
|---|
| 3480 | INT 21H
|
|---|
| 3481 | TEST AL, AL
|
|---|
| 3482 | JNZ SHORT ERROR
|
|---|
| 3483 | ; TODO: Time window
|
|---|
| 3484 | MOV DL, BYTE PTR MDT.DAY
|
|---|
| 3485 | MOV DH, BYTE PTR MDT.MONTH
|
|---|
| 3486 | MOV CX, WORD PTR MDT.YEAR
|
|---|
| 3487 | MOV AH, 2BH ; Set system date
|
|---|
| 3488 | INT 21H
|
|---|
| 3489 | TEST AL, AL
|
|---|
| 3490 | JNZ SHORT ERROR
|
|---|
| 3491 | XOR EAX, EAX
|
|---|
| 3492 | RET
|
|---|
| 3493 |
|
|---|
| 3494 | ERROR: MOV EAX, EINVAL
|
|---|
| 3495 | RET
|
|---|
| 3496 | DO_SETTIME ENDP
|
|---|
| 3497 |
|
|---|
| 3498 | ASSUME ESI:NOTHING
|
|---|
| 3499 |
|
|---|
| 3500 |
|
|---|
| 3501 | ;
|
|---|
| 3502 | ; Compare two strings
|
|---|
| 3503 | ;
|
|---|
| 3504 | ; In: DS:ESI First string
|
|---|
| 3505 | ; ES:EDI Second string
|
|---|
| 3506 | ;
|
|---|
| 3507 | ; Out: ZR Strings are equal
|
|---|
| 3508 | ; ESI Modified
|
|---|
| 3509 | ; EDI Modified
|
|---|
| 3510 | ;
|
|---|
| 3511 | TALIGN 4
|
|---|
| 3512 | STRCMP PROC NEAR
|
|---|
| 3513 | SC_1: LODS BYTE PTR DS:[ESI]
|
|---|
| 3514 | SCAS BYTE PTR ES:[EDI]
|
|---|
| 3515 | JNE SHORT SC_RET
|
|---|
| 3516 | OR AL, AL
|
|---|
| 3517 | JNZ SHORT SC_1
|
|---|
| 3518 | SC_RET: RET
|
|---|
| 3519 | STRCMP ENDP
|
|---|
| 3520 |
|
|---|
| 3521 | ;
|
|---|
| 3522 | ; Compare two strings, disregarding letter case
|
|---|
| 3523 | ;
|
|---|
| 3524 | ; In: DS:SI First string
|
|---|
| 3525 | ; ES:DI Second string
|
|---|
| 3526 | ;
|
|---|
| 3527 | ; Out: ZR Strings are equal
|
|---|
| 3528 | ; SI Modified
|
|---|
| 3529 | ;
|
|---|
| 3530 | TALIGN 4
|
|---|
| 3531 | STRICMP PROC NEAR
|
|---|
| 3532 | PUSH DI
|
|---|
| 3533 | SIC_1: LODSB
|
|---|
| 3534 | CALL UPPER
|
|---|
| 3535 | MOV AH, AL
|
|---|
| 3536 | MOV AL, ES:[DI]
|
|---|
| 3537 | INC DI
|
|---|
| 3538 | CALL UPPER
|
|---|
| 3539 | CMP AL, AH
|
|---|
| 3540 | JNE SHORT SIC_RET
|
|---|
| 3541 | OR AL, AL
|
|---|
| 3542 | JNZ SHORT SIC_1
|
|---|
| 3543 | SIC_RET: POP DI
|
|---|
| 3544 | RET
|
|---|
| 3545 | STRICMP ENDP
|
|---|
| 3546 |
|
|---|
| 3547 |
|
|---|
| 3548 |
|
|---|
| 3549 | SV_CODE ENDS
|
|---|
| 3550 |
|
|---|
| 3551 | END
|
|---|