#include "../_sdk/io.h"
#include "../_sdk/str.h"
STRUCT FCB{
CHAR mode; //0 = free, 'r' = read, 'w' = write
//copy of TR-DOS descriptor
CHAR fn;
CHAR fn1;
CHAR fn2;
CHAR fn3;
CHAR fn4;
CHAR fn5;
CHAR fn6;
CHAR fn7;
CHAR ext;
BYTE block; //cur block for write, next block for read (start LSB)
BYTE blockpad; // (start HSB)
BYTE lastlenLSB; BYTE lastlenHSB; //length of block in bytes //TODO т√Ёртэштрэшх!!!
BYTE secinblk; //sectors remained in block (for read), block size (for write)
BYTE firstsectorLSB; BYTE firstsectorHSB; //first sector of block (for write) //TODO т√Ёртэштрэшх!!!
//end of TR-DOS descriptor
BYTE cursectorLSB; BYTE cursectorHSB; //cur sector for write, next sector for read //TODO т√Ёртэштрэшх!!!
BYTE remain; //remaining bytes in buf (for read)
BYTE secwritten; //sectors written (for write)
BYTE descpos; //position of descriptor (for write) 0..127
//BYTE buf; //256 bytes padded
};
/**
_fin
EXPORT _fin
DW 0
_fout
EXPORT _fout
DW 0
_waseof
EXPORT _waseof
DB 0
FCB1=0x4800 ;aligned ;len=0x0200
DOSBUF=0xff00 ;aligned
*/
EXPORT VAR PBYTE _fin;
EXPORT VAR PBYTE _fout;
EXPORT VAR BOOL _waseof;
CONST PBYTE FCB1; // = 0x4800; //aligned ;len=0x0200
//#define FCB1 (PBYTE)(0x4800) /**aligned, len = 0x0200 every FCB*/
CONST PBYTE DOSBUF; // = 0xff00; //aligned
//#define DOSBUF (PBYTE)(0xff00) /**aligned*/
VAR PBYTE pdesc;
#define DOSBUFfreesectorsLSB (PBYTE)(DOSBUF+0x00e5)
#define DOSBUFfreesectorsHSB (PBYTE)(DOSBUF+0x00e6)
#define DOSBUFfiles (PBYTE)(DOSBUF+0x00e4)
#define DOSBUFfreesectorLSB (PBYTE)(DOSBUF+0x00e1)
#define DOSBUFfreesectorHSB (PBYTE)(DOSBUF+0x00e2)
FUNC BOOL findfile(FCB* pfcb, BYTE namesz)
{
//find new block if exists
//find Nth block of file with hl pointed filename (10 bytes: name, ext, block N)
VAR PBYTE pfn;
VAR BYTE sector;
VAR BYTE i;
VAR BYTE b;
VAR BOOL res = +TRUE; //found
sector = 0x00;
REPEAT {
readsectors(DOSBUF, (UINT)sector, 0x01);
pdesc = DOSBUF;
#define DOSBUFEND (UINT)(DOSBUF+0x0100)
REPEAT {
pfn = (PBYTE)&(pfcb->fn);
i = 0x00;
REPEAT {
b = *(PBYTE)pfn;
INC pfn;
IF (pdesc[i] != b) goto wrong;
INC i;
}UNTIL (i == namesz/**0x0a*/); //bytes to compare
goto found;
wrong:
pdesc = &pdesc[16];
}UNTIL ((UINT)pdesc == DOSBUFEND); //next descriptor
INC sector;
}UNTIL (sector == 0x08); //next sector
res = +FALSE; //not found
found:
RETURN res;
}
/**
findlastslash
findlastslash.A.=$+1
ld hl,0
;hl = poi to filename in string
nfopenfnslash.
ld d,h
ld e,l ;de = after last slash
;find last slash
nfopenfnslash0.
ld a,[hl]
inc hl
or a
jr z,nfopenfnslashq.
cp '/'
jr nz,nfopenfnslash0.
jr nfopenfnslash.
nfopenfnslashq.
ex de,hl
;hl = after last slash
ret
*/
EXPORT FUNC PCHAR findlastslash(PCHAR s)
{
VAR PCHAR slast;
VAR CHAR c;
loopslash:
slast = s;
loop:
c = *(PCHAR)s;
INC s;
IF (c == '\0') goto quit;
IF (c == '/') goto loopslash;
goto loop;
quit:
RETURN slast;
}
/**
nfopen
;todo яЁютхЁ Є№ эрышўшх Їрщыр яЁш юЄъЁ√Єшш эр ўЄхэшх
EXPORT nfopen
xor a
ld hl,FCB1-0x0200
inc h
inc h
cp [hl]
jr nz,$-3
;nfopenFCB
nfopen.B.=$+1
EXPORT nfopen.B.
ld a,[0] ;poi to mode ("wb"/"rb")
ld [hl],a ;mode in FCB
inc hl ;poi to fn in FCB
push hl ;poi to fn in FCB
ld d,h
ld e,l
inc de
ld [hl],' '
ld bc,8
ldir ;empty filename
nfopen.A.=$+1
EXPORT nfopen.A.
ld hl,0 ;poi to filename in string
ld [findlastslash.A.],hl
call findlastslash
ex de,hl
;de = after last slash
pop hl ;poi to fn in FCB
ld b,9
nfopenfn0.
ld a,[de]
or a
jr z,nfopenfnq. ;no extension in string
inc de
cp '.'
jr z,nfopenfndot.
ld [hl],a
inc hl
djnz nfopenfn0.
;9 bytes in filename, no dot (9th byte goes to extension)
jr nfopenfnq.
nfopenfndot.
inc hl
djnz $-1 ;hl points to extension in FCB
dec hl
ld a,[de] ;extension in string
ld [hl],a ;extension in FCB
nfopenfnq.
xor a
ld l,FCB.block
ld [hl],a;0 ;cur block for write, next block for read
inc hl
ld [hl],0x60 ;(padding for "start")
inc hl
ld [hl],a;0 ;lastlen LSB ;???
inc hl
ld [hl],a;0 ;lastlen HSB ;???
inc hl
ld [hl],a;0 ;sectors remained in block (for read), block size (for write)
ld l,FCB.remain
ld [hl],0xff ;remain (0xff = no data) for read
inc hl
ld [hl],a;0 ;sectors written (for write)
ld l,a;0;FCB.mode
ret ;hl = poi to FCB
*/
EXPORT FUNC PBYTE nfopen(PCHAR filename, PCHAR pmode)
{
VAR FCB* pfcb = (FCB*)((UINT)FCB1 - 0x0200);
VAR BYTE i = 0x09;
VAR CHAR c;
//VAR PBYTE pdesc;
REPEAT {
pfcb = (FCB*)((UINT)pfcb + 0x0200);
}UNTIL (*(PBYTE)pfcb == 0x00); //first free FCB
//pfcb->mode = *(PCHAR)pmode; //see in the end if success
pdesc = (PBYTE)&(pfcb->fn); //poi to fn in FCB
memcopy((PBYTE)" ", 9, pdesc); //from, len, to
filename = findlastslash(filename); //after last slash
REPEAT {
c = *(PCHAR)filename;
IF (c == '\0') goto nfopenfnq; //no extension in string
INC filename;
IF (c == '.') goto nfopenfndot;
POKE *(PCHAR)(pdesc) = c;
INC pdesc;
DEC i;
}UNTIL (i == 0x00);
//9 bytes in filename, no dot (9th byte goes to extension)
goto nfopenfnq;
nfopenfndot:
pfcb->ext = *(PCHAR)filename;
nfopenfnq:
pfcb->block = 0x00; //cur block (for write!!!)
pfcb->blockpad = 0x60; //padding for "start"
/**
ld l,a;0
ld a,(hl)
cp 'w'
jr z,nfopen_nofindfile. ;TODO єфрышЄ№, хёыш хёЄ№
;яЁютхЁшЄ№, ўЄю Їрщы ёє∙хёЄтєхЄ, шэрўх тхЁэєЄ№ ю°шсъє ш юётюсюфшЄ№ FCB
ld c,9 ;FILENAMESZ
call findfile
or a
jr nz,nfopen_fail.
;hl,de = after filename
;open for read!
ld l,FCB.block
ld a,(de)
inc de
ld [hl],a;0 ;cur block for write, next block for read
inc hl
ld a,(de)
inc de
ld [hl],a;0x60 ;(padding for "start")
;ld a,FALSE
;ld [_waseof],a
nfopen_nofindfile.
*/
IF (*(PCHAR)pmode != 'w') {
IF (!findfile(pfcb, 0x09)) {
pfcb = (FCB*)0;
goto nfopenfail;
};
memcopy(pdesc, 11, (PBYTE)&(pfcb->fn)); //from, len, to
};
pfcb->lastlenLSB = 0x00;
pfcb->lastlenHSB = 0x00;
pfcb->secinblk = 0x00; //sectors remained in block (for read), block size (for write)
pfcb->remain = 0xff; //remain (0xff = no data) for read
pfcb->secwritten = 0x00; //sectors written (for write)
pfcb->mode = *(PCHAR)pmode;
nfopenfail:
RETURN (PBYTE)pfcb;
}
/**
topenwr.
db "wb"
db 0
openwrite
EXPORT openwrite
ld hl,topenwr.
ld [nfopen.B.],hl
openwrite.A.=$+1
EXPORT openwrite.A.
ld hl,0 ;filename
ld [nfopen.A.],hl
jp nfopen
*/
EXPORT FUNC PBYTE openwrite(PCHAR s)
{
RETURN nfopen(s, "wb");
}
/**
flushdesc
flushdesc.A.=$+1
ld hl,0
push hl ;poi to FCB
ld l,FCB.descpos
ld l,[hl]
ld d,0 ;track of descriptor
ld h,d;0
add hl,hl
add hl,hl
add hl,hl
add hl,hl
ld e,h ;sector of descriptor
ld h,DOSBUF.>>8
push hl ;hl = poi to descriptor
push de ;track,sector of descriptor
call rdsecDOSBUF.
pop bc ;track,sector of descriptor
pop de ;poi to descriptor
pop hl ;poi to FCB
ld l,FCB.fn
push bc ;track,sector of descriptor
ld bc,16
ldir
pop de ;track,sector of descriptor
ld hl,DOSBUF.
call wrsec.
ret
*/
//write descriptor
//if created or finished
PROC flushdesc(FCB* pfcb)
{
VAR UINT trsec = (UINT)((pfcb->descpos)>>0x04);
//VAR PBYTE pdesc;
pdesc = (PBYTE)((UINT)DOSBUF + (UINT)((pfcb->descpos)<<0x04));
readsectors(DOSBUF, trsec, 0x01);
// memcopy(/**from*/(PBYTE)&(pfcb->fn)/**(PBYTE)((UINT)pfcb+1)*/, 16, /**to*/pdesc); //ёюфхЁцшьюх ёЄЁєъЄєЁ√ чртшёшЄ юЄ яюЁ фър срщЄют т ёыютх ш ЁрчьхЁр UINT!!!
memcopy((PBYTE)&(pfcb->fn), 11, pdesc); //from,len,to
pdesc = &pdesc[11];
POKE *(PBYTE)(pdesc) = pfcb->lastlenLSB;
INC pdesc;
POKE *(PBYTE)(pdesc) = pfcb->lastlenHSB;
INC pdesc;
POKE *(PBYTE)(pdesc) = pfcb->secinblk;
INC pdesc;
POKE *(PBYTE)(pdesc) = pfcb->firstsectorLSB;
INC pdesc;
POKE *(PBYTE)(pdesc) = pfcb->firstsectorHSB;
writesectors(DOSBUF, trsec, 0x01);
}
/**
flushwritebuf
flushwritebuf.A.=$+1
ld hl,0
;write buf
ld l,FCB.cursector
push hl ;poi to cursector
ld e,[hl]
inc hl
ld d,[hl]
ld l,0
inc h ;poi to buf
call wrsec.
ex de,hl ;ld de,(0x5cf4) ;de=next sector
pop hl ;poi to cursector
ld [hl],e
inc hl
ld [hl],d
;increase secwritten
;get new block if this block filled up
ld l,FCB.secinblk
ld a,[hl]
ld l,FCB.secwritten
inc [hl]
sub [hl]
jr nz,flushnblk. ;not filled up
;block is filled up
;zero secwritten
;ld l,FCB.secwritten
ld [hl],a;0 ;block not created
;write descriptor
ld l,0
ld (flushdesc.A.),hl
push hl
call flushdesc
pop hl
;increase block number (after flushdesc!!!)
ld l,FCB.block
inc [hl] ;cur block for write, next block for read
;ЄхяхЁ№ фхёъЁшяЄюЁ эхтрышфэ√щ, яюър эх ёючфрфшь хую т эрўрых фЁєуюую flush
;zero lastlen (after flushdesc!!!)
ld l,FCB.lastlen+1 ;(HSB), LSB is already 0 if not fclose
ld [hl],0
flushnblk.
ret
*/
PROC flushwritebuf(FCB* pfcb)
{
VAR UINT cursector;
//1Ёрч
cursector = writesectors((PBYTE)((UINT)pfcb+0x100), (UINT)(pfcb->cursectorLSB) + ((UINT)(pfcb->cursectorHSB)<<8), 0x01);
pfcb->cursectorLSB = (BYTE)cursector;
pfcb->cursectorHSB = (BYTE)(cursector>>8);
INC *(&(pfcb->secwritten)); //pfcb->secwritten = pfcb->secwritten + 0x01;
IF (pfcb->secwritten == pfcb->secinblk) { //block is filled up
//эх яюярыш
pfcb->secwritten = 0x00;
flushdesc(pfcb);
INC *(&(pfcb->block)); //pfcb->block = pfcb->block + 0x01; //cur block for write, next block for read
//ЄхяхЁ№ фхёъЁшяЄюЁ эхтрышфэ√щ, яюър эх ёючфрфшь хую т эрўрых фЁєуюую flush
pfcb->lastlenLSB = 0x00;
pfcb->lastlenHSB = 0x00;
};
}
/**
flush_
flush_.A.=$+1
ld hl,0 ;hl = poi to FCB
;if secwritten == 0 then reserve sectors, reserve descriptor
ld l,FCB.secwritten
ld a,[hl]
or a
jr nz,flushnnew.
;уы■ўшЄ, хёыш яюёыхфэшщ сыюъ <256
;яюЄюьє ўЄю fclose тЄюЁющ Ёрч т√ч√трхЄ flush
ld l,FCB.secinblk
ld [hl],16 ;TR-DOS reserves 16 sectors per block
;update sec8
push hl ;poi to FCB
ld de,0x0008
push de
ld hl,DOSBUF
call rdsec.
pop de ;0x0008
ld hl,[DOSBUF+0xe5] ;free sectors
ld bc,-16
add hl,bc
;bit 7,h
;jr nz,$ ;no free sectors
ld [DOSBUF+0xe5],hl ;free sectors
ld hl,DOSBUF+0xe4 ;files
ld a,[hl] ;descriptor position 0..127
;or a
;jp m,$ ;128 files, can't add
inc [hl] ;files
ld l,0xe1 ;free sector
ld c,[hl]
inc hl
ld b,[hl]
inc [hl] ;add 16 sectors = add 1 track
pop hl ;poi to FCB
ld l,FCB.descpos
ld [hl],a ;descriptor position 0..127
ld l,FCB.firstsector
ld [hl],c
inc hl
ld [hl],b
ld l,FCB.cursector
ld [hl],c
inc hl
ld [hl],b
push hl ;poi to FCB
ld hl,DOSBUF
;ld de,0x0008
call wrsec. ;write sec8
pop hl ;poi to FCB
flushnnew.
ld l,0
ld (flushwritebuf.A.),hl
jp flushwritebuf
*/
//Ёєўэющ flush яюър эхтючьюцхэ!!!
//can create zero length file
PROC flush_(FCB* pfcb)
{
VAR BYTE firstsectorLSB;
VAR BYTE firstsectorHSB;
VAR UINT freesectors;
IF (pfcb->secwritten == 0x00) { //reserve sectors, reserve descriptor
//уы■ўшЄ, хёыш яюёыхфэшщ сыюъ <256
//яюЄюьє ўЄю fclose тЄюЁющ Ёрч т√ч√трхЄ flush
pfcb->secinblk = 0x10; //TR-DOS reserves 16 sectors per block
//update sec8
readsectors(DOSBUF, 0x0008, 0x01);
//POKE *(PUINT)(/**(UINT)DOSBUF+0x00e5*/DOSBUFfreesectors) = *(PUINT)(/**(UINT)DOSBUF+0x00e5*/DOSBUFfreesectors) - 16; //free sectors //todo check < 0
freesectors = ((UINT)*(PBYTE)DOSBUFfreesectorsHSB << 8) + (UINT)*(PBYTE)DOSBUFfreesectorsLSB - 16;
// freesectors = (UINT)*(PBYTE)DOSBUFfreesectorsLSB + ((UINT)*(PBYTE)DOSbuffreesectorsHSB << 8) - 16; //todo эрщЄш уы■ъ т рёёхьсыхЁх!!! яюўхьє эх эрїюфшЄ ьхЄъє DOSbuffreesectorsHSB???
POKE *(PBYTE)(DOSBUFfreesectorsLSB) = (BYTE)freesectors;
POKE *(PBYTE)(DOSBUFfreesectorsHSB) = (BYTE)(freesectors>>8);
pfcb->descpos = *(PBYTE)(/**(UINT)DOSBUF+0x00e4*/DOSBUFfiles); //descriptor position 0..127
POKE *(PBYTE)(/**(UINT)DOSBUF+0x00e4*/DOSBUFfiles) = pfcb->descpos + 0x01; //files //todo check >=128
//*(PUINT)(/**(UINT)DOSBUF+0x00e1*/DOSBUFfreesector); //free sector
firstsectorLSB = *(PBYTE)DOSBUFfreesectorLSB;
firstsectorHSB = *(PBYTE)DOSBUFfreesectorHSB;
pfcb->firstsectorLSB = firstsectorLSB;
pfcb->firstsectorHSB = firstsectorHSB;
pfcb->cursectorLSB = firstsectorLSB;
pfcb->cursectorHSB = firstsectorHSB;
//POKE *(PUINT)(/**(UINT)DOSBUF+0x00e1*/DOSBUFfreesector) = firstsector + 0x0100; //add 16 sectors = add 1 track
POKE *(PBYTE)(DOSBUFfreesectorHSB) = firstsectorHSB + 0x01;
//1Ёрч
//goto l1;l1:
writesectors(DOSBUF, 0x0008, 0x01);
//goto l2;l2:
};
flushwritebuf(pfcb);
}
/**
comparedesc
comparedesc.A.=$+1 ;filename
ld hl,0
ld [findlastslash.A.],hl
call findlastslash
ex de,hl
;de = after last slash
comparedesc.B.=$+1 ;desc
ld hl,0
;compare until '.' or '\0' or 8 loops
ld b,8
comparedesc0.
ld a,[de] ;filename
inc de ;todo test '\0', descbuf all spaces
cp '.'
jr z,comparedescdot.
cp [hl] ;descriptor
jr nz,comparedescfalse.
inc hl
djnz comparedesc0.
ld a,[de] ;filename
inc de
cp '.'
jr z,comparedescdot8. ;filenam8.ext
;filenam8 (without ext)
ld a,[hl]
cp ' '
jr nz,comparedescfalse.
comparedesctrue.
ld a,0xff ;TRUE
ret
comparedescdot.
inc hl
djnz $-1 ;hl = descriptor ext
comparedescdot8.
ld a,[de] ;filename ext
cp [hl] ;descriptor ext
jr z,comparedesctrue.
comparedescfalse.
xor a ;FALSE
ret
*/
/**
FUNC BOOL comparedesc(PCHAR filename, PBYTE desc)
{
VAR CHAR c;
VAR BOOL res;
VAR BYTE i = 0x08;
filename = findlastslash(filename);
loop:
c = *(PCHAR)filename;
INC filename;
IF (c == '.') { //todo test '\0', descbuf all spaces
dot:
//desc = (PBYTE)((UINT)desc + (UINT)i);
res = (*(PCHAR)((UINT)desc + (UINT)i) == *(PCHAR)filename);
goto quit;
};
IF (c != *(PCHAR)desc) {
res = +FALSE;
goto quit;
};
INC desc;
DEC i;
IF (i == 0x00) {
c = *(PCHAR)filename;
INC filename;
//IF (c == '.')
goto dot;
//res = (*(PCHAR)desc == ' '); //filenam8 (without ext) //TODO
//goto quit;
};
goto loop;
quit:
RETURN res;
}
*/
/**
fread_readnextsector
fread_readnextsector.A.=$+1
ld hl,0
ld l,FCB.cursector
push hl ;poi to cursector
ld e,[hl]
inc hl
ld d,[hl]
inc h
ld l,0;a;0 ;poi to buf
call rdsec.
ex de,hl ;ld de,[0x5cf4] ;de=next sector
pop hl ;poi to cursector
ld [hl],e
inc hl
ld [hl],d
ret
*/
/**
PROC fread_readnextsector(FCB* pfcb)
{
pfcb->cursector = readsectors((PBYTE)((UINT)pfcb+0x100), pfcb->cursector, 0x01);
}
*/
/**
fread1sec
fread1sec.A.=$+1
ld hl,0
ld (fread_readnextsector.A.),hl
push hl
call fread_readnextsector
pop hl
;if last sector of block, then remain = -lastlen and shift data in buf to the end
;else remain = 0 (read + 255 bytes)
xor a
ld l,FCB.secinblk
dec [hl] ;sectors remained in block
jr nz,fread1nlast.
;last sector in block: shift data to the end of buf
ld l,FCB.lastlen
ld c,[hl] ;1..256
ld b,a;0
dec c ;0..255
ld l,c ;end of data
inc h
inc bc ;1..256
ld d,h
ld e,0xff
lddr
;hl = poi to buf - 1
;h = poi to FCB
ld a,e ;0xfe (1 byte) ... -1 (256 bytes)
inc a ;remain = 0xff (read + no data) ... 0 (read + 255 bytes)
fread1nlast.
ld l,FCB.remain
ld [hl],a
ret
*/
PROC fread1sec(FCB* pfcb)
{
VAR BYTE eod;
VAR UINT cursector;
//1Ёрч
//fread_readnextsector(pfcb);
cursector = readsectors((PBYTE)((UINT)pfcb+0x100), (UINT)(pfcb->cursectorLSB) + ((UINT)(pfcb->cursectorHSB)<<8), 0x01);
pfcb->cursectorLSB = (BYTE)cursector;
pfcb->cursectorHSB = (BYTE)(cursector>>8);
//if last sector of block, then remain = -lastlen and shift data in buf to the end
//else remain = 0 (read + 255 bytes)
pfcb->remain = 0x00;
DEC *(&(pfcb->secinblk)); //sectors remained in block
IF (pfcb->secinblk == 0x00) {
//last sector in block: shift data to the end of buf
eod = pfcb->lastlenLSB - 0x01; //1..256 => 0..255
memcopyback(
(PBYTE)((UINT)pfcb + 0x0100 + (UINT)eod), //end of data
(UINT)eod + 1, //1..256
(PBYTE)((UINT)pfcb + 0x01ff) //end of buf
);
pfcb->remain = ~eod; //0xff (read + no data) ... 0 (read + 255 bytes)
};
}
/**
fread1blkq
fread1blkq.A.=$+1 ;FCB
ld hl,0
fread1blkq.B.=$+1 ;desc
ld de,0
;de = poi to descriptor ;+ 10
;hl = FCB
ld l,FCB.fn ;+ 10
ex de,hl
;hl = poi to descriptor ;+ 10
;de = poi to filename ;+ 10
ld bc,16;6 ;padding, len(LSB), len(HSB), secinblk, sec, track
ldir
ex de,hl
ld l,FCB.firstsector
ld e,[hl]
inc hl
ld d,[hl]
ld l,FCB.cursector
ld [hl],e
inc hl
ld [hl],d
;secinblk = (lastlen+255)/256 = (lastlen-1)/256 + 1
;шэрўх эхы№ч сєфхЄ т√фхы Є№ сыюъш эрт√ЁюёЄ (ъръ фхырхЄ TR-DOS)
ld l,FCB.lastlen
ld e,[hl]
inc hl
ld d,[hl]
dec de
inc d
inc hl ;ld l,FCB.secinblk
ld [hl],d
jr z,fread1qEOF. ;(secinblk == 0)
ld l,FCB.block
inc [hl] ;cur block for write, next block for read
ld a,0xff ;TRUE ;no EOF
ret
fread1qEOF.
xor a
ret
*/
FUNC BOOL fread1blkq(FCB* pfcb, PBYTE pdesc1)
{
VAR BOOL res = +FALSE; //EOF
//memcopy(pdesc1, 16, (PBYTE)&(pfcb->fn)); //from, len, to //ёюфхЁцшьюх ёЄЁєъЄєЁ√ чртшёшЄ юЄ яюЁ фър срщЄют т ёыютх ш ЁрчьхЁр UINT!!!
memcopy(pdesc1, 11, (PBYTE)&(pfcb->fn)); //from, len, to
pdesc1 = &pdesc1[11];
pfcb->lastlenLSB = *(PBYTE)(pdesc1);
pfcb->lastlenHSB = *(PBYTE)((UINT)pdesc1+1);
pdesc1 = &pdesc1[2];
pfcb->secinblk = *(PBYTE)(pdesc1);
INC pdesc1;
pfcb->firstsectorLSB = *(PBYTE)(pdesc1);
pfcb->firstsectorHSB = *(PBYTE)((UINT)pdesc1+1);
pfcb->cursectorLSB = pfcb->firstsectorLSB;
pfcb->cursectorHSB = pfcb->firstsectorHSB;
//secinblk = (lastlen+255)/256 = (lastlen-1)/256 + 1
//шэрўх эхы№ч сєфхЄ т√фхы Є№ сыюъш эрт√ЁюёЄ (ъръ фхырхЄ TR-DOS)
pfcb->secinblk = (BYTE)(((UINT)(pfcb->lastlenLSB) + ((UINT)(pfcb->lastlenHSB)<<8) + 0x00ff) >> 8);
IF (pfcb->secinblk != 0x00) {
INC *(&(pfcb->block)); //cur block for write, next block for read
res = +TRUE; //no EOF
};
RETURN res;
}
/**
readnewbuf
;read new buf (if exists)
readnewbuf.A.=$+1
ld hl,0
ld l,FCB.secinblk
xor a
cp [hl] ;sectors remained in block (0 means none)
jr nz,fread1sec. ;a = 0
;find new block if exists
;find Nth block of file with hl pointed filename (10 bytes: name, ext, block N)
ld b,8 ;sectors
findfile0.
push bc
push hl
ld d,0 ;track
ld a,8
sub b
ld e,a ;sector
ld hl,DOSBUF
ld b,1
call rdsectors.
pop hl
pop bc
;hl=filename
;b=sectors
ld de,DOSBUF
findfilecp0.
ld l,0
ld (fread1blkq.A.),hl ;FCB
ld (fread1blkq.B.),de ;desc
ld l,FCB.fn ;poi to fn
push bc
ld bc,0x0a00 ;b=bytes to compare, c=errors
findfilecp00.
ld a,[de]
sub [hl]
or c
ld c,a ;errors
inc hl
inc de
djnz findfilecp00.
pop bc
jr z,fread1blkq. ;ret z ;found (carry = off, a = 0)
ld a,e
add a,6
ld e,a
jr nz,findfilecp0. ;next descriptor
djnz findfile0. ;next sector
;not found
xor a ;EOF
ret
fread1blkq.
;de = poi to descriptor ;+ 10
;hl = poi to fn ;+ 10
push hl
call fread1blkq
pop hl
or a ;EOF
ret z;jr z,fread1EOF.
fread1sec.
ld l,0
ld (fread1sec.A.),hl
call fread1sec
ld a,0xff ;not EOF
ret
*/
FUNC BOOL readnewbuf(FCB* pfcb)
{
VAR BOOL res = +FALSE; //EOF
IF (pfcb->secinblk == 0x00) { //sectors remained in block (0 means none)
IF (!findfile(pfcb, 0x0a)) goto quit; //EOF
IF (!fread1blkq(pfcb, pdesc)) goto quit; //EOF
};
fread1sec(pfcb);
res = +TRUE; //not EOF
quit:
RETURN res;
}
/**
fputs
EXPORT fputs
;todo optimize
fputs.A.=$+1
EXPORT fputs.A.
ld bc,0 ;poi to string
jp fputsgo.
fputs0.
fputs.B.=$+1
EXPORT fputs.B.
ld hl,0 ;poi to FCB
call fwrite1. ;a=data
inc bc
fputsgo.
ld a,[bc]
or a
jp nz,fputs0.
ret ;end of string ;(TODO hl = non-negative value)
*/
EXPORT FUNC INT
fputs(PCHAR s
, PBYTE file
)
{
VAR CHAR c;
loop:
c = *(PCHAR)s;
IF (c == '\0') goto quit;
fwrite((PBYTE
)&c
, 1, 1, file
);
INC s;
goto loop;
quit:
RETURN +1; //OK
}
/**
closewrite
EXPORT closewrite
fclose
EXPORT fclose
closewrite.A.=$+1
EXPORT closewrite.A.
fclose.A.=$+1
EXPORT fclose.A.
ld hl,0 ;poi to FCB
ld a,[hl]
ld [hl],l;0
cp 'w'
ret nz ;hl!=0
;hl = poi to FCB
push hl
ld (flush_.A.),hl
call flush_
pop hl
;ёыхфє■∙р яЁютхЁър эх уюфшЄё , хёыш сєфхЄ Ёєўэющ flush:
ld l,FCB.secwritten
ld a,[hl]
or a
ret z ;no sectors written - descriptor already saved
ld l,0
ld (flushdesc.A.),hl
call flushdesc
;ld l,1 ;OK TODO
ret ;hl!=0
*/
EXPORT FUNC INT
fclose(PBYTE file
)
{
VAR FCB* pfcb = (FCB*)file;
VAR CHAR mode = pfcb->mode;
pfcb->mode = '\0';
IF (mode == 'w') {
flush_(pfcb);
IF (pfcb->secwritten != 0x00) {
flushdesc(pfcb);
};
};
RETURN +1; //OK
}
/**
EXPORT PROC closewrite(PBYTE file)
{
fclose(file);
}
*/