1185 lines
19 KiB
NASM
Executable File
1185 lines
19 KiB
NASM
Executable File
.FILE "COMM.ASM"
|
|
*----------------------------------------------------------------------------
|
|
*
|
|
*
|
|
*COPYRIGHT (C) 1994 BY TV GAMES, INC.
|
|
*ALL RIGHTS RESERVED
|
|
*
|
|
|
|
.include C30.EQU
|
|
.include OBJ.EQU
|
|
.include MACS.EQU
|
|
.include MPROC.EQU
|
|
.include VUNIT.EQU
|
|
.include CMOS.EQU
|
|
.include SYSID.EQU
|
|
.include SYS.EQU
|
|
.include GLOBALS.EQU
|
|
.include SNDTAB.EQU
|
|
.include PALL.EQU
|
|
.include OBJECTS.EQU
|
|
.include TEXT.EQU
|
|
.include COMM.EQU
|
|
|
|
|
|
|
|
TIME_DELAY .set 18
|
|
|
|
.globl COMM_MASTER_ERROR_CNT
|
|
.globl COMM_MASTER_TRANSES
|
|
.globl COMM_SLAVE_ERROR_CNT
|
|
.globl COMM_SLAVE_TRANSES
|
|
.globl COMM_SLAVE_NREADY
|
|
|
|
|
|
fbss COMM_MASTER_ERROR_CNT,1
|
|
fbss COMM_MASTER_TRANSES,1
|
|
fbss COMM_SLAVE_ERROR_CNT,1
|
|
fbss COMM_SLAVE_TRANSES,1
|
|
fbss COMM_SLAVE_NREADY,1
|
|
.bss COMMFLAG,1 ;COMMUNICATIONS IS OVER
|
|
|
|
pbss ONEFLAG,1
|
|
|
|
pbss TRANSMISSION_ACTIVE,1 ;1=TRUE
|
|
|
|
pbss TRANSMISSION_DEAD,1 ;1=DEAD LINK
|
|
|
|
|
|
|
|
*----------------------------------------------------------------------------
|
|
COMM_INIT:
|
|
PUSH DP
|
|
LDP @DIPRAM
|
|
LDI @DIPRAM,R1
|
|
|
|
LDI 0,R0
|
|
STI R0,@ONEFLAG ;CLEAR OUT ONE PLAYER FLAG
|
|
|
|
LDI C_SLA,R0
|
|
|
|
TSTB CMDP_MASTER,R1
|
|
LDIZ C_MAS,R0
|
|
LS 16,R0
|
|
|
|
LDP @COMMDP
|
|
STI R0,@COMM_IO
|
|
LDI C_CE,R0
|
|
LS 16,R0
|
|
STI R0,@COMM_CTL
|
|
|
|
POP DP
|
|
RETS
|
|
*----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
RECEIVE_BUFFERI .word RECEIVE_BUFFER
|
|
COMM_IOI .word COMM_IO
|
|
CTL EQU COMM_CTL-COMM_IO
|
|
|
|
|
|
|
|
*----------------------------------------------------------------------------
|
|
COMM_ENABLE_INT2:
|
|
;
|
|
;if slave then enable the interrupt 2
|
|
;(comm int 2)
|
|
;
|
|
LDP @DIPRAM
|
|
LDI @DIPRAM,R1
|
|
|
|
TSTB DIP_COMMP,R1
|
|
BNZ BABA
|
|
|
|
TSTB CMDP_MASTER,R1
|
|
BZ BABA
|
|
|
|
LDI INT2_M,R1
|
|
LDP @COMMINTM
|
|
STI R1,@COMMINTM
|
|
BABA LDP @COMMINTM
|
|
OR @COMMINTM,IE
|
|
SETDP
|
|
RETS
|
|
*----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
*----------------------------------------------------------------------------
|
|
COMM_MASTER_SEND_SYNC:
|
|
LDI @COMMFLAG,R0 ;DONT INTERRUPT COMMUNICATIONS
|
|
RETSNZ
|
|
|
|
LDI @DIPRAM,R0
|
|
TSTB CMDP_MASTER,R0
|
|
RETSNZ
|
|
|
|
DINT
|
|
ANDN INT2_M,IE ;DISABLE LINK INT2
|
|
|
|
LDI @COMM_IOI,AR5 ;SETUP I/O REGISTER
|
|
|
|
*TRIGGER INTERRUPT IN SLAVE
|
|
|
|
LDI *AR5,R0
|
|
RS 16,R0
|
|
AND C_C2,R0
|
|
LDI R0,R1
|
|
OR C_MAS|C_IRQ,R0
|
|
LS 16,R0
|
|
STI R0,*AR5 ;INT2 HI COMM_IO
|
|
NOP
|
|
NOP
|
|
NOP
|
|
LDI C_MAS,R0
|
|
OR R1,R0
|
|
LS 16,R0
|
|
STI R0,*AR5 ;INT2 LO COMM_IO
|
|
|
|
ANDN INT2_M,IF ;REMOVE ANY LATCHED INT
|
|
RETS
|
|
*----------------------------------------------------------------------------
|
|
*
|
|
*SET ONE PLAYER GAME (NO LINK)
|
|
*
|
|
SETONE:
|
|
PUSH R0
|
|
PUSH AR0
|
|
|
|
CLRI R0
|
|
STI R0,@TRANSMISSION_ACTIVE
|
|
LDI 1,R0
|
|
STI R0,@ONEFLAG
|
|
|
|
LDI @DIPRAM,R0
|
|
TSTB CMDP_MASTER,R0
|
|
|
|
LDIZ C_C2|C_MAS,R0 ;MASTER CASE SEND C2=1
|
|
LDINZ C_C1|C_SLA,R0 ;SLAVE CASE SEND C1=1
|
|
B ONEX
|
|
|
|
*
|
|
*CLR ONE PLAYER GAME (NO LINK)
|
|
*
|
|
|
|
CLRONE:
|
|
PUSH R0
|
|
PUSH AR0
|
|
|
|
LDI 1,R0
|
|
STI R0,@TRANSMISSION_ACTIVE
|
|
|
|
LDI 0,R0
|
|
STI R0,@ONEFLAG
|
|
|
|
LDI @DIPRAM,R0
|
|
TSTB CMDP_MASTER,R0
|
|
|
|
LDIZ C_MAS,R0 ;MASTER CASE
|
|
LDINZ C_SLA,R0 ;SLAVE CASE
|
|
|
|
ONEX
|
|
LDI @COMM_IOI,AR0 ;SETUP I/O REGISTER
|
|
LS 16,R0
|
|
STI R0,*AR0
|
|
POP AR0
|
|
POP R0
|
|
RETS
|
|
|
|
*----------------------------------------------------------------------------
|
|
*COMMUNICATIONS LINK
|
|
*
|
|
COMMPAL .set 0990000h ;COMMUNICATIONS PAL
|
|
|
|
COMM_ROUTINE:
|
|
CLRI AR7
|
|
LDP @COMMPAL
|
|
LDI @COMMPAL,R0
|
|
LDI *AR7,R1
|
|
SETDP
|
|
|
|
AND 0FH,R0
|
|
CMPI 4,R0 ;BAD PAL ?
|
|
RETSNZ ;YES....QUIT
|
|
|
|
LDI @DIPRAM,R0 ;CHECK FOR COMMUNICATIONS
|
|
TSTB DIP_COMMP,R0
|
|
RETSNZ ;NO
|
|
|
|
COMM_HOLDFORA2D
|
|
LDI @RDPOT,R1
|
|
CMPI 3,R1
|
|
BNZ COMM_HOLDFORA2D
|
|
|
|
LDI 1,R1
|
|
STI R1,@COMMFLAG ;DONT INTERRUPT COMMUNICATIONS
|
|
|
|
TSTB CMDP_MASTER,R0 ;CHECK MASTER/SLAVE
|
|
BNZ COMM_SLAVE
|
|
*
|
|
*MASTER MUST ALWAYS 0 <- C_IRQE
|
|
*
|
|
|
|
COMM_MASTER:
|
|
SETDP
|
|
LDI @COMM_IOI,AR5 ;SETUP I/O REGISTER
|
|
|
|
*CHECK ONE PLAYER MODE
|
|
|
|
LDI @ONEFLAG,R0
|
|
BZ CM1
|
|
RETS ;WE'RE IN ONE PLAYER, EXIT
|
|
CM1
|
|
LDI @SEND_BUFFER_A_LEN,R6 ;16 bits
|
|
LDI @SEND_BUFFER_AI,AR2
|
|
|
|
CMPI 0,R6
|
|
BLE CMERRORL ;ZERO LENGTH, NO MESSAGE
|
|
|
|
CMPI 240H,R6
|
|
BGE CMERRORL ;LENGTH ERROR
|
|
|
|
ADDI R6,AR2,AR0 ;ADD 2 NULLS TO THE END DUDES
|
|
LDI CB_NULL,R2
|
|
STI R2,*AR0
|
|
STI R2,*+AR0(1)
|
|
|
|
*BEGIN SYNC ROUTINE
|
|
|
|
LDI C_MAS,R0 ;send C2=0
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
LDI 120,R3
|
|
LDI @TRANSMISSION_DEAD,R0 ;GET TIMEOUT VALUES
|
|
BZ WTLPMI
|
|
|
|
LDI 1,R3 ;WAIT A FRAME IF DEAD
|
|
ADDI @INFRAMES,R3
|
|
CMPI 4,R3
|
|
LDIGT 4,R3
|
|
|
|
WTLPMI LDI *AR5,R0 ;GET C0,C1
|
|
RS 16,R0
|
|
|
|
TSTB C_C1,R0 ;SLAVE C1=1 (ONE PLAYER MODE)
|
|
BZ CM2 ;NO
|
|
|
|
LDI 0,R0 ;SLAVE IN ONE PLAYER MODE, EXIT
|
|
STI R0,@TRANSMISSION_ACTIVE
|
|
STI R0,@TRANSMISSION_DEAD
|
|
RETS
|
|
CM2
|
|
TSTB C_C0,R0 ;WAIT FOR SLAVE READY SIGNAL
|
|
BNZ CM3 ;GOT IT...
|
|
|
|
CMPI @INFRAMES,R3 ;WAITING TOO LONG?
|
|
BGT WTLPMI ;NO, KEEP LOOPING
|
|
B CMERRORDEAD ;YES, ITS DEAD...
|
|
|
|
CM3
|
|
LDI 0,R0
|
|
STI R0,@TRANSMISSION_DEAD
|
|
|
|
LDI 1,R0
|
|
STI R0,@TRANSMISSION_ACTIVE
|
|
|
|
LDI C_C2|C_MAS,R0 ;SEND C2=1
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
ADDI 1,R3 ;A LITTLE MORE TIME
|
|
WTLPMI2
|
|
CMPI @INFRAMES,R3 ;WAITING TOO LONG?
|
|
BLE CMERRORDEAD ;YES, ITS DEAD...
|
|
|
|
LDI *AR5,R0 ;WAIT C0=0
|
|
RS 16,R0
|
|
TSTB C_C0,R0
|
|
BNZ WTLPMI2
|
|
|
|
LDI C_MAS,R0 ;send C2=0
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
|
|
;
|
|
;END SYNC ROUTINE
|
|
|
|
|
|
DINT
|
|
|
|
|
|
WTLPMI3 LDI *AR5,R0 ;WAIT C1=1
|
|
RS 16,R0
|
|
TSTB C_C1,R0
|
|
BZ WTLPMI3
|
|
|
|
LDI C_MAS,R0
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
LDI C_SND,R0 ;SET DATA CONTROL FOR SEND
|
|
LS 16,R0
|
|
STI R0,*+AR5(CTL) ;COMM_CTL
|
|
*
|
|
*SEND MESSAGE LENGTH TO SLAVE
|
|
*16 BITS LENGTH
|
|
*MESSAGE LENGTH IS MULT OF 2
|
|
*
|
|
ADDI 1,R6
|
|
RS 1,R6
|
|
LDI R6,AR6
|
|
NOT R6,R7
|
|
|
|
LDI R7,R5
|
|
LSH -8,R7
|
|
|
|
LDI R6,R4
|
|
LSH -8,R6
|
|
|
|
AND 0FFH,R7
|
|
AND 0FFH,R6
|
|
AND 0FFH,R5
|
|
AND 0FFH,R4
|
|
|
|
*SEND LENGTH (BYTE 1 MSB)
|
|
|
|
OR C_MAS|C_C2,R6 ; (C2=1)
|
|
LS 16,R6
|
|
STI R6,*AR5 ;SEND C2 HIGH WITH DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
*SEND LENGTH (BYTE 2 LSB)
|
|
|
|
OR C_MAS,R4 ; (C2=1)
|
|
LS 16,R4
|
|
STI R4,*AR5 ;SEND C2 HIGH WITH DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
*SEND LENGTH (BYTE 3 MSB COMPLEMENTED)
|
|
|
|
OR C_MAS|C_C2,R7 ; (C2=1)
|
|
LS 16,R7
|
|
STI R7,*AR5 ;SEND C2 HIGH WITH DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
*SEND LENGTH (BYTE 4 LSB COMPLEMENTED)
|
|
|
|
OR C_MAS,R5
|
|
LS 16,R5
|
|
STI R5,*AR5 ;SEND C2 LOW WITH DATA
|
|
RPTS 65
|
|
NOP
|
|
|
|
DEC AR6
|
|
|
|
LDI 0FFh,R4
|
|
*
|
|
* SEND MASTERS BUFFER
|
|
*
|
|
LDI 0,R3 ;CHECKSUM
|
|
*byte1
|
|
AND *AR2++,R4,R6
|
|
ADDI R6,R3 ;FORM CHECKSUM
|
|
OR C_MAS|C_C2,R6 ;(C2=1)
|
|
MSDLP
|
|
LS 16,R6
|
|
STI R6,*AR5
|
|
RPTS TIME_DELAY
|
|
NOP
|
|
*byte2
|
|
AND *AR2++,R4,R6
|
|
ADDI R6,R3
|
|
OR C_MAS,R6 ;(C2=0)
|
|
LS 16,R6
|
|
|
|
STI R6,*AR5
|
|
RPTS TIME_DELAY
|
|
NOP
|
|
DBUD AR6,MSDLP
|
|
|
|
AND *AR2++,R4,R6
|
|
ADDI R6,R3 ;FORM CHECKSUM
|
|
OR C_MAS|C_C2,R6 ; (C2=1)
|
|
;---->DBUD AR6,MSDLP
|
|
|
|
ANDN C_MAS|C_C2,R6 ;ONE TOO MANY...
|
|
SUBI R6,R3
|
|
|
|
*SEND THE CHECKSUM
|
|
|
|
AND 0FFFFH,R3 ;MASK CKSUM TO 16 BITS
|
|
LDI R3,R6 ;SEND MSB
|
|
RS 8,R6
|
|
OR C_MAS|C_C2,R6 ;(C2=1)
|
|
LS 16,R6
|
|
STI R6,*AR5 ;SEND 2 HIGH
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
LS 24,R3
|
|
RS 24,R3
|
|
OR C_MAS,R3 ;(C2=0)
|
|
LS 16,R3
|
|
STI R3,*AR5 ;SEND 2 HIGH
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
LDI C_RCV,R0 ;CHANGE CONTROL TO RECEIVE
|
|
LS 16,R0
|
|
STI R0,*+AR5(CTL) ;@COMM_CTL
|
|
*
|
|
* WAIT FOR SLAVE TO SIGNIFY DONE (C1=0)
|
|
*
|
|
LDI 30,R5 ;TIMEOUT
|
|
CML1XX DEC R5
|
|
BLT CMERROR10
|
|
LDI *AR5,R0
|
|
RS 16,R0
|
|
TSTB C_C1,R0
|
|
BNZ CML1XX
|
|
|
|
*
|
|
* MASTER TELLS SLAVE IT IS LISTENING (C2=1)
|
|
*
|
|
LDI @RECEIVE_BUFFERI,AR2 ;SETUP RECEIVE BUFFER
|
|
|
|
LDI C_C2|C_MAS,R0 ;SET C2=HI
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
* GET SLAVES BUFFER LENGTH
|
|
* BUFFER LENGTH IS X 2
|
|
* 4 BYTES LENGTH MSB, LSB, COMP MSB, COMP LSB
|
|
*
|
|
|
|
LDP COMM_IO
|
|
LDI C_C1,R5
|
|
LS 16,R5
|
|
|
|
LDI 300,AR3
|
|
PWL2M TSTB @COMM_IO,R5
|
|
DBZ AR3,PWL2M
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR1 ;ERROR IN TIMEOUT
|
|
NOP
|
|
LDI 300,AR3
|
|
LDI @COMM_IO,R7 ;GET MSB
|
|
;---->BNZD CMERROR1
|
|
|
|
PWL3M TSTB @COMM_IO,R5
|
|
DBNZ AR3,PWL3M
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR2 ;ERROR IN TIMEOUT
|
|
NOP
|
|
LDI @COMM_IO,R6 ;GET LSB
|
|
LS 8,R6
|
|
;---->BNZD CMERROR2
|
|
|
|
LDI 300,AR3
|
|
PWL4M TSTB @COMM_IO,R5
|
|
DBZ AR3,PWL4M
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR1 ;ERROR IN TIMEOUT
|
|
NOP
|
|
LDI 300,AR3
|
|
NOT @COMM_IO,R4 ;GET MSB COMPLEMENT
|
|
;---->BNZD CMERROR1
|
|
|
|
PWL5M TSTB @COMM_IO,R5
|
|
DBNZ AR3,PWL5M
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR2 ;ERROR IN TIMEOUT
|
|
NOP
|
|
NOT @COMM_IO,R2 ;GET LSB COMPLEMENT
|
|
LS 8,R2
|
|
;---->BNZD CMERROR2
|
|
|
|
LS 8,R4
|
|
LS 8,R7
|
|
RS 24,R2
|
|
RS 24,R4
|
|
RS 24,R6
|
|
RS 24,R7
|
|
|
|
CMPI R2,R6
|
|
BNE CMERROR3 ;ERROR IN LENGTH
|
|
|
|
CMPI R4,R7
|
|
BNE CMERROR3 ;ERROR IN LENGTH
|
|
|
|
LSH 8,R7
|
|
ADDI R6,R7,AR6
|
|
|
|
CMPI 140H,AR6 ;LENGTH ERROR
|
|
BGE CMERROR3 ;TOO LONG
|
|
|
|
CMPI 0,AR6 ;SLAVE LENGTH ZERO...
|
|
BEQ CMERROR3
|
|
|
|
DEC AR6 ;THIS IS THE LENGTH INDEX
|
|
|
|
*
|
|
* GET SLAVES BUFFER
|
|
*
|
|
SETDP
|
|
STI AR6,@RBUFF_LEN
|
|
LDP @COMM_IO
|
|
CLRI R3 ;RESET CKSUM
|
|
LDI 0FFH,R2
|
|
LSH 16,R2
|
|
LDI 300,AR3
|
|
|
|
WL2M TSTB @COMM_IO,R5
|
|
DBZ AR3,WL2M
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR4 ;YES...QUIT
|
|
LDI 300,AR3
|
|
NOP
|
|
AND R2,*AR5,R6
|
|
;----> BNZD CMERROR4
|
|
|
|
ADDI R6,R3
|
|
STI R6,*AR2++
|
|
|
|
WL3M TSTB *AR5,R5
|
|
DBNZ AR3,WL3M
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR5 ;YES...QUIT
|
|
NOP
|
|
NOP
|
|
AND R2,*AR5,R6
|
|
;----> BNZD CMERROR5
|
|
|
|
DBUD AR6,WL2M
|
|
ADDI R6,R3
|
|
STI R6,*AR2++
|
|
LDI 300,AR3
|
|
;---->DBUD AR6,WL2M
|
|
|
|
*GET SLAVES CKSUM
|
|
|
|
WL2MC TSTB @COMM_IO,R5
|
|
DBZ AR3,WL2MC
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR6 ;YES...QUIT
|
|
NOP
|
|
LDI 300,AR3
|
|
LDI @COMM_IO,R6 ;MSB CKSUM
|
|
;----> BNZD CMERROR6
|
|
|
|
WL3MC TSTB @COMM_IO,R5
|
|
DBNZ AR3,WL3MC
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CMERROR7 ;YES...QUIT
|
|
RS 8,R6
|
|
AND 0FF00h,R6
|
|
LDI @COMM_IO,R7 ;LSB CKSUM
|
|
;----> BNZD CMERROR7
|
|
|
|
RS 16,R7
|
|
AND 0FFh,R7
|
|
ADDI R6,R7
|
|
RS 16,R3
|
|
CMPI R7,R3
|
|
BNE CMERROR8 ;CKSUM ERROR
|
|
|
|
M0LENGTH
|
|
|
|
COMM_MASTER_X
|
|
|
|
LDP @COMM_MASTER_TRANSES
|
|
INCM @COMM_MASTER_TRANSES
|
|
|
|
COMM_MASTER_ERR_X
|
|
|
|
LDI C_MAS,R0 ;SET C2=0
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
|
|
LDI C_RCV,R0 ;SET DATA CONTROL TO RECEIVE
|
|
LS 16,R0
|
|
STI R0,*+AR5(CTL)
|
|
|
|
SETDP
|
|
LDI 0,R0
|
|
STI R0,@COMMFLAG ;COMMUNICATIONS IS OVER
|
|
EINT
|
|
RETS
|
|
|
|
.globl CMERROR1
|
|
CMERROR1 B COMM_MASTER_ERROR ;LENGTH TIMEOUT
|
|
CMERROR2 B COMM_MASTER_ERROR ;LENGTH TIMEOUT
|
|
CMERROR3 B COMM_MASTER_ERROR ;BAD LENGTH
|
|
CMERROR4 B COMM_MASTER_ERROR ;DATA TIMEOUT
|
|
CMERROR5 B COMM_MASTER_ERROR ;DATA TIMEOUT
|
|
CMERROR6 B COMM_MASTER_ERROR ;CKSUM TIMEOUT
|
|
CMERROR7 B COMM_MASTER_ERROR ;CKSUM TIMEOUT
|
|
CMERROR8 B COMM_MASTER_ERROR ;BAD CKSUM
|
|
CMERROR9 B COMM_MASTER_ERROR ;MASTER SEND TIMEOUT
|
|
CMERROR10 B COMM_MASTER_ERROR ;MASTER END TIMEOUT (SLAVE ERR)
|
|
CMERRORL B COMM_MASTER_ERROR ;LENGTH TOO LONG
|
|
|
|
CMERRORDEAD
|
|
LDI 1,R0 ;YES OTHER GAME IS DEAD, LEAVE...
|
|
STI R0,@TRANSMISSION_DEAD
|
|
B COMM_MASTER_ERROR ;WENT DEAD...
|
|
|
|
COMM_MASTER_ERROR
|
|
|
|
LDP @COMM_MASTER_TRANSES
|
|
INCM @COMM_MASTER_ERROR_CNT
|
|
|
|
SETDP
|
|
LDI 0,R0
|
|
STI R0,@RBUFF_LEN ;RECEIVE BUFFER CLEARED ON ERROR
|
|
|
|
; LDI C_C2|C_MAS,R0 ;SET C2=HI
|
|
; LS 16,R0
|
|
; STI R0,*AR5
|
|
|
|
B COMM_MASTER_ERR_X
|
|
*----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
*----------------------------------------------------------------------------
|
|
COMM_IRQ:
|
|
PUSH ST
|
|
PUSH DP
|
|
PUSH R0
|
|
|
|
ANDN INT2_M,IF
|
|
;determine if I am a master being interrupted
|
|
;
|
|
LDP @DIPRAM
|
|
LDI @DIPRAM,R0
|
|
TSTB CMDP_MASTER,R0
|
|
BNZ DO_SLAVE_SYNC
|
|
|
|
POP R0
|
|
POP DP
|
|
POP ST
|
|
RETI
|
|
|
|
DO_SLAVE_SYNC:
|
|
PUSH R1
|
|
PUSH IE
|
|
LDI INT1_M|INT2_M,IE ;disable everything except TV30 interrupt & comm int
|
|
ANDN INT2_M,IF ;we wont irq ourself
|
|
|
|
LDP @CPU_WS
|
|
LDI @CPU_WS,R0
|
|
PUSH R0
|
|
|
|
LDI SOFT_WS,R0
|
|
STI R0,@CPU_WS
|
|
|
|
|
|
;sync the systems...
|
|
;
|
|
;
|
|
LDP @FIFO_CONTROL
|
|
LDI @FIFO_CONTROL,R0
|
|
ANDN FIFO_CONTROL_DMA_RUNSEL,R0
|
|
STI R0,@FIFO_CONTROL
|
|
|
|
|
|
WTLP LDI @FIFO_STATUS,R0
|
|
AND FIFO_STATUS_FD_CRITICAL,R0
|
|
BNZ WTLP
|
|
|
|
;same LDP @CRT_VCNT
|
|
LDI @CRT_VCNT,R0
|
|
AND 1FFh,R0
|
|
|
|
|
|
; CMPI 400,R0
|
|
; LDIEQ 1b0h,R0
|
|
; LDIGT 1b1h,R0
|
|
; LDILT 1afh,R0
|
|
|
|
LDI 1B0H,R1
|
|
SUBI 400,R0
|
|
CMPI -1,R0 ;GRACE AREA DUDES
|
|
LDILT 1afh,R1
|
|
CMPI 1,R0
|
|
LDIGT 1b1h,R1
|
|
|
|
STI R1,@CRT_VTTL
|
|
|
|
|
|
LDI @FIFO_CONTROL,R0
|
|
OR FIFO_CONTROL_DMA_RUNSEL,R0
|
|
STI R0,@FIFO_CONTROL
|
|
|
|
POP R0
|
|
LDP @CPU_WS
|
|
STI R0,@CPU_WS
|
|
|
|
POP IE
|
|
POP R1
|
|
POP R0
|
|
POP DP
|
|
; LDI INT1_M|INT2_M|INT3_M|INT0_M,IE
|
|
POP ST
|
|
RETI
|
|
*----------------------------------------------------------------------------
|
|
|
|
|
|
*----------------------------------------------------------------------------
|
|
*CALLED FROM THE MAIN LOOP
|
|
*
|
|
*SET C0 HIGH
|
|
*WAIT FOR C2 TO GO HIGH
|
|
*BEGIN TRANSFER
|
|
*END OF TRANSFER
|
|
*SET ALL LOW
|
|
*
|
|
*
|
|
COMM_SLAVE:
|
|
|
|
SETDP
|
|
LDI @COMM_IOI,AR5 ;AR5=COMM I/O ADDRESS
|
|
LDI @RECEIVE_BUFFERI,AR2 ;AR2=RECEIVE BUFFER
|
|
|
|
LDI C_C2,R5 ;R5=C_C2 MASK
|
|
LS 16,R5
|
|
|
|
*CHECK ONE PLAYER MODE
|
|
|
|
LDI @ONEFLAG,R0
|
|
BZ CS1
|
|
RETS ;WE'RE IN ONE PLAYER, EXIT
|
|
|
|
CS1
|
|
TSTB *AR5,R5
|
|
BZ CS2 ;C2=1, MASTER IN ONE PLAYER, EXIT
|
|
LDI 0,R0
|
|
STI R0,@TRANSMISSION_DEAD
|
|
STI R0,@TRANSMISSION_ACTIVE
|
|
RETS
|
|
|
|
*SYNC UP
|
|
|
|
CS2
|
|
LDI 120,R3 ;WAIT 120 FRAMES IF NOT DEAD
|
|
LDI @TRANSMISSION_DEAD,R0 ;GET TIMEOUT VALUES
|
|
BZ CS20
|
|
LDI 1,R3 ;WAIT 1 IF DEAD
|
|
ADDI @INFRAMES,R3
|
|
CMPI 4,R3
|
|
LDIGT 4,R3
|
|
CS20
|
|
LDI 1,R0
|
|
STI R0,@TRANSMISSION_ACTIVE
|
|
|
|
LDI C_C0|C_SLA,R0
|
|
LS 16,R0
|
|
STI R0,*AR5 ;SEND C0=1
|
|
|
|
WTLPI
|
|
CMPI @INFRAMES,R3 ;WAITING TOO LONG?
|
|
BLE CSERRORDEAD ;YES, ITS DEAD...
|
|
|
|
TSTB *AR5,R5 ;WAIT C2=1
|
|
BZ WTLPI
|
|
|
|
LDI C_SLA,R0 ;SEND C0=0
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
LDI 0,R0
|
|
STI R0,@TRANSMISSION_DEAD
|
|
|
|
LDI 10000,AR3 ;TIMEOUT VALUE
|
|
WTLPI2
|
|
TSTB *AR5,R5 ;WAIT C2=0
|
|
DBNZ AR3,WTLPI2
|
|
|
|
TSTB 8000H,AR3 ;TIMEOUT?
|
|
BZ CS3 ;NO
|
|
RETS ;YES, LEAVE
|
|
|
|
|
|
*END SYNC
|
|
|
|
CS3
|
|
DINT
|
|
|
|
*SET DATA CONTROL TO RECEIVE ;CM_A 1
|
|
|
|
LDI C_RCV,R0
|
|
LS 16,R0
|
|
STI R0,*+AR5(CTL)
|
|
|
|
*TELL MASTER WE ARE LISTENING (C0=0,C1=1)
|
|
|
|
LDI C_C1|C_SLA,R0
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
*GET MASTERS BUFFER LENGTH
|
|
*BUFFER LENGTH IS X 2
|
|
*FIRST BYTE IS LENGTH
|
|
*SECOND BYTE IS COMPLEMENT OF LENGTH
|
|
|
|
LDP @COMM_IO
|
|
|
|
LDI 300,AR3
|
|
PWL2 TSTB @COMM_IO,R5
|
|
DBZ AR3,PWL2
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR1 ;ERROR IN TIMEOUT
|
|
NOP
|
|
LDI 300,AR3
|
|
LDI @COMM_IO,R7 ;GET MSB
|
|
;---->BNZD CSERROR1
|
|
|
|
PWL3 TSTB @COMM_IO,R5
|
|
DBNZ AR3,PWL3
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR2 ;ERROR IN TIMEOUT
|
|
NOP
|
|
LDI @COMM_IO,R6 ;GET LSB
|
|
LS 8,R6
|
|
;---->BNZD CSERROR2
|
|
|
|
LDI 300,AR3
|
|
PWL4 TSTB @COMM_IO,R5
|
|
DBZ AR3,PWL4
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR1 ;ERROR IN TIMEOUT
|
|
NOP
|
|
LDI 300,AR3
|
|
NOT @COMM_IO,R4 ;GET MSB COMPLEMENT
|
|
;---->BNZD CSERROR1
|
|
|
|
PWL5 TSTB @COMM_IO,R5
|
|
DBNZ AR3,PWL5
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR2 ;ERROR IN TIMEOUT
|
|
NOP
|
|
NOT @COMM_IO,R2 ;GET LSB COMPLEMENT
|
|
LS 8,R2
|
|
;---->BND CSERROR2
|
|
|
|
LS 8,R4
|
|
LS 8,R7
|
|
RS 24,R2
|
|
RS 24,R4
|
|
RS 24,R6
|
|
RS 24,R7
|
|
|
|
CMPI R2,R6
|
|
BNE CSERROR3 ;ERROR IN LENGTH
|
|
|
|
CMPI R4,R7
|
|
BNE CSERROR3 ;ERROR IN LENGTH
|
|
|
|
LSH 8,R7
|
|
ADDI R6,R7,AR6
|
|
DEC AR6 ;THIS IS THE LENGTH INDEX
|
|
|
|
CMPI 140H,AR6 ;LENGTH ERROR
|
|
BGE CSERROR3 ;TOO LONG
|
|
|
|
*
|
|
*GET MASTERS BUFFER
|
|
*
|
|
SETDP
|
|
STI AR6,@RBUFF_LEN
|
|
LDP @COMM_IO
|
|
CLRI R3 ;RESET CKSUM
|
|
LDI 0FFH,R2
|
|
LSH 16,R2
|
|
LDI 300,AR3
|
|
|
|
WL2 TSTB @COMM_IO,R5
|
|
DBZ AR3,WL2
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR4 ;YES...QUIT
|
|
LDI 300,AR3
|
|
NOP
|
|
AND R2,*AR5,R6
|
|
;----> BNZD CSERROR4 ;YES...QUIT
|
|
|
|
ADDI R6,R3
|
|
STI R6,*AR2++
|
|
|
|
WL3 TSTB *AR5,R5
|
|
DBNZ AR3,WL3
|
|
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR5 ;YES...QUIT
|
|
NOP
|
|
NOP
|
|
AND R2,*AR5,R6
|
|
;----> BNZD CSERROR5 ;YES...QUIT
|
|
|
|
DBUD AR6,WL2
|
|
ADDI R6,R3
|
|
STI R6,*AR2++
|
|
LDI 300,AR3
|
|
|
|
*GET MASTERS CKSUM
|
|
|
|
WL2C TSTB @COMM_IO,R5
|
|
DBZ AR3,WL2C
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR6 ;YES...QUIT
|
|
NOP
|
|
LDI 300,AR3
|
|
LDI @COMM_IO,R6 ;MSB CKSUM
|
|
;----> BNZD CSERROR6 ;YES...QUIT
|
|
|
|
WL3C TSTB @COMM_IO,R5
|
|
DBNZ AR3,WL3C
|
|
|
|
TSTB 8000H,AR3
|
|
BNZD CSERROR7 ;YES...QUIT
|
|
RS 8,R6
|
|
AND 0FF00h,R6
|
|
LDI @COMM_IO,R7 ;LSB CKSUM
|
|
;----> BNZD CSERROR7 ;YES...QUIT
|
|
|
|
RS 16,R7
|
|
AND 0FFh,R7
|
|
ADDI R6,R7
|
|
RS 16,R3
|
|
CMPI R7,R3
|
|
BNE CSERROR8 ;CKSUM ERROR
|
|
|
|
* LOWER SLAVES C1
|
|
* (tell master we are prepared to send)
|
|
*
|
|
|
|
SETDP
|
|
LDI C_SLA,R0
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
|
|
*
|
|
* SLAVE SEND
|
|
*
|
|
|
|
* WAIT FOR MASTER TO LISTEN (C2=1)
|
|
|
|
LDI 50,R5 ;TIMEOUT
|
|
CML1S DEC R5
|
|
BLT CSERROR9
|
|
LDI *AR5,R0
|
|
RS 16,R0
|
|
TSTB C_C2,R0
|
|
BZ CML1S
|
|
|
|
LDI C_SND,R0 ;CHANGE DATA BUFFER DIRECTION TO SEND
|
|
LS 16,R0
|
|
STI R0,*+AR5(CTL)
|
|
|
|
|
|
* SEND SLAVE LENGTH
|
|
|
|
|
|
*SEND MESSAGE LENGTH TO MASTER
|
|
*MESSAGE LENGTH IS MULTIPLE OF 2
|
|
|
|
SETDP
|
|
|
|
LDI @SEND_BUFFER_A_LEN,R6
|
|
LDI @SEND_BUFFER_AI,AR2
|
|
|
|
ADDI R6,AR2,AR0 ;ADD 2 NULLS TO THE END DUDES
|
|
LDI CB_NULL,R2
|
|
STI R2,*AR0
|
|
STI R2,*+AR0(1)
|
|
|
|
ADDI 1,R6
|
|
RS 1,R6
|
|
LDI R6,AR6
|
|
NOT R6,R7
|
|
|
|
LDI R7,R5
|
|
LSH -8,R7
|
|
|
|
LDI R6,R4
|
|
LSH -8,R6
|
|
|
|
AND 0FFH,R7
|
|
AND 0FFH,R6
|
|
AND 0FFH,R5
|
|
AND 0FFH,R4
|
|
|
|
|
|
*SEND LENGTH (BYTE 1 MSB)
|
|
|
|
OR C_SLA|C_C1,R6 ; (C2=1)
|
|
LS 16,R6
|
|
STI R6,*AR5 ;SEND C2 HIGH WITH DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
*SEND LENGTH (BYTE 2 LSB)
|
|
|
|
OR C_SLA,R4 ; (C2=1)
|
|
LS 16,R4
|
|
STI R4,*AR5 ;SEND C2 HIGH WITH DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
*SEND LENGTH (BYTE 3 MSB COMPLEMENTED)
|
|
|
|
OR C_SLA|C_C1,R7 ; (C2=1)
|
|
LS 16,R7
|
|
STI R7,*AR5 ;SEND C2 HIGH WITH DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
*SEND LENGTH (BYTE 4 LSB COMPLEMENTED)
|
|
|
|
OR C_SLA,R5
|
|
LS 16,R5
|
|
STI R5,*AR5 ;SEND C2 LOW WITH DATA
|
|
RPTS 65
|
|
NOP
|
|
|
|
DEC AR6
|
|
LDI 0FFh,R4
|
|
*
|
|
* SLAVE SEND BUFFER TO MASTER
|
|
*
|
|
LDI 0,R3 ;CHECKSUM
|
|
*byte1
|
|
AND *AR2++,R4,R6
|
|
ADDI R6,R3 ;FORM CHECKSUM
|
|
OR C_SLA|C_C1,R6 ;(C1=1)
|
|
SSDLP
|
|
LS 16,R6
|
|
STI R6,*AR5
|
|
RPTS TIME_DELAY
|
|
NOP
|
|
*byte2
|
|
AND *AR2++,R4,R6
|
|
ADDI R6,R3
|
|
OR C_SLA,R6 ;(C1=0)
|
|
LS 16,R6
|
|
|
|
STI R6,*AR5
|
|
RPTS TIME_DELAY
|
|
NOP
|
|
DBUD AR6,SSDLP
|
|
|
|
AND *AR2++,R4,R6
|
|
ADDI R6,R3 ;FORM CHECKSUM
|
|
OR C_SLA|C_C1,R6 ; (C2=1)
|
|
;---->DBUD AR6,SSDLP
|
|
|
|
ANDN C_SLA|C_C1,R6
|
|
SUBI R6,R3 ;ONE OVER!!!
|
|
|
|
*SEND THE CHECKSUM
|
|
|
|
AND 0FFFFH,R3 ;MASK CKSUM TO 16 BITS
|
|
LDI R3,R6 ;SEND MSB
|
|
RS 8,R6
|
|
OR C_SLA|C_C1,R6 ;(C1=1)
|
|
LS 16,R6
|
|
STI R6,*AR5 ;SEND DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
LS 24,R3
|
|
RS 24,R3
|
|
OR C_SLA,R3 ;(C1=0)
|
|
LS 16,R3
|
|
STI R3,*AR5 ;SEND DATA
|
|
RPTS TIME_DELAY ;HOLD FOR A SEC
|
|
NOP
|
|
|
|
*WAIT FOR MASTER TO INDICATE O.K. C2=0
|
|
|
|
LENGTHOF0
|
|
|
|
LDI 50,R5 ;TIMEOUT
|
|
CML1WT DEC R5
|
|
BLT CSERROR11
|
|
LDI *AR5,R0
|
|
RS 16,R0
|
|
TSTB C_C2,R0
|
|
BNZ CML1WT
|
|
|
|
COMM_SLAVE_X
|
|
|
|
LDP @COMM_SLAVE_TRANSES
|
|
INCM @COMM_SLAVE_TRANSES
|
|
|
|
COMM_SLAVE_ERR_X
|
|
|
|
SETDP
|
|
|
|
LDI C_SLA,R0 ;SET C0=0,C1=0, NO ERROR
|
|
LS 16,R0
|
|
STI R0,*AR5
|
|
|
|
LDI C_RCV,R0 ;CHANGE CONTROL TO RECEIVE
|
|
LS 16,R0
|
|
STI R0,*+AR5(CTL) ;@COMM_CTL
|
|
|
|
LDI 0,R0
|
|
STI R0,@COMMFLAG ;COMMUNICATIONS IS OVER
|
|
|
|
EINT
|
|
RETS
|
|
|
|
CSERROR1 B COMM_SLAVE_ERROR ;LENGTH TIMEOUT
|
|
CSERROR2 B COMM_SLAVE_ERROR ;LENGTH TIMEOUT
|
|
CSERROR3 B COMM_SLAVE_ERROR ;BAD LENGTH
|
|
CSERROR4 B COMM_SLAVE_ERROR ;DATA TIMEOUT
|
|
CSERROR5 B COMM_SLAVE_ERROR ;DATA TIMEOUT
|
|
CSERROR6 B COMM_SLAVE_ERROR ;CKSUM TIMEOUT
|
|
CSERROR7 B COMM_SLAVE_ERROR ;CKSUM TIMEOUT
|
|
CSERROR8 B COMM_SLAVE_ERROR ;BAD CKSUM
|
|
CSERROR9 B COMM_SLAVE_ERROR ;SLAVE SEND TIMEOUT
|
|
CSERROR11 B COMM_SLAVE_ERROR ;MASTER ERROR END TIMEOUT
|
|
|
|
CSERRORDEAD
|
|
LDI 1,R0 ;YES OTHER GAME IS DEAD, LEAVE...
|
|
STI R0,@TRANSMISSION_DEAD
|
|
B COMM_SLAVE_ERROR ;WENT DEAD...
|
|
|
|
COMM_SLAVE_ERROR
|
|
LDP @COMM_SLAVE_ERROR_CNT
|
|
INCM @COMM_SLAVE_ERROR_CNT
|
|
SETDP
|
|
|
|
LDI 0,R0
|
|
STI R0,@RBUFF_LEN ;RECEIVE BUFFER CLEARED ON ERROR
|
|
|
|
BU COMM_SLAVE_ERR_X
|
|
|
|
*----------------------------------------------------------------------------
|
|
.END
|