Friday 4 April 2014

A 4 digit calculator using 8086 microprocessor.....

A 4 digit calculator using 8086 microprocessor.....


circuit diagram.


                      

Download programs required for various programmable chips from below...




7seg.h

/* 7-seg LED driver routines and defines */

/* Defines To Be Changed According To The Current Schematic */

// Comment following line if common cathode (non inverted), and uncomment if common cathode (inverted).
//#define LED_INVERT 1

// Digits positions

#ifndef LED_SEG_POS_A

#define LED_SEG_POS_A   0
#define LED_SEG_POS_B   1
#define LED_SEG_POS_C   2
#define LED_SEG_POS_D   3
#define LED_SEG_POS_E   4
#define LED_SEG_POS_F   5
#define LED_SEG_POS_G   6
#define LED_SEG_POS_H   7

#endif

/* Non-changeable Defines */

#ifndef LED_INVERT
#define LED_INVERT 0
#endif

#if LED_INVERT
#define LED_OPER             &
#define LED_INV            ~
#define LED_INIT_VAL       0xFF
#define LED_SEG_VAL(seg_pos)  (0xFF & ~(1 << seg_pos))
#else
#define LED_OPER             |
#define LED_INV
#define LED_INIT_VAL       0x00
#define LED_SEG_VAL(seg_pos)  (1 << seg_pos)
#endif


#define LED_SEG_A       LED_SEG_VAL(LED_SEG_POS_A)
#define LED_SEG_B        LED_SEG_VAL(LED_SEG_POS_B)
#define LED_SEG_C        LED_SEG_VAL(LED_SEG_POS_C)
#define LED_SEG_D       LED_SEG_VAL(LED_SEG_POS_D)
#define LED_SEG_E        LED_SEG_VAL(LED_SEG_POS_E)
#define LED_SEG_F        LED_SEG_VAL(LED_SEG_POS_F)
#define LED_SEG_G       LED_SEG_VAL(LED_SEG_POS_G)
#define LED_SEG_H       LED_SEG_VAL(LED_SEG_POS_H)

/* Output bytes for diffirent numbers */

#define LED_SIGN_0      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_B LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_F)
#define LED_SIGN_1      (LED_INIT_VAL LED_OPER LED_SEG_B LED_OPER LED_SEG_C)
#define LED_SIGN_2      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_B LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_G)
#define LED_SIGN_3      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_B LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_G)
#define LED_SIGN_4      (LED_INIT_VAL LED_OPER LED_SEG_B LED_OPER LED_SEG_C LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_5      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_6      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_7      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_B LED_OPER LED_SEG_C)
#define LED_SIGN_8      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_B LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_9      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_B LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_A     (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_B LED_OPER LED_SEG_C LED_OPER LED_SEG_E LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_B     (LED_INIT_VAL LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_C     (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_F)
#define LED_SIGN_D     (LED_INIT_VAL LED_OPER LED_SEG_B LED_OPER LED_SEG_C LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_G)
#define LED_SIGN_E      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_D LED_OPER LED_SEG_E LED_OPER LED_SEG_F LED_OPER LED_SEG_G)
#define LED_SIGN_F      (LED_INIT_VAL LED_OPER LED_SEG_A LED_OPER LED_SEG_E LED_OPER LED_SEG_F LED_OPER LED_SEG_G)

/* Encode one digit number into the output byte */

#define LED_ENCODE(value)  \
 (value & 0x08)?           \
    ((value & 0x04)?       \
       ((value & 0x02)?    \
          ((value & 0x01)? \
             (LED_SIGN_F): \
             (LED_SIGN_E)  \
          ):               \
          ((value & 0x01)? \
             (LED_SIGN_D): \
             (LED_SIGN_C)  \
          )                \
       ):                  \
       ((value & 0x02)?    \
          ((value & 0x01)? \
             (LED_SIGN_B): \
             (LED_SIGN_A)  \
          ):               \
          ((value & 0x01)? \
             (LED_SIGN_9): \
             (LED_SIGN_8)  \
          )                \
       )                   \
    ):                     \
    ((value & 0x04)?       \
       ((value & 0x02)?    \
          ((value & 0x01)? \
             (LED_SIGN_7): \
             (LED_SIGN_6)  \
          ):               \
          ((value & 0x01)? \
             (LED_SIGN_5): \
             (LED_SIGN_4)  \
          )                \
       ):                  \
       ((value & 0x02)?    \
          ((value & 0x01)? \
             (LED_SIGN_3): \
             (LED_SIGN_2)  \
          ):               \
          ((value & 0x01)? \
             (LED_SIGN_1): \
             (LED_SIGN_0)  \

Board.c

#include "board.h"
#include "7seg.h"

void outp(unsigned int addr, char data)
// Output byte to port
 { __asm
    { mov dx, addr
      mov al, data
      out dx, al
    }
 }

char inp(unsigned int addr)
// Input byte from port
 { char result;
   __asm
    { mov dx, addr
      in al, dx
      mov result, al
    }
   return result;
 }

void set_int(unsigned char int_no, void * service_proc)
 { _asm
    { push es
      xor ax, ax
      mov es, ax
      mov al, int_no
      xor ah, ah
      shl ax, 1
      shl ax, 1
      mov si, ax
      mov ax, service_proc
      mov es:[si], ax
      inc si
      inc si
      mov bx, cs
      mov es:[si], bx
      pop es
    }
 }

/* USART */

unsigned char putch_buffer[256];
unsigned char putch_out_pos;
unsigned char putch_pos;

void putch_out(void)
// Output one symbol from buffer to 8251A USART
 { if (putch_out_pos == putch_pos)
      return;
   if((inp(ADR_USART_STAT) & 0x01) == 0)
      return;
   outp(ADR_USART_DATA, putch_buffer[putch_out_pos]);
   putch_out_pos++;
 }

unsigned char putch( unsigned char c )
// Put one symbol into buffer
 { putch_buffer[putch_pos] = c;
   putch_pos++;
   return c;
 }

void prints(char* s)
// Print string using putch() function
 { char c;
   while(s && *s)
    { c = *s;
      if (c == '\r')
         c = '\n';
      putch(c);
      s++;
    }
 }

void printui(unsigned int i)
// Print unsigned int using putch() function
 { unsigned char val;
   unsigned int temp = 10000;
   unsigned char printed=0;
   while (temp >= 1)
    { val = (i / temp) % 10;
      if ((val!=0) || printed || (temp == 1))
       { putch(val + '0');
         printed = 1;
       }
      if (temp == 1)
         break;
      temp /= 10;
    }
 }

void setup_usart(void)
// 8251 USART Setup
 { /* setup USART */
   outp(ADR_USART_CMD, 0x7D); /* ED */
   outp(ADR_USART_CMD, 0x07); /* RxEn, TxEn, DTRa */

   putch_out_pos = 0;
   putch_pos = 0;
 }

/* Timer */

signed char delay;

int sound_enabled;
int display_enabled;

void sound_nmi(void)
 { delay++;
   if (delay >= 10)
      delay = -delay;  
   outp(ADR_TIMER_CONTROL, TIMER_COUNTER2 | TIMER_MODE2 | TIMER_LSB);
   outp(ADR_TIMER_DATA2, ABS(delay)+0x40);
 }

void _interrupt _far nmi_handler(void);

void setup_nmi(void)
// Set NMI Timer at 50Hz.
 { set_int(0x02, (void *)&nmi_handler);

   outp(ADR_TIMER_CONTROL, TIMER_COUNTER1 | TIMER_MODE2 | TIMER_LSB_MSB);
   outp(ADR_TIMER_DATA1, 0xD0);         
   outp(ADR_TIMER_DATA1, 0x07);         
 }

/* PIO */

// Value to be displayed
unsigned int display_value;

// Current display position
unsigned char cur_display_pos;
// Current dispaly segments
unsigned char cur_display_segs;

unsigned char keys[16];

#define KEY_7   0
#define KEY_8   1
#define KEY_9   2
#define KEY_DIV              3
#define KEY_4   4
#define KEY_5   5
#define KEY_6   6
#define KEY_MUL           7
#define KEY_1   8
#define KEY_2   9
#define KEY_3   10
#define KEY_MIN            11
#define KEY_C  12
#define KEY_0   13
#define KEY_EQ               14
#define KEY_PLU             15

#define KEYBUFFERLEN 16

unsigned char keybuffer[KEYBUFFERLEN];
unsigned char keypos=0;

void process_key(unsigned char keycode)
 { if (keypos < KEYBUFFERLEN)
    { keybuffer[keypos] = keycode;
      keypos++;
    }
 }

#define NUM_LED_DIGITS 4

unsigned char disp_buffer[4] = {LED_INIT_VAL, LED_INIT_VAL, LED_INIT_VAL, LED_INIT_VAL};

void display_nmi(void)
// Display And Keyboard Handler
 { unsigned int i;
   unsigned int cur_key;
   unsigned int keys_inp;
   unsigned int out_value;

   // Light Off All Digits
   outp(ADR_PPI_PORTA, 0xFF);
   // Output Segments Value
   outp(ADR_PPI_PORTB, cur_display_segs);
   // Light On Current Digit
   outp(ADR_PPI_PORTA, 0xFF & ~(1 << cur_display_pos));

   // Keyboard Input
   keys_inp = inp(ADR_PPI_PORTC);
   cur_key = (cur_display_pos * 4);
   for (i=0; i<4; i++)
    { if (keys_inp & (1 << i))
         keys[cur_key]=0;
      else
       { if (!keys[cur_key])
          { process_key(cur_key);
            keys[cur_key]=1;
          }
       }
      cur_key++;
    }

   // Shift To The Next Digit
   cur_display_pos++;
   if (cur_display_pos > 3)
    { cur_display_pos = 0;
    }
   // Set Next Digit Value
   cur_display_segs = disp_buffer[cur_display_pos];
 }

void init_pio(void)
/* 8255A PIO Demo */
 {  outp(ADR_PPI_CONTROL, PPI_PORTA_OUT | PPI_PORTB_OUT | PPI_PORTCL_INP | PPI_PORTCH_INP | PPI_MODE_BCL_0 | PPI_MODE_ACH_0 | PPI_ACTIVE);

    display_value = 0;
    cur_display_pos = 0;
    cur_display_segs = 0xFF;

    display_enabled = 1;
 }


/* NMI Interrupt Handler */

void _interrupt _far nmi_handler(void)
 { if (sound_enabled)
      sound_nmi();
   if (display_enabled)
      display_nmi();
   putch_out();
 }

/* Support functions */

void initialise(void)
 { sound_enabled = 0;
   display_enabled = 0;
   cur_display_segs = LED_INIT_VAL;
   setup_nmi();
   setup_usart();
   init_pio();
 }

char input ()
 { if (keypos > 0)
    { unsigned char head_key = keybuffer[0];
      keypos--;
      for (unsigned char i=0; i<keypos; i++)
         keybuffer[i] = keybuffer[i+1];
      switch (head_key)
       { case KEY_0:
            return '0';
         case KEY_1:
            return '1';
         case KEY_2:
            return '2';
         case KEY_3:
            return '3';
         case KEY_4:
            return '4';
         case KEY_5:
            return '5';
         case KEY_6:
            return '6';
         case KEY_7:
            return '7';
         case KEY_8:
            return '8';
         case KEY_9:
            return '9';
         case KEY_PLU:
            return '+';
         case KEY_MIN:
            return '-';
         case KEY_MUL:
            return '*';
         case KEY_DIV:
            return '/';
         case KEY_EQ:
            return '=';
         case KEY_C:
            return 'C';
       }
    }
   return 0;
 }

char output(char ch)
 { putch(ch);
   if (ch >= '0' && ch <= '9')
    { for (char i=0; i<NUM_LED_DIGITS-1; i++)
         disp_buffer[i] = disp_buffer[i+1];
      disp_buffer[NUM_LED_DIGITS-1] = LED_ENCODE(ch - '0');
    }
   return ch;
 }

void clearscreen()
 { putch(13);
   for (char i=0; i<NUM_LED_DIGITS; i++)
      disp_buffer[i] = LED_INIT_VAL;
 }

          )                \
       )                   \
    )

Board.h

#ifndef _board_h_
#define _board_h_


/* 8086 Demo Board support functions and macros */


// Absolute value of an argument
#define ABS(a) ((a>=0)?a:-a)

// Set an Interrupt Handler
void set_int(unsigned char int_no, void * service_proc);

// I/O Ports input and output
void outp(unsigned int addr, char data);
char inp(unsigned int addr);


/* I/O Address Bus decode - every device gets 0x200 addresses */

#define IO0  0x0000
#define IO1  0x0200
#define IO2  0x0400
#define IO3  0x0600
#define IO4  0x0800
#define IO5  0x0A00
#define IO6  0x0C00
#define IO7  0x0E00
#define IO8  0x1000
#define IO9  0x1200
#define IO10 0x1400
#define IO11 0x1600
#define IO12 0x1800
#define IO13 0x1A00
#define IO14 0x1C00
#define IO15 0x1E00

/* 8251A USART */

#define ADR_USART_DATA (IO0 + 0x00)
#define ADR_USART_CMD  (IO0 + 0x02)
#define ADR_USART_STAT ADR_USART_CMD

/* 8253A Timer */

#define ADR_TIMER_CONTROL (IO2 + 0x06)
#define ADR_TIMER_DATA0   (IO2 + 0x00)
#define ADR_TIMER_DATA1   (IO2 + 0x02)
#define ADR_TIMER_DATA2   (IO2 + 0x04)

#define TIMER_COUNTER0          0x00
#define TIMER_COUNTER1          0x40
#define TIMER_COUNTER2          0x80

#define TIMER_LATCH   0x00
#define TIMER_LSB         0x10
#define TIMER_MSB       0x20
#define TIMER_LSB_MSB              0x30

#define TIMER_MODE0 0x00
#define TIMER_MODE1 0x02
#define TIMER_MODE2 0x04
#define TIMER_MODE3 0x06
#define TIMER_MODE4 0x08
#define TIMER_MODE5 0x09

#define TIMER_BCD        0x01

/* 8255A PIO */

#define ADR_PPI_PORTA             (IO1)
#define ADR_PPI_PORTB             (IO1 + 0x02)
#define ADR_PPI_PORTC             (IO1 + 0x04)
#define ADR_PPI_CONTROL       (IO1 + 0x06)

#define PPI_PORTA_INP              0x10
#define PPI_PORTA_OUT             0x00
#define PPI_PORTB_INP               0x02
#define PPI_PORTB_OUT             0x00
#define PPI_PORTCL_INP             0x01
#define PPI_PORTCL_OUT           0x00
#define PPI_PORTCH_INP            0x08
#define PPI_PORTCH_OUT          0x00
#define PPI_MODE_BCL_0           0x00
#define PPI_MODE_BCL_1           0x04
#define PPI_MODE_ACH_0          0x00
#define PPI_MODE_ACH_1          0x20
#define PPI_MODE_ACH_2          0x40
#define PPI_ACTIVE       0x80

#endif



Calc.c

/                            
************          Integer Calculator ( 2K Code Limit)           ************
*******************************************************************************/

#include "calc.h"

//Variables
static  LONG lvalue;
static  LONG rvalue;
static  CHAR currtoken;
static  CHAR lasttoken;
static  CHAR lastpress;
static  CHAR outputbuffer[MAX_DISPLAY_CHAR];

VOID main (VOID)
//Initialise our variables and call the
//Assembly routine to initialise the LCD display.
 { lvalue    = 0;
   rvalue    = 0;
   currtoken = '=';
   lasttoken = '0';
   initialise();  // Initialize the LCD
   calc_output(OK);
   calc_evaluate();
 }  

VOID calc_evaluate()
 { CHAR key;
   INT  i;
   CHAR number[MAX_DISPLAY_CHAR];
   CHAR *bufferptr;
  
   // Clear the buffer before we start.
   for (i = 0; i <= MAX_DISPLAY_CHAR; i++)
      { number[i] = ' ';
                  }
   bufferptr = number; 
  
   for (;;)
     { key = calc_getkey();
                   if (calc_testkey(key))
       // Key test positive for digit so we read it into the
       // buffer and then write the buffer to the screen/LCD.
                   // Size limit the number of digits - allow for termination
                   // and possible negative results.
          { if (bufferptr != &number[MAX_DISPLAY_CHAR - 2])
               { *bufferptr = key;
                 calc_display(number);
                 bufferptr++;
               }
          }

       else
       // Key is an operator so pass it to the function handlers.
       // If we are just after startup or cancel then assign to lvalue
       // otherwise assign to rvalue.
          {
                                    //Assign the value.
            if (lasttoken == '0')
               { lvalue = calc_asciidec (number);}
            else
               { rvalue = calc_asciidec (number);}

            //Clear the number buffer.
            bufferptr = number;
            for (i = 0;i <= MAX_DISPLAY_CHAR; i++)
               { number[i] = ' '; }
                                 
            //Process the Operator.
            currtoken = key;
                                                if (currtoken == 'C')
                                                   { calc_opfunctions(currtoken); }
                                                else
                                                   { calc_opfunctions(lasttoken); }
                               
                                    // Clear the outputbuffer for reuse on next operation.
            for (i = 0;i <= MAX_DISPLAY_CHAR;i++)
               { outputbuffer[i] = ' ';}
                                     
                     bufferptr = number;
                                                // Handle the equals operation here for brevity.
                                                // All we need do is preserve the previous operator in
                                                // lasttoken.
                                                if (currtoken != 0x3D) lasttoken = currtoken;
           
                                  }
       lastpress = key;
     }
 }

VOID calc_opfunctions (CHAR token)
// Handle the operations. Lvalue holds the result and we test for
// consecutive operator presses.
 { CHAR result;
   switch(token)
        // Add.
     {  case '+' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
                                                      { lvalue += rvalue;
                                                    result = calc_chkerror(lvalue);
                                                                                  }
                                                                   else
                                                                  { result =  SLEEP; }                          break;
        // Subtract.
                                case '-' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
                      { lvalue -= rvalue;
                        result = calc_chkerror(lvalue);                           
                                                                                  }
                   else
                      { result = SLEEP;}                        break;
        // Multiply.
                                case '*' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
                      { lvalue *= rvalue;
                        result =  calc_chkerror(lvalue);
                      }
                   else
                      { result =  SLEEP;}                       break;
                                // Divide.                                              
                                case '/' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
                      { if (rvalue)
                           { lvalue /= rvalue;
                             result = calc_chkerror(lvalue);
                           }
                        else
                           { result = ERROR;}                                                
                      }
                   else
                      { result = SLEEP;}                        break;
                                // Cancel.
                                case 'C' : lvalue = 0;
                   rvalue = 0;
                   currtoken = '0';
                   lasttoken = '0';
                   result = OK;                                                                     break;
               
                                default :  result = SLEEP; 

      }
   calc_output(result);
 }


/************************************************************************
***** Utility Routines *****
***************************/

INT calc_chkerror (LONG num)
// Check upper and lower bounds for the display.
// i.e. 99999999 and -99999999.
 { if ((num >= -9999999) && (num <= 9999999))
      return OK;
   else
      return ERROR;
 }


VOID calc_output (INT status)
// Output according to the status of the operation.
// *Sleep* is used for the first op press after a full cancel
// or on startup. 
 { switch (status)
      { case OK      : calc_display(calc_decascii(lvalue));    break;
        case SLEEP   :                                         break;
                                case ERROR   : calc_display("Exception ");                                                break;               
        default      : calc_display("Exception ");                              break;
      }
 }


LONG calc_asciidec (CHAR *buffer)
// Convert the ASCII string into the floating point number.
 { LONG value;
   LONG digit;
   value = 0;
   while (*buffer != ' ')
      { digit = *buffer - 48;
                    value = value*10 + digit;
        buffer++;
                  }
   return value;
 }

CHAR *calc_decascii (LONG num)
// A rather messy function to convert a floating
// point number into an ASCII string.
 { LONG temp = num;
   CHAR *arrayptr = &outputbuffer[MAX_DISPLAY_CHAR];
   LONG divisor = 10;
   LONG result;
   CHAR remainder,asciival;
   INT  i;
  
   // If the result of the calculation is zero
   // insert a zero in the buffer and finish.
   if (!temp)
      { *arrayptr = 48;
                    goto done;
                  }
   // Handle Negative Numbers.
   if (temp < 0)
      { outputbuffer[0] = '-';
                    temp -= 2*temp;
                  }

   for (i=0 ; i < sizeof(outputbuffer) ; i++)
      { remainder = temp % divisor;  
        result = temp / divisor;
                   
                                // If we run off the end of the number insert a space into
                    // the buffer.
                    if ((!remainder) && (!result))
                       { *arrayptr = ' ';}
                 
                    // We're in business - store the digit offsetting
                    // by 48 decimal to account for the ascii value.
                    else
                       { asciival = remainder + 48;
                                     *arrayptr = asciival;
                                   }
                 
                                temp /= 10;
                    // Save a place for a negative sign.
                    if (arrayptr != &outputbuffer[1]) arrayptr--;
                   }
   done: return outputbuffer;
 }


CHAR calc_testkey (CHAR key)
// Test whether the key is a digit or an operator. Return 1 for digit, 0 for op.
 { if ((key >= 0x30) && (key <= 0x39))
      { return 1;}
   else
      { return 0;}
 }

/************************************************************************
***** I/O Routines *****
***********************/

CHAR calc_getkey (VOID)
// Use the input routine from the *Keypad_Read* assembly file to
// Scan for a key and return ASCII value of the Key pressed.
{ CHAR mykey;
  do mykey = input();
     while (mykey == 0);
  return mykey;
 }

VOID calc_display (CHAR buf[MAX_DISPLAY_CHAR])
// Use the Output and Clearscreen routines from the
// *LCD_Write* assembly file to output ASCII values to the LCD.
 { INT i = 0;
   clearscreen();
   for (i = 0 ; i <= MAX_DISPLAY_CHAR ; i++)
      { if (buf[i] != ' ')
                     { output(buf[i]); }
                  }           
 }





 Cal.h

/                                            
************                       Integer Calculator ( 2K Code Limit)            ************
********************************************************************************/

typedef void VOID;
typedef int  INT;
typedef unsigned short WORD;
typedef char CHAR;
typedef unsigned char BYTE;
typedef float FLOAT;
typedef double DOUBLE;
typedef long LONG;

// Define the maximum number of ASCII characters that can fit
// on the display.
#define MAX_DISPLAY_CHAR 9

//Error handling status.
enum ERROR { OK = 0, SLEEP = 1, ERROR = 2};

/************************************************************************
***** FUNCTION PROTOTYPES *****
******************************/

VOID calc_evaluate();

//Operator indirect function.
VOID calc_opfunctions (CHAR token);

//Utility functions.
CHAR  calc_testkey  (CHAR ch);
LONG  calc_asciidec (CHAR *buffer);
CHAR *calc_decascii (LONG num);
INT   calc_chkerror (LONG num);
VOID  calc_output   (INT status);

// I/O functions.
CHAR calc_getkey (VOID);
VOID calc_display (CHAR buf[MAX_DISPLAY_CHAR]);

//Assembly Function prototypes.
void initialise();
char input ();
char output(char ch);
void clearscreen();




Rt.asm


                                                   .MODEL             SMALL
.8086

.code

extrn _main:proc

.startup

                                                   call  near ptr _main
endless:
   jmp   endless

.data

public                                       __acrtused                      ; trick to force in startup
                                                   __acrtused = 9876h     ; funny value not easily matched in SYMDEB

.stack

END