Compare commits
No commits in common. "b9c83b11cd3b87703793847591630c6b4e6cc74a" and "2cab8ae6cf46d3f84ec4035e5c980b8c8662e401" have entirely different histories.
b9c83b11cd
...
2cab8ae6cf
1 changed files with 32 additions and 241 deletions
273
io.asm
273
io.asm
|
@ -22,7 +22,7 @@ data ends
|
|||
iogroup group code, constants, data
|
||||
|
||||
code segment
|
||||
assume cs:iogroup
|
||||
assume cs:iogroup, ds:iogroup, es:iogroup
|
||||
org 0
|
||||
|
||||
; Jump table
|
||||
|
@ -36,9 +36,9 @@ jmp unimplemented ; 0012 Serial write
|
|||
jmp near ptr diskread ; 0015
|
||||
jmp diskwrite ; 0018
|
||||
jmp near ptr diskchange ; 001b
|
||||
jmp near ptr setdate ; 001e
|
||||
jmp near ptr settime ; 0021
|
||||
jmp near ptr gettime ; 0024
|
||||
jmp setdate ; 001e
|
||||
jmp settime ; 0021
|
||||
jmp gettime ; 0024
|
||||
jmp near ptr flush ; 0027
|
||||
jmp near ptr mapdev ; 002a
|
||||
|
||||
|
@ -60,30 +60,18 @@ init:
|
|||
; AX = memory size in kilobytes
|
||||
; We want it in paragraphs
|
||||
; There are 64 paragraphs in a kilobyte
|
||||
mov cx, 6
|
||||
shl ax, cl
|
||||
mov cx, 64
|
||||
shl al, cl
|
||||
; Memory size is passed in dx
|
||||
mov dx, ax
|
||||
call hexprint16
|
||||
call newline
|
||||
|
||||
; Disk table is passed in si
|
||||
mov si, offset iogroup:disks_table
|
||||
|
||||
call dosinit
|
||||
|
||||
; Memory for command.com is at ds, with PSP already set up
|
||||
|
||||
; Retrieve amount of memory in the program segment
|
||||
mov cx, word ptr ds:6
|
||||
|
||||
; Set up DTA
|
||||
mov dx, 100h
|
||||
mov ah, 1ah
|
||||
int 21h
|
||||
|
||||
; Save command.com's segment for later and revert ds for opening the FCB
|
||||
mov bx, ds
|
||||
; Memory for command.com is at ds, save for later and revert ds
|
||||
push ds
|
||||
mov ax, cs
|
||||
mov ds, ax
|
||||
|
||||
|
@ -91,67 +79,15 @@ init:
|
|||
mov dx, offset iogroup:command_fcb
|
||||
mov ah, 0fh
|
||||
int 21h
|
||||
|
||||
test al, al
|
||||
jnz open_error
|
||||
|
||||
mov al, '+'
|
||||
mov ah, 0eh
|
||||
int 10h
|
||||
jmp unfinished
|
||||
|
||||
; Set random record field 0
|
||||
mov word ptr iogroup:command_fcb+33, 0
|
||||
mov word ptr iogroup:command_fcb+35, 0
|
||||
|
||||
; Set record size to 1 byte
|
||||
mov word ptr iogroup:command_fcb+14, 1
|
||||
|
||||
; Read command.com into memory
|
||||
mov ah, 27h
|
||||
int 21h
|
||||
|
||||
jcxz read_error
|
||||
|
||||
cmp al, 1
|
||||
jne read_error
|
||||
|
||||
mov ax, cx
|
||||
call hexprint16
|
||||
|
||||
mov al, '.'
|
||||
mov ah, 0eh
|
||||
int 10h
|
||||
|
||||
; Set up segments for command.com
|
||||
mov ds, bx
|
||||
mov es, bx
|
||||
mov ss, bx
|
||||
mov sp, 5ch ; Microsoft's documentation says to use this
|
||||
|
||||
; Put a zero at top of the stack
|
||||
xor ax, ax
|
||||
push ax
|
||||
|
||||
; Set default DTA
|
||||
mov dx, 80h
|
||||
mov ah, 1ah
|
||||
int 21h
|
||||
|
||||
; Jump to command.com
|
||||
push bx
|
||||
mov ax, 100h
|
||||
push ax
|
||||
|
||||
trampoline proc far
|
||||
ret
|
||||
trampoline endp
|
||||
|
||||
; TODO: Better error reporting
|
||||
open_error:
|
||||
mov al, '-'
|
||||
jmp unfinished
|
||||
|
||||
read_error:
|
||||
mov al, '!'
|
||||
|
||||
unfinished:
|
||||
mov ah, 0eh
|
||||
|
@ -210,24 +146,7 @@ diskread proc far
|
|||
int 10h
|
||||
pop ax
|
||||
call far_caller
|
||||
push ax
|
||||
call hexprint8
|
||||
call space
|
||||
mov ax, ds
|
||||
call hexprint16
|
||||
call space
|
||||
mov ax, bx
|
||||
call hexprint16
|
||||
call space
|
||||
mov ax, cx
|
||||
call hexprint16
|
||||
call space
|
||||
mov ax, dx
|
||||
call hexprint16
|
||||
call newline
|
||||
pop ax
|
||||
|
||||
; TODO: Everything except sregs can be trashed
|
||||
push es
|
||||
push ax
|
||||
push bx
|
||||
|
@ -271,11 +190,6 @@ diskread proc far
|
|||
jmp try_sector_read
|
||||
|
||||
sector_read_fail:
|
||||
mov al, ah
|
||||
call hexprint8;debg
|
||||
mov al, '?'
|
||||
mov ah, 0eh
|
||||
int 10h
|
||||
pop cx
|
||||
pop ax
|
||||
|
||||
|
@ -287,7 +201,6 @@ diskread proc far
|
|||
pop es
|
||||
|
||||
mov al, 12 ; TODO: Don't hardcode
|
||||
stc
|
||||
ret
|
||||
|
||||
sector_read_success:
|
||||
|
@ -306,7 +219,6 @@ diskread proc far
|
|||
pop ax
|
||||
pop es
|
||||
|
||||
clc
|
||||
ret
|
||||
|
||||
diskread endp
|
||||
|
@ -326,7 +238,7 @@ chs proc
|
|||
; cylinder = LBA / sectorspertrack / heads
|
||||
; head = LBA / sectorspertrack % heads
|
||||
; sector = LBA % sectorspertrack + 1
|
||||
div iogroup:sectorspertrack
|
||||
div cs:sectorspertrack
|
||||
; ax = LBA / sectorspertrack
|
||||
; dx = LBA % sectorspertrack
|
||||
|
||||
|
@ -335,7 +247,7 @@ chs proc
|
|||
inc cl
|
||||
|
||||
xor dx, dx
|
||||
div iogroup:heads
|
||||
div cs:heads
|
||||
; ax = LBA / sectorspertrack / heads
|
||||
; dx = LBA / sectorspertrack % heads
|
||||
|
||||
|
@ -344,10 +256,10 @@ chs proc
|
|||
|
||||
; cylinder (track)
|
||||
mov ch, al
|
||||
shr ax, 1
|
||||
shr ax, 1
|
||||
and al, 0c0h
|
||||
or cl, al
|
||||
;shr ax, 1
|
||||
;shr ax, 1
|
||||
;and al, 0c0h
|
||||
;or cl, al
|
||||
|
||||
mov ax, dx
|
||||
pop dx
|
||||
|
@ -368,138 +280,26 @@ diskwrite:
|
|||
; 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, 0000h
|
||||
mov ax, 0100h
|
||||
clc
|
||||
ret
|
||||
diskchange endp
|
||||
|
||||
; IN:
|
||||
; ax = days since 1980-01-01
|
||||
setdate proc far
|
||||
mov iogroup:days_since_epoch, ax
|
||||
ret
|
||||
setdate endp
|
||||
|
||||
; IN:
|
||||
; ch = hour
|
||||
; cl = minute
|
||||
; dh = second
|
||||
; dl = 1/100 second
|
||||
settime proc far
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
|
||||
; Save second & 1/100 second in bx
|
||||
mov bx, dx
|
||||
|
||||
; Hour
|
||||
mov al, ch
|
||||
cbw
|
||||
mul iogroup:doubleticks_per_hour
|
||||
shl ax, 1
|
||||
rcl dx, 1
|
||||
; Store the partial sum in si:di
|
||||
mov di, ax
|
||||
mov si, dx
|
||||
|
||||
; Minute
|
||||
mov al, cl
|
||||
cbw
|
||||
mul iogroup:ticks_per_minute
|
||||
add di, ax
|
||||
adc si, dx
|
||||
|
||||
; Second
|
||||
mov al, bh
|
||||
cbw
|
||||
mul iogroup:ticks_per_second
|
||||
add di, ax
|
||||
adc si, dx
|
||||
|
||||
; 1/100 second
|
||||
mov al, bl
|
||||
cbw
|
||||
div iogroup:cs_per_tick
|
||||
xor ah, ah
|
||||
add di, ax
|
||||
adc si, 0
|
||||
|
||||
; Move result to cx:ds and set timer
|
||||
mov cx, si
|
||||
mov dx, di
|
||||
mov ah, 01h
|
||||
int 1ah
|
||||
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
settime endp
|
||||
|
||||
; OUT:
|
||||
; ax = days since 1980-01-01
|
||||
; ch = hour
|
||||
; cl = minute
|
||||
; dh = second
|
||||
; dl = 1/100 second
|
||||
gettime proc far
|
||||
; TODO: Use RTC if available
|
||||
push bx
|
||||
|
||||
; Get ticks since midnight and day rollover flag
|
||||
xor ah, ah
|
||||
int 1ah
|
||||
|
||||
; al is nonzero if day has changed
|
||||
test al, al
|
||||
jz same_day
|
||||
inc iogroup:days_since_epoch
|
||||
|
||||
same_day:
|
||||
|
||||
; Divide the ticks by 2, to keep all our arithmetic within bounds
|
||||
shr cx, 1
|
||||
rcr dx, 1
|
||||
|
||||
; int 1ah / ah=00 returns the ticks in cx:dx, div operates on dx:ax
|
||||
mov ax, dx
|
||||
mov dx, cx
|
||||
div iogroup:doubleticks_per_hour
|
||||
mov ch, al ; Hour
|
||||
|
||||
; Remainder in dx, range [0,doubleticks_per_hour[ represents an hour
|
||||
; Multiply by 60, divide by doubleticks_per_hour to get the minute
|
||||
mov ax, dx
|
||||
mul iogroup:sixty
|
||||
div iogroup:doubleticks_per_hour
|
||||
mov cl, al ; Minute
|
||||
|
||||
; Do same again to get seconds
|
||||
mov ax, dx
|
||||
mul iogroup:sixty
|
||||
div iogroup:doubleticks_per_hour
|
||||
mov bl, al ; Save seconds in bl, since dh gets destroyed by next muldiv
|
||||
|
||||
; For 1/100th of a second, multiply by 100 instead
|
||||
mov ax, dx
|
||||
mul iogroup:hundred
|
||||
div iogroup:doubleticks_per_hour
|
||||
mov dh, bl ; Second
|
||||
mov dl, al ; 1/100 second
|
||||
|
||||
mov ax, iogroup:days_since_epoch
|
||||
|
||||
pop bx
|
||||
ret
|
||||
gettime endp
|
||||
setdate:
|
||||
mov al, 'd'
|
||||
jmp error
|
||||
settime:
|
||||
mov al, 't'
|
||||
jmp error
|
||||
gettime:
|
||||
mov al, 'T'
|
||||
jmp error
|
||||
|
||||
flush proc far
|
||||
push ax
|
||||
|
@ -520,6 +320,7 @@ flush endp
|
|||
|
||||
mapdev proc far
|
||||
; TODO: Implement
|
||||
xor al, al
|
||||
ret
|
||||
mapdev endp
|
||||
|
||||
|
@ -561,14 +362,6 @@ parameters_320k:
|
|||
dw 112 ; Number of directory entries
|
||||
dw 320*2 ; Number of sectors
|
||||
|
||||
doubleticks_per_hour dw 32772 ; 1800B0h / 2 / 24
|
||||
ticks_per_minute dw 1092 ; 1800B0h / 24 / 60
|
||||
ticks_per_second dw 18 ; 1800B0h / 24 / 60 / 60
|
||||
cs_per_tick db 5 ; 24 * 60 * 60 * 100 / 1800B0h
|
||||
|
||||
sixty dw 60
|
||||
hundred dw 100
|
||||
|
||||
constants ends
|
||||
|
||||
data segment
|
||||
|
@ -578,8 +371,6 @@ command_fcb:
|
|||
db "COMMAND COM"
|
||||
db 25 dup (?)
|
||||
|
||||
days_since_epoch: dw 0
|
||||
|
||||
data ends
|
||||
|
||||
code segment
|
||||
|
|
Loading…
Reference in a new issue