Post your WIPs

Use this forum to share and discuss Uzebox games and demos.
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Post your WIPs

Post by CunningFellow »

Yes - it needs to be cycle accurate because I am bastardizing it as a timer to end the scanline. TIMR0_OVF is already being used for something else crazy.

It however does not need to be "uart accurate". I don't care if it can emulate the sending of data or if it listens to the configuration bits regarding bits lenghts and parity etc.

All I need is that it triggers an interrupt 1305 clocks cycles after I do a

STS UBRR0L, r16
STS UDR0, r16

That is how many clocks the real hardware will trigger USART0_TXCI with UBRR0L being set to 8 and data length set to 7.

I was planing on cheating and modifying cuzebox so it just triggered an interrupt on that clock count rather than trying to emulate the intricacies of the uart prescaler etc.

I don't think I am smart enough to modify cuzebox to fully emulate the USART hardware.
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Post your WIPs

Post by Artcfox »

CunningFellow wrote: Wed Oct 11, 2017 11:14 am Yes - it needs to be cycle accurate because I am bastardizing it as a timer to end the scanline. TIMR0_OVF is already being used for something else crazy.

It however does not need to be "uart accurate". I don't care if it can emulate the sending of data or if it listens to the configuration bits regarding bits lenghts and parity etc.

All I need is that it triggers an interrupt 1305 clocks cycles after I do a

STS UBRR0L, r16
STS UDR0, r16

That is how many clocks the real hardware will trigger USART0_TXCI with UBRR0L being set to 8 and data length set to 7.

I was planing on cheating and modifying cuzebox so it just triggered an interrupt on that clock count rather than trying to emulate the intricacies of the uart prescaler etc.

I don't think I am smart enough to modify cuzebox to fully emulate the USART hardware.
Here is my "This looks like where the changes need to happen" analysis, but it's probably not complete, and there are probably some side-effects that I haven't anticipated, so I'm not going to actually attempt an implementation. I think that Jubatian is the only one that has a complete understanding of how CUzeBox works, but I at least wanted to try to understand what modifications would need to be made to support this, just as a fun exercise.

There are two different implementations of the opcode decoder in cu_avr_n.h and cu_avr_e.h, but I don't think those need to be touched, because we're not adding or changing any opcodes, only keying off the values set by existing opcodes (STS).

In cu_avr.c, there is a function called cu_avr_write_io. Depending on how much we want to cheat at this, I assume that we'll need to add cases for CU_IO_UBRR0L and CU_IO_UDR0, and CU_IO_USCRA, CU_IO_USCRB, CU_IO_USCRC along with some state variables so we can calculate how many clocks the interrupt needs to fire after.

You said that in your code, those two instructions were right after each other, but the timing would still be correct as long as those two instructions were within 80 clocks of each other?

I would take a look at the cu_avr_interrupt function in that file to see how it works, but I don't think we'll need to modify that, only understand it. It looks another case needs to be added to the cu_avr_itcheck function to get it to enter the new interrupt that has to be defined.

These variables look like they might be good ones to search for in the code to understand how the interrupt scheduling code works:

Code: Select all

/* Interrupt might be waiting to be serviced flag. This is set nonzero by
** any event which should trigger an IT including setting the I flag in the
** status register. It can be safely set nonzero to ask for a certain IT
** check. */
boole           event_it;

/* Interrupt entry necessary if set. */
boole           event_it_enter;

/* Vector to call when entering interrupt */
auint           event_it_vect;
In the same file, I believe cu_avr_hwexec is another function that will need to be modified as well to keep things cycle-perfect, but that might be tricky as well and AVR Studio might be needed in order to verify that everything stays cycle-perfect.

Like I said before, I'm not going to attempt these modifications myself, but I figured this could be a good opportunity to at least familiarize myself with a bit more of the CUzeBox codebase.
User avatar
Jubatian
Posts: 1563
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Post your WIPs

Post by Jubatian »

These are about right. What you need to pay more attention is cu_avr_hwexec and the event system implemented, that is, how CUzeBox determines the next cycle when it should service a hardware event (this is a critical part of having blazing fast emulation). Just check what other peripherals do to time stuff.

Emulation is cycle-exact on terms of when an input port is sampled or when an output can have effect, so normally you don't need hacks, things will just work (unlike in Uzem where Timer1 carried ugly hacks to realize cycle-accurate timing). If you are unsure, Mode 13 or something similar may be a good base to fix your timing even if you don't have any instrumentation. I actually did this: I compared the last pixel between the real hardware and CUzeBox, how it is affected by shifting around timing in either.

The process is roughly that using the real hardware, you have to get to the point where your code does what you think it should be doing. In the case of Mode 13, it is that the interrupt fires exactly after the last "out" (resulting in a 7 clocks wide last pixel due to 3 cy IT latency + 3 cy "jmp" instruction in the vector table). You reduce the timer one by one until you see the last pixel disappearing. The value just before that is the correct timer value for the mode. Then you do the same for the emulator. If in the end the two values are the same, the emulator is cycle exact.

Simple, and really no tools are required beyond the Uzebox.

If you however have a fixed time, just start adding nops to shift around the end of the display to get the same effect (or the point where you fire the timer).
User avatar
ry755
Posts: 226
Joined: Mon May 22, 2017 6:01 am

Re: Post your WIPs

Post by ry755 »

I'm working on a Doodle Jump type of game. It's called UzeJump. I've got the basics done, I just need to work on the levels and scrolling.

Picture:
https://i.imgur.com/BQLPrls.png

Here's the source code if you want to take a look:
https://github.com/ry755/UzeJump
User avatar
D3thAdd3r
Posts: 3221
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Post your WIPs

Post by D3thAdd3r »

Very cool, looking forward to seeing this one progress :)
User avatar
danboid
Posts: 1937
Joined: Sun Jun 14, 2020 12:14 am

Re: Post your WIPs

Post by danboid »

I have to second what Uze said about Mega Bomber. Its arguably the most graphically impressive game for the Uzebox and it could almost pass as being a SNES game so I was diappointed to test it with a friend last night and discover that two player mode doesn't work. Surely adding a working second player would be pretty easy to do? I've not looked at or tried building its code yet.

With Mega Bomber's two player mode not working, it makes me doubt that four player mode (via a multi-tap) has ever worked. Does the standard UB kernel support the multi-tap ie 4 or 5 joystick inputs?
User avatar
danboid
Posts: 1937
Joined: Sun Jun 14, 2020 12:14 am

Re: Post your WIPs

Post by danboid »

I've not been able to build Mega Bomber ( in the MegaBomber subdir of https://github.com/weber21w/uzebox-weber/ )

Code: Select all

avr-gcc -I"../../../../uzebox/kernel/"  -mmcu=atmega644 -mmcu=atmega644 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=28636360UL -Os -fsigned-char -ffunction-sections  -MD -MP -MT uzeboxSoundEngineCore.o -MF dep/uzeboxSoundEngineCore.o.d  -DVIDEO_MODE=3 -DINTRO_LOGO=0 -DSOUND_CHANNEL_4_ENABLE=1 -DSOUND_CHANNEL_2_ENABLE=1 -DSOUND_CHANNEL_3_ENABLE=1 -DCENTER_ADJUSTMENT=4 -DMAX_SPRITES=31 -DRAM_TILES_COUNT=31 -DSCREEN_SECTIONS_COUNT=0 -DSCREEN_TILES_V=23 -DFIRST_RENDER_LINE=60 -DFORMAT_EEPROM=0 -mcall-prologues -x assembler-with-cpp -Wa,-gdwarf2 -c  ../../../../uzebox/kernel//uzeboxSoundEngineCore.s
avr-gcc -I"../../../../uzebox/kernel/"  -mmcu=atmega644 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=28636360UL -Os -fsigned-char -ffunction-sections  -MD -MP -MT uzeboxVideoEngine.o -MF dep/uzeboxVideoEngine.o.d  -DVIDEO_MODE=3 -DINTRO_LOGO=0 -DSOUND_CHANNEL_4_ENABLE=1 -DSOUND_CHANNEL_2_ENABLE=1 -DSOUND_CHANNEL_3_ENABLE=1 -DCENTER_ADJUSTMENT=4 -DMAX_SPRITES=31 -DRAM_TILES_COUNT=31 -DSCREEN_SECTIONS_COUNT=0 -DSCREEN_TILES_V=23 -DFIRST_RENDER_LINE=60 -DFORMAT_EEPROM=0 -mcall-prologues -c  ../../../../uzebox/kernel//uzeboxVideoEngine.c
avr-gcc -I"../../../../uzebox/kernel/"  -mmcu=atmega644 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=28636360UL -Os -fsigned-char -ffunction-sections  -MD -MP -MT main.o -MF dep/main.o.d  -DVIDEO_MODE=3 -DINTRO_LOGO=0 -DSOUND_CHANNEL_4_ENABLE=1 -DSOUND_CHANNEL_2_ENABLE=1 -DSOUND_CHANNEL_3_ENABLE=1 -DCENTER_ADJUSTMENT=4 -DMAX_SPRITES=31 -DRAM_TILES_COUNT=31 -DSCREEN_SECTIONS_COUNT=0 -DSCREEN_TILES_V=23 -DFIRST_RENDER_LINE=60 -DFORMAT_EEPROM=0 -mcall-prologues -c  ../main.c
In file included from ../gamedefines.h:235:0,
                 from ../engine.h:1,
                 from ../main.c:23:
../functiondefs.h:120:4: error: variable ‘colormap’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
 u8 colormap[] PROGMEM = {0x0F,0x30,0xF0,0xC0,0x37};
    ^
In file included from ../engine.h:5:0,
                 from ../main.c:23:
../logic.h: In function ‘FindKiller’:
../logic.h:512:7: warning: variable ‘closest’ set but not used [-Wunused-but-set-variable]
    u8 closest = 255;
       ^
make: *** [Makefile:83: main.o] Error 1
User avatar
danboid
Posts: 1937
Joined: Sun Jun 14, 2020 12:14 am

Re: Post your WIPs

Post by danboid »

I see Lee hasn't updated his repo since 2017. It'd be great if we can get Mega Bomber to build again and get two player mode working as I think Mega Bomber could become a good demo for the Uzebox with only a little extra effort.
User avatar
danboid
Posts: 1937
Joined: Sun Jun 14, 2020 12:14 am

Re: Post your WIPs

Post by danboid »

I have got Mega Bomber to build simply by adding a const to the start of line 120 of functiondefs.h but the player sprites don't get drawn correctly and there are no enemies so it doesn't look like this is the same (latest) code that was used to build the binary on the wiki.

Hopefully Lee still has a copy or he can tell us where the latest source is?
User avatar
D3thAdd3r
Posts: 3221
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Post your WIPs

Post by D3thAdd3r »

Oh eh... :oops:

Hopefully I will find it in spring cleaning. I think I had the source on a laptop for both the igloo(cool walking under igloo roof foreground) and several other levels at one point, sorry for not releasing it but the code got rotten and split up. The AI was getting there, but was no entertainment to play against at it's best, and ran out of flash. I'm surprised 2 players doesnt work.

The game could be done with reflashing per level, but it turned to chaos trying to find a way to make a complete game in 60K. As is, a pretty demo that kept a large chunk of it's 60K assets on the screen at once. The state of the code got bad because I had different builds, each with 1 single level, and each build had it's own custom code for various level gimmicks.

If trying to make a complete game, probably easier to build from scratch IMO. The clever thing was just reducing an almost grid based game, into strictly grid based. Probably not much to learn from the code but I will release whatever I can find.
Post Reply