;; ;; $Id: bcd.asm,v 1.3 2001/03/05 03:45:00 james Exp $ ;; ;; bcd.asm, convert value to binary coded decimal for output ;; Copyright (C) 2001 James Cameron (quozl@us.netrek.org) ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;; ;;; ;;; convert value to binary coded decimal for output ;;; ;;; data stack: ( lsb msb -- d0 d1 d2 ) [total 5] ;;; stack: calls others that do not call ;;; sb_bcd ; ( lsb msb -- d0 d1 d2 ) ;; ( lsb msb ) popf r_ephemeral ; msb popf r_temporary ; lsb movlw 0 pushw ; d0 (lsd) pushw ; d1 pushw ; d2 (msd) pushf r_temporary ; lsb pushf r_ephemeral ; msb pushl d'16' ; count ;; ( d0 d1 d2 msb lsb count ) bcf status,c sb_bcd_loop incf fsr,f ; ( d0 d1 d2 lsb msb ^ count ) incf fsr,f ; ( d0 d1 d2 lsb ^ msb count ) rlf indf,f ; lsb decf fsr,f ; ( d0 d1 d2 lsb msb ^ count ) rlf indf,f ; msb incf fsr,f incf fsr,f incf fsr,f incf fsr,f ; ( d0 ^ d1 d2 lsb msb count ) rlf indf,f ; d0 (lsd) decf fsr,f ; ( d0 d1 ^ d2 lsb msb count ) rlf indf,f ; d1 decf fsr,f ; ( d0 d1 d2 ^ lsb msb count ) rlf indf,f ; d2 (msd) movlw d'3' subwf fsr,f ; ( d0 d1 d2 lsb msb count ) decfsz indf,f ; count goto sb_bcd_adjust movlw d'3' addwf fsr,f ; drop drop drop ;; ( d0 d1 d2 ) retlw 0 sb_bcd_adjust ;; ( d0 d1 d2 lsb msb count ) movlw d'3' addwf fsr,f ; ( d0 d1 d2 ^ lsb msb count ) call sb_bcd_fix ; d2 call sb_bcd_fix ; d1 call sb_bcd_fix ; d0 ; ( ^ d0 d1 d2 lsb msb count ) movlw d'6' subwf fsr,f ; ( d0 d1 d2 lsb msb count ) goto sb_bcd_loop sb_bcd_fix movlw 3 addwf indf,w ; add 3 to low nibble movwf r_ephemeral ; test bits btfsc r_ephemeral,3 ; if bit three is set movwf indf ; store the adjusted value movlw 0x30 addwf indf,w ; add 3 to high nibble movwf r_ephemeral ; test bits btfsc r_ephemeral,7 ; if bit seven is set movwf indf ; store the adjusted value incf fsr,f ; move to next digit pair retlw 0