summaryrefslogtreecommitdiff
path: root/bcopy.asm
blob: 2023ba37f145991737cbbcc4aad2792b726e920f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
		section .text
		org 8000h
;
; 32-bit bcopy routine for real mode
;
; We enter protected mode, set up a flat 32-bit environment, run rep movsd
; and then exit.  IMPORTANT: This code assumes cs == ss == 0.
;
; This code is probably excessively anal-retentive in its handling of
; segments.
;
bcopy_main:	jmp short bcopy
	
bcopy_gdt_ptr:	dw bcopy_gdt_size-1
		dd bcopy_gdt

		align 4
bcopy_gdt:	dd 0			; Null descriptor
		dd 0
		dd 0000ffffh		; Code segment, use16, readable,
		dd 00009b00h		; present, dpl 0, cover 64K
		dd 0000ffffh		; Data segment, use16, read/write,
		dd 008f9300h		; present, dpl 0, cover all 4G
		dd 0000ffffh		; Data segment, use16, read/write,
		dd 00009300h		; present, dpl 0, cover 64K
bcopy_gdt_size:	equ $-bcopy_gdt

bcopy:
		push eax
		push gs
		push fs
		push ds
		push es
		lgdt [bcopy_gdt_ptr]

		mov eax,cr0
		or eax,byte 1
		cli
		mov cr0,eax		; Enter protected mode
		jmp 8:.in_pm

.in_pm:		xor ax,ax		; Null selector
		mov fs,ax
		mov gs,ax

		mov al,16		; Data segment selector
		mov es,ax
		mov ds,ax

		mov al,24		; "Real-mode-like" data segment
		mov ss,ax
	
		a32 rep movsd		; Do our business
		
		mov es,ax		; Set to "real-mode-like"
		mov ds,ax
		mov fs,ax
		mov gs,ax	
	
		mov eax,cr0
		and eax,0fffffffeh
		mov cr0,eax		; Disable protected mode
		jmp 0:.in_rm

.in_rm:		xor ax,ax		; Back in real mode
		mov ss,ax
		sti
		pop es
		pop ds
		pop fs
		pop gs
		pop eax
		ret