summaryrefslogtreecommitdiff
path: root/v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM')
-rw-r--r--v4.0-ozzie/bin/DISK2/BIOS/IBMMTCON.ASM1424
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
54FALSE EQU 0
55TRUE EQU NOT FALSE
56
57CVERS equ 01 ; update version number!!
58CREV equ 08
59
60BLANK equ TRUE ; blank screen during data r/w
61INBIOS equ TRUE ; link with BIOS
62ANSI equ TRUE ; include ANSI escape sequences
63 LINE25 equ TRUE ; special 25th line like VT52
64EAGLE equ TRUE ; Eagle PC ROM botches CRT_LEN
65
66
67subttl Screen Information Block Definition
68page
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;------------------------------------------------------------------------
79MaxSEG equ 2 ; NOTE: assumption is made in the
80 ; code that all SIB's have same
81 ; number os SEGs
82SEGst struc
83SizeNeeded dw 0 ; needed size for seg, (0 = unused)
84MemFlag dw ? ; maintened by system (0 = in mem)
85MPointer dd ? ; vaild iff MemFlag == 0
86SEGst ends
87
88;------------------------------------------------------------------------
89MaxSIB equ 8 ; maximum number of Screens
90
91
92IF ANSI
93TermSize EQU 20 ; max. size of terminal emulation state
94ENDIF
95
96SIBst struc
97ctlS db 0 ; if the screen is NOT frozen = 0
98 ; NOTE: this field should be the
99 ; FIRST of each SIB !! (see ConWrit)
100OffsetVal dw 7 ; start of Seg Descriptors
101SegCnt dw MaxSeg ; max number of Segments
102SIBlen dw (SIZE SIBst) ; length of the SIB
103;--- Segments
104 db ((SIZE SEGst) * MaxSeg) dup (?)
105;--- PC video state info
106xCRT_MODE DB ?
107xCRT_COLS DW ?
108xCRT_LEN DW ?
109xCRT_START DW ?
110xCURSOR_POSN DW 8 DUP(?)
111xCURSOR_MODE DW ?
112xACTIVE_PAGE DB ?
113xADDR_6845 DW ?
114xCRT_MODE_SET DB ?
115xCRT_PALETTE DB ?
116xTERM_STATE DB TermSize DUP(?)
117SIBst ends
118
119
120subttl Request packet definitions
121page
122
123;------------------------------------------------------------------------
124; Request packet offset definitions
125;
126
127CMDLEN = 0 ;LENGTH OF THIS COMMAND
128UNIT = 1 ;SUB UNIT SPECIFIER
129CMD = 2 ;COMMAND CODE
130STATUS = 3 ;STATUS
131MEDIA = 13 ;MEDIA DESCRIPTOR
132TRANS = 14 ;TRANSFER ADDRESS
133COUNT = 18 ;COUNT OF BLOCKS OR CHARACTERS
134START = 20 ;FIRST BLOCK TO TRANSFER
135
136
137subttl IBM-PC ROM Data area Locations
138page
139
140;------------------------------------------------------------------------
141; IBM-PC ROM Data area Locations
142;
143
144RomData SEGMENT AT 40H
145 ORG 1AH
146BufferHead DW ?
147BufferTail DW ?
148KeyBuffer DW 16 DUP (?)
149KeyBufLen equ ($-KeyBuffer) ; length of KeyBuffer
150
151 ORG 49H
152CRT_MODE DB ?
153CRT_COLS DW ?
154CRT_LEN DW ?
155CRT_START DW ?
156CURSOR_POSN DW 8 DUP(?)
157CURSOR_MODE DW ?
158ACTIVE_PAGE DB ?
159ADDR_6845 DW ?
160CRT_MODE_SET DB ?
161CRT_PALETTE DB ?
162
163CrtLen EQU ($-CRT_MODE) ; length of screen state area
164RomData ENDS
165
166MonoSc SEGMENT AT 0B000H
167;--- 4k of screen memory
168MonoSc ENDS
169
170ColorSc SEGMENT AT 0B800H
171;--- 16k of screen memory
172ColorSc ENDS
173
174BRKADR equ 006CH ; Break vector address
175
176
177subttl Device Header
178page
179
180
181BiosSeg group Code,BiosInit
182Code Segment byte public 'CODE'
183
184;------------------------------------------------------------------------
185; Device Header
186;
187
188assume cs:Code,ds:NOTHING,es:NOTHING,ss:NOTHING
189
190 PUBLIC CONDEV
191IF INBIOS
192 extrn AUXDEV:FAR
193CONDEV dd AUXDEV
194ELSE
195CONDEV dw 0FFFFh,0FFFFh
196ENDIF ;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
208ComTbl:
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
232ComTblEnd:
233
234CTSIZE equ (ComTblEnd - ComTbl)/2 ; number of table entries
235
236
237subttl Device Data Area
238page
239
240;------------------------------------------------------------------------
241; Device Data Area
242;
243
244SaveFlg db 0 ; Screen being saved flag, (true = 1)
245IF INBIOS
246 EXTRN DosFunction:DWORD
247ELSE
248DosFunction dd ? ; pointer to dos "helper" functions
249ENDIF ;INBIOS
250AltAH db 0 ; Side buffer for input
251CurrSc dw 0 ; Current screen number
252CurrSIB dw SIB ; offset to the current SIB
253SIB SIBst MaxSIB dup (<>) ; allocate room for SIB's
254
255IF EAGLE
256ScreenLen 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
264ENDIF
265
266
267IFDEF DEBUGFLG
268IF INBIOS
269 EXTRN BUGBITS:BYTE,DPRINTF:NEAR
270ELSE
271BUGBITS db 0ffh,0ffh
272ENDIF
273ENDIF
274
275subttl Device Entry Points
276page
277
278;------------------------------------------------------------------------
279; 2.0 Interrupt Routine (Not Used)
280;
281
282EntryP proc far
283Entry: ret
284EntryP endp
285
286
287;------------------------------------------------------------------------
288; 2.0 Strategy Routine, main entry point
289;
290; entry
291; ES:BX points to Request packet
292;
293
294StratP proc far
295
296Strategy:
297IF INBIOS
298 extrn Interrupt:NEAR
299
300 push si
301 mov si,OFFSET CS:ComTbl
302 jmp Interrupt
303ELSE
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
328ENDIF ;INBIOS
329
330StratP endp
331
332
333subttl Exit Routines
334page
335
336;------------------------------------------------------------------------
337; Exit Routines, Common to all device functions
338;
339
340IF INBIOS
341 extrn StatusComplete:NEAR,StatusError:NEAR,StatusDevReady:NEAR
342 extrn CmdErr:NEAR
343ELSE
344
345assume ds:NOTHING,es:NOTHING
346
347StatusDevReady:
348 mov ah,00000011b ; device busy
349 jmp short errEx
350
351CmdErr:
352 mov al,3 ; Unknown command Error
353StatusError:
354 mov ah,10000001b
355 jmp short errEx
356
357ExitP proc far
358StatusComplete: mov ah,00000001b
359errEx: 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
372ExitP endp
373
374ENDIF ;INBIOS
375
376
377subttl Break - Break interrupt routine
378page
379
380;------------------------------------------------------------------------
381; Break interrupt routine
382;
383
384assume ds:NOTHING,es:NOTHING
385
386Break 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
401brk1:
402 iret
403Break ENDP
404
405SUBTTL Keyboard interrupt routine
406PAGE
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
417OldKeyInterrupt DD ?
418KeySem db 0 ; non-zero if someone waiting on input
419
420KeyboardInterrupt 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)
438kbi1:
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
445kbi2:
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
462NoKey:
463 IRET
464KeyBoardInterrupt 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
482OldKbdHandler dd ?
483ScrnIoOk dd ?
484
485;-------------------------------------------------------------
486
487KeyBoardHandler proc far
488 or ah,ah
489 je DoLocalRead
490 cmp ah,1
491 je DoLocalStat
492OldKBint:
493 jmp [OldKbdHandler]
494
495DoLocalStat:
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
505DoInt16 LABEL FAR ; entry for ChrIn
506DoLocalRead:
507 push ax
508 push bx
509 push cx
510 push dx
511DoLocalRd1:
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
523DoLocalRd2:
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
538LocalRead:
539 pop dx
540 pop cx
541 pop bx
542 pop ax
543 jmp [OldKbdHandler] ; read the character and return
544
545KeyBoardHandler endp
546
547
548subttl $ConRead - Console Input (Read)
549page
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
560assume 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
567jgl2: 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
573ConRLoop:
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
581sjp0:
582 call ChrIn
583 stosb
584; loop ConRLoop
585 loop jgl3
586CRExit: jmp StatusComplete
587
588jgl3: jmp ConRLoop
589
590subttl ChrIn - Read a single character In
591page
592
593;------------------------------------------------------------------------
594; Read a single character In
595;
596; exit:
597; Character in AL
598;
599; modifies: AX
600;
601
602assume ds:NOTHING,es:NOTHING
603
604ChrIn:
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
624jgl1: cmp ax,7200h ; CTRL-PRTSC ?
625 jnz sja0
626 mov al,10h ; yes, make it a ctrl-P
627sja0: or al,al ; special case?
628 jnz KeyRet
629 mov [AltAH],ah
630KeyRet:
631 ret
632
633
634subttl $ConRdnd - Console non-destructive Input, no wait
635page
636
637;------------------------------------------------------------------------
638; Console non-destructive Input, no wait
639;
640; entry:
641; DS:BX = pointer to Request packet
642;
643
644assume 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
652sjq0:
653 DEBUG 10h,1,<CNDR:$x=$x? >,<dx,CurrSc>
654 cmp dx,[CurrSc]
655IFDEF DEBUGFLG
656 je sjq1
657 jmp ConBus
658ELSE
659 jne ConBus ; not current screen, no char avail
660ENDIF
661; call GetSIBAdr ; get pointer to the SIB
662; call DoPBlock ; block the process
663; jmp short sjq0 ; test flag again
664sjq1:
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
679NotBk:
680 cmp ax,7200h ; CTRL-PRTSC ?
681 jnz rdExit
682 mov al,10h ; yes, make it a ctrl-P
683rdExit:
684 mov byte ptr ds:[bx].MEDIA,al ; save character
685DoExit: jmp StatusComplete
686
687ConBus: DEBUG 10h,1,< ConBus - >,<>
688 jmp StatusDevReady
689
690
691subttl $ConFlsh - Console Flush Input
692page
693
694;------------------------------------------------------------------------
695; Console Flush Input
696;
697; entry:
698; DS:BX = pointer to Request packet
699;
700
701assume 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
709sjr0:
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
715sjr1:
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
731subttl $ConWrit - Console Output (Write)
732page
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
743assume 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
752sjb0: push cs
753 pop ds
754 assume ds:Code
755 mov bx,[CurrSIB]
756
757ConWLoop:
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
761sjb1: call DoPBlock ; block the process
762 jmp short ConWLoop ; test ALL flags again
763sjb2:
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
768sjb3:
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...
773sjb4:
774 mov al,es:[di] ; get a character
775 inc di
776 call CharOut
777 loop ConWLoop
778CWExit: jmp StatusComplete
779
780
781subttl CharOut - Output a character to the screen
782page
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
794assume ds:NOTHING,es:NOTHING
795
796IF ANSI
797 include ansi.inc
798ELSE
799CharOut:
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
808ENDIF
809
810
811subttl $GenIOCTL - Generic IOCTL
812page
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
823FunCode = 14 ; Function Code
824FunCat = 13 ; Function Category
825;***
826RegSI = 15 ; Contents of SI
827RegDI = 17 ; Contents of DI
828DatBuf = 19 ; Pointer to data buffer
829
830;--- Code & Category definitions
831IOC_SC = 03h ;--- Screen Control
832IOSC_LS = 41h ; Locate SIB
833IOSC_SS = 42h ; save segment
834IOSC_RS = 43h ; restore segment
835IOSC_EI = 44h ; re-enable i/o
836IOSC_IS = 45h ; initialize screen
837
838assume 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
848sjc0: cmp al,IOSC_SS
849 jne sjc1
850 jmp short do_IOSC_SS
851sjc1: cmp al,IOSC_RS
852 jne sjc2
853 jmp do_IOSC_RS
854sjc2: cmp al,IOSC_EI
855 jne sjc3
856 jmp do_IOSC_EI
857sjc3: cmp al,IOSC_IS
858 jne GI_BadCode
859 jmp do_IOSC_IS
860
861GI_BadCode:
862 jmp CmdErr ; error exit: Command error
863
864
865subttl do_IOSC_LS - Locate SIB
866page
867
868;------------------------------------------------------------------------
869; Locate SIB
870;
871; entry:
872; SI = SIB Number
873; DS:BX = pointer to Request packet
874;
875
876assume ds:NOTHING,es:NOTHING
877
878do_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
894CurrLS:
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
904IF EAGLE
905 mov al,es:[CRT_MODE]
906 xor ah,ah
907 mov si,ax
908 mov ah,ScreenLen[si]
909 xor al,al
910ELSE
911 mov ax,es:[CRT_LEN]
912 assume es:NOTHING ; not true, but just to be safe
913ENDIF
914 mov [bx].SizeNeeded,ax ; save size of segment
915 mov ax,dx ; pointer to current SIB
916retLS:
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
925BadNum:
926 mov word ptr ds:[bx].RegSI,1 ; bad SIB number error
927 jmp StatusComplete
928
929
930subttl do_IOSC_SS - Save Segment
931page
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
941assume ds:NOTHING,es:NOTHING
942
943do_IOSC_SS:
944 cmp si,(MaxSeg-1) ; within range?
945BadNumJ1:
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
965IF 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
972ENDIF
973 pop si ; restore segment index
974;--- save a segment of screen data
975nfSS:
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
993do_save:
994IF 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
1000ENDIF
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
1006IF BLANK
1007 or al,8
1008 out dx,al ; turn on video
1009ENDIF
1010 pop ds
1011 pop bx
1012 mov word ptr ds:[bx].RegSI,0 ; operation ok
1013 jmp StatusComplete
1014
1015
1016subttl do_IOSC_RS - Restore Segment
1017page
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
1027assume ds:NOTHING,es:NOTHING
1028
1029do_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
1051IF 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
1061ENDIF
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
1069sjd0:
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
1089nfRS:
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
1104do_rest:
1105IF 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
1111ENDIF
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
1117IF BLANK
1118 or al,8
1119 out dx,al ; turn on video
1120ENDIF
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
1128BadNumJ:
1129 jmp BadNum
1130
1131
1132subttl do_IOSC_EI - Re-enable i/o
1133page
1134
1135;------------------------------------------------------------------------
1136; Re-enable i/o
1137;
1138; entry:
1139; DS:BX = pointer to Request packet
1140;
1141
1142assume ds:NOTHING,es:NOTHING
1143
1144do_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
1154subttl do_IOSC_IS - Initialize Screen
1155page
1156
1157;------------------------------------------------------------------------
1158; Initialize Screen
1159;
1160; entry:
1161; SI = SIB Number
1162; DS:BX = pointer to Request packet
1163;
1164
1165assume ds:NOTHING,es:NOTHING
1166
1167do_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
1189subttl $ConStop - Stop (freeze) console output
1190page
1191
1192;------------------------------------------------------------------------
1193; Stop (freeze) console output
1194;
1195
1196assume 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
1204subttl $ConStart - Start (continue) console output
1205page
1206
1207;------------------------------------------------------------------------
1208; Start (continue) console output
1209;
1210
1211assume 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
1220csRet: jmp StatusComplete
1221
1222
1223subttl DoPBlock - Block the current process
1224page
1225
1226;------------------------------------------------------------------------
1227; Block the current process
1228;
1229; entry:
1230; CS:AX = address to block on
1231;
1232; modifies: AX, FLAGS
1233;
1234
1235assume ds:NOTHING,es:NOTHING
1236
1237DoPBlock:
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
1255subttl DoPRun - Restart a process
1256page
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
1267assume ds:NOTHING,es:NOTHING
1268
1269DoPRun:
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
1283subttl GetSIBAdr - Return SIB address
1284page
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
1298assume ds:Code,es:NOTHING
1299
1300GetSIBAdr:
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
1310subttl GetSegAdr - Return segment address
1311page
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
1324assume ds:Code,es:NOTHING
1325
1326GetSegAdr:
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
1336ifdef DEBUGFLG
1337if NOT INBIOS
1338 INCLUDE BUGCODE.INC
1339endif
1340endif
1341
1342
1343subttl $ConInit - Initialization Routine
1344page
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
1354assume ds:NOTHING,es:NOTHING
1355
1356$ConInit:
1357IF 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
1367ENDIF
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
1411IF INBIOS
1412Code ends
1413
1414BiosInit segment para public 'CODE'
1415ENDIF
1416
1417Intro 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
1422BiosInit ends
1423
1424 END