;************************************************************************ ;* Copyright 1999, Caldera Thin Clients, Inc. * ;* This software is licenced under the GNU Public License. * ;* Please see LICENSE.TXT for further information. * ;* * ;* Historical Copyright * ;* * ;* * ;* * ;* Copyright (c) 1987, Digital Research, Inc. All Rights Reserved. * ;* The Software Code contained in this listing is proprietary to * ;* Digital Research, Inc., Monterey, California and is covered by U.S. * ;* and other copyright protection. Unauthorized copying, adaptation, * ;* distribution, use or display is prohibited and may be subject to * ;* civil and criminal penalties. Disclosure to others is prohibited. * ;* For the terms and conditions of software code use refer to the * ;* appropriate Digital Research License Agreement. * ;* * ;************************************************************************ EJECT ;Hist ; cseg public vec_len public GET_DS public ABLINE public HABLINE public DIS_CUR public HIDE_CUR public MOV_CUR public SMUL_DIV public CLC_FLIT public XFM_CRFM public XFM_UDFL public VEX_BUTV public VEX_MOTV public VEX_CURV public RECTFILL if mono_port public next_seg_pgdown next_seg_pgdown: sub di, plane_size ;wrap back to 0 offset base push dx push ax mov dx, plane_sel_port mov al, ss:current_bank inc al out dx, al mov ss:current_bank, al pop ax pop dx ret endif vec_len: push bp mov bp, sp ; Check for zeroes. cmp word ptr 4[bp], 0 jne x_squared cmp word ptr 6[bp], 0 jne x_squared xor bx, bx ; return value jmp search_loop_end ; Calculate delta_x squared. x_squared: mov dx, 4[bp] ; delta_x parameter mov ax, dx imul dx mov vec_len_high, dx ; save high word of square mov vec_len_low, ax ; save low word of square ; Calculate delta_y squared and add to delta_x squared. mov dx, 6[bp] ; delta_y parameter mov ax, dx imul dx add vec_len_low, ax adc vec_len_high, dx ; high/low = sum of squares ; Get the initial binary search boundaries. This is done by taking an ; approximate square root based on the highest order set bit in the ; high/low bit string. cmp vec_len_high, 0 je no_high_byte mov ax, vec_len_high ; check on high order byte mov cl, 16 jmp bounds_loop no_high_byte: mov ax, vec_len_low ; check on low order byte sub cl, cl bounds_loop: cmp ax, 1 ; done yet? je bounds_loop_end inc cl shr ax, 1 jmp bounds_loop bounds_loop_end: shr cl, 1 mov bx, 1 shl bx, cl ; bx = initial low bound mov cx, bx shl cx, 1 ; cx = initial high bound ; Perform a binary search for a square root (somewhat brutishly). search_loop: mov ax, cx sub ax, bx cmp ax, 1 ; done with the search? jle search_loop_end shr ax, 1 add ax, bx ; candidate = (high+low)/2 mov si, ax ; save a copy for next pass mul ax ; dx/ax = candidate square cmp dx, vec_len_high ; check against high word ja high_adjust jb low_adjust cmp ax, vec_len_low ; check against low word ja high_adjust jb low_adjust mov bx, si ; exact root found! jmp search_loop_end high_adjust: mov cx, si ; adjust high value down jmp search_loop low_adjust: mov bx, si ; adjust low value up jmp search_loop search_loop_end: mov ax, bx ; ax = solution pop bp ret ; ;*************************************************************************** ; ; SMUL_DIV (m1,m2,d1) ; ; ( ( ( m1 * m2 ) / d1 ) + 1 / 2 ; m1 = signed 16 bit integer ; m2 = snsigned 15 bit integer ; d1 = signed 16 bit integer ; ;*************************************************************************** SMUL_DIV: push bp ;save the callers bp mov bp,sp mov ax,06[bp] mov bx,04[bp] imul bx ; m2 * m1 mov si, 1 and dx, dx jns smul_div_1 neg si smul_div_1: mov bx,08[bp] idiv bx ; m2 * m1 / d1 pop bp and bx, bx ; test if divisor is negative jns smul_div_2 neg si neg bx ; make it positive smul_div_2: and dx, dx ; test if remainder is negative jns smul_div_3 neg dx ; make remainder positive smul_div_3: shl dx, 1 ; see if 2 * remainder is > divisor cmp dx, bx jl smul_div_4 add ax, si smul_div_4: ret eject EJECT ;************************************************************************ ;TENNIS * ; Entry CX - delta count for ABLINE (count includes last point) * ; Exit CX is decremented by one if: * ; XOR writing mode and the line about to be * ; drawn is not the last of the poly line * ; else Cx is left alone * ; Purpose: Xor does not Xor itself at intersection points of * ; polline or plydpl of fill * ;************************************************************************ tennis: cmp WRT_MODE, 2 ; check if xor jnz jimmy cmp LSTLIN, 0 ; check if XOR and last line of pollin jnz jimmy ; if false go around cmp cx, 1 jz jimmy dec cx jimmy: ret ; EJECT ;**************************************************************** ;Subroutine HABLINE * ; Entry: X1-coordinate * ; Y1-coordinate * ; X2-coordinate * ; patptr - pointer to fill pattern table * ; * ; Purpose: * ; This routine will draw a line from (X1,Y1) to * ; (X2,Y1) using a horizontal line algorithm. * ;**************************************************************** HABLINE: push bp push Y2 mov ax, Y1 mov Y2, ax call BOX_FILL pop Y2 pop bp ret GET_DS: mov ax,ds ret ; ;****************************************************************************** ; ; PROCEDURE: RECTFIL Fill Rectangle ; ; Inputs: X1,Y1 = upper left ; X2,Y2 = lower right ; ;****************************************************************************** ; RECTFILL: mov ax, CLIP ; is clipping on? and ax, ax jnz rectfill_clip_1 jmp BOX_FILL ; goto horizontal line draw routine rectfill_clip_1: mov ax, XMN_CLIP mov bx, X1 mov cx, X2 cmp bx, ax ; is x1 < xmn_clip jnl rectfill_clip_3 cmp cx, ax ; is x2 >= xmn_clip jl rectfill_clip_2 mov X1, ax rectfill_clip_3: mov ax, XMX_CLIP cmp cx, ax ; is x2 > xmx_clip jle rectfill_clip_4 cmp bx, ax ; is x1 <= xmx_clip jg rectfill_clip_2 mov X2, ax jmps rectfill_clip_4 rectfill_clip_2: ret ; if x2 not > xmn_clip exit rectfill_clip_4: mov ax, YMN_CLIP mov bx, Y1 mov cx, Y2 cmp bx, ax ; is y1 < ymn_clip jnl rectfill_clip_5 cmp cx, ax ; is y2 >= ymn_clip jl rectfill_clip_2 mov Y1, ax rectfill_clip_5: mov ax, YMX_CLIP cmp cx, ax ; is y2 > ymx_clip jle rectfill_clip_6 cmp bx, ax ; is y1 <= ymx_clip jg rectfill_clip_2 mov Y2, ax rectfill_clip_6: jmps BOX_FILL ;****************************************************************************** ; BOX_FILL ; Fill a rectangular area with pattern ; ; Entry X1,Y1 = upper left corner inclusive ; X2,Y2 = lower right corner inclusive ; ;****************************************************************************** BOX_FILL: mov bx, X1 and bx, 0fff0h ; make sure it lines up on a word boundary mov ax, Y1 ; find the physical address call concat ; di = display memory pointer if byte_swap and di, 0fffeh ; make sure it points to low byte endif if mono_multisegs or mono_xrxfp ; else mov ax, graph_plane mov es, ax ; init the segment register endif BOX_FILL_LINE: mov ax, 0fh mov dx, X1 mov bx, dx ; save X1 for later and bx, ax ; get the left mask word shl bx, 1 ; index by words mov bx, word_mask_table[bx] not bx ; make it the left one xchg bh,bl ; account for byte swap mov left_word_mask, bx mov bp, X2 inc bp ; point one past the right most pixel mov bx, bp ; save X2 + 1 for later and bx, ax shl bx, 1 ; index by words mov bx, word_mask_table[bx] xchg bh,bl mov right_word_mask,bx mov cl,4 ; find the word count bp = x2 , dx = x1 shr bp, cl ; divide by four shr dx, cl sub bp, dx ; word count = x2/4 - x1/4 -1 dec bp jge box_fill_ok xor bp,bp ; make word count = 0 cmp bx, 0ffffh ; is it left only? jz box_left_mask_only or left_word_mask, bx box_left_mask_only: mov right_word_mask,0ffffh ; don't let the right mask do anything box_fill_ok: mov si, Y1 mov cx, Y2 ; calculate the scan count sub cx, si inc cx ; cx = scan count = delta y + 1 if wy700 shr si,1 endif and si, patmsk ; get the pattern index value mov bx, patptr ; get the pattern pointer add bx, si add bx, si ; index in properly ; box_fill_1: mov plane_loop_count, num_planes ; load up the plane count mov ax, FG_BP_1 shl ax,1 shl ax,1 ; set up the color index values mov TMP_FG_BP,ax mov ax, 1 ; set up the mask bit for plane/color push patptr ; save away the pointer for user fill push ax box_fill_0: pop ax ; get ax back if (num_planes gt 1) and not( segment_access ) push dx push bx mov dx, plane_sel_port mov bx, ax ; load up the pointer to table mov al, plane_port_tbl[bx] out dx, al ; output the byte for the port mov dx, plane_read_port mov al, plane_read_tbl[bx] out dx, al mov ax, bx pop bx pop dx endif shl ax, 1 ; move the bit mask over one push ax ; save the mask mov ax, bx add bx, NEXT_PAT ; add in the next pattern ammount push bx mov bx,TMP_FG_BP ; get the and bx,4 ; mask off color bit mov BOX_MODE, bx mov bx,WRT_MODE shl bx,1 mov bx, box_optbl[bx] shr TMP_FG_BP,1 ; put the next plane bit into place push cx push dx push si push di push bp call bx ; call the box fill routine mov bx, NEXT_PAT add patptr, bx pop bp pop di pop si pop dx pop cx pop bx if (num_planes gt 1) and segment_access mov ax, es add ax, next_plane mov es, ax endif dec plane_loop_count ; is line done jnz box_fill_0 pop ax pop patptr ret ;******************************* ; box_tran_mode ; entry es:di = memory address ; si = pattern index ; ax = pattern pointer ; patmsk = current pattern max count ; bp = word count ; cx = scan line count ; dx used for pattern storage ; ;******************************* box_tran_mode: mov patcnt, si mov si, ax jmps box_tran box_tran_loop: if wy700 call dest_add else add di, next_line endif if mono_mem cmp di, plane_size jc box_tran_pattinc sub di, plane_size mov al, ss:current_bank inc al cmp al, 0c7h ;past last bank? jnz box_tran_monook mov al, 0c0h add di, bytes_line box_tran_monook: mov ss:current_bank, al mov es:.mono_mem_off, al endif if mono_port cmp di, plane_size ;have we wrapped past the end? jc box_tran_pattinc call next_seg_pgdown endif if mono_xrxfp jnc box_tran_pattinc mov ax, es cmp ax, graph_plane mov ax, graph_plane_high jz box_tran_pattinc_xrx mov ax, graph_plane add di, bytes_line box_tran_pattinc_xrx: mov es, ax endif if mono_multisegs jnc box_tran_pattinc mov es, graph_seg_high ;get the data from cs: endif if multiseg cmp di, plane_size jc box_tran_pattinc add di, move_to_first endif box_tran_pattinc: if wy700 test cs:current_port,3 jnz skip_inc_pat1 endif inc si inc si ; point to next word inc patcnt ; point to next word skip_inc_pat1: mov ax, patmsk cmp patcnt, ax ; is the pattern index > mask jle box_tran mov si, patptr ; point pattern back to top mov patcnt, 0 ; start pattern count over box_tran: push di ; save the current address push cx ; save the outer loop count mov dx,[si] ; get the current pattern xchg dh,dl ; requires byte swap ; ; Left Fringe mov ax, es:[di] ; apply the left fringe mask mov cx, ax ; save the dest word test BOX_MODE, 0ffffh jz box_tran_left_back if not rev_vid or ax, dx else not dx and ax, dx not dx endif jmps box_tran_left_mask box_tran_left_back: if rev_vid or ax, dx else not dx and ax, dx not dx endif box_tran_left_mask: xor cx, ax ; mask out the bits and cx, left_word_mask xor ax, cx ; xor out the pattern stosw ; store the word to memory ; ; Inner Word Loop mov cx, bp jcxz box_tran_right test BOX_MODE, 0ffffh jz box_tran_back_word_loop if not rev_vid box_tran_fore_word_loop: mov ax, es:[di] ; get the destination word or ax, dx stosw ; move out the word to memory in fastest way loop box_tran_fore_word_loop else not dx box_tran_fore_word_loop: mov ax, es:[di] ; get the destination word and ax, dx stosw ; move out the word to memory in fastest way loop box_tran_fore_word_loop not dx endif jmps box_tran_right if rev_vid box_tran_back_word_loop: mov ax, es:[di] ; get the destination word or ax, dx stosw ; move out the word to memory in fastest way loop box_tran_back_word_loop else box_tran_back_word_loop: not dx box_tran_back_word_loop1: mov ax, es:[di] ; get the destination word and ax, dx stosw ; move out the word to memory in fastest way loop box_tran_back_word_loop1 not dx endif ; ; Right Fringe box_tran_right: mov ax, es:[di] ; apply the left fringe mask mov cx, ax ; save the dest word test BOX_MODE, 0ffffh jz box_tran_right_back if not rev_vid or ax, dx else not dx and ax, dx not dx endif jmps box_tran_right_mask box_tran_right_back: if rev_vid or ax, dx else not dx and ax, dx not dx endif box_tran_right_mask: xor cx, ax ; mask out the bits and cx, right_word_mask xor ax, cx ; xor out the pattern stosw ; store the word to memory pop cx pop di dec cx jcxz box_tran_done jmp box_tran_loop box_tran_done: ret ; ;******************************* ; box_xor_mode ; entry es:di = memory address ; si = pattern index ; ax = pattern pointer ; patmsk = current pattern max count ; bp = word count ; cx = scan line count ; dx used for pattern storage ; ;******************************* box_xor_mode: mov patcnt, si mov si, ax jmps box_xor box_xor_loop: if wy700 call dest_add else add di, next_line endif if mono_xrxfp jnc box_xor_pattinc mov ax, es cmp ax, graph_plane mov ax, graph_plane_high jz box_xor_pattinc_xrx mov ax, graph_plane add di, bytes_line box_xor_pattinc_xrx: mov es, ax endif if mono_multisegs jnc box_xor_pattinc mov es, graph_seg_high ;get the data from cs: endif if mono_mem cmp di, plane_size jc box_xor_pattinc sub di, plane_size mov al, ss:current_bank inc al cmp al, 0c7h ;past last bank? jnz box_xor_monook mov al, 0c0h add di, bytes_line box_xor_monook: mov ss:current_bank, al mov es:.mono_mem_off, al endif if mono_port cmp di, plane_size ;have we wrapped past the end? jc box_xor_pattinc call next_seg_pgdown endif if multiseg cmp di, plane_size jc box_xor_pattinc add di, move_to_first endif box_xor_pattinc: if wy700 test cs:current_port,3 jnz skip_inc_pat2 endif inc si inc si ; point to next word inc patcnt ; point to next word skip_inc_pat2: mov ax, patmsk cmp patcnt, ax ; is the pattern index > mask jle box_xor mov si, patptr ; point pattern back to top mov patcnt, 0 ; start pattern count over box_xor: push di ; save the current address push cx ; save the outer loop count mov dx,[si] ; get the current pattern xchg dh,dl ; requires byte swap ; ; Left Fringe mov ax, es:[di] ; apply the left fringe mask mov cx, ax ; save the dest word xor ax, dx xor cx, ax ; mask out the bits and cx, left_word_mask xor ax, cx ; xor out the pattern stosw ; store the word to memory ; ; Inner Word Loop mov cx, bp jcxz box_xor_right box_xor_fore_word_loop: mov ax, es:[di] ; get the destination word xor ax, dx stosw ; move out the word to memory in fastest way loop box_xor_fore_word_loop ; ; Right Fringe box_xor_right: mov ax, es:[di] ; apply the left fringe mask mov cx, ax ; save the dest word xor ax, dx xor cx, ax ; mask out the bits and cx, right_word_mask xor ax, cx ; xor out the pattern stosw ; store the word to memory pop cx pop di loop box_xor_loop ret ;******************************* ; box_invtran_mode ; entry es:di = memory address ; si = pattern index ; ax = pattern pointer ; patmsk = current pattern max count ; bp = word count ; cx = scan line count ; dx used for pattern storage ; ;******************************* box_invtran_mode: mov patcnt, si mov si, ax jmps box_invtran box_invtran_loop: if wy700 call dest_add else add di, next_line endif if mono_xrxfp jnc box_invtran_pattinc mov ax, es cmp ax, graph_plane mov ax, graph_plane_high jz box_invtran_pattinc_xrx mov ax, graph_plane add di, bytes_line box_invtran_pattinc_xrx: mov es, ax endif if mono_multisegs jnc box_invtran_pattinc mov es, graph_seg_high ;get the data from cs: endif if mono_mem cmp di, plane_size jc box_invtran_pattinc sub di, plane_size mov al, ss:current_bank inc al cmp al, 0c7h ;past last bank? jnz box_invtran_monook mov al, 0c0h add di, bytes_line box_invtran_monook: mov ss:current_bank, al mov es:.mono_mem_off, al endif if mono_port cmp di, plane_size ;have we wrapped past the end? jc box_invtran_pattinc call next_seg_pgdown endif if multiseg cmp di, plane_size jc box_invtran_pattinc add di, move_to_first endif box_invtran_pattinc: if wy700 test cs:current_port,3 jnz skip_inc_pat3 endif inc si inc si ; point to next word inc patcnt ; point to next word skip_inc_pat3: mov ax, patmsk cmp patcnt, ax ; is the pattern index > mask jle box_invtran mov si, patptr ; point pattern back to top mov patcnt, 0 ; start pattern count over box_invtran: push di ; save the current address push cx ; save the outer loop count mov dx,[si] ; get the current pattern xchg dh,dl ; requires byte swap ; ; Left Fringe mov ax, es:[di] ; apply the left fringe mask mov cx, ax ; save the dest word test BOX_MODE, 0ffffh jz box_invtran_left_back if not rev_vid not dx or ax, dx not dx else and ax, dx endif jmps box_invtran_left_mask box_invtran_left_back: if rev_vid not dx or ax, dx not dx else and ax, dx endif box_invtran_left_mask: xor cx, ax ; mask out the bits and cx, left_word_mask xor ax, cx ; xor out the pattern stosw ; store the word to memory ; ; Inner Word Loop mov cx, bp jcxz box_invtran_right test BOX_MODE, 0ffffh jz box_invtran_back_word_loop if not rev_vid not dx box_invtran_fore_word_loop: mov ax, es:[di] ; get the destination word or ax, dx stosw ; move out the word to memory in fastest way loop box_invtran_fore_word_loop not dx else box_invtran_fore_word_loop: mov ax, es:[di] ; get the destination word and ax, dx stosw ; move out the word to memory in fastest way loop box_invtran_fore_word_loop endif jmps box_invtran_right if rev_vid box_invtran_back_word_loop: not dx box_invtran_back_word_loop1: mov ax, es:[di] ; get the destination word or ax, dx stosw ; move out the word to memory in fastest way loop box_invtran_back_word_loop1 not dx else box_invtran_back_word_loop: mov ax, es:[di] ; get the destination word and ax, dx stosw ; move out the word to memory in fastest way loop box_invtran_back_word_loop endif ; ; Right Fringe box_invtran_right: mov ax, es:[di] ; apply the left fringe mask mov cx, ax ; save the dest word test BOX_MODE, 0ffffh jz box_invtran_right_back if not rev_vid not dx or ax, dx not dx else and ax, dx endif jmps box_invtran_right_mask box_invtran_right_back: if rev_vid not dx or ax, dx not dx else and ax, dx endif box_invtran_right_mask: xor cx, ax ; mask out the bits and cx, right_word_mask xor ax, cx ; xor out the pattern stosw ; store the word to memory pop cx pop di dec cx jcxz box_invtran_done jmp box_invtran_loop box_invtran_done: ret ;******************************* ; box_replace_mode ; entry es:di = memory address ; si = pattern index ; bx = pattern pointer ; patmsk = current pattern max count ; bp = word count ; cx = scan line count ; dx used for pattern storage ; ;******************************* box_replace_mode: ; mov bx, ax test NEXT_PAT, 0ffffh jnz box_replace test BOX_MODE, 0ffffh jz box_to_0 jmps box_replace box_to_0: mov bx, offset HOLLOW push patptr push patmsk mov patptr, bx xor si, si mov patmsk, si call box_replace pop patmsk pop patptr ret box_rep_loop: if wy700 call dest_add else add di, next_line endif if mono_xrxfp jnc box_replace_pattinc mov ax, es cmp ax, graph_plane mov ax, graph_plane_high jz box_replace_pattinc_xrx mov ax, graph_plane add di, bytes_line box_replace_pattinc_xrx: mov es, ax endif if mono_multisegs jnc box_replace_pattinc mov es, graph_seg_high ;get the data from cs: endif if mono_mem cmp di, plane_size jc box_replace_pattinc sub di, plane_size mov al, ss:current_bank inc al cmp al, 0c7h ;past last bank? jnz box_replace_monook mov al, 0c0h add di, bytes_line box_replace_monook: mov ss:current_bank, al mov es:.mono_mem_off, al endif if mono_port cmp di, plane_size ;have we wrapped past the end? jc box_replace_pattinc call next_seg_pgdown endif if multiseg cmp di, plane_size jc box_replace_pattinc add di, move_to_first endif box_replace_pattinc: if wy700 test cs:current_port,3 jnz skip_inc_pat4 endif inc si inc bx inc bx ; point to next word skip_inc_pat4: cmp si, patmsk ; is the pattern index > mask jle box_replace mov si,0 mov bx, patptr ; point pattern back to top box_replace: push di ; save the current address push cx ; save the outer loop count mov dx,[bx] ; get the current pattern if rev_vid not dx endif xchg dh,dl ; requires byte swap ; ; Left Fringe mov ax, es:[di] ; apply the left fringe mask xor ax, dx ; xor in the pattern and ax, left_word_mask xor ax, dx ; xor out the pattern stosw ; store the word to memory ; ; Inner Word Loop mov cx, bp mov ax,dx jcxz box_rep_right rep stosw ; move out the words to memory in fastest way ; ; Right Fringe box_rep_right: mov ax, es:[di] ; apply the right fringe mask xor ax, dx and ax, right_word_mask xor ax,dx stosw ; store the word to memory pop cx pop di loop box_rep_loop ret ;****************************************************************************** ; ; VEX_BUTV ; ; Exchange button change vector ; ; Entry contrl(7),contrl(8) = pointer to user defined routine ; ; Exit contrl(9),contrl(10) = old pointer to button routine ; ; ;****************************************************************************** VEX_BUTV: mov si, offset userbut call exchg_vector ret exchg_vector: pushf cli push es push ds mov ax, seg contrl mov ds, ax les di,contrl_ptr mov ax,[si] ;get the offset mov es:word ptr 18[di],ax mov ax,2[si] mov es:word ptr 20[di],ax ;get the segment mov ax,contrl+14 mov [si],ax mov ax,contrl+16 mov 2[si],ax ;load the new offset/segment pop ds pop es popf ret ;****************************************************************************** ; ; VEX_MOTV ; ; Exchange coordinate change vector ; ; Entry contrl(7),contrl(8) = pointer to user defined routine ; ; Exit contrl(9),contrl(10) = old pointer to button routine ; ; ;****************************************************************************** VEX_MOTV: mov si, offset usermot call exchg_vector ret ;****************************************************************************** ; ; VEX_CURV ; ; Exchange cursor draw vector ; ; Entry contrl(7),contrl(8) = pointer to user defined routine ; ; Exit contrl(9),contrl(10) = old pointer to button routine ; ; ;****************************************************************************** VEX_CURV: mov si, offset usercur call exchg_vector ret ; ;*********************************************************************** ;XFM_CRFM ; Transform the user defined cursor form to device spec format ; ; Entry CONTRL[7] ; CONTRL[8] = long pointer to input data ; ; Exit ; ; ;*********************************************************************** XFM_CRFM: push ds ;make sure es=ds pop es mov di,offset mxhot ;point at dest mov si,offset intin mov cx,37 rep movsw ;copy the data mov bx, mous_ci_mask ; get the color index val shl bx,1 mov ax, MAP_COL[bx] mov bx, mous_ci_data shl bx,1 mov bx, MAP_COL[bx] mov cx, 4 xfm_crlp: ror al,1 rcr ah,1 ror bl,1 rcr ah,1 loop xfm_crlp mov mous_col_map,ah ret eject ;*********************************************************************** ;XFM_UDFL ; Transform the user defined fill pattern to device spec format ; ; Entry INTIN[0] - INTIN[15] = fill pattern ; ; ;*********************************************************************** XFM_UDFL: mov dx, CONTRL+6 ;get the intin count mov cx, dx ; save away the count xor al, al xfm_udfl_size_ck: inc al sub dx, 16 jc xfm_udfl_bad jz xfm_udfl_size jmps xfm_udfl_size_ck xfm_udfl_size: cmp al, 1 ; 1 is always ok jz xfm_udfl_ok cmp al, num_planes jz xfm_udfl_ok1 xfm_udfl_bad: ;must be integral of 16 mov ax, -1 ret xfm_udfl_ok: mov udpt_np, 0 jmps xfm_udfl_ok2 xfm_udfl_ok1: mov udpt_np, 32 xfm_udfl_ok2: mov dx, cx push ds ;make sure es=ds pop es mov di,offset ud_patrn ;point at dest mov si,offset INTIN mov cx, dx rep movsw ;copy the data mov si,offset ud_patrn if (msb_first and byte_swap) mov cx, dx ;swap 16 words xfm_udfl_loop: mov ax,[si] xchg ah,al mov [si],ax inc si inc si loop xfm_udfl_loop ret endif if (msb_first and not byte_swap) ret endif if (not msb_first and not byte_swap) mov cx, dx xfm_udfl_loop: push cx mov ax,[si] mov cx,16 xfm_udfl_ilp: rol ax,1 rcr bx,1 loop xfm_udfl_ilp mov [si],bx pop cx inc si inc si loop xfm_udfl_loop ret endif eject ;*********************************************************************** ;CLC_FLIT ; Find the Intersection points for each raster line y ; ; Entry CONTRL[1] = vectex count ; PTSIN[] = verticies ; y = scan line to intersect ; fill_int = 0 ; ; Exit fill_int = count of intersections ; INTIN = x values of intersections ; ;*********************************************************************** CLC_FLIT: mov cx,CONTRL+2 ; get points count mov si,offset PTSIN mov di,offset INTIN flit_lp: push cx mov cx, 6[si] ; test ch, 80h ; look at the flag if not a required edge ; jnz no_fill_int mov dx, 2[si] ; and dx, 7fffh ; get rid of flag if any sub cx, dx ; get delta y jz fillit_zero ; goto next x,y if deltay = 0 mov bx,Y1 mov ax,bx sub ax, dx ; delta y1 sub bx, 6[si] ; delta y2 mov dx,ax xor dx,bx ; check if signs = jns fillit_done mov dx, 4[si] sub dx, [si] ; dx = delta x add dx,dx ; 2 * delta x imul dx ; ax = dx * 2 * deltay1 idiv cx ; ax = dx * 2 * deltay1 / deltay and ax,ax ; test if negative js int_neg inc ax shr ax,1 load_fill_int: add ax, [si] ; add in x1 mov [di],ax inc di inc di inc fill_int ; increment fill count and buffer pointer no_fill_int: inc si inc si inc si inc si ; increment ptsin ptr pop cx loop flit_lp jmps sort_fill_int ret fillit_zero: ; or 6[si], 8000h ; set the flag for done with edge jmps no_fill_int fillit_done: and ax, ax jns no_fill_int ; or 6[si], 8000h jmps no_fill_int int_neg: neg ax inc ax shr ax,1 neg ax jmps load_fill_int sort_fill_int: mov cx, fill_int cmp cx, 2 jz fast_fill_int ; if 2 then simple sort and draw jl fill_no_int ; if less than 2 then do nothing dec cx ; make it 0 based jmp full_fill_sort fill_no_int: ret fast_fill_int: mov ax, INTIN ; get the first x mov bx, INTIN+2 cmp ax, bx jle fast_fill_int_1 xchg ax, bx ; if x1 > x2 exchange them fast_fill_int_1: mov X1, ax mov X2, bx call HLINE_CLIP ret full_fill_sort: mov dx, cx mov di, offset INTIN full_fill_sort_outlp: push cx ; save the full count mov si, di mov ax, word ptr 0[si] ; get the initial lower word full_fill_sort_inlp: mov bx, word ptr 2[si] cmp ax, bx ; is ax <= bx jle full_fill_sort_inlp_1 mov word ptr 0[si], bx ; if ax > bx then exchange mov word ptr 2[si], ax mov bx, ax ; set up for next word full_fill_sort_inlp_1: mov ax, bx ; already have lower word inc si inc si ; point upwards loop full_fill_sort_inlp pop cx dec dx jnz full_fill_sort_outlp mov cx, fill_int shr cx, 1 ; make count of word pairs full_fill_drawlp: mov ax, [di] mov bx, 2[di] mov X1, ax mov X2, bx push di push cx call HLINE_CLIP pop cx pop di add di,4 ; point to the next pair loop full_fill_drawlp ret HLINE_CLIP: mov ax, CLIP ; is clipping on? and ax, ax jnz hline_clip_1 jmp HABLINE ; goto horizontal line draw routine hline_clip_1: mov ax, XMN_CLIP mov bx, X1 mov cx, X2 cmp bx, ax ; is x1 < xmn_clip jnl hline_clip_3 cmp cx, ax ; is x2 >= xmn_clip jl hline_clip_2 mov X1, ax hline_clip_3: mov ax, XMX_CLIP cmp cx, ax ; is x2 > xmx_clip jle hline_clip_4 cmp bx, ax ; is x1 <= xmx_clip jg hline_clip_2 mov X2, ax hline_clip_4: jmp HABLINE hline_clip_2: ret ; if x2 not > xmn_clip exit eject if wy700 dest_add: push ax ;save registers push dx mov al,cs:current_port ;get current control port value mov dx,3dfh ;point to control port xor al,3 ;switch banks out dx,al mov cs:current_port,al ;save new value test al,2 jnz wy700_end1 add di,next_line ;add offset wy700_end1: pop dx ;restore registers pop ax ret endif