;; # @(#) vesafns.asm Version 1.1 (12/29/94). Copyright Venue # ;************************************************************************/ ;* */ ;* (C) Copyright 1989, 1990, 1990, 1991, 1992, 1993, 1994, 1995 Venue. */ ;* All Rights Reserved. */ ;* Manufactured in the United States of America. */ ;* */ ;************************************************************************/ .386P DATA SEGMENT USE32 ;;; ****************************** ;;; DevRec is the ``SuperClass'' of devices. ;;; It is included at the top of all the device record. ;;; **IT IS IMPORTANT THAT YOU KEEP THIS RECORD IN SYNC ;;; WITH THE DspInterfaceRec DEFINED IN devif.h ;;; ****************************** DevRec STRUC active DD ? locked DD ? deventer DD ? devexit DD ? before_raid DD ? after_raid DD ? sync_device DD ? DevRec ENDS ;;; ****************************** ;;; MRegion is the generic region record. It is used for geometry ;;; calculations. ;;; ****************************** MRegion STRUC x DD ? y DD ? RegWidth DD ? RegHeight DD ? MRegion ENDS ;;; ****************************** ;;; DspInterfaceRec is the record that represents the ;;; display interface. ;;; **IT IS IMPORTANT THAT YOU KEEP THIS RECORD IN SYNC ;;; WITH THE DspInterfaceRec DEFINED IN devif.h ;;; ****************************** DspInterfaceRec STRUC device DevRec <> drawline DD ? cleardisplay DD ? get_color_map_entry DD ? set_color_map_entry DD ? available_colors DD ? possible_colors DD ? ;; get_color_map DD ? ;; set_color_map DD ? ;; make_color_map DD ? medley_to_native_bm DD ? native_to_mdley_bm DD ? bitblit_to_screen DD ? bitblit_from_screen DD ? scroll_region DD ? mouse_invisible DD ? mouse_visible DD ? Disp MRegion <> bitsperpixel DD ? colors DD ? oldstate DD ? graphicsstate DD ? numberofbanks DD ? BytesPerLine DD ? DisplayStartAddr DD ? DisplaySegSize DD ? DisplaySegMagnitude DD ? LinesPerBank DD ? SwitchBank DD ? DspInterfaceRec ENDS ;;; ****************************** ;;; IOPAGE good old iopage from medley... ;;; **IT IS IMPORTANT THAT YOU KEEP THIS RECORD IN SYNC ;;; WITH THE DspInterfaceRec DEFINED IN C. ;;; ****************************** IOPAGE STRUC dummy0 DW 22o DUP (?) dlfloppycmd DW ? dlmaintpanel DW ? dlprocessorcmd DW ? dlttyportcmd DW ? dlbeepcmd DW ? newmousestate DW ? dlrs232cputflag DW ? dlrs232cmisccommand DW ? dummy1b DW ? dlrs232cgetflag DW ? dummy1 DW 4o DUP (?) dlfloppy DW ? dummy1a DW ? dummy2 DW ? dlttyout DW ? dummy3 DW ? dlttyin DW ? dlprocessor1 DW ? dlprocessor2 DW ? newmousex DW ? dlprocessor0 DW ? dlbeepfreq DW ? newmousey DW ? dlrs232cparametercsbhi DW ? dlrs232cparametercsblo DW ? dlrs232csetrs366status DW 2o DUP (?) dlrs232cputcsblo DW ? dlrs232csetrs366statusa DW ? dlrs232cgetcsblo DW ? dlrs232cputcsbhi DW ? dlrs232cdevicestatus DW ? dlrs232cgetcsbhi DW ? dltodvalid DW ? dlrs232cparameteroutcome DW ? dltodhi DW ? dltodlo DW ? dlmousex DW ? dltodlo2 DW ? dlutilin DW ? dlmousey DW ? dlkbdad1 DW ? dlkbdad0 DW ? dlkbdad3 DW ? dlkbdad2 DW ? dlkbdad5 DW ? dlkbdad4 DW ? dllsepimagecsb DW 40o DUP (?) dummy4a DW ? dliophardwareconfig DW ? dummy4 DW 12o DUP (?) dlrs232cparametercsbhi_11 DW ? dlrs232cparametercsblo_11 DW ? dlrs232csetrs366status_11 DW 16o DUP (?) dummy5 DW 74o DUP (?) dlmagtape DW 4o DUP (?) dlethernet DW 14o DUP (?) dummy6 DW 36o DUP (?) dldispinterrupt DW ? dummy6a DW ? dldispborder DW ? dldispcontrol DW ? dlcursory DW ? dlcursorx DW ? dlcursorbitmap DW 20o DUP (?) IOPAGE ENDS DATA ENDS CODE SEGMENT USE32 ASSUME DS:DATA ASSUME CS:CODE DOBANK MACRO NUMBER push eax mov ax, NUMBER mov dx, 3cdh out dx, ax pop eax ENDM RET2C MACRO VALUE mov eax,VALUE leave ret ENDM ;; ************************************************** ;; D o s c l e a r b a n k s ;; arg1: dsp (pointer to dsp struct) ;; ;; Fill banks with 0. ;; ************************************************** dsp = 8 bank = -8 PUBLIC Dosclearbanks Dosclearbanks PROC NEAR enter 16,0 push edx push ecx push edi mov DWORD PTR bank[ebp], 0 mov edx, dsp[ebp] mov ecx, [edx.numberofbanks] clrbnk: push ecx DOBANK bank[ebp] add DWORD PTR bank[ebp], 1 mov eax, 0 mov edi, [edx.DisplayStartAddr] mov ecx, [edx.DisplaySegSize] rep stosd pop ecx loop clrbnk pop edi pop ecx pop edx RET2C 0 Dosclearbanks ENDP ;; ************************************************** ;; D O S C u r s o r V i s s i b l e ;; arg1: dsp (pointer to dsp struct) ;; arg2: iop (pointer to IOPAGE struct ;; Medley's cursor has no meaningful mask. The mask ;; is just the invers of the map (sigh...). The function ;; f(bg, map, curs) = bg*mask + (not mask)*curs thus ;; collapses to bg*(not curs) + curs. Since the medley ;; bitmaps have the inverse meaning of the vesa bitmaps ;; (ie. they are pre inverted for your convenience!) ;; the expression turns out to be: ;; bg*curs + (not curs) ;; ;; The general idea here is that we blit the cursor ;; directly to the screen instead of to the displayregion. ;; this saves a whole bunch of time since taking the ;; mouse down is just a matter of updating the screen. ;; since this operation has to be done every charblt ;; we save bunches of time. /jarl ;; ;; Assumption: we can straddle at most two banks ;; ************************************************** dsp = 8 iop = 12 PUBLIC DOSCursorVisible DOSCursorVisible PROC NEAR enter 32,0 push edx push esi push edi push ebx push ecx mov edx, dsp[ebp] mov esi, iop[ebp] ;; find the destiniation byte index movzx eax, [esi.dlcursory] imul eax, [edx.BytesPerLine] movzx ebx, [esi.dlcursorx] sar ebx, 3 ; Make it a byte address add eax, ebx mov edi, eax ;; make the dest index be an address within bounds and edi, [edx.DisplaySegSize] or edi, [edx.DisplayStartAddr] setbnk: mov dx, 3cdh ; Set the bank mov ax, 0 out dx, ax add esi, dlcursorbitmap mov ecx, 16 ; The curs height bltcur: lodsw ; cursorbitmap to ax mov ax, 1010101010101010b stosw add edi, [edx.BytesPerLine] loop bltcur pop ecx pop ebx pop edi pop esi pop edx RET2C 0 DOSCursorVisible ENDP ;; ************************************************** ;; ************************************************** ;; D o s b b t 1 ;; arg1: dsp (pointer to a dsp struct) ;; arg2: buffer (pointer to array of word) ;; arg3: left (dword) (in pixels) ;; arg4: top (dword) (in pixels) ;; arg5: swidth (dword) (in pixels) ;; arg6: height (dword) (in pixels) ;; ;; Bitblits the image stored in buffer to the display ;; buffer. Assumption: buffer and the displaybuffer ;; are equally large and thus left, top etc. pertains ;; to the same offsets. ;; ;; ;; C-CALL: void Dosbbt1( ... ); ;; RETURN: 0 in eax. should be ignored... ;; ************************************************** dsp = 8 buffer = 12 left = 16 top = 20 swidth = 24 height = 28 left32 = -8 width32 = -12 endptr = -16 desttop = -20 dstincr = -24 srcincr = -28 PUBLIC Dosbbt1 Dosbbt1 PROC NEAR ;;; ***************************** ;;; Save the volatile environment ;;; ***************************** enter 32,0 push ebx push ecx push edx push esi push edi mov edx, dsp[ebp] ;; Adjust the arguments to fit inside the display ;; if left > displaywidth then exit mov eax, [edx.Disp.RegWidth] cmp left[ebp], eax jg alldone ;; if 0 > (width + left) then exit mov eax, left[ebp] add eax, swidth[ebp] cmp eax, 0 jl alldone ;; if top > displayheight then exit mov eax, [edx.Disp.RegHeight] cmp top[ebp], eax jg alldone ;; if 0 > (top + height) then exit mov eax, top[ebp] add eax, height[ebp] cmp eax, 0 jl alldone ;; if 0 > left then clipleft mov eax, left[ebp] cmp eax, 0 jl clipleft tstwdt: ;; if (left + swidth) > displaywidth then clipwidth mov eax, left[ebp] add eax, swidth[ebp] cmp eax, [edx.Disp.RegWidth] jg clipwidth tsttop: ;; if 0 > top then cliptop mov eax, top[ebp] cmp eax, 0 jl cliptop tsthit: ;; if (top + height) > displayheight then clipbottom mov eax, top[ebp] add eax, height[ebp] cmp eax, [edx.Disp.RegHeight] jg clipbtm jmp startpoint clipleft: mov DWORD PTR left[ebp], 0 jmp tstwdt clipwidth: mov eax, [edx.Disp.RegWidth] sub eax, left[ebp] mov swidth[ebp], eax jmp tsttop cliptop: mov DWORD PTR top[ebp], 0 jmp tsthit clipbtm: mov eax, [edx.Disp.RegHeight] sub eax, top[ebp] mov height[ebp], eax ;; Calculate byte offset into bitmap startpoint: mov eax, [edx.Disp.RegWidth] imul eax, top[ebp] add eax, left[ebp] sar eax, 5 ; Make it a byte address on dword boundaries. sal eax, 2 ;; Set dst and src start mov edi, eax mov esi, eax add edi, [edx.DisplayStartAddr] add esi, buffer[ebp] ;; Set dst and src incr mov eax, left[ebp] add eax, swidth[ebp] add eax, 1fh sar eax, 5 mov ebx, left[ebp] sar ebx, 5 sub eax, ebx mov width32[ebp], eax ; width32 is width in dwords sal eax, 2 ; Make width32 a byteadr on dword boundaries. mov ebx, [edx.Disp.RegWidth] sar ebx, 3 sub ebx, eax ;; {dst,src}incr is what to add to {esi,edi} to get to the new line mov dstincr[ebp], ebx mov srcincr[ebp], ebx ;;; ****************************** Newline1: mov ecx, width32[ebp] ; swidth into ecx Dumpline1: lodsd ; Load eax and increment esi xchg ah,al ; Swap low byte rol eax,10h ; Get the high byte into position xchg ah,al ; Swap again not eax ; In medley 1=black 0=white, Hence invert. stosd ; Store eax and increment edi loop Dumpline1 ;; calc vals for src and dest for the next line. add edi, dstincr[ebp] add esi, srcincr[ebp] dec DWORD PTR height[ebp] jg Newline1 alldone: pop edi pop esi pop edx pop ecx pop ebx RET2C 0 Dosbbt1 ENDP ;; ************************************************** ;; ************************************************** ;; D o s b b t 2 ;; arg1: dsp (pointer to a dsp struct) ;; arg2: buffer (pointer to array of word) ;; arg3: left (dword) (in pixels) ;; arg4: top (dword) (in pixels) ;; arg5: swidth (dword) (in pixels) ;; arg6: height (dword) (in pixels) ;; ;; FUNCTION: Monocrome bbt to a 4-plane displaybuffer. ;; ;; Bitblits the image stored in buffer to the display ;; buffer. ASSUMPTION: buffer and the displaybuffer ;; are equally large and thus left, top etc. pertains ;; to the same offsets. ;; ;; Medley has a packed bitmap structure. Dosbbt2 assumes ;; that we are operating in 4-plane mode. The medley ;; bitmap is blitted to the first plane of the display. ;; Thus the bitmap appears black and white. ;; ;; ;; C-CALL: void Dosbbt2( ... ); ;; RETURN: 0 in eax. should be ignored... ;; ************************************************** dsp = 8 buffer = 12 left = 16 top = 20 swidth = 24 height = 28 left32 = -8 width32 = -12 endptr = -16 desttop = -20 dstincr = -24 srcincr = -28 tmpheight = -32 switchr = -36 PUBLIC Dosbbt2 Dosbbt2 PROC NEAR ;;; ***************************** ;;; Save the volatile environment ;;; ***************************** enter 36,0 push ebx push ecx push edx push esi push edi mov edx, dsp[ebp] ;; Adjust the arguments to fit inside the display ;; if left > displaywidth then exit mov eax, [edx.Disp.RegWidth] cmp left[ebp], eax jg allbye ;; if 0 > (width + left) then exit mov eax, left[ebp] add eax, swidth[ebp] cmp eax, 0 jl allbye ;; if top > displayheight then exit mov eax, [edx.Disp.RegHeight] cmp top[ebp], eax jg allbye ;; if 0 > (top + height) then exit mov eax, top[ebp] add eax, height[ebp] cmp eax, 0 jl allbye ;; if 0 > left then clipleft mov eax, left[ebp] cmp eax, 0 jl clipleft2 tstwdt2: ;; if (left + swidth) > displaywidth then clipwidth mov eax, left[ebp] add eax, swidth[ebp] cmp eax, [edx.Disp.RegWidth] jg clipwidth2 tsttop2: ;; if 0 > top then cliptop mov eax, top[ebp] cmp eax, 0 jl cliptop2 tsthit2: ;; if (top + height) > displayheight then clipbottom mov eax, top[ebp] add eax, height[ebp] cmp eax, [edx.Disp.RegHeight] jg clipbtm2 jmp startpt clipleft2: mov DWORD PTR left[ebp], 0 jmp tstwdt2 clipwidth2: mov eax, [edx.Disp.RegWidth] sub eax, left[ebp] mov swidth[ebp], eax jmp tsttop2 cliptop2: mov DWORD PTR top[ebp], 0 jmp tsthit2 clipbtm2: mov eax, [edx.Disp.RegHeight] sub eax, top[ebp] mov height[ebp], eax ;; Calculate byte offset into bitmap startpt: mov eax, [edx.Disp.RegWidth] imul eax, top[ebp] add eax, left[ebp] sar eax, 5 ; Make it a byte address on dword boundaries. sal eax, 2 ;; Calculate which bank to start in. push eax push ecx mov ecx, [edx.DisplaySegMagnitude] sar eax, cl mov DWORD PTR bank[ebp], eax pop ecx pop eax ;; Set dst and src start mov edi, eax mov esi, eax add esi, buffer[ebp] ;; Set dst and src incr mov eax, left[ebp] add eax, swidth[ebp] add eax, 1fh sar eax, 5 mov ebx, left[ebp] sar ebx, 5 sub eax, ebx mov width32[ebp], eax ; width32 is width in dwords sal eax, 2 ; Make width32 a byteadr on dword boundaries. mov ebx, [edx.Disp.RegWidth] sar ebx, 3 sub ebx, eax ;; {dst,src}incr is what to add to {esi,edi} to get to the new line mov dstincr[ebp], ebx mov srcincr[ebp], ebx ;; Adjust top to be inside the startbank push eax mov eax, [edx.LinesPerBank] dec eax and DWORD PTR top[ebp], eax pop eax Newbank2: ;; Set the bank ;; Use VESA int procedure to do this. mov edx, DWORD PTR bank[ebp] mov bx, 0 mov ax,4f05h int 10h mov edx, dsp[ebp] ;Restore edx. ;; Adjust dst to be within axxxxh push eax mov eax, [edx.DisplaySegSize] dec eax and edi, eax add edi, [edx.DisplayStartAddr] pop eax ;; XX mov ebx, height[ebp] mov eax, top[ebp] add eax, ebx cmp eax, [edx.LinesPerBank] jle doit mov ebx, [edx.LinesPerBank] sub ebx, top[ebp] doit: mov DWORD PTR top[ebp], 0 mov tmpheight[ebp], ebx sub height[ebp], ebx Newline2: mov ecx, width32[ebp] ; swidth into ecx Dumpline2: lodsd ; Load eax and increment esi xchg ah,al ; Swap low byte rol eax,10h ; Get the high byte into position xchg ah,al ; Swap again not eax ; In medley 1=black 0=white, Hence invert. stosd ; Store eax and increment edi loop Dumpline2 ;; calc vals for src and dest for the next line. add edi, dstincr[ebp] add esi, srcincr[ebp] dec DWORD PTR tmpheight[ebp] jg Newline2 inc DWORD PTR bank[ebp] cmp DWORD PTR height[ebp], 0 jg Newbank2 allbye: pop edi pop esi pop edx pop ecx pop ebx RET2C 0 Dosbbt2 ENDP ;; ************************************************** ;; ************************************************** ;; D o s b b t 3 ;; arg1: dsp (pointer to a dsp struct) ;; arg2: buffer (pointer to array of word) ;; arg3: left (dword) (in pixels) ;; arg4: top (dword) (in pixels) ;; arg5: swidth (dword) (in pixels) ;; arg6: height (dword) (in pixels) ;; ;; Bitblits the image stored in buffer to the display ;; buffer. ASSUMPTION: buffer and the displaybuffer ;; are equally large and thus left, top etc. pertains ;; to the same offsets. ;; ;; Medley has a packed bitmap structure. Dosbbt3 assumes ;; that we are operating in 4-plane mode. The medley ;; bitmap is blitted to the first plane of the display. ;; Thus the bitmap appears black and white. ;; ;; ;; C-CALL: void Dosbbt3( ... ); ;; RETURN: 0 in eax. should be ignored... ;; ************************************************** dsp = 8 buffer = 12 left = 16 top = 20 swidth = 24 height = 28 srcend = -8 PUBLIC Dosbbt3 Dosbbt3 PROC NEAR ;;; ***************************** ;;; Save the volatile environment ;;; ***************************** enter 32,0 push ebx push ecx push edx push esi push edi ;;; Set up the dsp in edx mov edx, dsp[ebp] ;;; Adjust left to be a byte offset at a dword boundary ;;; - Not needed. We shove bytes at byte boundaries ;;; Adjust width to be a byte offset at a dword boundary ;;; - Not needed. We shove bytes at byte boundaries ;;; Calculate start index for src mov eax, top[ebp] imul eax, [edx.BytesPerLine] add eax, left[ebp] mov esi, eax ;;; Calculate start index for dst. mov edi, eax ;;; Calculate end address for src mov eax, top[ebp] add eax, height[ebp] imul eax, [edx.BytesPerLine] add eax, buffer[ebp] mov srcend[ebp], eax ;;; Calculate the dstincr, ie. what to add to dst to ;;; get to the next line mov eax, [edx.BytesPerLine] sub eax, swidth[ebp] mov dstincr[ebp], eax ;;; Calculate the srcincr, ie. what to add to src to ;;; get to the next line mov srcincr[ebp], eax ;;; Calculate the start address for the src ;; We already know the byte index. Easy calculat'n add esi, buffer[ebp] ;esi now points to src Newbank3: ;; Set the bank mov eax, esi ; 1. Calculate the index. sub eax, buffer[ebp] sar eax, 10h ; 2. Divide by "bytes-per-buffer" ; WARNING! this implies buffersize. mov dx, 3cdh out dx, ax ; 3. Set the port. mov edx, dsp[ebp] ; Reinstate edx ;; Adjust dst to be within the bank. and edi, [edx.DisplaySegSize] or edi, [edx.DisplayStartAddr] Newline3: mov ecx, swidth[ebp] ; width into ecx rep movsb ; Dump a line to the display ;; calc vals for src and dest for the next line. add edi, dstincr[ebp] add esi, srcincr[ebp] ;; End of block? cmp esi, srcend[ebp] jge QuitThis ; Yes, scram. ;; End of bank ? cmp ax, 0 jge Newline3 ; No. Blit a new line. mov edi, esi ; Yes. Reload edi, jmp Newbank3 ; and blit a new line. QuitThis: pop edi pop esi pop edx pop ecx pop ebx RET2C 0 Dosbbt3 ENDP CODE ENDS END