123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585 |
- /*
- doctor64jr.c - Bung Doctor V64 Junior support for uCON64
- Copyright (c) 1999 - 2002 NoisyB
- Copyright (c) 2004, 2015 dbjh
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /*
- drjr transfer protocol
- DB25 pin name
- p2~p9 pd[7:0] XXXXXXXXXXX ai XXXXX data XXXX
- p1 nwrite ~~~~~~~~~|_____________________|~~
- p14 ndstb ~~~~~~~~~~~~~~~~~~~~~~~~~|_|~~~~~~
- p17 nastb ~~~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~
- ai[]=0 r/w a[7..0]
- ai[]=1 r/w a[15..8]
- ai[]=2 r/w a[23..16]
- ai[]=3 w a[28..24]
- ai[]=3 r (rst,wdf,wcf,a[28..24])
- ai[]=4 r/w data
- ai[]=5 w mode
- ai[]=6 w en_1
- ai[]=7 w en_0
- *remark
- a[8..1] support page count up
- ai[3]d7:0=N64 power off, 1=N64 power on
- d6:0=no dram data written, 1=dram data written
- d5:0=no data write in b4000000~b7ffffff, 1=some data written in b4000000~b7ffffff
- mode d0:0=dram read only and clear wdf, 1=dram write enable
- d1:0=disable cartridge read and clear wcf flag,
- 1=enable cartridge read(write b4000000~b7ffffff will switch off dram and cartridge will present at b0000000~b3ffffff)
- en_0=05 and en_1=0a is enable port control
- mode:q0 0 1 0 1
- mode:q1 0 0 1 1
- b7ff ffff
- b400 0000 dram read only dram r/w cartridge read cartridge read(* write this area will switch off dram)
- b3ff ffff
- b000 0000 dram read only dram r/w dram read only dram r/w
- eg:enable port control
- DB25 pin name
- p2~p9 pd[7:0] XXXXXXXXXXX 07 XX 05 XXXX 06 XX 0a XXXXXXXXXXXX
- p1 nwrite ~~~~~~~~~|_____________________________|~~~~~~~
- p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~
- p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~
- en_0=05 en_1=0a
- eg:write adr $b0123456, data $a55a,$1234..
- DB25 pin name
- p2~p9 pd[7:0] XXXXXXXXXXX 00 XX 56 XXXX 01 XX 34 XXXX 02 XX 12 XXXX 03 XX b0 XXXXXX 04 XX 5a XX a5 XX 34 XX 12 XXXXXXXXXXX
- p1 nwrite ~~~~~~~~~|_______________________________________________________________________________________|~~~~~~~~~~
- p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~|_|~~~|_|~~~|_|~~~|_|~~~~~~~~~~~
- p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- set adr word low set adr word high wdata a55a wdata 1234 (after write adr=b012345a)
- eg:read adr $b0123400~$b01235ff, 512 data
- DB25 pin name
- p2~p9 pd[7:0] XXXXXXXXXXX 00 XX 00 XXXX 01 XX 34 XXXX 02 XX 12 XXXX 03 XX b0 XXXXXX 04 XX data0 XX data1 X ... X data510 XX data511 XXXXX
- p1 nwrite ~~~~~~~~~|________________________________________________________________~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~~|_|~~~~~~|_|~~~ ~~~ ~~~~|_|~~~~~~~~|_|~~~~~~~~
- p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- set adr word low set adr word high (after 512 read adr=b0123400)
- eg:dram write protect, disable N64 access to cartridge and disable port control
- DB25 pin name
- p2~p9 pd[7:0] XXXXXXXXXXX 05 XX 00 XXXX 07 XX 00 XXXX 06 XX 00 XXXXXXXXXXXX
- p1 nwrite ~~~~~~~~~|________________________________________|~~~~~~~~~~
- p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~
- p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~
- mode=00 en_0=00 en_1=00
- simple backup rountine for N64
- void writePI(unsigned long addr, unsigned long value)
- {
- do {} while (*(volatile unsigned long *) (0xa4600010) & 3); // check parallel interface not busy
- addr &=0xbffffffc;
- *(unsigned long *)(addr)=value;
- }
- unsigned long readPI(unsigned long addr)
- {
- do {} while (*(volatile unsigned long *) (0xa4600010) & 3); // check parallel interface not busy
- addr &=0xbffffffc;
- return *(unsigned long *)(addr);
- }
- // MAIN -- START OF USER CODE
- void mainproc(void *arg) {
- u32 base_adr;
- for (base_adr=0;base_adr<0x1000000;base_adr++){ // backup 128Mbits
- writePI(0xb0000000+base_adr,readPI(0xb4000000 + base_adr)); // write data
- }
- }
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <stdlib.h>
- #include "misc/archive.h"
- #include "misc/parallel.h"
- #include "ucon64.h"
- #include "ucon64_misc.h"
- #include "backup/doctor64jr.h"
- #ifdef USE_PARALLEL
- static st_ucon64_obj_t doctor64jr_obj[] =
- {
- {UCON64_N64, WF_DEFAULT | WF_STOP | WF_NO_ROM}
- };
- #endif
- const st_getopt2_t doctor64jr_usage[] =
- {
- {
- NULL, 0, 0, 0,
- NULL, "Doctor V64 Junior"/*"19XX Bung Enterprises Ltd http://www.bung.com.hk"*/,
- NULL
- },
- #ifdef USE_PARALLEL
- {
- "xdjr", 0, 0, UCON64_XDJR,
- NULL, "send ROM to Doctor V64 Junior; " OPTION_LONG_S "port=PORT",
- &doctor64jr_obj[0]
- },
- #if 0
- {
- "xdjrs", 0, 0, UCON64_XDJRS,
- NULL, "send/receive SRAM to/from Doctor V64 Junior; " OPTION_LONG_S "port=PORT\n"
- "receives automatically when SRAM does not exist",
- &doctor64jr_obj[0]
- },
- #endif
- #endif // USE_PARALLEL
- {NULL, 0, 0, 0, NULL, NULL, NULL}
- };
- #ifdef USE_PARALLEL
- #define BUFFERSIZE 32768
- //#define set_ai_write outportb (port_a, 5); // ninit=1, nwrite=0
- #define set_data_write outportb (port_a, 1); // ninit=0, nwrite=0
- #define set_data_read outportb (port_a, 0); // ninit=0, nwrite=1
- //#define set_normal outportb (port_a, 4); // ninit=1, nwrite=1
- static unsigned short int port_8, port_9, port_a, port_b, port_c,
- *buffer;
- static int wv_mode;
- static void
- set_ai (unsigned char ai)
- {
- outportb (port_a, 5); // ninit=1, nwrite=0
- outportb (port_b, ai);
- }
- static void
- set_ai_data (unsigned char ai, unsigned char data)
- {
- set_ai (ai);
- set_data_write // ninit=0, nwrite=0
- outportb (port_c, data);
- }
- static void
- init_port (int enable_write)
- {
- #ifndef USE_PPDEV
- outportb (port_9, 1); // clear EPP time flag
- #endif
- set_ai_data (6, 0x0a);
- set_ai_data (7, 0x05); // 6==0x0a, 7==0x05 is pc_control mode
- // set_ai (5);
- // set_data_read
- // enable_write = inportb (port_c);
- set_ai_data (5, (unsigned char) enable_write); // d0=0 is write protect mode
- }
- static void
- end_port (int enable_write)
- {
- set_ai_data (5, (unsigned char) enable_write); // d0=0 is write protect mode
- set_ai_data (7, 0); // release pc mode
- set_ai_data (6, 0); // 6==0x0a, 7==0x05 is pc_control mode
- outportb (port_a, 4); // ninit=1, nwrite=1
- }
- static int
- check_card (void)
- {
- set_ai_data (3, 0x12);
- set_ai_data (2, 0x34);
- set_ai_data (1, 0x56);
- set_ai_data (0, 0x78);
- set_ai (3);
- set_data_read // ninit=0, nwrite=1
- if ((inportb (port_c) & 0x1f) != 0x12)
- return 1;
- set_ai (2);
- set_data_read
- if (inportb (port_c) != 0x34)
- return 1;
- set_ai (1);
- set_data_read
- if (inportb (port_c) != 0x56)
- return 1;
- set_ai (0);
- set_data_read
- if (inportb (port_c) != 0x78)
- return 1;
- return 0;
- }
- static int
- write_32k (unsigned short int hi_word, unsigned short int lo_word)
- {
- unsigned char unpass, pass1;
- unsigned short int i, j, fix;
- set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
- set_ai_data (2, (unsigned char) hi_word);
- for (i = 0; i < 0x40; i++)
- {
- unpass = 3;
- while (unpass)
- {
- set_ai_data (1, (unsigned char) ((i << 1) | lo_word));
- set_ai_data (0, 0);
- set_ai (4); // set address index=4
- set_data_write // ninit=0, nwrite=0
- fix = i << 8;
- for (j = 0; j < 256; j++)
- outportw (port_c, buffer[j + fix]);
- set_data_read // ninit=0, nwrite=1
- if (wv_mode)
- {
- for (j = 0; j < 256; j++)
- if (inportw (port_c) != buffer[j + fix])
- break;
- }
- else
- {
- pass1 = 1;
- for (j = 0; j < 4; j++)
- if (inportw (port_c) != buffer[j + fix])
- {
- pass1 = 0;
- break;
- }
- if (pass1)
- {
- set_ai_data (1, (unsigned char) ((i << 1) | lo_word | 1));
- set_ai_data (0, 0xf8);
- set_ai (4);
- set_data_read // ninit=0, nwrite=1
- for (j = 252; j < 256; j++)
- if (inportw (port_c) != buffer[j + fix])
- break;
- }
- }
- set_ai (0);
- set_data_read // ninit=0, nwrite=1
- if (inportb (port_c) != 0)
- {
- unpass--;
- outportb (port_a, 0x0b); // set all pin=0 for debug
- set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
- set_ai_data (2, (unsigned char) hi_word);
- if (unpass == 0)
- return 1;
- }
- else
- unpass = 0;
- }
- }
- /*
- outportb (ai, 0);
- printf ("\na[7..0]=%02x\n", inportb (data));
- outportb (ai, 1);
- printf ("a[15..8]=%02x\n", inportb (data));
- */
- return 0;
- }
- #if 0 // not used
- static int
- verify_32k (unsigned short int hi_word, unsigned short int lo_word)
- {
- char unpass;
- unsigned short int i, j, fix;
- set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
- set_ai_data (2, (unsigned char) hi_word);
- for (i = 0; i < 0x40; i++)
- {
- unpass = 3;
- while (unpass)
- {
- set_ai_data (1, (unsigned char) ((i << 1) | lo_word));
- set_ai_data (0, 0);
- set_ai (4);
- set_data_read // ninit=0, nwrite=1
- fix = i << 8;
- for (j = 0; j < 256; j++)
- {
- if (inportw (port_c) != buffer[j + fix])
- {
- outportb (port_a, 0x0b); // all pin=0 for debug
- set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
- set_ai_data (2, (unsigned char) hi_word);
- unpass--;
- if (unpass == 0)
- return 1;
- else
- break;
- }
- }
- if (j == 256)
- break;
- }
- }
- /*
- outportb (ai,0);
- printf ("\na[7..0]=%02x\n", inportb (data));
- outportb (ai, 1);
- printf ("a[15..8]=%02x\n", inportb (data));
- */
- return 0;
- }
- static void
- gen_pat_32k (unsigned short int offset)
- {
- int i;
- for (i = 0; i < 0x4000; i++)
- buffer[i] = i + offset;
- }
- static unsigned short int
- test_dram (void)
- {
- int n_pages = 0, page;
- gen_pat_32k (0x0000);
- write_32k (0, 0);
- gen_pat_32k (0x8000);
- write_32k (0x100, 0);
- gen_pat_32k (0x0000);
- if (verify_32k (0, 0) == 0) // find lower 128 Mbits
- n_pages = 0x100;
- gen_pat_32k (0x8000);
- if (verify_32k (0x100, 0) == 0) // find upper 128 Mbits
- n_pages = 0x200;
- printf ("Testing DRAM...\n");
- for (page = 0; page < n_pages; page++)
- {
- gen_pat_32k ((unsigned short int) (page * 2));
- if (write_32k (page, 0))
- return 0;
- else
- {
- fputc ('w', stdout);
- fflush (stdout);
- }
- gen_pat_32k ((unsigned short int) (page * 2 + 1));
- if (write_32k (page, 0x80))
- return 0;
- else
- {
- fputc ('w', stdout);
- fflush (stdout);
- }
- }
- fputc ('\n', stdout);
- for (page = 0; page < n_pages; page++)
- {
- gen_pat_32k ((unsigned short int) (page * 2));
- if (verify_32k (page, 0))
- return 0;
- else
- {
- fputc ('v', stdout);
- fflush (stdout);
- }
- gen_pat_32k ((unsigned short int) (page * 2 + 1));
- if (verify_32k (page, 0x80))
- return 0;
- else
- {
- fputc ('v', stdout);
- fflush (stdout);
- }
- }
- return n_pages;
- }
- #endif
- static unsigned long int
- get_address (void)
- {
- unsigned long int address;
- set_ai_data (6, 0x0a); // enable pc mode
- set_ai_data (7, 0x05); // enable pc mode
- set_ai (3);
- set_data_read // ninit=0, nwrite=1
- address = inportb (port_c) << 24;
- set_ai (2);
- set_data_read
- address |= inportb (port_c) << 16;
- set_ai (1);
- set_data_read
- address |= inportb (port_c) << 8;
- set_ai (0);
- set_data_read
- address |= inportb (port_c);
- return address;
- }
- int
- doctor64jr_read (const char *filename, unsigned short parport)
- {
- (void) filename;
- (void) parport;
- return fprintf (stderr, "ERROR: The function for dumping a cartridge is not yet implemented for the\n"
- " Doctor V64 Junior\n");
- }
- int
- doctor64jr_write (const char *filename, unsigned short parport)
- {
- unsigned int enable_write = 0, size, bytesread, bytessent = 0, n_pages;
- time_t init_time;
- unsigned short int page;
- FILE *file;
- parport_print_info ();
- port_8 = parport;
- port_9 = parport + 1;
- port_a = parport + 2;
- port_b = parport + 3;
- port_c = parport + 4;
- init_port (enable_write);
- if (check_card () != 0)
- {
- fprintf (stderr, "ERROR: No Doctor V64 Junior card present\n");
- end_port (enable_write);
- exit (1);
- }
- wv_mode = 0;
- if ((file = fopen (filename, "rb")) == NULL)
- {
- fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
- exit (1);
- }
- if ((buffer = (unsigned short int *) malloc (BUFFERSIZE)) == NULL)
- {
- fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
- exit (1);
- }
- size = ucon64.file_size;
- printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
- #if 0
- if (dram_test)
- {
- dram_size = test_dram ();
- if (dram_size)
- printf ("\nDRAM size=%dMbits\n", (dram_size / 2));
- else
- fprintf (stderr, "\nERROR: DRAM test failed\n");
- return 0;
- }
- #endif
- n_pages = (size + (64 * 1024 - 1)) / (64 * 1024); // "+ (64 * 1024 - 1)" to round up
- init_time = time (0);
- for (page = 0; page < n_pages; page++)
- {
- bytesread = fread ((unsigned char *) buffer, 1, BUFFERSIZE, file);
- if (write_32k (page, 0))
- {
- fprintf (stderr, "ERROR: Transfer failed at address 0x%8lx", get_address ());
- break;
- }
- bytesread += fread ((unsigned char *) buffer, 1, BUFFERSIZE, file);
- if (write_32k (page, 0x80))
- {
- fprintf (stderr, "ERROR: Transfer failed at address 0x%8lx", get_address ());
- break;
- }
- bytessent += bytesread;
- ucon64_gauge (init_time, bytessent, size);
- }
- fputc ('\n', stdout);
- if (enable_write) // 1 or 3
- printf ("DRAM write protect disabled\n");
- if (enable_write & 2) // 3
- printf ("Run cartridge enabled\n");
- // set_ai_data(5, enable_write); // d0=0 is write protect mode
- end_port (enable_write);
- return 0;
- }
- #endif // USE_PARALLEL
|