lxxx.s 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "386l.h"
  2. #define KZERO (0)
  3. #define DELAY BYTE $0xeb; /* JMP .+2 */ \
  4. BYTE $0x00
  5. #define NOP BYTE $0x90 /* NOP */
  6. #define pFARJMP32(s, o) BYTE $0xea; /* far jmp ptr32:16 */ \
  7. LONG $o; WORD $s
  8. #define rFARJMP16(s, o) BYTE $0xea; /* far jump ptr16:16 */ \
  9. WORD $o; WORD $s;
  10. #define rFARJMP32(s, o) BYTE $0x66; /* far jump ptr32:16 */ \
  11. pFARJMP32(s, o)
  12. #define rLGDT(gdtptr) BYTE $0x0f; /* LGDT */ \
  13. BYTE $0x01; BYTE $0x16; \
  14. WORD $gdtptr
  15. #define rAX 0 /* rX */
  16. #define rCX 1
  17. #define rDX 2
  18. #define rBX 3
  19. #define rSP 4 /* SP */
  20. #define rBP 5 /* BP */
  21. #define rSI 6 /* SI */
  22. #define rDI 7 /* DI */
  23. #define rMOV16(i, rX) BYTE $(0xB8+rX); /* i -> rX */ \
  24. WORD $i;
  25. #define rMOV32(i, rX) BYTE $0x66; /* i -> rX */ \
  26. BYTE $(0xB8+rX); \
  27. LONG $i;
  28. /*
  29. * Real mode. Welcome to 1978.
  30. */
  31. TEXT _real<>(SB), 1, $-4
  32. rFARJMP16(0, _endofheader<>-KZERO(SB)) /* */
  33. NOP; NOP; NOP /* align */
  34. _startofheader:
  35. WORD $0; WORD $0 /* flags */
  36. TEXT _gdt32p<>(SB), 1, $-4
  37. LONG $0x0000; LONG $0 /* NULL descriptor */
  38. LONG $0xffff; LONG $0x00cf9a00 /* CS */
  39. LONG $0xffff; LONG $0x00cf9200 /* DS */
  40. TEXT _gdtptr32p<>(SB), 1, $-4
  41. WORD $(3*8-1)
  42. LONG $_gdt32p<>-KZERO(SB)
  43. TEXT _hello<>(SB), $0
  44. BYTE $'H'; BYTE $'e'; BYTE $'l'; BYTE $'l';
  45. BYTE $'o'; BYTE $' '; BYTE $'f'; BYTE $'r';
  46. BYTE $'o'; BYTE $'m'; BYTE $' '; BYTE $'1';
  47. BYTE $'9'; BYTE $'7'; BYTE $'8'; BYTE $'.';
  48. BYTE $'\r';
  49. BYTE $'\n';
  50. BYTE $'\z';
  51. BYTE $'\z';
  52. TEXT _endofheader<>(SB), 1, $-4
  53. CLI
  54. CLD
  55. XORL AX, AX
  56. MOVW AX, DS /* initialise DS */
  57. MOVW AX, ES /* initialise ES */
  58. MOVW AX, SS /* initialise SS */
  59. rMOV16(_real<>-KZERO(SB), rSP) /* stack */
  60. PUSHL AX /* CS segment */
  61. rMOV16(_setCS<>-KZERO(SB), rAX) /* address within segment */
  62. PUSHL AX
  63. BYTE $0xcb /* far return */
  64. TEXT _setCS<>(SB), 1, $-4
  65. MOVB $0x0f, AH /* get current display mode */
  66. INT $0x10
  67. SUBB $3, AL /* is it text mode 3? */
  68. JEQ _cgaputs
  69. MOVB $0x0f, AH /* text mode 3 */
  70. MOVB $0x03, AL
  71. INT $0x10
  72. _cgaputs:
  73. rMOV16(_hello<>-KZERO(SB), rAX) /* a cheery wee message */
  74. MOVL AX, SI
  75. XORL BX, BX /* page number, colour */
  76. _cgaputsloop:
  77. LODSB /* next character in string */
  78. ORB AL, AL /* \0? */
  79. JEQ _cgaend
  80. MOVB $0x0e, AH /* teletype output */
  81. INT $0x10
  82. JMP _cgaputsloop
  83. _cgaend:
  84. rMOV16(_real<>+(8-KZERO)(SB), rSI) /* flag */
  85. LODSW
  86. ORL AX, AX
  87. JNE _e820
  88. INCL AX
  89. rMOV16(_real<>+(8-KZERO)(SB), rDI) /* flag */
  90. STOSW
  91. rMOV16(0x0467, rDI) /* reset entry point */
  92. rMOV16(_endofheader<>-KZERO(SB), rAX)
  93. STOSW
  94. MOVW CS, AX
  95. STOSW
  96. rMOV16(0x70, rDX)
  97. MOVB $0x8f, AL
  98. OUTB
  99. DELAY
  100. INCL DX
  101. MOVB $0x0a, AL
  102. OUTB
  103. DELAY
  104. rMOV16(0x1234, rBP)
  105. rMOV16(0x5678, rDX)
  106. rFARJMP16(0xffff, 0) /* reset */
  107. _e820:
  108. rMOV16(_real<>-(KZERO+1024)(SB), rDI) /* e820 save area */
  109. // XORL AX, AX /* nothing to see here (yet) */
  110. // STOSL
  111. // STOSL
  112. XORL BX, BX /* continuation */
  113. _e820int:
  114. rMOV32(40, rCX) /* buffer size */
  115. rMOV32(0x534d4150, rDX) /* signature - ASCII "SMAP" */
  116. rMOV32(0xe820, rAX) /* function code */
  117. INT $0x15 /* query system address map */
  118. JCS _e820end
  119. INCL AX
  120. _e820end:
  121. STOSL
  122. MOVL CX, AX
  123. STOSL
  124. // MOVL BX, AX
  125. // STOSL
  126. rMOV16(0xaabb, rAX)
  127. STOSL
  128. MOVW CS, AX
  129. STOSL
  130. rLGDT(_gdtptr32p<>-KZERO(SB)) /* load a basic gdt */
  131. MOVL CR0, AX
  132. ORL $Pe, AX
  133. MOVL AX, CR0 /* turn on protected mode */
  134. DELAY /* JMP .+2 */
  135. rMOV16(SSEL(SiDS, SsTIGDT|SsRPL0), rAX) /* */
  136. MOVW AX, DS
  137. MOVW AX, ES
  138. MOVW AX, FS
  139. MOVW AX, GS
  140. MOVW AX, SS
  141. rFARJMP32(SSEL(SiCS, SsTIGDT|SsRPL0), _start32p-KZERO(SB))
  142. #ifdef standalone
  143. /*
  144. * Protected mode. Welcome to 1982.
  145. */
  146. TEXT _start32p(SB), 1, $-4
  147. _ndnr:
  148. JMP _ndnr
  149. RET
  150. #endif /* standalone */