'**************************************************************** '* Name : megaduck.pbp * '* Author : Sean Riddle * '* Notice : Copyright (c) 2013 Sean Riddle * '* : All Rights Reserved * '* Date : 08/10/2013 * '* Version : 1.0 * '* Notes : * '* : * '**************************************************************** INCLUDE "modedefs.bas" #config CONFIG FOSC = INTIO67 ;Internal oscillator block CONFIG PLLCFG = OFF ;Oscillator not multiplied by 4 CONFIG PRICLKEN = ON ;Primary clock is always enabled CONFIG FCMEN = OFF ;Fail-Safe Clock Monitor disabled CONFIG IESO = OFF ;Oscillator Switchover mode disabled CONFIG PWRTEN = OFF ;Power up timer disabled CONFIG BOREN = OFF ;Brown-out Reset disabled in hardware and software CONFIG BORV = 285 ;VBOR set to 2.85 V nominal CONFIG WDTEN = OFF ;Watch dog timer is always disabled. SWDTEN has no effect. CONFIG WDTPS = 32768 ;1:32768 CONFIG CCP2MX = PORTC1 ;CCP2 input/output is multiplexed with RC1 CONFIG PBADEN = OFF ;PORTB<5:0> pins are configured as digital I/O on Reset CONFIG CCP3MX = PORTB5 ;P3A/CCP3 input/output is multiplexed with RB5 CONFIG HFOFST = ON ;HFINTOSC output and ready status are not delayed by the oscillator stable status CONFIG T3CMX = PORTC0 ;T3CKI is on RC0 CONFIG P2BMX = PORTD2 ;P2B is on RD2 CONFIG MCLRE = EXTMCLR ;MCLR pin enabled, RE3 input pin disabled CONFIG STVREN = ON ;Stack full/underflow will cause Reset CONFIG LVP = OFF ;Single-Supply ICSP disabled CONFIG XINST = OFF ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode) CONFIG DEBUG = OFF ;Disabled CONFIG CP0 = OFF ;Block 0 (000800-003FFFh) not code-protected CONFIG CP1 = OFF ;Block 1 (004000-007FFFh) not code-protected CONFIG CP2 = OFF ;Block 2 (008000-00BFFFh) not code-protected CONFIG CP3 = OFF ;Block 3 (00C000-00FFFFh) not code-protected CONFIG CPB = OFF ;Boot block (000000-0007FFh) not code-protected CONFIG CPD = OFF ;Data EEPROM not code-protected CONFIG WRT0 = OFF ;Block 0 (000800-003FFFh) not write-protected CONFIG WRT1 = OFF ;Block 1 (004000-007FFFh) not write-protected CONFIG WRT2 = OFF ;Block 2 (008000-00BFFFh) not write-protected CONFIG WRT3 = OFF ;Block 3 (00C000-00FFFFh) not write-protected CONFIG WRTC = OFF ;Configuration registers (300000-3000FFh) not write-protected CONFIG WRTB = OFF ;Boot Block (000000-0007FFh) not write-protected CONFIG WRTD = OFF ;Data EEPROM not write-protected CONFIG EBTR0 = OFF ;Block 0 (000800-003FFFh) not protected from table reads executed in other blocks CONFIG EBTR1 = OFF ;Block 1 (004000-007FFFh) not protected from table reads executed in other blocks CONFIG EBTR2 = OFF ;Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks CONFIG EBTR3 = OFF ;Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks CONFIG EBTRB = OFF ;Boot Block (000000-0007FFh) not protected from table reads executed in other blocks #endconfig DEFINE OSC 16 ;16x1 MHz oscillator DEFINE NO_CLRWDT 1 ;watchdog is off define LOADER_USAD 1 BRGH var TXSTA1.2 BRG16 var BAUDCON1.3 SYNC var TXSTA1.4 SPEN var RCSTA1.7 CKTXP var BAUDCON1.4 DTRXP var BAUDCON1.5 TXEN var TXSTA1.5 CREN var RCSTA1.4 OERR var RCSTA1.1 TRMT var TXSTA1.1 ;set when transmit shift reg is empty RC1IF var PIR1.5 RBPU var intcon2.7 PLLEN var osctune.6 databus var portb ;aliases addrh var portd addrl var porta _WR var porte.0 _RD var porte.1 _RST var porte.2 i var byte ;general purpose var j var byte k var byte sercmd var byte[3] db var byte startupstring var byte[20] blstring var byte[10] ;PIC initialization OSCCON = %01110000 ;16MHz using Primary Int Osc PLLEN = 0 ;0=PLL disabled for internal osc only ANSELA = 0 ;turn off analog ANSELB = 0 ANSELC = 0 ANSELD = 0 ANSELE = 0 ADCON0 = 0 ;disable ADCs CM1CON0 = 0 ;disable Comparators CM2CON0 = 0 ;disable Comparators intcon2.7 = 0 ;weak pull-ups on portb rbpu=0 ;weak pull-ups on port B wpub=$ff trisa=$00 ;port A all out - address bus A7-A0 trisb=$ff ;port B all in - databus trisd=$00 ;port D all out - address bus A15-A8 trise=$00 ;port e all out - unused, E3=MCLR, _RST, _RD, _WR porta=0 portd=0 porte=0 ;manually configure serial for high-speed inverted polarity - no MAX232 needed SPBRGH1=0 ; BRGH=1 ;BRGH - high speed BRG BRG16=1 ;BRG16 - 8-bit BRG SPBRG1=15 ;16MHz/(4*(34+1))=115200 trisc=%11000000 ;port C all out - RX1 and TX1 in portc=0 SYNC=0 ;SYNC off for async serial SPEN=1 ;SPEN enables serial port CKTXP=1 ;CKTXP invert polarity so no converter needed TXEN=1 ;TXEN to enable transmit DTRXP=1 ;DTRXP invert polarity so no converter needed CREN=1 ;CREN to enable receive arraywrite startupstring, [13,10,"MegaDuck V0.4",13,10] arraywrite blstring, ["B/L",13,10] pause 1000 for i=1 to 8 ;send 8 "U"s for sync (0x55) while TRMT=0 ;wait until TX buffer empty wend TXREG1="U" next for i=0 to 16 ;send startup message while TRMT=0 ;wait until TX buffer empty wend TXREG1=startupstring[i] next ;setup cart signals _RD=1 ;_RD=0 for read _WR=1 ;_WR=1 for not write _RST=0 ;/reset=0 for reset - set ROM bank to 0 pauseus 10 _RST=1 ;/reset=1 for not reset mloop: cren=0 ;clear overrun, if needed cren=1 while RC1IF=0 ;wait for serial input if OERR=1 then cren=0 cren=1 endif wend sercmd[0]=RCREG1 ;commands follow if sercmd[0]="!" then ;run the bootloader wdtcon.0=0 ;turn off watchdog timer for i=0 to 4 ;send message while TRMT=0 wend TXREG1=blstring[i] next pause 10 ;jump to the bootloader @ movlw 0xfd @ movwf PCLATH @ goto 0xfd00 ;update address from .lst if bl reassembled endif if sercmd[0]="?" then ;show version # for i=0 to 16 while TRMT=0 wend TXREG1=startupstring[i] next endif ;set bank # 0 = F if (sercmd[0]>="0" and sercmd[0]<="9") or (sercmd[0]>="A" and sercmd[0]<="F") then _RD=1 ;bank switch modes: ; $0001 for 16K banks addrh=$00 addrl=$01 ; $B000 for 32K banks ; addrh=$B0 ; addrl=$00 trisb=$00 ;data bus output @ nop if (sercmd[0]>="0" and sercmd[0]<="9") then databus=sercmd[0]-"0" else databus=sercmd[0]-"A"+10 endif @ nop _WR=0 ;_WR=0 for write @ nop _WR=1 ;_WR=1 for not write @ nop trisb=$FF ;d0 input while TRMT=0 ;wait until TX buffer empty wend TXREG1="B" while TRMT=0 ;wait until TX buffer empty wend TXREG1=sercmd[0] while TRMT=0 ;wait until TX buffer empty wend TXREG1=$d while TRMT=0 ;wait until TX buffer empty wend TXREG1=$a endif ;test code - reset bank if sercmd[0]="P" then _RST=0 ;/reset=0 for reset pauseus 10 _RST=1 ;/reset=1 for not reset while TRMT=0 ;wait until TX buffer empty wend TXREG1="B" while TRMT=0 ;wait until TX buffer empty wend TXREG1="R" while TRMT=0 ;wait until TX buffer empty wend TXREG1=$d while TRMT=0 ;wait until TX buffer empty wend TXREG1=$a endif ;read one bank if sercmd[0]="R" then for i=0 to 255 portd=i for j=0 to 255 porta=j @ nop _RD=0 ;_RD=0 for read @ nop db=databus _RD=1 ;_RD=0 for read (1=all FFs) while TRMT=0 ;wait until TX buffer empty wend TXREG1=db ;write data bus contents to serial port next j next i endif ;read 32 banks if sercmd[0]="Z" then _RD=1 for k=0 to 31 ;bank switch modes: ; $0001 for 16K banks addrh=$00 addrl=$01 ; $B000 for 32K banks ; addrh=$B0 ; addrl=$00 trisb=$00 ;data bus output @ nop databus=k @ nop _WR=0 ;_WR=0 for write @ nop _WR=1 ;_WR=1 for not write @ nop trisb=$FF ;db input for i=0 to 255 portd=i ;set high address bits for j=0 to 255 porta=j ;set low address bits @ nop _RD=0 ;_RD=0 for read @ nop db=databus _RD=1 while TRMT=0 ;wait until TX buffer empty wend TXREG1=db ;write data bus contents to serial port next j next i next k endif goto mloop end