Skip to content

Commit 3d4fa61

Browse files
committed
64drive: add support for extended mode, handle errors for ROMs >64MiB
1 parent a6e90ef commit 3d4fa61

File tree

3 files changed

+88
-9
lines changed

3 files changed

+88
-9
lines changed

drive64/const.go

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ const (
2020
CmdSetCicType Cmd = 0x72
2121
// CmdSetSaveType sets the save emulation
2222
CmdSetSaveType Cmd = 0x70
23+
// CmdSetExtended sets the CI extended mode (to use the whole 256Mb of SDRAM)
24+
CmdSetExtended Cmd = 0x74
2325
// CmdVersionRequest requests the hardware and firmware version
2426
CmdVersionRequest Cmd = 0x80
2527
// CmdUpgradeStart starts a firmware upgrade

drive64/drive64.go

+8
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,14 @@ func (d *Device) CmdSetSaveType(st SaveType) error {
255255
return d.SendCmd(CmdSetSaveType, args[:], nil, nil)
256256
}
257257

258+
func (d *Device) CmdSetExtended(enable bool) error {
259+
var args [1]uint32
260+
if enable {
261+
args[0] = 1
262+
}
263+
return d.SendCmd(CmdSetExtended, args[:], nil, nil)
264+
}
265+
258266
func idealChunkSize(size int64) int {
259267
switch {
260268
case size >= 16*1024*1024:

main.go

+78-9
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ var (
3333
flagSize sizeUnit
3434
flagAutoCic bool
3535
flagAutoSave bool
36+
flagAutoExtended bool
3637
flagBank string
3738
flagQuiet bool
3839
flagByteswapD int
3940
flagByteswapU int
4041
flagFwExtractOut string
4142

42-
pflagAutoCic *pflag.Flag
43-
pflagAutoSave *pflag.Flag
43+
pflagAutoCic *pflag.Flag
44+
pflagAutoSave *pflag.Flag
45+
pflagAutoExtended *pflag.Flag
4446
)
4547

4648
type sizeUnit struct {
@@ -365,11 +367,6 @@ func cmdUpload(cmd *cobra.Command, args []string) error {
365367
offset := uint32(flagOffset.size)
366368
vprintf("offset: %v\n", offset)
367369

368-
rommd5 := md5.New()
369-
if err := upload(dev, io.TeeReader(bs.NewReader(f), rommd5), size, bank, offset, filepath.Base(args[0])); err != nil {
370-
return err
371-
}
372-
373370
// --autocic defaults to true when uploading a ROM to CARTROM at offset 0
374371
if !pflagAutoCic.Changed && bank == drive64.BankCARTROM && offset == 0 {
375372
flagAutoCic = true
@@ -378,6 +375,36 @@ func cmdUpload(cmd *cobra.Command, args []string) error {
378375
flagAutoSave = true
379376
}
380377

378+
// --extended defaults to true when uploading a ROM to CARTROM at offset 0, if the ROM is larger than 64MB
379+
// Otherwise, the ROM would uploaded correctly but the data would be inaccessible.
380+
if !pflagAutoExtended.Changed && bank == drive64.BankCARTROM && offset == 0 && size > 64*1024*1024 {
381+
if hwvar, fwver, _, err := dev.CmdVersionRequest(); err == nil && hwvar == drive64.VarRevA {
382+
// Return an appropriate error message for HW1, taking into account that the user doesn't
383+
// probably know what extended mode is.
384+
return errors.New("ROMs larger than 64 MiB not supported on 64drive HW1")
385+
} else if fwver < 206 {
386+
return errors.New("ROMs larger than 64 MiB not supported on 64drive firmware < 2.06")
387+
}
388+
flagAutoExtended = true
389+
}
390+
391+
if flagAutoExtended {
392+
vprintf("Set extended mode\n")
393+
if hwvar, fwver, _, err := dev.CmdVersionRequest(); err == nil && hwvar == drive64.VarRevA {
394+
return errors.New("extended mode not supported on 64drive HW1")
395+
} else if fwver < 206 {
396+
return errors.New("extended mode not supported on 64drive firmware < 2.06")
397+
} else if err := dev.CmdSetExtended(true); err != nil {
398+
return err
399+
}
400+
}
401+
402+
vprintf("uploading\n")
403+
rommd5 := md5.New()
404+
if err := upload(dev, io.TeeReader(bs.NewReader(f), rommd5), size, bank, offset, filepath.Base(args[0])); err != nil {
405+
return err
406+
}
407+
381408
if flagAutoCic {
382409
cic, err := cicAutodetect(dev)
383410
if err != nil {
@@ -563,6 +590,31 @@ func cmdSaveType(cmd *cobra.Command, args []string) error {
563590

564591
}
565592

593+
func cmdExtended(cmd *cobra.Command, args []string) error {
594+
dev, err := drive64.NewDeviceSingle()
595+
if err != nil {
596+
return err
597+
}
598+
defer dev.Close()
599+
600+
var extended bool
601+
switch args[0] {
602+
case "t", "true", "1":
603+
extended = true
604+
}
605+
606+
vprintf("64drive serial: %v\n", dev.Description().Serial)
607+
vprintf("Extended mode: %v\n", extended)
608+
609+
if hwvar, fwver, _, err := dev.CmdVersionRequest(); err == nil && hwvar == drive64.VarRevA {
610+
return errors.New("extended mode not supported on 64drive HW1")
611+
} else if fwver < 206 {
612+
return errors.New("extended mode not supported on 64drive firmware < 2.06")
613+
} else {
614+
return dev.CmdSetExtended(extended)
615+
}
616+
}
617+
566618
func fwCmd(filename string, cb func(rpk *drive64.RPK) error) error {
567619
f, err := os.Open(filename)
568620
if err != nil {
@@ -720,11 +772,13 @@ func main() {
720772
cmdUpload.Flags().VarP(&flagSize, "size", "s", "size of data to upload (default: file size)")
721773
cmdUpload.Flags().StringVarP(&flagBank, "bank", "b", "rom", "bank where data should be uploaded")
722774
cmdUpload.Flags().BoolVarP(&flagAutoCic, "autocic", "c", false, "autoset CIC after upload (default: true if uploading a ROM)")
723-
cmdUpload.Flags().BoolVarP(&flagAutoSave, "autosave", "S", false, "autoset save tyep after upload (default: true if uploading a ROM)")
775+
cmdUpload.Flags().BoolVarP(&flagAutoSave, "autosave", "S", false, "autoset save type after upload (default: true if uploading a ROM)")
776+
cmdUpload.Flags().BoolVarP(&flagAutoExtended, "extended", "e", false, "set extended mode after upload (default: true if uploading a >64Mb ROM)")
724777
cmdUpload.Flags().BoolVarP(&flagVerbose, "verbose", "v", false, "be verbose")
725778
cmdUpload.Flags().IntVarP(&flagByteswapU, "byteswap", "w", -1, "byteswap format: 0=none, 2=16bit, 4=32bit, -1=autodetect")
726779
pflagAutoCic = cmdUpload.Flag("autocic")
727780
pflagAutoSave = cmdUpload.Flag("autosave")
781+
pflagAutoExtended = cmdUpload.Flag("extended")
728782

729783
var cmdDownload = &cobra.Command{
730784
Use: "download [file]",
@@ -776,6 +830,21 @@ The save type can be specified using one of the following names:
776830
}
777831
cmdSaveType.Flags().BoolVarP(&flagVerbose, "verbose", "v", false, "be verbose")
778832

833+
var cmdExtended = &cobra.Command{
834+
Use: "extended [bool]",
835+
Aliases: []string{"ext"},
836+
Short: "enabel or disabled the 64drive extended mode",
837+
Long: `Extended mode allows 64drive to expose the full 240 MiB of SDRAM as ROM to the N64.
838+
This is required to run ROMs larger than 64 MiB, because otherwise the upper part of the ROM would not
839+
be accessible. Please notice that extended mode is only available on 64Drive HW2 with firmware >= 2.06.`,
840+
Example: ` g64drive extended true
841+
-- enable extended mode.`,
842+
RunE: cmdExtended,
843+
Args: cobra.ExactArgs(1),
844+
SilenceUsage: true,
845+
}
846+
cmdExtended.Flags().BoolVarP(&flagVerbose, "verbose", "v", false, "be verbose")
847+
779848
var cmdFirmwareInfo = &cobra.Command{
780849
Use: "info [file.rpk]",
781850
Short: "show information on 64drive firmware file",
@@ -838,7 +907,7 @@ No proprietary FTDI/D2XX is required and will not be installed.`,
838907
Use: "g64drive",
839908
}
840909
rootCmd.PersistentFlags().BoolVarP(&flagQuiet, "quiet", "q", false, "do not show any output unless an error occurs")
841-
rootCmd.AddCommand(cmdList, cmdUpload, cmdDownload, cmdCic, cmdSaveType, cmdFirmware, cmdDebug)
910+
rootCmd.AddCommand(cmdList, cmdUpload, cmdDownload, cmdCic, cmdSaveType, cmdExtended, cmdFirmware, cmdDebug)
842911
if runtime.GOOS == "windows" {
843912
rootCmd.AddCommand(cmdDriverInstall)
844913
}

0 commit comments

Comments
 (0)