Gameboy RS 232 interfacing

This topic is one I grabbed off the internet. It is a method to have the link port talk in a way that modern computers can understand it. I.e. at RS 232 levels and at 9600 bps. I did not design this project, nor did I code it. I show it to have a look at some GameBoy source code.

Download the sources here.

The sourcecode

;***********************************
;* RS232    9600,n,8,1             *
;*                                 *
;*     through serial port         *
;*                                 *
;* Ken Kaarvik    May21/99         *
;*                                 *
;***********************************

;Talk to a RS232 device at 9800,n,8,1
;
;Pin outs - wire through a MAX-232
;
;CGB           MAX-232       9pin serial
;                             port on computer
;  +5V-----------+---+
;                |   |
;               16   =
;                |   |+
;                |   |
;             |~~~~~~~~|
;             |  16  2 |
;             |        |
;< Pin 4------|12    13|------3 <
;> Sout-------|11    14|------2 >
;             |        |
;          +--|4      1|--+
;         +|  |        |  |+
;          =  |        |  =
;          |  |        |  |
;          +--|5      3|--+
;             |        |
;             |__15__6_|
;                |   |
;                |   =
;                |   |+
;  gnd-----------+---+--------5
;
; (4) caps @10uF Note polarity
;

display_col		equ	$9800
blank			equ	16
text_line		equ	$9800+$20*5

        SECTION    "Org $0", HOME
        ret

; Button Push Interrupt - For sending out data while waiting for input

        SECTION "Org $60",HOME[$60]

        push    af
	call	pad_Read
	call	send_test
	xor	a
	ldh	[$00],a
	pop	af
	reti


	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	"RS232          "
	DB	$80	; $80=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"
	INCLUDE "keypad.asm"

	SECTION	"Main",home[$0150]

Startup
	call	initialize

Main
	call	inc_counter
	call	read_rs232
	call	wait_vb
	call	write_to_screen
	jp	Main

send_test
	ld	a,[_PadDataEdge]	; _PadData]
	cp	0
	ret	z

	cp	PADF_A
	jp	z, service_button_a

	cp	PADF_B
	jp	z, service_button_b

	cp	PADF_START
	jp	z, service_start

	cp	PADF_SELECT
	jp	z, service_select

	cp	PADF_UP
	jp	z, service_up

	cp	PADF_DOWN
	jp	z, service_down

	cp	PADF_LEFT
	jp	z, service_left

	cp	PADF_RIGHT
	jp	z, service_right
	ret

service_button_a
	ld	hl, a_button_text
	call	send_text
	ret

service_button_b
	ld	hl, b_button_text
	call	send_text
	ret

service_start
	ld	hl, start_text
	call	send_text
	ret

service_select
	ld	hl, select_text
	call	send_text
	ret

service_up
	ld	hl, up_text
	call	send_text
	ret

service_down
	ld	hl, down_text
	call	send_text
	ret

service_left
	ld	hl, left_text
	call	send_text
	ret
service_right
	ld	hl, right_text
	call	send_text
	ret

send_text
	ld	a, [hl+]
	cp	$80
	ret	z

	ld	b, a
	call	send_rs232
	jp	send_text

a_button_text
	db	"You pressed the A button ", $80

b_button_text
	db	"Hello world I pressed B ", $80

start_text
	db	"Start ", $80

select_text
	db	"Select ",$80

up_text
	db	"Up ", $80

down_text
	db	"Down ", $80

left_text
	db	"Left ", $80

right_text
	db	"Right ", $80

title_text
	db	"RS232 send & receive"

clear_ram
	ld	a, blank
	ld	hl, raw_data
	ld	bc, 36
	call	mem_Set
	ret

read_rs232		; read in byte at pin4
	ld	b, $80	; $01
	ei
	
wait_for_start_bit
	ldh	a, [$56]
	bit	4, a
	jp	nz, wait_for_start_bit
	di
	call	delay_130us

read_next_bit
	ldh	a, [$56]
	swap	a
	rr	a	; put pin 4 into carry
	rr	b
	jp	c, wait_for_stop_bit

	call	delay_104us
	jp	read_next_bit

wait_for_stop_bit
	call	delay_104us
	call	delay_104us

wait_for_after_stop_bit	
	ld	a, b
	ld	[raw_data], a
	ret

send_rs232			; send byte in B out Sout
	ld	e, 8
	ld	a, 0		; send start bit
	ldh	[$01], a
	ld	a, $83
	ldh	[$02], a
	call	delay_104us_send

send_next_bit
	rr	b
	ld	a, 0
	jp	nc, keep_it_zero
	ld	a, $FF

keep_it_zero
	ldh	[$01], a
	ld	a, $83
	ldh	[$02], a
	call	delay_104us_send
	dec	e
	jp	nz, send_next_bit

	ld	a, $FF		; send stop bit
	ldh	[$01], a
	ld	a, $83
	ldh	[$02], a
	call	delay_104us_send
	ret

delay_130us
	ld	d, 23
d130	dec	d
	jp	nz, d130
	ret

delay_104us
	ld	d, 17
d104	dec	d
	jp	nz, d104
	ret

delay_104us_send
	ld	d, 16
d104s	dec	d
	jp	nz, d104s
	ret

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

write_to_screen
	call	shift_display_left
	ld	a, [raw_data]
	ld	hl, text_line+19
	call	display_char

	ld	de, counter
	ld	hl, display_col+$20*3
	call	display_byte
	ret

shift_display_left
	ld	hl, text_line+1
	ld	de, text_line
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+2
	ld	de, text_line+1
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+3
	ld	de, text_line+2
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+4
	ld	de, text_line+3
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+5
	ld	de, text_line+4
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+6
	ld	de, text_line+5
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+7
	ld	de, text_line+6
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+8
	ld	de, text_line+7
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+9
	ld	de, text_line+8
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+10
	ld	de, text_line+9
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+11
	ld	de, text_line+10
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+12
	ld	de, text_line+11
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+13
	ld	de, text_line+12
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+14
	ld	de, text_line+13
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+15
	ld	de, text_line+14
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+16
	ld	de, text_line+15
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+17
	ld	de, text_line+16
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+18
	ld	de, text_line+17
	ld	bc, 1
	call	mem_CopyVRAM

	ld	hl, text_line+19
	ld	de, text_line+18
	ld	bc, 1
	call	mem_CopyVRAM

	ret
	
display_byte			; enter with value in [de]
	lcd_WaitVRAM
	ld	a, [de]
	ld	b, a
	and	$F0
	swap	a
	ld	[hl+], a
	lcd_WaitVRAM
	ld	a, b
	and	$0F
	ld	[hl], a
	ret

display_char
	bit	7, a		;don't look up non print chars
	ret	nz

	add	a, 20		;add imb char offset
	push	af
	lcd_WaitVRAM
	pop	af
	ld	[hl], a
	ret

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

	ld	a, %10000000
	ldh	[$68], a		; BCPS
	ld	a, %00000000	        ; palette 0 0  bg
	ldh	[$69], a		; BCPD
	ld	a,%00000000
	ldh	[$69],a

        ld	a, %11111110	        ; palette 0 1
	ldh	[$69], a
	ld	a, %00011110
	ldh	[$69], a

	ld	a, %11111111	        ; palette 0 2  fg test font
	ldh	[$69], a
	ld	a, %01111111
	ldh	[$69], a

	ld	a, %11111111	        ; palette 0 3  fg ibm font
	ldh	[$69], a
	ld	a, %01111111
	ldh	[$69], a

	;ld	a, %00000000	        ; palette 1 0  bg
	;ldh	[$69], a
	;ld	a, %00000000
	;ldh	[$69], a

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

	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, %00000011
	ldh	[$47], a		; BGP

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

        ld      hl, title_text
        ld      de, $9800
        ld      bc, 20
        call    mem_Copy_offset

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

	xor	a
	ld	[$FF24], a
	xor	a
	ld	[counter], a

	ld	a, %11000000
	ldh	[$56], a

	ld	a, $FF		        ; send stop bit
	ldh	[$01], a
	ld	a, $83
	ldh	[$02], a

        ld      a, IEF_HILO
        ldh     [rIE], a

	ret

wait_vb
	ldh	a, [$44]
	cp	144
	jp	nz, wait_vb
	ret

mem_Copy_offset::
	inc	b
	inc	c
	jr	.skip
.loop	ld	a, [hl+]
	add	a, 20	        ; my offset hack
	ld	[de], a
	inc	de
.skip	dec	c
	jr	nz, .loop
	dec	b
	jr	nz, .loop
	ret

ibm_characters
	chr_IBMPC1	1,8

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
raw_data	DS	1
   

Page created December 11, 2005 and