Here is my copy code:
Code:
source_sel = 8
dest_sel = 10h
flat_sel = 18h
LoadGdt:
load_gdt0:
DW 27h
DD 0
DW 0
load_gdt_source:
DW 0FFFFh
DD 92000000h
DW 0
load_gdt_dest:
DW 0FFFFh
DD 92300000h
DW 0
load_gdt_flat:
DW 0FFFFh
DD 92000000h
DW 008Fh
load_gdt_cs:
DW 0FFFFh
DD 9A000000h
DW 0
InitGdt Proc near
mov ax,cs
movzx eax,ax
shl eax,4
add eax,OFFSET LoadGdt
mov dword ptr cs:load_gdt0+2,eax
lgdt fword ptr cs:load_gdt0
;
mov ax,cs
movzx eax,ax
shl eax,4
or dword ptr cs:load_gdt_cs+2,eax
ret
InitGdt Endp
MoveData Proc near
push ds
push es
pushad
;
mov eax,esi
mov dword ptr cs:load_gdt_source+2,eax
mov al,92h
xchg al,byte ptr cs:load_gdt_source+5
mov byte ptr cs:load_gdt_source+7,al
;
mov eax,edi
mov dword ptr cs:load_gdt_dest+2,eax
mov al,92h
xchg al,byte ptr cs:load_gdt_dest+5
mov byte ptr cs:load_gdt_dest+7,al
mov word ptr cs:MoveDataRmCs,cs
;
cli
mov eax,cr0
or al,1
mov cr0,eax
;
db 0EAh
dw OFFSET MoveDataPm
dw 20h
MoveDataPm:
mov ax,source_sel
mov ds,ax
mov ax,dest_sel
mov es,ax
xor esi,esi
xor edi,edi
rep movs byte ptr es:[edi],[esi]
;
mov eax,cr0
and al,NOT 1
mov cr0,eax
;
db 0EAh
dw OFFSET MoveDataRm
MoveDataRmCs:
dw 0
MoveDataRm:
sti
popad
pop es
pop ds
ret
MoveData Endp
I can see that I gate A20 and load GDT before starting to read the disc, and the MoveData seems to rely on BIOS not changing GDT or A20 gating. That could be a problem, although the code seems to work on many real PCs.