/* download.c - download a file from the PC using the CTERM protocol.
 *  Copyright (C) 2022 by Jed Marti
 *   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 3 of the License, or
 *   (at your option) 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, see https://www.gnu.org/licenses/.
 */


#include <C8051F380.h>
#include <stdint.h>

#include "config.h"
#include "lfxmit.h"
#include "serial.h"
#include "lex.h"
#include "fs.h"

// Lexical interface.
extern __xdata uint8_t ttype;
extern __xdata char    STR[];
extern __bit           errorThrown;

// CTERM escape sequences:
//  <esc>Dfile-name0           Open file on CTERM PC for input, returns 0/1
//  <esc>d                     Read next 64 bytes, returns byte count.


void download(void)
//     Input line has a file name on it. Request this from the caller. It will
// have been converted to upper case so works for Windows but can cause trouble
// in Linux.
{
  uint8_t fh;
  uint8_t c;
  uint8_t i;

  ntok();
  if (!(ttype == LEXID || ttype == LEXSTRING))
  {
    putstring("download missing file name\n");
    errorThrown = 1;
    return;
  }

  // Request file from PC. <esc>Dfilename 0x00
  putch(27);
  putch('D');
  putstring(STR);
  putch(0);
  
  // A 1 indicates success, 0, no remoote.
  c = getch();
  if (c == 0)
  {
    putstring("download ");
    putstring(STR);
    putstring(" file not found\n");
    errorThrown = 1;
    return;
  }

  // Create the file.
  if ((fh = createFile(STR)) == 0xFF)
  {
    putstring("download no file handles\n");
    errorThrown = 1;
    return;
  }

 loop:
  // Request the next record. Remote returns number of bytes and the bytes.
  // A zero size indicates EOF.
  putch(27);
  putch('d');
  c = getch();

  // EOF.
  if (c == 0)
  {
    closeFile(fh);
    terpri();
    ntok();
    return;
  }

  // Read the bytes and write to the file. This can cause trouble at higher
  // baud rates since putchFile will go away when it needs to write a new
  // sector or allocate another block.
  for (i = 0; i < c; ++i) putchFile(getch(), fh);
  putch('.');
  goto loop;
}



// EOF
