/***********************************************************************
The SimpleTron for Pilot is written by: 
Gisle Bjoerneseth gisle(curly thing)break(full stop)org  
based on the info found in the book "C:How To Program" HM Deitel Prentice Hall 
ISBN: 0-13-288333-3

This supplied source code is the main part of the simpletron app. for
the Palm Pilot. The programming interface and such has changed so much over the years that
I see no point in releasing the rest of the project files. This code is meant as an example of
how a simple computer works.

SIMPLETRON is a simple, but quite powerful 'computer'. It runs programs
written in the only language is directly understands, that is, Simpletron
Machine Language, or SML for short. The Simpletron contains a Work Register
- a special 'register' in which the information is put before the Simpletron.
The information in the WorkReg is used in calculations or is examined
in various ways. All information in the Simpletron is handled in terms of
words. A word is a signed, four-digit decimal number, such as +3364, -1293,
+0007, -0001, etc. The Simpletron is equipped with a 100 word memory, and
these words are referenced by their location numbers 00,01,02,03,...,99.
Each instruction written in SML occupies one word of the Simpletron's
memory. The first two digits of a SML instruction are the operation code,
which specifies the operation to be performed. The operation code is always plus. 
The last two digits of an SML instruction are the operand, which is the
address of the memory location containing the word to which the operation applies.

The SimpleTron instruction set'SML'

Examples further down  
I/O operations:
10XX   READ word from user 
      and write to XX in
      Mem
11XX WRITE word from Mem
     to console

Load/Store Operations:
20XX LOAD word from Mem  
     to WorkRegister

21XX STORE word from
     WorkRegister to XX
    in Mem

22XX SET WorkReg to XX


Arithmetic Operations:

30XX ADD word from XX in
     Mem to word in Work
     Reg and leave result 
     in WorkReg

31XX SUBTRACT word  XX in
     Mem from word in
     WorkReg and leave
     result in WorkReg

32XX DIVIDE word in Work
     Reg with word XX in 
     Mem and leave result
     in WorkReg

33XX MULTIPLY word in
     WorkReg with
     word from XX in
     Mem


Transfer Operations:

40XX BRANCH to XX in Mem

41XX BRANCHNEG Branch to
     XX if word in  WorkReg 
     is negative

42XX BRANCHZERO Branch
     to XX in Mem if word 
    in WorkReg is Zero

4300 HALT program. 

Simple exammple programs:
add:
1020 :Read from console to variable 20
1021 :Read from console to variable 21
2020 :load accumulator with variable in 20
3021 :add accumulator with variable i 20
2122 :store accumulator in varable 22
1122 :Print out variable 22

divide:
1020 :Read from console to variable 20
1021 :Read from console to variable 21
2020 :load accumulator with variable in 20
3221 :divide workreg med variable in 21 
2122 :store accumulator in varable 22
1122 :Print out variable 22

loop:
0	1020 :
1	2201 :move '1' to work
2	2121 :store in 21
3	2020 :load 20 to work
4	3121 :subtract 21 from work
5	2122 :store work in 22
6	1122 :print out 22
7	4209 :goto 9 if work is 0
8	4004 :goto 4
9	4300 :halt 

//Here is a comment and SML application that Neil D. Fraser
//once sent me.

Thank-you for creating SimpleTron.  It is a very neat, well-documented
application.

I had fun playing around with it, and wrote a little program that performs
a binary search for the number you are thinking of.  It displays a number,
and you enter -1 (its number was too low), 1 (its number was too high) or 0
(it got it right).  I was rather stunned when the program worked the first
time I ran it.

00  2021  Load the high value
01  3120  Subtract low from high
02  3224  Divide range by two
03  3020  Add low to half-range
04  2122  Store the current guess
05  1122  Print the current guess
06  1023  Read the answer
07  2023  Load the answer
08  4216  If zero, goto end
09  4113  If negative, too low
10  2022  Load the current guess
11  2121  Store guess as high value
12  4000  Restart
13  2022  Load the current guess
14  2120  Store guess as low value
15  4000  Restart
16  4300  End

20  0000  (Low value)
21  0100  (High value + 1)
22  0000  (Current guess)
23  0000  (User input)
24  0002  (Two)

Your language lends itself to self-modifying programs.  I'm trying to think
of an application for this...

Well, there you go ! Have fun. Use this sourcecode for whatever you like,
but if you make an app or something, please mention my name.
**********************************************************************/
 
#include <Pilot.h>				// all the system toolbox headers
#include "TemplateRsc.h"			// application resource defines



#define MAXRAM 100				//Maximun RAM for SimpleTron
#define SimpleTronAppID		'HSK1'
#define SimpleTronDBType	'Data'

/***********************************************************************
 * Global variables for this module
 **********************************************************************/
static MenuBarPtr		CurrentMenu = NULL;	// P2. ptr to current menu
static	Char		InfoStr0[]="Welcome - Simpletron (c) HSK 1998\n\n";
static	Char		InfoStr1[]="- Initializing ..... \n";
static	Char		InfoStr2[]="- Loading instructions -\n";
static	Char		InfoStr3[]="- Memory Dump - \n";
static	Char		InfoStr4[]="REGISTERS:\n";
static	Char		InfoStr5[]="WorkReg: ";
static	Char		InfoStr6[]="InstructionCounter: ";
static	Char		InfoStr7[]="OpCode: ";
static	Char		InfoStr8[]="Operand: ";
static	Char		InfoStr9[]="Memory: \n";
static	Char		InfoStr10[]="- Executing Program -\n";
static	Char		InfoStr11[]="- Execution Ended -\n";
static	Char		InfoStr12[]="- Division by Zero -\n";
static	Char		InfoStr13[]="- Execution Terminated -\n";
static	Char		InfoStr14[]=" Invalid Instruction\n";
static	Char		InfoStr15[]="InputCounter: ";

int TronMemory[MAXRAM], WorkReg=0, InstructionCounter;
int InstructionInputCounter,OpCode,Operand;
Handle bufferHandle;
Handle bufferHandle2;

/*--------------------------------------*/
/* Record structure for program database */
/*--------------------------------------*/
typedef struct {
	int InputCounter;
	Char Name[20];
	int Program[100];
} dbRecord;

char SimpleTronDBName[]="SimpleTronDB";
DmOpenRef					SimpleTronDB;


/***********************************************************************
 * Prototypes for internal functions
 **********************************************************************/
static int StartApplication(void);
static void StopApplication(void);
static void SetCurrentMenu(Word rscID);	// P2. set new current menu
static Boolean MainFormHandleEvent(EventPtr event);
static void EventLoop(void);
static FieldPtr GetFocusObjectPtr (void);
static void EditDoMenuCommand (Word command);
void GetInstructions(void);
void DumpMemory(void);
void ExecuteProgram(void);
void SplitExeCode(void);
void ExecuteInstruction(void);
int Prompt(Char What[30]);
void DisplayDivZError(void);
static Boolean OpenDataBase(void);
static void addRecord(Char FileName[20]);
static dbRecord getRecord(UInt recNum);
void LoadProgram(int ListItem);
void SaveLoadProgram(void);
static void updateRecordList(FormPtr form,int fieldID);
CharPtr makeListItem(dbRecord rec);


/***********************************************************************
 *
 * FUNCTION:     StartApplication
 *
 * DESCRIPTION:  This routine sets up the initial state of the application.
 *
 * PARAMETERS:   None.
 *
 * RETURNED:     Nothing.
 *
 ***********************************************************************/
static int StartApplication(void)
{
	FormPtr	frm;
	FieldPtr 	FldPtrConsole,FldPtrInput;		//HSK
	Char		OutCount[12];
	int error=0;
		
	// Initialize and draw the main memo pad form.
	frm = FrmInitForm(HSKTemplateMainForm);	
	FrmSetActiveForm(frm);
	FrmDrawForm(frm);
	SetCurrentMenu(MainFormMenuBar);		// P2. set the current menu to the main menu
		
	error = OpenDataBase();
	if(error) return error;
	
	
		frm = FrmGetFormPtr(HSKTemplateMainForm);
		FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));
		FldPtrInput = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainInputField))));

		FldInsert(FldPtrConsole, InfoStr0,StrLen(InfoStr0));
//		SysTaskDelay(50);
		FldInsert(FldPtrConsole, InfoStr1,StrLen(InfoStr1));
//		SysTaskDelay(100);
		FldInsert(FldPtrConsole, InfoStr2,StrLen(InfoStr2));
		InstructionInputCounter=0;

		WorkReg=0;

		StrIToA(OutCount,InstructionInputCounter);
		StrCat(OutCount," ?");
		FldInsert(FldPtrConsole, OutCount,StrLen(OutCount));		

return 0;
}

/*---------------------*/
/* StopApplication     */
/*---------------------*/
/* Closes the database */
/*---------------------*/
static void StopApplication()
{
	DmCloseDatabase(SimpleTronDB);
}


/***********************************************************************
 *
 * FUNCTION:    SetCurrentMenu
 *
 * DESCRIPTION: P2. This routine loads the specified menu resource and makes
 *              it the current menu.  
 *
 * PARAMETERS:  rscID  - resource id of the new menu
 *
 * RETURNED:    nothing
 *
 ***********************************************************************/
static void SetCurrentMenu(Word rscID)
{
	// Dispose of an existing current menu.
	if (CurrentMenu)
		MenuDispose(CurrentMenu);
	
	// Set the current menu and remember it.
	CurrentMenu = MenuInit(rscID);
}

/***********************************************************************
 *
 * FUNCTION:    GetFocusObjectPtr
 *
 * DESCRIPTION: P4. This routine returns a pointer to the field object, in 
 *              the current form, that has the focus.
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    pointer to a field object or NULL of there is no focus
 *
 ***********************************************************************/
static FieldPtr GetFocusObjectPtr (void)
{
	FormPtr frm;
	Word focus;
	
	// get a pointer to tha active form and the index of the form object with focus
	frm = FrmGetActiveForm ();
	focus = FrmGetFocus (frm);

	// if no object has the focus return NULL pointer
	if (focus == noFocus)
		return (NULL);
		
	// return a pointer to the object with focus
	return (FrmGetObjectPtr (frm, focus));
}


/***********************************************************************
 *
 * FUNCTION:    EditDoMenuCommand
 *
 * DESCRIPTION: P4. This routine performs the menu command specified.
 *
 * PARAMETERS:  command  - menu item id
 *
 * RETURNED:    nothing
 *
 ***********************************************************************/
static void EditDoMenuCommand (Word command)
{
	FieldPtr fld;
	FormPtr	frm;
	EventType	newEvent;
	FieldPtr 	FldPtrConsole;		//HSK
	Char		OutCount[12];
	int temp=0;	

	switch (command)
		{
		
		case MainOptionsRun:
			frm = FrmInitForm(HSKTemplateMainForm);	
			frm = FrmGetFormPtr(HSKTemplateMainForm);
			FrmSetActiveForm (frm);	
			FrmDrawForm(frm);
			ExecuteProgram();
			break;
		
		case MainOptionsNew:
			frm = FrmInitForm(HSKTemplateMainForm);	
			frm = FrmGetFormPtr(HSKTemplateMainForm);
			FrmSetActiveForm (frm);	
			FrmDrawForm(frm);
			FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));


			FldDelete(FldPtrConsole, 0, FldGetTextLength(FldPtrConsole));		
			FldInsert(FldPtrConsole, InfoStr2,StrLen(InfoStr2));

			for(temp=0;temp<MAXRAM;temp++)
				  TronMemory[temp]=0;

			InstructionInputCounter=0;
			StrIToA(OutCount,InstructionInputCounter);
			StrCat(OutCount," ?");
			FldInsert(FldPtrConsole, OutCount,StrLen(OutCount));		

			break;

		case MainOptionsDumpMem:
			frm = FrmInitForm(HSKTemplateMainForm);	
			frm = FrmGetFormPtr(HSKTemplateMainForm);
			FrmSetActiveForm (frm);	
			FrmDrawForm(frm);
			DumpMemory();
			break;			

		case MainOptionsGotoMemPos:
			InstructionInputCounter=Prompt(" Memory Position");
			frm = FrmGetFormPtr(HSKTemplateMainForm);
			FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));
	
			FldInsert(FldPtrConsole,"\n",1);
			StrIToA(OutCount,InstructionInputCounter);
			StrCat(OutCount," ?");
			FldInsert(FldPtrConsole, OutCount,StrLen(OutCount));		
			break;
			
		case MainOptionsSave:
			SaveLoadProgram();
			break;
	
		case MainOptionsLoad:
			SaveLoadProgram();
			break;

		case MainOptionsDelete:
			SaveLoadProgram();
			break;

		case MainOptionsExit:
			MemSet(&newEvent, sizeof(EventType), 0);
	   		newEvent.eType = appStopEvent;
   			EvtAddEventToQueue(&newEvent);
			break;
				
		case HelpHelp:
			FrmHelp( HelpMainHelpString );			
			break;
			
		case HelpSMLInstructions:
			FrmHelp( HelpInstructionsString );
			break;

		case HelpAbout:
			frm = FrmInitForm(HSKTemplateInfoForm);
			FrmDoDialog(frm);
 			FrmDeleteForm(frm);
			break;

		case EditCut:			// Do a cut to the clipboard if text is highlighted.
			fld = GetFocusObjectPtr();
			if (fld)
				FldCut(fld);
			break;
		
		case EditCopy:			// Copy the highlighted text to the clipboard.
			fld = GetFocusObjectPtr();
			if (fld)
				FldCopy(fld);	
			break;
		
		case EditPaste:			// Do a paste from the clipboard.
			fld = GetFocusObjectPtr();
			if (fld)
				FldPaste(fld);		
			break;
			
		case EditUndo:			// undo the last text change.
			fld = GetFocusObjectPtr();
			if (fld)
				FldUndo(fld);
			break;
		
		case EditSelectAll:	// Select all the existing text.
			fld = GetFocusObjectPtr();
			if (fld)
				FldSetSelection(fld, 0, FldGetTextLength(fld));
			break;
			
		case EditKeyboard:		// display the on screen keyboard
			SysKeyboardDialog (kbdAlpha);
			break;
			
		case EditGraffiti:		// Display the graffiti reference screen
			SysGraffitiReferenceDialog (referenceDefault);
			break;
			
		}	
}


/***********************************************************************
 *
 * FUNCTION:		MainFormHandleEvent
 *
 * DESCRIPTION:	Handles processing of events for the ÒmainÓ form.
 *
 * PARAMETERS:		event		- the most recent event.
 *
 * RETURNED:		True if the event is handled, false otherwise.
 *
 ***********************************************************************/
static Boolean MainFormHandleEvent(EventPtr event)
{
	Boolean		handled = false;

   if (event->eType == ctlSelectEvent)
   {

   		if (event->data.ctlEnter.controlID==HSKTemplateMainEnterButton)
		{
		GetInstructions();
   		}

		handled = true;
	}

	else if (event->eType == menuEvent)		// P2. process menu events for this form
		{
			// First clear the menu status from the display.
			MenuEraseStatus(0);
			EditDoMenuCommand(event->data.menu.itemID);
			handled = true;

		}
	return handled;
}


/***********************************************************************
 *
 * FUNCTION:		EventLoop
 *
 * DESCRIPTION:	A simple loop that obtains events from the Event
 *						Manager and passes them on to various applications and
 *						system event handlers before passing them on to
 *						FrmHandleEvent for default processing.
 *
 * PARAMETERS:		None.
 *
 * RETURNED:		Nothing.
 *
 ***********************************************************************/
static void EventLoop(void)
{
	EventType	event;
	Word			error;
	
	do
		{
		// Get the next available event.
		EvtGetEvent(&event, evtWaitForever);
		
		// Give the system a chance to handle the event.
		if (! SysHandleEvent(&event))

			// P2. Give the menu bar a chance to update and handle the event.	
			if (! MenuHandleEvent(CurrentMenu, &event, &error))

				// Give the application a chance to handle the event.
				if (! MainFormHandleEvent(&event))

					// Let the form object provide default handling of the event.
					FrmHandleEvent(FrmGetActiveForm(), &event);
		}
	while (event.eType != appStopEvent);
}


/***********************************************************************
 *
 * FUNCTION:		PilotMain
 *
 * DESCRIPTION:	This function is the equivalent of a main() function
 *						under standard ÒCÓ.  It is called by the Emulator to begin
 *						execution of this application.
 *
 * PARAMETERS:		cmd - command specifying how to launch the application.
 *						cmdPBP - parameter block for the command.
 *						launchFlags - flags used to configure the launch.			
 *
 * RETURNED:		Any applicable error code.
 *
 ***********************************************************************/
DWord PilotMain(Word cmd, Ptr cmdPBP, Word launchFlags)
{
short err;

	// Check for a normal launch.
	if (cmd == sysAppLaunchCmdNormalLaunch)
		{
		// Set up initial form.

		err = StartApplication();
		if(err) return err;

		
		// Start up the event loop.

		EventLoop();

		StopApplication();
		}
		
	return 0;
}

void GetInstructions(void)
{
	int count=0;
	FieldPtr 	FldPtrConsole;		//HSK
	FieldPtr	FldPtrInput;
	FormPtr		frm;
	CharPtr		txtptr;
	Char		OutCount[12];
	long			temp=0;

		frm = FrmGetFormPtr(HSKTemplateMainForm);
		FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));
		FldPtrInput	= (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainInputField))));	

		bufferHandle = MemHandleNew(20);
		txtptr = MemHandleLock(bufferHandle);			//NB totalhavari pŒ CharPtr Buffer om ikke denne var med nŒr den ble st¿rre enn 26..


		txtptr=FldGetTextPtr (FldPtrInput);

		if(FldGetTextLength(FldPtrConsole)>5201) 
			FldDelete(FldPtrConsole, 0, 5000);		

		if (txtptr!=NULL )temp=StrAToI(txtptr);
		
		if(temp>-10000 && temp<10000)
			{		

			TronMemory[InstructionInputCounter]=temp;
			
			
			if (txtptr!=NULL )FldInsert(FldPtrConsole,txtptr,StrLen(txtptr));
			FldInsert(FldPtrConsole,"\n",1);
			FldDelete(FldPtrInput, 0, FldGetTextLength(FldPtrInput));		
	
			if(InstructionInputCounter==MAXRAM-1) InstructionInputCounter=0;
				else
					InstructionInputCounter++;
	
			StrIToA(OutCount,InstructionInputCounter);
			StrCat(OutCount," ?");
			FldInsert(FldPtrConsole, OutCount,StrLen(OutCount));		
			}
			else	//invalid instruction
				{
				if (txtptr!=NULL )FldInsert(FldPtrConsole,txtptr,StrLen(txtptr));
				FldInsert(FldPtrConsole, InfoStr14,StrLen(InfoStr14));
				FldDelete(FldPtrInput, 0, FldGetTextLength(FldPtrInput));		
		
				StrIToA(OutCount,InstructionInputCounter);
				StrCat(OutCount," ?");
				FldInsert(FldPtrConsole, OutCount,StrLen(OutCount));		
				}


MemHandleUnlock(bufferHandle);		
MemHandleFree(bufferHandle);

}

void DumpMemory(void)
{
	FormPtr	frm;
	FieldPtr 	FldPtrConsole;		//HSK
	unsigned int i=0;	
	CharPtr Buffer;		//MŒtte bruker ekte charptr, fikk totalhavari av CoPilot dersom ikke...
	CharPtr	Buffer2;
	
	frm = FrmGetFormPtr(HSKTemplateMainForm);
	FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));
	FldDelete(FldPtrConsole, 0, FldGetTextLength(FldPtrConsole));		

FldInsert(FldPtrConsole, InfoStr3,StrLen(InfoStr3));
FldInsert(FldPtrConsole, InfoStr4,StrLen(InfoStr4));	//"REGISTERS:"

bufferHandle = MemHandleNew(600);
Buffer = MemHandleLock(bufferHandle);			//NB totalhavari pŒ CharPtr Buffer om ikke denne var med nŒr den ble st¿rre enn 26..
//bufferHandle2 = MemHandleNew(20);
//Buffer2 = MemHandleLock(bufferHandle);			//NB totalhavari pŒ CharPtr Buffer om ikke denne var med nŒr den ble st¿rre enn 26..


StrIToA(Buffer2,WorkReg);
Buffer=StrCopy(Buffer,InfoStr5);
StrCat(Buffer,Buffer2);
StrCat(Buffer," \n");
FldInsert(FldPtrConsole, Buffer,StrLen(Buffer));		//"WorkReg:"

StrIToA(Buffer2,InstructionCounter);
Buffer=StrCopy(Buffer,InfoStr6);
StrCat(Buffer,Buffer2);
StrCat(Buffer," \n");
FldInsert(FldPtrConsole, Buffer,StrLen(Buffer));		//"InstructionCounter:"

StrIToA(Buffer2,InstructionInputCounter);
Buffer=StrCopy(Buffer,InfoStr15);
StrCat(Buffer,Buffer2);
StrCat(Buffer," \n");
FldInsert(FldPtrConsole, Buffer,StrLen(Buffer));		//"InstructionInputCounter:"


StrIToA(Buffer2,OpCode);
Buffer=StrCopy(Buffer,InfoStr7);
StrCat(Buffer,Buffer2);
StrCat(Buffer," \n");
FldInsert(FldPtrConsole, Buffer,StrLen(Buffer));		//"OpCode:"


StrIToA(Buffer2,Operand);
Buffer=StrCopy(Buffer,InfoStr8);
StrCat(Buffer,Buffer2);
StrCat(Buffer," \n");
FldInsert(FldPtrConsole, Buffer,StrLen(Buffer));		//"Operand:"


FldInsert(FldPtrConsole, InfoStr9,StrLen(InfoStr9));	//"MEMORY:"

Buffer=StrCopy(Buffer,"");
Buffer2=StrCopy(Buffer2,"");

for(i=0;i<MAXRAM;i++)
	{
	StrIToA(Buffer2,TronMemory[i]);
	StrCat(Buffer,Buffer2);
	StrCat(Buffer," ");
	}
	FldInsert(FldPtrConsole,Buffer ,StrLen(Buffer));	//"MEMORY:"	


MemHandleUnlock(bufferHandle);		
MemHandleFree(bufferHandle);

}

void ExecuteProgram(void)
{
	FormPtr	frm;
	FieldPtr 	FldPtrConsole;		//HSK
	unsigned int i=0;	
	
	frm = FrmGetFormPtr(HSKTemplateMainForm);
	FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));
	FldDelete(FldPtrConsole, 0, FldGetTextLength(FldPtrConsole));		

	FldInsert(FldPtrConsole, InfoStr10,StrLen(InfoStr10));

	WorkReg=0;
	InstructionCounter=0;
	OpCode=0;
	Operand=0;

	while (InstructionCounter<100)
	{
	SplitExeCode();
	ExecuteInstruction();
	InstructionCounter=InstructionCounter+1;
	}
	FldInsert(FldPtrConsole, InfoStr11,StrLen(InfoStr11));
}

void SplitExeCode(void)
{
	Operand=(TronMemory[InstructionCounter] % 100);
	OpCode=(TronMemory[InstructionCounter] / 100);
}

void ExecuteInstruction(void)
{
	FormPtr frm;
	FieldPtr FldPtrConsole;
	CharPtr txtptr;

	Char OutVariable[6];
	Handle	tempBufferHandle;
	
	tempBufferHandle = MemHandleNew(60);
	txtptr = MemHandleLock(tempBufferHandle);			//NB totalhavari pŒ CharPtr Buffer om ikke denne var med nŒr den ble st¿rre enn 26..
	
	MemSet(txtptr,sizeof(txtptr),0);
	
	switch (OpCode)
	{
	case 10:
		StrIToA(OutVariable,Operand);				
		txtptr=StrCopy(txtptr," Variable  ");
		StrCat(txtptr,OutVariable);		
		TronMemory[Operand]=Prompt(txtptr);
		break;

	case 11:
		frm = FrmGetFormPtr(HSKTemplateMainForm);
		FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));

		bufferHandle = MemHandleNew(50);
		txtptr = MemHandleLock(bufferHandle);			//NB totalhavari pŒ CharPtr Buffer om ikke denne var med nŒr den ble st¿rre enn 26..

		txtptr=StrCopy(txtptr,"");
		StrIToA(txtptr,TronMemory[Operand]);
		StrCat(txtptr," \n");		

		if(FldGetTextLength(FldPtrConsole)>5201) 
			FldDelete(FldPtrConsole, 0, 5000);		

		FldInsert(FldPtrConsole, txtptr,StrLen(txtptr));
		MemHandleUnlock(bufferHandle);
		MemHandleFree(bufferHandle);
		break;

	case 20:
		WorkReg=TronMemory[Operand];
		break;

	case 21:
		TronMemory[Operand]=WorkReg;
		break;

	case 22:
		WorkReg=Operand;
		break;

	case 30:
		WorkReg=WorkReg+TronMemory[Operand];
		break;

	case 31:
		WorkReg=WorkReg-TronMemory[Operand];
		break;

	case 32:
		if(TronMemory[Operand]!=0) 
		WorkReg=WorkReg/TronMemory[Operand];
			else 
				{
				DisplayDivZError();
				InstructionCounter=100;				
				}
		break;

	case 33:
		WorkReg=WorkReg*TronMemory[Operand];
		break;

	case 40:
		InstructionCounter=(Operand-1);
		break;

	case 41:
		if (WorkReg<0) InstructionCounter=(Operand-1);
		break;

	case 42:
		if (WorkReg==0) InstructionCounter=(Operand-1);
		break;

	case 43:
		InstructionCounter=100;
		break;
	}

	MemHandleUnlock(tempBufferHandle);
	MemHandleFree(tempBufferHandle);

}


int Prompt(Char What[30])
{

	FormPtr frm;
	FieldPtr FldPtrInput,FldPtrNeedVariable;
	CharPtr txtptr;
	int result=0;
	Handle	tempBufferHandle;
	
	tempBufferHandle = MemHandleNew(60);
	txtptr = MemHandleLock(tempBufferHandle);			//NB totalhavari pŒ CharPtr Buffer om ikke denne var med nŒr den ble st¿rre enn 26..

	frm = FrmInitForm(InputForm);

	frm = FrmGetFormPtr(InputForm);
	FrmSetActiveForm (frm);
	
	FldPtrInput = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm,InputInputField))));
	FldPtrNeedVariable = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, InputNeedVariableField))));

	txtptr=StrCopy(txtptr,What);
	FldInsert(FldPtrNeedVariable, txtptr,StrLen(txtptr));


	FrmDoDialog(frm);

	txtptr=StrCopy(txtptr,"");
	txtptr=FldGetTextPtr (FldPtrInput);	

	if (txtptr!=NULL)result= StrAToI (txtptr);


	
	MemHandleUnlock(tempBufferHandle);
	MemHandleFree(tempBufferHandle);
	FrmDeleteForm(frm);
		
	frm = FrmGetFormPtr(HSKTemplateMainForm);
	FrmSetActiveForm (frm);	
	FrmDrawForm(frm);
	SetCurrentMenu(MainFormMenuBar);		// P2. set the current menu to the main menu
	return result;
}

void DisplayDivZError(void)
{
	FormPtr	frm;
	FieldPtr 	FldPtrConsole;		//HSK

	frm = FrmGetFormPtr(HSKTemplateMainForm);
	FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));
	FldInsert(FldPtrConsole, InfoStr12,StrLen(InfoStr12));
	FldInsert(FldPtrConsole, InfoStr13,StrLen(InfoStr13));

}


/*----------------------------------*/
/* openDatabase                     */
/*----------------------------------*/
/* Does what it says on the label ! */
/*----------------------------------*/
static Boolean OpenDataBase()
{
	SimpleTronDB = DmOpenDatabaseByTypeCreator(SimpleTronDBType,SimpleTronAppID,dmModeReadWrite);

	if(!SimpleTronDB)
	{
		if(DmCreateDatabase(0,SimpleTronDBName,SimpleTronAppID,SimpleTronDBType,false)) return 1;
		SimpleTronDB = DmOpenDatabaseByTypeCreator(SimpleTronDBType,SimpleTronAppID,dmModeReadWrite);
	}

	return 0;
}

/*----------------------------------*/
/*Add record to database			*/
/*----------------------------------*/
static void addRecord(Char FileName[20])
{
	dbRecord Rec;
	int i;
	UInt currRec;
	VoidHand recHandle;
	Ptr		recPtr;
	UInt count = DmNumRecords(SimpleTronDB);
	
	for(i=0;i<MAXRAM;i++)
	{
		Rec.Program[i] = TronMemory[i];
	}
	
	StrCopy(Rec.Name,FileName);
	Rec.InputCounter=InstructionInputCounter;
		
	currRec=0;
	recHandle = DmNewRecord(SimpleTronDB,&currRec,sizeof(Rec));

	recPtr = MemHandleLock(recHandle);
	DmWrite(recPtr,0,&Rec,sizeof(Rec));
	MemPtrUnlock(recPtr);
	DmReleaseRecord(SimpleTronDB,currRec,true);
}


/*-------------------------------------------------------*/
/* getRecord                                             */
/*-------------------------------------------------------*/
/* Returns the record retrieved from the specified index */
/*-------------------------------------------------------*/
static dbRecord getRecord(UInt recNum)
{
	VoidHand recHandle;
	Ptr recPtr;
	dbRecord rec;
	UInt count = DmNumRecords(SimpleTronDB);	
	
	if (count!=NULL)
	{
	recHandle = DmQueryRecord(SimpleTronDB,recNum);
	recPtr = MemHandleLock(recHandle);
	MemMove(&rec,recPtr,sizeof(rec));
	MemPtrUnlock(recPtr);
	}
	else
		{
		MemSet(rec.Program,sizeof(rec.Program),0);
		MemSet(rec.Name,sizeof(rec.Name),0);
		rec.InputCounter=0;
		}

return(rec);
}





void LoadProgram(int ListItem)
{
	dbRecord Rec;
	int i;
	FieldPtr 	FldPtrConsole;
	FormPtr		frm;
	Char		OutCount[12];
	
	
	MemSet(Rec.Program,sizeof(Rec.Program),0);
	MemSet(Rec.Name,sizeof(Rec.Name),0);
	Rec.InputCounter=0;
	Rec = getRecord(ListItem);
	
	InstructionInputCounter = Rec.InputCounter;
	for(i=0;i<MAXRAM;i++)
	{
		TronMemory[i]=Rec.Program[i];
	}

		frm = FrmGetFormPtr(HSKTemplateMainForm);
		FldPtrConsole = (FieldPtr)(FrmGetObjectPtr(frm, (FrmGetObjectIndex(frm, HSKTemplateMainConsoleField))));

		FldInsert(FldPtrConsole,"\n",1);
		StrIToA(OutCount,InstructionInputCounter);
		StrCat(OutCount," ?");
		FldInsert(FldPtrConsole, OutCount,StrLen(OutCount));		
}



void SaveLoadProgram(void)
{
	FormPtr frmSaveLoad;
	FieldPtr FldPtrSaveAs;
	int 	button,ListItem=0;
	CharPtr	txtptr;
	Char 	FileName[20];
	Handle tempBufferHandle;
	
		
	tempBufferHandle = MemHandleNew(60);
	txtptr = MemHandleLock(tempBufferHandle);			//NB totalhavari pŒ CharPtr Buffer om ikke denne var med nŒr den ble st¿rre enn 26..

			frmSaveLoad = FrmInitForm(SaveDialogForm);
	 	    FldPtrSaveAs = (FieldPtr)(FrmGetObjectPtr(frmSaveLoad, (FrmGetObjectIndex(frmSaveLoad,SaveDialogSaveAsField))));

			updateRecordList(frmSaveLoad,SaveDialogFileList);

			button=FrmDoDialog(frmSaveLoad);
			
			ListItem=LstGetSelection(FrmGetObjectPtr(frmSaveLoad,FrmGetObjectIndex(frmSaveLoad,SaveDialogFileList)));
			
			txtptr=FldGetTextPtr (FldPtrSaveAs);	

			if (txtptr!=NULL) StrCopy(FileName,txtptr);
				else StrCopy(FileName,"NoName.sml");			

 			FrmDeleteForm(frmSaveLoad);
	
		MemHandleUnlock(tempBufferHandle);
		MemHandleFree(tempBufferHandle);


	switch(button)
		{
		
		case SaveDialogSaveButton:
			addRecord(FileName);			
			break;

		case SaveDialogLoadButton:
			LoadProgram(ListItem);			
			break;

		case SaveDialogDeleteButton:
			if(ListItem!=-1)DmRemoveRecord(SimpleTronDB,ListItem);
			break;
		
		}

}

static UInt getListSelection(FormPtr form, UInt listID)
{
	return LstGetSelection(FrmGetObjectPtr(form,FrmGetObjectIndex(form,listID)));
}


/*---------------------------------------------------------*/
/* updateRecordList                                        */
/*---------------------------------------------------------*/
/* Dynamically updates the specified list from the records */
/* in the database.                                        */
/*---------------------------------------------------------*/
static void updateRecordList(FormPtr form,int fieldID)
{
	UInt i;
	UInt count = DmNumRecords(SimpleTronDB);
	char **listChoices = (char **) MemPtrNew(count * (sizeof(char *)));
	dbRecord checkingRecord;
	Ptr field;


	for (i = 0; i < count; i++)
	{
		checkingRecord = getRecord(i);
		listChoices[i] = makeListItem(checkingRecord);
	}

	field = FrmGetObjectPtr(form, FrmGetObjectIndex(form, fieldID));
	LstSetListChoices((ListPtr) field, listChoices, count);
}



/*------------------------------------------------------------*/
/* makeListItem                                               */
/*------------------------------------------------------------*/
/* Returns a CharPtr to a new item to be added to a list.     */
/*------------------------------------------------------------*/
CharPtr makeListItem(dbRecord rec)
{
	CharPtr listItem;
	Char temp[20];


	listItem=MemPtrNew(35);
	MemSet(listItem,35,0);
	MemSet(temp,20,0);

	StrCat(listItem,rec.Name); 

	return listItem;
}







