--- /dev/null
+; MMURTL Operating System Source Code\r
+; Copyright 1991,1992,1993,1994 Richard A. Burgess\r
+; ALL RIGHTS RESERVED\r
+; Version 1.0\r
+\r
+;This module contains ALL Video code & Data\r
+; (along with EdLine for lack of a better place)\r
+;\r
+;This module supports MMURTL's Virtual Text Video.\r
+;All video calls are based on the video information in the job's\r
+;Job Control Block.\r
+;\r
+;Virtual video buffers allow a job to output data even when it is\r
+;not assigned to the real video display buffer.\r
+;\r
+;The call SetVidOwner is the key. It swaps virtual buffers for the real one\r
+;and changes the current pointer in that job's JCB. It also updates\r
+;the cursor in the correct place on entry.\r
+;\r
+; The following calls are implemented here:\r
+;\r
+;------------------------------\r
+;GetVidOwner(pdJobNumRet)\r
+; Desc: This returns the Job Number that currently has active video\r
+; screen.\r
+;------------------------------\r
+;SetVidOwner(ddJobNum)\r
+; Desc: This selects the screen that you see. This call is used\r
+; by the monitor in conjunction with the SetKbdOwner call to change\r
+; who gets the keystrokes and video (should be the same app).\r
+; The internal debugger is the only code that will use this call\r
+; and not move the keyboard also. It has it's own keyboard code\r
+; (else how could it debug the real keyboard code??)\r
+; Params:\r
+; ddJobNum is the new Job to get the active screen\r
+; (the one to be displayed)\r
+;------------------------------\r
+;SetNormVid(dAttr)\r
+; Desc: This selects the normal background attribute and fill char\r
+; used by ClrScr and ScrollVid on the screen.\r
+; Params:\r
+; dCharAttr is the Character and aAttr values used in\r
+; standard video operation on the current screen\r
+;\r
+;------------------------------\r
+;GetNormVid(pVidRet)\r
+;\r
+; Desc: This returns the value the normal screen attribute\r
+; used by ClrScr and ScrollVid on the screen.\r
+;\r
+; Params:\r
+; pVidRet points to the character where you want the NormVid\r
+; attribute returned.\r
+;\r
+;------------------------------\r
+;ClrScr ();\r
+;\r
+; Desc:\r
+; This clears the screen for the executing job. It may or may not\r
+; be the one you are viewing...\r
+;\r
+;------------------------------\r
+;TTYOut (pTextOut, ddTextOut, ddAttrib)\r
+;\r
+; Desc: This places characters on the screen in a TTY fashion at the\r
+; X & Y coordinates that are in effect for that screen.\r
+; The following characters in the stream are interpreted as follows:\r
+; Hex Action\r
+; 0A Line Feed\r
+; The cursor (next active character placement) will be on the\r
+; following line at column 0. If this line is below the bottom\r
+; of the screen, the entire screen will be scrolled up on line,\r
+; the bottom line will be blanked, and the cursor will be placed\r
+; on the last line in the first column.\r
+; 0D Carriage Return\r
+; The Cursor will be moved to column zero on the current line.\r
+; 08 BackSpace - The cursor will be moved one column to the left.\r
+; If already at column 0, Backspace will have no effect.\r
+; The backspace is non-destructive (no chars are changed)\r
+;\r
+; pTextOut is a NEAR Ptr to the text.\r
+; ddTextOut is the number of chars of text.\r
+; ddAttrib is the attribute/Color you want.\r
+;\r
+;------------------------------\r
+;PutVidChars(ddCol,ddLine,pChars,sChars,ddAttrib)\r
+;\r
+; Desc: This places characters on the screen without affecting\r
+; the current TTY coordinates or the TTY data. It is independent\r
+; of the current video "Stream."\r
+;\r
+; Params:\r
+; ddCol is the column to start on (0-79)\r
+; ddLine is the line (0-24)\r
+; pChars is a pointer the text to be displayed\r
+; sChars is the number of chars\r
+; ddAtrib is the color/attribute to use during display\r
+; which applies to all of the characters on this\r
+; call to PutVidChars.\r
+;------------------------------\r
+;GetVidChar(ddCol,ddLine,pCharRet,pAttrRet)\r
+;\r
+; Desc: This returns the current character and attribute\r
+; from the screen coordinates you specify.\r
+;\r
+; Params:\r
+; ddCol is the column to start on (0-79)\r
+; ddLine is the line (0-24)\r
+; pCharRet is a pointer where you want the character returned\r
+; pAttrRet is a pointer where you want the attribute returned\r
+;------------------------------\r
+;PutVidAttrs(ddCol,ddLine,sChars,dAttr)\r
+;\r
+; Desc: This sets screen colors (attrs) for the without affecting\r
+; the current TTY coordinates or the character data. It is independent\r
+; of the current video "Stream."\r
+;\r
+; Params:\r
+; ddCol is the column to start on (0-79)\r
+; ddLine is the line (0-24)\r
+; sChars is the number of char spaces to place dAttr\r
+; dAttr is the color/attribute to fill the character spaces with\r
+;\r
+;------------------------------\r
+;ScrollVid(ddULCol,ddULline,nddCols,nddLines, ddfUp)\r
+;\r
+; Desc: This scrolls the described square area on the screen either\r
+; UP or DOWN one line. If ddfUp is NON-ZERO the scroll will be UP.\r
+; The line left blank is filled with NormAttr from JCB.\r
+; Parms:\r
+; ddULCol is the UPERR LEFT column to start on (0-79)\r
+; ddULLine is the UPPER LEFT line (0-24)\r
+; nddCols is the number of columns to be scrolled.\r
+; nddLines is the count of lines to be scrolled.\r
+; ddfUp is NON-ZERO to cause the scroll to be up (vise down).\r
+;\r
+; If you want to scroll the entire screen UP one line, the\r
+; params would be ScrollVid(VidNum, 0,0,80,25,1).\r
+; In this case the top line is lost (not really scrolled),\r
+; and the bottom line would be blanked. Infact, if you specified\r
+; (Vidnum, 0,1,80,24,1) you would get the same results.\r
+;\r
+;------------------------------\r
+;SetXY(NewX,NewY)\r
+; Desc: Position VGA cursor (Text mode) to the X & Y position.\r
+;\r
+; Params:\r
+; NewX is the new horizontal cursor postion\r
+; NewY is the new vertical cursor position\r
+;\r
+;------------------------------\r
+;GetXY(pXRet,pYRet)\r
+; Desc: Returns the current X & Y position for your job.\r
+;\r
+; Params:\r
+; pXRet is a ptr where you want the current horizontal cursor postion\r
+; pYRet is a ptr where you want the current vertical cursor position\r
+;\r
+.DATA\r
+.INCLUDE MOSEDF.INC\r
+.INCLUDE JOB.INC\r
+\r
+;This is the data for the virtual character video service.\r
+;The video code is fully reentrant because each job has it's own\r
+;video screen. Only one of these screens will be the active video\r
+;display.\r
+;\r
+;Video Equates and Types\r
+;\r
+CRTCPort1 EQU 03D4h ;Index port for CRTC\r
+CRTCPort2 EQU 03D5h ;Data port for CRTC\r
+CRTCAddHi EQU 0Ch ;Register for lo byte of Video address\r
+CRTCAddLo EQU 0Dh ;Register for lo byte of Video address\r
+CRTCCurHi EQU 0Eh ;Register for lo byte of Cursor address\r
+CRTCCurLo EQU 0Fh ;Register for lo byte of Cursor address\r
+CRTC0C DB 0 ;CRT Reg 0C HiByte address value\r
+CRTC0D DB 0 ;CRT Reg 0D LoByte address value\r
+\r
+PUBLIC ddVidOwner DD 1 ;JCB that currently owns video\r
+ ;Default to monitor (Job 1)\r
+\r
+;End of Data & Equates\r
+;\r
+;============================================================================\r
+; BEGIN INTERNAL CODE FOR VIDEO\r
+;============================================================================\r
+;\r
+.CODE\r
+;\r
+EXTRN GetpJCB NEAR\r
+EXTRN GetpCrntJCB NEAR\r
+EXTRN ReadDbgKbd NEAR\r
+EXTRN GetCrntJobNum NEAR\r
+\r
+;InitVideo makes Video Screen 0 the default screen. That\r
+;makes the VGATextBase address 0B8000h\r
+;\r
+PUBLIC InitVideo:\r
+ MOV AL, CRTCAddHi ;Index of hi byte\r
+ MOV DX, CRTCPort1 ;Index Port\r
+ OUT DX, AL\r
+ MOV AL, CRTC0C ;hi byte value to send\r
+ MOV DX, CRTCPort2 ;Data Port\r
+ OUT DX, AL\r
+ ;\r
+ MOV AL, CRTCAddLo ;Index of lo byte\r
+ MOV DX, CRTCPort1 ;Index Port\r
+ OUT DX, AL\r
+ MOV AL, CRTC0D ;lo byte value to send\r
+ MOV DX, CRTCPort2 ;Data Port\r
+ OUT DX, AL\r
+ RETN\r
+;\r
+;============================================================================\r
+; BEGIN PUBLIC CODE FOR VIDEO\r
+;============================================================================\r
+;\r
+;============================================================================\r
+; SetVidOwner - Make a new a screen actively displayed.\r
+; EAX Returns NON-Zero if JOB number is invalid\r
+\r
+ddJobVidCV EQU DWORD PTR [EBP+12]\r
+\r
+PUBLIC __SetVidOwner:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ MOV EAX, ddJobVidCV ;\r
+ CMP EAX, ddVidOwner ;Already own it?\r
+ JNE ChgVid01 ;No\r
+ XOR EAX, EAX ;Yes\r
+ JMP ChgVidDone\r
+ChgVid01:\r
+ CALL GetpJCB ;Leaves ptr to new vid JCB in EAX\r
+ CMP DWORD PTR [EAX+pVidMem] ,0 ;Got valid video memory???\r
+ JNE ChgVid02 ;Yes\r
+ MOV EAX, ErcVidNum ;NO! Give em an error!\r
+ JMP ChgVidDone\r
+ChgVid02:\r
+ ;Save data on screen to CURRENT job's pVirtVid\r
+ MOV EAX, ddVidOwner\r
+ CALL GetpJCB\r
+ PUSH VGATextBase ;Source\r
+ MOV EBX, [EAX+pVirtVid] ;Destination\r
+ PUSH EBX\r
+ PUSH 4000 ;Size of video\r
+ CALL FWORD PTR _CopyData ;Do it!\r
+\r
+ ;Make pVidMem same as pVirtVid for CURRENT OWNER\r
+ MOV EAX, ddVidOwner\r
+ CALL GetpJCB ;Leaves ptr to new vid JCB in EAX\r
+ MOV EBX, [EAX+pVirtVid]\r
+ MOV [EAX+pVidMem], EBX\r
+\r
+ ;Update current video owner to NEW owner\r
+\r
+ MOV EAX, ddJobVidCV ;\r
+ MOV ddVidOwner, EAX\r
+\r
+ ;Copy in Data from new pVirtVid\r
+\r
+ MOV EAX, ddVidOwner\r
+ CALL GetpJCB\r
+ MOV EBX, [EAX+pVirtVid] ;Source\r
+ PUSH EBX\r
+ PUSH VGATextBase ;Destination\r
+ PUSH 4000 ;Size of video\r
+ CALL FWORD PTR _CopyData ;Do it!\r
+\r
+ ;Make new pVidMem real video screen for new owner\r
+\r
+ MOV EAX, ddVidOwner\r
+ CALL GetpJCB\r
+ MOV EBX, VGATextBase\r
+ MOV [EAX+pVidMem], EBX\r
+\r
+ ;Set Cursor position\r
+\r
+ MOV EAX, ddVidOwner\r
+ CALL GetpJCB\r
+ MOV ECX, EAX\r
+ MOV EBX, [ECX+CrntX] ;Get current X for new screen\r
+ MOV EAX, [EBX+CrntY] ;Current Y\r
+ CALL HardXY ;Set it up\r
+ XOR EAX, EAX ;No Error\r
+ChgVidDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 4\r
+\r
+;============================================================================\r
+; SetNormVid - Sets the normal video attribute (color) used in\r
+; ClrScr, EditLine, and ScrollVid.\r
+; EAX Returns Zero (No Error)\r
+\r
+ddNormVid EQU DWORD PTR [EBP+12]\r
+\r
+PUBLIC __SetNormVid:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;pJCB -> EAX\r
+ MOV EBX, ddNormVid ;\r
+ MOV [EAX+NormAttr], EBX ;\r
+ XOR EAX, EAX\r
+ POP EBP ;\r
+ RETF 4\r
+\r
+;============================================================================\r
+; GetNormVid - Returns the normal video attribute (color) used in\r
+; ClrScr, EditLine, and ScrollVid.\r
+; EAX Returns Zero (No Error)\r
+\r
+pdNormVidRet EQU DWORD PTR [EBP+12]\r
+\r
+PUBLIC __GetNormVid:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;pJCB -> EAX\r
+ MOV EBX, [EAX+NormAttr] ;\r
+ MOV ESI, pdNormVidRet ;\r
+ MOV [ESI], BL ;\r
+ XOR EAX, EAX\r
+ POP EBP ;\r
+ RETF 4\r
+\r
+;============================================================================\r
+; GetVidOwner - Returns the Job number of current active video\r
+; number to the caller.\r
+;=============================================================================\r
+\r
+pVidNumRet EQU DWORD PTR [EBP+12]\r
+\r
+PUBLIC __GetVidOwner:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ MOV ESI, pVidNumRet ;\r
+ MOV EAX, ddVidOwner ;\r
+ MOV [ESI], EAX ;\r
+ XOR EAX, EAX ; no error obviously\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 4\r
+\r
+;=============================================================================\r
+; Clear caller's video screen (Use Space and Attr from JCB NormAttr)\r
+;=============================================================================\r
+;\r
+PUBLIC __ClrScr:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX\r
+ MOV EDI,[EBX+pVidMem] ;EDI points to his video memory\r
+ MOV EAX, [EBX+NormAttr] ;Attr\r
+ SHL EAX, 8 ;\r
+ MOV AL, 20h ;\r
+ MOV DX, AX\r
+ SHL EAX, 16\r
+ MOV AX, DX ;Fill Char & Attr\r
+ MOV ECX,0400h\r
+ CLD\r
+ REP STOSD\r
+ PUSH 0\r
+ PUSH 0\r
+ CALL FWORD PTR _SetXY ;Erc in EAX on Return\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF\r
+\r
+;=============================================================================\r
+; TTYOut:\r
+;=============================================================================\r
+\r
+pTextOut EQU DWORD PTR [EBP+20]\r
+sTextOut EQU DWORD PTR [EBP+16]\r
+dAttrText EQU DWORD PTR [EBP+12]\r
+\r
+DataByte EQU BYTE PTR [ECX]\r
+\r
+PUBLIC __TTYOut:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX\r
+ MOV EAX, sTextOut ;make sure count isn't null\r
+ OR EAX, EAX\r
+ JZ TTYDone\r
+\r
+TTY00:\r
+ MOV EAX,[EBX+CrntX] ; EAX has CrntX (col)\r
+ MOV EDX,[EBX+CrntY] ; EDX has CrntY (line)\r
+ MOV ECX,pTextOut\r
+\r
+ CMP DataByte,0Ah ; LF?\r
+ JNE TTY02\r
+ INC EDX\r
+ CMP EDX,[EBX+nLines] ; Equal to or past the bottom?\r
+ JB TTY06 ; No\r
+ JMP TTYScr ; Yes, goto scroll\r
+TTY02:\r
+ CMP DataByte,0Dh ; CR?\r
+ JNE TTY03\r
+ MOV EAX,0\r
+ JMP TTY06\r
+TTY03:\r
+ CMP DataByte,08h ; BackSpace?\r
+ JNE TTY04\r
+ CMP EAX,0\r
+ JE TTY04\r
+ DEC EAX\r
+ JMP TTY06\r
+TTY04:\r
+ PUSH EBX ;Save pointer to VCB\r
+\r
+ PUSH EAX ;X (Param 1)\r
+ PUSH EDX ;Y (Param 2)\r
+ PUSH ECX ;pointer to text char (Param3)\r
+ PUSH 1 ;Param 4 (nchars)\r
+ MOV ECX,dAttrText ;\r
+ PUSH ECX ;Param 5\r
+ CALL FWORD PTR _PutVidChars ;\r
+ POP EBX ;restore ptr to VCB\r
+ CMP EAX, 0\r
+ JNE TTYDone\r
+ MOV EAX, [EBX+CrntX]\r
+ MOV EDX, [EBX+CrntY]\r
+ INC EAX ;Next column\r
+ CMP EAX,[EBX+nCols]\r
+ JNE TTY06 ;Make cursor follow\r
+ MOV EAX,0\r
+ INC EDX\r
+ CMP EDX,[EBX+nLines] ; past the bottom?\r
+ JNE TTY06 ; No - goto 06 else fall thru\r
+\r
+TTYScr:\r
+ DEC EDX ; back up one line\r
+ PUSH EAX ;Save registers (scroll eats em)\r
+ PUSH EBX\r
+ PUSH ECX\r
+ PUSH EDX\r
+\r
+ PUSH 0\r
+ PUSH 0\r
+ PUSH 80\r
+ PUSH 25\r
+ PUSH 1 ;fUP (non zero)\r
+ CALL FWORD PTR _ScrollVid ;Ignore error\r
+ POP EDX ;restore registers\r
+ POP ECX\r
+ POP EBX\r
+ POP EAX ;Fall thru to\r
+\r
+TTY06:\r
+ PUSH EBX ;save ptr to pJCB\r
+\r
+ PUSH EAX\r
+ PUSH EDX\r
+ CALL FWORD PTR _SetXY\r
+\r
+ POP EBX ;Restore ptr to VCB\r
+ CMP EAX, 0\r
+ JNE TTYDone\r
+ DEC sTextOut\r
+ JZ TTYDone\r
+ INC pTextOut\r
+ JMP TTY00 ; Go back for next char\r
+TTYDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 12\r
+\r
+\r
+\r
+;=============================================================================\r
+; PutVidAttrs:\r
+; Desc: This sets screen colors (attrs) for the without affecting\r
+; the current TTY coordinates or the character data. It is independent\r
+; of the current video "Stream."\r
+;\r
+; Params:\r
+; ddCol is the column to start on (0-79)\r
+; ddLine is the line (0-24)\r
+; sChars is the number of char spaces to place dAttr\r
+; dAttr is the color/attribute to fill the character spaces with\r
+;\r
+; Start Position in screen memory is (Line * 80 + (Column*2))\r
+; pass Char, then Color, pass char, then color etc... DO NOT EXCEED 2000!\r
+; Needs to be fixed to tell if ECX + sDDChars will go off screen...\r
+;\r
+;=============================================================================\r
+\r
+oADDX EQU DWORD PTR [EBP+24] ;Param 1 COLUMN\r
+oADDY EQU DWORD PTR [EBP+20] ;Param 2 LINE\r
+sADDChars EQU DWORD PTR [EBP+16] ;Param 3 sChars\r
+sADDColor EQU DWORD PTR [EBP+12] ;Param 4 Attr\r
+\r
+PUBLIC __PutVidAttrs:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX\r
+\r
+ MOV EDI, [EBX+pVidMem] ;point to this VCBs video memory\r
+ MOV EBX,oADDx ;x Position\r
+ SHL EBX,1 ;Times 2\r
+ MOV EAX,oADDy ;y Position\r
+ MOV ECX,0A0h ;Times 160 (char/attrs per line)\r
+ MUL ECX ;Times nColumns\r
+ ADD EAX,EBX\r
+ CMP EAX,0F9Eh ;Last legal posn on screen\r
+ JBE PutAttrs00\r
+ MOV EAX, ErcVidParam\r
+ JMP PcADone\r
+PutAttrs00:\r
+ MOV ECX,sADDChars\r
+ OR ECX, ECX\r
+ JZ PcADone\r
+ ADD EDI,EAX\r
+ MOV EAX,sADDColor\r
+ CLD\r
+pcAMore:\r
+ INC EDI ;Pass the char value\r
+ STOSB ;Move Color in\r
+ LOOP pcAMore\r
+ XOR EAX, EAX ;No Error!\r
+pcADone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 16\r
+\r
+;=============================================================================\r
+; PutVidChars:\r
+; This Places characters on the VGA Character Screen in the XY Coords\r
+; Params\r
+; 1) DD X (Column 0-79)\r
+; 2) DD Y (Line 0-24)\r
+; 3) DD Near Ptr (relative to DS) of string\r
+; 4) DD Size of String\r
+; 5) DD (of which the low order byte is the Color)\r
+;\r
+; Start Position in screen memory is (Line * 80 + (Column*2))\r
+; Put Char, then Color, then char, then color etc... DO NOT EXCEED 2000!\r
+; Needs to be fixed to tell if ECX + sDDChars will go off screen...\r
+;\r
+;=============================================================================\r
+\r
+oDDX EQU DWORD PTR [EBP+28] ;Param 1 COLUMN\r
+oDDY EQU DWORD PTR [EBP+24] ;Param 2 LINE\r
+pDDChars EQU DWORD PTR [EBP+20] ;Param 3 pChars\r
+sDDChars EQU DWORD PTR [EBP+16] ;Param 4 sChars\r
+sDDColor EQU DWORD PTR [EBP+12] ;Param 5 Attr\r
+\r
+PUBLIC __PutVidChars:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CLI\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX\r
+ MOV EDI, [EBX+pVidMem] ;point to this VCBs video memory\r
+ STI\r
+ MOV EBX,oDDx\r
+ SHL EBX,1 ;Times 2\r
+ MOV EAX,oDDy\r
+ MOV ECX,0A0h ;Times 160\r
+ MUL ECX ;Times nColumns\r
+ ADD EAX,EBX\r
+ CMP EAX,0F9Eh ;Last legal posn on screen\r
+ JBE PutChars00\r
+ MOV EAX, ErcVidParam\r
+ JMP PcDone\r
+PutChars00:\r
+ MOV ECX,sDDChars\r
+ OR ECX, ECX\r
+ JZ PcDone\r
+ MOV ESI,pDDChars\r
+ ADD EDI,EAX\r
+ MOV EAX,sDDColor\r
+ CLD\r
+pcMore:\r
+ MOVSB ;Move Char in\r
+ STOSB ;Move Color in\r
+ LOOP pcMore\r
+ XOR EAX, EAX ;No Error!\r
+pcDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 20\r
+\r
+;=============================================================================\r
+;GetVidChar(ddCol,ddLine,pCharRet,pAttrRet)\r
+;\r
+; Desc: This returns the current character and attribute\r
+; from the screen coordinates you specify.\r
+;\r
+; Params:\r
+; ddCol is the column to start on (0-79)\r
+; ddLine is the line (0-24)\r
+; pCharRet is a pointer where you want the character returned\r
+; pAttrRet is a pointer where you want the attribute returned\r
+;\r
+\r
+oGDDX EQU DWORD PTR [EBP+24] ;Param 1 COLUMN\r
+oGDDY EQU DWORD PTR [EBP+20] ;Param 2 LINE\r
+pGDDCRet EQU DWORD PTR [EBP+16] ;Param 3 pCharRet\r
+pGDDARet EQU DWORD PTR [EBP+12] ;Param 4 pAttrRet\r
+\r
+PUBLIC __GetVidChar:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX\r
+\r
+ MOV EDI, [EBX+pVidMem] ;point to this VCBs video memory\r
+ MOV EBX,oGDDx\r
+ SHL EBX,1 ;Times 2\r
+ MOV EAX,oGDDy\r
+ MOV ECX,0A0h ;Times 160\r
+ MUL ECX ;Times nColumns\r
+ ADD EAX,EBX\r
+ CMP EAX,0F9Eh ;Last legal posn on screen\r
+ JBE GetChar00\r
+ MOV EAX, ErcVidParam\r
+ JMP PcGDone\r
+GetChar00:\r
+ ADD EDI,EAX ;EDI now points to char\r
+ MOV ESI,pGDDCRet\r
+ MOV AL, [EDI]\r
+ MOV [ESI], AL ;Give them the char\r
+ INC EDI ;Move to Attr\r
+ MOV ESI,pGDDARet\r
+ MOV AL, [EDI]\r
+ MOV [ESI], AL ;Give them the Attr\r
+ XOR EAX, EAX ;No Error!\r
+pcGDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 20\r
+;=============================================================================\r
+; ScrollVid:\r
+; This scrolls the defined area up or down one line.\r
+; Params\r
+; 1) Upper Left column X (Column 0-79)\r
+; 2) Upper Left line Y (Line 0-24)\r
+; 3) nCols to scroll\r
+; 4) nLines to scroll\r
+; 5) TRUE for up (any NON zero QUAD)\r
+;\r
+; We check all params for validity. ErcVidParam is returned if one is\r
+; invalid.\r
+;=============================================================================\r
+\r
+oULX EQU DWORD PTR [EBP+28] ;Param 1 COLUMN\r
+oULY EQU DWORD PTR [EBP+24] ;Param 2 LINE\r
+nddCols EQU DWORD PTR [EBP+20] ;Param 3 Number of columns\r
+nddLines EQU DWORD PTR [EBP+16] ;Param 4 Number of Lines\r
+ddfUP EQU DWORD PTR [EBP+12] ;Param 5 Attr\r
+\r
+PUBLIC __ScrollVid:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX ;Save pJCB & use in EBX\r
+ MOV EAX, oULX\r
+ CMP EAX, 79\r
+ JA svErcExit\r
+ ADD EAX, nddCols\r
+ CMP EAX, 80\r
+ JA svErcExit\r
+ MOV EAX, oULY\r
+ CMP EAX, 24\r
+ JA svErcExit\r
+ ADD EAX, nddLines\r
+ CMP EAX, 25\r
+ JA svErcExit\r
+\r
+ CMP ddfUP, 0 ;Scroll UP?\r
+ JNE svUP0 ;Yes... Scroll UP!\r
+\r
+;Scroll DOWN begins\r
+\r
+ MOV EAX, oULY ;First line\r
+ ADD EAX, nddLines ;Last line\r
+ MOV ECX, 160\r
+ MUL ECX ;times nBytes per line\r
+ MOV EDI, [EBX+pVidMem] ;EDI points to video memory 0,0\r
+ MOV EDX, EBX ;Save pJCB\r
+ ADD EDI, EAX ;EDI is ptr to 1st dest line\r
+ ADD EDI, oULX ;offset into line\r
+ ADD EDI, oULX ;add again for attributes\r
+ MOV ESI, EDI ;\r
+ SUB ESI, 160 ;ESI is 1st source line\r
+ MOV EBX, ESI ;Save in EBX for reload\r
+ MOV EAX, nDDLines ;How many lines to move\r
+ DEC EAX ;one less than window height\r
+svDOWN1:\r
+ MOV ECX, nddCols ;How many WORDS per line to move\r
+ REP MOVSW ;Move a line (of WORDS!)\r
+ MOV EDI, EBX ;Reload Dest to next line\r
+ MOV ESI, EDI\r
+ SUB ESI, 160\r
+ MOV EBX, ESI ;Save again\r
+ DEC EAX\r
+ JNZ svDOWN1\r
+ MOV EAX, [EDX+NormAttr] ;Normal video attributes!!!\r
+ SHL EAX, 8\r
+ MOV AL, 20h ;Space\r
+ MOV EDI, EBX ;Put the last line into EDI\r
+ MOV ECX, nddCols\r
+ CLD\r
+ REP STOSW\r
+ XOR EAX, EAX ;No error\r
+ JMP svDone\r
+ ;No... scroll down begins\r
+svUP0:\r
+ MOV EAX, oULY ;First line\r
+ MOV ECX, 160\r
+ MUL ECX ;times nBytes per line\r
+ MOV EDI, [EBX+pVidMem] ;EDI points to video memory 0,0\r
+ MOV EDX, EBX ;Save pJCB\r
+ ADD EDI, EAX ;EDI is ptr to 1st dest line\r
+ ADD EDI, oULX ;offset into line\r
+ ADD EDI, oULX ;add again for attributes\r
+ MOV ESI, EDI ;\r
+ ADD ESI, 160 ;ESI is 1st source line\r
+ MOV EBX, ESI ;Save in EBX for reload\r
+ MOV EAX, nDDLines ;How many lines to move\r
+ DEC EAX ;two less than window height\r
+svUP1:\r
+ MOV ECX, nddCols ;How many WORDS per line to move\r
+ REP MOVSW ;Move a line (of WORDS!)\r
+ MOV EDI, EBX ;Reload Dest to next line\r
+ MOV ESI, EDI\r
+ ADD ESI, 160\r
+ MOV EBX, ESI ;Save again\r
+ DEC EAX\r
+ JNZ svUP1\r
+ MOV EAX, [EDX+NormAttr] ;Normal video attributes!!!\r
+ SHL EAX, 8\r
+ MOV AL, 20h ;Space\r
+ MOV EDI, EBX ;Put the last line into EDI\r
+ SUB EDI, 160\r
+ MOV ECX, nddCols\r
+ CLD\r
+ REP STOSW\r
+ XOR EAX, EAX ;No error\r
+ JMP svDone\r
+svErcExit: ;Error exits will jump here\r
+ MOV EAX, ErcVidParam\r
+svDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 20\r
+;\r
+;=============================================================\r
+; HardXY - Intenal Internal to support SetXY and SetVidOwner\r
+; This sets the hardware cursor position\r
+; Input:\r
+; EAX : New Y position\r
+; EBX : New X position\r
+; Used:\r
+; EAX, EBX, EDX, Flags\r
+; Output:\r
+; None\r
+\r
+HardXY:\r
+ MOV ECX,80\r
+ MUL ECX ; Line * 80\r
+ ADD EAX,EBX ; Line plus column\r
+ MOV DX,CRTCPort1 ; Index register\r
+ PUSH EAX\r
+ MOV AL,CRTCCurLo\r
+ OUT DX,AL ; Index 0Fh for low byte\r
+ POP EAX\r
+ MOV DX,CRTCPort2 ; Data register\r
+ OUT DX,AL ; Send Low byte out\r
+ SHR EAX,08 ; shift hi byte into AL\r
+ PUSH EAX\r
+ MOV DX,CRTCPort1\r
+ MOV AL,CRTCCurHi\r
+ OUT DX,AL ; Index for High byte\r
+ POP EAX\r
+ MOV DX,CRTCPort2\r
+ OUT DX,AL ; Send High byte out\r
+ RETN\r
+;\r
+;=============================================================================\r
+; SetXY:\r
+; Position VGA cursor (Text mode) to the X & Y position.\r
+; Also sets hardware CrntX and CrntY cursor position if\r
+; crnt job is assigned the real screen\r
+;=============================================================================\r
+\r
+NewX EQU DWORD PTR [EBP+16]\r
+NewY EQU DWORD PTR [EBP+12]\r
+\r
+PUBLIC __SetXY:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX\r
+\r
+ MOV ECX,NewX ; Column\r
+ MOV EDX,NewY ; Line\r
+ MOV [EBX+CrntX],ECX ; This saves it in the VCB\r
+ MOV [EBX+CrntY],EDX ;\r
+\r
+ CALL GetCrntJobNum ;Leaves ptr to current JCB in EAX\r
+ CMP EAX, ddVidOwner\r
+ JNE GotoXYDone ;If not on Active screen, skip it\r
+\r
+ MOV EAX,NewY ;Setup to call HardXY\r
+ MOV EBX,NewX\r
+ CALL HardXY\r
+GotoXYDone:\r
+ XOR EAX,EAX ;No Error\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 8\r
+\r
+;=============================================================================\r
+; GetXY:\r
+; Returns position of VGA cursor (Text mode X & Y position).\r
+; This appliies to the values for the caller's VCB\r
+;=============================================================================\r
+\r
+pXret EQU DWORD PTR [EBP+16]\r
+pYret EQU DWORD PTR [EBP+12]\r
+\r
+PUBLIC __GetXY:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, EAX\r
+\r
+ MOV EAX,[EBX+CrntX] ; Column\r
+ MOV ESI,pXret\r
+ MOV [ESI], EAX\r
+ MOV EAX,[EBX+CrntY] ; Line\r
+ MOV ESI,pYret\r
+ MOV [ESI], EAX\r
+ XOR EAX,EAX\r
+QXYDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 8\r
+\r
+\r
+;=============================================================================\r
+; EditLine\r
+; Reads a line of text from the keyboard and puts it into the\r
+; specified string with full line editing features.\r
+;\r
+; EditLine(pStr, dCrntLen, dMaxLen, pdLenRet, pbExitChar): dError\r
+;\r
+; Param 1 is a NEAR Ptr to string to be edited\r
+; Param 2 is current length of string to edit (80 Max)\r
+; Param 3 is the max length the string can be (80 Max)\r
+; Param 4 is a NEAR Ptr to a DD where the length of the string is returned\r
+; Param 5 is a pointer to a Byte where the exit key from the edit\r
+; operation is returned.\r
+; Param 6 is the editing attribute to use.\r
+;\r
+; Display and keyboard are handled entirely inside EditLine.\r
+; The following keys are recognized and handled inside, any other key\r
+; causes Editline to exit returning the string in it's current condition\r
+; and returning the key that caused the exit to pKeyRet:\r
+;\r
+; 08 (Backspace) move cursor to left replacing char with 20h\r
+; which is a destructive backspace\r
+; 20-7E Hex places character in current position and advances position\r
+\r
+; Any other keystroke causes the edit line routine to be exited\r
+; with that keystroke returned to pExitKeyRet\r
+;\r
+;\r
+;=============================================================================\r
+\r
+pEdString EQU DWORD PTR [EBP+32]\r
+ddSzCrnt EQU DWORD PTR [EBP+28]\r
+ddSzMax EQU DWORD PTR [EBP+24]\r
+pddSzRet EQU DWORD PTR [EBP+20]\r
+pExitKeyRet EQU DWORD PTR [EBP+16]\r
+dEditAttr EQU DWORD PTR [EBP+12]\r
+\r
+;Local vars EditX and EditY hold position of first char of text\r
+;CrntX is the cursor postion\r
+;\r
+PosnX EQU DWORD PTR [EBP-04]\r
+EditX EQU DWORD PTR [EBP-08]\r
+EditY EQU DWORD PTR [EBP-12]\r
+KeyCode EQU DWORD PTR [EBP-16]\r
+\r
+PUBLIC __EditLine:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ SUB ESP, 16\r
+\r
+ CMP ddSzCrnt, 80 ;Is it currently too long?\r
+ JA BadEdit\r
+ CMP ddSzMax, 80 ;Is Max len to long?\r
+ JA BadEdit\r
+ MOV EAX, ddSzCrnt\r
+ CMP EAX, ddSzMax ;Is Crnt len > Max???\r
+ JA BadEdit\r
+\r
+ LEA EAX, EditX ;Get current cursor posns in local vars\r
+ PUSH EAX\r
+ LEA EAX, EditY\r
+ PUSH EAX\r
+ CALL FWORD PTR _GetXY\r
+ CMP EAX, 0\r
+ JNE EditDone ;Bad Erc from call\r
+\r
+ MOV EAX, EditX\r
+ ADD EAX, ddSzCrnt\r
+ MOV PosnX, EAX ;make PosnX end of string\r
+\r
+ MOV ECX, ddSzMax\r
+ SUB ECX, ddSzCrnt ;ECX how many bytes to zero\r
+ JZ EdLn01 ;None to zero out\r
+ MOV ESI, pEdString ;Initialize currrent string\r
+ ADD ESI, ddSzCrnt ;ESI ptr to 1st empty byte\r
+ MOV AL, 20h ;fill with spaces\r
+Edln00:\r
+ MOV [ESI], AL\r
+ INC ESI\r
+ LOOP Edln00\r
+\r
+EdLn01:\r
+ PUSH PosnX\r
+ PUSH EditY\r
+ CALL FWORD PTR _SetXY\r
+ CMP EAX, 0\r
+ JNE EditDone\r
+\r
+EdLn02:\r
+ PUSH EditX ;Display current string\r
+ PUSH EditY\r
+ PUSH pEdString\r
+ PUSH ddSzMax\r
+ PUSH dEditAttr ;Attribute they selected\r
+ CALL FWORD PTR _PutVidChars\r
+ CMP EAX, 0\r
+ JNE EditDone\r
+EdLn03:\r
+ LEA EAX, KeyCode\r
+ PUSH EAX\r
+ CMP ddVidOwner, 2 ;Debugger???\r
+ JE EdLn035\r
+ PUSH 1 ;Wait for a key\r
+ CALL FWORD PTR _ReadKbd ;Get a key\r
+ JMP SHORT EdLn036\r
+EdLn035:\r
+ CALL ReadDbgKbd\r
+EdLn036:\r
+ MOV EAX, KeyCode\r
+ AND EAX, 07Fh\r
+ OR EAX, EAX\r
+ JZ EdLn03\r
+ CMP EAX, 08h ;BackSpace?\r
+ JNE EdLn04 ;No - Next test\r
+EdLn037:\r
+ CMP ddSzCrnt, 0\r
+ JE EdLn01\r
+ DEC PosnX\r
+ DEC ddSzCrnt\r
+ MOV ESI, pEdString\r
+ MOV ECX, ddSzCrnt\r
+ MOV BYTE PTR [ESI+ECX], 20h\r
+ JMP Edln01\r
+EdLn04: CMP EAX, 03h ;Left?\r
+ JNE EdLn045 ;No - Next test\r
+ JMP EdLn037\r
+EdLn045:\r
+ CMP EAX, 83h ;Num-Left?\r
+ JNE EdLn046 ;No - Next test\r
+ JMP EdLn037\r
+EdLn046:\r
+ CMP EAX, 0Dh ;CR?\r
+ JNE EdLn05 ;No - Next test\r
+ JMP EdLn07\r
+EdLn05: CMP EAX, 1Bh ;Escape?\r
+ JNE EdLn06 ;No - Next test\r
+ JMP EdLn07\r
+EdLn06:\r
+ CMP EAX, 7Eh ;Is it above text?\r
+ JA EdLn07 ;Yes, Exit!\r
+ CMP EAX, 20h ;Is it below text??\r
+ JB EdLn07 ;Yes, Exit\r
+ MOV ESI, pEdString ;It's really a char!\r
+ MOV ECX, ddSzCrnt\r
+ MOV BYTE PTR [ESI+ECX], AL\r
+ MOV ECX, ddSzMax\r
+ CMP ddSzCrnt, ECX\r
+ JAE EdLn01\r
+ INC PosnX\r
+ INC ddSzCrnt\r
+ JMP EdLn01\r
+EdLn07:\r
+ MOV ESI,pExitKeyRet\r
+ MOV [ESI], AL\r
+ MOV ESI,pddSzRet\r
+ MOV EAX, ddSzCrnt\r
+ MOV [ESI], EAX\r
+\r
+ PUSH EditX ;Display current string w/Norm Attrs\r
+ PUSH EditY\r
+ PUSH pEdString\r
+ PUSH ddSzMax\r
+ CALL GetpCrntJCB ;Leaves ptr to current JCB in EAX\r
+ MOV EBX, [EAX+NormAttr]\r
+ PUSH EBX ;Normal Attribute from JCB\r
+ CALL FWORD PTR _PutVidChars ;Ignore error (we are leaving anyway)\r
+ XOR EAX, EAX\r
+ JMP EditDone\r
+BadEdit:\r
+ MOV EAX, ErcEditParam\r
+EditDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 24\r
+\r
+;===================== END OF MODULE ================\r