Ymir Dungeon Designer

Products: Dungeon of Ymir
Developer(s): Fred Nachbaur
Date: 198x
Type: Cassette
Platform(s): TS 1000
Tags: Game

Ymir Dungeon Designer is a level editor for Dungeon of Ymir, allowing users to design, review, save, and export custom maze sets. The program stores up to nine dungeon levels in a three-dimensional string array M$(9,20,30), with each cell holding either a space or CHR$(128) (the inverse space block graphic used as a wall tile). Cursor movement in the editor follows an 8-direction numpad-style scheme, with row and column wrapping handled explicitly. The export process is notably complex: it uses RAND USR calls at addresses 8200 and 837 to invoke machine code routines that transfer the designed mazes into the original game’s data via SRAM, requiring the user to load Part 2 of the Dungeon of Ymir tape in a specific sequence. Variables such as WL, FRAME, PRINT, CLEAR2, CLEAR1, and KEY store line numbers used as GOSUB targets, a common technique to make subroutine dispatch more readable.


Program Analysis

Program Structure

The program is organized into clearly separated functional sections, with a main menu dispatching to numbered modules via GOTO 1000*VAL Z$. An introductory splash screen runs first at line 9000, then falls through to initialization at line 100.

Line RangeFunction
100–230Initialization: array, subroutine address variables, mode flags
500–550Main menu display and dispatch
1000–1090Option 1: View a maze level
2000–2320Option 2: Edit a maze level
3000–3080Option 3: Save dungeon to tape
4000–4190Option 4: Export/install dungeon into game
8000–8030Subroutine: level selector
8100–8170Subroutine: draw border frame
8200–8240Subroutine: print maze contents to screen
8300–8340Subroutine: clear status lines 22–23
8400–8450Subroutine: “press any key” wait
9000–9090Introduction/splash screen

Data Storage

All nine dungeon levels are held in a single three-dimensional string array declared at line 100: DIM M$(9,20,30). Each element is a one-character string; walls are stored as CHR$(128) (the inverse-space block graphic) and empty cells as the default space. This maps neatly to a 20-row by 30-column playfield bordered by the frame subroutine.

Subroutine Address Variables

Lines 110–160 assign BASIC line numbers to named variables (WL, FRAME, PRINT, CLEAR2, CLEAR1, KEY), which are then used as GOSUB targets throughout the program. This is a deliberate idiom that improves readability and makes renumbering easier, at the cost of shadowing the BASIC keyword PRINT with a numeric variable of the same name — a legal but unusual choice that could surprise a reader.

Menu Dispatch

The menu at line 500 accepts a single keypress and dispatches with GOTO 1000*VAL Z$, routing to lines 1000, 2000, 3000, or 4000 for options 1–4, and to line 0 (non-existent) for option 0 — which causes a BASIC error and effectively performs a NEW-like reset since option 0 is described as “START ANEW (CLEARS DUNGEON).” This is a well-known technique for clearing program state without a dedicated handler.

Editor Mechanics

The maze editor at line 2000 uses an 8-direction movement scheme mapped to the keys 1–8. Row and column deltas are computed simultaneously using Boolean arithmetic in lines 2250–2260:

  • Keys 6, 1, 3 move south (row+1); keys 7, 2, 4 move north (row−1)
  • Keys 8, 3, 4 move east (col+1); keys 5, 1, 2 move west (col−1)

Wrapping is handled explicitly at lines 2270–2300, with the boundary check IF NOT R serving as a test for zero (since NOT 0 is true in BASIC). The cursor is shown by printing an inverse asterisk [*] then immediately reprinting the cell’s actual content at the same position, exploiting the print position to restore the display.

The fill/erase toggle uses M as a Boolean (0 or 1). Pressing CHR$(118) (the ENTER/newline character as detected via INKEY$) toggles the mode. Wall data is written as CHR$(128*M) — either CHR$(128) for fill or CHR$(0) (space) for erase.

Machine Code Integration and Export Process

Option 4 provides a multi-step export procedure to patch the maze data into the original “Dungeon of Ymir” game. Two RAND USR calls are central to this process:

  • RAND USR 837: loads Part 2 of the game tape into memory (the maze data segment)
  • RAND USR 8200: installs the new maze data from the designer into the game’s memory area

Line 4180 calls RAND USR 16514 to trigger a system-level routine, followed by NEW at line 4190 to reset BASIC. The SRAM (8K static RAM expansion) is required as temporary storage during the transfer. The process also involves re-saving the patched Part 2 back to tape, as described in the step-by-step on-screen instructions.

System Variable Manipulation

POKE 16418 appears repeatedly throughout the program. Address 16418 is the system variable FLAGS; poking it to 0 clears the print-suppression flag, ensuring output goes to the screen rather than the printer, while poking it to 2 at line 3010 redirects output. This is used carefully around SAVE to control what the system variable state is during tape operations.

Level Display

The print subroutine at line 8200 uses PRINT AT N,1;M$(L,N) to output each row of the current level’s maze slice as a string, exploiting the fact that slicing a 2D sub-array of a 3D string array returns a string of the full row width. Line 8230 displays the level number using CHR$(L+156), which maps levels 1–9 to characters 157–165 — the UDG character range, though here it relies on the game’s own character definitions being present.

Notable Anomalies

  • Line 2030 lists “4: NORTH-WEST” twice (for both keys 2 and 4), though the movement code at line 2260 makes key 4 move northeast (east + north). This is a display bug in the help text.
  • The introductory sequence calls CLEAR at line 9080 before jumping to line 100 where DIM M$(9,20,30) is declared — this intentionally wipes any previous array contents, fulfilling the “CLEAR” semantics without losing the program itself.
  • The “press any key” subroutine at lines 8420–8430 first waits for all keys to be released, then waits for a keypress — a standard debounce pattern to avoid immediately consuming a prior keypress.

Content

Appears On

Related Products

High resolution, “Dungeons and Dragons” graphic adventure game, Rogue-like. Travel to the ninth level of the Dungeon of Ymir to...

Related Articles

Related Content

Image Gallery

Source Code

   1 REM E(RND)~~ ;)=4▘/+#[B]C▝Y▛>7<"#[L]4 PAUSE 5[F]RND)▒4▘£  GOSUB [K]TAN   ▘/+5=4) # GOSUB [K]TAN 
  10 GOTO 9000
 100 DIM M$(9,20,30)
 110 LET WL=8000
 120 LET FRAME=8100
 130 LET PRINT=8200
 140 LET CLEAR2=8300
 150 LET CLEAR1=8320
 160 LET KEY=8400
 200 LET MENU=500
 210 LET M=0
 220 LET R=NOT M
 230 LET C=NOT M
 500 CLS
 510 PRINT "[M][E][N][U][:]",,"0: START ANEW (CLEARS DUNGEON)","1: VIEW A MAZE",,"2: EDIT A MAZE",,"3: SAVE DUNGEON TO TAPE","4: INSTALL DUNGEON"
 520 LET Z$=INKEY$ 
 530 IF Z$="" THEN GOTO 520
 540 IF Z$<"0" OR Z$>"4" THEN GOTO MENU
 550 GOTO 1000*VAL Z$
 1000 CLS
 1010 GOSUB WL
 1020 GOSUB FRAME
 1030 GOSUB CLEAR2
 1035 GOSUB PRINT
 1040 PRINT AT 23,5;"PRINT NEXT LEVEL? Y/N"
 1050 IF INKEY$ ="N" THEN GOTO MENU
 1060 IF INKEY$ <>"Y" THEN GOTO 1050
 1070 LET L=L+1
 1080 IF L=10 THEN LET L=1
 1090 GOTO 1030
 2000 CLS
 2010 GOSUB FRAME
 2020 PRINT AT 3,8;"[C][U][R][S][O][R]█[C][O][N][T][R][O][L][S][:]"
 2030 PRINT AT 5,3;"1: SOUTH-WEST    5: WEST";AT 6,3;"2: NORTH-WEST    6: SOUTH";AT 7,3;"3: SOUTH-EAST    7: NORTH";AT 8,3;"4: NORTH-WEST    8: EAST"
 2040 PRINT AT 10,2;"ENTER: CHANGE FILL/ERASE MODE";AT 12,3;"Q: RETURN TO MENU";AT 16,3;
 2050 GOSUB WL
 2060 GOSUB PRINT
 2100 LET M=NOT M
 2105 GOSUB CLEAR1
 2110 PRINT AT 23,0;"MODE: ";("FILL" AND M);("ERASE" AND NOT M)
 2200 PRINT AT R,C;"[*]";AT R,C;M$(L,R,C)
 2210 LET Z$=INKEY$ 
 2220 IF Z$="Q" THEN GOTO MENU
 2230 IF Z$=CHR$ 118 THEN GOTO 2100
 2250 LET R=R+(Z$="6" OR Z$="1" OR Z$="3")-(Z$="7" OR Z$="2" OR Z$="4")
 2260 LET C=C+(Z$="8" OR Z$="3" OR Z$="4")-(Z$="5" OR Z$="1" OR Z$="2")
 2270 IF R>20 THEN LET R=1
 2280 IF NOT R THEN LET R=20
 2290 IF C>30 THEN LET C=1
 2300 IF NOT C THEN LET C=30
 2310 LET M$(L,R,C)=CHR$ (128*M)
 2320 GOTO 2200
 3000 CLS
 3010 POKE 16418,2
 3020 PRINT "SAVE TO TAPE: INPUT SAVE NAME.",,,,,"START TAPE BEFORE PRESSING ENTER"
 3030 INPUT S$
 3040 CLS
 3050 PRINT "DUNGEON OF YMIR ALTERNATE MAZE: ",,"NAME: ";S$
 3060 SAVE S$
 3070 GOSUB KEY
 3080 GOTO MENU
 4000 CLS
 4010 PRINT "ARE YOU SURE THAT THE DUNGEON ISAS YOU WANT IT?"
 4020 PAUSE 4E4
 4030 IF INKEY$ <>"Y" THEN GOTO MENU
 4040 CLS
 4050 PRINT "TO EXPORT YOUR NEW MAZE SET TO  DUNGEON OF YMIR, PROCEED THUSLY:"
 4060 PRINT ,,"1: BE SURE THAT YOUR 8K SRAM IS   [E][N][A][B][L][E][D]. MAZES WILL BE TEMPO-   RARILY STORED THERE."
 4070 PRINT ,,"2: THIS PROGRAM WILL NEW ITSELF.  WHEN THE CURSOR RE-APPEARS,     ENTER [F][A][S][T] MODE."
 4080 PRINT ,,"3: POSITION YOUR ORIGINAL D OF Y  TAPE TO THE START OF PART 2."
 4090 PRINT ,,"4: ENTER [R][A][N][D]█[U][S][R]█[8][3][7] AND START   THE TAPE IN PLAY MODE."
 4100 PRINT ,,"5: WHEN LOADED WITH ERROR C/0,    ENTER [R][A][N][D]█[U][S][R]█[8][2][0][0]. THIS IN-   STALLS THE NEW MAZE."
 4110 GOSUB KEY
 4120 PRINT "6: PUT YOUR NEW TAPE INTO YOUR    RECORDER, AND POSITION TO JUST  AFTER THEN END OF PART 1."
 4130 PRINT ,,"7: SAVE THE MODIFIED PART TO      YOUR TAPE BY ENTERING [G][O][T][O]█[2]."
 4140 PRINT ,,"8: AFTER SAVING, THE PROGRAM      WILL RUN, BUT THE COVER SCREEN  WILL BE MESSED UP. THE PROPER   SCREEN WILL BE DISPLAYED ON     RE-LOADING LATER."
 4150 PRINT ,,,,"[R][E][A][D]█[I][N][S][T][R][U][C][T][I][O][N][S]█[A][G][A][I][N][?]█[Y][/][N]"
 4160 IF INKEY$ ="Y" THEN GOTO 4000
 4170 IF INKEY$ <>"N" THEN GOTO 4160
 4180 RAND USR 16514
 4190 NEW
 8000 PRINT "WHICH LEVEL? 1-9"
 8010 LET L=CODE INKEY$ -28
 8020 IF L<1 OR L>9 THEN GOTO 8010
 8030 RETURN
 8100 CLS
 8110 POKE 16418,0
 8120 PRINT "[▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒]";
 8130 FOR N=0 TO 19
 8140 PRINT "[▒]";TAB 31;"[▒]";
 8150 NEXT N
 8160 PRINT "[▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒][▒]";
 8170 RETURN
 8200 FOR N=1 TO 20
 8210 PRINT AT N,1;M$(L,N)
 8220 NEXT N
 8230 PRINT AT 22,4;"[T][H][I][S]█[I][S]█[D][U][N][G][E][O][N]█[L][E][V][E][L]█";CHR$ (L+156)
 8240 RETURN
 8300 POKE 16418,0
 8310 PRINT AT 22,0;"                                "
 8320 POKE 16418,0
 8330 PRINT AT 23,0;"                                "
 8340 RETURN
 8400 POKE 16418,0
 8410 PRINT AT 23,0;"[P][R][E][S][S]█[A][N][Y]█[K][E][Y]█[T][O]█[C][O][N][T][I][N][U][E][.][.][.][.][.][.][.]"
 8420 IF INKEY$ <>"" THEN GOTO 8420
 8430 IF INKEY$ ="" THEN GOTO 8430
 8440 CLS
 8450 RETURN
 9000 CLS
 9010 PRINT "[C][U][S][T][O][M]█[M][A][Z][E][S]█[F][O][R]█[D][U][N][G][E][O][N]█[O][F]█[Y][M][I][R]",,"THIS PROGRAM LETS YOU DESIGN ANDINSTALL YOUR OWN MAZES FOR VERSN3 OF ""DUNGEON OF YMIR"""
 9020 PRINT ,,"START BY LOADING ""YMIR"" (PART","1), AND BREAK WHEN LOADED. SAVE TO A NEW BLANK TAPE WITH GOTO 2."
 9030 PRINT ,,"THEN LOAD THIS PROGRAM TO DESIGNYOUR NEW MAZES. FROM THE MENU,  YOU MAY EDIT, SAVE, REVIEW, OR  ""EXPORT"" (INSTALL) NEW ""DUNGEON"""
 9040 PRINT ,,"[R][U][N] OR [C][L][E][A][R] ZAPS YOUR WORK. TO RE-START AFTER BREAK, ENTER     [G][O][T][O]█[M][E][N][U]."
 9050 PRINT ,,"YOU MAY MAKE YOUR MAZE LEVELS ASSIMPLE OR AS COMPLEX AS YOU LIKE"
 9060 SLOW
 9070 GOSUB 8400
 9080 CLEAR
 9090 GOTO 100

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top