Rework BDOS to make use of BIOS entrypoints
This commit is contained in:
parent
af61db5e40
commit
a49e3b2610
13
Makefile
13
Makefile
@ -1,10 +1,10 @@
|
||||
FLOPPY = 360
|
||||
|
||||
BDOS = 0xF000
|
||||
BDOSIMG = bdos.bin
|
||||
BDOSIMG = bdos/8086.bin
|
||||
|
||||
BIOS = 0xF800
|
||||
BIOSIMG = bios8086.bin
|
||||
BIOSIMG = bios/8086.bin
|
||||
|
||||
PROGRAMS = $(patsubst %.asm,%.com,$(wildcard com/*.asm))
|
||||
DISTFILES = $(PROGRAMS)
|
||||
@ -37,10 +37,6 @@ endif
|
||||
|
||||
default: fdimage.img
|
||||
|
||||
# BDOS image
|
||||
bdos.bin: bdos/*.asm lib/*.asm
|
||||
$(NASM) $(NASM_ARGS) -o $@ -I bdos bdos/main.asm
|
||||
|
||||
# Boot sectors
|
||||
boot/%.bs: boot/%.asm
|
||||
$(NASM) $(NASM_ARGS) -DFLOPPY=$(FLOPPY) -o $@ $<
|
||||
@ -53,7 +49,10 @@ rom/%.rom: rom/%.asm
|
||||
com/%.com: com/%.asm
|
||||
$(NASM) $(NASM_ARGS) -o $@ $<
|
||||
|
||||
bios%.bin: bios/%.asm
|
||||
bdos/%.bin: bdos/%.asm lib/*.asm
|
||||
$(NASM) $(NASM_ARGS) -o $@ -I bdos $<
|
||||
|
||||
bios/%.bin: bios/%.asm
|
||||
$(NASM) $(NASM_ARGS) -o $@ $<
|
||||
|
||||
fdimage.img: boot/fat.bs $(BDOSIMG) $(BIOSIMG) $(DISTFILES)
|
||||
|
136
bdos/8086.asm
Normal file
136
bdos/8086.asm
Normal file
@ -0,0 +1,136 @@
|
||||
ORG BDOS
|
||||
|
||||
%include "bios/header.asm"
|
||||
|
||||
DISKBUF: EQU (BDOS-0x200) ; deblocking
|
||||
STACK: EQU (DISKBUF) ; grows down
|
||||
DEFDRV: EQU 4
|
||||
|
||||
FCB_DRV: EQU 0 ; BYTE 0=A: 1=B: 2=C: ...
|
||||
FCB_NAM: EQU 1 ; 8 BYTES, space padded
|
||||
FCB_EXT: EQU 9 ; 3 BYTES, space padded
|
||||
FCB_TYP: EQU 12 ; 1 for regular file
|
||||
FCB_BLK: EQU 13 ; current 128b block in sector
|
||||
FCB_CLU: EQU 14 ; current sector
|
||||
FCB_LFT: EQU 16 ; bytes left to read in current file
|
||||
|
||||
SYSCALL:
|
||||
TEST CL, CL
|
||||
JE SETUP
|
||||
CMP CL, 1
|
||||
JE GETC
|
||||
CMP CL, 2
|
||||
JE PUTC
|
||||
CMP CL, 9
|
||||
JE PUTS
|
||||
CMP CL, 10
|
||||
JE GETS
|
||||
STC
|
||||
RET
|
||||
|
||||
SETUP:
|
||||
MOV SP, STACK
|
||||
MOV BYTE [DEFDRV], 0x01
|
||||
MOV CX, DISKBUF
|
||||
CALL SETDMA
|
||||
|
||||
MOV DL, BYTE [DEFDRV]
|
||||
ADD DL, '@'
|
||||
CALL PUTC
|
||||
MOV DL, '>'
|
||||
CALL PUTC
|
||||
|
||||
MOV DX, 0x7F
|
||||
MOV BYTE [0x7F], 0x2F
|
||||
MOV BYTE [0x80], 2
|
||||
CALL GETS
|
||||
|
||||
INT3
|
||||
|
||||
CLI
|
||||
HALT:
|
||||
HLT
|
||||
JMP HALT
|
||||
|
||||
GETC:
|
||||
CALL CONIN
|
||||
TEST AL, AL
|
||||
JZ GETC
|
||||
PUSH DX
|
||||
MOV DL, AL
|
||||
CALL CONOUT
|
||||
POP DX
|
||||
ret
|
||||
|
||||
PUTC:
|
||||
CALL CONOUT
|
||||
RET
|
||||
|
||||
PUTS:
|
||||
PUSH SI
|
||||
MOV SI, DX
|
||||
PUTS_L:
|
||||
MOV DL, BYTE [SI]
|
||||
CMP DL, '$'
|
||||
JZ PUTS_E
|
||||
CALL CONOUT
|
||||
INC SI
|
||||
JMP PUTS_L
|
||||
PUTS_E:
|
||||
POP SI
|
||||
RET
|
||||
|
||||
; BX base ptr to buffer
|
||||
; CH maximum BL
|
||||
; CL minimum BL
|
||||
GETS:
|
||||
PUSH AX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH BX
|
||||
; BX is base pointer
|
||||
MOV BX, DX
|
||||
; CL is maximum, CH is current position
|
||||
MOV CX, [BX]
|
||||
XOR CH, CH
|
||||
; BX starts at actual character area
|
||||
ADD BX, 2
|
||||
GETS_L:
|
||||
; Read and maybe handle control chars
|
||||
CALL GETC
|
||||
CMP AL, 0x0D
|
||||
JE GETS_E
|
||||
CMP AL, 8
|
||||
JE GETS_BS
|
||||
; Store character
|
||||
PUSH BX
|
||||
ADD BL, CH
|
||||
ADC BH, 0
|
||||
MOV [BX], AL
|
||||
POP BX
|
||||
; Loop if we arent full yet
|
||||
INC CH
|
||||
CMP CH, CL
|
||||
JC GETS_L
|
||||
GETS_E:
|
||||
; Append LF to CR
|
||||
MOV DL, 0x0A
|
||||
CALL PUTC
|
||||
; Write back length data
|
||||
SUB BX, 2
|
||||
MOV [BX], CX
|
||||
; Restore registers
|
||||
POP BX
|
||||
POP DX
|
||||
POP CX
|
||||
POP AX
|
||||
ret
|
||||
GETS_BS:
|
||||
TEST CH, CH
|
||||
JZ GETS_L
|
||||
MOV DL, 0x20
|
||||
CALL PUTC
|
||||
MOV DL, 8
|
||||
CALL PUTC
|
||||
DEC CL
|
||||
JMP GETS_L
|
@ -1,56 +0,0 @@
|
||||
console_hide_cursor:
|
||||
push ax
|
||||
push cx
|
||||
mov ah, 1
|
||||
mov cx, 0x1F1F
|
||||
int 0x10
|
||||
pop cx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
console_show_cursor:
|
||||
push ax
|
||||
push cx
|
||||
mov ah, 1
|
||||
mov cx, 0x001F
|
||||
int 0x10
|
||||
pop cx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
; Raw console i/o without echo
|
||||
; IN DL character to output or FF
|
||||
; OUT ZF if DL=FF: zero if character input
|
||||
; AL if not ZF: ascii char, otherwise corrupt
|
||||
console_io:
|
||||
cmp dl, 0xFF
|
||||
je .read
|
||||
push ax
|
||||
push bx
|
||||
mov al, dl
|
||||
mov ah, 0x0e
|
||||
xor bx, bx
|
||||
int 0x10
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
.read:
|
||||
call console_show_cursor
|
||||
|
||||
; if no character avail, exit with leaving
|
||||
; cursor displayed
|
||||
mov ah, 1
|
||||
int 0x16
|
||||
jz .end
|
||||
pushf
|
||||
|
||||
; actually read character
|
||||
xor ax, ax
|
||||
int 0x16
|
||||
|
||||
call console_hide_cursor
|
||||
|
||||
; restore zero flag
|
||||
popf
|
||||
.end:
|
||||
ret
|
168
bdos/disk.asm
168
bdos/disk.asm
@ -1,168 +0,0 @@
|
||||
disk_num: equ 0x40 ; BYTE drive number (A=0)
|
||||
disk_heads: equ 0x41 ; BYTE number of heads/sides
|
||||
disk_parm: equ 0x42 ; 11 BYTES for int 0x1E
|
||||
disk_spt: equ 0x46 ; - BYTE
|
||||
|
||||
disk_parm_init:
|
||||
push ax
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
|
||||
; invalidate existing data
|
||||
mov byte [disk_num], 0xFF
|
||||
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
|
||||
; if int 0x1E is already pointing to us,
|
||||
; we have nothing to copy
|
||||
mov di, disk_parm
|
||||
lds si, [0x1E*4]
|
||||
cmp si, di
|
||||
je .correctparm
|
||||
|
||||
; copy bios table into our location
|
||||
mov cx, 11
|
||||
rep movsb
|
||||
|
||||
; make the interrupt vector point to our address
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov [0x1E*4], di
|
||||
mov ax, cs
|
||||
mov [0x1E*4+2], ax
|
||||
|
||||
.correctparm:
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop ax
|
||||
ret
|
||||
|
||||
disk_load_bpb:
|
||||
mov ax, 0x0201
|
||||
mov cx, 0x0001
|
||||
xor dh, dh
|
||||
mov bx, diskbuf
|
||||
stc
|
||||
|
||||
int 0x13
|
||||
jnc .end
|
||||
|
||||
; try a second time
|
||||
mov ax, 0x0201
|
||||
int 0x13
|
||||
jnc .end
|
||||
|
||||
; try a third time
|
||||
mov ax, 0x0201
|
||||
int 0x13
|
||||
.end:
|
||||
ret
|
||||
|
||||
disk_select:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
push bx
|
||||
|
||||
cmp byte [disk_num], dl
|
||||
je .end
|
||||
mov byte [disk_num], dl
|
||||
call disk_load_bpb
|
||||
jc .end
|
||||
|
||||
; Validate and apply sector size
|
||||
mov ax, [diskbuf+fdc_ss]
|
||||
; test ax, 0xF87F
|
||||
; jnz .nobpd
|
||||
call log2
|
||||
sub al, 7
|
||||
mov [disk_parm+3], al
|
||||
|
||||
; fetch sectors per track
|
||||
mov al, [diskbuf+fdc_spt]
|
||||
mov [disk_parm+4], al
|
||||
|
||||
; fetch number of sides/heads
|
||||
mov ax, [diskbuf+fdc_nos]
|
||||
mov [disk_heads], al
|
||||
|
||||
xor ah, ah
|
||||
int 0x13
|
||||
.end:
|
||||
pop bx
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
; Setup CX, DX and BX for int 13h transfer
|
||||
; IN BX ptr to 32-bit number
|
||||
; OUT CL Sector number
|
||||
; CH Cylinder number
|
||||
; DL Drive number
|
||||
; DH Head number
|
||||
; BX Sector buffer
|
||||
disk_prepare_chs:
|
||||
mov ax, word [bx]
|
||||
mov dx, word [bx+2]
|
||||
|
||||
xor bh, bh
|
||||
mov bl, byte [disk_spt]
|
||||
|
||||
div word bx ; ax:temp = (lba / spt)
|
||||
inc dx ; dx:sector = (lba % spt) + 1
|
||||
mov cl, dl ; sector number
|
||||
|
||||
xor bx, bx
|
||||
mov bl, byte [disk_heads]
|
||||
|
||||
xor dx, dx
|
||||
div word bx ; ax:cylinder = (temp / nos)
|
||||
; dx:head = (temp % nos)
|
||||
mov ch, al ; cylinder number
|
||||
mov dh, dl ; head number
|
||||
|
||||
mov dl, byte [disk_num]
|
||||
mov bx, diskbuf
|
||||
ret
|
||||
|
||||
; Read a sector into diskbuf
|
||||
; IN BX ptr to DWORD giving sector number
|
||||
disk_read:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
push bx
|
||||
|
||||
call disk_prepare_chs
|
||||
|
||||
mov ax, 0x0201
|
||||
int 0x13
|
||||
|
||||
pop bx
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
; Write a sector from diskbuf
|
||||
; IN BX ptr to DWORD giving sector number
|
||||
disk_write:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
push bx
|
||||
|
||||
call disk_prepare_chs
|
||||
|
||||
mov ax, 0x0301
|
||||
int 0x13
|
||||
|
||||
pop bx
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
ret
|
@ -27,7 +27,7 @@ print8:
|
||||
add al, 0x07
|
||||
.out:
|
||||
mov dl, al
|
||||
call console_output
|
||||
call CONOUT
|
||||
ret
|
||||
|
||||
dump:
|
||||
@ -36,9 +36,9 @@ dump:
|
||||
push dx
|
||||
push bx
|
||||
mov dl, 0x0A
|
||||
call console_output
|
||||
call CONOUT
|
||||
mov dl, 0x0D
|
||||
call console_output
|
||||
call CONOUT
|
||||
mov cx, 4
|
||||
.loop_line:
|
||||
push cx
|
||||
@ -46,9 +46,9 @@ dump:
|
||||
mov ax, bx
|
||||
call print16
|
||||
mov dl, ':'
|
||||
call console_output
|
||||
call CONOUT
|
||||
mov dl, ' '
|
||||
call console_output
|
||||
call CONOUT
|
||||
mov cx, 0x8
|
||||
.loop_bin:
|
||||
mov ax, [bx]
|
||||
@ -57,7 +57,7 @@ dump:
|
||||
inc bx
|
||||
call print16
|
||||
mov dl, ' '
|
||||
call console_output
|
||||
call CONOUT
|
||||
loop .loop_bin
|
||||
pop bx
|
||||
mov cx, 0x10
|
||||
@ -70,13 +70,13 @@ dump:
|
||||
mov dl, [bx]
|
||||
.print:
|
||||
inc bx
|
||||
call console_output
|
||||
call CONOUT
|
||||
loop .loop_ascii
|
||||
pop cx
|
||||
mov dl, 0x0A
|
||||
call console_output
|
||||
call CONOUT
|
||||
mov dl, 0x0D
|
||||
call console_output
|
||||
call CONOUT
|
||||
loop .loop_line
|
||||
pop bx
|
||||
pop dx
|
||||
|
@ -1,13 +0,0 @@
|
||||
; Exec the cmdline at SI or 0x81
|
||||
exec_chain:
|
||||
mov si, 0x81
|
||||
exec:
|
||||
push bx
|
||||
sub sp, 0x20
|
||||
mov bx, sp
|
||||
|
||||
call fcb_parse
|
||||
|
||||
add sp, 0x20
|
||||
pop bx
|
||||
ret
|
@ -1,8 +0,0 @@
|
||||
; diskbuf needs to be defined
|
||||
|
||||
; User-accessible part of FCB (12 bytes)
|
||||
fcb_drv: equ 0 ; 1 byte, 1=A: 2=B: 3=C:
|
||||
fcb_fn: equ 1 ; 8 bytes
|
||||
fcb_ext: equ 9 ; 3 bytes
|
||||
|
||||
fcb_type: equ 12 ; BYTE type identifier
|
@ -1,62 +0,0 @@
|
||||
cpu 8086
|
||||
|
||||
self: equ 0xF000
|
||||
diskbuf: equ (self-0x200) ; deblocking
|
||||
stack: equ (diskbuf) ; grows down
|
||||
defdrv: equ 4
|
||||
|
||||
org self
|
||||
jmp init
|
||||
pad 3
|
||||
|
||||
self_offset:
|
||||
db (self >> 8)
|
||||
|
||||
banner:
|
||||
db "RDOS 2019-09", 0x0A, 0x0D, '$', 0
|
||||
|
||||
init:
|
||||
mov sp, stack
|
||||
mov byte [defdrv], 0x01
|
||||
|
||||
mov dx, banner
|
||||
call print_string
|
||||
|
||||
call disk_parm_init
|
||||
|
||||
mov dx, 0x7F
|
||||
mov byte [0x7F], 0x7F
|
||||
mov byte [0x80], 2
|
||||
call read_buffer
|
||||
|
||||
int3
|
||||
|
||||
cli
|
||||
.halt:
|
||||
hlt
|
||||
jmp .halt
|
||||
|
||||
init_program:
|
||||
db "HELLO.COM", 0
|
||||
|
||||
; helper function for idle loops
|
||||
idle:
|
||||
pushf
|
||||
sti
|
||||
hlt
|
||||
popf
|
||||
ret
|
||||
|
||||
%include "syscall.asm"
|
||||
|
||||
%include "con86.asm"
|
||||
|
||||
%include "exec.asm"
|
||||
%include "fdc.asm"
|
||||
%include "fcb.asm"
|
||||
%include "fcbparse.asm"
|
||||
|
||||
%include "disk.asm"
|
||||
|
||||
%include "log2.asm"
|
||||
%include "dump.asm"
|
@ -1,31 +0,0 @@
|
||||
; IN DS:SI offset of needle
|
||||
; ES:DI offset to haystack table
|
||||
; OUT ES:DI found offset in table
|
||||
; ZF zero flag set if match
|
||||
|
||||
string_search_token:
|
||||
push bp
|
||||
push cx
|
||||
.loop:
|
||||
cmp BYTE [es:di], 0
|
||||
je .fail
|
||||
push si
|
||||
push di
|
||||
mov bp, di
|
||||
xor ch, ch
|
||||
mov cl, [es:di]
|
||||
inc di
|
||||
add bp, cx
|
||||
inc bp
|
||||
repe cmpsb
|
||||
pop di
|
||||
pop si
|
||||
je .end
|
||||
mov di, bp
|
||||
jmp .loop
|
||||
.fail:
|
||||
stc
|
||||
.end:
|
||||
pop cx
|
||||
pop cx
|
||||
ret
|
@ -1,96 +0,0 @@
|
||||
cpm_syscall:
|
||||
cmp cl, 0
|
||||
je init
|
||||
|
||||
cmp cl, 1
|
||||
jne console_input.chain
|
||||
|
||||
console_input.loop:
|
||||
call idle
|
||||
console_input:
|
||||
push dx
|
||||
mov dl, 0xFF
|
||||
call console_io
|
||||
pop dx
|
||||
jz console_input.loop
|
||||
test al, al
|
||||
jz console_input.loop
|
||||
push dx
|
||||
mov dl, al
|
||||
call console_output
|
||||
pop dx
|
||||
ret
|
||||
|
||||
.chain:
|
||||
cmp cl, 2
|
||||
jne console_output.chain
|
||||
|
||||
console_output:
|
||||
cmp dl, 0xFF
|
||||
je .end
|
||||
call console_io
|
||||
.end:
|
||||
ret
|
||||
|
||||
.chain:
|
||||
cmp cl, 9
|
||||
jne print_string.chain
|
||||
|
||||
print_string:
|
||||
push si
|
||||
mov si, dx
|
||||
.loop:
|
||||
mov dl, BYTE [si]
|
||||
cmp dl, '$'
|
||||
jz .end
|
||||
call console_output
|
||||
inc si
|
||||
jmp .loop
|
||||
.end:
|
||||
pop si
|
||||
ret
|
||||
|
||||
.chain:
|
||||
cmp cl, 10
|
||||
jne read_buffer.chain
|
||||
|
||||
read_buffer:
|
||||
push ax
|
||||
push dx
|
||||
push bx
|
||||
push si
|
||||
xor bx, bx
|
||||
mov si, dx
|
||||
.loop:
|
||||
call console_input
|
||||
cmp al, 0x0D
|
||||
je .end
|
||||
cmp al, 8
|
||||
je .bs
|
||||
mov [si+bx+2], al
|
||||
inc bx
|
||||
cmp bl, [si]
|
||||
jc .loop
|
||||
.end:
|
||||
mov byte [si+bx+2], 0x0D
|
||||
mov [si+1], bl
|
||||
mov dl, 0x0A
|
||||
call console_output
|
||||
pop si
|
||||
pop bx
|
||||
pop dx
|
||||
pop ax
|
||||
ret
|
||||
.bs:
|
||||
test bx, bx
|
||||
jz .loop
|
||||
mov dl, 0x20
|
||||
call console_output
|
||||
mov dl, 8
|
||||
call console_output
|
||||
dec bx
|
||||
jmp .loop
|
||||
|
||||
.chain:
|
||||
stc
|
||||
ret
|
@ -28,7 +28,7 @@ BOOT:
|
||||
DB "BIOS", 0
|
||||
|
||||
WBOOT:
|
||||
XOR AX, AX
|
||||
XOR CX, CX
|
||||
JMP BDOS
|
||||
RET
|
||||
|
||||
|
17
bios/header.asm
Normal file
17
bios/header.asm
Normal file
@ -0,0 +1,17 @@
|
||||
; Labels for BIOS entry points
|
||||
BOOT: EQU (BIOS+0)
|
||||
WBOOT: EQU (BIOS+3)
|
||||
CONST: EQU (BIOS+6)
|
||||
CONIN: EQU (BIOS+9)
|
||||
CONOUT: EQU (BIOS+12)
|
||||
LIST: EQU (BIOS+15)
|
||||
PUNCH: EQU (BIOS+18)
|
||||
READER: EQU (BIOS+21)
|
||||
HOME: EQU (BIOS+24)
|
||||
SELDSK: EQU (BIOS+27)
|
||||
SETTRK: EQU (BIOS+30)
|
||||
SETSEC: EQU (BIOS+33)
|
||||
SETDMA: EQU (BIOS+36)
|
||||
READ: EQU (BIOS+39)
|
||||
WRITE: EQU (BIOS+42)
|
||||
LISTST: EQU (BIOS+45)
|
Loading…
Reference in New Issue
Block a user