/*
  HI65 - a high-level Commodore 65 emulator
  Copyright (C) 2013-2023  Simone Gremmo
  Contact: devilmaster@email.com

  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
  http://www.gnu.org/licenses/gpl.txt
*/

// var.h
#include "muParser.h"
#ifdef MAIN
 #define umode
#else
 #define umode extern
#endif

umode uint forecolor,backcolor,CharX,CharY;

 // the drawscreen is the screen influenced by the various draw operations.
 // The viewscreen is the screen that is currently viewed. They are
 // usually the same screen, except for double buffering
umode uchar DrawViewScreen[2]; 

umode uchar xzoom,yzoom,shifted,fullscreen;
umode uint screen_width,screen_height,screen_border_x,screen_border_y;
umode uchar program[PROGRAMSIZE];
umode uchar linebuffer[80];
umode ulong pc; // program counter
umode ulong dc; // data counter
umode ulong ec; // expression counter (used for future implementation of expression evaluation)
umode uchar lc; // line counter (it counts the characters within the line being typed)
umode ulong instruction_end_address, old_instruction_end_address;
umode ulong program_end_address;
umode uchar null_char_counter;
umode uint line_number;
umode uchar found_goto, found_end, found_colon;
umode ulong trap;
umode uchar loaderror;
umode uchar program_loaded_from_frontend;
umode uchar enable_muparser;

// used to stop the execution in case that a bug is found
// it is assigned to 1 in eventual debug functions
umode uchar bug;

// The C65 accepts variable names with 1 or 2 characters, which results
// in 962 possible names:
// - 26 single-char names
// - the second character can be a letter or a digit, so 26+10=36
// - there can be 26*36=936 two-char combinations
// - 26 single-char names +936 two-char combinations =962
// Moreover: any variable can be either a normal variable or an array.
// If it is an array, it can have at most 255 elements.
umode double numvars[962][255];
umode uint numvarpos;

// The C65 accepts string names with 1 or 2 characters (followed by the
// character "$" indicating that the variable is a string but not
// actually memorized), which results in 962 possible strings. A string
// can be up to 255 characters long
// Moreover: any variable can be either a normal variable or an array.
// If it is an array, it can have at most 255 elements.
umode char stringvars[255][962][255];
umode uint stringvarpos;
umode char stringtemp[255][2]; // used to evaluate IF conditions

// NOTE about variables: the position of a variable can be univocally
// identified by its name alone (so "A " is at position 0, "A0" at
// position 1, "A1" at position 2... "AA" at position 10, "AB" at
// position 11... "AZ" at position 35, "B " at position 36 and so on.
// This removes the need to memorize the name of the variable, and the
// sequential search of a variable can be replaced by a simple
// calculation of its position given its name.

// And: the possible names for variables are
// (amount of letters) * (amount of letters + amount of digits + space)
// 26*(26+10+1)=26*37=962


// The C65 has two definable screens (0 and 1). Each has 3 parameters:
// width (0=320, 1=640, 2=1280)
// height (0=200, 1=400)
// depth (1-8 bitplanes (2-256 colors))
umode uchar graphicscreen[2][3];
umode uchar openscreen; // this contains the value of the screen that's currently open

// The C65 has 256 definable colors for each definable screen. Each
// color is defined by 3 values (red, green, blue)
umode uchar palette[2][256][3];

#ifdef SYSTEMRAM
// As far as the BASIC is concerned, the RAM of the C65 is split into
// 256 (0-255) banks of 64 KB (65536 bytes) each. A bank number greater
// than 127 means "use the current system  configuration", and  must
// be used to access an I/O location. BASIC defaults to BANK 128.
umode uchar systemram[256][65536];
#endif
umode uchar currentbank;
umode FILE *cFile[256]; // for file operations in BASIC programs
umode uchar filestatus[256]; // status for each of the 256 logical file numbers

// Every time we enter a loop structure (FOR..NEXT, DO..LOOP) we must
// keep trace of the address to which to return at the end of the loop.
// This is what each value of loopstack[] does.
// More loops can be nested: every time we enter another loop we
// increase the value of loopnestinglevel (which determines which value
// of loopstack we operate on); every time we exit a loop, we decrease
// it.
// The C65 manual indicates a maximum of approximately 28 nested loops,
// so we will use a maximum of 32 nested loops to outperform a physical C65.
// The element loopstack[0] is never used. This would indicate the
// return address when we are inside 0 loops... but if we are not
// inside any loop, we don't need a return address!
umode uint loopstack[MAXLOOPS];
umode uint loop_instruction_end_address;
umode uchar loopnestinglevel, oldloopnestinglevel;
umode uint forvarpos[MAXLOOPS];
umode uint forarrayindex[MAXLOOPS];
umode double forto[MAXLOOPS],forstep[MAXLOOPS];
umode uchar must_exit;
umode uint gosubstack[MAXLOOPS];
umode uint gosub_instruction_end_address;
umode uchar gosubnestinglevel, oldgosubnestinglevel;

umode uchar inside_if_clause;
umode uchar condition;
umode uchar coming_from; // are we coming from the THEN or ELSE branch of an IF statement?)

umode int ticks, tickscapped; // variables used for timers
umode uchar screentype; // which computer screen is imitated by the emulator
umode uchar chperline; // how many characters per line

#ifdef DEBUG_SCREEN
umode uchar cfgarray[3]; // the configuration is loaded here
#endif

// this array contains the native (Allegro screen) coordinates for
// each of the vertices
umode uint vertex[4][2];

umode mu::Parser p;

