1 // 2 // d_copy.s 3 // x86 assembly-language screen copying code. 4 // 5 6 #include "asm_i386.h" 7 #include "quakeasm.h" 8 #include "asm_draw.h" 9 10 .data 11 12 LCopyWidth: .long 0 13 LBlockSrcStep: .long 0 14 LBlockDestStep: .long 0 15 LSrcDelta: .long 0 16 LDestDelta: .long 0 17 18 #define bufptr 4+16 19 20 // copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since 21 // no Mode X mode is wider than 360, all the data should fit in the cache for 22 // the passes for the next 3 planes 23 24 .text 25 26 .globl C(VGA_UpdatePlanarScreen) 27 C(VGA_UpdatePlanarScreen): 28 pushl %ebp // preserve caller's stack frame 29 pushl %edi 30 pushl %esi // preserve register variables 31 pushl %ebx 32 33 movl C(VGA_bufferrowbytes),%eax 34 shll $1,%eax 35 movl %eax,LBlockSrcStep 36 movl C(VGA_rowbytes),%eax 37 shll $1,%eax 38 movl %eax,LBlockDestStep 39 40 movl $0x3C4,%edx 41 movb $2,%al 42 outb %al,%dx // point the SC to the Map Mask 43 incl %edx 44 45 movl bufptr(%esp),%esi 46 movl C(VGA_pagebase),%edi 47 movl C(VGA_height),%ebp 48 shrl $1,%ebp 49 50 movl C(VGA_width),%ecx 51 movl C(VGA_bufferrowbytes),%eax 52 subl %ecx,%eax 53 movl %eax,LSrcDelta 54 movl C(VGA_rowbytes),%eax 55 shll $2,%eax 56 subl %ecx,%eax 57 movl %eax,LDestDelta 58 shrl $4,%ecx 59 movl %ecx,LCopyWidth 60 61 LRowLoop: 62 movb $1,%al 63 64 LPlaneLoop: 65 outb %al,%dx 66 movb $2,%ah 67 68 pushl %esi 69 pushl %edi 70 LRowSetLoop: 71 movl LCopyWidth,%ecx 72 LColumnLoop: 73 movb 12(%esi),%bh 74 movb 8(%esi),%bl 75 shll $16,%ebx 76 movb 4(%esi),%bh 77 movb (%esi),%bl 78 movl %ebx,(%edi) 79 addl $16,%esi 80 addl $4,%edi 81 decl %ecx 82 jnz LColumnLoop 83 84 addl LDestDelta,%edi 85 addl LSrcDelta,%esi 86 decb %ah 87 jnz LRowSetLoop 88 89 popl %edi 90 popl %esi 91 incl %esi 92 93 shlb $1,%al 94 cmpb $16,%al 95 jnz LPlaneLoop 96 97 subl $4,%esi 98 addl LBlockSrcStep,%esi 99 addl LBlockDestStep,%edi 100 decl %ebp 101 jnz LRowLoop 102 103 popl %ebx // restore register variables 104 popl %esi 105 popl %edi 106 popl %ebp // restore the caller's stack frame 107 108 ret 109 110 111 #define srcptr 4+16 112 #define destptr 8+16 113 #define width 12+16 114 #define height 16+16 115 #define srcrowbytes 20+16 116 #define destrowbytes 24+16 117 118 .globl C(VGA_UpdateLinearScreen) 119 C(VGA_UpdateLinearScreen): 120 pushl %ebp // preserve caller's stack frame 121 pushl %edi 122 pushl %esi // preserve register variables 123 pushl %ebx 124 125 cld 126 movl srcptr(%esp),%esi 127 movl destptr(%esp),%edi 128 movl width(%esp),%ebx 129 movl srcrowbytes(%esp),%eax 130 subl %ebx,%eax 131 movl destrowbytes(%esp),%edx 132 subl %ebx,%edx 133 shrl $2,%ebx 134 movl height(%esp),%ebp 135 LLRowLoop: 136 movl %ebx,%ecx 137 rep/movsl (%esi),(%edi) 138 addl %eax,%esi 139 addl %edx,%edi 140 decl %ebp 141 jnz LLRowLoop 142 143 popl %ebx // restore register variables 144 popl %esi 145 popl %edi 146 popl %ebp // restore the caller's stack frame 147 148 ret 149 150