Views: 23,293,183 | Homepage | Main | Rules/FAQ | Memberlist | Active users | Last posts | Calendar | Stats | Online users | Search | 12-11-24 07:38 PM |
Guest: |
0 users reading GBAtek addendum/errata | 1 bot |
Main - Development - GBAtek addendum/errata | Hide post layouts | New reply |
Arisotura |
| ||
Big fire melon magical melon girl Level: 58 Posts: 27/945 EXP: 1541493 Next: 36053 Since: 03-28-17 From: France Last post: 41 days ago Last view: 19 hours ago |
GBAtek is an amazing piece of documentation, but it can be improved upon
This is a general pile of findings. I claim no ownership on those, they come from several individuals. VRAM * VRAMCNT registers are readable!! * TODO: add notes about overlapping VRAM banks and mirroring * invalid MST values for a VRAM bank result in the bank not being mapped ROM transfers * transfer time is 8 cycles for a command, 4 cycles per response word (basically 1 cycle per byte) (see ROMCTRL bit27 for cycle duration) * plus start delay and 0x200-block delay at the start of each 0x200 block * bit28 allows skipping incoming bytes automatically during delays * DELAYS DO NOT APPLY WHEN THE WR BIT IS SET * DRQ bit (bit23) is set once a response word has been transferred * reading from 0x04100010 clears the DRQ bit, and: ** if the transfer is finished: clears the busy bit and triggers IRQ if specified ** if there are more words to transfer: begins transferring the next word 2D * The main memory display FIFO is a simple circular buffer that holds 16 pixels. The video controller reads from it regardless of whether you fill it. It doesn't get 'empty' or 'full'. * Writing to the upper halfword of 0x04000068 increments the FIFO write pointer by two (writes to the lower halfword leave it unchanged). The write pointer simply wraps to 0 when reaching the end of the buffer. It is also reset upon VBlank. * 8-bit writes to 0x04000068 don't work well. TODO: figure out what's happening. eventually. * Colors are converted early from 5-bit to 6-bit, as such: 6bit = 5bit*2 * Color special effects (brightness, blending) are applied to the 6-bit color components * In some cases, the MSb of color values is used as LSb for the green component. TODO: find out where this applies. Confirmed to apply to the standard BG palette. * Bitmap sprite blending follows the same rules as non-bitmap semitransparent sprites, with EVA=alpha+1 and EVB=16-EVA. Except: bitmap sprites with alpha=0 are always hidden. * 3D layer blending follows rules similar to those of semitransparent sprites (only requires second target bits set in BLDCNT, overrides BLDCNT color effect selection and window 'enable color effect' setting where it applies). * 3D layer blending uses 5-bit alpha values (from the 3D graphics), such as: EVA=alpha+1 and EVB=32-EVA. * When the 3D alpha is less than 16, the final color components are incremented by one. (seems to be some hardware glitch??) * 3D layer pixels with alpha=0 are always hidden (not rendered). They're preserved when capturing the 3D output alone, though. * BG mode 6 works on both GPUs. On the sub GPU, it only gets 128K of VRAM, so it will repeat the same bitmap 4 times. * BG mode 7 renders (text-mode) BG0, BG1, and sprites. No BG2/BG3. * large BG sizes 2-3 are the same as corresponding sizes for regular bitmap BGs (512x256, 512x512) 3D * Shadow polygons can use textures. In that case, decal blending is applied. * The stencil buffer can hold two scanlines. It's cleared only when the current scanline contains shadow mask polygons, before rendering a group of shadow mask polygons. * Stencil buffer bits are set only where the shadow mask is drawn but fails the depth test. * Visible shadow polygons (polyID>0) are only drawn where stencil buffer bits are set and where the destination pixel's polygonID is different from that of the shadow, regardless of whether that pixel was translucent. * * Toon highlight mode uses the following formula: (GBAtek is wrong) v=vertex t=texture s=tooncolor=toontable[Rv]
R = ((Rt+1)*(Rv+1)-1)/64+Rs ;truncated to MAX=63 G = ((Gt+1)*(Rv+1)-1)/64+Gs ;truncated to MAX=63 B = ((Bt+1)*(Rv+1)-1)/64+Bs ;truncated to MAX=63 A = ((At+1)*(Av+1)-1)/64 * Translucent pixels are only drawn where the destination pixel has a different polygonID OR where the destination pixel was opaque. * for each separate polygon, W values are 'normalized', they're collectively shifted left or right by 4 until they all fit within 16 bits (if they fit within 12 bits or less, they can be shifted left to use the 16-bit range better) * conversion for Z values: ** Z-buffering: zbuf = (((Z * 0x4000) / W) + 0x3FFF) * 0x200 (using original W) ** W-buffering: zbuf = W (but it appears to use normalized W) * conversion for clear depth: ** clearZ = (val * 0x200) + 0x1FF * There are special depth-test rules for polygon borders. TODO: work it out. ** it seems to only apply to wireframe polygons ** when Z values are equal, left edges have priority over right edges, and top edges have priority over bottom edges (TODO: check wireframe vs normal) ** 'less or equal' depth test has no margin ** (dunno about other orders but they should use the regular rules. Y-sorting gets in the way) * Cases where 'less than' depth test becomes 'less or equal': ** wireframe polygon borders as mentioned above ** apparently, polygon borders in some other cases too ** when rendering frontfacing polygon pixels over existing opaque backfacing polygon pixels * in W-buffering mode, 'equal' depth test mode has a margin of 0xFF in either direction. That is, for example, incoming Z range of 0x100-0x2FE is considered equal to an existing Z-buffer value of 0x1FF. * in Z-buffering mode, margins are +-0x200. * PUSH/POP/STORE/RESTORE to the modelview matrix always apply to the vector matrix too, even in matrix mode 1. * "NORMAL/VEC_TEST require matrix mode 2" <- wrong. They work the same regardless of the matrix mode. * edge marking Posted by GBAtek -> polygon ID rule for screen edges confirmed -> at screen edges, the aforementioned depth test uses CLEAR_DEPTH (when testing against a pixel that would be offscreen), even when using a clear bitmap * antialiasing ** seems to be calculated from edge slopes ** topmost two pixels are retained, antialiasing blends them together including alpha (except color isn't blended when the pixel below has alpha=0) ** during rendering, if an incoming pixel fails the depth test with the topmost pixel, it is checked against the pixel below DMA * ARM9 DMA start mode 3 is similar to the GBA's 'video capture' DMA, although GBAtek doesn't make it obvious. It is triggered at the start of each scanline from 2 to 193. The enable bit is automatically cleared on scanline 194. * TODO: find when 'main memory display' DMA starts. Probably 8 pixels (48 cycles) in advance from the actual display. -- DMA starts ~32 cycles after the start of the scanline. Actual display starts ~48 cycles after the start of the scanline. Sound * repeat mode 3 behaves same as mode 1 (loops) * TODO: check to see what can be changed while a channel is playing. Format can be changed and that's a whole fucking pile of things to check. ____________________ Kuribo64 |
TechnoNightz |
| ||
Melon seeds Jamie account #123933 Level: 4 Posts: 2/3 EXP: 251 Next: 28 Since: 07-12-18 From: England Last post: 2344 days ago Last view: 1961 days ago |
I'd actually like to see an open-source documentation (perhaps a melonDS wiki) on this. As you say GBATEK is great but yeah.
Also you did a nice job explaining things, you've always been clear ^^ |
PoroCYon |
| ||
Half-eaten melon Normal user Level: 11 Posts: 1/24 EXP: 5039 Next: 946 Since: 12-01-19 From: .be Last post: 486 days ago Last view: 482 days ago |
Some that need to be confirmed:
DSP
|
Chagall |
| ||
Newcomer Normal user Level: 6 Posts: 3/6 EXP: 619 Next: 288 Since: 01-28-20 Last post: 1301 days ago Last view: 1226 days ago |
Rumble pak detection needs bit 6 set in addition to bit 1 reset (GBAtek only mentions bit 1).
Found empirically: https://github.com/Arisotura/melonDS/pull/719#discussion_r474976353 |
Generic aka RSDuck |
| ||
Big fire melon Administrator Level: 45 Posts: 224/610 EXP: 654487 Next: 5677 Since: 10-12-19 Last post: 70 days ago Last view: 19 hours ago |
there is a power saving mode for the wifi in which it stops receiving and transmitting data.
W_MODE_WEP: bit0-3 is set to 1: bit1 of W_POWERUNK is set bit0-3 is set to 2: bit0-1 of W_POWERUNK are set (i.e. it's value becomes 3) if bit0-3 are either one of those is the case and bit1 of W_POWER_TX is set the corrosponding bit is/bits are not manually changeable writeable (I haven't checked if setting W_MODE_WEB while W_POWER_TX bit1 is set makes a difference). W_MODE_RST: Only bit0 is relevant for power saving. Changing bit0 from 0 to 1: if bit1 of W_POWERUNK is set, bit8 of W_POWERSTATE is set. A short while later bit9 changes to 0 and if bit0 of W_POWERUNK is set at this point at time bit8 is set to 0 Changing bit0 from 1 to 0: returns back to power saving mode immediately. W_POWERSTATE: bit8 seems to indicate some other state related to power saving mode bit9 seems to indicate normal power saving mode while atleast one of bit8 and bit9 is 1 power saving mode is enabled Once that 2048 us power up period (initialised e.g. by setting bit0 of W_MODE_RST from 0 to 1) is over: when bit0-1 is 2 (the exact purpose of bit0 is still unknown) and bit8 is set, power saving mode is left and bit1 is set to 0 (thus the register value will be 0). W_POWERFORCE: setting bit15 and bit0 is set (=0x8001) switches to power saving mode (it also switches to regular power saving mode from bit8 power saving mode) setting bit15 and not bit0 (=0x8000) initiates waking up from power saving mode (like always first W_POWERSTATE bit8 is set then the register is cleared). Neither W_POWER_UNK nor bit2 of W_POWERSTATE are relevant for this. having bit15 set to 0 and and bit1 (=0x0001) of W_POWERSTATE initiates waking up from power saving mode (independently of bit1 of W_POWER_UNK), so bit8 of W_POWERSTATE is set. If bit0-1 of W_POWERSTATE is 2 once that process is done W_POWERSTATE becomes 0 (as already described in it's section) otherwise W_POWERSTATE stays 0x100. This doesn't work while bit0 of W_MODE_RST=0. Note that when switching power saving mode off via W_POWERFORCE it acts similarly to setting W_MODE_RST bit0 from 0 to 1, but the value of W_POWER_UNK doesn't matter. Leaving power saving mode takes about 2048 microseconds (measured with the wifi timer register). Both methods of leaving power saving mode will first set trigger IRQ11. After entering power saving mode: RFStatus: 9 RFPins: 0x4 After leaving power saving mode: RFStatus: 1 RFPins: 0x84 There's probably still a lot more to unpack. What is disabled and what not is currently an educated guess and the consequences of writing 0x8000 to W_POWERFORCE mentioned in gbatek are still to be explored. Als Gbatek says on bit1 of W_POWERSTATE: "Note: That queue stuff seems to work only if W_POWER_US=0 and W_MODE_RST=1.". I haven't tried bringing W_POWER_US into this yet. What does power saving mode do exactly? An existing program which utilises wifi I tried continued to work fine, except that nothing was being received anymore. W_CONTENTFREE and W_US_COUNT seemed to still count down. My guess is that only the antenna hardware is affected. In regards to transmission: what happens seems to be that upon requesting to send data just nothing happens. So W_TXBUSY is never flagged nor is W_TX_SEQNO incremented. A request made in power saving mode will be discarded, i.e. not sent once power saving mode is off. Not implementing power saving mode can lead to freezes in the Pokemon games. See here: https://melonds.kuribo64.net/board/thread.php?pid=2314#2314 ____________________ Take me to your heart / never let me go! "clearly you need to mow more lawns and buy a better pc" - Hydr8gon |
PoroCYon |
| ||
Half-eaten melon Normal user Level: 11 Posts: 8/24 EXP: 5039 Next: 946 Since: 12-01-19 From: .be Last post: 486 days ago Last view: 482 days ago |
IR cartridgesIR cartridges seem to work as follows, but I'd like to have someone else to verify this (seems to work with HGSS, BW and B2W2 carts, idk about others):Everything automatically happens at 115200 baud, 8n1. There seem to be three main SPI commands that are sent to what normally would be the savegame SPI bus, there's a fourth command to perform actual savegame operations. All transfers happen at 1 MHz (serial AUXSPI mode) unless indicated otherwise. The cartridge needs to be powered on, but nothing more besides this. No header reading or KEY1/KEY2 init, and so on. (I rebooted the cart with SCFG_MC and started doing SPI commands immediately afterwards, seems to work fine). This seems to be relevant for pretty much all NTR-031 carts, so Pokémon HGSS, BW, B2W2, "Walk With Me" and similar games, ... The commands:
Allegedly, the chip in carts responsible for IR is another H8/38606F (or 38602F?) (connected to the SPI bus on one side, and to some IR leds or so on the other). [UPDATE: 2021-03-01: added info on cmd 0x03..0x07, and non-Pokémon games. info from nocash, not me.] |
PoroCYon |
| ||
Half-eaten melon Normal user Level: 11 Posts: 10/24 EXP: 5039 Next: 946 Since: 12-01-19 From: .be Last post: 486 days ago Last view: 482 days ago |
Recently I've done some timing tests with the DSi's NDMA units. These are all my findings:
NOTE: all testing has been done as main RAM->main RAM (functional), or as TIMER0_DATA->main RAM (priority/timing). CPU timing comparison was done with TIMER0_DATA->DTCM. I did not yet test the interaction between the DSP's DMA capabilities, NDMA, and the ARM9. Function
Access ordering and priority
Timing stuff
|
Rayyan |
| ||
Big melon Administrator Level: 30 Posts: 155/238 EXP: 148258 Next: 17611 Since: 06-25-20 From: UK Last post: 213 days ago Last view: 14 days ago |
Makercodes: 00 = Homebrew 01 = Nintendo 41 = Ubisoft Entertainment (will add to this later) ____________________
How to write an emulator
1. throw code to be emulated somewhere 2. make memory system that allows accessing that code 3. emulate CPU 4. have fun implementing all the other hardware -- Arisotura, Tuesday 5th January 2021, 22:00:17 |
Mighy Max |
| ||
Member Normal user Level: 7 Posts: 1/10 EXP: 1119 Next: 329 Since: 07-08-21 Last post: 329 days ago Last view: 329 days ago |
Addendum to NWRAM:
Priorities between the sets of WRAM from highest to lowest. They are the same for reading and writing:
Within a set of WRAM, the parts can be set to lay on top of each other. The lowest part has the highest read priority. Write Priority is special. Writing to overlapping parts, writes to them all at once! Result of a testcase on HW: |
Arisotura |
| ||
Big fire melon magical melon girl Level: 58 Posts: 731/945 EXP: 1541493 Next: 36053 Since: 03-28-17 From: France Last post: 41 days ago Last view: 19 hours ago |
Posted by Mighy Max interesting! have you checked that reading from overlapping parts doesn't OR them together? like it does for VRAM. also, the NWRAM regions could theoretically overlap I/O space, but in practice I doubt that works ____________________ Kuribo64 |
Mighy Max |
| ||
Member Normal user Level: 7 Posts: 2/10 EXP: 1119 Next: 329 Since: 07-08-21 Last post: 329 days ago Last view: 329 days ago |
Posted by Arisotura Yes, that is the first part of the check. I write an initial individual value to all parts and overlay them. Afterwareds I read the value. The Part containing that value then is moved away and the read repeats, until all parts are done. See the line WRAM Bank Read Priorities, which notes which line is moved in which order. Also checked for the different sets. The WRAM Write Priority line shows which set really got written to, when the windows overlap: the write and read only applies to the highest priority.
Yes. But I have not yet have a safe method to test this behavior. And I doubt this is something that is used intentionally .... I thought about using it to blend over the Wifi RAM at 04800000h but you can't specify a window start that high, only the window end can be in the 04... range. Will make a repository of the NWRAM Testcase. It was first only a way to verify I understood the access found in my reversing of the stage 2 loader. Edit: Testcase source is here: https://github.com/DesperateProgrammer/DSiTestCases |
Arisotura |
| ||
Big fire melon magical melon girl Level: 58 Posts: 732/945 EXP: 1541493 Next: 36053 Since: 03-28-17 From: France Last post: 41 days ago Last view: 19 hours ago |
re: leaking NWRAM over I/O
I think the way memory mapping on the DS works makes that impossible anyway ____________________ Kuribo64 |
PoroCYon |
| ||
Half-eaten melon Normal user Level: 11 Posts: 14/24 EXP: 5039 Next: 946 Since: 12-01-19 From: .be Last post: 486 days ago Last view: 482 days ago |
In the past I once tried overlapping NWRAM and the IO space (by the request of, either profi200 or normmatt iirc), and reads always returned IO stuff. maybe a write would go to both, didn't test that, but I think it did end up at at least the IO registers, iirc. (Testing wasn't very thorough, though, we mainly wanted to know if we could exploit possible IO r/w redirection stuff, and the result is 'no'.) |
Mighy Max |
| ||
Member Normal user Level: 7 Posts: 3/10 EXP: 1119 Next: 329 Since: 07-08-21 Last post: 329 days ago Last view: 329 days ago |
Posted by PoroCYon I got curious today and wanted to check, if we can find out by either write or read through happening, if a HW register is actually present at a given address. Unfortunally this is not the case. The area 0x04.... is completely prioritized by the HW Registers. No NWRAM write passes nor any read operation shines through. But this makes the emulation simplier for melonDS, as NWRAM does not need to be implemented on this region. It would require the Bus Client for the NWRAM to do a sub instead of a mask (You can just mask with a fixed 0x03000000) but if you allow 03 and 04 you need to sub 1 to create such a mask or create a mask for each region and oring them. Both ways slow down the cirquit and increase its gatecount for no apperent reason. But that opens some other questions i would like to check: - is Bit28 really writeable? - did not check if the info on GBATEK is correct here - if this bit is writeable, does it have any other function then that in GBATEK? Does it change the priority, the fallthrough, timing? Any other suggestions or ideas what this bit ould control instead of an increased mapping region? For completeness and crosschecking, the simple test I made below. It shows 0 counts n both output lines. Image Size of set A was set to 64k from the previos tests. /***************************************************************************** * Test HW Registers via overlay. * Check if the NWRAM below HW registers show through, if there is no * physical register present *****************************************************************************/ int count = 0; WRAMSetWindow(0, 0x03FF0000, 0x04000000) ; memset((void *)0x03FF0000, 0xAA, 0x10000) ; WRAMSetWindow(0, 0x03FF0000, 0x04FF0000) ; for (int i=0;i<0x0ff0000;i++) { uint8_t val = ((volatile uint8_t *)0x04000000)[i] ; if (val == 0xAA) { printf("| %08x ", i) ; count++; if (count > 20) break ; } } printf("Read HW Regs Fallthrough Check: %i\n", count) ; count = 0; memset((void *)0x03FF0000, 0xAA, 0x10000) ; for (int i=0;i<0x0ff0000;i++) { ((volatile uint8_t *)0x04000000)[i] |= 0; if (((volatile uint8_t *)0x03FF0000)[i & 0xFFFF] == ((volatile uint8_t *)0x04000000)[i]) { printf("| %08x:%02x ", i, ((volatile uint8_t *)0x03FF0000)[i & 0xFFFF]) ; count++; if (count > 20) break ; } } printf("Write HW Regs Fallthrough Check: %i\n", count) ; WRAMSetWindow(0, 0x03FF0000, 0x04000000) ; |
Arisotura |
| ||
Big fire melon magical melon girl Level: 58 Posts: 734/945 EXP: 1541493 Next: 36053 Since: 03-28-17 From: France Last post: 41 days ago Last view: 19 hours ago |
that makes sense, at a coarse level memory mapping is probably implemented similarly to how melonDS does it (the big switch statement deciding which area the read/write goes to) ____________________ Kuribo64 |
Mighy Max |
| ||
Member Normal user Level: 7 Posts: 4/10 EXP: 1119 Next: 329 Since: 07-08-21 Last post: 329 days ago Last view: 329 days ago |
Posted by Arisotura Yes, it kind of makes sense, but i am not 100% sure on that. I thought of another test for that. I will do this as i get time. If bit28 extends the region, it must blend in 03ff0000 to 0x3ffffff, he start index is ff and the end is 1ff. Otherwise it should fall through. :edit: It dawned to me just now. It is part of the region. Its required so the last 32kB can be mapped and a zero length window still can be created. This means the end index is cropped internally at 0x100 |
Mighy Max |
| ||
Member Normal user Level: 7 Posts: 5/10 EXP: 1119 Next: 329 Since: 07-08-21 Last post: 329 days ago Last view: 329 days ago |
Tested more today, until the battery died just a few mins ago:
The end indizes in the windows are indeed completely writeable and do not reflect the cut at 0x04000000 happening. With Bit28 is set, last 32/64kB is accessible (It actually was already tested but not realized in the code posted above). So it is really part of the window region, allthough there is no observed difference if the end index is any greater. than 100(A)/200(B&C) The bits 0xE00FC00F at window for set A and 0xE007C007 in the windows for set B and C can not be chnaged. The bits 0x72 in set A banks and 0x60 in set B and C banks can not be set. This is not yet reflected in code and will be implemented (at the write, the performance impact is minimal) Some addendum to the SCFG_EXT7/9 Bit 25: Allthough gbatek states this enables/disables NWRAM, the NWRAM related HW registers seems still accessible and changeable with the same masks. So I need to revert the fall-through for NWRAM HW registers, when disabled NWRAM bit in SCFG_EXT and get some better understanding on that bit effect on the NWRAM. Did someone already play with it? |
Mighy Max |
| ||
Member Normal user Level: 7 Posts: 6/10 EXP: 1119 Next: 329 Since: 07-08-21 Last post: 329 days ago Last view: 329 days ago |
SCFG_EXT7/9. Bit 25: R/W on Arm7. RO on Arm9.
If cleared, the NWRAM is not blended in on the Arm7 or Arm9 system bus. However, the HW Registers at 0x04004040..0x04004063 are still working. Test: https://github.com/DesperateProgrammer/DSiTestCases/tree/master/NWRAM |
PoroCYon |
| ||
Half-eaten melon Normal user Level: 11 Posts: 15/24 EXP: 5039 Next: 946 Since: 12-01-19 From: .be Last post: 486 days ago Last view: 482 days ago |
Aptina MT9V113 internal MCU stuffThe Aptina cameras have an internal 68HC11-based MCU. Parts of its address space can be accessed through the XDMA registers (0x98c, 0x990, reachable over I2C) There's a "physical" address range (0x0000..0x1fff) and a "virtual"/"logical" one (0x2000..0x3fff). The former can be used to access "system" and "user RAM" (resp. 0x0000..0x03ff and 0x0400..0x7ff), as well as "Special Function Registers" (SFRs), basically just MMIO regs of the HC11. The latter allows access to the variable spaces of several "firmwares"/"services" running on the MCU, used for autofocus, autowhitebalance, etc. Each camera has a separate HC11. The above is already kinda known, but now for the new stuff. (Keep this section of GBATEK at hand while reading this, as I guess only a handful people ever looked at the cameras to begin with.) (NOTE: as the HC11 is an 8/16-bit MCU, pointers etc. are 16-bit (its address space is 16 bits wide). Also, it's a big-endian architecture, keep that in mind.) SFRs
Address translationAs alluded to in the previous part, SFR 0x1050 is used to set the mapping. Its value is 0x0100, which means we can access and modify the "pagetable mapping" over I2C. (I'm using quotes here because it's far from anything like a real MMU.) At 0x0100, a list of 16 pointes can be found: 0x0140 (MONITOR), 0x0000 (SEQ), 0x005d (AF), 0x0165 (AWB), 0x01d4 (FD), 0, 0, 0x282 (MODE), 0, 0, 0, 0x0220 (HG), and then more zeros. This matches what you'll find when dumping the 0x2000..0x2fff area. While system RAM has space for 16 more pointers (starting at 0x0120) for addresses 0x3000..0x3fff, in practice these are mirrors of the 0x2*** range. Setting a pagetable entry to an address of 0x2000 or higher seems to return 0 values, maybe there's a carveout, or maybe there's just nothing behind those addresses. Additionally, it does seem to mirror the upper half of memory (0x8000 and up) to the lower half, which is *quite* suspicious as a datasheet says there's 32 kilobytes of firmware ROM, and the exception vectors of the HC11 are at 0xfffe etc. (6502-style) So I'm betting the firmware ROM is in the upper half of MCU memory. System RAM layoutWith the above, we can start building a map of the system RAM space. As one datasheet (links at the end of this post) alludes to the stack of the HC11 firmware also being in system RAM and being 128 bytes in size, it's not too hard to guess where it is.
User RAM (0x0400 and on) doesn't seem to be writable, sadly. Or maybe I'm missing some kind of magic switch. Running code on the HC11A datasheet alludes to using the MONITOR variables to run code: arg1 is the pointer of the code to run, arg2 an optional argument (where is this put in? the accumulators?), and then set cmd to 0x01 to start the code. Sadly, this did not work for me: it resets the MCU, while doing not much else. Maybe it needs some kind of CRC (which the datasheet also alludes to), or maybe the feature is just locked away. (EDIT: maybe the resetting thing would be added to have the XDMA thing avoid messing with internal state. But does using the virtual addressing mode bypass it? Would chaining using another peripheral (the "ring bus access" maybe?) be able to be used as a bypass? I haven't tested.) Then I tried putting some shellcode in low system RAM and filling the stack with bad addresses (that is at the same time a NOP sled). Sadly this didn't work either, as the MCU also got reset before it got to execute my code. Maybe I'm triggering some kind of (bad) crash, or maybe there's a safety mechanism that automatically resets everything. (I hope it's not the latter.) (MCU resets seem to clear/reset the pagetable, stack (0x0380 and up), and some of the "logical variable" spaces in system RAM. 0x300..0x37f seems to be preserved, as well as some other small places in low system RAM.) Maybe this is a fun challenge for someone else here? P.S. I used Pk11's dsi-camera proof-of-concept as a base to mess with the cameras. Not really publishing my code because it's mostly just a spaghetti of I2C accesses and FIFO ugliness. I used vasm as HC11 assembler, though be aware that it gets some opcodes wrong, check with A09 (which doesn't seem to be able to process "org" directives) and this and this opcode listing I found. For more info on the HC11, see this (original DIP CPU info) and this (more modern microcontroller impl, only gave it a cursory glance, idk how useful it is outside of the instruction set info). Datasheets
|
Rayyan |
| ||
Big melon Administrator Level: 30 Posts: 207/238 EXP: 148258 Next: 17611 Since: 06-25-20 From: UK Last post: 213 days ago Last view: 14 days ago |
From GBATEK:
BPTWL Chip (LED/Volume/Powerbutton/Reset) (Device 4Ah) 20h R Battery State (bit0..3=Battery Level, bit7=Charge) BPTWL Battery State register and the battery icon on the DSi MenuCritical? (causes a shutdown) 0000 = 0x0 Almost Empty (one flashing red bar) 0001 = 0x1 0010 = 0x2 0100 = 0x4 Low (one red bar) 0011 = 0x3 0101 = 0x5 0110 = 0x6 1000 = 0x8 Two blue bars 0111 = 0x7 1001 = 0x9 1010 = 0x8 1100 = 0xc Three blue bars 1011 = 0xb 1101 = 0xd 1110 = 0xe Full (four blue bars) 1111 = 0xf ____________________
How to write an emulator
1. throw code to be emulated somewhere 2. make memory system that allows accessing that code 3. emulate CPU 4. have fun implementing all the other hardware -- Arisotura, Tuesday 5th January 2021, 22:00:17 |
Main - Development - GBAtek addendum/errata | Hide post layouts | New reply |
Page rendered in 0.158 seconds. (2048KB of memory used) MySQL - queries: 30, rows: 118/118, time: 0.036 seconds. Acmlmboard 2.064 (2018-07-20) © 2005-2008 Acmlm, Xkeeper, blackhole89 et al. |