; ihex - bootsector that reads intel hex from the keyboard %define base (0x10000 - 0x400) org base ; relocate to end of memory reloc: ; set up src addr xor ax, ax mov ds, ax mov si, 0x7C00 ; calculate target segment mov ax, [0x413] mov cl, 6 shl ax, cl sub ax, 0x1000 mov es, ax mov di, base ; set up dst addr mov ss, ax mov sp, di ; relocate mov cx, 0x100 rep movsw ; set DS mov ds, ax ; jump relocated push ds mov ax, main push ax retf ; AL -> display putc: mov ah, 0x0e xor bx, bx int 0x10 ret ; read a line read: mov si, line .loop: xor ax, ax int 0x16 cmp al, 0x08 je .bs cmp al, 0x0A je .cr cmp al, 0x0D je .cr cmp ax, 0x4D00 je .r test al, al jz .loop cmp al, 0x60 jc .l01 sub al, 0x20 .l01: mov [si], al .l02: inc si call putc jmp .loop .r: mov al, [si] jmp .l02 .bs: dec si push ax call putc mov al, 0x20 call putc pop ax call putc jmp .loop .cr: mov cx, line xchg cx, si sub cx, si jmp nl ; read 2 hex chars from line into al ; BX is byte number getb: add bx, bx lea si, [line+1+bx] mov ax, [si] call .a2b xchg ah, al call .a2b test ax, 0xF0F0 jnz err push cx mov cl, 4 shl al, cl shr ax, cl pop cx .ret: ret .err: xor ax, ax stc ret .a2b: sub al, 0x30 cmp al, 0x10 jc .ret sub al, 7 ret ; same like getb, except reads a full word getw: push bx call getb mov dl, al pop bx inc bx call getb mov ah, dl ret nl: mov al, 0x0A call putc mov al, 0x0D jmp putc main: mov sp, base ; reset stack call read cmp byte [line], ':' jmp hexcmd err: mov cx, si sub cx, line jz .l01 cmp cx, 80 jnc .l01 mov al, ' ' .l02: call putc loop .l02 .l01: mov al, '^' call putc mov al, 7 call putc call nl jmp main hexcmd: sub cx, 11 jc err shr cx, 1 xor bx, bx call getb ; line not long enough for size field cmp cl, al jc err ; calculate checksum add cl, 5 xor dx, dx .loop: push bx call getb pop bx add dl, al inc bx add dl, al loop .loop jnz err ; get record type mov bx, 3 call getb cmp al, 0 je cmd0 cmp al, 1 je cmd1 cmp al, 2 je cmd2 cmp al, 3 je cmd3 jmp err ; ihex command 0: data cmd0: les di, [addr] mov bx, 0 push bx call getb pop bx mov cx, ax add bx, 4 .loop: push bx call getb pop bx inc bx stosb loop .loop mov [addr], di jmp main ; ihex command 1: eof / exec cmd1: push word [exec+2] push word [exec] push es pop ds retf ; ihex command 2: set segment cmd2: mov bx, 4 call getw mov [addr], ax jmp main ; ihex command 3: set start address cmd3: ; copy CS mov bx, 4 call getw mov [exec+2], ax ; copy IP mov bx, 6 call getw mov [exec], ax jmp main hlt: hlt jmp hlt addr: dw 0, 0x100 exec: dw 0, 0x100 times 510-($-$$) db 0x00 db 0x55,0xaa section .bss line: resb 80