home *** CD-ROM | disk | FTP | other *** search
- ;
- ; CONVERSI.ASM ver 1.2
- ; Base conversion program
- ;
- ;From Heathkit course on assembly language
- ;
- ;Converts between ASCII, Binary, Decimal,
- ;Hexadecimal, Octal, and Split Octal.
- ;
- VERN EQU 1
- REVN EQU 2
- ;
- ; v1.2 Added upper case conversion to input. Added
- ; version display in message. Since <cr> ends input
- ; the Ascii conversion won't show a 'return' key and
- ; I can't figure a good way around it.
- ; 09/26/84 Dick Mead WB6NGC
- ;
- ; v1.1 Entered by Ben Miller WB8LGH
- ; on 02/20/80, with routines for CP/M
- ; I/O. Added prompt for input info.
- ; Added lower case print on ASCII output.
- ;
- CR EQU 0DH ;CARRIAGE RETURN
-
- LF EQU 0AH ;LINE FEED
- BDOS EQU 0005H ;CP/M ENTRY POINT
- ;
- ORG 100H ;ORIGIN OF OBJECT CODE
- ;
- BEGIN LXI SP,STACK;DEFINE TOP OF STACK
- LXI H,MESS6 ;SET H-L TO MESSAGE #6
- CALL PRINT ;GO PRINT MESSAGE
- ;
- BEGIN1 LXI H,MESS1 ;SET H-L TO MESSAGE #1
- CALL PRINT ;GO PRINT MESSAGE
- LXI D,0000H ;LOAD D-E REGISTERS WITH 0
- CALL INPUT ;GET BASE OF ENTRY
- CPI 'a' ;..lower to
- JC BEG2 ;..upper case
- CPI 'z'+1 ;..conversion
- JNC BEG2 ;..for
- XRI 20H ;..commands
- BEG2: CPI 'D' ;IS IT DECIMAL?
- JZ DECIN ;IF DECIMAL GO DECIN
- CPI 'H' ;IS IT HEXADECIMAL?
- JZ HEXIN ;IF HEXADECIMAL GO HEXIN
- CPI 'O' ;IS IT OCTAL?
- JZ OCTIN ;IF OCTAL GO OCTIN
- CPI 'S' ;IS IT SPLIT OCTAL
- JZ SOCTN ;IF SPLIT OCTAL GO SOCTN
- CPI 'B' ;IS IT BINARY
- JZ BININ ;IF BINARY GO BININ
- CPI 'A' ;IS IT ASCII?
- JZ ASCIN ;IF ASCII GO ASCIN
- CPI 'X' ;ARE YOU DONE?
- JZ 0000H ;DO A WARM BOOT
- LXI H,MESS2 ;NONE OF THE ABOVE? -MUST BE AN ERROR
- CALL PRINT ;GO PRINT ERROR MESSAGE
- JMP BEGIN ;START AGAIN TURKEY INPUT IN ERROR
- ;
- PRINT MOV A,M ;GET MESSAGE CHARACTER
- ORA A ;CHECK FOR DELIMITER
- RZ ;RETURN IF DONE
- CALL OUTPT ;DISPLAY CHARACTER
- INX H ;SET H-L TO NEXT CHARACTER
- JMP PRINT ;DO ANOTHER CHARACTER
- ;
- INPUT PUSH B ;SAVE REGISTERS
- PUSH D
- PUSH H
- MVI C,1 ;READ CONSOLE KBD
- CALL BDOS ;CALL CP/M ENTRY
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- RET ;RETURN TO MAIN PROGRAM
- ;
- OUTPT PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- MOV E,A ;GET CHARACTER FOR CP/M
- MVI C,2 ;WRITE CHARACTER TO CRT
- CALL BDOS ;CALL CP/M ENTRY
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW
- RET ;RETURN TO MAIN PROGRAM
- ;
- DECIN LXI H,DECIMAL;POINT TO ASCII FOR DECIMAL
- CALL VALIN ;SHOW QUESTIONS WITH PROPER BASE
- ;
- NEXT1 CALL GETIN ;GET CHARACTER AND ECHO
- JZ CNVRT ;GO CONVERT TO ALL BASES IF SO
- SUI 30H ;SUBTRACT 30 HEX FROM ASCII
- JC ERROR ;NO GOOD IF CARRY
- CPI 10 ;HIGHER THAN "9"?
- JNC ERROR ;NO GOOD IF SO
- LXI H,0000H ;CLEAR H-L FOR MULTIPLICATION
- DAD D ;H-L=D-E TIMES ONE
- DAD H ;H-L=D-E TIMES TWO
- DAD H ;H-L=D-E TIMES FOUR
- DAD D ;H-L=D-E TIMES FIVE
- DAD H ;H-L=D-E TIMES TEN
- MOV E,A ;NEW KEY VALUE TO E
- MVI D,00H ;CLEAR D
- DAD D ;ADD UNIT VALUE TO D-E
- XCHG ;NEW TOTAL TO D-E
- JMP NEXT1 ;LOOP FOR NEXT CHARACTER
- ;
- OCTIN LXI H,OCTAL ;POINT TO ASCII FOR OCTAL
- CALL VALIN ;SHOWS QUESTION WITH PROPER BASE
- ;
- NEXT2 CALL GETIN ;GET CHARACTER AND ECHO IT
- JZ CNVRT ;GO CONVERT TO ALL BASES IF SO
- SUI 30H ;SUBTRACT 30 HEX FROM ASCII
- JC ERROR ;NO GOOD IF CARRY
- CPI 8 ;HIGHER THAN "7"?
- JNC ERROR ;NO GOOD IF SO
- LXI H,0000H ;CLEAR H-L FOR MULTIPLICATION
- DAD D ;H-L=D-E TIMES ONE
- DAD H ;H-L=D-E TIMES TWO
- DAD H ;H-L=D-E TIMES FOUR
- DAD H ;H-L=D-E TIMES EIGHT
- MOV E,A ;NEW KEY VALUE TO E
- MVI D,00H ;CLEAR D
- DAD D ;ADD UNIT VALUE TO TOTAL
- XCHG ;NEW TOTAL TO D-E
- JMP NEXT2 ;LOOP FOR NEXT DIGIT
- ;
- HEXIN LXI H,HEXAD ;POINT TO ASCII FOR HEXADECIMAL
- CALL VALIN ;SHOWS QUESTION WITH PROPER BASE
- ;
- NEXT3 CALL GETIN ;GET CHARACTER AND ECHO IT
- JZ CNVRT ;GO CONVERT TO ALL BASES IF DONE
- CPI 'a' ;force
-
- JC HEX4 ;..lower
- CPI 'z'+1 ;...to
- JNC HEX4 ;...upper
- XRI 20H ;..case
- HEX4 SUI 30H ;SUBTRACT 30 HEX ASCII
- JC ERROR ;NO GOOD IF CARRY
- CPI 10 ;IS IT 0 THROUGH 9?
- JC HEXOK ;IT'S OK IF SO
- SUI 7 ;SUBTRACT 7 MORE FOR LETTERS
- CPI 10 ;LOWER THAN 10?
- JC ERROR ;NO GOOD IF SO
- CPI 16 ;HIGHER THAN 16?
- JNC ERROR ;NO GOOD IF SO
- ;
- HEXOK LXI H,0000H ;CLEAR H-L FOR MULTIPLICATION
- DAD D ;H-L=D-E TIMES ONE
- DAD H ;H-L=D-E TIMES TWO
- DAD H ;H-L=D-E TIMES FOUR
- DAD H ;H-L=D-E TIMES EIGHT
- DAD H ;H-L=D-E TIMES SIXTEEN
- MOV E,A ;NEW KEY VALUE TO E
- MVI D,00H ;CLEAR D
- DAD D ;ADD UNIT VALUE TO TOTAL
- XCHG ;NEW TOTAL TO D-E
- JMP NEXT3 ;LOOP FOR NEXT DIGIT
- ;
- BININ LXI H,BINRY ;SHOWS ASCII FOR BINARY
- CALL VALIN ;SHOWS QUESTION WITH PROPER BASE
-
- ;
- NEXT4 CALL GETIN ;GET CHARACTER AND ECHO IT
- JZ CNVRT ;GO CONVERT IF SO
- SUI 30H ;SUBTRACT 30H FROM ASCII
- JC ERROR ;NO GOOD IF CARRY
- CPI 2 ;IF HIGHER THAN "1"?
- JNC ERROR ;NO GOOD IF SO
- LXI H,0000H ;CLEAR H-L FOR MULTIPLICATION
- DAD D ;H-L=D-E TIMES ONE
- DAD H ;H-L=D-E TIMES TWO
- MOV E,A ;NEW KEY VALUE TO E
- MVI D,00H ;CLEAR D
- DAD D ;ADD UNIT VALUE TO TOTAL
- XCHG ;NEW TOTAL TO D-E
- JMP NEXT4 ;LOOP FOR NEXT DIGIT
- ;
- SOCTN LXI H,SPLIT ;POINT TO ASCII FOR SPLIT OCTAL
- CALL VALIN ;SHOWS QUESTION WITH PROPER BASE
- ;
- NEXT5 CALL GETIN ;GET CHARACTER AND ECHO IT
- JZ CNVRT ;GO CONVERT TO ALL BASES IF SO
- CPI '/' ;IS CHARACTER A SLASH?
- JNZ NODOT ;NO-CONTINUE
- MOV D,E ;YES - TOTAL IN E BECOMES HIGH BYTE
- MVI E,00H ;CLEAR E
- JMP NEXT5 ;GO GET NEXT CHARACTER
- ;
- NODOT SUI 30H ;SUBTRACT30H FROM ASCII
- JC ERROR ;NO GOOD IF CARRY
- CPI 8 ;HIGHER THAN "7"?
- JNC ERROR ;NO GOOD IF SO
- MOV L,A ;SAVE NEW KEY VALUE IN L
- MOV A,E ;PREVIOUS TOTAL TO A
- ADD A ;PREVIOUS TOTAL TIMES TWO
- ADD A ;PREVIOUS TOTAL TIMES FOUR
- ADD A ;PREVIOUS TOTAL TIMES EIGHT
- ADD L ;ADD NEW KEY TO MULTIPLIED TOTAL
- MOV E,A ;NEWTOTAL BACK TO E
- JMP NEXT5 ;LOOP FOR NEXT DIGIT
- ;
- ASCIN LXI H,ASCII ;POINT TO ASCII FOR ASCII
- CALL VALIN ;SHOWS QUESTION WITH PROPER BASE
- ;
- NEXT6 CALL GETIN ;GET CHARACTER AND ECHO IT
- JZ CNVRT ;GO CONVERT TO ALL BASES IF SO
- MOV D,E ;LAST CHARACTER MOVES TO D
-
- MOV E,A ;NEW CHARACTER GOES IN E
- JMP NEXT6 ;LOOP FOR NEXT CHARACTER
- ;
- CNVRT LXI H,MESS5 ;SET H-L TO BEGINNING OF MESSAGE
- CALL PRINT ;DISPLAY MESSAGE
- ;
- DOUT XCHG ;SWAP UNKNOWN INTO H-L
- PUSH H ;SAVE UNKNOWN ON STACK
- LXI B,10000D;LOAD B-C WITH 10000 DECIMAL
- CALL SUBTR ;SUBTRACT AND DISPLAY
- LXI B,1000D ;LOAD B-C WITH 1000 DECIMAL
- CALL SUBTR ;SUBTRACT AND DISPLAY
- LXI B,100D ;LOAD B-C WITH 100 DECIMAL
- CALL SUBTR ;SUBTRACT AND DISPLAY
- LXI B,10D ;LOAD B-C WITH 10 DECIMAL
- CALL SUBTR ;SUBTRACT AND DISPLAY
- MOV A,L ;WHAT'S LEFT IS UNITS ONLY
- ADI 30H ;MAKE IT ASCII
- CALL OUTPT ;DISPLAY UNITS
- POP D ;GET ORIGINAL BACK
- CALL SPACES ;OUTPUT TWO SPACES
- ;
- HOUT MOV A,D ;HIGH BYTE OF UNKNOWN TO A
- CALL DOHEX ;CONVERT HEX AND DISPLAY
- MOV A,E ;LOW BYTE OF UNKNOWN TO A
- CALL DOHEX ;CONVERT AND DISPLAY
- CALL SPACES ;OUTPUT TWO SPACES
- ;
- OOUT MOV A,D ;HIGH BYTE OF UNKNOWN TO A
- RAL ;ROTATE LEFT MOST BIT
- RAL ; INTO RIGHTMOST POSITION
- PUSH PSW ;SAVE NEW BYTE ON STACK
- ANI 01H ;ZER0 ALL BUT RIGHT BIT
- CALL OCTOUT ;MAKE ASCII AND DISPLAY ON CRT
- POP PSW ;GET MODIFIED BYTE BACK
- CALL ROTES ;GO NEXT 3 BYTES 2 TIMES
- MOV A,E ;LOW BYTE OF UNKNOWN TO A
- CALL ROTES ;DO LEFTOVER OF HIGH AND 5 OF LOW
- CALL ROTER ;DO LAST THREE BYETE
- CALL SPACES ;OUTPUT TWO SPACES
- ;
- SOOUT MOV A,D ;HIGH BYTE OF UNKNOWN TO A
- CALL SOCT ;CONVERT TO OCTAL DISPLAY
- MVI A,'/' ;SET UP A '/' TO DISPLAY
- CALL OUTPT ;DISPLAY ON CRT
- MOV A,E ;LOW BYTE OF UNKNOWN TO A
- CALL SOCT ;CONVERT TO OCTAL AND DISPLAY
- CALL SPACES ;OUTPUT TWO SPACES
- ;
- BOUT MOV A,D ;HIGH BYTE OF UNKNOWN TO A
- CALL BINOUT ;DISPLAY AS 0'S AND 1'S
- MOV A,E ;LOW BYTE OF UNKNOWN TO A
- CALL BINOUT ;DISPLAY AS O'S AND 1'S
- CALL SPACES ;OUTPUT TWO SPACES
- ;
- AOUT MOV A,D ;HIGH BYTE OF UNKNOWN TO A
- CALL ATEST ;TEST FOR LEGAL AND DISPLAY
- MVI A,' ' ;NEED A SPACE TO SEPERATE
- CALL OUTPT ;DISPLAY THE SPACE
- MOV A,E ;LOW BYTE OF UNKNOWN TO A
- CALL ATEST ;TEST FOR LEGAL AND DISPLAY
- CALL CRLF ;DO A CAR RET AND LINE FEED
- CALL CRLF ;ONE MORE MAKES IT NICE
- JMP BEGIN1 ;START ALL OVER AGAIN???
- ;
- CRLF MVI A,0DH ;SETUP A CARRIAGE RETURN
- CALL OUTPT ;DISPLAY IT
- MVI A,0AH ;SET UP A LINE FEED
- JMP OUTPT ;DISPLAY IT AND RETURN TO WHEREVER
- ;
- ATEST CPI ' ' ;LOWER THAN A SPACE?
- JC DODOT ;DISPLAY A '.' IF SO
- CPI 7FH ;HIGHER THAN A RUBOUT?
- JC OUTPT ;DISPLAY A CHARACTER IF SO
- ;
- DODOT MVI A,'.' ;SETUP A DOT TO DISPLAY
- JMP OUTPT ;DISPLAY THE DOT ON THE CRT
-
- BINOUT MVI B,08H ;8 BITS TO DO - SETUP COUNTER
- ;
- BLOOP RAL ;ROTATE A BIT INTO CARRY
- PUSH PSW ;SAVE THE MODIFIED BYTE
- MVI A,'1' ;ASSUME BIT LOGIC IS 1
- JC BINOK ;DISPLAY IT IF A-OK
- MVI A,'0' ;OOPS CHANGED MY MIND FICKLE
- ;
- BINOK CALL OUTPT ;DISPLAY WHATEVER
- POP PSW ;GET MODIFIED BYTE BACK
- DCR B ;COUNT ONE BIT COMPLETED
- JNZ BLOOP ;DO ANOTHER UNTILL ALL 8 ARE DONE
- RET ;THEN GO BACK TO WHEREVER
- ;
- SOCT RAL ;ROTATE TWO LEFTMOST BITS
- RAL ; INTO TWO RIGHTMOST
- RAL ; POSITIONS
- PUSH PSW ;SAVE MODIFIED BYTE ON STACK
- ANI 03H ;ZERO ALL BUT TWO RIGHTMOST BITS
- CALL SPOUT ;MAKE ASCII AND DISPLAY ON CRT
- POP PSW ;GET MODIFIED BYTE BACK
- CALL SPINR ;DO 3 BITS AND FALL INTO 3 MORE
- ;
- SPINR RAL ;ROTATE TWO LEFTMOST BITS
- RAL ; INOT TWO RIGHTMOST
- RAL ; POSITIONS
- ;
- SPOUT PUSH PSW ;SAVE MODIFIED BYTE ON STACK
- ANI 07H ;ZERO ALL BUT THREE RIGHT BITS
- ADI 30H ;ADD ASCII OFFSET
- CALL OUTPT ;DISPLAY CHARACTER ON CRT
- POP PSW ;GET MODIFIED BYTE BACK
- RET ;GO BACK TO WHERE YOU CAME FROM
- ;
- ROTES CALL ROTER ;DO 3 BITS AND FALL INTO 3 MORE
- ;
- ROTER RAL ;ROTATE CARRY PLUS LEFTMOST
- RAL ; TWO BITS OF DATA BYTE INTO
- RAL ; THREE RIGHTMOST BITS
- ;
- OCTOUT PUSH PSW ;SAVE MODIFIED BYTE ON STACK
- ANI 07H ;ZERO ALL BUT RIGHT THREE BITS
- ADI 30H ;ADD IN ASCII OFFSET
- CALL OUTPT ;DISPLAY CHARACTER ON CRT
- POP PSW ;GET MODIFIEY BYTE BACK
- RET ;RETURN TO MAIN PROGRAM
- ;
- DOHEX PUSH PSW ;SAVE BYTE ON STACK
- RRC ;ROTATE
- RRC ;LEFT
- RRC ; FOUR BITS
- RRC ; INTO PLACE
- CALL HEXOUT ;MAKE ASCII AND DISPLAY
- POP PSW ;GET BYTE BACK
- ;
- HEXOUT ANI 0FH ;KEEP ONLY RIGHT FOUR BITS
- ADI 30H ;ADD ASCII OFFSET
- CPI ':' ;IS IT A NUMBER
- JC OUTPT ;DISPLAY IT ON CRT IF SO
- ADI 07H ;MAKE IT A LETTER
- JMP OUTPT ;AND DISPLAY ON CRT
- ;
- SUBTR MVI D,0FFH ;D REGISTER TO MINUS ONE
- ;
- LOOP5 MOV A,L ;LOW BYTE OF UNKNOWN TO A
- SUB C ;SUBTRACT LOW BYTE OF DIVISOR
- MOV L,A ;DIFFERENCE BACK TO L
- MOV A,H ;HIGHT BYTE OF UNKNOWN TO A
- SBB B ;SUBTRACT B AND BORROW IF ANY
- MOV H,A ;DIFFERENCE BACK TO H
- INR D ;COUNT ONE SUBTRACTION
- JNC LOOP5 ;SUBTRACT AGAIN IF NO BORROW
- DAD B ;ADD DIVISOR BACK TO UNKNOWN
- MOV A,D ;COUNT TO A
- ADI 30H ;MAKE IT ASCII
- JMP OUTPT ;DISPLAY ON CRT
- ;
- ERROR LXI H,MESS4 ;SET H-L TO BEGINNING OF MESSAGE
- CALL PRINT ;GO PRINT IT
- JMP BEGIN ;START OVER
- ;
- SPACES MVI A,' ' ;PUT A SPACE IN REGISTER A
- CALL OUTPT ;PRINT IT
- JMP OUTPT ;OUTPUT ANOTHER SPACE THEN RETURN
- ;
- GETIN CALL INPUT ;GET CHARACTER FROM KEYBOARD
- CPI 0DH ;ARE THEY DONE ENTERING?
- RNZ ;BACK TO WHOEVER IF NOT
- JMP CNVRT ;JMP TO CONVERT ALL BASES
- ;
- VALIN PUSH H ;SAVE BASE POINTER
- LXI H,WHAT ;POINT TO QUESTION
- CALL PRINT ;SHOWS THE QUESTION
- POP H ;GET THE BASE NAME POINTER BACK
- CALL PRINT ;PRINT IT
- LXI H,VALUE ;POINT TO VALUE
- JMP PRINT ;PRINT IT THEN JUMP WHEREVER
- ;
- WHAT DB CR,LF,'What''s your ',0
- VALUE DB ' Value? ',0
- DECIMAL DB 'Decimal',0
- HEXAD DB 'Hexadecimal',0
- OCTAL DB 'Octal',0
- SPLIT DB 'Split Octal',0
- BINRY DB 'Binary',0
- ASCII DB 'ASCII',0
- MESS1 DB CR,LF,'What base is your entry? ',0
- MESS2 DB CR,LF,'Sorry that is not a base I can work with. ',0
- MESS4 DB CR,LF
- DB 'Input character wrong for base specified, '
- DB 're-enter',0
- MESS5 DB CR,LF,' Decimal Hex Octal S/Octal Binary'
- DB ' ASCII',CR,LF,' ',0
- MESS6 DB CR,LF,'Base Converter Ver. ',(VERN MOD 10)+'0','.'
- DB REVN/10+'0',(REVN MOD 10)+'0'
- DB CR,LF,'Possible choices are: ',CR,LF
- DB CR,LF,' A = ASCII '
- DB CR,LF,' B = Binary '
- DB CR,LF,' D = Decimal '
- DB CR,LF,' H = Hexadecimal'
- DB CR,LF,' O = Octal '
- DB CR,LF,' S = Split Octal '
- DB CR,LF,' X = Exit '
- DB CR,LF,0
- ;
- DS 60 ;RESERVE SPACE FOR STACK
- STACK EQU $ ;TOP OF STACK
- ;
- END
-
-