d_copy.s 2.5 KB

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