home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol147 / roman80a.asm < prev    next >
Encoding:
Assembly Source File  |  1985-02-10  |  5.4 KB  |  247 lines

  1. .po1
  2. ;    ROMAN80 - VERSION 0.2
  3. ;       (Now version 0.2a)
  4. ;
  5. ;    ROMAN CONVERSION PROGRAM
  6. ;
  7. ;    DATE: 10-OCT-78
  8. ;    BY: M PEDDER
  9. ;
  10. ;    Taken from SIG/M Users' Group Vol. 75, Prog. 75.21
  11. ;    Modified for CP/M by D. Mc Lanahan, Marlow, NH 2/13/83
  12. ;
  13. ;    DEFINITIONS
  14.  
  15. CPM$BASE    EQU    0        ; BASE ADDRESS OF CP/M SYSTEM
  16.     BDOS    EQU    CPM$BASE+5    ; ADDRESS OF BDOS ENTRY
  17.     CR    EQU    0DH
  18.     LF    EQU    0AH
  19.         SPACE   EQU     20H
  20.         PERIOD  EQU     2EH
  21.         COMMA   EQU     2CH
  22.     COLON    EQU    3AH
  23.     ORG    CPM$BASE+100H
  24. ;
  25. START:    JMP    ROMAN
  26. STACK:    EQU    400H
  27. ;
  28. ;    MESSAGES
  29. ;
  30. STM    DB    'Copr. (C) 1978 M Pedder. Mod. 1983, D. Mc Lanahan',CR,LF
  31.     DB    '"ROMAN" accepts decimal numbers in the range 1 - 3999'
  32.     DB    CR,LF
  33.     DB    'and converts to Roman numerals, checking validity.'
  34.     DB    CR,LF,LF
  35.     DB    'Enter data following "Ready: ", ending with <cr>'
  36. CRLF:    DB    CR,LF,'$'
  37. RDM    DB    CR,LF,'Ready:  $'
  38. TOOL:    DB    '  Too Large!$'
  39. INV:    DB    '  Invalid character!$'
  40. LIST:    DB    0,0,'IVXLCDM'
  41. ;
  42. ;    WORKSPACE:
  43. ;
  44. DBUF:    DS    5        ;DECIMAL BUFFER
  45. RBUF:    DS    16        ;ROMAN BUFFER
  46. DCNT:    DS    1        ;DECIMAL COUNT
  47. STK:    DS    2        ;SP HOLDER
  48. ;
  49. ;    SUPERVISORY:
  50. ;
  51. ROMAN:    LXI    H,0
  52.     DAD    SP
  53.     SHLD    STK
  54.     LXI    SP,STACK    ;PREPARE STACK
  55.     LXI    H,STM        ;POINT TO START MESSAGE
  56.     CALL    PRINT        ;AND OUTPUT IT
  57. èRDY:    CALL    RDYM        ;PRODUCE READY MESSAGE, AND SET UP
  58.     CALL    INPUT        ;GET DATA
  59.     JC    RDY        ;IF IT IS VALID
  60.     CALL    ENC        ;ENCODE AND OUTPUT IT
  61.     JMP    RDY
  62. ;
  63. ;    READY MESSAGE AND SETTING UP:
  64. ;
  65. RDYM:    LXI    H,RDM        ;POINT TO READY MESSAGE
  66.     CALL    PRINT        ;AND OUTPUT IT
  67.     LXI    B,DBUF        ;PREPARE DECIMAL POINTER
  68.     LXI    H,DCNT        ;AND COUNT POINTER
  69.     MVI    M,00H        ;CLEAR COUNTER
  70.     RET
  71. ;
  72. ;    GET INPUT FROM CONSOLE INTO DBUF, CHECKING VALIDITY:
  73. ;
  74. INPUT:  PUSH    H
  75.     PUSH    D
  76.     PUSH    B
  77.     MVI    C,1
  78.     CALL    BDOS        ;IF CHARACTER
  79.         POP    B
  80.     POP    D
  81.     POP     H
  82.         ANI    7FH        ;STRIP PARITY
  83.     CPI    03H        ;IF IT IS EXIT CMD
  84.     JZ    EXIT        ;THEN GO
  85.     CPI    0DH        ;IF IT IS 'CR'
  86.     JNZ    ECHO        ;THEN
  87.         LXI     H,CRLF
  88.         CALL    PRINT
  89.     MVI    A,20H        ;LOAD 'SPACE'     
  90.         CALL    COUT            ;AND OUTPUT IT
  91.         MVI     A,'='
  92.     CALL    COUT        
  93.         MVI     A,SPACE
  94.         CALL    COUT
  95.     MVI    A,'$'        ;MARK END
  96.     STAX    B        ;OF DATA
  97.     ORA    A        ;CLEAR FLAG
  98.     RET
  99. ;
  100. EXIT:    LHLD    STK
  101.     SPHL
  102.     RET
  103. ;
  104. ECHO:    ;CALL    COUT        ;ECHO CHARACTER
  105.     CPI    '0'        ;IF IT IS ZERO OR MORE
  106.     JM    INVCH        ;AND
  107.     CPI    ':'        ;IF IT IS NINE OR LESS
  108.     JP    INVCH        ;THEN IT IS VALID CHARACTER
  109.     INR    M        ;SO COUNT IT
  110.     STAX    B        ;AND STORE IT
  111.     INX    B        ;ADVANCE POINTER
  112. è    MOV    A,M        ;CHECK COUNT
  113.     CPI    05H        ;IF IT IS LESS THAN FIVE
  114.     JM    INPUT        ;THEN CONTINUE
  115.     LXI    H,TOOL        ;ELSE POINT TO 'TOO LARGE'
  116.     JMP    MES
  117. ;
  118. INVCH:    LXI    H,INV        ;POINT TO 'INVALID CHARACTER'
  119. MES:    CALL    PRINT        ;AND OUTPUT IT
  120.     STC            ;SET ERROR FLAG
  121.     RET
  122. ;
  123. ;
  124. ;
  125. ;    PREPARE TO ENCODE:
  126. ;
  127. ENC:    LXI    B,DBUF        ;PREPARE DECIMAL POINTER
  128.     LXI    D,LIST        ;PREPARE LIST POINTER
  129.     LXI    H,DCNT        ;PREPARE COUNT POINTER
  130.     MOV    A,M        ;GET COUNT
  131.     CPI    04H        ;IF IT IS NOT FOUR
  132.     JNZ    CONT        ;CONTINUE
  133.     LDAX    B        ;ELSE GET FIRST CHARACTER
  134.     CPI    34H        ;IF IT IS NOT FOUR
  135.     JM    CONT        ;CONTINUE
  136.     LXI    H,TOOL        ;ELSE LOAD 'TOO LARGE'
  137.     CALL    PRINT        ;AND OUTPUT IT
  138.     RET
  139. ;
  140. CONT:    MOV    L,M        ;GET COUNT
  141.     MVI    H,00H        ;INTO HL
  142.     DAD    H        ;DOUBLE IT
  143.     DAD    D        ;ADD TO LIST
  144.     XCHG            ;AND RESTORE LIST
  145.     LXI    H,RBUF        ;PREPARE ROMAN POINTER
  146. ;
  147. ;    ENCODE CHARACTER STREAM IN DBUF:
  148. ;
  149. ENCA:    LDAX    B        ;GET A CHARACTER
  150.     INX    B        ;UPDATE THE POINTER
  151.     CPI    '$'        ;IF IT IS NOT "END MARKER"
  152.     RZ            ;THEN
  153.     CPI    '9'        ;IF IT IS NOT A NINE
  154.     JZ    NINE        ;THEN
  155.     CPI    '5'        ;IF IT IS NOT FIVE OR MORE
  156.     JP    FIVE        ;THEN
  157.     CPI    '4'        ;IF IT IS NOT FOUR
  158.     JZ    FOUR        ;THEN
  159. ETA:    CPI    '0'        ;IF IT IS ZERO
  160.     JNZ    ONE        ;THEN
  161. ETB:    DCX    D        ;MODIFY ROMAN POINTER
  162.     DCX    D        ;TWICE
  163.     LDA    DCNT        ;REDUCE COUNT
  164.     DCR    A        ;AND
  165.     STA    DCNT        ;IF IT IS NOT ZERO
  166.     JNZ    ENCA        ;THEN LOOP
  167. è    MVI    A,'$'        ;ELSE MARK END
  168.     CALL    STOR        ;AND STORE IT
  169.     JMP    ROUT        ;ENCODE COMPLETED
  170. ;
  171. ;
  172. ;    ITS A 1=I, 10=X, 100=C, 1000=M OR MORE:
  173. ;
  174. ONE:    PUSH    PSW        ;SAVE DATA
  175.     LDAX    D        ;LOAD ROMAN CHARACTER
  176.     CALL    STOR        ;AND STORE IT
  177.     POP    PSW        ;UNSAVE DATA
  178.     DCR    A        ;SUBTRACT ONE
  179.     JMP    ETA        ;AND TRY AGAIN
  180. ;
  181. ;    ITS A 4=IV, 40=XL, 400=CD:
  182. ;
  183. FOUR:    LDAX    D        ;LOAD ROMAN CHARACTER I, X OR C
  184.     CALL    STOR        ;AND STORE IT
  185.     INX    D        ;GET NEXT
  186.     LDAX    D        ;ROMAN CHARACTER V, L OR D
  187.     CALL    STOR        ;AND STORE THAT
  188.     DCX    D        ;RESTORE POINTER
  189.     JMP    ETB        ;AND EXIT
  190. ;
  191. ;    ITS A 5=V, 50=L, 500=D OR MORE:
  192. ;
  193. FIVE:    PUSH    PSW        ;SAVE DATA
  194.     INX    D        ;PREPARE POINTER
  195.     LDAX    D        ;GET ROMAN CHARACTER V, L OR D
  196.     CALL    STOR        ;AND STORE IT
  197.     DCX    D        ;RESTORE POINTER
  198.     POP    PSW        ;AND DATA
  199.     SUI    05H        ;SUBTRACT FIVE
  200.     JMP    ETA        ;AND TRY AGAIN
  201. ;
  202. ;    ITS A 9=IX, 90=XC, OR 900=CM:
  203. ;
  204. NINE:    LDAX    D        ;GET ROMAN CHARACTER I, X OR C
  205.     CALL    STOR        ;AND STORE IT
  206.     INX    D        ;MOVE
  207.     INX    D        ;POINTER
  208.     LDAX    D        ;GET ROMAN CHARACTER X, C OR M
  209.     CALL    STOR        ;AND STORE THAT
  210.     DCX    D        ;RESTORE
  211.     DCX    D        ;POINTER
  212.     JMP    ETB        ;AND EXIT
  213. ;
  214. ;
  215. ;    STORE ROMAN CHARACTER IN RBUF FOR OUTPUT:
  216. ;
  217. STOR:    MOV    M,A        ;STORE DATA IN BUFFER
  218.     INX    H        ;AND MOVE POINTER
  219.     RET
  220. ;
  221. ;    ROMAN OUTPUT TO CONSOLE:
  222. è;
  223. ROUT:    LXI    H,RBUF        ;POINT TO ROMAN BUFFER
  224.     CALL    PRINT        ;AND OUTPUT IT
  225.     RET
  226. ;
  227. *  PRINT STRING ENDING IN 0 PTED TO BY H & L
  228. PRINT:    MOV    A,M    ; GET BYTE
  229.     INX    H    ; PT TO NEXT
  230.     CPI    '$'    ; DONE?
  231.         RZ
  232.     CALL    COUT    ; PRINT IT
  233.     JMP    PRINT
  234.  
  235. *  PRINT CHAR IN REG A ON CONSOLE
  236. COUT:   PUSH    A
  237.     PUSH    H    ; SAVE REGS
  238.     PUSH    D
  239.     PUSH    B
  240.     MOV    E,A
  241.     MVI    C,2    ; CONSOLE OUTPUT
  242.     CALL    BDOS
  243.     POP    B    ; RESTORE REGS
  244.     POP    D
  245.     POP    H
  246.         POP     A
  247.     RET
  248.  
  249. ;
  250.     END
  251.