From a49e3b26101f3218f802ab14415442576840996f Mon Sep 17 00:00:00 2001 From: Nero <41307858+nero@users.noreply.github.com> Date: Tue, 29 Oct 2019 11:08:11 +0000 Subject: [PATCH] Rework BDOS to make use of BIOS entrypoints --- Makefile | 13 ++-- bdos/8086.asm | 136 ++++++++++++++++++++++++++++++++++++++ bdos/con86.asm | 56 ---------------- bdos/disk.asm | 168 ----------------------------------------------- bdos/dump.asm | 18 ++--- bdos/exec.asm | 13 ---- bdos/fcb.asm | 8 --- bdos/main.asm | 62 ----------------- bdos/string.asm | 31 --------- bdos/syscall.asm | 96 --------------------------- bios/8086.asm | 2 +- bios/header.asm | 17 +++++ 12 files changed, 169 insertions(+), 451 deletions(-) create mode 100644 bdos/8086.asm delete mode 100644 bdos/con86.asm delete mode 100644 bdos/disk.asm delete mode 100644 bdos/exec.asm delete mode 100644 bdos/fcb.asm delete mode 100644 bdos/main.asm delete mode 100644 bdos/string.asm delete mode 100644 bdos/syscall.asm create mode 100644 bios/header.asm diff --git a/Makefile b/Makefile index 0f5045d..8c30b2c 100644 --- a/Makefile +++ b/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) diff --git a/bdos/8086.asm b/bdos/8086.asm new file mode 100644 index 0000000..de9f06c --- /dev/null +++ b/bdos/8086.asm @@ -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 diff --git a/bdos/con86.asm b/bdos/con86.asm deleted file mode 100644 index 1da3f8b..0000000 --- a/bdos/con86.asm +++ /dev/null @@ -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 diff --git a/bdos/disk.asm b/bdos/disk.asm deleted file mode 100644 index 86e3195..0000000 --- a/bdos/disk.asm +++ /dev/null @@ -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 diff --git a/bdos/dump.asm b/bdos/dump.asm index b01da68..115ff7b 100644 --- a/bdos/dump.asm +++ b/bdos/dump.asm @@ -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 diff --git a/bdos/exec.asm b/bdos/exec.asm deleted file mode 100644 index faf2d23..0000000 --- a/bdos/exec.asm +++ /dev/null @@ -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 diff --git a/bdos/fcb.asm b/bdos/fcb.asm deleted file mode 100644 index 06f3ffe..0000000 --- a/bdos/fcb.asm +++ /dev/null @@ -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 diff --git a/bdos/main.asm b/bdos/main.asm deleted file mode 100644 index eaac4cc..0000000 --- a/bdos/main.asm +++ /dev/null @@ -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" diff --git a/bdos/string.asm b/bdos/string.asm deleted file mode 100644 index dc9a744..0000000 --- a/bdos/string.asm +++ /dev/null @@ -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 diff --git a/bdos/syscall.asm b/bdos/syscall.asm deleted file mode 100644 index df72948..0000000 --- a/bdos/syscall.asm +++ /dev/null @@ -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 diff --git a/bios/8086.asm b/bios/8086.asm index 8bdc82f..a6f4ac3 100644 --- a/bios/8086.asm +++ b/bios/8086.asm @@ -28,7 +28,7 @@ BOOT: DB "BIOS", 0 WBOOT: - XOR AX, AX + XOR CX, CX JMP BDOS RET diff --git a/bios/header.asm b/bios/header.asm new file mode 100644 index 0000000..9a645b0 --- /dev/null +++ b/bios/header.asm @@ -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)