Advertisement
MichaelPetch

SO 78421958

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