* HEX RPN Calculator * The calculator has only 2 functions: addition and subtraction * The user enters lines with operands and operators terminated * with a CR. Operands can have up to four HEX digits. * An empty line causes a return to the monitor. * The calculator uses reverse Polish notation * example: input: 1 FFFF 3210++ * output: TOS=3210 ; TOS=Top of Stack * Declaration of constants: * BUFFALO subroutines outa equ $ffb8 output the ASCII character in A outstrg equ $ffca output string at x ; string is terminated by $04 outcrlf equ $ffc4 output crlf outlhlf equ $ffb2 output left nibble of a in ASCII outrhlf equ $ffb5 output right nibble of a in ASCII out2bsp equ $ffc1 output 2byte value at x in HEX input equ $ffac a=input() ; a=0 if no char entered inchar equ $ffcd a=input() ; loop till user enters char upcase equ $ffa0 a=upcase(a) wchek equ $FFA3 z=1 if A={space,comma,tab} dchek equ $FFA6 z=1 if A={space,comma,tab,CR} * ASCII control codes cr equ $0d carriage return lf equ $0a line feed del equ $7f delete eot equ $04 eot ; end of text bsp equ $08 back space ORG $C000 OPT s * * Main Program * org $C000 ldx #headst point to header string jsr outstrg output header ldy #ustack initialize user operand stack (16bit values) loop ldx #buffer x points to start of input buffer jsr getinp get input line from terminal into buffer cmpx #buffer input buffer empty? beq quit ldx #buffer point to first char in buffer conv jsr convert convert input ASCI to binary cmpa #cr end of input line? beq disp jsr operate do operation cmpa #cr end of input line? bne conv disp jsr out else, output result and prompt bra loop quit swi * * * Subroutine getinput * gets characters from input device, converts them to upper case * and puts them into the input buffer till end of buffer or CR * recognizes back space and delete characters * returns: x ; pointer to end of command line buffer * a ; last character read = CR * modifies flags getinp ldx #buffer set input buffer pointer iloop jsr inchar input loop cmpa #lf line feed? beq iloop ignore lf's cmpa #del delete? bne case cmpa #bsp back space? bne case dex cpx #buffer past begining of buffer? beq getinp bra iloop case jsr upcase store staa 0,x store character cmpa #cr end of input line? beq idone inx point to next char cpx #endb buffer full? bne iloop idone rts * Subroutine convert * checks the next character in the input buffer for an ASCII HEX digit * if a digit is found the the ASCII HEX digit string with up to four * digits is converted to a binary number and pushed onto the user stack. * argument: x = pointer to last character in input buffer * y = pointer to user stack * returns : a = pointer to last nodigit character processed * modifies: b,flags * convert ldd #0 std 0,Y clear top of user operand stack clr digit getop ldaa 0,X load next character from input buffer suba #'0 hex digit? bmi nodigit cmpa #9 digit 0-9? bls isdigit suba #7 convert hex A-F to binary cmpa #$0F hex digit? bgt nodigit isdigit staa 0,X save digit inc digit ldd 0,Y load current operand asld asld asld asld 4bit shift addb 0,X add digit std 0,Y update operand inx cpx #endb end of buffer? bne getop nodigit ldaa digit was a number encountered? beq nooper dey accept number as new TOS dey decrement operand stack pointer cpy #eustack user stack overflow? ble quit nooper ldaa 0,X a = next char (no digit) rts digit fcb 0 * Subroutine operate * performs an add or subtract between the operand on TOS+2 and * the operand TOS+4 if the character in A is in {+,-} and loads * the next character from the input buffer. * An error message is printed if * -an add or subtract overflow occurred * -if an unknown operator is encountered * argument: a = current input char from buffer * x = pointer to last character in input buffer * y = pointer to user stack TOS-2 * result: The two operand of an add or subtract are poped * from the stack and the result is pushed onto the * user stack. * y points to TOS-2. * a next char from input line * modifies: b,flags operate jsr dchek is char white space? beq endoper cmpa #'+ is operator = + ? bne tsub add cpy #ustack-2 user stack underflow? bhs stackuf ldd 2,Y load TOS+2 addd 4,Y add TOS+4 bvs overfl iny POP iny std 2,Y put result on new TOS stack bra endoper tsub cmpa #'- is operator = - ? bne error sub cpy #ustack-2 user stack underflow? bhs stackuf ldd 4,Y load TOS+4 subd 2,Y subtract TOS+2 bvs overfl iny POP iny std 2,Y put result on stack endoper inx ldaa 0,X rts * print error message and return to monitor * overfl ldx #ovmsg load pointer to overflow msg bra printm stackuf ldx #stackum load pointer to stack overflow msg bra printm error ldx #emsg load pointer to error message printm jsr outstrg print error message swi * Subroutine output * displays the TOS and prompts user for input * arguments: y points to TOS-2 * modifies : a,x,flags * out ldx #prompt jsr outstrg ;output prompt pshy pulx inx inx x points to TOS jsr out2bsp ;output TOS ldaa #'> jsr outa rts * Definition of strings * headst fcc 'CML HEX RPN CALCULATOR' fcb cr,lf,eot prompt fcc 'TOS=' fcb eot emsg fcb cr,lf fcc 'UNKNOWN OPERATOR' fcb cr,lf,eot ovmsg fcb cr,lf fcc 'OVERFLOW' fcb cr,lf,eot stackum fcb cr,lf fcc 'OPERAND STACK UNDERFLOW' fcb cr,lf,eot * Declaration of buffer and operand stack org $c200 eustack rmb 254 16bit operand stack ustack equ * fcb 0,0,0,0 initial TOS,TOS-2 buffer rmb 80 input line buffer endb equ * org $df00 fcc '1 F' fcb del fcc '3210' fcb cr,lf fcc '++' fcb del,cr,lf fcc '1 FFFF 3210++' fcb cr,lf fcc '0 abcd +' fcb cr,lf fcc 'abcd -' fcb cr,lf fcc '0 1 -' fcb cr,lf fcb cr,lf