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èRDY:    CALL    RDYM        ;PRODUCE READY MESSAGE, AND SET UP
  57.     CALL    INPUT        ;GET DATA
  58.     JC    RDY        ;IF IT IS VALID
  59.     CALL    ENC        ;ENCODE AND OUTPUT IT
  60.     JMP    RDY
  61. ;
  62. ;    READY MESSAGE AND SETTING UP:
  63. ;
  64. RDYM:    LXI    H,RDM        ;POINT TO READY MESSAGE
  65.     CALL    PRINT        ;AND OUTPUT IT
  66.     LXI    B,DBUF        ;PREPARE DECIMAL POINTER
  67.     LXI    H,DCNT        ;AND COUNT POINTER
  68.     MVI    M,00H        ;CLEAR COUNTER
  69.     RET
  70. ;
  71. ;    GET INPUT FROM CONSOLE INTO DBUF, CHECKING VALIDITY:
  72. ;
  73. INPUT:  PUSH    H
  74.     PUSH    D
  75.     PUSH    B
  76.     MVI    C,1
  77.     CALL    BDOS        ;IF CHARACTER
  78.         POP    B
  79.     POP    D
  80.     POP     H
  81.         ANI    7FH        ;STRIP PARITY
  82.     CPI    03H        ;IF IT IS EXIT CMD
  83.     JZ    EXIT        ;THEN GO
  84.     CPI    0DH        ;IF IT IS 'CR'
  85.     JNZ    ECHO        ;THEN
  86.         LXI     H,CRLF
  87.         CALL    PRINT
  88.     MVI    A,20H        ;LOAD 'SPACE'     
  89.         CALL    COUT            ;AND OUTPUT IT
  90.         MVI     A,'='
  91.     CALL    COUT        
  92.         MVI     A,SPACE
  93.         CALL    COUT
  94.     MVI    A,'$'        ;MARK END
  95.     STAX    B        ;OF DATA
  96.     ORA    A        ;CLEAR FLAG
  97.     RET
  98. ;
  99. EXIT:    LHLD    STK
  100.     SPHL
  101.     RET
  102. ;
  103. ECHO:    ;CALL    COUT        ;ECHO CHARACTER
  104.     CPI    '0'        ;IF IT IS ZERO OR MORE
  105.     JM    INVCH        ;AND
  106.     CPI    ':'        ;IF IT IS NINE OR LESS
  107.     JP    INVCH        ;THEN IT IS VALID CHARACTER
  108.     INR    M        ;SO COUNT IT
  109.     STAX    B        ;AND STORE IT
  110.     INX    B        ;ADVANCE POINTERè    MOV    A,M        ;CHECK COUNT
  111.     CPI    05H        ;IF IT IS LESS THAN FIVE
  112.     JM    INPUT        ;THEN CONTINUE
  113.     LXI    H,TOOL        ;ELSE POINT TO 'TOO LARGE'
  114.     JMP    MES
  115. ;
  116. INVCH:    LXI    H,INV        ;POINT TO 'INVALID CHARACTER'
  117. MES:    CALL    PRINT        ;AND OUTPUT IT
  118.     STC            ;SET ERROR FLAG
  119.     RET
  120. ;
  121. ;
  122. ;
  123. ;    PREPARE TO ENCODE:
  124. ;
  125. ENC:    LXI    B,DBUF        ;PREPARE DECIMAL POINTER
  126.     LXI    D,LIST        ;PREPARE LIST POINTER
  127.     LXI    H,DCNT        ;PREPARE COUNT POINTER
  128.     MOV    A,M        ;GET COUNT
  129.     CPI    04H        ;IF IT IS NOT FOUR
  130.     JNZ    CONT        ;CONTINUE
  131.     LDAX    B        ;ELSE GET FIRST CHARACTER
  132.     CPI    34H        ;IF IT IS NOT FOUR
  133.     JM    CONT        ;CONTINUE
  134.     LXI    H,TOOL        ;ELSE LOAD 'TOO LARGE'
  135.     CALL    PRINT        ;AND OUTPUT IT
  136.     RET
  137. ;
  138. CONT:    MOV    L,M        ;GET COUNT
  139.     MVI    H,00H        ;INTO HL
  140.     DAD    H        ;DOUBLE IT
  141.     DAD    D        ;ADD TO LIST
  142.     XCHG            ;AND RESTORE LIST
  143.     LXI    H,RBUF        ;PREPARE ROMAN POINTER
  144. ;
  145. ;    ENCODE CHARACTER STREAM IN DBUF:
  146. ;
  147. ENCA:    LDAX    B        ;GET A CHARACTER
  148.     INX    B        ;UPDATE THE POINTER
  149.     CPI    '$'        ;IF IT IS NOT "END MARKER"
  150.     RZ            ;THEN
  151.     CPI    '9'        ;IF IT IS NOT A NINE
  152.     JZ    NINE        ;THEN
  153.     CPI    '5'        ;IF IT IS NOT FIVE OR MORE
  154.     JP    FIVE        ;THEN
  155.     CPI    '4'        ;IF IT IS NOT FOUR
  156.     JZ    FOUR        ;THEN
  157. ETA:    CPI    '0'        ;IF IT IS ZERO
  158.     JNZ    ONE        ;THEN
  159. ETB:    DCX    D        ;MODIFY ROMAN POINTER
  160.     DCX    D        ;TWICE
  161.     LDA    DCNT        ;REDUCE COUNT
  162.     DCR    A        ;AND
  163.     STA    DCNT        ;IF IT IS NOT ZERO
  164.     JNZ    ENCA        ;THEN LOOPè    MVI    A,'$'        ;ELSE MARK END
  165.     CALL    STOR        ;AND STORE IT
  166.     JMP    ROUT        ;ENCODE COMPLETED
  167. ;
  168. ;
  169. ;    ITS A 1=I, 10=X, 100=C, 1000=M OR MORE:
  170. ;
  171. ONE:    PUSH    PSW        ;SAVE DATA
  172.     LDAX    D        ;LOAD ROMAN CHARACTER
  173.     CALL    STOR        ;AND STORE IT
  174.     POP    PSW        ;UNSAVE DATA
  175.     DCR    A        ;SUBTRACT ONE
  176.     JMP    ETA        ;AND TRY AGAIN
  177. ;
  178. ;    ITS A 4=IV, 40=XL, 400=CD:
  179. ;
  180. FOUR:    LDAX    D        ;LOAD ROMAN CHARACTER I, X OR C
  181.     CALL    STOR        ;AND STORE IT
  182.     INX    D        ;GET NEXT
  183.     LDAX    D        ;ROMAN CHARACTER V, L OR D
  184.     CALL    STOR        ;AND STORE THAT
  185.     DCX    D        ;RESTORE POINTER
  186.     JMP    ETB        ;AND EXIT
  187. ;
  188. ;    ITS A 5=V, 50=L, 500=D OR MORE:
  189. ;
  190. FIVE:    PUSH    PSW        ;SAVE DATA
  191.     INX    D        ;PREPARE POINTER
  192.     LDAX    D        ;GET ROMAN CHARACTER V, L OR D
  193.     CALL    STOR        ;AND STORE IT
  194.     DCX    D        ;RESTORE POINTER
  195.     POP    PSW        ;AND DATA
  196.     SUI    05H        ;SUBTRACT FIVE
  197.     JMP    ETA        ;AND TRY AGAIN
  198. ;
  199. ;    ITS A 9=IX, 90=XC, OR 900=CM:
  200. ;
  201. NINE:    LDAX    D        ;GET ROMAN CHARACTER I, X OR C
  202.     CALL    STOR        ;AND STORE IT
  203.     INX    D        ;MOVE
  204.     INX    D        ;POINTER
  205.     LDAX    D        ;GET ROMAN CHARACTER X, C OR M
  206.     CALL    STOR        ;AND STORE THAT
  207.     DCX    D        ;RESTORE
  208.     DCX    D        ;POINTER
  209.     JMP    ETB        ;AND EXIT
  210. ;
  211. ;
  212. ;    STORE ROMAN CHARACTER IN RBUF FOR OUTPUT:
  213. ;
  214. STOR:    MOV    M,A        ;STORE DATA IN BUFFER
  215.     INX    H        ;AND MOVE POINTER
  216.     RET
  217. ;
  218. ;    ROMAN OUTPUT TO CONSOLE:è;
  219. ROUT:    LXI    H,RBUF        ;POINT TO ROMAN BUFFER
  220.     CALL    PRINT        ;AND OUTPUT IT
  221.     RET
  222. ;
  223. *  PRINT STRING ENDING IN 0 PTED TO BY H & L
  224. PRINT:    MOV    A,M    ; GET BYTE
  225.     INX    H    ; PT TO NEXT
  226.     CPI    '$'    ; DONE?
  227.         RZ
  228.     CALL    COUT    ; PRINT IT
  229.     JMP    PRINT
  230.  
  231. *  PRINT CHAR IN REG A ON CONSOLE
  232. COUT:   PUSH    A
  233.     PUSH    H    ; SAVE REGS
  234.     PUSH    D
  235.     PUSH    B
  236.     MOV    E,A
  237.     MVI    C,2    ; CONSOLE OUTPUT
  238.     CALL    BDOS
  239.     POP    B    ; RESTORE REGS
  240.     POP    D
  241.     POP    H
  242.         POP     A
  243.     RET
  244.  
  245. ;
  246.     END
  247.