;************************************
;* N64 controller to GB interface   *
;*     through serial port          *
;*                                  *
;* Ken Kaarvik    June20/99         *
;*                                  *
;* THIS WILL NOT WORK ON A COLOR GB *
;*                                  *
;************************************
;
;                    +5v
;                     |
;  N64signal--+  |~~~~~~~~~|
;  Pin4-------+--|1   16  4|-----Clk
;  Sin--------+  |         |
;                | 74HC123 |   +5v
;            +5v |         |    |
;             |  |         |    R1=1K
;             +--|2        |    |
;             +--|3      15|----+
;             +--|9        |    |
;             +--|10       |    C1=1nF
;             +--|11       |    |
;                |       14|----+
;                |         |
;                |____8____|
;                     |
;                 To N64 gnd
;
;
;  N64 +3.5v------------ +5v
;
;  N64 Gnd ----->|->|---  0v  (2 diodes in series)
;
;
;
;N64 controller
;   This is a description of an N64 controller jack
;   (not the plug on the controller itself - you probably
;    would want to use an extension cable cut in half and
;    use the jack portion, leaving the controller wiring
;    intact).
;
;   Looking at the jack with flat side down,left to right:
;   (same as looking at an N64 console)
;   +3.5v,signal,0v
;
;To check out the rumble pak only just connect N64signal to pin4
;   (and N64gnd to 0v, N64 power to +5v)
;
;
;
display_col		equ	$9800+32
test1			equ	$80

bit_0:	MACRO
	ldh	[$00],a		;low
	rrca
	nop
	nop
	nop
	nop
	ldh	[$00],a
	rlca
	ENDM

bit_1:	MACRO
	ldh	[$00],a		;hi 8
	rrca
	ldh	[$00],a
	rlca
	nop
	nop
	nop
	nop
	nop
	nop
	ENDM

bit_stop:	MACRO
	ldh	[$00],a		;hi 8
	rrca
	nop
	nop
	ldh	[$00],a
	rlca
	ENDM
	
	INCLUDE	"hardware.inc"
;	INCLUDE	"ibmpc1.inc"

	SECTION "Header",HOME[$0100]

	nop
	jp	Startup

	DB	$CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D
	DB	$00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99
	DB	$BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E

		;0123456789ABCDE
	DB	"N64 Controller "
	DB	$00	;$00=NOT Color GB
	DB	0,0,0	;SuperGameboy
	DB	0	;CARTTYPE
			;--------
			;0 - ROM ONLY
			;1 - ROM+MBC1
			;2 - ROM+MBC1+RAM
			;3 - ROM+MBC1+RAM+BATTERY
			;5 - ROM+MBC2
			;6 - ROM+MBC2+BATTERY

	DB	0	;ROMSIZE
			;-------
			;0 - 256 kBit ( 32 kByte,  2 banks)
			;1 - 512 kBit ( 64 kByte,  4 banks)
			;2 -   1 MBit (128 kByte,  8 banks)
			;3 -   2 MBit (256 kByte, 16 banks)
			;3 -   4 MBit (512 kByte, 32 banks)

	DB	0	;RAMSIZE
			;-------
			;0 - NONE
			;1 -  16 kBit ( 2 kByte, 1 bank )
			;2 -  64 kBit ( 8 kByte, 1 bank )
			;3 - 256 kBit (32 kByte, 4 banks)

	DW	$0000	;Manufacturer

	DB	0	;Version
	DB	0	;Complement check
	DW	0	;Checksum

	INCLUDE	"memory1.asm"

	SECTION	"Main",home[$0150]

Startup

	ld	a,$10		;set pin4 high
	ldh	[$00],a

	call	delay_big

	call	initialize

	call	send_rumble_init_mac
	
	call	delay_big

	call	send_rumble_on_mac
	call	delay_big
	call	send_rumble_off_mac
	call	delay_big
	REPT	20
	call	send_rumble_on2_mac
	call	delay
	call	send_rumble_off_mac
	call	delay
	ENDR


Main
	call	inc_counter

	call	N64_read_buttons

	call	check_for_zed

	call	wait_vb

	call	write_to_screen

	jp	Main

check_for_zed			;rumble if Z button pushed
	call	wait_vb
	ld	a,[N64]
	bit	5,a
	jp	nz,rumble_on
	bit	5,a
	jp	z,rumble_off
	ret
	
rumble_on
	call	send_rumble_on_mac
	ret
rumble_off
	call	send_rumble_off_mac
	ret

send_rumble_on_mac
	ld	a,$20
	bit_0	;7	$03
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_1	;1
	bit_1	;0
	
	bit_1	;7	$C0
	bit_1	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_0	;0

	bit_0	;7	$1B
	bit_0	;6
	bit_0	;5
	bit_1	;4
	bit_1	;3
	bit_0	;2
	bit_1	;1
	bit_1	;0

	REPT	32
	bit_0	;7	$01
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_1	;0
	ENDR

	;call	read_4_bytes

	bit_0	;stop
	
	ret

send_rumble_on2_mac
	ld	a,$20
	bit_0	;7	$03
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_1	;1
	bit_1	;0
	
	bit_1	;7	$C0
	bit_1	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_0	;0

	bit_0	;7	$1B
	bit_0	;6
	bit_0	;5
	bit_1	;4
	bit_1	;3
	bit_0	;2
	bit_1	;1
	bit_1	;0

	bit_0	;7	$01
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_1	;0

	;call	read_4_bytes

	bit_0	;stop
	
	ret


send_rumble_off_mac
	ld	a,$20
	bit_0	;7	$03
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_1	;1
	bit_1	;0
	
	bit_1	;7	$C0
	bit_1	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_0	;0

	bit_0	;7	$1B
	bit_0	;6
	bit_0	;5
	bit_1	;4
	bit_1	;3
	bit_0	;2
	bit_1	;1
	bit_1	;0

	REPT	32
	bit_0	;7	$00
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_0	;0
	ENDR

	;call	read_4_bytes

	bit_0	;stop
	
	ret

send_rumble_init_mac
	ld	a,$20
	bit_0	;7	$03
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_1	;1
	bit_1	;0
	
	bit_1	;7	$80
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_0	;0

	bit_0	;7	$01
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_1	;0

	REPT	34
	bit_1	;7	$80
	bit_0	;6
	bit_0	;5
	bit_0	;4
	bit_0	;3
	bit_0	;2
	bit_0	;1
	bit_0	;0
	ENDR

	;call	read_4_bytes

	bit_0	;stop
	
	ret


N64_read_buttons
	ld	a,$01
	call	send_out_pin4
	call	read_4_bytes
	ret
	
read_4_bytes
	ld	a,0
	ldh	[$00],a	;-ve going stop bit
	ld	a,$80
	ldh	[$02],a	;start first xfer
	ld	a,$10
	ldh	[$00],a	;+ve going stop
			;we should now see 33 bits
			;coming back from controller
	REPT	9
	ld	a,[$FF01]
	ENDR
	ld	a,$80
	ldh	[$02],a	;start next xfer
	ldh	a,[$01]	;get first byte from controller
	ld	[N64],a

	REPT	7
	ldh	a,[$01]
	ENDR
	ld	a,$80
	ldh	[$02],a
	ldh	a,[$01]	;get second byte
	ld	[N64+1],a

	REPT	7
	ldh	a,[$01]
	ENDR
	ld	a,$80
	ldh	[$02],a
	ldh	a,[$01]	;get third byte
	ld	[N64+2],a

	REPT	7
	ldh	a,[$01]
	ENDR
	ld	a,$80
	ldh	[$02],a
	ldh	a,[$01]	;get fourth byte
	ld	[N64+3],a

	ret

	REPT	7
	ldh	a,[$01]
	ENDR
	ld	a,$80
	ldh	[$02],a
	ldh	a,[$01]	;get fifth byte
	ld	[N64+4],a

	REPT	7
	ldh	a,[$01]
	ENDR
	ld	a,$80
	ldh	[$02],a
	ldh	a,[$01]	;get 6th byte
	ld	[N64+5],a

	ret






send_stop_bit
	ld	a,0		;stop bit
	ldh	[$00],a
	nop
	nop
	nop
	nop
	ld	a,$10
	ldh	[$00],a
	nop


	ret


send_out_pin4
	rrca
	rrca
	rrca
	ld	b,a

	REPT	8
	xor	a
	ldh	[$00],a
	nop
	nop
	ld	a,b
	ldh	[$00],a
	nop
	nop
	ld	a,$10
	ldh	[$00],a
	nop
	nop
	rlc	b
	ENDR



	ret

delay_big
	ld	d,250
delay_big_loop
	dec	e
	REPT	1
	nop
	nop
	nop
	ENDR
	jp	nz,delay_big_loop
	dec	d
	jp	nz,delay_big_loop
	ret

delay
	ld	d,30
delay_loop
	dec	e
	REPT	1
	nop
	nop
	nop
	ENDR
	jp	nz,delay_loop
	dec	d
	jp	nz,delay_loop
	ret

inc_counter
	ld	a,[counter]
	inc	a
	ld	[counter],a
	ret

write_to_screen

	ld	hl,$FE00	;postion my sprite
	ld	a,[N64+3]
	cpl
	add	a,80
	ld	[hl+],a
	ld	a,[N64+2]
	add	a,80
	ld	[hl+],a

	ld	de,counter
	ld	hl,display_col
	call	display_byte

	ld	de,N64
	ld	hl,display_col+$40+4
	call	display_byte

	ld	de,N64+1
	ld	hl,display_col+$40+7
	call	display_byte

	ld	de,N64+2
	ld	hl,display_col+$40+10
	call	display_byte

	ld	de,N64+3
	ld	hl,display_col+$40+13
	call	display_byte

	ret

display_byte
	ld	a,[de]
	ld	b,a
	and	$F0
	swap	a
	ld	[hl+],a
	ld	a,b
	and	$0F
	ld	[hl],a
	ret

initialize

.wait	ldh	a,[$44]		;LY LCDC compare
	cp	144
	jr	nc,.wait
	ld	a,0
	ldh	[$40],a		;LCDC lcd control



	ld	hl,Font		;load my test Font
	ld	de,$8000
	ld	bc,20*8*2
	call	mem_Copy


	ld	hl,my_sprite
	ld	de,$8000+20*8*2
	ld	bc,1*8*2
	call	mem_Copy

	ld	a,0
	ld	hl,$FE04
	ld	bc,154
	call	mem_Set


	ld	hl,$FE00
	ld	a,0
	ld	[hl+],a
	ld	[hl+],a
	ld	a,20
	ld	[hl+],a
	ld	a,%10000000
	ld	[hl+],a
	
;	ld	hl,ibm_characters	;load ibm font
;	ld	de,$8000+20*8*2		;$8140
;	ld	bc,8*128
;	call	mem_CopyMono


	ld	a,16		;blank char
	ld	hl,$9800
	ld	bc,20*32*32
	call	mem_Set

	ld	a,0
	ldh	[$42],a		;SCY Scroll Y
	ldh	[$43],a		;SCX Scroll X

	ld	a,$F0
	ldh	[$47],a		;BGP

	ld	a,$00000000
	ldh	[$FF],a		;IE

	ld	a,%10010011
	ldh	[$40],a

	xor	a
	ld	[$FF24],a

	xor	a
	ld	[counter],a
	ld	[N64],a
	ld	[N64+1],a
	ld	[N64+2],a
	ld	[N64+3],a
	ld	[N64+4],a
	ld	[N64+5],a
	ld	[N64+6],a
	ld	[N64+7],a
	ld	[N64+8],a
	ld	[N64+9],a
	ld	[N64+10],a
	ld	[N64+11],a
	ld	[N64+12],a




	ret


wait_vb
	ldh	a,[$44]
	cp	144
	jp	nz,wait_vb
	ret
	
my_sprite
	DW	`11100111
	DW	`10000001
	DW	`10000001
	DW	`00000000
	DW	`00000000
	DW	`10000001
	DW	`10000001
	DW	`11100111
	
Font:
	DW	`01111100
	DW	`10000010
	DW	`10000010
	DW	`10000010
	DW	`10000010
	DW	`10000010
	DW	`01111100
	DW	`00000000

	DW	`00010000
	DW	`00110000
	DW	`00010000
	DW	`00010000
	DW	`00010000
	DW	`00010000
	DW	`00111000
	DW	`00000000

	DW	`01111100
	DW	`10000010
	DW	`00000010
	DW	`01111100
	DW	`10000000
	DW	`10000000
	DW	`11111110
	DW	`00000000

	DW	`01111100
	DW	`10000010
	DW	`00000010
	DW	`00011100
	DW	`00000010
	DW	`10000010
	DW	`01111100
	DW	`00000000

	DW	`00001100
	DW	`00010100
	DW	`00100100
	DW	`01000100
	DW	`11111110
	DW	`00000100
	DW	`00000100
	DW	`00000000

	DW	`11111110
	DW	`10000000
	DW	`10000000
	DW	`11111100
	DW	`00000010
	DW	`00000010
	DW	`11111100
	DW	`00000000

	DW	`01111100
	DW	`10000000
	DW	`10000000
	DW	`11111100
	DW	`10000010
	DW	`10000010
	DW	`01111100
	DW	`00000000

	DW	`11111110
	DW	`00000010
	DW	`00000100
	DW	`00001000
	DW	`00010000
	DW	`00010000
	DW	`00010000
	DW	`00000000

	DW	`01111100
	DW	`10000010
	DW	`10000010
	DW	`01111100
	DW	`10000010
	DW	`10000010
	DW	`01111100
	DW	`00000000

	DW	`01111100
	DW	`10000010
	DW	`10000010
	DW	`01111110
	DW	`00000010
	DW	`00000010
	DW	`01111100
	DW	`00000000

	DW	`00111000
	DW	`01000100
	DW	`10000010
	DW	`11111110
	DW	`10000010
	DW	`10000010
	DW	`10000010
	DW	`00000000

	DW	`11111100
	DW	`10000010
	DW	`10000010
	DW	`11111100
	DW	`10000010
	DW	`10000010
	DW	`11111100
	DW	`00000000

	DW	`00111100
	DW	`01000010
	DW	`10000000
	DW	`10000000
	DW	`10000000
	DW	`01000010
	DW	`00111100
	DW	`00000000

	DW	`11111000
	DW	`10000100
	DW	`10000010
	DW	`10000010
	DW	`10000010
	DW	`10000100
	DW	`11111000
	DW	`00000000

	DW	`11111110
	DW	`10000000
	DW	`10000000
	DW	`11111000
	DW	`10000000
	DW	`10000000
	DW	`11111110
	DW	`00000000

	DW	`11111110
	DW	`10000000
	DW	`10000000
	DW	`11111000
	DW	`10000000
	DW	`10000000
	DW	`10000000
	DW	`00000000

	DW	`00000000	;16
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000

	DW	`11111111	;17 web mark
	DW	`10000001
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000

	DW	`00000000	;18 web space
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`00000000
	DW	`10000001
	DW	`11111111
	DW	`00000000

	DW	`11111100	;19
	DW	`10000010	;P for parity
	DW	`10000010
	DW	`11111100
	DW	`10000000
	DW	`10000000
	DW	`10000000
	DW	`00000000


	SECTION	"GB_ram",BSS
counter			DS	1
port56			DS	1
n64_byte_1		DS	1
n64_byte_2		DS	1
n64_byte_3		DS	1
n64_byte_send		DS	1
N64			DS	20
