Using a task list for multi-game or simultaneus game use
Moderator: Moderators
Using a task list for multi-game or simultaneus game use
What if you designed a game such that each routine was given a label 0-255. A single game would consist of a static array of 8-bit values that would prompt the game engine to jump to the coinciding routine.
I'm not sure what terminology this would fall into. Perhaps single-threading? A jump table?
Are there any advantages to this technique? I'm hoping that such a method would allow multiple games of the same cart. Also, two separate threads could be used for split screen games wherein each player could be running a different game.
I'm not sure what terminology this would fall into. Perhaps single-threading? A jump table?
Are there any advantages to this technique? I'm hoping that such a method would allow multiple games of the same cart. Also, two separate threads could be used for split screen games wherein each player could be running a different game.
Re: Using a task list for multi-game or simultaneus game use
This is already done in a lot of games to control the current game state, but I guess you could generalize it further to individual tasks within the game state.slobu wrote:What if you designed a game such that each routine was given a label 0-255. A single game would consist of a static array of 8-bit values that would prompt the game engine to jump to the coinciding routine.
Not sure either... A NES game would be single-threaded even without this technique, and a jump table table is just the mechanism to call the functions, but it doesn't describe the general idea at all.I'm not sure what terminology this would fall into. Perhaps single-threading? A jump table?
Not sure. Most games already are basically a chain of different systems running one after the other, only they're executed in a hardwired order. The only advantages of shuffling the order of the tasks I can think of is completely skipping unnecessary tasks in certain parts of the game or reusing individual systems in different engines, but we can kinda do that already.Are there any advantages to this technique?
I don't get it... You want to code some generic functions and chain them together in different ways in order to create different games?I'm hoping that such a method would allow multiple games of the same cart.
I guess so, as long as you have the RAM to keep track of both games (and they were programmed to make use of relocatable variables).Also, two separate threads could be used for split screen games wherein each player could be running a different game.
Re: Using a task list for multi-game or simultaneus game use
It's easier to store and work with an address than to store a gamestate variable. You can have substates that are also addresses, and just emulate a jsr indirect in place of say a jump table. This allows for saving of an address anywhere as well for a yield kind of functionality.
Re: Using a task list for multi-game or simultaneus game use
This would be interesting, to see something like the Mixed Match from SNES Tetris & Dr. Mario.slobu wrote:Also, two separate threads could be used for split screen games wherein each player could be running a different game.
Re: Using a task list for multi-game or simultaneus game use
Thanks for the replies, guys. The idea is half-baked. I'm thankful it got your attention.
The main reason I was thinking about a list of sub-routines to jump to is not only for mini-games but RPG Maker use. I could see storing the list in battery backed RAM.
The main reason I was thinking about a list of sub-routines to jump to is not only for mini-games but RPG Maker use. I could see storing the list in battery backed RAM.
Re: Using a task list for multi-game or simultaneus game use
This "list of subroutines" has been used in real life as threaded code and return-oriented programming and bytecode.
Re: Using a task list for multi-game or simultaneus game use
So I had a problem of handling multiple background tasks that wouldn't hog the main routine that executes every frame. First I tried a linked list of nmi interrupts in the stack. that was conceptually unwieldy. Next I tried a fixed task list only to realize that it was equivalent to lists of subroutines like tepples said. Recently I figured out that what I really wanted was coroutines and event loops, so I tried a routine that pushed an address at the bottom of the stack instead of the top like a jsr. That was closer to what I wanted, but that approach ended up with lots of house keeping code. After some tweaks I think I've got a fairly efficient pair of routines that implement the thread safe multitasking I wanted.Movax12 wrote:It's easier to store and work with an address than to store a gamestate variable. You can have substates that are also addresses, and just emulate a jsr indirect in place of say a jump table. This allows for saving of an address anywhere as well for a yield kind of functionality.
EDIT: The code has been edited to only save addresses, and to be robust against overflowing the queue. Also the examples has been removed for space.
Code: Select all
.segment "ZEROPAGE"
sub_queue_head: .res 1
sub_queue_tail: .res 1
.segment "CODE"
sub_queue = $0300 ; uses the low end of the page
;;
; queues the top of the return stack to the event loop,
; and forces the caller to rts.
; This will cause the rest of the caller to execute
; after the whole return stack unwinds.
.proc yield
; clc = pre increment
; sec = post increment
sec
lda #$00
; increment ptr and load into A atomically
; this way nmi can safely call yield even if normal
; processes are executing yield as well.
; isc zp is an unofficial opcode that compiles to $E7
isc sub_queue_head
eor #$ff
; if queue is full, execute one item before pushing this.
cmp sub_queue_tail
bmi @queue_not_full
pha
jsr __execute_queued_routine
pla
@queue_not_full:
and #%00011111 ; A = (sub_queue_head++)%32
tay
pla
sta sub_queue+192+32*0, y
pla
sta sub_queue+192+32*1, y
rts
.endproc
.proc event_loop_start
lda #0
sta sub_queue_head
lda #32
sta sub_queue_tail
;!; jmp event_loop
.endproc
.proc event_loop
lda #>(event_loop-1)
pha
lda #<(event_loop-1)
pha
sec
lda sub_queue_tail
sbc #32
; busy loop until queue is not empty
@wait_loop:
cmp sub_queue_head
beq @wait_loop
;!; jmp __execute_queued_routine
.endproc
.proc __execute_queued_routine
; atomic increment and load needs to happen here as well
; because this can be called by yield as well.
sec
lda #$00
isc sub_queue_tail
eor #$ff
and #%00011111
tay
lda sub_queue+192+32*1, y
pha
lda sub_queue+192+32*0, y
pha
rts
.endproc
Last edited by JRoatch on Mon Oct 20, 2014 4:53 pm, edited 1 time in total.
Re: Using a task list for multi-game or simultaneus game use
NES Games become multithreaded the instant you add interrupts.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: Using a task list for multi-game or simultaneus game use
Right, but I'm making a distinction between a multi-threading and multi-tasking. Since I'm going to have some IO bound tasks (such as map decompression, and tile uploading), I want those tasks to yield their time to other tasks during the spare time before the next NMI.
Re: Using a task list for multi-game or simultaneus game use
Sounds like you want this idea: viewtopic.php?t=11075&p=126450
You can do a simplistic two thread setup by splitting the stack into two, and saving all the registers for a thread when you switch. (No recursion of course.)
So you could yield while waiting for NMI, and then force a yield when NMI hits.
You can do a simplistic two thread setup by splitting the stack into two, and saving all the registers for a thread when you switch. (No recursion of course.)
So you could yield while waiting for NMI, and then force a yield when NMI hits.
Re: Using a task list for multi-game or simultaneus game use
Yes the async idea but not a multi stack implementation. I know this isn't a new idea, I think the only novel thing I did was the use of an unofficial opcode for thread safety.
For the multi-stack setup, why would you not be able to recurse if the entire stack is preserved on the context switch?
EDIT: clarifying which context switch I'm talking about.
For the multi-stack setup, why would you not be able to recurse if the entire stack is preserved on the context switch?
EDIT: clarifying which context switch I'm talking about.
Last edited by JRoatch on Mon Oct 20, 2014 6:19 pm, edited 1 time in total.
Re: Using a task list for multi-game or simultaneus game use
Actually, I guess that is not a limitation in this case.