Open command.com in io.sys

This commit is contained in:
Juhani Krekelä 2021-09-07 12:30:59 +03:00
parent 007af45879
commit 7d99699b7e

345
io.asm
View file

@ -26,21 +26,21 @@ assume cs:iogroup, ds:iogroup, es:iogroup
org 0
; Jump table
jmp init
jmp status
jmp getch
jmp putch
jmp unimplemented ; Output to printer
jmp unimplemented ; Serial read
jmp unimplemented ; Serial write
jmp diskread
jmp diskwrite
jmp diskchange
jmp setdate
jmp settime
jmp gettime
jmp flush
jmp mapdev
jmp init ; 0000
jmp status ; 0003
jmp getch ; 0006
jmp putch ; 0009
jmp unimplemented ; 000c Output to printer
jmp unimplemented ; 000f Serial read
jmp unimplemented ; 0012 Serial write
jmp diskread ; 0015
jmp diskwrite ; 0018
jmp near ptr diskchange ; 001b
jmp setdate ; 001e
jmp settime ; 0021
jmp gettime ; 0024
jmp flush ; 0027
jmp near ptr mapdev ; 002a
init:
cld
@ -70,13 +70,39 @@ init:
call dosinit
mov al, 'c'
jmp error
; Memory for command.com is at ds, save for later and revert ds
push ds
mov ax, cs
mov ds, ax
; Open command.com
mov dx, offset iogroup:command_fcb
mov ah, 0fh
int 21h
test al, al
jnz open_error
mov al, '+'
jmp unfinished
open_error:
mov al, '-'
unfinished:
mov ah, 0eh
int 10h
jmp hang
; OUT:
; al = character if any
; zf = there were no characters
status proc far
push ax
mov ax, 0e00h + 's'
int 10h
pop ax
call far_caller
; TODO: Implement
xor ax, ax
test ax, ax
@ -97,15 +123,164 @@ putch proc far
ret
putch endp
diskread:
mov al, 'r'
jmp error
; IN:
; al = driver number
; ds:bx = buffer
; cx = number of sectors to read
; dx = LBA of first sector
; OUT:
; TODO: Document
diskread proc far
push ax
mov ax, 0e00h + 'r'
int 10h
pop ax
call far_caller
push es
push ax
push bx
push cx
push dx
push di
; Save driver number
push ax
; BIOS uses es:bx instead of ds:bx
mov ax, ds
mov es, ax
mov ax, dx
; Put drive(r) number in dl
pop dx
sector_read_loop:
jcxz ret_diskread
mov di, 3 + 1 ; 3 retries, + 1 since we dec first
try_sector_read:
push ax
push cx
call chs
mov ah, 2
mov al, 1
int 13h
jnc sector_read_success
dec di
jz sector_read_fail
pop cx
pop ax
jmp try_sector_read
sector_read_fail:
pop cx
pop ax
pop di
pop dx
pop ax ; Would be cx, don't overwrite
pop bx
pop ax
pop es
mov al, 12 ; TODO: Don't hardcode
ret
sector_read_success:
pop cx
pop ax
dec cx
inc ax
add bx, 512
jmp sector_read_loop
ret_diskread:
pop di
pop dx
pop cx
pop bx
pop ax
pop es
ret
diskread endp
; IN:
; ax = LBA
; OUT:
; ch = cylinder
; cl = sector & 2 high bits of cylinder
; dh = head
chs proc
push ax
push dx
xor dx, dx
; cylinder (track) - head - sector
; cylinder = LBA / sectorspertrack / heads
; head = LBA / sectorspertrack % heads
; sector = LBA % sectorspertrack + 1
div cs:sectorspertrack
; ax = LBA / sectorspertrack
; dx = LBA % sectorspertrack
; sector
mov cl, dl
inc cl
xor dx, dx
div cs:heads
; ax = LBA / sectorspertrack / heads
; dx = LBA / sectorspertrack % heads
; head
mov dh, dl
; cylinder (track)
mov ch, al
;shr ax, 1
;shr ax, 1
;and al, 0c0h
;or cl, al
mov ax, dx
pop dx
mov dh, ah
pop ax
ret
chs endp
diskwrite:
mov al, 'w'
jmp error
diskchange:
mov al, 'c'
jmp error
; IN:
; al = drive
; OUT:
; ah = -1 different / 0 dunno / 1 same
; cf = 0 -> al = driver num
; cf = 1 -> al = disk error code
diskchange proc far
push ax
mov ax, 0e00h + 'd'
int 10h
pop ax
call far_caller
; TODO: Implement
mov ax, 0100h
clc
ret
diskchange endp
setdate:
mov al, 'd'
jmp error
@ -119,9 +294,15 @@ flush:
mov al, 'f'
jmp error
mapdev:
mov al, 'm'
jmp error
mapdev proc far
push ax
mov ax, 0e00h + 'm'
int 10h
pop ax
call far_caller
; TODO: Figure out if this does anything?
ret
mapdev endp
unimplemented:
mov al, '@'
@ -129,6 +310,10 @@ unimplemented:
error:
mov ah, 0eh
int 10h
mov ah, 0eh
mov al, '!'
int 10h
call far_caller
hang:
hlt
@ -136,10 +321,15 @@ hang:
code ends
; TODO: STRUC?
constants segment
sectorspertrack dw 8 ; TODO: Don't hardcode
heads dw 2 ; TODO: Don't hardcode
disks_table:
db 1 ; 1 drive
db 1 ; 1 drive, TODO: Don't hardcode
db 0 ; Physical drive 0
dw offset iogroup:parameters_320k
@ -154,4 +344,105 @@ parameters_320k:
constants ends
data segment
command_fcb:
db 1 ; First drive, TODO: Don't hardcode
db "COMMAND COM"
db 25 dup (?)
data ends
code segment
hexprint16 proc
xchg al, ah
call hexprint8
xchg al, ah
hexprint8 proc
rol al, 1
rol al, 1
rol al, 1
rol al, 1
call hexprint4
rol al, 1
rol al, 1
rol al, 1
rol al, 1
hexprint4 proc
push ax
and al, 0fh
cmp al, 9
jbe under_10
add al, 'a' - 10 - '0'
under_10:
add al, '0'
mov ah, 0eh
int 10h
pop ax
ret
hexprint4 endp
hexprint8 endp
hexprint16 endp
newline proc
push ax
mov ax, 0e0dh
int 10h
mov ax, 0e0ah
int 10h
pop ax
ret
newline endp
space proc
push ax
mov ax, 0e20h
int 10h
pop ax
ret
space endp
far_caller proc
push ax
push bx
mov bx, sp
mov ax, [ss:bx + 8]
call hexprint16
mov al, ':'
mov ah, 0eh
int 10h
pop bx
pop ax
near_caller proc
push ax
push bx
mov bx, sp
mov ax, [ss:bx + 6]
call hexprint16
call space
pop bx
pop ax
ret
near_caller endp
far_caller endp
logaddr proc
push ax
push bx
mov al, '>'
mov ah, 0eh
int 10h
mov bx, sp
mov ax, [ss:bx + 4]
call hexprint16
call space
pop bx
pop ax
ret
logaddr endp
code ends
end