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 default: kernel.rom
kernel.rom: kernel/*.asm 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 boot/%.bin: boot/%.asm
nasm -s -o $@ -I lib $< nasm -s -o $@ -I lib $<

View File

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

View File

@ -1,8 +1,17 @@
cpu 8086 cpu 8086
org 0x0000 org 0x0000
db 0x55, 0xAA, 0x00 db 0x55, 0xAA
optrom_length:
db 0x00
jmp optrom_init jmp optrom_init
str_vendor:
db "Nero", 0
align 16
str_product:
db "Nero DOS", 0
times (0x1A - ($-$$)) db 0 times (0x1A - ($-$$)) db 0
dw pnp dw pnp
@ -15,8 +24,8 @@ pnp:
db 0 db 0
db 0 ; checksum (filled by fix-rom) db 0 ; checksum (filled by fix-rom)
dd 0 ; device identifier dd 0 ; device identifier
dw .vendor ; manufacturer string dw str_vendor ; manufacturer string
dw .product ; product name string dw str_product ; product name string
db 0,0,0 ; device type string db 0,0,0 ; device type string
db 0x20 ; device indicator, bit for "read cacheable" set db 0x20 ; device indicator, bit for "read cacheable" set
dw 0 ; boot connection vector dw 0 ; boot connection vector
@ -24,15 +33,9 @@ pnp:
dw start ; bootstrap entry point dw start ; bootstrap entry point
dw 0 ; reserved dw 0 ; reserved
dw 0 dw 0
.vendor:
db "Nero", 0
.product:
db "2B", 0
align 16 align 16
optrom_init: optrom_init:
push di
push es
xor ax, ax xor ax, ax
mov es, ax mov es, ax
mov di, 0x0060 ; vector (0x18 * 4 bytes) mov di, 0x0060 ; vector (0x18 * 4 bytes)
@ -40,74 +43,71 @@ optrom_init:
stosw stosw
mov ax, cs mov ax, cs
stosw stosw
pop es
pop di
retf retf
start: putc:
call intr_init
sti
mov si, 0x0000
mov ds, si
.loop:
push bx push bx
mov dx, 0x0000 push cx
mov ah, 0x02 mov ah, 0x0e
mov bx, 0x0000 mov bx, 0x0000
int 0x10 int 0x10
pop cx
pop bx 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 start:
int 0x21 mov ax, cs
mov ds, ax
cmp al, 0x30 call announce
jne .notup
sub bx, 0x0100 ; clear memory until 0x01000
.notup: xor ax, ax
cmp al, 0x31 mov es, ax
jne .notdown mov di, 0x500
add bx, 0x0100 mov cx, 0xB00
.notdown: rep stosb
jmp .loop
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: .halt:
hlt hlt
jmp .halt jmp .halt
dump: %include "ramdisk.inc"
mov si, bx %include "printf.inc"
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 "intr.asm" %include "intr.asm"
%include "debug.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