1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-01-15 15:57:13 +00:00
Interlisp.maiko/src/vesafns.asm
2021-01-15 16:59:32 +00:00

827 lines
18 KiB
NASM

;; # @(#) 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