diff options
Diffstat (limited to 'c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm')
-rw-r--r-- | c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm | 575 |
1 files changed, 0 insertions, 575 deletions
diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm b/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm deleted file mode 100644 index cd951ec8fd..0000000000 --- a/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm +++ /dev/null @@ -1,575 +0,0 @@ -; loader_hybrid_com.asm -; -; This is a DOS command-line loader for RTEMS executables running on -; the Technologic Systems TS-1325 Embedded PC. -; -; It loads a DOS file given on the command line to the address `KernelBase', -; and then transfers control there. It uses DOS file I/O commands to read from -; the A: flash disk, and direct memory access to read from the C: ramdisk. -; -; Copying uses protected flat mode, so kernelbase could be above 1MB. -; It does not initialize protected mode before transferring control -; to the RTEMS executable image. -; -; Compile with: nasm -o loader.com loader_hybrid_com.asm -; -; Tony Ambardar (c) 1999 -; E.C.E. Department -; University of British Columbia - -%include "ts1325.inc" ; Some useful LED and button macros - -; IMPORTANT: [org xxx] MUST be the same as RelocAddr below. - -[org E000h] -[bits 16] - -; Only these three definitions may need to change - -KernelBase equ 08000h ; Where (32-bit) to locate and run RTEMS executable - -RelocSeg equ 9000h ; Segment to relocate code. -RelocAddr equ 0E000h ; Address to relocate code, same as "org" above - -; Next three used in GDT - -RelocBase equ RelocSeg*16 -Reloc15 equ RelocBase & 0FFFFh -Reloc23 equ RelocBase / 10000h - -Buffer equ RelocAddr+400h ; In same segment as RelocSeg -BuffSiz equ 200h ; Size of disk read + copy - -StackSeg equ RelocSeg -StackSiz equ 40h -StackAddr equ Buffer+BuffSiz+StackSiz - -; Used to jump to kernel in real mode - -KernelAddr equ KernelBase & 0FFFFh -KernelSeg equ (KernelBase - KernelAddr) / 16 - -; Used to load from the ramdisk - -Extended equ 100000h ; Start of extended memory / C: ramdisk -OffsetBPB equ 0Bh ; Start of BIOS param block in bootsector - -; Command-line parameters - -ParamLen equ 80h ; Byte length of command line params -ParamStr equ 82h ; Start of param string - -; The ORG address above means pre-relocation addresses are wrong. The -; following macro fixes these up. - -%define PRE_RELOC_ADDR(addr) (addr-CodeStart+100h) - -CodeStart: - -mov dx, PRE_RELOC_ADDR(Greet) -mov ah, 9h -int 21h - -mov ax, 0b021h ; Exit to DOS if push-button switch pressed -int 15h -and al, 01h ; Bit 0 == 0 if button pressed -jz ButtonExit - -xor cx, cx -mov cl, [ParamLen] ; See if there is a command line arg -jcxz NameError - -dec cx ; Nix leading space. Is this standard? -cmp cx, 12 ; Limit to 12 chars: e.g. ABCDEFGH.IJK -jg NameError - ; Damn. Should make sure of no ':' or '\' chars too. - -; Required by "relocated" [org] statement above - -mov di, PRE_RELOC_ADDR(FName) -mov si, ParamStr -repne -movsb ; Copy command line arg - -; Make sure no ':' in filename. This forces using the default dir. - -mov di, PRE_RELOC_ADDR(FName) -mov al, ':' -mov cx, 12 -repne -scasb -je NameError - -jmp Relocate - -ButtonExit: -mov dx, PRE_RELOC_ADDR(Button) -jmp short DosPrint - -NameError: -mov dx, PRE_RELOC_ADDR(FError) -jmp short DosPrint - -DosError: ; Only call this AFTER relocation -mov dx, RError - -DosPrint: -mov ah, 9h -int 21h - -DosExit: -mov ax, 04C00h ; DOS Function: Exit program -int 21h ; Call DOS. Terminate Program - -Relocate: ; Move this code down to RelocAddr - -cld -mov ax, RelocSeg -mov es, ax ; Set destination = RelocSeg:RelocAddr -mov di, RelocAddr -mov si, 100h ; Source is ds:0100h i.e. a COM file -mov cx, CodeEnd - CodeStart ; Size of all code - -repne -movsb - -; continue in copied code - -jmp RelocSeg:RelocAddr + (RelocStart - CodeStart) - -RelocStart: -cli -mov ax, StackSeg -mov ss, ax -mov sp, StackAddr -mov ax, cs -mov ds, ax -mov es, ax ; Setup segments and stack -sti - -mov ah, 19h -int 21h -mov [DDrive], al ; Save current default drive - -mov ax, 3d00h ; DOS Function: Open the file for reading -mov dx, FName ; Presume DS points at filename segment -int 21h -jc DosError - -GoodOpen: -mov [FHndl], ax ; Save file handle - -mov al, [DDrive] ; Check if loading from C: drive (ramdisk) -cmp al, 2 -je LoadRamdisk - -LoadDosdisk: - -; Here we are loading from A: drive. Use DOS calls to load the file into -; extended memory. Then copy from extended memory to `KernelBase'. This way -; we avoid overwriting DOS file I/O structures if reading directly into -; conventional (<640K) memory. - -mov edi, Extended ; Destination for code read @ 1 Meg - -ReadLoop: - -mov ah,3fh ; DOS Function: Read data from the file -mov bx, [FHndl] -mov dx, Buffer ; Address of data buffer -mov cx, BuffSiz ; Request BuffSiz bytes -int 21h -jc DosError - -GoodRead: - -cmp ax, cx ; EOF reached? AX = # bytes read -pushf - -add ax, 3 -shr ax, 2 ; Copy buffer by dwords, # = (ax + 3)/4 -movzx ecx, ax -mov esi, RelocBase + Buffer ; Source for copy, destination is in edi - -call CopyData32 ; Do protected-mode copy - -popf -je ReadLoop ; Still data left, so read next chunk - -mov esi, Extended ; Source for copy @ 1 Meg -mov ecx, edi ; Make count in dwords -sub ecx, esi -add ecx, 3 -shr ecx, 2 -mov edi, KernelBase ; Destination copy - -call CopyData32 ; Move code into conventional memory -jmp RunKernel - -LoadRamdisk: - -; Here we are loading from C: drive. Use protected mode to directly access -; the virtual disk sectors in extended memory and copy to `KernelBase'. -; This way we avoid using DOS file I/O calls, except for an `open' earlier -; which tells us the file exists. - -; Copy C: "bootsector" to buffer and save the BIOS parameter block - -mov esi, Extended -mov edi, RelocBase + Buffer ; Must be a 32-but address... -mov ecx, 80h -call CopyData32 - -mov si, Buffer + OffsetBPB -mov di, SavBPB -mov cx, EndBPB - SavBPB -repne -movsb - -; Calculate FAT, root dir, and data start addresses for the ramdisk - -xor eax, eax -mov ebx, eax -mov ecx, ebx - -mov ax, [ResSec] - -mov bl, [NumFAT] -imul bx, [SecFAT] - -mov cx, [NRoot] -shr cx, 4 ; 10h directory entries per sector - -add bx, ax -add cx, bx - -mov dx, [BpSect] -imul ax, dx -imul bx, dx -imul cx, dx - -add eax, Extended -add ebx, Extended -add ecx, Extended - -mov [BegFAT], eax -mov [BegRoot], ebx -mov [BegData], ecx - -; Convert the saved filename to format used in directory entry. Assume -; there's a `.' in it. Hopefully this won't haunt us later... - -mov di, FName ; Find the `.' -mov al, '.' -mov cx, 12 -repne -scasb - -mov bx, di ; di points to filename extension - -mov di, DirName -mov si, FName -mov cx, bx ; Make count -sub cx, si -dec cx -repne ; Copy initial part of filename -movsb - -mov di, bx ; Find the terminating zero -xor al,al -mov cx, 4 -repne -scasb - -mov cx, di ; Make count -sub cx, bx -dec cx -mov si, bx -mov di, DirName + 8 -repne ; Copy filename extension -movsb - -mov si, DirName ; Convert the stupid thing to upper case -mov di, si -mov cx, 11 - -Cvt2Upper: - -lodsb -cmp al, 'a' -jb NotLow -cmp al, 'z' -ja NotLow -xor al, 20h - -NotLow: - -stosb -loop Cvt2Upper - -; Now load in the root directory (temporarily) to find the first cluster -; of our file. Use KernelSeg:KernelAddr as temporary storage. - -mov esi, [BegRoot] -mov edi, KernelBase -xor ecx, ecx -mov cx, [NRoot] -shl cx, 3 ; Each root entry is 8 dwords -call CopyData32 - -mov dx, [NRoot] ; Max # of dir entries - -mov cx, KernelSeg ; Setup segment selector for comparison -mov es, cx -mov di, KernelAddr - -FindEntry: - -mov cx, 11 -mov si, DirName -push di -rep cmpsb -pop di -je GotEntry -add di, 20h ; Point to next dir entry -dec dx -jnz FindEntry - -int 3h ; Should never get here... - -GotEntry: - -mov eax, KernelBase ; Setup initial address for copy -mov [CurrDst], eax - -add di, 32 - 6 ; Load first cluster number -mov ax, [es:di] -mov cx, ds ; Fix `es' selector just in case -mov es, cx - -LoadKernel: - -call LoadCluster ; Load cluster `ax' to [CurrDst], update [CurrDst] - -call NextCluster ; Get next cluster number in ax - -cmp ax, 0FF8h ; Repeat until EOF -jb LoadKernel - -RunKernel: - -mov ax, KernelSeg ; Setup data segment and transfer control -mov ds, ax - -jmp KernelSeg:KernelAddr ; Huzzah!! - - -; Load cluster `ax' to [CurrDst], update [CurrDst] - -LoadCluster: - -push ax -sub ax, 2 ; Cluster numbers start at 2 -movzx eax, ax - -xor ecx, ecx ; Calculate bytes in a cluster -mov cl, [SpClst] -imul cx, [BpSect] - -imul eax, ecx -add eax, [BegData] ; Start of cluster - -shr ecx, 2 ; Cluster size in dwords -mov esi, eax ; Copy source -mov edi, [CurrDst] ; Copy destination -call CopyData32 - -mov [CurrDst], edi ; Update dest -pop ax ; Restore cluster number - -ret - -; Search FAT (FAT12 format) for next cluster in file after `ax'. - -NextCluster: - -movzx ecx, ax ; Calculate offset into FAT -shr ax, 1 -pushf -add cx, ax - -mov esi, [BegFAT] ; Copy word containing next cluster to buffer -add esi, ecx -mov edi, RelocBase + Buffer -xor ecx, ecx -inc ecx -call CopyData32 - -mov ax, [Buffer] ; Handle odd/even cluster numbers -popf -jnc EvenCluster -shr ax, 4 - -EvenCluster: - -and ax, 0FFFh -ret - -; Enable the A20 line for accesses to extended memory. - -EnableA20: - in al,92h - or al,2 - jmp short $+2 - jmp short $+2 - jmp short $+2 - out 92h,al - ret - -; The CopyData32 routine copies ecx dwords from esi to edi. Both esi -; and edi hold 32-bit values. CopyData32 runs in 32-bit protected mode. - -CopyData32: - cli - - call EnableA20 ; Put here in case file I/O screws with this - ; or with the GDTR - - lgdt [GDTStart] ; Initialize GDTR for 32-bit protected mode - - mov eax, cr0 - or al, 1 - mov cr0, eax ;go to real flat mode - -; LED_GRN -; PSW_WAIT - - jmp dword 8h : RelocBase+ProtJmp -[bits 32] -ProtJmp: -; LED_YEL -; PSW_WAIT - - mov ax, 10h - mov ds, ax - mov es, ax - mov ss, ax - - rep movsd ;copy the sector to where it should be - - mov ax, 20h - mov ds, ax - mov es, ax - mov ss, ax - -; LED_RED -; PSW_WAIT - - jmp 18h : RealJmp1 ;use code segment with 64K limit -[bits 16] -RealJmp1: -; LED_OFF -; PSW_WAIT - - mov eax, cr0 ;back to real segmented mode - and eax, 0fffffffeh - mov cr0, eax - - jmp RelocSeg : RealJmp2 -RealJmp2: -; LED_GRN -; PSW_WAIT - - mov ax, cs - mov es, ax - mov ds, ax - mov ss, ax - - sti -ret - -; Storage for a Dos 3+ BIOS Parameter Block (for the C: ramdisk) - -SavBPB: - -BpSect dw 0h ; Bytes per sector, always 512 -SpClst db 0h ; Sectors per cluster -ResSec dw 0h ; Num of reserved sectors -NumFAT db 0h ; Num of FATs -NRoot dw 0h ; Num of root directory entries -TotSec dw 0h ; Total sectors -Media db 0h ; Media descriptor byte -SecFAT dw 0h ; Sectors per FAT - -EndBPB: - -CurrDst dd 0h ; Current destination address for copying RTEMS exec - -; Important (32-bit) address for the C: ramdisk - -BegFAT dd 0h ; Start of the FAT -BegRoot dd 0h ; Start of root directory -BegData dd 0h ; Start of data clusters - -DDrive db 0h ; Default drive: 0h = A:, 2h = C: - -DirName times 11 db 32 ; Room for 8.3 directory entry name - -FName times 13 db 0 ; Room for a 12 character null-terminated string -FHndl dw 0000h - -Greet db "RTEMS DOS Loader (c) 1999 Tony R. Ambardar",13,10,"$" -Button db "Button pressed -- Aborting.",13,10,"$" -FError db "Missing or incorrect file name.",13,10,"$" -RError db "Error opening or reading file.",13,10,"$" - -; Global Descriptor Table used for protectd mode. -; Store the GDTR in the first null GDT entry - -GDTStart: - -dw GDTEnd - GDTStart - 1 -dd RelocBase + GDTStart -dw 0 - -; base=0h, limit=4Gb, present, code, exec/read, conform, 32-bit - -dw 0ffffh ;seg. lim. [15:0] -dw 0 ;base[15:0] -db 0 ;base[23:16] -db 9eh ;p=1,dpl=0,s=1 ; code: execute/read, conforming -db 0cfh ;c: gran=4K, D/B=1(32-bit) ; f: seg. lim. [19:16] -db 0 ;base[31:24] - -; base=0h, limit=4Gb, present, data, read/write exp. up, 32-bit SP - -dw 0ffffh ;seg. lim. [15:0] -dw 0 ;base[15:0] -db 0 ;base[23:16] -db 92h ;p=1,dpl=0,s=1 ; data: read/write expand-up -db 0cfh ;c: gran=4K, D/B=1(32-bit) ; f: seg. lim. [19:16] -db 0 ;base[31:24] - -; base=0h, limit=ffffh, present, code, exec/read, conform, 16-bit -; NOTE: this descriptor is used to change back to real mode. - -dw 0ffffh ;seg. lim. [15:0] -dw Reloc15 ;base[15:0] -db Reloc23 ;base[23:16] -db 9eh ;p=1,dpl=0,s=1 ; code: execute/read, conforming -db 000h ;4: gran=1 byte, D/B=0(16-bit) ; 0: seg. lim. [19:16] -db 0 ;base[31:24] - -; base=0h, limit=ffffh, present, data, read/write exp. up, 16-bit SP -; NOTE: this descriptor is used to change back to real mode. - -dw 0ffffh ;seg. lim. [15:0] -dw Reloc15 ;base[15:0] -db Reloc23 ;base[23:16] -db 92h ;p=1,dpl=0,s=1 ; data: read/write expand-up -db 000h ;0: gran=1 byte, D/B=0(16-bit) ; 0: seg. lim. [19:16] -db 0 ;base[31:24] - -GDTEnd: - -CodeEnd: ; end-of-code marker for copy |