Files
Doom2DosOriginal/PLANAR.ASM
T

1 line
13 KiB
NASM

.386
.MODEL small
INCLUDE defs.inc
;============================================================================
;
; R_DrawColumn
;
;============================================================================
.data
loopcount dd 0
pixelcount dd 0
EXTRN _centery:DWORD
EXTRN _destview:DWORD
.code
ALIGN 16
PROC R_DrawColumnLow_
PUBLIC R_DrawColumnLow_
pushr
mov ebp,[_dc_yl]
cmp ebp,[_dc_yh]
jg done
lea edi,[ebp*8+ebp]
add edi,ebp
shl edi,3
mov ebx,[_dc_x]
mov ecx,ebx
shr ebx,1
add edi,ebx
add edi,[_destview] ; edi = destscreen + y*80 + x/2
and ecx,1
shl ecx,1
mov eax,3
shl eax,cl
mov edx,SC_INDEX+1
out dx,al ; set mapmask register
jmp lowentry
ENDP
ALIGN 16
PROC R_DrawColumn_
PUBLIC R_DrawColumn_
pushr
mov ebp,[_dc_yl]
cmp ebp,[_dc_yh]
jg done
lea edi,[ebp*8+ebp]
add edi,ebp
shl edi,3
mov ebx,[_dc_x]
mov ecx,ebx
shr ebx,2
add edi,ebx
add edi,[_destview] ; edi = destscreen + y*80 + x/4
and ecx,3
mov eax,1
shl eax,cl
mov edx,SC_INDEX+1
out dx,al ; set mapmask register
lowentry:
mov eax,[_dc_yh]
inc eax
sub eax,ebp ; pixel count
mov [pixelcount],eax ; save for final pixel
js done
; nothing to scale
shr eax,1 ; double pixel count
mov [loopcount],eax
mov ecx,[_dc_iscale]
mov eax,[_centery]
sub eax,ebp
imul ecx
mov ebp,[_dc_texturemid]
sub ebp,eax
shl ebp,9 ; 7 significant bits, 25 frac
mov esi,[_dc_source]
mov ebx,[_dc_iscale]
shl ebx,9
mov eax,OFFSET patch1+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET patch2+2 ; convice tasm to modify code...
mov [eax],ebx
; eax aligned colormap
; ebx aligned colormap
; ecx,edx scratch
; esi virtual source
; edi moving destination pointer
; ebp frac
mov ecx,ebp ; begin calculating first pixel
add ebp,ebx ; advance frac pointer
shr ecx,25 ; finish calculation for first pixel
mov edx,ebp ; begin calculating second pixel
add ebp,ebx ; advance frac pointer
shr edx,25 ; finish calculation for second pixel
mov eax,[_dc_colormap]
mov ebx,eax
mov al,[esi+ecx] ; get first pixel
mov bl,[esi+edx] ; get second pixel
mov al,[eax] ; color translate first pixel
mov bl,[ebx] ; color translate second pixel
test [pixelcount],0fffffffeh
jnz doubleloop ; at least two pixels to map
jmp checklast
ALIGN 16
doubleloop:
mov ecx,ebp ; begin calculating third pixel
patch1:
add ebp,12345678h ; advance frac pointer
mov [edi],al ; write first pixel
shr ecx,25 ; finish calculation for third pixel
mov edx,ebp ; begin calculating fourth pixel
patch2:
add ebp,12345678h ; advance frac pointer
mov [edi+PLANEWIDTH],bl ; write second pixel
shr edx,25 ; finish calculation for fourth pixel
mov al,[esi+ecx] ; get third pixel
add edi,PLANEWIDTH*2 ; advance to third pixel destination
mov bl,[esi+edx] ; get fourth pixel
dec [loopcount] ; done with loop?
mov al,[eax] ; color translate third pixel
mov bl,[ebx] ; color translate fourth pixel
jnz doubleloop
; check for final pixel
checklast:
test [pixelcount],1
jz done
mov [edi],al ; write final pixel
done:
popr
ret
ENDP
;============================================================================
;
; R_DrawSpan
;
; Horizontal texture mapping
;
;============================================================================
.data
startdest dd 0
startplane dd 0
plane dd 0
startfrac dd 0
fracstep dd 0
qfracstep dd 0
firstx dd 0
firstbyte dd 0
lastbyte dd 0
.code
ALIGN 16
PROC R_DrawSpan_
PUBLIC R_DrawSpan_
PUSHR
;
; calculate screen dest and plane position
;
mov eax,[_ds_x1]
mov [firstx],eax
mov ebx,eax
and ebx,3
mov [startplane],ebx
mov [plane],ebx
shr eax,2
mov ebp,[_ds_y]
lea edi,[ebp*8+ebp]
add edi,ebp
shl edi,3
add edi,eax
add edi,[_destview] ; edi = destscreen + y*80 + x/4
mov [startdest],edi
;
; build composite position
;
mov ebx,[_ds_xfrac]
shl ebx,10
and ebx,0ffff0000h
mov eax,[_ds_yfrac]
shr eax,6
and eax,0ffffh
or ebx,eax
mov [startfrac],ebx
;
; build composite step
;
mov ebx,[_ds_xstep]
shl ebx,10
and ebx,0ffff0000h
mov eax,[_ds_ystep]
shr eax,6
and eax,0ffffh
or ebx,eax
mov [fracstep],ebx
;
; patch composite step * 4 into the immediate fields
;
shl ebx,2
mov [qfracstep],ebx
mov eax,OFFSET hpatch1+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET hpatch2+2 ; convice tasm to modify code...
mov [eax],ebx
;
; draw a plane
;
mov ecx,[plane]
planeloop:
mov eax,1
shl eax,cl
mov edx,SC_INDEX+1
out dx,al
;
; find loop count
;
mov eax,[_ds_x2]
cmp eax,[firstx]
jb alldone
sub eax,[plane] ; - plane
js hdone
shr eax,2 ; last planar byte to write
mov [lastbyte],eax
dec eax
js singlepixel
shr eax,1 ; last full word to write on line
mov ebx,[firstx]
shr ebx,2 ; first plane byte to write
cmp ebx,[lastbyte]
je singlepixel
mov [firstbyte],ebx
inc ebx
shr ebx,1 ; first full word to write on line
inc eax
sub eax,ebx
js hdone
mov [loopcount],eax
; eax aligned colormap
; ebx aligned colormap
; ecx,edx scratch
; esi virtual source
; edi moving destination pointer
; ebp frac
mov eax,[_ds_colormap]
mov ebx,eax
mov esi,[_ds_source]
mov edi,[startdest]
mov ebp,[startfrac]
test [firstbyte],1
jz evenstart
;
; map one extra pixel at start
;
shld ecx,ebp,22 ; begin calculating first pixel (y units)
shld ecx,ebp,6 ; begin calculating first pixel (x units)
add ebp,[qfracstep] ; advance frac pointer
and ecx,4095 ; finish calculation for first pixel
mov al,[esi+ecx] ; get first pixel
mov dl,[eax] ; color translate first pixel
mov [edi],dl
inc edi
jz hdone
evenstart:
;
; set up for word mapping
;
shld ecx,ebp,22 ; begin calculating first pixel (y units)
shld ecx,ebp,6 ; begin calculating first pixel (x units)
add ebp,[qfracstep] ; advance frac pointer
and ecx,4095 ; finish calculation for first pixel
shld edx,ebp,22 ; begin calculating second pixel (y units)
shld edx,ebp,6 ; begin calculating second pixel (x units)
add ebp,[qfracstep] ; advance frac pointer
and edx,4095 ; finish calculation for second pixel
mov al,[esi+ecx] ; get first pixel
mov bl,[esi+edx] ; get second pixel
mov dl,[eax] ; color translate first pixel
test [loopcount],0ffffffffh
jnz hdoubleloop ; at least one pixels to map
jmp hchecklast
singlepixel:
mov eax,[_ds_colormap]
mov esi,[_ds_source]
mov edi,[startdest]
mov ebp,[startfrac]
shld ecx,ebp,22 ; begin calculating first pixel (y units)
shld ecx,ebp,6 ; begin calculating first pixel (x units)
and ecx,4095 ; finish calculation for first pixel
mov al,[esi+ecx] ; get first pixel
mov dl,[eax] ; color translate first pixel
mov [edi],dl
jmp hdone
ALIGN 16
hdoubleloop:
shld ecx,ebp,22 ; begin calculating third pixel (y units)
mov dh,[ebx] ; color translate second pixel
shld ecx,ebp,6 ; begin calculating third pixel (x units)
hpatch1:
add ebp,12345678h ; advance frac pointer
and ecx,4095 ; finish calculation for third pixel
mov [edi],dx ; write two pixels
shld edx,ebp,22 ; begin calculating fourth pixel (y units)
add edi,2 ; advance to third pixel destination
shld edx,ebp,6 ; begin calculating fourth pixel (x units)
hpatch2:
add ebp,12345678h ; advance frac pointer
and edx,4095 ; finish calculation for fourth pixel
mov al,[esi+ecx] ; get third pixel
mov bl,[esi+edx] ; get fourth pixel
dec [loopcount] ; done with loop?
mov dl,[eax] ; color translate third pixel
jnz hdoubleloop
;
; check for final pixel at end
;
hchecklast:
test [lastbyte],1
jnz hdone
mov [edi],dl ; write final pixel
hdone:
mov ecx,[plane]
inc ecx
and ecx,3
jnz noinc
inc [startdest] ; over to next byte
noinc:
cmp ecx,[startplane]
je alldone
mov [plane],ecx
mov ebx,[startfrac]
add ebx,[fracstep]
mov [startfrac],ebx ; advance frac to next pixel
inc [firstx]
jmp planeloop
alldone:
popr
ret
ENDP
;============================================================================
;
; R_DrawSpanLow
;
; Horizontal texture mapping
;
;============================================================================
ALIGN 16
PROC R_DrawSpanLow_
PUBLIC R_DrawSpanLow_
PUSHR
;
; calculate screen dest and plane position
;
mov eax,[_ds_x1]
mov [firstx],eax
mov ebx,eax
and ebx,1
mov [startplane],ebx
mov [plane],ebx
shr eax,1
mov ebp,[_ds_y]
lea edi,[ebp*8+ebp]
add edi,ebp
shl edi,3
add edi,eax
add edi,[_destview] ; edi = destscreen + y*80 + x/2
mov [startdest],edi
;
; build composite position
;
mov ebx,[_ds_xfrac]
shl ebx,10
and ebx,0ffff0000h
mov eax,[_ds_yfrac]
shr eax,6
and eax,0ffffh
or ebx,eax
mov [startfrac],ebx
;
; build composite step
;
mov ebx,[_ds_xstep]
shl ebx,10
and ebx,0ffff0000h
mov eax,[_ds_ystep]
shr eax,6
and eax,0ffffh
or ebx,eax
mov [fracstep],ebx
;
; patch composite step * 4 into the immediate fields
;
shl ebx,1
mov [qfracstep],ebx
mov eax,OFFSET hlpatch1+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET hlpatch2+2 ; convice tasm to modify code...
mov [eax],ebx
;
; draw a plane
;
mov ecx,[plane]
lplaneloop:
mov eax,3
shl eax,cl
shl eax,cl
mov edx,SC_INDEX+1
out dx,al
;
; find loop count
;
mov eax,[_ds_x2]
cmp eax,[firstx]
jb lalldone
sub eax,[plane] ; - plane
js hldone
shr eax,1 ; last planar byte to write
mov [lastbyte],eax
dec eax
js lsinglepixel
shr eax,1 ; last full word to write on line
mov ebx,[firstx]
shr ebx,1 ; first plane byte to write
cmp ebx,[lastbyte]
je lsinglepixel
mov [firstbyte],ebx
inc ebx
shr ebx,1 ; first full word to write on line
inc eax
sub eax,ebx
js hldone
mov [loopcount],eax
; eax aligned colormap
; ebx aligned colormap
; ecx,edx scratch
; esi virtual source
; edi moving destination pointer
; ebp frac
mov eax,[_ds_colormap]
mov ebx,eax
mov esi,[_ds_source]
mov edi,[startdest]
mov ebp,[startfrac]
test [firstbyte],1
jz levenstart
;
; map one extra pixel at start
;
shld ecx,ebp,22 ; begin calculating first pixel (y units)
shld ecx,ebp,6 ; begin calculating first pixel (x units)
add ebp,[qfracstep] ; advance frac pointer
and ecx,4095 ; finish calculation for first pixel
mov al,[esi+ecx] ; get first pixel
mov dl,[eax] ; color translate first pixel
mov [edi],dl
inc edi
jz hldone
levenstart:
;
; set up for word mapping
;
shld ecx,ebp,22 ; begin calculating first pixel (y units)
shld ecx,ebp,6 ; begin calculating first pixel (x units)
add ebp,[qfracstep] ; advance frac pointer
and ecx,4095 ; finish calculation for first pixel
shld edx,ebp,22 ; begin calculating second pixel (y units)
shld edx,ebp,6 ; begin calculating second pixel (x units)
add ebp,[qfracstep] ; advance frac pointer
and edx,4095 ; finish calculation for second pixel
mov al,[esi+ecx] ; get first pixel
mov bl,[esi+edx] ; get second pixel
mov dl,[eax] ; color translate first pixel
test [loopcount],0ffffffffh
jnz hldoubleloop ; at least one pixels to map
jmp hlchecklast
lsinglepixel:
mov eax,[_ds_colormap]
mov esi,[_ds_source]
mov edi,[startdest]
mov ebp,[startfrac]
shld ecx,ebp,22 ; begin calculating first pixel (y units)
shld ecx,ebp,6 ; begin calculating first pixel (x units)
and ecx,4095 ; finish calculation for first pixel
mov al,[esi+ecx] ; get first pixel
mov dl,[eax] ; color translate first pixel
mov [edi],dl
jmp hldone
ALIGN 16
hldoubleloop:
shld ecx,ebp,22 ; begin calculating third pixel (y units)
mov dh,[ebx] ; color translate second pixel
shld ecx,ebp,6 ; begin calculating third pixel (x units)
hlpatch1:
add ebp,12345678h ; advance frac pointer
and ecx,4095 ; finish calculation for third pixel
mov [edi],dx ; write two pixels
shld edx,ebp,22 ; begin calculating fourth pixel (y units)
add edi,2 ; advance to third pixel destination
shld edx,ebp,6 ; begin calculating fourth pixel (x units)
hlpatch2:
add ebp,12345678h ; advance frac pointer
and edx,4095 ; finish calculation for fourth pixel
mov al,[esi+ecx] ; get third pixel
mov bl,[esi+edx] ; get fourth pixel
dec [loopcount] ; done with loop?
mov dl,[eax] ; color translate third pixel
jnz hldoubleloop
;
; check for final pixel at end
;
hlchecklast:
test [lastbyte],1
jnz hldone
mov [edi],dl ; write final pixel
hldone:
mov ecx,[plane]
inc ecx
and ecx,1
jnz lnoinc
inc [startdest] ; over to next byte
lnoinc:
cmp ecx,[startplane]
je lalldone
mov [plane],ecx
mov ebx,[startfrac]
add ebx,[fracstep]
mov [startfrac],ebx ; advance frac to next pixel
inc [firstx]
jmp lplaneloop
lalldone:
popr
ret
ENDP
END