220 lines
2.7 KiB
NASM
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
|