]> 4ch.mooo.com Git - 16.git/blobdiff - 16/keen456/KEEN4-6/ID_RF_A.ASM
extrcted keen code remake
[16.git] / 16 / keen456 / KEEN4-6 / ID_RF_A.ASM
diff --git a/16/keen456/KEEN4-6/ID_RF_A.ASM b/16/keen456/KEEN4-6/ID_RF_A.ASM
new file mode 100755 (executable)
index 0000000..56db0c7
--- /dev/null
@@ -0,0 +1,690 @@
+; Catacomb 3-D Source Code\r
+; Copyright (C) 1993-2014 Flat Rock Software\r
+;\r
+; This program is free software; you can redistribute it and/or modify\r
+; it under the terms of the GNU General Public License as published by\r
+; the Free Software Foundation; either version 2 of the License, or\r
+; (at your option) any later version.\r
+;\r
+; This program is distributed in the hope that it will be useful,\r
+; but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+; GNU General Public License for more details.\r
+;\r
+; You should have received a copy of the GNU General Public License along\r
+; with this program; if not, write to the Free Software Foundation, Inc.,\r
+; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+\r
+; ID_RF_A.ASM\r
+\r
+IDEAL\r
+MODEL  MEDIUM,C\r
+\r
+INCLUDE        "ID_ASM.EQU"\r
+\r
+;============================================================================\r
+\r
+TILESWIDE      =       21\r
+TILESHIGH      =       14\r
+\r
+UPDATESIZE     =       (TILESWIDE+1)*TILESHIGH+1\r
+\r
+DATASEG\r
+\r
+EXTRN  screenseg:WORD\r
+EXTRN  updateptr:WORD\r
+EXTRN  updatestart:WORD\r
+EXTRN  masterofs:WORD          ;start of master tile port\r
+EXTRN  bufferofs:WORD          ;start of current buffer port\r
+EXTRN  screenstart:WORD        ;starts of three screens (0/1/master) in EGA mem\r
+EXTRN  grsegs:WORD\r
+EXTRN  mapsegs:WORD\r
+EXTRN  originmap:WORD\r
+EXTRN  updatemapofs:WORD\r
+EXTRN  tinf:WORD                       ;seg pointer to map header and tile info\r
+EXTRN  blockstarts:WORD        ;offsets from bufferofs for each update block\r
+\r
+planemask      db      ?\r
+planenum       db      ?\r
+\r
+CODESEG\r
+\r
+screenstartcs  dw      ?               ;in code segment for accesability\r
+\r
+\r
+\r
+\r
+IFE GRMODE-CGAGR\r
+;============================================================================\r
+;\r
+; CGA refresh routines\r
+;\r
+;============================================================================\r
+\r
+TILEWIDTH      =       4\r
+\r
+;=================\r
+;\r
+; RFL_NewTile\r
+;\r
+; Draws a composit two plane tile to the master screen and sets the update\r
+; spot to 1 in both update pages, forcing the tile to be copied to the\r
+; view pages the next two refreshes\r
+;\r
+; Called to draw newlly scrolled on strips and animating tiles\r
+;\r
+;=================\r
+\r
+PROC   RFL_NewTile     updateoffset:WORD\r
+PUBLIC RFL_NewTile\r
+USES   SI,DI\r
+\r
+;\r
+; mark both update lists at this spot\r
+;\r
+       mov     di,[updateoffset]\r
+\r
+       mov     bx,[updateptr]                  ;start of update matrix\r
+       mov     [BYTE bx+di],1\r
+\r
+       mov     dx,SCREENWIDTH-TILEWIDTH                ;add to get to start of next line\r
+\r
+;\r
+; set di to the location in screenseg to draw the tile\r
+;\r
+       shl     di,1\r
+       mov     si,[updatemapofs+di]    ;offset in map from origin\r
+       add     si,[originmap]\r
+       mov     di,[blockstarts+di]             ;screen location for tile\r
+       add     di,[masterofs]\r
+\r
+;\r
+; set BX to the foreground tile number and SI to the background number\r
+; If either BX or SI = 0xFFFF, the tile does not need to be masked together\r
+; as one of the planes totally eclipses the other\r
+;\r
+       mov     es,[mapsegs+2]                  ;foreground plane\r
+       mov     bx,[es:si]\r
+       mov     es,[mapsegs]                    ;background plane\r
+       mov     si,[es:si]\r
+\r
+       mov     es,[screenseg]\r
+\r
+       or      bx,bx\r
+       jz      @@singletile\r
+       jmp     @@maskeddraw                    ;draw both together\r
+\r
+;=============\r
+;\r
+; Draw single background tile from main memory\r
+;\r
+;=============\r
+\r
+@@singletile:\r
+       shl     si,1\r
+       mov     ds,[grsegs+STARTTILE16*2+si]\r
+\r
+       xor     si,si                                   ;block is segment aligned\r
+\r
+REPT   15\r
+       movsw\r
+       movsw\r
+       add     di,dx\r
+ENDM\r
+       movsw\r
+       movsw\r
+\r
+       mov     ax,ss\r
+       mov     ds,ax                                   ;restore turbo's data segment\r
+       ret\r
+\r
+\r
+;=========\r
+;\r
+; Draw a masked tile combo\r
+; Interupts are disabled and the stack segment is reassigned\r
+;\r
+;=========\r
+@@maskeddraw:\r
+       cli                                                     ; don't allow ints when SS is set\r
+       shl     bx,1\r
+       mov     ss,[grsegs+STARTTILE16M*2+bx]\r
+       shl     si,1\r
+       mov     ds,[grsegs+STARTTILE16*2+si]\r
+\r
+       xor     si,si                                   ;first word of tile data\r
+\r
+REPT   16\r
+       mov     ax,[si]                                 ;background tile\r
+       and     ax,[ss:si]                              ;mask\r
+       or      ax,[ss:si+64]                   ;masked data\r
+       stosw\r
+       mov     ax,[si+2]                               ;background tile\r
+       and     ax,[ss:si+2]                    ;mask\r
+       or      ax,[ss:si+66]                   ;masked data\r
+       stosw\r
+       add     si,4\r
+       add     di,dx\r
+ENDM\r
+\r
+       mov     ax,@DATA\r
+       mov     ss,ax\r
+       sti\r
+       mov     ds,ax\r
+       ret\r
+ENDP\r
+\r
+ENDIF\r
+\r
+\r
+\r
+IFE GRMODE-EGAGR\r
+;===========================================================================\r
+;\r
+; EGA refresh routines\r
+;\r
+;===========================================================================\r
+\r
+TILEWIDTH      =       2\r
+\r
+;=================\r
+;\r
+; RFL_NewTile\r
+;\r
+; Draws a composit two plane tile to the master screen and sets the update\r
+; spot to 1 in both update pages, forcing the tile to be copied to the\r
+; view pages the next two refreshes\r
+;\r
+; Called to draw newlly scrolled on strips and animating tiles\r
+;\r
+; Assumes write mode 0\r
+;\r
+;=================\r
+\r
+PROC   RFL_NewTile     updateoffset:WORD\r
+PUBLIC RFL_NewTile\r
+USES   SI,DI\r
+\r
+;\r
+; mark both update lists at this spot\r
+;\r
+       mov     di,[updateoffset]\r
+\r
+       mov     bx,[updatestart]                ;page 0 pointer\r
+       mov     [BYTE bx+di],1\r
+       mov     bx,[updatestart+2]              ;page 1 pointer\r
+       mov     [BYTE bx+di],1\r
+\r
+;\r
+; set screenstartcs to the location in screenseg to draw the tile\r
+;\r
+       shl     di,1\r
+       mov     si,[updatemapofs+di]    ;offset in map from origin\r
+       add     si,[originmap]\r
+       mov     di,[blockstarts+di]             ;screen location for tile\r
+       add     di,[masterofs]\r
+       mov     [cs:screenstartcs],di\r
+\r
+;\r
+; set BX to the foreground tile number and SI to the background number\r
+; If either BX or SI = 0xFFFF, the tile does not need to be masked together\r
+; as one of the planes totally eclipses the other\r
+;\r
+       mov     es,[mapsegs+2]                  ;foreground plane\r
+       mov     bx,[es:si]\r
+       mov     es,[mapsegs]                    ;background plane\r
+       mov     si,[es:si]\r
+\r
+       mov     es,[screenseg]\r
+       mov     dx,SC_INDEX                             ;for stepping through map mask planes\r
+\r
+       or      bx,bx\r
+       jz      @@singletile\r
+       jmp     @@maskeddraw                    ;draw both together\r
+\r
+;=========\r
+;\r
+; No foreground tile, so draw a single background tile.\r
+;\r
+;=========\r
+@@singletile:\r
+\r
+       mov     bx,SCREENWIDTH-2                ;add to get to start of next line\r
+       shl     si,1\r
+\r
+       mov     ax,[cs:screenstartcs]\r
+       mov     ds,[grsegs+STARTTILE16*2+si]\r
+\r
+       xor     si,si                                   ;block is segment aligned\r
+\r
+       mov     ax,SC_MAPMASK+0001b*256 ;map mask for plane 0\r
+\r
+       mov     cx,4                                    ;draw four planes\r
+@@planeloop:\r
+       mov     dx,SC_INDEX\r
+       WORDOUT\r
+\r
+       mov     di,[cs:screenstartcs]   ;start at same place in all planes\r
+\r
+REPT   15\r
+       movsw\r
+       add     di,bx\r
+ENDM\r
+       movsw\r
+\r
+       shl     ah,1                                    ;shift plane mask over for next plane\r
+       loop    @@planeloop\r
+\r
+       mov     ax,ss\r
+       mov     ds,ax                                   ;restore turbo's data segment\r
+       ret\r
+\r
+\r
+;=========\r
+;\r
+; Draw a masked tile combo\r
+; Interupts are disabled and the stack segment is reassigned\r
+;\r
+;=========\r
+@@maskeddraw:\r
+       cli                                                     ; don't allow ints when SS is set\r
+       shl     bx,1\r
+       mov     ss,[grsegs+STARTTILE16M*2+bx]\r
+       shl     si,1\r
+       mov     ds,[grsegs+STARTTILE16*2+si]\r
+\r
+       xor     si,si                                   ;first word of tile data\r
+\r
+       mov     ax,SC_MAPMASK+0001b*256 ;map mask for plane 0\r
+\r
+       mov     di,[cs:screenstartcs]\r
+@@planeloopm:\r
+       WORDOUT\r
+tileofs                =       0\r
+lineoffset     =       0\r
+REPT   16\r
+       mov     bx,[si+tileofs]                 ;background tile\r
+       and     bx,[ss:tileofs]                 ;mask\r
+       or      bx,[ss:si+tileofs+32]   ;masked data\r
+       mov     [es:di+lineoffset],bx\r
+tileofs                =       tileofs + 2\r
+lineoffset     =       lineoffset + SCREENWIDTH\r
+ENDM\r
+       add     si,32\r
+       shl     ah,1                                    ;shift plane mask over for next plane\r
+       cmp     ah,10000b\r
+       je      @@done                                  ;drawn all four planes\r
+       jmp     @@planeloopm\r
+\r
+@@done:\r
+       mov     ax,@DATA\r
+       mov     ss,ax\r
+       sti\r
+       mov     ds,ax\r
+       ret\r
+ENDP\r
+\r
+ENDIF\r
+\r
+IFE GRMODE-VGAGR\r
+;============================================================================\r
+;\r
+; VGA refresh routines\r
+;\r
+;============================================================================\r
+\r
+\r
+ENDIF\r
+\r
+\r
+;============================================================================\r
+;\r
+; reasonably common refresh routines\r
+;\r
+;============================================================================\r
+\r
+\r
+;=================\r
+;\r
+; RFL_UpdateTiles\r
+;\r
+; Scans through the update matrix pointed to by updateptr, looking for 1s.\r
+; A 1 represents a tile that needs to be copied from the master screen to the\r
+; current screen (a new row or an animated tiled).  If more than one adjacent\r
+; tile in a horizontal row needs to be copied, they will be copied as a group.\r
+;\r
+; Assumes write mode 1\r
+;\r
+;=================\r
+\r
+\r
+; AX   0/1 for scasb, temp for segment register transfers\r
+; BX    width for block copies\r
+; CX   REP counter\r
+; DX   line width deltas\r
+; SI   source for copies\r
+; DI   scas dest / movsb dest\r
+; BP   pointer to UPDATETERMINATE\r
+;\r
+; DS\r
+; ES\r
+; SS\r
+\r
+PROC   RFL_UpdateTiles\r
+PUBLIC RFL_UpdateTiles\r
+USES   SI,DI,BP\r
+\r
+       jmp     SHORT @@realstart\r
+@@done:\r
+;\r
+; all tiles have been scanned\r
+;\r
+       ret\r
+\r
+@@realstart:\r
+       mov     di,[updateptr]\r
+       mov     bp,(TILESWIDE+1)*TILESHIGH+1\r
+       add     bp,di                                   ; when di = bx, all tiles have been scanned\r
+       push    di\r
+       mov     cx,-1                                   ; definately scan the entire thing\r
+\r
+;\r
+; scan for a 1 in the update list, meaning a tile needs to be copied\r
+; from the master screen to the current screen\r
+;\r
+@@findtile:\r
+       pop     di                                              ; place to continue scaning from\r
+       mov     ax,ss\r
+       mov     es,ax                                   ; search in the data segment\r
+       mov     ds,ax\r
+       mov al,1\r
+       repne   scasb\r
+       cmp     di,bp\r
+       je      @@done\r
+\r
+       cmp     [BYTE di],al\r
+       jne     @@singletile\r
+       jmp     @@tileblock\r
+\r
+;============\r
+;\r
+; copy a single tile\r
+;\r
+;============\r
+EVEN\r
+@@singletile:\r
+       inc     di                                              ; we know the next tile is nothing\r
+       push    di                                      ; save off the spot being scanned\r
+       sub     di,[updateptr]\r
+       shl     di,1\r
+       mov     di,[blockstarts-4+di]   ; start of tile location on screen\r
+       mov     si,di\r
+       add     di,[bufferofs]                  ; dest in current screen\r
+       add     si,[masterofs]                  ; source in master screen\r
+\r
+       mov     dx,SCREENWIDTH-TILEWIDTH\r
+       mov     ax,[screenseg]\r
+       mov     ds,ax\r
+       mov     es,ax\r
+\r
+;--------------------------\r
+\r
+IFE GRMODE-CGAGR\r
+\r
+REPT   15\r
+       movsw\r
+       movsw\r
+       add     si,dx\r
+       add     di,dx\r
+ENDM\r
+       movsw\r
+       movsw\r
+\r
+ENDIF\r
+\r
+;--------------------------\r
+\r
+IFE GRMODE-EGAGR\r
+\r
+REPT   15\r
+       movsb\r
+       movsb\r
+       add     si,dx\r
+       add     di,dx\r
+ENDM\r
+       movsb\r
+       movsb\r
+\r
+ENDIF\r
+\r
+;--------------------------\r
+\r
+       jmp     @@findtile\r
+\r
+;============\r
+;\r
+; more than one tile in a row needs to be updated, so do it as a group\r
+;\r
+;============\r
+EVEN\r
+@@tileblock:\r
+       mov     dx,di                                   ; hold starting position + 1 in dx\r
+       inc     di                                              ; we know the next tile also gets updated\r
+       repe    scasb                           ; see how many more in a row\r
+       push    di                                      ; save off the spot being scanned\r
+\r
+       mov     bx,di\r
+       sub     bx,dx                                   ; number of tiles in a row\r
+       shl     bx,1                                    ; number of bytes / row\r
+\r
+       mov     di,dx                                   ; lookup position of start tile\r
+       sub     di,[updateptr]\r
+       shl     di,1\r
+       mov     di,[blockstarts-2+di]   ; start of tile location\r
+       mov     si,di\r
+       add     di,[bufferofs]                  ; dest in current screen\r
+       add     si,[masterofs]                  ; source in master screen\r
+\r
+       mov     dx,SCREENWIDTH\r
+       sub     dx,bx                                   ; offset to next line on screen\r
+IFE GRMODE-CGAGR\r
+       sub     dx,bx                                   ; bx is words wide in CGA tiles\r
+ENDIF\r
+\r
+       mov     ax,[screenseg]\r
+       mov     ds,ax\r
+       mov     es,ax\r
+\r
+REPT   15\r
+       mov     cx,bx\r
+IFE GRMODE-CGAGR\r
+       rep     movsw\r
+ENDIF\r
+IFE GRMODE-EGAGR\r
+       rep     movsb\r
+ENDIF\r
+       add     si,dx\r
+       add     di,dx\r
+ENDM\r
+       mov     cx,bx\r
+IFE GRMODE-CGAGR\r
+       rep     movsw\r
+ENDIF\r
+IFE GRMODE-EGAGR\r
+       rep     movsb\r
+ENDIF\r
+\r
+       dec     cx                                              ; was 0 from last rep movsb, now $ffff for scasb\r
+       jmp     @@findtile\r
+\r
+ENDP\r
+\r
+\r
+;============================================================================\r
+\r
+\r
+;=================\r
+;\r
+; RFL_MaskForegroundTiles\r
+;\r
+; Scan through update looking for 3's.  If the foreground tile there is a\r
+; masked foreground tile, draw it to the screen\r
+;\r
+;=================\r
+\r
+PROC   RFL_MaskForegroundTiles\r
+PUBLIC RFL_MaskForegroundTiles\r
+USES   SI,DI,BP\r
+       jmp     SHORT @@realstart\r
+@@done:\r
+;\r
+; all tiles have been scanned\r
+;\r
+       ret\r
+\r
+@@realstart:\r
+       mov     di,[updateptr]\r
+       mov     bp,(TILESWIDE+1)*TILESHIGH+2\r
+       add     bp,di                                   ; when di = bx, all tiles have been scanned\r
+       push    di\r
+       mov     cx,-1                                   ; definately scan the entire thing\r
+;\r
+; scan for a 3 in the update list\r
+;\r
+@@findtile:\r
+       mov     ax,ss\r
+       mov     es,ax                                   ; scan in the data segment\r
+       mov     al,3\r
+       pop     di                                              ; place to continue scaning from\r
+       repne   scasb\r
+       cmp     di,bp\r
+       je      @@done\r
+\r
+;============\r
+;\r
+; found a tile, see if it needs to be masked on\r
+;\r
+;============\r
+\r
+       push    di\r
+\r
+       sub     di,[updateptr]\r
+       shl     di,1\r
+       mov     si,[updatemapofs-2+di]  ; offset from originmap\r
+       add     si,[originmap]\r
+\r
+       mov     es,[mapsegs+2]                  ; foreground map plane segment\r
+       mov     si,[es:si]                              ; foreground tile number\r
+\r
+       or      si,si\r
+       jz      @@findtile                              ; 0 = no foreground tile\r
+\r
+       mov     bx,si\r
+       add     bx,INTILE                               ;INTILE tile info table\r
+       mov     es,[tinf]\r
+       test    [BYTE PTR es:bx],80h            ;high bit = masked tile\r
+       jz      @@findtile\r
+\r
+;-------------------\r
+\r
+IFE GRMODE-CGAGR\r
+;=================\r
+;\r
+; mask the tile CGA\r
+;\r
+;=================\r
+\r
+       mov     di,[blockstarts-2+di]\r
+       add     di,[bufferofs]\r
+       mov     es,[screenseg]\r
+       shl     si,1\r
+       mov     ds,[grsegs+STARTTILE16M*2+si]\r
+\r
+       mov     bx,64                                   ;data starts 64 bytes after mask\r
+\r
+       xor     si,si\r
+\r
+lineoffset     =       0\r
+REPT   16\r
+       mov     ax,[es:di+lineoffset]   ;background\r
+       and     ax,[si]                                 ;mask\r
+       or      ax,[si+bx]                              ;masked data\r
+       mov     [es:di+lineoffset],ax   ;background\r
+       inc     si\r
+       inc     si\r
+       mov     ax,[es:di+lineoffset+2] ;background\r
+       and     ax,[si]                                 ;mask\r
+       or      ax,[si+bx]                              ;masked data\r
+       mov     [es:di+lineoffset+2],ax ;background\r
+       inc     si\r
+       inc     si\r
+lineoffset     =       lineoffset + SCREENWIDTH\r
+ENDM\r
+ENDIF\r
+\r
+;-------------------\r
+\r
+IFE GRMODE-EGAGR\r
+;=================\r
+;\r
+; mask the tile\r
+;\r
+;=================\r
+\r
+       mov     [BYTE planemask],1\r
+       mov     [BYTE planenum],0\r
+\r
+       mov     di,[blockstarts-2+di]\r
+       add     di,[bufferofs]\r
+       mov     [cs:screenstartcs],di\r
+       mov     es,[screenseg]\r
+       shl     si,1\r
+       mov     ds,[grsegs+STARTTILE16M*2+si]\r
+\r
+       mov     bx,32                                   ;data starts 32 bytes after mask\r
+\r
+@@planeloopm:\r
+       mov     dx,SC_INDEX\r
+       mov     al,SC_MAPMASK\r
+       mov     ah,[ss:planemask]\r
+       WORDOUT\r
+       mov     dx,GC_INDEX\r
+       mov     al,GC_READMAP\r
+       mov     ah,[ss:planenum]\r
+       WORDOUT\r
+\r
+       xor     si,si\r
+       mov     di,[cs:screenstartcs]\r
+lineoffset     =       0\r
+REPT   16\r
+       mov     cx,[es:di+lineoffset]   ;background\r
+       and     cx,[si]                                 ;mask\r
+       or      cx,[si+bx]                              ;masked data\r
+       inc     si\r
+       inc     si\r
+       mov     [es:di+lineoffset],cx\r
+lineoffset     =       lineoffset + SCREENWIDTH\r
+ENDM\r
+       add     bx,32                                   ;the mask is now further away\r
+       inc     [ss:planenum]\r
+       shl     [ss:planemask],1                ;shift plane mask over for next plane\r
+       cmp     [ss:planemask],10000b   ;done all four planes?\r
+       je      @@drawn                                 ;drawn all four planes\r
+       jmp     @@planeloopm\r
+\r
+@@drawn:\r
+ENDIF\r
+\r
+;-------------------\r
+\r
+       mov     ax,ss\r
+       mov     ds,ax\r
+       mov     cx,-1                                   ;definately scan the entire thing\r
+\r
+       jmp     @@findtile\r
+\r
+ENDP\r
+\r
+\r
+END\r
+\r