Advertisement
MichaelPetch

SO 78421958

May 3rd, 2024 (edited)
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.94 KB | None | 0 0
  1. ; Assemble with
  2. ; nasm -f bin unreal.asm -o unreal.com
  3.  
  4. ; Macro to build a GDT descriptor entry
  5. %define MAKE_GDT_DESC(base, limit, access, flags) \
  6. (((base & 0x00FFFFFF) << 16) | \
  7. ((base & 0xFF000000) << 32) | \
  8. (limit & 0x0000FFFF) | \
  9. ((limit & 0x000F0000) << 32) | \
  10. ((access & 0xFF) << 40) | \
  11. ((flags & 0x0F) << 52))
  12.  
  13. bits 16
  14. org 0x100
  15.  
  16. section .data
  17. align 4
  18. gdt:
  19. FLAT_SEL equ .flat - .start
  20.  
  21. .start:
  22. .null:
  23. dq MAKE_GDT_DESC(0, 0, 0, 0) ; null descriptor
  24. .flat:
  25. dq MAKE_GDT_DESC(0, 0x000fffff, 10010010b, 1100b)
  26. ; 32-bit data, 4kb gran, limit 0xffffffff bytes, base=0
  27. .end:
  28.  
  29. .gdtr:
  30. dw .end - .start - 1
  31. ; limit (Size of GDT - 1)
  32. dd .start ; base of GDT. Needs to be fixed up at runtime
  33.  
  34. in_pmode_str: db "Processor already in protected mode - exiting", 0x0a, 0x0d, "$"
  35.  
  36. section .text
  37. start:
  38. ; Save initial EFLAGS state
  39. pushfd
  40. cli
  41.  
  42. check_pmode:
  43. smsw ax
  44. test ax, 0x1 ; Check if we are already in protected mode
  45. ; This may be the case if we are in a VM8086 task.
  46. ; EMM386 and other expanded memory manager often
  47. ; run DOS in a VM8086 task. DOS extenders will have
  48. ; the same effect
  49.  
  50. jz not_prot_mode ; If not in protected mode proceed to switch
  51. mov dx, in_pmode_str ; otherwise print an error and exit back to DOS
  52. mov ah, 0x9
  53. int 0x21 ; Print Error
  54. jmp exit ; Exit program
  55.  
  56. not_prot_mode:
  57. ; Apply a fixup to the GDTR base to convert to a linear address
  58. mov eax, ds
  59. shl eax, 4
  60. add [gdt.gdtr+2], eax
  61. lgdt [gdt.gdtr] ; Load our GDT
  62.  
  63. mov cx, ds ; Save DS so it can be restored
  64. mov eax, cr0
  65. or al, 1
  66. mov cr0, eax ; Set protected mode flag
  67. jmp .next1 ; Flush the instruction pefetch queue
  68. .next1:
  69.  
  70. ; In 16-bit protected mode
  71. ; Since we aren't changing CS
  72. ; we don't need to enter 32-bit protected mode
  73. mov bx, FLAT_SEL
  74. mov ss, bx
  75. mov ds, bx
  76. mov es, bx
  77. mov fs, bx
  78. mov gs, bx
  79.  
  80. and al, ~1
  81. mov cr0, eax ; Unset protected mode flag
  82. jmp .next2 ; Flush the instruction pefetch queue
  83. .next2:
  84.  
  85. ; Unreal mode here
  86. ; Restore SS=DS=ES
  87. mov ss, cx
  88. mov ds, cx
  89. mov es, cx
  90.  
  91. ; Print UNR to the screen using a flat 4GiB selector
  92. ; This code won't work in regular real mode
  93. xor ax, ax
  94. mov fs, ax
  95.  
  96. mov word fs:[dword 0xb8000+80*2*3+0], 0x57<<8 | 'U'
  97. mov word fs:[dword 0xb8000+80*2*3+2], 0x57<<8 | 'N'
  98. mov word fs:[dword 0xb8000+80*2*3+4], 0x57<<8 | 'R'
  99.  
  100. exit:
  101. ; Restore initial EFLAGS state
  102. popfd
  103. ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement