1/* 2 d_copy.S 3 4 x86 assembly-language screen copying code. 5 6 Copyright (C) 1996-1997 Id Software, Inc. 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 2 11 of the License, or (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 17 See the GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to: 21 22 Free Software Foundation, Inc. 23 59 Temple Place - Suite 330 24 Boston, MA 02111-1307, USA 25 26 $Id$ 27*/ 28 29#ifdef HAVE_CONFIG_H 30# include <config.h> 31#endif 32#include "asm_i386.h" 33#include "quakeasm.h" 34#include "asm_draw.h" 35 36#ifdef PIC 37# undef USE_INTEL_ASM //XXX asm pic hack 38#endif 39 40#ifdef USE_INTEL_ASM 41 .data 42 43LCopyWidth: .long 0 44LBlockSrcStep: .long 0 45LBlockDestStep: .long 0 46LSrcDelta: .long 0 47LDestDelta: .long 0 48 49#define bufptr 4+16 50 51// copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since 52// no Mode X mode is wider than 360, all the data should fit in the cache for 53// the passes for the next 3 planes 54 55 .text 56 57.globl C(VGA_UpdatePlanarScreen) 58C(VGA_UpdatePlanarScreen): 59 pushl %ebp // preserve caller's stack frame 60 pushl %edi 61 pushl %esi // preserve register variables 62 pushl %ebx 63 64 movl C(VGA_bufferrowbytes),%eax 65 shll $1,%eax 66 movl %eax,LBlockSrcStep 67 movl C(VGA_rowbytes),%eax 68 shll $1,%eax 69 movl %eax,LBlockDestStep 70 71 movl $0x3C4,%edx 72 movb $2,%al 73 outb %al,%dx // point the SC to the Map Mask 74 incl %edx 75 76 movl bufptr(%esp),%esi 77 movl C(VGA_pagebase),%edi 78 movl C(VGA_height),%ebp 79 shrl $1,%ebp 80 81 movl C(VGA_width),%ecx 82 movl C(VGA_bufferrowbytes),%eax 83 subl %ecx,%eax 84 movl %eax,LSrcDelta 85 movl C(VGA_rowbytes),%eax 86 shll $2,%eax 87 subl %ecx,%eax 88 movl %eax,LDestDelta 89 shrl $4,%ecx 90 movl %ecx,LCopyWidth 91 92LRowLoop: 93 movb $1,%al 94 95LPlaneLoop: 96 outb %al,%dx 97 movb $2,%ah 98 99 pushl %esi 100 pushl %edi 101LRowSetLoop: 102 movl LCopyWidth,%ecx 103LColumnLoop: 104 movb 12(%esi),%bh 105 movb 8(%esi),%bl 106 shll $16,%ebx 107 movb 4(%esi),%bh 108 movb (%esi),%bl 109 movl %ebx,(%edi) 110 addl $16,%esi 111 addl $4,%edi 112 decl %ecx 113 jnz LColumnLoop 114 115 addl LDestDelta,%edi 116 addl LSrcDelta,%esi 117 decb %ah 118 jnz LRowSetLoop 119 120 popl %edi 121 popl %esi 122 incl %esi 123 124 shlb $1,%al 125 cmpb $16,%al 126 jnz LPlaneLoop 127 128 subl $4,%esi 129 addl LBlockSrcStep,%esi 130 addl LBlockDestStep,%edi 131 decl %ebp 132 jnz LRowLoop 133 134 popl %ebx // restore register variables 135 popl %esi 136 popl %edi 137 popl %ebp // restore the caller's stack frame 138 139 ret 140 141 142#define srcptr 4+16 143#define destptr 8+16 144#define width 12+16 145#define height 16+16 146#define srcrowbytes 20+16 147#define destrowbytes 24+16 148 149.globl C(VGA_UpdateLinearScreen) 150C(VGA_UpdateLinearScreen): 151 pushl %ebp // preserve caller's stack frame 152 pushl %edi 153 pushl %esi // preserve register variables 154 pushl %ebx 155 156 cld 157 movl srcptr(%esp),%esi 158 movl destptr(%esp),%edi 159 movl width(%esp),%ebx 160 movl srcrowbytes(%esp),%eax 161 subl %ebx,%eax 162 movl destrowbytes(%esp),%edx 163 subl %ebx,%edx 164 shrl $2,%ebx 165 movl height(%esp),%ebp 166LLRowLoop: 167 movl %ebx,%ecx 168 rep/movsl (%esi),(%edi) 169 addl %eax,%esi 170 addl %edx,%edi 171 decl %ebp 172 jnz LLRowLoop 173 174 popl %ebx // restore register variables 175 popl %esi 176 popl %edi 177 popl %ebp // restore the caller's stack frame 178 179 ret 180#endif /* USE_INTEL_ASM */ 181