13#include "sio2man_hook.h"
15#include "spi_sdcard_driver.h"
17#include "module_debug.h"
19IRX_ID(
"mx4sio", 1, 2);
25static int sd_detect_thread_id = -1;
27static uint8_t sio2_current_baud = SIO2_BAUD_DIV_SLOW;
28static uint32_t sio2_save_crtl;
31int mx_sio2_dma_isr_rx(
void *arg)
34 int eflags = EF_SIO2_INTR_REVERSE;
37 inl_sio2_stat_set(inl_sio2_stat_get());
40 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
43#ifdef CONFIG_USE_CRC16
45 cmd.crc[cmd.sectors_transferred] = reverse_byte_LUT8[inl_sio2_data_in()] << 8;
46 cmd.crc[cmd.sectors_transferred] |= reverse_byte_LUT8[inl_sio2_data_in()];
55 if (inl_sio2_data_in() != 0xFE) {
56 cmd.response = mx_sio2_wait_equal(0xFE, READ_TOKEN_TIMEOUT);
58 cmd.response = SPISD_RESULT_OK;
61 cmd.sectors_transferred++;
63 if (cmd.sectors_transferred < cmd.sector_count && cmd.abort == 0) {
65 if (cmd.response == SPISD_RESULT_OK) {
67 mx_sio2_start_rx_dma(&cmd.buffer[cmd.sectors_transferred * SECTOR_SIZE]);
69 iSetEventFlag(ef, eflags);
74 cmd.abort = CMD_ABORT_NO_READ_TOKEN;
78 eflags |= EF_SIO2_INTR_COMPLETE;
79 iSetEventFlag(ef, eflags);
85int mx_sio2_dma_isr_tx(
void *arg)
91 inl_sio2_stat_set(inl_sio2_stat_get());
98 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
102 mx_sio2_write_dummy();
103 mx_sio2_write_dummy();
105 cmd.sectors_transferred++;
111 cmd.response = mx_sio2_wait_equal_masked(0x5, 0x1F, 10);
112 if (cmd.response != 0x5) {
113 M_DEBUG(
"ERROR: write data rejected, token 0x%x\n", cmd.response);
118 cmd.response = mx_sio2_wait_equal(0xFF, 0x80000);
119 if (cmd.response != SPISD_RESULT_OK) {
120 M_DEBUG(
"ERROR: failed to finish programming\n");
124 if (cmd.sectors_transferred < cmd.sector_count && cmd.abort == 0) {
126 mx_sio2_write_byte(0xFC);
128 mx_sio2_start_tx_dma(&cmd.buffer[cmd.sectors_transferred * SECTOR_SIZE]);
134 eflags = EF_SIO2_INTR_COMPLETE;
135 iSetEventFlag(ef, eflags);
142 for (uint8_t i = 0; i < 4; i++) {
143 inl_sio2_portN_ctrl1_set(i, td->port_ctrl1[i]);
144 inl_sio2_portN_ctrl2_set(i, td->port_ctrl2[i]);
150 for (uint8_t i = 0; i < 4; i++) {
151 td->port_ctrl1[i] = 0;
152 td->port_ctrl2[i] = 0;
155 td->port_ctrl1[PORT_NR] =
156 PCTRL0_ATT_LOW_PER(0x5) |
157 PCTRL0_ATT_MIN_HIGH_PER(0x5) |
158 PCTRL0_BAUD0_DIV(0x78) |
159 PCTRL0_BAUD1_DIV(sio2_current_baud);
161 td->port_ctrl2[PORT_NR] =
162 PCTRL1_ACK_TIMEOUT_PER(0x12C) |
163 PCTRL1_INTER_BYTE_PER(0x0) |
165 PCTRL1_IF_MODE_SPI_DIFF(0x0);
168void mx_sio2_lock(uint8_t intr_type)
173 sio2man_hook_sio2_lock();
176 sio2_save_crtl = inl_sio2_ctrl_get();
179 mx_sio2_init_ports(&global_td);
184 if (intr_type == INTR_RX) {
189 if (intr_type == INTR_TX) {
197void mx_sio2_unlock(uint8_t intr_type)
205 if (intr_type == INTR_RX)
208 if (intr_type == INTR_TX)
214 inl_sio2_ctrl_set(sio2_save_crtl | 0xc);
217 sio2man_hook_sio2_unlock();
220void mx_sio2_set_baud(uint8_t baud)
222 sio2_current_baud = baud;
224 mx_sio2_init_td(&global_td);
225 mx_sio2_init_ports(&global_td);
228uint8_t mx_sio2_write_byte(uint8_t
byte)
231 inl_sio2_ctrl_set(0x0bc);
234 TR_CTRL_PORT_NR(PORT_NR) |
236 TR_CTRL_TX_MODE_PIO_DMA(0) |
237 TR_CTRL_RX_MODE_PIO_DMA(0) |
238 TR_CTRL_NORMAL_TR(1) |
239 TR_CTRL_SPECIAL_TR(0) |
240 TR_CTRL_BAUD_DIV(1) |
241 TR_CTRL_WAIT_ACK_FOREVER(0) |
242 TR_CTRL_TX_DATA_SZ(1) |
243 TR_CTRL_RX_DATA_SZ(1));
244 inl_sio2_regN_set(1, 0);
247 inl_sio2_data_out(reverse_byte_LUT8[
byte]);
250 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
253 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
257 uint8_t rx = reverse_byte_LUT8[inl_sio2_data_in()];
258 M_DEBUG(
"W:0x%x, R:0x%x\n",
byte, rx);
263 return reverse_byte_LUT8[inl_sio2_data_in()];
266uint8_t mx_sio2_write_dummy(
void)
269 inl_sio2_ctrl_set(0x0bc);
273 TR_CTRL_PORT_NR(PORT_NR) |
275 TR_CTRL_TX_MODE_PIO_DMA(0) |
276 TR_CTRL_RX_MODE_PIO_DMA(0) |
277 TR_CTRL_NORMAL_TR(1) |
278 TR_CTRL_SPECIAL_TR(0) |
279 TR_CTRL_BAUD_DIV(1) |
280 TR_CTRL_WAIT_ACK_FOREVER(0) |
281 TR_CTRL_TX_DATA_SZ(1) |
282 TR_CTRL_RX_DATA_SZ(1));
283 inl_sio2_regN_set(1, 0);
286 inl_sio2_data_out(0xFF);
289 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
292 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
296 uint8_t rx = reverse_byte_LUT8[inl_sio2_data_in()];
297 M_DEBUG(
"R:0x%x\n", rx);
302 return reverse_byte_LUT8[inl_sio2_data_in()];
306uint8_t mx_sio2_wait_equal(uint8_t value, uint32_t
count)
308 uint8_t exp_byte = reverse_byte_LUT8[value];
311 while (
count > 0 && in_byte != exp_byte) {
313 inl_sio2_ctrl_set(0x0bc);
316 TR_CTRL_PORT_NR(PORT_NR) |
318 TR_CTRL_TX_MODE_PIO_DMA(0) |
319 TR_CTRL_RX_MODE_PIO_DMA(0) |
320 TR_CTRL_NORMAL_TR(1) |
321 TR_CTRL_SPECIAL_TR(0) |
322 TR_CTRL_BAUD_DIV(1) |
323 TR_CTRL_WAIT_ACK_FOREVER(0) |
324 TR_CTRL_TX_DATA_SZ(0) |
325 TR_CTRL_RX_DATA_SZ(1));
326 inl_sio2_regN_set(1, 0);
329 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
332 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
335 in_byte = inl_sio2_data_in();
338 M_DEBUG(
"WE: 0x%x, EX: 0x%x\n", reverse_byte_LUT8[in_byte], value);
344 return (exp_byte != in_byte) ? SPISD_RESULT_ERROR : SPISD_RESULT_OK;
347uint8_t mx_sio2_wait_not_equal(uint8_t value, uint32_t
count)
349 uint8_t exp_byte = reverse_byte_LUT8[value];
350 uint8_t in_byte = exp_byte;
352 while (
count > 0 && in_byte == exp_byte) {
354 inl_sio2_ctrl_set(0x0bc);
358 TR_CTRL_PORT_NR(PORT_NR) |
360 TR_CTRL_TX_MODE_PIO_DMA(0) |
361 TR_CTRL_RX_MODE_PIO_DMA(0) |
362 TR_CTRL_NORMAL_TR(1) |
363 TR_CTRL_SPECIAL_TR(0) |
364 TR_CTRL_BAUD_DIV(1) |
365 TR_CTRL_WAIT_ACK_FOREVER(0) |
366 TR_CTRL_TX_DATA_SZ(0) |
367 TR_CTRL_RX_DATA_SZ(1));
368 inl_sio2_regN_set(1, 0);
371 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
374 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
378 in_byte = inl_sio2_data_in();
381 M_DEBUG(
"WNE: 0x%x, EX: !0x%x\n", reverse_byte_LUT8[in_byte], value);
386 return reverse_byte_LUT8[in_byte];
389uint8_t mx_sio2_wait_equal_masked(uint8_t value, uint8_t mask, uint32_t
count)
391 uint8_t exp_byte = reverse_byte_LUT8[value];
392 uint8_t rev_mask = reverse_byte_LUT8[mask];
395 while (
count > 0 && in_byte != exp_byte) {
397 inl_sio2_ctrl_set(0x0bc);
400 TR_CTRL_PORT_NR(PORT_NR) |
402 TR_CTRL_TX_MODE_PIO_DMA(0) |
403 TR_CTRL_RX_MODE_PIO_DMA(0) |
404 TR_CTRL_NORMAL_TR(1) |
405 TR_CTRL_SPECIAL_TR(0) |
406 TR_CTRL_BAUD_DIV(1) |
407 TR_CTRL_WAIT_ACK_FOREVER(0) |
408 TR_CTRL_TX_DATA_SZ(0) |
409 TR_CTRL_RX_DATA_SZ(1));
410 inl_sio2_regN_set(1, 0);
413 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
416 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
419 in_byte = inl_sio2_data_in();
422 M_DEBUG(
"WEM: 0x%x M:\n", reverse_byte_LUT8[in_byte], reverse_byte_LUT8[in_byte & rev_mask]);
424 in_byte = in_byte & rev_mask;
429 return reverse_byte_LUT8[in_byte];
432void mx_sio2_rx_pio(uint8_t *buffer, uint32_t size)
434 uint32_t transfer_size;
436 uint8_t *buffer_start = buffer;
440 transfer_size = size > SIO2_MAX_TRANSFER_SIZE ? SIO2_MAX_TRANSFER_SIZE : size;
443 inl_sio2_ctrl_set(0x0bc);
447 TR_CTRL_PORT_NR(PORT_NR) |
449 TR_CTRL_TX_MODE_PIO_DMA(0) |
450 TR_CTRL_RX_MODE_PIO_DMA(0) |
451 TR_CTRL_NORMAL_TR(1) |
452 TR_CTRL_SPECIAL_TR(0) |
453 TR_CTRL_BAUD_DIV(1) |
454 TR_CTRL_WAIT_ACK_FOREVER(0) |
455 TR_CTRL_TX_DATA_SZ(0) |
456 TR_CTRL_RX_DATA_SZ(transfer_size));
457 inl_sio2_regN_set(1, 0);
460 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
463 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
467 for (
int i = 0; i < transfer_size; i++) {
468 *buffer++ = reverse_byte_LUT8[inl_sio2_data_in()];
472 for (
int i = 0; i < transfer_size; i++) {
473 M_DEBUG(
"W:0xFF, R:0x%x\n", buffer_start[i]);
477 size -= transfer_size;
481void mx_sio2_tx_pio(uint8_t *buffer, uint32_t size)
483 uint32_t transfer_size;
486 uint8_t *buffer_start = buffer;
491 transfer_size = size > SIO2_MAX_TRANSFER_SIZE ? SIO2_MAX_TRANSFER_SIZE : size;
494 inl_sio2_ctrl_set(0x0bc);
498 TR_CTRL_PORT_NR(PORT_NR) |
500 TR_CTRL_TX_MODE_PIO_DMA(0) |
501 TR_CTRL_RX_MODE_PIO_DMA(0) |
502 TR_CTRL_NORMAL_TR(1) |
503 TR_CTRL_SPECIAL_TR(0) |
504 TR_CTRL_BAUD_DIV(1) |
505 TR_CTRL_WAIT_ACK_FOREVER(0) |
506 TR_CTRL_TX_DATA_SZ(transfer_size) |
508 TR_CTRL_RX_DATA_SZ(transfer_size));
510 TR_CTRL_RX_DATA_SZ(0));
513 inl_sio2_regN_set(1, 0);
516 for (
int i = 0; i < transfer_size; i++) {
517 inl_sio2_data_out(reverse_byte_LUT8[*buffer++]);
521 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
524 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0)
528 for (
int i = 0; i < transfer_size; i++) {
529 M_DEBUG(
"W:0x%x, R:0x%x\n", buffer_start[i], reverse_byte_LUT8[inl_sio2_data_in()]);
532 size -= transfer_size;
536void mx_sio2_start_rx_dma(uint8_t *buffer)
539 const uint32_t tr_ctrl_dma =
541 TR_CTRL_TX_MODE_PIO_DMA(0) |
542 TR_CTRL_RX_MODE_PIO_DMA(1) |
543 TR_CTRL_NORMAL_TR(1) |
544 TR_CTRL_SPECIAL_TR(0) |
545 TR_CTRL_TX_DATA_SZ(0) |
546 TR_CTRL_RX_DATA_SZ(0x100) |
547 TR_CTRL_BAUD_DIV(1) |
548 TR_CTRL_WAIT_ACK_FOREVER(0);
551 const uint32_t tr_ctrl_pio =
553 TR_CTRL_TX_MODE_PIO_DMA(0) |
554 TR_CTRL_RX_MODE_PIO_DMA(0) |
555 TR_CTRL_NORMAL_TR(1) |
556 TR_CTRL_SPECIAL_TR(0) |
557 TR_CTRL_TX_DATA_SZ(0) |
558 TR_CTRL_RX_DATA_SZ(3) |
559 TR_CTRL_BAUD_DIV(1) |
560 TR_CTRL_WAIT_ACK_FOREVER(0);
563 inl_sio2_ctrl_set(0x0bc);
566 inl_sio2_regN_set(0, tr_ctrl_dma | TR_CTRL_PORT_NR(PORT_NR));
567 inl_sio2_regN_set(1, tr_ctrl_dma | TR_CTRL_PORT_NR(PORT_NR));
568 inl_sio2_regN_set(2, tr_ctrl_pio | TR_CTRL_PORT_NR(PORT_NR));
569 inl_sio2_regN_set(3, 0);
572 sceSetSliceDMA(IOP_DMAC_SIO2out, buffer, 0x100 >> 2, 2, DMAC_TO_MEM);
573 sceStartDMA(IOP_DMAC_SIO2out);
576 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
579void mx_sio2_start_tx_dma(uint8_t *buffer)
582 const uint32_t tr_ctrl_dma =
584 TR_CTRL_TX_MODE_PIO_DMA(1) |
585 TR_CTRL_RX_MODE_PIO_DMA(0) |
586 TR_CTRL_NORMAL_TR(1) |
587 TR_CTRL_SPECIAL_TR(0) |
588 TR_CTRL_TX_DATA_SZ(0x100) |
589 TR_CTRL_RX_DATA_SZ(0) |
590 TR_CTRL_BAUD_DIV(1) |
591 TR_CTRL_WAIT_ACK_FOREVER(0);
594 inl_sio2_ctrl_set(0x0bc);
597 inl_sio2_regN_set(0, tr_ctrl_dma | TR_CTRL_PORT_NR(PORT_NR));
598 inl_sio2_regN_set(1, tr_ctrl_dma | TR_CTRL_PORT_NR(PORT_NR));
599 inl_sio2_regN_set(2, 0);
600 inl_sio2_regN_set(3, 0);
603 sceSetSliceDMA(IOP_DMAC_SIO2in, buffer, 0x100 >> 2, 2, DMAC_FROM_MEM);
604 sceStartDMA(IOP_DMAC_SIO2in);
607 inl_sio2_ctrl_set(inl_sio2_ctrl_get() | 1);
610static void sd_detect()
614 mx_sio2_lock(INTR_NONE);
616 if (sdcard.initialized == 0) {
617 M_PRINTF(
"Trying to init card\n");
619 if (spisd_init_card() == SPISD_RESULT_OK) {
622 if (spisd_get_card_info() == SPISD_RESULT_OK) {
624 sdcard.initialized = 1;
629 results = spisd_read_status_register();
631 if (results != 0x0) {
633 results = spisd_recover();
635 if ((sdcard.initialized == 1) && (results != SPISD_RESULT_OK)) {
637 M_DEBUG(
"Recovery failed, disconnecting from bdm.\n");
638 bdm_disconnect_bd(&bd);
639 sdcard.initialized = 0;
644 mx_sio2_unlock(INTR_NONE);
647static void sd_detect_thread(
void *arg)
651 M_PRINTF(
"card detection thread running\n");
654 DelayThread(1000 * 1000);
657 if (sdcard.used == 0)
666#pragma GCC push_options
667#pragma GCC optimize("-O3")
668inline void reverse_buffer(uint32_t *buffer, uint32_t
count)
670 const uint32_t mask0F = 0x0F0F0F0F;
671 const uint32_t maskF0 = 0xF0F0F0F0;
672 const uint32_t mask33 = 0x33333333;
673 const uint32_t maskCC = 0xCCCCCCCC;
674 const uint32_t mask55 = 0x55555555;
675 const uint32_t maskAA = 0xAAAAAAAA;
679 for (
int i = 0; i <
count; i++) {
681 n = ((n & maskF0) >> 4) | ((n & mask0F) << 4);
682 n = ((n & maskCC) >> 2) | ((n & mask33) << 2);
683 n = ((n & maskAA) >> 1) | ((n & mask55) << 1);
688#pragma GCC pop_options
691const uint8_t reverse_byte_LUT8[256] = {
692 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
693 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
694 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
695 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
696 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
697 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
698 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
699 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
700 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
701 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
702 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
703 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
704 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
705 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
706 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
707 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
708 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
709 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
710 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
711 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
712 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
713 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
714 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
715 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
716 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
717 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
718 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
719 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
720 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
721 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
722 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
723 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff};
726int module_start(
int argc,
char *argv[])
736 M_PRINTF(
"Starting module\n");
737 for (i = 0; i < argc; i++)
738 M_PRINTF(
" - argv[%d] = %s\n", i, argv[i]);
745 mx_sio2_init_td(&global_td);
751 sio2_event_flag = CreateEventFlag(&
event);
752 if (sio2_event_flag < 0) {
753 M_PRINTF(
"ERROR: CreateEventFlag returned %d\n", sio2_event_flag);
757 rv = sio2man_hook_init();
759 M_PRINTF(
"ERROR: sio2man_hook_init returned %d\n", rv);
764 sceSetDMAPriority(IOP_DMAC_SIO2in, 3);
765 sceSetDMAPriority(IOP_DMAC_SIO2out, 3);
766 sceEnableDMAChannel(IOP_DMAC_SIO2in);
767 sceEnableDMAChannel(IOP_DMAC_SIO2out);
773 mx_sio2_lock(INTR_NONE);
774 mx_sio2_rx_pio((
void *)&rv, 4);
775 mx_sio2_unlock(INTR_NONE);
779 thread.thread = sd_detect_thread;
781 thread.priority = USER_LOWEST_PRIORITY;
782 thread.stacksize = 0x1000;
783 rv = sd_detect_thread_id = CreateThread(&
thread);
785 M_PRINTF(
"ERROR: CreateThread returned %d\n", rv);
790 rv = StartThread(sd_detect_thread_id, NULL);
792 M_PRINTF(
"ERROR: StartThread returned %d\n", rv);
796 lib_modload = ioplib_getByName(
"modload");
797 if (lib_modload != NULL) {
798 M_DEBUG(
"modload 0x%x detected\n", lib_modload->version);
801 if (lib_modload->version > 0x102)
802 return MODULE_REMOVABLE_END;
804 M_DEBUG(
"modload not detected!\n");
807 return MODULE_RESIDENT_END;
810 DeleteThread(sd_detect_thread_id);
812 sio2man_hook_deinit();
814 DeleteEventFlag(sio2_event_flag);
816 return MODULE_NO_RESIDENT_END;
819int module_stop(
int argc,
char *argv[])
824 M_PRINTF(
"Stopping module\n");
825 for (i = 0; i < argc; i++)
826 M_PRINTF(
" - argv[%d] = %s\n", i, argv[i]);
832 DeleteThread(sd_detect_thread_id);
833 sio2man_hook_deinit();
834 DeleteEventFlag(sio2_event_flag);
836 return MODULE_NO_RESIDENT_END;
839int _start(
int argc,
char *argv[])
841 M_PRINTF(
"MX4SIO v1.2\n");
844 return module_start(argc, argv);
846 return module_stop(-argc, argv);
int CpuResumeIntr(int state)
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
int DisableIntr(int irq, int *res)
int CpuSuspendIntr(int *state)
u32 count
start sector of fragmented bd/file