I'm still working on my game project (a text-based dungeon crawl in the tradition of several DOS-based BBS door games), although it's coming along further. I ran into a design problem, though, and I'd like some input on my stop-gap solution.
With my current approach the stack will eventually overflow if the user dies and either starts a new game or loads from a previous save several times in a single program execution. My tentative fix is to save SP right before the main loop that calls all other branching functions, and in the event the player restarts I restore that SP value and jump back to the beginning of that main loop. Here are some code snippets, TASM syntax:
public SP_STATE, GAME_RESET
SP_STATE dw 0 ;Stack Pointer state stored for game resetting
; to keep stack from overflowing.
GAME_RESET dw DrawMenu ;Offset of DrawMenu for resetting game.
extrn ReadByte:proc, ClearScreen:proc, WriteString:proc
extrn SendCRLF:proc, GotoXY:proc, WriteChar:proc
extrn RandomMonster:proc, ResetChar:proc
mov [SP_STATE],sp ;Save SP to SP_STATE for later reset
call GotoXY ;Put cursor at 0,0 (top left)
call WriteString ;Draw menu and prompt
And here is the current SP resetting procedure:
extrn ClearScreen:proc, ChangeName:proc, TextDungeon:proc
extrn SP_STATE:word, GAME_RESET:word
jmp ax ;Jump to TextDungeon DrawMenu label.
mov ax,4C99h ;Should never be reached but gives error
int 21h ; and exits if it happens...
I've read repeatedly that SP should never be modified directly unless you know exactly what you're doing, given that a system interrupt can occur in the middle of the process and bring the whole thing to an ugly, grinding halt. I've done my best to ensure that the IP change happens immediately after the SP change, which seems to me like it should minimize the chance of a problem down to the smallest it can get.
Is this a good way to do things or should I suck it up and fix my short-sighted design?