home *** CD-ROM | disk | FTP | other *** search
- ; ROMAN80 - VERSION 0.2
- ;
- ; ROMAN CONVERSION PROGRAM
- ;
- ; DATE: 10-OCT-78
- ; BY: M PEDDER
- ;
- ;
- ; DEFINITIONS
- ;
- ORG 100H ;ALLOCATE
- START: JMP ROMAN
- CR: EQU 0DH
- LF: EQU 0AH
- CONSTA: EQU 1H ;Console status port
- CONDAT: EQU 0H ;Console data port
- B$KDR: EQU 02H ;Data available mask
- STACK: EQU 400H
- B$VDR: EQU 01H ;Tx ready mask
- ;
- ; MESSAGES
- ;
- STM DB 'COPYRIGHT (C) 1978 M PEDDER',CR,LF
- DB '"ROMAN" ACCEPTS DECIMAL NUMBERS IN THE RANGE 1 - 3999'
- DB CR,LF
- DB 'AND CONVERTS TO ROMAN NUMERALS, CHECKING VALIDITY.'
- DB CR,LF,LF
- DB 'ENTER DATA FOLLOWING "READY =", ENDING WITH "CR"'
- DB CR,LF,'$'
- RDM DB CR,LF,'READY = $'
- TOOL: DB ' TOO LARGE$'
- INV: DB ' INVALID CHARACTER$'
- LIST: DB 0,0,'IVXLCDM'
- ;
- ; WORKSPACE:
- ;
- DBUF: DS 5 ;DECIMAL BUFFER
- RBUF: DS 16 ;ROMAN BUFFER
- DCNT: DS 1 ;DECIMAL COUNT
- STK: DS 2 ;SP HOLDER
- ;
- ; SUPERVISORY:
- ;
- ROMAN: LXI H,0
- DAD SP
- SHLD STK
- LXI SP,STACK ;PREPARE STACK
- LXI H,STM ;POINT TO START MESSAGE
- CALL PRINS ;AND OUTPUT IT
- RDY: CALL RDYM ;PRODUCE READY MESSAGE, AND SET UP
- CALL INPUT ;GET DATA
- JC RDY ;IF IT IS VALID
- CALL ENC ;ENCODE AND OUTPUT IT
- JMP RDY
- PAGE
- ;
- ; READY MESSAGE AND SETTING UP:
- ;
- RDYM: LXI H,RDM ;POINT TO READY MESSAGE
- CALL PRINS ;AND OUTPUT IT
- LXI B,DBUF ;PREPARE DECIMAL POINTER
- LXI H,DCNT ;AND COUNT POINTER
- MVI M,00H ;CLEAR COUNTER
- RET
- ;
- ; GET INPUT FROM CONSOLE INTO DBUF, CHECKING VALIDITY:
- ;
- INPUT: IN CONSTA ;IF CHARACTER
- ANI B$KDR ;IS AVAILABLE
- JZ INPUT
- IN CONDAT ;GET IT
- ANI 7FH ;STRIP PARITY
- CPI 03H ;IF IT IS EXIT CMD
- JZ EXIT ;THEN GO
- CPI 0DH ;IF IT IS 'CR'
- JNZ ECHO ;THEN
- MVI A,20H ;LOAD 'SPACE'
- CALL PRINC ;AND OUTPUT IT
- CALL PRINC ;TWICE
- MVI A,'$' ;MARK END
- STAX B ;OF DATA
- ORA A ;CLEAR FLAG
- RET
- ;
- EXIT: LHLD STK
- SPHL
- RET
- ;
- ECHO: CALL PRINC ;ECHO CHARACTER
- CPI '0' ;IF IT IS ZERO OR MORE
- JM INVCH ;AND
- CPI ':' ;IF IT IS NINE OR LESS
- JP INVCH ;THEN IT IS VALID CHARACTER
- INR M ;SO COUNT IT
- STAX B ;AND STORE IT
- INX B ;ADVANCE POINTER
- MOV A,M ;CHECK COUNT
- CPI 05H ;IF IT IS LESS THAN FIVE
- JM INPUT ;THEN CONTINUE
- LXI H,TOOL ;ELSE POINT TO 'TOO LARGE'
- JMP MES
- ;
- INVCH: LXI H,INV ;POINT TO 'INVALID CHARACTER'
- MES: CALL PRINS ;AND OUTPUT IT
- STC ;SET ERROR FLAG
- RET
- ;
- ;
- PAGE
- ;
- ; PREPARE TO ENCODE:
- ;
- ENC: LXI B,DBUF ;PREPARE DECIMAL POINTER
- LXI D,LIST ;PREPARE LIST POINTER
- LXI H,DCNT ;PREPARE COUNT POINTER
- MOV A,M ;GET COUNT
- CPI 04H ;IF IT IS NOT FOUR
- JNZ CONT ;CONTINUE
- LDAX B ;ELSE GET FIRST CHARACTER
- CPI 34H ;IF IT IS NOT FOUR
- JM CONT ;CONTINUE
- LXI H,TOOL ;ELSE LOAD 'TOO LARGE'
- CALL PRINS ;AND OUTPUT IT
- RET
- ;
- CONT: MOV L,M ;GET COUNT
- MVI H,00H ;INTO HL
- DAD H ;DOUBLE IT
- DAD D ;ADD TO LIST
- XCHG ;AND RESTORE LIST
- LXI H,RBUF ;PREPARE ROMAN POINTER
- ;
- ; ENCODE CHARACTER STREAM IN DBUF:
- ;
- ENCA: LDAX B ;GET A CHARACTER
- INX B ;UPDATE THE POINTER
- CPI '$' ;IF IT IS NOT "END MARKER"
- RZ ;THEN
- CPI '9' ;IF IT IS NOT A NINE
- JZ NINE ;THEN
- CPI '5' ;IF IT IS NOT FIVE OR MORE
- JP FIVE ;THEN
- CPI '4' ;IF IT IS NOT FOUR
- JZ FOUR ;THEN
- ETA: CPI '0' ;IF IT IS ZERO
- JNZ ONE ;THEN
- ETB: DCX D ;MODIFY ROMAN POINTER
- DCX D ;TWICE
- LDA DCNT ;REDUCE COUNT
- DCR A ;AND
- STA DCNT ;IF IT IS NOT ZERO
- JNZ ENCA ;THEN LOOP
- MVI A,'$' ;ELSE MARK END
- CALL STOR ;AND STORE IT
- JMP ROUT ;ENCODE COMPLETED
- ;
- PAGE
- ;
- ; ITS A 1=I, 10=X, 100=C, 1000=M OR MORE:
- ;
- ONE: PUSH PSW ;SAVE DATA
- LDAX D ;LOAD ROMAN CHARACTER
- CALL STOR ;AND STORE IT
- POP PSW ;UNSAVE DATA
- DCR A ;SUBTRACT ONE
- JMP ETA ;AND TRY AGAIN
- ;
- ; ITS A 4=IV, 40=XL, 400=CD:
- ;
- FOUR: LDAX D ;LOAD ROMAN CHARACTER I, X OR C
- CALL STOR ;AND STORE IT
- INX D ;GET NEXT
- LDAX D ;ROMAN CHARACTER V, L OR D
- CALL STOR ;AND STORE THAT
- DCX D ;RESTORE POINTER
- JMP ETB ;AND EXIT
- ;
- ; ITS A 5=V, 50=L, 500=D OR MORE:
- ;
- FIVE: PUSH PSW ;SAVE DATA
- INX D ;PREPARE POINTER
- LDAX D ;GET ROMAN CHARACTER V, L OR D
- CALL STOR ;AND STORE IT
- DCX D ;RESTORE POINTER
- POP PSW ;AND DATA
- SUI 05H ;SUBTRACT FIVE
- JMP ETA ;AND TRY AGAIN
- ;
- ; ITS A 9=IX, 90=XC, OR 900=CM:
- ;
- NINE: LDAX D ;GET ROMAN CHARACTER I, X OR C
- CALL STOR ;AND STORE IT
- INX D ;MOVE
- INX D ;POINTER
- LDAX D ;GET ROMAN CHARACTER X, C OR M
- CALL STOR ;AND STORE THAT
- DCX D ;RESTORE
- DCX D ;POINTER
- JMP ETB ;AND EXIT
- ;
- PAGE
- ;
- ; STORE ROMAN CHARACTER IN RBUF FOR OUTPUT:
- ;
- STOR: MOV M,A ;STORE DATA IN BUFFER
- INX H ;AND MOVE POINTER
- RET
- ;
- ; ROMAN OUTPUT TO CONSOLE:
- ;
- ROUT: LXI H,RBUF ;POINT TO ROMAN BUFFER
- CALL PRINS ;AND OUTPUT IT
- RET
- ;
- ; OUTPUT A STRING OF CHARACTERS:
- ;
- PRX: CALL PRINC ;OUTPUT IT
- PRINS: MOV A,M ;GET CHARACTER
- INX H ;POINT TO NEXT
- CPI '$' ;IF IT IS NOT END
- JNZ PRX ;THEN GO
- RET
- ;
- ; OUTPUT A CHARACTER TO CONSOLE:
- ;
- PRINC: PUSH PSW ;SAVE DATA
- PRA: IN CONSTA ;IF CHARACTER
- ANI B$VDR ;CAN BE TAKEN
- JZ PRA
- POP PSW ;UNSAVE CHARACTER
- OUT CONDAT ;AND OUTPUT IT
- RET
- ;
- END
-