| /* |
| * hmloadstart.S -- A DOS utility for loading a file into high memory. |
| * Copyright (C) 2006 Tinybit(tinybit@tom.com) |
| * Copyright (C) 2006 John Cobb (Queen Mary, University of London) |
| * |
| * 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 |
| * (at your option) 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. |
| */ |
| |
| /* |
| * This program is used to generate the hmload.com file. |
| * |
| * Use the following shell command to generate the file: |
| * |
| * cp hmloadstart hmload.com |
| * |
| */ |
| |
| /* John Cobb's Note: |
| * It takes two parameters -f filename -a address |
| * Address is in megabytes. It assumes that himem.sys |
| * or equivalent XMS provider is running. |
| */ |
| |
| /* Use the following command to compile and build: |
| * |
| * gcc -o hmloadstart.exec -nostdlib -I. -I.. -I../stage1 -Wl,-N -Wl,-s hmloadstart.S |
| * |
| */ |
| |
| #define ABS(x) (x - _start + 0x100) |
| |
| .text |
| .globl _start |
| |
| _start: |
| |
| /* this is real mode dos code */ |
| |
| .code16 |
| |
| |
| //org 100h |
| //section .text |
| //start: |
| xorw %ax, %ax |
| movw %ax, ABS(hand) #; not strictly necessary but ensure handle zero |
| movw %ax, ABS(file) |
| movw %ax, ABS(addr) |
| movb $0x09, %ah |
| movw $ABS(hallo), %dx |
| int $0x21 #; output first part of message reflecting back the parameters |
| xorw %cx, %cx |
| movb 0x80, %cl |
| movw $0x81, %si |
| movw $ABS(buffer), %di |
| cld |
| repz movsb |
| // jcxz .srt2 |
| //.srt1: |
| // movb (%si), %ah #; copy the parameter block to a convenient place |
| // movb %ah, (%di) |
| // incw %si |
| // incw %di |
| // loop .srt1 |
| //.srt2: |
| movw $0x0A0D, %ax |
| stosw |
| movb $0x24, %al #; '$' |
| stosb |
| movb $0x09, %ah |
| movw $ABS(buffer), %dx |
| int $0x21 #; echo the parameters |
| xorw %cx, %cx |
| movb 0x80, %cl |
| movw $0x81, %si |
| movw $ABS(errparam), %dx |
| jcxz paramerr |
| jmp parameters |
| paramerr: |
| movb $0x09, %ah |
| int $0x21 |
| movw $ABS(use), %dx |
| movb $0x09, %ah |
| int $0x21 |
| movw $ABS(func), %dx |
| jmp failexit |
| nohyphen: |
| movw $ABS(needhyphen), %dx |
| jmp paramerr |
| noparamletter: |
| movw $ABS(misparam), %dx |
| notparam: |
| movb %ah, ABS(notknown) |
| movw $ABS(notknown), %dx |
| jmp paramerr |
| novalue: |
| movb %ah, ABS(misvalue+11) |
| movw $ABS(misvalue), %dx |
| jmp paramerr |
| nofile: |
| movw $ABS(misfile), %dx |
| jmp paramerr |
| noaddr: |
| movw $ABS(misaddr), %dx |
| jmp paramerr |
| |
| parameters: |
| .spc1: |
| movb (%si), %ah #; skip spaces |
| cmpb $0x20, %ah #; space |
| jnz .spc2 |
| incw %si |
| loop .spc1 |
| jcxz endparams |
| .spc2: |
| cmpb $'-', %ah |
| jne nohyphen |
| incw %si |
| decw %cx |
| jcxz noparamletter |
| movb (%si), %ah |
| incw %si |
| decw %cx |
| jcxz novalue |
| .spc3: |
| movb (%si), %al #; skip spaces after parameter letter |
| cmpb $0x20, %al #; ' ' |
| jnz .spc4 |
| incw %si |
| loop .spc3 |
| jcxz novalue |
| .spc4: |
| cmpb $'f', %ah |
| je isfile |
| cmpb $'a', %ah |
| je isaddr |
| jmp notparam |
| isfile: |
| movw %si, ABS(file) |
| jmp nextparam |
| isaddr: |
| movw %si, ABS(addr) |
| nextparam: |
| .nsp1: |
| movb (%si), %ah |
| cmpb $0x20, %ah #; ' ' |
| je .nsp2 |
| incw %si |
| loop .nsp1 |
| .nsp2: |
| movb $0, %ah |
| movb %ah, (%si) |
| incw %si |
| jcxz endparams |
| decw %cx |
| jcxz endparams |
| jmp parameters |
| #; check we got everything |
| endparams: |
| movw ABS(addr), %cx |
| jcxz noaddr |
| movw ABS(file), %cx |
| jcxz nofile |
| xorl %eax, %eax |
| movl $10, %ecx |
| movw ABS(addr), %si #; address of addressvalue |
| xorl %ebx, %ebx |
| .dec1: |
| movb (%si), %bl |
| subb $'0', %bl |
| jl .dec2 |
| cmpb $10, %bl |
| jge .dec2 |
| mull %ecx |
| addl %ebx, %eax |
| incw %si |
| jmp .dec1 |
| .dec2: |
| shll $20, %eax #; shift to megabytes |
| movl %eax, ABS(address) |
| movw ABS(file), %dx |
| xorw %cx, %cx |
| movw $0x3d00, %ax #; open the file |
| int $0x21 |
| jnc opened |
| movw $ABS(erropen), %dx |
| movw ABS(file), %si |
| jmp err |
| opened: |
| movw %ax, ABS(hand) |
| movw $ABS(act1), %dx |
| movb $0x09, %ah |
| int $0x21 |
| movw ABS(file), %si |
| xorw %cx, %cx |
| .del1: |
| movb (%si), %cl |
| jcxz .del2 |
| incw %si |
| jmp .del1 |
| .del2: |
| movb $'$', (%si) |
| movw ABS(file), %dx |
| movb $0x09, %ah |
| int $0x21 |
| movw $ABS(act2), %dx |
| movb $0x09, %ah |
| int $0x21 |
| movl ABS(address), %eax |
| movw $8, %cx |
| movw $ABS(buffer), %di |
| .hex1: |
| xorl %edx, %edx |
| |
| //shld edx,eax,4 #; mov highest 4 bits of EAX to DL |
| //shll $4, %eax |
| roll $4, %eax |
| movb %al, %dl |
| andb $0xf0, %al |
| andb $0x0f, %dl |
| |
| movw $ABS(hexdigits), %si |
| addw %dx, %si |
| movb (%si), %dl |
| movb %dl, (%di) |
| incw %di |
| loop .hex1 |
| movb $13, (%di) |
| incw %di |
| movb $10, (%di) |
| incw %di |
| movb $'$', (%di) |
| movw $ABS(buffer), %dx |
| movb $0x09, %ah |
| int $0x21 |
| |
| #; start the load |
| movl ABS(address), %eax |
| #; mov eax,128 |
| #; shl eax,20 |
| copyin: |
| pushl %eax |
| movb $0x3f, %ah #; read file |
| movw ABS(hand), %bx |
| movw $4096, %cx |
| movw $ABS(buffer), %dx |
| int $0x21 |
| jc eof |
| movw %ax, %cx |
| jcxz eof |
| shrw $2, %cx |
| popl %eax |
| movw $ABS(buffer), %bx |
| xorw %dx, %dx |
| movw %dx, %fs #; FS = 0 |
| copyloop: |
| movl (%bx), %edx |
| addr32 fs movl %edx, (%eax) |
| addw $4, %bx |
| addl $4, %eax |
| loop copyloop |
| jmp copyin |
| eof: |
| popl %eax |
| #; pop cx |
| //exitc: |
| movw ABS(hand), %bx |
| movb $0x3e, %ah #; close file |
| int $0x21 |
| movw $0x4c00, %ax #; return success |
| int $0x21 |
| |
| err: |
| movw $256, %cx |
| movw $ABS(buffer), %di |
| .str1: |
| movb (%si), %ah |
| orb %ah, %ah |
| jz .str2 |
| movb %ah, (%di) |
| incw %di |
| incw %si |
| loop .str1 |
| .str2: |
| movb $13, (%di) |
| incw %di |
| movb $10, (%di) |
| incw %di |
| movb $'$', (%di) |
| movb $0x09, %ah |
| int $0x21 |
| movw $ABS(buffer), %dx |
| failexit: |
| movb $0x09, %ah |
| int $0x21 |
| movw ABS(hand), %bx |
| jz .exit |
| movb $0x3e, %ah #; close file |
| int $0x21 |
| .exit: |
| movw $0x4c01, %ax #; return failure |
| int $0x21 |
| |
| //section .data |
| |
| hallo: |
| .ascii "Parameters: $" |
| //; file: db 'C:\temp\mdump',0 |
| erropen: |
| .ascii "Could not open file:$" |
| errparam: |
| .ascii "No Parameters!$" |
| use: |
| .ascii "\tUse:\t-f filename -a address (in megabytes)\r\n$" |
| func: |
| .ascii "Loads file to address\r\n$" |
| needhyphen: |
| .ascii " parameters must start with -\r\n$" |
| notknown: |
| .ascii "x is not a recognised parameter\r\n$" |
| misparam: |
| .ascii "Parameter type missing after -\r\n$" |
| misvalue: |
| .ascii "Parameter -x has no value!\r\n$" |
| misfile: |
| .ascii "-f (filename) parameter missing\r\n$" |
| misaddr: |
| .ascii "-a (address) parameter missing\r\n$" |
| act1: |
| .ascii "Loading file: $" |
| act2: |
| .ascii " to 0x$" |
| hexdigits: |
| .ascii "0123456789ABCDEF" |
| |
| .align 2 |
| file: |
| .word 0 |
| addr: |
| .word 0 |
| hand: |
| .word 0 |
| |
| //section .bss |
| |
| .align 4 |
| address: |
| .long 0 |
| |
| .align 16 |
| buffer: //.space 4096 |
| |