Electronic Quarterback

I have a confession to make. I’ve never actually played a Gameboy, never even seen one up close. When I was a tadpole we had handhelds, but they were a little different. One of the most popular on my school bus was this: Electronic Quarterback. This is fairly accurate other than running a little slow, which makes it much easier than the real thing. If you want to be really accurate you’ll need to get a red marker and scribble all over your screen. We had color screens, but that color was red.

The short instructions are you select pass or run. On a run play just try to run forward using your 2 blockers to help you. On a pass you are moving your lower dot downfield try to line him up with your QB and press A to pass. When the play’s over you press B to see the down & distance, and press it a second time to see the score and time. You can read the instructions here: (https://archive.org/details/hh_cqback) We’re short a button so if you hold B and press A it switches the play call from run to pass. This is indicated in the upper right of the screen.

This uses a TMS1100 which is basically a hacked up calculator chip from the early 70’s. I thought a 4 bit CPU would be easier, but no. What sane person would have thought of using a random number generator for a program counter? Also it has 1 byte opcodes, also not as cool as it seems. It means every branch is basically an indirect jump so I couldn’t easily use static recompilation like I’ve been doing. Every memory read/write takes multiple opcodes to do, which makes it hard to optimize, or even understand the disassembly. That’s one reason why it’s running a little slow. Not sure how to speed it up, there’s no frames to skip. In retrospect maybe I should have put the extra effort in to do a static recompile.

One thing that was really helpful and kind of interesting was the patent app. http://patft.uspto.gov/netacgi/nph-Parser?Sect2=PTO1&Sect2=HITOFF&p=1&u=%2Fnetahtml%2Fsearch-bool.html&r=1&f=G&l=50&d=PALL&RefSrch=yes&Query=PN%2F4249735.

Dave

EQBack.ino.leonardo.hex (33.7 KB)

3 Likes

I saw this on Porn Stars - the original the person was pawning was in great condition and I think they sold it for a measly $25!

@filmote I think you meant Pawn Stars…

:slight_smile: I know.

A picture just flashed through my mind. Seems like I’ll be able to skip breakfast this morning.

2 Likes

I got a working keychain version of this :wink:
s-l300

As weird as it sounds, I still didn’t understand how to play it.

Yeah, I never understood how to play it at the time. I was just mashing buttons. Now with this in slow motion I see how the blockers work and the passing Apparently there’s a lot more to it, at least according to that patent.

That’s really cool key chain. I didn’t know that was a thing.

I really thought this would run much faster. I never clear the screen, I just make changes to the LED segments. Is there a way to do that and skip the .Display or would that not help? What I’m doing now is just calling display every so many writes to LED segments. If I wait too long I end up skipping some of the blinking, and I assume if I did it after every segment change it would slow it down.

Without knowing what the code is like,
any guesses as to what the speed issues could be will be wild stabs in the dark.

I’m just asking a general question, is there a simple way to write to the screen w/o using the framebuffer? It seems a waste of time since this system doesn’t have frames and I’m pushing 6 pixels at time.

There is a way to write directly to the screen, but there’s no simple API for it,
you’d have to manually send commands and data over SPI.

I don’t know if it’s possible to only write to parts of the display at a time though.
You’d have to check the datasheet:


Out of interest, will the code be shared at any point?

1 Like

Maybe, it won’t do anything without the ROM, so I’m not sure it’d be of interest to anyone. And it’s kind of lazy code, I don’t know that I want to take the time to clean it up. BTW, getting the ROM in there wasn’t easy, the compiler kept trying to help me out by converting it into lookup table, and I kept trying to trick it into thinking it was code. I ended up doing a bunch of separate if statements and switch statements. And if you even look at it wrong it will compile it as ram and you end up at 184% usage.

1 Like

You’ll never know if it’s closed source.
If it’s open source then you at least give people the chance to decide how interesting it is.

I’ve never encountered that happening before.
Just to check, you have been using PROGMEM, yes?
You haven’t just been marking an array as const/constexpr and hoping it ends up in progmem?

No, I never used PROGMEM, wasn’t sure if there would be side effects so I didn’t bother. Hadn’t had a problem until this time around. Since I build maps and stuff in an external program, I just have the program spit out the C code of a function with a switch that returns the data, and plug in the function. For some reason this time around the compiler optimized my function back into table.

That’s concerning.

PROGMEM is how you’re supposed to put something into program memory instead of RAM.
If you aren’t using PROGMEM and pgm_read_byte (or one of the other pgm_read_ functions) then you’re bound to run into issues eventually.

Yes, it’s supposed to do that.

Half the point of the switch statement is to allow the compiler to create a lookup table when it’s able to.
(Though that lookup table should be in progmem usually.)
Sometimes it will do a binary search instead, depending on the data involved,
and sometimes it will create a ‘jump table’.

It’s C++, not C.

Yes you can, there are commands for partial draws.

This is true, this only has any kind of performance gain if your code is deterministic, i.e. you are able to draw on the fly based on what contents exist in some data structure.

As such, it’s pretty terrible at doing any game that has any significant overlapping as you have to run blitting operations within each page which is less efficient than using a screen buffer.

The Tetris Micro Card uses a direct draw method to save on space that we ended up not needing in the end.

Also, as each page of data itself stored in stripes, the data structure for images bigger than one page is “annoying”. Basically you are dealing with tile data.

Thanks, I was hoping there was a magic command somewhere. It just seems wasteful, but then I’m not used to buffers at all.

Looks like I’m OK now. I’m getting pretty close to 100% speed now I think.

I expected there probably were, but I’ve never seen anyone actually need to do that.

I remember seeing ‘coulmns’ and ‘pages’ in the documentation but never bothered to look into how they work.

Do you not normally write video games?

Only for fun on arcade hardware. There I write to VRAM while the electron beam is busy somewhere else.

Otherwise I write business apps. It’s even more boring than you would imagine. But the work is steady, and the pay is good.

3 Likes

Ah, OK, that makes sense.
That’s probably the only kind of system where you wouldn’t have a frame buffer.

This is one of the reasons I’d be reluctant to program as a professional.