!************************************************************************** !* !* Network driver interface for netboot bootrom !* !* Module: fileio.S !* Purpose: File I/O functions for DOS simulator !* Entries: dos3C, dos3D, dos3E, dos3F, dos40, dos44 !* !************************************************************************** !* !* Copyright (C) 1995-2003 Gero Kuhlmann !* !* This program is free software; you can redistribute it and/or modify !* it under the terms of the GNU General Public License as published by !* the Free Software Foundation; either version 2 of the License, or !* any later version. !* !* This program is distributed in the hope that it will be useful, !* but WITHOUT ANY WARRANTY; without even the implied warranty of !* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !* GNU General Public License for more details. !* !* You should have received a copy of the GNU General Public License !* along with this program; if not, write to the Free Software !* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. !* !* $Id: fileio.S,v 1.4 2003/01/25 23:29:41 gkminix Exp $ !* ! !************************************************************************** ! ! Include assembler macros: ! #include #include "dospriv.inc" ! !************************************************************************** ! ! BSS segment ! .bss extrn curr_psp ! segment of current PSP ! !************************************************************************** ! ! Start code segment. ! .text extrn dos02 extrn dos03 extrn dos04 extrn dos05 extrn dos07 public dos3C public dos3D public dos3E ! define entry points public dos3F public dos40 public dos44 ! !************************************************************************** ! ! Create a new file. Since its not possible to create a new file with ! the DOS simulator, this just returns an error. ! Input: CX - file attribute ! DS:DX - pointer to file name ! Output: AX - file handle or error code if carry flag set ! Carry flag - set if error ! Registers changed: AX ! dos3C: mov ax,#ERR_NODIR ! return with error stc ret ! !************************************************************************** ! ! Open file. Since the DOS simulator cannot use files, just return with ! an error. ! Input: DS:DX - pointer to file name ! Output: AX - file handle or error code if carry flag set ! Carry flag - set if error ! Registers changed: AX ! dos3D: mov ax,#ERR_NOFILE ! return with error stc ret ! !************************************************************************** ! ! Close file. This just clears the file handle in the PSP. If no file IO ! is enabled this is just a NOP. ! Input: BX - file handle ! Output: AX - error code if carry flag set ! Carry flag - set if error ! Registers changed: AX ! dos3E: #ifdef NEEDFILEIO call chkhndl ! check file handle jc dos3E9 # ifdef IS386 mov fs,[curr_psp] seg fs mov byte ptr psp_handles[bx],#0 ! reset handle # else push ds mov ds,[curr_psp] mov byte ptr psp_handles[bx],#0 ! reset handle pop ds # endif #else clc #endif dos3E9: ret ! !************************************************************************** ! ! Read file. ! Input: BX - file handle ! CX - number of bytes to read ! DS:DX - pointer to read buffer ! Output: AX - number of bytes read, or error code if carry flag set ! Carry flag - set if error ! Registers changed: AX ! dos3F: #ifdef NEEDFILEIO call chkhndl ! check file handle jc dos3F9 # if defined(NEEDKBD) || defined(NEEDEXTIO) push es push di ! Read the data from the device into the buffer. mov di,dx mov es,old_ds[bp] dos3F3: # if defined(NEEDKBD) && !defined(NEEDEXTIO) call dos07 ! read character from keyboard # else call readchar ! read character from device # endif ! Handle end-of-line or end-of-file. dos3F4: cmp al,#CHR_RET ! end of line? je dos3F5 cmp al,#CHR_LF je dos3F5 cmp al,#CHR_EOF ! or end of file? jne dos3F6 dos3F5: mov al,#CHR_RET # ifdef NEEDEXTIO call writechar ! return to a new line on the screen # else int $29 # endif mov al,#CHR_LF # ifdef NEEDEXTIO call writechar # else int $29 # endif mov ax,di sub ax,dx ! compute actual length of input buffer clc jmp dos3F2 ! Handle backspace character dos3F6: cmp al,#CHR_BS jne dos3F7 cmp dx,di ! already at beginning of line je dos3F3 dec di # ifdef NEEDEXTIO call writechar ! print backspace onto the screen # else int $29 # endif jmp dos3F3 ! Add character to the end of the line dos3F7: cmp al,#$20 ! only care for printable characters jb dos3F3 push ax mov ax,cx add ax,dx ! check if end of buffer reached cmp ax,di pop ax jae dos3F5 stosb ! save character into buffer # ifdef NEEDEXTIO call writechar ! print character # else int $29 # endif jmp dos3F3 dos3F8: stc dos3F2: pop di pop es # else xor ax,ax ! if no keyboard or aux I/O, return 0 # endif #else xor ax,ax ! if no FILEIO, read just 0 bytes #endif dos3F9: ret ! !************************************************************************** ! ! Write to file. ! Input: BX - file handle ! CX - buffer size ! DS:DX - output buffer ! Output: AX - number of characters written, or error code if carry set ! Carry flag - set if error ! Registers changed: AX ! dos40: #ifdef NEEDFILEIO call chkhndl ! check file handle jc dos409 pushfs push si ! Write all characters onto the output device mov si,dx # ifdef IS386 mov fs,old_ds[bp] # else mov es,old_ds[bp] # endif dos402: mov ax,dx add ax,cx ! check if at end of buffer cmp si,ax jae dos403 segfs lodsb # ifdef NEEDEXTIO call writechar ! print character # else int $29 # endif jmp dos402 dos403: mov ax,si sub ax,dx ! compute number of bytes written clc pop si popfs #else mov ax,cx ! if no FILEIO, wrote all bytes clc #endif dos409: ret ! !************************************************************************** ! ! Handle IOCTL request for file. ! Input: BX - file handle ! Output: AX - error code if carry set ! Carry flag - set if error ! Registers changed: AX ! dos44: mov ax,#ERR_INVHDL ! return with error stc ret #if defined(NEEDFILEIO) && defined(NEEDEXTIO) ! !************************************************************************** ! ! Read character from device. ! Input: BX - file handle ! Output: AL - character ! Registers changed: AX ! readchar: # ifdef NEEDKBD cmp bx,#RES_STDERR ! check for keyboard input # ifdef IS386 jbe near dos07 ! read character from keyboard # else ja read2 jmp near dos07 ! read character from keyboard # endif # endif read2: cmp bx,#RES_AUX ! check for serial device # ifdef IS386 je near dos03 ! receive character # else jne read9 jmp near dos03 ! receive character # endif read9: mov al,#CHR_EOF ! nothing more to read ret #endif #if defined(NEEDFILEIO) && defined(NEEDEXTIO) ! !************************************************************************** ! ! Write character to device. ! Input: BX - file handle ! AL - character to write ! Output: none ! Registers changed: none ! writechar: push dx cmp bx,RES_STDERR ! check for console output ja write1 int $29 ! print character jmp write9 write1: mov dl,al cmp bx,RES_AUX ! check for serial device jne write2 call dos04 ! send character jmp write9 write2: cmp bx,RES_PRN ! check for printer device jne write9 call dos05 ! send character write9: pop dx ret #endif #ifdef NEEDFILEIO ! !************************************************************************** ! ! Check if a file handle is correct ! Input: BX - file handle ! Output: AX - error code if handle not correct ! Carry flag - set if file handle not correct ! Registers changed: AX ! chkhndl: # ifndef NEEDEXTIO cmp bx,#RES_AUX ! we can only use console handles # else cmp bx,#RES_HANDLES ! we can only use reserved handles # endif jae chkh8 # ifdef IS386 mov fs,[curr_psp] seg fs test byte ptr psp_handles[bx],#$0FF # else push ds mov ds,[curr_psp] test byte ptr psp_handles[bx],#$0FF pop ds # endif jnz chkh9 ! check if handle is open chkh8: mov ax,#ERR_INVHDL stc chkh9: ret #endif ! !************************************************************************** ! end