ARM Thumb machine code, Nintendo DS, 30 bytes
05 48 05 49 00 23 02 88 12 0a fc d2 01 80 43 80 09 0c 40 23 f7 e7 c0 01 00 04 02 88 02 80
Thumb function. Runs at an address that is 2 byte aligned, 4 byte unaligned, on the ARM7. The ARM9 cannot access these registers.
This version follows the spec by writing the two halfwords separately, like the code in libnds. Known to work on DeSuMME (it will log it in the console menu) and melonDS, and should work on hardware.
Assembler source:
.syntax unified .arch armv4t .thumb // Force misalignment to align PC load // Not part of function .p2align 2,0 .hword 0 // Begin code // void shutdown(void); .thumb_func .globl shutdown shutdown: // Load address of SPI register ldr r0, REG_SPICNT // Load packed SPI commands ldr r1, SPI_COMMANDS // Set SPIDATA to select PM_CONTROL_REG movs r3, #0x00 .Lloop: // Wait for REG_SPICNT & SPI_BUSY to clear ldrh r2, [r0] // Test bit 7 by shifting into carry flag lsrs r2, r2, #8 bcs .Lloop // Store the low 16 bits of the command to REG_SPICNT strh r1, [r0] // Store data to REG_SPIDATA strh r3, [r0, #2] // Shift in the next SPI command lsrs r1, r1, #16 // Set SPIDATA to PM_SYSTEM_PWR movs r3, #0x40 // Run again with the new commands // Then spin again until the SPI powers off the system. b .Lloop REG_SPICNT: // Address of ARM7 IO register .word 0x040001c0 // Two packed halfwords SPI_COMMANDS: // Start a command on the Power Management device, // read a byte to select the register // SPI_ENABLE | SPI_BAUD_1MHz | SPI_BYTE_MODE | SPI_CONTINUOUS | SPI_DEVICE_POWER .hword 0x8802 // Finish the command on the Power Management device, // read a byte to run the action. // SPI_ENABLE | SPI_BAUD_1MHz | SPI_BYTE_MODE | SPI_DEVICE_POWER .hword 0x8002
ARM Thumb machine code function, Nintendo DS, unsafe, 28 bytes
03 48 04 49 02 88 12 0a fc d2 01 60 02 49 f9 e7 c0 01 00 04 02 88 00 00 02 80 40 00
This function runs at a 4 byte aligned address on the ARM7.
This cheats 2 bytes by writing to SPICNT and SPIDATA at the same time in a full word write, something that has not yet been confirmed to work on hardware. It does not work on DeSuMME, but this might just be an emulator bug.
I am including this because it uses different code.
Assembler source:
.syntax unified .arch armv4t .thumb // Force 4 byte alignment .p2align 2,0 // Begin code .thumb_func .globl shutdown shutdown: // address of SPI register ldr r0, REG_SPICNT // Set SPI register bank ldr r1, SPI_SELECT_PM_CONTROL_REG .Lloop: // Wait for REG_SPICNT & SPI_BUSY to clear ldrh r2, [r0] // Test bit 7 by shifting into carry flag lsrs r2, #8 bcs .Lloop // Store to both SPICNT and SPIDATA str r1, [r0] // Send SPI command ldr r1, SPI_SEND_PM_SYSTEM_PWR // Loop again with the new value. b .Lloop .p2align 2,0 REG_SPICNT: .word 0x040001c0 // SPICNT = SPI_ENABLE | SPI_CONTINUOUS | SPI_BAUD_1MHz | SPI_DEVICE_POWER // SPIDATA = PM_CONTROL_REG SPI_SELECT_PM_CONTROL_REG: // Combined halfwords .hword 0x8802 .hword 0x0000 // SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | SPI_DEVICE_POWER // SPIDATA = PM_SYSTEM_PWR SPI_SEND_PM_SYSTEM_PWR: // Combined halfwords .hword 0x8002 .hword 0x0040
`whatever`;Bash/Perl/PHP/Ruby/etc. stupiglots. \$\endgroup\$shatdown: past tense of the verb shutdown\$\endgroup\$