?login_element?

Subversion Repositories NedoOS

Rev

Rev 49 | Blame | Compare with Previous | Last modification | View Log | Download

  1. #include "../_sdk/io.h"
  2. #include "../_sdk/str.h"
  3.  
  4. STRUCT FCB{
  5.   CHAR mode; //0 = free, 'r' = read, 'w' = write
  6. //copy of TR-DOS descriptor
  7.   CHAR fn;
  8.   CHAR fn1;
  9.   CHAR fn2;
  10.   CHAR fn3;
  11.   CHAR fn4;
  12.   CHAR fn5;
  13.   CHAR fn6;
  14.   CHAR fn7;
  15.   CHAR ext;
  16.   BYTE block; //cur block for write, next block for read (start LSB)
  17.   BYTE blockpad; // (start HSB)
  18.   BYTE lastlenLSB; BYTE lastlenHSB; //length of block in bytes //TODO т√Ёртэштрэшх!!!
  19.   BYTE secinblk; //sectors remained in block (for read), block size (for write)
  20.   BYTE firstsectorLSB; BYTE firstsectorHSB; //first sector of block (for write) //TODO т√Ёртэштрэшх!!!
  21. //end of TR-DOS descriptor
  22.   BYTE cursectorLSB; BYTE cursectorHSB; //cur sector for write, next sector for read //TODO т√Ёртэштрэшх!!!
  23.   BYTE remain; //remaining bytes in buf (for read)
  24.   BYTE secwritten; //sectors written (for write)
  25.   BYTE descpos; //position of descriptor (for write) 0..127
  26.   //BYTE buf; //256 bytes padded
  27. };
  28.  
  29. /**
  30. _fin
  31.         EXPORT _fin
  32.         DW 0
  33. _fout
  34.         EXPORT _fout
  35.         DW 0
  36. _waseof
  37.         EXPORT _waseof
  38.         DB 0
  39.  
  40. FCB1=0x4800 ;aligned ;len=0x0200
  41. DOSBUF=0xff00 ;aligned
  42. */
  43. EXPORT VAR PBYTE _fin;
  44. EXPORT VAR PBYTE _fout;
  45. EXPORT VAR BOOL _waseof;
  46. CONST PBYTE FCB1; // = 0x4800; //aligned ;len=0x0200
  47. //#define FCB1 (PBYTE)(0x4800) /**aligned, len = 0x0200 every FCB*/
  48. CONST PBYTE DOSBUF; // = 0xff00; //aligned
  49. //#define DOSBUF (PBYTE)(0xff00) /**aligned*/
  50.  
  51. VAR PBYTE pdesc;
  52.  
  53. #define DOSBUFfreesectorsLSB (PBYTE)(DOSBUF+0x00e5)
  54. #define DOSBUFfreesectorsHSB (PBYTE)(DOSBUF+0x00e6)
  55. #define DOSBUFfiles (PBYTE)(DOSBUF+0x00e4)
  56. #define DOSBUFfreesectorLSB (PBYTE)(DOSBUF+0x00e1)
  57. #define DOSBUFfreesectorHSB (PBYTE)(DOSBUF+0x00e2)
  58.  
  59. FUNC BOOL findfile(FCB* pfcb, BYTE namesz)
  60. {
  61. //find new block if exists
  62. //find Nth block of file with hl pointed filename (10 bytes: name, ext, block N)
  63. VAR PBYTE pfn;
  64. VAR BYTE sector;
  65. VAR BYTE i;
  66. VAR BYTE b;
  67. VAR BOOL res = +TRUE; //found
  68.     sector = 0x00;
  69.     REPEAT {
  70.       readsectors(DOSBUF, (UINT)sector, 0x01);
  71.       pdesc = DOSBUF;
  72. #define DOSBUFEND (UINT)(DOSBUF+0x0100)
  73.       REPEAT {
  74.         pfn = (PBYTE)&(pfcb->fn);
  75.         i = 0x00;
  76.         REPEAT {
  77.           b = *(PBYTE)pfn;
  78.           INC pfn;
  79.           IF (pdesc[i] != b) goto wrong;
  80.           INC i;
  81.         }UNTIL (i == namesz/**0x0a*/); //bytes to compare
  82.         goto found;
  83.         wrong:
  84.         pdesc = &pdesc[16];
  85.       }UNTIL ((UINT)pdesc == DOSBUFEND); //next descriptor
  86.       INC sector;
  87.     }UNTIL (sector == 0x08); //next sector
  88.   res = +FALSE; //not found
  89. found:
  90. RETURN res;
  91. }
  92.  
  93. /**
  94. findlastslash
  95. findlastslash.A.=$+1
  96.         ld hl,0
  97. ;hl = poi to filename in string
  98. nfopenfnslash.
  99.         ld d,h
  100.         ld e,l ;de = after last slash
  101. ;find last slash
  102. nfopenfnslash0.
  103.         ld a,[hl]
  104.         inc hl
  105.         or a
  106.         jr z,nfopenfnslashq.
  107.         cp '/'
  108.         jr nz,nfopenfnslash0.
  109.         jr nfopenfnslash.
  110. nfopenfnslashq.
  111.         ex de,hl
  112. ;hl = after last slash
  113.         ret
  114. */
  115. EXPORT FUNC PCHAR findlastslash(PCHAR s)
  116. {
  117. VAR PCHAR slast;
  118. VAR CHAR c;
  119.   loopslash:
  120.     slast = s;
  121.   loop:
  122.     c = *(PCHAR)s;
  123.     INC s;
  124.     IF (c == '\0') goto quit;
  125.     IF (c == '/') goto loopslash;
  126.     goto loop;
  127.   quit:
  128. RETURN slast;
  129. }
  130.  
  131. /**
  132. nfopen
  133. ;todo яЁютхЁ Є№ эрышўшх Їрщыр яЁш юЄъЁ√Єшш эр ўЄхэшх
  134.         EXPORT nfopen
  135.         xor a
  136.         ld hl,FCB1-0x0200
  137.  
  138.         inc h
  139.         inc h
  140.         cp [hl]
  141.         jr nz,$-3
  142.  
  143. ;nfopenFCB
  144. nfopen.B.=$+1
  145.         EXPORT nfopen.B.
  146.         ld a,[0] ;poi to mode ("wb"/"rb")
  147.         ld [hl],a ;mode in FCB
  148.         inc hl ;poi to fn in FCB
  149.         push hl ;poi to fn in FCB
  150.         ld d,h
  151.         ld e,l
  152.         inc de
  153.         ld [hl],' '
  154.         ld bc,8
  155.         ldir ;empty filename
  156. nfopen.A.=$+1
  157.         EXPORT nfopen.A.
  158.         ld hl,0 ;poi to filename in string
  159.         ld [findlastslash.A.],hl
  160.         call findlastslash
  161.         ex de,hl
  162. ;de = after last slash
  163.         pop hl ;poi to fn in FCB
  164.         ld b,9
  165. nfopenfn0.
  166.         ld a,[de]
  167.         or a
  168.         jr z,nfopenfnq. ;no extension in string
  169.         inc de
  170.         cp '.'
  171.         jr z,nfopenfndot.
  172.         ld [hl],a
  173.         inc hl
  174.         djnz nfopenfn0.
  175. ;9 bytes in filename, no dot (9th byte goes to extension)
  176.         jr nfopenfnq.
  177. nfopenfndot.
  178.         inc hl
  179.         djnz $-1 ;hl points to extension in FCB
  180.         dec hl
  181.         ld a,[de] ;extension in string
  182.         ld [hl],a ;extension in FCB
  183. nfopenfnq.
  184.         xor a
  185.         ld l,FCB.block
  186.         ld [hl],a;0 ;cur block for write, next block for read
  187.         inc hl
  188.         ld [hl],0x60 ;(padding for "start")
  189.         inc hl
  190.         ld [hl],a;0 ;lastlen LSB ;???
  191.         inc hl
  192.         ld [hl],a;0 ;lastlen HSB ;???
  193.         inc hl
  194.         ld [hl],a;0 ;sectors remained in block (for read), block size (for write)
  195.         ld l,FCB.remain
  196.         ld [hl],0xff ;remain (0xff = no data) for read
  197.         inc hl
  198.         ld [hl],a;0 ;sectors written (for write)
  199.         ld l,a;0;FCB.mode
  200.         ret ;hl = poi to FCB
  201. */
  202. EXPORT FUNC PBYTE nfopen(PCHAR filename, PCHAR pmode)
  203. {
  204. VAR FCB* pfcb = (FCB*)((UINT)FCB1 - 0x0200);
  205. VAR BYTE i = 0x09;
  206. VAR CHAR c;
  207. //VAR PBYTE pdesc;
  208.   REPEAT {
  209.     pfcb = (FCB*)((UINT)pfcb + 0x0200);
  210.   }UNTIL (*(PBYTE)pfcb == 0x00); //first free FCB
  211.   //pfcb->mode = *(PCHAR)pmode; //see in the end if success
  212.   pdesc = (PBYTE)&(pfcb->fn); //poi to fn in FCB
  213.   memcopy((PBYTE)"         ", 9, pdesc); //from, len, to
  214.   filename = findlastslash(filename); //after last slash
  215.   REPEAT {
  216.     c = *(PCHAR)filename;
  217.     IF (c == '\0') goto nfopenfnq; //no extension in string
  218.     INC filename;
  219.     IF (c == '.') goto nfopenfndot;
  220.     POKE *(PCHAR)(pdesc) = c;
  221.     INC pdesc;
  222.     DEC i;
  223.   }UNTIL (i == 0x00);
  224. //9 bytes in filename, no dot (9th byte goes to extension)
  225.   goto nfopenfnq;
  226. nfopenfndot:
  227.   pfcb->ext = *(PCHAR)filename;
  228. nfopenfnq:
  229.   pfcb->block = 0x00; //cur block (for write!!!)
  230.   pfcb->blockpad = 0x60; //padding for "start"
  231.  
  232. /**
  233.         ld l,a;0
  234.         ld a,(hl)
  235.         cp 'w'
  236.         jr z,nfopen_nofindfile. ;TODO єфрышЄ№, хёыш хёЄ№
  237. ;яЁютхЁшЄ№, ўЄю Їрщы ёє∙хёЄтєхЄ, шэрўх тхЁэєЄ№ ю°шсъє ш юётюсюфшЄ№ FCB
  238.         ld c,9 ;FILENAMESZ
  239.         call findfile
  240.         or a
  241.         jr nz,nfopen_fail.
  242. ;hl,de = after filename
  243. ;open for read!
  244.         ld l,FCB.block
  245.         ld a,(de)
  246.         inc de
  247.         ld [hl],a;0 ;cur block for write, next block for read
  248.         inc hl
  249.         ld a,(de)
  250.         inc de
  251.         ld [hl],a;0x60 ;(padding for "start")
  252.        ;ld a,FALSE
  253.        ;ld [_waseof],a
  254. nfopen_nofindfile.
  255. */
  256.   IF (*(PCHAR)pmode != 'w') {
  257.     IF (!findfile(pfcb, 0x09)) {
  258.       pfcb = (FCB*)0;
  259.       goto nfopenfail;
  260.     };
  261.     memcopy(pdesc, 11, (PBYTE)&(pfcb->fn)); //from, len, to
  262.   };
  263.  
  264.   pfcb->lastlenLSB = 0x00;
  265.   pfcb->lastlenHSB = 0x00;
  266.   pfcb->secinblk = 0x00; //sectors remained in block (for read), block size (for write)
  267.   pfcb->remain = 0xff; //remain (0xff = no data) for read
  268.   pfcb->secwritten = 0x00; //sectors written (for write)
  269.   pfcb->mode = *(PCHAR)pmode;
  270. nfopenfail:
  271. RETURN (PBYTE)pfcb;
  272. }
  273.  
  274. /**
  275. topenwr.
  276.         db "wb"
  277.         db 0
  278.  
  279. openwrite
  280.         EXPORT openwrite
  281.         ld hl,topenwr.
  282.         ld [nfopen.B.],hl
  283. openwrite.A.=$+1
  284.         EXPORT openwrite.A.
  285.         ld hl,0 ;filename
  286.         ld [nfopen.A.],hl
  287.         jp nfopen
  288.  
  289. */
  290. EXPORT FUNC PBYTE openwrite(PCHAR s)
  291. {
  292. RETURN nfopen(s, "wb");
  293. }
  294.  
  295. /**
  296. flushdesc
  297. flushdesc.A.=$+1
  298.         ld hl,0
  299.         push hl ;poi to FCB
  300.         ld l,FCB.descpos
  301.         ld l,[hl]
  302.         ld d,0 ;track of descriptor
  303.         ld h,d;0
  304.         add hl,hl
  305.         add hl,hl
  306.         add hl,hl
  307.         add hl,hl
  308.         ld e,h ;sector of descriptor
  309.         ld h,DOSBUF.>>8
  310.         push hl ;hl = poi to descriptor
  311.         push de ;track,sector of descriptor
  312.         call rdsecDOSBUF.
  313.         pop bc ;track,sector of descriptor
  314.         pop de ;poi to descriptor
  315.         pop hl ;poi to FCB
  316.         ld l,FCB.fn
  317.         push bc ;track,sector of descriptor
  318.         ld bc,16
  319.         ldir
  320.         pop de ;track,sector of descriptor
  321.         ld hl,DOSBUF.
  322.         call wrsec.
  323.         ret
  324. */
  325. //write descriptor
  326. //if created or finished
  327. PROC flushdesc(FCB* pfcb)
  328. {
  329. VAR UINT trsec = (UINT)((pfcb->descpos)>>0x04);
  330. //VAR PBYTE pdesc;
  331.   pdesc = (PBYTE)((UINT)DOSBUF + (UINT)((pfcb->descpos)<<0x04));
  332.   readsectors(DOSBUF, trsec, 0x01);
  333. //  memcopy(/**from*/(PBYTE)&(pfcb->fn)/**(PBYTE)((UINT)pfcb+1)*/, 16, /**to*/pdesc); //ёюфхЁцшьюх ёЄЁєъЄєЁ√ чртшёшЄ юЄ яюЁ фър срщЄют т ёыютх ш ЁрчьхЁр UINT!!!
  334.   memcopy((PBYTE)&(pfcb->fn), 11, pdesc); //from,len,to
  335.   pdesc = &pdesc[11];
  336.   POKE *(PBYTE)(pdesc) = pfcb->lastlenLSB;
  337.   INC pdesc;
  338.   POKE *(PBYTE)(pdesc) = pfcb->lastlenHSB;
  339.   INC pdesc;
  340.   POKE *(PBYTE)(pdesc) = pfcb->secinblk;
  341.   INC pdesc;
  342.   POKE *(PBYTE)(pdesc) = pfcb->firstsectorLSB;
  343.   INC pdesc;
  344.   POKE *(PBYTE)(pdesc) = pfcb->firstsectorHSB;
  345.   writesectors(DOSBUF, trsec, 0x01);
  346. }
  347.  
  348. /**
  349. flushwritebuf
  350. flushwritebuf.A.=$+1
  351.         ld hl,0
  352. ;write buf
  353.         ld l,FCB.cursector
  354.         push hl ;poi to cursector
  355.         ld e,[hl]
  356.         inc hl
  357.         ld d,[hl]
  358.         ld l,0
  359.         inc h ;poi to buf
  360.         call wrsec.
  361.         ex de,hl ;ld de,(0x5cf4) ;de=next sector
  362.         pop hl ;poi to cursector
  363.         ld [hl],e
  364.         inc hl
  365.         ld [hl],d
  366. ;increase secwritten
  367. ;get new block if this block filled up
  368.         ld l,FCB.secinblk
  369.         ld a,[hl]
  370.         ld l,FCB.secwritten
  371.         inc [hl]
  372.         sub [hl]
  373.         jr nz,flushnblk. ;not filled up
  374. ;block is filled up
  375. ;zero secwritten
  376.         ;ld l,FCB.secwritten
  377.         ld [hl],a;0 ;block not created
  378. ;write descriptor
  379.         ld l,0
  380.         ld (flushdesc.A.),hl
  381.         push hl
  382.         call flushdesc
  383.         pop hl
  384. ;increase block number (after flushdesc!!!)
  385.         ld l,FCB.block
  386.         inc [hl] ;cur block for write, next block for read
  387. ;ЄхяхЁ№ фхёъЁшяЄюЁ эхтрышфэ√щ, яюър эх ёючфрфшь хую т эрўрых фЁєуюую flush
  388. ;zero lastlen (after flushdesc!!!)
  389.         ld l,FCB.lastlen+1 ;(HSB), LSB is already 0 if not fclose
  390.         ld [hl],0
  391. flushnblk.
  392.         ret
  393. */
  394. PROC flushwritebuf(FCB* pfcb)
  395. {
  396. VAR UINT cursector;
  397. //1Ёрч
  398.   cursector = writesectors((PBYTE)((UINT)pfcb+0x100), (UINT)(pfcb->cursectorLSB) + ((UINT)(pfcb->cursectorHSB)<<8), 0x01);
  399.   pfcb->cursectorLSB = (BYTE)cursector;
  400.   pfcb->cursectorHSB = (BYTE)(cursector>>8);
  401.   INC *(&(pfcb->secwritten)); //pfcb->secwritten = pfcb->secwritten + 0x01;
  402.   IF (pfcb->secwritten == pfcb->secinblk) { //block is filled up
  403. //эх яюярыш
  404.     pfcb->secwritten = 0x00;
  405.     flushdesc(pfcb);
  406.     INC *(&(pfcb->block)); //pfcb->block = pfcb->block + 0x01; //cur block for write, next block for read
  407.     //ЄхяхЁ№ фхёъЁшяЄюЁ эхтрышфэ√щ, яюър эх ёючфрфшь хую т эрўрых фЁєуюую flush
  408.     pfcb->lastlenLSB = 0x00;
  409.     pfcb->lastlenHSB = 0x00;
  410.   };
  411. }
  412.  
  413. /**
  414. flush_
  415. flush_.A.=$+1
  416.         ld hl,0 ;hl = poi to FCB
  417. ;if secwritten == 0 then reserve sectors, reserve descriptor
  418.         ld l,FCB.secwritten
  419.         ld a,[hl]
  420.         or a
  421.         jr nz,flushnnew.
  422. ;уы■ўшЄ, хёыш яюёыхфэшщ сыюъ <256
  423. ;яюЄюьє ўЄю fclose тЄюЁющ Ёрч т√ч√трхЄ flush
  424.         ld l,FCB.secinblk
  425.         ld [hl],16 ;TR-DOS reserves 16 sectors per block
  426. ;update sec8
  427.         push hl ;poi to FCB
  428.         ld de,0x0008
  429.         push de
  430.         ld hl,DOSBUF
  431.         call rdsec.
  432.         pop de ;0x0008
  433.         ld hl,[DOSBUF+0xe5] ;free sectors
  434.         ld bc,-16
  435.         add hl,bc
  436.          ;bit 7,h
  437.          ;jr nz,$ ;no free sectors
  438.         ld [DOSBUF+0xe5],hl ;free sectors
  439.  
  440.         ld hl,DOSBUF+0xe4 ;files
  441.         ld a,[hl] ;descriptor position 0..127
  442.          ;or a
  443.          ;jp m,$ ;128 files, can't add
  444.         inc [hl] ;files
  445.  
  446.         ld l,0xe1 ;free sector
  447.         ld c,[hl]
  448.         inc hl
  449.         ld b,[hl]
  450.         inc [hl] ;add 16 sectors = add 1 track
  451.  
  452.         pop hl ;poi to FCB
  453.         ld l,FCB.descpos
  454.         ld [hl],a ;descriptor position 0..127
  455.         ld l,FCB.firstsector
  456.         ld [hl],c
  457.         inc hl
  458.         ld [hl],b
  459.         ld l,FCB.cursector
  460.         ld [hl],c
  461.         inc hl
  462.         ld [hl],b
  463.  
  464.         push hl ;poi to FCB
  465.         ld hl,DOSBUF
  466.         ;ld de,0x0008
  467.         call wrsec. ;write sec8
  468.         pop hl ;poi to FCB
  469. flushnnew.
  470.         ld l,0
  471.         ld (flushwritebuf.A.),hl
  472.         jp flushwritebuf
  473. */
  474. //Ёєўэющ flush яюър эхтючьюцхэ!!!
  475. //can create zero length file
  476. PROC flush_(FCB* pfcb)
  477. {
  478. VAR BYTE firstsectorLSB;
  479. VAR BYTE firstsectorHSB;
  480. VAR UINT freesectors;
  481.   IF (pfcb->secwritten == 0x00) { //reserve sectors, reserve descriptor
  482.     //уы■ўшЄ, хёыш яюёыхфэшщ сыюъ <256
  483.     //яюЄюьє ўЄю fclose тЄюЁющ Ёрч т√ч√трхЄ flush
  484.     pfcb->secinblk = 0x10; //TR-DOS reserves 16 sectors per block
  485.     //update sec8
  486.     readsectors(DOSBUF, 0x0008, 0x01);
  487.     //POKE *(PUINT)(/**(UINT)DOSBUF+0x00e5*/DOSBUFfreesectors) = *(PUINT)(/**(UINT)DOSBUF+0x00e5*/DOSBUFfreesectors) - 16; //free sectors //todo check < 0
  488.     freesectors = ((UINT)*(PBYTE)DOSBUFfreesectorsHSB << 8) + (UINT)*(PBYTE)DOSBUFfreesectorsLSB - 16;
  489. //    freesectors = (UINT)*(PBYTE)DOSBUFfreesectorsLSB + ((UINT)*(PBYTE)DOSbuffreesectorsHSB << 8) - 16; //todo эрщЄш уы■ъ т рёёхьсыхЁх!!! яюўхьє эх эрїюфшЄ ьхЄъє DOSbuffreesectorsHSB???
  490.     POKE *(PBYTE)(DOSBUFfreesectorsLSB) = (BYTE)freesectors;
  491.     POKE *(PBYTE)(DOSBUFfreesectorsHSB) = (BYTE)(freesectors>>8);
  492.     pfcb->descpos = *(PBYTE)(/**(UINT)DOSBUF+0x00e4*/DOSBUFfiles); //descriptor position 0..127
  493.     POKE *(PBYTE)(/**(UINT)DOSBUF+0x00e4*/DOSBUFfiles) = pfcb->descpos + 0x01; //files //todo check >=128
  494.     //*(PUINT)(/**(UINT)DOSBUF+0x00e1*/DOSBUFfreesector); //free sector
  495.     firstsectorLSB = *(PBYTE)DOSBUFfreesectorLSB;
  496.     firstsectorHSB = *(PBYTE)DOSBUFfreesectorHSB;
  497.     pfcb->firstsectorLSB = firstsectorLSB;
  498.     pfcb->firstsectorHSB = firstsectorHSB;
  499.     pfcb->cursectorLSB = firstsectorLSB;
  500.     pfcb->cursectorHSB = firstsectorHSB;
  501.     //POKE *(PUINT)(/**(UINT)DOSBUF+0x00e1*/DOSBUFfreesector) = firstsector + 0x0100; //add 16 sectors = add 1 track
  502.     POKE *(PBYTE)(DOSBUFfreesectorHSB) = firstsectorHSB + 0x01;
  503. //1Ёрч
  504. //goto l1;l1:
  505.     writesectors(DOSBUF, 0x0008, 0x01);
  506. //goto l2;l2:
  507.   };
  508.   flushwritebuf(pfcb);
  509. }
  510.  
  511. /**
  512. comparedesc
  513. comparedesc.A.=$+1 ;filename
  514.         ld hl,0
  515.         ld [findlastslash.A.],hl
  516.         call findlastslash
  517.         ex de,hl
  518. ;de = after last slash
  519. comparedesc.B.=$+1 ;desc
  520.         ld hl,0
  521. ;compare until '.' or '\0' or 8 loops
  522.         ld b,8
  523. comparedesc0.
  524.         ld a,[de] ;filename
  525.         inc de ;todo test '\0', descbuf all spaces
  526.         cp '.'
  527.         jr z,comparedescdot.
  528.         cp [hl] ;descriptor
  529.         jr nz,comparedescfalse.
  530.         inc hl
  531.         djnz comparedesc0.
  532.         ld a,[de] ;filename
  533.         inc de
  534.         cp '.'
  535.         jr z,comparedescdot8. ;filenam8.ext
  536.         ;filenam8 (without ext)
  537.         ld a,[hl]
  538.         cp ' '
  539.         jr nz,comparedescfalse.
  540. comparedesctrue.
  541.         ld a,0xff ;TRUE
  542.         ret
  543. comparedescdot.
  544.         inc hl
  545.         djnz $-1 ;hl = descriptor ext
  546. comparedescdot8.
  547.         ld a,[de] ;filename ext
  548.         cp [hl] ;descriptor ext
  549.         jr z,comparedesctrue.
  550. comparedescfalse.
  551.         xor a ;FALSE
  552.         ret
  553. */
  554. /**
  555. FUNC BOOL comparedesc(PCHAR filename, PBYTE desc)
  556. {
  557. VAR CHAR c;
  558. VAR BOOL res;
  559. VAR BYTE i = 0x08;
  560.   filename = findlastslash(filename);
  561.   loop:
  562.     c = *(PCHAR)filename;
  563.     INC filename;
  564.     IF (c == '.') { //todo test '\0', descbuf all spaces
  565.       dot:
  566.       //desc = (PBYTE)((UINT)desc + (UINT)i);
  567.       res = (*(PCHAR)((UINT)desc + (UINT)i) == *(PCHAR)filename);
  568.       goto quit;
  569.     };
  570.     IF (c != *(PCHAR)desc) {
  571.       res = +FALSE;
  572.       goto quit;
  573.     };
  574.     INC desc;
  575.     DEC i;
  576.     IF (i == 0x00) {
  577.       c = *(PCHAR)filename;
  578.       INC filename;
  579.       //IF (c == '.')
  580.               goto dot;
  581.       //res = (*(PCHAR)desc == ' '); //filenam8 (without ext) //TODO
  582.       //goto quit;
  583.     };
  584.     goto loop;
  585.   quit:
  586. RETURN res;
  587. }
  588. */
  589.  
  590. /**
  591. fread_readnextsector
  592. fread_readnextsector.A.=$+1
  593.         ld hl,0
  594.         ld l,FCB.cursector
  595.         push hl ;poi to cursector
  596.         ld e,[hl]
  597.         inc hl
  598.         ld d,[hl]
  599.         inc h
  600.         ld l,0;a;0 ;poi to buf
  601.         call rdsec.
  602.         ex de,hl ;ld de,[0x5cf4] ;de=next sector
  603.         pop hl ;poi to cursector
  604.         ld [hl],e
  605.         inc hl
  606.         ld [hl],d
  607.         ret
  608. */
  609. /**
  610. PROC fread_readnextsector(FCB* pfcb)
  611. {
  612.   pfcb->cursector = readsectors((PBYTE)((UINT)pfcb+0x100), pfcb->cursector, 0x01);
  613. }
  614. */
  615.  
  616. /**
  617. fread1sec
  618. fread1sec.A.=$+1
  619.         ld hl,0
  620.         ld (fread_readnextsector.A.),hl
  621.         push hl
  622.         call fread_readnextsector
  623.         pop hl
  624. ;if last sector of block, then remain = -lastlen and shift data in buf to the end
  625. ;else remain = 0 (read + 255 bytes)
  626.         xor a
  627.         ld l,FCB.secinblk
  628.         dec [hl] ;sectors remained in block
  629.         jr nz,fread1nlast.
  630. ;last sector in block: shift data to the end of buf
  631.         ld l,FCB.lastlen
  632.         ld c,[hl] ;1..256
  633.         ld b,a;0
  634.         dec c ;0..255
  635.         ld l,c ;end of data
  636.         inc h
  637.         inc bc ;1..256
  638.         ld d,h
  639.         ld e,0xff
  640.         lddr
  641.         ;hl = poi to buf - 1
  642.         ;h = poi to FCB
  643.         ld a,e ;0xfe (1 byte) ... -1 (256 bytes)
  644.         inc a ;remain = 0xff (read + no data) ... 0 (read + 255 bytes)
  645. fread1nlast.
  646.         ld l,FCB.remain
  647.         ld [hl],a
  648.         ret
  649. */
  650. PROC fread1sec(FCB* pfcb)
  651. {
  652. VAR BYTE eod;
  653. VAR UINT cursector;
  654. //1Ёрч
  655.   //fread_readnextsector(pfcb);
  656.   cursector = readsectors((PBYTE)((UINT)pfcb+0x100), (UINT)(pfcb->cursectorLSB) + ((UINT)(pfcb->cursectorHSB)<<8), 0x01);
  657.   pfcb->cursectorLSB = (BYTE)cursector;
  658.   pfcb->cursectorHSB = (BYTE)(cursector>>8);
  659.   //if last sector of block, then remain = -lastlen and shift data in buf to the end
  660.   //else remain = 0 (read + 255 bytes)
  661.   pfcb->remain = 0x00;
  662.   DEC *(&(pfcb->secinblk)); //sectors remained in block
  663.   IF (pfcb->secinblk == 0x00) {
  664.     //last sector in block: shift data to the end of buf
  665.     eod = pfcb->lastlenLSB - 0x01; //1..256 => 0..255
  666.     memcopyback(
  667.       (PBYTE)((UINT)pfcb + 0x0100 + (UINT)eod), //end of data
  668.       (UINT)eod + 1, //1..256
  669.       (PBYTE)((UINT)pfcb + 0x01ff) //end of buf
  670.     );
  671.     pfcb->remain = ~eod; //0xff (read + no data) ... 0 (read + 255 bytes)
  672.   };
  673. }
  674.  
  675. /**
  676. fread1blkq
  677. fread1blkq.A.=$+1 ;FCB
  678.         ld hl,0
  679. fread1blkq.B.=$+1 ;desc
  680.         ld de,0
  681. ;de = poi to descriptor ;+ 10
  682. ;hl = FCB
  683.         ld l,FCB.fn ;+ 10
  684.         ex de,hl
  685. ;hl = poi to descriptor ;+ 10
  686. ;de = poi to filename ;+ 10
  687.         ld bc,16;6 ;padding, len(LSB), len(HSB), secinblk, sec, track
  688.         ldir
  689.         ex de,hl
  690.         ld l,FCB.firstsector
  691.         ld e,[hl]
  692.         inc hl
  693.         ld d,[hl]
  694.         ld l,FCB.cursector
  695.         ld [hl],e
  696.         inc hl
  697.         ld [hl],d
  698. ;secinblk = (lastlen+255)/256 = (lastlen-1)/256 + 1
  699. ;шэрўх эхы№ч  сєфхЄ т√фхы Є№ сыюъш эрт√ЁюёЄ (ъръ фхырхЄ TR-DOS)
  700.         ld l,FCB.lastlen
  701.         ld e,[hl]
  702.         inc hl
  703.         ld d,[hl]
  704.         dec de
  705.         inc d
  706.         inc hl ;ld l,FCB.secinblk
  707.         ld [hl],d
  708.         jr z,fread1qEOF. ;(secinblk == 0)
  709.         ld l,FCB.block
  710.         inc [hl] ;cur block for write, next block for read
  711.         ld a,0xff ;TRUE ;no EOF
  712.         ret
  713. fread1qEOF.
  714.         xor a
  715.         ret
  716. */
  717. FUNC BOOL fread1blkq(FCB* pfcb, PBYTE pdesc1)
  718. {
  719. VAR BOOL res = +FALSE; //EOF
  720.   //memcopy(pdesc1, 16, (PBYTE)&(pfcb->fn)); //from, len, to //ёюфхЁцшьюх ёЄЁєъЄєЁ√ чртшёшЄ юЄ яюЁ фър срщЄют т ёыютх ш ЁрчьхЁр UINT!!!
  721.   memcopy(pdesc1, 11, (PBYTE)&(pfcb->fn)); //from, len, to
  722.   pdesc1 = &pdesc1[11];
  723.   pfcb->lastlenLSB = *(PBYTE)(pdesc1);
  724.   pfcb->lastlenHSB = *(PBYTE)((UINT)pdesc1+1);
  725.   pdesc1 = &pdesc1[2];
  726.   pfcb->secinblk = *(PBYTE)(pdesc1);
  727.   INC pdesc1;
  728.   pfcb->firstsectorLSB = *(PBYTE)(pdesc1);
  729.   pfcb->firstsectorHSB = *(PBYTE)((UINT)pdesc1+1);
  730.   pfcb->cursectorLSB = pfcb->firstsectorLSB;
  731.   pfcb->cursectorHSB = pfcb->firstsectorHSB;
  732.   //secinblk = (lastlen+255)/256 = (lastlen-1)/256 + 1
  733.   //шэрўх эхы№ч  сєфхЄ т√фхы Є№ сыюъш эрт√ЁюёЄ (ъръ фхырхЄ TR-DOS)
  734.   pfcb->secinblk = (BYTE)(((UINT)(pfcb->lastlenLSB) + ((UINT)(pfcb->lastlenHSB)<<8) + 0x00ff) >> 8);
  735.   IF (pfcb->secinblk != 0x00) {
  736.     INC *(&(pfcb->block)); //cur block for write, next block for read
  737.     res = +TRUE; //no EOF
  738.   };
  739. RETURN res;
  740. }
  741.  
  742. /**
  743. readnewbuf
  744. ;read new buf (if exists)
  745. readnewbuf.A.=$+1
  746.         ld hl,0
  747.         ld l,FCB.secinblk
  748.         xor a
  749.         cp [hl] ;sectors remained in block (0 means none)
  750.         jr nz,fread1sec. ;a = 0
  751. ;find new block if exists
  752. ;find Nth block of file with hl pointed filename (10 bytes: name, ext, block N)
  753.         ld b,8 ;sectors
  754. findfile0.
  755.         push bc
  756.         push hl
  757.         ld d,0 ;track
  758.         ld a,8
  759.         sub b
  760.         ld e,a ;sector
  761.         ld hl,DOSBUF
  762.         ld b,1
  763.         call rdsectors.
  764.         pop hl
  765.         pop bc
  766. ;hl=filename
  767. ;b=sectors
  768.         ld de,DOSBUF
  769. findfilecp0.
  770.         ld l,0
  771.         ld (fread1blkq.A.),hl ;FCB
  772.         ld (fread1blkq.B.),de ;desc
  773.         ld l,FCB.fn ;poi to fn
  774.         push bc
  775.         ld bc,0x0a00 ;b=bytes to compare, c=errors
  776. findfilecp00.
  777.         ld a,[de]
  778.         sub [hl]
  779.         or c
  780.         ld c,a ;errors
  781.         inc hl
  782.         inc de
  783.         djnz findfilecp00.
  784.         pop bc
  785.         jr z,fread1blkq. ;ret z ;found (carry = off, a = 0)
  786.         ld a,e
  787.         add a,6
  788.         ld e,a
  789.         jr nz,findfilecp0. ;next descriptor
  790.         djnz findfile0. ;next sector
  791. ;not found
  792.         xor a ;EOF
  793.         ret
  794. fread1blkq.
  795. ;de = poi to descriptor ;+ 10
  796. ;hl = poi to fn ;+ 10
  797.         push hl
  798.         call fread1blkq
  799.         pop hl
  800.         or a ;EOF
  801.         ret z;jr z,fread1EOF.
  802. fread1sec.
  803.         ld l,0
  804.         ld (fread1sec.A.),hl
  805.         call fread1sec
  806.         ld a,0xff ;not EOF
  807.         ret
  808. */
  809. FUNC BOOL readnewbuf(FCB* pfcb)
  810. {
  811. VAR BOOL res = +FALSE; //EOF
  812.   IF (pfcb->secinblk == 0x00) { //sectors remained in block (0 means none)
  813.     IF (!findfile(pfcb, 0x0a)) goto quit; //EOF
  814.     IF (!fread1blkq(pfcb, pdesc)) goto quit; //EOF
  815.   };
  816.   fread1sec(pfcb);
  817.   res = +TRUE; //not EOF
  818. quit:
  819. RETURN res;
  820. }
  821.  
  822. /**
  823. fputs
  824.         EXPORT fputs
  825. ;todo optimize
  826. fputs.A.=$+1
  827.         EXPORT fputs.A.
  828.         ld bc,0 ;poi to string
  829.         jp fputsgo.
  830. fputs0.
  831. fputs.B.=$+1
  832.         EXPORT fputs.B.
  833.         ld hl,0 ;poi to FCB
  834.         call fwrite1. ;a=data
  835.         inc bc
  836. fputsgo.
  837.         ld a,[bc]
  838.         or a
  839.         jp nz,fputs0.
  840.         ret ;end of string ;(TODO hl = non-negative value)
  841. */
  842. EXPORT FUNC INT fputs(PCHAR s, PBYTE file)
  843. {
  844. VAR CHAR c;
  845. loop:
  846.   c = *(PCHAR)s;
  847.   IF (c == '\0') goto quit;
  848.   fwrite((PBYTE)&c, 1, 1, file);
  849.   INC s;
  850.   goto loop;
  851. quit:
  852. RETURN +1; //OK
  853. }
  854.  
  855. /**
  856. closewrite
  857.         EXPORT closewrite
  858. fclose
  859.         EXPORT fclose
  860. closewrite.A.=$+1
  861.         EXPORT closewrite.A.
  862. fclose.A.=$+1
  863.         EXPORT fclose.A.
  864.         ld hl,0 ;poi to FCB
  865.         ld a,[hl]
  866.         ld [hl],l;0
  867.         cp 'w'
  868.         ret nz ;hl!=0
  869. ;hl = poi to FCB
  870.         push hl
  871.         ld (flush_.A.),hl
  872.         call flush_
  873.         pop hl
  874.         ;ёыхфє■∙р  яЁютхЁър эх уюфшЄё , хёыш сєфхЄ Ёєўэющ flush:
  875.         ld l,FCB.secwritten
  876.         ld a,[hl]
  877.         or a
  878.         ret z ;no sectors written - descriptor already saved
  879.         ld l,0
  880.         ld (flushdesc.A.),hl
  881.         call flushdesc
  882.         ;ld l,1 ;OK TODO
  883.         ret ;hl!=0
  884. */
  885. EXPORT FUNC INT fclose(PBYTE file)
  886. {
  887. VAR FCB* pfcb = (FCB*)file;
  888. VAR CHAR mode = pfcb->mode;
  889.   pfcb->mode = '\0';
  890.   IF (mode == 'w') {
  891.     flush_(pfcb);
  892.     IF (pfcb->secwritten != 0x00) {
  893.       flushdesc(pfcb);
  894.     };
  895.   };
  896. RETURN +1; //OK
  897. }
  898. /**
  899. EXPORT PROC closewrite(PBYTE file)
  900. {
  901.   fclose(file);
  902. }
  903. */