Skip to content

Commit

Permalink
Merge pull request #11 from medvecky/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
medvecky authored Apr 2, 2024
2 parents 9f25b68 + e321f10 commit d1c9f0a
Show file tree
Hide file tree
Showing 12 changed files with 646 additions and 60 deletions.
28 changes: 24 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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
59 changes: 58 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
@@ -1,2 +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 * <return>
# 9 + 4
9 4 + <return>
# 9 / 4
9 4 / <return>
# 9 ^ 4
9 4 ↑ <return>
```

### Complex Operations in RPN Format

```bash
#√( 2 * 300.51 / 9.8 )
300.51 2 * 9.8 / 0.5 ↑
```
55 changes: 0 additions & 55 deletions src/main.fs

This file was deleted.

89 changes: 89 additions & 0 deletions src/modules/adt_stack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include <string.h>

#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;
}
}

26 changes: 26 additions & 0 deletions src/modules/adt_stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef ATD_STACK_H
#define ATD_STACK_H

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#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
119 changes: 119 additions & 0 deletions src/modules/math_helper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include <stdio.h>

#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" );
}
Loading

0 comments on commit d1c9f0a

Please sign in to comment.