; BALCHECK Bally Board tester 4/29/80
;
; This software requires extra hardware to give results,
; basically a 2 digit hex display which is addressed 
; at $FF. Schematics are available here: ???
;
; *********************************************************
; * This code is modified from the original, but only
; * comments. The assembled code of this version will
; * match the WinMD5sum of:
; *
; * fc8ba769c894e4b0ac5a97bc33094107
; * 
; * which means the object file is EXACTLY the same as
; * the original.
; *
; * Modifications by David Turner (cmdr-dave@spamcop.net)
; * 01/21/06: Commented RAM test routines
; * 
; *
; *
; *
; *********************************************************
;
; Retyped by Adam Trionfo
; 
;
; Revisions:
;    * Janurary 21, 2006 - 1.1
;           - Thouroughly commented memory test section
;             by David Turner
;    * February 7, 2004  - 1.0
;           - Finished typing in source-code
;           - Code assembles without problem
;           - Added conditional assembly for new or old ROM
;    * January 25, 2005  - .01
;           - Begin typing in source-code
;
;  To assemble this Z-80 source code using ZMAC:
;  
;  zmac -d -o <outfile> -x <listfile> <filename>
;  
;  For example, assemble this Astrocade Z-80 ROM file:
;     
;  zmac -i -m -o balcheck.bin -x balcheck.lst balcheck.asm
;
; *********************************************************
; *                                                       *
; *           IMPORTANT: Conditional Assembly!            *
; *                                                       *
; *  This code can assemble into two different binary     *
; *  files, as per the 5/16/82 update by Richard G.       *
; *  Belton.  One assembly is for the old ROM and the     *
; *  other is for the new ROM.                            *
; *                                                       *
; *     Here's how to tell which ROM to assemble for      *
; *        Old ROM - Gunfighter score = 0-99              *
; *                  Menu reads (C) BALLY MFG 1977        *
; *        New ROM - Gunfighter score = 0-9999            *
; *                  Menu reads (C) BALLY MFG 1978        *
; *                                                       *
; *  The default is for the new ROM.  To assemble for     *
; *  the new ROM, change NEWROM EQU YES to NEWROM EQU NO  *
; *                                                       *
; *********************************************************

YES     EQU    1
NO      EQU    0
NEWROM  EQU    YES

;********************************************************
;*                                                      *
;*                  B A L C H E C K                     *
;*                                                      *
;*             Check Bally Mother-boards                *
;*                                                      *
;*                      4/29/80                         *
;*                                                      *
;********************************************************
;
DSPLY   EQU    0FFH             ; Test unit display port
                                ; Display patterns
                                ; 0 = 0
                                ; .   .
                                ; .   .
                                ; 9 = 9
                                ; A = -
                                ; B = E
                                ; C = H
                                ; D = L
                                ; E = P
                                ; F = blank
;
        INCLUDE "HVGLIB.H"
;
;       LIST   ON
;
        ORG    FIRSTC		
;
        JP     BCHK             ; Go start testing
;
; *********************************************************
; * Multiply A by 16; Shift A left 4
; *********************************************************
;
A2003   ADD    A,A              ; x2
        ADD    A,A              ; x4
        ADD    A,A              ; x8
        ADD    A,A              ; x16
        RET
;
; *********************************************************
; * Key masks
; *********************************************************
;
T2008   DB     00101111B
        DB     00001111B
        DB     00001111B
        DB     00101111B

;
; *********************************************************
; * Expander Test patterns
; *********************************************************
;
T200C   DB     0,55H,0AAH,0FFH
;
;
; *********************************************************
; * Interrupt vectors
; *********************************************************
;
T2010   DW     A2728            ; Display all input devices
T2012   DW     A2777            ; Rainbow Interrupt Routine
T2014   DW     A2016            ; Normal Interrupt  Routine
;
; *********************************************************
; * Normal Interrupt routine
; *
; *  === Keypad Layout ===
; *
; *  Port--> 17  16  15  14  
; *        +----------------
; *  Bit 0 |  1   2   3   4  
; *      1 |  5   6   7   8  
; *      2 |  9   A   B   C  
; *      3 |  D   E   F   0  
; *      4 | Q/S  x   x   x  
; *      5 | CE   x   x  Go  
; *
; *********************************************************
; 
A2016   DI
        EX     AF,AF'           ; Using only  reg.
        IN     A,(KEY1)
        AND    A
        JR     NZ,A2046         ; 3 or 7
        IN     A,(KEY2)
        AND    A
        JR     NZ,A2052         ; 2 or 6
        IN     A,(KEY3)
        AND    A
        JR     NZ,A2036         ; 1 or 5 or Q/S
        IN     A,(KEY0)
        AND    A
        JR     Z,A2062
        CP     1                ; 4 or 8
        JP     Z,A2627          ; Output Port Write routine
        CP     2
        JP     Z,A27BA          ; Enter machine code from keys
A2036   CP     1
        JP     Z,A25D9          ; Memory Read routine
        CP     2
        JP     Z,A264F          ; Memory Read & write routine
        CP     10H
        JR     Z,A205C          ; Q/S
        JR     A2062            ; None of the above
;
A2046   CP     1
        JP     Z,A2611          ; Input Port Read Routine
        CP     2
        JP     Z,A2748          ; Rainbow Color Display
        JR     A2062
;
A2052   CP     1
        JP     Z,A25EA          ; Memory Write routine
        CP     2
        JP     Z,A2673          ; Display all input devices
;
A205C   EXX                     ; Q/S key
        LD     A,C
        AND    0FH              ; Remove bit 7
        LD     C,A
        EXX
;
A2062   EXX
        INC    D                ; 1/60 sec counter
        LD     A,D
        CP     60
        JR     NZ,A20A9         ; Jp if no overflow to seconds
        LD     D,0              ; Reset 1/60 sec counter
        BIT    0,E
        JR     NZ,A2080         ; Jp if odd second
        LD     A,C
        CP     84H
        JR     NZ,A2078         ; Jp if test not done
        LD     A,0B1H           ; "E1" on display
        JR     A2081
;
A2078   LD     A,B
        AND    A
        JR     NZ,A2081
        LD     A,0A0H           ; "-0" on display
        JR     A2081
;
A2080   XOR    A                ; "00" on display
A2081   OUT    (DSPLY),A
        INC    E                ; Increment 1 second counter
        LD     A,E
        CP     60
        JR     NZ,A20A9         ; Jp if no seconds overflow
        LD     E,0              ; Reset seconds
        INC    H                ; Increment minutes
        LD     A,H
        CP     60
        JR     NZ,A20A9         ; Jp if no minutes overflow
        LD     H,0              ; Reset minutes
        INC    L                ; Increment hours
        LD     A,L
        CALL   A2003            ; Mul A by 16
        CP     0A0H
        JR     NZ,A20A0         ; Jp if not 10 hours
        LD     A,B
        ADD    A,6
        LD     B,A
A20A0   INC    B
        LD     A,B
        CP     99H
        JR     NZ,A20A9
        XOR    A
        LD     B,A
        LD     L,A
A20A9   EXX
        EX     AF,AF'
        EI
        RET
;
; *********************************************************
; * Beginning of program
; *********************************************************
;
BCHK    DI			; No interruptions

        EXX			; Init alt registers ???
        XOR    A
        LD     B,A
        LD     C,81H
        LD     D,A
        LD     E,A
        LD     H,A
        LD     L,A
        EXX

        LD     A,0AAH	
        OUT    (DSPLY),A        ; Set display to "--"

        LD     A,0
        OUT    (CONCM),A        ; Set Consumer Mode

        LD     A,100 SHL 1	; Vertical blank line * 2
        OUT    (VERBL),A        
;
; *********************************************************
; * 1. Ensure keypad isn't stuck
; *********************************************************
;
        XOR    A
        LD     C,KEY0
A20C7   IN     A,(C)            ; Ensure no keys stuck
        AND    A
        JR     NZ,A20D4         ; Have a stuck key
        INC    C                ; Check all columns
        LD     A,C
        CP     KEY3+1
        JR     Z,A20DB          ; Keyboard has no stuck keys
        JR     A20C7
;
; Have a stuck keyboard key
;
A20D4   LD     E,1              ; Error Code 1
        LD     HL,T23EF
        JR     A2147
;
; *********************************************************
; * 2. Test RAM at 4F00 - 4FFF (no interrupts)
; *********************************************************
;
A20DB   LD     IY,T20E2
        JP     A2164
;
T20E2   JR     A20E8
        DB     $4E
        DB     $50
        DW     NORMEM+3840

;
; *********************************************************
; * 3. Check screen interrupts
; *********************************************************
;
A20E8   LD     SP,BEGRAM-6
        LD     A,8
        OUT    (INMOD),A        ; Set interrupt mode
        LD     HL,T2014         ; Initialize interrupt routine
        LD     A,H
        LD     I,A
        LD     A,L
        OUT    (INFBK),A
        XOR    A
        OUT    (INLIN),A        ; Interrupt on line 0
        IM     2
        EI
        LD     D,1
        CALL   A25CF            ; Delay
        DI
        EXX
        LD     A,D              ; 1/60 seconds
        AND    A
        JR     NZ,A2117         ; Must have gotten screen int.
        LD     A,E              ; Seconds
        AND    A
        JR     NZ,A2117         ; Must have gotten screen int.
        EXX
        LD     E,2              ; Error 2 Screen line Int. err.
        LD     C,0FFH           ; Info byte = blank
        LD     HL,T23EF         ; Where to continue test
        JR     A2147
;
A2117   LD     C,80H            ; Set loop counter
        EXX
        EI
;
; *********************************************************
; * Start repetitive tests
; *********************************************************
;
; *********************************************************
; * Checksum check ROMs
; *********************************************************
;
IF NEWROM			; Which ROM is being used - old or new?
A211B   LD     BC,8192
ELSE
A211B   LD     BC,2048
ENDIF

        LD     HL,SCREEN        ; Start with low memory
A2121   XOR    A                ; Initialize checksum
A2122   ADD    A,(HL)           ; Accumulate checksum
        LD     D,A
        INC    HL
        DEC    C
        JR     NZ,A2122
        DEC    B
        JR     NZ,A2122
        LD     A,D


IF NEWROM			; Which ROM is being used - old or new?
        CP     0A4H
ELSE
        CP     0FFH
ENDIF

        JR     NZ,A213A         ; Checksum bad


IF NEWROM			; Which ROM is being used - old or new?
        JP     A214A
ELSE
        LD     BC,800H
ENDIF

        LD     A,H
        CP     [FIRSTC+2048] SHR 8
        JR     Z,A214A          ; Done with checksum test
        JR     A2121            ; Do next checksum
;
A213A   LD     E,3              ; Error 3 ROM checksum err.
        LD     A,H
        SUB    8
        LD     C,A
        JR     NZ,A2144
        LD     C,0A0H           ; "-0" on display
A2144   LD     HL,A214A         ; Where to continue testing
A2147   JP     A23E6
;
; *********************************************************
; * Test RAM
; *********************************************************
;
; Test small amount of RAM while interrupts 
; are disabled. This area of memory is used for 
; stack/interrupt processing and we would hate
; to be in there when an interrupt hits.
;
A214A   DI	
        LD     IY,T2151         ; Test 4F00 - 4FFF 
        JR     A2164
				; Offset from IY...
T2151   JR     A2157		; +0,+1	  Next routine's address        
        DB     4EH		; +2      Lower range boundry          
        DB     50H		; +3      Upper range boundry        
        DW     NORMEM+3840	; +4,+5   Beginning address of memory to test    
;
; Test the larger amount of RAM with interrupts enabled
;
A2157   EI
        LD     IY,T215E         ; Test 4000 - 4EFF
        JR     A2164
				; Offset from IY...
T215E   JR     A21C8		; +0,+1   Next routine's address
        DB     63		; +2	  Lower range boundry  
        DB     79		; +3	  Upper range boundry 
        DW     NORMEM		; +4,+5   Beginning address of memory to test
;
;**********************************************************
;** Memory test routine
;**
;** This routine expects a 'context block' which is an
;** offset of IY as follows:
;**    
;**	IY+0, IY+1 -> Address of next routine to run (return location)
;**	IY+2	   -> Lower range to test (high byte)
;**	IY+3	   -> Upper range to test (high byte)
;**	IY+4, IY+5 -> Beginning address of memory to test
;** 
;** Here is the basic algorithm for the memory test:
;**
;** 1. Set pattern to 0000 0001 initially.
;**
;** 2. Start with lowest address and go to highest
;**    writing the pattern, reading it back and checking
;**    for errors at every location.
;** 
;** 3. When top of range is reached, start back down
;**    through memory.
;**    3A. Read previous memory pattern and check for errors
;**    3B. Complement pattern (flip all the bits),
;**        write it, read it, and check for errors
;**
;** 4. When bottom of range is reached, go back up
;**    through memory:
;**    4A. Read previous memory pattern and check for errors
;**    4B. Zero memory location (no error check)
;**
;** 5. When top of range is reached, rotate original 
;**    pattern to the left one bit and go back and do
;**    the whole procedure over (item #2) until every
;**    bit in the test byte has been checked.
;** 
;** If there is any error at any location, the data bits
;** that are in error at that location are OR'ed with 
;** register C and the memory test continues At the end 
;** of the test, if register C is a non-zero value, then 
;** a RAM ERROR is reported.
;**  
;** Speculation: 
;** 
;** This RAM test tests both for immediate 
;** errors by testing right after the write, but also 
;** testing after all of memory has been filled which gives 
;** it a slight delay, I assume, to detect memory fading.
;** 
;**********************************************************
;
A2164   LD     C,0		; Clear error register                          
        LD     B,1		; Initial test pattern 0000 0001 
A2168   LD     H,(IY+5)		; Get beginning memory address
        LD     L,(IY+4)		                             
A216E   LD     (HL),B		; Test memory location   
        LD     A,(HL)		;                 
        XOR    B		;             
        JR     Z,A2179		; Test passes, continue testing                    
        LD     IX,A2179		; Test failed...
        JR     A21C4		; Log error and continue testing 
;
A2179   INC    HL		; Going up through memory    
        LD     A,H		                             
        CP     (IY+3)		; Are we out of high range?  
        JR     NZ,A216E		; In range, go back and keep testing 
	
A2180   DEC    HL		; Going down through memory now...
        LD     A,H		;                           
        CP     (IY+2)		; Are we out of low range? 
        JR     Z,A219D		; Out of range, jump out to next test
;
        LD     A,(HL)		; Test memory against normal pattern 
        XOR    B		;  
        JR     Z,A2191		; Test passes, continue tests             
        LD     IX,A2191		; Test failed...             
        JR     A21C4		; Log error and continue testing
;				                             
A2191   LD     A,B		; Get original pattern	     
        CPL			; Flip all the bits          
        LD     (HL),A		; Test memory location          
        XOR    (HL)		;                                        
        JR     Z,A2180		; Test passes, continue testing                                          
        LD     IX,A2180		; Test failed...                         
        JR     A21C4		; Log error and continue testing                             
;					                             
A219D   INC    HL		; Going up through memory again...
        LD     A,H		                             
        CP     (IY+3)		; Are we out of high range?            
        JR     Z,A21B3		; Out of range, jump out to next test        
        LD     A,B		; Get normal pattern 	             
        CPL			; flip the bits              
        XOR    (HL)		; Test memory location                             
        JR     Z,A21AF		; Test passes, continue testing                                                     
        LD     IX,A21AF		; Test failed...                                    
        JR     A21C4		; Log error and continue testing                    
;				                             
A21AF   XOR    A		;                        
        LD     (HL),A		; Clear memory location       
        JR     A219D		; and continue testing...  
;				                             
A21B3   SLA    B		; Walk the original patter left one bit         
        JR     NC,A2168		; If more patterns to do, do tests again with new pattern
        LD     A,C		; Otherwise, test is over, check for errors
        AND    A		;                           
        JR     NZ,A21BD		; If errors occurred, go to error routine 
        JP     (IY)		; End of memory testing     
;				                             
A21BD   LD     E,4              ; Error 4 RAM error
        LD     HL,A21C8		                           
        JR     A2213		; Report error and go to next routine                          
;
; 
A21C4   OR     C		; RAM location had error	                             
        LD     C,A		; Store the faulty bit location(s)     
        JP     (IX)		; Return to test routine. 
	
;
;**********************************************************
;* Shifter test
;**********************************************************
; 
A21C8   LD     IY,2064
        LD     IX,NORMEM+2064
        XOR    A
        LD     C,A              ; Init shift count
A21D2   LD     B,1
A21D4   LD     A,C
        OUT    (MAGIC),A        ; Set shifter
        XOR    A
        LD     H,A              ; Expected first byte
        LD     L,A
        LD     (IY),A
        LD     A,B
        LD     L,B             ; Expected first byte
        LD     (IY),A
        XOR    A
        LD     (IY+1),A
        LD     A,C
        AND    A
        JR     Z,A21F5          ; Jp if shift = 0
A21EA   RR     L
        RR     H
        RR     L
        RR     H
        DEC    A
        JR     NZ,A21EA         ; Shift proper number of times
A21F5   LD     A,(IX)           ; Pick resulting RAM data
        CP     L
        JR     NZ,A220E         ; Shifter error
        LD     A,(IX+1)         ; Second resulting byte
        CP     H
        JR     NZ,A220E         ; Shifter error
        RL     B                ; Store pattern left 1 bit
        JR     NC,A21D4         ; Keep trying
        LD     A,C              ; Done 8 patterns
        INC    A
        LD     C,A
        CP     4
        JR     NZ,A21D2         ; Jp if not all shifter sets
        JR     A2215
;
A220E   LD     E,5              ; Error 5 Shifter error
        LD     HL,A2215
A2213   JR     A2248
;
;**********************************************************
;* Flopper test
;**********************************************************
;
A2215   LD     A,01000000B
        OUT    (MAGIC),A        ; Set flopper
        LD     DE,NORMEM+2064
        LD     HL,T224A
        LD     C,1              ; Write 1s
A2221   LD     A,C
        LD     (IY),A
        LD     A,(DE)
        CP     (HL)
        JR     NZ,A2243         ; Bad Flop
        INC    HL
        SLA    C
        JR     NC,A2221         ; Do all 8 bites
        RR     C                ; Shift back to hi bit
A2230   LD     A,C              ; Write 0s
        CPL
        LD     (IY),A
        LD     A,(DE)
        CP     (HL)
        JR     NZ,A2240         ; Bad flop
        INC    HL
        SRL    C
        JR     NC,A2230         ; Do all 8
        JR     A225A
;
A2240   LD     A,C
        CPL
        LD     C,A
A2243   LD     E,7              ; Error 7 Flopper error
        LD     HL,A225A
A2248   JR     A2291
;
; Expected flopper patterns
T224A   DB     01000000B
        DB     10000000B
        DB     00010000B
        DB     00100000B
        DB     00000100B
        DB     00001000B
        DB     00000001B
        DB     00000010B
        DB     11111101B
        DB     11111110B
        DB     11110111B
        DB     11111011B
        DB     11011111B
        DB     11101111B
        DB     01111111B
        DB     10111111B
;
;**********************************************************
;* Expander test
;**********************************************************
;
A225A   LD     A,8
        OUT    (MAGIC),A        ; Set Expander
        XOR    A
        LD     C,A
        LD     D,A
        LD     HL,T200C
A2264   OUT    (XPAND),A
        LD     B,4
A2268   LD     A,(HL)
        LD     (IY),A           ; Expand M. S. nybble
        LD     (IY+1),A         ; Expand L. S. nybble
        LD     A,(IX)           ; Resulting data
        CP     D
        JR     NZ,A228C         ; Bad expand
        LD     A,(IX+1)
        CP     D
        JR     NZ,A228C         ; Bad expand
        INC    HL
        DJNZ   A2268
        LD     A,D
        ADD    A,01010101B
        LD     D,A
        LD     A,C
        ADD    A,0101B
        LD     C,A
        CP     14H
        JR     NZ,A2264
        JR     A2293
;
A228C   LD     E,12H            ; Error 12 Expander error
        LD     HL,A2293
A2291   JR     A22CB
;
;**********************************************************
;* OR/XOR write, OR/XOR Intercept test
;**********************************************************
;
A2293   LD     A,10H            ; Set for OR write
        CALL   A22CE
        CALL   A22E3
        CP     1
        JR     Z,A22BB          ; OR write error
        CP     2
        JR     Z,A22B7          ; OR intercept error
T22A3   LD     A,20H            ; Set for XOR write
        CALL   A22CE
        INC    L
        CALL   A22E3
        CP     1
        JR     Z,A22C2          ; XOR Write error
        CP     2
        JR     Z,A22C6          ; XOR intercept error
        JP     A233A
;
A22B7   LD     E,10H            ; Error 10 OR intercept err.
        JR     A22BD
;
A22BB   LD     E,8              ; Error 8 OR Write error
A22BD   LD     HL,T22A3
        JR     A22CB
;
A22C2   LD     E,9              ; Error 9 XOR Write error
        JR     A22C8
;
A22C6   LD     E,11H            ; Error 11 XOR intercept err.
A22C8   LD     HL,A233A
A22CB   JP     A23E6
;
A22CE   OUT    (MAGIC),A
        IN     A,(INTST)        ; Clear intercept status
        LD     HL,104H
        XOR    A
        LD     D,A
        LD     E,A
        LD     C,A
        LD     L,A
        LD     B,4
        RET
;
A22DD   LD     A,1              ; Write error
        RET
;
A22E0   LD     A,2              ; Intercept error
        RET
;
A22E3   CALL   A2333
        CALL   A2333
        CALL   A2333
        XOR    A
        CP     L
        JR     NZ,A22F4
        LD     A,D
        OR     C
        JR     A22F6
;
A22F4   LD     A,D
        XOR    C
A22F6   CP     (IX)
        JR     NZ,A22DD         ; Write error
        LD     A,C
        AND    A
        JR     Z,A2306          ; 0 write = no intercept check
        IN     A,(INTST)        ; Get intercept status
        CP     E
        JR     NZ,A22E0         ; Intercept error
        JR     A230B
;
A2306   IN     A,(INTST)
        CP     C
        JR     NZ,A22E0         ; Intercept error
A230B   LD     A,C
        ADD    A,H
        LD     C,A
        DJNZ   A22E3
        LD     BC,400H
        SRL    E
        SLA    H
        SLA    H
        JR     NC,A22E3
        RL     H
        LD     A,E
        AND    A
        JR     NZ,A2325
        LD     E,88H
        JR     A2327
;
A2325   SRL    E
A2327   LD     A,D
        ADD    A,55H
        LD     D,A
        LD     BC,400H
        LD     E,88H
        JR     NC,A22E3
        RET
;
A2333   LD     (IX),D
        LD     (IY),C
        RET
;
;**********************************************************
;* Trigger/Joystick test
;**********************************************************
;
A233A   LD     B,255
A233C   IN     A,(VERAF)        ; Clear feedback registers
        IN     A,(HORAF)
        LD     C,SW0
A2342   IN     A,(C)
        AND    A
        JP     NZ,A23C8         ; ERROR 13
        INC    C
        LD     A,C
        CP     SW3+1
        JR     NZ,A2342
;
T234E   IN     A,(KEY0)
        IN     A,(KEY1)
        IN     A,(KEY2)
        IN     A,(KEY3)
        LD     C,POT0
A2358   IN     A,(C)
        CP     0FFH
        JR     NZ,A23CF         ; Error 14
        INC    C
        LD     A,C
        CP     POT3+1
        JR     NZ,A2358
        DJNZ   A233C

;
;**********************************************************
;* Exercise output ports
;**********************************************************
;
        LD     B,255
A2368   LD     A,0
        OUT    (CONCM),A        ; Set consumer mode
        LD     A,B
        OUT    (COL0R),A
        OUT    (COL0L),A
        OUT    (COL1R),A
        OUT    (COL1L),A
        OUT    (COL2R),A
        OUT    (COL2L),A
        OUT    (COL3R),A
        OUT    (COL3L),A
        LD     A,20
        OUT    (HORCB),A
        LD     A,100*2
        OUT    (VERBL),A
        LD     D,B
        LD     HL,T23DE
        LD     B,8
        LD     C,COLBX          ; Color multiple port
        OTIR
        LD     HL,T23D6
        LD     B,8
        LD     C,SNDBX          ; Sound multiple port
        OTIR
        LD     A,0FFH
        OUT    (VOLN),A
        OUT    (VOLAB),A
        OUT    (VIBRA),A
        LD     A,D
        OUT    (TONMO),A
        OUT    (TONEA),A
        OUT    (TONEB),A
        OUT    (TONEC),A
        OUT    (VOLC),A
        LD     B,D
        DJNZ   A2368
        DI
        EXX
        LD     A,C
        BIT    7,A
        JR     Z,A23BF
        INC    C                ; Increment loop counter
        LD     A,C
        CP     84H
        JR     NZ,A23C3         ; Not done
;
        EXX                     ; Done with tests
        EI
A23BD   JR     A23BD            ; Loop forever, but process interrupts
;

A23BF   AND    A                ; C,7=0 and 6-0 not 0
        JR     NZ,A23C3
        INC    C
A23C3   EXX
        EI
        JP     A211B            ; Start tests over
;
A23C8   LD     E,13H            ; Error 13 Trigger/Joystick
        LD     HL,T234E
        JR     A23E6
;
A23CF   LD     E,14H            ; Error 14 Pot Error
        LD     HL,A2368
        JR     A23E6
;
; Sound port values
T23D6   DB     48H              ; 17H
        DB     44H              ; 16H
        DB     34H              ; 15H
        DB     0                ; 14H
        DB     0FFH             ; 13H
        DB     0FDH             ; 12H
        DB     0F5H             ; 11H
        DB     0F5H             ; 10H
;
; Color port values
T23DE   DB     0DBH             ; 07
        DB     92H              ; 06
        DB     49H              ; 05
        DB     0                ; 04
        DB     0DBH             ; 03
        DB     92H              ; 02
        DB     49H              ; 01
        DB     0                ; 00
;
;**********************************************************
;* Error routine. Enter E = error code #, C = error data
;**********************************************************
;
A23E6   DI
        EXX
        LD     A,C
        EXX
        AND    0FH
        AND    A
        JR     Z,A243F
T23EF   LD     A,E
        OUT    (DSPLY),A        ; Send error code
        LD     HL,T23F7
        JR     A2430
;
T23F7   LD     A,C
        OUT    (DSPLY),A
        LD     HL,T23FF
        JR     A2430
;
T23FF   LD     A,0CBH           ; "HE"
        OUT    (DSPLY),A
        LD     HL,T2408
        JR     A2430
;
T2408   LD     A,0DEH           ; "LP"
        OUT    (DSPLY),A
        LD     HL,T2411
        JR     A2430
;
T2411   EXX
        LD     A,B
        EXX
        LD     HL,T2420
        AND    A
        JR     NZ,A241C
        LD     A,0A0H           ; "-0"
A241C   OUT    (DSPLY),A
        JR     A2430
;
T2420   LD     A,0AAH           ; "--"
        OUT    (DSPLY),A
        LD     HL,T2429
        JR     A2430
;
T2429   LD     A,0AAH           ; "--"
        OUT    (DSPLY),A
        LD     HL,T23EF         ; Circle back for error report

;
;**********************************************************
;* Display delay routine
;**********************************************************
;
A2430   LD     D,2
A2432   LD     A,255
A2434   LD     B,255
A2436   DJNZ   A2436
        DEC    A
        JR     NZ,A2434
        DEC    D
        JR     NZ,A2432
        JP     (HL)
;
A243F   EI
        JP     (HL)
EJECT
T2441   DB     'ENTR 4-DIGT HEX',0
T2451   DB     'READ ADDR',0
T245B   DB     'WRITE ADDR',0
T2466   DB     'ENTR 2-DIGT HEX',0
T2476   DB     'READ PORT',0
T2480   DB     'WRITE PORT',0
T248B   DB     'STRT ADDR',0
T2495   DB     'ENTR 2-DIGT HEX',0
T24A5   DB     'DATA',0
T24AA   DB     'BYTE TO WRITE',0
T24B8   DB     '**',0
T24BB   DB     '****',0
;
T24C0   DB     '0E='
        DB     '0F='
        DB     '   '
        DB     '   '
        DB     '10='
        DB     '11='
        DB     '12='
        DB     '13='
T24D8   DB     '14='
        DB     '15='
        DB     '16='
        DB     '17='
        DB     '   '
        DB     '1C='
        DB     '1D='
        DB     '1E='
        DB     '1F='
T24F3   DB     '"GO" TO RUN',0
;
;**********************************************************
;* GENERAL USE SUBROUTINES
;**********************************************************
;
;
;**********************************************************
;* Set colors for special routines
;**********************************************************
;
A24FF   XOR    A
        OUT    (COL0L),A
        OUT    (COL0R),A
        OUT    (HORCB),A
        LD     A,0FH
        OUT    (COL1R),A
        OUT    (COL2R),A
        OUT    (COL3R),A
        SYSSUK FILL             ; Screen Fill Subroutine
        DW     NORMEM           ;    First byte
        DW     4016             ;    Number of bytes
        DB     0                ;    Data to fill with
        RET
;
A2516   SYSSUK STRDIS           ; Display String Subroutine
        DB     4                ;    X coordinate 
        DB     40               ;    Y coordinate
        DB     00001100B        ;    Options (On Color 03H)
        DW     T2441            ;    'ENTR 4-DIGT HEX'
        RET
;
A251E   SYSSUK STRDIS           ; Display String Subroutine
        DB     4                ;    X coordinate 
        DB     50               ;    Y coordinate
        DB     00001100B        ;    Options (On Color 03H)
        DW     T2451            ;    'READ ADDR'
        RET
;
A2526   SYSSUK STRDIS           ; Display String Subroutine
        DB     4                ;    X coordinate 
        DB     40               ;    Y coordinate
        DB     00001100B        ;    Options (On Color 03H)
        DW     T2466            ;    'ENTR 2-DIGT HEX'
        RET
;
A252E   SYSSUK STRDIS           ; Display String Subroutine
        DB     4                ;    X coordinate 
        DB     40               ;    Y coordinate
        DB     00001100B        ;    Options (On Color 03H)
        DW     T2495            ;    'ENTR 4-DIGT HEX'
        SYSSUK STRDIS           ; Display String Subroutine
        DB     4                ;    X coordinate 
        DB     50               ;    Y coordinate
        DB     00001100B        ;    Options (On Color 03H)
        DW     T24AA            ;    'BYTE TO WRITE'
        RET
;
;**********************************************************
;* Display character in A
;**********************************************************
;
A253D   LD     C,00001100B      ;    Options (On Color 03H)
A253F   LD     IX,FNTSML        ;    Unnecessary instruction
        SYSTEM CHRDIS           ; Display Character Subroutine
	RET
;
;**********************************************************
;* Hex nybble to ASCII byte
;**********************************************************
;
A2546   CP     10
        JP     M,A254D          ; Could be JR C,
        ADD    A,7
A254D   ADD    A,'0'
        RET
;
A2550   PUSH   DE
        PUSH   HL
        LD     A,255
        LD     (TIMOUT),A       ; 4 min 15 sec timeout
A2557   SYSSUK SENTRY           ; Sense Transition Subroutine
        DW     T2008            ;    Key Mask Address
        CP     SKYD
        JR     NZ,A2557         ; Wait for key
        LD     A,B
        CP     16
        JR     NZ,A2565
        XOR    A
A2565   CP     20
        JP     P,A256E          ; Keys 20-24
        LD     B,A              ; Keys 1-19
        CALL   A2546
A256E   POP    HL
        POP    DE
        RET
;
; Get 2 or 4 hex digits from keypad
; A=0=2 digits
A2571   PUSH   AF
        AND    A
        JR     NZ,A257E
A2575   SYSSUK STRDIS           ; Display 2 asterisks
        DB     72               ;    X coordinate 
        DB     70               ;    Y coordinate 
        DB     00001100B        ;    Options (On Color 03H)
        DW     T24B8            ;    '**'
        JR     A2585
;
A257E   SYSSUK STRDIS           ; Display 4 asterisks
        DB     72               ;    X coordinate 
        DB     70               ;    Y coordinate 
        DB     00001100B        ;    Options (On Color 03H)
        DW     T24BB            ;    '****'
A2585   LD     HL,0
        CALL   A2550
        CP     24
        JR     Z,A25CD          ; "GO" key
        CP     21
        JR     Z,A2575          ; "CE" key
        XYRELL DE,72,70
        CALL   A253D
        LD     A,B
        CALL   A2003            ; Mul A by 16
        LD     H,A              ; First nybble
        CALL   A2550
        CP     21
        JR     Z,A2575          ; "CE" key
        CALL   A253D
        LD     A,H
        OR     B
        LD     H,A              ; Second nybble
        POP    AF
        AND    A
        JR     NZ,A25B0
        RET
;
A25B0   PUSH   AF
        CALL   A2550
        CP     21
        JR     Z,A257E          ; "CE" key
        CALL   A253D
        LD     A,B
        CALL   A2003            ; Mul A by 16
        LD     L,A
        CALL   A2550
        CP     21
        JR     Z,A257E          ; "CE" key
        CALL   A253D
        LD     A,L
        OR     B
        LD     L,A
A25CD   POP    AF
        RET
;
; Fixed delay routine
A25CF   LD     A,255
A25D1   LD     B,255
A25D3   DJNZ   A25D3
        DEC    A
        JR     NZ,A25D1
        RET
;
; Special routine 1     Memory Read Routine
;
A25D9   CALL   A24FF            ; Set colors
        CALL   A2516            ; "ENTR 4-DIGT HEX"
        CALL   A251E            ; "READ ADDR"
        LD     A,1              ; Get 4 digits
        CALL   A2571
A25E7   LD     A,(HL)
        JR     A25E7            ; Loop forever
;
; Special routine 2     Memory Write Routine
;
A25EA   CALL   A24FF            ; Set colors
        CALL   A252E            ; "ENTR 2-DIGT BYTE TO WRITE"
        XOR    A                ; Get 2 digits
        CALL   A2571
        PUSH   HL               ; Save
        LD     A,H
        OUT    (DSPLY),A        ; Put digits on display
        CALL   A25CF            ; Delay
        CALL   A24FF            ; Clear screen
        CALL   A2516            ; "ENTR 4-DIGT HEX"
        SYSSUK STRDIS
        DB     4
        DB     50
        DB     00001100B
        DW     T245B            ; 'WRITE ADDR'
        LD     A,1              ; Get 4 digits
        CALL   A2571
        POP    BC
A260E   LD     (HL),B
        JR     A260E            ; Loop forever
;
; Special routine 3     Input Port Read Routine
;
A2611   CALL   A24FF            ; Set colors
        CALL   A2526            ; "ENTR 2-DIGT HEX"
        SYSSUK STRDIS
        DB     4
        DB     50
        DB     00001100B
        DW     T2476            ; 'READ PORT'
        XOR    A
        CALL   A2571
        LD     C,H
A2623   IN     A,(C)
        JR     A2623            ; Loop forever
;
; Special routine 4     Output Port Write Routine
;
A2627   CALL   A24FF            ; Set colors
        CALL   A2526            ; "ENTR 2-DIGT HEX"
        SYSSUK STRDIS
        DB     4
        DB     50
        DB     00001100B
        DW     T2480            ; 'WRITE PORT'
        XOR    A
        CALL   A2571
        PUSH   HL
        LD     A,H
        OUT    (DSPLY),A
        CALL   A25CF
        CALL   A24FF
        CALL   A252E            ; "ENTR 2-DIGT BYTE TO WRITE"
        XOR    A
        CALL   A2571
        POP    BC
        LD     C,B
A264B   OUT    (C),H
        JR     A264B
;
; Special routine 5     Memory Read and Write Routine
;
A264F   CALL   A24FF            ; Set colors
        CALL   A252E            ; "ENTR 2-DIGT BYTE TO WRITE"
        XOR    A                ; Get 2 digits
        CALL   A2571
        PUSH   HL               ; Save
        LD     A,H
        OUT    (DSPLY),A        ; Send to display
        CALL   A25CF            ; Delay
        CALL   A24FF            ; Clear screen
        CALL   A2516            ; "ENTR 4-DIGT HEX"
        CALL   A251E            ; "READ ADDR"
        LD     A,1              ; Get 4 digits
        CALL   A2571
        POP    BC
A266F   LD     (HL),B
        LD     A,(HL)
        JR     A266F            ; Loop forever
;
; Special routine 6     Display all Input Devices
;
A2673   CALL   A24FF
        LD     HL,T24C0         ; Labels
        XYRELL DE,4,10
        CALL   A26FB
        LD     HL,T24D8         ; Labels
        XYRELL DE,80,0
        CALL   A26FB
        EX     AF,AF'
        XOR    A
        EX     AF,AF'
        LD     HL,T2010         ; Set interrupt routine adrs.
        LD     A,H
        LD     I,A
        LD     A,L
        OUT    (INFBK),A
        LD     A,3
        OUT    (INMOD),A
        EI
A2699   IN     A,(SW0)
        XYRELL DE,28,50
        CALL   A2711
        IN     A,(SW1)
        XYRELL DE,28,60
        CALL   A2711
        IN     A,(SW2)
        XYRELL DE,28,70
        CALL   A2711
        IN     A,(SW3)
        XYRELL DE,28,80
        CALL   A2711
        IN     A,(KEY0)
        XYRELL DE,104,0
        CALL   A2711
        IN     A,(KEY1)
        XYRELL DE,104,10
        CALL   A2711
        IN     A,(KEY2)
        XYRELL DE,104,20
        CALL   A2711
        IN     A,(KEY3)
        XYRELL DE,104,30
        CALL   A2711
        IN     A,(POT0)
        XYRELL DE,104,50
        CALL   A2711
        IN     A,(POT1)
        XYRELL DE,104,60
        CALL   A2711
        IN     A,(POT2)
        XYRELL DE,104,70
        CALL   A2711
        IN     A,(POT3)
        XYRELL DE,104,80
        CALL   A2711
        JR     A2699            ; Loop forever
;
; Display input port labels
;
A26FB   LD     B,3              ; 3 char/line
A26FD   LD     A,(HL)           ; Get character
        CALL   A253D            ; Display
        INC    HL
        DJNZ   A26FD            ; Do all 3
        LD     A,E              ; Get horizontal pos'n
        SUB    18H              ; Reduce 3 char positions
        LD     E,A
        LD     A,D              ; Get vertical position
        ADD    A,10             ; Increment by 1 line
        LD     D,A              ;  (10 pixels)
        CP     90
        JR     NZ,A26FB         ; Line 80 is last line
        RET
;
; Display A in ASCII
;
A2711   LD     H,A              ; Save input value
        AND    0F0H             ; M. S. nybble first
        RRCA
        RRCA
        RRCA
        RRCA
        CALL   A2546            ; Convert to ASCII
        CALL   A253D            ; Display
        LD     A,H              ; L. S. nybble last
        AND    0FH
        CALL   A2546            ; Convert to ASCII
        CALL   A253D            ; Display
        RET
;
; Interrupt routine for Display ALL Input Devices
;
A2728   DI
        EX     AF,AF'
        AND    A
        JR     Z,A2744
        EX     AF,AF'
        IN     A,(VERAF)        ; Get vertical Lite Pen
        SRL    A
        XYRELL DE,28,10
        CALL   A2711
        IN     A,(HORAF)        ; Get horizontal Lite Pen
        SUB    8
        XYRELL DE,28,20
        CALL   A2711
A2742   EI
        RET
;
A2744   INC    A
        EX     AF,AF'
        JR     A2742
;
; Special Routine 7     Rainbow Color Display
;
A2748   LD     DE,NORMEM
        LD     HL,T27A6
        LD     BC,20
        LDIR                    ; Put up rainbow pattern
        LD     HL,NORMEM
        LD     BC,0FDCH
        LDIR                    ; Fill rest of screen
        LD     HL,T2012         ; Set up interrupt adrs
        LD     A,H
        LD     I,A
        LD     A,L
        OUT    (INFBK),A
        LD     A,20
        OUT    (HORCB),A        ; Middle of screen
        XYRELL BC,INLIN,0F8H    ; Output port, mask
        XYRELL DE,0,32
        LD     HL,NORMEM+4096
        LD     A,4              ; Color 0, intensity 4
        OUT    (C),E            ; Interrupt line 0
        EI
        HALT                    ; Wait for interrupt
;
A2777   DI
        OUT    (COL0R),A        ; Intensity 4
        INC    A
        OUT    (COL1R),A        ; Intensity 5
        INC    A
        OUT    (COL2R),A        ; Intensity 6
        INC    A
        OUT    (COL3R),A        ; Intensity 7
        AND    B                ; Reset to intensity 0
        OUT    (COL0L),A        ; Intensity 0
        INC    A
        OUT    (COL1L),A        ; Intensity 1
        INC    A
        OUT    (COL2L),A        ; Intensity 2
        INC    A
        OUT    (COL3L),A        ; Intensity 3
        ADD    A,9              ; Intensity 4, next color
        INC    E                ; Increment interrupt line #
        INC    E
        INC    E
        INC    E
        INC    E
        INC    E
        DEC    D
        JP     NZ,A27A0         ; Finish 32 bands
        XYRELL DE,0,32          ; Reset to top
        LD     A,4              ; Reset to color 0, intens 4
A27A0   OUT    (C),E            ; Line 5,10,15,...155
                                ; (32 different bands)
        POP    IX               ; Clear stack
        EI
        HALT                    ; Wait for next interrupt
;
; Rainbow pixel pattern
T27A6   DB     0,0,0,0,0                        ; Color 0
        DB     55H,55H,55H,55H,55H              ; Color 1
        DB     0AAH,0AAH,0AAH,0AAH,0AAH         ; Color 2
        DB     0FFH,0FFH,0FFH,0FFH,0FFH         ; Color 3
;
; Special Routine 8     Enter Machine Code From Keypad
A27BA   CALL   A24FF            ; Set colors
        CALL   A2516            ; "ENTR 4-DIGT HEX"
        SYSSUK STRDIS
        DB     4
        DB     50
        DB     00001100B
        DW     T248B            ; 'STRT ADDR'
        LD     A,1              ; Get 4 digits
        CALL   A2571
        PUSH   HL               ; Save start
        PUSH   HL
        CALL   A25CF
        CALL   A24FF
        SYSSUK STRDIS
        DB     4
        DB     40
        DB     00001100B
        DW     T2495            ; 'ENTR 2-DIGT HEX'
        SYSSUK STRDIS
        DB     4
        DB     50
        DB     00001100B
        DW     T24A5            ; 'DATA'
        SYSSUK STRDIS
        DB     4
        DB     90
        DB     00001100B
        DW     T24F3            ; '"GO" TO RUN'
A27E9   CALL   A25CF            ; Delay
        XOR    A                ; Get 2 digits
        CALL   A2571
        LD     A,B
        CP     24
        JR     NZ,A27F8
        POP    HL               ; "GO" key
        POP    HL
        JP     (HL)
;
A27F8   POP    DE
        LD     A,H
        LD     (DE),A
        INC    DE
        PUSH   DE
        JR     A27E9
;
        DB     37H              ; Checksum byte
;
;       END                     ; End of program
