Add lots of instructions which are displayed when launched or on demand by pressing H. Update the readme.

This commit is contained in:
Jeremy Rand 2018-06-21 23:27:51 -04:00
parent a55ab9353b
commit 61f3931dd9
8 changed files with 171 additions and 40 deletions

View File

@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
9D24616A20D8B2AE00227E1D /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D24616920D8B2AE00227E1D /* main.c */; };
9D24616C20D8B2AE00227E1D /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 9D24616B20D8B2AE00227E1D /* Makefile */; };
9D24616F20D8B2AE00227E1D /* AppleCommander.jar in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D24616E20D8B2AE00227E1D /* AppleCommander.jar */; };
9D24617120D8B2AE00227E1D /* createDiskImage in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9D24617020D8B2AE00227E1D /* createDiskImage */; };
@ -46,7 +45,6 @@
/* Begin PBXFileReference section */
9D24616620D8B2AE00227E1D /* doNotBuild */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = doNotBuild; sourceTree = BUILT_PRODUCTS_DIR; };
9D24616920D8B2AE00227E1D /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
9D24616B20D8B2AE00227E1D /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
9D24616E20D8B2AE00227E1D /* AppleCommander.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = AppleCommander.jar; path = make/AppleCommander.jar; sourceTree = "<group>"; };
9D24617020D8B2AE00227E1D /* createDiskImage */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = createDiskImage; path = make/createDiskImage; sourceTree = "<group>"; };
@ -101,7 +99,6 @@
9D24616820D8B2AE00227E1D /* CurtaSim */ = {
isa = PBXGroup;
children = (
9D24616920D8B2AE00227E1D /* main.c */,
9D24618F20D8B30C00227E1D /* curta.c */,
9D24618B20D8B30B00227E1D /* curtaModel.c */,
9D24618D20D8B30B00227E1D /* curtaModel.h */,
@ -216,7 +213,6 @@
buildActionMask = 2147483647;
files = (
9D24616C20D8B2AE00227E1D /* Makefile in Sources */,
9D24616A20D8B2AE00227E1D /* main.c in Sources */,
9D24619220D8B30C00227E1D /* curtaModel.c in Sources */,
9D24619520D8B30C00227E1D /* curtaUI.c in Sources */,
9D24619320D8B30C00227E1D /* joystick.c in Sources */,

View File

@ -12,6 +12,9 @@
int main(void)
{
bool timeToQuit = false;
printInstructions();
initUI();
while (!timeToQuit) {

View File

@ -363,25 +363,138 @@ static tAction getNextAction(void)
}
void textMode(void)
{
clrscr();
asm ("STA %w", 0xc051);
}
void graphicsMode(void)
{
asm ("STA %w", 0xc050);
}
void printInstructions(void)
{
textMode();
// 0000000001111111111222222222233333333334
// 1234567890123456789012345678901234567890
printf(" CURTASIM\n"
"\n"
"A CURTA IS A MECHANICAL CALCULATOR THAT\n"
"LOOKS SOMEWHAT LIKE A PEPPER GRINDER.\n"
"GOOGLE CURTA AND CHECKOUT SOME PICS.\n"
"TO REPLACE THE CRANK, THIS SIMULATION\n"
"USES A JOYSTICK.\n"
"\n"
"THE PRIMARY INTERACTION IS PERFORMED\n"
"BY \"CRANKING\" THE JOYSTICK THROUGH\n"
"360 DEGREES. TO PERFORM A CRANK, START\n"
"WITH THE JOYSTICK CENTERED. PULL THE\n"
"JOYSTICK TOWARDS YOU AND THEN CRANK\n"
"AROUND A CIRCLE CLOCKWISE UNTIL IT IS\n"
"AGAIN PULLED TOWARDS YOU. THEN RELEASE\n"
"TO THE CENTRE POSITION.\n"
"\n"
"THE OPERAND IS THE SET OF DIGITS AT THE\n"
"TOP OF THE SCREEN. THE SLIDERS CONTROL\n"
"THE OPERAND. THE RESULT IS AT THE\n"
"BOTTOM OF THE SCREEN. THE COUNTER IS A\n"
"MULTIPLICAND.\n"
"\n"
"PRESS ANY KEY FOR MORE INFORMATION");
cgetc();
clrscr();
// 0000000001111111111222222222233333333334
// 1234567890123456789012345678901234567890
printf(" CURTASIM\n"
"\n"
"BELOW THE RESULT IS A CARAT THAT POINTS\n"
"TO A DIGIT. THIS IS THE SAME AS THE\n"
"CARRIAGE POSITION ON A REAL CURTA.\n"
"\n"
"THE JOYSTICK OPERATIONS ARE:\n"
"\n"
" LEFT/RIGHT - SELECT A DIGIT IN THE\n"
" OPERAND\n"
" UP/DOWN - CHANGE THE SELECTED DIGIT IN\n"
" THE OPERAND\n"
" LEFT/RIGHT WITH BUTTON 0 - CHANGE\n"
" THE CARRIAGE POSITION\n"
" CRANK - ADD OPERAND TIMES CARRIAGE\n"
" POSITION TO THE RESULT\n"
" CRANK WITH BUTTON 0 - SUBTRACT OPERAND\n"
" TIMES CARRIAGE POSITION FROM\n"
" THE RESULT\n"
" CRANK WITH BUTTON 1 - CLEAR THE RESULT\n"
" AND COUNTER\n"
"\n"
"PRESS ANY KEY FOR MORE INFORMATION");
cgetc();
clrscr();
// 0000000001111111111222222222233333333334
// 1234567890123456789012345678901234567890
printf(" CURTASIM\n"
"\n"
"THESE KEYBOARD COMMANDS CAN BE USED:\n"
"\n"
" Q - QUIT THE SIMULATION\n"
" H - PRINT THIS HELP AGAIN\n"
"\n"
"IMAGINE YOU WANT TO MULTIPLY 123 BY 990."
"PERFORM A CLEAR OPERATION IF RESULT IS\n"
"NOT ZERO. USE LEFT/RIGHT/UP/DOWN\n"
"OPERATIONS TO PUT 123 IN THE OPERAND.\n"
"HOLD BUTTON 0 AND PERFORM LEFT MOVES TO\n"
"GET THE CARRIAGE POINTING TO THE\n"
"THOUSANDS POSITION IN THE RESULT.\n"
"\n"
"NOW DO AN ADD OPERATION. THIS FINDS\n"
"123 * 1000 = 123000 AND ADDS IT TO THE\n"
"RESULT. MOVE THE CARRIAGE TO THE TENS\n"
"POSITION. DO A SUBTRACT WHICH SUBTRACTS"
"123 * 10 = 1230 FROM RESULT. COUNT SAYS"
"990 AND RESULT HAS THE ANSWER: 121770\n"
"\n"
"PRESS ANY KEY TO START THE SIMULATION");
cgetc();
}
void redrawUI(void)
{
tDigitPos pos;
graphicsMode();
tgi_clear();
for (pos = 0; pos < NUM_OPERAND_DIGITS; pos++) {
drawOperand(pos);
}
// Mixed text and graphics mode
asm ("STA %w", 0xc053);
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printState();
}
void initUI(void)
{
// Install drivers
tDigitPos pos;
initDevice(changeOperand, changeSelectedOperand);
tgi_install(&a2_hires_drv);
tgi_init();
tgi_clear();
for (pos = 0; pos < NUM_OPERAND_DIGITS; pos++) {
drawOperand(pos);
}
// Mixed text and graphics mode
asm ("STA %w", 0xc053);
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printState();
redrawUI();
}
@ -390,10 +503,22 @@ bool processNextEvent(void)
bool timeToQuit = false;
// Exit on ESC
if ((kbhit()) &&
(cgetc() == 27)) {
timeToQuit = true;
if (kbhit()) {
switch (cgetc()) {
case 27:
case 'Q':
case 'q':
timeToQuit = true;
break;
case 'H':
case 'h':
printInstructions();
redrawUI();
break;
}
}
switch (getNextAction()) {
case ACTION_NULL:
break;

View File

@ -11,6 +11,7 @@
#ifndef _CURTAUI_H
#define _CURTAUI_H
extern void printInstructions(void);
extern void initUI(void);
extern void shutdownUI(void);
extern bool processNextEvent(void);

View File

@ -1,20 +0,0 @@
/*
* main.c
* CurtaSim
*
* Created by Jeremy Rand on 2018-06-18.
* Copyright (c) 2018 Jeremy Rand. All rights reserved.
*
*/
#include <stdio.h>
#include <conio.h>
int main(void)
{
printf("HELLO, WORLD!\n");
cgetc();
return 0;
}

Binary file not shown.

View File

@ -1,8 +1,34 @@
CurtaSim
========
This is a simulation of the Curta mechanical calculator written for the Apple //.
This is a simulation of the [Curta mechanical calculator](https://en.wikipedia.org/wiki/Curta) written for the Apple //.
![CurtaSim Screenshot](/curta.png "CurtaSim Screenshot")
[Download a disk image](https://github.com/jeremysrand/CurtaSim/releases/download/1.0/curta.dsk)
[Download a disk image](https://github.com/jeremysrand/CurtaSim/releases/download/1.1/curta.dsk)
A Curta looks somewhat like a pepper grinder. To replace the crank, this simulation uses a joystick.
The primary interaction is performed by "cranking" the joystick through 360 degrees. To perform a crank, start with the joystick centered. Pull the joystick towards you and then crank around a circle clockwise until it is again pulled towards you. Then release the joystick back to the centre position.
The operand is the set of digits at the top of the screen. The sliders control the operand. The result is at the bottom of the screen. The counter is a multiplicand. Below the result is a carat that points to a digit. This is the same as the carriage position on a real curta.
The joystick operations are:
* Left/Right - Select a digit in the operand.
* Up/Down - Change the selected digit in the operand.
* Left/Right with Button 0 Down - Change the carriage position.
* Crank - Add the operand times the carriage position to the result. If the carriage position is pointing to the hundreds position, then 100 times the operand is added to the result.
* Crank with Button 0 Down - Subtract the operand times the carriage postion from the result.
* Crank with Button 1 Down - Clear the result and counter values.
These keyboard commands can be used:
* Q - Quit the simulation.
* H - Print help information.
Imagine you want to multiply 123 by 990. Perform a clear operation if result is not zero. Use Left/Right/Up/Down operations to put 123 in the operand. Hold button 0 down and perform Left/Right moves to get the carriage pointing to the thousands position in the result.
Now do an Add operation. The calculator multiplies the operand by 1000 from the carriage position which results in 123,000 which is then added to the result. The result was zero so now the result is 123,000. Note the counter is 1000. The operand (123) multiplied by the counter (1000) is the result (123,000).
Move the carriage to the tens position. Do a Subtract operation. The calculate multiplies the operand by 10 from the carriage psition which results in 1230 which is then subtracted from the result. The result was 123,000 so now the result is 121,770. Note that the counter is now 990. Again, the operand (123) multiplied by the counter (990) is the result (121,770).
If you want more information about how to use a Curta, check out [these Curta manuals](http://www.curtamania.com/curta/code/curta_manuals.html).