mirror of
https://github.com/Interlisp/maiko.git
synced 2026-01-15 15:57:13 +00:00
827 lines
18 KiB
NASM
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
|