Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
10 saved 1 decle
source | link

CP-1610 assembly (Intellivision),  52 50 49 ... 48  4847 DECLEs1 = 6059 bytes

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            SDBD                    ; R5 = pointer into test case index
4802            MVII    #ndx,     R5
4805            MVII    #$214,    R3    ; R3 = backtab pointer
4807            MVII    #11,      R0    ; R0 = number of test cases

4809  loop      SDBD                    ; R4 = pointer to next test case
480A            MVI@    R5,       R4
480B            PSHR    R0              ; save R0, R3, R5 onto the stack
480C            PSHR    R3
480D            PSHR    R5
480E            CALL    isRoman         ; invoke our routine
4811            PULR    R5              ; restore R5 and R3
4812            PULR    R3

4813            MVII    #$1A7,    R0    ; use a white 'T' by default
4815            BEQ     disp

4817            MVII    #$137,    R0    ; or a white 'F' is the Z flag was cleared

4819  disp      MVO@    R0,       R3    ; draw it
481A            INCR    R3              ; increment the backtab pointer

481B            PULR    R0              ; restore R0
481C            DECR    R0              ; and goadvance to the next test case, if any
481D            BNEQ    loop

481F            DECR    R7              ; loop forever

                ;; ------------------------------------------------------------- ;;
                ;;  test cases                                                   ;;
                ;; ------------------------------------------------------------- ;;
4820  ndx       BIDECLE test0, test1, test2, test3
4828            BIDECLE test4, test5, test6, test7, test8, test9, test10

                ; truthy
4836  test0     STRING  "MCCXXXIV", 0
483F  test1     STRING  "CMLXXXVIII", 0
484A  test2     STRING  "DXIV", 0
484F  test3     STRING  "CI", 0

                ; falsy
4852  test4     STRING  "MMIXVIII", 0
485B  test5     STRING  "IVX", 0
485F  test6     STRING  "IXV", 0
4863  test7     STRING  "MMMM", 0
4868  test8     STRING  "XXXVX", 0
486E  test9     STRING  "IVI", 0
4872  test10    STRING  "VIV", 0

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      isRoman   PROC

4876            PSHR    R5              ; push the return address

4877            MOVR    R7,       R2    ; R2 = dummy 1st suffix
4878            MOVR    R2,       R5    ; R5 = pointer into table
4879            ADDI    #@tbl-$+1,R5

487B  @loop     MVI@    R5,       R1    ; R1 = main digit (M, C, X, I)
487C            MVI@    R5,       R3    ; R3 = prefix or 2nd suffix (-, D, L, V)

487D            MVI@    R4,       R0    ; R0 = next digit

487E            CMPR    R0,       R3    ; if this is the prefix ...
487F            BNEQ    @main

4881            COMR    R2              ; ... disable the suffixes
4882            COMR    R3              ; by setting them to invalid values
4883            MVI@    R4,       R0    ; and read R0 again

4884  @main     CMPR    R0,       R1    ; if R0 is not equal to the main digit,
4885            BNEQ    @back           ; assume that this part is over

4887            MVI@    R4,       R0    ; R0 = next digit
4888            CMPR    R0,       R1    ; if this is a 2nd occurrence
4889            BNEQ    @suffix         ; of the main digit ...

488B            CMP@    R4,       R1    ; ... it may be followed by a 3rd occurrence
488C            BEQ     @next
488E            B   BNEQ    @back

4890488E  @suffix   CMPR    R0,   MOVR    R2    ; otherwise, it may be either the 1st suffix
4891            BEQ     @next
4893            CMPR    R0,       R3    ; or the 2nd suffix
4894          if so, BEQforce the test below to @nextsucceed

4896488F  @back@suffix   CMPR  DECR  R0,  R4     R2    ; otherwise, it may be ;either the last1st digitsuffix
4890 belongs to the next iteration       BEQ     @next
4892            CMPR    R0,       R3    ; or the 2nd suffix (these tests always fail
4893            BEQ     @next           ; (orif isthe invalidsuffixes were disabled above)

48974895  @back     DECR    R4              ; the last digit either belongs to the next
                                        ; iteration or is invalid

4896  @next     MOVR    R1,       R2    ; use the current main digit
                                        ; as the next 1st suffix

48984897            SUBI    #'I',     R1    ; was it the last iteration? ...
489A4899            BNEQ    @loop

489C489B            CMP@    R4,       R1    ; ... yes: make sure that we've also reached
                                        ; the end of the input

489D489C            PULR    R7              ; return

489E489D  @tbl      DECLE   'M', '-'        ; table format: main digit, 2nd suffix
48A0489F            DECLE   'C', 'D'
48A248A1            DECLE   'X', 'L'
48A448A3            DECLE   'I', 'V'

                ENDP

1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 4847 DECLEs long, starting at $4876 and ending at $48A5$48A4 (included).

CP-1610 assembly (Intellivision),  52 50 49  48 DECLEs1 = 60 bytes

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            SDBD                    ; R5 = pointer into test case index
4802            MVII    #ndx,     R5
4805            MVII    #$214,    R3    ; R3 = backtab pointer
4807            MVII    #11,      R0    ; R0 = number of test cases

4809  loop      SDBD                    ; R4 = pointer to next test case
480A            MVI@    R5,       R4
480B            PSHR    R0              ; save R0, R3, R5 onto the stack
480C            PSHR    R3
480D            PSHR    R5
480E            CALL    isRoman         ; invoke our routine
4811            PULR    R5              ; restore R5 and R3
4812            PULR    R3

4813            MVII    #$1A7,    R0    ; use a white 'T' by default
4815            BEQ     disp

4817            MVII    #$137,    R0    ; or a white 'F' is the Z flag was cleared

4819  disp      MVO@    R0,       R3    ; draw it
481A            INCR    R3              ; increment the backtab pointer

481B            PULR    R0              ; restore R0
481C            DECR    R0              ; and go to the next test case, if any
481D            BNEQ    loop

481F            DECR    R7              ; loop forever

4820  ndx       BIDECLE test0, test1, test2, test3
4828            BIDECLE test4, test5, test6, test7, test8, test9, test10

                ; truthy
4836  test0     STRING  "MCCXXXIV", 0
483F  test1     STRING  "CMLXXXVIII", 0
484A  test2     STRING  "DXIV", 0
484F  test3     STRING  "CI", 0

                ; falsy
4852  test4     STRING  "MMIXVIII", 0
485B  test5     STRING  "IVX", 0
485F  test6     STRING  "IXV", 0
4863  test7     STRING  "MMMM", 0
4868  test8     STRING  "XXXVX", 0
486E  test9     STRING  "IVI", 0
4872  test10    STRING  "VIV", 0

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      isRoman   PROC

4876            PSHR    R5              ; push the return address

4877            MOVR    R7,       R2    ; R2 = dummy 1st suffix
4878            MOVR    R2,       R5    ; R5 = pointer into table
4879            ADDI    #@tbl-$+1,R5

487B  @loop     MVI@    R5,       R1    ; R1 = main digit (M, C, X, I)
487C            MVI@    R5,       R3    ; R3 = prefix or 2nd suffix (-, D, L, V)

487D            MVI@    R4,       R0    ; R0 = next digit

487E            CMPR    R0,       R3    ; if this is the prefix ...
487F            BNEQ    @main

4881            COMR    R2              ; ... disable the suffixes
4882            COMR    R3              ; by setting them to invalid values
4883            MVI@    R4,       R0    ; and read R0 again

4884  @main     CMPR    R0,       R1    ; if R0 is not equal to the main digit,
4885            BNEQ    @back           ; assume that this part is over

4887            MVI@    R4,       R0    ; R0 = next digit
4888            CMPR    R0,       R1    ; if this is a 2nd occurrence
4889            BNEQ    @suffix         ; of the main digit ...

488B            CMP@    R4,       R1    ; ... it may be followed by a 3rd occurrence
488C            BEQ     @next
488E            B       @back

4890  @suffix   CMPR    R0,       R2    ; otherwise, it may be either the 1st suffix
4891            BEQ     @next
4893            CMPR    R0,       R3    ; or the 2nd suffix
4894            BEQ     @next

4896  @back     DECR    R4              ; the last digit belongs to the next iteration
                                        ; (or is invalid)

4897  @next     MOVR    R1,       R2    ; use the current main digit
                                        ; as the next 1st suffix

4898            SUBI    #'I',     R1    ; was it the last iteration? ...
489A            BNEQ    @loop

489C            CMP@    R4,       R1    ; ... yes: make sure that we've also reached
                                        ; the end of the input

489D            PULR    R7              ; return

489E  @tbl      DECLE   'M', '-'        ; table format: main digit, 2nd suffix
48A0            DECLE   'C', 'D'
48A2            DECLE   'X', 'L'
48A4            DECLE   'I', 'V'

                ENDP

1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 48 DECLEs long, starting at $4876 and ending at $48A5 (included).

CP-1610 assembly (Intellivision),  52 ... 48  47 DECLEs1 = 59 bytes

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            SDBD                    ; R5 = pointer into test case index
4802            MVII    #ndx,     R5
4805            MVII    #$214,    R3    ; R3 = backtab pointer
4807            MVII    #11,      R0    ; R0 = number of test cases

4809  loop      SDBD                    ; R4 = pointer to next test case
480A            MVI@    R5,       R4
480B            PSHR    R0              ; save R0, R3, R5 onto the stack
480C            PSHR    R3
480D            PSHR    R5
480E            CALL    isRoman         ; invoke our routine
4811            PULR    R5              ; restore R5 and R3
4812            PULR    R3

4813            MVII    #$1A7,    R0    ; use a white 'T' by default
4815            BEQ     disp

4817            MVII    #$137,    R0    ; or a white 'F' is the Z flag was cleared

4819  disp      MVO@    R0,       R3    ; draw it
481A            INCR    R3              ; increment the backtab pointer

481B            PULR    R0              ; restore R0
481C            DECR    R0              ; and advance to the next test case, if any
481D            BNEQ    loop

481F            DECR    R7              ; loop forever

                ;; ------------------------------------------------------------- ;;
                ;;  test cases                                                   ;;
                ;; ------------------------------------------------------------- ;;
4820  ndx       BIDECLE test0, test1, test2, test3
4828            BIDECLE test4, test5, test6, test7, test8, test9, test10

                ; truthy
4836  test0     STRING  "MCCXXXIV", 0
483F  test1     STRING  "CMLXXXVIII", 0
484A  test2     STRING  "DXIV", 0
484F  test3     STRING  "CI", 0

                ; falsy
4852  test4     STRING  "MMIXVIII", 0
485B  test5     STRING  "IVX", 0
485F  test6     STRING  "IXV", 0
4863  test7     STRING  "MMMM", 0
4868  test8     STRING  "XXXVX", 0
486E  test9     STRING  "IVI", 0
4872  test10    STRING  "VIV", 0

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      isRoman   PROC

4876            PSHR    R5              ; push the return address

4877            MOVR    R7,       R2    ; R2 = dummy 1st suffix
4878            MOVR    R2,       R5    ; R5 = pointer into table
4879            ADDI    #@tbl-$+1,R5

487B  @loop     MVI@    R5,       R1    ; R1 = main digit (M, C, X, I)
487C            MVI@    R5,       R3    ; R3 = prefix or 2nd suffix (-, D, L, V)

487D            MVI@    R4,       R0    ; R0 = next digit

487E            CMPR    R0,       R3    ; if this is the prefix ...
487F            BNEQ    @main

4881            COMR    R2              ; ... disable the suffixes
4882            COMR    R3              ; by setting them to invalid values
4883            MVI@    R4,       R0    ; and read R0 again

4884  @main     CMPR    R0,       R1    ; if R0 is not equal to the main digit,
4885            BNEQ    @back           ; assume that this part is over

4887            MVI@    R4,       R0    ; R0 = next digit
4888            CMPR    R0,       R1    ; if this is a 2nd occurrence
4889            BNEQ    @suffix         ; of the main digit ...

488B            CMP@    R4,       R1    ; ... it may be followed by a 3rd occurrence
488C            BNEQ    @back

488E            MOVR    R2,       R0    ; if so, force the test below to succeed

488F  @suffix   CMPR    R0,       R2    ; otherwise, it may be either the 1st suffix
4890            BEQ     @next
4892            CMPR    R0,       R3    ; or the 2nd suffix (these tests always fail
4893            BEQ     @next           ; if the suffixes were disabled above)

4895  @back     DECR    R4              ; the last digit either belongs to the next
                                        ; iteration or is invalid

4896  @next     MOVR    R1,       R2    ; use the current main digit
                                        ; as the next 1st suffix

4897            SUBI    #'I',     R1    ; was it the last iteration? ...
4899            BNEQ    @loop

489B            CMP@    R4,       R1    ; ... yes: make sure that we've also reached
                                        ; the end of the input

489C            PULR    R7              ; return

489D  @tbl      DECLE   'M', '-'        ; table format: main digit, 2nd suffix
489F            DECLE   'C', 'D'
48A1            DECLE   'X', 'L'
48A3            DECLE   'I', 'V'

                ENDP

1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 47 DECLEs long, starting at $4876 and ending at $48A4 (included).

9 saved 1 decle
source | link

CP-1610 assembly (Intellivision),  52 50 50 49  4948 DECLEs1 = 6260 bytes

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            SDBD                    ; R5 = pointer into test case index
4802            MVII    #ndx,     R5
4805            MVII    #$214,    R3    ; R3 = backtab pointer
4807            MVII    #11,      R0    ; R0 = number of test cases

4809  loop      SDBD                    ; R4 = pointer to next test case
480A            MVI@    R5,       R4
480B            PSHR    R0              ; save R0, R3, R5 onto the stack
480C            PSHR    R3
480D            PSHR    R5
480E            CALL    isRoman         ; invoke our routine
4811            PULR    R5              ; restore R5 and R3
4812            PULR    R3

4813            MVII    #$1A7,    R0    ; use a white 'T' by default
4815            BEQ     disp

4817            MVII    #$137,    R0    ; or a white 'F' is the Z flag was cleared

4819  disp      MVO@    R0,       R3    ; draw it
481A            INCR    R3              ; increment the backtab pointer

481B            PULR    R0              ; restore R0
481C            DECR    R0              ; and go to the next test case, if any
481D            BNEQ    loop

481F            DECR    R7              ; loop forever

4820  ndx       BIDECLE test0, test1, test2, test3
4828            BIDECLE test4, test5, test6, test7, test8, test9, test10

                ; truthy
4836  test0     STRING  "MCCXXXIV", 0
483F  test1     STRING  "CMLXXXVIII", 0
484A  test2     STRING  "DXIV", 0
484F  test3     STRING  "CI", 0

                ; falsy
4852  test4     STRING  "MMIXVIII", 0
485B  test5     STRING  "IVX", 0
485F  test6     STRING  "IXV", 0
4863  test7     STRING  "MMMM", 0
4868  test8     STRING  "XXXVX", 0
486E  test9     STRING  "IVI", 0
4872  test10    STRING  "VIV", 0

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      isRoman   PROC

4876            PSHR    R5              ; push the return address

4877            MOVR    R7,       R2    ; R2 = dummy 1st suffix
4878            SDBD     MOVR    R2,       R5    ; R5 = pointer into table
4879            MVIIADDI    #@digits#@tbl-$+1, R5

487C487B  @loop     MVI@    R5,       R1    ; R1 = main digit (M, C, X, I)
487D487C            MVI@    R5,       R3    ; R3 = prefix or 2nd suffix (-, D, L, V)

487E487D            MVI@    R4,       R0    ; R0 = next digit

487F487E            CMPR    R0,       R3    ; if this is the prefix ...
4880487F            BNEQ    @main

48824881            COMR    R2              ; ... disable the suffixes
48834882            COMR    R3              ; by setting them to invalid values
48844883            MVI@    R4,       R0    ; and read R0 again

48854884  @main     CMPR    R0,       R1    ; if R0 is not equal to the main digit,
48864885            BNEQ    @back           ; assume that this part is over

48884887            MVI@    R4,       R0    ; R0 = next digit
48894888            CMPR    R0,       R1    ; if this is a 2nd occurrence
488A4889            BNEQ    @suffix         ; of the main digit ...

488C488B            CMP@    R4,       R1    ; ... it may be followed by a 3rd occurrence
488D488C            BEQ     @next
488F488E            B       @back

48914890  @suffix   CMPR    R0,       R2    ; otherwise, it may be either the 1st suffix
48924891            BEQ     @next
48944893            CMPR    R0,       R3    ; or the 2nd suffix
48954894            BEQ     @next

48974896  @back     DECR    R4              ; the last digit belongs to the next iteration
                                        ; (or is invalid)

48984897  @next     MOVR    R1,       R2    ; use the current main digit
                                        ; as the next 1st suffix

48994898            SUBI    #'I',     R1    ; was it the last iteration? ...
489B489A            BNEQ    @loop

489D489C            CMP@    R4,       R1    ; ... yes: make sure that we've also reached
                                        ; the end of the input

489E489D            PULR    R7              ; return

489F489E  @digits@tbl      DECLE   'M', '-'        ; table format: main digit, 2nd suffix
48A148A0            DECLE   'C', 'D'
48A348A2            DECLE   'X', 'L'
48A548A4            DECLE   'I', 'V'

                ENDP

1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 4948 DECLEs long, starting at $4876 and ending at $48A6$48A5 (included).

CP-1610 assembly (Intellivision),  52 50  49 DECLEs1 = 62 bytes

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            SDBD                    ; R5 = pointer into test case index
4802            MVII    #ndx,     R5
4805            MVII    #$214,    R3    ; R3 = backtab pointer
4807            MVII    #11,      R0    ; R0 = number of test cases

4809  loop      SDBD                    ; R4 = pointer to next test case
480A            MVI@    R5,       R4
480B            PSHR    R0              ; save R0, R3, R5 onto the stack
480C            PSHR    R3
480D            PSHR    R5
480E            CALL    isRoman         ; invoke our routine
4811            PULR    R5              ; restore R5 and R3
4812            PULR    R3

4813            MVII    #$1A7,    R0    ; use a white 'T' by default
4815            BEQ     disp

4817            MVII    #$137,    R0    ; or a white 'F' is the Z flag was cleared

4819  disp      MVO@    R0,       R3    ; draw it
481A            INCR    R3              ; increment the backtab pointer

481B            PULR    R0              ; restore R0
481C            DECR    R0              ; and go to the next test case, if any
481D            BNEQ    loop

481F            DECR    R7              ; loop forever

4820  ndx       BIDECLE test0, test1, test2, test3
4828            BIDECLE test4, test5, test6, test7, test8, test9, test10

                ; truthy
4836  test0     STRING  "MCCXXXIV", 0
483F  test1     STRING  "CMLXXXVIII", 0
484A  test2     STRING  "DXIV", 0
484F  test3     STRING  "CI", 0

                ; falsy
4852  test4     STRING  "MMIXVIII", 0
485B  test5     STRING  "IVX", 0
485F  test6     STRING  "IXV", 0
4863  test7     STRING  "MMMM", 0
4868  test8     STRING  "XXXVX", 0
486E  test9     STRING  "IVI", 0
4872  test10    STRING  "VIV", 0

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      isRoman   PROC

4876            PSHR    R5              ; push the return address

4877            MOVR    R7,       R2    ; R2 = dummy 1st suffix
4878            SDBD                    ; R5 = pointer into table
4879            MVII    #@digits, R5

487C  @loop     MVI@    R5,       R1    ; R1 = main digit (M, C, X, I)
487D            MVI@    R5,       R3    ; R3 = prefix or 2nd suffix (-, D, L, V)

487E            MVI@    R4,       R0    ; R0 = next digit

487F            CMPR    R0,       R3    ; if this is the prefix ...
4880            BNEQ    @main

4882            COMR    R2              ; ... disable the suffixes
4883            COMR    R3              ; by setting them to invalid values
4884            MVI@    R4,       R0    ; and read R0 again

4885  @main     CMPR    R0,       R1    ; if R0 is not equal to the main digit,
4886            BNEQ    @back           ; assume that this part is over

4888            MVI@    R4,       R0    ; R0 = next digit
4889            CMPR    R0,       R1    ; if this is a 2nd occurrence
488A            BNEQ    @suffix         ; of the main digit ...

488C            CMP@    R4,       R1    ; ... it may be followed by a 3rd occurrence
488D            BEQ     @next
488F            B       @back

4891  @suffix   CMPR    R0,       R2    ; otherwise, it may be either the 1st suffix
4892            BEQ     @next
4894            CMPR    R0,       R3    ; or the 2nd suffix
4895            BEQ     @next

4897  @back     DECR    R4              ; the last digit belongs to the next iteration
                                        ; (or is invalid)

4898  @next     MOVR    R1,       R2    ; use the current main digit
                                        ; as the next 1st suffix

4899            SUBI    #'I',     R1    ; was it the last iteration? ...
489B            BNEQ    @loop

489D            CMP@    R4,       R1    ; ... yes: make sure that we've also reached
                                        ; the end of the input

489E            PULR    R7              ; return

489F  @digits   DECLE   'M', '-'        ; table format: main digit, 2nd suffix
48A1            DECLE   'C', 'D'
48A3            DECLE   'X', 'L'
48A5            DECLE   'I', 'V'

                ENDP

1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 49 DECLEs long, starting at $4876 and ending at $48A6 (included).

CP-1610 assembly (Intellivision),  52 50 49  48 DECLEs1 = 60 bytes

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            SDBD                    ; R5 = pointer into test case index
4802            MVII    #ndx,     R5
4805            MVII    #$214,    R3    ; R3 = backtab pointer
4807            MVII    #11,      R0    ; R0 = number of test cases

4809  loop      SDBD                    ; R4 = pointer to next test case
480A            MVI@    R5,       R4
480B            PSHR    R0              ; save R0, R3, R5 onto the stack
480C            PSHR    R3
480D            PSHR    R5
480E            CALL    isRoman         ; invoke our routine
4811            PULR    R5              ; restore R5 and R3
4812            PULR    R3

4813            MVII    #$1A7,    R0    ; use a white 'T' by default
4815            BEQ     disp

4817            MVII    #$137,    R0    ; or a white 'F' is the Z flag was cleared

4819  disp      MVO@    R0,       R3    ; draw it
481A            INCR    R3              ; increment the backtab pointer

481B            PULR    R0              ; restore R0
481C            DECR    R0              ; and go to the next test case, if any
481D            BNEQ    loop

481F            DECR    R7              ; loop forever

4820  ndx       BIDECLE test0, test1, test2, test3
4828            BIDECLE test4, test5, test6, test7, test8, test9, test10

                ; truthy
4836  test0     STRING  "MCCXXXIV", 0
483F  test1     STRING  "CMLXXXVIII", 0
484A  test2     STRING  "DXIV", 0
484F  test3     STRING  "CI", 0

                ; falsy
4852  test4     STRING  "MMIXVIII", 0
485B  test5     STRING  "IVX", 0
485F  test6     STRING  "IXV", 0
4863  test7     STRING  "MMMM", 0
4868  test8     STRING  "XXXVX", 0
486E  test9     STRING  "IVI", 0
4872  test10    STRING  "VIV", 0

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      isRoman   PROC

4876            PSHR    R5              ; push the return address

4877            MOVR    R7,       R2    ; R2 = dummy 1st suffix
4878            MOVR    R2,       R5    ; R5 = pointer into table
4879            ADDI    #@tbl-$+1,R5

487B  @loop     MVI@    R5,       R1    ; R1 = main digit (M, C, X, I)
487C            MVI@    R5,       R3    ; R3 = prefix or 2nd suffix (-, D, L, V)

487D            MVI@    R4,       R0    ; R0 = next digit

487E            CMPR    R0,       R3    ; if this is the prefix ...
487F            BNEQ    @main

4881            COMR    R2              ; ... disable the suffixes
4882            COMR    R3              ; by setting them to invalid values
4883            MVI@    R4,       R0    ; and read R0 again

4884  @main     CMPR    R0,       R1    ; if R0 is not equal to the main digit,
4885            BNEQ    @back           ; assume that this part is over

4887            MVI@    R4,       R0    ; R0 = next digit
4888            CMPR    R0,       R1    ; if this is a 2nd occurrence
4889            BNEQ    @suffix         ; of the main digit ...

488B            CMP@    R4,       R1    ; ... it may be followed by a 3rd occurrence
488C            BEQ     @next
488E            B       @back

4890  @suffix   CMPR    R0,       R2    ; otherwise, it may be either the 1st suffix
4891            BEQ     @next
4893            CMPR    R0,       R3    ; or the 2nd suffix
4894            BEQ     @next

4896  @back     DECR    R4              ; the last digit belongs to the next iteration
                                        ; (or is invalid)

4897  @next     MOVR    R1,       R2    ; use the current main digit
                                        ; as the next 1st suffix

4898            SUBI    #'I',     R1    ; was it the last iteration? ...
489A            BNEQ    @loop

489C            CMP@    R4,       R1    ; ... yes: make sure that we've also reached
                                        ; the end of the input

489D            PULR    R7              ; return

489E  @tbl      DECLE   'M', '-'        ; table format: main digit, 2nd suffix
48A0            DECLE   'C', 'D'
48A2            DECLE   'X', 'L'
48A4            DECLE   'I', 'V'

                ENDP

1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 48 DECLEs long, starting at $4876 and ending at $48A5 (included).

8 added an explanation
source | link

How?

The regular expression can be rewritten as 4 groups with the same structure, provided that # is any invalid character that is guaranteed not be present in the input string.

                 +-------+---> main digit
                 |       |
(M[##]|#?M{0,3})(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})
                   ||  |
                   |+--+-----> prefix or second suffix
                   |
                   +---------> first suffix

The first suffix of the group \$N\$ is the main digit of the group \$N-1\$. Therefore, we can store the patterns with the pair \$(\text{main_digit}, \text{second_suffix})\$ alone.

Our routine attempts to parse the input string character by character according to these patterns and eventually checks whether the end of the string is reached.

output

screenshot of jzIntv

output

How?

The regular expression can be rewritten as 4 groups with the same structure, provided that # is any invalid character that is guaranteed not be present in the input string.

                 +-------+---> main digit
                 |       |
(M[##]|#?M{0,3})(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})
                   ||  |
                   |+--+-----> prefix or second suffix
                   |
                   +---------> first suffix

The first suffix of the group \$N\$ is the main digit of the group \$N-1\$. Therefore, we can store the patterns with the pair \$(\text{main_digit}, \text{second_suffix})\$ alone.

Our routine attempts to parse the input string character by character according to these patterns and eventually checks whether the end of the string is reached.

output

screenshot of jzIntv

7 added the new test case
source | link
6 minor update
source | link
5 fixed a bug introduced in the last revision
source | link
4 saved 1 decle
source | link
3 saved 2 decles
source | link
2 improved source formatting
source | link
1
source | link