Search the web
Sign In
New User? Sign Up
gbadev
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Hear how Yahoo! Groups has changed the lives of others. Take me there.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
Enhanced GBA MultiBoot Cable   Message List  
Reply | Forward Message #13601 of 15019 |
Happy new year.

This is a project I have always want to do, which is a Enhanced MB cable
capable of downloading MultiBoot code to GBA without a computer.

This perticular design contains a 256kbyte FLASH memory wich is capable
of storing a single program.

The cable is very similar to the cable from www.godsmaze.org, except the
external FLASH memory device.

The cable is compatable with the software from www.godsmaze.org. I also
have written a PC side software that is used to download the code to the
FLASH memory, I wll post it as soon as I can get it cleaned up. The
software is kind of large and hard to use, if you need it, please send
me a note to request for it, since I want to avoid sending it though the
mailing list. (The program also includes a version of Multiboot
downloading code that does not use 32bit multiplication, could be useful
for people who are writing multiboot games who want to speed up the
download.)

I hope someone can make good use of this software, since I'm not good
with webpages, so chances are, I won't put it up on a webpage. This is
why I'm releasing it though the mailing list.

If anyone want to post this on their website, please feel free to do so.

The hardware description is included in the code. Feel free to ask any
question.

I probally won't do more work on this since I'm out of time.


Tn.


Thu Jan 2, 2003 4:34 am

kaijuupie
Offline Offline
Send Email Send Email

;**********************************************************************
;
; Enhanced GBA multiboot smart cable
; First release, Version 0.1.0, Jan 1, 2003 (Happy new year!)
;
; - Compiled by Tuna (by hand... )
; - Origional C code from godmaze.org
; - You can use this code for watever you wish, but I take no
; responsability for any injury, damage to property or copywrite
; breaches.
;
; - 100% compatable to the software from godsmaze.org
; - Extended function includes:
; - EEprom read/write
; - External FLASH read/write
; - 10 bits ADC
; - Debug serial port output, 57600 baud
; - The external dataFLASH are from Atmel, the code is tested
; with the 2-mbit device (AT45DB021B)
;
; Connection:
; Device tested: PIC16F872
; Device that might work: PIC16F87X (X = 3, 4, 6, 7)
; PortB 0: Printer D0 (pin 2) through 500Ohm resistor
; PortB 1: Printer D1 (pin 3) through 500Ohm resistor
; PortB 2: Printer D2 (pin 4) through 500Ohm resistor
; PortB 3: Printer D3 (pin 5) through 500Ohm resistor
; PortB 4: Printer (pin 11) through 100Ohm resistor
; PortB 5: Printer (pin 16) through 2.2kOhm resistor
; PortB 6: Printer (pin 17) through 2.2kOhm resistor
; PortB 7: Debug port, connect to RX of serial port
; though MAX232 (Optional)
; - Pulling the Debug port to Vcc though 10Kohm resistor start the
; processor in slave mode, waiting command from computer.
; - Pulling the Debug port to GND though 10Kohm resistor start the
; processor in mastor mode, sending the stored program to GBA
;
; PortA 0: Analog port, accept any analog input (Optional)
; PortA 1: GBA Pin 3
; PortA 2: GBA Pin 2
; PortA 3: Analog V+ reference port, can not be used when
; communicating with GBA. (Optional)
; PortA 4: GBA Pin 5
; PortA 5: GBA Pin 4
;
; GBA Pin 1 - Vcc (3.3V) connected to the Vcc of the entire circuit
; The entire system power is supplied by GBA
; GBA Pin 6 - System ground. (GND)
;
; PortC 3: to /CS pin of the dataFLASH
; PortC 4: to /SO pin of the dataFLASH (Data Input)
; PortC 5: to /SI pin of the dataFLASH (Data Output)
; PortC 6: to /CLK pin of the dataFLASH (Serial Clock)
;
; PortC 0,1,2,7 Not used, maybe someone will find a use for them
; System clock: 3.6864Mhz, same as the design from godsmaze.org
;
;**********************************************************************

list p=16F872 ; list directive to define processor
include <p16F872.inc> ; processor specific variable definitions

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF & _BODEN_OFF

;**********************************************************************
#define _DEBUG PORTB,7
#define _CMD PORTB,6
#define _HSi PORTB,5
#define _HSo PORTB,4

; Reserv PORTA,0 and PORTA,1 for analog signals
#define _SO PORTA,1
#define _SI PORTA,2
#define _SC PORTA,4
#define _SD PORTA,5

#define _CS PORTC,6



;********************************************************************** Variable
Command EQU 0x20
Nibble0 EQU 0x21
Nibble1 EQU 0x22
Nibble2 EQU 0x23
Nibble3 EQU 0x24
_Data EQU 0x25
Delay EQU 0x26
sendBy EQU 0x27
eeAddr EQU 0x28
Loop EQU 0x29
DF_ADDR_H EQU 0x2A
DF_ADDR_L EQU 0x2B
Loop2 EQU 0x2C
WordH EQU 0x22 ; Overlap Nibble1
WordL EQU 0x24 ; Overlap Nibble3
pAddr EQU 0x2D
Wtemp EQU 0x2E

Var1L EQU 0x30
LengthH EQU 0x31
LengthM EQU 0x32
LengthL EQU 0x33
Var8L EQU 0x34
VarCH EQU 0x35
VarCL EQU 0x36
PosH EQU 0x37
PosM EQU 0x38
PosL EQU 0x39

CRC32H EQU 0x3b
CRC32L EQU 0x3c
Var30 EQU 0x3f
SeedA EQU 0x40
SeedB EQU 0x41
SeedC EQU 0x42
SeedD EQU 0x43
TempA EQU 0x44
TempB EQU 0x45
TempC EQU 0x46
TempD EQU 0x47
DataH EQU 0x48
DataL EQU 0x49
DebugD EQU 0x4a
DebugL EQU 0x4b
;**********************************************************************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program

ORG 0x004 ; interrupt vector location

;********************************************************************** Main
main:
clrf INTCON
clrf PORTB
bsf STATUS, RP0

movlw b'10101000'
movwf OPTION_REG
clrf PIE1
clrf PIE2

movlw b'10001110' ; Analog channel setup
movwf ADCON1
bsf PORTA, 0 ; Analog input
bsf PORTA, 3 ; Analog input
; GBA signals
bcf _SO ; O
bsf _SI ; I
bsf _SD ; I
bsf _SC ; I

bsf _HSi ; I
bsf _CMD ; I
bcf _HSo ; O
bsf _DEBUG ; I Use as mode select when starting

bcf STATUS, RP0
bcf _DEBUG ; Debug is inactive low

movlw b'01000000' ; Analog converter off, Fosc/8 as clock
movwf ADCON0
bsf _SO ; Idle high

;************ DEBUG here!
;goto chip_id
;************ END DEBUG JP PT

;************************************************************ Receive a command
from computer
get_cmd:
bsf _HSo
bsf STATUS, RP0
movlw 0x0f
iorwf TRISB, F ; Set portB[0:3] to input
bcf STATUS, RP0
wait_cmd:
btfss _DEBUG
goto send_mb_image
btfss _CMD
goto wait_cmd

movfw PORTB
andlw 0x0f
movwf Command
bcf _HSo

wait_cmd_done:
btfss _DEBUG
goto send_mb_image
btfsc _CMD
goto wait_cmd_done

bsf STATUS, RP0
bcf _DEBUG ; Return to output
bcf STATUS, RP0

movfw Command
addwf PCL, f
goto get_cmd ; CMD 0 - Reserved
goto cmd_xfer ; CMD 1 - Transfer
goto chip_id ; CMD 2 - Standard ID
goto get_cmd ; CMD 3 - Reserved
goto get_cmd ; CMD 4 - Reserved
goto get_cmd ; CMD 5 - Reserved
goto get_cmd ; CMD 6 - Reserved
goto get_cmd ; CMD 7 - Reserved
goto ee_read ; CMD 8 - EEprom read
goto ee_write ; CMD 9 - EEprom write
goto spi_read ; CMD A - SPI read
goto spi_write ; CMD B - SPI write
goto adc_read ; CMD C - ADC read
goto get_cmd ; CMD D - Reserved
goto get_cmd ; CMD E - Reserved
goto EXT_id ; CMD F - Extended ID
goto get_cmd

;************************************************************
; CMD 0 - Transfer
;
cmd_xfer:
bsf STATUS,RP0
bcf _SO ; Output
bsf _SI ; Input
bsf _SD ; Input
bsf _SC ; Input
bcf STATUS,RP0

call get_nibbles ; Get a word from the computer
waitbh:
btfss _SC
goto waitbh
btfss _SD
goto waitbh

bsf STATUS,RP0
bcf _SD ; Output
bcf _SC ; Output
bcf STATUS,RP0

call send_bits ; send 16bits to GBA
call recv_bits ; receive 16bits from GBA
call put_nibbles ; put the 16bits to the computer

goto cmd_xfer ; Loop forever
goto get_cmd ; Waste catcher

;************************************************************
; CMD 1 - Chip ID - Return 0x636100
;
chip_id:
bsf STATUS,RP0
movfw TRISB
andlw 0xf0 ;PORTB[0:3] AS OUTPUTS
movwf TRISB
bcf STATUS,RP0

bsf _DEBUG ; Inactive high

movlw 0x06
call put_nibble_wH
movlw 0x03
call put_nibble_wL

movlw 0x06
call put_nibble_wH
movlw 0x01
call put_nibble_wL

movlw 0x00
call put_nibble_wH
movlw 0x00
call put_nibble_wL

movlw 'a'
call Send_Debug
goto get_cmd

;************************************************************
; CMD 8 - EEProm data read
;
ee_read:
bsf STATUS, RP0
movlw 0xf0
andwf TRISB, F ; PORTB[0:3] AS OUTPUTS
bcf STATUS, RP0

movlw 0x40
movwf Loop
movlw 0x00
movwf eeAddr
read_loop:
bsf STATUS, RP1 ; Bank 2
movfw eeAddr
movwf EEADR
bsf STATUS, RP0 ; Bank 3
bcf EECON1, EEPGD ; Data
bsf EECON1, RD ; Read
bcf STATUS, RP0 ; Bank 2
movfw EEDATA
bcf STATUS, RP1 ; Bank 0
call par_send_byte
incf eeAddr, F
decfsz Loop, F
goto read_loop
goto get_cmd

;************************************************************
; CMD A - EEProm data write
;
ee_write:
call par_read_byte ; Read address first
movwf eeAddr
call par_read_byte ; Read data next
movwf _Data

bsf STATUS, RP1 ; Bank 2
movfw eeAddr
movwf EEADR ; Address
movfw _Data
movwf EEDATA ; Data
bsf STATUS, RP0 ; Bank 3
bcf EECON1, EEPGD
bsf EECON1, WREN
bcf INTCON, GIE
movlw 0x55
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1, WR ; Start writing
;bsf INTCON, GIE ; Don't need it at this point
bcf EECON1, WREN
bcf STATUS, RP0
bcf STATUS, RP1 ; Bank 0
Write_loop:
btfss PIR2, EEIF
goto Write_loop
bcf PIR2, EEIF
goto get_cmd

;************************************************************
; CMD A - SPI DataFLASH read
; Receive a 2 byte block address
; Always send out a block of data, for 2Mbit
; chip, it is 264 bytes
spi_read:
bsf STATUS, RP0
bcf PORTC, 3 ; SCK set to output
bsf PORTC, 4 ; SDI set to input
bcf PORTC, 5 ; SDO set to output
bcf _CS ; CS set to output
bsf SSPSTAT, CKE ; DataFLASH Sample on falling cycle
bcf SSPSTAT, SMP ; PIC sample on falling cycle
bcf STATUS, RP0
movlw b'00100000' ; SPI master Fosc/4
movwf SSPCON ; SPI clock Idle low
bsf _CS ; CS idle high

call par_read_byte ; Read address first
movwf DF_ADDR_H
call par_read_byte ; Read data next
movwf DF_ADDR_L
;*********************** Finished setting up SPI port
bsf STATUS, RP0
movlw 0xf0
andwf TRISB, F ; PORTB[0:3] AS OUTPUTS
bcf STATUS, RP0

call read_df_setup

movlw 2
movwf Loop2
movlw 8
movwf Loop
SPI_read_loop2:
call Read_Next
call par_send_byte
decfsz Loop, F
goto SPI_read_loop2
decfsz Loop2, F
goto SPI_read_loop2
bsf _CS
goto get_cmd

;************************************************************
; CMD B - SPI DataFLASH write
spi_write:
bsf STATUS, RP0
bcf PORTC, 3 ; SCK set to output
bsf PORTC, 4 ; SDI set to input
bcf PORTC, 5 ; SDO set to output
bcf _CS ; CS set to output
bsf SSPSTAT, CKE ; DataFLASH Sample on falling cycle
bcf SSPSTAT, SMP ; PIC sample on falling cycle
bcf STATUS, RP0
movlw b'00100000' ; SPI master Fosc/4
movwf SSPCON ; SPI clock Idle low
bsf _CS ; CS idle high

call par_read_byte ; Read address first
movwf DF_ADDR_H
call par_read_byte ; Read data next
movwf DF_ADDR_L
spi_test:
;*********************** Finished setting up SPI port
bsf _DEBUG
bcf _DEBUG
bcf _CS
movlw 0x82 ; Buffer 1 write
movwf SSPBUF
bcf STATUS, C ; 1
rlf DF_ADDR_L, F ; 2
rlf DF_ADDR_H, F ; 3
nop ; 4
nop ; 5
nop ; 6
nop ; 7
nop ; 8
nop ; 9
movfw DF_ADDR_H ; 10
movwf SSPBUF ; High Address
nop
nop
nop
nop
nop
nop
nop
nop
nop ; 9
movfw DF_ADDR_L ; 10
movwf SSPBUF ; Low Address
nop
nop
nop
nop
nop
nop
nop
nop
movlw 0 ; 6
call Send_SPI_d ; Empty address, no addr within page
nop
nop
movlw 2
movwf Loop2
movlw 8
movwf Loop
SPI_write_loop:
call par_read_byte
movwf SSPBUF ; Send the data out
decfsz Loop, F
goto SPI_write_loop
decfsz Loop2, F
goto SPI_write_loop
nop
nop
nop
nop
nop
nop ; Last byte delay
bsf _CS
bcf _HSo ; Set _HSo low to indicate busy
SPI_write_wait:
bsf _CS
bcf _CS
movlw 0xd7
call Send_SPI_d
nop
movlw 0
call Send_SPI_d ; Read status
nop
nop
nop
nop
movfw SSPBUF
andlw 0x80 ; 7th bit is BUSY/READY
btfss STATUS, Z
goto SPI_write_wait
bsf _HSo ; High indicate ready, same as get_cmd
Deadlock:
bsf _CS
goto Deadlock ; Stall the process,
goto get_cmd ; must use a hard reset to exit
; Required for the computer to sense
; HSo correctly
;************************************************************
; CMD C - ADC read
;
adc_read:
bsf STATUS, RP0
movlw 0xf0
andwf TRISB, F ; PORTB[0:3] AS OUTPUTS
bcf STATUS, RP0

movlw 0xc7
andwf ADCON0, F ; Select channel 0
bsf ADCON0, ADON
call long_delay ; Wait at least 20uS for 5V
bsf ADCON0, GO
Wait_ADC:
btfsc ADCON0, GO
goto Wait_ADC
movf ADRESH, W
call par_send_byte
bsf STATUS, RP0
movf ADRESL, W
bcf STATUS, RP0
call par_send_byte
bcf ADCON0, ADON ; ADC off
goto get_cmd

;************************************************************
; CMD F - Extended Chip ID - Return 0x0001
;
EXT_id:
bsf STATUS,RP0
movfw TRISB
andlw 0xf0 ;PORTB(0-3) AS OUTPUTS
movwf TRISB
bcf STATUS,RP0

movlw 0x0
call put_nibble_wH
movlw 0x0
call put_nibble_wL
movlw 0x0
call put_nibble_wH
movlw 0x1
call put_nibble_wL
goto get_cmd


;************************************************************
; Boot up mode: send MB image from FLASH to GBA
;
send_mb_image:
bsf STATUS, RP0 ; Setup DataFLASH first
bcf PORTC, 3 ; SCK set to output
bsf PORTC, 4 ; SDI set to input
bcf PORTC, 5 ; SDO set to output
bcf _CS ; CS set to output
bsf SSPSTAT, CKE ; DataFLASH Sample on falling cycle
bcf SSPSTAT, SMP ; PIC sample on falling cycle
bcf _DEBUG ; Return to output
bcf STATUS, RP0

movlw b'00100000' ; SPI master Fosc/4
movwf SSPCON ; SPI clock Idle low
bsf _CS ; CS idle high
bsf _DEBUG ; Inactive high Use as serial out
call long_delay
movlw 'S'
call Send_Debug ; Mark Starting point
movlw ':'
call Send_Debug ; Again...

movlw 0x62 ; Send 0x6202, Attention
movwf WordH
movlw 0x02
movwf WordL ; Get GBA attention
call xfer_word ; Check if returning 0x7202

movf WordH, W
call Send_Debug
movf WordL, W
call Send_Debug ; Send out debug

movlw 0x72
xorwf WordH, F
btfss STATUS, Z
goto get_cmd ; Error, try again
movlw 0x02
xorwf WordL, F
btfss STATUS, Z
goto get_cmd ; Error, try again

movlw 0x61 ; Send 0x6100, header data
movwf WordH
clrf WordL
call xfer_word

movlw 0x60
movwf Loop ; Send 60 words of data
clrf DF_ADDR_H
clrf DF_ADDR_L ; Start from 1st page
call read_df_setup
nop
nop
nop
nop ; Wait for the first byte to be ready
nop
nop
load_loop1:
call Read_Next
movwf WordL
;call Send_Debug ; Also debug
call Read_Next
movwf WordH
;call Send_Debug ; Send out debug

call xfer_word
decfsz Loop, F
goto load_loop1

movlw 0x62 ; Sending command
movwf WordH
movlw 0x02
movwf WordL
call xfer_word

;movf WordH, W
;call Send_Debug
;movf WordL, W
;call Send_Debug ; Send out debug

movlw 0x63 ; Send encryption value
movwf WordH
movlw 0xc1
movwf WordL
call xfer_word

;movf WordH, W
;call Send_Debug
;movf WordL, W
;call Send_Debug ; Send out debug

movlw 0x63 ; Get encryption value
movwf WordH
movlw 0xc1
movwf WordL
call xfer_word

;movf WordH, W
;call Send_Debug
;movf WordL, W
;call Send_Debug ; Send out debug

movf WordL, W
movwf SeedC ; Seed of encryption
movlw 0xc1
movwf SeedD
movlw 0xff
movwf SeedB ; Setup the Encryption seed with 0xFFFFxxC1
movwf SeedA ; Note, xx is given by GBA
movf WordL, W
addlw 0x0F
movwf Var1L
movlw 0x64
movwf WordH
movf Var1L, W
movwf WordL
call xfer_word ; Send back Var1L | 0x6400

;*********************** Read the length of the program
bsf STATUS, RP1 ; Bank 2
movlw 0x00
movwf EEADR
bsf STATUS, RP0 ; Bank 3
bcf EECON1, EEPGD ; Data
bsf EECON1, RD ; Read
bcf STATUS, RP0 ; Bank 2
movlw LengthH
movwf FSR
movf EEDATA, W ; LengthH
movwf INDF
incf EEADR, F
bsf STATUS, RP0 ; Bank 3
bcf EECON1, EEPGD ; Data
bsf EECON1, RD ; Read
bcf STATUS, RP0 ; Bank 2
incf FSR, F
movf EEDATA, W ; LengthM
movwf INDF
incf EEADR, F
bsf STATUS, RP0 ; Bank 3
bcf EECON1, EEPGD ; Data
bsf EECON1, RD ; Read
bcf STATUS, RP0 ; Bank 2
incf FSR, F
movf EEDATA, W ; LengthL
movwf INDF
bcf STATUS, RP1 ; Bank 0


movf LengthL, W
movwf TempD
movf LengthM, W
movwf TempC
movf LengthH, W
movwf TempB

movlw 0xc0
subwf TempD, F
btfsc STATUS, C
goto SkipDecCarry
movf TempC, F
btfsc STATUS, Z
decf TempB, F
decf TempC, F ; Length - 0xc0
SkipDecCarry:
bcf STATUS, C
rrf TempB, F
rrf TempC, F
rrf TempD, F
bcf STATUS, C
rrf TempB, F
rrf TempC, F
rrf TempD, F ; Length >> 2

movlw 0x34
subwf TempD, W
movwf WordL
movf TempC, W
btfss STATUS, C
decf TempC, W
movwf WordH ; Length - 0x34
call xfer_word

movf WordL, W
movwf Var8L

movlw 0xff
movwf VarCH
movlw 0xf8
movwf VarCL
movlw 0xc0
movwf PosL
clrf PosM
clrf PosH
;----------------------------------------------------
Send_data_loop:
call Read_Next
movwf DataL
movwf CRC32L
call Read_Next
movwf DataH
movwf CRC32H

;movf DataL, W
;call Send_Debug
;movf DataH, W
;call Send_Debug ; Send out debug

call Do_CRC

;movf SeedA, W
;call Send_Debug
;movf SeedB, W
;call Send_Debug ; Send out debug
;movf SeedC, W
;call Send_Debug
;movf SeedD, W
;call Send_Debug ; Send out debug

btfsc PosL, 1
goto Skip_Encrypt
;Compute Encryption seed, which is
; (seed * 0x6F64573) + 1
bcf STATUS, C
rlf SeedD, W
movwf TempD
rlf SeedC, W
movwf TempC
rlf SeedB, W
movwf TempB
rlf SeedA, W
movwf TempA
call AddM ; Bit 0 and 1
call Shift
call Shift
call Shift
call AddM ; Bit 4
call Shift
call AddM ; Bit 5
call Shift
call AddM ; Bit 6
call Shift
call Shift
call AddM1 ; Bit 8
call Shift
call Shift
call AddM1 ; Bit 10
call Shift
call Shift
call Shift
call AddM1 ; Bit 13
call Shift
call AddM1 ; Bit 14
call Shift
call Shift
call Shift
call Shift
call AddM2 ; Bit 18
call Shift
call Shift
call Shift
call AddM2 ; Bit 21
call Shift
call AddM2 ; Bit 22
call Shift
call Shift
call AddM2 ; Bit 24
call Shift
call AddM3 ; Bit 25
call Shift
call AddM3 ; Bit 26
call Shift
call AddM3 ; Bit 27
call Shift
call Shift
call AddM3 ; Bit 29
call Shift
call AddM3 ; Bit 30
incf SeedD, F
btfsc STATUS, Z
incf SeedC, F
btfsc STATUS, Z
incf SeedB, F
btfsc STATUS, Z
incf SeedA, F ; Increase Seed by 1

comf PosL, W
movwf WordL
comf PosM, W
movwf WordH
comf PosH, W ; Use temp B & A for the client_pos
movwf TempB ; of next xfer
movlw 0xfd ; ~0x20
movwf TempA
incf WordL, F
btfsc STATUS, Z
incf WordH, F
btfsc STATUS, Z
incf TempB, F
btfsc STATUS, Z
incf TempA, F ; ~client_pos+1

movf SeedD, W
xorwf DataL, W
xorlw 0x6f
xorwf WordL, F
movf SeedC, W
xorwf DataH, W
xorlw 0x64
xorwf WordH, F
goto Send_data_16
Skip_Encrypt:
movf TempB, W
xorwf SeedB, W
xorwf DataL, W
xorlw 0x65
movwf WordL
movf TempA, W
xorwf SeedA, W
xorwf DataH, W
xorlw 0x64
movwf WordH
Send_data_16:
call xfer_word ; Send out the computed data

movlw 0x02
addwf PosL, F ; client_pos += 2
btfsc STATUS, C
incf PosM, F
btfsc STATUS, Z
incf PosH, F

movf PosL, W
xorwf LengthL, W
btfss STATUS, Z
goto Send_data_loop

movf PosM, W
xorwf LengthM, W
btfss STATUS, Z
goto Send_data_loop

movf PosH, W
xorwf LengthH, W
btfss STATUS, Z
goto Send_data_loop

movlw 'D'
call Send_Debug
movlw ':'
call Send_Debug ; Send out debug
Wait_for_ack:

movlw 0x65
movwf WordL
clrf WordH
call xfer_word ; End of transfer

movf WordH, W
call Send_Debug
movf WordL, W
call Send_Debug ; Send out debug

movlw 0x75
xorwf WordL, W
btfss STATUS, Z
goto Wait_for_ack ; Wait for GBA to ack

movlw 0x66
movwf WordL
clrf WordH
call xfer_word

movf VarCH, W
call Send_Debug
movf VarCL, W
call Send_Debug ; Send out debug


movf Var8L, W
movwf CRC32H
movf Var1L, W
movwf CRC32L
call Do_CRC
movlw 0xff
movwf CRC32H
movwf CRC32L
call Do_CRC
movf VarCL, W
movwf WordL
movf VarCH, W
movwf WordH
call xfer_word ; Send CRC out

movf WordH, W
call Send_Debug
movf WordL, W
call Send_Debug ; Send out debug

movf VarCH, W
call Send_Debug
movf VarCL, W
call Send_Debug ; Send out debug

movf Var8L, W ; Final CRC value for debug
call Send_Debug
movf Var1L, W
call Send_Debug ; Send out debug
goto get_cmd


Shift:
bcf STATUS, C
rlf TempD, F
rlf TempC, F
rlf TempB, F
rlf TempA, F
return

AddM:
movf TempD, W
addwf SeedD, F
bcf STATUS, Z ; If incf is not executed,
btfsc STATUS, C ; Make sure carry does not goes on
incf SeedC, F
btfsc STATUS, Z
incf SeedB, F
btfsc STATUS, Z
incf SeedA, F ; Byte D
AddM1:
movf TempC, W
addwf SeedC, F
bcf STATUS, Z
btfsc STATUS, C
incf SeedB, F
btfsc STATUS, Z
incf SeedA, F ; Byte C
AddM2:
movf TempB, W
addwf SeedB, F
btfsc STATUS, C
incf SeedA, F
AddM3:
movf TempA, W
addwf SeedA, F
bcf STATUS, C
return

Do_CRC:
;******* Compute CRC
movlw 0x10
movwf Loop ; Process 16 bits
CRCLoop:
movf VarCL, W
xorwf CRC32L, W
movwf Var30 ; var_30 = var_C^CRCTemp
bcf STATUS, C
rrf VarCH, F
rrf VarCL, F ; Var_C = Var_C >> 1
bcf STATUS, C
rrf CRC32H, F
rrf CRC32L, F ; CRCTemp = CRCTemp >> 1
btfss Var30, 0
goto Skip_reset
movlw 0xa5
xorwf VarCH, F
movlw 0x17
xorwf VarCL, F
Skip_reset:
decfsz Loop, F
goto CRCLoop
return

;************************************************************
; subroutine: send nibble bits to GBA,
;
send_nibble_bits:
btfss INDF,0 ;6 ;38
goto Set0_Lo ;7 ;39
bsf _SD ;8 ;40 (*)
goto Set1 ;9 ;41
Set0_Lo:
bcf _SD ;9 (**) <-- ;41
nop ;10 ;42
Set1:
btfss INDF,1 ;11 <-- ;43
goto Set1_Lo ;12 ;44
nop ;13 ;45
nop ;14 ;46
nop ;15 ;47
bsf _SD ;16 (*) ;48
goto Set2 ;17 ;49
Set1_Lo:
nop ;14 <-- ;46
nop ;15 ;47
bcf _SD ;16 (*) ;48
nop ;17
nop ;18
Set2:
btfss INDF,2 ;19 <--
goto Set2_Lo ;20
nop ;21
nop ;22
nop ;23
bsf _SD ;24 (*) ;56
goto Set3 ;25
Set2_Lo:
nop ;22 <--
nop ;23
bcf _SD ;24 (*) ;56
nop ;25
nop ;26
Set3:
btfss INDF,3 ;27 <--
goto Set3_Lo ;28
nop ;29
nop ;30
nop ;31
bsf _SD ;32 (*) ;64
return ;33
Set3_Lo:
nop ;30 <--
nop ;31
bcf _SD ;32 (*) ;64
return ;33

;************************************************************
; subroutine: send a 16 bit word to GBA, stored in Nibble
;
send_bits:
movlw Nibble3
movwf FSR

movfw PORTA
andlw B'11001111' ; raise SC & SD (Active low)
movwf PORTA ; SC- Clock, SD- Data
nop
nop
nop
nop
nop ;3 -2
call send_nibble_bits ;4
decf FSR,f ;35
call send_nibble_bits ;36
decf FSR,f ;67
call send_nibble_bits ;68
decf FSR,f ;99
call send_nibble_bits ;100
;131
nop ;(3)
nop ;(4) keep the last bit
nop ;(5)
nop ;(6)
nop ;(7)
bsf _SD ;(8) STOP bit

return

;************************************************************
; subroutine: send and receive a 16 bit word to GBA,
; stored in Word
xfer_word:
bsf STATUS,RP0
bcf _SO ; Output
bsf _SI ; Input
bsf _SD ; Input
bsf _SC ; Input
bcf STATUS,RP0
swapf Nibble3, W ; [4:7] Word L
movwf Nibble2
swapf Nibble1, W ; [8:11] Word H
movwf Nibble0

waitbh_W:
btfss _SC
goto waitbh_W
btfss _SD
goto waitbh_W

bsf STATUS,RP0
bcf _SD ; Output
bcf _SC ; Output
bcf STATUS,RP0

call send_bits ; send 16bits to GBA
call recv_bits ; receive 16bits from GBA
return

;************************************************************
; subroutine: receive nibble bits,
;
recv_nibble_bits:
btfss _SD ;9 ;38
goto rSet0_Lo ;7 ;39
bsf INDF,0 ;8 ;40 (*)
goto rSet1 ;9 ;41
rSet0_Lo:
bcf INDF,0 ;9 (**) <-- ;41
nop ;10 ;42
rSet1:
btfss _SD ;11 <-- ;43
goto rSet1_Lo ;12 ;44
nop ;13 ;45
nop ;14 ;46
nop ;15 ;47
bsf INDF,1 ;16 (*) ;48
goto rSet2 ;17 ;49
rSet1_Lo:
nop ;14 <-- ;46
nop ;15 ;47
bcf INDF,1 ;16 (*) ;48
nop ;17
nop ;18
rSet2:
btfss _SD ;19 <--
goto rSet2_Lo ;20
nop ;21
nop ;22
nop ;23
bsf INDF,2 ;24 (*) ;56
goto rSet3 ;25
rSet2_Lo:
nop ;22 <--
nop ;23
bcf INDF,2 ;24 (*) ;56
nop ;25
nop ;26
rSet3:
btfss _SD ;27 <--
goto rSet3_Lo ;28
nop ;29
nop ;30
nop ;31
bsf INDF,3 ;32 (*) ;64
return ;33
rSet3_Lo:
nop ;30 <--
nop ;31
bcf INDF,3 ;32 (*) ;64
return ;33

;************************************************************
; subroutine: receive 16 bit word from GBA, stored in Nibble
;
recv_bits:
bsf STATUS,RP0
bsf _SD ;SD as input
bcf STATUS,RP0
movlw Nibble3
movwf FSR
bcf _SO ;ask for 16bits
wait_for_start:
btfsc _SD ;0
goto wait_for_start ;1
nop ;2
nop ;3
nop ;4
nop ;5
nop ;6
nop ;-------centering waveform ;P
nop
nop
nop
nop
call recv_nibble_bits ;7
decf FSR,f
call recv_nibble_bits
decf FSR,f
call recv_nibble_bits
decf FSR,f
call recv_nibble_bits
movlw 0x0f ; Steal 5 cycle to use
andwf Nibble0, F
andwf Nibble1, F
andwf Nibble2, F
andwf Nibble3, F ; stop bit -5

swapf Nibble2, W ; Steal 4 more cycle to assemble the 16bit word
iorwf Nibble3, F
swapf Nibble0, W
bsf _SO ; SO high as ACK
iorwf Nibble1, F
wait_ack:
btfsc _SI
goto wait_ack
wait_nack
btfss _SI
goto wait_nack
bsf _SC ;put _SC high ; EOT
return

;************************************************************
; subroutine: write a byte into parallel port, data in W
par_send_byte:
movwf sendBy
swapf sendBy, W
call put_nibble_wH
movfw sendBy
call put_nibble_wL
return

;************************************************************
; subroutine: read a byte from parallel port, place in W
par_read_byte:
call get_nibble_wH
movwf sendBy
call get_nibble_wL
movlw 0x0f
andwf _Data, F
swapf sendBy, W
andlw 0xf0
iorwf _Data, W
return

;************************************************************
; subroutine: Read from parallel port - 4 nibbles
;
get_nibbles:
bsf STATUS, RP0
movlw 0x0f ; PortB[0,3] as input
iorwf TRISB, F
bcf STATUS, RP0
call get_nibble_wH ; [15,12]
movwf Nibble0
call get_nibble_wL ; [11, 8]
movwf Nibble1

call get_nibble_wH ; [ 7, 4]
movwf Nibble2
call get_nibble_wL ; [ 3, 0]
movwf Nibble3
return

;************************************************************
; subroutine: Write to parallel port - 4 nibbles
;
put_nibbles:
bsf STATUS, RP0
movlw 0xf0
andwf TRISB, F
bcf STATUS, RP0

movfw Nibble0
call put_nibble_wH
movfw Nibble1
call put_nibble_wL

movfw Nibble2
call put_nibble_wH
movfw Nibble3
call put_nibble_wL
return

;************************************************************
; subroutine: Get nibble from parallel port

get_nibble_wH:
btfss _HSi ; Wait for_HSi high
goto get_nibble_wH
Call GetBits
bsf _HSo ; Set _HSo high
return

get_nibble_wL:
btfsc _HSi ; Wait for _HSi low
goto get_nibble_wL
Call GetBits ; both W and _Data contain the data
bcf _HSo ; set _HSo low
return

;************************************************************
; subroutine: Put nibble to parallel port

put_nibble_wH:
movwf _Data
Call PutBits
bsf _HSo
pn_wH:
btfss _HSi ;Wait for_HSi high
goto pn_wH
return

put_nibble_wL:
movwf _Data
Call PutBits
bcf _HSo
pn_wL:
btfsc _HSi ; Wait for_HSi low
goto pn_wL
return

;************************************************************
; subroutine: Put/get data on/to the parallel port
PutBits:
movlw 0xf0
andwf PORTB, F
movfw _Data
andlw 0x0f
iorwf PORTB, F
return

GetBits:
movlw 0x0f
andwf PORTB, W
movwf _Data
return

;************************************************************
; subroutine: Delay, 255 cycles 830uS for 3.684Mhz clock
long_delay:
decfsz Delay, F
goto long_delay
return

;************************************************************
; subroutine: Setup DataFlash for transfer at address
; specified in DF_ADDR.
;
read_df_setup:
bsf _CS ; Reset for next transfer
bcf _CS
movlw 0xd2 ; Main memory read 0xd2
movwf SSPBUF
bcf STATUS, C ; 1
nop ; 2
nop ; 3
nop ; 4
nop ; 5
nop ; 6
nop ; 7
nop ; 8
rlf DF_ADDR_L, W ; 9
rlf DF_ADDR_H, W ; 10
movwf SSPBUF ; High Address
nop
nop
nop
nop
nop
nop
nop
bcf STATUS, C
rlf DF_ADDR_L, W ; 9
nop ; 10
movwf SSPBUF ; Low Address
nop
nop
nop
nop
nop
nop
nop
nop
movlw 0 ; 6
call Send_SPI_d ; Empty address, no addr within page
nop
nop
call Send_SPI_d ; 4 don't care bytes
nop
nop
call Send_SPI_d
nop
nop
call Send_SPI_d
nop
nop
call Send_SPI_d
nop
movf SSPBUF, W ; EMPTY out buffer
call Send_SPI_d ; Init receving
clrf pAddr ; Clear address pt
return

;************************************************************
; subroutine: Read the next byte from DataFLASH
Read_Next:
movf SSPBUF, W
clrf SSPBUF ; Start the next transfer
incf pAddr, F ; Point to next byte
nop
nop
btfss STATUS, Z
return
; Read the next page
incf DF_ADDR_L, F
btfsc STATUS, Z
incf DF_ADDR_H, F
movwf Wtemp
call read_df_setup
movf Wtemp, W
return

;************************************************************
; subroutine: SendSPI with delay
Send_SPI_d: ; Call need 2 cycles
movwf SSPBUF
nop ; Total 9 cycles, leaving 1 cycle to load data
nop ;
nop
nop
return ; return need 2 cycles
;************************************************************
; subroutine: SendSPI with delay, roughly 57600 baud
Send_Debug:
movwf DebugD
movlw 0x08
movwf DebugL
bcf _DEBUG ; Start bit, always low
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
DebugLoop:
rrf DebugD, F
btfss STATUS, C
goto BitSetLow
nop
bsf _DEBUG
goto BitFinish
BitSetLow:
bcf _DEBUG
nop
nop
BitFinish:
nop
nop
nop
nop
nop
nop
decfsz DebugL, F
goto DebugLoop
nop
nop
nop
nop
nop
bsf _DEBUG ; Stop bit, always high
return
;************************************************************ End
end


Forward
Message #13601 of 15019 |
Expand Messages Author Sort by Date

Happy new year. This is a project I have always want to do, which is a Enhanced MB cable capable of downloading MultiBoot code to GBA without a computer. This...
Tuna
kaijuupie
Offline Send Email
Jan 2, 2003
4:43 am

Interesting..is the device capable of sending the data from flash to the gba on powerup? If so I'd like to try it out. ... [30kb code cropped by mod to save...
Steve Garcia
DeathPing
Offline Send Email
Jan 2, 2003
10:56 am

That is exactly the purpose of the device. It seems there are still some little bugs in the program, the device has to reset several times before GBA will...
Tuna
kaijuupie
Offline Send Email
Jan 3, 2003
1:18 am
Advanced

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help