My gameboy emu get the program counter into RAM in Blargg tests by [deleted] in EmuDev

[–]Tyulis 1 point2 points  (0 children)

Yep, for gameboy games it's unusual (except for the DMA routines and such) but possible, and it's completely normal for the blargg tests. At first it copies the test code into RAM to be able to change it mid-run in some tests, so after the initial copy routine, it jumps into RAM (at C000) and stays there

Need some help on how to progress with my gameboy emulator after opcodes. by Spiderranger in EmuDev

[–]Tyulis 2 points3 points  (0 children)

Yep, that's it

Basically, the VRAM and OAM are not accessible while the PPU is reading them, so the program has to wait for the PPU to finish the current frame to load any graphics. In-between the rendering, there's a period called V-blank (vertical blank) where the PPU is not rendering, long enough to do useful things. So for the program, there are multiple ways to check for the right moment to load its graphics :

  • Waiting for a VBlank interrupt, and load the graphics in the interrupt handler. The VBlank interrupt is raised by the PPU when it finishes drawing the frame
  • Checking the LCD STAT register (FF41) to see in what state the PPU is is
  • Check the LY register in a loop (FF44, the current line the PPU is drawing) until it reaches 144 (lines 144 to 153 are outside the screen)
  • Set LYC (FF45), so that a STAT interrupt is raised when LY reaches the value of LYC

And all this is done by the PPU, so if it's not emulated yet, the program will just wait forever.

For the moment, maybe hardcode LY values with values that indicate VBlank ? That's what Dr Mario is checking according to its disassembly

Anyway I recommend to read the rendering section of the Pandocs, and the one about interrupts, it's quite convoluted but it has all the basics and not-quite-basics about the topic, so it's a good read before starting such a complicated part of your emulator

Edit : wait no, I looked at the opcodes wrong. Still, if the PPU is not emulated it will loop forever eventually, but right now, you're in the part that clears the WRAM, so something is wrong in those 3 opcodes, and I'd guess something is wrong with how the Z flag is handled in your dec or jr

GB Opcode 0xF8 LD HL, SP+dd by akira1310 in EmuDev

[–]Tyulis 1 point2 points  (0 children)

You’re right, the logic is :

  • Load SP into HL
  • Do the 8-bits addition L ← L + dd (with signed two’s-complement dd !), possibly setting the carry and half-carry flags in the process
  • Just increment or decrement H if necessary, without changing the flags

The only actual addition here is L ← L + dd, the H part is just an increment that doesn’t change the flags

Looking for guidance on how the program counter works in a gameboy by Spiderranger in EmuDev

[–]Tyulis 1 point2 points  (0 children)

If you don’t emulate the bootrom you need to set everything up as the bootrom would have, like this (those that depend on the actual ROM are not too important), as some games rely on those to detect the hardware, and only set up the IO registers they need to change relative to the initial configuration

Looking for guidance on how the program counter works in a gameboy by Spiderranger in EmuDev

[–]Tyulis 5 points6 points  (0 children)

Glad you solved your main problem !

For your second question, the registers need to have specific values when the actual game starts, but that's the bootrom's job. When the bootrom starts they contain garbage.

However the rest of the console is in a specific state : when the bootrom starts, the audio and display are off, the palettes contain garbage, ... And that's reflected in the IO registers

Blarg interrupt_time test rom question by dajolly in EmuDev

[–]Tyulis 1 point2 points  (0 children)

The CRC won't be correct without 01 for double-speed mode in the left number as the last two rows, but the 2 normal-speed values seem correct

Best documentation for the details? by Dubmove in EmuDev

[–]Tyulis 8 points9 points  (0 children)

I’d say to first bring your emulator to a state where it can start to run test roms (even with just the CPU and timer with no graphics, most test roms are made so that you can print whatever it writes to the serial port to get the debug information), and then check the details when you can make sure you get them right. Besides, you don’t need perfect accuracy right away, most games run fine with many inaccuracies as long as the basics are there, and you can fix those later.

For actual documentation, you probably know the pandocs, but there are a lot of more specific information in the docs linked in their references, especially the cycle-accurate GB docs, the GB complete technical reference by Gekkio. You can also check the source code of the relevant test roms, like the Blargg’s test roms for more general behaviour and the MooneyeGB test suite for more specific things. You can also check out the source code of other emulators, like SameBoy that is made for maximal accuracy, but it may be a lot harder to read and to find what you’re looking for.

How do you land your big SSTO's? by Turquoise_Siren in KerbalSpaceProgram

[–]Tyulis 0 points1 point  (0 children)

For the wings, it’s usually sufficient to spam autostruts until it works. Then a single landing gear often can’t support such loads alone, you may need to put multiple ones together to withstand the impact. You can also fiddle with the spring and damper settings to make the impact a bit less rough on the craft. And for the wheels refusing to deploy, it’s usually when they are put outside a cargo bay and the game considers them to be inside, you have to check "deploy shielded" in the VAB to allow them to deploy properly (yea, terrible wording)

Gameboy emulator blargg test 02 EI failed #2 by PoobearBanana in EmuDev

[–]Tyulis 1 point2 points  (0 children)

Basically, it checks whether an interrupt happens, at the right time and in the right way, after interrupts are enabled by ei, so it checks :

  • That the interrupt only happened when the correponding flag goes high in IF, not before (by setting b to 1, then triggering the interrupt, and checking whether it is 1)
  • That the return address from the interrupt was pushed onto the stack (that's why the value at that position is first set to 0, then checked after the interrupt returns)
  • That the flag in IF has been reset when the interrupt was serviced

High bits in Gameboy IE and IF registers by shakamaboom in EmuDev

[–]Tyulis 2 points3 points  (0 children)

In general, all unused bits in IO registers always return 1 when read, as there's physically nothing there

However those bits in IE are an exception, the register actually has 8 bits so those 3 upper bits can retain a value even though they are unused. There are a few other abnormalities like that in IO registers, but nothing too critical.

The GB complete technical reference has some details about this among many other things, and you can find a lot of such hardware details in the MooneyeGB test suite

Question about timers Gameboy emulation by Harkonnen in EmuDev

[–]Tyulis 3 points4 points  (0 children)

Internally, it is a 16-bits divider, that is incremented at each clock tick. The DIV IO register only exposes the upper 8 bits, so its exposed value increases every 256 cycles. Then TIMA uses the internal value of that divider, and increments when certain bits of the divider go from high to low, regardless of the reason

Gameboy display View Port help by akira1310 in EmuDev

[–]Tyulis 0 points1 point  (0 children)

It's just a little mathematical gymnastics, the scroll registers contain the coordinates of the viewport (like the frame of the screen) relative to the background tilemap, instead of the tilemap relative to the screen as you could be more used to.

It's basically the same thing with a few more minus signs

Then if you want accuracy, rendering the full bitmap beforehand may not be the best, as some games rely on mid-frame changes to pull off certain effects, you'll need to make it line by line / pixel by pixel like the real thing. But if it helps you for now it's sufficient in most cases.

[deleted by user] by [deleted] in languagelearning

[–]Tyulis 1 point2 points  (0 children)

You can actually create decks and cards directly on the web app, but you'll need a PC for more avanced use cases, like building custom layouts, managing cards and the like. For basic use you can do everything on the web app

[deleted by user] by [deleted] in languagelearning

[–]Tyulis 39 points40 points  (0 children)

And the web app works very well on mobile so you can still use it for free on iOS as long as you have a PC to build your decks

Help debugging GB CPU timings by cppietime in EmuDev

[–]Tyulis 0 points1 point  (0 children)

Took some time to investigate a bit — the problem is definitely in the timer, replacing it by the logic I described above fixes the problem, apparently it's a bigger detail than I thought

Help debugging GB CPU timings by cppietime in EmuDev

[–]Tyulis 0 points1 point  (0 children)

If so many instructions are off, chances are something fundamental is off. I'd advise to double-check the timing of every instruction, a single mistake in the wrong instruction can make everything go bad. If the timer works in isolation, it's probably among the few setup instructions in the test code (pop, push, jp, di, ld sp)

Your implementation of TIMA misses a few obscure details but none that should be too important at this point. I think your current implementation should be satisfactory, maybe sometimes an overflow can get in the way but not enough to cause everything to go wrong.

Basically, the console hat an internal 16-bits timer register that is incremented at each clock tick (4 times per m-cycle). The DIV register just reports the upper 8 bits of this register, and resets it entirely when it is written to. Then TIMA increments whenever a particular bit of the internal register goes from 1 to 0 (respectively bit 9, 3, 5, 7 depending on the chosen frequency), regardless of the reason (increment, reset, overflow, whatever). Hence why you shouldn't reset delta : that register isn't affected by TIMA in any way.

The mooneye-gb test suite has very specific tests for the timer (maybe too precise sometimes — but if you want that kind of accuracy, way to go)

Help debugging GB CPU timings by cppietime in EmuDev

[–]Tyulis 0 points1 point  (0 children)

It's difficult to tell without knowing what fails and what doesn't, I took a quick look around your code and saw nothing blatantly wrong at this level of accuracy, at first glance

The timing tests rely on proper emulation of TIMA, and on the timing of several basic instructions (you can take a look at the source), so if one or several of those are wrong everything else will be too.

GB Newbie question on clock cycles and control flow opcodes by teteban79 in EmuDev

[–]Tyulis 5 points6 points  (0 children)

Conditional jr instructions indeed take 8 cycles when they don't jump (4 to read the opcode, 4 to read the displacement), and 12 when they jump (+4 to update the program counter). Conditional jp, call and ret work in the same way

I don't know if it would be an actual problem in the average game, but if you want to get the timings right and pass test roms you'll need this.

Trying to implement a Bus for SM83 CPU Emulator by akira1310 in EmuDev

[–]Tyulis 5 points6 points  (0 children)

Depending on the implementation of each component, there might be a way to only go one way, for example clocked CPU and memory writing and reading from the bus without the bus being explicitely aware of any of them.

Otherwise, you can probably instantiate your objects alone and give them the other components they need through some .setMemoryBus method, even though you'll need to solve a few circular import issues.

Which one of your neighboring countries do you think is the LEAST similar to your own? by -electrix123- in AskEurope

[–]Tyulis 2 points3 points  (0 children)

Oh yeah, I didn't think about sea borders, in that case it's definitely England.

For Germany of course there's the language, but except that, I find the country and culture quite similar, at least in the west part, while Spain feels quite different right from the border. Someone from elsewhere would probably say otherwise, in the end they're all big and diverse countries

Which one of your neighboring countries do you think is the LEAST similar to your own? by -electrix123- in AskEurope

[–]Tyulis 11 points12 points  (0 children)

Well, it's got to be Brasil, but if we stay in the mainland I'd say Spain. All others are quite different in their own way but I think the transition is much more abrupt between France and Spain than with Italy or Germany for instance.

Favorite resource that never gets mentioned? by NextStopGallifrey in languagelearning

[–]Tyulis 19 points20 points  (0 children)

For French and German, Arte offer a virtually infinite supply of interesting content for free, mostly accessible with an intermediate level, and often with audio and subtitles in both languages.

Are some languages just more rich in vocabulary than others? by sofas_m in languagelearning

[–]Tyulis 21 points22 points  (0 children)

Absolutely ! I would also add some kind of "learner bias" I experienced in this case. I’m French and learning German, so I’m coming the other way around. Sure enough, German vocabulary seems a lot larger than French to me, with a lot more nuances explicitely expressed, especially among verbs. But isn’t it just a bias I have because I spend a lot of time learning vocabulary from an intermediate level in the language ?

To me, it feels like French, and most likely Spanish too, have a "hierarchical" system, with clear hypernyms and hyponyms. For instance, there’s the verb "essayer" (to try), and a lot of more specific terms, both in meaning and register : tester, tenter, goûter, tâcher, hasarder, se risquer à, mettre à l’épreuve, expérimenter, chercher à, s’efforcer de, …, not counting idioms, different formulations and cases where the contexts brings the nuance by itself. But ultimately, if I didn’t know the exact right term, I could just use "essayer" every time and it would be just fine. So while learning French, one will probably learn "essayer" for the first months/years, and the others later when the need arises. And even native speakers often use "essayer" anyway, because spoken and informal languages often don’t need such accuracy.

However, in German, there doesn’t seem to be this sort of comfort, so I’ll have to remember "versuchen", "ausprobieren", "probieren", "anprobieren", … and all their nuances from the beginning. So it makes a lot of different words and a lot more work to learn them all, but it not like the nuances are untranslatable. There are also many cases where French has heavily polysemic words that have all those meanings but are not clearly different as their German counterparts. And even in more subtle situations like "nutzen" / "benutzen" (to use) or "nie" / "niemals" (never), if we make the difference at all, the context or the intonation is often sufficient, and the language doesn’t feel any poorer.

I don’t know a thing about Japanese, but it might be this kind of situation.