]> 4ch.mooo.com Git - 16.git/blobdiff - 16/sod8086/wl_dr_a.asm
got 8086 port of wolf3d to work and sod to work
[16.git] / 16 / sod8086 / wl_dr_a.asm
diff --git a/16/sod8086/wl_dr_a.asm b/16/sod8086/wl_dr_a.asm
new file mode 100755 (executable)
index 0000000..aec139a
--- /dev/null
@@ -0,0 +1,795 @@
+       IDEAL\r
+       MODEL   MEDIUM,C\r
+       P286\r
+\r
+SCREENSEG      =       0a000h\r
+\r
+FINEANGLES     =       3600\r
+DEG90          =       900\r
+DEG180         =       1800\r
+DEG270         =       2700\r
+DEG360         =       3600\r
+\r
+OP_JLE         =       07eh\r
+OP_JGE         =       07dh\r
+\r
+EXTRN  finetangent:DWORD       ; far array, starts at offset 0\r
+\r
+EXTRN  HitHorizWall:FAR\r
+EXTRN  HitVertWall:FAR\r
+EXTRN  HitHorizDoor:FAR\r
+EXTRN  HitVertDoor:FAR\r
+EXTRN  HitHorizPWall:FAR\r
+EXTRN  HitVertPWall:FAR\r
+\r
+\r
+DATASEG\r
+\r
+EXTRN  viewwidth:WORD\r
+\r
+EXTRN  tilemap:BYTE\r
+EXTRN  spotvis:BYTE\r
+EXTRN  pixelangle:WORD\r
+\r
+\r
+EXTRN  midangle:WORD\r
+EXTRN  angle:WORD\r
+\r
+EXTRN  focaltx:WORD\r
+EXTRN  focalty:WORD\r
+EXTRN  viewtx:WORD\r
+EXTRN  viewty:WORD\r
+EXTRN  viewx:DWORD\r
+EXTRN  viewy:DWORD\r
+\r
+EXTRN  xpartialup:WORD\r
+EXTRN  ypartialup:WORD\r
+EXTRN  xpartialdown:WORD\r
+EXTRN  ypartialdown:WORD\r
+\r
+EXTRN  tilehit:WORD\r
+EXTRN  pixx:WORD\r
+EXTRN  wallheight:WORD                 ; array of VIEWWIDTH entries\r
+\r
+EXTRN  xtile:WORD\r
+EXTRN  ytile:WORD\r
+EXTRN  xtilestep:WORD\r
+EXTRN  ytilestep:WORD\r
+EXTRN  xintercept:DWORD\r
+EXTRN  yintercept:DWORD\r
+EXTRN  xstep:DWORD\r
+EXTRN  ystep:DWORD\r
+\r
+EXTRN  doorposition:WORD               ; table of door position values\r
+\r
+\r
+EXTRN  pwallpos:WORD                   ; amound a pushable wall has been moved\r
+\r
+CODESEG\r
+\r
+;-------------------\r
+;\r
+; xpartialbyystep\r
+;\r
+; multiplies long [ystep] (possibly negative), by word [xpartial] (in BX)\r
+;\r
+; returns dx:ax\r
+; trashes bx,cx,di\r
+;\r
+;-------------------\r
+\r
+PROC xpartialbyystep NEAR\r
+;\r
+; setup\r
+;\r
+       mov     ax,[WORD ystep]\r
+       mov     cx,[WORD ystep+2]\r
+       or      cx,cx               ; is ystep negatice?\r
+       jns     @@multpos\r
+;\r
+; multiply negative cx:ax by bx\r
+;\r
+       neg     cx\r
+       neg     ax\r
+       sbb     cx,0\r
+\r
+       mul     bx                                      ; fraction*fraction\r
+       mov     di,dx                           ; di is low word of result\r
+       mov     ax,cx                           ;\r
+       mul     bx                                      ; units*fraction\r
+       add     ax,di\r
+       adc     dx,0\r
+\r
+       neg     dx\r
+       neg     ax\r
+       sbb     dx,0\r
+       ret\r
+;\r
+; multiply positive cx:ax by bx\r
+;\r
+EVEN\r
+@@multpos:\r
+       mul     bx                                      ; fraction*fraction\r
+       mov     di,dx                           ; di is low word of result\r
+       mov     ax,cx                           ;\r
+       mul     bx                                      ; units*fraction\r
+       add     ax,di\r
+       adc     dx,0\r
+\r
+       ret\r
+\r
+ENDP\r
+\r
+\r
+\r
+;-------------------\r
+;\r
+; ypartialbyxstep\r
+;\r
+; multiplies long [xstep] (possibly negative), by word [ypartial] (in BP)\r
+;\r
+; returns dx:ax\r
+; trashes cx,di,bp\r
+;\r
+;-------------------\r
+\r
+PROC ypartialbyxstep NEAR\r
+;\r
+; setup\r
+;\r
+       mov     ax,[WORD xstep]\r
+       mov     cx,[WORD xstep+2]\r
+       or      cx,cx               ; is ystep negatice?\r
+       jns     @@multpos\r
+;\r
+; multiply negative cx:ax by bx\r
+;\r
+       neg     cx\r
+       neg     ax\r
+       sbb     cx,0\r
+\r
+       mul     bp                                      ; fraction*fraction\r
+       mov     di,dx                           ; di is low word of result\r
+       mov     ax,cx                           ;\r
+       mul     bp                                      ; units*fraction\r
+       add     ax,di\r
+       adc     dx,0\r
+\r
+       neg     dx\r
+       neg     ax\r
+       sbb     dx,0\r
+       ret\r
+;\r
+; multiply positive cx:ax by bx\r
+;\r
+EVEN\r
+@@multpos:\r
+       mul     bp                                      ; fraction*fraction\r
+       mov     di,dx                           ; di is low word of result\r
+       mov     ax,cx                           ;\r
+       mul     bp                                      ; units*fraction\r
+       add     ax,di\r
+       adc     dx,0\r
+       ret\r
+\r
+ENDP\r
+\r
+\r
+;============================\r
+;\r
+; AsmRefresh\r
+;\r
+;\r
+;============================\r
+\r
+PROC   AsmRefresh\r
+PUBLIC AsmRefresh\r
+\r
+       push    si\r
+       push    di\r
+       push    bp\r
+\r
+       mov     [pixx],0\r
+;---------------------------------------------------------------------------\r
+;\r
+; Setup to trace a ray through pixx view pixel\r
+;\r
+; CX : angle of the ray through pixx\r
+; ES : points to segment of finetangent array for this block of code\r
+;\r
+; Upon entrance to initialize block\r
+;\r
+; BX : xpartial\r
+; BP : ypartial\r
+;\r
+;---------------------------------------------------------------------------\r
+       EVEN\r
+pixxloop:\r
+       mov     ax,SEG finetangent\r
+       mov     es,ax\r
+       mov     cx,[midangle]                   ; center of view area\r
+       mov     bx,[pixx]\r
+       shl     bx,1\r
+       add     cx,[pixelangle+bx]              ; delta for this pixel\r
+       cmp     cx,0\r
+       jge     not0\r
+;----------\r
+;\r
+; -90 - -1 degree arc\r
+;\r
+;----------\r
+       add     cx,FINEANGLES                   ; -90 is the same as 270\r
+       jmp     entry360\r
+\r
+not0:\r
+       cmp     cx,DEG90\r
+       jge     not90\r
+;----------\r
+;\r
+; 0-89 degree arc\r
+;\r
+;----------\r
+entry90:\r
+       mov     [xtilestep],1                   ; xtilestep = 1\r
+       mov     [ytilestep],-1                  ; ytilestep = -1\r
+       mov     [BYTE cs:horizop],OP_JGE        ; patch a jge in\r
+       mov     [BYTE cs:vertop],OP_JLE         ; patch a jle in\r
+       mov     bx,DEG90-1\r
+       sub     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx]\r
+       mov     dx,[es:bx+2]\r
+       mov     [WORD xstep],ax\r
+       mov     [WORD xstep+2],dx               ; xstep = finetangent[DEG90-1-angle]\r
+       mov     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx]\r
+       mov     dx,[es:bx+2]\r
+       neg     dx\r
+       neg     ax\r
+       sbb     dx,0\r
+       mov     [WORD ystep],ax\r
+       mov     [WORD ystep+2],dx               ; ystep = -finetangent[angle]\r
+\r
+       mov     bx,[xpartialup]                 ; xpartial = xpartialup\r
+       mov     bp,[ypartialdown]               ; ypartial = ypartialdown\r
+       jmp     initvars\r
+\r
+not90:\r
+       cmp     cx,DEG180\r
+       jge     not180\r
+;----------\r
+;\r
+; 90-179 degree arc\r
+;\r
+;----------\r
+       mov     ax,-1\r
+       mov     [xtilestep],ax                  ; xtilestep = -1\r
+       mov     [ytilestep],ax                  ; ytilestep = -1\r
+       mov     [BYTE cs:horizop],OP_JLE        ; patch a jle in\r
+       mov     [BYTE cs:vertop],OP_JLE         ; patch a jle in\r
+\r
+       mov     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx-DEG90*4]\r
+       mov     dx,[es:bx+2-DEG90*4]\r
+       neg     dx\r
+       neg     ax\r
+       sbb     dx,0\r
+       mov     [WORD xstep],ax\r
+       mov     [WORD xstep+2],dx               ; xstep = -finetangent[angle-DEG90]\r
+       mov     bx,DEG180-1\r
+       sub     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx]\r
+       mov     dx,[es:bx+2]\r
+       neg     dx\r
+       neg     ax\r
+       sbb     dx,0\r
+       mov     [WORD ystep],ax\r
+       mov     [WORD ystep+2],dx               ; ystep = -finetangent[DEG180-1-angle]\r
+\r
+       mov     bx,[xpartialdown]               ; xpartial = xpartialdown\r
+       mov     bp,[ypartialdown]               ; ypartial = ypartialdown\r
+       jmp     initvars\r
+\r
+not180:\r
+       cmp     cx,DEG270\r
+       jge     not270\r
+;----------\r
+;\r
+; 180-269 degree arc\r
+;\r
+;----------\r
+       mov     [xtilestep],-1                  ; xtilestep = -1\r
+       mov     [ytilestep],1                   ; ytilestep = 1\r
+       mov     [BYTE cs:horizop],OP_JLE        ; patch a jle in\r
+       mov     [BYTE cs:vertop],OP_JGE         ; patch a jge in\r
+\r
+       mov     bx,DEG270-1\r
+       sub     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx]\r
+       mov     dx,[es:bx+2]\r
+       neg     dx\r
+       neg     ax\r
+       sbb     dx,0\r
+       mov     [WORD xstep],ax\r
+       mov     [WORD xstep+2],dx               ; xstep = -finetangent[DEG270-1-angle]\r
+       mov     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx-DEG180*4]\r
+       mov     dx,[es:bx+2-DEG180*4]\r
+       mov     [WORD ystep],ax\r
+       mov     [WORD ystep+2],dx               ; ystep = finetangent[angle-DEG180]\r
+\r
+       mov     bx,[xpartialdown]               ; xpartial = xpartialdown\r
+       mov     bp,[ypartialup]                 ; ypartial = ypartialup\r
+       jmp     initvars\r
+\r
+\r
+not270:\r
+       cmp     cx,DEG360\r
+       jge     not360\r
+;----------\r
+;\r
+; 270-359 degree arc\r
+;\r
+;----------\r
+entry360:\r
+       mov     ax,1\r
+       mov     [xtilestep],ax                  ; xtilestep = 1\r
+       mov     [ytilestep],ax                  ; ytilestep = 1\r
+       mov     [BYTE cs:horizop],OP_JGE        ; patch a jge in\r
+       mov     [BYTE cs:vertop],OP_JGE         ; patch a jge in\r
+\r
+       mov     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx-DEG270*4]\r
+       mov     dx,[es:bx+2-DEG270*4]\r
+       mov     [WORD xstep],ax\r
+       mov     [WORD xstep+2],dx               ; xstep = finetangent[angle-DEG270]\r
+       mov     bx,DEG360-1\r
+       sub     bx,cx\r
+       ;begin 8086 hack\r
+       ;shl    bx,2\r
+       shl bx,1\r
+       shl bx,1\r
+       ;end 8086 hack\r
+       mov     ax,[es:bx]\r
+       mov     dx,[es:bx+2]\r
+       mov     [WORD ystep],ax\r
+       mov     [WORD ystep+2],dx               ; ystep = finetangent[DEG360-1-angle]\r
+\r
+       mov     bx,[xpartialup]                 ; xpartial = xpartialup\r
+       mov     bp,[ypartialup]                 ; ypartial = ypartialup\r
+       jmp     initvars\r
+\r
+\r
+not360:\r
+;----------\r
+;\r
+; 360-449 degree arc\r
+;\r
+;----------\r
+       sub     cx,FINEANGLES                   ; -449 is the same as 89\r
+       jmp     entry90\r
+\r
+;---------------------------------------------------------------------------\r
+;\r
+; initialise variables for intersection testing\r
+;\r
+;---------------------------------------------------------------------------\r
+initvars:\r
+       call    NEAR xpartialbyystep    ; xpartial is in BX\r
+       add     ax,[WORD viewy]\r
+       adc     dx,[WORD viewy+2]\r
+       mov     [WORD yintercept],ax\r
+       mov     [WORD yintercept+2],dx\r
+\r
+       mov     si,[focaltx]\r
+       add     si,[xtilestep]\r
+       mov     [xtile],si                                      ; xtile = focaltx+xtilestep\r
+       ;begin 8086 hack\r
+       ;shl    si,6\r
+       push cx\r
+       mov cl,6\r
+       shl si,cl\r
+       pop cx\r
+       ;end 8086 hack\r
+       add     si,dx                                           ; xspot = (xtile<<6) + yinttile\r
+\r
+\r
+       call    NEAR ypartialbyxstep    ; ypartial is in BP\r
+       add     ax,[WORD viewx]\r
+       adc     dx,[WORD viewx+2]\r
+       mov     [WORD xintercept],ax\r
+       mov     cx,dx\r
+\r
+       mov     bx,[focalty]\r
+       add     bx,[ytilestep]\r
+       mov     bp,bx                                           ; ytile = focalty+ytilestep\r
+       mov     di,dx\r
+       ;begin 8086 hack\r
+       ;shl    di,6\r
+       push cx\r
+       mov cl,6\r
+       shl di,cl\r
+       pop cx\r
+       ;end 8086 hack\r
+       add     di,bx                                           ; yspot = (xinttile<<6) + ytile\r
+\r
+       mov     bx,[xtile]\r
+       mov     dx,[WORD yintercept+2]\r
+       mov     ax,SCREENSEG\r
+       mov     es,ax                                           ; faster than mov es,[screenseg]\r
+\r
+\r
+;---------------------------------------------------------------------------\r
+;\r
+; trace along this angle until we hit a wall\r
+;\r
+; CORE LOOP!\r
+;\r
+; All variables are killed when a wall is hit\r
+;\r
+; AX : scratch\r
+; BX : xtile\r
+; CX : high word of xintercept\r
+; DX : high word of yintercept\r
+; SI : xspot (yinttile<<6)+xtile (index into tilemap and spotvis)\r
+; DI : yspot (xinttile<<6)+ytile (index into tilemap and spotvis)\r
+; BP : ytile\r
+; ES : screenseg\r
+;\r
+;---------------------------------------------------------------------------\r
+\r
+;-----------\r
+;\r
+; check intersections with vertical walls\r
+;\r
+;-----------\r
+\r
+       EVEN\r
+vertcheck:\r
+       cmp     dx,bp\r
+vertop:                                                                ; 0x7e = jle (ytilestep==-1)\r
+       jle     horizentry                                      ; 0x7d = jge (ytilestep==1)\r
+vertentry:\r
+       test [BYTE tilemap+si],0ffh             ; tilehit = *((byte *)tilemap+xspot);\r
+       jnz     hitvert\r
+passvert:\r
+       mov     [BYTE spotvis+si],1                     ; *((byte *)spotvis+xspot) = true;\r
+       add     bx,[xtilestep]                          ; xtile+=xtilestep\r
+       mov     ax,[WORD ystep]\r
+       add     [WORD yintercept],ax            ; yintercept += ystep\r
+       adc     dx,[WORD ystep+2]\r
+       mov     si,bx\r
+       ;begin 8086 hack\r
+       ;shl    si,6\r
+       push cx\r
+       mov cl,6\r
+       shl si,cl\r
+       pop cx\r
+       ;end 8086 hack\r
+       add     si,dx                                           ; xspot = (xtile<<6)+yinttile\r
+       jmp     vertcheck\r
+\r
+       EVEN\r
+hitvert:\r
+       mov     al,[BYTE tilemap+si]            ; tilehit = *((byte *)tilemap+xspot);\r
+       mov     [BYTE tilehit],al\r
+       or      al,al                                           ; set flags\r
+       jns     notvertdoor\r
+       jmp     vertdoor\r
+notvertdoor:\r
+       mov     [WORD xintercept],0\r
+       mov     [WORD xintercept+2],bx\r
+       mov     [xtile],bx\r
+       mov     [WORD yintercept+2],dx\r
+       mov     [ytile],dx\r
+       call FAR HitVertWall\r
+       jmp nextpix\r
+\r
+\r
+;-----------\r
+;\r
+; check intersections with horizontal walls\r
+;\r
+;-----------\r
+       EVEN\r
+horizcheck:\r
+       cmp     cx,bx\r
+horizop:                                                       ; 0x7e = jle (xtilestep==-1)\r
+       jle     vertentry                                       ; 0x7d = jge (xtilestep==1)\r
+horizentry:\r
+       test [BYTE tilemap+di],0ffh             ; tilehit = *((byte *)tilemap+yspot);\r
+       jnz     hithoriz\r
+passhoriz:\r
+       mov     [BYTE spotvis+di],1                     ; *((byte *)spotvis+yspot) = true;\r
+       add     bp,[ytilestep]                          ; ytile+=ytilestep\r
+       mov     ax,[WORD xstep]\r
+       add     [WORD xintercept],ax            ; xintercept += xstep\r
+       adc     cx,[WORD xstep+2]\r
+       mov     di,cx\r
+       ;begin 8086 hack\r
+       ;shl    di,6\r
+       push cx\r
+       mov cl,6\r
+       shl di,cl\r
+       pop cx\r
+       ;end 8086 hack\r
+       add     di,bp                                           ; yspot = (xinttile<<6)+ytile\r
+       jmp     horizcheck\r
+\r
+       EVEN\r
+hithoriz:\r
+       mov     al,[BYTE tilemap+di]            ; tilehit = *((byte *)tilemap+yspot);\r
+       mov     [BYTE tilehit],al\r
+       or      al,al                                           ; set flags\r
+       js      horizdoor\r
+       mov     [WORD xintercept+2],cx\r
+       mov     [xtile],cx\r
+       mov     [WORD yintercept],0\r
+       mov     [WORD yintercept+2],bp\r
+       mov     [ytile],bp\r
+       call FAR HitHorizWall\r
+       jmp nextpix\r
+\r
+;---------------------------------------------------------------------------\r
+;\r
+; next pixel over\r
+;\r
+;---------------------------------------------------------------------------\r
+\r
+nextpix:\r
+       mov     ax,[pixx]\r
+       inc     ax\r
+       mov     [pixx],ax\r
+       cmp     ax,[viewwidth]\r
+       jge     done\r
+       jmp     pixxloop\r
+done:\r
+       pop     bp\r
+       pop     di\r
+       pop     si\r
+       retf\r
+\r
+;===========================================================================\r
+\r
+;=============\r
+;\r
+; hit a special horizontal wall, so find which coordinate a door would be\r
+; intersected at, and check to see if the door is open past that point\r
+;\r
+;=============\r
+horizdoor:\r
+       mov     [xtile],bx                                      ; save off live register variables\r
+       mov     [WORD yintercept+2],dx\r
+\r
+       test al,040h                                    ; both high bits set == pushable wall\r
+       jnz     horizpushwall\r
+\r
+       mov     bx,ax\r
+       and     bx,7fh                                          ; strip high bit\r
+       shl     bx,1                        ; index into word width door table\r
+\r
+       mov     ax,[WORD xstep]\r
+       mov     dx,[WORD xstep+2]\r
+       sar     dx,1\r
+       rcr ax,1                                                ; half a step gets to door position\r
+\r
+       add     ax,[WORD xintercept]            ; add half step to current intercept pos\r
+       adc     dx,cx                                           ; CX hold high word of xintercept\r
+\r
+       cmp     cx,dx                                           ; is it still in the same tile?\r
+       je      hithmid\r
+;\r
+; midpoint is outside tile, so it hit the side of the wall before a door\r
+;\r
+continuehoriz:\r
+       mov     bx,[xtile]                                      ; reload register variables\r
+       mov     dx,[WORD yintercept+2]\r
+       jmp     passhoriz                                       ; continue tracing\r
+;\r
+; the trace hit the door plane at pixel position AX, see if the door is\r
+; closed that much\r
+;\r
+hithmid:\r
+       cmp     ax,[doorposition+bx]            ; position of leading edge of door\r
+       jb      continuehoriz\r
+;\r
+; draw the door\r
+;\r
+       mov     [WORD xintercept],ax            ; save pixel intercept position\r
+       mov     [WORD xintercept+2],cx\r
+\r
+       mov     [WORD yintercept],8000h         ; intercept in middle of tile\r
+       mov     [WORD yintercept+2],bp\r
+\r
+       call    FAR HitHorizDoor\r
+       jmp     nextpix\r
+\r
+;============\r
+;\r
+; hit a sliding horizontal wall\r
+;\r
+;============\r
+\r
+horizpushwall:\r
+       mov     ax,[WORD xstep+2]                       ; multiply xstep by pwallmove (0-63)\r
+       mul     [pwallpos]\r
+       mov     bx,ax\r
+       mov     ax,[WORD xstep]\r
+       mul     [pwallpos]\r
+       add     dx,bx\r
+\r
+       sar     dx,1                                            ; then divide by 64 to accomplish a\r
+       rcr ax,1                                                ; fixed point multiplication\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+\r
+       add     ax,[WORD xintercept]            ; add partial step to current intercept\r
+       adc     dx,cx                                           ; CX hold high word of xintercept\r
+\r
+       cmp     cx,dx                                           ; is it still in the same tile?\r
+       jne     continuehoriz                           ; no, it hit the side\r
+\r
+;\r
+; draw the pushable wall at the new height\r
+;\r
+       mov     [WORD xintercept],ax            ; save pixel intercept position\r
+       mov     [WORD xintercept+2],dx\r
+\r
+       mov     [WORD yintercept+2],bp\r
+       mov     [WORD yintercept],0\r
+\r
+       call    FAR HitHorizPWall\r
+       jmp     nextpix\r
+\r
+\r
+\r
+;===========================================================================\r
+\r
+;=============\r
+;\r
+; hit a special vertical wall, so find which coordinate a door would be\r
+; intersected at, and check to see if the door is open past that point\r
+;\r
+;=============\r
+vertdoor:\r
+       mov     [xtile],bx                                      ; save off live register variables\r
+       mov     [WORD yintercept+2],dx\r
+\r
+       test al,040h                                    ; both high bits set == pushable wall\r
+       jnz     vertpushwall\r
+\r
+       mov     bx,ax\r
+       and     bx,7fh                                          ; strip high bit\r
+       shl     bx,1                        ; index into word width doorposition\r
+\r
+       mov     ax,[WORD ystep]\r
+       mov     dx,[WORD ystep+2]\r
+       sar     dx,1\r
+       rcr ax,1                                                ; half a step gets to door position\r
+\r
+       add     ax,[WORD yintercept]            ; add half step to current intercept pos\r
+       adc     dx,[WORD yintercept+2]\r
+\r
+       cmp     [WORD yintercept+2],dx          ; is it still in the same tile?\r
+       je      hitvmid\r
+;\r
+; midpoint is outside tile, so it hit the side of the wall before a door\r
+;\r
+continuevert:\r
+       mov     bx,[xtile]                                      ; reload register variables\r
+       mov     dx,[WORD yintercept+2]\r
+       jmp     passvert                                        ; continue tracing\r
+;\r
+; the trace hit the door plane at pixel position AX, see if the door is\r
+; closed that much\r
+;\r
+hitvmid:\r
+       cmp     ax,[doorposition+bx]            ; position of leading edge of door\r
+       jb      continuevert\r
+;\r
+; draw the door\r
+;\r
+       mov     [WORD yintercept],ax            ; save pixel intercept position\r
+       mov     [WORD xintercept],8000h         ; intercept in middle of tile\r
+       mov     ax,[xtile]\r
+       mov     [WORD xintercept+2],ax\r
+\r
+       call    FAR HitVertDoor\r
+       jmp     nextpix\r
+\r
+;============\r
+;\r
+; hit a sliding vertical wall\r
+;\r
+;============\r
+\r
+vertpushwall:\r
+       mov     ax,[WORD ystep+2]                       ; multiply ystep by pwallmove (0-63)\r
+       mul     [pwallpos]\r
+       mov     bx,ax\r
+       mov     ax,[WORD ystep]\r
+       mul     [pwallpos]\r
+       add     dx,bx\r
+\r
+       sar     dx,1                                            ; then divide by 64 to accomplish a\r
+       rcr ax,1                                                ; fixed point multiplication\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+       sar     dx,1\r
+       rcr ax,1\r
+\r
+       add     ax,[WORD yintercept]            ; add partial step to current intercept\r
+       adc     dx,[WORD yintercept+2]\r
+\r
+       cmp     [WORD yintercept+2],dx          ; is it still in the same tile?\r
+       jne     continuevert                            ; no, it hit the side\r
+\r
+;\r
+; draw the pushable wall at the new height\r
+;\r
+       mov     [WORD yintercept],ax            ; save pixel intercept position\r
+       mov     [WORD yintercept+2],dx\r
+\r
+       mov     bx,[xtile]\r
+       mov     [WORD xintercept+2],bx\r
+       mov     [WORD xintercept],0\r
+\r
+       call    FAR HitVertPWall\r
+       jmp     nextpix\r
+\r
+\r
+\r
+ENDP\r
+\r
+\r
+END\r
+\r
+\r