;Mini-Monitor.asm
;Disassembled by WinPHUNSY 30.2 at 20:49:59 on 30/8/2023
; (and by hand)
;Platform: PHUNSY
;Size:     512 bytes ($1E00..$1FFF)
;Disassembled by James Jacobs of Amigan Software in August-September 2023.

;User Equates-------------------------------------------------------------
BOOT              EQU $0000 ;code
INTERRUPT         EQU $001D ;code
RTDIGITS          EQU $1DF0 ;5th and 6th digits
MDDIGITS          EQU $1DF1 ;3rd and 4th digits
LTDIGITS          EQU $1DF2 ;1st and 2th digits
PTR_B             EQU $1DF3
PTR_H             EQU $1DF3
PTR_L             EQU $1DF4
NUMDIGITS         EQU $1DF4 ;bits 2..0 are number of digits
STORER0           EQU $1DF5
STORER1           EQU $1DF6
KEYBOARD_END2     EQU $1DF7 ;PPSL
STOREPSL          EQU $1DF8
KEYBOARD_END3     EQU $1DF9 ;RETE,un
PTR2_H            EQU $1DFA ;start address
PTR2_L            EQU $1DFB ;start address
PTR3_H            EQU $1DFC ;end   address
PTR3_L            EQU $1DFD ;end   address

        ORG     $1E00
  
;Subroutine INIT----------------------------------------------------------
INIT: ;$1E00
;*(RTDIGITS..LTDIGITS) = r1 = 0 ["00"];
;*(NUMDIGITS) = %11110,000;
;return;
        EORZ    r0                                       ;  6,1 $1E00 20       r0 = 0;
        STRR,r0 RTDIGITS                                 ;  9,2 $1E01 C8 6D    *(RTDIGITS) = r0;
        STRR,r0 MDDIGITS                                 ;  9,2 $1E03 C8 6C    *(MDDIGITS) = r0;
        STRR,r0 LTDIGITS                                 ;  9,2 $1E05 C8 6B    *(LTDIGITS) = r0;
        STRZ    r1                                       ;  6,1 $1E07 C1       r1 = r0;
        LODI,r0 $F0                                      ;  6,2 $1E08 04 F0    r0 = $F0;
        STRR,r0 NUMDIGITS                                ;  9,2 $1E0A C8 68    NUMDIGITS = r0;
        RETC,un                                          ;  9,1 $1E0C 17       return;
;End of Subroutine INIT---------------------------------------------------
;Subroutine DRAWSCREEN----------------------------------------------------
DRAWSCREEN: ;$1E0D
;*(IOPORT($10)) = *(RTDIGITS);
;*(IOPORT($11)) = *(MDDIGITS);
;*(IOPORT($12)) = *(LTDIGITS);
;*(IOPORT($13)) = *(NUMDIGITS) & %00000111;
;return;
        LODR,r0 RTDIGITS                                 ;  9,2 $1E0D 08 61    r0 = *(RTDIGITS);
        WRTE,r0 $10                                      ;  9,2 $1E0F D4 10    IOPORT($10) = r0;
        LODR,r0 MDDIGITS                                 ;  9,2 $1E11 08 5E    r0 = *(MDDIGITS);
        WRTE,r0 $11                                      ;  9,2 $1E13 D4 11    IOPORT($11) = r0;
        LODR,r0 LTDIGITS                                 ;  9,2 $1E15 08 5B    r0 = *(RTDIGITIS);
        WRTE,r0 $12                                      ;  9,2 $1E17 D4 12    IOPORT($12) = r0;
        LODR,r0 NUMDIGITS                                ;  9,2 $1E19 08 59    r0 = *(NUMDIGITS);
        ANDI,r0 $7                                       ;  6,2 $1E1B 44 07    r0 &= $7;
        WRTE,r0 $13                                      ;  9,2 $1E1D D4 13    IOPORT($13) = r0;
        RETC,un                                          ;  9,1 $1E1F 17       return;
;End of Subroutine DRAWSCREEN---------------------------------------------
;Subroutine MONOTONIC-----------------------------------------------------
MONOTONIC: ;$1E20
;*(MDDIGITS)++;
;if a carry was generated, *(RTDIGITS)++;
;if (*(RTDIGITS) >= 128)
;{   *(RTDIGITS) = 0;
;}
;if (*(RTDIGITS) == *(PTR3_H))
;{   r0 = *(MDDIGITS);
;    compare r0 against *(PTR3_L);
;}
;return CC;
        LODR,r0 MDDIGITS                                 ;  9,2 $1E20 08 4F    r0 = *(MDDIGITS);
        ADDI,r0 $1                                       ;  6,2 $1E22 84 01    r0++;
        STRR,r0 MDDIGITS                                 ;  9,2 $1E24 C8 4B    *(MDDIGITS) = r0;
        EORZ    r0                                       ;  6,1 $1E26 20       r0 = 0;
        PPSL    WC                                       ;  9,2 $1E27 77 08    PSL |= $8;
                                                                              ;Set WC (With Carry) bit
        ADDR,r0 RTDIGITS                                 ;  9,2 $1E29 88 45    r0 += *(RTDIGITS);
        CPSL    WC                                       ;  9,2 $1E2B 75 08    PSL &= ~($8);
                                                                              ;Clear WC (With Carry) bit
        BCFR,lt $1E30                                    ;  9,2 $1E2D 9A 01    if >= then goto $1E30;
        EORZ    r0                                       ;  6,1 $1E2F 20       r0 = 0;
        STRA,r0 RTDIGITS                                 ; 12,3 $1E30 CC 1D F0 *(RTDIGITS) = r0;
        COMR,r0 PTR3_H                                   ;  9,2 $1E33 E8 47    compare r0 against *(PTR3_H);
        BCFR,eq $1E3C                                    ;  9,2 $1E35 98 05    if != then goto $1E3C;
        LODA,r0 MDDIGITS                                 ; 12,3 $1E37 0C 1D F1 r0 = *(MDDIGITS);
        COMR,r0 PTR3_L                                   ;  9,2 $1E3A E8 41    compare r0 against *(PTR3_L);
        RETC,un                                          ;  9,1 $1E3C 17       return;
;End of Subroutine MONOTONIC----------------------------------------------
;Subroutine DUMPCASS------------------------------------------------------
DUMPCASS: ;$1E3D
;set Flag bit
;inhibit interrupts
;PSL = COM;
;gosub INIT;
;gosub DUMP1CHAR($50);
;*(RTDIGITS) = *(PTR2_H);
;gosub DUMP1CHAR(*(RTDIGITS));
;*(MDDIGITS) = *(PTR2_L);
;gosub DUMP1CHAR(*(MDDIGITS));
;gosub DUMP1CHAR(*(PTR3_H));
;gosub DUMP1CHAR(*(PTR3_L));
;for (;;)
;{   gosub DUMP1CHAR(r1);
;    gosub DRAWSCREEN;
;    do
;    {   gosub DUMP1CHAR(*(RTDIGITS));
;        gosub MONOTONIC;
;        if (CC == eq)
;        {   gosub DUMP1CHAR(*(MDDIGITS));
;            gosub DUMP1CHAR(r1);
;            *(LTDIGITS) = $AF ["AF"];
;            gosub DRAWSCREEN;
;            enable interrupts
;            return;
;        } // implied else
;        r0 = *(MDDIGITS);
;    } while (CC != eq);
;}
        PPSU    $60                                      ;  9,2 $1E3D 76 60    PSU |= $60 & %01100111;
                                                                              ;Set F (Flag) bit
                                                                              ;Set II (Interrupt Inhibit) bit (now inhibited)
        LODI,r0 $2                                       ;  6,2 $1E3F 04 02    r0 = $2 [STX];
        LPSL                                             ;  6,1 $1E41 93       PSL = r0;
        BSTA,un INIT                                     ;  9,3 $1E42 3F 1E 00 gosub INIT;
        LODI,r0 $50                                      ;  6,2 $1E45 04 50    r0 = $50 ['P'];
        BSTA,un DUMP1CHAR                                ;  9,3 $1E47 3F 1E 8C gosub DUMP1CHAR;
        LODA,r0 PTR2_H                                   ; 12,3 $1E4A 0C 1D FA r0 = *(PTR2_H);
        STRA,r0 RTDIGITS                                 ; 12,3 $1E4D CC 1D F0 *(RTDIGITS) = r0;
        BSTR,un DUMP1CHAR                                ;  9,2 $1E50 3B 3A    gosub DUMP1CHAR;
        LODA,r0 PTR2_L                                   ; 12,3 $1E52 0C 1D FB r0 = *(PTR2_L);
        STRA,r0 MDDIGITS                                 ; 12,3 $1E55 CC 1D F1 *(MDDIGITS) = r0;
        BSTR,un DUMP1CHAR                                ;  9,2 $1E58 3B 32    gosub DUMP1CHAR;
        LODA,r0 PTR3_H                                   ; 12,3 $1E5A 0C 1D FC r0 = *(PTR3_H);
        BSTR,un DUMP1CHAR                                ;  9,2 $1E5D 3B 2D    gosub DUMP1CHAR;
        LODA,r0 PTR3_L                                   ; 12,3 $1E5F 0C 1D FD r0 = *(PTR3_L);
        BSTR,un DUMP1CHAR                                ;  9,2 $1E62 3B 28    gosub DUMP1CHAR;
        LODZ    r1                                       ;  6,1 $1E64 01       r0 = r1;
        BSTR,un DUMP1CHAR                                ;  9,2 $1E65 3B 25    gosub DUMP1CHAR;
        BSTA,un DRAWSCREEN                               ;  9,3 $1E67 3F 1E 0D gosub DRAWSCREEN;
        LODA,r0 *RTDIGITS                                ; 18,3 $1E6A 0C 9D F0 r0 = *(*RTDIGITS);
        BSTR,un DUMP1CHAR                                ;  9,2 $1E6D 3B 1D    gosub DUMP1CHAR;
        BSTA,un MONOTONIC                                ;  9,3 $1E6F 3F 1E 20 gosub MONOTONIC;
        BCTR,eq $1E7B                                    ;  9,2 $1E72 18 07    if == then goto $1E7B;
        LODA,r0 MDDIGITS                                 ; 12,3 $1E74 0C 1D F1 r0 = *(MDDIGITS);
        BCTR,eq $1E64                                    ;  9,2 $1E77 18 6B    if == then goto $1E64;
        BCTR,un $1E6A                                    ;  9,2 $1E79 1B 6F    goto $1E6A;
        LODA,r0 *RTDIGITS                                ; 18,3 $1E7B 0C 9D F0 r0 = *(*RTDIGITS);
        BSTR,un DUMP1CHAR                                ;  9,2 $1E7E 3B 0C    gosub DUMP1CHAR;
        LODZ    r1                                       ;  6,1 $1E80 01       r0 = r1;
        BSTR,un DUMP1CHAR                                ;  9,2 $1E81 3B 09    gosub DUMP1CHAR;
        LODI,r0 $AF                                      ;  6,2 $1E83 04 AF    r0 = $AF ["AF"];
        STRA,r0 LTDIGITS                                 ; 12,3 $1E85 CC 1D F2 *(LTDIGITS) = r0;
        BSTA,un DRAWSCREEN                               ;  9,3 $1E88 3F 1E 0D gosub DRAWSCREEN;
        RETE,un                                          ;  9,1 $1E8B 37       PSU &= ~PSU_II; return;
;End of Subroutine DUMPCASS-----------------------------------------------
;Subroutine DUMP1CHAR-----------------------------------------------------
DUMP1CHAR: ;$1E8C
        BSTR,un $1EB8                                    ;  9,2 $1E8C 3B 2A    gosub $1EB8;
DUMP1CHAR_ALT: ;$1E8E
        PPSL    RS                                       ;  9,2 $1E8E 77 10    PSL |= $10;
                                                                              ;Set RS (Register Select) bit (now r4..r6)
        LODI,r4 $8                                       ;  6,2 $1E90 05 08    r4 = $8 [BS];
        STRZ    r5                                       ;  6,1 $1E92 C2       r5 = r0;
        RRR,r5                                           ;  6,1 $1E93 52       r5 >>= 1;
        CPSU    F                                        ;  9,2 $1E94 74 40    PSU &= ~($40 & %01100111);
                                                                              ;Clear F (Flag) bit
        BSTR,un DELAY                                    ;  9,2 $1E96 3B 17    gosub DELAY;
        RRR,r5                                           ;  6,1 $1E98 52       r5 >>= 1;
        SPSU                                             ;  6,1 $1E99 12       r0 = PSU;
        STRZ    r6                                       ;  6,1 $1E9A C3       r6 = r0;
        ANDI,r6 $BF                                      ;  6,2 $1E9B 47 BF    r6 &= $BF;
        LODZ    r5                                       ;  6,1 $1E9D 02       r0 = r5;
        ANDI,r0 $40                                      ;  6,2 $1E9E 44 40    r0 &= $40;
        IORZ    r6                                       ;  6,1 $1EA0 63       r0 |= r6;
        LPSU                                             ;  6,1 $1EA1 92       PSU &= %10000000; PSU |= (r0 & %01100111);
        BSTR,un DELAY                                    ;  9,2 $1EA2 3B 0B    gosub DELAY;
        BDRR,r4 $1E98                                    ;  9,2 $1EA4 F9 72    if (--r4 != 0) goto $1E98;
        PPSU    F                                        ;  9,2 $1EA6 76 40    PSU |= $40 & %01100111;
                                                                              ;Set F (Flag) bit
        BSTR,un DELAY                                    ;  9,2 $1EA8 3B 05    gosub DELAY;
        BSTR,un DELAY                                    ;  9,2 $1EAA 3B 03    gosub DELAY;
        CPSL    RS                                       ;  9,2 $1EAC 75 10    PSL &= ~($10);
                                                                              ;Clear RS (Register Select) bit (now r1..r3)
        RETC,un                                          ;  9,1 $1EAE 17       return;
;End of Subroutine DUMP1CHAR----------------------------------------------
;Subroutine DELAY---------------------------------------------------------
DELAY: ;$1EAF:
        LODI,r0 $B6                                      ;  6,2 $1EAF 04 B6    r0 = $B6;
        BDRR,r0 $1EB1                                    ;  9,2 $1EB1 F8 7E    if (--r0 != 0) goto $1EB1;
DELAY_ALT: ;$1EB3
;alternate entry point (half a bit delay)
        LODI,r0 $B6                                      ;  6,2 $1EB3 04 B6    r0 = $B6;
        BDRR,r0 $1EB5                                    ;  9,2 $1EB5 F8 7E    if (--r0 != 0) goto $1EB5;
        RETC,un                                          ;  9,1 $1EB7 17       return;
;End of Subroutine DELAY--------------------------------------------------
;Subroutine $1EB8---------------------------------------------------------
;r0 and r1 are passed as arguments.
;Restores r0 to its original value before returning; also puts this value in r2.
;r1 is the return code.
;r1 = (r0 ^ r1) >> 1;
        STRZ    r2                                       ;  6,1 $1EB8 C2       r2 = r0;
        EORZ    r1                                       ;  6,1 $1EB9 21       r0 ^= r1;
        STRZ    r1                                       ;  6,1 $1EBA C1       r1 = r0;
        RRR,r1                                           ;  6,1 $1EBB 51       r1 >>= 1;
        LODZ    r2                                       ;  6,1 $1EBC 02       r0 = r2;
        RETC,un                                          ;  9,1 $1EBD 17       return;
;Subroutine LOAD1CHAR-----------------------------------------------------
LOAD1CHAR: ;$1EBE
;r4 and r5 are scratch.
;do
;{   r0 = IOPORT($10);
;} while high bit of r0 is set;
;gosub DELAY_ALT; // wait for midpoint of bit
;for (r4 = 8; r4 >= 1; r4--)
;{   gosub DELAY;
;    r0 >>= 1;
;    r0 |= (IOPORT($10) & %10000000);
;}
;gosub DELAY;
;gosub $1EB8;
;return;
        PPSL    RS                                       ;  9,2 $1EBE 77 10    PSL |= $10;
                                                                              ;Set RS (Register Select) bit (now r4..r6)
        LODI,r4 $8                                       ;  6,2 $1EC0 05 08    r4 = $8 [BS];
        LODI,r5 $0                                       ;  6,2 $1EC2 06 00    r5 = $0 [NUL];
        REDE,r0 $10                                      ;  9,2 $1EC4 54 10    r0 = IOPORT($10);
        BCTR,lt $1EC4                                    ;  9,2 $1EC6 1A 7C    if < then goto $1EC4;
        BSTR,un DELAY_ALT                                ;  9,2 $1EC8 3B 69    gosub DELAY_ALT;
        BSTR,un DELAY                                    ;  9,2 $1ECA 3B 63    gosub DELAY;
        REDE,r0 $10                                      ;  9,2 $1ECC 54 10    r0 = IOPORT($10);
        ANDI,r0 $80                                      ;  6,2 $1ECE 44 80    r0 &= $80;
        RRR,r5                                           ;  6,1 $1ED0 52       r5 >>= 1;
        IORZ    r5                                       ;  6,1 $1ED1 62       r0 |= r5;
        STRZ    r5                                       ;  6,1 $1ED2 C2       r5 = r0;
        BDRR,r4 $1ECA                                    ;  9,2 $1ED3 F9 75    if (--r4 != 0) goto $1ECA;
        BSTR,un DELAY                                    ;  9,2 $1ED5 3B 58    gosub DELAY;
        LODZ    r5                                       ;  6,1 $1ED7 02       r0 = r5;
        CPSL    RS                                       ;  9,2 $1ED8 75 10    PSL &= ~($10);
                                                                              ;Clear RS (Register Select) bit (now r1..r3)
        BSTR,un $1EB8                                    ;  9,2 $1EDA 3B 5C    gosub $1EB8;
        RETC,un                                          ;  9,1 $1EDC 17       return;
;End of Subroutine LOAD1CHAR----------------------------------------------
;Subroutine LOADCASS------------------------------------------------------
LOADCASS: ;$1EDD
;Set F (Flag) bit
;Set II (Interrupt Inhibit) bit (now inhibited)
;PSL = %eq,d,r,w,o,M,c;
;gosub INIT;
;if (LOAD1CHAR() != $50)
;{   goto LOADCASS_END;
;} // implied else
;*(RTDIGITS) = *(PTR2_H) = LOAD1CHAR();
;*(MDDIGITS) = *(PTR2_L) = LOAD1CHAR();
;              *(PTR3_H) = LOAD1CHAR();
;              *(PTR3_L) = LOAD1CHAR();
;for (;;)
;{   r3 := r1;
;    if (LOAD1CHAR() != r3)
;    {   goto LOADCASS_END;
;    } // implied else
;    gosub DRAWSCREEN();
;    do
;    {   *(*RTDIGITS) := LOAD1CHAR();
;        gosub MONOTONIC;
;        if (==)
;        {   *(*RTDIGITS) := LOAD1CHAR();
;            r3 = r1;
;            if (LOAD1CHAR() == r3)
;            {   *(LTDIGITS) := "C0";
;            } else
;            {   *(LTDIGITS) := "F0";
;            }
;            enable interrupts
;            return;
;        } // implied else
;        r0 := *(MDDIGITS);
;    } while (r0 != 0);
;}
        PPSU    $60                                      ;  9,2 $1EDD 76 60    PSU |= $60 & %01100111;
        LODI,r0 $2                                       ;  6,2 $1EDF 04 02    r0 = $2 [STX];
        LPSL                                             ;  6,1 $1EE1 93       PSL = r0;
        BSTA,un INIT                                     ;  9,3 $1EE2 3F 1E 00 gosub INIT;
        BSTR,un LOAD1CHAR                                ;  9,2 $1EE5 3B 57    gosub LOAD1CHAR;
        COMI,r0 $50                                      ;  6,2 $1EE7 E4 50    compare r0 against $50 ['P'];
        BCFA,eq $1F36                                    ;  9,3 $1EE9 9C 1F 36 if != then goto $1F36;
        BSTR,un LOAD1CHAR                                ;  9,2 $1EEC 3B 50    gosub LOAD1CHAR;
        STRA,r0 RTDIGITS                                 ; 12,3 $1EEE CC 1D F0 *(RTDIGITS) = r0;
        STRA,r0 PTR2_H                                   ; 12,3 $1EF1 CC 1D FA *(PTR2_H) = r0;
        BSTR,un LOAD1CHAR                                ;  9,2 $1EF4 3B 48    gosub LOAD1CHAR;
        STRA,r0 MDDIGITS                                 ; 12,3 $1EF6 CC 1D F1 *(MDDIGITS) = r0;
        STRA,r0 $PTR2_L                                  ; 12,3 $1EF9 CC 1D FB *(PTR2_L) = r0;
        BSTR,un LOAD1CHAR                                ;  9,2 $1EFC 3B 40    gosub LOAD1CHAR;
        STRA,r0 PTR3_H                                   ; 12,3 $1EFE CC 1D FC *(PTR3_H) = r0;
        BSTA,un LOAD1CHAR                                ;  9,3 $1F01 3F 1E BE gosub LOAD1CHAR;
        STRA,r0 PTR3_L                                   ; 12,3 $1F04 CC 1D FD *(PTR3_L) = r0;
        LODZ    r1                                       ;  6,1 $1F07 01       r0 = r1;
        STRZ    r3                                       ;  6,1 $1F08 C3       r3 = r0;
        BSTA,un LOAD1CHAR                                ;  9,3 $1F09 3F 1E BE gosub LOAD1CHAR;
        COMZ    r3                                       ;  6,1 $1F0C E3       compare r0 against r3;
        BCFR,eq LOADCASS_END                             ;  9,2 $1F0D 98 27    if != then goto LOADCASS_END;
        BSTA,un DRAWSCREEN                               ;  9,3 $1F0F 3F 1E 0D gosub DRAWSCREEN;
        BSTA,un LOAD1CHAR                                ;  9,3 $1F12 3F 1E BE gosub LOAD1CHAR;
        STRA,r0 *RTDIGITS                                ; 18,3 $1F15 CC 9D F0 *(*RTDIGITS) = r0;
        BSTA,un MONOTONIC                                ;  9,3 $1F18 3F 1E 20 gosub MONOTONIC;
        BCTR,eq $1F24                                    ;  9,2 $1F1B 18 07    if == then goto $1F24;
        LODA,r0 MDDIGITS                                 ; 12,3 $1F1D 0C 1D F1 r0 = *(MDDIGITS);
        BCTR,eq $1F07                                    ;  9,2 $1F20 18 65    if == then goto $1F07;
        BCTR,un $1F12                                    ;  9,2 $1F22 1B 6E    goto $1F12;
        BSTA,un LOAD1CHAR                                ;  9,3 $1F24 3F 1E BE gosub LOAD1CHAR;
        STRA,r0 *RTDIGITS                                ; 18,3 $1F27 CC 9D F0 *(*RTDIGITS) = r0;
        LODZ    r1                                       ;  6,1 $1F2A 01       r0 = r1;
        STRZ    r3                                       ;  6,1 $1F2B C3       r3 = r0;
        BSTA,un LOAD1CHAR                                ;  9,3 $1F2C 3F 1E BE gosub LOAD1CHAR;
        COMZ    r3                                       ;  6,1 $1F2F E3       compare r0 against r3;
        BCFR,eq LOADCASS_END                             ;  9,2 $1F30 98 04    if != then goto LOADCASS_END;
        LODI,r0 $C0                                      ;  6,2 $1F32 04 C0    r0 = $C0 ["CO"];
        BCTR,un LOADCASS_END2                            ;  9,2 $1F34 1B 02    goto LOADCASS_END2;
LOADCASS_END: ;$1F36
        LODI,r0 $F0                                      ;  6,2 $1F36 04 F0    r0 = $F0 ["F0"];
LOADCASS_END2:
        STRA,r0 LTDIGITS                                 ; 12,3 $1F38 CC 1D F2 *(LTDIGITS) = r0;
        BSTA,un DRAWSCREEN                               ;  9,3 $1F3B 3F 1E 0D gosub DRAWSCREEN;
        RETE,un                                          ;  9,1 $1F3E 37       PSU &= ~PSU_II; return;
;End of Subroutine LOADCASS-------------------------------------------------------
;Subroutine KEYBOARD------------------------------------------------------
KEYBOARD: ;$1F3F
;STORER0       := r0;
;STOREPSL      := PSL;
;PSL           := %00000010; // set unsigned compare, clear all other bits
;STORER1       := r1;
;r1            := IOPORT($10);
;PTR_H         := $1D;
;KEYBOARD_END2 := PPSL;
;KEYBOARD_END3 := RETE,un;
;r1            &= %000,11111;
;if (r1 >= $14) goto KEYBOARD_END;
;if (r1 == $13) goto $1FD2;
;if (r1 == $12) goto $1FCB;
;if (r1 == $11) goto $1FB6;
;if (r1 == $10) goto $1FA5;
        STRA,r0 STORER0                                  ; 12,3 $1F3F CC 1D F5 STORER0 = r0;
        SPSL                                             ;  6,1 $1F42 13       r0 = PSL;
        STRA,r0 STOREPSL                                 ; 12,3 $1F43 CC 1D F8 STOREPSL = r0;
        LODI,r0 $2                                       ;  6,2 $1F46 04 02    r0 = $2 [STX];
        LPSL                                             ;  6,1 $1F48 93       PSL = r0;
        STRA,r1 STORER1                                  ; 12,3 $1F49 CD 1D F6 STORER1 = r1;
        REDE,r1 $10                                      ;  9,2 $1F4C 55 10    r1 = IOPORT($10);
        LODI,r0 $1D                                      ;  6,2 $1F4E 04 1D    r0 = $1D;
        STRA,r0 PTR_H                                    ; 12,3 $1F50 CC 1D F3 *(PTR_H) = r0;
        LODI,r0 $77                                      ;  6,2 $1F53 04 77    r0 = $77;
        STRA,r0 KEYBOARD_END2                            ; 12,3 $1F55 CC 1D F7 *(KEYBOARD_END2) = r0 [PPSL];
        LODI,r0 $37                                      ;  6,2 $1F58 04 37    r0 = $37;
        STRA,r0 $1DF9                                    ; 12,3 $1F5A CC 1D F9 *($1DF9) = r0;
        ANDI,r1 $1F                                      ;  6,2 $1F5D 45 1F    r1 &= $1F;
        COMI,r1 $14                                      ;  6,2 $1F5F E5 14    compare r1 against $14 [DC4];
        BCFA,lt KEYBOARD_END                             ;  9,3 $1F61 9E 1F DE if >= then goto KEYBOARD_END;
        COMI,r1 $13                                      ;  6,2 $1F64 E5 13    compare r1 against $13 [DC3];
        BCTA,eq $1FD2                                    ;  9,3 $1F66 1C 1F D2 if == then goto $1FD2;
        COMI,r1 $12                                      ;  6,2 $1F69 E5 12    compare r1 against $12 [DC2];
        BCTA,eq $1FCB                                    ;  9,3 $1F6B 1C 1F CB if == then goto $1FCB;
        COMI,r1 $11                                      ;  6,2 $1F6E E5 11    compare r1 against $11 [DC1];
        BCTA,eq $1FB6                                    ;  9,3 $1F70 1C 1F B6 if == then goto $1FB6;
        COMI,r1 $10                                      ;  6,2 $1F73 E5 10    compare r1 against $10 [DLE];
        BCTR,eq $1FA5                                    ;  9,2 $1F75 18 2E    if == then goto $1FA5;

;assert(r1 < $10); // "0".."F"
;r0 := *(NUMDIGITS) & 7;
;if (r0 < 6)
;{   set With Carry bit
;    r0 >>= 1;
;    r0 |= $F0;
;    *(NUMDIGITS) := r0;
;    if Carry bit is clear
;    {    r1 <<= 4;
;         *(PTR_H) := r1;
;    }
;    r1 |= *(PTR_H);
;    *(*PTR_B) := r1;
;    r0 <<= 1;
;    clear With Carry bit
;    r0++;
;    r0 |= $F0;
;    goto KEYBOARD_END;
;}
        LODA,r0 NUMDIGITS                                ; 12,3 $1F77 0C 1D F4 r0 = *(NUMDIGITS);
        ANDI,r0 $7                                       ;  6,2 $1F7A 44 07    r0 &= $7;
        COMI,r0 $6                                       ;  6,2 $1F7C E4 06    compare r0 against $6 [ACK];
        BCFR,lt $1F9E                                    ;  9,2 $1F7E 9A 1E    if >= then goto $1F9E;
        PPSL    WC                                       ;  9,2 $1F80 77 08    PSL |= $8;
                                                                              ;Set WC (With Carry) bit
        RRR,r0                                           ;  6,1 $1F82 50       r0 >>= 1;
        IORI,r0 $F0                                      ;  6,2 $1F83 64 F0    r0 |= $F0;
        STRA,r0 NUMDIGITS                                ; 12,3 $1F85 CC 1D F4 *(NUMDIGITS) = r0;
        TPSL    C                                        ;  9,2 $1F88 B5 01    CC = (PSL & %00000001 == %00000001) ? EQ : LT;
                                                                              ;Test C (Carry) bit
        BCTR,eq $1F93                                    ;  9,2 $1F8A 18 07    if == then goto $1F93;
        RRL,r1                                           ;  6,1 $1F8C D1       r1 <<= 1;
        RRL,r1                                           ;  6,1 $1F8D D1       r1 <<= 1;
        RRL,r1                                           ;  6,1 $1F8E D1       r1 <<= 1;
        RRL,r1                                           ;  6,1 $1F8F D1       r1 <<= 1;
        STRA,r1 *PTR_B                                   ; 18,3 $1F90 CD 9D F3 *(*PTR_B) = r1;
        IORA,r1 *PTR_B                                   ; 18,3 $1F93 6D 9D F3 r1 |= *(*PTR_B);
        STRA,r1 *PTR_B                                   ; 18,3 $1F96 CD 9D F3 *(*PTR_B) = r1;
        RRL,r0                                           ;  6,1 $1F99 D0       r0 <<= 1;
        CPSL    WC                                       ;  9,2 $1F9A 75 08    PSL &= ~($8);
                                                                              ;Clear WC (With Carry) bit
        ADDI,r0 $1                                       ;  6,2 $1F9C 84 01    r0++;
        IORI,r0 $F0                                      ;  6,2 $1F9E 64 F0    r0 |= $F0;
        STRA,r0 NUMDIGITS                                ; 12,3 $1FA0 CC 1D F4 *(NUMDIGITS) = r0;
        BCTR,un KEYBOARD_END                             ;  9,2 $1FA3 1B 39    goto KEYBOARD_END;
;Key $10 (D->M)-----------------------------------------------------------
;if (*(NUMDIGITS) & %00000111 == 6)
;{   *(*(RTDIGITS)) := *(LTDIGITS); // poke
;    gosub MONOTONIC;
;    *(NUMDIGITS) := %01110,100;
;    *(LTDIGITS) := *(*RTDIGITS)); // peek
;    goto KEYBOARD_END;
;}
        LODA,r0 NUMDIGITS                                ; 12,3 $1FA5 0C 1D F4 r0 = *(NUMDIGITS);
        ANDI,r0 $7                                       ;  6,2 $1FA8 44 07    r0 &= $7;
        COMI,r0 $6                                       ;  6,2 $1FAA E4 06    compare r0 against $6 [ACK];
        BCFR,eq KEYBOARD_END                             ;  9,2 $1FAC 98 30    if != then goto KEYBOARD_END;
        LODA,r0 LTDIGITS                                 ; 12,3 $1FAE 0C 1D F2 r0 = *(LTDIGITS);
        STRA,r0 *RTDIGITS                                ; 18,3 $1FB1 CC 9D F0;*(*RTDIGITS) = r0;
        BCTR,un $1FBB                                    ;  9,2 $1FB4 1B 05    goto $1FBB;
;Key $11 (M->D)-----------------------------------------------------------
;if (*(NUMDIGITS) & $80 == $00) // if high bit is clear
;{   gosub MONOTONIC;
;}
;*(NUMDIGITS) := %01110,100;
;*(LTDIGITS) := *(*RTDIGITS)); // peek
;goto KEYBOARD_END;
        LODA,r0 NUMDIGITS                                ; 12,3 $1FB6 0C 1D F4 r0 = *(NUMDIGITS);
        BCTR,lt $1FBE                                    ;  9,2 $1FB9 1A 03    if < then goto $1FBE;
        BSTA,un MONOTONIC                                ;  9,3 $1FBB 3F 1E 20 gosub MONOTONIC;
        LODI,r0 $74                                      ;  6,2 $1FBE 04 74    r0 = $74;
        STRA,r0 NUMDIGITS                                ; 12,3 $1FC0 CC 1D F4 *(NUMDIGITS) = r0 [%01110,100];
        LODA,r0 *RTDIGITS                                ; 18,3 $1FC3 0C 9D F0 r0 = *(*RTDIGITS);
        STRA,r0 LTDIGITS                                 ; 12,3 $1FC6 CC 1D F2 *(LTDIGITS) = r0;
        BCTR,un KEYBOARD_END                             ;  9,2 $1FC9 1B 13    goto KEYBOARD_END;
;Key $12 (Go to)----------------------------------------------------------
        CPSL    $FF                                      ;  9,2 $1FCB 75 FF    PSL &= ~($FF); // or, PSL = 0;
;Set CC (Condition Code) to EQ
;Clear IDC (Inter-Digit Carry) bit
;Clear RS (Register Select) bit (now r1..r3)
;Clear WC (With Carry) bit
;Clear OVF (Overflow) bit
;Clear COM (Compare) bit (now signed/arithmetic)
;Clear C (Carry) bit
        CPSU    $27                                      ;  9,2 $1FCD 74 27    PSU &= ~($27 & %01100111);
;Clear II (Interrupt Inhibit) bit (now disinhibited)
;Clear SP (Stack Pointer) to 0!
;Go to address comprised by 1st..4th digits
        BCTA,un *RTDIGITS                                ; 15,3 $1FCF 1F 9D F0 goto *RTDIGITS;
;Key $13 (Clear)----------------------------------------------------------
;if (*(NUMDIGITS) & 7) >= 5)
;{   *(NUMDIGITS) := %01110,100;
;    *(LTDIGITS)  := *(*RTDIGITS)); // peek
;} else
;{   gosub INIT;
;}
;goto KEYBOARD_END;
        LODA,r0 NUMDIGITS                                ; 12,3 $1FD2 0C 1D F4 r0 = *(NUMDIGITS);
        ANDI,r0 $7                                       ;  6,2 $1FD5 44 07    r0 &= $7;
        COMI,r0 $5                                       ;  6,2 $1FD7 E4 05    compare r0 against $5;
        BCFR,lt $1FBE                                    ;  9,2 $1FD9 9A 63    if >= then goto $1FBE;
        BSTA,un INIT                                     ;  9,3 $1FDB 3F 1E 00 gosub INIT;
;Any Key------------------------------------------------------------------
KEYBOARD_END: ;$1FDE:
        BSTA,un DRAWSCREEN                               ;  9,3 $1FDE 3F 1E 0D gosub DRAWSCREEN;
        LODA,r1 STORER1                                  ; 12,3 $1FE1 0D 1D F6 r1 = STORER1;
        LODA,r0 STORER0                                  ; 12,3 $1FE4 0C 1D F5 r0 = STORER0;
        CPSL    $FF                                      ;  9,2 $1FE7 75 FF    PSL &= ~($FF);
;Set CC (Condition Code) to EQ
;Clear IDC (Inter-Digit Carry) bit
;Clear RS (Register Select) bit (now r1..r3)
;Clear WC (With Carry) bit
;Clear OVF (Overflow) bit
;Clear COM (Compare) bit (now signed/arithmetic)
;Clear C (Carry) bit
        BCTA,un KEYBOARD_END2                            ;  9,3 $1FE9 1F 1D F7 goto KEYBOARD_END2;
;Subroutine HALTKEY-------------------------------------------------------
HALTKEY: ;$1FEC
;for (;;)
;{   PSL = %00000000;
;    PSU = %01000000; // set Flag bit, enable interrupts, etc.
;    for (;;);
;}
        CPSL    $FF                                      ;  9,2 $1FEC 75 FF    PSL &= ~($FF);
;Set CC (Condition Code) to EQ
;Clear IDC (Inter-Digit Carry) bit
;Clear RS (Register Select) bit (now r1..r3)
;Clear WC (With Carry) bit
;Clear OVF (Overflow) bit
;Clear COM (Compare) bit (now signed/arithmetic)
;Clear C (Carry) bit
        LODI,r0 $40                                      ;  6,2 $1FEE 04 40    r0 = $40; // set Flag bit, enable interrupts, etc.
        LPSU                                             ;  6,1 $1FF0 92       PSU &= %1,0,0,00,000; PSU |= (r0 & %0,1,1,00,111);
;Flag       is  set     (%1)
;Interrupts are enabled (%0)
;SP         is  zeroed  (%000)
        HALT                                             ;  6,1 $1FF1 40       for (;;);
        BCTR,un HALTKEY                                  ;  9,2 $1FF2 1B 78    goto HALTKEY;
;End of Subroutine HALTKEY------------------------------------------------
        DW      KEYBOARD                                 ;  0,1 $1FF4 1F 3F
        DW      LOADCASS                                 ;  0,2 $1FF6 1E DD
        DW      DUMPCASS                                 ;  0,2 $1FF8 1E 3D

        DB      $50                                      ;  0,1 $1FFA 50
        DB      $48                                      ;  0,1 $1FFB 48
        DB      $55                                      ;  0,1 $1FFC 55
        DB      $4E                                      ;  0,1 $1FFD 4E
        DB      $53                                      ;  0,1 $1FFE 53
        DB      $59                                      ;  0,1 $1FFF 59

        END     $0000
        
Worker subroutines:
 Subroutine INIT
 Subroutine DRAWSCREEN
 Subroutine MONOTONIC
 Subroutine DELAY
 Subroutine $1EB8
Non-worker subroutines:
 Subroutine DUMPCASS
  inhibits interrupts during routine
  calls INIT, DRAWSCREEN, MONOTONIC, DUMP1CHAR
 Subroutine DUMP1CHAR
  calls $1EB8, DELAY
 Subroutine LOAD1CHAR
  calls $1EB8, DELAY
 Subroutine LOADCASS
  inhibits interrupts during routine
  calls INIT, DRAWSCREEN, MONOTONIC, LOAD1CHAR
 Subroutine KEYBOARD
  calls INIT, DRAWSCREEN, MONOTONIC
  enables interrupts at end
