Split code up into directories for bs and com binaries

This commit is contained in:
Nero 2020-03-30 12:13:21 +00:00
parent 5a24ceb9b8
commit 955acdacba
9 changed files with 2 additions and 2 deletions

293
boot/fat.asm Normal file
View file

@ -0,0 +1,293 @@
; Bootsector for FAT12 filesystems
; Memory layout:
; 0000-03FF IVT
; 0400-0500 Bios data area
; 0501-0600 Stack for us
; 0600-0800 This code
org 0x0600
; 0800-0A00 Buffer for disk
buf: equ 0x0800
jmp near init
; current cluster number
cclus: dw 0
; sector number in cluster
csec: dw 0
times (0x0B - ($-$$)) db 0
; BIOS PARAMETER BLOCK
fdc: ; sector size
.ss: dw 0x200
; sectors per cluster
.sc: db 2
; reserved sector count
.rsc: dw 1
.fn: ; number of file allocation tables
db 2
.rde: ; number of root directory entries
dw 0x70
.ts: ; total number of sectors
dw 720
.mid: db 0xFD
.sf: dw 2
.spt: dw 9
.nos: dw 2
.po: dd 0
.lrgts: ; large sector count - relevant if .ts is 0
dd 0
; mformat keeps writing until here
; if we place init earlier, code gets overwritten
; this also marks the end for the BPB
times (62 - ($-$$)) nop
init: xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x0600
; Relocate and jump
mov di, sp
mov si, 0x7C00
mov cx, 0x0100
rep movsw
jmp 0:main
; Set adress for sector read/write
; Number is relative to current partition
; IN dx:ax sector number
seek: push ax
push dx
push ds
push cs
pop ds
; add partition offset (required for HDD)
add ax, [fdc.po]
adc dx, [fdc.po+2]
; ax:temp = (lba / spt)
; dx:sector = (lba % spt) + 1
div word [fdc.spt]
inc dx
; Sector number (bits 0-5) into CL
; This is blindly assumed to never exeed 63
mov byte [.cl], dl
; ax:cylinder = (tmp / heads)
; dx:head = (tmp % heads)
xor dx, dx
div word [fdc.nos]
; Cylinder number bit 0-7 into CH
mov byte [.ch], al
; Head number into DL
mov byte [.dh], dl
; Bits 8-9 of cylinder number into bits 6-7 of CL
and ah, 0x03
ror ah, 1
ror ah, 1
or byte [.cl], ah
pop ds
pop dx
pop ax
ret
.cl: db 0
.ch: db 0
.dl: db 0
.dh: db 0
; Read sector into ES:BX
; Sector number has been previously set with seek
read: push ax
push cx
push dx
; ah = int13 subfunction 2
; al = read 1 sector
mov ax, 0x0201
; load seek data into registers
mov cx, word [cs:seek.cl]
mov dx, word [cs:seek.dl]
int 0x13
int 3
pop dx
pop cx
pop ax
ret
; Get start sector of root dirrectory
; OUT ax sector number
dirsec: ; Multiply sectors per fat with number of fats
mov ax, [cs:fdc.sf]
mul byte [cs:fdc.fn]
; Add number of reserved sectors
add ax, [cs:fdc.rsc]
ret
; Get root directory length in sectors
; OUT cx sectors
dirlen: push ax
mov ax, [cs:fdc.rde]
mov cl, 4
shr ax, cl ; 32 bytes per entry
mov cx, ax
pop ax
ret
; Get first sector of data area
; OUT ax sector number
clusec: push cx
call dirsec
call dirlen
add ax, cx
pop cx
ret: ret
; Get total number of sectors
; OUT: dx:ax number of sectors
secnum: xor dx, dx
mov ax, [cs:fdc.ts]
test ax, ax
jnz ret
mov ax, [cs:fdc.lrgts]
mov dx, [cs:fdc.lrgts+2]
ret
; Get number of clusters
; OUT: ax number of clusters
; Cant overflow for FAT16 :P
clunum: push cx
push dx
call clusec
mov cx, ax
call secnum
sub ax, cx
sbb dx, 0
mov cl, byte [cs:fdc.sc]
xor ch, ch
div cx
pop dx
pop cx
ret
; Scan current buffer for matching file
; IN ds = cs
; es = cs
; OUT bx start cluster if file found
; trashed if no match
; carry is set if no file was found
scadir:
push cx
push si
mov si, buf
mov cx, 0x10
.loop: push cx
push si
mov bx, [si+0x1A]
mov di, .name
mov cx, 11
repe cmpsb
pop si
pop cx
je .found
add si, 0x20
loop .loop
stc
.found: pop si
pop cx
ret
.name: db "HELLO "
.ext: db "COM"
fopen:
push ax
push cx
push dx
push bx
push ds
push es
cmp word [cclus], 0
jne .err
xor ax, ax
mov ds, ax
mov es, ax
call dirsec
call dirlen
.loop: xor dx, dx
mov bx, buf
call seek
call read
call scadir
jnc .found
inc ax
loop .loop
.err: stc
jmp .ret
.found: mov [cclus], bx
mov word [csec], 0
.ret: pop es
pop ds
pop bx
pop dx
pop cx
pop ax
ret
fread: push ax
push cx
push dx
; abort if there is no file opened
cmp word [cs:cclus], 0
je .err
; get start sector for data area
call clusec
push ax
; get current cluster number
mov ax, [cs:cclus]
; clusters are 2-indexed
sub ax, 2
; multiply that with sectors per cluster
mov cl, [cs:fdc.sc]
xor ch, ch
mul word cx
; add current cluster offset, cluster start and current sector
pop cx
add cx, [cs:csec]
add ax, cx
adc dx, 0
; dx:ax now point to the sector that should be read next
call seek
call read
jc .err
inc word [cs:csec]
jmp .ret
.err: ; in case of error, trash current state
call fclose
stc
.ret: pop dx
pop cx
pop ax
ret
; Reset open file info
fclose: mov [cclus], bx
mov word [csec], 0
ret
main: mov [seek.dl], dl ; save drive number
call fopen
mov bx, 0x1100
call fread
mov ax, 0x0100
mov ds, ax
mov es, ax
call 0x100:0x100
.hlt: hlt
jmp .hlt
; Padding and signature
times (0x1FE - ($-$$)) db 0
dw 0xAA55

214
boot/fat32.asm Normal file
View file

@ -0,0 +1,214 @@
; Bootsector for FAT32 filesystems
org 0x0800
jmp short init
nop
; WORD reserved sector count
rsc: equ ( $$ + 0x00E )
; BYTE number of sectors per cluster
sc: equ ( $$ + 0x00D )
; BYTE number of FATs
fn: equ ( $$ + 0x010 )
; DWORD hidden sector count (partition offset)
po: equ ( $$ + 0x01C )
; DWORD sectors per FAT
sf: equ ( $$ + 0x024 )
; BYTE drive number (we set it from dl)
dn: equ ( $$ + 0x040 )
; Area for BPB
times (0x5A - ($-$$)) db 0
init: xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
mov si, sp
mov di, 0x0800
mov cx, 0x0100
rep movsw
jmp 0x0:main
msg: pop si
mloop: lodsb
test al, al
jz mend
mov ah, 0x0e
mov bx, 7
int 0x10
jmp mloop
mend: push si
ret
err: call msg
db "DISKERR", 0x0A, 0x0D, 0
hlt: hlt
jmp hlt
; Requires DWORD ptr and QWORD sector on the stack
read: pop bp
push cx
mov ax, 0x10
push ax
mov ah, 0x42
mov dl, 0x80
mov si, sp
mov di, [si+4]
int 0x13
jc err
pop ax
pop cx
push bp
ret
; Advances [clus] to next FAT entry
next: ; push upper two words for sector num
xor ax, ax
push ax
push ax
; get current cluster number
mov ax, [clus]
mov dx, [clus+2]
; shift 2 left for dword-sized FAT entries
; shift 9 right for sector size
mov cl, 7
shftl: clc
rcr dx, 1
rcr ax, 1
loop shftl
; add reserved sector count
add ax, word [rsc]
adc dx, 0
; push lower dword of sector number
push dx
push ax
; push ptr to target buffer
push cs
mov ax, buf
push ax
mov cx, 1
call read
; get lower part of cluster number
mov si, [clus]
; multiply with 4
sal si, 1
sal si, 1
; make sure its within sector range
and si, 0x1FF
add si, buf
mov di, clus
; copy dword from FAT to [clus]
movsw
movsw
; 1x QWORD, 1x DWORD = 12 bytes
add sp, 12
ret
; reads current cluster into [dest]
readc: ; load cluster number
mov ax, [clus]
mov dx, [clus+2]
; subtract the two dummy entries from FAT start
sub ax, 2
sbb dx, 0
; convert cluster number to sector number
; this is some cheapo multiplication with 2^n
mov ch, [sc]
l02: shr cl, 1
jz l02e
clc
rcl dx, 1
rcl ax, 1
jmp l02
l02e:
; dx:ax is now sector num in data area
; get number of FATs
xor ch, ch
mov cl, byte [fn]
; add their sizes up
floop: add ax, [sf]
adc dx, [sf+2]
loop floop
; add reserved sector count
add ax, [rsc]
add dx, 0
; push sector num QWORD
xor cx, cx
push cx
push cx
push dx
push ax
; push target buffer DWORD
; dest gives the segment register
mov ax, [dest]
push ax
push cx
; push sector count
; always an full cluster
mov cx, [sc]
xor ch, ch
call read
cmp cl, [sc]
jne err
xchg bx, cx
mov cl, 5
sal bx, cl
add [dest], bx
add sp, 12
ret
loadf: call readc
call next
cmp word [clus+2], 0x0FFF
jne loadf
ret
main: call loadf
mov ax, [dest]
int 3
xor ah,ah
int 0x16
int 0x19
jmp hlt
; the packing is so that it looks nice in a hexdump
times (0x1E0 - ($-$$)) db 0
; directory the kernel is in
tdir: db "RDOS ", 0
; current cluster number
clus: dd 2
times (0x1F0 - ($-$$)) db 0
; filename for the kernel
tfile: db "KERNEL BS ", 0
; segment register for data
dest: dw 0x07c0
; Padding and signature
times (0x1FE - ($-$$)) db 0
dw 0xAA55
buf:

14
boot/kernel.asm Normal file
View file

@ -0,0 +1,14 @@
org 0x7C00
main: mov si, msg
mov ah, 0x0e
xor bx, bx
loop: lodsb
test al, al
jz end
int 0x10
jmp loop
end: hlt
jmp end
msg: db "rdos kernel stub", 0x0A, 0x0D, 0

136
boot/mbr.asm Normal file
View file

@ -0,0 +1,136 @@
; Memory layout:
%define self 0x00600 ; 1 sector
%define prog 0x07C00 ; 1 sector
; FDC fields in VBR
%define spt (prog + 0x18)
%define nos (prog + 0x1A)
%define po (prog + 0x1C)
org self
cpu 8086
init:
cli
; Stack grows down from PSP + 64k
xor ax, ax
mov ss, ax
mov sp, ax
push dx
; Relocate from [prog] to [self]
mov ds, ax
mov es, ax
mov si, prog
mov di, self
mov cx, 0x100
rep movsw
jmp 0:main
main:
mov bp, 0x3335
mov si, part1
mov cx, 4
.loop:
test BYTE [si], 0x80
jnz loadpart
add si, 0x10
loop .loop
jmp error
loadpart:
; transfer starting address into DAP
push si
add si, 0x08
mov di, dap.blocknum
movsw
movsw
pop si
; load sector
push si
mov si, dap
mov bp, 0x3336
mov ah, 0x42
stc
int 0x13
jc error
pop si
cmp BYTE [si+4], 0x01
jne jump
adjust:
push dx
mov bp, 0x3337
mov ah, 0x08
stc
int 0x13
jc error
; update sectors per track
xor ax, ax
mov al, cl
mov [spt], ax
; update number of sides
xor ax, ax
mov al, dh
mov [nos], ax
; update partition offset
push si
add si, 0x08
mov di, po
movsw
movsw
pop si
pop dx
jump:
jmp 0:prog
error:
mov ax, bp
mov ah, 0x0e
mov bx, 7
int 0x10
mov al, 0x21
int 0x10
xor ax, ax
int 0x16
int 0x19
dap:
.size:
db 0
db 0
.count:
dw 1
.buffer:
dw prog
dw 0
.blocknum:
dq 0
times (0x1BE - ($-$$)) db 0
part1:
db 0x80
.chs_start:
db 0xFF, 0xFF, 0xFF
.type:
db 0x01
.chs_end:
db 0xFF, 0xFF, 0xFF
.begin:
dd 1
.end:
dd (FLOPPY * 2)
times (0x1FE - ($-$$)) db 0
dw 0xAA55

113
boot/pxeboot.asm Normal file
View file

@ -0,0 +1,113 @@
org BASE
main:
mov ax, [es:bx+0x0A]
mov [cs:pxejmp], ax
mov ax, [es:bx+0x0A+2]
mov [cs:pxejmp+2], ax
mov ax, cs
mov ds, ax
mov si, pxejmp
call dump
mov ax, cs
mov ds, ax
mov di, pxestat
mov bx, 0x0071
call UsePXEAPI
mov ax, cs
mov ds, ax
mov si, pxestat
call dump
call dump
hlt: hlt
jmp hlt
UsePXEAPI:
push ds
push di
push bx
int 3
call far [pxejmp]
int 3
add sp, 6
ret
pxejmp: dd 0
pxestat:
.Status dw 0
.PacketType dw 2
.BufferSize dw 0
.BufferOff dw 0
.BufferSeg dw 0
.BufferLimit dw 0
;tftp_open:
; .Status dw 0
; .SIP dd 0
; .GIP dd 0
; .Filename db "pxe.bs"
; times (128-6) db 0
; .Port dw 0
; .PacketSize dw 0
space:
mov al, 0x20
jmp putc
putbc:
cmp al, 0x80
jnc dot
cmp al, 0x20
jnc putc
dot:
mov al, '.'
putc:
push ax
push bx
mov ah, 0x0e
xor bx, bx
int 0x10
pop bx
pop ax
ret
dump: push cx
mov ax, ds
call print16
mov al, ':'
call putc
mov ax, si
call print16
call space
call space
mov cx, 0x08
push si
.hloop: lodsb
call print8
lodsb
call print8
call space
loop .hloop
pop si
call space
mov cx, 0x10
.aloop: lodsb
call putbc
loop .aloop
mov al, 0x0A
call putc
mov al, 0x0D
call putc
pop cx
ret
%include "print.asm"
%include "printf.asm"

90
boot/serial.asm Normal file
View file

@ -0,0 +1,90 @@
org 0x7c00
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
jmp 0:start
getc:
mov ah, 0x02
mov dx, 0x0000
int 0x14
test ah, 0x80
jnz getc
ret
putc:
mov ah, 0x01
mov dx, 0x0000
int 0x14
ret
init_port:
mov ah, 0x00
mov al, 0b11100011
mov dx, 0x0000
int 0x14
ret
dump:
mov si, 0x500
mov cx, di
sub cx, si
.loop:
lodsb
call print8
loop .loop
mov al, 0x0A
call putc
mov al, 0x0D
call putc
ret
line_reset:
cmp di, 0x500
je .reset
call line_process
.reset:
mov di, 0x500
xor bp, bp
jmp mainloop
line_process:
call dump
ret
start:
call init_port
mov di, 0x500
jmp line_reset
mainloop:
call getc
cmp al, ':'
je line_reset
cmp al, 0x20
jb line_reset
sub al, 0x30
cmp al, 9
jbe .noadjust
sub al, 7
.noadjust:
test bp, bp
jnz .secondnib
mov cl, 4
shl al, cl
mov [di], al
not bp
jmp mainloop
.secondnib:
or [di], al
inc di
not bp
jmp mainloop
%include "print.asm"
times 510-($-$$) db 0x00
db 0x55,0xaa

99
boot/vga11.asm Normal file
View file

@ -0,0 +1,99 @@
org 0x7C00
cols: equ 80
rows: equ 30
main:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor sp, sp
mov ah, 0x42
mov si, dap
int 0x13
mov ax, 0x0011
int 0x10
mov di, txtbuf
.loop:
call sync
xor ax, ax
int 0x16
stosb
jmp .loop
hlt:
hlt
jmp hlt
sync:
push ax
push si
push di
push es
mov si, txtbuf
mov ax, 0xA000
mov es, ax
mov di, 0
mov bx, font
mov cx, rows
.loop:
call charline
loop .loop
pop es
pop di
pop si
pop ax
ret
charline:
push bx
push cx
mov cx, 8
.loop:
call scanline
call scanline
inc bh
loop .loop
add si, cols
pop cx
pop bx
ret
scanline:
push si
push cx
mov cx, cols
.loop:
lodsb
mov bl, al
mov al, [bx]
stosb
loop .loop
pop cx
pop si
ret
dap:
db 0x10
db 1
dw 20
dw font, 0
dq 1
times (510 - ($-$$)) nop
dw 0xAA55
font:
incbin "cp437.bin"
txtbuf:
times (rows * cols) db 0
end: