Code: Select all
; This is a multitap game designed for NES Four Score / NES Satellite
; and even for additional controllers connected to the Famicom expansion port.
; Controllers #1 and #2 end up at [0] and [1], respectively.
; Controllers #3 and #4 end up at [2] and [3], respectively.
;
; Strobe the multitap to reset it for reading.
0F:FE43 LDX #$01 ;
0F:FE45 STX $4016 ; [PORT] = 1;
0F:FE48 DEX ;
0F:FE49 STX $4016 ; [PORT] = 0;
0F:FE4C INX
; Read NES / Famicom controllers #1 and #2 into [0] and [1], respectively.
;
loop2: ; for(X = 1; X >= 0; X--) {
0F:FE4D LDY #$08
loop1: ; for(Y = 8; Y > 0; Y--) {
0F:FE4F LDA $4016,X ;
0F:FE52 AND #$03 ;
0F:FE54 CMP #$01 ;
0F:FE56 ROL $00,X ; [X] = ([X] << 1) | (([PORT + X] & 3) >= 1);
0F:FE58 DEY ;
0F:FE59 BNE $FE4F ;
0F:FE5B DEX ; }
0F:FE5C BEQ $FE4D ; }
; Read NES multitap controllers #3 and #4 into [6] and [7], respectively.
; Read Famicom controllers #3 and #4 into [4] and [5], respectively.
;
0F:FE5E LDX #$01 ; for(X = 1; X >= 0; X--) {
loop4: ;
0F:FE60 LDY #$08 ; for(Y = 8; Y > 0; Y--) {
loop3: ;
0F:FE62 LDA $4016,X ; A = [PORT + X];
0F:FE65 LSR A ;
0F:FE66 ROL $06,X ; [6 + X] = ([6 + X] << 1) | (A & 1);
0F:FE68 LSR A ;
0F:FE69 ROL $04,X ; [4 + X] = ([4 + X] << 1) | ((A >> 1) & 1);
0F:FE6B DEY ;
0F:FE6C BNE $FE62 ; }
0F:FE6E DEX ;
0F:FE6F BEQ $FE60 ; }
; Read potential NES multitap signatures into [$A] and [$B], expecting $10 and $20 for
; the input ports #1 and #2, respectively.
; Read potential Famicom expansion port signatures into [8] and [9], expecting $00 and
; $10 for input ports #1 and #2, respectively.
0F:FE71 LDX #$01 ; for(X = 1; X >= 0; X--) {
loop6:
0F:FE73 LDY #$08 ; for(Y = 8; Y > 0; Y--) {
loop5:
0F:FE75 LDA $4016,X ; A = [PORT + X];
0F:FE78 LSR A ;
0F:FE79 ROL $0A,X ; [$A + X] = ([$A + X] << 1) | (A & 1);
0F:FE7B LSR A ;
0F:FE7C ROL $08,X ; [8 + X] = ([8 + X] << 1) | ((A >> 1) & 1);
0F:FE7E DEY ;
0F:FE7F BNE $FE75 ; }
0F:FE81 DEX ;
0F:FE82 BEQ $FE73 ; }
; If the signatures are detected in [8], [9], [$A] or [$B], mark bits of [$C] accordingly.
0F:FE84 LDA #$00 ;
0F:FE86 STA $000C ; [$C] = 0;
0F:FE88 LDA $0008 ;
0F:FE8A CMP #$20 ;
0F:FE8C BNE $FE94 ; if ([8] == $20) {
0F:FE8E LDA #$80 ; [$C] |= $80;
0F:FE90 ORA $000C ; }
0F:FE92 STA $000C ;
label7:
0F:FE94 LDA $0009 ;
0F:FE96 CMP #$10 ;
0F:FE98 BNE $FEA0 ; if ([9] == $10) {
0F:FE9A LDA #$40 ; [$C] |= $40;
0F:FE9C ORA $000C ; }
0F:FE9E STA $000C ;
label8:
0F:FEA0 LDA $000A ;
0F:FEA2 CMP #$10 ;
0F:FEA4 BNE $FEAC ; if ([$A] == $10) {
0F:FEA6 LDA #$20 ; [$C] |= $20;
0F:FEA8 ORA $000C ; }
0F:FEAA STA $000C ;
label9:
0F:FEAC LDA $000B ;
0F:FEAE CMP #$20 ;
0F:FEB0 BNE $FEB8 ; if ([$B] == $20) {
0F:FEB2 LDA #$10 ; [$C] |= $10;
0F:FEB4 ORA $000C ; }
0F:FEB6 STA $000C ;
; If Famicom signatures are detected, then copy [4] and [5] (Famicom contollers #3 and #4)
; to [2] and [3], respectively.
label10:
0F:FEB8 LDA $000C ;
0F:FEBA CMP #$C0 ;
0F:FEBC BNE $FEC8 ; if ([$C] == $C0) {
0F:FEBE LDX #$02 ; for(X = 2; X > 0; X--) {
label11:
0F:FEC0 LDA $03,X ;
0F:FEC2 STA $01,X ; [1 + X] = [3 + X];
0F:FEC4 DEX ;
0F:FEC5 BNE $FEC0 ; }
0F:FEC7 RTS ;
;
; Otherwise, if NES signatures are detected, copy [6] and [7] (NES controllers #3 and #4)
; to [2] and [3], respectively.
label12:
0F:FEC8 CMP #$30
0F:FECA BNE $FED5 ; } else if ([$C] == $30) {
0F:FECC LDX #$02 ; for(X = 2; X > 0; X--) {
label13:
0F:FECE LDA $05,X ;
0F:FED0 STA $01,X ; [1 + X] = [5 + X];
0F:FED2 DEX ;
0F:FED3 BNE $FECE ; }
; }
label14:
0F:FED5 RTS ; return;