;CONTROLLER FOR MAME DUAL HOME GAME INTERFACE PIC17C42A

;(C) 2003 LUPINE SYSTEMS, LTD.
;USE OF THIS CODE IS LICENSED AND LIMITED TO PRIVATE
;NON-COMMERCIAL HOME USE ONLY AND MAY NOT BE REPRODUCED OR
;REDISTRIBUTED IN WHOLE OR IN PART FOR ANY REASON WITHOUT 
;PRIOR CONSENT FROM LUPINE SYSTEMS, LTD.

;PROGRAM WRITTEN BY SPIKE TSASMALI

;CLOCK EXTERNAL, 8MHz

;SET ASSEMBLER RADIX FOR DECIMAL

;SET PROGRAMMING OPTIONS FOR

;OSCILLATOR:  XT
;WATCHDOG TIMER: TMR
;PROCESSOR MODE:  PROT. MICROCONTROLLER


;DIP SWITCHES

;DIP SW 1 CONTROLS GAME 1 ADJUSTMENTS

; 1-2-3-4  SETS DELAY TIME BETWEEN GAME CHANGE
; 5-6-7    NUMBER OF "ENTER" KEYSTROKES AFTER DELAY
; 8	   ONE OR TWO GAMES IN CABINET

;DIP SW 2 CONTROLS GAME 2 ADJUSTMENTS


; 1-2-3-4  SETS DELAY TIME BETWEEN GAME CHANGE
; 5-6-7    NUMBER OF "ENTER" KEYSTROKES AFTER DELAY
; 8	   SWAP GAME START ORDER FROM 1-2 TO 2-1

PWR_ON_DEL	EQU	010	;POWER ON DELAY IN SECONDS

;************************************************************************
;************************************************************************

; THIS DATA TABLE CONTAINS THE KEY STROKE CODES FOR EACH OF
; THE JAMMA INPUTS.  IT MAY BE NECESSARY TO ADJUST THESE FOR
; PARTICULAR GAMES.  REFER TO THE IBM SCAN CODE SET 2 KEY 
; CODE CHART FOR MORE INFORMATION.

; EXAMPLE:  USING THE FIRST ENTRY AS A SAMPLE...

; I11CODE IS THE ASSEMBLER LABEL AND SHOULD NEVER BE CHANGED.
; EQU IS THE ASSEMBLER COMMAND AND SHOULD NEVER BE CHANGED.
; 0x06 IS THE IBM SCAN CODE FOR THE KEY F2 AS SHOWN TO THE RIGHT.
; KEY 11 REFERS TO THE SCAN ORDER FOR WHICH THE KEY IS SCANNED.
; F2 IS THE IBM KEYBOARD KEY CORRESPONDING TO THE HEX SCAN CODE.
; (SERVICE) IS THE JAMMA SWITCH NAME REPRESENTED BY THE I11 INPUT.

; WHEN MAKING CHANGES TO THIS DATA TABLE, YOU WILL NEED TO KNOW
; WHICH KEY YOU NEED TO DO A SPECIFIC TASK; I.E. YOU WOULD NEED
; TO KNOW THAT THE "SPACE BAR" IS PLAYER 1 BUTTON 3.  YOU NEED
; TO KNOW THIS BEFORE YOU BEGIN.  THEN, CHANGE THE HEX CODE 
; FOLLOWING THE EQU DIRECTIVE TO THE APPROPRIATE SCAN CODE AS 
; DEFINED IN THE IBM SCAN CODE SET 2 CHART, THEN BE SURE TO CHANGE
; THE INFORMATION TO THE FAR RIGHT PAST THE SEMICOLON FOR YOUR
; FUTURE REFERENCE.

; ONCE YOU HAVE CHANGED THE INFORMATION, YOU MUST SAVE THE FILE 
; AND RE-ASSEMBLE USING THE PULL-DOWN MENU PROJECT, BUILD ALL.
; ONCE BUILT, YOU CAN NOW PROGRAM A NEW PIC WITH THE MODIFIED
; KEYBOARD ENTRY TABLE.

;************************************************************************
;************************************************************************

;LABEL NAME     DIR   SCAN CODE  FUNCTION KEY          JAMMA

I11CODE         EQU	0x06  	;KEY 11   F2           (SERVICE)
I12CODE         EQU 	0x07   	;KEY 12   F12          (TEST)
I13CODE		EQU	0x26	;KEY 13   3#           (COIN 1)
I14CODE         EQU    	0x25   	;KEY 14   4$           (COIN 2)
I15CODE         EQU    	0x16	;KEY 15   1!           (1 START)
I16CODE         EQU    	0x1E  	;KEY 16   3#           (2 ST)
I17CODE         EQU   	0x75   	;KEY 17   ARROW UP*    (1 UP)
I18CODE         EQU    	0x2D   	;KEY 18   R            (2 UP)

I21CODE         EQU   	0x72   	;KEY 21   ARROW DOWN*  (1 DOWN)
I22CODE         EQU    	0x23  	;KEY 22   D            (2 DOWN)
I23CODE         EQU    	0x6B   	;KEY 23   ARROW LEFT*  (LEFT)
I24CODE         EQU   	0x34  	;KEY 24   G            (2 LEFT)
I25CODE         EQU    	0x2B  	;KEY 25   F            (2 RIGHT)
I26CODE         EQU   	0x74   	;KEY 26   ARROW RIGHT* (1 RIGHT)
I27CODE         EQU   	0x1C   	;KEY 27   A            (2 P1)
I28CODE         EQU    	0x14	;KEY 28   L-CTRL       (1 P1)

I31CODE         EQU  	0x4B  	;KEY 31   L            (2 P2)
I32CODE         EQU    	0x11   	;KEY 32   L-ALT        (1 P2)
I33CODE         EQU   	0x33   	;KEY 33   H            (2 P3)
I34CODE         EQU    	0x29   	;KEY 34   SPACE        (1 P3)
I35CODE         EQU   	0x3B  	;KEY 35   J            (2 P4)
I36CODE         EQU    	0x24 	;KEY 36   E            (1 P4)
I37CODE         EQU  	0x42 	;KEY 37   K            (2 P5)
I38CODE         EQU    	0x35    ;KEY 38   Y            (1 P5)

  ;PIC SPECIAL FUNCTION REGISTERS

INDF0           EQU	0x00 	;PIC INDIRECT ADDR REG 0
FSR0            EQU	0x01  	;PIC FILE SEL REG 0
PCLO		EQU	0x02	;PROGRAM COUNTER
PCHI		EQU	0x03	;PC HI LATCH
ALUSTA		EQU	0x04	;ALU STATUS REG
CPUSTA		EQU	0x06	;CPU STATUS REG
INTSTA		EQU	0x07	;INTERRUPT STATUS REG
INDF1		EQU	0x08	;PIC INDIRECT ADDR REG 1
FSR1		EQU	0x09	;PIC FILE SEL REG 1
W               EQU	0x0A	;PIC W REGISTER
BSR             EQU	0x0F	;BANK SELECT REGISTER

PORTA           EQU	0x10 	;PORT A IN BANK0
DDRC            EQU	0x10 	;DDRC IN BANK1

DDRB            EQU	0x11 	;DDRB IN BANK0
PORTC           EQU	0x11  	;PORT C IN BANK1

PORTB           EQU 	0x12  	;PORT B IN BANK0
DDRD            EQU  	0x12  	;DDRD IN BANK1

PORTD           EQU  	0x13  	;PORT D IN BANK1

DDRE            EQU 	0x14 	;DDRE IN BANK1

PORTE           EQU	0x15 	;PORT E IN BANK1

  ;USER DEFINED REGISTERS

	CBLOCK	0x20

TXBUF           ;TRANSMIT BUFFER REGISTER
D1LOOP          ;INNER TIMING LOOP
D2LOOP          ;MIDDLE TIMING LOOP
D3LOOP          ;OUTER TIMING LOOP
BITCNTR         ;BIT COUNTER
PARITY          ;PARITY REGISTER
BSAV            ;BANK SELECT SAVE REGISTER
CONVREG         ;SERIAL CONVERSION REGISTER
TBREG           ;COPY REG FOR RESEND
INDREG          ;INDAK COUNTER
SETR            ;SCAN CODE SELECT REGISTER
JREG            ;JUNK TIMER
FLAGS           ;FLAGS REGISTER
YSAV            ;TX SAVE REGISTER
BR1             ;SWITCH FLAGS
BR2             ;SWITCH FLAGS
BR3		;SWITCH FLAGS
FINCTR		;LOOP COUNTER
D1S		;1ST 1 SEC LOOP
D2S		;2ND 1 SEC LOOP
D3S		;3RD 1 SEC LOOP
DIP1BUF		;DIP SW 1 BUFFER
DIP2BUF		;DIP SW 2 BUFFER
CURGAME		;CURRENT GAME COUNTER
EADDR		;EEPROM ADDRESS REGISTER
EDATA		;EEPROM DATA REGISTER
EBUF		;EEPROM ROUTINE BUFFER
CREG		;EEPROM UTILITY REGISTER
PATEMP		;PORT A TEMP REGISTER
METBUF		;CASH METER BUFFER
CASHREG		;CASH METER DELAY REGISTER
CRT		;CASH METER TIMER REG

	ENDC

STACKTOP        EQU	0x7F	;TOP OF KEYBOARD INPUT STACK

  ;SPECIAL IBM KEY CODES USED BY SCAN CODE SET 2

BREAKCODE       EQU	0xF0 	;KEY OPEN CODE
COMPCODE        EQU	0xAA   	;SYSTEM OK CODE
ACKCODE         EQU	0xFA  	;ACKNOLEDGE CODE
RESETCODE       EQU	0xFF   	;RESET CODE
RESENDCODE      EQU	0xFE   	;RESEND CODE
ECHOCODE        EQU	0xEE   	;ECHO CODE
TMRCODE         EQU	0xF3   	;TYPEMATIC RATE CODE
INDCODE         EQU	0xED   	;INDICATOR CODE
DDCODE          EQU	0xF5   	;DEFAULT DISABLE CODE
ENACODE         EQU   	0xF4   	;ENABLE CODE
IDCODE          EQU   	0xF2   	;READ ID CODE
ALTCODE         EQU   	0xF0   	;REQ ALT CODE
SAK1CODE        EQU   	0xF7   	;SET ALL TYPEMATIC
SAK2CODE        EQU   	0xF8   	;SET ALL M/B
SAK3CODE        EQU   	0xF9   	;SET ALL MAKE
SAK4CODE        EQU   	0xFA   	;SET KEY TYPEMATIC M/B
SKT1CODE        EQU   	0xFB   	;SET KEY TYPEMATIC
SKT2CODE        EQU    	0xFC   	;SET KEY M/B
SKT3CODE        EQU 	0xFD   	;SET KEY MAKE
DEFCODE         EQU   	0xF6   	;SET DEFAULT CODE
IDLOW           EQU   	0xAB   	;KEYBOARD ID LOW BYTE
IDHIGH          EQU    	0x83   	;KEYBOARD ID HIGH BYTE
XCODE		EQU	0xE0	;EXTENDED KEY CODE
ESCCODE		EQU	0x76	;ESC KEY

  ;USER DEFINED VARIABLES

DY1             EQU    	020   	;INNER LOOP
DY2             EQU    	030  	;MIDDLE LOOP
DY3             EQU  	01     	;OUTER LOOP
CASHDEL		EQU	04	;CASH METER DELAY

  ;BIT DEFINITIONS

#DEFINE		CARRY		ALUSTA,0	;PIC CARRY BIT
#DEFINE		Z		ALUSTA,2	;ZERO BIT

#DEFINE		GLINTD		CPUSTA,4	;GLOBAL INT DIS BIT

#DEFINE		SDIDIR		DDRE,0		;DATA DIRECTION SDI PORT

#DEFINE		SDO		PORTA,0		;SERIAL DATA FROM EEPROM

#DEFINE		ENA1		PORTB,0 	;U2 SWITCH ENABLE
#DEFINE		ENA2            PORTB,1         ;U3 SWITCH ENABLE
#DEFINE		METER		PORTB,2		;CASH METER DRIVE OUTPUT
#DEFINE		DIP2		PORTB,3		;DIP SW 2 ENABLE
#DEFINE		DIP1		PORTB,4		;DIP SW 1 ENABLE
#DEFINE		ENA3		PORTB,5		;U4 SWITCH ENABLE
#DEFINE		OSDVID		PORTB,6		;REM VIDEO ENABLE
#DEFINE		MAMEVID		PORTB,7		;MAME VIDEO ENABLE

#DEFINE         I1              PORTC,0         ;INPUT 1
#DEFINE         I2              PORTC,1         ;INPUT 2
#DEFINE         I3              PORTC,2         ;INPUT 3
#DEFINE         I4              PORTC,3         ;INPUT 4
#DEFINE         I5              PORTC,4         ;INPUT 5
#DEFINE         I6              PORTC,5         ;INPUT 6
#DEFINE         I7              PORTC,6         ;INPUT 7
#DEFINE         I8              PORTC,7         ;INPUT 8

#DEFINE         KEYCLKIN        PORTD,0         ;KEYBOARD CLOCK INPUT PIN
#DEFINE         KEYCLKOUT       PORTD,1         ;KEYBOARD CLOCK OUTPUT PIN
#DEFINE         KEYDATOUT       PORTD,2         ;KEYBOARD DATA OUTPUT PIN
#DEFINE         KEYDATIN        PORTD,3         ;KEYBOARD DATA INPUT PIN
#DEFINE		SPEC1		PORTD,4		;SPECIAL SW 1 INPUT
#DEFINE		SPEC2		PORTD,5		;SPECIAL SW 2 INPUT
#DEFINE		SPEC3		PORTD,6		;SPECIAL SW 3 INPUT
#DEFINE		SPEC4		PORTD,7		;SPECIAL SW 4 INPUT

#DEFINE         SDI             PORTE,0 	;SERIAL DATA TO EEPROM
#DEFINE         SCLK            PORTE,1 	;STROBE LINE TO EEPROM
#DEFINE         SCS             PORTE,2 	;SELECT TO EEPROM

#DEFINE         INITFLAG        FLAGS,0         ;RE-INITIALIZE FLAG BIT
#DEFINE         ERBIT           FLAGS,1         ;ERROR IN SEND OR INDAK FLAG
#DEFINE		SECONDPASS	FLAGS,2		;SECOND PASS FLAG
#DEFINE		CASHBIT		FLAGS,3		;CASH METER FLAG
#DEFINE		SPEC1FLAG	FLAGS,4		;SPECIAL SW 1 FLAG
#DEFINE		SPEC2FLAG	FLAGS,5		;SPECIAL SW 2 FLAG
#DEFINE		SPEC3FLAG	FLAGS,6		;SPECIAL SW 3 FLAG
#DEFINE		SPEC4FLAG	FLAGS,7		;SPECIAL SW 4 FLAG

;*****************************************************************************

;MACRO DEFINITIONS 

;*****************************************************************************

BANK0   MACRO
        MOVLB   00
        ENDM

BANK1   MACRO
        MOVLB   01
        ENDM

BANK2	MACRO
	MOVLB	02
	ENDM

BANK3	MACRO
	MOVLB	03
	ENDM

;************************************************************************

	ORG	0x00

;*****************************************************************************
;*****************************************************************************
;*****************************************************************************

;HOUSEKEEPING SECTION

;INITIALIZE PIC

;*****************************************************************************

INIT    BSF	GLINTD		;OFF INT'S

	BANK0
	MOVLW	B'11111000'
	MOVWF	PORTB		;PRE-SET PORT B
        MOVLW   B'00000000'
        MOVWF   DDRB         	;DIRECTION PORT B
        BANK1
        MOVLW   B'11111111'
        MOVWF   DDRC
        MOVLW   B'11111111'
        MOVWF   DDRD
        MOVLW   B'00000000'
        MOVWF   DDRE       	;DIRECTION PORT D,E
        MOVLW   B'11111111'
        MOVWF   PORTC          	

	BANK0
	BCF	MAMEVID		;OFF MAME VIDEO
	BSF	OSDVID		;ON REM VIDEO
	
	BSF	DIP1
	BSF	DIP2
	BSF	ENA1
	BSF	ENA2
	BSF	ENA3		;CLEAR ALL ENABLES

        MOVLW   40		;KEYBOARD POWER ON DELAY (REQUIRED)
        MOVWF   JREG
PWRDX   CALL    DELAY
        CALL    DELAY
        CALL    DELAY
        DECFSZ  JREG,1
        GOTO    PWRDX

        MOVLW   COMPCODE
        CALL    SEND          	;SEND DIAGS COMPLETE CODE (REQUIRED)

        BANK1
        CLRF    FLAGS,1        	;CLEAR FLAGS
        CLRF    PORTC,1        	;CLEAR DATA BUS
	CLRF	METBUF,1	;CLEAR METER BUFFER
	CLRF	CRT,1		;CLEAR METER TIMER REG
	CLRF	CURGAME,1	;CURRENT GAME IS SET FOR 1

        SETF    BR1,1                   
        SETF    BR2,1         	;CLEAR SWITCH FLAGS
        SETF	BR3,1		;ACTIVE LOW
	BSF	SPEC1FLAG	;SPECIAL SWITCH FLAGS
	BSF	SPEC2FLAG
	BSF	SPEC3FLAG
	BSF	SPEC4FLAG		
	
	MOVLW	PWR_ON_DEL	;EXECUTE POWER ON DELAY -- ALLOW
	MOVWF	FINCTR		;PC TO LOAD DOS AND DRIVERS
PDXL	CALL	SEC1DELAY
	DECFSZ	FINCTR,1
	GOTO	PDXL
	
	CALL	ENTRKEY		;SEND ENTER KEY
	CALL	ENTRKEY		;THIS INSURES CONSOLE IS CLEAR
	CALL	ENTRKEY
	CALL	ENTRKEY
	
  ;READ DIP SWITCHES

	BANK0
	BCF	DIP1		;ENABLE DIP SW 1
	BANK1
	MOVPF	PORTC,DIP1BUF	;SAVE DIP SW 1 DATA
	BANK0
	BSF	DIP1
	BCF	DIP2
	BANK1
	MOVPF	PORTC,DIP2BUF	;SAVE DIP SW 2 DATA
	BANK0
	BSF	DIP1
	BSF	DIP2
	COMF	DIP1BUF,1
	COMF	DIP2BUF,1	;COMPLIMENT DATA
	
	MOVLW	CASHDEL		;INITIALIZE CASH METER TIMER
	MOVWF	CASHREG
	 
  ;LOAD GAME ON PC

	BTFSS	DIP2BUF,0	;SWAP GAME ORDER?
	GOTO	STG		;GAME 1 LOAD ROUTINE
	INCF	CURGAME,1
	GOTO	STG		;SWAP START ORDER
	
;*****************************************************************************
;*****************************************************************************
;*****************************************************************************

;PC KEYBOARD ENCODER SECTION

;MAIN LOOP AND SWITCH SCAN ROUTINE

;*****************************************************************************

SCANSW	CALL    PROCLKOL
        BTFSC   INITFLAG      	;CHECK INIT FLAG (FROM RESET COMMAND)
        GOTO    INIT           	;RESTART SYSTEM
        CALL    PROCLKOL      	;CHECK FOR PC COMMUNICATION

  ;UPDATE CASH METER

F1T	BTFSC	CASHBIT		;IS THERE ALREADY A PULSE IN PROGRESS?
	GOTO	CMPULSE
	
	BTFSC	SECONDPASS	;IS THIS A SECOND PASS TIMEOUT?
	GOTO	SECPASS

	TSTFSZ	METBUF		;ARE THERE STILL SOME PULSES LEFT?
	GOTO	NEWPULSE
	GOTO	BSC		;THERE ARE NO METER PULSES LEFT

CMPULSE	DECFSZ	CRT,1		;TIME OUT YET?
	GOTO	BSC		;NOT YET...
	DECFSZ	CASHREG,1	;TIME OUT?
	GOTO	BSC
	BCF	CASHBIT		;RESET IN PROGRESS BIT	
	BANK0
	BCF	METER		;TURN OFF METER
	MOVLW	CASHDEL		;RESTORE TIMER
	MOVWF	CASHREG
	BSF	SECONDPASS	;SET SECOND PASS BIT
	GOTO	BSC		;DONE WITH THIS PULSE...

SECPASS	DECFSZ	CRT,1		;TIME OUT AS USUAL...
	GOTO	BSC		;NOT YET..
	DECFSZ	CASHREG,1	;TIME OUT?
	GOTO	BSC
	BCF	SECONDPASS	;RESET SECOND PASS BIT
	MOVLW	CASHDEL
	MOVWF	CASHREG		;RESTORE DELAY TIME
	GOTO	BSC		;END OF THIS PULSE

NEWPULSE
	DECF	METBUF,1	;DECREMENT METER BUFFER
	BANK0
	BSF	METER		;TURN ON CASH METER
	BSF	CASHBIT		;SET PULSE IN PROGRESS BIT

  ;BEGIN SCANNING SWITCHES

BSC	BANK0
	BSF	ENA3		;START SCAN OVER AGAIN
	BSF	ENA2
	BCF	ENA1

	BANK1
	BTFSS   I1          	;INPUT 1 CLOSURES
        GOTO    K11  
K11R  	BTFSS   I2
        GOTO    K12
K12R    BTFSS   I3
        GOTO    K13
K13R	BTFSS   I4
        GOTO    K14
K14R	BTFSS   I5
        GOTO    K15
K15R	BTFSS   I6
        GOTO    K16
K16R	BTFSS   I7
        GOTO    K17
K17R	BTFSS   I8
        GOTO    K18

K18R	BTFSC   I1         	;INPUT 1 OPENS
        GOTO    K11B  
K11BR  	BTFSC   I2
        GOTO    K12B
K12BR   BTFSC   I3
        GOTO    K13B
K13BR	BTFSC   I4
        GOTO    K14B
K14BR	BTFSC   I5
        GOTO    K15B
K15BR	BTFSC   I6
        GOTO    K16B
K16BR	BTFSC   I7
        GOTO    K17B
K17BR	BTFSC   I8
        GOTO    K18B

K18BR	BANK1
	BTFSS   KEYDATIN	;REDUNDANT KEYBOARD COM CHECK
        CALL    PROCLKOL

	BANK0
	BSF	ENA1
	BCF	ENA2		;ENABLE LINE 2
	
	BANK1
	BTFSS   I1     		;INPUT 1 CLOSURES    	
        GOTO    K21  
K21R  	BTFSS   I2
        GOTO    K22
K22R    BTFSS   I3
        GOTO    K23
K23R	BTFSS   I4
        GOTO    K24
K24R	BTFSS   I5
        GOTO    K25
K25R	BTFSS   I6
        GOTO    K26
K26R	BTFSS   I7
        GOTO    K27
K27R	BTFSS   I8
        GOTO    K28

K28R	BTFSC   I1          	;INPUT 1 OPENS
        GOTO    K21B  
K21BR  	BTFSC   I2
        GOTO    K22B
K22BR   BTFSC   I3
        GOTO    K23B
K23BR	BTFSC   I4
        GOTO    K24B
K24BR	BTFSC   I5
        GOTO    K25B
K25BR	BTFSC   I6
        GOTO    K26B
K26BR	BTFSC   I7
        GOTO    K27B
K27BR	BTFSC   I8
        GOTO    K28B

K28BR	BANK1
	BTFSS   KEYDATIN	;REDUNDANT KEYBOARD COM CHECK
        CALL    PROCLKOL

	BANK0
	BSF	ENA2
	BCF	ENA3		;ON ENABLE 3
	
	BANK1
	BTFSS   I1      	;INPUT 1 CLOSURES
        GOTO    K31  
K31R  	BTFSS   I2
        GOTO    K32
K32R    BTFSS   I3
        GOTO    K33
K33R	BTFSS   I4
        GOTO    K34
K34R	BTFSS   I5
        GOTO    K35
K35R	BTFSS   I6
        GOTO    K36
K36R	BTFSS   I7
        GOTO    K37
K37R	BTFSS   I8
        GOTO    K38

K38R	BTFSC   I1      	;INPUT 1 OPENS
        GOTO    K31B  
K31BR  	BTFSC   I2
        GOTO    K32B
K32BR   BTFSC   I3
        GOTO    K33B
K33BR	BTFSC   I4
        GOTO    K34B
K34BR	BTFSC   I5
        GOTO    K35B
K35BR	BTFSC   I6
        GOTO    K36B
K36BR	BTFSC   I7
        GOTO    K37B
K37BR	BTFSC   I8
        GOTO    K38B

K38BR	BANK0
	BSF	ENA3		;OFF ALL SWITCH INPUTS
	
	BANK1
	BTFSS   KEYDATIN	;REDUNDANT KEYBOARD COM CHECK
        CALL    PROCLKOL

  ;SPECIAL FUNCTION KEYS

	BTFSC   INITFLAG      	;RE-INIT?
        GOTO    INIT

  ;GAME CHANGE KEY HANDLER -- SPECIAL FUNCTION KEY 1

	BANK1

	BTFSS	SPEC1		;GAME CHANGE KEY
	GOTO	KSP1

KSP1R	BTFSC	SPEC1
	GOTO	KSP1B

KSP1BR	GOTO	SCANSW		;SCAN AGAIN...

;*****************************************************************************

;SWITCH PROCESSOR ROUTINES 

;*****************************************************************************

K11     BTFSS	BR1,0
	GOTO	K11R
	BCF     BR1,0
	CALL	DELAY
        MOVLW   I11CODE
	CALL	SEND
	GOTO	K11R
K11B    BTFSC   BR1,0          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K11BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,0          	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE         
        CALL    SEND       	;SEND BREAK CODE
        MOVLW	I11CODE
        CALL    SEND
	GOTO	K11BR

K12     BTFSS	BR1,1
	GOTO	K12R
	BCF     BR1,1
	CALL	DELAY
        MOVLW   I12CODE
	CALL	SEND
	GOTO	K12R
K12B    BTFSC   BR1,1         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K12BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,1      	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE    	;BREAK KEY CODE        
        CALL    SEND           	;SEND BREAK CODE
        MOVLW	I12CODE
        CALL    SEND
	GOTO	K12BR

K13     BTFSS	BR1,2		;KEY K13 IS COIN SW 1 INPUT
	GOTO	K13R
	BCF     BR1,2
	CALL	DELAY
        MOVLW   I13CODE
	CALL	SEND
	INCF	METBUF,1	;INCREMENT CASH METER
	GOTO	K13R
K13B    BTFSC   BR1,2          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K13BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,2          	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE
        CALL    SEND        	;SEND BREAK CODE
        MOVLW	I13CODE
        CALL    SEND
	GOTO	K13BR

K14     BTFSS	BR1,3		;KEY K14 IS COIN SW 2 INPUT
	GOTO	K14R
	BCF     BR1,3
	CALL	DELAY
        MOVLW   I14CODE
	CALL	SEND
	INCF	METBUF,1	;INCREMENT CASH METER
	GOTO	K14R
K14B    BTFSC   BR1,3          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K14BR      	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,3         	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE    	;BREAK KEY CODE       
        CALL    SEND        	;SEND BREAK CODE
        MOVLW	I14CODE
        CALL    SEND
	GOTO	K14BR

K15     BTFSS	BR1,4
	GOTO	K15R
	BCF     BR1,4
	CALL	DELAY
        MOVLW   I15CODE
	CALL	SEND
	GOTO	K15R
K15B    BTFSC   BR1,4         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K15BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,4        	;SET KEY CLOSURE BIT
	MOVLW   BREAKCODE     	;BREAK KEY CODE         
        CALL    SEND         	;SEND BREAK CODE
        MOVLW	I15CODE
        CALL    SEND
	GOTO	K15BR

K16     BTFSS	BR1,5
	GOTO	K16R
	BCF     BR1,5
	CALL	DELAY
        MOVLW   I16CODE
	CALL	SEND
	GOTO	K16R
K16B    BTFSC   BR1,5          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K16BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,5        	;SET KEY CLOSURE BIT
	MOVLW   BREAKCODE     	;BREAK KEY CODE
        CALL    SEND        	;SEND BREAK CODE
        MOVLW	I16CODE
        CALL    SEND
	GOTO	K16BR

K17     BTFSS	BR1,6
	GOTO	K17R
	BCF     BR1,6
	CALL	DELAY
	MOVLW	XCODE
	CALL	SEND
        MOVLW   I17CODE
	CALL	SEND
	GOTO	K17R
K17B    BTFSC   BR1,6         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K17BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,6          	;SET KEY CLOSURE BIT
        MOVLW	XCODE
	CALL	SEND
	MOVLW   BREAKCODE      	;BREAK KEY CODE 
        CALL    SEND          	;SEND BREAK CODE
        MOVLW	I17CODE
        CALL    SEND
	GOTO	K17BR

K18     BTFSS	BR1,7
	GOTO	K18R
	BCF     BR1,7
	CALL	DELAY
        MOVLW   I18CODE
	CALL	SEND
	GOTO	K18R
K18B    BTFSC   BR1,7          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K18BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR1,7        	;SET KEY CLOSURE BIT
	MOVLW   BREAKCODE     	;BREAK KEY CODE
        CALL    SEND       	;SEND BREAK CODE
        MOVLW	I18CODE
        CALL    SEND
	GOTO	K18BR

K21     BTFSS	BR2,0
	GOTO	K21R
	BCF     BR2,0
	CALL	DELAY
	MOVLW	XCODE
	CALL	SEND
        MOVLW   I21CODE
	CALL	SEND
	GOTO	K21R
K21B    BTFSC   BR2,0         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K21BR        	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,0       	;SET KEY CLOSURE BIT
	MOVLW	XCODE
	CALL	SEND
        MOVLW   BREAKCODE     	;BREAK KEY CODE         
        CALL    SEND         	;SEND BREAK CODE
        MOVLW	I21CODE
        CALL    SEND
	GOTO	K21BR

K22     BTFSS	BR2,1
	GOTO	K22R
	BCF     BR2,1
	CALL	DELAY
        MOVLW   I22CODE
	CALL	SEND
	GOTO	K22R
K22B    BTFSC   BR2,1          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K22BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,1          	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE     
        CALL    SEND          	;SEND BREAK CODE
        MOVLW	I22CODE
        CALL    SEND
	GOTO	K22BR

K23     BTFSS	BR2,2
	GOTO	K23R
	BCF     BR2,2
	CALL	DELAY
	MOVLW	XCODE
	CALL	SEND
        MOVLW   I23CODE
	CALL	SEND
	GOTO	K23R
K23B    BTFSC   BR2,2          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K23BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,2         	;SET KEY CLOSURE BIT
	MOVLW	XCODE
	CALL	SEND
        MOVLW   BREAKCODE      	;BREAK KEY CODE
        CALL    SEND          	;SEND BREAK CODE
        MOVLW	I23CODE
        CALL    SEND
	GOTO	K23BR

K24     BTFSS	BR2,3
	GOTO	K24R
	BCF     BR2,3
	CALL	DELAY
        MOVLW   I24CODE
	CALL	SEND
	GOTO	K24R
K24B    BTFSC   BR2,3          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K24BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,3        	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE     	;BREAK KEY CODE        
        CALL    SEND       	;SEND BREAK CODE
        MOVLW	I24CODE
        CALL    SEND
	GOTO	K24BR

K25     BTFSS	BR2,4
	GOTO	K25R
	BCF     BR2,4
	CALL	DELAY
        MOVLW   I25CODE
	CALL	SEND
	GOTO	K25R
K25B    BTFSC   BR2,4        	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K25BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,4        	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE         
        CALL    SEND       	;SEND BREAK CODE
        MOVLW	I25CODE
        CALL    SEND
	GOTO	K25BR

K26     BTFSS	BR2,5
	GOTO	K26R
	BCF     BR2,5
	CALL	DELAY
	MOVLW	XCODE
	CALL	SEND
        MOVLW   I26CODE
	CALL	SEND
	GOTO	K26R
K26B    BTFSC   BR2,5         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K26BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,5        	;SET KEY CLOSURE BIT
	MOVLW	XCODE
	CALL	SEND
        MOVLW   BREAKCODE     	;BREAK KEY CODE       
        CALL    SEND       	;SEND BREAK CODE
        MOVLW	I26CODE
        CALL    SEND
	GOTO	K26BR

K27     BTFSS	BR2,6
	GOTO	K27R
	BCF     BR2,6
	CALL	DELAY
        MOVLW   I27CODE
	CALL	SEND
	GOTO	K27R
K27B    BTFSC   BR2,6          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K27BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,6          	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE   	;BREAK KEY CODE
        CALL    SEND     	;SEND BREAK CODE
        MOVLW	I27CODE
        CALL    SEND
	GOTO	K27BR

K28     BTFSS	BR2,7
	GOTO	K28R
	BCF     BR2,7
	CALL	DELAY
        MOVLW   I28CODE
	CALL	SEND
	GOTO	K28R
K28B    BTFSC   BR2,7         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K28BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR2,7          	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE   
        CALL    SEND       	;SEND BREAK CODE
        MOVLW	I28CODE
        CALL    SEND
	GOTO	K28BR

K31     BTFSS	BR3,0
	GOTO	K31R
	BCF     BR3,0
	CALL	DELAY
        MOVLW   I31CODE
	CALL	SEND
	GOTO	K31R
K31B    BTFSC   BR3,0         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K31BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,0         	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE         
        CALL    SEND        	;SEND BREAK CODE
        MOVLW	I31CODE
        CALL    SEND
	GOTO	K31BR

K32     BTFSS	BR3,1
	GOTO	K32R
	BCF     BR3,1
	CALL	DELAY
        MOVLW   I32CODE
	CALL	SEND
	GOTO	K32R
K32B    BTFSC   BR3,1         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K32BR       	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,1       	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE         
        CALL    SEND         	;SEND BREAK CODE
        MOVLW	I32CODE
        CALL    SEND
	GOTO	K32BR

K33     BTFSS	BR3,2
	GOTO	K33R
	BCF     BR3,2
	CALL	DELAY
        MOVLW   I33CODE
	CALL	SEND
	GOTO	K33R
K33B    BTFSC   BR3,2        	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K33BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,2        	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE
        CALL    SEND         	;SEND BREAK CODE
        MOVLW	I33CODE
        CALL    SEND
	GOTO	K33BR

K34     BTFSS	BR3,3
	GOTO	K34R
	BCF     BR3,3
	CALL	DELAY
        MOVLW   I34CODE
	CALL	SEND
	GOTO	K34R
K34B    BTFSC   BR3,3         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K34BR        	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,3         	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE      
        CALL    SEND         	;SEND BREAK CODE
        MOVLW	I34CODE
        CALL    SEND
	GOTO	K34BR

K35     BTFSS	BR3,4
	GOTO	K35R
	BCF     BR3,4
	CALL	DELAY
        MOVLW   I35CODE
	CALL	SEND
	GOTO	K35R
K35B    BTFSC   BR3,4         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K35BR        	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,4        	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE   	;BREAK KEY CODE         
        CALL    SEND        	;SEND BREAK CODE
        MOVLW	I35CODE
        CALL    SEND
	GOTO	K35BR

K36     BTFSS	BR3,5
	GOTO	K36R
	BCF     BR3,5
	CALL	DELAY
        MOVLW   I36CODE
	CALL	SEND
	GOTO	K36R
K36B    BTFSC   BR3,5          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K36BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,5         	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE  
        CALL    SEND        	;SEND BREAK CODE
        MOVLW	I36CODE
        CALL    SEND
	GOTO	K36BR

K37     BTFSS	BR3,6
	GOTO	K37R
	BCF     BR3,6
	CALL	DELAY
        MOVLW   I37CODE
	CALL	SEND
	GOTO	K37R
K37B    BTFSC   BR3,6          	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K37BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,6          	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE     	;BREAK KEY CODE
        CALL    SEND        	;SEND BREAK CODE
        MOVLW	I37CODE
        CALL    SEND
	GOTO	K37BR

K38     BTFSS	BR3,7
	GOTO	K38R
	BCF     BR3,7
	CALL	DELAY
        MOVLW   I38CODE
	CALL	SEND
	GOTO	K38R
K38B    BTFSC   BR3,7         	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	K38BR          	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     BR3,7          	;SET KEY CLOSURE BIT
        MOVLW   BREAKCODE      	;BREAK KEY CODE   
        CALL    SEND         	;SEND BREAK CODE
        MOVLW	I38CODE
        CALL    SEND
	GOTO	K38BR

;*****************************************************************************

;GAME CHANGE PROCESSING ROUTINE -- SPECIAL FUNCTION 1 KEY

;*****************************************************************************

KSP1	BTFSS	SPEC1FLAG	;FLAG BIT
	GOTO	KSP1R
	BCF     SPEC1FLAG
	CALL	DELAY

	BTFSS	DIP1BUF,0	;SKIP THIS ROUTINE IF ONLY ONE GAME
	GOTO	KSP1R		;EXIT--DON'T CHANGE GAME...

	BANK0
	BCF	MAMEVID		;OFF MAME VIDEO
	BSF	OSDVID		;ON REM VIDEO

	CALL	ESC		;SEND ESC KEY TO PC
	CALL	ESC		;SEND ESC TWICE

	CALL	ENTRKEY		;SEND ENTER KEY TO CLEAR CONSOLE

	INCF	CURGAME,1	;INCREMENT CURRENT GAME COUNTER
	
  ;EXIT CURRENT GAME AND LOAD NEXT GAME IN SEQUENCE
  ;THIS IS ENTRY POINT FOR INITIAL GAME LOAD SEQUENCE

STG	CALL	SEC14DEL	;DELAY
	
	BTFSC	CURGAME,0	;TEST FOR GAME 1 OR GAME 2
	GOTO	GR2
	
	MOVLW	0x16		;SCAN CODE FOR "1" KEY
	CALL	SEND

	CALL	SEC14DEL	;REQUIRED KEY SPACING DELAY
	MOVLW	BREAKCODE	;SEND "1" KEY BREAK CODE
	CALL	SEND
	MOVLW	0x16
	CALL	SEND

	CALL	ENTRKEY		;ENTER KEY
  
  ;INITIALIZE GAME 1

	MOVFP	DIP1BUF,W	;GET THE DIP SW DATA
	ANDLW	B'11110000'	;MASK OUT HIGH NIBBLE
	SWAPF	W,1		;SWAP NIBBLES
	CALL	GSDEL		;DELAY AWAITING SOFTWARE LOAD

	MOVFP	DIP1BUF,W	;GET THE DIP SW DATA
	ANDLW	B'00001110'	;MASK OUT BAD BITS
	RRNCF	W,1		;ADJUST BIT POSITION
	MOVWF	FINCTR		;COUNTER

NXENT1	CALL	ENTRKEY		;SEND ENTER KEY
	CALL	SEC14DEL	;SPACING DELAY...
	DECFSZ	FINCTR,1
	GOTO	NXENT1		;NEXT ...
	
	GOTO	ENDSEQ		;COMPLETE AND RETURN TO GAME 1

GR2	MOVLW	0x1E		;SCAN CODE FOR "2" KEY
	CALL	SEND

	CALL	SEC14DEL	;REQUIRED KEY SPACING DELAY
	MOVLW	BREAKCODE	;SEND "2" KEY BREAK CODE
	CALL	SEND
	MOVLW	0x1E
	CALL	SEND

	CALL	ENTRKEY		;ENTER KEY
	
  ;INITIALIZE GAME 2

	MOVFP	DIP2BUF,W	;GET THE DIP SW DATA
	ANDLW	B'11110000'	;MASK OUT HIGH NIBBLE
	SWAPF	W,1		;SWAP NIBBLES
	CALL	GSDEL		;DELAY AWAITING SOFTWARE LOAD

	MOVFP	DIP2BUF,W	;GET THE DIP SW DATA	
	ANDLW	B'00001110'	;MASK OUT BAD BITS
	RRNCF	W,1		;ADJUST BIT POSITION
	MOVWF	FINCTR		;COUNTER

NXENT2	CALL	ENTRKEY		;SEND ENTER KEY
	CALL	SEC14DEL	;SPACING DELAY...
	DECFSZ	FINCTR,1
	GOTO	NXENT2		;NEXT ...
	
ENDSEQ	BANK0	
	BSF	MAMEVID		;ON MAME VIDEO
	BCF	OSDVID		;OFF REM VIDEO
	
        GOTO	KSP1R

KSP1B   BTFSC   SPEC1FLAG      	;CHECK TO SEE IF KEY IS ALREADY OPEN
        GOTO	KSP1BR         	;IF SO, RETURN AND CONTINUE SCANNING
        BSF     SPEC1FLAG 	;SET KEY CLOSURE BIT
	GOTO	SCANSW          ;KSP1BR

;*****************************************************************************

;SEND DATA TO PC SUBROUTINE

;*****************************************************************************

SEND    MOVPF   BSR,BSAV      	;SAVE BANK SELECT
        MOVWF   TXBUF
        MOVWF   TBREG         	;SAVE IN CASE OF RESEND
        BANK1
        MOVLW   B'11111111'
        MOVWF   DDRD          	;ALL PORTS INPUT -- OFF LINE
        NOP
SND     CALL    DELAY         	;~~10mS DELAY BETWEEN TRANSMISSIONS
        CALL    DELAY         	;TIMING WIDTH ...
        BTFSS   KEYCLKIN      	;CHECK FOR BUS ACTIVITY
        GOTO    SND           	;WAIT FOR FREE BUS
        BTFSS   KEYDATIN      	;IS DATA LINE CLEAR?
        GOTO    SEND          	;WAIT FOR CLEAR DATA LINE
        BSF     KEYDATOUT
        BSF     KEYCLKOUT      	;CLEAR LINES BEFORE TX DATA
        NOP
        MOVLW   B'11111001'          
        MOVWF   DDRD           	;PUT PORTS ON LINE
        NOP

  ;SEND START BIT

        BCF     KEYDATOUT     	;LOW ON DATA LINE
        CALL    PDEL
        CALL    PCCLK  
        
  ;SETUP FOR LOOP

        MOVLW   08
        MOVWF   BITCNTR        	;BIT COUNTER 
        CLRF    PARITY,1       	;CLEAR PARITY COUNTER
NXBIT   BANK1
        MOVLW   B'11111111'
        MOVWF   DDRD          	;OFF LINE FOR TEST
        NOP
        BTFSS   KEYCLKIN     	;LINE CONTENTION?
        GOTO    SERR          	;PC IS REQUESTING SERVICE ...
        BANK1
        MOVLW   B'11111001'
        MOVWF   DDRD          	;ON LINE
        NOP
        BTFSS   TXBUF,0       	;SET BIT POLARITY
        GOTO    OUTAZERO
        BSF     KEYDATOUT     	;SET DATA BIT HIGH
        INCF    PARITY,1      	;INCREMENT PARITY COUNTER
        GOTO    COT
OUTAZERO
        BCF     KEYDATOUT      	;SET DATA BIT LOW
COT     NOP
        CALL    PDEL
        CALL    PCCLK
        RRNCF   TXBUF,1      	;ROTATE TO NEXT BIT
        DECFSZ  BITCNTR,1    	;LOOP CONTROL
        GOTO    NXBIT

  ;SEND PARITY BIT
        
        BTFSS   PARITY,0     	;SET BIT POLARITY
        GOTO    POUTAZERO
        BCF     KEYDATOUT     	;SET DATA BIT HIGH
        GOTO    PCOT
POUTAZERO
        BSF     KEYDATOUT      	;LOW ON DATA LINE
PCOT    NOP
        CALL    PDEL
        CALL    PCCLK

  ;SEND STOP BIT

        BSF     KEYDATOUT      	;HIGH ON DATA LINE
        NOP
        CALL    PDEL
        CALL    PCCLK
        BANK1
        MOVLW   B'11111111'
        MOVWF   DDRD          	;PORTS OFF LINE
        NOP

SWT     BTFSS   KEYCLKIN    	;HOLD OFF?
        GOTO    SWT
        
        MOVFP   BSAV,BSR     	;RESTORE BSR

        RETURN

SERR    CALL    DELAY
        MOVFP   TBREG,W       	;RESTORE DATA
        GOTO    SEND       	;TRY AGAIN

;*****************************************************************************

;DELAY SUBROUTINE

;*****************************************************************************

DELAY   MOVLW   DY1
        MOVWF   D1LOOP
        MOVLW   DY2
        MOVWF   D2LOOP
        MOVLW   DY3
        MOVWF   D3LOOP
DELOOP  NOP
        NOP
        NOP
        NOP
        DECFSZ  D1LOOP,1
        GOTO    DELOOP
        MOVLW   DY1
        MOVWF   D1LOOP
        DECFSZ  D2LOOP,1
        GOTO    DELOOP
        MOVLW   DY2
        MOVWF   D2LOOP
        DECFSZ  D3LOOP,1
        GOTO    DELOOP
TP1	RETURN

;*****************************************************************************

;PULSE DELAY SUBROUTINE

;*****************************************************************************

PDEL    NOP                     ;DELAY TIME OF ~~40uS
        MOVLW   013            
        MOVWF   D1LOOP
PELOOP  DECFSZ  D1LOOP,1
        GOTO    PELOOP
        NOP
        RETURN

;*****************************************************************************

;7uSEC DELAY SUBROUTINE

;*****************************************************************************

DEL7U   NOP
        MOVLW   01
        MOVWF   D1LOOP
U7LP1   NOP
        DECFSZ  D1LOOP,1
        GOTO    U7LP1
        NOP
        RETURN

;*****************************************************************************

;PC CLOCK SUBROUTINE

;*****************************************************************************

PCCLK   BCF     KEYCLKOUT       
        CALL    PDEL            ;~~40uSEC DELAY
        CALL    PDEL
        BSF     KEYCLKOUT
        CALL    PDEL            ;DELAY ONLY ~~2OuSEC
        RETURN

;*****************************************************************************

;PC COMMUNICATIONS HANDLING ROUTINE 

;*****************************************************************************

PROCLKOL  
	BANK1
        BTFSC   KEYDATIN     	;CHECK FOR RTS STATE FROM KBD
        RETURN
        CALL    INDAK          	;INPUT DATA FROM PC
        BTFSS   ERBIT
        GOTO    KXK
        BCF     ERBIT
        RETURN

;*****************************************************************************
;
;INPUT COMMANDS FROM PC SUBROUTINE
;
;*****************************************************************************

INDAK   MOVPF   BSR,BSAV       	;SAVE BANK SELECT
        BANK1
        MOVLW   B'11111111'
        MOVWF   DDRD          	;ALL PORTS OFF LINE -- INPUT MODE
        NOP
        MOVLW   STACKTOP     	;POINT TO TOP OF STACK
        MOVWF   FSR0          	;INDIRECT REG

KCWT    BTFSS   KEYCLKIN      	;IS CLOCK HIGH?
        GOTO    KCWT         	;WAIT FOR CLOCK HIGH
        
        BTFSS   KEYDATIN
        GOTO    GDTA         	;SOME KIND OF ERROR HAS OCCURRED
        BSF     ERBIT
        RETURN

GDTA    BSF     KEYCLKOUT     	;BE SURE BIT IS HIGH BEFORE CLOCKING
        NOP
        MOVLW   B'11111101'   	;PUT CLOCK OUT ON LINE
        MOVWF   DDRD 
        NOP

        MOVLW   09		;PREPARE TO INPUT 9 BITS OF DATA
        MOVWF   INDREG        	;BIT COUNTER

INDLOOP MOVPF   PORTD,INDF0    	;READ DATA INTO REGISTER
        NOP
        CALL    PDEL
        CALL    PCCLK          	;CLOCK PULSE
        DECF    FSR0,1

        DECFSZ  INDREG,1      	;LOOP 9 BITS
        GOTO    INDLOOP                       

  ;10TH BIT INPUT          

        MOVPF   PORTD,INDF0    	;READ DATA PORT
        NOP
        CALL    PDEL
        CALL    PCCLK
        DECF    FSR0,1

  ;AFTER 10TH BIT, KEYBOARD CHECKS FOR A HIGH ON DATA LINE -- IF SO, THE
  ;KEYBOARD FORCES DATA LINE LOW AND THEN READS IN THE LAST BIT OF DATA.

  ;11TH BIT INPUT        
  
        CALL    DEL7U
        BTFSS   KEYDATIN       	;CHECK FOR DATA ACTIVITY FROM HOST
        GOTO    INDAKERR      	;ERROR HAS OCCURED
        BANK1
        MOVLW   B'11111001'
        MOVWF   DDRD        	;PUT DATA OUT ON LINE
        NOP
        BCF     KEYDATOUT    	;LOW ON DATA LINE OUT TO PC
        CALL    PDEL
        CALL    PCCLK         	;CLOCK PULSE
        BSF     KEYDATOUT
        BANK1
        MOVLW   B'11111111'
        MOVWF   DDRD         	;OFF LINE TO PC
        NOP
        CALL    PDEL
        GOTO    COMB       	;COMBINE DATA

INDAKERR
        CALL    PCCLK     	;CLOCK PULSE
        BTFSS   KEYDATIN     	;IS DATA LINE HIGH YET?
        GOTO    INDAKERR
        BSF     ERBIT
        RETURN

  ;COMBINE BITS INTO A SINGLE 8-BIT WORD

COMB    MOVLW   STACKTOP-1
        MOVWF   FSR0        	;TOP OF STACK
        MOVLW   08
        MOVWF   INDREG    	;LOOP 8 BITS
        CLRF    CONVREG,1  	;CLEAR ALL BITS IN CONVERSION REG

CVLOOP  RRNCF   CONVREG,1
        BTFSS   INDF0,3
        GOTO    AXK
        BSF     CONVREG,7
AXK     DECF    FSR0,1
        DECFSZ  INDREG,1
        GOTO    CVLOOP

  ;BITS 10 AND 11 ARE DELIBRATLEY IGNORED -- 10 IS PARITY AND 11 IS STOP BIT.

        MOVFP   BSAV,BSR       	;RESTORE BSR

        RETURN

;*****************************************************************************

;COMMAND INTERPRETER

;*****************************************************************************

KXK     MOVLW   RESETCODE      	;*CHECK FOR RESET
        CPFSEQ  CONVREG
        GOTO    Q1
        GOTO    CMD1
Q1      MOVLW   INDCODE      	;*INDICATOR CODE
        CPFSEQ  CONVREG
        GOTO    Q2
        GOTO    INDICATORS
Q2      MOVLW   IDCODE      	;*CHECK FOR ID REQ
        CPFSEQ  CONVREG
        GOTO    Q3
        GOTO    CMD5
Q3      MOVLW   RESENDCODE    	;*CHECK FOR A RESEND
        CPFSEQ  CONVREG
        GOTO    Q4
        GOTO    CMD2                    
Q4      MOVLW   ECHOCODE      	;*CHECK FOR ECHO BACK CODE
        CPFSEQ  CONVREG
        GOTO    Q5
        GOTO    CMD3
Q5      MOVLW   TMRCODE      	;*CHECK FOR TYPEMATIC RATE COMMAND
        CPFSEQ  CONVREG
        GOTO    Q6
        GOTO    CMD4
Q6      MOVLW   DDCODE      	;*CHECK FOR DEFAULT DISABLE
        CPFSEQ  CONVREG
        GOTO    Q7
        GOTO    CMDX           	;*RE-INITIALIZE SYSTEM ON DEFAULT
Q7      MOVLW   ENACODE      	;*CHECK FOR ENABLE CODE
        CPFSEQ  CONVREG
        GOTO    Q8
        GOTO    CMDX
Q8      MOVLW   ALTCODE     	;*CHECK FOR ALTERNATE CODE REQ
        CPFSEQ  CONVREG
        GOTO    Q9
        GOTO    ALCD
Q9      MOVLW   SAK1CODE    	;*CHECK FOR SET ALL KEYS CODE
        CPFSEQ  CONVREG
        GOTO    Q10
        GOTO    CMDX
Q10     MOVLW   SAK2CODE   	;*CHECK FOR SET ALL KEYS CODE
        CPFSEQ  CONVREG
        GOTO    Q11
        GOTO    CMDX
Q11     MOVLW   SAK3CODE  	;*CHECK FOR SET ALL KEYS CODE
        CPFSEQ  CONVREG
        GOTO    Q12
        GOTO    CMDX
Q12     MOVLW   SAK4CODE  	;*CHECK FOR SET ALL KEYS CODE
        CPFSEQ  CONVREG
        GOTO    Q13
        GOTO    CMDX
Q13     MOVLW   SKT1CODE   	;*CHECK FOR SET KEY TYPE CODE
        CPFSEQ  CONVREG
        GOTO    Q14
        GOTO    CMDX
Q14     MOVLW   SKT2CODE   	;*CHECK FOR SET KEY TYPE CODE
        CPFSEQ  CONVREG
        GOTO    Q15
        GOTO    CMDX
Q15     MOVLW   SKT3CODE  	;*CHECK FOR SET KEY TYPE CODE
        CPFSEQ  CONVREG
        GOTO    Q16
        GOTO    CMDX
Q16     MOVLW   DEFCODE   	;*CHECK FOR DEFAULT SET CODE
        CPFSEQ  CONVREG
        GOTO    CMDX
        GOTO    CMDX    	;*ACK EVERYTHING ELSE -- ALL NOP'S

;*****************************************************************************

;COMMAND PROCESSOR ROUTINES 

;*****************************************************************************

CMD1    MOVLW   ACKCODE
        CALL    SEND
ACKW    CALL    PDEL
        BTFSS   KEYCLKIN    	;TEST FOR ACK
        GOTO    ACKW
        BSF     INITFLAG
        GOTO    PROCLKOL
CMD2    MOVFP   TBREG,W
        CALL    SEND        	;SEND AGAIN LAST DATUM
        GOTO    PROCLKOL  	;SCAN AGAIN
CMD3    MOVLW   ECHOCODE      	;SEND ECHO RESPONSE AND QUIT
        CALL    SEND
        GOTO    PROCLKOL    	;SCAN AGAIN
CMD4    CALL    SENDACODE
        BANK1
TRWT    BCF     ERBIT
        BTFSC   KEYCLKIN
        GOTO    TRWT
        CALL    INDAK        
        BTFSC   ERBIT
        GOTO    TRWT
        NOP
        NOP
        NOP
        NOP
        CALL    SENDACODE
        CALL    DELAY
        CALL    DELAY
        GOTO    PROCLKOL  	;SCAN AGAIN
CMD5    MOVLW   ACKCODE
        CALL    SEND
        CALL    DELAY
        NOP
        NOP
        NOP
        NOP
        MOVLW   IDLOW   
        CALL    SEND
        MOVLW   IDHIGH
        CALL    SEND
        CALL    DELAY
        GOTO    PROCLKOL    	;SCAN AGAIN                                    
CMDX    MOVLW   ACKCODE
        CALL    SEND
        GOTO    PROCLKOL   	;SCAN AGAIN                                   
INDICATORS
        CALL    SENDACODE
        BANK1
IDWT    BCF     ERBIT
        CALL    INDAK        
        BTFSC   ERBIT
        GOTO    IDWT
        MOVFP   CONVREG,W
	NOP
        MOVWF   PORTC
        CALL    SENDACODE

        MOVLW   30
        MOVWF   JREG
ASLP    CALL    DELAY
        DECFSZ  JREG,1
        GOTO    ASLP
	CALL    DELAY
        GOTO	PROCLKOL        
        
ALCD    CALL    SENDACODE
        BANK1
ACWT    BCF     ERBIT      	;SET SCAN CODE SET
        BTFSC   KEYCLKIN
        GOTO    ACWT
        CALL    INDAK        
        BTFSC   ERBIT
        GOTO    ACWT
        NOP
        NOP
        NOP
        NOP
        CALL    SENDACODE
        CALL    DELAY
        MOVLW   B'00001111'        
        ANDWF   CONVREG,1
        TSTFSZ  CONVREG
        GOTO    SETSCR          ;SET SCAN CODE TYPE
        MOVFP   SETR,W
        CALL    SEND
        CALL    DELAY
        GOTO    PROCLKOL
SETSCR  MOVFP   CONVREG,W
        MOVWF   SETR
        CALL    DELAY
        GOTO    PROCLKOL

;*****************************************************************************
;
;SEND BREAK CODE SUBROUTINE
;
;*****************************************************************************

SENDBCODE
        MOVLW   BREAKCODE
        CALL    SEND
        RETURN

;*****************************************************************************
;
;SEND ACK CODE SUBROUTINE
;
;*****************************************************************************

SENDACODE
        MOVLW   ACKCODE
        CALL    SEND
        RETURN

;****************************************************************************

;1 SECOND DELAY SUBROUTINE

;****************************************************************************

SEC1DELAY
	MOVLW	255
	MOVWF	D1S
	MOVWF	D2S
	MOVLW	10
	MOVWF	D3S
	
SEC1LP	DECFSZ	D1S,1
	GOTO	SEC1LP	
	MOVLW	255
	MOVWF	D1S

	DECFSZ	D2S,1
	GOTO	SEC1LP
	MOVLW	255
	MOVWF	D2S

	DECFSZ	D3S,1
	GOTO	SEC1LP

	RETURN

;****************************************************************************

;250mS DELAY SUBROUTINE

;****************************************************************************

SEC14DEL
	MOVLW	255
	MOVWF	D1S
	MOVWF	D2S
	MOVLW	01
	MOVWF	D3S
	
SEC14LP	DECFSZ	D1S,1
	GOTO	SEC14LP	
	MOVLW	255
	MOVWF	D1S

	DECFSZ	D2S,1
	GOTO	SEC14LP
	MOVLW	255
	MOVWF	D2S

	DECFSZ	D3S,1
	GOTO	SEC14LP

	RETURN
;****************************************************************************

;SEND ESC KEY SUBROUTINE

;****************************************************************************

ESC	MOVLW	ESCCODE		;SEND ESC KEY
	CALL	SEND
	CALL	SEC14DEL
	MOVLW	BREAKCODE
	CALL	SEND
	MOVLW	ESCCODE
	CALL	SEND
	CALL	SEC14DEL
	RETURN

;****************************************************************************

;SEND ENTER KEY SUBROUTINE

;****************************************************************************

ENTRKEY	MOVLW	0x5A
	CALL	SEND
	CALL	SEC14DEL
	MOVLW	BREAKCODE
	CALL	SEND
	MOVLW	0x5A
	CALL	SEND		;ENTER KEY
	CALL	SEC14DEL

	RETURN

;****************************************************************************

;GAME SW DELAY SUBROUTINE

GSDEL	MOVWF	FINCTR
GSD	CALL	SEC1DELAY	;DELAY WHILE SOFTWARE LOADS	
	DECFSZ	FINCTR,1
	GOTO	GSD
	RETURN

;********************************************************
;********************************************************

;SERIAL EEPROM HANDLING ROUTINES

; HOW TO USE THESE ROUTINES...

; WRITE DATA -- PUT DATA TO BE WRITTEN IN EDATA REGISTER.
;   PUT ADDRESS WHERE TO WRITE THE DATA IN EADDR REGISTER.
;   CALL EWRITE.

; READ DATA -- PUT ADDRESS OF DATA IN EADDR REGISTER.
;   CALL EREAD.  DATA WILL APPEAR IN EDATA REGISTER.

;********************************************************
;********************************************************

;EEPROM WRITE SUBROUTINE

;********************************************************

EWRITE  NOP   

                ;SEND DUMMY CLOCK PULSE
	
	BANK1
	
	BCF	SDIDIR		;BE SURE SDI IS AN OUTPUT	

	NOP
	BSF     SCLK            ;HIGH PULSE	;	5
        NOP					;	1
        NOP					;	2
	NOP					;	3
        BCF     SCLK            ;LOW PULSE	;	4
        NOP					;	5
		
		;SEND START BIT -- CREATE START CONDITION
	
        BSF     SCS             ;SELECT EEPROM		1
	NOP					;	2
        BSF     SDI             ;SEND START BIT		3
        NOP					;	4
	BSF     SCLK            ;HIGH PULSE	;	5
        NOP					;	1
	NOP					;	2
        NOP					;	3
        NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
        NOP					;	1
        				
        
                ;SEND READ OPCODE "00" -- EWEN

        BCF     SDI             ;BIT LOW		2
	NOP					;	3
	NOP					;	4
        BSF     SCLK            ;HIGH PULSE	;	5
        NOP					;	1
        NOP					;	2
	NOP					;	3	
        NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
        NOP					;	1
        NOP					;	1
        BCF     SDI             ;BIT LOW		2
	NOP					;	3
	NOP					;	4
        BSF     SCLK            ;HIGH PULSE		5
        NOP					;	1
        NOP					;	2
        NOP					;	3
	NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
       
                ;SEND ADDRESS

	MOVLW	B'11000000'
        MOVWF   EBUF            ;MOVE DATA INTO I/O BUF
        
        MOVLW   07
        MOVWF   CREG

        CALL    SOUT            ;OUTPUT DATA
                       
        BCF     SCS             ;DESELECT DEVICE
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP

        NOP
        NOP
                       ;SEND START BIT
	
	BANK1
	NOP
        BSF     SCS             ;SELECT EEPROM		1
	NOP					;	2
        BSF     SDI             ;SEND START BIT		3
        NOP					;	4
	BSF     SCLK            ;HIGH PULSE	;	5
        NOP					;	1
	NOP					;	2
        NOP					;	3
        NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
        NOP					;	1
        				
        
                ;SEND WRITE OPCODE "01" 

        BCF     SDI             ;BIT LOW		2
	NOP					;	3
	NOP					;	4
        BSF     SCLK            ;HIGH PULSE	;	5
        NOP					;	1
        NOP					;	2
	NOP					;	3	
        NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
        NOP					;	1
        NOP					;	1
        BSF     SDI             ;BIT LOW		2
	NOP					;	3
	NOP					;	4
        BSF     SCLK            ;HIGH PULSE		5
        NOP					;	1
        NOP					;	2
        NOP					;	3
	NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
        
        MOVFP   EADDR,W
        MOVWF   EBUF            ;MOVE ADDR INTO I/O BUFF
        RLNCF   EBUF,1          ;POSITION 7 BITS OF DATA
        MOVLW   07
        MOVWF   CREG
        CALL    SOUT            ;SEND ADDRESS
        
        MOVLW   08
        MOVWF   CREG
        MOVFP   EDATA,W
        MOVWF   EBUF            ;MOVE DATA INTO I/0 BUF
        CALL    SOUT            ;OUTPUT DATA
	NOP
	NOP
        BCF     SCS             ;WRITE CYCLE STARTS

        CALL    EWAIT           ;WAIT FOR DEVICE TO WRITE

  ;SEND ERASE/WRITE DISABLE TO PROTECT DATA

		;SEND START BIT -- CREATE START CONDITION
	
        BSF     SCS             ;SELECT EEPROM		1
	NOP					;	2
        BSF     SDI             ;SEND START BIT		3
        NOP					;	4
	BSF     SCLK            ;HIGH PULSE	;	5
        NOP					;	1
	NOP					;	2
        NOP					;	3
        NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
        NOP					;	1
        				
        
                ;SEND READ OPCODE "00" -- EWDS

        BCF     SDI             ;BIT LOW		2
	NOP					;	3
	NOP					;	4
        BSF     SCLK            ;HIGH PULSE	;	5
        NOP					;	1
        NOP					;	2
	NOP					;	3	
        NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
        NOP					;	1
        NOP					;	1
        BCF     SDI             ;BIT LOW		2
	NOP					;	3
	NOP					;	4
        BSF     SCLK            ;HIGH PULSE		5
        NOP					;	1
        NOP					;	2
        NOP					;	3
	NOP					;	4
        BCF     SCLK            ;LOW PULSE	;	5
       
                ;SEND ADDRESS

	MOVLW	B'00000000'
        MOVWF   EBUF            ;MOVE DATA INTO I/O BUF
        
        MOVLW   07
        MOVWF   CREG

        CALL    SOUT            ;OUTPUT DATA
                       
        BCF     SCS             ;DESELECT DEVICE


        RETURN

;********************************************************

;EEPROM READ SUBROUTINE

;********************************************************

EREAD   NOP   

                ;SEND START BIT
	
	BANK1
	BCF	SDIDIR		;BE SURE SDI IS AN OUTPUT

        BSF     SCS             ;SELECT EEPROM
	BANK1
        BSF     SDI             ;SEND START BIT
        BANK1
	BSF     SCLK            ;HIGH PULSE
        NOP
        NOP
        BANK1
        BCF     SCLK            ;LOW PULSE
        NOP
        NOP
        BANK1
        
                ;SEND READ OPCODE "10"

        BSF     SDI             ;BIT HIGH
	BANK1
        BSF     SCLK            ;HIGH PULSE
        NOP
        NOP
        BANK1
        BCF     SCLK            ;LOW PULSE
        NOP
        NOP
        BANK1
        
        BCF     SDI             ;BIT LOW
	BANK1
        BSF     SCLK            ;HIGH PULSE
        NOP
        NOP
        BANK1
        BCF     SCLK            ;LOW PULSE
        NOP
        NOP
        NOP
        NOP
                ;SEND ADDRESS

        MOVFP   EADDR,W
        MOVWF   EBUF            ;MOVE DATA INTO I/O BUF
        RLNCF   EBUF,1
        MOVLW   07
        MOVWF   CREG

        CALL    SOUT            ;OUTPUT DATA

                ;RECEIVE DATA

        MOVLW   08
        MOVWF   CREG            ;SET UP 8-BIT LOOP CTR

RDLP    BANK1                   
        RLNCF   EBUF,1          ;SHIFT LEFT ONE BIT
        BSF     SCLK            ;HIGH PULSE
        NOP
        NOP
        NOP
        BCF     SCLK            ;LOW PULSE
        NOP
        NOP
        BANK0
        MOVPF	PORTA,PATEMP	;MOVE PORT
        BTFSS   SDO             ;CHECK FOR BIT POLARITY
        GOTO    INAZERO         ;INPUT ZERO
        
        BSF     EBUF,0          ;LOAD A "1" IN FROM MEM
        GOTO    EINF            ;END LOOP
 
INAZERO BCF     EBUF,0          ;LOAD A "0" IN FROM MEM

EINF    DECFSZ  CREG,1          ;LOOP 8 BITS IN
        GOTO    RDLP            ;AGAIN
	BANK1
        BCF     SCS             ;BRING EEPROM OFF LINE

        MOVFP   EBUF,W
        MOVWF   EDATA           ;PUT DATA IN PROPER REG

        RETURN

;********************************************************

;SERIAL OUTPUT SUBROUTINE

;********************************************************

SOUT    NOP
        BANK1
        BTFSS   EBUF,7
        GOTO    OUTZ
        BSF     SDI
        GOTO    CLOCK
OUTZ
        BCF     SDI

CLOCK   BANK1
        BSF     SCLK            ;HIGH PULSE
        NOP
        NOP
        BANK1
        BCF     SCLK            ;LOW PULSE
        NOP
        NOP
        NOP
        
        RLNCF   EBUF,1          ;SHIFT TO NEXT BIT

        DECFSZ  CREG,1          ;LOOP OUT 8 BITS
        GOTO    SOUT    
        BANK1
        BCF     SDI             ;LOW BEFORE RETURN

        RETURN

;********************************************************
        
;WRITE WAIT SUBROUTINE

;********************************************************
        
EWAIT   BANK1 
        NOP
        BSF     SCS             ;SELECT EEPROM

EBUSY   BANK0
	MOVPF	PORTA,PATEMP
        BTFSS   SDO             ;CHECK FOR BUSY STATUS
        GOTO    EBUSY           ;WAIT HERE UNTIL FINISHED
        
        NOP
        NOP
        NOP
        BANK1

        BCF     SCS             ;DESELECT DEVICE

        RETURN

        END




