| 1 | ;
|
|---|
| 2 | ; PMINT.ASM -- Handle interrupts
|
|---|
| 3 | ;
|
|---|
| 4 | ; Copyright (c) 1991-1996 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 | ;
|
|---|
| 27 | ; Handle interrupts in protected mode (hardware and software interrupts).
|
|---|
| 28 | ; Includes DOS interface.
|
|---|
| 29 | ;
|
|---|
| 30 |
|
|---|
| 31 | __PMINT = 1
|
|---|
| 32 | INCLUDE EMX.INC
|
|---|
| 33 | INCLUDE TABLES.INC
|
|---|
| 34 | INCLUDE VPRINT.INC
|
|---|
| 35 | INCLUDE OPRINT.INC
|
|---|
| 36 | INCLUDE PAGING.INC
|
|---|
| 37 | INCLUDE SYSCALL.INC
|
|---|
| 38 | INCLUDE EXTAPI.INC
|
|---|
| 39 | INCLUDE SIGNAL.INC
|
|---|
| 40 | INCLUDE PROCESS.INC
|
|---|
| 41 | INCLUDE PROFIL.INC
|
|---|
| 42 | INCLUDE VCPI.INC
|
|---|
| 43 | INCLUDE PMINT.INC
|
|---|
| 44 | INCLUDE EXCEPT.INC
|
|---|
| 45 | INCLUDE RPRINT.INC
|
|---|
| 46 | INCLUDE A20.INC
|
|---|
| 47 | INCLUDE DEBUG.INC
|
|---|
| 48 | INCLUDE SEGMENTS.INC
|
|---|
| 49 | INCLUDE OPTIONS.INC
|
|---|
| 50 | INCLUDE MISC.INC
|
|---|
| 51 | INCLUDE CORE.INC
|
|---|
| 52 | INCLUDE RMINT.INC
|
|---|
| 53 | INCLUDE FILEIO.INC
|
|---|
| 54 | INCLUDE UTILS.INC
|
|---|
| 55 | INCLUDE TERMIO.INC
|
|---|
| 56 | INCLUDE STAT.INC
|
|---|
| 57 | INCLUDE ERRORS.INC
|
|---|
| 58 |
|
|---|
| 59 | PUBLIC IRQ0_ADD, IRQ8_ADD
|
|---|
| 60 | PUBLIC INTERRUPT, PMINT_21H, PMINT_10H, PMINT_11H
|
|---|
| 61 | PUBLIC PMINT_14H, PMINT_16H, PMINT_17H, PMINT_31H, PMINT_33H
|
|---|
| 62 | PUBLIC DOSF_ERROR, BREAK_AFTER_IRET, NMI, INT_RM
|
|---|
| 63 | PUBLIC BUF_SEG, BUF1_SEG, BUF2_SEG, BUF_SEL, RM_CR0, PM_CR0
|
|---|
| 64 | PUBLIC V2P_CONT, V2V_CONT, INIT_BUFFER
|
|---|
| 65 | PUBLIC PMINT0_TAB, PMINT8_TAB, DBCS_LEAD_TAB
|
|---|
| 66 | PUBLIC DOS_INT ; put into map file for debugging
|
|---|
| 67 |
|
|---|
| 68 | SER_FLAG = FALSE ; Don't use serial interface
|
|---|
| 69 | DEBUG_DOSDUMP = FALSE
|
|---|
| 70 |
|
|---|
| 71 | SV_DATA SEGMENT
|
|---|
| 72 |
|
|---|
| 73 | PMINT0_TAB LABEL WORD
|
|---|
| 74 | IRP X,<0,1,2,3,4,5,6,7>
|
|---|
| 75 | WORD OFFSET SV_CODE:PMINT&X
|
|---|
| 76 | ENDM
|
|---|
| 77 | PMINT8_TAB LABEL WORD
|
|---|
| 78 | IRP X,<8,9,10,11,12,13,14,15>
|
|---|
| 79 | WORD OFFSET SV_CODE:PMINT&X
|
|---|
| 80 | ENDM
|
|---|
| 81 |
|
|---|
| 82 | PMHWINT_LSS LABEL FWORD
|
|---|
| 83 | PMHWINT_ESP DWORD ?
|
|---|
| 84 | PMHWINT_SS WORD ?
|
|---|
| 85 | ;
|
|---|
| 86 | ; This variable points to the interrupt stack frame of protected mode
|
|---|
| 87 | ; (in the protected-mode stack SV_STACK). It is used for accessing the
|
|---|
| 88 | ; stack frame in real mode. Be sure to save this variable when passing
|
|---|
| 89 | ; signals from real mode to protected mode!
|
|---|
| 90 | ;
|
|---|
| 91 | FRAME_PTR WORD ?
|
|---|
| 92 |
|
|---|
| 93 | ;
|
|---|
| 94 | ; Before switching back to real/virtual mode, we restore the floating point
|
|---|
| 95 | ; related bits of CR0 saved at the beginning. We can save the bits only
|
|---|
| 96 | ; in protected mode, as CR0 isn't readable in virtual mode. After switching
|
|---|
| 97 | ; to protected mode, we restore the floating point related bits of CR0
|
|---|
| 98 | ; from PM_CR0.
|
|---|
| 99 | ;
|
|---|
| 100 | DALIGN 4
|
|---|
| 101 | RM_CR0 DWORD ? ; Real-mode CR0 (AND CR0_FPU)
|
|---|
| 102 | PM_CR0 DWORD ? ; Prot-mode CR0 (AND CR0_FPU)
|
|---|
| 103 |
|
|---|
| 104 | ;
|
|---|
| 105 | ; Table of conversions
|
|---|
| 106 | ;
|
|---|
| 107 |
|
|---|
| 108 | DF_INVALID = 00H ; syscall function not supported
|
|---|
| 109 | DF_NULL = 01H ; No parameters to be converted
|
|---|
| 110 | DF_WRITE = 02H ; Input: src=DS:EDX, length=ECX -> DS:DX, CX
|
|---|
| 111 | DF_PATH = 03H ; Input: pathname=DS:EDX -> DS:DX
|
|---|
| 112 | DF_TEXT = 04H ; Input: text=DS:EDX ($ terminated) -> DS:DX
|
|---|
| 113 | DF_READ = 05H ; Output: dst=DS:DX, length=AX (CY=0 only) -> DS:EDX
|
|---|
| 114 | DF_SEEK = 06H ; Input: EDX -> CX:DX; output: DX:AX -> EAX (CY=0)
|
|---|
| 115 | DF_TMP = 07H ; Input/output: DS:DX (0 term.) + 13 bytes
|
|---|
| 116 | DF_INPUT = 08H ; Input/output: DS:DX, length=DX[0]+2
|
|---|
| 117 | DF_MOVE = 09H ; Input: DS:EDX -> DS:DX, DS:EDI -> ES:DI file names
|
|---|
| 118 | DF_DUP2 = 0AH ; Force duplicate file handle
|
|---|
| 119 | DF_CLOSE = 0BH ; Close file handle
|
|---|
| 120 | DF_IOCTL = 0CH ; IOCTL, use additional table
|
|---|
| 121 | DF_GETCWD = 0DH ; Output: DS:SI -> DS:ESI (64 bytes)
|
|---|
| 122 | DF_EXIT = 0EH ; Exit
|
|---|
| 123 | DF_FFIRST = 0FH ; Find first (DS:EDX, DTA DS:ESI)
|
|---|
| 124 | DF_FNEXT = 10H ; Find next (DTA DS:ESI)
|
|---|
| 125 | DF_VERSION = 11H ; Return DOS version (and emx)
|
|---|
| 126 | DF_EXEC = 12H ; Load and execute program
|
|---|
| 127 | DF_RETCODE = 13H ; Get return code of child process
|
|---|
| 128 | DF_STR_BP = 14H ; Input: EBP null-terminated string -> ES:BP
|
|---|
| 129 | DF_VESA = 15H ; VESA BIOS (10H, AH=4FH), use additional table
|
|---|
| 130 | DF_VESAINFO = 16H ; VESA function 00H (return 256 bytes)
|
|---|
| 131 | DF_VESAMODE = 17H ; VESA function 01H (return 256 bytes)
|
|---|
| 132 | DF_MOU_GCURSOR = 18H ; Mouse function 09H (in: ES:DX -> 64 bytes)
|
|---|
| 133 | DF_MOU_LGCURSOR = 19H ; Mouse function 12H (in: ES:DX -> var. bytes)
|
|---|
| 134 | DF_COUNTRY = 1AH ; Output: EDX->DS:DX (34 bytes) unless DX=-1
|
|---|
| 135 | DF_LOCK = 1BH ; Input: EDX->CX:DX, EDI->SI:DI
|
|---|
| 136 | DF_TRUENAME = 1CH ; DOS function 60H
|
|---|
| 137 | DF_PATH_SI = 1DH ; Input: pathname=DS:ESI -> DS:SI
|
|---|
| 138 | DF_DUP = 1EH ; Duplicate file handle
|
|---|
| 139 | DF_VIO11 = 1FH ; INT 10H AH=11H, use additional table (AL)
|
|---|
| 140 | DF_VIO12 = 20H ; INT 10H AH=12H, use additional table (BL)
|
|---|
| 141 | DF_LAST = 20H
|
|---|
| 142 | DF_SPARSE_END = 0FFH ; End of sparse table
|
|---|
| 143 |
|
|---|
| 144 | ;
|
|---|
| 145 | ; The following flag bits are used for INT 21H only. They also apply
|
|---|
| 146 | ; to the INT 21H IOCTL calls.
|
|---|
| 147 | ;
|
|---|
| 148 | DFE = 8000H ; CY indicates error, convert to errno
|
|---|
| 149 | DFM_STDIN = 4000H ; Map stdin before invoking INT 21H
|
|---|
| 150 | DFM_STDOUT = 2000H ; Map stdout before invoking INT 21H
|
|---|
| 151 | DFM_STDIO = DFM_STDIN OR DFM_STDOUT
|
|---|
| 152 |
|
|---|
| 153 | DFH_IN = 0100H ; BX contains file handle (in)
|
|---|
| 154 | DFH_OUT = 0200H ; New file handle returned in EAX (out, CY=0)
|
|---|
| 155 | DFH_IN_OUT = DFH_IN OR DFH_OUT
|
|---|
| 156 |
|
|---|
| 157 | ;
|
|---|
| 158 | ; Get conversion flag from a table
|
|---|
| 159 | ;
|
|---|
| 160 | ; In: BL Function number
|
|---|
| 161 | ;
|
|---|
| 162 | ; Out: AX Conversion flag
|
|---|
| 163 | ; BX Modified
|
|---|
| 164 | ;
|
|---|
| 165 | TBGET MACRO TABLE
|
|---|
| 166 | TABLE&_GET
|
|---|
| 167 | ENDM
|
|---|
| 168 |
|
|---|
| 169 | ;
|
|---|
| 170 | ; Start a dense table
|
|---|
| 171 | ;
|
|---|
| 172 | ; In: TABLE Name of the table
|
|---|
| 173 | ; MAXFUN Highest function number
|
|---|
| 174 | ;
|
|---|
| 175 | DENSE_TABLE MACRO TABLE, MAXFUN
|
|---|
| 176 | TABLE LABEL WORD
|
|---|
| 177 | DENSE_NEXT = 0
|
|---|
| 178 | DENSE_MAXFUN = MAXFUN
|
|---|
| 179 | TBENTRY MACRO FUNC, FLAG
|
|---|
| 180 | DENSE_ENTRY FUNC, FLAG
|
|---|
| 181 | ENDM
|
|---|
| 182 | TBEND MACRO
|
|---|
| 183 | DENSE_END
|
|---|
| 184 | ENDM
|
|---|
| 185 | TABLE&_MAXFUN = MAXFUN
|
|---|
| 186 | TABLE&_GET MACRO
|
|---|
| 187 | DENSE_GET TABLE
|
|---|
| 188 | ENDM
|
|---|
| 189 | ENDM
|
|---|
| 190 |
|
|---|
| 191 | ;
|
|---|
| 192 | ; Add an entry to a dense table
|
|---|
| 193 | ;
|
|---|
| 194 | DENSE_ENTRY MACRO FUNC, FLAG
|
|---|
| 195 | .ERRE FUNC GE DENSE_NEXT
|
|---|
| 196 | IF FUNC NE DENSE_NEXT
|
|---|
| 197 | WORD FUNC-DENSE_NEXT DUP (DF_INVALID)
|
|---|
| 198 | DENSE_NEXT = FUNC
|
|---|
| 199 | ENDIF
|
|---|
| 200 | WORD FLAG
|
|---|
| 201 | DENSE_NEXT = DENSE_NEXT+1
|
|---|
| 202 | ENDM
|
|---|
| 203 |
|
|---|
| 204 | ;
|
|---|
| 205 | ; End a dense table
|
|---|
| 206 | ;
|
|---|
| 207 | DENSE_END MACRO
|
|---|
| 208 | IF DENSE_NEXT NE DENSE_MAXFUN + 1
|
|---|
| 209 | DENSE_ENTRY DENSE_MAXFUN, <DF_INVALID>
|
|---|
| 210 | ENDIF
|
|---|
| 211 | ENDM
|
|---|
| 212 |
|
|---|
| 213 | ;
|
|---|
| 214 | ; Get conversion flag from a dense table
|
|---|
| 215 | ;
|
|---|
| 216 | ; In: BL Function number
|
|---|
| 217 | ;
|
|---|
| 218 | ; Out: AX Conversion flag
|
|---|
| 219 | ; BX Modified
|
|---|
| 220 | ;
|
|---|
| 221 | DENSE_GET MACRO TABLE
|
|---|
| 222 | IF TABLE&_MAXFUN NE 0FFH
|
|---|
| 223 | CMP BL, TABLE&_MAXFUN
|
|---|
| 224 | JA D_INVALID
|
|---|
| 225 | ENDIF
|
|---|
| 226 | XOR BH, BH
|
|---|
| 227 | SHL BX, 1
|
|---|
| 228 | MOV AX, TABLE[BX]
|
|---|
| 229 | ENDM
|
|---|
| 230 |
|
|---|
| 231 | ;
|
|---|
| 232 | ; Start a sparse table
|
|---|
| 233 | ;
|
|---|
| 234 | ; In: TABLE Name of the table
|
|---|
| 235 | ;
|
|---|
| 236 | SPARSE_TABLE MACRO TABLE
|
|---|
| 237 | TABLE LABEL BYTE
|
|---|
| 238 | TBENTRY MACRO FUNC, FLAG
|
|---|
| 239 | SPARSE_ENTRY FUNC, FLAG
|
|---|
| 240 | ENDM
|
|---|
| 241 | TBEND MACRO
|
|---|
| 242 | SPARSE_END
|
|---|
| 243 | ENDM
|
|---|
| 244 | TABLE&_GET MACRO
|
|---|
| 245 | SPARSE_GET TABLE
|
|---|
| 246 | ENDM
|
|---|
| 247 | ENDM
|
|---|
| 248 |
|
|---|
| 249 | ;
|
|---|
| 250 | ; Add an entry to a sparse table
|
|---|
| 251 | ;
|
|---|
| 252 | SPARSE_ENTRY MACRO FUNC, FLAG
|
|---|
| 253 | BYTE FUNC
|
|---|
| 254 | WORD FLAG
|
|---|
| 255 | ENDM
|
|---|
| 256 |
|
|---|
| 257 | ;
|
|---|
| 258 | ; End a sparse table
|
|---|
| 259 | ;
|
|---|
| 260 | SPARSE_END MACRO
|
|---|
| 261 | SPARSE_ENTRY 00H, DF_SPARSE_END
|
|---|
| 262 | ENDM
|
|---|
| 263 |
|
|---|
| 264 | ;
|
|---|
| 265 | ; Get conversion flag from a sparse table
|
|---|
| 266 | ;
|
|---|
| 267 | ; In: BL Function number
|
|---|
| 268 | ;
|
|---|
| 269 | ; Out: AX Conversion flag
|
|---|
| 270 | ; BX Modified
|
|---|
| 271 | ;
|
|---|
| 272 | SPARSE_GET MACRO TABLE
|
|---|
| 273 | LOCAL LOOP1, DONE
|
|---|
| 274 | MOV AL, BL
|
|---|
| 275 | LEA BX, TABLE - 3
|
|---|
| 276 | LOOP1: ADD BX, 3
|
|---|
| 277 | CMP BYTE PTR [BX+1], DF_SPARSE_END
|
|---|
| 278 | JE D_INVALID
|
|---|
| 279 | CMP [BX+0], AL
|
|---|
| 280 | JNE LOOP1
|
|---|
| 281 | MOV AX, [BX+1]
|
|---|
| 282 | ENDM
|
|---|
| 283 |
|
|---|
| 284 |
|
|---|
| 285 | DENSE_TABLE DOS_FUNCS, 6CH
|
|---|
| 286 | TBENTRY 01H, <DF_NULL OR DFM_STDIO> ; Read keyboard and echo
|
|---|
| 287 | TBENTRY 02H, <DF_NULL OR DFM_STDOUT> ; Display character
|
|---|
| 288 | TBENTRY 03H, <DF_NULL> ; Auxiliary input
|
|---|
| 289 | TBENTRY 04H, <DF_NULL> ; Auxiliary output
|
|---|
| 290 | TBENTRY 05H, <DF_NULL> ; Print character
|
|---|
| 291 | TBENTRY 06H, <DF_NULL OR DFM_STDIO> ; Direct console i/o
|
|---|
| 292 | TBENTRY 07H, <DF_NULL OR DFM_STDIN> ; Direct console input
|
|---|
| 293 | TBENTRY 08H, <DF_NULL OR DFM_STDIN> ; Read keyboard
|
|---|
| 294 | TBENTRY 09H, <DF_TEXT OR DFM_STDOUT> ; Display string
|
|---|
| 295 | TBENTRY 0AH, <DF_INPUT OR DFM_STDIO> ; Buffered keyboard input
|
|---|
| 296 | TBENTRY 0BH, <DF_NULL OR DFM_STDIN> ; Check keyboard status
|
|---|
| 297 | TBENTRY 0CH, <DF_NULL OR DFM_STDIO> ; Flush keyboard buffer
|
|---|
| 298 | TBENTRY 0DH, <DF_NULL> ; Reset disk
|
|---|
| 299 | TBENTRY 0EH, <DF_NULL> ; Select disk
|
|---|
| 300 | TBENTRY 19H, <DF_NULL> ; Get current disk
|
|---|
| 301 | TBENTRY 2AH, <DF_NULL> ; Get date
|
|---|
| 302 | TBENTRY 2BH, <DF_NULL> ; Set date
|
|---|
| 303 | TBENTRY 2CH, <DF_NULL> ; Get time
|
|---|
| 304 | TBENTRY 2DH, <DF_NULL> ; Set time
|
|---|
| 305 | TBENTRY 2EH, <DF_NULL> ; Set/reset verify flag
|
|---|
| 306 | TBENTRY 30H, <DF_VERSION> ; Get DOS version number
|
|---|
| 307 | TBENTRY 33H, <DF_NULL> ; Control-C check
|
|---|
| 308 | TBENTRY 36H, <DF_NULL> ; Get disk free space
|
|---|
| 309 | TBENTRY 37H, <DF_NULL> ; Get/set switch character
|
|---|
| 310 | TBENTRY 38H, <DFE OR DF_COUNTRY> ; Get/set country data
|
|---|
| 311 | TBENTRY 39H, <DFE OR DF_PATH> ; Create directory
|
|---|
| 312 | TBENTRY 3AH, <DFE OR DF_PATH> ; Remove directory
|
|---|
| 313 | TBENTRY 3BH, <DFE OR DF_PATH> ; Change current directory
|
|---|
| 314 | TBENTRY 3CH, <DFE OR DF_PATH OR DFH_OUT> ; Create handle
|
|---|
| 315 | TBENTRY 3DH, <DFE OR DF_PATH OR DFH_OUT> ; Open handle
|
|---|
| 316 | TBENTRY 3EH, <DFE OR DF_CLOSE> ; Close handle
|
|---|
| 317 | TBENTRY 3FH, <DFE OR DF_READ OR DFH_IN> ; Read handle
|
|---|
| 318 | TBENTRY 40H, <DFE OR DF_WRITE OR DFH_IN> ; Write handle
|
|---|
| 319 | TBENTRY 41H, <DFE OR DF_PATH> ; Delete directory entry
|
|---|
| 320 | TBENTRY 42H, <DFE OR DF_SEEK OR DFH_IN> ; Move file pointer
|
|---|
| 321 | TBENTRY 43H, <DFE OR DF_PATH> ; Get/set file attributes
|
|---|
| 322 | TBENTRY 44H, <DF_IOCTL> ; IOCTL
|
|---|
| 323 | TBENTRY 45H, <DF_DUP> ; Duplicate file handle
|
|---|
| 324 | TBENTRY 46H, <DF_DUP2> ; Force duplicate handle
|
|---|
| 325 | TBENTRY 47H, <DFE OR DF_GETCWD> ; Get current directory
|
|---|
| 326 | TBENTRY 4BH, <DFE OR DF_EXEC> ; Load and execute program
|
|---|
| 327 | TBENTRY 4CH, <DF_EXIT> ; End process
|
|---|
| 328 | TBENTRY 4DH, <DF_RETCODE> ; Get rc of child process
|
|---|
| 329 | TBENTRY 4EH, <DFE OR DF_FFIRST> ; Find first file
|
|---|
| 330 | TBENTRY 4FH, <DFE OR DF_FNEXT> ; Find next file
|
|---|
| 331 | TBENTRY 54H, <DF_NULL> ; Get verify state
|
|---|
| 332 | TBENTRY 56H, <DFE OR DF_MOVE> ; Change directory entry
|
|---|
| 333 | TBENTRY 57H, <DFE OR DF_NULL OR DFH_IN> ; Time/date of file
|
|---|
| 334 | TBENTRY 58H, <DFE OR DF_NULL> ; Get/set alloc strat
|
|---|
| 335 | TBENTRY 59H, <DF_NULL> ; Get extended error
|
|---|
| 336 | TBENTRY 5AH, <DFE OR DF_TMP OR DFH_OUT> ; Create temporary file
|
|---|
| 337 | TBENTRY 5BH, <DFE OR DF_PATH OR DFH_OUT> ; Create new file
|
|---|
| 338 | TBENTRY 5CH, <DFE OR DF_LOCK OR DFH_IN> ; Lock
|
|---|
| 339 | TBENTRY 60H, <DFE OR DF_TRUENAME> ; Canonicalize path
|
|---|
| 340 | TBENTRY 66H, <DFE OR DF_NULL> ; Get/set global cp table
|
|---|
| 341 | TBENTRY 67H, <DFE OR DF_NULL> ; Set handle count
|
|---|
| 342 | TBENTRY 68H, <DFE OR DF_NULL OR DFH_IN> ; Commit file
|
|---|
| 343 | TBENTRY 6AH, <DFE OR DF_NULL OR DFH_IN> ; Commit file
|
|---|
| 344 | TBENTRY 6CH, <DFE OR DF_PATH_SI OR DFH_OUT> ; Extended open/create
|
|---|
| 345 | TBEND
|
|---|
| 346 |
|
|---|
| 347 | DENSE_TABLE IOCTL_FUNCS, 0BH
|
|---|
| 348 | TBENTRY 00H, <DFE OR DF_NULL OR DFH_IN> ; Get device data
|
|---|
| 349 | TBENTRY 01H, <DFE OR DF_NULL OR DFH_IN> ; Set device data
|
|---|
| 350 | TBENTRY 02H, <DFE OR DF_WRITE OR DFH_IN> ; Send control data (char)
|
|---|
| 351 | TBENTRY 03H, <DFE OR DF_READ OR DFH_IN> ; Receive ctl data (char)
|
|---|
| 352 | TBENTRY 04H, <DFE OR DF_WRITE> ; Send ctl data (block)
|
|---|
| 353 | TBENTRY 05H, <DFE OR DF_READ> ; Receive ctl data (block)
|
|---|
| 354 | TBENTRY 06H, <DFE OR DF_NULL OR DFH_IN> ; Check input status
|
|---|
| 355 | TBENTRY 07H, <DFE OR DF_NULL OR DFH_IN> ; Check output status
|
|---|
| 356 | TBENTRY 08H, <DFE OR DF_NULL> ; Is changable
|
|---|
| 357 | TBENTRY 09H, <DFE OR DF_NULL> ; Is redirected block
|
|---|
| 358 | TBENTRY 0AH, <DFE OR DF_NULL OR DFH_IN> ; Is redirected handle
|
|---|
| 359 | TBENTRY 0BH, <DFE OR DF_NULL> ; Retry
|
|---|
| 360 | TBEND
|
|---|
| 361 |
|
|---|
| 362 | DENSE_TABLE VIO_FUNCS, 0FFH
|
|---|
| 363 | TBENTRY 00H, <DF_NULL> ; Set video mode
|
|---|
| 364 | TBENTRY 01H, <DF_NULL> ; Set cursor shape
|
|---|
| 365 | TBENTRY 02H, <DF_NULL> ; Set cursor position
|
|---|
| 366 | TBENTRY 03H, <DF_NULL> ; Set cursor pos and size
|
|---|
| 367 | TBENTRY 04H, <DF_NULL> ; Read light pen position
|
|---|
| 368 | TBENTRY 05H, <DF_NULL> ; Select display page
|
|---|
| 369 | TBENTRY 06H, <DF_NULL> ; Scroll up
|
|---|
| 370 | TBENTRY 07H, <DF_NULL> ; Scroll down
|
|---|
| 371 | TBENTRY 08H, <DF_NULL> ; Read char and attribute
|
|---|
| 372 | TBENTRY 09H, <DF_NULL> ; Write char and attribute
|
|---|
| 373 | TBENTRY 0AH, <DF_NULL> ; Write character
|
|---|
| 374 | TBENTRY 0BH, <DF_NULL> ; Set palette
|
|---|
| 375 | TBENTRY 0CH, <DF_NULL> ; Write graphics pixel
|
|---|
| 376 | TBENTRY 0DH, <DF_NULL> ; Read graphics pixel
|
|---|
| 377 | TBENTRY 0EH, <DF_NULL> ; Teletype output
|
|---|
| 378 | TBENTRY 0FH, <DF_NULL> ; Get current video mode
|
|---|
| 379 | TBENTRY 10H, <DF_NULL> ; Palette (AL != 02H,
|
|---|
| 380 | ; 09H, 12H, 17H)
|
|---|
| 381 | TBENTRY 11H, <DF_VIO11> ; Font
|
|---|
| 382 | TBENTRY 12H, <DF_VIO12> ; Miscellaneous stuff
|
|---|
| 383 | TBENTRY 13H, <DF_STR_BP> ; Write string
|
|---|
| 384 | TBENTRY 14H, <DF_INVALID> ; LCD
|
|---|
| 385 | TBENTRY 15H, <DF_INVALID> ; Get parameters
|
|---|
| 386 | TBENTRY 1AH, <DF_NULL> ; Display combination
|
|---|
| 387 | TBENTRY 1BH, <DF_INVALID> ; State information
|
|---|
| 388 | TBENTRY 1CH, <DF_INVALID> ; Save/restore state
|
|---|
| 389 | TBENTRY 1FH, <DF_INVALID> ; XGA DMQS
|
|---|
| 390 | TBENTRY 30H, <DF_INVALID> ; 3270 stuff
|
|---|
| 391 | TBENTRY 40H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 392 | TBENTRY 41H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 393 | TBENTRY 42H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 394 | TBENTRY 43H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 395 | TBENTRY 44H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 396 | TBENTRY 45H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 397 | TBENTRY 46H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 398 | TBENTRY 47H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 399 | TBENTRY 48H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 400 | TBENTRY 49H, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 401 | TBENTRY 4AH, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 402 | TBENTRY 4BH, <DF_NULL> ; Hercules GRAFIX / FRIEZE
|
|---|
| 403 | TBENTRY 4CH, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 404 | TBENTRY 4DH, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 405 | TBENTRY 4EH, <DF_NULL> ; Hercules GRAFIX
|
|---|
| 406 | TBENTRY 4FH, <DF_VESA> ; VESA
|
|---|
| 407 | TBENTRY 6FH, <DF_NULL> ; Various functions
|
|---|
| 408 | TBENTRY 0F0H, <DF_NULL> ; EGA register interface
|
|---|
| 409 | TBENTRY 0F1H, <DF_NULL> ; EGA register interface
|
|---|
| 410 | TBENTRY 0F6H, <DF_NULL> ; EGA register interface
|
|---|
| 411 | TBEND
|
|---|
| 412 |
|
|---|
| 413 | DENSE_TABLE VESA_FUNCS, 08H
|
|---|
| 414 | TBENTRY 00H, <DF_VESAINFO> ; Get SVGA info
|
|---|
| 415 | TBENTRY 01H, <DF_VESAMODE> ; Get SVGA mode info
|
|---|
| 416 | TBENTRY 02H, <DF_NULL> ; Set mode
|
|---|
| 417 | TBENTRY 03H, <DF_NULL> ; Get mode
|
|---|
| 418 | TBENTRY 04H, <DF_INVALID> ; Save/restore state
|
|---|
| 419 | TBENTRY 05H, <DF_NULL> ; Memory control
|
|---|
| 420 | TBENTRY 06H, <DF_NULL> ; Scan line length
|
|---|
| 421 | TBENTRY 07H, <DF_NULL> ; Display start
|
|---|
| 422 | TBENTRY 08H, <DF_NULL> ; DAC palette control
|
|---|
| 423 | TBEND
|
|---|
| 424 |
|
|---|
| 425 | DENSE_TABLE VIO11_FUNCS, 24H
|
|---|
| 426 | TBENTRY 01H, <DF_NULL> ; Load ROM patterns 8x14
|
|---|
| 427 | TBENTRY 02H, <DF_NULL> ; Load ROM patterns 8x8
|
|---|
| 428 | TBENTRY 03H, <DF_NULL> ; Set block specifier
|
|---|
| 429 | TBENTRY 04H, <DF_NULL> ; Load ROM charset 8x14
|
|---|
| 430 | TBENTRY 11H, <DF_NULL> ; Load ROM patterns 8x14
|
|---|
| 431 | TBENTRY 12H, <DF_NULL> ; Load ROM patterns 8x8
|
|---|
| 432 | TBENTRY 14H, <DF_NULL> ; Load ROM charset 8x14
|
|---|
| 433 | TBENTRY 22H, <DF_NULL> ; Set ROM graph chars 8x14
|
|---|
| 434 | TBENTRY 23H, <DF_NULL> ; Set ROM graph chars 8x8
|
|---|
| 435 | TBENTRY 24H, <DF_NULL> ; Set ROM graph chars 8x16
|
|---|
| 436 | TBEND
|
|---|
| 437 |
|
|---|
| 438 | SPARSE_TABLE VIO12_FUNCS
|
|---|
| 439 | TBENTRY 10H, <DF_NULL> ; Get EGA info
|
|---|
| 440 | TBENTRY 20H, <DF_NULL> ; Alternate PrtSc
|
|---|
| 441 | TBENTRY 30H, <DF_NULL> ; Select vert. resolution
|
|---|
| 442 | TBENTRY 31H, <DF_NULL> ; Palette loading
|
|---|
| 443 | TBENTRY 32H, <DF_NULL> ; Video addressing
|
|---|
| 444 | TBENTRY 33H, <DF_NULL> ; Gray-scale summing
|
|---|
| 445 | TBENTRY 34H, <DF_NULL> ; Cursor emulation
|
|---|
| 446 | TBENTRY 36H, <DF_NULL> ; Video refresh control
|
|---|
| 447 | TBENTRY 37H, <DF_NULL> ; Mainframe interact. sup
|
|---|
| 448 | TBEND
|
|---|
| 449 |
|
|---|
| 450 | DENSE_TABLE MOU_FUNCS, 6DH
|
|---|
| 451 | TBENTRY 00H, <DF_NULL> ; Reset
|
|---|
| 452 | TBENTRY 01H, <DF_NULL> ; Show mouse cursor
|
|---|
| 453 | TBENTRY 02H, <DF_NULL> ; Hide mouse cursor
|
|---|
| 454 | TBENTRY 03H, <DF_NULL> ; Get position & status
|
|---|
| 455 | TBENTRY 04H, <DF_NULL> ; Position mouse cursor
|
|---|
| 456 | TBENTRY 05H, <DF_NULL> ; Get button down data
|
|---|
| 457 | TBENTRY 06H, <DF_NULL> ; Get button up data
|
|---|
| 458 | TBENTRY 07H, <DF_NULL> ; Define hor. range
|
|---|
| 459 | TBENTRY 08H, <DF_NULL> ; Define ver. range
|
|---|
| 460 | TBENTRY 09H, <DF_MOU_GCURSOR> ; Define graphics cursor
|
|---|
| 461 | TBENTRY 0AH, <DF_NULL> ; Define text cursor
|
|---|
| 462 | TBENTRY 0BH, <DF_NULL> ; Read motion counters
|
|---|
| 463 | TBENTRY 0CH, <DF_INVALID> ; Define IRQ routine
|
|---|
| 464 | TBENTRY 0DH, <DF_NULL> ; Light pen emulation on
|
|---|
| 465 | TBENTRY 0EH, <DF_NULL> ; Light pen emulation off
|
|---|
| 466 | TBENTRY 0FH, <DF_NULL> ; Define mickeys/pixel
|
|---|
| 467 | TBENTRY 10H, <DF_NULL> ; Define update region
|
|---|
| 468 | TBENTRY 11H, <DF_NULL> ; GENIUS: # of buttons
|
|---|
| 469 | TBENTRY 12H, <DF_MOU_LGCURSOR> ; Graphics cursor block
|
|---|
| 470 | TBENTRY 13H, <DF_NULL> ; Double-speed threshold
|
|---|
| 471 | TBENTRY 14H, <DF_INVALID> ; Exchange IRQ routines
|
|---|
| 472 | TBENTRY 15H, <DF_NULL> ; Get state buffer size
|
|---|
| 473 | TBENTRY 16H, <DF_INVALID> ; Save state
|
|---|
| 474 | TBENTRY 17H, <DF_INVALID> ; Restore state
|
|---|
| 475 | TBENTRY 18H, <DF_INVALID> ; Set event handler
|
|---|
| 476 | TBENTRY 19H, <DF_INVALID> ; Return event handler
|
|---|
| 477 | TBENTRY 1AH, <DF_NULL> ; Set sensitivity
|
|---|
| 478 | TBENTRY 1BH, <DF_NULL> ; Return sensitivity
|
|---|
| 479 | TBENTRY 1CH, <DF_NULL> ; Set interrupt rate
|
|---|
| 480 | TBENTRY 1DH, <DF_NULL> ; Define display page
|
|---|
| 481 | TBENTRY 1EH, <DF_NULL> ; Return display page
|
|---|
| 482 | TBENTRY 1FH, <DF_NULL> ; Disable mouse driver
|
|---|
| 483 | TBENTRY 20H, <DF_NULL> ; Enable mouse driver
|
|---|
| 484 | TBENTRY 21H, <DF_NULL> ; Software reset
|
|---|
| 485 | TBENTRY 22H, <DF_NULL> ; Set language
|
|---|
| 486 | TBENTRY 23H, <DF_NULL> ; Get language
|
|---|
| 487 | TBENTRY 24H, <DF_NULL> ; Get misc. info
|
|---|
| 488 | TBENTRY 25H, <DF_NULL> ; Get general driver info
|
|---|
| 489 | TBENTRY 26H, <DF_NULL> ; Get maximum coordinates
|
|---|
| 490 | TBENTRY 27H, <DF_NULL> ; Get masks & counts
|
|---|
| 491 | TBENTRY 28H, <DF_NULL> ; Set video mode
|
|---|
| 492 | TBENTRY 29H, <DF_INVALID> ; Enumerate video modes
|
|---|
| 493 | TBENTRY 2AH, <DF_NULL> ; Get cursor hot spot
|
|---|
| 494 | TBENTRY 2BH, <DF_INVALID> ; Load acceleration prof.
|
|---|
| 495 | TBENTRY 2CH, <DF_INVALID> ; Get acceleration prof.
|
|---|
| 496 | TBENTRY 2DH, <DF_INVALID> ; Select acc. profile
|
|---|
| 497 | TBENTRY 2EH, <DF_INVALID> ; Set acc. profile names
|
|---|
| 498 | TBENTRY 2FH, <DF_NULL> ; Hardware reset
|
|---|
| 499 | TBENTRY 30H, <DF_NULL> ; Ballpoint information
|
|---|
| 500 | TBENTRY 31H, <DF_NULL> ; Max. virtual coordinates
|
|---|
| 501 | TBENTRY 32H, <DF_NULL> ; Get active adv. funcs.
|
|---|
| 502 | TBENTRY 33H, <DF_INVALID> ; Switch settings etc.
|
|---|
| 503 | TBENTRY 34H, <DF_INVALID> ; Get initialization file
|
|---|
| 504 | TBENTRY 35H, <DF_NULL> ; LCD large pointer
|
|---|
| 505 | TBENTRY 4DH, <DF_INVALID> ; Get copyright string
|
|---|
| 506 | TBENTRY 6DH, <DF_INVALID> ; Get version string
|
|---|
| 507 | TBEND
|
|---|
| 508 |
|
|---|
| 509 | ;
|
|---|
| 510 | ; Buffer for DOS interface
|
|---|
| 511 | ;
|
|---|
| 512 | BUF_SEG WORD ? ; Current buffer (BUF?_SEG)
|
|---|
| 513 | BUF_SEL WORD ? ; Current buffer (G_BUF?_SEL)
|
|---|
| 514 |
|
|---|
| 515 | BUF1_SEG WORD ? ; 1st buffer (64KB)
|
|---|
| 516 | BUF2_SEG WORD ? ; 2nd buffer (4KB, for swapper)
|
|---|
| 517 |
|
|---|
| 518 | COUNTRYDATA LABEL BYTE
|
|---|
| 519 | CD_DATE WORD ?
|
|---|
| 520 | CD_CURRENCY BYTE 5 DUP (?)
|
|---|
| 521 | CD_1000_SEP BYTE 2 DUP (?)
|
|---|
| 522 | CD_DECIMAL_SEP BYTE 2 DUP (?)
|
|---|
| 523 | CD_DATE_SEP BYTE 2 DUP (?)
|
|---|
| 524 | CD_TIME_SEP BYTE 2 DUP (?)
|
|---|
| 525 | CD_FLAGS BYTE ?
|
|---|
| 526 | CD_CURRENCY_N BYTE ?
|
|---|
| 527 | CD_TIME BYTE ?
|
|---|
| 528 | CD_CASEMAP DWORD ?
|
|---|
| 529 | CD_LIST_SEP BYTE 2 DUP (?)
|
|---|
| 530 | CD_RESERVED BYTE 10 DUP (?)
|
|---|
| 531 |
|
|---|
| 532 | ;
|
|---|
| 533 | ; This table contains 256 bits; if bit i is set, byte i is a DBCS
|
|---|
| 534 | ; lead byte.
|
|---|
| 535 | ;
|
|---|
| 536 | DBCS_LEAD_TAB WORD (256 / 8 / 2) DUP (?)
|
|---|
| 537 |
|
|---|
| 538 | $INTERRUPT BYTE "Unexpected interrupt", 0
|
|---|
| 539 | $NMI BYTE "Nonmaskable interrupt (NMI) at ", 0
|
|---|
| 540 | $BAD_MOU_FUNC BYTE "Illegal moucall function code: ", 0
|
|---|
| 541 | $BAD_DOS_FUNC BYTE "Illegal syscall function code: ", 0
|
|---|
| 542 | $BAD_VIO_FUNC BYTE "Illegal viocall function code: ", 0
|
|---|
| 543 | $DOS_PARAM BYTE "Invalid arguments for syscall ", 0
|
|---|
| 544 | $EMERGENCY BYTE "Emergency exit", 0
|
|---|
| 545 |
|
|---|
| 546 |
|
|---|
| 547 | IF DEBUG_DOSDUMP
|
|---|
| 548 | $DOSDUMP BYTE "DOSDUMP.000"
|
|---|
| 549 | $DOSDUMP_C = THIS BYTE - 1
|
|---|
| 550 | BYTE 0
|
|---|
| 551 | ENDIF
|
|---|
| 552 |
|
|---|
| 553 | SV_DATA ENDS
|
|---|
| 554 |
|
|---|
| 555 |
|
|---|
| 556 | SV_CODE SEGMENT
|
|---|
| 557 |
|
|---|
| 558 | .386P
|
|---|
| 559 |
|
|---|
| 560 | ASSUME CS:SV_CODE, DS:NOTHING
|
|---|
| 561 |
|
|---|
| 562 | TALIGN 2
|
|---|
| 563 | CONV_TAB WORD D_INVALID ; DF_INVALID
|
|---|
| 564 | WORD D_NULL ; DF_NULL
|
|---|
| 565 | WORD D_WRITE ; DF_WRITE
|
|---|
| 566 | WORD D_PATH ; DF_PATH
|
|---|
| 567 | WORD D_TEXT ; DF_TEXT
|
|---|
| 568 | WORD D_READ ; DF_READ
|
|---|
| 569 | WORD D_SEEK ; DF_SEEK
|
|---|
| 570 | WORD D_TMP ; DF_TMP
|
|---|
| 571 | WORD D_INPUT ; DF_INPUT
|
|---|
| 572 | WORD D_MOVE ; DF_MOVE
|
|---|
| 573 | WORD D_DUP2 ; DF_DUP2
|
|---|
| 574 | WORD D_CLOSE ; DF_CLOSE
|
|---|
| 575 | WORD D_INVALID ; DF_IOCTL (handled before jumping)
|
|---|
| 576 | WORD D_GETCWD ; DF_GETCWD
|
|---|
| 577 | WORD D_EXIT ; DF_EXIT
|
|---|
| 578 | WORD D_FFIRST ; DF_FFIRST
|
|---|
| 579 | WORD D_FNEXT ; DF_FNEXT
|
|---|
| 580 | WORD D_VERSION ; DF_VERSION
|
|---|
| 581 | WORD D_EXEC ; DF_EXEC
|
|---|
| 582 | WORD D_RETCODE ; DF_RETCODE
|
|---|
| 583 | WORD D_STR_BP ; DF_STR_BP
|
|---|
| 584 | WORD D_VESA ; DF_VESA
|
|---|
| 585 | WORD D_VESAINFO ; DF_VESAINFO
|
|---|
| 586 | WORD D_VESAMODE ; DF_VESAMODE
|
|---|
| 587 | WORD D_MOU_GCURSOR ; DF_MOU_GCURSOR
|
|---|
| 588 | WORD D_MOU_LGCURSOR ; DF_MOU_LGCURSOR
|
|---|
| 589 | WORD D_COUNTRY ; DF_COUNTRY
|
|---|
| 590 | WORD D_LOCK ; DF_LOCK
|
|---|
| 591 | WORD D_TRUENAME ; DF_TRUENAME
|
|---|
| 592 | WORD D_PATH_SI ; DF_PATH_SI
|
|---|
| 593 | WORD D_DUP ; DF_DUP
|
|---|
| 594 | WORD D_VIO11 ; DF_VIO11
|
|---|
| 595 | WORD D_VIO12 ; DF_VIO12
|
|---|
| 596 |
|
|---|
| 597 | .ERRE ($-CONV_TAB)/2 EQ DF_LAST+1
|
|---|
| 598 |
|
|---|
| 599 |
|
|---|
| 600 | ;
|
|---|
| 601 | ; All undefined interrupts go here
|
|---|
| 602 | ;
|
|---|
| 603 | ; This cannot happen, as undefined interrupts cannot be called
|
|---|
| 604 | ; from the user program (CPL=3 & DPL=0) and all hardware interrupts
|
|---|
| 605 | ; have their own vector. Yes, the supervisor could issue an
|
|---|
| 606 | ; undefined software interrupt, but it doesn't. At least I hope so.
|
|---|
| 607 | ;
|
|---|
| 608 |
|
|---|
| 609 | ASSUME DS:NOTHING
|
|---|
| 610 | INTERRUPT: MOV AX, G_SV_DATA_SEL
|
|---|
| 611 | MOV DS, AX
|
|---|
| 612 | ASSUME DS:SV_DATA
|
|---|
| 613 | LEA EDX, $INTERRUPT
|
|---|
| 614 | CALL INT_MSG
|
|---|
| 615 | JMP SHORT $
|
|---|
| 616 |
|
|---|
| 617 | ASSUME DS:NOTHING
|
|---|
| 618 | NMI: MOV AX, G_SV_DATA_SEL
|
|---|
| 619 | MOV DS, AX
|
|---|
| 620 | ASSUME DS:SV_DATA
|
|---|
| 621 | LEA EDX, $NMI
|
|---|
| 622 | CALL INT_MSG
|
|---|
| 623 | MOV AX, SS:[ESP+4] ; CS
|
|---|
| 624 | CALL VWORD
|
|---|
| 625 | MOV AL, ":"
|
|---|
| 626 | CALL VCHAR
|
|---|
| 627 | MOV EAX, SS:[ESP+0] ; EIP
|
|---|
| 628 | CALL VDWORD
|
|---|
| 629 | IF FALSE
|
|---|
| 630 | MOV AL, " "
|
|---|
| 631 | CALL VCHAR
|
|---|
| 632 | MOV EAX, SS:[ESP+8] ; EFLAGS
|
|---|
| 633 | CALL VDWORD
|
|---|
| 634 | ENDIF
|
|---|
| 635 | JMP SHORT $
|
|---|
| 636 |
|
|---|
| 637 | ;
|
|---|
| 638 | ; Display fatal error message (unexpected interrupt / NMI)
|
|---|
| 639 | ;
|
|---|
| 640 | ASSUME DS:SV_DATA
|
|---|
| 641 | INT_MSG PROC NEAR
|
|---|
| 642 | MOV AX, G_VIDEO_SEL
|
|---|
| 643 | MOV ES, AX
|
|---|
| 644 | CALL VCLS
|
|---|
| 645 | CALL VTEXT
|
|---|
| 646 | RET
|
|---|
| 647 | INT_MSG ENDP
|
|---|
| 648 |
|
|---|
| 649 |
|
|---|
| 650 | ;
|
|---|
| 651 | ; Backward jump here (for processors with BIG prefetch queue)
|
|---|
| 652 | ;
|
|---|
| 653 | RM_INT1: XOR EAX, EAX
|
|---|
| 654 | MOV CR3, EAX ; Clear TLB
|
|---|
| 655 | JMP FAR PTR RM_INT2 ; Reload CS, real mode!
|
|---|
| 656 |
|
|---|
| 657 | ;
|
|---|
| 658 | ; Call the real-mode interrupt INT_NO
|
|---|
| 659 | ;
|
|---|
| 660 | ASSUME DS:SV_DATA
|
|---|
| 661 | TALIGN 4
|
|---|
| 662 | INT_RM0 PROC FAR
|
|---|
| 663 | CLI
|
|---|
| 664 | CMP PROFIL_COUNT, 0 ; Suspend generating RTC
|
|---|
| 665 | JE SHORT NOPROF ; interrupts for the profiler
|
|---|
| 666 | CALL PROFIL_SUSPEND
|
|---|
| 667 | TALIGN 4
|
|---|
| 668 | NOPROF: MOV PMHWINT_ESP, ESP ; Save stack pointer
|
|---|
| 669 | MOV PMHWINT_SS, SS ; and stack segment
|
|---|
| 670 | MOV FRAME_PTR, BP ; After CLI!!!
|
|---|
| 671 | MOV EAX, CR0
|
|---|
| 672 | AND EAX, CR0_FPU ; Keep only FPU bits
|
|---|
| 673 | MOV PM_CR0, EAX ; Save for switching back to PM
|
|---|
| 674 | MOV EAX, CR0
|
|---|
| 675 | AND EAX, NOT CR0_FPU ; Restore floating point
|
|---|
| 676 | OR EAX, RM_CR0 ; bits of real/virtual mode
|
|---|
| 677 | MOV CR0, EAX
|
|---|
| 678 | XOR AX, AX
|
|---|
| 679 | LLDT AX ; Zero LDTR
|
|---|
| 680 | CMP VCPI_FLAG, FALSE ; Running under VCPI server?
|
|---|
| 681 | JNE INT_VCPI ; Yes -> let the server do it
|
|---|
| 682 | MOV AX, G_REAL_SEL ; Load values suitable for
|
|---|
| 683 | MOV DS, AX ; real mode into all the
|
|---|
| 684 | ASSUME DS:NOTHING ; segment registers
|
|---|
| 685 | MOV ES, AX ; (see below for CS)
|
|---|
| 686 | MOV FS, AX
|
|---|
| 687 | MOV GS, AX
|
|---|
| 688 | MOV SS, AX
|
|---|
| 689 | MOV EAX, CR0
|
|---|
| 690 | AND EAX, NOT (CR0_PG OR CR0_PE) ; Turn off paging and PM
|
|---|
| 691 | MOV CR0, EAX
|
|---|
| 692 | JMP SHORT RM_INT1 ; Flush prefetch queue
|
|---|
| 693 | ;
|
|---|
| 694 | ; ... real mode ...
|
|---|
| 695 | ;
|
|---|
| 696 | ASSUME DS:NOTHING
|
|---|
| 697 | TALIGN 4
|
|---|
| 698 | RM_INT9:: MOV AX, G_SV_DATA_SEL
|
|---|
| 699 | MOV DS, AX ; Make data accessible
|
|---|
| 700 | ASSUME DS:SV_DATA
|
|---|
| 701 | LSS ESP, PMHWINT_LSS ; Restore stack
|
|---|
| 702 | AND TSS_BUSY, NOT 2 ; Otherwise exception on LTR
|
|---|
| 703 | MOV AX, G_TSS_SEL
|
|---|
| 704 | LTR AX ; Setup task
|
|---|
| 705 | CMP PAGING, FALSE ; Use paging?
|
|---|
| 706 | JE SHORT RM_INT10 ; No -> skip
|
|---|
| 707 | MOV EAX, PAGE_DIR_PHYS
|
|---|
| 708 | MOV CR3, EAX ; Setup page directory
|
|---|
| 709 | MOV EAX, CR0
|
|---|
| 710 | OR EAX, CR0_PG ; Enable paging
|
|---|
| 711 | MOV CR0, EAX
|
|---|
| 712 | ;
|
|---|
| 713 | ; Common code for `manual' return from real mode and for VCPI
|
|---|
| 714 | ;
|
|---|
| 715 | RM_INT10: MOV EAX, CR0
|
|---|
| 716 | AND EAX, NOT CR0_FPU ; Restore floating point
|
|---|
| 717 | OR EAX, PM_CR0 ; bits of protected mode
|
|---|
| 718 | MOV CR0, EAX
|
|---|
| 719 | RET ; FAR return!!!
|
|---|
| 720 |
|
|---|
| 721 | ;
|
|---|
| 722 | ; When running under a VCPI server, we return here from virtual mode
|
|---|
| 723 | ;
|
|---|
| 724 |
|
|---|
| 725 | ASSUME DS:NOTHING
|
|---|
| 726 | TALIGN 4
|
|---|
| 727 | V2P_CONT:: MOV AX, G_SV_DATA_SEL
|
|---|
| 728 | MOV DS, AX ; Make data accessible
|
|---|
| 729 | ASSUME DS:SV_DATA
|
|---|
| 730 | MOV ES, AX
|
|---|
| 731 | MOV FS, AX
|
|---|
| 732 | MOV GS, AX
|
|---|
| 733 | LSS ESP, PMHWINT_LSS ; Setup stack
|
|---|
| 734 | JMP SHORT RM_INT10 ; Floating point bits of CR0
|
|---|
| 735 |
|
|---|
| 736 | INT_RM0 ENDP
|
|---|
| 737 |
|
|---|
| 738 |
|
|---|
| 739 | ASSUME DS:SV_DATA
|
|---|
| 740 | TALIGN 4
|
|---|
| 741 | INT_RM PROC NEAR
|
|---|
| 742 | PUSH EBP ; Save EBP
|
|---|
| 743 | PUSHFD ; Save flags
|
|---|
| 744 | SLDT AX
|
|---|
| 745 | PUSH AX ; Save LDTR
|
|---|
| 746 | CALLF16 G_SV_CODE_SEL, INT_RM0 ; FAR call!
|
|---|
| 747 | MOV AX, G_SV_DATA_SEL ; Initialize all segment
|
|---|
| 748 | MOV DS, AX ; registers
|
|---|
| 749 | MOV ES, AX
|
|---|
| 750 | MOV FS, AX
|
|---|
| 751 | MOV GS, AX
|
|---|
| 752 | ;
|
|---|
| 753 | ; Important: Restore LDTR of interrupted program. Real/virtual mode may have
|
|---|
| 754 | ; changed LDTR (INT 15H: extended memory). Actually, we zero LDTR after
|
|---|
| 755 | ; entering real mode. We need the LDTR for popping the segment registers
|
|---|
| 756 | ; of the interrupted program, which may reference the LDT.
|
|---|
| 757 | ;
|
|---|
| 758 | POP AX
|
|---|
| 759 | LLDT AX ; Restore LDTR
|
|---|
| 760 | CMP PROFIL_COUNT, 0
|
|---|
| 761 | JE SHORT NOPROF
|
|---|
| 762 | CLI ; Resume generating RTC
|
|---|
| 763 | CALL PROFIL_RESUME ; interrupts for the profiler
|
|---|
| 764 | TALIGN 4
|
|---|
| 765 | NOPROF: POPFD ; Restore flags
|
|---|
| 766 | POP EBP ; Restore EBP
|
|---|
| 767 | RET ; Done
|
|---|
| 768 | INT_RM ENDP
|
|---|
| 769 |
|
|---|
| 770 | ;
|
|---|
| 771 | ; This is the first interrupt vector used for redirecting IRQ0..IRQ7
|
|---|
| 772 | ; and IRQ8..IRQ15, respectively. These variables are located in SV_CODE
|
|---|
| 773 | ; as they are accessed with unknown segment registers (only CS is known
|
|---|
| 774 | ; to be SV_CODE_SEL).
|
|---|
| 775 | ;
|
|---|
| 776 | IRQ0_ADD BYTE ? ; Initialized by INIT_INT
|
|---|
| 777 | IRQ8_ADD BYTE ? ; Initialized by INIT_INT
|
|---|
| 778 |
|
|---|
| 779 |
|
|---|
| 780 | ;
|
|---|
| 781 | ; Entry points for hardware interrupts IRQ 0 to IRQ 7.
|
|---|
| 782 | ;
|
|---|
| 783 |
|
|---|
| 784 | ASSUME DS:NOTHING
|
|---|
| 785 |
|
|---|
| 786 | IRP X, <0,1,2,3,4,5,6,7>
|
|---|
| 787 | TALIGN 4
|
|---|
| 788 | PMINT&X: PUSH EAX ; Mock error code
|
|---|
| 789 | PUSHAD ; Save all general registers
|
|---|
| 790 | MOV CX, &X * 0100H + &X ; Compute real-mode interrupt
|
|---|
| 791 | ADD CL, IRQ0_ADD ; number (in SV_CODE segment!)
|
|---|
| 792 | JMP PMINT ; Common code
|
|---|
| 793 | ENDM
|
|---|
| 794 |
|
|---|
| 795 | ;
|
|---|
| 796 | ; Entry points for hardware interrupts IRQ 8 to IRQ 15.
|
|---|
| 797 | ;
|
|---|
| 798 |
|
|---|
| 799 | ASSUME DS:NOTHING
|
|---|
| 800 |
|
|---|
| 801 | IRP X, <8,9,10,11,12,13,14,15>
|
|---|
| 802 | TALIGN 4
|
|---|
| 803 | PMINT&X: PUSH EAX ; Mock error code
|
|---|
| 804 | PUSHAD ; Save all general registers
|
|---|
| 805 | MOV CX, &X * 0100H + &X-8 ; Compute real-mode interrupt
|
|---|
| 806 | ADD CL, IRQ8_ADD ; number (in SV_CODE segment!)
|
|---|
| 807 | JMP PMINT ; Common code
|
|---|
| 808 | ENDM
|
|---|
| 809 |
|
|---|
| 810 | ;
|
|---|
| 811 | ; Entry point for software interrupt 10H (video interface).
|
|---|
| 812 | ;
|
|---|
| 813 | TALIGN 4
|
|---|
| 814 | PMINT_10H: PUSH EAX ; Mock error code
|
|---|
| 815 | PUSHAD ; Save all general registers
|
|---|
| 816 | MOV CX, 1010H ; Real-mode interrupt number
|
|---|
| 817 | JMP SHORT PMINT ; Common code
|
|---|
| 818 |
|
|---|
| 819 | ;
|
|---|
| 820 | ; Entry point for software interrupt 11H (equipment).
|
|---|
| 821 | ;
|
|---|
| 822 | TALIGN 4
|
|---|
| 823 | PMINT_11H: PUSH EAX ; Mock error code
|
|---|
| 824 | PUSHAD ; Save all general registers
|
|---|
| 825 | MOV CX, 1111H ; Real-mode interrupt number
|
|---|
| 826 | JMP SHORT PMINT ; Common code
|
|---|
| 827 |
|
|---|
| 828 | ;
|
|---|
| 829 | ; Entry point for software interrupt 14H (RS-232 interface).
|
|---|
| 830 | ;
|
|---|
| 831 | TALIGN 4
|
|---|
| 832 | PMINT_14H: PUSH EAX ; Mock error code
|
|---|
| 833 | PUSHAD ; Save all general registers
|
|---|
| 834 | MOV CX, 1414H ; Real-mode interrupt number
|
|---|
| 835 | JMP SHORT PMINT ; Common code
|
|---|
| 836 |
|
|---|
| 837 | ;
|
|---|
| 838 | ; Entry point for software interrupt 16H (keyboard interface).
|
|---|
| 839 | ;
|
|---|
| 840 | TALIGN 4
|
|---|
| 841 | PMINT_16H: PUSH EAX ; Mock error code
|
|---|
| 842 | PUSHAD ; Save all general registers
|
|---|
| 843 | MOV CX, 1616H ; Real-mode interrupt number
|
|---|
| 844 | JMP SHORT PMINT ; Common code
|
|---|
| 845 |
|
|---|
| 846 | ;
|
|---|
| 847 | ; Entry point for software interrupt 17H (printer interface).
|
|---|
| 848 | ;
|
|---|
| 849 | TALIGN 4
|
|---|
| 850 | PMINT_17H: PUSH EAX ; Mock error code
|
|---|
| 851 | PUSHAD ; Save all general registers
|
|---|
| 852 | MOV CX, 1717H ; Real-mode interrupt number
|
|---|
| 853 | JMP SHORT PMINT ; Common code
|
|---|
| 854 |
|
|---|
| 855 | ;
|
|---|
| 856 | ; Entry point for software interrupt 21H (DOS interface).
|
|---|
| 857 | ;
|
|---|
| 858 | TALIGN 4
|
|---|
| 859 | PMINT_21H: PUSH EAX ; Mock error code
|
|---|
| 860 | PUSHAD ; Save all general registers
|
|---|
| 861 | MOV CX, 2121H ; Real-mode interrupt number
|
|---|
| 862 | JMP SHORT PMINT ; Common code
|
|---|
| 863 |
|
|---|
| 864 | ;
|
|---|
| 865 | ; Entry point for software interrupt 31H (DOS extender interface).
|
|---|
| 866 | ;
|
|---|
| 867 | TALIGN 4
|
|---|
| 868 | PMINT_31H: PUSH EAX ; Mock error code
|
|---|
| 869 | PUSHAD ; Save all general registers
|
|---|
| 870 | MOV CX, 3131H ; Real-mode interrupt number
|
|---|
| 871 | JMP SHORT PMINT ; Common code
|
|---|
| 872 |
|
|---|
| 873 | ;
|
|---|
| 874 | ; Entry point for software interrupt 33H (mouse interface).
|
|---|
| 875 | ;
|
|---|
| 876 | TALIGN 4
|
|---|
| 877 | PMINT_33H: PUSH EAX ; Mock error code
|
|---|
| 878 | PUSHAD ; Save all general registers
|
|---|
| 879 | MOV CX, 3333H ; Real-mode interrupt number
|
|---|
| 880 | JMP SHORT PMINT ; Common code
|
|---|
| 881 |
|
|---|
| 882 | ;
|
|---|
| 883 | ; Common code for protected-mode interrupts (hardware and software interrupts).
|
|---|
| 884 | ;
|
|---|
| 885 | ; Note: this code runs with interrupts masked.
|
|---|
| 886 | ;
|
|---|
| 887 | TALIGN 4
|
|---|
| 888 | PMINT: PUSH DS ; Save segment registers
|
|---|
| 889 | PUSH ES
|
|---|
| 890 | PUSH FS
|
|---|
| 891 | PUSH GS
|
|---|
| 892 | IF SER_FLAG
|
|---|
| 893 | SERIAL "I"
|
|---|
| 894 | ENDIF
|
|---|
| 895 | CLD
|
|---|
| 896 | MOV AX, G_SV_DATA_SEL
|
|---|
| 897 | MOV DS, AX ; Make data segment available
|
|---|
| 898 | ASSUME DS:SV_DATA
|
|---|
| 899 | MOV EBP, ESP ; Setup stack frame pointer
|
|---|
| 900 | SUB ESP, FRAME_SIZE ; Local variables
|
|---|
| 901 | PMINT_STACK_SNAP_SHOT: ; For documentation only
|
|---|
| 902 | MOV INT_NO, CL ; Save interrupt number
|
|---|
| 903 | MOV HW_INT_VEC, CH
|
|---|
| 904 | CMP CH, 8 ; RTC interrupt?
|
|---|
| 905 | JE RTC_INT ; Yes -> profile or reflect
|
|---|
| 906 | IF FLOATING_POINT
|
|---|
| 907 | CMP CH, 13 ; Coprocessor interrupt?
|
|---|
| 908 | JE COPROC ; Yes -> map to SIGFPE
|
|---|
| 909 | SKIP_COPROC:
|
|---|
| 910 | ENDIF
|
|---|
| 911 | CMP CL, 21H ; DOS call interrupt?
|
|---|
| 912 | JE DOSCALL ; Yes ->
|
|---|
| 913 | CMP CL, 10H ; Video API interrupt?
|
|---|
| 914 | JE VIOCALL ; Yes ->
|
|---|
| 915 | CMP CL, 11H ; Equiment interrupt?
|
|---|
| 916 | JE GENERIC_CALL ; Yes ->
|
|---|
| 917 | CMP CL, 14H ; RS-232 API interrupt?
|
|---|
| 918 | JE GENERIC_CALL ; Yes ->
|
|---|
| 919 | CMP CL, 16H ; Keyboard API interrupt?
|
|---|
| 920 | JE GENERIC_CALL ; Yes ->
|
|---|
| 921 | CMP CL, 17H ; Printer API interrupt?
|
|---|
| 922 | JE GENERIC_CALL ; Yes ->
|
|---|
| 923 | CMP CL, 31H ; DOS extender API interrupt?
|
|---|
| 924 | JE EXT_CALL ; Yes ->
|
|---|
| 925 | CMP CL, 33H ; Mouse API interrupt?
|
|---|
| 926 | JE MOUCALL ; Yes ->
|
|---|
| 927 | ;
|
|---|
| 928 | ; This is the simple case: just reissue the interrupt in real mode.
|
|---|
| 929 | ;
|
|---|
| 930 | REFLECT: CALL INT_RM
|
|---|
| 931 | ;
|
|---|
| 932 | ; The STI in the following line has been removed in emx 0.8b to fix a stack
|
|---|
| 933 | ; overflow problem with high speed communications and an interrupt controller
|
|---|
| 934 | ; reprogrammed to AEOI mode.
|
|---|
| 935 | ;
|
|---|
| 936 | ;*** STI ; At the risk of stack overflow
|
|---|
| 937 | ;
|
|---|
| 938 | ; Back in protected mode, return to interrupted code (and check for signals)
|
|---|
| 939 | ;
|
|---|
| 940 | PMINT_RET: CMP EMERGENCY_FLAG, FALSE ; Emergency exit pending?
|
|---|
| 941 | JE SHORT SKIP_EMGCY
|
|---|
| 942 | CALL EMERGENCY_EXIT
|
|---|
| 943 | SKIP_EMGCY: ADD ESP, FRAME_SIZE ; Remove local variables
|
|---|
| 944 | CALL SIG_DELIVER_PENDING
|
|---|
| 945 | IF SER_FLAG
|
|---|
| 946 | SERIAL "i"
|
|---|
| 947 | ENDIF
|
|---|
| 948 | POP GS ; Restore segment registers
|
|---|
| 949 | POP FS
|
|---|
| 950 | POP ES
|
|---|
| 951 | POP DS
|
|---|
| 952 | POPAD ; Restore general registers
|
|---|
| 953 | NOP ; Avoid 386 bug
|
|---|
| 954 | ADD ESP, 4 ; Remove error code
|
|---|
| 955 | IRETD ; End of interrupt routine
|
|---|
| 956 | ; 32-bit interrupt gate!!!
|
|---|
| 957 |
|
|---|
| 958 |
|
|---|
| 959 | ;
|
|---|
| 960 | ; Syscall functions
|
|---|
| 961 | ;
|
|---|
| 962 | TALIGN 4
|
|---|
| 963 | SYSCALL_1: CALL DO_SYSCALL
|
|---|
| 964 | JMP PMINT_RET
|
|---|
| 965 |
|
|---|
| 966 | ;
|
|---|
| 967 | ; Emergency exit
|
|---|
| 968 | ;
|
|---|
| 969 | EMERGENCY_EXIT PROC NEAR
|
|---|
| 970 | MOV EMERGENCY_FLAG, FALSE
|
|---|
| 971 | LEA EDX, $EMERGENCY
|
|---|
| 972 | CALL OTEXT
|
|---|
| 973 | CALL OCRLF
|
|---|
| 974 | MOV AX, 4CFFH
|
|---|
| 975 | INT 21H
|
|---|
| 976 | EMERGENCY_EXIT ENDP
|
|---|
| 977 |
|
|---|
| 978 | ;
|
|---|
| 979 | ; Real-time clock interrupt (IRQ8).
|
|---|
| 980 | ;
|
|---|
| 981 | TALIGN 4
|
|---|
| 982 | RTC_INT: CMP PROFIL_COUNT, 0
|
|---|
| 983 | JE REFLECT
|
|---|
| 984 | CALL PROFIL_TICK
|
|---|
| 985 | JMP PMINT_RET
|
|---|
| 986 |
|
|---|
| 987 | ;
|
|---|
| 988 | ; Coprocessor interrupt (IRQ13). Reset the BUSY pin and raise SIGFPE.
|
|---|
| 989 | ;
|
|---|
| 990 | TALIGN 4
|
|---|
| 991 | COPROC: CMP MACHINE, MACH_PC ; PC architecture?
|
|---|
| 992 | JNE SKIP_COPROC ; No -> give up
|
|---|
| 993 | ;
|
|---|
| 994 | ; Reset the interrupt condition
|
|---|
| 995 | ;
|
|---|
| 996 | MOV AL, 00H ; Send a byte of zeros
|
|---|
| 997 | OUT 0F0H, AL ; to reset the BUSY pin
|
|---|
| 998 | MOV AL, 20H ; Send EOI command to the
|
|---|
| 999 | OUT 0A0H, AL ; slave interrupt controller,
|
|---|
| 1000 | OUT 20H, AL ; master interrupt controller
|
|---|
| 1001 | FNCLEX ; Clear exceptions
|
|---|
| 1002 | ;
|
|---|
| 1003 | ; Raise SIGFPE
|
|---|
| 1004 | ;
|
|---|
| 1005 | MOV AL, 16 ; Exception 16: Coproc error
|
|---|
| 1006 | JMP EXCEPT_FAKE ; Fake an exception
|
|---|
| 1007 |
|
|---|
| 1008 | COPROC_DONE: JMP PMINT_RET
|
|---|
| 1009 |
|
|---|
| 1010 | ;
|
|---|
| 1011 | ; DOS extender interface.
|
|---|
| 1012 | ;
|
|---|
| 1013 | TALIGN 4
|
|---|
| 1014 | EXT_CALL: STI
|
|---|
| 1015 | CALL EXTAPI
|
|---|
| 1016 | JMP PMINT_RET
|
|---|
| 1017 |
|
|---|
| 1018 | ;
|
|---|
| 1019 | ; DOS interface.
|
|---|
| 1020 | ;
|
|---|
| 1021 | ASSUME DS:SV_DATA
|
|---|
| 1022 | ASSUME BP:PTR ISTACKFRAME
|
|---|
| 1023 | TALIGN 4
|
|---|
| 1024 | DOSCALL: STI ; Be venturous!
|
|---|
| 1025 | AND I_EFLAGS, NOT FLAG_C ; Clear carry flag (no error)
|
|---|
| 1026 | MOV EAX, I_EAX ; Get EAX (we need only AX)
|
|---|
| 1027 | CMP AH, 7FH ; Syscall functions?
|
|---|
| 1028 | JE SHORT SYSCALL_1 ; Yes ->
|
|---|
| 1029 | CALL REGS_TO_RM ; Set real-mode registers
|
|---|
| 1030 | ;
|
|---|
| 1031 | ; Apply umask for __creat()
|
|---|
| 1032 | ;
|
|---|
| 1033 | CMP BYTE PTR RM_AX[1], 3CH ; Create handle?
|
|---|
| 1034 | JNE SHORT SKIP_CREAT ; No -> skip
|
|---|
| 1035 | MOV BX, PROCESS_PTR ; Current process
|
|---|
| 1036 | CMP BX, NO_PROCESS ; In user code?
|
|---|
| 1037 | JE SHORT SKIP_CREAT ; No -> keep mode
|
|---|
| 1038 | TEST (PROCESS PTR [BX]).P_UMASK, S_IWRITE
|
|---|
| 1039 | JZ SHORT SKIP_CREAT ; Write perm. -> keep mode
|
|---|
| 1040 | OR RM_CX, 1 ; Set read-only attribute
|
|---|
| 1041 | TALIGN 4
|
|---|
| 1042 | ;
|
|---|
| 1043 | ; Get conversion flag for INT 21H functions, convert handles if appropriate.
|
|---|
| 1044 | ;
|
|---|
| 1045 | SKIP_CREAT: MOV INP_HANDLE, NO_FILE_HANDLE ; Handle not converted
|
|---|
| 1046 | MOV BL, BYTE PTR RM_AX[1] ; AH
|
|---|
| 1047 | TBGET DOS_FUNCS ; Get conversion flag
|
|---|
| 1048 | CMP AL, DF_IOCTL ; Use second table?
|
|---|
| 1049 | JNE SHORT DOSCALL_1
|
|---|
| 1050 | MOV BL, BYTE PTR RM_AX[0] ; AL
|
|---|
| 1051 | TBGET IOCTL_FUNCS ; Get conversion flag
|
|---|
| 1052 | DOSCALL_1: MOV CONV_FLAG, AX ; Save conversion flag
|
|---|
| 1053 | CMP PROCESS_PTR, NO_PROCESS ; Translate handles?
|
|---|
| 1054 | JE SHORT DOSCALL_9 ; No -> skip
|
|---|
| 1055 | TEST CONV_FLAG, DFH_IN ; Convert handle (input)?
|
|---|
| 1056 | JZ SHORT DOSCALL_2 ; No -> check for output
|
|---|
| 1057 | MOV AX, RM_BX ; Get process' handle
|
|---|
| 1058 | MOV INP_HANDLE, AX ; Save this value
|
|---|
| 1059 | CALL GET_HANDLE ; Convert to DOS handle
|
|---|
| 1060 | MOV RM_BX, AX ; and store to BX
|
|---|
| 1061 | DOSCALL_2: TEST CONV_FLAG, DFH_OUT ; Convert handle (output)?
|
|---|
| 1062 | JZ SHORT DOSCALL_3 ; No -> skip
|
|---|
| 1063 | MOV AX, NO_FILE_HANDLE
|
|---|
| 1064 | CALL NEW_HANDLE ; Slot available?
|
|---|
| 1065 | JNC SHORT DOSCALL_3 ; Yes -> continue
|
|---|
| 1066 | MOV I_EAX, EMFILE ; Too many open files
|
|---|
| 1067 | OR BYTE PTR I_EFLAGS, FLAG_C ; Set carry flag
|
|---|
| 1068 | JMP PMINT_RET ; Return to caller
|
|---|
| 1069 | ;
|
|---|
| 1070 | ; Check whether identical mapping should be used for handles 0 and 1.
|
|---|
| 1071 | ; This can be done after calling GET_HANDLE because all functions
|
|---|
| 1072 | ; for which DFM_STDIN or DFM_STDOUT is set, don't use an explicit
|
|---|
| 1073 | ; file handle (that's why DFM_STDIN and DFM_STDOUT are required in
|
|---|
| 1074 | ; the first place).
|
|---|
| 1075 | ;
|
|---|
| 1076 | DOSCALL_3: TEST CONV_FLAG, DFM_STDIN ; Remap handle 0?
|
|---|
| 1077 | JZ SHORT DOSCALL_4
|
|---|
| 1078 | MOV AX, 0
|
|---|
| 1079 | CALL MAP_HANDLE
|
|---|
| 1080 | JC SHORT MAP_ERROR
|
|---|
| 1081 | DOSCALL_4: TEST CONV_FLAG, DFM_STDOUT ; Remap handle 1?
|
|---|
| 1082 | JZ SHORT DOSCALL_9
|
|---|
| 1083 | MOV AX, 1
|
|---|
| 1084 | CALL MAP_HANDLE
|
|---|
| 1085 | JNC SHORT DOSCALL_9
|
|---|
| 1086 | MAP_ERROR: MOV WORD PTR I_EAX+0, AX
|
|---|
| 1087 | MOV WORD PTR I_EAX+2, 0
|
|---|
| 1088 | OR BYTE PTR I_EFLAGS, FLAG_C ; Set carry flag
|
|---|
| 1089 | JMP PMINT_RET
|
|---|
| 1090 |
|
|---|
| 1091 | ;
|
|---|
| 1092 | ; Dispatcher for INT 21H
|
|---|
| 1093 | ;
|
|---|
| 1094 | TALIGN 4
|
|---|
| 1095 | DOSCALL_9: MOVZX BX, BYTE PTR CONV_FLAG ; Get conversion flag
|
|---|
| 1096 | SHL BX, 1
|
|---|
| 1097 | JMP CONV_TAB[BX]
|
|---|
| 1098 |
|
|---|
| 1099 | ;
|
|---|
| 1100 | ; Dispatcher for other interrupts (use AX as conversion flag)
|
|---|
| 1101 | ;
|
|---|
| 1102 | TALIGN 4
|
|---|
| 1103 | INTCALL: MOV CONV_FLAG, AX ; No conversion at DOSCALL_RET
|
|---|
| 1104 | MOV BX, AX
|
|---|
| 1105 | SHL BX, 1
|
|---|
| 1106 | JMP CONV_TAB[BX]
|
|---|
| 1107 |
|
|---|
| 1108 | ;
|
|---|
| 1109 | ; INT 10H -- video BIOS
|
|---|
| 1110 | ;
|
|---|
| 1111 | VIOCALL: MOV INP_HANDLE, NO_FILE_HANDLE
|
|---|
| 1112 | CALL REGS_TO_RM
|
|---|
| 1113 | MOV BL, BYTE PTR RM_AX[1] ; AH
|
|---|
| 1114 | TBGET VIO_FUNCS ; Get conversion flag
|
|---|
| 1115 | JMP SHORT INTCALL
|
|---|
| 1116 |
|
|---|
| 1117 | D_VESA: MOV BL, BYTE PTR RM_AX[0] ; AL
|
|---|
| 1118 | TBGET VESA_FUNCS ; Get conversion flag
|
|---|
| 1119 | JMP SHORT INTCALL
|
|---|
| 1120 |
|
|---|
| 1121 | D_VIO11: MOV BL, BYTE PTR RM_AX[0] ; AL
|
|---|
| 1122 | TBGET VIO11_FUNCS ; Get conversion flag
|
|---|
| 1123 | JMP SHORT INTCALL
|
|---|
| 1124 |
|
|---|
| 1125 | D_VIO12: MOV BL, BYTE PTR RM_BX[0] ; BL
|
|---|
| 1126 | TBGET VIO12_FUNCS ; Get conversion flag
|
|---|
| 1127 | JMP SHORT INTCALL
|
|---|
| 1128 |
|
|---|
| 1129 | ;
|
|---|
| 1130 | ; INT 33H -- mouse driver
|
|---|
| 1131 | ;
|
|---|
| 1132 | MOUCALL: MOV INP_HANDLE, NO_FILE_HANDLE
|
|---|
| 1133 | CALL REGS_TO_RM
|
|---|
| 1134 | MOV BX, RM_AX ; Get AX
|
|---|
| 1135 | CMP BH, 0 ; AH=0?
|
|---|
| 1136 | JNE D_INVALID ; No -> error
|
|---|
| 1137 | TBGET MOU_FUNCS ; Get conversion flag
|
|---|
| 1138 | JMP INTCALL
|
|---|
| 1139 |
|
|---|
| 1140 | ;
|
|---|
| 1141 | ; Generic software interrupt, no conversion
|
|---|
| 1142 | ;
|
|---|
| 1143 | GENERIC_CALL: MOV INP_HANDLE, NO_FILE_HANDLE
|
|---|
| 1144 | CALL REGS_TO_RM
|
|---|
| 1145 | MOV AX, DF_NULL ; No conversion
|
|---|
| 1146 | JMP INTCALL
|
|---|
| 1147 |
|
|---|
| 1148 | ;
|
|---|
| 1149 | ; Duplicate file handle
|
|---|
| 1150 | ;
|
|---|
| 1151 | D_DUP: MOV BX, PROCESS_PTR
|
|---|
| 1152 | CMP BX, NO_PROCESS ; Called from user process?
|
|---|
| 1153 | JE D_NULL ; No -> directly call DOS
|
|---|
| 1154 | MOV AX, RM_BX ; Handle
|
|---|
| 1155 | CALL DO_DUP
|
|---|
| 1156 | D_DUP_COMMON: MOV WORD PTR I_EAX + 0, AX
|
|---|
| 1157 | MOV WORD PTR I_EAX + 2, 0
|
|---|
| 1158 | JNC SHORT D_DUP_FIN
|
|---|
| 1159 | OR BYTE PTR I_EFLAGS, FLAG_C ; Set carry flag
|
|---|
| 1160 | D_DUP_FIN: JMP PMINT_RET ; DFE not set for D_DUP!
|
|---|
| 1161 |
|
|---|
| 1162 | ;
|
|---|
| 1163 | ; Force duplicate file handle
|
|---|
| 1164 | ;
|
|---|
| 1165 | D_DUP2: MOV BX, PROCESS_PTR
|
|---|
| 1166 | CMP BX, NO_PROCESS ; Called from user process?
|
|---|
| 1167 | JE D_NULL ; No -> directly call DOS
|
|---|
| 1168 | MOV AX, RM_BX ; Handle1
|
|---|
| 1169 | MOV CX, RM_CX ; Handle2
|
|---|
| 1170 | CALL DO_DUP2
|
|---|
| 1171 | JMP D_DUP_COMMON
|
|---|
| 1172 |
|
|---|
| 1173 | ;
|
|---|
| 1174 | ; Invalid function
|
|---|
| 1175 | ;
|
|---|
| 1176 | D_INVALID: MOV BL, BYTE PTR RM_AX[0]
|
|---|
| 1177 | LEA EDX, $BAD_MOU_FUNC ; MOU function not supported
|
|---|
| 1178 | CMP INT_NO, 33H
|
|---|
| 1179 | JE SHORT DOSF_ERROR
|
|---|
| 1180 | MOV BL, BYTE PTR RM_AX[1]
|
|---|
| 1181 | LEA EDX, $BAD_VIO_FUNC ; VIO function not supported
|
|---|
| 1182 | CMP INT_NO, 10H
|
|---|
| 1183 | JE SHORT DOSF_ERROR
|
|---|
| 1184 | LEA EDX, $BAD_DOS_FUNC ; DOS function not supported
|
|---|
| 1185 | DOSF_ERROR: PUSH BX ; Save function number (BL)
|
|---|
| 1186 | CALL OTEXT ; Display message
|
|---|
| 1187 | POP AX ; Restore function number (AL)
|
|---|
| 1188 | CALL OBYTE ; Display hex byte
|
|---|
| 1189 | MOV AX, 4CFFH ; Terminate program (255)
|
|---|
| 1190 | INT 21H ; This is recursive!
|
|---|
| 1191 |
|
|---|
| 1192 | ;
|
|---|
| 1193 | ; Invalid arguments
|
|---|
| 1194 | ;
|
|---|
| 1195 | DOSF_PARAM: LEA EDX, $DOS_PARAM ; Invalid arguments
|
|---|
| 1196 | JMP DOSF_ERROR ; Abort
|
|---|
| 1197 |
|
|---|
| 1198 | ;
|
|---|
| 1199 | ; Convert output:
|
|---|
| 1200 | ;
|
|---|
| 1201 | ; Insert emx version
|
|---|
| 1202 | ;
|
|---|
| 1203 | D_VERSION: CALL INT_RM ; Call DOS
|
|---|
| 1204 | CALL REGS_FROM_RM ; Copy all general registers
|
|---|
| 1205 | MOV WORD PTR I_EAX+2, 6D65H ; Indicate emx: "em"
|
|---|
| 1206 | JMP DOSCALL_RET ; Done
|
|---|
| 1207 |
|
|---|
| 1208 |
|
|---|
| 1209 | ;
|
|---|
| 1210 | ; Convert input:
|
|---|
| 1211 | ;
|
|---|
| 1212 | ; DS:EDX points to "$" terminated string
|
|---|
| 1213 | ;
|
|---|
| 1214 | TALIGN 4
|
|---|
| 1215 | D_TEXT: MOV AL, "$" ; Look for "$"
|
|---|
| 1216 | MOV AH, FALSE ; Not a path name
|
|---|
| 1217 | XOR EBX, EBX ; Don't add
|
|---|
| 1218 | CALL G_DELIM
|
|---|
| 1219 | JMP DOSCALL_RET ; Done
|
|---|
| 1220 |
|
|---|
| 1221 |
|
|---|
| 1222 | ;
|
|---|
| 1223 | ; Convert input and output:
|
|---|
| 1224 | ;
|
|---|
| 1225 | ; DS:EDX points to 0 terminated string (path)
|
|---|
| 1226 | ; DS:ESI points to DTA (43 bytes)
|
|---|
| 1227 | ;
|
|---|
| 1228 | TALIGN 4
|
|---|
| 1229 | D_FFIRST: CALL SET_DTA_1 ; Uses OFFSET_1
|
|---|
| 1230 | MOV ESI, I_EDX
|
|---|
| 1231 | MOV AL, 00H ; Terminator
|
|---|
| 1232 | MOV AH, NOT FALSE ; It's a path name
|
|---|
| 1233 | XOR EBX, EBX
|
|---|
| 1234 | MOV EDI, OFFSET_2
|
|---|
| 1235 | MOV RM_DX, DI ; Offset of buffer
|
|---|
| 1236 | CALL I_DELIM
|
|---|
| 1237 | D_FFIRST_1: PUSH I_EDX ; Save EDX (argument)
|
|---|
| 1238 | CALL INT_RM ; Call DOS
|
|---|
| 1239 | CALL REGS_FROM_RM ; Retrieve real-mode registers
|
|---|
| 1240 | POP I_EDX ; Restore EDX (of caller)
|
|---|
| 1241 | MOV AX, I_DS ; AX:EDI = destination
|
|---|
| 1242 | MOV EDI, I_ESI
|
|---|
| 1243 | MOV ECX, 43
|
|---|
| 1244 | CALL MOVE_FROM_RM ; Copy from real-mode buffer
|
|---|
| 1245 | JMP DOSCALL_RET
|
|---|
| 1246 |
|
|---|
| 1247 | ;
|
|---|
| 1248 | ; Convert input and output:
|
|---|
| 1249 | ;
|
|---|
| 1250 | ; DS:ESI points to DTA (43 bytes)
|
|---|
| 1251 | ;
|
|---|
| 1252 | TALIGN 4
|
|---|
| 1253 | D_FNEXT: CALL SET_DTA_1 ; Uses OFFSET_1
|
|---|
| 1254 | MOV AX, I_DS
|
|---|
| 1255 | MOV ESI, I_ESI
|
|---|
| 1256 | MOV EDI, OFFSET_1
|
|---|
| 1257 | MOV ECX, 43
|
|---|
| 1258 | CALL MOVE_TO_RM
|
|---|
| 1259 | JMP SHORT D_FFIRST_1
|
|---|
| 1260 |
|
|---|
| 1261 | ;
|
|---|
| 1262 | ;
|
|---|
| 1263 | ; Convert input:
|
|---|
| 1264 | ;
|
|---|
| 1265 | ; DS:EDX points to 0 terminated string (path) -> DS:DX
|
|---|
| 1266 | ; DS:EDI points to 0 terminated string (path) -> ES:DI
|
|---|
| 1267 | ;
|
|---|
| 1268 | TALIGN 4
|
|---|
| 1269 | D_MOVE: MOV ESI, I_EDI
|
|---|
| 1270 | MOV AL, 00H ; Terminator
|
|---|
| 1271 | MOV AH, NOT FALSE ; It's a path name
|
|---|
| 1272 | XOR EBX, EBX
|
|---|
| 1273 | MOV EDI, OFFSET_2
|
|---|
| 1274 | MOV RM_DI, DI ; Offset of buffer
|
|---|
| 1275 | CALL I_DELIM
|
|---|
| 1276 | ; fall through to D_PATH
|
|---|
| 1277 | ;
|
|---|
| 1278 | ; Convert input:
|
|---|
| 1279 | ;
|
|---|
| 1280 | ; DS:EDX points to 0 terminated string (path)
|
|---|
| 1281 | ;
|
|---|
| 1282 | TALIGN 4
|
|---|
| 1283 | D_PATH: MOV AL, 0 ; Look for zeros
|
|---|
| 1284 | MOV AH, NOT FALSE ; It's a path name
|
|---|
| 1285 | XOR EBX, EBX ; Don't add
|
|---|
| 1286 | CALL G_DELIM
|
|---|
| 1287 | JMP DOSCALL_RET
|
|---|
| 1288 |
|
|---|
| 1289 | ;
|
|---|
| 1290 | ; Convert input:
|
|---|
| 1291 | ;
|
|---|
| 1292 | ; DS:ESI points to 0 terminated string (path)
|
|---|
| 1293 | ;
|
|---|
| 1294 | D_PATH_SI: MOV AL, 0 ; Look for zeros
|
|---|
| 1295 | MOV AH, NOT FALSE ; It's a path name
|
|---|
| 1296 | XOR EBX, EBX ; Don't add
|
|---|
| 1297 | MOV ESI, I_ESI
|
|---|
| 1298 | MOV EDI, OFFSET_1
|
|---|
| 1299 | MOV RM_SI, DI ; Offset of buffer
|
|---|
| 1300 | CALL I_DELIM
|
|---|
| 1301 | PUSH I_ESI ; Save ESI (argument)
|
|---|
| 1302 | CALL INT_RM ; Call DOS
|
|---|
| 1303 | CALL REGS_FROM_RM ; Retrieve real-mode registers
|
|---|
| 1304 | POP I_ESI ; Restore ESI (of caller)
|
|---|
| 1305 | JMP DOSCALL_RET
|
|---|
| 1306 |
|
|---|
| 1307 | ;
|
|---|
| 1308 | ; Convert input/output:
|
|---|
| 1309 | ;
|
|---|
| 1310 | ; DS:EDX points to 0 terminated string (path) + 13 bytes
|
|---|
| 1311 | ;
|
|---|
| 1312 | TALIGN 4
|
|---|
| 1313 | D_TMP: MOV AL, 0 ; Look for zeros
|
|---|
| 1314 | MOV AH, NOT FALSE ; It's a path name
|
|---|
| 1315 | MOV EBX, 13 ; Add 13 bytes
|
|---|
| 1316 | CALL G_DELIM
|
|---|
| 1317 | MOV AX, I_DS ; AX:EDI = destination
|
|---|
| 1318 | MOV EDI, I_EDX
|
|---|
| 1319 | CALL MOVE_FROM_RM ; Copy from real-mode buffer
|
|---|
| 1320 | JMP DOSCALL_RET
|
|---|
| 1321 |
|
|---|
| 1322 | ;
|
|---|
| 1323 | ; Convert input/output:
|
|---|
| 1324 | ;
|
|---|
| 1325 | ; DS:EDX points to buffer, length: first byte + 2
|
|---|
| 1326 | ;
|
|---|
| 1327 | TALIGN 4
|
|---|
| 1328 | D_INPUT: MOV AX, I_DS
|
|---|
| 1329 | MOV ESI, I_EDX
|
|---|
| 1330 | MOV ES, AX
|
|---|
| 1331 | MOVZX ECX, BYTE PTR ES:[ESI]
|
|---|
| 1332 | ADD ECX, 2
|
|---|
| 1333 | PUSH ECX
|
|---|
| 1334 | MOV EDI, OFFSET_1
|
|---|
| 1335 | MOV RM_DX, DI ; Offset of buffer
|
|---|
| 1336 | CALL MOVE_TO_RM
|
|---|
| 1337 | CALL INT_RM
|
|---|
| 1338 | POP ECX
|
|---|
| 1339 | MOV AX, I_DS
|
|---|
| 1340 | MOV EDI, I_EDX
|
|---|
| 1341 | CALL MOVE_FROM_RM
|
|---|
| 1342 | JMP DOSCALL_RET
|
|---|
| 1343 |
|
|---|
| 1344 | ;
|
|---|
| 1345 | ; Convert output:
|
|---|
| 1346 | ;
|
|---|
| 1347 | ; DS:ESI points to zero terminated string
|
|---|
| 1348 | ;
|
|---|
| 1349 | TALIGN 4
|
|---|
| 1350 | D_GETCWD: MOV RM_SI, OFFSET_1 ; Offset of buffer
|
|---|
| 1351 | CALL INT_RM
|
|---|
| 1352 | TEST RM_FLAGS, FLAG_C
|
|---|
| 1353 | JNZ DOSCALL_RET
|
|---|
| 1354 | MOV EDI, I_ESI
|
|---|
| 1355 | MOV AX, I_DS
|
|---|
| 1356 | CALL MOVEZ_FROM_RM
|
|---|
| 1357 | JMP DOSCALL_RET
|
|---|
| 1358 |
|
|---|
| 1359 | ;
|
|---|
| 1360 | ; Input (registers of caller):
|
|---|
| 1361 | ; BX = handle
|
|---|
| 1362 | ; DS:EDX = buffer
|
|---|
| 1363 | ; ECX = number of bytes
|
|---|
| 1364 | ;
|
|---|
| 1365 | ; Output (registers of caller):
|
|---|
| 1366 | ; EAX = number of bytes or error code
|
|---|
| 1367 | ; CY=1 : error
|
|---|
| 1368 | ;
|
|---|
| 1369 | ; Truncate the file at the current position of the file pointer (in contrast
|
|---|
| 1370 | ; to the statement in system.doc). This is required for the implementation
|
|---|
| 1371 | ; of _ftruncate().
|
|---|
| 1372 | ;
|
|---|
| 1373 | TALIGN 4
|
|---|
| 1374 | D_WRITE: MOV AX, WORD PTR I_EAX
|
|---|
| 1375 | MOV N_AX, AX
|
|---|
| 1376 | MOV EAX, I_ECX
|
|---|
| 1377 | MOV NREQ, EAX
|
|---|
| 1378 | PUSH EAX ; Save caller's ECX
|
|---|
| 1379 | MOV EAX, I_EDX
|
|---|
| 1380 | MOV NPTR, EAX
|
|---|
| 1381 | PUSH EAX ; Save caller's EDX
|
|---|
| 1382 | MOV I_EAX, 0 ; Result := 0 (EAX)
|
|---|
| 1383 | D_WRITE1: MOV EAX, NREQ
|
|---|
| 1384 | CMP EAX, 0FFFFH - OFFSET_1
|
|---|
| 1385 | JBE SHORT D_WRITE2
|
|---|
| 1386 | MOV AX, 0FE00H ; 64K - 512
|
|---|
| 1387 | D_WRITE2: MOV RM_CX, AX
|
|---|
| 1388 | MOV RM_DX, OFFSET_1 ; Offset of buffer
|
|---|
| 1389 | MOV AX, I_DS ; AX:ESI = source
|
|---|
| 1390 | MOV ESI, NPTR
|
|---|
| 1391 | MOVZX ECX, RM_CX ; Size of buffer
|
|---|
| 1392 | MOV EDI, OFFSET_1
|
|---|
| 1393 | MOV RM_DX, DI ; Offset of buffer
|
|---|
| 1394 | CALL MOVE_TO_RM ; Copy to real-mode buffer
|
|---|
| 1395 | MOV AX, N_AX
|
|---|
| 1396 | MOV RM_AX, AX
|
|---|
| 1397 | CALL INT_RM ; Call DOS
|
|---|
| 1398 | TEST RM_FLAGS, FLAG_C ; Error?
|
|---|
| 1399 | JNZ SHORT D_WRITE_ERR
|
|---|
| 1400 | MOV AX, RM_AX ; Number of bytes written
|
|---|
| 1401 | TEST AX, AX ; Zero?
|
|---|
| 1402 | JZ SHORT D_WRITE_END ; Yes -> done
|
|---|
| 1403 | MOVZX ECX, AX
|
|---|
| 1404 | ADD I_EAX, ECX ; Update return value
|
|---|
| 1405 | CMP AX, RM_CX ; Less than requested?
|
|---|
| 1406 | JB SHORT D_WRITE_END ; Yes -> done
|
|---|
| 1407 | ADD NPTR, ECX
|
|---|
| 1408 | SUB NREQ, ECX
|
|---|
| 1409 | JNZ SHORT D_WRITE1
|
|---|
| 1410 | JMP SHORT D_WRITE_END
|
|---|
| 1411 |
|
|---|
| 1412 | D_WRITE_ERR: MOVZX EAX, RM_AX ; Copy error code
|
|---|
| 1413 | MOV I_EAX, EAX
|
|---|
| 1414 | D_WRITE_END: MOV AL, RM_FLAGS ; Copy flags
|
|---|
| 1415 | MOV BYTE PTR I_EFLAGS[0], AL
|
|---|
| 1416 | POP I_EDX ; Restore caller's EDX
|
|---|
| 1417 | POP I_ECX ; Restore caller's ECX
|
|---|
| 1418 | JMP DOSCALL_RET ; Done
|
|---|
| 1419 |
|
|---|
| 1420 | ;
|
|---|
| 1421 | ; Input (registers of caller):
|
|---|
| 1422 | ; BX = handle
|
|---|
| 1423 | ; DS:EDX = buffer
|
|---|
| 1424 | ; ECX = number of bytes
|
|---|
| 1425 | ;
|
|---|
| 1426 | ; Output (registers of caller):
|
|---|
| 1427 | ; EAX = number of bytes or error code
|
|---|
| 1428 | ; CY=1 : error
|
|---|
| 1429 | ;
|
|---|
| 1430 | TALIGN 4
|
|---|
| 1431 | D_READ: CMP BYTE PTR RM_AX[1], 3FH ; AH=3FH (read handle)?
|
|---|
| 1432 | JNE SHORT D_READ_10
|
|---|
| 1433 | CMP RM_BX, 0 ; Handle = stdin?
|
|---|
| 1434 | JNE SHORT D_READ_10
|
|---|
| 1435 | TEST STDIN_TERMIO.C_LFLAG, IDEFAULT
|
|---|
| 1436 | JNZ SHORT D_READ_10
|
|---|
| 1437 | CMP PROCESS_PTR, NO_PROCESS
|
|---|
| 1438 | JE SHORT D_READ_10
|
|---|
| 1439 | TEST I_CS, 3 ; Called from user code?
|
|---|
| 1440 | JZ SHORT D_READ_10 ; No ->
|
|---|
| 1441 | PUSH RM_BX
|
|---|
| 1442 | MOV RM_AX, 4400H ; IOCTL: Get device data
|
|---|
| 1443 | CALL INT_RM
|
|---|
| 1444 | TEST RM_FLAGS, FLAG_C ; Error?
|
|---|
| 1445 | JNZ SHORT D_READ_09 ; Yes -> continue
|
|---|
| 1446 | TEST RM_DX, 80H ; Device?
|
|---|
| 1447 | JZ SHORT D_READ_09 ; No -> continue
|
|---|
| 1448 | TEST RM_DX, 01H ; Console input device?
|
|---|
| 1449 | JZ SHORT D_READ_09 ; No -> continue
|
|---|
| 1450 | POP RM_BX ; Cleanup stack
|
|---|
| 1451 | MOV ES, I_DS
|
|---|
| 1452 | MOV EDI, I_EDX
|
|---|
| 1453 | MOV ECX, I_ECX
|
|---|
| 1454 | CALL TERMIO_READ
|
|---|
| 1455 | MOV I_EAX, EAX
|
|---|
| 1456 | JNC D_READ_01
|
|---|
| 1457 | OR I_EFLAGS, FLAG_C
|
|---|
| 1458 | D_READ_01: MOV AX, INP_HANDLE
|
|---|
| 1459 | CMP AX, NO_FILE_HANDLE ; Input handle converted?
|
|---|
| 1460 | JE SHORT D_READ_02 ; No -> skip
|
|---|
| 1461 | MOV WORD PTR I_EBX, AX ; Store to (E)BX
|
|---|
| 1462 | D_READ_02: JMP PMINT_RET
|
|---|
| 1463 |
|
|---|
| 1464 | D_READ_09: CALL REGS_TO_RM
|
|---|
| 1465 | POP RM_BX
|
|---|
| 1466 | D_READ_10: MOV AX, WORD PTR I_EAX
|
|---|
| 1467 | MOV N_AX, AX
|
|---|
| 1468 | MOV EAX, I_ECX
|
|---|
| 1469 | MOV NREQ, EAX
|
|---|
| 1470 | PUSH EAX ; Save caller's ECX
|
|---|
| 1471 | MOV EAX, I_EDX
|
|---|
| 1472 | MOV NPTR, EAX
|
|---|
| 1473 | PUSH EAX ; Save caller's EDX
|
|---|
| 1474 | MOV I_EAX, 0 ; 0 bytes read
|
|---|
| 1475 | D_READ1: MOV EAX, NREQ
|
|---|
| 1476 | CMP EAX, 0FFFFH - OFFSET_1
|
|---|
| 1477 | JBE SHORT D_READ2
|
|---|
| 1478 | MOV AX, 0FE00H ; 64K - 512
|
|---|
| 1479 | D_READ2: MOV RM_CX, AX
|
|---|
| 1480 | MOV RM_DX, OFFSET_1 ; Offset of buffer
|
|---|
| 1481 | MOV AX, N_AX
|
|---|
| 1482 | MOV RM_AX, AX
|
|---|
| 1483 | CALL INT_RM ; Call DOS
|
|---|
| 1484 | TEST RM_FLAGS, FLAG_C ; Error?
|
|---|
| 1485 | JNZ SHORT D_READ_ERR
|
|---|
| 1486 | MOVZX ECX, RM_AX ; Get number of bytes read
|
|---|
| 1487 | JECXZ D_READ3 ; EOF -> done
|
|---|
| 1488 | MOV AX, I_DS ; AX:EDI = destination
|
|---|
| 1489 | MOV EDI, NPTR
|
|---|
| 1490 | CALL MOVE_FROM_RM ; Copy from real-mode buffer
|
|---|
| 1491 | ADD I_EAX, ECX ; Adjust return value (EAX)
|
|---|
| 1492 | CMP CX, RM_CX ; All bytes of this chunk read?
|
|---|
| 1493 | JNE SHORT D_READ3 ; No -> done
|
|---|
| 1494 | ADD NPTR, ECX ; Move pointer
|
|---|
| 1495 | SUB NREQ, ECX ; Decrement byte count
|
|---|
| 1496 | JNZ SHORT D_READ1 ; Not done -> repeat
|
|---|
| 1497 | D_READ3: JMP SHORT D_READ_END
|
|---|
| 1498 |
|
|---|
| 1499 | D_READ_ERR: MOVZX EAX, RM_AX ; Copy error code
|
|---|
| 1500 | MOV I_EAX, EAX
|
|---|
| 1501 | D_READ_END: MOV AL, RM_FLAGS ; Copy flags
|
|---|
| 1502 | MOV BYTE PTR I_EFLAGS[0], AL
|
|---|
| 1503 | POP I_EDX ; Restore caller's EDX
|
|---|
| 1504 | POP I_ECX ; Restore caller's ECX
|
|---|
| 1505 | JMP DOSCALL_RET ; Done
|
|---|
| 1506 |
|
|---|
| 1507 |
|
|---|
| 1508 | ;
|
|---|
| 1509 | ; Convert input/output:
|
|---|
| 1510 | ;
|
|---|
| 1511 | ; EDX -> CX:DX
|
|---|
| 1512 | ; Call DOS
|
|---|
| 1513 | ; DX:AX -> EAX
|
|---|
| 1514 | ;
|
|---|
| 1515 | TALIGN 4
|
|---|
| 1516 | D_SEEK: MOV EAX, I_EDX ; Get EDX
|
|---|
| 1517 | MOV RM_DX, AX ; Store lower word
|
|---|
| 1518 | SHR EAX, 16 ; Get upper word
|
|---|
| 1519 | MOV RM_CX, AX ; Store upper word
|
|---|
| 1520 | CALL INT_RM ; Call DOS
|
|---|
| 1521 | XOR EAX, EAX ; Clear upper word of EAX
|
|---|
| 1522 | TEST RM_FLAGS, FLAG_C ; Error?
|
|---|
| 1523 | JNZ SHORT D_SEEK_1 ; Yes -> no conversion
|
|---|
| 1524 | MOV AX, RM_DX ; Get DX
|
|---|
| 1525 | SHL EAX, 16 ; and put it into upper word
|
|---|
| 1526 | D_SEEK_1: MOV AX, RM_AX ; Put AX into lower word
|
|---|
| 1527 | MOV I_EAX, EAX ; of EAX
|
|---|
| 1528 | MOV AL, RM_FLAGS ; Copy flags
|
|---|
| 1529 | MOV BYTE PTR I_EFLAGS[0], AL
|
|---|
| 1530 | JMP DOSCALL_RET ; Done
|
|---|
| 1531 |
|
|---|
| 1532 | ;
|
|---|
| 1533 | ; Close a file handle
|
|---|
| 1534 | ;
|
|---|
| 1535 | ; Note: When called from user code no translation of error codes
|
|---|
| 1536 | ; is done because DO_CLOSE already returns errno value.
|
|---|
| 1537 | ; DO_CLOSE in turn may invoke this code via INT 21H. In that
|
|---|
| 1538 | ; case (called from the kernel), error translation is performed,
|
|---|
| 1539 | ; but the handle is not translated.
|
|---|
| 1540 | ;
|
|---|
| 1541 | TALIGN 4
|
|---|
| 1542 | D_CLOSE: MOV BX, PROCESS_PTR
|
|---|
| 1543 | CMP BX, NO_PROCESS ; Called from user process?
|
|---|
| 1544 | JE D_NULL ; No -> no translation
|
|---|
| 1545 | MOV AX, RM_BX ; This is the handle
|
|---|
| 1546 | CALL DO_CLOSE ; Close the handle
|
|---|
| 1547 | JNC SHORT D_CLOSE_FIN ; No error -> done
|
|---|
| 1548 | D_CLOSE_ERROR: MOV WORD PTR I_EAX+0, AX ; Return errno in EAX
|
|---|
| 1549 | MOV WORD PTR I_EAX+2, 0
|
|---|
| 1550 | OR BYTE PTR I_EFLAGS, FLAG_C ; Set carry flag
|
|---|
| 1551 | D_CLOSE_FIN: JMP PMINT_RET ; Don't translate error code!
|
|---|
| 1552 |
|
|---|
| 1553 | ;
|
|---|
| 1554 | ; Exit
|
|---|
| 1555 | ;
|
|---|
| 1556 | TALIGN 4
|
|---|
| 1557 | D_EXIT: TEST I_CS, 3 ; Called from user program?
|
|---|
| 1558 | JZ SHORT D_EXIT_QUIT ; No -> exit to DOS
|
|---|
| 1559 | MOV SI, PROCESS_PTR ; Current process
|
|---|
| 1560 | CMP SI, NO_PROCESS ; No current process?
|
|---|
| 1561 | JE SHORT D_EXIT_QUIT ; Yes -> impossible (go DOS)
|
|---|
| 1562 | ASSUME SI:PTR PROCESS
|
|---|
| 1563 | ;
|
|---|
| 1564 | ; ...to do: process 0 becomes parent process of all children
|
|---|
| 1565 | ;
|
|---|
| 1566 | MOV AL, BYTE PTR I_EAX ; Get return code
|
|---|
| 1567 | MOV [SI].P_RC, AL ; Store it
|
|---|
| 1568 | MOV EAX, [SI].P_PPID ; Get parent process ID
|
|---|
| 1569 | TEST EAX, EAX ; Root process?
|
|---|
| 1570 | JZ SHORT D_EXIT_QUIT ; Yes -> return to DOS
|
|---|
| 1571 | CALL FIND_PROCESS ; Find parent process
|
|---|
| 1572 | CMP BX, NO_PROCESS ; Does parent process exist?
|
|---|
| 1573 | JZ SHORT D_EXIT_QUIT ; No -> cannot happen, quit
|
|---|
| 1574 | ASSUME BX:PTR PROCESS
|
|---|
| 1575 | MOV PROCESS_PTR, BX ; Switch to parent process
|
|---|
| 1576 | MOV PROCESS_SIG, BX
|
|---|
| 1577 | MOV EAX, I_EAX ; Get return code
|
|---|
| 1578 | AND EAX, 0FFH ; Use only lower 8 bits
|
|---|
| 1579 | TEST [BX].P_FLAGS, PF_PSEUDO_ASYNC ; Pseudo async?
|
|---|
| 1580 | JNZ SHORT D_EXIT_PSEUDO ; Yes -> don't overwrite PID
|
|---|
| 1581 | MOV [BX].P_SPAWN_RC, EAX ; Store the return code
|
|---|
| 1582 | JMP SHORT D_EXIT_RESTORE ; Continue
|
|---|
| 1583 | D_EXIT_PSEUDO: MOV [BX].P_RC, AL ; Store the return code
|
|---|
| 1584 | D_EXIT_RESTORE: CALL REST_PROCESS ; Restore parent process
|
|---|
| 1585 | MOV BX, SI ; The dying process
|
|---|
| 1586 | PUSH [BX].P_NUMBER ; Save for FPUEMU_ENDPROC
|
|---|
| 1587 | TEST [BX].P_FLAGS, PF_DEBUG ; In debugging mode?
|
|---|
| 1588 | JZ SHORT D_EXIT_1 ; No -> kill process
|
|---|
| 1589 | CALL ZOMBIE_PROCESS ; Make process defunct
|
|---|
| 1590 | JMP SHORT D_EXIT_2
|
|---|
| 1591 | D_EXIT_1: CALL REMOVE_PROCESS ; Thoroughly kill process
|
|---|
| 1592 | D_EXIT_2: CALL BREAK_AFTER_IRET ; Allow debugging
|
|---|
| 1593 | POP EAX ; P_NUMBER of the dead process
|
|---|
| 1594 | CALL FPUEMU_ENDPROC ; Notify FPU emulator
|
|---|
| 1595 | JMP DOSCALL_RET ; Continue with parent
|
|---|
| 1596 | ASSUME BX:NOTHING
|
|---|
| 1597 | ASSUME SI:NOTHING
|
|---|
| 1598 | ;
|
|---|
| 1599 | ; Exit to DOS
|
|---|
| 1600 | ;
|
|---|
| 1601 | D_EXIT_QUIT: CMP FP_FLAG, FP_387 ; 387 available?
|
|---|
| 1602 | JNE SHORT EQUIT1 ; No -> skip
|
|---|
| 1603 | FNINIT ; Initialize
|
|---|
| 1604 | EQUIT1: CALL DEBUG_QUIT ; Swapper statistics
|
|---|
| 1605 | XOR EAX, EAX
|
|---|
| 1606 | MOV DR7, EAX ; Avoid unexpected behaviour
|
|---|
| 1607 | JMP SHORT D_NULL
|
|---|
| 1608 |
|
|---|
| 1609 | ;
|
|---|
| 1610 | ; No conversion
|
|---|
| 1611 | ;
|
|---|
| 1612 | TALIGN 4
|
|---|
| 1613 | D_NULL: CALL INT_RM ; Call DOS
|
|---|
| 1614 | CALL REGS_FROM_RM ; Copy all general registers
|
|---|
| 1615 | JMP DOSCALL_RET ; Done
|
|---|
| 1616 |
|
|---|
| 1617 | ;
|
|---|
| 1618 | ; Just check for supervisor code
|
|---|
| 1619 | ;
|
|---|
| 1620 | TALIGN 4
|
|---|
| 1621 | D_RETCODE: TEST I_CS, 3 ; Called from supervisor?
|
|---|
| 1622 | JNZ D_INVALID ; No -> bad function code
|
|---|
| 1623 | JMP SHORT D_NULL ; No conversion
|
|---|
| 1624 |
|
|---|
| 1625 | ;
|
|---|
| 1626 | ; Load and execute (a DOS) program
|
|---|
| 1627 | ;
|
|---|
| 1628 | TALIGN 4
|
|---|
| 1629 | D_EXEC: TEST I_CS, 3 ; Called from supervisor?
|
|---|
| 1630 | JNZ D_INVALID ; No -> bad function code
|
|---|
| 1631 | MOV AX, SV_DATA ; Load real-mode segment
|
|---|
| 1632 | MOV RM_DS, AX ; registers
|
|---|
| 1633 | MOV RM_ES, AX
|
|---|
| 1634 | CALL INT_RM
|
|---|
| 1635 | MOV AX, RM_AX
|
|---|
| 1636 | MOV WORD PTR I_EAX, AX
|
|---|
| 1637 | MOV AL, RM_FLAGS
|
|---|
| 1638 | MOV BYTE PTR I_EFLAGS[0], AL
|
|---|
| 1639 | JMP DOSCALL_RET
|
|---|
| 1640 |
|
|---|
| 1641 | ;
|
|---|
| 1642 | ; Convert input:
|
|---|
| 1643 | ;
|
|---|
| 1644 | ; EBP points to null-terminated string (-> ES:BP)
|
|---|
| 1645 | ;
|
|---|
| 1646 | TALIGN 4
|
|---|
| 1647 | D_STR_BP: MOV AL, 0 ; Look for 0
|
|---|
| 1648 | MOV AH, FALSE ; Not a path name
|
|---|
| 1649 | XOR EBX, EBX ; Don't add
|
|---|
| 1650 | MOV ESI, I_EBP
|
|---|
| 1651 | MOV EDI, OFFSET_1
|
|---|
| 1652 | MOV RM_BP, DI ; Offset of buffer
|
|---|
| 1653 | CALL I_DELIM
|
|---|
| 1654 | PUSH I_EBP ; Save EBP (of caller)
|
|---|
| 1655 | CALL INT_RM ; Call interrupt
|
|---|
| 1656 | CALL REGS_FROM_RM ; Retrieve real-mode registers
|
|---|
| 1657 | POP I_EBP ; Restore EBP (of caller)
|
|---|
| 1658 | JMP DOSCALL_RET ; Done
|
|---|
| 1659 |
|
|---|
| 1660 |
|
|---|
| 1661 | ;
|
|---|
| 1662 | ; Convert output of VESA function 0.
|
|---|
| 1663 | ;
|
|---|
| 1664 | ; EDI (-> ES:DI) points to a 256-byte buffer on entry which is filled-in
|
|---|
| 1665 | ; by the function. There are two pointers to secondary buffers in the
|
|---|
| 1666 | ; buffer. We have to copy the data pointed to by these pointers into
|
|---|
| 1667 | ; the process' address space.
|
|---|
| 1668 | ;
|
|---|
| 1669 | TALIGN 4
|
|---|
| 1670 | D_VESAINFO: MOV RM_DI, OFFSET_1 ; Offset of buffer
|
|---|
| 1671 | PUSH I_EDI ; Save EDI (of caller)
|
|---|
| 1672 | CALL INT_RM ; Call interrupt
|
|---|
| 1673 | CALL REGS_FROM_RM ; Retrieve real-mode registers
|
|---|
| 1674 | POP I_EDI ; Restore EDI (of caller)
|
|---|
| 1675 | ;
|
|---|
| 1676 | ; Copy 256-byte buffer
|
|---|
| 1677 | ;
|
|---|
| 1678 | MOV AX, I_DS ; AX:EDI = destination
|
|---|
| 1679 | MOV EDI, I_EDI
|
|---|
| 1680 | MOV ECX, 256
|
|---|
| 1681 | CALL MOVE_FROM_RM ; Copy from real-mode buffer
|
|---|
| 1682 | CMP RM_AX, 004FH ; Successful?
|
|---|
| 1683 | JNE DOSCALL_RET ; No -> don't convert pointers
|
|---|
| 1684 | ;
|
|---|
| 1685 | ; Allocate a page in the process address space for the secondary buffers
|
|---|
| 1686 | ;
|
|---|
| 1687 | MOV DI, PROCESS_PTR
|
|---|
| 1688 | ASSUME DI:PTR PROCESS
|
|---|
| 1689 | MOV EAX, [DI].P_VESAINFO_PTR
|
|---|
| 1690 | TEST EAX, EAX
|
|---|
| 1691 | JNZ SHORT DVI_REUSE
|
|---|
| 1692 | MOV ECX, 1
|
|---|
| 1693 | CALL ADD_PAGES
|
|---|
| 1694 | TEST EAX, EAX
|
|---|
| 1695 | JZ SHORT DVI_FAIL
|
|---|
| 1696 | MOV [DI].P_VESAINFO_PTR, EAX
|
|---|
| 1697 | DVI_REUSE: MOV EDI, EAX
|
|---|
| 1698 | ;
|
|---|
| 1699 | ; Copy the OEM name
|
|---|
| 1700 | ;
|
|---|
| 1701 | MOV ES, I_DS
|
|---|
| 1702 | MOV ESI, I_EDI
|
|---|
| 1703 | XCHG EAX, ES:[ESI+06H] ; Pointer to OEM name
|
|---|
| 1704 | CALL ACCESS_LOWMEM
|
|---|
| 1705 | MOV AX, G_LOWMEM_SEL
|
|---|
| 1706 | MOV FS, AX
|
|---|
| 1707 | MOV ECX, 128 ; Maximum string length
|
|---|
| 1708 | DVI_OEM_1: MOV AL, FS:[EBX]
|
|---|
| 1709 | TEST AL, AL
|
|---|
| 1710 | JZ SHORT DVI_OEM_2
|
|---|
| 1711 | INC EBX
|
|---|
| 1712 | STOS BYTE PTR ES:[EDI]
|
|---|
| 1713 | LOOP DVI_OEM_1
|
|---|
| 1714 | DVI_OEM_2: XOR AL, AL
|
|---|
| 1715 | STOS BYTE PTR ES:[EDI]
|
|---|
| 1716 | ;
|
|---|
| 1717 | ; Copy the mode list
|
|---|
| 1718 | ;
|
|---|
| 1719 | INC EDI ; Make the address even
|
|---|
| 1720 | AND EDI, NOT 1
|
|---|
| 1721 | MOV EAX, EDI
|
|---|
| 1722 | XCHG EAX, ES:[ESI+0EH] ; Pointer to video modes
|
|---|
| 1723 | CALL ACCESS_LOWMEM
|
|---|
| 1724 | MOV ECX, (4096 - 128) / 2 - 1
|
|---|
| 1725 | DVI_MODES_1: MOV AX, FS:[EBX]
|
|---|
| 1726 | CMP AX, 0FFFFH
|
|---|
| 1727 | JE SHORT DVI_MODES_2
|
|---|
| 1728 | ADD EBX, 2
|
|---|
| 1729 | STOS WORD PTR ES:[EDI]
|
|---|
| 1730 | LOOP DVI_MODES_1
|
|---|
| 1731 | DVI_MODES_2: MOV AX, 0FFFFH
|
|---|
| 1732 | STOS WORD PTR ES:[EDI]
|
|---|
| 1733 | JMP DOSCALL_RET ; Done
|
|---|
| 1734 |
|
|---|
| 1735 | ;
|
|---|
| 1736 | ; Function call failed, invalidate the two pointers.
|
|---|
| 1737 | ;
|
|---|
| 1738 | DVI_FAIL: MOV ES, I_DS
|
|---|
| 1739 | MOV ESI, I_EDI
|
|---|
| 1740 | MOV DWORD PTR ES:[ESI+06H], 0
|
|---|
| 1741 | MOV DWORD PTR ES:[ESI+0EH], 0
|
|---|
| 1742 | JMP DOSCALL_RET
|
|---|
| 1743 |
|
|---|
| 1744 | ASSUME DI:NOTHING
|
|---|
| 1745 |
|
|---|
| 1746 | ;
|
|---|
| 1747 | ; Convert output of VESA function 1.
|
|---|
| 1748 | ;
|
|---|
| 1749 | ; EDI (-> ES:DI) points to a 256-byte buffer on entry which is filled-in
|
|---|
| 1750 | ; by the function. There's one pointer in the buffer which points to
|
|---|
| 1751 | ; a function. Set that pointer to NULL.
|
|---|
| 1752 | ;
|
|---|
| 1753 | TALIGN 4
|
|---|
| 1754 | D_VESAMODE: MOV RM_DI, OFFSET_1 ; Offset of buffer
|
|---|
| 1755 | PUSH I_EDI ; Save EDI (of caller)
|
|---|
| 1756 | CALL INT_RM ; Call interrupt
|
|---|
| 1757 | CALL REGS_FROM_RM ; Retrieve real-mode registers
|
|---|
| 1758 | POP I_EDI ; Restore EDI (of caller)
|
|---|
| 1759 | ;
|
|---|
| 1760 | ; Copy 256-byte buffer
|
|---|
| 1761 | ;
|
|---|
| 1762 | MOV AX, I_DS ; AX:EDI = destination
|
|---|
| 1763 | MOV EDI, I_EDI
|
|---|
| 1764 | MOV ECX, 256
|
|---|
| 1765 | CALL MOVE_FROM_RM ; Copy from real-mode buffer
|
|---|
| 1766 | MOV ES, I_DS
|
|---|
| 1767 | MOV ESI, I_EDI
|
|---|
| 1768 | ;
|
|---|
| 1769 | ; Invalidate pointer to window positioning function (same as AX=4F05H)
|
|---|
| 1770 | ;
|
|---|
| 1771 | MOV DWORD PTR ES:[ESI+0CH], 0
|
|---|
| 1772 | JMP DOSCALL_RET ; Done
|
|---|
| 1773 |
|
|---|
| 1774 | ;
|
|---|
| 1775 | ; Convert input
|
|---|
| 1776 | ;
|
|---|
| 1777 | ; EDX points 64-byte buffer (-> ES:DX)
|
|---|
| 1778 | ;
|
|---|
| 1779 | TALIGN 4
|
|---|
| 1780 | D_MOU_GCURSOR: MOV AX, I_DS
|
|---|
| 1781 | MOV ESI, I_EDX
|
|---|
| 1782 | PUSH ESI ; Save EDX (of caller)
|
|---|
| 1783 | MOV ES, AX ; Source: AX:ESI
|
|---|
| 1784 | MOV ECX, 64 ; Copy 2*16 16-bit words
|
|---|
| 1785 | MOV EDI, OFFSET_1 ; to real-mode buffer
|
|---|
| 1786 | MOV RM_DX, DI ; Offset of buffer
|
|---|
| 1787 | CALL MOVE_TO_RM
|
|---|
| 1788 | CALL INT_RM
|
|---|
| 1789 | POP I_EDX ; Restore EDX (of caller)
|
|---|
| 1790 | JMP DOSCALL_RET
|
|---|
| 1791 |
|
|---|
| 1792 | ;
|
|---|
| 1793 | ; Convert input
|
|---|
| 1794 | ;
|
|---|
| 1795 | ; EDX points to a buffer (-> ES:DX). The size of the buffer is
|
|---|
| 1796 | ; BH * CH * 4 bytes.
|
|---|
| 1797 | ;
|
|---|
| 1798 | TALIGN 4
|
|---|
| 1799 | D_MOU_LGCURSOR: MOV AL, BYTE PTR RM_BX[1] ; BH
|
|---|
| 1800 | MUL BYTE PTR RM_CX[1] ; CH
|
|---|
| 1801 | MOVZX ECX, AX ; ECX = BH * CH
|
|---|
| 1802 | SHL ECX, 2 ; Multiply by 4
|
|---|
| 1803 | MOV AX, I_DS
|
|---|
| 1804 | MOV ESI, I_EDX
|
|---|
| 1805 | PUSH ESI ; Save EDX (of caller)
|
|---|
| 1806 | MOV ES, AX ; Source: AX:ESI
|
|---|
| 1807 | MOV EDI, OFFSET_1 ; to real-mode buffer
|
|---|
| 1808 | MOV RM_DX, DI ; Offset of buffer
|
|---|
| 1809 | CALL MOVE_TO_RM
|
|---|
| 1810 | CALL INT_RM
|
|---|
| 1811 | POP I_EDX ; Restore EDX (of caller)
|
|---|
| 1812 | JMP DOSCALL_RET
|
|---|
| 1813 |
|
|---|
| 1814 | ;
|
|---|
| 1815 | ; Convert output:
|
|---|
| 1816 | ;
|
|---|
| 1817 | ; DS:EDX (input) points to buffer, length: 34 bytes
|
|---|
| 1818 | ;
|
|---|
| 1819 | TALIGN 4
|
|---|
| 1820 | D_COUNTRY: CMP RM_DX, 0FFFFH
|
|---|
| 1821 | JE SHORT D_COUNTRY_SET
|
|---|
| 1822 | MOV RM_DX, OFFSET_1
|
|---|
| 1823 | CALL INT_RM
|
|---|
| 1824 | MOV AX, I_DS
|
|---|
| 1825 | MOV EDI, I_EDX
|
|---|
| 1826 | MOV ECX, 34
|
|---|
| 1827 | CALL MOVE_FROM_RM
|
|---|
| 1828 | D_COUNTRY_1: CALL REGS_FROM_RM
|
|---|
| 1829 | JMP DOSCALL_RET
|
|---|
| 1830 |
|
|---|
| 1831 | D_COUNTRY_SET: CALL INT_RM
|
|---|
| 1832 | JMP D_COUNTRY_1
|
|---|
| 1833 |
|
|---|
| 1834 | ;
|
|---|
| 1835 | ; Convert input:
|
|---|
| 1836 | ;
|
|---|
| 1837 | ; EDX -> CX:DX
|
|---|
| 1838 | ; EDI -> SI:DI
|
|---|
| 1839 | ;
|
|---|
| 1840 | TALIGN 4
|
|---|
| 1841 | D_LOCK: MOV EAX, I_EDX
|
|---|
| 1842 | PUSH EAX
|
|---|
| 1843 | MOV RM_DX, AX
|
|---|
| 1844 | SHR EAX, 16
|
|---|
| 1845 | MOV RM_CX, AX
|
|---|
| 1846 | MOV EAX, I_EDI
|
|---|
| 1847 | PUSH EAX
|
|---|
| 1848 | MOV RM_DI, AX
|
|---|
| 1849 | SHR EAX, 16
|
|---|
| 1850 | MOV RM_SI, AX
|
|---|
| 1851 | CALL INT_RM
|
|---|
| 1852 | CALL REGS_FROM_RM
|
|---|
| 1853 | POP I_EDI
|
|---|
| 1854 | POP I_EDX
|
|---|
| 1855 | JMP DOSCALL_RET
|
|---|
| 1856 |
|
|---|
| 1857 | ;
|
|---|
| 1858 | ; Convert input: ASCIZ ESI -> DS:SI, EDI -> ES:DI
|
|---|
| 1859 | ; Convert output: ASCIZ EDI
|
|---|
| 1860 | ;
|
|---|
| 1861 | TALIGN 4
|
|---|
| 1862 | D_TRUENAME: MOV AL, 0 ; Look for 0
|
|---|
| 1863 | MOV AH, NOT FALSE ; It's a path name
|
|---|
| 1864 | XOR EBX, EBX ; Don't add
|
|---|
| 1865 | MOV ESI, I_ESI
|
|---|
| 1866 | MOV EDI, OFFSET_2
|
|---|
| 1867 | MOV RM_SI, DI ; Offset of buffer
|
|---|
| 1868 | CALL I_DELIM
|
|---|
| 1869 | MOV RM_DI, OFFSET_1
|
|---|
| 1870 | PUSH I_ESI ; Save EDI and ESI (of caller)
|
|---|
| 1871 | PUSH I_EDI
|
|---|
| 1872 | CALL INT_RM
|
|---|
| 1873 | CALL REGS_FROM_RM
|
|---|
| 1874 | POP I_EDI
|
|---|
| 1875 | POP I_ESI
|
|---|
| 1876 | TEST I_EFLAGS, FLAG_C ; Error?
|
|---|
| 1877 | JNZ SHORT D_TRUENAME_1 ; Yes -> skip
|
|---|
| 1878 | MOV AX, I_ES
|
|---|
| 1879 | MOV EDI, I_EDI
|
|---|
| 1880 | CALL MOVEZ_FROM_RM ; Copies from OFFSET_1
|
|---|
| 1881 | D_TRUENAME_1: JMP DOSCALL_RET
|
|---|
| 1882 |
|
|---|
| 1883 |
|
|---|
| 1884 | ;
|
|---|
| 1885 | ; Return from DOS call
|
|---|
| 1886 | ;
|
|---|
| 1887 | TALIGN 4
|
|---|
| 1888 | DOSCALL_RET: MOV AX, INP_HANDLE
|
|---|
| 1889 | CMP AX, NO_FILE_HANDLE ; Input handle converted?
|
|---|
| 1890 | JE SHORT DOSCALL_RET1 ; No -> skip
|
|---|
| 1891 | MOV WORD PTR I_EBX, AX ; Store to (E)BX
|
|---|
| 1892 | DOSCALL_RET1: TEST CONV_FLAG, DFH_OUT ; New handle?
|
|---|
| 1893 | JZ SHORT DOSCALL_RET2
|
|---|
| 1894 | CMP PROCESS_PTR, NO_PROCESS ; Called from user process?
|
|---|
| 1895 | JE SHORT DOSCALL_RET2 ; No -> skip
|
|---|
| 1896 | TEST I_EFLAGS, FLAG_C ; Error?
|
|---|
| 1897 | JNZ SHORT DOSCALL_RET2 ; Yes -> skip
|
|---|
| 1898 | MOV AX, WORD PTR I_EAX ; Get DOS handle
|
|---|
| 1899 | CALL NEW_HANDLE ; New slot
|
|---|
| 1900 | MOV I_EAX, EAX ; Return translated handle
|
|---|
| 1901 | DOSCALL_RET2: TEST CONV_FLAG, DFE ; Convert error code?
|
|---|
| 1902 | JZ SHORT DOSCALL_RET3 ; No -> skip
|
|---|
| 1903 | TEST I_EFLAGS, FLAG_C ; Error?
|
|---|
| 1904 | JZ SHORT DOSCALL_RET3 ; No -> skip
|
|---|
| 1905 | MOV AX, WORD PTR I_EAX ; Get error code
|
|---|
| 1906 | CALL DOS_ERROR_TO_ERRNO ; Translate error code
|
|---|
| 1907 | MOV I_EAX, EAX ; Put errno into EAX
|
|---|
| 1908 | DOSCALL_RET3: JMP PMINT_RET
|
|---|
| 1909 |
|
|---|
| 1910 | ASSUME BP:NOTHING
|
|---|
| 1911 |
|
|---|
| 1912 | ;
|
|---|
| 1913 | ; In: EBX Number of bytes to move beyond terminator
|
|---|
| 1914 | ; AL Terminator
|
|---|
| 1915 | ; AH Path name flag
|
|---|
| 1916 | ;
|
|---|
| 1917 | ; Out: ECX Buffer size
|
|---|
| 1918 | ;
|
|---|
| 1919 | ASSUME DS:SV_DATA
|
|---|
| 1920 | ASSUME BP:PTR ISTACKFRAME
|
|---|
| 1921 | G_DELIM PROC NEAR
|
|---|
| 1922 | MOV ESI, I_EDX
|
|---|
| 1923 | MOV EDI, OFFSET_1
|
|---|
| 1924 | MOV RM_DX, DI ; Offset of buffer
|
|---|
| 1925 | CALL I_DELIM
|
|---|
| 1926 | PUSH ECX ; Save ECX (buffer size)
|
|---|
| 1927 | PUSH I_EDX ; Save EDX (argument)
|
|---|
| 1928 | CALL INT_RM ; Call DOS
|
|---|
| 1929 | CALL REGS_FROM_RM ; Retrieve real-mode registers
|
|---|
| 1930 | POP I_EDX ; Restore EDX (of caller)
|
|---|
| 1931 | POP ECX ; Restore ECX (buffer size)
|
|---|
| 1932 | RET
|
|---|
| 1933 | ASSUME BP:NOTHING
|
|---|
| 1934 | G_DELIM ENDP
|
|---|
| 1935 |
|
|---|
| 1936 |
|
|---|
| 1937 | ;
|
|---|
| 1938 | ; In: ESI Pointer to argument
|
|---|
| 1939 | ; EDI Offset in buffer
|
|---|
| 1940 | ; EBX Number of bytes to move beyond terminator
|
|---|
| 1941 | ; AL Terminator
|
|---|
| 1942 | ; AH Path name flag (for truncation). Non-zero if path name
|
|---|
| 1943 | ;
|
|---|
| 1944 | ASSUME DS:SV_DATA
|
|---|
| 1945 | ASSUME BP:PTR ISTACKFRAME
|
|---|
| 1946 | I_DELIM PROC NEAR
|
|---|
| 1947 | PUSH AX ; Save terminator and flag
|
|---|
| 1948 | PUSH EDI ; Save offset
|
|---|
| 1949 | MOV ES, I_DS ; ES:EDI points to argument
|
|---|
| 1950 | MOV ECX, 0FFFFH
|
|---|
| 1951 | SUB ECX, EDI ; Maximum length
|
|---|
| 1952 | MOV EDI, ESI
|
|---|
| 1953 | CLD ; Incrementing
|
|---|
| 1954 | REPNE SCAS BYTE PTR ES:[EDI] ; Look for terminator
|
|---|
| 1955 | JECXZ IDELIM_2 ; Not found -> abort
|
|---|
| 1956 | MOV ECX, EDI
|
|---|
| 1957 | SUB ECX, ESI ; Length of string
|
|---|
| 1958 | ADD ECX, EBX ; Add
|
|---|
| 1959 | MOV AX, I_DS ; AX:ESI = source
|
|---|
| 1960 | POP EDI ; Offset
|
|---|
| 1961 | CALL MOVE_TO_RM ; Copy to real-mode buffer
|
|---|
| 1962 | POP AX ; Terminator and flag
|
|---|
| 1963 | CMP AH, FALSE ; Path name?
|
|---|
| 1964 | JE SHORT IDELIM_1 ; No -> return
|
|---|
| 1965 | PUSH ES
|
|---|
| 1966 | MOV ES, BUF_SEL
|
|---|
| 1967 | CALL TRUNCATE
|
|---|
| 1968 | POP ES
|
|---|
| 1969 | IDELIM_1: RET
|
|---|
| 1970 |
|
|---|
| 1971 | IDELIM_2: POP EDI
|
|---|
| 1972 | POP AX
|
|---|
| 1973 | JMP DOSF_PARAM
|
|---|
| 1974 | ASSUME BP:NOTHING
|
|---|
| 1975 | I_DELIM ENDP
|
|---|
| 1976 |
|
|---|
| 1977 | ;
|
|---|
| 1978 | ; Set disk transfer address to OFFSET_1
|
|---|
| 1979 | ;
|
|---|
| 1980 | SET_DTA_1 PROC NEAR
|
|---|
| 1981 | PUSH RM_AX ; Save real-mode AX
|
|---|
| 1982 | PUSH RM_DX ; Save real-mode DX
|
|---|
| 1983 | MOV RM_AX, 1A00H ; Set disk transfer address
|
|---|
| 1984 | MOV RM_DX, OFFSET_1 ; to OFFSET_1
|
|---|
| 1985 | CALL INT_RM ; Call DOS
|
|---|
| 1986 | POP RM_DX ; Restore real-mode DX
|
|---|
| 1987 | POP RM_AX ; Restore real-mode AX
|
|---|
| 1988 | RET
|
|---|
| 1989 | SET_DTA_1 ENDP
|
|---|
| 1990 |
|
|---|
| 1991 |
|
|---|
| 1992 | ;
|
|---|
| 1993 | ; Copy protected-mode registers to real-mode registers
|
|---|
| 1994 | ;
|
|---|
| 1995 | ASSUME DS:SV_DATA
|
|---|
| 1996 | ASSUME BP:PTR ISTACKFRAME
|
|---|
| 1997 | TALIGN 4
|
|---|
| 1998 | REGS_TO_RM PROC NEAR
|
|---|
| 1999 | IRP R, <AX,BX,CX,DX,SI,DI,BP>
|
|---|
| 2000 | MOV AX, WORD PTR I_E&R ; Load general real-mode
|
|---|
| 2001 | MOV RM_&R, AX ; registers
|
|---|
| 2002 | ENDM
|
|---|
| 2003 | MOV AX, BUF_SEG ; Load real-mode segment
|
|---|
| 2004 | MOV RM_DS, AX ; registers
|
|---|
| 2005 | MOV RM_ES, AX
|
|---|
| 2006 | RET
|
|---|
| 2007 | ASSUME BP:NOTHING
|
|---|
| 2008 | REGS_TO_RM ENDP
|
|---|
| 2009 |
|
|---|
| 2010 | ;
|
|---|
| 2011 | ; Copy real-mode registers to protected-mode stack frame
|
|---|
| 2012 | ;
|
|---|
| 2013 | ASSUME DS:SV_DATA
|
|---|
| 2014 | ASSUME BP:PTR ISTACKFRAME
|
|---|
| 2015 | TALIGN 4
|
|---|
| 2016 | REGS_FROM_RM PROC NEAR
|
|---|
| 2017 | IRP R, <AX,BX,CX,DX,SI,DI,BP>
|
|---|
| 2018 | MOV AX, RM_&R
|
|---|
| 2019 | MOV WORD PTR I_E&R, AX
|
|---|
| 2020 | ENDM
|
|---|
| 2021 | MOV AL, RM_FLAGS
|
|---|
| 2022 | MOV BYTE PTR I_EFLAGS[0], AL
|
|---|
| 2023 | RET
|
|---|
| 2024 | ASSUME BP:NOTHING
|
|---|
| 2025 | REGS_FROM_RM ENDP
|
|---|
| 2026 |
|
|---|
| 2027 |
|
|---|
| 2028 |
|
|---|
| 2029 | ;
|
|---|
| 2030 | ; Copy buffer from protected mode to real mode
|
|---|
| 2031 | ;
|
|---|
| 2032 | ; In: AX:ESI Source (protected mode)
|
|---|
| 2033 | ; EDI OFFSET_1 or OFFSET_2
|
|---|
| 2034 | ; ECX Number of bytes
|
|---|
| 2035 | ;
|
|---|
| 2036 |
|
|---|
| 2037 | ASSUME DS:SV_DATA
|
|---|
| 2038 |
|
|---|
| 2039 | TALIGN 4
|
|---|
| 2040 | MOVE_TO_RM PROC NEAR PUBLIC
|
|---|
| 2041 | PUSH DS
|
|---|
| 2042 | PUSH ES
|
|---|
| 2043 | PUSH EAX
|
|---|
| 2044 | PUSH ECX
|
|---|
| 2045 | PUSH EDX
|
|---|
| 2046 | PUSH ESI
|
|---|
| 2047 | PUSH EDI
|
|---|
| 2048 | MOV ES, BUF_SEL
|
|---|
| 2049 | MOV DS, AX
|
|---|
| 2050 | ASSUME DS:NOTHING
|
|---|
| 2051 | CLD
|
|---|
| 2052 | MOV EAX, ECX
|
|---|
| 2053 | SHR ECX, 2
|
|---|
| 2054 | REP MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI]
|
|---|
| 2055 | MOV ECX, EAX
|
|---|
| 2056 | AND ECX, 3
|
|---|
| 2057 | REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]
|
|---|
| 2058 | POP EDI
|
|---|
| 2059 | POP ESI
|
|---|
| 2060 | POP EDX
|
|---|
| 2061 | POP ECX
|
|---|
| 2062 | POP EAX
|
|---|
| 2063 | POP ES
|
|---|
| 2064 | POP DS
|
|---|
| 2065 | RET
|
|---|
| 2066 | MOVE_TO_RM ENDP
|
|---|
| 2067 |
|
|---|
| 2068 |
|
|---|
| 2069 | ;
|
|---|
| 2070 | ; Copy buffer from real mode to protected mode
|
|---|
| 2071 | ;
|
|---|
| 2072 | ; In: AX:EDI Destination address
|
|---|
| 2073 | ; ECX Number of bytes
|
|---|
| 2074 | ;
|
|---|
| 2075 | ; Note: always uses OFFSET_1
|
|---|
| 2076 | ;
|
|---|
| 2077 |
|
|---|
| 2078 | ASSUME DS:SV_DATA
|
|---|
| 2079 |
|
|---|
| 2080 | MOVE_FROM_RM PROC NEAR PUBLIC
|
|---|
| 2081 | PUSH DS
|
|---|
| 2082 | PUSH ES
|
|---|
| 2083 | PUSH EAX
|
|---|
| 2084 | PUSH ECX
|
|---|
| 2085 | PUSH ESI
|
|---|
| 2086 | PUSH EDI
|
|---|
| 2087 | MOV ES, AX
|
|---|
| 2088 | MOV ESI, OFFSET_1
|
|---|
| 2089 | MOV DS, BUF_SEL
|
|---|
| 2090 | ASSUME DS:NOTHING
|
|---|
| 2091 | CLD
|
|---|
| 2092 | MOV EAX, ECX
|
|---|
| 2093 | SHR ECX, 2
|
|---|
| 2094 | REP MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI]
|
|---|
| 2095 | MOV ECX, EAX
|
|---|
| 2096 | AND ECX, 3
|
|---|
| 2097 | REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]
|
|---|
| 2098 | POP EDI
|
|---|
| 2099 | POP ESI
|
|---|
| 2100 | POP ECX
|
|---|
| 2101 | POP EAX
|
|---|
| 2102 | POP ES
|
|---|
| 2103 | POP DS
|
|---|
| 2104 | RET
|
|---|
| 2105 | MOVE_FROM_RM ENDP
|
|---|
| 2106 |
|
|---|
| 2107 |
|
|---|
| 2108 | ;
|
|---|
| 2109 | ; Copy zero-terminated buffer from real mode to protected mode
|
|---|
| 2110 | ;
|
|---|
| 2111 | ; In: AX:EDI Destination address
|
|---|
| 2112 | ;
|
|---|
| 2113 | ; Note: always uses OFFSET_1
|
|---|
| 2114 | ;
|
|---|
| 2115 |
|
|---|
| 2116 | ASSUME DS:SV_DATA
|
|---|
| 2117 |
|
|---|
| 2118 | MOVEZ_FROM_RM PROC NEAR
|
|---|
| 2119 | PUSH DS
|
|---|
| 2120 | PUSH ES
|
|---|
| 2121 | PUSH EAX
|
|---|
| 2122 | PUSH ESI
|
|---|
| 2123 | PUSH EDI
|
|---|
| 2124 | MOV ES, AX
|
|---|
| 2125 | MOV ESI, OFFSET_1
|
|---|
| 2126 | MOV DS, BUF_SEL
|
|---|
| 2127 | ASSUME DS:NOTHING
|
|---|
| 2128 | CLD
|
|---|
| 2129 | TALIGN 4
|
|---|
| 2130 | MZFRM1: LODS BYTE PTR DS:[ESI]
|
|---|
| 2131 | STOS BYTE PTR ES:[EDI]
|
|---|
| 2132 | TEST AL, AL
|
|---|
| 2133 | JNZ SHORT MZFRM1
|
|---|
| 2134 | POP EDI
|
|---|
| 2135 | POP ESI
|
|---|
| 2136 | POP EAX
|
|---|
| 2137 | POP ES
|
|---|
| 2138 | POP DS
|
|---|
| 2139 | RET
|
|---|
| 2140 | MOVEZ_FROM_RM ENDP
|
|---|
| 2141 |
|
|---|
| 2142 | ;
|
|---|
| 2143 | ; Set a breakpoint to the return address of the current interrupt/exception
|
|---|
| 2144 | ; frame (only if -S option is used)
|
|---|
| 2145 | ;
|
|---|
| 2146 | ASSUME DS:SV_DATA
|
|---|
| 2147 | ASSUME BP:PTR ISTACKFRAME
|
|---|
| 2148 | TALIGN 4
|
|---|
| 2149 | BREAK_AFTER_IRET PROC NEAR
|
|---|
| 2150 | CMP STEP_FLAG, FALSE
|
|---|
| 2151 | JE SHORT BAI_RET
|
|---|
| 2152 | MOV DX, I_CS
|
|---|
| 2153 | MOV EAX, I_EIP
|
|---|
| 2154 | CALL SET_BREAKPOINT
|
|---|
| 2155 | CALL INS_BREAKPOINTS
|
|---|
| 2156 | BAI_RET: RET
|
|---|
| 2157 | ASSUME BP:NOTHING
|
|---|
| 2158 | BREAK_AFTER_IRET ENDP
|
|---|
| 2159 |
|
|---|
| 2160 |
|
|---|
| 2161 | ;
|
|---|
| 2162 | ; Set the DBCS lead byte table. This function must be called from PMINT.
|
|---|
| 2163 | ;
|
|---|
| 2164 | ; Out: AX Zero if successful, non-zero on error
|
|---|
| 2165 | ;
|
|---|
| 2166 | ASSUME DS:SV_DATA
|
|---|
| 2167 | GET_DBCS_LEAD PROC NEAR
|
|---|
| 2168 | ;
|
|---|
| 2169 | ; First clear all bits in case we can't retrieve the DBCS lead bytes
|
|---|
| 2170 | ;
|
|---|
| 2171 | PUSH DS
|
|---|
| 2172 | POP ES
|
|---|
| 2173 | MOV DI, DBCS_LEAD_TAB
|
|---|
| 2174 | MOV CX, 256 / 8 / 2
|
|---|
| 2175 | MOV AX, 0
|
|---|
| 2176 | REP STOSW
|
|---|
| 2177 | ;
|
|---|
| 2178 | ; Call DOS to get the DBCS lead bytes
|
|---|
| 2179 | ;
|
|---|
| 2180 | MOV RM_AX, 6300H
|
|---|
| 2181 | MOV RM_DS, 0FFFEH
|
|---|
| 2182 | MOV RM_SI, 0FFFFH
|
|---|
| 2183 | CALL INT_RM
|
|---|
| 2184 | ;
|
|---|
| 2185 | ; Note that some DOS versions return AL=0 even if this function is
|
|---|
| 2186 | ; not supported. Do some sanity checking on DS:SI
|
|---|
| 2187 | ;
|
|---|
| 2188 | CMP BYTE PTR RM_AX[0], 0
|
|---|
| 2189 | JNE SHORT GDL_FAIL
|
|---|
| 2190 | CMP RM_SI, -12
|
|---|
| 2191 | JA SHORT GDL_FAIL
|
|---|
| 2192 | MOV AX, RM_DS
|
|---|
| 2193 | CMP AX, 0FFFEH
|
|---|
| 2194 | JE SHORT GDL_FAIL
|
|---|
| 2195 | SHL EAX, 16
|
|---|
| 2196 | MOV AX, RM_SI
|
|---|
| 2197 | CALL ACCESS_LOWMEM
|
|---|
| 2198 | MOV ESI, EBX
|
|---|
| 2199 | MOV AX, G_LOWMEM_SEL
|
|---|
| 2200 | MOV ES, AX
|
|---|
| 2201 | MOV CX, 6
|
|---|
| 2202 | GDL_CHECK1: MOV AX, ES:[EBX]
|
|---|
| 2203 | TEST AX, AX
|
|---|
| 2204 | JZ SHORT GDL_CHECK1_OK
|
|---|
| 2205 | CMP AL, 80H
|
|---|
| 2206 | JB SHORT GDL_FAIL
|
|---|
| 2207 | CMP AL, AH
|
|---|
| 2208 | JA SHORT GDL_FAIL
|
|---|
| 2209 | ADD EBX, 2
|
|---|
| 2210 | LOOP GDL_CHECK1
|
|---|
| 2211 | GDL_FAIL: MOV AX, 1
|
|---|
| 2212 | RET
|
|---|
| 2213 |
|
|---|
| 2214 | ;
|
|---|
| 2215 | ; The table looks OK; now set the bits
|
|---|
| 2216 | ;
|
|---|
| 2217 | GDL_CHECK1_OK: MOV CX, 0
|
|---|
| 2218 | GDL_LOOP1: MOV AX, ES:[ESI]
|
|---|
| 2219 | TEST AX, AX
|
|---|
| 2220 | JZ SHORT GDL_DONE
|
|---|
| 2221 | ADD ESI, 2
|
|---|
| 2222 | MOV CL, AL
|
|---|
| 2223 | GDL_LOOP2: BTS DBCS_LEAD_TAB, CX
|
|---|
| 2224 | CMP CL, AH
|
|---|
| 2225 | JAE SHORT GDL_LOOP1
|
|---|
| 2226 | INC CL
|
|---|
| 2227 | JMP SHORT GDL_LOOP2
|
|---|
| 2228 |
|
|---|
| 2229 | GDL_DONE: XOR AX, AX
|
|---|
| 2230 | RET
|
|---|
| 2231 |
|
|---|
| 2232 | GET_DBCS_LEAD ENDP
|
|---|
| 2233 |
|
|---|
| 2234 | SV_CODE ENDS
|
|---|
| 2235 |
|
|---|
| 2236 |
|
|---|
| 2237 | ;
|
|---|
| 2238 | ; Yes, this module contains real-mode code.
|
|---|
| 2239 | ;
|
|---|
| 2240 | INIT_CODE SEGMENT
|
|---|
| 2241 |
|
|---|
| 2242 | ASSUME CS:INIT_CODE, DS:NOTHING
|
|---|
| 2243 |
|
|---|
| 2244 | ;
|
|---|
| 2245 | ;
|
|---|
| 2246 | ;
|
|---|
| 2247 |
|
|---|
| 2248 | ;
|
|---|
| 2249 | ; Use backward jump to this code for processors with BIG prefetch queue
|
|---|
| 2250 | ;
|
|---|
| 2251 | TALIGN 4
|
|---|
| 2252 | INT_BACK_1: JMPF16 G_SV_CODE_SEL, RM_INT9
|
|---|
| 2253 |
|
|---|
| 2254 | ;
|
|---|
| 2255 | ; Generic software interrupt without conversion
|
|---|
| 2256 | ;
|
|---|
| 2257 | ASSUME DS:SV_DATA
|
|---|
| 2258 | FLUSH2: CALL GET_REGS ; Load registers from variables
|
|---|
| 2259 | ASSUME DS:NOTHING
|
|---|
| 2260 | INT_OP_2 LABEL BYTE
|
|---|
| 2261 | INT 0 ; Call interrupt routine
|
|---|
| 2262 | CALL PUT_REGS ; Store registers to variables
|
|---|
| 2263 | JMP SHORT INT_BACK ; Back to protected mode
|
|---|
| 2264 |
|
|---|
| 2265 | ;
|
|---|
| 2266 | ; Hardware interrupt
|
|---|
| 2267 | ;
|
|---|
| 2268 | ASSUME DS:NOTHING
|
|---|
| 2269 | TALIGN 4
|
|---|
| 2270 | FLUSH1: PUSH ES
|
|---|
| 2271 | PUSH BP
|
|---|
| 2272 | INT_OP_1 LABEL BYTE
|
|---|
| 2273 | INT 0
|
|---|
| 2274 | STI ; Allow interrupts here
|
|---|
| 2275 | POP BP
|
|---|
| 2276 | POP ES
|
|---|
| 2277 | CMP ES:HW_INT_VEC, 01H ; Keyboard interrupt (IRQ1)?
|
|---|
| 2278 | JNE SHORT POSTINT_10
|
|---|
| 2279 | MOV AX, SV_DATA
|
|---|
| 2280 | MOV DS, AX
|
|---|
| 2281 | ASSUME DS:SV_DATA
|
|---|
| 2282 | TEST STDIN_TERMIO.C_LFLAG, IDEFAULT
|
|---|
| 2283 | JNZ SHORT POSTINT_10
|
|---|
| 2284 | TEST STDIN_TERMIO.C_LFLAG, ISIG
|
|---|
| 2285 | JZ SHORT POSTINT_10
|
|---|
| 2286 | CALL POLL_KEYBOARD
|
|---|
| 2287 | ASSUME DS:NOTHING
|
|---|
| 2288 | POSTINT_10:
|
|---|
| 2289 | ;
|
|---|
| 2290 | ;
|
|---|
| 2291 | ;
|
|---|
| 2292 | ASSUME DS:NOTHING
|
|---|
| 2293 | INT_BACK: MOV AX, SV_DATA
|
|---|
| 2294 | MOV DS, AX
|
|---|
| 2295 | ASSUME DS:SV_DATA
|
|---|
| 2296 | CALL CHECK_A20 ; A20 enabled?
|
|---|
| 2297 | TEST AX, AX
|
|---|
| 2298 | JNZ SHORT INT_BACK_GO ; Yes -> skip
|
|---|
| 2299 | CALL A20_ON ; Enable A20
|
|---|
| 2300 | INT_BACK_GO: CLI
|
|---|
| 2301 | CMP VCPI_FLAG, FALSE ; VCPI?
|
|---|
| 2302 | JNE INT_BACK_VCPI ; Yes -> use server
|
|---|
| 2303 | LGDT GDT_PTR
|
|---|
| 2304 | LIDT IDT_PTR
|
|---|
| 2305 | MOV EAX, CR0
|
|---|
| 2306 | OR EAX, CR0_PE ; Enable protected mode
|
|---|
| 2307 | MOV CR0, EAX
|
|---|
| 2308 | JMP INT_BACK_1 ; Flush prefetch queue
|
|---|
| 2309 |
|
|---|
| 2310 |
|
|---|
| 2311 | TALIGN 4
|
|---|
| 2312 | RM_INT2 LABEL FAR
|
|---|
| 2313 | MOV AX, SV_DATA
|
|---|
| 2314 | MOV DS, AX
|
|---|
| 2315 | ASSUME DS:SV_DATA
|
|---|
| 2316 | MOV FS, AX
|
|---|
| 2317 | MOV GS, AX
|
|---|
| 2318 | MOV AX, RM_STACK
|
|---|
| 2319 | MOV SS, AX
|
|---|
| 2320 | LEA SP, RM_TOS
|
|---|
| 2321 | LIDT REAL_IDT_PTR
|
|---|
| 2322 | ;
|
|---|
| 2323 | ; Entrypoint from VCPI server
|
|---|
| 2324 | ;
|
|---|
| 2325 | V2V_CONT: MOV BP, FRAME_PTR ; Access registers of prot mode
|
|---|
| 2326 | MOV AX, SV_STACK
|
|---|
| 2327 | MOV ES, AX
|
|---|
| 2328 | CMP MACHINE, MACH_PC ; PC?
|
|---|
| 2329 | JE SHORT INT_BEG_1 ; Yes -> keep A20 enabled
|
|---|
| 2330 | CMP MACHINE, MACH_INBOARD ; Inboard 386/PC?
|
|---|
| 2331 | JE SHORT INT_BEG_1 ; Yes -> keep A20 enabled
|
|---|
| 2332 | CALL A20_OFF ; No -> disable A20
|
|---|
| 2333 | INT_BEG_1: MOV AL, ES:INT_NO ; Uses BP!
|
|---|
| 2334 | CMP AL, 10H
|
|---|
| 2335 | JE VIO_INT
|
|---|
| 2336 | CMP AL, 11H
|
|---|
| 2337 | JE SOFTWARE_INT
|
|---|
| 2338 | CMP AL, 14H
|
|---|
| 2339 | JE SOFTWARE_INT
|
|---|
| 2340 | CMP AL, 16H
|
|---|
| 2341 | JE SOFTWARE_INT
|
|---|
| 2342 | CMP AL, 17H
|
|---|
| 2343 | JE SOFTWARE_INT
|
|---|
| 2344 | CMP AL, 21H
|
|---|
| 2345 | JE SHORT DOS_INT
|
|---|
| 2346 | CMP AL, 33H
|
|---|
| 2347 | JE SOFTWARE_INT
|
|---|
| 2348 | MOV CS:INT_OP_1+1, AL ; Self-modifying code,
|
|---|
| 2349 | JMP FLUSH1 ; flush prefetch queue!
|
|---|
| 2350 |
|
|---|
| 2351 |
|
|---|
| 2352 |
|
|---|
| 2353 | ASSUME DS:SV_DATA
|
|---|
| 2354 |
|
|---|
| 2355 | TALIGN 4
|
|---|
| 2356 | DOS_INT: STI ; Enable interrupts
|
|---|
| 2357 | MOV AX, ES:RM_AX
|
|---|
| 2358 | CMP AX, 7F16H ; Poll keyboard?
|
|---|
| 2359 | JE SHORT DOS_INT_PK
|
|---|
| 2360 | CMP AX, 7F2AH ; __nls_memupr()?
|
|---|
| 2361 | JE SHORT DOS_INT_MEMUPR
|
|---|
| 2362 | PUSH AX
|
|---|
| 2363 | CMP AH, 4BH ; Exec?
|
|---|
| 2364 | JNE SHORT DOS_INT_1
|
|---|
| 2365 | PUSH ES
|
|---|
| 2366 | CALL CLEANUP_INT ; Cleanup interrupts
|
|---|
| 2367 | POP ES
|
|---|
| 2368 | DOS_INT_1: CALL GET_REGS ; Load registers from variables
|
|---|
| 2369 | ASSUME DS:NOTHING
|
|---|
| 2370 | CMP AH, 4CH ; Terminate process?
|
|---|
| 2371 | JE EXIT ; Yes ->
|
|---|
| 2372 | INT 21H
|
|---|
| 2373 | CALL PUT_REGS
|
|---|
| 2374 | POP AX
|
|---|
| 2375 | CMP AH, 4BH ; Exec?
|
|---|
| 2376 | JNE SHORT DOS_INT_2
|
|---|
| 2377 | CALL INIT_INT ; Reinitialize interrupts
|
|---|
| 2378 | DOS_INT_2: JMP INT_BACK
|
|---|
| 2379 |
|
|---|
| 2380 |
|
|---|
| 2381 | DOS_INT_PK: CALL POLL_KEYBOARD
|
|---|
| 2382 | JMP SHORT DOS_INT_2
|
|---|
| 2383 |
|
|---|
| 2384 | ;
|
|---|
| 2385 | ; Real-mode part of __nls_memupr()
|
|---|
| 2386 | ;
|
|---|
| 2387 | ASSUME DS:SV_DATA
|
|---|
| 2388 |
|
|---|
| 2389 | DOS_INT_MEMUPR: CMP ES:RM_CX, 0
|
|---|
| 2390 | JE SHORT DOS_INT_2
|
|---|
| 2391 | LEA DX, COUNTRYDATA
|
|---|
| 2392 | MOV AX, 3800H
|
|---|
| 2393 | INT 21H
|
|---|
| 2394 | JC SHORT DOS_INT_2
|
|---|
| 2395 | MOV BX, ES:RM_DX
|
|---|
| 2396 | MOV CX, ES:RM_CX
|
|---|
| 2397 | MOV ES, BUF_SEG
|
|---|
| 2398 | MEMUPR_LOOP: MOV AL, ES:[BX]
|
|---|
| 2399 | TEST AL, AL
|
|---|
| 2400 | JS SHORT MEMUPR_HIGH
|
|---|
| 2401 | CMP AL, "a"
|
|---|
| 2402 | JB SHORT MEMUPR_NEXT
|
|---|
| 2403 | CMP AL, "z"
|
|---|
| 2404 | JA SHORT MEMUPR_NEXT
|
|---|
| 2405 | SUB AL, "a" - "A"
|
|---|
| 2406 | MEMUPR_STORE: MOV ES:[BX], AL
|
|---|
| 2407 | MEMUPR_NEXT: INC BX
|
|---|
| 2408 | LOOP MEMUPR_LOOP
|
|---|
| 2409 | JMP SHORT DOS_INT_2
|
|---|
| 2410 |
|
|---|
| 2411 | MEMUPR_HIGH: CALL CD_CASEMAP
|
|---|
| 2412 | JMP SHORT MEMUPR_STORE
|
|---|
| 2413 |
|
|---|
| 2414 | ;
|
|---|
| 2415 | ; Software interrupt 10H
|
|---|
| 2416 | ;
|
|---|
| 2417 | ASSUME DS:SV_DATA
|
|---|
| 2418 | TALIGN 4
|
|---|
| 2419 | VIO_INT: STI ; Enable interrupts
|
|---|
| 2420 | CALL GET_REGS ; Load registers from variables
|
|---|
| 2421 | ASSUME DS:NOTHING
|
|---|
| 2422 | PUSH AX ; Save AH (function number)
|
|---|
| 2423 | INT 10H ; Call BIOS
|
|---|
| 2424 | CALL PUT_REGS ; Store registers to variables
|
|---|
| 2425 | POP AX ; Restore AH (function number)
|
|---|
| 2426 | CMP AH, 00H ; Set mode?
|
|---|
| 2427 | JNE INT_BACK ; No -> back to protected mode
|
|---|
| 2428 | CALL VINIT ; Get new width and height
|
|---|
| 2429 | JMP INT_BACK ; Back to protected mode
|
|---|
| 2430 |
|
|---|
| 2431 | ;
|
|---|
| 2432 | ; Generic software interrupt
|
|---|
| 2433 | ;
|
|---|
| 2434 | ASSUME DS:SV_DATA
|
|---|
| 2435 | TALIGN 4
|
|---|
| 2436 | SOFTWARE_INT: STI ; Enable interrupts
|
|---|
| 2437 | MOV CS:INT_OP_2+1, AL ; Self-modifying code,
|
|---|
| 2438 | JMP FLUSH2 ; flush prefetch queue!
|
|---|
| 2439 |
|
|---|
| 2440 |
|
|---|
| 2441 | ;
|
|---|
| 2442 | ; Load registers from variables
|
|---|
| 2443 | ;
|
|---|
| 2444 | ; Attention: ES:BP points to protected mode stack frame!
|
|---|
| 2445 | ;
|
|---|
| 2446 | ASSUME DS:NOTHING
|
|---|
| 2447 | TALIGN 4
|
|---|
| 2448 | GET_REGS PROC NEAR
|
|---|
| 2449 | MOV AX, ES:RM_AX
|
|---|
| 2450 | MOV BX, ES:RM_BX
|
|---|
| 2451 | MOV CX, ES:RM_CX
|
|---|
| 2452 | MOV DX, ES:RM_DX
|
|---|
| 2453 | MOV SI, ES:RM_SI
|
|---|
| 2454 | MOV DI, ES:RM_DI
|
|---|
| 2455 | MOV DS, ES:RM_DS
|
|---|
| 2456 | PUSH ES:RM_BP
|
|---|
| 2457 | MOV ES, ES:RM_ES
|
|---|
| 2458 | POP BP
|
|---|
| 2459 | RET
|
|---|
| 2460 | GET_REGS ENDP
|
|---|
| 2461 |
|
|---|
| 2462 |
|
|---|
| 2463 | ;
|
|---|
| 2464 | ; Has to load ES:BP with address of protected-mode stack frame!
|
|---|
| 2465 | ;
|
|---|
| 2466 | ASSUME DS:NOTHING
|
|---|
| 2467 | TALIGN 4
|
|---|
| 2468 | PUT_REGS PROC NEAR
|
|---|
| 2469 | PUSH DS
|
|---|
| 2470 | PUSH ES
|
|---|
| 2471 | PUSH BP
|
|---|
| 2472 | PUSH AX
|
|---|
| 2473 | MOV AX, SV_DATA
|
|---|
| 2474 | MOV DS, AX
|
|---|
| 2475 | ASSUME DS:SV_DATA
|
|---|
| 2476 | MOV AX, SV_STACK
|
|---|
| 2477 | MOV ES, AX
|
|---|
| 2478 | MOV BP, FRAME_PTR
|
|---|
| 2479 | LAHF
|
|---|
| 2480 | MOV ES:RM_FLAGS, AH
|
|---|
| 2481 | POP ES:RM_AX
|
|---|
| 2482 | POP ES:RM_BP
|
|---|
| 2483 | POP ES:RM_ES
|
|---|
| 2484 | POP ES:RM_DS
|
|---|
| 2485 | MOV ES:RM_BX, BX
|
|---|
| 2486 | MOV ES:RM_CX, CX
|
|---|
| 2487 | MOV ES:RM_DX, DX
|
|---|
| 2488 | MOV ES:RM_SI, SI
|
|---|
| 2489 | MOV ES:RM_DI, DI
|
|---|
| 2490 | RET
|
|---|
| 2491 | PUT_REGS ENDP
|
|---|
| 2492 |
|
|---|
| 2493 |
|
|---|
| 2494 |
|
|---|
| 2495 | ;
|
|---|
| 2496 | ; Allocate buffers for real-mode interface.
|
|---|
| 2497 | ;
|
|---|
| 2498 | ; We need two buffers:
|
|---|
| 2499 | ;
|
|---|
| 2500 | ; - the first buffer is used for the user program's i/o
|
|---|
| 2501 | ;
|
|---|
| 2502 | ; - the second buffer is used for the swapper's i/o. The swapper
|
|---|
| 2503 | ; may be activated while copying the user program's i/o buffer
|
|---|
| 2504 | ;
|
|---|
| 2505 | ; The two buffers have there own selectors (and GDT entries)
|
|---|
| 2506 | ;
|
|---|
| 2507 |
|
|---|
| 2508 | ASSUME DS:SV_DATA
|
|---|
| 2509 | INIT_BUFFER PROC NEAR
|
|---|
| 2510 | MOV BX, 1000H ; 64 KB
|
|---|
| 2511 | LEA DI, G_BUF1_DESC
|
|---|
| 2512 | CALL INIT_BUF_1
|
|---|
| 2513 | MOV BUF1_SEG, AX ; Main buffer segment
|
|---|
| 2514 | MOV BX, 0101H ; 4 KB + 16 Bytes
|
|---|
| 2515 | LEA DI, G_BUF2_DESC
|
|---|
| 2516 | CALL INIT_BUF_1
|
|---|
| 2517 | MOV BUF2_SEG, AX ; Swapper buffer segment
|
|---|
| 2518 | ;
|
|---|
| 2519 | ; Select 1st buffer (64KB)
|
|---|
| 2520 | ;
|
|---|
| 2521 | MOV AX, BUF1_SEG
|
|---|
| 2522 | MOV BUF_SEG, AX
|
|---|
| 2523 | MOV BUF_SEL, G_BUF1_SEL
|
|---|
| 2524 | RET
|
|---|
| 2525 |
|
|---|
| 2526 |
|
|---|
| 2527 | INIT_BUF_1 PROC NEAR
|
|---|
| 2528 | MOV AH, 48H
|
|---|
| 2529 | INT 21H
|
|---|
| 2530 | JC RM_OUT_OF_MEM
|
|---|
| 2531 | PUSH AX
|
|---|
| 2532 | MOVZX EAX, AX
|
|---|
| 2533 | SHL EAX, 4
|
|---|
| 2534 | CALL RM_SEG_BASE
|
|---|
| 2535 | POP AX
|
|---|
| 2536 | RET
|
|---|
| 2537 | INIT_BUF_1 ENDP
|
|---|
| 2538 |
|
|---|
| 2539 | INIT_BUFFER ENDP
|
|---|
| 2540 |
|
|---|
| 2541 |
|
|---|
| 2542 | IF DEBUG_DOSDUMP
|
|---|
| 2543 |
|
|---|
| 2544 | ASSUME DS:NOTHING
|
|---|
| 2545 | DOSDUMP PROC NEAR
|
|---|
| 2546 | PUSHAD
|
|---|
| 2547 | PUSH DS
|
|---|
| 2548 | PUSH ES
|
|---|
| 2549 | MOV AX, SV_DATA
|
|---|
| 2550 | MOV DS, AX
|
|---|
| 2551 | ASSUME DS:SV_DATA
|
|---|
| 2552 | LEA BX, $DOSDUMP_C
|
|---|
| 2553 | DOSDUMP_10: MOV AL, [BX]
|
|---|
| 2554 | INC BYTE PTR [BX]
|
|---|
| 2555 | CMP AL, "9"
|
|---|
| 2556 | JNE SHORT DOSDUMP_11
|
|---|
| 2557 | MOV BYTE PTR [BX], "0"
|
|---|
| 2558 | DEC BX
|
|---|
| 2559 | JMP SHORT DOSDUMP_10
|
|---|
| 2560 |
|
|---|
| 2561 | DOSDUMP_11: LEA DX, $DOSDUMP
|
|---|
| 2562 | MOV CX, 0
|
|---|
| 2563 | MOV AH, 3CH
|
|---|
| 2564 | INT 21H
|
|---|
| 2565 | JC SHORT DOSDUMP_ERR
|
|---|
| 2566 | MOV BX, AX
|
|---|
| 2567 | MOV CX, 640 / 32
|
|---|
| 2568 | MOV SI, 0
|
|---|
| 2569 | DOSDUMP_20: PUSH CX
|
|---|
| 2570 | PUSH DS
|
|---|
| 2571 | MOV DS, SI
|
|---|
| 2572 | ASSUME DS:NOTHING
|
|---|
| 2573 | MOV DX, 0
|
|---|
| 2574 | MOV CX, 32 * 1024
|
|---|
| 2575 | MOV AH, 40H
|
|---|
| 2576 | INT 21H
|
|---|
| 2577 | POP DS
|
|---|
| 2578 | ASSUME DS:SV_DATA
|
|---|
| 2579 | POP CX
|
|---|
| 2580 | JC SHORT DOSDUMP_ERR
|
|---|
| 2581 | ADD SI, 32 * 1024 / 16
|
|---|
| 2582 | LOOP DOSDUMP_20
|
|---|
| 2583 | MOV AH, 3EH
|
|---|
| 2584 | INT 21H
|
|---|
| 2585 | JMP SHORT DOSDUMP_RET
|
|---|
| 2586 |
|
|---|
| 2587 | DOSDUMP_ERR:
|
|---|
| 2588 | DOSDUMP_RET: POP ES
|
|---|
| 2589 | POP DS
|
|---|
| 2590 | POPAD
|
|---|
| 2591 | RET
|
|---|
| 2592 | DOSDUMP ENDP
|
|---|
| 2593 |
|
|---|
| 2594 | ENDIF
|
|---|
| 2595 |
|
|---|
| 2596 |
|
|---|
| 2597 | INIT_CODE ENDS
|
|---|
| 2598 |
|
|---|
| 2599 | END
|
|---|