Implement ramdisk i/o, advance kernel printf

This commit is contained in:
Nero 2019-04-28 22:01:30 +00:00
parent acef5262eb
commit bc6a49c54d
5 changed files with 231 additions and 65 deletions

View File

@ -20,7 +20,7 @@ endif
default: kernel.rom
kernel.rom: kernel/*.asm
nasm -s -o $@ -I kernel kernel/main.asm && scripts/fix-rom.sh $@
nasm -s -o $@ -I lib -I kernel kernel/main.asm && scripts/fix-rom.sh $@
boot/%.bin: boot/%.asm
nasm -s -o $@ -I lib $<

View File

@ -15,5 +15,5 @@ isr_getc_echo:
isr_putc:
mov al, dl
call kputc
call putc
iret

View File

@ -1,8 +1,17 @@
cpu 8086
org 0x0000
db 0x55, 0xAA, 0x00
db 0x55, 0xAA
optrom_length:
db 0x00
jmp optrom_init
str_vendor:
db "Nero", 0
align 16
str_product:
db "Nero DOS", 0
times (0x1A - ($-$$)) db 0
dw pnp
@ -15,8 +24,8 @@ pnp:
db 0
db 0 ; checksum (filled by fix-rom)
dd 0 ; device identifier
dw .vendor ; manufacturer string
dw .product ; product name string
dw str_vendor ; manufacturer string
dw str_product ; product name string
db 0,0,0 ; device type string
db 0x20 ; device indicator, bit for "read cacheable" set
dw 0 ; boot connection vector
@ -24,15 +33,9 @@ pnp:
dw start ; bootstrap entry point
dw 0 ; reserved
dw 0
.vendor:
db "Nero", 0
.product:
db "2B", 0
align 16
optrom_init:
push di
push es
xor ax, ax
mov es, ax
mov di, 0x0060 ; vector (0x18 * 4 bytes)
@ -40,74 +43,71 @@ optrom_init:
stosw
mov ax, cs
stosw
pop es
pop di
retf
start:
call intr_init
sti
mov si, 0x0000
mov ds, si
.loop:
putc:
push bx
mov dx, 0x0000
mov ah, 0x02
push cx
mov ah, 0x0e
mov bx, 0x0000
int 0x10
pop cx
pop bx
ret
call dump
announce:
push cs
mov ax, str_product
push ax
call printf
db "%S (CS=%Xh)", 0x0A, 0x0D, 0x00
add sp, 4
ret
mov ah, 0x01
int 0x21
start:
mov ax, cs
mov ds, ax
cmp al, 0x30
jne .notup
sub bx, 0x0100
.notup:
cmp al, 0x31
jne .notdown
add bx, 0x0100
.notdown:
jmp .loop
call announce
; clear memory until 0x01000
xor ax, ax
mov es, ax
mov di, 0x500
mov cx, 0xB00
rep stosb
call intr_init
sti
sub sp, 0x10
mov si, sp
mov word [ss:si+0x00], 0
mov word [ss:si+0x02], 1
mov word [ss:si+0x04], 0
mov word [ss:si+0x06], 0x2000
mov word [ss:si+0x08], 0x07fc
mov word [ss:si+0x0A], 0
mov word [ss:si+0x0C], 0
mov word [ss:si+0x0E], 0
mov ah, 0x42
push ss
pop ds
call ramdisk_io
push ax
call printf
db "AX=%X", 0x0A, 0x0D, 0x00
pop ax
add sp, 0x10
.halt:
hlt
jmp .halt
dump:
mov si, bx
mov cx, 0x10
.nextline:
mov ax, si
call kprint16
mov al, 0x3A
call kputc
mov al, 0x20
call kputc
push cx
mov cx, 0x0020
.bytes:
lodsb
call kprint8
loop .bytes
pop cx
mov al,0x20
call kputc
mov al,0x0A
call kputc
mov al,0x0D
call kputc
loop .nextline
ret
%include "ramdisk.inc"
%include "printf.inc"
%include "intr.asm"
%include "debug.asm"

86
kernel/ramdisk.inc Normal file
View File

@ -0,0 +1,86 @@
; Spanning whole conventional memory
; Sector size 0x200 (512 bytes)
; Start address 0x00600, 3 hidden sectors for IVT and BDA
; Kernel .data may be in reserved sectors
; Ramdisk I/O, similar invocation to BIOS int 13h
; in AH 42=read, 43=write
; in DS:SI location of disk address packet
; out AH error code or 00 (also in CF)
ramdisk_io:
; backup original values
push cx
push dx
push si
push di
push ds
push es
; 3 most significant addr bytes must be all zero
test WORD [ds:si+0x0E], 0xFFFF
jnz .invaddr
test WORD [ds:si+0x0C], 0xFFFF
jnz .invaddr
test WORD [ds:si+0x0A], 0xFFFF
jnz .invaddr
; calculate segment register for ramdisk access
mov dx, [ds:si+0x08]
cmp dx, 0x07fd ; 0x800 sectors in adress space, 3 hidden
jge .invaddr
mov cl, 0x05 ; 2^5 = 32 paragraphs per sector
sal dx, cl
add dx, 0x0060 ; 3 hidden sectors
xor cx, cx
push cx ; offset = 0
push dx ; segment
; store addresses for buffer access
mov dx, [ds:si+0x04]
push dx ; offset
mov dx, [ds:si+0x06]
push dx ; segment
; setup transfer length (in words) in CX
mov dx, [ds:si+0x02] ; sector count
mov cx, 0x0008 ; 2^8 = 256 words per sector
sal dx, cl
xchg dx, cx
cmp ah, 0x42
je .read
cmp ah, 0x43
je .write
sub sp, 8 ; remove src & dst pointers from stack
.invval:
mov ah, 0x01
stc
jmp .ret
.invaddr: ; out of bounds
mov ah, 0x04
stc
jmp .ret
.read:
pop es ; ES:DI buffer
pop di
pop ds ; DS:SI ramdisk data
pop si
rep movsw
clc
jmp .ret
.write:
pop ds ; DS:SI buffer
pop si
pop es ; ES:DI ramdisk data
pop di
rep movsw
clc
.ret:
; restore backupped values
pop es
pop ds
pop di
pop si
pop dx
pop cx
ret

80
lib/printf.inc Normal file
View File

@ -0,0 +1,80 @@
printf:
cld
pop si
push bp
mov bp, sp
.loop:
mov al, [cs:si]
inc si
cmp al, 0x00
je .end
cmp al, 0x25
je .handle_25h
.literal:
call putc
jmp .loop
.end:
pop bp
push si
ret
.handle_25h:
mov al, [cs:si]
inc si
cmp al, 0x25
je .literal
cmp al, 0x58 ; 'X'
je .printhex
cmp al, 0x55 ; 'U'
je .printdec
cmp al, 0x53 ; 'S'
je .printstr
mov al, 0x3F
jmp .literal
.printhex:
add bp, 2
mov ax, [bp]
mov bx, 0x0010
call print_number
jmp .loop
.printdec:
add bp, 2
mov ax, [bp]
mov bx, 0x000A
call print_number
jmp .loop
.printstr:
add bp, 2
mov ax, [bp]
call print_string
jmp .loop
print_number:
xor dx, dx
div bx ; ax = dx:ax / 10, dx = dx:ax % 10
and ax, ax
jz .print
push dx
call print_number
pop dx
.print:
mov al, dl
add al, 0x30
cmp al, 0x3A
jl .noadj
add al, 0x07
.noadj:
call putc
ret
print_string:
push si
mov si, ax
.loop:
lodsb
cmp al, 0x00
je .end
call putc
jmp .loop
.end:
pop si
ret