diff options
Diffstat (limited to 'v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM')
| -rw-r--r-- | v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM | 1424 |
1 files changed, 1424 insertions, 0 deletions
diff --git a/v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM b/v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM new file mode 100644 index 0000000..6cfefbe --- /dev/null +++ b/v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM | |||
| @@ -0,0 +1,1424 @@ | |||
| 1 | TITLE MTCON - Console device driver for MT-MSDOS | ||
| 2 | page ,132 | ||
| 3 | |||
| 4 | |||
| 5 | ;; TODO - | ||
| 6 | ;; split CON and KBD | ||
| 7 | ;; interruptible waits and unwinding | ||
| 8 | ;; per screen keyboard buffers | ||
| 9 | |||
| 10 | ;------------------------------------------------------------------------ | ||
| 11 | ; Revision History | ||
| 12 | ; | ||
| 13 | ; V1.00 04/10/84 M.A.Ulloa | ||
| 14 | ; First Implementation: Only one segment used and only | ||
| 15 | ; one screen in the color card (alpha mode). | ||
| 16 | ; | ||
| 17 | ; V1.01 04/15/84 M.A.Ulloa | ||
| 18 | ; Re-enabled the blocking of writing from processes not | ||
| 19 | ; with the current screen. | ||
| 20 | ; | ||
| 21 | ; V1.02 04/16/84 M.A.Ulloa | ||
| 22 | ; Increased to 8 the num of screens. Added the screen | ||
| 23 | ; blanking when reading and writing the screen data | ||
| 24 | ; (see BLANK switch). Added screen # for writes. | ||
| 25 | ; | ||
| 26 | ; V1.03 04/17/84 M.A.Ulloa | ||
| 27 | ; Corrected problem with flush. | ||
| 28 | ; | ||
| 29 | ; V1.05 04/30/84 A.R.Whitney | ||
| 30 | ; Added conditional compilation to allow linking with | ||
| 31 | ; resident BIOS. | ||
| 32 | ; | ||
| 33 | ; V1.06 05/08/84 A.R.Whitney | ||
| 34 | ; Added ANSI escape sequences. Conditional on ANSI. | ||
| 35 | ; | ||
| 36 | ; V1.07 05/15/84 A.R.Whitney | ||
| 37 | ; Fixed compatibility problems with Eagle PC Turbo. | ||
| 38 | ; Fixed BLANK conditional code to allow saving graphics | ||
| 39 | ; mode screens. | ||
| 40 | ; Added enable/disable 25th line to Ansi. | ||
| 41 | ; | ||
| 42 | ; V1.08 05/22/84 A.R.Whitney | ||
| 43 | ; Fixed problem with scrolling in screen modes other | ||
| 44 | ; than 80x25. Bug due to 25th line stuff. | ||
| 45 | ; | ||
| 46 | ;------------------------------------------------------------------------ | ||
| 47 | |||
| 48 | ;DEBUGFLG = 1 | ||
| 49 | |||
| 50 | .xlist | ||
| 51 | include DEFDBUG.INC | ||
| 52 | .list | ||
| 53 | |||
| 54 | FALSE EQU 0 | ||
| 55 | TRUE EQU NOT FALSE | ||
| 56 | |||
| 57 | CVERS equ 01 ; update version number!! | ||
| 58 | CREV equ 08 | ||
| 59 | |||
| 60 | BLANK equ TRUE ; blank screen during data r/w | ||
| 61 | INBIOS equ TRUE ; link with BIOS | ||
| 62 | ANSI equ TRUE ; include ANSI escape sequences | ||
| 63 | LINE25 equ TRUE ; special 25th line like VT52 | ||
| 64 | EAGLE equ TRUE ; Eagle PC ROM botches CRT_LEN | ||
| 65 | |||
| 66 | |||
| 67 | subttl Screen Information Block Definition | ||
| 68 | page | ||
| 69 | |||
| 70 | ;------------------------------------------------------------------------ | ||
| 71 | ; Screen Information Block (SIB) Definition | ||
| 72 | ; | ||
| 73 | ; This structure contains all information necessary to | ||
| 74 | ; describe the state of the screen, plus pointers to buffers | ||
| 75 | ; which contain the actual screen content. | ||
| 76 | ; | ||
| 77 | |||
| 78 | ;------------------------------------------------------------------------ | ||
| 79 | MaxSEG equ 2 ; NOTE: assumption is made in the | ||
| 80 | ; code that all SIB's have same | ||
| 81 | ; number os SEGs | ||
| 82 | SEGst struc | ||
| 83 | SizeNeeded dw 0 ; needed size for seg, (0 = unused) | ||
| 84 | MemFlag dw ? ; maintened by system (0 = in mem) | ||
| 85 | MPointer dd ? ; vaild iff MemFlag == 0 | ||
| 86 | SEGst ends | ||
| 87 | |||
| 88 | ;------------------------------------------------------------------------ | ||
| 89 | MaxSIB equ 8 ; maximum number of Screens | ||
| 90 | |||
| 91 | |||
| 92 | IF ANSI | ||
| 93 | TermSize EQU 20 ; max. size of terminal emulation state | ||
| 94 | ENDIF | ||
| 95 | |||
| 96 | SIBst struc | ||
| 97 | ctlS db 0 ; if the screen is NOT frozen = 0 | ||
| 98 | ; NOTE: this field should be the | ||
| 99 | ; FIRST of each SIB !! (see ConWrit) | ||
| 100 | OffsetVal dw 7 ; start of Seg Descriptors | ||
| 101 | SegCnt dw MaxSeg ; max number of Segments | ||
| 102 | SIBlen dw (SIZE SIBst) ; length of the SIB | ||
| 103 | ;--- Segments | ||
| 104 | db ((SIZE SEGst) * MaxSeg) dup (?) | ||
| 105 | ;--- PC video state info | ||
| 106 | xCRT_MODE DB ? | ||
| 107 | xCRT_COLS DW ? | ||
| 108 | xCRT_LEN DW ? | ||
| 109 | xCRT_START DW ? | ||
| 110 | xCURSOR_POSN DW 8 DUP(?) | ||
| 111 | xCURSOR_MODE DW ? | ||
| 112 | xACTIVE_PAGE DB ? | ||
| 113 | xADDR_6845 DW ? | ||
| 114 | xCRT_MODE_SET DB ? | ||
| 115 | xCRT_PALETTE DB ? | ||
| 116 | xTERM_STATE DB TermSize DUP(?) | ||
| 117 | SIBst ends | ||
| 118 | |||
| 119 | |||
| 120 | subttl Request packet definitions | ||
| 121 | page | ||
| 122 | |||
| 123 | ;------------------------------------------------------------------------ | ||
| 124 | ; Request packet offset definitions | ||
| 125 | ; | ||
| 126 | |||
| 127 | CMDLEN = 0 ;LENGTH OF THIS COMMAND | ||
| 128 | UNIT = 1 ;SUB UNIT SPECIFIER | ||
| 129 | CMD = 2 ;COMMAND CODE | ||
| 130 | STATUS = 3 ;STATUS | ||
| 131 | MEDIA = 13 ;MEDIA DESCRIPTOR | ||
| 132 | TRANS = 14 ;TRANSFER ADDRESS | ||
| 133 | COUNT = 18 ;COUNT OF BLOCKS OR CHARACTERS | ||
| 134 | START = 20 ;FIRST BLOCK TO TRANSFER | ||
| 135 | |||
| 136 | |||
| 137 | subttl IBM-PC ROM Data area Locations | ||
| 138 | page | ||
| 139 | |||
| 140 | ;------------------------------------------------------------------------ | ||
| 141 | ; IBM-PC ROM Data area Locations | ||
| 142 | ; | ||
| 143 | |||
| 144 | RomData SEGMENT AT 40H | ||
| 145 | ORG 1AH | ||
| 146 | BufferHead DW ? | ||
| 147 | BufferTail DW ? | ||
| 148 | KeyBuffer DW 16 DUP (?) | ||
| 149 | KeyBufLen equ ($-KeyBuffer) ; length of KeyBuffer | ||
| 150 | |||
| 151 | ORG 49H | ||
| 152 | CRT_MODE DB ? | ||
| 153 | CRT_COLS DW ? | ||
| 154 | CRT_LEN DW ? | ||
| 155 | CRT_START DW ? | ||
| 156 | CURSOR_POSN DW 8 DUP(?) | ||
| 157 | CURSOR_MODE DW ? | ||
| 158 | ACTIVE_PAGE DB ? | ||
| 159 | ADDR_6845 DW ? | ||
| 160 | CRT_MODE_SET DB ? | ||
| 161 | CRT_PALETTE DB ? | ||
| 162 | |||
| 163 | CrtLen EQU ($-CRT_MODE) ; length of screen state area | ||
| 164 | RomData ENDS | ||
| 165 | |||
| 166 | MonoSc SEGMENT AT 0B000H | ||
| 167 | ;--- 4k of screen memory | ||
| 168 | MonoSc ENDS | ||
| 169 | |||
| 170 | ColorSc SEGMENT AT 0B800H | ||
| 171 | ;--- 16k of screen memory | ||
| 172 | ColorSc ENDS | ||
| 173 | |||
| 174 | BRKADR equ 006CH ; Break vector address | ||
| 175 | |||
| 176 | |||
| 177 | subttl Device Header | ||
| 178 | page | ||
| 179 | |||
| 180 | |||
| 181 | BiosSeg group Code,BiosInit | ||
| 182 | Code Segment byte public 'CODE' | ||
| 183 | |||
| 184 | ;------------------------------------------------------------------------ | ||
| 185 | ; Device Header | ||
| 186 | ; | ||
| 187 | |||
| 188 | assume cs:Code,ds:NOTHING,es:NOTHING,ss:NOTHING | ||
| 189 | |||
| 190 | PUBLIC CONDEV | ||
| 191 | IF INBIOS | ||
| 192 | extrn AUXDEV:FAR | ||
| 193 | CONDEV dd AUXDEV | ||
| 194 | ELSE | ||
| 195 | CONDEV dw 0FFFFh,0FFFFh | ||
| 196 | ENDIF ;INBIOS | ||
| 197 | ;*** should ioctl bit be set for gen ioctl too? | ||
| 198 | dw 1100000000010011b ; console in and out | ||
| 199 | dw Strategy | ||
| 200 | dw Entry | ||
| 201 | db "CON " | ||
| 202 | |||
| 203 | |||
| 204 | ;------------------------------------------------------------------------ | ||
| 205 | ; Command dispatch table | ||
| 206 | ; | ||
| 207 | |||
| 208 | ComTbl: | ||
| 209 | ;--- 2.0 | ||
| 210 | dw OFFSET BiosSeg:$ConInit ; Initialization function | ||
| 211 | dw StatusComplete ; Media Check | ||
| 212 | dw StatusComplete ; Build BPB | ||
| 213 | dw CmdErr ; IOCTL Input | ||
| 214 | dw $ConRead ; Input (Read) | ||
| 215 | dw $ConRdnd ; Non-Destructive read, no wait | ||
| 216 | dw StatusComplete ; Input Status | ||
| 217 | dw $ConFlsh ; Input Flush | ||
| 218 | dw $ConWrit ; Output (Write) | ||
| 219 | dw $ConWrit ; Output with verify | ||
| 220 | dw StatusComplete ; Output Status | ||
| 221 | dw StatusComplete ; Output Flush | ||
| 222 | dw StatusComplete ; IOCTL Output | ||
| 223 | ;--- 3.0 | ||
| 224 | dw StatusComplete ; Device Open | ||
| 225 | dw StatusComplete ; Device Close | ||
| 226 | dw StatusComplete ; Removable Media | ||
| 227 | ;--- 4.0 | ||
| 228 | dw $GenIOCTL ; Generic IOCTL | ||
| 229 | dw $ConStop ; Pause Device | ||
| 230 | dw $ConStart ; Continue Device | ||
| 231 | |||
| 232 | ComTblEnd: | ||
| 233 | |||
| 234 | CTSIZE equ (ComTblEnd - ComTbl)/2 ; number of table entries | ||
| 235 | |||
| 236 | |||
| 237 | subttl Device Data Area | ||
| 238 | page | ||
| 239 | |||
| 240 | ;------------------------------------------------------------------------ | ||
| 241 | ; Device Data Area | ||
| 242 | ; | ||
| 243 | |||
| 244 | SaveFlg db 0 ; Screen being saved flag, (true = 1) | ||
| 245 | IF INBIOS | ||
| 246 | EXTRN DosFunction:DWORD | ||
| 247 | ELSE | ||
| 248 | DosFunction dd ? ; pointer to dos "helper" functions | ||
| 249 | ENDIF ;INBIOS | ||
| 250 | AltAH db 0 ; Side buffer for input | ||
| 251 | CurrSc dw 0 ; Current screen number | ||
| 252 | CurrSIB dw SIB ; offset to the current SIB | ||
| 253 | SIB SIBst MaxSIB dup (<>) ; allocate room for SIB's | ||
| 254 | |||
| 255 | IF EAGLE | ||
| 256 | ScreenLen db 08h ; table of (high byte of) regen. buffer | ||
| 257 | db 08h ; len. Indexed by screen mode. | ||
| 258 | db 10h ; 80x25 text modes | ||
| 259 | db 10h | ||
| 260 | db 40h ; graphics modes | ||
| 261 | db 40h | ||
| 262 | db 40h | ||
| 263 | db 10h ; monochrome | ||
| 264 | ENDIF | ||
| 265 | |||
| 266 | |||
| 267 | IFDEF DEBUGFLG | ||
| 268 | IF INBIOS | ||
| 269 | EXTRN BUGBITS:BYTE,DPRINTF:NEAR | ||
| 270 | ELSE | ||
| 271 | BUGBITS db 0ffh,0ffh | ||
| 272 | ENDIF | ||
| 273 | ENDIF | ||
| 274 | |||
| 275 | subttl Device Entry Points | ||
| 276 | page | ||
| 277 | |||
| 278 | ;------------------------------------------------------------------------ | ||
| 279 | ; 2.0 Interrupt Routine (Not Used) | ||
| 280 | ; | ||
| 281 | |||
| 282 | EntryP proc far | ||
| 283 | Entry: ret | ||
| 284 | EntryP endp | ||
| 285 | |||
| 286 | |||
| 287 | ;------------------------------------------------------------------------ | ||
| 288 | ; 2.0 Strategy Routine, main entry point | ||
| 289 | ; | ||
| 290 | ; entry | ||
| 291 | ; ES:BX points to Request packet | ||
| 292 | ; | ||
| 293 | |||
| 294 | StratP proc far | ||
| 295 | |||
| 296 | Strategy: | ||
| 297 | IF INBIOS | ||
| 298 | extrn Interrupt:NEAR | ||
| 299 | |||
| 300 | push si | ||
| 301 | mov si,OFFSET CS:ComTbl | ||
| 302 | jmp Interrupt | ||
| 303 | ELSE | ||
| 304 | push ax ; save all | ||
| 305 | push cx | ||
| 306 | push dx | ||
| 307 | push si | ||
| 308 | push di | ||
| 309 | push bp | ||
| 310 | push ds | ||
| 311 | |||
| 312 | push es ; DS = ES | ||
| 313 | pop ds | ||
| 314 | |||
| 315 | push es | ||
| 316 | push bx | ||
| 317 | mov al, byte ptr ds:[bx].CMD | ||
| 318 | cmp al,CTSIZE ; Command within range? | ||
| 319 | jae CmdErr ; no must be an error | ||
| 320 | mov cx, word ptr ds:[bx].COUNT | ||
| 321 | les di, dword ptr ds:[bx].TRANS | ||
| 322 | xor ah,ah | ||
| 323 | mov si, offset ComTbl | ||
| 324 | add si,ax | ||
| 325 | add si,ax | ||
| 326 | |||
| 327 | jmp word ptr cs:[si] ; dispatch | ||
| 328 | ENDIF ;INBIOS | ||
| 329 | |||
| 330 | StratP endp | ||
| 331 | |||
| 332 | |||
| 333 | subttl Exit Routines | ||
| 334 | page | ||
| 335 | |||
| 336 | ;------------------------------------------------------------------------ | ||
| 337 | ; Exit Routines, Common to all device functions | ||
| 338 | ; | ||
| 339 | |||
| 340 | IF INBIOS | ||
| 341 | extrn StatusComplete:NEAR,StatusError:NEAR,StatusDevReady:NEAR | ||
| 342 | extrn CmdErr:NEAR | ||
| 343 | ELSE | ||
| 344 | |||
| 345 | assume ds:NOTHING,es:NOTHING | ||
| 346 | |||
| 347 | StatusDevReady: | ||
| 348 | mov ah,00000011b ; device busy | ||
| 349 | jmp short errEx | ||
| 350 | |||
| 351 | CmdErr: | ||
| 352 | mov al,3 ; Unknown command Error | ||
| 353 | StatusError: | ||
| 354 | mov ah,10000001b | ||
| 355 | jmp short errEx | ||
| 356 | |||
| 357 | ExitP proc far | ||
| 358 | StatusComplete: mov ah,00000001b | ||
| 359 | errEx: pop bx | ||
| 360 | pop es | ||
| 361 | |||
| 362 | mov word ptr es:[bx].STATUS,ax ; put status out | ||
| 363 | |||
| 364 | pop ds | ||
| 365 | pop bp | ||
| 366 | pop di | ||
| 367 | pop si | ||
| 368 | pop dx | ||
| 369 | pop cx | ||
| 370 | pop ax | ||
| 371 | ret | ||
| 372 | ExitP endp | ||
| 373 | |||
| 374 | ENDIF ;INBIOS | ||
| 375 | |||
| 376 | |||
| 377 | subttl Break - Break interrupt routine | ||
| 378 | page | ||
| 379 | |||
| 380 | ;------------------------------------------------------------------------ | ||
| 381 | ; Break interrupt routine | ||
| 382 | ; | ||
| 383 | |||
| 384 | assume ds:NOTHING,es:NOTHING | ||
| 385 | |||
| 386 | Break PROC NEAR | ||
| 387 | int 32H ; save registers | ||
| 388 | cli ; ints should be off, make sure! | ||
| 389 | mov ax,RomData | ||
| 390 | mov ds,ax | ||
| 391 | assume ds:RomData | ||
| 392 | mov ax,offset RomData:KeyBuffer | ||
| 393 | mov [BufferHead],ax | ||
| 394 | mov [BufferTail],ax | ||
| 395 | assume ds:NOTHING | ||
| 396 | mov ax,3 ; send char to system | ||
| 397 | mov dx,5 ; ConsInputFilter subfunction | ||
| 398 | call [DosFunction] | ||
| 399 | jz brk1 ; key was eaten by system | ||
| 400 | mov [AltAH],al ; force a ^C | ||
| 401 | brk1: | ||
| 402 | iret | ||
| 403 | Break ENDP | ||
| 404 | |||
| 405 | SUBTTL Keyboard interrupt routine | ||
| 406 | PAGE | ||
| 407 | ; Replacement for ROM keyboard interrupt, tacks on the front. | ||
| 408 | ; OldKeyInterrupt is set to original contents of INT 09H. | ||
| 409 | ; The input character is passed to the O.S. console input filter | ||
| 410 | ; to determine if any special action should be taken. The filter | ||
| 411 | ; return value indicates if the character should be saved in the | ||
| 412 | ; type ahead buffer or if it should be discarded. A keyboard | ||
| 413 | ; semaphore exists to indicate if a process is waiting for input. | ||
| 414 | ; If the keboard semaphore is set all of the processes sleeping on | ||
| 415 | ; it are woken up. | ||
| 416 | |||
| 417 | OldKeyInterrupt DD ? | ||
| 418 | KeySem db 0 ; non-zero if someone waiting on input | ||
| 419 | |||
| 420 | KeyboardInterrupt PROC FAR | ||
| 421 | INT 32H ; Save regs | ||
| 422 | MOV AX,RomData | ||
| 423 | MOV DS,AX | ||
| 424 | ASSUME DS:RomData | ||
| 425 | |||
| 426 | PUSHF ; Save flags to simulate INT | ||
| 427 | CALL CS:OldKeyInterrupt ; Now do ROM code | ||
| 428 | ; Now tell DOS keyboard had char | ||
| 429 | cli ; interrupts off! | ||
| 430 | mov bx,BufferTail ; Get tail of queue | ||
| 431 | cmp bx,BufferHead ; Anything in keyboard queue? | ||
| 432 | JE NoKey ; No, don't requeue then | ||
| 433 | dec bx | ||
| 434 | dec bx | ||
| 435 | cmp bx,offset RomData:KeyBuffer | ||
| 436 | jae kbi1 ; no wrap around in buffer | ||
| 437 | mov bx,offset RomData:KeyBuffer+(KeyBufLen-2) | ||
| 438 | kbi1: | ||
| 439 | mov ax,[bx] ; get last queued char. | ||
| 440 | mov dx,5 ; ConsInputFilter subfunction | ||
| 441 | call [DosFunction] | ||
| 442 | jnz kbi2 ; key should remain in buffer | ||
| 443 | mov BufferTail,bx ; discard key from buffer | ||
| 444 | jmp SHORT NoKey | ||
| 445 | kbi2: | ||
| 446 | cli | ||
| 447 | CMP KeySem,0 ; Outstanding request? | ||
| 448 | JE NoKey ; No, may not be inited either | ||
| 449 | push ax | ||
| 450 | push bx | ||
| 451 | push cx | ||
| 452 | push dx | ||
| 453 | mov ax,cs | ||
| 454 | mov bx,OFFSET KeySem | ||
| 455 | mov cs:byte ptr [bx],0 ; reset keyboard semaphore | ||
| 456 | mov dx,10 ;; ProcRun | ||
| 457 | call [DosFunction] ; awaken anyone waiting on input | ||
| 458 | pop dx | ||
| 459 | pop cx | ||
| 460 | pop bx | ||
| 461 | pop ax | ||
| 462 | NoKey: | ||
| 463 | IRET | ||
| 464 | KeyBoardInterrupt ENDP | ||
| 465 | |||
| 466 | ;------------------------------------------------------------- | ||
| 467 | ; Keyboard INT 16 intercept routine to allow console input to sleep. | ||
| 468 | ; Only console input function 1 is intercepted, all other functions | ||
| 469 | ; are allowed to go directly to the ROM BIOS. For the function 1 | ||
| 470 | ; the input status is checked, if a character is ready the function | ||
| 471 | ; is allowed to go to the ROM BIOS. Otherwise the keyboard semaphore | ||
| 472 | ; is set and the process is put to sleep on the address of the | ||
| 473 | ; semaphore. When a key is typed the keyboard interrupt routine | ||
| 474 | ; will wakeup any processes sleeping on this semaphore. | ||
| 475 | ; | ||
| 476 | ; WARNING: The following routines can be entered recursively | ||
| 477 | ; due to the fact that the ROM BIOS routines called | ||
| 478 | ; reenable interrupts. It's not usually a problem | ||
| 479 | ; since interrupts will generally be processed faster | ||
| 480 | ; than anyone can type. | ||
| 481 | |||
| 482 | OldKbdHandler dd ? | ||
| 483 | ScrnIoOk dd ? | ||
| 484 | |||
| 485 | ;------------------------------------------------------------- | ||
| 486 | |||
| 487 | KeyBoardHandler proc far | ||
| 488 | or ah,ah | ||
| 489 | je DoLocalRead | ||
| 490 | cmp ah,1 | ||
| 491 | je DoLocalStat | ||
| 492 | OldKBint: | ||
| 493 | jmp [OldKbdHandler] | ||
| 494 | |||
| 495 | DoLocalStat: | ||
| 496 | push bx | ||
| 497 | push ds | ||
| 498 | lds bx,ScrnIoOk | ||
| 499 | test byte ptr [bx],0FFh | ||
| 500 | pop ds | ||
| 501 | pop bx | ||
| 502 | jnz OldKBint | ||
| 503 | xor ax,ax | ||
| 504 | ret 2 | ||
| 505 | DoInt16 LABEL FAR ; entry for ChrIn | ||
| 506 | DoLocalRead: | ||
| 507 | push ax | ||
| 508 | push bx | ||
| 509 | push cx | ||
| 510 | push dx | ||
| 511 | DoLocalRd1: | ||
| 512 | push ds | ||
| 513 | lds bx,ScrnIoOk | ||
| 514 | mov ax,ds | ||
| 515 | test byte ptr [bx],0FFh | ||
| 516 | pop ds | ||
| 517 | jnz DoLocalRd2 | ||
| 518 | xor cx,cx | ||
| 519 | mov dx,9 ;; ProcBlock | ||
| 520 | call [DosFunction] ; sleep until a screen switch | ||
| 521 | jmp DoLocalRd1 | ||
| 522 | |||
| 523 | DoLocalRd2: | ||
| 524 | mov ah,1 ; get console status | ||
| 525 | pushf ; simulate INT to old handler | ||
| 526 | cli | ||
| 527 | call [OldKbdHandler] | ||
| 528 | cli ; subfunction 1 unconditionally sets IF | ||
| 529 | jnz LocalRead ; go read character | ||
| 530 | mov ax,cs | ||
| 531 | mov bx,OFFSET KeySem | ||
| 532 | mov cs:byte ptr [bx],0FFh ; set keyboard semaphore | ||
| 533 | xor cx,cx | ||
| 534 | mov dx,9 ;; ProcBlock | ||
| 535 | call [DosFunction] ; sleep until a char is typed | ||
| 536 | jmp DoLocalRd1 | ||
| 537 | |||
| 538 | LocalRead: | ||
| 539 | pop dx | ||
| 540 | pop cx | ||
| 541 | pop bx | ||
| 542 | pop ax | ||
| 543 | jmp [OldKbdHandler] ; read the character and return | ||
| 544 | |||
| 545 | KeyBoardHandler endp | ||
| 546 | |||
| 547 | |||
| 548 | subttl $ConRead - Console Input (Read) | ||
| 549 | page | ||
| 550 | |||
| 551 | ;------------------------------------------------------------------------ | ||
| 552 | ; Console Input (Read) | ||
| 553 | ; | ||
| 554 | ; entry: | ||
| 555 | ; DS:BX = pointer to Request packet | ||
| 556 | ; ES:DI = Transfer address | ||
| 557 | ; CX = Count | ||
| 558 | ; | ||
| 559 | |||
| 560 | assume ds:NOTHING,es:NOTHING | ||
| 561 | |||
| 562 | $ConRead: | ||
| 563 | and cx,cx | ||
| 564 | jnz jgl2 | ||
| 565 | jmp CRExit | ||
| 566 | ; jcxz CRExit ; no chars to read BUGBUG restore | ||
| 567 | jgl2: cld ; make sure! | ||
| 568 | mov dx,word ptr ds:[bx].START ; get screen number | ||
| 569 | cmp dx,(MaxSIB-1) ; valid number? | ||
| 570 | jbe ConRLoop ; yes, do input | ||
| 571 | mov al,0BH ; no, READ FAULT ERROR | ||
| 572 | jmp StatusError | ||
| 573 | ConRLoop: | ||
| 574 | DEBUG 10h,1,<CONR:$x=$x? >,<dx,CurrSc> | ||
| 575 | cmp dx,[CurrSc] | ||
| 576 | je sjp0 | ||
| 577 | call GetSIBAdr ; get pointer to the SIB | ||
| 578 | DEBUG 10h,1,<Block read wrong screen >,<> | ||
| 579 | call DoPBlock ; block the process | ||
| 580 | jmp short ConRLoop ; test flag again | ||
| 581 | sjp0: | ||
| 582 | call ChrIn | ||
| 583 | stosb | ||
| 584 | ; loop ConRLoop | ||
| 585 | loop jgl3 | ||
| 586 | CRExit: jmp StatusComplete | ||
| 587 | |||
| 588 | jgl3: jmp ConRLoop | ||
| 589 | |||
| 590 | subttl ChrIn - Read a single character In | ||
| 591 | page | ||
| 592 | |||
| 593 | ;------------------------------------------------------------------------ | ||
| 594 | ; Read a single character In | ||
| 595 | ; | ||
| 596 | ; exit: | ||
| 597 | ; Character in AL | ||
| 598 | ; | ||
| 599 | ; modifies: AX | ||
| 600 | ; | ||
| 601 | |||
| 602 | assume ds:NOTHING,es:NOTHING | ||
| 603 | |||
| 604 | ChrIn: | ||
| 605 | DEBUG 10h,1,<in.ChrIn >,<> | ||
| 606 | xor ax,ax | ||
| 607 | xchg al,[AltAH] ; Get Character & zero AltAH | ||
| 608 | or al,al ; A char available? | ||
| 609 | jnz KeyRet | ||
| 610 | ; | ||
| 611 | ;--- NOTE: The blocking on read is done at int 16h level | ||
| 612 | ; in IBMBIO. No need to block here. | ||
| 613 | ; | ||
| 614 | DEBUG 10h,1,< con.do.16 >,<> | ||
| 615 | mov ah,0 ; no, do a read call | ||
| 616 | pushf | ||
| 617 | call DoInt16 | ||
| 618 | ;; int 16h | ||
| 619 | DEBUG 10h,1,< con.got.$x >,<ax> | ||
| 620 | or ax,ax ; check for non-key after BREAK | ||
| 621 | jnz jgl1 | ||
| 622 | jmp chrin | ||
| 623 | |||
| 624 | jgl1: cmp ax,7200h ; CTRL-PRTSC ? | ||
| 625 | jnz sja0 | ||
| 626 | mov al,10h ; yes, make it a ctrl-P | ||
| 627 | sja0: or al,al ; special case? | ||
| 628 | jnz KeyRet | ||
| 629 | mov [AltAH],ah | ||
| 630 | KeyRet: | ||
| 631 | ret | ||
| 632 | |||
| 633 | |||
| 634 | subttl $ConRdnd - Console non-destructive Input, no wait | ||
| 635 | page | ||
| 636 | |||
| 637 | ;------------------------------------------------------------------------ | ||
| 638 | ; Console non-destructive Input, no wait | ||
| 639 | ; | ||
| 640 | ; entry: | ||
| 641 | ; DS:BX = pointer to Request packet | ||
| 642 | ; | ||
| 643 | |||
| 644 | assume ds:NOTHING,es:NOTHING | ||
| 645 | |||
| 646 | $ConRdnd: | ||
| 647 | mov dx,word ptr ds:[bx].START ; get screen number | ||
| 648 | cmp dx,(MaxSIB-1) ; valid number? | ||
| 649 | jbe sjq0 ; yes, do input | ||
| 650 | mov al,0BH ; no, READ FAULT ERROR | ||
| 651 | jmp StatusError | ||
| 652 | sjq0: | ||
| 653 | DEBUG 10h,1,<CNDR:$x=$x? >,<dx,CurrSc> | ||
| 654 | cmp dx,[CurrSc] | ||
| 655 | IFDEF DEBUGFLG | ||
| 656 | je sjq1 | ||
| 657 | jmp ConBus | ||
| 658 | ELSE | ||
| 659 | jne ConBus ; not current screen, no char avail | ||
| 660 | ENDIF | ||
| 661 | ; call GetSIBAdr ; get pointer to the SIB | ||
| 662 | ; call DoPBlock ; block the process | ||
| 663 | ; jmp short sjq0 ; test flag again | ||
| 664 | sjq1: | ||
| 665 | mov al,[AltAH] ; char avail already? | ||
| 666 | or al,al | ||
| 667 | jnz rdExit | ||
| 668 | DEBUG 10h,1,< NRD:do.16 >,<> | ||
| 669 | mov ah,1 ; no, get status | ||
| 670 | int 16h | ||
| 671 | jz ConBus | ||
| 672 | DEBUG 10h,1,< NRD:nonbus $x >,<ax> | ||
| 673 | or ax,ax | ||
| 674 | jnz NotBk ; Check for null after break | ||
| 675 | mov ah,0 ; flush the null | ||
| 676 | int 16h | ||
| 677 | jmp $ConRdnd ; try again | ||
| 678 | ; jmp short $ConRdnd ; try again BUGBUG | ||
| 679 | NotBk: | ||
| 680 | cmp ax,7200h ; CTRL-PRTSC ? | ||
| 681 | jnz rdExit | ||
| 682 | mov al,10h ; yes, make it a ctrl-P | ||
| 683 | rdExit: | ||
| 684 | mov byte ptr ds:[bx].MEDIA,al ; save character | ||
| 685 | DoExit: jmp StatusComplete | ||
| 686 | |||
| 687 | ConBus: DEBUG 10h,1,< ConBus - >,<> | ||
| 688 | jmp StatusDevReady | ||
| 689 | |||
| 690 | |||
| 691 | subttl $ConFlsh - Console Flush Input | ||
| 692 | page | ||
| 693 | |||
| 694 | ;------------------------------------------------------------------------ | ||
| 695 | ; Console Flush Input | ||
| 696 | ; | ||
| 697 | ; entry: | ||
| 698 | ; DS:BX = pointer to Request packet | ||
| 699 | ; | ||
| 700 | |||
| 701 | assume ds:NOTHING,es:NOTHING | ||
| 702 | |||
| 703 | $ConFlsh: | ||
| 704 | mov dx,word ptr ds:[bx].START ; get screen number | ||
| 705 | cmp dx,(MaxSIB-1) ; valid number? | ||
| 706 | jbe sjr0 ; yes, do flush | ||
| 707 | mov al,0BH ; no, READ FAULT ERROR | ||
| 708 | jmp StatusError | ||
| 709 | sjr0: | ||
| 710 | cmp dx,[CurrSc] | ||
| 711 | je sjr1 | ||
| 712 | call GetSIBAdr ; get pointer to the SIB | ||
| 713 | call DoPBlock ; block the process | ||
| 714 | jmp short sjr0 ; test flag again | ||
| 715 | sjr1: | ||
| 716 | mov [AltAH],0 ; clear side bufer | ||
| 717 | push ds | ||
| 718 | mov ax,RomData | ||
| 719 | mov ds,ax | ||
| 720 | assume ds:RomData | ||
| 721 | cli ; Disable interrupts | ||
| 722 | mov ax,offset RomData:KeyBuffer ; Start of Rom buffer | ||
| 723 | mov [BufferHead],ax | ||
| 724 | mov [BufferTail],ax ; Empty the queue | ||
| 725 | sti | ||
| 726 | pop ds | ||
| 727 | assume ds:NOTHING | ||
| 728 | jmp StatusComplete | ||
| 729 | |||
| 730 | |||
| 731 | subttl $ConWrit - Console Output (Write) | ||
| 732 | page | ||
| 733 | |||
| 734 | ;------------------------------------------------------------------------ | ||
| 735 | ; Console Output (Write) | ||
| 736 | ; | ||
| 737 | ; entry: | ||
| 738 | ; DS:BX = pointer to Request packet | ||
| 739 | ; ES:DI = Transfer address | ||
| 740 | ; CX = Count | ||
| 741 | ; | ||
| 742 | |||
| 743 | assume ds:NOTHING,es:NOTHING | ||
| 744 | |||
| 745 | $ConWrit: | ||
| 746 | jcxz CWExit | ||
| 747 | mov dx, word ptr ds:[bx].START ; get screen number | ||
| 748 | cmp dx,(MaxSIB-1) ; valid screen number? | ||
| 749 | jbe sjb0 | ||
| 750 | mov al,0AH ; no, write fault error | ||
| 751 | jmp StatusError | ||
| 752 | sjb0: push cs | ||
| 753 | pop ds | ||
| 754 | assume ds:Code | ||
| 755 | mov bx,[CurrSIB] | ||
| 756 | |||
| 757 | ConWLoop: | ||
| 758 | cmp dx,[CurrSc] ; Is it to the current screen? | ||
| 759 | je sjb2 ; yes, do not block | ||
| 760 | call GetSIBAdr ; get pointer to the SIB | ||
| 761 | sjb1: call DoPBlock ; block the process | ||
| 762 | jmp short ConWLoop ; test ALL flags again | ||
| 763 | sjb2: | ||
| 764 | cmp [bx].ctlS,0 ; is the screen frozen? | ||
| 765 | je sjb3 | ||
| 766 | mov ax,bx ; AX = [CurrSIB] = [CurrSIB].ctlS !!!! | ||
| 767 | jmp short sjb1 ; yes, block the process | ||
| 768 | sjb3: | ||
| 769 | cmp [SaveFlg],0 ; are we in the middle of a save? | ||
| 770 | je sjb4 ; no, do write | ||
| 771 | mov ax,offset SaveFlg | ||
| 772 | jmp short sjb1 ; yes, block... | ||
| 773 | sjb4: | ||
| 774 | mov al,es:[di] ; get a character | ||
| 775 | inc di | ||
| 776 | call CharOut | ||
| 777 | loop ConWLoop | ||
| 778 | CWExit: jmp StatusComplete | ||
| 779 | |||
| 780 | |||
| 781 | subttl CharOut - Output a character to the screen | ||
| 782 | page | ||
| 783 | |||
| 784 | ;------------------------------------------------------------------------ | ||
| 785 | ; Output a character to the screen | ||
| 786 | ; | ||
| 787 | ; entry: | ||
| 788 | ; AL = Character to write | ||
| 789 | ; | ||
| 790 | ; preserves: | ||
| 791 | ; BX, CX, DX, DI, DS & ES | ||
| 792 | ; | ||
| 793 | |||
| 794 | assume ds:NOTHING,es:NOTHING | ||
| 795 | |||
| 796 | IF ANSI | ||
| 797 | include ansi.inc | ||
| 798 | ELSE | ||
| 799 | CharOut: | ||
| 800 | push bx | ||
| 801 | push di | ||
| 802 | mov bx,7 | ||
| 803 | mov ah,14 | ||
| 804 | int 10h ; Write Character | ||
| 805 | pop di | ||
| 806 | pop bx | ||
| 807 | ret | ||
| 808 | ENDIF | ||
| 809 | |||
| 810 | |||
| 811 | subttl $GenIOCTL - Generic IOCTL | ||
| 812 | page | ||
| 813 | |||
| 814 | ;------------------------------------------------------------------------ | ||
| 815 | ; Generic IOCTL | ||
| 816 | ; | ||
| 817 | ; entry: | ||
| 818 | ; DS:BX = pointer to Request packet | ||
| 819 | ; | ||
| 820 | |||
| 821 | ;--- Offsets into the request packet | ||
| 822 | ;*** Check offset are correct | ||
| 823 | FunCode = 14 ; Function Code | ||
| 824 | FunCat = 13 ; Function Category | ||
| 825 | ;*** | ||
| 826 | RegSI = 15 ; Contents of SI | ||
| 827 | RegDI = 17 ; Contents of DI | ||
| 828 | DatBuf = 19 ; Pointer to data buffer | ||
| 829 | |||
| 830 | ;--- Code & Category definitions | ||
| 831 | IOC_SC = 03h ;--- Screen Control | ||
| 832 | IOSC_LS = 41h ; Locate SIB | ||
| 833 | IOSC_SS = 42h ; save segment | ||
| 834 | IOSC_RS = 43h ; restore segment | ||
| 835 | IOSC_EI = 44h ; re-enable i/o | ||
| 836 | IOSC_IS = 45h ; initialize screen | ||
| 837 | |||
| 838 | assume ds:NOTHING,es:NOTHING | ||
| 839 | |||
| 840 | $GenIOCTL: | ||
| 841 | cmp byte ptr ds:[bx].FunCode,IOC_SC | ||
| 842 | jne GI_BadCode ; function not suported | ||
| 843 | mov si,word ptr ds:[bx].RegSI | ||
| 844 | mov al,byte ptr ds:[bx].FunCat | ||
| 845 | cmp al,IOSC_LS | ||
| 846 | jne sjc0 | ||
| 847 | jmp short do_IOSC_LS | ||
| 848 | sjc0: cmp al,IOSC_SS | ||
| 849 | jne sjc1 | ||
| 850 | jmp short do_IOSC_SS | ||
| 851 | sjc1: cmp al,IOSC_RS | ||
| 852 | jne sjc2 | ||
| 853 | jmp do_IOSC_RS | ||
| 854 | sjc2: cmp al,IOSC_EI | ||
| 855 | jne sjc3 | ||
| 856 | jmp do_IOSC_EI | ||
| 857 | sjc3: cmp al,IOSC_IS | ||
| 858 | jne GI_BadCode | ||
| 859 | jmp do_IOSC_IS | ||
| 860 | |||
| 861 | GI_BadCode: | ||
| 862 | jmp CmdErr ; error exit: Command error | ||
| 863 | |||
| 864 | |||
| 865 | subttl do_IOSC_LS - Locate SIB | ||
| 866 | page | ||
| 867 | |||
| 868 | ;------------------------------------------------------------------------ | ||
| 869 | ; Locate SIB | ||
| 870 | ; | ||
| 871 | ; entry: | ||
| 872 | ; SI = SIB Number | ||
| 873 | ; DS:BX = pointer to Request packet | ||
| 874 | ; | ||
| 875 | |||
| 876 | assume ds:NOTHING,es:NOTHING | ||
| 877 | |||
| 878 | do_IOSC_LS: | ||
| 879 | cmp si,(MaxSIB-1) ; index within range? | ||
| 880 | ja BadNum | ||
| 881 | push bx | ||
| 882 | push ds | ||
| 883 | push cs | ||
| 884 | pop ds | ||
| 885 | assume ds:Code | ||
| 886 | cmp si,[CurrSc] ; is it the current screen? | ||
| 887 | je CurrLS | ||
| 888 | mov [CurrSc],si ; no, just switch curr screens | ||
| 889 | mov dx,si ; index | ||
| 890 | call GetSIBAdr ; get pointer to SIB | ||
| 891 | mov [CurrSIB],ax ; save pointer to curr SIB | ||
| 892 | jmp short retLS | ||
| 893 | |||
| 894 | CurrLS: | ||
| 895 | mov [SaveFlg],1 ; Signal we are Saving the screen | ||
| 896 | |||
| 897 | ;*** Only one segment for now | ||
| 898 | |||
| 899 | mov ax,0 | ||
| 900 | call GetSegAdr ; on return BX points to segment | ||
| 901 | mov ax,RomData | ||
| 902 | mov es,ax | ||
| 903 | assume es:RomData | ||
| 904 | IF EAGLE | ||
| 905 | mov al,es:[CRT_MODE] | ||
| 906 | xor ah,ah | ||
| 907 | mov si,ax | ||
| 908 | mov ah,ScreenLen[si] | ||
| 909 | xor al,al | ||
| 910 | ELSE | ||
| 911 | mov ax,es:[CRT_LEN] | ||
| 912 | assume es:NOTHING ; not true, but just to be safe | ||
| 913 | ENDIF | ||
| 914 | mov [bx].SizeNeeded,ax ; save size of segment | ||
| 915 | mov ax,dx ; pointer to current SIB | ||
| 916 | retLS: | ||
| 917 | pop ds | ||
| 918 | pop bx | ||
| 919 | assume ds:NOTHING | ||
| 920 | mov word ptr ds:[bx].DatBuf,ax ; offset | ||
| 921 | mov word ptr ds:[bx].DatBuf+2,cs ; segment | ||
| 922 | mov word ptr ds:[bx].RegSI,0 ; operation ok | ||
| 923 | jmp StatusComplete | ||
| 924 | |||
| 925 | BadNum: | ||
| 926 | mov word ptr ds:[bx].RegSI,1 ; bad SIB number error | ||
| 927 | jmp StatusComplete | ||
| 928 | |||
| 929 | |||
| 930 | subttl do_IOSC_SS - Save Segment | ||
| 931 | page | ||
| 932 | |||
| 933 | ;------------------------------------------------------------------------ | ||
| 934 | ; Save Segment | ||
| 935 | ; | ||
| 936 | ; entry: | ||
| 937 | ; SI = Segment Index (into the Current SIB) | ||
| 938 | ; DS:BX = pointer to Request packet | ||
| 939 | ; | ||
| 940 | |||
| 941 | assume ds:NOTHING,es:NOTHING | ||
| 942 | |||
| 943 | do_IOSC_SS: | ||
| 944 | cmp si,(MaxSeg-1) ; within range? | ||
| 945 | BadNumJ1: | ||
| 946 | ja BadNum ; no, somebody screwed up... | ||
| 947 | push bx | ||
| 948 | push ds | ||
| 949 | cmp si,0 ; first segment save? | ||
| 950 | jne nfSS ; no, just save screen data | ||
| 951 | ;--- save screen state data | ||
| 952 | push si ; save index | ||
| 953 | mov ax,RomData | ||
| 954 | mov ds,ax ; DS = ROM data area | ||
| 955 | assume ds:RomData | ||
| 956 | mov si,offset RomData:CRT_MODE | ||
| 957 | mov cx,CrtLen ; length of screen state data | ||
| 958 | push cs | ||
| 959 | pop es | ||
| 960 | assume es:Code | ||
| 961 | mov di,[CurrSIB] | ||
| 962 | lea di,[di].xCRT_MODE | ||
| 963 | cld | ||
| 964 | rep movsb ; copy ROM info to SIB area | ||
| 965 | IF ANSI | ||
| 966 | push cs | ||
| 967 | pop ds | ||
| 968 | assume ds:Code | ||
| 969 | mov si,offset AnsiState ; point to ANSI state info | ||
| 970 | mov cx,AnsiSize | ||
| 971 | rep movsb ; save ANSI state info in SIB | ||
| 972 | ENDIF | ||
| 973 | pop si ; restore segment index | ||
| 974 | ;--- save a segment of screen data | ||
| 975 | nfSS: | ||
| 976 | push cs | ||
| 977 | pop ds | ||
| 978 | assume ds:Code | ||
| 979 | mov ax,si | ||
| 980 | call GetSegAdr ; get adress of segment and curr SIB ptr | ||
| 981 | mov cx,[bx].SizeNeeded ; CX = Ammount to transfer | ||
| 982 | shr cx,1 ; words! | ||
| 983 | les di,[bx].MPointer ; ES:DI = Screen save area | ||
| 984 | assume es:NOTHING | ||
| 985 | |||
| 986 | ;*** For now we are using only one segment | ||
| 987 | |||
| 988 | mov si,dx ; SI points to the current SIB | ||
| 989 | mov bx,ColorSc ; assume color card | ||
| 990 | cmp [si].xCRT_MODE,7 ; is this a BW monitor? | ||
| 991 | jne do_save | ||
| 992 | mov bx,MonoSc | ||
| 993 | do_save: | ||
| 994 | IF BLANK | ||
| 995 | mov dx,[si].xADDR_6845 ; point to mode register | ||
| 996 | add dx,4 | ||
| 997 | mov al,[si].xCRT_MODE_SET ; and get value | ||
| 998 | and al,NOT 8 | ||
| 999 | out dx,al ; turn off video | ||
| 1000 | ENDIF | ||
| 1001 | mov ds,bx ; DS points to apropiate screen area | ||
| 1002 | assume ds:NOTHING | ||
| 1003 | mov si,0 | ||
| 1004 | cld | ||
| 1005 | rep movsw ; copy the screen | ||
| 1006 | IF BLANK | ||
| 1007 | or al,8 | ||
| 1008 | out dx,al ; turn on video | ||
| 1009 | ENDIF | ||
| 1010 | pop ds | ||
| 1011 | pop bx | ||
| 1012 | mov word ptr ds:[bx].RegSI,0 ; operation ok | ||
| 1013 | jmp StatusComplete | ||
| 1014 | |||
| 1015 | |||
| 1016 | subttl do_IOSC_RS - Restore Segment | ||
| 1017 | page | ||
| 1018 | |||
| 1019 | ;------------------------------------------------------------------------ | ||
| 1020 | ; Restore Segment | ||
| 1021 | ; | ||
| 1022 | ; entry: | ||
| 1023 | ; SI = Segment Index (into the Current SIB) | ||
| 1024 | ; DS:BX = pointer to Request packet | ||
| 1025 | ; | ||
| 1026 | |||
| 1027 | assume ds:NOTHING,es:NOTHING | ||
| 1028 | |||
| 1029 | do_IOSC_RS: | ||
| 1030 | cmp si,(MaxSeg-1) ; within range? | ||
| 1031 | ja BadNumJ1 ; no, somebody screwed up... | ||
| 1032 | push bx | ||
| 1033 | push ds | ||
| 1034 | push cs | ||
| 1035 | pop ds | ||
| 1036 | assume ds:Code | ||
| 1037 | cmp si,0 ; first segment save? | ||
| 1038 | jne nfRS ; no, just restore screen data | ||
| 1039 | ;--- restore screen state data | ||
| 1040 | push si ; save index | ||
| 1041 | mov si,[CurrSIB] | ||
| 1042 | push si | ||
| 1043 | lea si,[si].xCRT_MODE | ||
| 1044 | mov ax,RomData | ||
| 1045 | mov es,ax ; ES = ROM data area | ||
| 1046 | assume es:RomData | ||
| 1047 | mov cx,CrtLen ; length of screen state data | ||
| 1048 | mov di,offset RomData:CRT_MODE | ||
| 1049 | cld | ||
| 1050 | rep movsb ; copy ROM info from SIB area | ||
| 1051 | IF ANSI | ||
| 1052 | push es | ||
| 1053 | push cs | ||
| 1054 | pop es | ||
| 1055 | assume es:Code | ||
| 1056 | mov di,offset AnsiState ; point to ANSI state info | ||
| 1057 | mov cx,AnsiSize | ||
| 1058 | rep movsb ; restore ANSI state info from SIB | ||
| 1059 | pop es | ||
| 1060 | assume es:RomData | ||
| 1061 | ENDIF | ||
| 1062 | |||
| 1063 | ;--- Setup new screen state | ||
| 1064 | pop si | ||
| 1065 | mov al,[si].xCRT_MODE | ||
| 1066 | cmp al,7 ; is this the BW monitor? | ||
| 1067 | jne sjd0 | ||
| 1068 | mov al,2 ; this is the "real" mode | ||
| 1069 | sjd0: | ||
| 1070 | mov ah,0 | ||
| 1071 | int 10h ; set new mode | ||
| 1072 | mov cx,[si].xCURSOR_MODE | ||
| 1073 | mov ah,1 | ||
| 1074 | int 10h ; set cursor type | ||
| 1075 | mov dx,[si].xCURSOR_POSN | ||
| 1076 | mov bh,[si].xACTIVE_PAGE | ||
| 1077 | mov ah,2 | ||
| 1078 | int 10h ; set cursor position | ||
| 1079 | mov al,[si].xACTIVE_PAGE | ||
| 1080 | mov ah,5 | ||
| 1081 | int 10h ; set page # | ||
| 1082 | mov dx,[si].xADDR_6845 | ||
| 1083 | add dx,5 | ||
| 1084 | mov al,[si].xCRT_PALETTE | ||
| 1085 | out dx,al ; set color port | ||
| 1086 | mov es:CRT_PALETTE,al | ||
| 1087 | pop si ; restore segment index | ||
| 1088 | ;--- restore a segment of screen data | ||
| 1089 | nfRS: | ||
| 1090 | mov ax,si | ||
| 1091 | call GetSegAdr ; get adress of segment | ||
| 1092 | mov cx,[bx].SizeNeeded ; CX = Ammount to transfer | ||
| 1093 | shr cx,1 ; words! | ||
| 1094 | lds si,[bx].MPointer ; DS:SI = Screen save area | ||
| 1095 | assume ds:NOTHING | ||
| 1096 | |||
| 1097 | ;*** For now we are using only one segment | ||
| 1098 | |||
| 1099 | mov di,dx ; DI points to the current SIB | ||
| 1100 | mov bx,ColorSc ; assume color card | ||
| 1101 | cmp cs:[di].xCRT_MODE,7 ; is this a BW monitor? | ||
| 1102 | jne do_rest | ||
| 1103 | mov bx,MonoSc | ||
| 1104 | do_rest: | ||
| 1105 | IF BLANK | ||
| 1106 | mov dx,cs:[di].xADDR_6845 ; point to mode register | ||
| 1107 | add dx,4 | ||
| 1108 | mov al,cs:[di].xCRT_MODE_SET ; and get value | ||
| 1109 | and al,NOT 8 | ||
| 1110 | out dx,al ; turn off video | ||
| 1111 | ENDIF | ||
| 1112 | mov es,bx ; ES points to apropiate screen area | ||
| 1113 | assume es:NOTHING | ||
| 1114 | mov di,0 | ||
| 1115 | cld | ||
| 1116 | rep movsw ; copy the screen | ||
| 1117 | IF BLANK | ||
| 1118 | or al,8 | ||
| 1119 | out dx,al ; turn on video | ||
| 1120 | ENDIF | ||
| 1121 | |||
| 1122 | pop ds | ||
| 1123 | assume ds:NOTHING | ||
| 1124 | pop bx | ||
| 1125 | mov word ptr ds:[bx].RegSI,0 ; operation ok | ||
| 1126 | jmp StatusComplete | ||
| 1127 | |||
| 1128 | BadNumJ: | ||
| 1129 | jmp BadNum | ||
| 1130 | |||
| 1131 | |||
| 1132 | subttl do_IOSC_EI - Re-enable i/o | ||
| 1133 | page | ||
| 1134 | |||
| 1135 | ;------------------------------------------------------------------------ | ||
| 1136 | ; Re-enable i/o | ||
| 1137 | ; | ||
| 1138 | ; entry: | ||
| 1139 | ; DS:BX = pointer to Request packet | ||
| 1140 | ; | ||
| 1141 | |||
| 1142 | assume ds:NOTHING,es:NOTHING | ||
| 1143 | |||
| 1144 | do_IOSC_EI: | ||
| 1145 | mov [SaveFlg],0 ; Signal we are done Saving the screen | ||
| 1146 | mov ax,offset Code:SaveFlg | ||
| 1147 | call DoPRun ; ProcRun | ||
| 1148 | mov ax,[CurrSIB] ; pointer to current SIB | ||
| 1149 | call DoPRun ; ProcRun any output blocked because | ||
| 1150 | ; screen was not current | ||
| 1151 | jmp StatusComplete | ||
| 1152 | |||
| 1153 | |||
| 1154 | subttl do_IOSC_IS - Initialize Screen | ||
| 1155 | page | ||
| 1156 | |||
| 1157 | ;------------------------------------------------------------------------ | ||
| 1158 | ; Initialize Screen | ||
| 1159 | ; | ||
| 1160 | ; entry: | ||
| 1161 | ; SI = SIB Number | ||
| 1162 | ; DS:BX = pointer to Request packet | ||
| 1163 | ; | ||
| 1164 | |||
| 1165 | assume ds:NOTHING,es:NOTHING | ||
| 1166 | |||
| 1167 | do_IOSC_IS: | ||
| 1168 | cmp si,(MaxSIB-1) ; index within range? | ||
| 1169 | ja BadNumJ | ||
| 1170 | push ds | ||
| 1171 | push cs | ||
| 1172 | pop ds | ||
| 1173 | assume ds:Code | ||
| 1174 | mov [CurrSc],si ; switch curr screens | ||
| 1175 | mov dx,si ; index | ||
| 1176 | call GetSIBAdr ; get pointer to SIB | ||
| 1177 | mov [CurrSIB],ax ; save pointer to curr SIB | ||
| 1178 | mov si,ax | ||
| 1179 | mov [si].ctlS,0 ; screen not frozen | ||
| 1180 | ;--- set screen mode to pc mode 3 (80x25 BW) | ||
| 1181 | mov ax,0003 ; Set mode 3 | ||
| 1182 | int 10h | ||
| 1183 | pop ds | ||
| 1184 | assume ds:NOTHING | ||
| 1185 | mov word ptr ds:[bx].RegSI,0 ; operation ok | ||
| 1186 | jmp StatusComplete | ||
| 1187 | |||
| 1188 | |||
| 1189 | subttl $ConStop - Stop (freeze) console output | ||
| 1190 | page | ||
| 1191 | |||
| 1192 | ;------------------------------------------------------------------------ | ||
| 1193 | ; Stop (freeze) console output | ||
| 1194 | ; | ||
| 1195 | |||
| 1196 | assume ds:NOTHING,es:NOTHING | ||
| 1197 | |||
| 1198 | $ConStop: | ||
| 1199 | mov bx,[CurrSIB] ; pointer to current SIB | ||
| 1200 | mov cs:[bx].ctlS,01 ; set the freeze flag | ||
| 1201 | jmp StatusComplete | ||
| 1202 | |||
| 1203 | |||
| 1204 | subttl $ConStart - Start (continue) console output | ||
| 1205 | page | ||
| 1206 | |||
| 1207 | ;------------------------------------------------------------------------ | ||
| 1208 | ; Start (continue) console output | ||
| 1209 | ; | ||
| 1210 | |||
| 1211 | assume ds:NOTHING,es:NOTHING | ||
| 1212 | |||
| 1213 | $ConStart: | ||
| 1214 | mov bx,[CurrSIB] ; pointer to current SIB | ||
| 1215 | cmp cs:[bx].ctlS,0 ; is it already going? | ||
| 1216 | je csRet ; yes, no need to re-enable | ||
| 1217 | mov cs:[bx].ctlS,0 ; reset the freeze flag | ||
| 1218 | lea ax,[bx].ctlS ; get address of current ctlS | ||
| 1219 | call DoPRun ; do ProcRun | ||
| 1220 | csRet: jmp StatusComplete | ||
| 1221 | |||
| 1222 | |||
| 1223 | subttl DoPBlock - Block the current process | ||
| 1224 | page | ||
| 1225 | |||
| 1226 | ;------------------------------------------------------------------------ | ||
| 1227 | ; Block the current process | ||
| 1228 | ; | ||
| 1229 | ; entry: | ||
| 1230 | ; CS:AX = address to block on | ||
| 1231 | ; | ||
| 1232 | ; modifies: AX, FLAGS | ||
| 1233 | ; | ||
| 1234 | |||
| 1235 | assume ds:NOTHING,es:NOTHING | ||
| 1236 | |||
| 1237 | DoPBlock: | ||
| 1238 | push bx | ||
| 1239 | push cx | ||
| 1240 | push dx | ||
| 1241 | mov bx,ax | ||
| 1242 | mov ax,cs ; AX:BX = event identifier | ||
| 1243 | xor cx,cx ; No timeout | ||
| 1244 | ;; mov dx,0109h ;;BUGBUG - should be interruptible wait; will | ||
| 1245 | ;; give InternalError (SchedFind - not on Q) | ||
| 1246 | mov dx,0009h ; PROCBLOC function | ||
| 1247 | cli ; No races! | ||
| 1248 | call [DosFunction] | ||
| 1249 | pop dx ; on return ints are back on | ||
| 1250 | pop cx | ||
| 1251 | pop bx | ||
| 1252 | ret | ||
| 1253 | |||
| 1254 | |||
| 1255 | subttl DoPRun - Restart a process | ||
| 1256 | page | ||
| 1257 | |||
| 1258 | ;------------------------------------------------------------------------ | ||
| 1259 | ; Restart a process | ||
| 1260 | ; | ||
| 1261 | ; entry: | ||
| 1262 | ; CS:AX = address to signal on (same as blocked on) | ||
| 1263 | ; | ||
| 1264 | ; modifies: AX, FLAGS | ||
| 1265 | ; | ||
| 1266 | |||
| 1267 | assume ds:NOTHING,es:NOTHING | ||
| 1268 | |||
| 1269 | DoPRun: | ||
| 1270 | push bx | ||
| 1271 | push cx | ||
| 1272 | push dx | ||
| 1273 | mov bx,ax | ||
| 1274 | mov ax,cs | ||
| 1275 | mov dx,10 ; PROCRUN function | ||
| 1276 | call [DosFunction] | ||
| 1277 | pop dx | ||
| 1278 | pop cx | ||
| 1279 | pop bx | ||
| 1280 | ret | ||
| 1281 | |||
| 1282 | |||
| 1283 | subttl GetSIBAdr - Return SIB address | ||
| 1284 | page | ||
| 1285 | |||
| 1286 | ;------------------------------------------------------------------------ | ||
| 1287 | ; Returns the adress of the specified SIB | ||
| 1288 | ; | ||
| 1289 | ; entry: | ||
| 1290 | ; DX = index to the SIB | ||
| 1291 | ; | ||
| 1292 | ; exit: | ||
| 1293 | ; AX = pointer to the SIB | ||
| 1294 | ; | ||
| 1295 | ; preserves: ALL | ||
| 1296 | ; | ||
| 1297 | |||
| 1298 | assume ds:Code,es:NOTHING | ||
| 1299 | |||
| 1300 | GetSIBAdr: | ||
| 1301 | push dx ; save screen # | ||
| 1302 | mov ax,dx ; index | ||
| 1303 | mov dx,(SIZE SIBst) | ||
| 1304 | mul dx ; multiply by size of SIB entry | ||
| 1305 | pop dx ; restore screen # | ||
| 1306 | add ax,offset SIB ; AX = pointer to SIB for the write | ||
| 1307 | ret | ||
| 1308 | |||
| 1309 | |||
| 1310 | subttl GetSegAdr - Return segment address | ||
| 1311 | page | ||
| 1312 | |||
| 1313 | ;------------------------------------------------------------------------ | ||
| 1314 | ; Returns the adress of a segment in the current SIB | ||
| 1315 | ; | ||
| 1316 | ; entry: | ||
| 1317 | ; AX = index to the segment | ||
| 1318 | ; | ||
| 1319 | ; exit: | ||
| 1320 | ; BX = pointer to the segment | ||
| 1321 | ; DX = pointer to the Current SIB | ||
| 1322 | ; | ||
| 1323 | |||
| 1324 | assume ds:Code,es:NOTHING | ||
| 1325 | |||
| 1326 | GetSegAdr: | ||
| 1327 | mov dx,(SIZE SEGst) | ||
| 1328 | mul dx ; multiply by size of SEG entry | ||
| 1329 | mov bx,[CurrSIB] ; pointer to SIB | ||
| 1330 | mov dx,bx ; save for exit | ||
| 1331 | mov bx,[bx].OffsetVal ; pointer to start of SEGs in SIB | ||
| 1332 | add bx,ax ; BX = pointer to SEG from start of SIB | ||
| 1333 | add bx,dx ; BX = absolute pointer to SEG to use | ||
| 1334 | ret | ||
| 1335 | |||
| 1336 | ifdef DEBUGFLG | ||
| 1337 | if NOT INBIOS | ||
| 1338 | INCLUDE BUGCODE.INC | ||
| 1339 | endif | ||
| 1340 | endif | ||
| 1341 | |||
| 1342 | |||
| 1343 | subttl $ConInit - Initialization Routine | ||
| 1344 | page | ||
| 1345 | |||
| 1346 | ;------------------------------------------------------------------------ | ||
| 1347 | ; Initialization Routine | ||
| 1348 | ; | ||
| 1349 | ;entry: | ||
| 1350 | ; DS:BX = pointer to Request packet | ||
| 1351 | ; ES:DI = Dos Functions entry point address | ||
| 1352 | ; | ||
| 1353 | |||
| 1354 | assume ds:NOTHING,es:NOTHING | ||
| 1355 | |||
| 1356 | $ConInit: | ||
| 1357 | IF NOT INBIOS | ||
| 1358 | push ds ; print greeting | ||
| 1359 | push cs | ||
| 1360 | pop ds | ||
| 1361 | mov dx,offset Intro | ||
| 1362 | MOV ah,9 | ||
| 1363 | int 21h | ||
| 1364 | pop ds | ||
| 1365 | mov word ptr ds:[bx].TRANS, offset $ConInit | ||
| 1366 | mov word ptr ds:[bx].TRANS+2,cs | ||
| 1367 | ENDIF | ||
| 1368 | mov cs:Word Ptr DosFunction,di ; Save pointer to service routines | ||
| 1369 | mov cs:Word Ptr DosFunction+2,es | ||
| 1370 | |||
| 1371 | mov ax,0 | ||
| 1372 | mov cx,1 | ||
| 1373 | mov dx,16 | ||
| 1374 | call [DosFunction] ; get DOS variable ScrnIoOk | ||
| 1375 | mov word ptr ScrnIoOk,ax | ||
| 1376 | mov word ptr ScrnIoOk+2,dx | ||
| 1377 | |||
| 1378 | ;* Initialize interrupt vectors. | ||
| 1379 | ;;BUGBUG - we should be using Get/Set_Interrupt_Vector calls | ||
| 1380 | |||
| 1381 | xor ax,ax ; initialize break interrupt handler | ||
| 1382 | mov es,ax ; points to page 0 | ||
| 1383 | mov ax,cs | ||
| 1384 | mov word ptr es:BRKADR,offset Break | ||
| 1385 | mov word ptr es:BRKADR+2,ax ; Vector for Break | ||
| 1386 | |||
| 1387 | MOV DI,9*4 ; INT 9 - Keyboard interrupt vector | ||
| 1388 | MOV CX,es:[DI] ; Save old addr to hook to | ||
| 1389 | MOV WORD PTR OldKeyInterrupt,CX | ||
| 1390 | MOV CX,es:2[DI] | ||
| 1391 | MOV WORD PTR (OldKeyInterrupt+2),CX | ||
| 1392 | MOV CX,OFFSET KeyboardInterrupt | ||
| 1393 | XCHG AX,CX | ||
| 1394 | STOSW | ||
| 1395 | XCHG AX,CX | ||
| 1396 | STOSW ; Set new keyboard interrupt | ||
| 1397 | |||
| 1398 | mov di,16h*4 ; INT 16 - keyboard input | ||
| 1399 | MOV CX,es:[DI] ; Save INT 16 addr to hook to | ||
| 1400 | MOV WORD PTR OldKbdHandler,CX | ||
| 1401 | MOV CX,es:2[DI] | ||
| 1402 | MOV WORD PTR (OldKbdHandler+2),CX | ||
| 1403 | MOV CX,OFFSET KeyboardHandler | ||
| 1404 | XCHG AX,CX | ||
| 1405 | STOSW | ||
| 1406 | XCHG AX,CX ; Set new keyboard Handler | ||
| 1407 | STOSW | ||
| 1408 | jmp StatusComplete | ||
| 1409 | |||
| 1410 | |||
| 1411 | IF INBIOS | ||
| 1412 | Code ends | ||
| 1413 | |||
| 1414 | BiosInit segment para public 'CODE' | ||
| 1415 | ENDIF | ||
| 1416 | |||
| 1417 | Intro db "--- Installing MTCON Device Driver V" | ||
| 1418 | db CVERS+"0",".",CREV/10+"0" | ||
| 1419 | db (CREV-CREV/10*10)+"0"," ---" | ||
| 1420 | db 13,10,"$" | ||
| 1421 | |||
| 1422 | BiosInit ends | ||
| 1423 | |||
| 1424 | END | ||