rdos/boot/ihex.asm

220 lines
2.7 KiB
NASM

; 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