// LOAD: for basic files in prodos format
// it is like a normal CMD_READ

// PRODOS format:
// "A","1", 510 bytes low memory, basic program

// global cmd

void comando_load_bas() {
   VIA_init();  // needed when called from Applesoft basic after a RESET

   // send command byte
   send_byte_to_MCU(CMD_LOAD);
   if(TIMEOUT) return;

   // send filename
   send_string_to_MCU(filename);
   if(TIMEOUT) return;

   // wait for OK response, MCU sends many WAIT_RESPONSE to avoid TIMEOUT
   while(1) {
      byte response = receive_byte_from_MCU();
      if(TIMEOUT) return;

      if(response == ERR_RESPONSE) {
         // error with file, print message
         print_string_response();
         return;
      }
      if(response == OK_RESPONSE) break;
   }

   // get matching file name
   receive_string_from_MCU(filename);
   woz_puts("FOUND ");
   woz_puts(filename);
   woz_putc('\r');

   byte filetype = 0;
   token_ptr = filename;
   while(1) {
      if(*token_ptr == '#') {
         if(token_ptr[1] == '0' && token_ptr[2] == '6') { filetype = 0x06; break; }
         if(token_ptr[1] == 'F' && token_ptr[2] == '1') { filetype = 0xF1; break; }
         if(token_ptr[1] == 'F' && token_ptr[2] == '8') { filetype = 0xF8; break; }
      }
      if(*token_ptr == 0) break;
      token_ptr++;
   }

   // calculate start address for 0x06 binary file
   if(filetype == 0x06 || filetype == 0xF8) {
      token_ptr+=2;
      hex_to_word(token_ptr);
      start_address = tmpword;
   }

   // get file length in tmpword
   receive_word_from_mcu();
   if(TIMEOUT) return;

   if(filetype == 0) {
      woz_puts("?INVALID FILE NAME TAG #");
      for(word t=0;t!=tmpword;t++) receive_byte_from_MCU(); // empty buffer
      return;
   }

   woz_puts("LOADING\r");

   if(filetype == 0x06) {
      // 0x06 BINARY FILE format

      // get file bytes
      token_ptr = (byte *) start_address;
      for(word t=0;t!=tmpword;t++) {
         byte data = receive_byte_from_MCU();
         if(TIMEOUT) return;
         *token_ptr++ = data;
      }

      // decrease by one for display result
      token_ptr--;

      // print feedback to user
      woz_putc('\r');
      woz_puts(filename);
      woz_puts("\r$");
      woz_print_hexword(start_address);
      woz_puts("-$");
      woz_print_hexword((word)token_ptr);
      woz_puts(" (");
      utoa(tmpword, filename, 10);   // use filename as string buffer
      woz_puts(filename);
      woz_puts(" BYTES)\rOK");

      // executes machine language program at start address
      if(cmd == CMD_RUN) {
         woz_putc('\r');
         tmpword = start_address;
         asm {
            jmp (tmpword)
         }
      }

      return;
   }

   if(filetype == 0xF8) {
      // 0xF8 APPLESOFT BASIC LITE

      *TXTTAB = start_address;

      // get file bytes
      token_ptr = (byte *) start_address;
      for(word t=0;t!=tmpword;t++) {
         byte data = receive_byte_from_MCU();
         if(TIMEOUT) return;
         *token_ptr++ = data;
      }

      *VARTAB = (word) token_ptr;
      *PRGEND = (word) token_ptr;

      // decrease by one for display result
      token_ptr--;

      // print feedback to user
      woz_putc('\r');
      woz_puts(filename);
      woz_puts("\r$");
      woz_print_hexword(start_address);
      woz_puts("-$");
      woz_print_hexword((word)token_ptr);
      woz_puts(" (");
      utoa(tmpword, filename, 10);   // use filename as string buffer
      woz_puts(filename);
      woz_puts(" BYTES)\rOK");

      // executes machine language program at start address
      //if(cmd == CMD_RUN) {
      //   woz_putc('\r');
      //   tmpword = start_address;
      //   asm {
      //      jmp (tmpword)
      //   }
      //}

      return;
   }

   // 0xF1 BASIC FILE TYPE

   // get file bytes
   token_ptr = (byte *) 0;
   for(word t=0;t!=tmpword;t++) {
      byte data = receive_byte_from_MCU();
      if(TIMEOUT) return;

      if((t==0 && data!=0x41) || (t==1 && data!=0x31)) {
         woz_puts("?UNKNOWN FILE FORMAT");
         t=t+1;         
         for(;t!=tmpword;t++) receive_byte_from_MCU(); // empty buffer
         return;
      }
      else if(t<0x004a) {
         // skip zone $00-$49
      }
      else if(t<0x0100) {
         // writes in the zone $4a-$ff (BASIC pointers)
         *token_ptr = data;
      }
      else if(t<0x1ff) {
         // skip zone $100-$1ff (stack)
      }
      else if(t==0x1ff) {
         // basic program chuck follows, move the pointer
         token_ptr = *BASIC_LOMEM;
         token_ptr--; // compensate for the increment in the loop
      }
      else {
         // writes in the BASIC program zone
         *token_ptr = data;
      }
      
      token_ptr++;
   }

   bas_file_info();

   // executes basic program $EFEC = RUN entry point
   if(cmd == CMD_RUN) {
      woz_putc('\r');
      asm {
         jmp $EFEC
      }      
   }
}

void bas_file_info() {
   // print feedback to user
   woz_putc('\r');
   woz_puts(filename);
   woz_putc('\r');   
   bas_info();
   woz_puts("\rOK");
}

void bas_info() {
   woz_puts("(LOMEM=$");
   woz_print_hexword((word) *BASIC_LOMEM);
   woz_puts(" HIMEM=$");
   woz_print_hexword((word) *BASIC_HIMEM);
   woz_putc(')');   
}
