mirror of
https://github.com/FDOS/kernel.git
synced 2025-04-08 17:15:17 +02:00
SYS and printer fixes
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@307 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
a957122ff6
commit
c8f7d66461
362
boot/boot32.asm
Normal file
362
boot/boot32.asm
Normal file
@ -0,0 +1,362 @@
|
||||
; +--------+
|
||||
; | |
|
||||
; | |
|
||||
; |--------| 4000:0000
|
||||
; | |
|
||||
; | FAT |
|
||||
; | |
|
||||
; |--------| 2000:0000
|
||||
; |BOOT SEC|
|
||||
; |RELOCATE|
|
||||
; |--------| 1FE0:0000
|
||||
; | |
|
||||
; | |
|
||||
; | |
|
||||
; | |
|
||||
; |--------|
|
||||
; |BOOT SEC|
|
||||
; |ORIGIN | 07C0:0000
|
||||
; |--------|
|
||||
; | |
|
||||
; | |
|
||||
; | |
|
||||
; |--------|
|
||||
; |KERNEL |
|
||||
; |LOADED |
|
||||
; |--------| 0060:0000
|
||||
; | |
|
||||
; +--------+
|
||||
|
||||
;%define MULTI_SEC_READ 1
|
||||
|
||||
|
||||
segment .text
|
||||
|
||||
%define BASE 0x7c00
|
||||
|
||||
org BASE
|
||||
|
||||
Entry: jmp short real_start
|
||||
nop
|
||||
|
||||
; bp is initialized to 7c00h
|
||||
%define bsOemName bp+0x03 ; OEM label
|
||||
%define bsBytesPerSec bp+0x0b ; bytes/sector
|
||||
%define bsSecPerClust bp+0x0d ; sectors/allocation unit
|
||||
%define bsResSectors bp+0x0e ; # reserved sectors
|
||||
%define bsFATs bp+0x10 ; # of fats
|
||||
%define bsRootDirEnts bp+0x11 ; # of root dir entries
|
||||
%define bsSectors bp+0x13 ; # sectors total in image
|
||||
%define bsMedia bp+0x15 ; media descrip: fd=2side9sec, etc...
|
||||
%define sectPerFat bp+0x16 ; # sectors in a fat
|
||||
%define sectPerTrack bp+0x18 ; # sectors/track
|
||||
%define nHeads bp+0x1a ; # heads
|
||||
%define nHidden bp+0x1c ; # hidden sectors
|
||||
%define nSectorHuge bp+0x20 ; # sectors if > 65536
|
||||
%define xsectPerFat bp+0x24 ; Sectors/Fat
|
||||
%define xrootClst bp+0x2c ; Starting cluster of root directory
|
||||
%define drive bp+0x40 ; Drive number
|
||||
|
||||
%define LOADSEG 0x0060
|
||||
|
||||
%define FATSEG 0x2000
|
||||
|
||||
%define fat_sector bp+0x48 ; last accessed sector of the FAT
|
||||
dd 0
|
||||
|
||||
times 0x5a-$+$$ db 0
|
||||
%define fat_start bp+0x5a ; first FAT sector
|
||||
dd 0
|
||||
%define data_start bp+0x5e ; first data sector
|
||||
dd 0
|
||||
%define fat_secmask bp+0x62 ; number of clusters in a FAT sector - 1
|
||||
dw 0
|
||||
%define fat_secshift bp+0x64 ; fat_secmask+1 = 2^fat_secshift
|
||||
dw 0
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
; ENTRY
|
||||
;-----------------------------------------------------------------------
|
||||
|
||||
real_start: cld
|
||||
sub ax, ax
|
||||
mov ds, ax
|
||||
mov bp, 0x7c00
|
||||
mov ss, ax ; initialize stack
|
||||
lea sp, [bp-0x20]
|
||||
int 0x13 ; reset drive
|
||||
|
||||
mov ax, 0x1FE0
|
||||
mov es, ax
|
||||
mov si, bp
|
||||
mov di, bp
|
||||
mov cx, 0x0100
|
||||
rep movsw ; move boot code to the 0x1FE0:0x0000
|
||||
push es
|
||||
mov bx, cont
|
||||
push bx
|
||||
retf
|
||||
|
||||
cont: mov ds, ax
|
||||
mov ss, ax
|
||||
mov [drive], dl ; BIOS passes drive number in DL
|
||||
|
||||
call print
|
||||
db "Loading FreeDOS...",13,10,0
|
||||
|
||||
; FINDFILE: Searches for the file in the root directory.
|
||||
;
|
||||
; Returns:
|
||||
; DX:AX = first cluster of file
|
||||
|
||||
mov word [fat_sector], cx ; CX is 0 after movsw
|
||||
mov word [fat_sector + 2], cx
|
||||
|
||||
mov ax, word [xrootClst]
|
||||
mov dx, word [xrootClst + 2]
|
||||
ff_next_cluster:
|
||||
push dx ; save cluster
|
||||
push ax
|
||||
call convert_cluster
|
||||
jc boot_error ; EOC encountered
|
||||
|
||||
ff_next_sector:
|
||||
push bx ; save sector count
|
||||
|
||||
mov bx, LOADSEG
|
||||
mov es, bx
|
||||
sub bx, bx
|
||||
call readDisk
|
||||
push dx ; save sector
|
||||
push ax
|
||||
|
||||
mov ax, [bsBytesPerSec]
|
||||
|
||||
; Search for KERNEL.SYS file name, and find start cluster.
|
||||
ff_next_entry: mov cx, 11
|
||||
mov si, filename
|
||||
mov di, ax
|
||||
sub di, 0x20
|
||||
repe cmpsb
|
||||
jz ff_done
|
||||
|
||||
sub ax, 0x20
|
||||
jnz ff_next_entry
|
||||
pop ax ; restore sector
|
||||
pop dx
|
||||
pop bx ; restore sector count
|
||||
dec bx
|
||||
jnz ff_next_sector
|
||||
ff_find_next_cluster:
|
||||
pop ax ; restore current cluster
|
||||
pop dx
|
||||
call next_cluster
|
||||
jmp ff_next_cluster
|
||||
ff_done:
|
||||
|
||||
mov ax, [es:di+0x1A-11] ; get cluster number
|
||||
mov dx, [es:di+0x14-11]
|
||||
c4:
|
||||
sub bx, bx ; ES points to LOADSEG
|
||||
c5: push dx
|
||||
push ax
|
||||
push bx
|
||||
call convert_cluster
|
||||
jc boot_success
|
||||
mov di, bx
|
||||
pop bx
|
||||
c6:
|
||||
call readDisk
|
||||
dec di
|
||||
jnz c6
|
||||
pop ax
|
||||
pop dx
|
||||
call next_cluster
|
||||
jmp c5
|
||||
|
||||
|
||||
boot_error: call print
|
||||
db 13,10,"BOOT error!",13,10,0
|
||||
|
||||
xor ah,ah
|
||||
int 0x16 ; wait for a key
|
||||
int 0x19 ; reboot the machine
|
||||
|
||||
; input:
|
||||
; DX:AX - cluster
|
||||
; output:
|
||||
; DX:AX - next cluster
|
||||
; CX = 0
|
||||
; modify:
|
||||
; DI
|
||||
next_cluster:
|
||||
push es
|
||||
mov di, ax
|
||||
and di, [fat_secmask]
|
||||
|
||||
mov cx, [fat_secshift]
|
||||
cn_loop:
|
||||
shr dx,1
|
||||
rcr ax,1
|
||||
dec cx
|
||||
jnz cn_loop ; DX:AX fat sector where our
|
||||
; cluster resides
|
||||
; DI - cluster index in this
|
||||
; sector
|
||||
|
||||
shl di,1 ; DI - offset in the sector
|
||||
shl di,1
|
||||
add ax, [fat_start]
|
||||
adc dx, [fat_start+2] ; DX:AX absolute fat sector
|
||||
|
||||
push bx
|
||||
mov bx, FATSEG
|
||||
mov es, bx
|
||||
sub bx, bx
|
||||
|
||||
cmp ax, [fat_sector]
|
||||
jne cn1 ; if the last fat sector we
|
||||
; read was this, than skip
|
||||
cmp dx,[fat_sector+2]
|
||||
je cn_exit
|
||||
cn1:
|
||||
mov [fat_sector],ax ; save the fat sector number,
|
||||
mov [fat_sector+2],dx ; we are going to read
|
||||
call readDisk
|
||||
cn_exit:
|
||||
pop bx
|
||||
mov ax, [es:di] ; DX:AX - next cluster
|
||||
mov dx, [es:di + 2] ;
|
||||
pop es
|
||||
ret
|
||||
|
||||
|
||||
boot_success:
|
||||
mov bl, [drive]
|
||||
jmp word LOADSEG:0
|
||||
|
||||
; Convert cluster to the absolute sector
|
||||
;input:
|
||||
; DX:AX - target cluster
|
||||
;output:
|
||||
; DX:AX - absoulute sector
|
||||
; BX - [bsSectPerClust]
|
||||
;modify:
|
||||
; CX
|
||||
convert_cluster:
|
||||
cmp dx,0x0fff
|
||||
jne c3
|
||||
cmp ax,0xfff8
|
||||
jb c3 ; if cluster is EOC (carry is set), do ret
|
||||
stc
|
||||
ret
|
||||
c3:
|
||||
mov cx, dx ; sector = (cluster - 2)*clussize +
|
||||
; + data_start
|
||||
sub ax, 2
|
||||
sbb cx, byte 0 ; CX:AX == cluster - 2
|
||||
mov bl, [bsSecPerClust]
|
||||
sub bh, bh
|
||||
xchg cx, ax ; AX:CX == cluster - 2
|
||||
mul bx ; first handle high word
|
||||
; DX must be 0 here
|
||||
xchg ax, cx ; then low word
|
||||
mul bx
|
||||
add dx, cx ; DX:AX target sector
|
||||
add ax, [data_start]
|
||||
adc dx, [data_start + 2]
|
||||
ret
|
||||
|
||||
; prints text after call to this function.
|
||||
|
||||
print: pop si ; this is the first character
|
||||
xor bx, bx ; video page 0
|
||||
mov ah, 0x0E ; else print it
|
||||
print1: lodsb ; get token
|
||||
cmp al, bl ; end of string? (al == bl == 0)
|
||||
je print2 ; if so, exit
|
||||
int 0x10 ; via TTY mode
|
||||
jmp short print1 ; until done
|
||||
print2: push si ; stack up return address
|
||||
ret ; and jump to it
|
||||
|
||||
|
||||
;input:
|
||||
; DX:AX - 32-bit DOS sector number
|
||||
; ES:BX - destination buffer
|
||||
;output:
|
||||
; ES:BX points one byte after the last byte read.
|
||||
; DX:AX - next sector
|
||||
;modify:
|
||||
; ES if DI * bsBytesPerSec >= 65536, CX
|
||||
|
||||
readDisk:
|
||||
read_next: push dx
|
||||
push ax
|
||||
;
|
||||
; translate sector number to BIOS parameters
|
||||
;
|
||||
|
||||
;
|
||||
; abs = sector offset in track
|
||||
; + head * sectPerTrack offset in cylinder
|
||||
; + track * sectPerTrack * nHeads offset in platter
|
||||
;
|
||||
; t1 = abs / sectPerTrack (ax has t1)
|
||||
; sector = abs mod sectPerTrack (cx has sector)
|
||||
;
|
||||
div word [sectPerTrack]
|
||||
mov cx, dx
|
||||
|
||||
;
|
||||
; t1 = head + track * nHeads
|
||||
;
|
||||
; track = t1 / nHeads (ax has track)
|
||||
; head = t1 mod nHeads (dl has head)
|
||||
;
|
||||
xor dx, dx
|
||||
div word [nHeads]
|
||||
|
||||
; the following manipulations are necessary in order to
|
||||
; properly place parameters into registers.
|
||||
; ch = cylinder number low 8 bits
|
||||
; cl = 7-6: cylinder high two bits
|
||||
; 5-0: sector
|
||||
mov dh, dl ; save head into dh for bios
|
||||
ror ah, 1 ; move track high bits into
|
||||
ror ah, 1 ; bits 7-6 (assumes top = 0)
|
||||
xchg al, ah ; swap for later
|
||||
mov dl, byte [sectPerTrack]
|
||||
sub dl, cl
|
||||
inc cl ; sector offset from 1
|
||||
or cx, ax ; merge cylinder into sector
|
||||
|
||||
mov ax, 0x0201
|
||||
mov dl, [drive]
|
||||
int 0x13
|
||||
|
||||
pop ax
|
||||
pop dx
|
||||
jnc read_ok ; jump if no error
|
||||
xor ah, ah ; else, reset floppy
|
||||
int 0x13
|
||||
jmp read_next
|
||||
read_ok:
|
||||
add bx, word [bsBytesPerSec]
|
||||
|
||||
jnc no_incr_es ; if overflow...
|
||||
|
||||
mov cx, es
|
||||
add ch, 0x10 ; ...add 1000h to ES
|
||||
mov es, cx
|
||||
|
||||
no_incr_es:
|
||||
add ax,byte 1
|
||||
adc dx,byte 0
|
||||
ret
|
||||
|
||||
filename db "KERNEL SYS"
|
||||
|
||||
times 0x01fe-$+$$ db 0
|
||||
|
||||
sign dw 0xAA55
|
24
docs/lfnapi.txt
Normal file
24
docs/lfnapi.txt
Normal file
@ -0,0 +1,24 @@
|
||||
FreeDOS LFN aid API.
|
||||
|
||||
|
||||
struct lfn_inode
|
||||
{
|
||||
UNICODE name[255];
|
||||
|
||||
struct dirent l_dir; /* this file's dir entry image */
|
||||
|
||||
ULONG l_diroff; /* offset of the dir entry */
|
||||
CLUSTER l_dirstart; /* the starting cluster of dir */
|
||||
/* when dir is not root */
|
||||
};
|
||||
|
||||
typedef struct lfn_inode FAR * lfn_inode_ptr;
|
||||
|
||||
COUNT lfn_allocate_inode();
|
||||
COUNT lfn_free_inode(COUNT handle);
|
||||
|
||||
COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip);
|
||||
COUNT lfn_remove_entries(COUNT handle, lfn_inode_ptr lip);
|
||||
|
||||
COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip);
|
||||
COUNT lfn_dir_write(COUNT handle, lfn_inode_ptr lip);
|
84
hdr/xstructs.h
Normal file
84
hdr/xstructs.h
Normal file
@ -0,0 +1,84 @@
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* xstructs.h */
|
||||
/* */
|
||||
/* Extended DOS 7.0+ structures */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *XStructs_hRcsId = "$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct xdpbdata
|
||||
{
|
||||
UWORD xdd_dpbsize;
|
||||
struct dpb xdd_dpb;
|
||||
};
|
||||
|
||||
struct xfreespace
|
||||
{
|
||||
UWORD xfs_datasize; /* size of this structure */
|
||||
union {
|
||||
UWORD requested; /* requested structure version */
|
||||
UWORD actual; /* actual structure version */
|
||||
} xfs_version;
|
||||
ULONG xfs_clussize; /* number of sectors per cluster */
|
||||
ULONG xfs_secsize; /* number of bytes per sector */
|
||||
ULONG xfs_freeclusters; /* number of available clusters */
|
||||
ULONG xfs_totalclusters; /* total number of clusters on the drive */
|
||||
ULONG xfs_freesectors; /* number of physical sectors available */
|
||||
ULONG xfs_totalsectors; /* total number of physical sectors */
|
||||
ULONG xfs_freeunits; /* number of available allocation units */
|
||||
ULONG xfs_totalunits; /* total allocation units */
|
||||
UBYTE xfs_reserved[8];
|
||||
};
|
||||
|
||||
struct xdpbforformat
|
||||
{
|
||||
UWORD xdff_datasize; /* size of this structure */
|
||||
union {
|
||||
UWORD requested; /* requested structure version */
|
||||
UWORD actual; /* actual structure version */
|
||||
} xdff_version;
|
||||
UDWORD xdff_function; /* function number:
|
||||
00h invalidate DPB counts
|
||||
01h rebuild DPB from BPB
|
||||
02h force media change
|
||||
03h get/set active FAT number and mirroring
|
||||
04h get/set root directory cluster number
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
DWORD nfreeclst; /* # free clusters
|
||||
(-1 - unknown, 0 - don't change) */
|
||||
DWORD cluster; /* cluster # of first free
|
||||
(-1 - unknown, 0 - don't change) */
|
||||
UDWORD reserved[2];
|
||||
} setdpbcounts;
|
||||
|
||||
struct {
|
||||
UDWORD unknown;
|
||||
bpb FAR *bpbp;
|
||||
UDWORD reserved[2];
|
||||
} rebuilddpb;
|
||||
|
||||
struct {
|
||||
DWORD newmirroring; /* new active FAT/mirroring state, or -1 to get
|
||||
bits 3-0: the 0-based FAT number of the active FAT
|
||||
bits 6-4: reserved (0)
|
||||
bit 7: do not mirror active FAT to inactive FATs
|
||||
*/
|
||||
DWORD oldmirroring; /* previous active FAT/mirroring state (as above) */
|
||||
UDWORD reserved[2];
|
||||
} setmirroring;
|
||||
|
||||
struct {
|
||||
DWORD newrootclst; /* set new root directory cluster, -1 - get current */
|
||||
DWORD oldrootclst; /* get previous root directory cluster */
|
||||
UDWORD reserved[2];
|
||||
} setroot;
|
||||
} xdff_f;
|
||||
};
|
@ -37,6 +37,9 @@ static BYTE *dosfnsRcsId = "$Id$";
|
||||
* /// Added SHARE support. 2000/09/04 Ron Cemer
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.27 2001/09/24 02:21:14 bartoldeman
|
||||
* SYS and printer fixes
|
||||
*
|
||||
* Revision 1.26 2001/09/23 20:39:44 bartoldeman
|
||||
* FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling
|
||||
*
|
||||
@ -551,16 +554,15 @@ UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err)
|
||||
}
|
||||
else
|
||||
{
|
||||
REG WORD /*c,*/
|
||||
cnt = n,
|
||||
xfer = 0;
|
||||
REG WORD xfer;
|
||||
|
||||
while(cnt-- != 0 && *bp != CTL_Z){
|
||||
for(xfer = 0; xfer < n && *bp != CTL_Z; bp++, xfer++)
|
||||
{
|
||||
if (s->sft_flags & SFT_FCONOUT)
|
||||
{
|
||||
cso(*bp);
|
||||
}
|
||||
else
|
||||
else FOREVER
|
||||
{
|
||||
rq.r_length = sizeof(request);
|
||||
rq.r_command = C_OUTPUT;
|
||||
@ -568,11 +570,24 @@ UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err)
|
||||
rq.r_trans = bp;
|
||||
rq.r_status = 0;
|
||||
execrh((request FAR *) & rq, s->sft_dev);
|
||||
if (rq.r_status & S_ERROR)
|
||||
char_error(&rq, s->sft_dev);
|
||||
if (!(rq.r_status & S_ERROR))
|
||||
break;
|
||||
charloop:
|
||||
switch(char_error(&rq, s->sft_dev))
|
||||
{
|
||||
case ABORT:
|
||||
case FAIL:
|
||||
*err = DE_INVLDACC;
|
||||
return xfer;
|
||||
case CONTINUE:
|
||||
break;
|
||||
case RETRY:
|
||||
continue;
|
||||
default:
|
||||
goto charloop;
|
||||
}
|
||||
break;
|
||||
}
|
||||
++bp;
|
||||
++xfer;
|
||||
if (control_break())
|
||||
{
|
||||
handle_break();
|
||||
|
31
kernel/init-dat.h
Normal file
31
kernel/init-dat.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Included by initialisation functions */
|
||||
|
||||
#if _MSC_VER != 0
|
||||
extern __segment DosDataSeg;/* serves for all references to the DOS DATA segment
|
||||
necessary for MSC+our funny linking model
|
||||
*/
|
||||
|
||||
extern __segment DosTextSeg;
|
||||
|
||||
#define DOSFAR __based(DosDataSeg)
|
||||
#define DOSTEXTFAR __based(DosTextSeg)
|
||||
|
||||
#elif defined(__TURBOC__)
|
||||
|
||||
#define DOSFAR FAR
|
||||
#define DOSTEXTFAR FAR
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
|
||||
#define DOSFAR FAR
|
||||
#define DOSTEXTFAR FAR
|
||||
|
||||
#else
|
||||
#pragma error("unknown compiler - please adjust")
|
||||
this should simply not compile !!
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
extern BYTE DOSFAR version_flags; /* minor version number */
|
||||
|
147
kernel/lfnapi.c
Normal file
147
kernel/lfnapi.c
Normal file
@ -0,0 +1,147 @@
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* lfnapi.c */
|
||||
/* */
|
||||
/* Directory access functions for LFN aid API */
|
||||
/* Module is under construction! */
|
||||
/****************************************************************/
|
||||
|
||||
#include "portab.h"
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *lfnaidRcsId = "$Id$";
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define E_INVLDHNDL -1
|
||||
#define E_NOFREEHNDL -2
|
||||
#define E_IOERROR -3
|
||||
#define E_INVLDDRV -4
|
||||
|
||||
COUNT lfn_allocate_inode()
|
||||
{
|
||||
f_node_ptr fnp = get_f_node();
|
||||
struct cds FAR *cdsp;
|
||||
if (fnp == 0) return E_NOFREEHNDL;
|
||||
|
||||
cdsp = &CDSp->cds_table[default_drive];
|
||||
|
||||
if (cdsp->cdsDpb == 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return E_INVLDDRV;
|
||||
}
|
||||
|
||||
fnp->f_dpb = cdsp->cdsDpb;
|
||||
|
||||
if (media_check(fnp->f_dpb) < 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return E_INVLDDRV;
|
||||
}
|
||||
|
||||
fnp->f_dsize = DIRENT_SIZE * fnp->f_dpb->dpb_dirents;
|
||||
|
||||
return xlt_fnp(fnp);
|
||||
}
|
||||
|
||||
COUNT lfn_free_inode(COUNT handle)
|
||||
{
|
||||
f_node_ptr fnp = xlt_fd(handle);
|
||||
if (fnp == 0 || fnp->f_count <= 0) return E_INVLHNDL;
|
||||
|
||||
release_f_node(fnp);
|
||||
}
|
||||
|
||||
COUNT lfn_to_unicode_chunk(UNICODE FAR **nptr, UNICODE FAR **uptr,
|
||||
UCOUNT *index, COUNT count)
|
||||
{
|
||||
COUNT j;
|
||||
|
||||
for (j = 0; j < count; j++, *uptr++, *index++, *nptr++)
|
||||
{
|
||||
**nptr = **uptr;
|
||||
if (**uptr == 0) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
COUNT lfn_to_unicode(UNICODE FAR *name, UBYTE FAR *lfn_entry, UCOUNT *index)
|
||||
{
|
||||
COUNT j;
|
||||
UNICODE FAR *uptr;
|
||||
UNICODE FAR *nptr = name;
|
||||
|
||||
uptr = (UNICODE FAR *)&lfn_entry[1];
|
||||
if (!lfn_to_unicode_chunk(&nptr, &uptr, index, 5)) return 0;
|
||||
uptr = (UNICODE FAR *)&lfn_entry[0xe];
|
||||
if (!lfn_to_unicode_chunk(&nptr, &uptr, index, 6)) return 0;
|
||||
uptr = (UNICODE FAR *)&lfn_entry[0x1c];
|
||||
if (!lfn_to_unicode_chunk(&nptr, &uptr, index, 2)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip)
|
||||
{
|
||||
COUNT index = 0; /* index of the first non-filled char in the long file
|
||||
name string */
|
||||
ULONG original_diroff;
|
||||
f_node_ptr fnp = xlt_fd(handle);
|
||||
if (fnp == 0 || fnp->f_count <= 0) return E_INVLHNDL;
|
||||
|
||||
if (lfnp->l_dirstart == 0)
|
||||
{
|
||||
}
|
||||
|
||||
original_diroff = fnp->f_diroff;
|
||||
|
||||
lip->name[0] = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (dir_read(fnp) != DIRENT_SIZE) return E_IOERROR;
|
||||
if (fnp->f_dir.dir_name[0] != DELETED && fnp->f_dir.dir_name[0] != 0
|
||||
&& fnp->f_dir.dir_attrib != D_LFN)
|
||||
{
|
||||
fmemcpy(lip->l_dir, fnp->f_dir, sizeof(struct dirent));
|
||||
lip->l_diroff = fnp->f_diroff;
|
||||
lip->l_dirstart = fnp->f_dirstart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fnp->f_diroff = original_diroff - DIRENT_SIZE;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (fnp->f_diroff == 0) break;
|
||||
fnp->f_diroff -= 2*DIRENT_SIZE;
|
||||
if (dir_read(fnp) != DIRENT_SIZE) return E_IOERROR;
|
||||
if (fnp->f_dir.dir_name[0] == '\0'
|
||||
|| fnp->f_dir.dir_name[0] == DELETED) break;
|
||||
if (!lfn_to_unicode(lip->name,
|
||||
(UBYTE FAR *)fnp->f_dir, index)) break;
|
||||
}
|
||||
|
||||
if (lip->name[0] == 0)
|
||||
{
|
||||
ConvertName83ToNameSZ(lip->name, lip->l_dir.dir_name);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Calculate checksum for the 8.3 name */
|
||||
UBYTE lfn_checksum(char *name)
|
||||
{
|
||||
UBYTE sum;
|
||||
COUNT i;
|
||||
|
||||
for (sum = 0, i = 11; --i >= 0; sum += *name++)
|
||||
sum = (sum << 7) | (sum >> 1);
|
||||
|
||||
return sum;
|
||||
}
|
||||
#endif
|
@ -28,6 +28,9 @@
|
||||
; $Header$
|
||||
;
|
||||
; $Log$
|
||||
; Revision 1.5 2001/09/24 02:21:14 bartoldeman
|
||||
; SYS and printer fixes
|
||||
;
|
||||
; Revision 1.4 2001/09/23 20:39:44 bartoldeman
|
||||
; FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling
|
||||
;
|
||||
@ -106,19 +109,29 @@ uPrtQuantum dw 50h
|
||||
|
||||
PrtWrite:
|
||||
jcxz PrtWr3 ; Exit if nothing to write
|
||||
PrtWr1:
|
||||
mov bx,2 ; number of retries
|
||||
PrtWr2:
|
||||
|
||||
call PrintSingleCharacter
|
||||
PrtCharLoop: ; next character loop
|
||||
|
||||
mov bx, 2 ; number of retries
|
||||
PrtRetryTwice:
|
||||
mov ah, PRT_GETSTATUS ; get status, ah=2
|
||||
call PrtIOCall ;
|
||||
jnz PrtWr4
|
||||
|
||||
jnz PrtWr4 ; Exit if done
|
||||
loop PrtWr1 ; otherwise loop
|
||||
mov al,[es:di]
|
||||
|
||||
mov ah, PRT_WRITECHAR ; print character, ah=0
|
||||
call PrtIOCall ; (0800)
|
||||
|
||||
jnz PrtWr4 ; NZ = error, retry
|
||||
|
||||
inc di
|
||||
loop PrtCharLoop ; next character
|
||||
PrtWr3:
|
||||
jmp _IOExit
|
||||
PrtWr4:
|
||||
PrtWr4: ; repeat
|
||||
dec bx
|
||||
jnz PrtWr2
|
||||
jnz PrtRetryTwice
|
||||
PrtWr5:
|
||||
jmp _IOErrCnt
|
||||
|
||||
@ -141,18 +154,27 @@ GetPrtStat:
|
||||
|
||||
PrtIOCall:
|
||||
call GetUnitNum
|
||||
int 17h ; print char al, get status ah
|
||||
test ah, PRT_TIMEOUT|PRT_IOERROR
|
||||
jnz PrtIOCal2
|
||||
mov al, E_PAPER
|
||||
test ah, PRT_OUTOFPAPER
|
||||
jnz PrtIOCal1
|
||||
inc al ; al<-E_WRITE
|
||||
PrtIOCal1:
|
||||
retn
|
||||
PrtIOCal2:
|
||||
int 17h ; print char al, get status ah
|
||||
|
||||
mov al, ah ; if (stat & 0x30) == 0x30 return 10;
|
||||
and al, PRT_SELECTED|PRT_OUTOFPAPER
|
||||
cmp al, PRT_SELECTED|PRT_OUTOFPAPER
|
||||
mov al, E_WRITE
|
||||
je ret_error_code
|
||||
|
||||
test ah, PRT_OUTOFPAPER|PRT_IOERROR|PRT_TIMEOUT ; 29h
|
||||
mov al, E_NOTRDY
|
||||
test ah, PRT_TIMEOUT
|
||||
jz ret_error_code
|
||||
|
||||
test ah, PRT_OUTOFPAPER ; 20h
|
||||
mov al, E_WRITE
|
||||
jz ret_error_code ; not out of paper -> E_WRITE
|
||||
|
||||
ret_error_code_9:
|
||||
mov al, E_PAPER
|
||||
|
||||
ret_error_code:
|
||||
cmp al, E_NOTRDY ; 2 = no error
|
||||
retn
|
||||
|
||||
|
||||
@ -222,8 +244,11 @@ PrtGnIoctl3:
|
||||
|
||||
|
||||
;
|
||||
; original implementation didn't work at all.
|
||||
; this one's not much better either,
|
||||
; some comments to last changes (TE, 23/09/01)
|
||||
;
|
||||
; original implementation didn't print at all - on my machine,LPT2
|
||||
;
|
||||
; maybe this one's not much better either,
|
||||
; but should print a little bit
|
||||
;
|
||||
; the status bits = AH
|
||||
@ -242,42 +267,7 @@ PrtGnIoctl3:
|
||||
; 10 - printer with power, but not initialized
|
||||
; 90 - this one is fine
|
||||
;
|
||||
|
||||
|
||||
; you must not simply print without asking for status
|
||||
; as the BIOS has a LARGE timeout before aborting
|
||||
;
|
||||
|
||||
PrintSingleCharacter:
|
||||
|
||||
mov ah, PRT_GETSTATUS ; get status, ah=2
|
||||
call GetUnitNum
|
||||
int 17h ; print char al, get status ah
|
||||
|
||||
test ah, PRT_OUTOFPAPER|PRT_IOERROR
|
||||
jnz decode_error
|
||||
|
||||
test ah, PRT_NOTBUSY
|
||||
jz decode_error
|
||||
|
||||
|
||||
mov al,[es:di]
|
||||
mov ah,PRT_WRITECHAR ; print character, ah=0
|
||||
call GetUnitNum
|
||||
int 17h ; print char al, get status ah
|
||||
|
||||
test ah, PRT_OUTOFPAPER|PRT_IOERROR|PRT_TIMEOUT
|
||||
jnz decode_error
|
||||
inc di
|
||||
xor al,al ; set zero flag + clear al
|
||||
ret
|
||||
|
||||
|
||||
decode_error:
|
||||
mov al, E_PAPER
|
||||
test ah, PRT_OUTOFPAPER ;out_of_paper, 20h
|
||||
jnz out_of_paper
|
||||
mov al, E_WRITE
|
||||
out_of_paper:
|
||||
or al,al ; reset zero flag
|
||||
ret
|
||||
|
Loading…
x
Reference in New Issue
Block a user