From b46045388cd0d5e9ca3b3c57ff5442bc4b85e7fa Mon Sep 17 00:00:00 2001 From: Aleksejs Medveckis Date: Thu, 22 Feb 2024 15:25:04 +0200 Subject: [PATCH 1/3] argument_parsing: add words to parse command line arguments --- src/main.fs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/src/main.fs b/src/main.fs index 9f72fbb..9e1dc81 100644 --- a/src/main.fs +++ b/src/main.fs @@ -1,5 +1,11 @@ create inputBuffer 80 allot + +variable inputBufferActualLength variable continueFlag +variable substringStartPosition +variable substringLength +variable replaceIndex + code prepareScreen lda #5 ; green @@ -7,6 +13,7 @@ code prepareScreen lda #$17 sta $D018 ; set mixed mode jsr $e544 ; clear screen + dex lda #$00 ; black sta $d020 ; border sta $d021 ; background @@ -30,6 +37,54 @@ code restoreScreen inputBuffer 80 0 fill ; +: debugString ( len -- ) + 0 do + i . inputBuffer i + c@ . inputBuffer i + c@ emit cr + loop +; + +: stringLenght ( addr - len) + + dup substringStartPosition ! + + 80 0 do + substringStartPosition @ i + c@ 0 = if + i 1 + + leave + then + loop +; + +: replaceSpaceToZero + substringStartPosition @ + substringStartPosition @ substringLength @ + 1 + substringStartPosition ! + 0 substringLength ! + replaceIndex @ 1 + inputBufferActualLength @ = if + substringLength @ 1 + substringLength ! + else + 0 inputBuffer replaceIndex @ + c! + then +; + +: parseArgs ( addr len - list of substrings ) + 0 substringLength ! + dup 0> if + dup inputBufferActualLength ! + + 0 do + inputBuffer i + c@ 32 = + i 1 + inputBufferActualLength @ = + or if + i replaceIndex ! + replaceSpaceToZero + else + substringLength @ 1 + substringLength ! + then + loop + cr + then +; + : main prepareScreen @@ -38,16 +93,24 @@ code restoreScreen ." Enter data for calculation using RPN: " cr cr cr begin + clearBuffer - inputBuffer 80 accept cr + inputBuffer 80 accept cr - inputBuffer @ 'q' = if + inputBuffer c@ 'q' = if -1 continueFlag ! else 0 continueFlag ! - then - - continueFlag @ until + inputBuffer substringStartPosition ! + inputBuffer swap parseArgs + + begin + stringLenght type cr + depth 1 = until + then + drop + + continueFlag @ until restoreScreen ; From 2705bfb017b8b65a43cbe205fe11d9ae98d8b832 Mon Sep 17 00:00:00 2001 From: medvecky Date: Tue, 26 Mar 2024 19:55:55 +0200 Subject: [PATCH 2/3] implement basic arithmetic operations in C --- Makefile | 28 ++++- Readme.md | 3 +- src/main.fs | 118 -------------------- src/modules/adt_stack.c | 89 +++++++++++++++ src/modules/adt_stack.h | 26 +++++ src/modules/math_helper.c | 119 ++++++++++++++++++++ src/modules/math_helper.h | 24 +++++ src/modules/misc_helper.c | 209 ++++++++++++++++++++++++++++++++++++ src/modules/misc_helper.h | 18 ++++ src/modules/system_helper.c | 38 +++++++ src/modules/system_helper.h | 4 + src/multicalc.c | 37 +++++++ 12 files changed, 590 insertions(+), 123 deletions(-) delete mode 100644 src/main.fs create mode 100644 src/modules/adt_stack.c create mode 100644 src/modules/adt_stack.h create mode 100644 src/modules/math_helper.c create mode 100644 src/modules/math_helper.h create mode 100644 src/modules/misc_helper.c create mode 100644 src/modules/misc_helper.h create mode 100644 src/modules/system_helper.c create mode 100644 src/modules/system_helper.h create mode 100644 src/multicalc.c diff --git a/Makefile b/Makefile index 24ff492..4267532 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,30 @@ -multicalc: build src/main.fs - acmeforth src/main.fs - acme -o bin/multicalc.prg -f cbm main.asm +multicalc: build build/multicalc.o build/system_helper.o build/math_helper.o build/misc_helper.o build/adt_stack.o + cl65 build/multicalc.o build/system_helper.o build/math_helper.o build/misc_helper.o build/adt_stack.o -o bin/multicalc.prg + +build/multicalc.o: src/multicalc.c + cl65 -c src/multicalc.c + @mv src/multicalc.o build/multicalc.o + +build/system_helper.o: src/modules/system_helper.c + cl65 -c src/modules/system_helper.c + @mv src/modules/system_helper.o build/system_helper.o + +build/math_helper.o: src/modules/math_helper.c + cl65 -c src/modules/math_helper.c + @mv src/modules/math_helper.o build/math_helper.o + +build/misc_helper.o: src/modules/misc_helper.c + cl65 -c src/modules/misc_helper.c + @mv src/modules/misc_helper.o build/misc_helper.o + +build/adt_stack.o: src/modules/adt_stack.c + cl65 -c src/modules/adt_stack.c + @mv src/modules/adt_stack.o build/adt_stack.o build: + @mkdir -p build @mkdir -p bin clean: - @rm -rf *.asm + @rm -rf build @rm -rf bin \ No newline at end of file diff --git a/Readme.md b/Readme.md index e619613..1cb9219 100644 --- a/Readme.md +++ b/Readme.md @@ -1,2 +1,3 @@ # C64-multi-functional-calculator -Multi-functional text-based calculator for the Commodore 64. \ No newline at end of file + +Multi-functional text-based calculator for the Commodore 64. diff --git a/src/main.fs b/src/main.fs deleted file mode 100644 index 9e1dc81..0000000 --- a/src/main.fs +++ /dev/null @@ -1,118 +0,0 @@ -create inputBuffer 80 allot - -variable inputBufferActualLength -variable continueFlag -variable substringStartPosition -variable substringLength -variable replaceIndex - - -code prepareScreen - lda #5 ; green - sta $0286 ; text color - lda #$17 - sta $D018 ; set mixed mode - jsr $e544 ; clear screen - dex - lda #$00 ; black - sta $d020 ; border - sta $d021 ; background - rts -;code - -code restoreScreen - lda #$f6 - sta $d021 ;background - lda #$fe - sta $d020 ;border - lda #$e - sta $0286 ;text color - jsr $e544 ;clear screen - lda #$15 ;set uper case - sta $d018 ; text mode - rts -;code - -: clearBuffer - inputBuffer 80 0 fill -; - -: debugString ( len -- ) - 0 do - i . inputBuffer i + c@ . inputBuffer i + c@ emit cr - loop -; - -: stringLenght ( addr - len) - - dup substringStartPosition ! - - 80 0 do - substringStartPosition @ i + c@ 0 = if - i 1 + - leave - then - loop -; - -: replaceSpaceToZero - substringStartPosition @ - substringStartPosition @ substringLength @ + 1 + substringStartPosition ! - 0 substringLength ! - replaceIndex @ 1 + inputBufferActualLength @ = if - substringLength @ 1 + substringLength ! - else - 0 inputBuffer replaceIndex @ + c! - then -; - -: parseArgs ( addr len - list of substrings ) - 0 substringLength ! - dup 0> if - dup inputBufferActualLength ! - - 0 do - inputBuffer i + c@ 32 = - i 1 + inputBufferActualLength @ = - or if - i replaceIndex ! - replaceSpaceToZero - else - substringLength @ 1 + substringLength ! - then - loop - cr - then -; - -: main - prepareScreen - - - ." Calculator " cr - ." Enter data for calculation using RPN: " cr cr cr - - begin - - clearBuffer - inputBuffer 80 accept cr - - inputBuffer c@ 'q' = if - -1 continueFlag ! - else - 0 continueFlag ! - inputBuffer substringStartPosition ! - inputBuffer swap parseArgs - - begin - stringLenght type cr - depth 1 = until - then - drop - - continueFlag @ until - - restoreScreen -; - -compile main \ No newline at end of file diff --git a/src/modules/adt_stack.c b/src/modules/adt_stack.c new file mode 100644 index 0000000..b918762 --- /dev/null +++ b/src/modules/adt_stack.c @@ -0,0 +1,89 @@ +#include + +#include "adt_stack.h" +#include "math_helper.h" + +void Stack_push( StackNodePtr * topPtr, FP value ) +{ + StackNodePtr newPtr; + + newPtr = malloc( sizeof( StackNode ) ); + + if ( newPtr != NULL ) + { + memcpy( newPtr->data, value, sizeof( FP ) ); + newPtr->nextPtr = *topPtr; + *topPtr = newPtr; + } + else + { + FP_printRaw( value ); + puts( "not inserted. No memory available.\n" ); + } +} + +void Stack_print( StackNodePtr currentPtr ) +{ + if ( currentPtr == NULL ) + { + puts( "The stack is empty" ); + } + else + { + puts( "The stack is: " ); + + while ( currentPtr != NULL ) + { + printf( "--> " ); + FP_printRaw( currentPtr->data ); + currentPtr = currentPtr->nextPtr; + } + + puts( "NULL\n" ); + } +} + +void Stack_pop( StackNodePtr * topPtr, FP * popValue ) +{ + StackNodePtr tempPtr; + + if ( Stack_isEmpty( *topPtr ) ) + { + puts( "Stack is empty. Cannot pop value." ); + return; + } + + tempPtr = *topPtr; + memcpy( *popValue, ( *topPtr )->data, sizeof( FP ) ); + *topPtr = ( *topPtr )->nextPtr; + free( tempPtr ); +} + +bool Stack_isEmpty( StackNodePtr topPtr ) +{ + return topPtr == NULL; +} + +void Stack_getTop( StackNodePtr topPtr, FP * topValue) +{ + if ( Stack_isEmpty( topPtr ) ) + { + puts( "Stack is empty. Cannot pop value." ); + return; + } + + memcpy( *topValue, topPtr->data, sizeof( FP ) ); +} + +void Stack_free( StackNodePtr * topPtr ) +{ + StackNodePtr tempPtr = *topPtr; + StackNodePtr nextPtr; + while ( tempPtr != NULL ) + { + nextPtr = ( *tempPtr ).nextPtr; + free( tempPtr ); + tempPtr = nextPtr; + } +} + diff --git a/src/modules/adt_stack.h b/src/modules/adt_stack.h new file mode 100644 index 0000000..7cee467 --- /dev/null +++ b/src/modules/adt_stack.h @@ -0,0 +1,26 @@ +#ifndef ATD_STACK_H +#define ATD_STACK_H + +#include +#include +#include + +#include "math_helper.h" + +struct stackNode +{ + FP data; + struct stackNode *nextPtr; +}; + +typedef struct stackNode StackNode; +typedef StackNode *StackNodePtr; + +void Stack_push( StackNodePtr * topPtr, FP value ); +void Stack_print( StackNodePtr currentPtr ); +void Stack_pop( StackNodePtr * topPtr, FP * popValue ); +bool Stack_isEmpty( StackNodePtr topPtr ); +void Stack_getTop( StackNodePtr topPtr, FP * topValue ); +void Stack_free( StackNodePtr * topPtr ); + +#endif \ No newline at end of file diff --git a/src/modules/math_helper.c b/src/modules/math_helper.c new file mode 100644 index 0000000..819aa89 --- /dev/null +++ b/src/modules/math_helper.c @@ -0,0 +1,119 @@ +#include + +#include "math_helper.h" + +uint8_t argLength = 0; +FP resultFp = { 0, 0, 0, 0, 0 }; +FP arg1Fp = { 0, 0, 0, 0, 0 }; +FP arg2Fp = { 0, 0, 0, 0, 0 }; +char arg1[ MAX_ARGUMENT_LENGTH ]; +char arg2[ MAX_ARGUMENT_LENGTH ]; + +void FP_arg1ToFp( void ) +{ + __asm__ ( "lda #<%v", arg1 ); + __asm__ ( "sta $22" ); + __asm__ ( "lda #>%v", arg1 ); + __asm__ ( "sta $23" ); + __asm__ ( "lda #<%v", argLength ); + __asm__ ( "jsr $b7b5" ); + + __asm__ ( "ldx #<%v", arg1Fp ); + __asm__ ( "ldy #>%v", arg1Fp ); + __asm__ ( "jsr $bbd4" ); +} + +void FP_arg2ToFp( void ) +{ + __asm__ ( "lda #<%v", arg2 ); + __asm__ ( "sta $22" ); + __asm__ ( "lda #>%v", arg2 ); + __asm__ ( "sta $23" ); + __asm__ ( "lda #<%v", argLength ); + __asm__ ( "jsr $b7b5" ); + + __asm__ ( "ldx #<%v", arg2Fp ); + __asm__ ( "ldy #>%v", arg2Fp ); + __asm__ ( "jsr $bbd4" ); +} + +void FP_printResult( void ) +{ + __asm__ ( "lda #<%v", resultFp ); + __asm__ ( "ldy #>%v", resultFp ); + __asm__ ( "jsr $bba2" ); + __asm__ ( "jsr $bddd" ); + __asm__ ( "jsr $ab1e" ); +} + +void FP_arg1ToFac( void ) +{ + __asm__ ( "lda #<%v", arg1Fp ); + __asm__ ( "ldy #>%v", arg1Fp ); + __asm__ ( "jsr $bba2" ); +} + +void FP_arg2ToFac( void ) +{ + __asm__ ( "lda #<%v", arg2Fp ); + __asm__ ( "ldy #>%v", arg2Fp ); + __asm__ ( "jsr $bba2" ); +} + +void FP_add( void ) +{ + FP_arg1ToFac(); + __asm__ ( "lda #<%v", arg2Fp ); + __asm__ ( "ldy #>%v", arg2Fp ); + __asm__ ( "jsr $b867" ); + +} + +void FP_facToResult( void ) +{ + __asm__ ( "ldx #<%v", resultFp ); + __asm__ ( "ldy #>%v", resultFp ); + __asm__ ( "jsr $bbd4" ); +} + +void FP_printRaw( FP fp ) +{ + printf( "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", fp[ 0 ], fp[ 1 ], fp[ 2 ], fp[ 3 ], fp[ 4 ] ); +} + +void FP_subst( void ) +{ + FP_arg1ToFac(); + __asm__ ( "lda #<%v", arg2Fp ); + __asm__ ( "ldy #>%v", arg2Fp ); + __asm__ ( "jsr $b850" ); +} + +void FP_mult( void ) +{ + FP_arg1ToFac(); + __asm__ ( "lda #<%v", arg2Fp ); + __asm__ ( "ldy #>%v", arg2Fp ); + __asm__ ( "jsr $ba28" ); +} + +void FP_div( void ) +{ + FP_arg1ToFac(); + __asm__ ( "lda #<%v", arg2Fp ); + __asm__ ( "ldy #>%v", arg2Fp ); + __asm__ ( "jsr $bb0f" ); +} + +void FP_pwr( void ) +{ + FP_arg2ToFac(); + FP_FACtoARG(); + FP_arg1ToFac(); + __asm__ ( "jsr $bf7b" ); +} + +void FP_FACtoARG( void ) +{ + __asm__ ( "jsr $bc0f" ); +} \ No newline at end of file diff --git a/src/modules/math_helper.h b/src/modules/math_helper.h new file mode 100644 index 0000000..e65ec06 --- /dev/null +++ b/src/modules/math_helper.h @@ -0,0 +1,24 @@ +#ifndef MATH_HELPER_H +#define MATH_HELPER_H + +#include + +#define MAX_ARGUMENT_LENGTH 12 + +typedef uint8_t FP[5]; + +void FP_arg1ToFp( void ); +void FP_arg2ToFp( void ); +void FP_printResult( void ); +void FP_arg1ToFac( void ); +void FP_add( void ); +void FP_facToResult( void ); +void FP_printRaw( FP fp ); +void FP_subst( void ); +void FP_mult( void ); +void FP_div( void ); +void FP_pwr( void ); +void FP_FACtoARG( void ); +void FP_arg2ToFac( void ); + +#endif \ No newline at end of file diff --git a/src/modules/misc_helper.c b/src/modules/misc_helper.c new file mode 100644 index 0000000..8587231 --- /dev/null +++ b/src/modules/misc_helper.c @@ -0,0 +1,209 @@ +#include "misc_helper.h" +#include "math_helper.h" +#include "system_helper.h" +#include "adt_stack.h" + +extern char arg1[ MAX_ARGUMENT_LENGTH ]; +extern uint8_t argLength; +extern StackNodePtr stackPtr; +extern FP arg1Fp; +extern FP arg2Fp; +extern FP resultFp; + +void header( void ) +{ + cputsxy( 13, 0, "CALCULATOR." ); + gotoxy( 0, 2 ); + puts( "Enter an expression for RPN calculation" ); + puts( "or 'q' for exit" ); + puts( "" ); + puts( "" ); +} + +void handleArgumentString( char * argumentString ) +{ + char * token; + token = strtok( argumentString, " " ); + + while ( token != NULL ) + { + if ( isdigit( ( unsigned char )token[ 0 ] ) ) + { + handleNumber( token ); + } + else + { + if ( ( unsigned char )token[ 0 ] == '-' && isdigit( ( unsigned char )token[ 1 ] ) ) + { + handleNumber( token ); + } + else + { + handleOperator( token ); + } + } + + token = strtok( NULL, " " ); + } + + printf( "" ); + + if ( Stack_isEmpty( stackPtr ) ) + { + puts( "Stack is empty" ); + } + else + { + showResult(); + } +} + +void handleNumber( char * token ) +{ + if ( strlen( token ) >= sizeof( arg1 ) ) + { + puts( "Number is too long" ); + return; + } + + strncpy( arg1, token, sizeof( arg1 ) - 1 ); + arg1[ sizeof( arg1 ) - 1 ] = '\0'; + + argLength = strlen( arg1 ); + + enableBasicRom(); + FP_arg1ToFp(); + disableBasicRom(); + + Stack_push( &stackPtr, arg1Fp ); +} + +void handleOperator( char * token ) +{ + char operator = token[ 0 ]; + + if ( Stack_isEmpty( stackPtr ) ) + { + puts( "Stack is empty" ); + } + else + { + switch ( operator ) + { + case '+' : + handleAddition(); + Stack_push( &stackPtr, resultFp ); + break; + + case '-' : + handleSubtraction(); + Stack_push( &stackPtr, resultFp ); + break; + + case '/' : + handleDivision(); + Stack_push( &stackPtr, resultFp ); + break; + + case '*' : + handleMultiplication(); + Stack_push( &stackPtr, resultFp ); + break; + + case 0x5e : + handlePower(); + Stack_push( &stackPtr, resultFp ); + break; + + default: + puts( "Invalid operator" ); + break; + } + } +} + +void handleAddition( void ) +{ + + Stack_pop( &stackPtr, &arg1Fp ); + Stack_pop( &stackPtr, &arg2Fp ); + + enableBasicRom(); + FP_add(); + FP_facToResult(); + disableBasicRom(); +} + +void showResult( void ) +{ + Stack_pop( &stackPtr, &resultFp ); + enableBasicRom(); + FP_printResult(); + disableBasicRom(); + puts( "" ); +} + +void handleSubtraction( void ) +{ + Stack_pop( &stackPtr, &arg1Fp ); + Stack_pop( &stackPtr, &arg2Fp ); + + enableBasicRom(); + FP_subst(); + FP_facToResult(); + disableBasicRom(); +} + +void handleMultiplication( void ) +{ + Stack_pop( &stackPtr, &arg1Fp ); + Stack_pop( &stackPtr, &arg2Fp ); + + enableBasicRom(); + FP_mult(); + FP_facToResult(); + disableBasicRom(); +} + +void handleDivision( void ) +{ + Stack_pop( &stackPtr, &arg1Fp ); + Stack_pop( &stackPtr, &arg2Fp ); + + enableBasicRom(); + FP_div(); + FP_facToResult(); + disableBasicRom(); +} + +void handlePower( void ) +{ + Stack_pop( &stackPtr, &arg1Fp ); + Stack_pop( &stackPtr, &arg2Fp ); + + enableBasicRom(); + FP_pwr(); + FP_facToResult(); + disableBasicRom(); +} + +void getUserInput( char * argumentString ) +{ + uint8_t len = 0; + printf( "> " ); + + if ( fgets( argumentString, MAX_INPUT_LENGTH, stdin ) == NULL ) + { + puts( "Error reading input" ); + cgetc(); + resetDefaultScreen(); + exit( EXIT_FAILURE ); + } + + len = strlen( argumentString ); + + if ( len > 0 && argumentString[ len - 1 ] == '\n' ) + { + argumentString[ --len ] = '\0'; + } +} diff --git a/src/modules/misc_helper.h b/src/modules/misc_helper.h new file mode 100644 index 0000000..d8e85bb --- /dev/null +++ b/src/modules/misc_helper.h @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +#define MAX_INPUT_LENGTH 80 + +void header( void ); +void handleArgumentString( char * argumentString ); +void handleNumber( char * token ); +void handleOperator( char * token ); +void handleAddition( void ); +void showResult( void ); +void handleSubtraction( void ); +void handleMultiplication( void ); +void handleDivision( void ); +void handlePower( void ); +void getUserInput( char * argumentString ); diff --git a/src/modules/system_helper.c b/src/modules/system_helper.c new file mode 100644 index 0000000..d08a72c --- /dev/null +++ b/src/modules/system_helper.c @@ -0,0 +1,38 @@ +#include +#include + +unsigned char defaultBGColor = 0; +unsigned char defaultBorderColor = 0; +unsigned char defaultTextColor = 0; + +void setUpScreen( void ) +{ + clrscr(); + defaultBGColor = bgcolor( COLOR_BLACK ); + defaultBorderColor = bordercolor( COLOR_BLACK ); + defaultTextColor = textcolor( COLOR_GREEN ); +} + +void resetDefaultScreen( void ) +{ + clrscr(); + bgcolor( defaultBGColor ); + bordercolor( defaultBorderColor ); + textcolor( defaultTextColor ); + * ( char * ) 0xD018 = 0x15; +} + +void enableBasicRom( void ) +{ + __asm__ ( "sei" ); + __asm__ ( "ldx #$37" ); + __asm__ ( "stx $01" ); + +} + +void disableBasicRom( void ) +{ + __asm__ ( "ldx #$36" ); + __asm__ ( "stx $01" ); + __asm__ ( "cli" ); +} \ No newline at end of file diff --git a/src/modules/system_helper.h b/src/modules/system_helper.h new file mode 100644 index 0000000..7b317a2 --- /dev/null +++ b/src/modules/system_helper.h @@ -0,0 +1,4 @@ +void setUpScreen( void ); +void resetDefaultScreen( void ); +void enableBasicRom( void ); +void disableBasicRom( void ); \ No newline at end of file diff --git a/src/multicalc.c b/src/multicalc.c new file mode 100644 index 0000000..499f456 --- /dev/null +++ b/src/multicalc.c @@ -0,0 +1,37 @@ +#include +#include + +#include "modules/system_helper.h" +#include "modules/misc_helper.h" +#include "modules/adt_stack.h" + +StackNodePtr stackPtr = NULL; + + +int main ( void ) +{ + + char argumentString[ MAX_INPUT_LENGTH ]; + char quitFlag = ' '; + + setUpScreen(); + + header(); + + getUserInput( argumentString ); + + quitFlag = argumentString[ 0 ]; + + while ( quitFlag != 'q' ) + { + handleArgumentString( argumentString ); + + getUserInput( argumentString ); + + quitFlag = argumentString[ 0 ]; + } + + resetDefaultScreen(); + + return EXIT_SUCCESS; +} \ No newline at end of file From 470b873f34de0c625bfb1942a90a69bb527dac13 Mon Sep 17 00:00:00 2001 From: medvecky Date: Tue, 2 Apr 2024 20:12:11 +0300 Subject: [PATCH 3/3] add_initial_documentation: * update Readme.md --- Readme.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 1cb9219..b02e357 100644 --- a/Readme.md +++ b/Readme.md @@ -1,3 +1,59 @@ # C64-multi-functional-calculator -Multi-functional text-based calculator for the Commodore 64. +Multi-functional, text-based RPN (Reverse Polish Notation) calculator designed specifically for the Commodore 64. This project brings a robust set of mathematical capabilities to the iconic Commodore 64, leveraging its unique architecture to deliver a fast, efficient, and user-friendly calculator experience + +## Description + +- addition '+' +- subtraction '-' +- division '/' +- multiplication '*' +- power '↑' + +Additionally, it accommodates floating-point numbers up to nine digits in both decimal (e.g., 3.14) and scientific (e.g., 8.9e-5) notations. + +## App development setup + +### Prerequisites + +- Installed [cc65](https://www.cc65.org/) + +### Build binary app + +- Clone the project: + +```bash +git clone https://github.com/medvecky/C64-multi-functional-calculator.git +``` + +- Navigate to the project directory. +- Execute the following command: + +```bash +make multicalc +``` + +The calculator binary, named multicalc.prg, is located in the /bin directory. + + +## Operating Manual + +### Simple Operations in RPN Format + +```bash +# 9 * 4 +9 4 * +# 9 + 4 +9 4 + +# 9 / 4 +9 4 / +# 9 ^ 4 +9 4 ↑ +``` + +### Complex Operations in RPN Format + +```bash +#√( 2 * 300.51 / 9.8 ) +300.51 2 * 9.8 / 0.5 ↑ +```