!************************************************************************** !* !* Boot-ROM-Code to load an operating system across a TCP/IP network. !* !* Module: lmove.S !* Purpose: Copy a memory block into extended memory !* Entries: _lmove !* !************************************************************************** !* !* Copyright (C) 1995-2003 Gero Kuhlmann !* !* This program is free software; you can redistribute it and/or modify !* it under the terms of the GNU General Public License as published by !* the Free Software Foundation; either version 2 of the License, or !* any later version. !* !* This program is distributed in the hope that it will be useful, !* but WITHOUT ANY WARRANTY; without even the implied warranty of !* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !* GNU General Public License for more details. !* !* You should have received a copy of the GNU General Public License !* along with this program; if not, write to the Free Software !* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. !* !* $Id: lmove.S,v 1.4 2003/01/25 23:29:41 gkminix Exp $ !* ! !************************************************************************** ! ! Include assembler macros: ! #include ! !************************************************************************** ! ! Layout of descriptors in GDT: ! gdt_length equ $0000 ! length of segment gdt_base_low equ $0002 ! base of segment (low 3 bytes) gdt_flags equ $0005 ! descriptor flags gdt_res equ $0006 ! reserved gdt_base_high equ $0007 ! base of segment (high byte) gdt_size equ 8 ! size of descriptor gdt_stdflag equ $93 ! standard flags for GDT entries ! !************************************************************************** ! ! Start code segment. ! .text public _lmove ! define entry points ! !************************************************************************** ! ! Move a memory block into extended memory. ! Input: 1. arg - linear address to destination (long word) ! 2. arg - near pointer to source memory block ! 3. arg - length of memory block ! Output: zero if error ! _lmove: gdt_table equ (6 * gdt_size) penter (gdt_table) cld push es push si getcarg (bx,3) #ifdef IS386 getcarg (edx,0) ! check for copy into lower memory cmp edx,#$00100000 #else getcarg (ax,0) getcarg (dx,1) ! check for copy into lower memory cmp dx,#$0010 #endif jae lmove1 ! Handle moves into lower memory push di #ifdef IS386 mov di,dx shr edx,#4 ! convert linear address into seg:ofs #else mov di,ax shift (shr,ax,4) ! convert linear address into seg:ofs shift (shl,dx,12) or dx,ax #endif and di,#$000F ! load destination pointer mov es,dx getcarg (si,2) ! load source pointer mov cx,bx inc cx ! convert byte count into word count shr cx,#1 rep movsw ! do the copy pop di jmp lmove8 ! Handle moves into high memory lmove1: mov ax,ss mov es,ax push di lea di,[bp - gdt_table] mov cx,#gdt_table / 2 xor ax,ax ! clear GDT rep stosw pop di #ifdef IS386 mov dword ptr [bp - gdt_table + 3 * gdt_size + gdt_base_low + 0],edx shr edx,#16 #else mov word ptr [bp - gdt_table + 3 * gdt_size + gdt_base_low + 0],ax mov byte ptr [bp - gdt_table + 3 * gdt_size + gdt_base_low + 2],dl #endif mov byte ptr [bp - gdt_table + 3 * gdt_size + gdt_base_high],dh mov byte ptr [bp - gdt_table + 3 * gdt_size + gdt_flags],#gdt_stdflag mov word ptr [bp - gdt_table + 3 * gdt_size + gdt_length],bx #ifdef IS386 xor eax,eax mov ax,ds shl eax,#4 getlarg (edx,2,word) add eax,edx mov dword ptr [bp - gdt_table + 2 * gdt_size + gdt_base_low + 0],eax #else mov ax,ds shift (rol,ax,4) mov cx,ax and ax,#$FFF0 ! convert segment and offset into and cx,#$000F ! a linear address getcarg (dx,2) add ax,dx adc cx,#0 mov word ptr [bp - gdt_table + 2 * gdt_size + gdt_base_low + 0],ax mov byte ptr [bp - gdt_table + 2 * gdt_size + gdt_base_low + 2],cl #endif mov byte ptr [bp - gdt_table + 2 * gdt_size + gdt_flags],#gdt_stdflag mov word ptr [bp - gdt_table + 2 * gdt_size + gdt_length],bx mov cx,bx inc cx ! convert byte count into word count shr cx,#1 lea si,[bp - gdt_table] mov ah,#$87 int INT_MISC ! call BIOS to do the copy jnc lmove8 xor ax,ax ! prepare return value jmp lmove9 lmove8: mov ax,#1 lmove9: pop si pop es pleave ret ! !************************************************************************** ! end