d_copy.s 2.5 KB

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