From 953fa9d1b5b8873890ecb8fe22846e67321ceaa4 Mon Sep 17 00:00:00 2001 From: Rob Date: Wed, 21 Sep 2016 21:28:17 -0500 Subject: [PATCH] First functional build with make, Merlin32, and AppleCommander! --- JOK.TITLE.PIC.bin => JEWEL.TITLE.PIC.bin | Bin Makefile | 19 +- castles.s | 375 ++++++++ convert.s | 137 +++ display.s | 332 +++++++ endgame.s | 320 +++++++ filing.s | 85 ++ general.mac.s | 74 ++ graphics.s | 473 ++++++++++ input.output.s | 335 +++++++ io.mac.s | 26 + jewel.end.game.s | 68 ++ jewel.of.kaldun.s | 428 +++++++++ jok-includes.inc | 35 + jok.segments.s | 20 + jok.system.s | 55 +- main.control.s | 1067 ++++++++++++++++++++++ math.mac.s | 34 + math.s | 126 +++ monsters.s | 390 ++++++++ noise.s | 28 + places.s | 240 +++++ prolib.mac.s | 77 ++ prolib.s | 121 +++ reset.s | 48 + shapes.s | 396 ++++++++ story.s | 274 ++++++ title.s | 472 ++++++++++ 28 files changed, 6031 insertions(+), 24 deletions(-) rename JOK.TITLE.PIC.bin => JEWEL.TITLE.PIC.bin (100%) create mode 100755 castles.s create mode 100755 convert.s create mode 100755 display.s create mode 100755 endgame.s create mode 100755 filing.s create mode 100755 general.mac.s create mode 100755 graphics.s create mode 100755 input.output.s create mode 100755 io.mac.s create mode 100755 jewel.end.game.s create mode 100755 jewel.of.kaldun.s create mode 100755 jok-includes.inc create mode 100755 jok.segments.s create mode 100755 main.control.s create mode 100755 math.mac.s create mode 100755 math.s create mode 100755 monsters.s create mode 100755 noise.s create mode 100755 places.s create mode 100755 prolib.mac.s create mode 100755 prolib.s create mode 100755 reset.s create mode 100755 shapes.s create mode 100755 story.s create mode 100755 title.s diff --git a/JOK.TITLE.PIC.bin b/JEWEL.TITLE.PIC.bin similarity index 100% rename from JOK.TITLE.PIC.bin rename to JEWEL.TITLE.PIC.bin diff --git a/Makefile b/Makefile index 8519d99..38ba43f 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,17 @@ include local.config # Local stuff: -# > PGMS is a list of direct assembler targetrs -PGMS = jok.system.s newgame.s # > SRC is a list of all source files used to trigger a rebuild -SRC = $(PGMS) castle-level-1.s castle-level-2.s variables.s +SRC = castle-level-1.s castles.s display.s filing.s graphics.s input.output.s jok.system.s \ + math.mac.s monsters.s noise.s prolib.mac.s reset.s story.s variables.s \ + castle-level-2.s convert.s endgame.s general.mac.s io.mac.s jewel.of.kaldun.s \ + main.control.s math.s newgame.s places.s prolib.s shapes.s title.s jewel.end.game.s \ + jok.segments.s JOK_SYS = JOK.SYSTEM -JOK_PIC = JOK.TITLE.PIC +JOK_PIC = JEWEL.TITLE.PIC NEWGAME = NEWGAME +JOK_PGM = JEWEL.OF.KALDUN +JOK_END = JEWEL.END.GAME TMPL = template.po APP = jewel-of-kaldun DISK = $(APP).po @@ -18,6 +22,7 @@ ZIP = $(APP).zip jok: $(SRC) $(ASM) jok.system.s $(ASM) newgame.s + $(ASM) jok.segments.s cp $(TMPL) $(DISK) cat $(JOK_SYS).bin | $(AC) -p $(DISK) $(JOK_SYS) SYS 0x2000 $(AC) -k $(DISK) $(JOK_SYS) @@ -25,11 +30,15 @@ jok: $(SRC) $(AC) -k $(DISK) $(JOK_PIC) cat $(NEWGAME).bin | $(AC) -p $(DISK) $(NEWGAME) BIN 0x1000 $(AC) -k $(DISK) $(NEWGAME) + cat $(JOK_PGM).bin | $(AC) -p $(DISK) $(JOK_PGM) BIN 0x6000 + $(AC) -k $(DISK) $(JOK_PGM) + cat $(JOK_END).bin | $(AC) -p $(DISK) $(JOK_END) BIN 0x0800 + $(AC) -k $(DISK) $(JOK_END) $(AC) -ll $(DISK) zip $(ZIP) $(DISK) clean: rm $(PGM) $(DISK) $(ZIP) rm *_Output.txt _FileInformation.txt - rm $(JOK_SYS).bin $(NEWGAME).bin + rm $(JOK_SYS).bin $(NEWGAME).bin $(JOK_PGM).bin $(JOK_END).bin diff --git a/castles.s b/castles.s new file mode 100755 index 0000000..bc11441 --- /dev/null +++ b/castles.s @@ -0,0 +1,375 @@ +******************************** +* Draw CASTLE1, CASTLE2, and * +* lower the drawbridge for * +* castle #1. * +* Uses: GENERAL.MAC * +******************************** + +******************************** +* Draw King Aradeas' castle * +******************************** + +CASTLE1 ENT + LDX #5 + JSR HCOLOR ; HCOLOR = 5 + MOVB #159;EY ; set starting points: + NILW EX ; HPLOT 0,? TO 0,159 + NILW SX + MOVB #5;CTR0 +:0 JSR PARAPET1 ; draw 5 sets of parapets + DEC CTR0 + BNE :0 + MOVB #10;SY ; draw a bar 10 pixels wide + JSR PARAPET0 ; ! + MOVB #0;SY ; ! + JSR PARAPET0 ; ! + MOVB #10;SY ; ! + JSR PARAPET0 ; finished tower + MOVW #90;SX ; prepare for sloped left + MOVW #90;EX ; side of tower + MOVB #0;SY + MOVB #20;EY + JSR SLOPDOWN + MOVW #130;SX ; prepare for sloped right + MOVW #130;EX ; side of tower + MOVB #0;SY + JSR SLOPUP + LDX #7 ; HCOLOR = 7 + JSR HCOLOR + MOVB #40;SY ; and prepare for drawing the + NILW SX ; outline of castle + MOVW #10;EX + MOVB #40;EY + MOVB #5;CTR0 +:1 JSR OUTLINE1 ; draw outline of parapets + DEC CTR0 + BNE :1 + MOVW #100;SX ; begin outlining the tower + MOVB #159;SY + MOVW #100;EX + MOVB #30;EY + JSR DRAWLINE + MOVW #90;EX + MOVB #20;EY + JSR LINETO + MOVB #0;EY + JSR LINETO + MOVB #0;SY + MOVW #90;SX + MOVW #100;EX + MOVB #2;CTR0 +:4 JSR OUTLINE1 ; now outlining upper parapets + DEC CTR0 ; of the tower + BNE :4 + MOVW #140;EX ; and finish off the tower. + JSR LINETO + MOVB #20;EY + JSR LINETO + MOVW #130;EX + MOVB #31;EY + JSR LINETO + MOVB #159;EY + JSR LINETO + NILW SX ; draw the bottom line. + MOVB #159;SY + MOVW #279;EX + JSR DRAWLINE + RTS + +******************************** +* Draw the Castle of Kaldun. * +******************************** + +CASTLE2 LDX #5 + JSR HCOLOR + MOVB #159;EY + MOVW #80;EX + MOVB #70;SY + MOVW #80;SX + JSR PARAPET0 + MOVB #60;SY + JSR PARAPET0 + MOVB #70;SY + JSR PARAPET0 + MOVB #100;SY + JSR PARAPET0 + JSR PARAPET0 + MOVB #5;CTR0 +:0 JSR PARAPET2 + DEC CTR0 + BNE :0 + MOVW #70;SX + MOVW #70;EX + MOVB #60;SY + MOVB #80;EY + JSR SLOPDOWN + MOVB #90;EY + MOVW #110;SX + MOVW #110;EX + JSR SLOPUP + LDX #7 + JSR HCOLOR + MOVB #159;SY + MOVB #159;EY + NILW SX + MOVW #279;EX + JSR DRAWLINE + MOVW #45;SX + MOVB #125;EY + MOVW #80;EX + JSR DRAWLINE + MOVB #159;SY + MOVW #80;SX + MOVW #80;EX + MOVB #90;EY + JSR DRAWLINE + MOVW #70;EX + MOVB #80;EY + JSR LINETO + MOVB #60;EY + JSR LINETO + MOVW #70;SX + MOVB #60;SY + MOVW #80;EX + JSR OUTLINE1 + JSR OUTLINE1 + MOVW #120;EX + JSR LINETO + MOVB #80;EY + JSR LINETO + MOVW #110;EX + MOVB #90;EY + JSR LINETO + MOVB #100;EY + JSR LINETO + MOVW #130;EX + JSR LINETO + MOVW #130;SX + MOVB #100;SY + MOVW #130;EX + MOVB #90;EY + MOVB #5;CTR0 +:1 JSR OUTLINE2 + DEC CTR0 + BNE :1 + MOVW #80;SX + MOVB #155;SY + MOVW #279;EX + MOVB #155;EY + MOVB #11;CTR0 +:2 JSR LAYERS2 + DEC CTR0 + BNE :2 + MOVW #110;EX + JSR LAYERS2 + JSR LAYERS2 + JSR LAYERS2 + MOVW #75;SX + MOVW #115;EX + JSR LAYERS2 + MOVW #70;SX + MOVW #120;EX + JSR LAYERS2 + JSR LAYERS2 + MOVW #80;SX + MOVB #81;SY + MOVW #80;EX + MOVB #84;EY + JSR BRICKS2 + MOVW #90;SX + MOVB #76;SY + MOVW #90;EX + MOVB #79;EY + JSR BRICKS2 + MOVW #100;SX + MOVB #81;SY + MOVW #100;EX + MOVB #84;EY + JSR BRICKS2 + MOVW #110;SX + MOVB #76;SY + MOVW #110;EX + MOVB #79;EY + JSR DRAWLINE + MOVB #9;CTR0 +:3 MOVB #106;SY + MOVB #109;EY + JSR BRICKS2 + ADDW SX;#10;SX + MOVW SX;EX + MOVB #111;SY + MOVB #114;EY + JSR BRICKS2 + ADDW SX;#10;SX + MOVW SX;EX + DEC CTR0 + BNE :3 + RTS + +******************************** +* General subroutines used by * +* castle drawing routines. * +******************************** + +BRICKS2 JSR DRAWLINE + ADDB SY;#10;SY + ADDB EY;#10;EY + LDA EY + CMP #160 + BLT BRICKS2 + RTS + +LAYERS2 JSR DRAWLINE + SUBB SY;#5;SY + SUBB EY;#5;EY + RTS + +OUTLINE2 JSR DRAWLINE + SUBB SY;#10;SY ; SY=SY-10 + ADDW EX;#20;EX ; EX=EX+20 + JSR DRAWLINE + ADDW SX;#20;SX ; SX=SX+20 + ADDB EY;#10;EY ; EY=EY+10 + JSR DRAWLINE + ADDB SY;#10;SY ; SY=SY+10 + ADDW EX;#9;EX ; EX=EX+9 (not off page..) + JSR DRAWLINE + ADDW EX;#1;EX ; EX=EX+1 (correct ^^^) + ADDW SX;#10;SX ; SX=SX+10 + SUBB EY;#10;EY ; EY=EY-10 + RTS + +OUTLINE1 JSR DRAWLINE + ADDB #10;SX;SX ; SX=SX+10 + ADDB #10;EY;EY ; EY=EY+10 + JSR DRAWLINE + ADDB #10;SY;SY ; SY=SY+10 + ADDB #10;EX;EX ; EX=EX+10 + JSR DRAWLINE + ADDB #10;SX;SX ; SX=SX+10 + SUBB EY;#10;EY ; EY=EY-10 + JSR DRAWLINE + SUBB SY;#10;SY ; SY=SY-10 + ADDB #10;EX;EX ; EX=EX+10 + RTS + +DRAWLINE ENT + LDA SY ; draws a hi-res line + LDX SX ; using the AppleSoft + LDY SX+1 ; routines: + JSR HPOSN ; HPLOT SX,SY TO EX,EY +LINETO LDY EY + LDA EX + LDX EX+1 + JSR HPLOTTO + RTS + +PARAPET1 MOVB #40;SY ; draw the high part of + JSR PARAPET0 ; a parapet and then the + MOVB #50;SY ; low part of it. + JMP PARAPET0 ; (King Aradeas' castle) + +PARAPET2 MOVB #90;SY ; draw parapets for + JSR PARAPET0 ; Kalduns' castle. + JSR PARAPET0 + MOVB #100;SY + +PARAPET0 MOVB #10;CTR1 ; draw a block of 10 lines +:0 JSR DRAWLINE ; (vertical) + JSR INCX + DEC CTR1 + BNE :0 + RTS + +SLOPDOWN MOVB #10;CTR0 +:0 JSR DRAWLINE + JSR INCX + INC EY + DEC CTR0 + BNE :0 + RTS + +SLOPUP MOVB #10;CTR0 +:0 JSR DRAWLINE + JSR INCX + DEC EY + DEC CTR0 + BNE :0 + RTS + +INCX INC SX ; increase both + BNE :0 ; SX and EX by one. + INC SX+1 +:0 INC EX + BNE :1 + INC EX+1 +:1 RTS + +******************************** +* Variables used by the Castle * +* drawing routines. * +******************************** + +SX ENT + HEX 0000 +SY ENT + HEX 00 +EX ENT + HEX 0000 +EY ENT + HEX 00 +CTR0 HEX 00 +CTR1 HEX 00 + +******************************** +* Lower King Aradeas' * +* drawbridge: * +******************************** + +DRAWBRID MOVB #0;CTR0 + NILW SX + NILW EX + MOVB #131;SX +:0 LDX #7 + JSR DISPLAYB + LDA #100 + JSR MONWAIT + LDX #4 + JSR DISPLAYB + INC CTR0 + LDA CTR0 + CMP #27 + BLT :0 + DEC CTR0 ; fall through to Display + LDX #7 ; Bridge routine... + +DISPLAYB JSR HCOLOR + MOVB #159;SY + LDY CTR0 + MOVB BRIDGEX,Y;EX + MOVB BRIDGEY,Y;EY + JSR DRAWLINE + MOVB #120;SY + LDY CTR0 + MOVB CHAINX,Y;EX + MOVB CHAINY,Y;EY + JSR DRAWLINE + RTS + +******************************** +* Drawbridge points: * +******************************** + +BRIDGEX DFB 131,133,136,139,142,145,148,151,154 + DFB 156,159,161,163,166,168,170,171,173 + DFB 175,176,177,178,179,180,180,180,180 +BRIDGEY DFB 109,109,109,109,110,111,112,113,114 + DFB 116,117,119,121,123,125,127,130,132 + DFB 135,138,140,143,146,149,152,155,159 +CHAINX DFB 131,133,135,138,140,142,145,147,149 + DFB 151,153,155,157,159,160,162,163,165 + DFB 166,167,168,169,169,170,170,170,170 +CHAINY DFB 119,119,119,119,120,120,121,122,123 + DFB 124,125,127,128,130,132,134,136,138 + DFB 140,142,144,146,149,151,153,156,159 + diff --git a/convert.s b/convert.s new file mode 100755 index 0000000..4b8b234 --- /dev/null +++ b/convert.s @@ -0,0 +1,137 @@ +******************************** +* Integer conversion routines. * +* Uses: IO * +* IO.MAC * +* MATH * +******************************** + +* External references + ; jewel.of.kaldun.s +DATA EXT + + +******************************** +* CONVERT converts a hex byte * +* to decimal and prints it in * +* the form: XXX. * +* I.E. $10 = 016 * +******************************** + +CONVERT LDA #"0" + LDY #3 +:0 STA CONVSTR-1,Y + DEY + BNE :0 + LDA (PTR),Y +:1 CMP #100 + BLT :2 + SBC #100 + INC CONVSTR + JMP :1 +:2 CMP #10 + BLT :3 + SBC #10 + INC CONVSTR+1 + JMP :2 +:3 CMP #1 + BLT :DONE + SBC #1 + INC CONVSTR+2 + JMP :3 +:DONE LDY #0 ; kill leading zeros +:LOOP LDA CONVSTR,Y + CMP #"0" + BNE :JUSTIFY + INY + CPY #2 ; check only 1st two 0's + BLT :LOOP +:JUSTIFY CPY #0 ; Y contains how many 0's + BEQ :PRINTIT ; to "zap" +:JBEGIN LDX #0 ; the Jloop shifts data left +:JLOOP LDA CONVSTR+1,X + STA CONVSTR,X + INX + CPX #3 + BLT :JLOOP + DEY + BNE :JBEGIN +:PRINTIT LDA DATA ; call output routine to + PHA ; print number string. + LDA DATA+1 + PHA + PRINT CONVSTR + PLA + STA DATA+1 + PLA + STA DATA + RTS +CONVSTR ASC "999"00 + +******************************** +* Converts a hex word into a * +* printable string. * +* I.E. $FFFF = 65535 * +* $0000 = 00000 * +******************************** + +CONVWORD LDY #5 + LDA #"0" +:0 STA CWSTR-1,Y + DEY + BNE :0 + LDX #0 +:AGAIN LDY #0 +:LOOP LDA (PTR),Y + STA NUM1,Y + LDA NUMBERS,X + STA NUM2,Y + INX + INY + CPY #2 + BLT :LOOP + STX XTEMP + JSR IDIV + LDX XTEMP + LDA #NUM1 + STA PTR+1 + TXA + LSR + TAY + LDA RESULT + CLC + ADC CWSTR-1,Y + STA CWSTR-1,Y + CPX #10 + BLT :AGAIN +:KILL LDY #0 ; kill leading zeros +:KILLOOP LDA CWSTR,Y + CMP #"0" + BNE :JUSTIFY + INY + CPY #4 ; check 1st 4 zeros + BLT :KILLOOP +:JUSTIFY CPY #0 ; Y contains how many 0's + BEQ :PRINTIT ; to "zap" +:JBEGIN LDX #0 ; the Jloop shifts data left +:JLOOP LDA CWSTR+1,X + STA CWSTR,X + INX + CPX #5 + BLT :JLOOP + DEY ; check if another leading 0 + BNE :JBEGIN ; must be killed. +:PRINTIT LDA DATA ; call output routine to + PHA ; print number string. + LDA DATA+1 + PHA + PRINT CWSTR + PLA + STA DATA+1 + PLA + STA DATA + RTS +CWSTR ASC "99999"00 +NUMBERS DA 10000,1000,100,10,1 + diff --git a/display.s b/display.s new file mode 100755 index 0000000..380d85a --- /dev/null +++ b/display.s @@ -0,0 +1,332 @@ +******************************** +* Display map routines: * +******************************** + +* Default values: + +WSCREEN = 24 +HSCREEN = 20 +WMAP = 48 +HMAP = 32 + +******************************** +* Get the value of map @ (x,y) * +******************************** + +MAPINDEX DEX + DEY + STX XOFF + STY YOFF + LDA #0 + STA XOFF+1 + STA YOFF+1 + LDA MAPSW + BMI :NOMONS +*------------------------------- + LDY #0 +:REPEAT LDA M_HP,Y ; if HP = 0, no monster at this + BEQ :CHECK ; location. + LDA M_LEVEL,Y ; check if monster is on the + CMP MAPADDR+1 ; correct level + BNE :CHECK + LDA M_X,Y ; check x-coordinate against + CMP XOFF ; map x-coordinate. + BNE :CHECK + LDA M_Y,Y ; check y-coordinate + CMP YOFF + BNE :CHECK + LDA XOFF ; ensure that map x and map y + ORA YOFF ; are not both 0 (no monster) + BEQ :CHECK + LDA M_TYPE,Y ; get the monster type! + STY MAP_MNUM + RTS ; have mons type, so exit +:CHECK INY + CPY #MONSMAX + BLT :REPEAT +*------------------------------- +:NOMONS IMULW YOFF;#WMAP;PTR + ADDW PTR;MAPADDR;PTR + LDY XOFF + LDA (PTR),Y + RTS +MAP_MNUM HEX 00 + +******************************** +* Update Screen * +******************************** + +UPSCREEN MOVB X0;AX + MOVB Y0;AY + MOVB CX;X0 + MOVB CY;Y0 + MOVB CX;X1 + MOVB CY;Y1 + LDA #%10000000 + STA CLRFLAG + LDA #%00000000 + STA XORFLAG +:0 LDA Y0 + CMP #2 + BLT :1 + DEC Y0 + LDX CX + LDY Y0 + JSR MAPCHECK + BCC :0 +:1 LDA X0 + CMP #2 + BLT :2 + DEC X0 + LDX X0 + LDY CY + JSR MAPCHECK + BCC :1 +:2 LDA X1 + CMP #WMAP+1 + BGE :3 + INC X1 + LDX X1 + LDY CY + JSR MAPCHECK + BCC :2 +:3 LDA Y1 + CMP #HMAP+1 + BGE :4 + INC Y1 + LDX CX + LDY Y1 + JSR MAPCHECK + BCC :3 +:4 SEC + LDA Y1 + SBC Y0 + CMP #HSCREEN-1 + BLT :5 + SEC + LDA CY + SBC Y0 + STA TEMP0 + SEC + LDA Y1 + SBC CY + CMP TEMP0 + BLT :40 + DEC Y1 + JMP :4 +:40 INC Y0 + JMP :4 +:5 SEC + LDA X1 + SBC X0 + CMP #WSCREEN-1 + BLT :6 + SEC + LDA CX + SBC X0 + STA TEMP0 + SEC + LDA X1 + SBC CX + CMP TEMP0 + BLT :50 + DEC X1 + JMP :5 +:50 INC X0 + JMP :5 +:6 SUBB X1;X0;WX + SUBB Y1;Y0;WY + LDA WX + LSR + STA ZX + SEC + LDA #WSCREEN/2 + SBC ZX + STA ZX + LDA WY + LSR + STA ZY + SEC + LDA #HSCREEN/2 + SBC ZY + STA ZY + LDA OX + ORA OY + BPL :7 + MOVB ZX;OX + MOVB ZY;OY + JSR HCLEAR + JMP :8 +:7 LDA #%10000000 ; to erase old picture + STA XORFLAG ; of Meltok ... + LDA #%00000000 + STA CLRFLAG + MOVB #2;SNUM + LDA CH:X+1 ; Should be current location + LDX CH:X ; of Meltok on screen. + LDY CH:Y ; Including "sliding" movement. + JSR DRAWSHAP ; Draw it + LDA #%00000000 ; Clear reverse flag + STA XORFLAG ; Done. + LDA #%10000000 + STA CLRFLAG + SUBB AX;X0;DX + SUBB AY;Y0;DY + SUBB OX;DX;NX + SUBB OY;DY;NY +:70 LDA NX + BPL :71 + JSR HRIGHT + INC NX + JMP :70 +:71 LDA NY + BPL :72 + JSR HDOWN + INC NY + JMP :71 +:72 CLC + LDA NY + ADC WY + CMP #19 + BLT :73 + JSR HUP + DEC NY + JMP :72 +:73 CLC + LDA NX + ADC WX + CMP #24 + BLT :74 + JSR HLEFT + DEC NX + JMP :73 +:74 MOVB NX;ZX + MOVB NY;ZY + MOVB ZX;OX + MOVB ZY;OY +:8 MOVB Y0;TEMPY +:_NEXTY MOVB X0;TEMPX +:_NEXTX LDY TEMPY + LDX TEMPX + JSR MAPINDEX + CMP #15 ; show monsters too! + BLT :SHGOOD + CMP #98 + BNE :NEXTSH1 + LDA #1 + JMP :SHGOOD +:NEXTSH1 CMP #99 + BNE :NEXTSH2 + LDA #6 + JMP :SHGOOD +:NEXTSH2 CMP #97 + BNE :NEXTSH3 + LDA #4 + JMP :SHGOOD +:NEXTSH3 CMP #100 + BLT :NEXTSH4 + LDA #0 + JMP :SHGOOD +:NEXTSH4 CMP #22 ; barred door + BEQ :SHGOOD +:NEXTSH5 LDA #15 ; circle -- for errors +:SHGOOD STA SNUM + NILB XPLACE+1 + NILB YPLACE+1 + MOVB ZX;XPLACE + MOVB ZY;YPLACE + LDY #3 +:MUL8 ASL XPLACE + ROL XPLACE+1 + ASL YPLACE + ROL YPLACE+1 + DEY + BNE :MUL8 + LDA SNUM + CMP #12 + BLT :MOREYET + CMP #14+1 + BGE :MOREYET + LDY MAP_MNUM + LDA YPLACE + STA M_Y0,Y + LDA XPLACE + STA M_X0,Y + LDA XPLACE+1 + STA M_X1,Y +:MOREYET LDY YPLACE + LDX XPLACE + LDA XPLACE+1 + JSR DRAWSHAP + LDA TEMPX + CMP CX + BNE :99 + LDA TEMPY + CMP CY + BNE :99 + LDA #%00000000 + STA CLRFLAG + LDA #%10000000 + STA XORFLAG + MOVB #2;SNUM + LDY YPLACE + LDX XPLACE + LDA XPLACE+1 + JSR DRAWSHAP + MOVW XPLACE;CH:X + MOVW YPLACE;CH:Y + LDA #%00000000 + STA XORFLAG + LDA #%10000000 + STA CLRFLAG +:99 INC ZX + INC TEMPX + LDA TEMPX + CMP #WMAP + BEQ :9999 + BGE :100 +:9999 CMP X1 + BLT :NEXTX + BEQ :NEXTX +:100 SUBB ZX;WX;ZX + DEC ZX + INC ZY + INC TEMPY + LDA TEMPY + CMP #HMAP + BEQ :1111 + BGE :EXIT +:1111 CMP Y1 + BLT :NEXTY + BEQ :NEXTY + JMP :EXIT +:NEXTY JMP :_NEXTY +:NEXTX JMP :_NEXTX +:EXIT RTS + +******************************** +* Map Check verifies that the * +* check square is valid to * +* see through. * +******************************** +MAPSW HEX 00 +MAPCHECK LDA #$80 ; special switch to ignore the + STA MAPSW ; monsters! + JSR MAPINDEX ; get data + PHA ; save data + LDA #0 ; reset switch to normal + STA MAPSW ; ... + PLA ; restore data and work with it: + CMP #99 + BGE :GOOD + CMP #0 + BEQ :GOOD + CMP #6 + BLT :BAD + CMP #12 ; for monsters #12-#14 + BGE :BAD +:GOOD CLC + RTS +:BAD SEC + RTS + diff --git a/endgame.s b/endgame.s new file mode 100755 index 0000000..503de02 --- /dev/null +++ b/endgame.s @@ -0,0 +1,320 @@ +******************************** +* End Game routines: * +* death * +* and WINNING! * +******************************** + +* External routines + ; graphics.s +HGRCLEAR EXT +HADDR EXT +HADDR2 EXT +SETHGR EXT + ; input.output.s +PRSTR EXT +CBOT3 EXT +CLRSCRN EXT +TEXT EXT +TEXTADDR EXT +CSTRING EXT +CLRMID EXT +GETRET EXT + ; title.s +WAIT EXT + ; shapes.s +CLRFLAG EXT +XORFLAG EXT +SNUM EXT +DRAWSHAP EXT + ; noise.s +DONOISE EXT +DURATION EXT +FREQUENC EXT +VOLUME EXT + ; castles.s +SX EXT +SY EXT +EX EXT +EY EXT +DRAWLINE EXT +CASTLE1 EXT + +******************************** +* This is the death routine. * +******************************** +THEDEATH ENT + JSR HGRCLEAR + JSR GREENBCK + LDY #10 + JSR PAUSE + PRINT DEATH1 + JSR RAISTONE + LDY #15 + JSR PAUSE + PRINT DEATH2 + JSR DRAWRIP + LDY #10 + JSR PAUSE + JSR CBOT3 + RTS +DEATH1 HEX 825583 + ASC "... You're dead! ..."00 +DEATH2 HEX 825583 + ASC "All good things must"8D83 + ASC "come to and end!"00 + +******************************** +* Pause for a bit. * +******************************** +PAUSE LDA #255 + JSR WAIT + DEY + BNE PAUSE + RTS + +******************************** +* Do the green background for * +* death scene. * +******************************** +GREENBCK LDA #90 + STA HLINE + LDA #92 + STA HLINE2 +:LOOP JSR HADDR + JSR HADDR2 + BCS :ALLDONE + JSR GREEN12 + ADDB #4;HLINE;HLINE + ADDB #4;HLINE2;HLINE2 + LDA HLINE2 + CMP #159 + BLT :LOOP +:ALLDONE RTS + +******************************** +* Do two lines of green. * +******************************** +GREEN12 LDY #0 +:1 LDX #0 +:0 LDA GREEN1,X + STA (HPTR),Y + LDA GREEN2,X + STA (HPTR2),Y + INX + INY + CPX #8 + BLT :0 + CPY #40 + BLT :1 + RTS +GREEN1 HEX 204102050A142850 +GREEN2 HEX 0A14285020410205 + +******************************** +* Draw R. I. P. on gravestone. * +******************************** +DRAWRIP LDA #%00000000 ; prepare to draw R. I. P. + STA CLRFLAG + LDA #%10000000 + STA XORFLAG + MOVB #19;SNUM ; Draw "R" + LDY #100 + LDX #<115 + LDA #>115 + JSR DRAWSHAP + MOVB #16;SNUM ; Draw "." + LDY #103 + LDX #<121 + LDA #>121 + JSR DRAWSHAP + JSR DO_THUMP ; make noise + MOVB #20;SNUM ; Draw "I" + LDY #100 + LDX #<135 + LDA #>135 + JSR DRAWSHAP + MOVB #16;SNUM ; Draw "." + LDY #103 + LDX #<141 + LDA #>141 + JSR DRAWSHAP + JSR DO_THUMP ; make noise + MOVB #21;SNUM ; Draw "P" + LDY #100 + LDX #<155 + LDA #>155 + JSR DRAWSHAP + MOVB #16;SNUM ; Draw "." + LDY #103 + LDX #<159 + LDA #>159 + JSR DRAWSHAP + JSR DO_THUMP + RTS + +******************************** +* Make a thumping sound. * +******************************** +DO_THUMP LDY #35 ; make a sound similar to +:LOOP BIT SPEAKER ; typical "thump" + LDA #45 + JSR WAIT + DEY + BNE :LOOP + LDY #2 + LDA #255 ; pause for effect. + JSR WAIT + RTS + +******************************** +* Routine to raise gravestone * +* out of the ground. * +******************************** +RAISTONE LDY #140 +:LOOP STY :YSAVE + JSR DRAWSTON + MOVB #15;VOLUME + MOVB #1;DURATION + MOVB #150;FREQUENC + JSR DONOISE + LDY :YSAVE + DEY + CPY #70 + BGE :LOOP + RTS +:YSAVE HEX 00 + +******************************** +* Routine to draw gravestone * +* from Y to 140. * +******************************** +DRAWSTON STY SY ; set starting and + STY EY ; ending y positions + MOVB #0;:COUNTER ; init counter + LDX #3 + JSR HCOLOR ; HCOLOR=3 +:LOOP MOVW #104;SX ; default starting and + MOVW #174;EX ; ending x positions + LDA :COUNTER ; check counter + CMP #15 ; if < 15 then use data + BGE :DRAW ; if =>15 then use default + ASL ; multiply by 2 + TAY + LDA GRAVSTON,Y ; set endpoints + STA SX ; for hline + LDA GRAVSTON+1,Y + STA EX +:DRAW JSR DRAWLINE ; use drawline routine + BIT SPEAKER ; buzz + INC :COUNTER ; counter+= 1 + LDA :COUNTER ; exit early -- no need + CMP #16 ; to draw the WHOLE gravestone + BGE :EXIT ; again! + INC SY ; sy+= 1 + INC EY ; ey+= 1 + LDA SY ; check if y is still + CMP #141 ; < 141. + BLT :LOOP ; if y<141 then repeat +:EXIT RTS +:COUNTER HEX 00 ; used for offset in table + +******************************** +* Data for gravestone. * +******************************** +GRAVSTON DFB 128,150 ; for y=70 (final position) + DFB 123,155 ; y=71 + DFB 120,158 ; y=72 + DFB 118,160 ; y=73 + DFB 116,162 ; y=74 + DFB 114,164 ; y=75 + DFB 112,166 ; y=76 + DFB 111,167 ; y=77 + DFB 110,168 ; y=78 + DFB 108,170 ; y=79 + DFB 107,171 ; y=80 + DFB 107,171 ; y=81 + DFB 106,172 ; y=82 + DFB 105,173 ; y=83 + DFB 105,173 ; y=84 + +GAMEWON ENT + JSR CLRSCRN + JSR TEXT + LDA #11 + STA TLINE + JSR TEXTADDR + CENTER CONGRATS + JSR HGRCLEAR + JSR CASTLE1 + LDY #15 +:DELAY LDA #255 + JSR WAIT + DEY + BNE :DELAY + JSR CLRMID + JSR SETHGR + PRINT GAMEWIN1 + JSR GETRET + JSR CLRMID + PRINT GAMEWIN2 + JSR GETRET + JSR CLRMID + PRINT GAMEWIN3 + JSR GETRET + JSR CLRMID + JSR TEXT + PRINT GAMEWIN4 + JSR GETRET + JSR CLRMID + PRINT GAMEWIN5 + JSR GETRET + JSR CLRMID + JSR SETHGR + PRINT GAMEWIN6 + RTS + +CONGRATS ASC "Contragulations!!"00 +GAMEWIN1 HEX 54 + ASC "As you return from your successful"8D + ASC "journey to retrieve the Jewel of Kaldun,"8D + ASC "the kingdom stirs with renewed hope!"00 +GAMEWIN2 HEX 54 + ASC "The king, upon hearing of your return,"8D + ASC "prepares a royal reception in honor of"8D + ASC "the kingdoms hero."00 +GAMEWIN3 HEX 54 + ASC "However, throughout the whole affair,"8D + ASC "the king appears troubled. By what, you"8D + ASC "do know."00 +GAMEWIN4 HEX 43 + ASC "Later, while the two of you relax in the"8D + ASC "plush surroundings, you inquire why he"8D + ASC "looked troubled."8D + HEX 8D + ASC "'Alas,' he replies, 'the whole kingdom"8D + ASC "rejoices at your wonderful success."8D + ASC "However, my daughter is another matter."8D + ASC "You see, she is a particularly strong-"8D + ASC "willed woman. I'm afraid that she is"8D + ASC "too dear to me to force her into an un-"8D + ASC "wanted marriage. And, I also don't wish"8D + ASC "for you to be forced to marry.'"8D + HEX 8D + ASC "You breathe a sigh of relief, that is"8D + ASC "not really your style. You tell the"8D + ASC "king that you understand, and was think-"8D + ASC "ing the same thing."00 +GAMEWIN5 HEX 43 + ASC "The king answers, 'I like you kid, and"8D + ASC "you definately are good material. So,"8D + ASC "here is the deal: I will give you a"8D + ASC "dutchy.'"8D + HEX 8D + ASC "Wow, your own dutchy... now if you can"8D + ASC "just figure out that last comment. When"8D + ASC "you left, the king mumbled, 'For the"8D + ASC "sake of the kingdom, I hope I have done"8D + ASC "the right thing...'"00 +GAMEWIN6 HEX 54 + ASC "Stay tuned for part two!"00 + diff --git a/filing.s b/filing.s new file mode 100755 index 0000000..e6b1562 --- /dev/null +++ b/filing.s @@ -0,0 +1,85 @@ +******************************** +* Filer Module: Load and Save * +* game states. * +* Uses: PROLIB * +* PROLIB.MAC * +* IO * +* IO.MAC * +******************************** + +BUFFER = $BB00 +GAMEDATA = $1000 + +******************************** +* Loader: Loads a new game * +* or an old game. Selected by * +* the user. * +******************************** + +LOADER PRINT LOADSTR + MOVB #0;LOADSTAT + STA KEYSTROB +:AGAIN LDA KEYBOARD + BPL :AGAIN + STA KEYSTROB + CMP #"N" + BEQ :NEWGAME + CMP #"n" + BEQ :NEWGAME + CMP #"O" + BEQ :OLDGAME + CMP #"o" + BNE :AGAIN +:OLDGAME JSR CLINE + PRINT OLDSTR + MOVB #1;LOADSTAT + @OPEN #OLDNAME;#BUFFER;REFNUM + JMP :LOAD +:NEWGAME JSR CLINE + PRINT NEWSTR + @OPEN #NEWNAME;#BUFFER;REFNUM +:LOAD @READ REFNUM;#GAMEDATA;#$D3C + @CLOSE REFNUM + JSR CLINE + RTS + +LOADSTR HEX 5783 + ASC "Play New or Old game? (N/O)"00 +OLDSTR HEX 5783 + ASC "... Loading old game ..."00 +NEWSTR HEX 5783 + ASC "... Loading new game ..."00 +OLDNAME STR "OLDGAME" +NEWNAME STR "NEWGAME" +REFNUM HEX 00 +LOADSTAT HEX 00 + +******************************** +* Saves a game currently in * +* play. * +******************************** + +SAVER PRINT SAVESTR + JSR GETYN + BCC :YUP + JMP :NOPE +:YUP PRINT SAVESTR2 + @DESTROY #OLDNAME + CMP #0 ; no error? + BEQ :FINISH ; ok! + CMP #$46 ; file not found? + BEQ :FINISH ; ok! + JMP _MLICHK ; unknown error +:FINISH @CREATE #OLDNAME;#$C3;#$F6;#$1000;#$01 + @OPEN #OLDNAME;#BUFFER;REFNUM + @WRITE REFNUM;#GAMEDATA;#$D3C + @FLUSH REFNUM + @CLOSE REFNUM +:NOPE JSR CLINE + RTS + +SAVESTR HEX 5783 + ASC "Do you wish to save the game?"00 +SAVESTR2 HEX 825783 + ASC "... Saving: Please Wait ..."00 + diff --git a/general.mac.s b/general.mac.s new file mode 100755 index 0000000..c43000d --- /dev/null +++ b/general.mac.s @@ -0,0 +1,74 @@ +******************************** +* General Macros used by * +* Jewel of Kaldun source * +******************************** + +MOVB MAC + LDA ]1 + STA ]2 + EOM + +MOVW MAC + MOVB ]1;]2 + IF #=]1 + MOVB ]1/$100;]2+1 + ELSE + MOVB ]1+1;]2+1 + FIN + EOM + +NILB MAC + LDA #0 + STA ]1 + EOM + +NILW MAC + LDA #0 + STA ]1 + STA ]1+1 + EOM + +ADDB MAC + CLC + LDA ]1 + ADC ]2 + STA ]3 + EOM + +ADDW MAC + ADDB ]1;]2;]3 + IF #=]1 + LDA ]1/$100 + ELSE + LDA ]1+1 + FIN + IF #=]2 + ADC ]2/$100 + ELSE + ADC ]2+1 + FIN + STA ]3+1 + EOM + +SUBB MAC + SEC + LDA ]1 + SBC ]2 + STA ]3 + EOM + +SUBW MAC + SUBB ]1;]2;]3 + IF #=]1 + LDA ]1/$100 + ELSE + LDA ]1+1 + FIN + IF #=]2 + SBC ]2/$100 + ELSE + SBC ]2+1 + FIN + STA ]3+1 + EOM + diff --git a/graphics.s b/graphics.s new file mode 100755 index 0000000..8e3e90d --- /dev/null +++ b/graphics.s @@ -0,0 +1,473 @@ +******************************** +* High-Resolution Graphics * +* routines for Jewel of Kaldun * +* Uses: MATH * +******************************** + +SETHGR ENT + STA $C057 + STA $C053 + STA $C050 + RTS + +******************************** +* Turn on the hi-res screen * +* and clear it. * +******************************** + +HGR JSR SETHGR +HGRCLEAR ENT + LDA #191 + STA HLINE +:0 JSR HADDR + BCC :CONT + RTS +:CONT LDA #0 + LDY #39 +:1 STA (HPTR),Y + DEY + BPL :1 + DEC HLINE + JMP :0 + +******************************** +* Store Hi-Res Screen @ $4000. * +******************************** +HSTORE MOVW #$2000;HPTR + MOVW #$4000;HPTR2 +:YLOOP LDY #0 +:LOOP LDA (HPTR),Y + STA (HPTR2),Y + INY + BNE :LOOP + INC HPTR2+1 + INC HPTR+1 + LDA HPTR+1 + CMP #$40 + BLT :YLOOP + RTS + +******************************** +* Restore hires screen to 4000 * +******************************** +HRESTORE MOVW #$4000;HPTR + MOVW #$2000;HPTR2 +:YLOOP LDY #0 +:LOOP LDA (HPTR),Y + STA (HPTR2),Y + INY + BNE :LOOP + INC HPTR+1 + INC HPTR2+1 + LDA HPTR2+1 + CMP #$40 + BLT :YLOOP + RTS + +******************************** +* Clear the scrolling portion * +* of the hi-res screen. * +******************************** + +HCLEAR LDA #159 + STA HLINE +:1 JSR HADDR + BCS :END + LDY #28 + LDA #0 +:0 STA (HPTR),Y + DEY + BPL :0 + DEC HLINE + JMP :1 +:END RTS + +******************************** +* Scroll the hi-res screen to * +* the left two pixels. * +******************************** + +HLEFT LDA #159 + STA HLINE +:1 JSR HADDR + BCS :END + LDY #1 +:0 LDA (HPTR),Y + AND #%01111110 + LSR + STA TEMP + INY + LDA (HPTR),Y + AND #%00000001 + ASL + ASL + ASL + ASL + ASL + ASL + ORA TEMP + DEY + DEY + STA (HPTR),Y + INY + INY + CPY #28 + BLT :0 + LDY #28 + LDA (HPTR),Y + AND #%01111110 + LSR + DEY + STA (HPTR),Y + INY + LDA #0 + STA (HPTR),Y + DEC HLINE + JMP :1 +:END RTS + +******************************** +* Scroll the hi-res screen to * +* the right two pixels. * +******************************** + +HRIGHT LDA #159 + STA HLINE +:1 JSR HADDR + BCS :END + LDY #26 +:0 LDA (HPTR),Y + AND #%01000000 + LSR + LSR + LSR + LSR + LSR + LSR + STA TEMP + INY + LDA (HPTR),Y + AND #%00111111 + ASL + ORA TEMP + INY + STA (HPTR),Y + DEY + DEY + DEY + CPY #-1 + BNE :0 + LDY #0 + LDA (HPTR),Y + AND #%00111111 + ASL + INY + STA (HPTR),Y + DEY + TYA + STA (HPTR),Y + DEC HLINE + LDY #28 + LDA (HPTR),Y + AND #%00001111 ; chop off rightmost bits + STA (HPTR),Y + JMP :1 +:END RTS + +******************************** +* Scroll the hi-res screen up * +* two pixels. * +******************************** + +HUP LDA #0 + STA HLINE2 + LDA #8 + STA HLINE +:0 JSR HADDR2 + JSR HADDR + BCS :END + LDY #28 +:1 LDA (HPTR),Y + STA (HPTR2),Y + DEY + BPL :1 + INC HLINE2 + INC HLINE + JMP :0 +:END LDY #28 + LDA #0 +:2 STA (HPTR2),Y + DEY + BPL :2 + INC HLINE2 + JSR HADDR2 + BCC :END + RTS + +******************************** +* Scroll the hi-res screen * +* down two pixels. * +******************************** + +HDOWN LDA #159 + STA HLINE2 + LDA #151 + STA HLINE +:0 JSR HADDR2 + JSR HADDR + BCS :END + LDY #28 +:1 LDA (HPTR),Y + STA (HPTR2),Y + DEY + BPL :1 + DEC HLINE2 + DEC HLINE + JMP :0 +:END LDY #28 + LDA #0 +:2 STA (HPTR2),Y + DEY + BPL :2 + DEC HLINE2 + JSR HADDR2 + BCC :END + RTS + +******************************** +* This routine calculates the * +* hi-res address of line that * +* is stored in LINE via the * +* look-up tables. * +******************************** + +HADDR ENT + LDA HLINE + CMP #192 + BCS :END + TAY + LDA HLOW,Y + STA HPTR + LDA HHIGH,Y + STA HPTR+1 + CLC +:END RTS + +******************************** +* This routine calculates the * +* hi-res address of line that * +* is stored in LINE2 via the * +* look-up tables. * +******************************** + +HADDR2 ENT + LDA HLINE2 + CMP #192 + BCS :END + TAY + LDA HLOW,Y + STA HPTR2 + LDA HHIGH,Y + STA HPTR2+1 + CLC +:END RTS + +******************************** +* Low-order bytes of hi-res * +* row address: * +******************************** + +HLOW HEX 0000000000000000 + HEX 8080808080808080 + HEX 0000000000000000 + HEX 8080808080808080 + HEX 0000000000000000 + HEX 8080808080808080 + HEX 0000000000000000 + HEX 8080808080808080 + HEX 2828282828282828 + HEX A8A8A8A8A8A8A8A8 + HEX 2828282828282828 + HEX A8A8A8A8A8A8A8A8 + HEX 2828282828282828 + HEX A8A8A8A8A8A8A8A8 + HEX 2828282828282828 + HEX A8A8A8A8A8A8A8A8 + HEX 5050505050505050 + HEX D0D0D0D0D0D0D0D0 + HEX 5050505050505050 + HEX D0D0D0D0D0D0D0D0 + HEX 5050505050505050 + HEX D0D0D0D0D0D0D0D0 + HEX 5050505050505050 + HEX D0D0D0D0D0D0D0D0 + +******************************** +* High-order bytes of hi-res * +* row address: * +******************************** + +HHIGH HEX 2024282C3034383C + HEX 2024282C3034383C + HEX 2125292D3135393D + HEX 2125292D3135393D + HEX 22262A2E32363A3E + HEX 22262A2E32363A3E + HEX 23272B2F33373B3F + HEX 23272B2F33373B3F + HEX 2024282C3034383C + HEX 2024282C3034383C + HEX 2125292D3135393D + HEX 2125292D3135393D + HEX 22262A2E32363A3E + HEX 22262A2E32363A3E + HEX 23272B2F33373B3F + HEX 23272B2F33373B3F + HEX 2024282C3034383C + HEX 2024282C3034383C + HEX 2125292D3135393D + HEX 2125292D3135393D + HEX 22262A2E32363A3E + HEX 22262A2E32363A3E + HEX 23272B2F33373B3F + HEX 23272B2F33373B3F + +******************************** +* Graphically displays the * +* amount of Gold Pieces * +* character has. * +******************************** + +STATUSGP LDY #38 + LDA GP+1 + BNE LOTAGOLD + LDA #160 + SEC + SBC GP + BCS STATUS +LOTAGOLD LDA #0 +STATUS STA TEMP + STY YTEMP + LDA #160 + STA HLINE +:1 JSR HADDR + BCS :EXIT + LDY YTEMP + LDA COLORS-29,Y + STA (HPTR),Y + INY + LDA COLORS-29,Y + STA (HPTR),Y + DEC HLINE + LDA HLINE + CMP TEMP + BGE :1 +:3 JSR HADDR + BCC :2 +:EXIT RTS +:2 LDA #0 + LDY YTEMP + STA (HPTR),Y + INY + STA (HPTR),Y + DEC HLINE + JMP :3 + +******************************** +* The colors associated with * +* the various statuses. * +******************************** + +COLORS HEX D5AA00552A00 + HEX AAD5002A55 + +******************************** +* Graphically displays the * +* status of your keys. * +******************************** + +STATUSKY LDY #29 + LDX KEY + LDA SPKEY + BEQ :0 + INX +:0 LDA #160 +:1 CPX #0 + BEQ :DONE + SEC + SBC #10 + DEX + CMP #0 + BNE :1 +:DONE JMP STATUS + +******************************** +* Graphically display the * +* percent of hitpoints * +* remaining. * +******************************** + +STATUSHP LDA #0 + STA NUM1+1 + STA NUM2+1 + LDA #160 + STA NUM1 + LDA HP + STA NUM2 + JSR IMUL + LDA RESULT + STA NUM1 + LDA RESULT+1 + STA NUM1+1 + LDA #0 + STA NUM2+1 + LDA MAXHP + STA NUM2 + JSR IDIV + SEC + LDA #160 + SBC RESULT + BCS :0 + LDA #0 +:0 LDY #32 + JMP STATUS + +******************************** +* Graphically display the * +* percent of experience * +* points required. * +******************************** +* problems occur here because when the player needs more +* than (or equal amount of) 800 XP, multiplied number +* grows larger than the 16 bit number allows (65,536)! + +* Old routine: [[ (XP * 160) / XPREQD = graphics X ]] +* MOVW XP;NUM1 +* MOVW #160;NUM2 +* JSR IMUL +* MOVW RESULT;NUM1 +* MOVW XPREQD;NUM2 +* JSR IDIV + +* New routine: [[ ( (1600/XPREQD) * (XP/10) ) ]] +* it's not quite as accurate, but at least the graphics bar +* will work for the higher levels! + +STATUSXP MOVW #1600;NUM1 + MOVW XPREQD;NUM2 + JSR IDIV ; RESULT = 1600 / XPREQD + MOVW RESULT;NUM1 + MOVW XP;NUM2 + JSR IMUL ; RESULT = RESULT * XP + MOVW RESULT;NUM1 + MOVW #10;NUM2 + JSR IDIV ; RESULT = RESULT / 10 + LDA RESULT+1 + BNE :1 + LDA RESULT + CMP #160 + BLT :0 +:1 LDA #0 +:0 LDY #35 + JMP STATUS + diff --git a/input.output.s b/input.output.s new file mode 100755 index 0000000..4988b48 --- /dev/null +++ b/input.output.s @@ -0,0 +1,335 @@ +******************************** +* Input/Output Routines * +* Uses: IO.MAC * +******************************** + +* External references + ; jewel.of.kaldun.s +DATA EXT + +******************************** +* Turn on text screen. * +******************************** + +TEXT ENT + STA $C056 + STA $C054 + STA $C051 + RTS + +******************************** +* Routine to pause for RETURN * +* to be pressed. * +******************************** + +GETRET ENT + LDA #23 + STA TLINE + JSR TEXTADDR + LDA ESCABORT + BMI :ESCCR + CENTER GRSTR + JMP :XXX +:ESCCR MOVB #0;TTAB + PRINT ESCCRSTR +:XXX JSR M:GETKEY + BIT ESCABORT + BPL :YYY + CMP #$9B ; ESCAPE + BEQ :EXIT +:YYY CMP #$8D ; RETURN + BNE :XXX +:EXIT LDA #23 + STA TLINE + JSR TEXTADDR + LDA KEYBOARD + CMP #$9B + BNE :LEAVE + PLA ; CLEAR STACK OF ADDRESS + PLA +:LEAVE LDA #%00000000 + STA ESCABORT + STA KEYSTROB ; clear keypress + JMP CLINE +ESCABORT HEX 00 +GRSTR ASC "Press to continue"00 +ESCCRSTR ASC " to continue or to stop"00 + +******************************** +* Routine to wait for a Y or * +* a N. * +******************************** + +GETYN JSR M:GETKEY + CMP #"Y" + BEQ :YES + CMP #"y" + BEQ :YES + CMP #"n" + BEQ :NO + CMP #"N" + BNE GETYN +:NO SEC + RTS +:YES CLC + RTS + +******************************** +* Routine to center a string. * +******************************** + +CSTRING ENT + LDY #0 +:0 LDA (DATA),Y + BEQ :FINISH + CMP #$8D + BEQ :FINISH + INY + BNE :0 +:FINISH TYA + LSR + STA TEMP + SEC + LDA #20 + SBC TEMP + STA TTAB + JSR PRSTR + +******************************** +* Print a carriage return. * +******************************** + +PRCR INC TLINE + JSR TEXTADDR + LDY #0 + STY TTAB + LDA TLINE + CMP #24 + BCC END1 + STY TLINE +END1 RTS + +******************************** +* The following routine(s) * +* handle printing with special * +* control characters: * +* * +* ^I ($89) Inverse mode * +* ^N ($8E) Normal mode * +* ^M ($8D) Carriage Return * +* ^@ ($80) Print Hex number * +* that is stored * +* at the pointer * +* location in Dec. * +* ^A ($81) Print Hex WORD * +* that is stored * +* at the pointer * +* location in Dec. * +* ^B ($82) To clear bottom * +* 3 lines. * +* ^C ($83) To center the * +* following line * +* of text on scrn. * +* %00xxxxxx Htab + 1 * +* %01xxxxxx Vtab * +* * +* All other characters lower * +* than a SPACE ($A0) are * +* ignored. * +******************************** + +* MASK byte and PTR increment routine: + +MASK HEX FF +DATAINC INC DATA + BNE END2 + INC DATA+1 +END2 RTS + +* This is the Print routine: + +PRSTR ENT + LDY #0 + LDA (DATA),Y + BEQ END2 + BMI :0 + CMP #%00111111 + BGE :VTAB + STA TTAB + DEC TTAB +:NEXT JSR DATAINC + JMP PRSTR +:VTAB AND #%00111111 +:V0 STA TLINE + JSR TEXTADDR + BCC :NEXT + LDA #0 + BEQ :V0 +:0 CMP #$89 + BNE :1 + LDA #%00111111 +:MASK STA MASK + BNE :NEXT +:1 CMP #$8E + BNE :2 + LDA #%11111111 + BNE :MASK +:2 CMP #$8D + BNE :3 +:NEWLINE JSR PRCR + JMP :NEXT +:3 CMP #$80 + BNE :4 + JSR DATAINC + LDA (DATA),Y + STA PTR + JSR DATAINC + LDA (DATA),Y + STA PTR+1 + JSR CONVERT + JMP :NEXT +:4 CMP #$83 + BNE :5 + LDY #1 ; pass #$83 +:40 LDA (DATA),Y + CMP #$A0 + BLT :41 + INY + BNE :40 +:41 TYA + LSR + STA TEMP + SEC + LDA #20 + SBC TEMP + STA TTAB + JMP :NEXT +:5 CMP #$82 + BNE :6 + JSR CBOT3 + JMP :NEXT +:6 CMP #$81 + BNE :7 + JSR DATAINC + LDA (DATA),Y + STA PTR + JSR DATAINC + LDA (DATA),Y + STA PTR+1 + JSR CONVWORD + JMP :NEXT +:7 CMP #$A0 + BLT :NEXTPTR + BIT AUTOCAPS + BPL :GO + JSR CHARCAPS ; capitalize letter +:GO LDY TTAB + AND MASK + STA (TPTR),Y + STA SPEAKER + INY + STY TTAB + CPY #40 + BLT :NEXTPTR + LDY #0 + STY TTAB +:NEXTPTR JMP :NEXT +AUTOCAPS HEX 00 ; default: Mixed mode + +******************************** +* CLINE clears the current * +* line pointed to by TPTR. * +******************************** + +CLINE LDY #40 + LDA #$A0 +:0 STA (TPTR),Y + DEY + BPL :0 + RTS + +******************************** +* CLRMID clears middle portion * +* of text screen. Lines 1-22. * +* (line 0 = vtab 1) * +******************************** + +CLRMID ENT + LDA #22 + STA TLINE +:0 JSR TEXTADDR + JSR CLINE + DEC TLINE + BNE :0 + RTS + +******************************** +* CBOT3 clears the bottom * +* three (3) lines of the text * +* screen. * +******************************** + +CBOT3 ENT + LDA #21 + BNE CLRSCRN0 + +******************************** +* Clears the text screen. * +******************************** + +CLRSCRN ENT + LDA #0 +CLRSCRN0 STA TLINE +:0 JSR TEXTADDR + BCS END0 + JSR CLINE + INC TLINE + JMP :0 + +******************************** +* TEXTADDR uses the lookup * +* tables to find the address * +* of the line number stored in * +* TLINE. * +******************************** + +TEXTADDR ENT + LDA TLINE + CMP #24 + BGE END0 + TAY + LDA TEXTLOW,Y + STA TPTR + LDA TEXTHIGH,Y + STA TPTR+1 + CLC +END0 RTS + +******************************** +* The lookup tables for the * +* text screen: * +******************************** + +TEXTLOW HEX 0080008000800080 + HEX 28A828A828A828A8 + HEX 50D050D050D050D0 +TEXTHIGH HEX 0404050506060707 + HEX 0404050506060707 + HEX 0404050506060707 + +******************************** +* Sets inverse status line and * +* clears last three lines of * +* text screen. * +******************************** + +STATLINE PRINT STATTEXT + JSR CBOT3 + LDA #21 + STA TLINE + JSR TEXTADDR + RTS +STATTEXT HEX 015489 ; htab 1:vtab 21:inverse + ASC " KY HP XP GP" + HEX 8E00 ; normal + diff --git a/io.mac.s b/io.mac.s new file mode 100755 index 0000000..d6d3dbb --- /dev/null +++ b/io.mac.s @@ -0,0 +1,26 @@ +* External references + ; jewel.of.kaldun.s +DATA EXT + ; input.output.s +PRSTR EXT + +******************************** +* Input/Output Macros * +******************************** + +PRINT MAC + LDA #<]1 + STA DATA + LDA #>]1 + STA DATA+1 + JSR PRSTR + EOM + +CENTER MAC + LDA #<]1 + STA DATA + LDA #>]1 + STA DATA+1 + JSR CSTRING + EOM + diff --git a/jewel.end.game.s b/jewel.end.game.s new file mode 100755 index 0000000..c1409df --- /dev/null +++ b/jewel.end.game.s @@ -0,0 +1,68 @@ +******************************** +* * +* Jewel of Kaldun * +* * +* written by * +* https://github.com/a2geek * +* * +* story by * +* https://github.com/bshagle * +* * +* Copyright (c) 1990,2016 * +* * +******************************** + +* Code location: + + ORG $0800 + +* Add in macro files: + + USE jok-includes.inc + PAG + USE io.mac + PAG + USE general.mac + PAG + USE prolib.mac + PAG + +* Memory map: +* __________ +* | | $FFFF +* | ProDOS | to ProDOS/ROM +* |__________| $BF00 +* | | $BEFF +* | J.O.K. | to Main program +* |__________| $6000 +* | | $5FFF +* | HGR P2 | to Copy of title page +* |__________| $4000 +* | | $3FFF +* | HGR P1 | to Graphics display +* |__________| $2000 +* | | $1FFF +* | Map/Stat | to Map & Stats (to $1Cxx) +* |__________| $1000 +* | | $0FFF +* --> | J.O.K. | to JOK End Game routines +* |__________| $0800 Reset routines +* | | $07FF +* | TextPage | to Text page +* |__________| $0400 +* | | $03FF Free ($0200-$03CF) +* | Zp & St | to System Stack ($0100-$01FF) +* |__________| $0000 Zero Page ($0000-$00FF) + + +* Save file name: + + DSK JEWEL.END.GAME.bin + + PAG +* End Game Routines + + PUT endgame + PAG + PUT reset + diff --git a/jewel.of.kaldun.s b/jewel.of.kaldun.s new file mode 100755 index 0000000..dfbed3d --- /dev/null +++ b/jewel.of.kaldun.s @@ -0,0 +1,428 @@ +******************************** +* * +* Jewel of Kaldun * +* (primary application segment)* +* * +* written by * +* https://github.com/a2geek * +* * +* story by * +* https://github.com/bshagle * +* * +* Copyright (c) 1990,2016 * +* * +******************************** + +* Code location: + + ORG $6000 + +* External references: + ; reset.s +RESETUP EXT +RESTORE EXT + ; endgame.s +THEDEATH EXT + ; graphics.s +HGRCLEAR EXT + +* Memory map: +* __________ +* | | $FFFF +* | ProDOS | to ProDOS/ROM +* |__________| $BF00 +* | | $BEFF +* --> | J.O.K. | to Main program +* |__________| $6000 +* | | $5FFF +* | HGR P2 | to Copy of title page +* |__________| $4000 +* | | $3FFF +* | HGR P1 | to Graphics display +* |__________| $2000 +* | | $1FFF +* | Map/Stat | to Map & Stats (to $1Cxx) +* |__________| $1000 +* | | $0FFF +* | J.O.K. | to JOK End Game routines +* |__________| $0800 Reset routines +* | | $07FF +* | TextPage | to Text page +* |__________| $0400 +* | | $03FF Free ($0200-$03CF) +* | Zp & St | to System Stack ($0100-$01FF) +* |__________| $0000 Zero Page ($0000-$00FF) +* + +* Save file name: + + DSK JEWEL.OF.KALDUN.bin + +* Add in macro files: + + USE jok-includes.inc + PAG + USE io.mac + PAG + USE general.mac + PAG + USE math.mac + PAG + USE prolib.mac + PAG + +RETURN = $8D ; ASCII for (high bit on) +ESCAPE = $9B ; ASCII for ( " " " ) + +LEVEL1 = $1000 +LEVEL2 = $1600 + +******************************** +* Jewel Of Kaldun, main file: * +******************************** + + JSR RESETUP + LDA #$20 ; page 1 of Hires... + STA 230 + JSR INIT ; initialize screens, etc. + JSR CLRSCRN + JSR CHEKCASE + JSR HGRCLEAR + JSR TITLEPG ; draw title page + JSR WALLFADE ; fade in wall + JSR HSTORE ; store hi-res page @ $4000 +MAIN ENT + JSR HRESTORE ; restore hi-res page + JSR SCPREP + JSR SETHGR ; ensure that hi-res is on + JSR SCROLL + CMP #RETURN + BEQ :PLAYGAM + CMP #"Q" + BEQ :BYEQUIT + CMP #"q" + BEQ :BYEQUIT + CMP #"I" + BEQ :INSTR + CMP #"i" + BNE MAIN +:INSTR JSR TEXT + JSR STORY + JMP MAIN +:BYEQUIT JSR DOQUIT + JMP MAIN +:PLAYGAM JSR LOADER + JSR HGRCLEAR + JSR CLRSCRN + LDA LOADSTAT + CMP #1 + BEQ :RESTART + JSR MONSINIT ; clear out monsters + MOVW #0;GP + MOVW #0;XP + MOVW #100;XPREQD + MOVB #0;KEY + MOVB #0;SPKEY + MOVB #10;HP + MOVB #10;MAXHP + MOVB #1;CLEVEL + MOVB #25;CX + MOVB #32;CY + MOVB #-1;OX + MOVB #-1;OY + MOVB #-1;X0 + MOVB #-1;Y0 + MOVW #LEVEL1;MAPADDR +:RESTART JSR STATLINE + JSR STATUSGP + JSR STATUSKY + JSR STATUSHP + JSR STATUSXP +:UPDATE JSR UPSCREEN +:GOING JSR CHKLEVEL + JSR CTRLLOOP + PHA ; save exit code + JSR MOVMONST + PLA ; and restore it + JSR CHKLIFE + BEQ :GOING + CMP #-1 + BNE :UPDATE + JSR CBOT3 + JSR GETRET + JMP MAIN + +******************************** +* Check if user can handle * +* lower case letters. * +******************************** +CHEKCASE LDX #%00000000 ; default: Mixed mode + LDA MACHID + AND #%11001000 ; Keep ID bits + BEQ :CHECK ; Have an Apple II + CMP #%01000000 ; Check for an Apple II+ + BNE :OKAY ; Nope. +:CHECK PRINT CASEMSG ; ask if user can view in + JSR GETYN ; lower case + BCC :OKAY + LDX #%10000000 +:OKAY STX AUTOCAPS ; adjust for user. + RTS +CASEMSG HEX 4A83 + ASC "DO YOU HAVE LOWERCASE?"8D83 + ASC "(Y/N)"00 + +******************************** +* Check if player wishes to * +* quit. * +******************************** +DOQUIT ENT + PRINT QUITMSG + JSR GETYN + BCC :QUITJOK + JSR CBOT3 + RTS + +:QUITJOK LDY #0 ; copy quit-code +:QLOOP LDA BEGQUIT,Y ; to $200 + STA $200,Y + INY + CPY #ENDQUIT-BEGQUIT+1 + BLT :QLOOP + LDY #0 ; restore +:MLOOP LDA RESTORE,Y ; old reset vector + STA $3F2,Y + INY + CPY #3 + BLT :MLOOP + JMP $200+$7 ; skip quit code +BEGQUIT DFB 4 ; quit code + DFB 0 + DW 0000 + DFB 0 + DW 0000 + + MOVW #$400;PTR ; clear memory + LDA #0 ; from $400 to + LDY #0 ; $BEFF +:LOOP STA (PTR),Y + INY + BNE :LOOP + STA SPEAKER + INC PTR+1 + LDA PTR+1 + CMP #$BF + BLT :LOOP + JSR $FB2F ; text.. + JSR $FC58 ; clear screen + LDA #"S" ; print "SMILE!" + STA $400 ; the hard way... + LDA #"M" + STA $401 + LDA #"I" + STA $402 + LDA #"L" + STA $403 + LDA #"E" + STA $404 + LDA #"!" + STA $405 + LDY #20 ; pause +:PAUSE LDA #255 + JSR $FCA8 + DEY + BNE :PAUSE + JSR $BF00 ; quit. + DFB $65 + DW $200 + HEX 00 +ENDQUIT +QUITMSG HEX 5783 + ASC "Do you wish to exit?"00 + +******************************** +* Check to see if Meltok is * +* still alive! * +******************************** +CHKLIFE PHA + LDA HP ; check hp + BEQ :DEATH ; if hp=0, dead + CMP MAXHP ; check against max + BLT :ALIVE ; if hpxpreq'd, go up level! +:NOINCR RTS +:CHECKLO LDA XP ; check lo byte of xp + CMP XPREQD ; against xpreq'd + BLT :NOINCR ; if xp100 + STA XPREQD+1 + LDA #10 + STA HP + STA MAXHP + LDA #1 + STA CLEVEL + RTS + +******************************** +* Variables for Jewel of * +* Kaldun, all are external: * +* GP: Gold Pieces * +* XP: Experience * +* XPREQD: Experience required* +* KEY: Number of keys * +* SPKEY: Special key flag * +* HP: Hit Points * +* MAXHP: Maximum HP * +* CLEVEL: Character level * +******************************** + +GP = $1C00 +XP = $1C02 +XPREQD = $1C04 +KEY = $1C06 +SPKEY = $1C07 +HP = $1C08 +MAXHP = $1C09 +CLEVEL = $1C0A +CX = $1C0B +CY = $1C0C +XOFF = $1C0D +YOFF = $1C0F +MAPADDR = $1C11 +OX = $1C13 +OY = $1C14 +DX = $1C15 +DY = $1C16 +AX = $1C17 +AY = $1C18 +X0 = $1C19 +Y0 = $1C1A +X1 = $1C1B +Y1 = $1C1C +TEMP0 = $1C1D +WX = $1C1E +WY = $1C1F +ZX = $1C20 +ZY = $1C21 +TEMPX = $1C22 +TEMPY = $1C23 +XPLACE = $1C24 +YPLACE = $1C26 +NX = $1C28 +NY = $1C29 +CH:X = $1C2A +CH:Y = $1C2C + +* Monster variables: + +MONSMAX = 30 +M_HP = $1C2E +M_TYPE = $1C4C +M_X = $1C6A +M_Y = $1C88 +M_MOVE = $1CA6 +M_X0 = $1CC4 +M_X1 = $1CE2 +M_Y0 = $1D00 +M_LEVEL = $1D1E + +* Add in all routines: + + PAG + PUT input.output + PAG + PUT convert + PAG + PUT graphics + PAG + PUT math + PAG + PUT castles + PAG + PUT shapes + PAG + PUT title + PAG + PUT prolib + PAG + PUT filing + PAG + PUT places + PAG + PUT noise + PAG + PUT display + PAG + PUT monsters + PAG + PUT main.control + PAG + PUT story + diff --git a/jok-includes.inc b/jok-includes.inc new file mode 100755 index 0000000..b7a76cb --- /dev/null +++ b/jok-includes.inc @@ -0,0 +1,35 @@ +* ZP Equates: + +TLINE EQU $00 ; address of text screen line +TPTR EQU $01 ; line number of current text +TTAB EQU $03 ; index for text screen (HTAB) +TEMP EQU $04 ; temporary storage +DATA EQU $05 ; data address +PTR EQU $07 ; an extra pointer... +HPTR EQU $09 ; address of hi-res line +HPTR2 EQU $0B ; address of 2ndary hi-res line +HLINE EQU $0D ; current hi-res line number +HLINE2 EQU $0F ; secondary hi-res line number +YTEMP EQU $10 ; temporary storage for Y reg. +XTEMP EQU $11 ; temporary storage for X reg. + +* ProDOS locations: + +MACHID EQU $BF98 ; machine ID in ProDOS global pg + +* I/O locations: + +KEYBOARD EQU $C000 ; address for keyboard input +KEYSTROB EQU $C010 ; clears current keypress +SPEAKER EQU $C030 ; to click the speaker: noise + +* AppleSoft locations: + +HCOLOR = $F6F0 +HPLOTTO = $F53A +HPOSN = $F411 + +* ROM locations: + +MONWAIT EQU $FCA8 ; monitor wait routine (Acc.) + diff --git a/jok.segments.s b/jok.segments.s new file mode 100755 index 0000000..3be6c2a --- /dev/null +++ b/jok.segments.s @@ -0,0 +1,20 @@ +*--------------------------* +* SEGMENTS * +*--------------------------* + + TYP $06 ; Binary File / Fixed Address + +*-------------------------- +* Segment #1 +*-------------------------- + + ASM jewel.of.kaldun.s ; Master Source File for Segment #1 + +*-------------------------- +* Segment #2 +*-------------------------- + + ASM jewel.end.game.s ; Master Source File for Segment #2 + +*-------------------------- + diff --git a/jok.system.s b/jok.system.s index 5a6cd2a..35499a0 100755 --- a/jok.system.s +++ b/jok.system.s @@ -5,8 +5,6 @@ TYP $FF ; system program ORG $2000 ; they originate @ $2000 - EXP OFF ; macro expansion - TR ON ; truncate * General Macros -- @@ -108,8 +106,9 @@ TIT_LEN EQU $2000 ; Length of Title (full screen) STA $BF6F * Load in Title: @OPEN #TIT_NAME;#TIT_BUFF;REFNUM - BCS :HELPERR ; can't quite make it. - @READ REFNUM;#TIT_ADDR;#TIT_LEN + BCC :OK_TITLE + JMP LOADERRT +:OK_TITLE @READ REFNUM;#TIT_ADDR;#TIT_LEN @CLOSE REFNUM * Print version of Loader: LDY #19 @@ -121,37 +120,56 @@ TIT_LEN EQU $2000 ; Length of Title (full screen) JSR CHECKSUM * Load in JOK: @OPEN #JOK_NAME;#JOK_BUFF;REFNUM -:HELPERR BCS :HELPER2 - @READ REFNUM;#JOK_ADDR;#JOK_LEN + BCC :OK_JOK + JMP LOADERRJ +:OK_JOK @READ REFNUM;#JOK_ADDR;#JOK_LEN @CLOSE REFNUM * Load in JOK end game: @OPEN #JOK2NAME;#JOK2BUFF;REFNUM -:HELPER2 BCS LOADERR2 + BCS LOADERRE @READ REFNUM;#JOK2ADDR;#JOK2LEN @CLOSE REFNUM * Check Checksum: (A0E647) LDA SUM+2 CMP #$A0 - BNE DATACORR + BNE :DATACORR LDA SUM+1 CMP #$E6 BNE DATACORR LDA SUM CMP #$47 - BNE DATACORR +:DATACORR BNE DATACORR * Start JOK: JMP JOK_ADDR ; begin game! -LOADERR LDY #40 -:LOOP LDA ERRORMSG-1,Y - STA LINE24-1,Y - DEY - BNE :LOOP - BEQ ERRORXX -LOADERR2 LDY #40 -:LOOP2 LDA ERRORMS2-1,Y +LOADERRT LDA #>TIT_NAME + LDY #JOK_NAME + LDY #JOK2NAME + LDY # in the text... + PLA + STA PTR + PLA + STA PTR+1 + LDY #0 + LDA (PTR),Y ; length byte + TAX +:LOOP2 INY + LDA (PTR),Y + STA LINE24+7,Y + DEX BNE :LOOP2 ERRORXX JSR $FF3A ; bell FOREVER LDA #<$0200 ; sets $03F0 (BRK address) to @@ -190,8 +208,7 @@ DATACORR LDY #28 JSR $FF3A ; bell JMP FOREVER -ERRORMSG ASC "ERROR: JEWEL.OF.KALDUN IS UNACCESSABLE!" -ERRORMS2 ASC "ERROR: JEWEL.END.GAME IS UNACCESSABLE!" +ERRORMSG ASC "ERROR: IS UNACCESSABLE!" JOK2NAME STR "JEWEL.END.GAME" JOK_NAME STR "JEWEL.OF.KALDUN" TIT_NAME STR "JEWEL.TITLE.PIC" diff --git a/main.control.s b/main.control.s new file mode 100755 index 0000000..42f54e1 --- /dev/null +++ b/main.control.s @@ -0,0 +1,1067 @@ +* External references + ; endgame.s +GAMEWON EXT + ; jewel.of.kaldun.s +DATA EXT + +******************************** +* Main Control Loop * +******************************** +CTRLLOOP STA KEYSTROB + MOVB #2;SNUM + LDA #%00000000 + STA DRAWFLAG + LDX CX + LDY CY + JSR MAPINDEX + CMP #3 + BEQ :SETFLAG + CMP #5 + BNE :KEYLOOP +:SETFLAG LDA #%10000000 + STA DRAWFLAG +:KEYLOOP JSR M:GETKEY + PHA + JSR MONCHECK ; check for new monsters + JSR CBOT3 + PLA + CMP #ESCAPE + BNE :CHKKEY + JSR GAMEDONE + JMP :KEYLOOP +:CHKKEY JSR CHARCAPS +:CONT CMP #"I" + BEQ :_UP + CMP #"M" + BEQ :_DOWN + CMP #"J" + BEQ :_LEFT + CMP #"K" + BEQ :_RIGHT + CMP #"F" + BEQ :_FIGHT + CMP #"$" + BEQ :_SAVE + CMP #"O" + BEQ :_OPENCH + CMP #"U" + BEQ :_UNLOCK + CMP #"R" + BEQ :_REST + CMP #"S" + BEQ :_SEARCH + CMP #"H" + BEQ :_HEALTH + CMP #"W" + BEQ :_WEALTH + CMP #"A" + BEQ :_ASCEND + CMP #"D" + BEQ :_DESCEN + CMP #"L" + BEQ :_LOOK + CMP #"T" + BEQ :_TAKE + CMP #"?" + BEQ :_HELP + JSR CBOT3 + JMP :KEYLOOP +:_UP JMP M:UP ; command table +:_DOWN JMP M:DOWN +:_LEFT JMP M:LEFT +:_RIGHT JMP M:RIGHT +:_FIGHT JMP M:FIGHT +:_SAVE JMP SAVER +:_OPENCH JMP M:OPENCH +:_UNLOCK JMP M:UNLOCK +:_SEARCH JMP M:SEARCH +:_HEALTH JMP M:HEALTH +:_WEALTH JMP M:WEALTH +:_REST JMP M:REST +:_ASCEND JMP M:ASCEND +:_DESCEN JMP M:DESCEN +:_LOOK JMP M:LOOK +:_TAKE JMP M:TAKE +:_HELP JMP M:HELP + +******************************** +* Gets a key, keeping counters * +* randomizing. * +******************************** +M:GETKEY STA KEYSTROB +:REPEAT INC RANDOM1 + BNE :MORE + INC RANDOM2 + BNE :MORE + INC RANDOM3 +:MORE LDA KEYBOARD + BPL :REPEAT + RTS +RANDOM1 HEX 00 +RANDOM2 HEX 00 +RANDOM3 HEX 00 + +******************************** +* Capitalizes character stored * +* in Accumulator. * +******************************** +CHARCAPS CMP #"a" ; compare to "a" + BLT :CONT ; if Acc < "a" then exit + CMP #"z"+1 ; compare to "z"+1 + BGE :CONT ; if Acc => "z"+1, exit + SEC + SBC #"a"-"A" ; capitalize char +:CONT RTS + +******************************** +* Get direction to do an act. * +******************************** +DIR:X HEX 00 ; direction to go X +DIR:Y HEX 00 ; direction to go Y +M:GETDIR JSR M:GETKEY ; get a keypress + JSR CHARCAPS ; capitalize key + LDX #0 + LDY #-1 + CMP #"I" + BEQ :FOUND + LDY #1 + CMP #"M" + BEQ :FOUND + LDY #0 + LDX #-1 + CMP #"J" + BEQ :FOUND + LDX #1 + CMP #"K" + BNE M:GETDIR +:FOUND STX DIR:X ; exits with X, Y + STY DIR:Y ; and Acc relating to call. + RTS + +******************************** +* Print a help screen. * +******************************** +M:HELP STA $C051 ; switch to text + JSR CLRSCRN ; clear the text screen + PRINT HELPMSG + JSR GETRET ; wait for a RETURN. + JSR CLRSCRN + STA $C050 ; switch to graphics + JSR STATLINE ; re-print status line + LDA #0 + RTS +HELPMSG HEX 4083 + ASC "<< Help >>"8D + ASC "Key Description"8D + ASC "--------- ----------------------------"8D + ASC "? Display this help screen."8D + ASC "$ Saves current game to disk."8D + ASC "A,D Tell Meltok to Ascend or"8D + ASC " Descend a ladder."8D + ASC "L,T,U Look, Take, or Unlock. Use"8D + ASC " direction keys to point."8D + ASC "O Open a chest that Meltok is"8D + ASC " standing over."8D + ASC "H,W,R Health, Wealth, or Rest."8D + ASC " Displays Meltoks' condition."8D + ASC " Rest heals Meltok by one HP."8D + ASC "F Fight monster, use dir keys."8D8D83 + ASC "<< DIRECTION KEYS >>"8D83 + ASC "(north)"8D83 + ASC "I"8D83 + ASC "(west) J K (east)"8D83 + ASC "M"8D83 + ASC "(south)"00 + +******************************** +* Fight a monster. * +******************************** +M:FIGHT PRINT FIGHTMSG + JSR M:GETDIR ; get direction offsets + ADDB CX;DIR:X;DIR:X + ADDB CY;DIR:Y;DIR:Y + LDX DIR:X + LDY DIR:Y + JSR MAPINDEX + CMP #12 + BNE :NEXT01 + JMP :AGHOST +:NEXT01 CMP #13 + BNE :NEXT02 + JMP :ABLOB +:NEXT02 CMP #14 + BNE :NEXT03 + JMP :AZOMBIE +:NEXT03 CMP #100 + BNE :NEXT04 + JMP :BLANK +:NEXT04 CMP #1 + BNE :NEXT05 + JMP :WALL +:NEXT05 CMP #3 + BNE :NEXT06 + JMP :DOOR +:NEXT06 CMP #4 + BNE :NEXT07 + JMP :DOOR +:NEXT07 CMP #5 + BNE :NEXT08 + JMP :DOOR +:NEXT08 CMP #6 + BNE :NEXT09 + JMP :CHEST +:NEXT09 CMP #7 + BNE :NEXT10 + JMP :CHEST +:NEXT10 CMP #8 + BNE :NEXT11 + JMP :LADDER +:NEXT11 CMP #9 + BNE :NEXT12 + JMP :THRONE +:NEXT12 CMP #10 + BNE :NEXT13 + JMP :JEWEL +:NEXT13 CMP #11 + BNE :NEXT14 + JMP :HOLDER +:NEXT14 CMP #98 + BNE :NEXT15 + JMP :WALL +:NEXT15 CMP #99 + BNE :NEXT16 + JMP :CHEST +:NEXT16 PRINT FIGHTHUH + LDA #0 + RTS +:AGHOST LDA CLEVEL ; auto hit at lvl > 6 + CMP #7 + BGE :HITIT + LDA RANDOM1 + AND #%00000011 ; 1 in 4 chance of hitting + BEQ :HITIT ; a ghost +:MISSED PRINT FIGHTMIS + LDA #0 + RTS +:ABLOB LDA CLEVEL ; automatic hit at lvl > 2 + CMP #3 + BGE :HITIT + LDA RANDOM1 + AND #%00000001 ; 50% chance of a blob + BEQ :HITIT + BNE :MISSED +:AZOMBIE LDA CLEVEL ; auto hit at lvl > 4 + CMP #5 + BGE :HITIT + LDA RANDOM1 + AND #%00000001 ; 50% chance of a zombie + BNE :MISSED +:HITIT PRINT FIGHTHIT + JSR MONSBUZZ + JSR MONSHIT + LDA #0 + RTS +:BLANK PRINT FIGHTBLA + LDA #0 + RTS +:WALL PRINT FIGHTWAL + LDA #0 + RTS +:DOOR PRINT FIGHTDOO + LDA #0 + RTS +:CHEST PRINT FIGHTCHE + LDA #255 ; smashed chest +:DISAPPR PHA + LDX DIR:X + LDY DIR:Y + JSR MAPINDEX + PLA + STA (PTR),Y + JSR UPSCREEN + LDA #0 + RTS +:LADDER PRINT FIGHTLAD + LDA #254 ; smashed ladder + JMP :DISAPPR +:THRONE PRINT FIGHTTHR + JSR GOTDAMAG + LDA #0 + RTS +:JEWEL PRINT FIGHTJE1 + LDY #5 +:WAIT1 LDA #0 + JSR WAIT + DEY + BNE :WAIT1 + JSR GOTDAMAG + LDA #0 ; and erase all HP's! + STA HP + JSR STATUSHP + PRINT FIGHTJE2 + LDY #5 +:WAIT2 LDA #0 + JSR WAIT + DEY + BNE :WAIT2 + LDA #0 + RTS +:HOLDER PRINT FIGHTHOL + LDA #0 + RTS +MONSBUZZ MOVB #15;SNUM + LDA #%00000000 + STA CLRFLAG + LDA #%10000000 + STA XORFLAG + MOVB #4;HITCOUNT +:BUZZER LDY MAP_MNUM + LDA M_X0,Y + TAX + LDA M_X1,Y + PHA + LDA M_Y0,Y + TAY + PLA + JSR DRAWSHAP + MOVB #20;VOLUME + MOVB #150;DURATION + MOVB #$80;FREQUENC + JSR DONOISE + DEC HITCOUNT + BNE :BUZZER + LDA #0 + STA XORFLAG + RTS +TEMP:X HEX 00 +TEMP:Y HEX 00 +FIGHTMSG HEX 825683 + ASC "Fight which monster?" + HEX 00 +FIGHTHUH HEX 825683 + ASC "huh?" + HEX 00 +FIGHTBLA HEX 825683 + ASC "Swish..." + HEX 00 +FIGHTWAL HEX 825683 + ASC "You give the wall a sound beating." + HEX 00 +FIGHTDOO HEX 825683 + ASC "Thwop! A few nicks appear in the door." + HEX 00 +FIGHTCHE HEX 825683 + ASC "Thwump! The chest breaks into"8D83 + ASC "splinters!" + HEX 00 +FIGHTLAD HEX 825683 + ASC "Whoops! Now you've destroyed the"8D83 + ASC "ladder... better control your anger!" + HEX 00 +FIGHTTHR HEX 825683 + ASC "You hurt your hands as the blade"8D83 + ASC "bounces off of the throne." + HEX 00 +FIGHTJE1 HEX 825683 + ASC "Oops. Now you've done it!" + HEX 00 +FIGHTJE2 HEX 825683 + ASC "The Jewel explodes!" + HEX 00 +FIGHTHOL HEX 825683 + ASC "Why?" + HEX 00 +FIGHTMIS HEX 825683 + ASC "You missed it!" + HEX 00 +FIGHTHIT HEX 825683 + ASC "You hit the monster!" + HEX 00 + +******************************** +* Take some object. * +******************************** +M:TAKE PRINT TAKEMSG + JSR M:GETDIR ; get direction offsets + ADDB CX;DIR:X;DIR:X + ADDB CY;DIR:Y;DIR:Y + LDX DIR:X + LDY DIR:Y + JSR MAPINDEX + CMP #10 ; check for JOK + BNE :NOWAY + LDA #11 ; place empty holder + STA (PTR),Y + LDA #$80 ; mark "special key" variable + STA SPKEY ; with $80 for have Jewel + PRINT GOTJEWEL + MOVW #LEVEL1;MAPADDR ; placing @ level 1 + LDX #1 ; place main gate with a wall... + LDY #30 ; @(24,30) - (26,30) + JSR MAPINDEX ; trick to get address.. + LDY #23 ; (x=24,25,26) set for x-1... + LDA #22 ; a wall -- + STA (PTR),Y ; across + INY ; all + STA (PTR),Y ; of the + INY ; main + STA (PTR),Y ; gate!! No way out! + MOVW #LEVEL2;MAPADDR ; return to level 2 + JSR UPSCREEN ; update screen at new location + MOVB #29;CY ; place Meltok in another + MOVB #4;CX ; position. + MOVB #-1;OX ; tell display routine + MOVB #-1;OY ; that the screen must + MOVB #-1;X0 ; be erased and redrawn + MOVB #-1;Y0 + LDY #15 +:PAUSE LDA #255 + JSR WAIT ; pause a bit + DEY + BNE :PAUSE + PRINT TELEPORT + JSR UPSCREEN ; surprise!! + LDA #0 + RTS +:NOWAY PRINT NOTEQUIP + RTS +TAKEMSG HEX 825683 + ASC "What do you wish to take?"00 +NOTEQUIP HEX 825683 + ASC "I regret to inform you that you are"8D83 + ASC "not equipped to take that!!"00 +GOTJEWEL HEX 825683 + ASC "As you pick up the Jewel, you realize"8D83 + ASC "that there is probably some trap!"00 +TELEPORT HEX 825683 + ASC "Alas, you were right. You have been"8D83 + ASC "teleported elsewhere in the castle!"00 + +******************************** +* Look in some direction. * +******************************** +M:LOOK PRINT LOOKMSG + JSR M:GETDIR ; get direction offsets + ADDB CX;DIR:X;DIR:X ; modify current x + ADDB CY;DIR:Y;DIR:Y ; and y + LDX DIR:X + LDY DIR:Y + JSR MAPINDEX ; get index at that location. + CMP #98 ; check for secret door + BNE :CONT255 ; if it is one, make it a + LDA #1 ; wall. +:CONT255 CMP #255 ; check if it is a smashed + BNE :CONT254 ; chest (#255) + PRINT SEE255 + LDA #0 + RTS +:CONT254 CMP #254 ; check if it is a smashed + BNE :CONT ; ladder (#254) + PRINT SEE254 + LDA #0 + RTS +:CONT CMP #99 ; check for special chest + BNE :CONT2 ; if it is one, do some + PRINT SEE99 ; special handling. + LDA #0 + RTS +:CONT2 CMP #22 ; barred door + BNE :CONT3 + PRINT SEE22 ; special handling + LDA #0 + RTS +:CONT3 CMP #97 ; check if special door + BNE :MORE + LDA #4 ; make special door "locked" +:MORE CMP #15 ; no shapes => #15 + BLT :DOLOOK ; this handles room desc. + LDA #0 ; fake it - blank space! +:DOLOOK PHA + JSR CBOT3 ; clear botton 3 lines + LDA #22 ; set vtab @ 22. + STA TLINE + JSR TEXTADDR + PLA + ASL ; multiply shape # by 2 + TAY + LDA SEETABLE,Y ; get address of message + STA DATA ; and prepare for center + INY ; routine + LDA SEETABLE,Y + STA DATA+1 + JSR CSTRING ; center string... + LDA #0 + RTS +SEETABLE DA SEE00,SEE01,SEE02,SEE03,SEE04,SEE05 + DA SEE06,SEE07,SEE08,SEE09,SEE10,SEE11 + DA SEE12,SEE13,SEE14 +SEE00 ASC "The empty air confounds you."00 +SEE01 ASC "The wall appears very solid."00 +SEE02 ASC "Huh? That's yourself!"00 +SEE03 ASC "This door is standing wide open."00 +SEE04 ASC "The door appears to be locked..."00 +SEE05 ASC "Remember? You found the secret door!"00 +SEE06 ASC "The chest might contain something!"00 +SEE07 ASC "You glance at an empty chest."00 +SEE08 ASC "That is a ladder."00 +SEE09 ASC "You see an ornate throne."00 +SEE10 ASC "That is the Jewel of Kaldun!!"00 +SEE11 ASC "It appears to be an empty holder..."00 +SEE12 ASC "You barely see the outline of a ghost."00 +SEE13 ASC "You see a blob creeping up on you!"00 +SEE14 ASC "Watch out! That is a zombie!"00 +SEE22 HEX 825683 + ASC "The door is barred. No way out!?"00 +SEE99 HEX 825683 + ASC "This chest has arcane symbols written"8D83 + ASC "all over. It may be dangerous!"00 +SEE254 HEX 825683 + ASC "Whoa, that ladder is ruined!"00 +SEE255 HEX 825683 + ASC "Wow, you really smashed this chest."00 +LOOKMSG HEX 825683 + ASC "Look in which direction?"00 + +******************************** +* Ascend a ladder. * +******************************** +M:ASCEND LDX CX + LDY CY + JSR MAPINDEX ; get attr @ (x,y) + CMP #8 ; is it a ladder? + BNE :NOGO ; nope -- can't do. + LDA #>LEVEL1 ; check if on first + CMP MAPADDR+1 ; level... + BNE :CANT ; cant ascend! + PRINT DOASCEND + MOVW #LEVEL2;MAPADDR ; point to 2nd level + MOVB #-1;OX ; notify update routine + MOVB #-1;OY ; that the screen must + MOVB #-1;X0 ; be cleared first. + MOVB #-1;Y0 + LDA #1 ; ensure game is continued, + RTS ; and map is updated +:CANT PRINT NOASCEND + RTS +:NOGO PRINT NOLADDER + RTS +DOASCEND HEX 825683 + ASC "Climbing up the ladder..."00 +NOLADDER HEX 825683 + ASC "Meltok looks around and fails to"8D83 + ASC "find a ladder that is near him!"00 +NOASCEND HEX 825683 + ASC "You are already on the second level!"00 + +******************************** +* Allow Meltok to descend a * +* ladder. * +******************************** +M:DESCEN LDX CX + LDY CY + JSR MAPINDEX ; get attr @ (x,y) + CMP #8 ; is it a ladder? + BNE :NOGO ; nope -- need a ladder + LDA #>LEVEL2 ; check to see if we are + CMP MAPADDR+1 ; on the second level. + BNE :CANT ; nope -- can't descend. + PRINT DODESCEN ; print message + MOVW #LEVEL1;MAPADDR ; update pointer + MOVB #-1;OX ; notify display routine + MOVB #-1;OY ; that we need to clear + MOVB #-1;X0 ; the screen, since we are + MOVB #-1;Y0 ; on a new map! + LDA #1 ; ensure that game is continued, + RTS ; and map is updated. +:CANT PRINT NODESCEN ; can't descend this ladder. + RTS +:NOGO PRINT NOLADDER ; ain't no ladder 'round, bud! + RTS +DODESCEN HEX 825683 + ASC "Climbing down the ladder..."00 +NODESCEN HEX 825683 + ASC "You are already on the first level!"00 + +******************************** +* Allows Meltok to rest: one * +* hit point is healed. * +******************************** +M:REST PRINT RESTING ; print message + INC HP ; add 1 to hp + LDA MAXHP + CMP HP ; compare maxhp w/ hp + BGE :OK ; if maxhp => hp, ok + STA HP ; not ok. hp= maxhp. +:OK JSR STATUSHP ; update hit points + LDA #0 + RTS +RESTING HEX 825683 + ASC "Meltok is resting."00 + +******************************** +* Health routine: displays * +* Meltok's health status. * +* Incl. HP/Max HP * +* XP/Max XP * +* Character Level * +******************************** +M:HEALTH PRINT CHHEALTH + RTS +CHHEALTH HEX 825501 + ASC "Meltok has: "80 + DA HP + ASC "/"80 + DA MAXHP + ASC " Hit Points"8D0E81 + DA XP + ASC "/"81 + DA XPREQD + ASC " Exp. Points"8D0E + ASC "(Level "80 + DA CLEVEL + ASC ".)"00 + +******************************** +* Wealth routine: displays * +* Meltok's wealth. * +* Incl. GP and Keys * +******************************** +M:WEALTH PRINT CHWEALTH + LDA SPKEY + CMP #1 + BNE :CJEWEL + PRINT CHSPKEY +:EXIT LDA #0 + RTS +:CJEWEL CMP #$80 + BNE :EXIT + PRINT CHJEWEL + JMP :EXIT +CHWEALTH HEX 825501 + ASC "Meltok has: "81 + DA GP + ASC " Gold Pieces"8D0D + ASC " and "80 + DA KEY + ASC " keys"00 +CHSPKEY HEX 570E + ASC "and a very ornate key!"00 +CHJEWEL HEX 570E + ASC "and the Jewel of Kaldun!"00 + +******************************** +* Search for a secret door. * +******************************** +M:SEARCH PRINT SEARCHDI ; get direction of search + JSR M:GETDIR + ADDB CX;DIR:X;DIR:X ; add directions to char + ADDB CY;DIR:Y;DIR:Y ; locations + LDX DIR:X + LDY DIR:Y + JSR MAPINDEX ; get value @ (x,y) + CMP #98 ; check for secret door + BNE :NOGOOD ; no door there + LDA #5 ; place found secret door + STA (PTR),Y ; @ (x,y) + JSR UPSCREEN + PRINT SECFOUND + RTS +:NOGOOD PRINT SECLOST + RTS +SECFOUND HEX 825683 + ASC "You have found a secret door!"00 +SECLOST HEX 825683 + ASC "You don't find anything of interest."00 +SEARCHDI HEX 825683 + ASC "Search in which direction?"00 + +******************************** +* Unlock a door. Checks to * +* see that user has a key, and * +* that a locked door is * +* present in direction choosen.* +******************************** +M:UNLOCK LDA KEY + CLC + ADC SPKEY + CMP #1 ; do we have 1 or more keys? + BLT :NOKEYS ; nope, error! + PRINT UNLOCKDI ; get direction + JSR M:GETDIR + ADDB CX;DIR:X;DIR:X ; add directions to char + ADDB CY;DIR:Y;DIR:Y ; locations. + LDX DIR:X + LDY DIR:Y + JSR MAPINDEX ; get the index + CMP #97 ; # for special door + BEQ :SPECIAL ; yes, special door + CMP #3 ; # for opened door + BEQ :OPENED ; door already opened. + CMP #4 ; # for locked door + BNE :NODOOR ; locked door not there. + LDA KEY ; check if we have normal keys + BNE :NORMAL ; we have a normal door + BEQ :NOCANDO ; no normal keys! +:SPECIAL LDA SPKEY + BEQ :NOCANDO ; w/o special key, no go + LDA #0 + STA SPKEY ; kill special key, make it + INC KEY ; a "normal" key... +:NORMAL LDA #3 + STA (PTR),Y ; place opened door... + DEC KEY ; get rid of used key + JSR UPSCREEN ; update screen + JSR STATUSKY ; update key graph + PRINT UNLOCKGD + RTS ; all done +:NOKEYS PRINT UNLOCKNO + RTS +:NODOOR PRINT UNLOCKBD + RTS +:OPENED PRINT OPENDOOR + RTS +:NOCANDO PRINT OPENPROB + RTS +UNLOCKDI HEX 825683 + ASC "Unlock door in which direction?"00 +UNLOCKGD HEX 825683 + ASC "The door is unlocked!"00 +UNLOCKNO HEX 825683 + ASC "You have no keys to unlock a door!"00 +UNLOCKBD HEX 825683 + ASC "There is no door there!"00 +OPENDOOR HEX 825683 + ASC "The door is already unlocked!"00 +OPENPROB HEX 825683 + ASC "None of your keys fit this door!"00 + +******************************** +* Opens a chest. Checks for * +* presence of a chest @ cx,cy * +* and then uses random numbers * +* 1-3 to open, amount of gold, * +* and if a key is found. * +******************************** +SPECHEST LDA CLEVEL + CMP #2 ; must be level 2 or higher!! + BLT :NOLUCK + LDA RANDOM1 + AND #%00001111 ; 0-16, 0 opens = 6.25% chance + BNE :NOLUCK + LDA #7 + STA (PTR),Y + LDA #1 ; add special key to + STA SPKEY ; inventory + LDA RANDOM2 + AND #%00001111 ; 0-15 damage! + STA OPENTMP3 + ADDW #250;XP;XP ; +250 experience! + SUBB HP;OPENTMP3;HP + JSR UPSCREEN + JSR STATUSXP + JSR STATUSHP + JSR STATUSKY + PRINT G_ORNATE ; got ornate! + LDA OPENTMP3 ; check if dart hit. + BEQ :EXIT ; nope: lucky! + PRINT CDARTHIT +:EXIT JSR GETRET + JSR CBOT3 + RTS +:NOLUCK PRINT OPENNO + RTS +M:SPEC JMP SPECHEST ; too far to branch! +M:OPENCH LDX CX + LDY CY + JSR MAPINDEX + CMP #7 ; ID # for opened chest + BEQ :ISOPEN + CMP #99 + BEQ M:SPEC + CMP #6 ; ID # for a chest + BNE :NOCHEST + LDA RANDOM1 + AND #%00000111 ; 0-7, 0 opens = 12.5% chance + BNE :BADLUCK + LDA #7 ; ID # for opened chest. + STA (PTR),Y ; store it. + LDA RANDOM2 + AND #%00011111 ; 0-31 GP found + STA OPENTMP1 + ADDW OPENTMP1;GP;GP + ADDW OPENTMP1;XP;XP + LDA RANDOM3 + AND #%00000001 ; 0-1 KEYs found + STA OPENTMP2 + ADDB OPENTMP2;KEY;KEY + JSR UPSCREEN ; Show our opened chest. + JSR STATUSKY ; update keys + JSR STATUSGP ; update gp + JSR STATUSXP ; update exp + LDA OPENTMP2 ; check if key found + BNE :PLUSKEY ; yes -- say so, w/ gold + BEQ :GOTGOLD ; no -- just tell of gold +:ISOPEN PRINT CHOPENED + RTS +:NOCHEST PRINT OPENBAD + RTS +:BADLUCK PRINT OPENNO + RTS +:GOTGOLD PRINT OPEN0KEY ; just got gp +:CHKDART LDA RANDOM1 ; check for dart hit. + EOR RANDOM2 ; randomize from 3 random + EOR RANDOM3 ; counters + AND #%00000011 ; damage, if any from dart. + BEQ :WHEW ; missed. + STA OPENTMP3 + SUBB HP;OPENTMP3;HP ; subtract damage + JSR STATUSHP ; update hit points + PRINT CDARTHIT +:WHEW RTS +:PLUSKEY PRINT OPEN1KEY ; gp + key + JMP :CHKDART ; go and check for dart hit +CHOPENED HEX 825583 + ASC "The chest is already open!"00 +OPENBAD HEX 825583 + ASC "I see no chest here!"00 +OPEN1KEY HEX 825503 + ASC "You find "80 + DA OPENTMP1 + ASC " Gold Pieces and a Key!"00 +OPEN0KEY HEX 825508 + ASC "You find "80 + DA OPENTMP1 + ASC " Gold Pieces!"00 +OPENNO HEX 825583 + ASC "You had no luck!" + HEX 5783 + ASC "(Try try again.)"00 +G_ORNATE HEX 825583 + ASC "You've found a very ornate key!"00 +CDARTHIT HEX 5602 + ASC "and are hit by a dart for "80 + DA OPENTMP3 + ASC " damage!"00 +OPENTMP1 HEX 0000 ; made a word for addition +OPENTMP2 HEX 00 ; tmp1=gp/xp, tmp2=keys +OPENTMP3 HEX 00 ; this is damage from dart. + +******************************** +* Ask player if they want to * +* exit the game. * +******************************** +GAMEDONE STY :YSAVE + STX :XSAVE + STA :ASAVE + PRINT EXITQUES + JSR GETYN + BCS :NO + PLA ; pull return address off + PLA ; of stack + LDA #-1 ; -1 = kill game + RTS ; return to main routine. +:NO LDA :ASAVE + LDY :YSAVE + LDX :XSAVE + RTS +:YSAVE HEX 00 +:XSAVE HEX 00 +:ASAVE HEX 00 +EXITQUES HEX 825683 + ASC "Do you wish to exit this game?"8D83 + ASC "(Y/N)"00 + +******************************** +* Allow Meltok to move upwards * +* Check for any obstacles... * +******************************** +M:UP DEC CY + LDX CX + LDY CY + BNE :CONT + JSR GAMEWON ; game winning routine + INC CY + LDA #-1 + RTS +:CONT JSR MAPVALID + BCS :ABORT + LDX #0 + LDY #-2 + JMP MOVEMENT +:ABORT INC CY +M:OWIE CMP #12 + BEQ M:GHOST + CMP #13 + BEQ M:BLOB + CMP #14 + BEQ M:ZOMBIE + PRINT WALLOUCH +GOTHIT01 DEC HP + JSR STATUSHP + LDA #0 + RTS +M:GHOST PRINT GHOSOUCH +GOTDAMAG MOVB #15;SNUM + LDA #%00000000 + STA CLRFLAG + LDA #%10000000 + STA XORFLAG + MOVB #4;HITCOUNT +:BUZZER LDY CH:Y + LDX CH:X + LDA #0 + JSR DRAWSHAP + MOVB #20;VOLUME + MOVB #150;DURATION + MOVB #$80;FREQUENC + JSR DONOISE + DEC HITCOUNT + BNE :BUZZER + LDA #0 + STA XORFLAG + JMP GOTHIT01 +HITCOUNT HEX 00 +M:BLOB PRINT BLOBOUCH + JMP GOTDAMAG +M:ZOMBIE PRINT ZOMBOUCH + JMP GOTDAMAG +WALLOUCH HEX 825683 + ASC "Ouch!!"00 +GHOSOUCH HEX 825683 + ASC "Yiiee! The ghost gotcha!"00 +BLOBOUCH HEX 825683 + ASC "Squish, the blob squirts you!"00 +ZOMBOUCH HEX 825683 + ASC "Ooomph, the zombie hits you!"00 + +******************************** +* Allow Meltok to move south. * +******************************** +M:DOWN INC CY + LDX CX + LDY CY + CPY #HMAP+1 + BLT :CONT + JSR GAMEDONE + DEC CY + LDA #0 + RTS +:CONT JSR MAPVALID + BCS :ABORT + LDX #0 + LDY #2 + BNE MOVEMENT +:ABORT DEC CY + JMP M:OWIE + +******************************** +* Allow Meltok to move west.. * +******************************** +M:LEFT DEC CX + LDX CX + LDY CY + JSR MAPVALID + BCS :ABORT + LDX #-2 + LDY #0 + BEQ MOVEMENT +:ABORT INC CX + JMP M:OWIE + +******************************** +* Allow Meltok to move East. * +******************************** +M:RIGHT INC CX + LDX CX + LDY CY + JSR MAPVALID + BCS :ABORT + LDX #2 + LDY #0 + BEQ MOVEMENT +:ABORT DEC CX + JMP M:OWIE + +******************************** +* Movement variables * +******************************** +M:DIRX HEX 00 +M:DIRY HEX 00 +M:COUNT HEX 00 + +******************************** +* Movement routines: Draw * +* Meltok moving, and update * +* the map. * +******************************** +MOVEMENT STX M:DIRX + STY M:DIRY + JSR ROOMDESC ; display room description + MOVB #4;M:COUNT + MOVB #2;SNUM + LDA #%00000000 + STA CLRFLAG + LDA #%10000000 + STA XORFLAG +:REPEAT LDY CH:Y + LDX CH:X + LDA #0 ; CH:X should not exceed 255 + JSR DRAWSHAP + ADDB M:DIRY;CH:Y;CH:Y + ADDB M:DIRX;CH:X;CH:X + LDY CH:Y + LDX CH:X + LDA #0 + JSR DRAWSHAP + LDA #25 + JSR WAIT + DEC M:COUNT + BNE :REPEAT + LDA #%00000000 + STA XORFLAG + LDA #%10000000 + STA CLRFLAG + LDA CX + CMP X0 + BEQ :REDRAW + CMP X1 + BEQ :REDRAW + LDA CY + CMP Y0 + BEQ :REDRAW + CMP Y1 + BEQ :REDRAW + LDA DRAWFLAG + BMI :REDRAW + LDA #0 + RTS +:REDRAW LDA #1 + RTS +DRAWFLAG HEX 00 + +******************************** +* Check to see if location at * +* (x,y) is a valid walking * +* location for Meltok. If so, * +* carry bit is clear. If not, * +* carry bit is on. * +******************************** +MAPVALID CPY #HMAP + BGE :BAD + CPX #WMAP + BGE :BAD + JSR MAPINDEX + BEQ :GOOD + CMP #99 + BGE :GOOD + CMP #3 + BEQ :GOOD + CMP #5 + BLT :BAD + CMP #12 + BGE :BAD +:GOOD CLC + RTS +:BAD SEC + RTS + diff --git a/math.mac.s b/math.mac.s new file mode 100755 index 0000000..f53c1e9 --- /dev/null +++ b/math.mac.s @@ -0,0 +1,34 @@ +******************************** +* Math macros used by Jewel of * +* Kaldun source: * +* Uses: * +* GENERAL.MAC * +* MATH * +******************************** + +IMULW MAC + MOVW ]1;NUM1 + MOVW ]2;NUM2 + JSR IMUL + MOVW RESULT;]3 + EOM + +IDIVW MAC + MOVW ]1;NUM1 + MOVW ]2;NUM2 + JSR IDIV + MOVW RESULT;]3 + EOM + +IMODW MAC + MOVW ]1;NUM1 + MOVW ]2;NUM2 + JSR IDIV + MOVW NUM1;]3 + EOM + +IDIVMODW MAC + IDIVW ]1;]2;]3 + MOVW NUM1;]4 + EOM + diff --git a/math.s b/math.s new file mode 100755 index 0000000..cb93cc5 --- /dev/null +++ b/math.s @@ -0,0 +1,126 @@ +******************************** +* Mathematical routines used * +* by Jewel of Kaldun * +******************************** + + +******************************** +* Integer division routine. * +* NUM0 = routine scratch * +* space * +* NUM1 = numerator * +* NUM2 = denominator * +* RESULT = quotient * +* remainder is in NUM1 after * +* completion of division. * +******************************** + +IDIV LDA #0 + STA RESULT + STA RESULT+1 + LDA NUM2 + ORA NUM2+1 + BNE :PREP + SEC + RTS +:PREP LDX #0 + LDA NUM2 + STA NUM0 + LDA NUM2+1 + STA NUM0+1 +:99 ASL NUM0 + ROL NUM0+1 + BCS :GO + INX + JMP :99 +:GO LDA NUM2 + STA NUM0 + LDA NUM2+1 + STA NUM0+1 + TXA + TAY + BEQ :SKIP +:0 ASL NUM0 + ROL NUM0+1 + DEY + BNE :0 +:SKIP LDA NUM0+1 + CMP NUM1+1 + BEQ :1 + BGE :CONT + BLT :2 +:1 LDA NUM0 + CMP NUM1 + BEQ :2 + BGE :CONT +:2 SEC + LDA NUM1 + SBC NUM0 + STA NUM1 + LDA NUM1+1 + SBC NUM0+1 + STA NUM1+1 + LDA #0 + STA NUM0+1 + LDA #1 + STA NUM0 + TXA + TAY + BEQ :11 +:10 ASL NUM0 + ROL NUM0+1 + DEY + BNE :10 +:11 CLC + LDA RESULT + ADC NUM0 + STA RESULT + LDA RESULT+1 + ADC NUM0+1 + STA RESULT+1 +:CONT DEX + BPL :GO + CLC + RTS + +******************************** +* Integer multiplication * +* routine: * +* NUM1 = one number * +* NUM2 = second number * +* RESULT = answer to NUM1xNUM2 * +******************************** + +IMUL LDA #0 + STA RESULT + STA RESULT+1 +:MORE LDA NUM2 + BNE :GO + LDA NUM2+1 + BNE :GO + RTS +:GO LSR NUM2+1 + ROR NUM2 + BCC :SHIFT + CLC + LDA NUM1 + ADC RESULT + STA RESULT + LDA NUM1+1 + ADC RESULT+1 + STA RESULT+1 +:SHIFT ASL NUM1 + ROL NUM1+1 + JMP :MORE + +******************************** +* Variables used by the * +* integer multiplication and * +* division routines: * +******************************** + +NUM0 HEX 0000 +NUM1 HEX 0000 +NUM2 HEX 0000 +RESULT HEX 0000 + diff --git a/monsters.s b/monsters.s new file mode 100755 index 0000000..47e1c62 --- /dev/null +++ b/monsters.s @@ -0,0 +1,390 @@ +******************************** +* Monster Routines: * +******************************** + +* Init Monster variables: +MONSINIT LDY #0 ; zero out all monster + LDA #0 ; data. +:FINISH STA M_HP,Y + STA M_TYPE,Y + STA M_X,Y + STA M_Y,Y + STA M_MOVE,Y + STA M_X0,Y + STA M_X1,Y + STA M_Y0,Y + INY + CPY #MONSMAX + BLT :FINISH + RTS + +******************************** +* Check to see if another * +* monster has appeared. * +******************************** +MONCHECK LDA RANDOM2 + EOR RANDOM3 ; 1 in 16 chance of appearing: + AND #%00001111 ; check if monster is + BNE :NOMONS0 ; appearing this time + LDY #0 +:CONT LDA M_HP,Y ; find space in monster + STY CURMONST ; list. + BEQ :FOUND + INY + CPY #MONSMAX + BLT :CONT +:NOMONS0 JMP _NOMONST ; no space in list. +:FOUND LDA RANDOM1 + EOR RANDOM3 + AND #%00011111 ; y location (max = 32) + STA CURMON_Y + INC CURMON_Y + LDA RANDOM2 + AND #%00011111 ; 1st part of x (gives 0-32) + STA CURMON_X ; map is 32 + 16 = 48. + INC CURMON_X + LDA RANDOM3 + AND #%00001111 ; 2nd part of x (gives 0-15) + CLC + ADC CURMON_X + STA CURMON_X + CMP #WMAP ; ensure that map does not + BGE :NOMONS0 ; exceed X coordinate max + LDA CURMON_Y + CMP #HMAP ; ensure that map does not + BGE :NOMONS0 ; exceed Y coordinate max + LDX #>LEVEL1 + LDA RANDOM1 + EOR RANDOM2 + EOR RANDOM3 + AND #%00000001 + BEQ :ATLVL1 +:ATLVL2 LDX #>LEVEL2 +:ATLVL1 STX CURMON_L +*------------------------------- + JSR MONMOVCK ; check if good locale + BCC :GOODLOC + JMP _NOMONST ; bad location +*------------------------------- +:GOODLOC LDY CURMONST + LDA RANDOM1 ; randomize + EOR RANDOM2 + EOR RANDOM3 + AND #%00000111 + CMP #2 + BLT :GHOST + CMP #4 + BLT :ZOMBIE +:BLOB LDA #2 + STA M_HP,Y + LDA #4 + STA M_MOVE,Y + LDA #13 + BNE :FINISH ; always +:GHOST LDA #8 + STA M_HP,Y + LDA #2 + STA M_MOVE,Y + LDA #12 + BNE :FINISH ; always +:ZOMBIE LDA #16 + STA M_HP,Y + LDA #1 + STA M_MOVE,Y + LDA #14 +:FINISH STA M_TYPE,Y + LDA CURMON_X + STA M_X,Y + LDA CURMON_Y + STA M_Y,Y + LDA CURMON_L + STA M_LEVEL,Y + CMP MAPADDR+1 ; no at same level + BNE _NOMONST + LDA M_X,Y + TAX + LDA M_Y,Y + TAY + CPX X0 + BLT _NOMONST ; exit, keep monster + CPX X1 + BGE _NOMONST ; exit, keep monster + CPY Y0 + BLT _NOMONST ; exit, keep monster + CPY Y1 + BGE _NOMONST ; exit, keep monster + LDA #0 ; no good -- same screen as + STA M_HP,Y ; Meltok! +_NOMONST RTS +CURMONST HEX 00 +CURMON_X HEX 00 +CURMON_Y HEX 00 +CURMON_L HEX 00 + +******************************** +* Make monsters move about! * +******************************** +MOVMONST LDY #0 +:DOMORE STY CURMONST + LDA M_HP,Y + BEQ :NEXTMON + LDA M_MOVE,Y + BEQ :MOVEIT + SEC + SBC #1 + STA M_MOVE,Y + JSR CH4CHAR ; attack anyway! + JMP :NEXTMON +:MOVEIT LDA M_TYPE,Y + TAX + LDA TYPCONST-12,X ; update move counter + STA M_MOVE,Y ; again... + LDA M_Y,Y + STA CURMON_Y + LDA M_X,Y + STA CURMON_X + LDA M_LEVEL,Y + STA CURMON_L + JSR CH4CHAR ; if M near, attack him + BCC :NEXTMON ; carry clear = attacked + LDA RANDOM1 + AND #%00000011 + BNE :MOVETOW +:MOVERAN JSR M_RANDOM ; move randomly + JMP :NEXTMON +:MOVETOW JSR M_TOWARD ; move toward Meltok +:NEXTMON INC CURMONST + LDY CURMONST + CPY #MONSMAX + BLT :DOMORE + LDY #0 +:CHECKIT LDA M_HP,Y ; see if monster is in table + BEQ :DOTHAT ; if HP = 0, not there + LDA M_TYPE,Y ; check if the monster moved + TAX ; this turn. That is, check + LDA TYPCONST-12,X ;if at the maximum number of + CMP M_MOVE,Y ; turns allowed for type. + BNE :DOTHAT ; if not eq, did not move + LDA M_X,Y ; see if monster is actually + TAX ; in the same room as + INX ; Meltok is. + CPX X0 ; checking the X range + BLT :DOTHAT + CPX X1 + BEQ :SKIP00 ; only if > than + BGE :DOTHAT +:SKIP00 LDA M_Y,Y ; checking the Y range + TAX + INX + CPX Y0 + BLT :DOTHAT + CPX Y1 + BEQ :SKIP11 ; if <=, in the same room + BGE :DOTHAT +:SKIP11 LDA M_LEVEL,Y + CMP MAPADDR+1 + BEQ :DOTHIS ; if ==, save level too! +:DOTHAT INY + CPY #MONSMAX + BGE :EXITNOW + BLT :CHECKIT +:DOTHIS JSR UPSCREEN +:EXITNOW RTS +TYPCONST DFB 2,4,1 + +CH4CHAR LDA M_LEVEL,Y ; check if on same leve + CMP MAPADDR+1 ; as Meltok + BEQ :CHECKX + SEC + RTS +:CHECKX LDA M_X,Y + SEC + SBC CX + CLC ; why, i do not know + ADC #1 + CMP #1 + BEQ :CHECKY0 ; Y should = 0; horizontal + CMP #-1 + BEQ :CHECKY0 ; Y should = 0; horizontal + CMP #0 + BEQ :CHECKY ; check for vertical + SEC + RTS +:CHECKY LDA M_Y,Y + SEC + SBC CY + CLC ; why, i do not know + ADC #1 + CMP #1 + BEQ :ATTACK + CMP #-1 + BEQ :ATTACK + SEC + RTS +:CHECKY0 LDA M_Y,Y + SEC + SBC CY + CLC ; why, i do not know + ADC #1 + CMP #0 ; we have a horizontal attack! + BEQ :ATTACK + SEC + RTS +:ATTACK LDA M_TYPE,Y + JSR M:OWIE + CLC + RTS + +M_TOWARD LDA CURMON_X + CMP CX + BEQ :CHECKY + BLT :XISLESS + DEC CURMON_X + JMP :FINISHX +:XISLESS INC CURMON_X +:FINISHX JSR MONMOVCK + BCC M_REGMOV ; ok move! + LDY CURMONST + LDA M_X,Y + STA CURMON_X +:CHECKY LDA CURMON_Y + CMP CY + BEQ :_RANDOM ; do random move + BLT :YISLESS + DEC CURMON_Y + JMP :FINISHY +:YISLESS INC CURMON_Y +:FINISHY JSR MONMOVCK + BCC M_REGMOV ; ok, move! + LDY CURMONST + LDA M_Y,Y + STA CURMON_Y +:_RANDOM JMP M_RANDOM + +M_REGMOV LDY CURMONST + LDA CURMON_X + STA M_X,Y + LDA CURMON_Y + STA M_Y,Y + RTS + +M_RANDOM LDA RANDOM1 + BMI :XDOWN +:XUP INC CURMON_X + JMP :CHECKX +:XDOWN DEC CURMON_X +:CHECKX JSR MONMOVCK + BCS :DO_Y ; was bad location + JMP M_REGMOV +:DO_Y LDY CURMONST ; restore old X value + LDA M_X,Y ; (this way monster does not + STA CURMON_X ; move diagonally) + LDA RANDOM2 + BMI :YDOWN +:YUP INC CURMON_Y + JMP :CHECKY +:YDOWN DEC CURMON_Y +:CHECKY JSR MONMOVCK + BCS :NO_GO ; was bad location + JMP M_REGMOV +:NO_GO LDA #0 ; make a move possible + LDY CURMONST ; next time through. + STA M_MOVE,Y ; (no move done this time) + LDA M_Y,Y ; restore current Y value to + STA CURMON_Y ; general locations.. + RTS + +MONMOVCK LDX CURMON_X ; monster move check routine + LDY CURMON_Y + LDA CURMON_L + CMP MAPADDR+1 ; check level + BNE :GO_ON + INX ; to overcome MAPINDEX's add + INY + CPX CX + BNE :GO_ON + CPY CY + BEQ :BAD ; that is the character! +:GO_ON LDA MAPADDR+1 + PHA + LDA CURMON_L + STA MAPADDR+1 + JSR MAPINDEX + CMP #100 ; text = blank space + BGE :GOOD + CMP #3 ; unlocked door + BEQ :GOOD + CMP #5 ; found secret door + BEQ :GOOD + CMP #6 ; chest + BEQ :GOOD + CMP #7 ; opened chest + BEQ :GOOD + CMP #8 ; ladder + BEQ :GOOD + CMP #9 ; throne + BEQ :GOOD + CMP #10 ; Jewel of Kaldun + BEQ :GOOD + CMP #11 ; empty holder + BEQ :GOOD +:BAD PLA ; restore real address + STA MAPADDR+1 ; of map. + SEC + RTS +:GOOD PLA ; restore real address + STA MAPADDR+1 ; of map. + CLC + RTS + + +******************************** +* Monsters Hit * +******************************** +MONSHIT LDY #0 +:NEXTMON LDA M_HP,Y + BEQ :NOTHERE + LDA M_X,Y + TAX + INX + CPX DIR:X + BNE :NOTHERE + LDA M_Y,Y + TAX + INX + CPX DIR:Y + BNE :NOTHERE + LDA M_HP,Y + SEC + SBC CLEVEL ; lose CLEVEL hit points + STA M_HP,Y + BEQ :DEAD + BCS :ALIVE +:DEAD LDA M_TYPE,Y + TAX + LDA M_XPER-12,X + STA XPGAIN + ADDW XPGAIN;XP;XP + TYA + PHA + JSR STATUSXP + PRINT MONDEAD + PLA + TAY + LDA #0 + STA M_HP,Y + JSR UPSCREEN ; monster died, redraw screen +:ALIVE LDA #0 + RTS +:NOTHERE INY + CPY #MONSMAX + BNE :NEXTMON + LDA #0 + RTS +M_XPER DFB 30,10,75 ; experience points/monsters +MONDEAD HEX 825501 ; vtab 22:htab 1 + ASC "You killed the monster! You receive"8D80 + DA XPGAIN + ASC " experience points."00 +XPGAIN HEX 0000 + diff --git a/noise.s b/noise.s new file mode 100755 index 0000000..2d4724b --- /dev/null +++ b/noise.s @@ -0,0 +1,28 @@ +******************************** +* Do noise routines: * +******************************** + +* Take from April issue of Nibble: +DONOISE ENT + LDA SPEAKER + LDY VOLUME ; get volume +:YLOOP DEY ; pause for volume control + BNE :YLOOP + STA SPEAKER ; click again + LDY DURATION ; load duration + LDA $F000,Y ; and use as index to ran #s + CLC + ADC FREQUENC ; add pitch + TAX ; get pause length +:XLOOP DEX ; pause + BNE :XLOOP + DEC DURATION ; decrement duration + BNE DONOISE + RTS +DURATION ENT + HEX 00 +FREQUENC ENT + HEX 00 +VOLUME ENT + HEX 00 + diff --git a/places.s b/places.s new file mode 100755 index 0000000..f1fc3c7 --- /dev/null +++ b/places.s @@ -0,0 +1,240 @@ +* External references + ; jewel.of.kaldun.s +DATA EXT + ; input.output.s +PRSTR EXT + +******************************** +* Print a room description for * +* the location at (cx,cy). * +* If on/in some item, describe * +* that. * +******************************** + +ROOMDESC JSR CBOT3 + LDA #22 ; set vtab at 23. + STA TLINE + JSR TEXTADDR + LDX CX + LDY CY + JSR MAPINDEX + CMP #100 + BGE :DOROOMS + CMP #12 ; won't handle a # > 11. + BLT :THINGS + CMP #99 ; handle special chest + BNE :BLANK + LDA #12 ; special case + JMP :THINGS +:BLANK LDA #0 +:THINGS ASL + TAY + LDA D:THINGS,Y + STA DATA + LDA D:THINGS+1,Y + STA DATA+1 + JSR PRSTR + RTS +:DOROOMS CMP #254 + BLT :DOROOM0 + BEQ :DORM254 + PRINT ROOM255 + RTS +:DORM254 PRINT ROOM254 + RTS +:DOROOM0 SEC + SBC #100 + CMP #63 ; deal with only rooms + BLT :ROOMS ; 100 - 162. + LDA #63 ; print warning msg. +:ROOMS ASL + TAY + LDA D:ROOMS,Y + STA DATA + LDA D:ROOMS+1,Y + STA DATA+1 + JSR PRSTR + RTS + +D:THINGS DA SHAPE00,SHAPE01,SHAPE02,SHAPE03 + DA SHAPE04,SHAPE05,SHAPE06,SHAPE07 + DA SHAPE08,SHAPE09,SHAPE10,SHAPE11 + DA SHAPE99 +SHAPE00 HEX 00 +SHAPE01 HEX 00 +SHAPE02 HEX 00 +SHAPE03 HEX 83 + ASC "You are in a doorway."00 +SHAPE04 HEX 00 +SHAPE05 HEX 83 + ASC "You are in a secret passage."00 +SHAPE06 HEX 83 + ASC "You stand before a chest."00 +SHAPE07 HEX 83 + ASC "You stand before an opened chest."00 +SHAPE08 HEX 83 + ASC "You stand before a ladder."00 +SHAPE09 HEX 83 + ASC "You stand before an ornate throne."00 +SHAPE10 HEX 83 + ASC "You are before the fabled"8D83 + ASC "Jewel of Kaldun!"00 +SHAPE11 HEX 83 + ASC "You are before an empty stand..."00 +SHAPE99 HEX 83 + ASC "... A very ornate chest ..."00 + +D:ROOMS DA ROOM100,ROOM101,ROOM102,ROOM103 + DA ROOM104,ROOM105,ROOM106,ROOM107 + DA ROOM108,ROOM109,ROOM110,ROOM111 + DA ROOM112,ROOM113,ROOM114,ROOM115 + DA ROOM116,ROOM117,ROOM118,ROOM119 + DA ROOM120,ROOM121,ROOM122,ROOM123 + DA ROOM124,ROOM125,ROOM126,ROOM127 + DA ROOM128,ROOM129,ROOM130,ROOM131 ; boo-boo in map: + DA ROOM132,ROOM133,ROOM134,ROOM135 ; no 131-139 rooms! + DA ROOM136,ROOM137,ROOM138,ROOM139 + DA ROOM140,ROOM141,ROOM142,ROOM143 + DA ROOM144,ROOM145,ROOM146,ROOM147 + DA ROOM148,ROOM149,ROOM150,ROOM151 + DA ROOM152,ROOM153,ROOM154,ROOM155 + DA ROOM156,ROOM157,ROOM158,ROOM159 + DA ROOM160,ROOM161,ROOM162,ROOM163 +ROOM100 HEX 83 + ASC "You are in front of the castle."00 +ROOM101 HEX 83 + ASC "You stand in the courtyard."00 +ROOM104 ; same message as #102 +ROOM102 HEX 83 + ASC "You are in a secret hallway."00 +ROOM103 HEX 83 + ASC "The south-west tower."00 +ROOM105 HEX 83 + ASC "The south-east tower."00 +ROOM106 HEX 83 + ASC "The guards room."00 +ROOM107 HEX 83 + ASC "The captain of the guards room."00 +ROOM108 HEX 83 + ASC "Someones' horde of ???"00 +ROOM109 HEX 83 + ASC "A hidden closet."00 +ROOM110 HEX 83 + ASC "The ladder room."00 +ROOM111 HEX 83 + ASC "A hall."00 +ROOM112 HEX 83 + ASC "The processional hall."00 +ROOM113 HEX 83 + ASC "The guest room."00 +ROOM114 HEX 83 + ASC "You are in the kitchen."00 +ROOM115 HEX 83 + ASC "The storage room."8D83 + ASC "It smells a bit in here!"00 +ROOM116 HEX 83 + ASC "The Kings' guards room."00 +ROOM117 HEX 83 + ASC "The Kings' closet."00 +ROOM118 HEX 83 + ASC "The Kings' bathroom."00 +ROOM119 HEX 83 + ASC "A private hall."00 +ROOM120 HEX 83 + ASC "The Kings' bedroom."00 +ROOM121 HEX 83 + ASC "The throne room and"8D83 + ASC "audience chamber."00 +ROOM122 HEX 83 + ASC "The dining room."00 +ROOM123 HEX 83 + ASC "The wine cellar."00 +ROOM124 HEX 83 + ASC "The north-west tower."00 +ROOM125 HEX 83 + ASC "The wizards' magic chamber!"00 +ROOM126 HEX 83 + ASC "The wizards' room."00 +ROOM127 HEX 83 + ASC "A secret back passage..."00 +ROOM128 HEX 83 + ASC "The north-east tower."00 +ROOM129 HEX 83 + ASC "You stand behind the castle"8D83 + ASC "Freedom is but a step away!"00 +ROOM130 HEX 83 + ASC "You stand somewhere on the"8D83 + ASC "second level!"00 +ROOM131 ; these rooms do not exist +ROOM132 ; on either level!! +ROOM133 +ROOM134 +ROOM135 +ROOM136 +ROOM137 +ROOM138 +ROOM139 HEX 00 ; cover for boo-boo +ROOM140 HEX 83 + ASC "You stand in a long, winding"8D83 + ASC "hallway."00 +ROOM141 HEX 83 + ASC "... some odd little room ..."00 +ROOM142 HEX 83 + ASC "This appears to be a reception"8D83 + ASC "room."00 +ROOM143 HEX 83 + ASC "Boy, this guy must've been rich!"00 +ROOM144 HEX 83 + ASC "You have no idea what this empty room"8D83 + ASC "was used for!"00 +ROOM145 HEX 83 + ASC "... another hallway ..."00 +ROOM146 HEX 83 + ASC "... and yet one more hallway ..."00 +ROOM147 HEX 83 + ASC "This looks like a great hall."00 +ROOM148 HEX 83 + ASC "A guests' room?"00 +ROOM149 HEX 83 + ASC "Maybe this is a guest room."00 +ROOM150 HEX 83 + ASC "And yet, another guest room!"00 +ROOM151 HEX 83 + ASC "Boy, one more ..."00 +ROOM152 HEX 83 + ASC "Wait, maybe these are servants"8D83 + ASC "quarters!"00 +ROOM153 HEX 83 + ASC "Someone must've done a lot of"8D83 + ASC "work here. The walls are black!"00 +ROOM154 HEX 83 + ASC "There is a beautiful jewel in"8D83 + ASC "this room."00 +ROOM155 HEX 83 + ASC "The south-west tower has a beautiful"8D83 + ASC "view of the landscape."00 +ROOM156 HEX 83 + ASC "Boy, ain't this fun?"00 +ROOM157 HEX 83 + ASC "The south-east tower doesn't have as"8D83 + ASC "beautiful a view as the south-west."00 +ROOM158 HEX 83 + ASC "Time to leave this place, eh?"00 +ROOM159 HEX 83 + ASC "Where do you think you are going?"00 +ROOM160 HEX 83 + ASC "The north-west tower... Ah, there"8D83 + ASC "is a ladder!"00 +ROOM161 HEX 83 + ASC "Boy, you feel tired."00 +ROOM162 HEX 83 + ASC "The south-west tower... There is a"8D83 + ASC "ladder here!"00 +ROOM163 HEX 83 + ASC "Oh dear, I have no idea what room"8D83 + ASC "this is!!"00 +ROOM254 HEX 83 + ASC "A rather broken up ladder."00 +ROOM255 HEX 83 + ASC "A smashed chest."00 + diff --git a/prolib.mac.s b/prolib.mac.s new file mode 100755 index 0000000..0419186 --- /dev/null +++ b/prolib.mac.s @@ -0,0 +1,77 @@ +******************************** +* ProDOS Library Macro command * +* list: * +******************************** + +~QUIT = $65 ; quit +~GETTIME = $82 ; get time +~CREATE = $C0 ; create +~DESTROY = $C1 ; destroy +~OPEN = $C8 ; open file +~READ = $CA ; read file +~WRITE = $CB ; write file +~CLOSE = $CC ; close file +~FLUSH = $CD ; flush file + +* ProDOS addresses -- + +MLI = $BF00 +_DATE = $BF90 +_TIME = $BF92 + +* ProDOS Macro commands -- +* call: @name parameter #1;parameter #2; ... ;parameter #n + +@QUIT MAC ; @quit + JSR _QUIT + EOM + +@GETTIME MAC ; @gettime + JSR _GETTIME + EOM + +@CREATE MAC ; @create path;access;file_type; + MOVW ]1;D:C0PATH ; auxiliary_type; + MOVB ]2;D:C0ACC ; storage_type + MOVB ]3;D:C0FTYP + MOVW ]4;D:C0ATYP + MOVB ]5;D:C0STYP + JSR _CREATE + EOM + +@DESTROY MAC ; @destroy path + MOVW ]1;D:C1PATH + JSR _DESTROY + EOM + +@OPEN MAC ; @open path;file_buffer; (1K) + MOVW ]1;D:C8PATH ; reference_number (ret) + MOVW ]2;D:C8BUFF + JSR _OPEN + MOVB D:C8REF;]3 + EOM + +@READ MAC ; @read ref_num;input_buff; + MOVB ]1;D:CAREF ; requested_length + MOVW ]2;D:CABUFF ; (actual_length returned) + MOVW ]3;D:CARLEN + JSR _READ + EOM + +@WRITE MAC ; @write ref_num;output_buff; + MOVB ]1;D:CBREF ; requested_length + MOVW ]2;D:CBBUFF ; (actual_length returned) + MOVW ]3;D:CBRLEN + JSR _WRITE + EOM + +@CLOSE MAC ; @close reference_number + MOVB ]1;D:CCREF + JSR _CLOSE + EOM + +@FLUSH MAC ; @flush reference_number + MOVB ]1;D:CDREF + JSR _FLUSH + EOM + diff --git a/prolib.s b/prolib.s new file mode 100755 index 0000000..92bb9d5 --- /dev/null +++ b/prolib.s @@ -0,0 +1,121 @@ +******************************** +* ProDOS MLI calls. * +* Uses: IO * +* IO.MAC * +******************************** + +_QUIT JSR MLI ; Perform QUIT function + DFB ~QUIT + DW D:QUIT +_MLICHK BNE MLIERROR ; Error occured ... + RTS + +MLIERROR LDA #23 + STA TLINE + JSR TEXTADDR + JSR CLINE + LDA #$40 + JSR WAIT + LDY #$C0 +:BELL LDA #$10 + JSR WAIT + STA SPEAKER + DEY + BNE :BELL + CENTER MLIERR_S + STA KEYSTROB +:KEYLOOP LDA KEYBOARD + CMP #RETURN + BNE :KEYLOOP + STA KEYSTROB + JMP MAIN +MLIERR_S ASC "AN ERROR HAS OCCURED! PRESS "00 + +_GETTIME JSR MLI ; perform get_time function + DFB ~GETTIME + DW 0 + JMP _MLICHK + +_CREATE @GETTIME ; perform create function + MOVW _DATE;D:C0DATE + MOVW _TIME;D:C0TIME + JSR MLI + DFB ~CREATE + DW D:CREATE + JMP _MLICHK + +_DESTROY JSR MLI ; perform destroy function + DFB ~DESTROY + DW D:DESTR + RTS ; error checking nulled + +_OPEN JSR MLI ; perform open function + DFB ~OPEN + DW D:OPEN + JMP _MLICHK + +_READ JSR MLI ; perform read function + DFB ~READ + DW D:READ + JMP _MLICHK + +_WRITE JSR MLI ; perform write function + DFB ~WRITE + DW D:WRITE + JMP _MLICHK + +_CLOSE ENT + JSR MLI ; perform close function + DFB ~CLOSE + DW D:CLOSE + JMP _MLICHK + +_FLUSH JSR MLI ; perform flush function + DFB ~FLUSH + DW D:FLUSH + JMP _MLICHK + +* ProDOS data/parameters -- + +D:QUIT DFB 4 ; 4 parameters + DFB 0 ; all are reserved. + DW 0 + DFB 0 + DW 0 + +D:CREATE DFB $7 ; 7 parameters +D:C0PATH DW 0 ; address of pathname +D:C0ACC DFB 0 ; access bits +D:C0FTYP DFB 0 ; file type +D:C0ATYP DW 0 ; auxiliary file type +D:C0STYP DFB 0 ; storage type +D:C0DATE DW 0 ; creation date +D:C0TIME DW 0 ; creation time + +D:DESTR DFB $1 ; 1 parameter +D:C1PATH DW 0 ; address of pathname + +D:OPEN DFB $3 ; 3 parameters +D:C8PATH DW 0 ; address of path name +D:C8BUFF DW 0 ; address of file buffer +D:C8REF DFB 0 ; reference number (returned) + +D:READ DFB $4 ; 4 parameters +D:CAREF DFB 0 ; reference number +D:CABUFF DW 0 ; address of data buffer +D:CARLEN DW 0 ; requested length +D:CAALEN DW 0 ; actual length + +D:WRITE DFB $4 ; 4 parameters +D:CBREF DFB 0 ; reference number +D:CBBUFF DW 0 ; address of data buffer +D:CBRLEN DW 0 ; requested length +D:CBALEN DW 0 ; actual length + +D:CLOSE DFB $1 ; 1 parameter +D:CCREF ENT + DFB 0 ; reference number + +D:FLUSH DFB $1 ; 1 parameter +D:CDREF DFB 0 ; reference number + diff --git a/reset.s b/reset.s new file mode 100755 index 0000000..0c8e61a --- /dev/null +++ b/reset.s @@ -0,0 +1,48 @@ +* External references + +_CLOSE EXT +D:CCREF EXT +DOQUIT EXT +MAIN EXT + +******************************** +* Reset routine handler. * +******************************** +RESETUP ENT + LDY #0 ; save old reset +:0 LDA $3F2,Y ; handler + STA RESTORE,Y + INY + CPY #3 + BLT :0 + LDA #DORESET + STA $3F3 + EOR #$A5 + STA $3F4 + RTS +RESTORE ENT + HEX 000000 ; store old reset bytes + +******************************** +* Actual reset routine: * +* close all files, * +* print message, * +* and call DOQUIT * +******************************** +DORESET @CLOSE #0 ; close all files + JSR TEXT + JSR CLRSCRN + PRINT RESETMSG + LDY #5 ; pause a bit +:LOOP LDA #255 + JSR WAIT + DEY + BNE :LOOP + JSR DOQUIT + JMP MAIN +RESETMSG HEX 4A83 + ASC "You didn't really want to do"8D83 + ASC "that now, did you?"00 + diff --git a/shapes.s b/shapes.s new file mode 100755 index 0000000..2909f85 --- /dev/null +++ b/shapes.s @@ -0,0 +1,396 @@ +* External references + ; jewel.of.kaldun.s +;DATA EXT + +******************************** +* Jewel of Kaldun shape * +* drawing routines. * +* Uses: GRAPHICS * +* MATH * +* MATH.MAC * +* GENERAL.MAC * +******************************** + +SHTABLE DFB %00000000 ; Shape #0: Blank space + DFB %00000000 + DFB %00000000 + DFB %00000000 + DFB %00000000 + DFB %00000000 + DFB %00000000 + DFB %00000000 + + DFB %11111111 ; Shape #1: Wall + DFB %11111111 + DFB %11111111 + DFB %11111111 + DFB %11111111 + DFB %11111111 + DFB %11111111 + DFB %11111111 + + DFB %00111100 ; Shape #2: Meltok + DFB %00111100 + DFB %00011000 + DFB %11111111 + DFB %00011000 + DFB %00111100 + DFB %00100100 + DFB %01100110 + + DFB %11111111 ; Shape #3: Door (unlocked) + DFB %11111111 + DFB %11100111 + DFB %11000011 + DFB %11000011 + DFB %11000011 + DFB %11000011 + DFB %11000011 + + DFB %11111111 ; Shape #4: Locked Door + DFB %11111111 + DFB %11100111 + DFB %11000011 + DFB %11000011 + DFB %11010011 + DFB %11000011 + DFB %11000011 + + DFB %11111111 ; Shape #5: Secret Door (found) + DFB %11100111 + DFB %11011011 + DFB %11011011 + DFB %11011011 + DFB %11011011 + DFB %11011011 + DFB %11011011 + + DFB %00000000 ; Shape #6: Chest + DFB %00000000 + DFB %00111100 + DFB %01100110 + DFB %01111110 + DFB %01100110 + DFB %01100110 + DFB %01111110 + + DFB %00000000 ; Shape #7: Opened Chest + DFB %00001100 + DFB %00000110 + DFB %00000110 + DFB %01111110 + DFB %01100110 + DFB %01100110 + DFB %01111110 + + DFB %00000000 ; Shape #8: Ladder + DFB %01100110 + DFB %01111110 + DFB %01100110 + DFB %01111110 + DFB %01100110 + DFB %01111110 + DFB %01100110 + + DFB %00000000 ; Shape #9: Throne + DFB %00000110 + DFB %00000110 + DFB %00000110 + DFB %01111110 + DFB %01100110 + DFB %01100110 + DFB %01100110 + + DFB %00011000 ; Shape #10: Jewel of Kaldun + DFB %00111100 + DFB %00111100 + DFB %00011000 + DFB %11000011 + DFB %01111110 + DFB %00011000 + DFB %00111100 + + DFB %00000000 ; Shape #11: Empty Holder + DFB %00000000 ; (Jewel of Kaldun gone) + DFB %00000000 + DFB %00000000 + DFB %11000011 + DFB %01111110 + DFB %00011000 + DFB %00111100 + + DFB %00000000 ; Shape #12: Ghost + DFB %00111100 + DFB %01111110 + DFB %01101010 + DFB %01111110 + DFB %01111110 + DFB %01011010 + DFB %00000000 + + DFB %00000000 ; Shape #13: Blob + DFB %01100110 + DFB %00101100 + DFB %00111100 + DFB %01111110 + DFB %01010110 + DFB %01000100 + DFB %00000000 + + DFB %00000000 ; Shape #14: Zombie + DFB %00011000 + DFB %01111110 + DFB %00011000 + DFB %00111100 + DFB %01100110 + DFB %01100110 + DFB %00000000 + + DFB %00000000 ; Shape #15: Circle + DFB %00111100 + DFB %01111110 + DFB %01111110 + DFB %01111110 + DFB %01111110 + DFB %00111100 + DFB %00000000 + + DFB %00000000 ; Shape #16: Dot + DFB %00000000 + DFB %00000000 + DFB %00011000 + DFB %00011000 + DFB %00000000 + DFB %00000000 + DFB %00000000 + + DFB %10101010 ; Shape #17: Half wall (fade-in) + DFB %01010101 + DFB %10101010 + DFB %01010101 + DFB %10101010 + DFB %01010101 + DFB %10101010 + DFB %01010101 + + DFB %01010101 ; Shape #18: Half wall (fade-in) + DFB %10101010 + DFB %01010101 + DFB %10101010 + DFB %01010101 + DFB %10101010 + DFB %01010101 + DFB %10101010 + + DFB %01111111 ; Shape #19: Letter "R" + DFB %11000011 + DFB %11000011 + DFB %11000011 + DFB %01111111 + DFB %00110011 + DFB %01100011 + DFB %11000011 + + DFB %11111111 ; Shape #20: Letter "I" + DFB %00011000 + DFB %00011000 + DFB %00011000 + DFB %00011000 + DFB %00011000 + DFB %00011000 + DFB %11111111 + + DFB %01111111 ; Shape #21: Letter "P" + DFB %11000011 + DFB %11000011 + DFB %11000011 + DFB %01111111 + DFB %00000011 + DFB %00000011 + DFB %00000011 + + DFB %11111111 ; Shape #22: Barred Door + DFB %11111111 + DFB %11100111 + DFB %11000011 + DFB %11111111 + DFB %11000011 + DFB %11111111 + DFB %11000011 + +******************************** +* Shape draw variables * +******************************** + +XOFFSET HEX 0000 +XLOC HEX 0000 +YLOC HEX 00 +SNUM ENT + HEX 0000 +DRAWREP HEX 00 +CLRFLAG ENT + DFB %10000000 ; flag for clearing background +XORFLAG ENT + DFB %00000000 ; flag to XOR with background +BITMASK DFB %01111111,%00111111 ; bits to keep for + DFB %00011111,%00001111 ; offset values + DFB %00000111,%00000011 + DFB %00000001 +BITABLE1 DFB %00000000,%00000001 ; bits to keep in 1st + DFB %00000011,%00000111 ; graphic byte + DFB %00001111,%00011111 + DFB %00111111 +BITABLE2 DFB %01111110,%01111100 ; bits to keep in 2nd + DFB %01111000,%01110000 ; graphicbyte + DFB %01100000,%01000000 + DFB %00000000 + +******************************** +* Draw a shape routine. Upon * +* entry: * +* X-axis: AAXX * +* Y-axis: YY * +* Shape Num: preset * +******************************** + +DRAWSHAP ENT + STA XLOC+1 ; save entry values: + STX XLOC ; xval = XXAA + STY YLOC ; yval = YY + STY HLINE + IMULW #8;SNUM;DATA + ADDW DATA;#SHTABLE;DATA + IDIVMODW XLOC;#7;XLOC;XOFFSET ; calc offset(s) + MOVB #8;DRAWREP +:REPEAT JSR HADDR + LDX XOFFSET + LDY XLOC + CPY #40 + BGE :SECOND + BIT CLRFLAG + BPL :20 + LDA BITABLE1,X + AND (HPTR),Y + STA (HPTR),Y +:20 LDY #0 + LDA BITMASK,X + STA BITSTORE + AND (DATA),Y + LDX XOFFSET +:10 CPX #0 + BEQ :11 + ASL + DEX + JMP :10 +:11 LDY XLOC + BIT XORFLAG + BMI :2X1 + ORA (HPTR),Y + JMP :2X2 +:2X1 EOR (HPTR),Y +:2X2 STA (HPTR),Y +:SECOND LDX XOFFSET + LDY XLOC + INY + CPY #40 + BGE :NOTGOOD + BIT CLRFLAG + BPL :30 + LDA BITABLE2,X + AND (HPTR),Y + STA (HPTR),Y +:30 LDY #0 + LDA BITSTORE + EOR #%11111111 + AND (DATA),Y + LDX XOFFSET +:0 CPX #7 + BGE :1 + LSR + INX + JMP :0 +:1 LDY XLOC + INY + BIT XORFLAG + BMI :3X1 + ORA (HPTR),Y + JMP :3X2 +:3X1 EOR (HPTR),Y +:3X2 STA (HPTR),Y +:NOTGOOD INC DATA + BNE :2 + INC DATA+1 +:2 INC HLINE + DEC DRAWREP + BNE :REPEATX + RTS +:REPEATX JMP :REPEAT +BITSTORE HEX 00 + +* NOTE: This is a hack. -8 is treated as 8 bites by Merlin32; +* thus the MOVW is in error. Using the value of $FFF8 +* because my trusty PC calculator tells me that is correct. :-) +ARRIVEC2 MOVW #$FFF8;XMELTOK + MOVB #2;SNUM + LDA #%00000000 + STA CLRFLAG + LDA #%10000000 + STA XORFLAG +:REPEAT LDY #151 + LDA XMELTOK+1 + LDX XMELTOK + JSR DRAWSHAP + LDA #70 + JSR WAIT + LDY #151 + LDA XMELTOK+1 + LDX XMELTOK + JSR DRAWSHAP + INC XMELTOK + BNE :1 + INC XMELTOK+1 +:1 LDA XMELTOK+1 + CMP #>71 + BNE :REPEAT + LDA XMELTOK + CMP #<71 + BNE :REPEAT + BEQ COMMONCX + +XMELTOK HEX 0000 + +LEAVEC1 MOVW #131;XMELTOK + MOVB #2;SNUM + LDA #%00000000 + STA CLRFLAG + LDA #%10000000 + STA XORFLAG +:REPEAT LDY #151 + LDA XMELTOK+1 + LDX XMELTOK + JSR DRAWSHAP + LDA #70 + JSR WAIT + LDY #151 + LDA XMELTOK+1 + LDX XMELTOK + JSR DRAWSHAP + INC XMELTOK + BNE :1 + INC XMELTOK+1 +:1 LDA XMELTOK+1 + CMP #>280 + BNE :REPEAT + LDA XMELTOK + CMP #<280 + BNE :REPEAT +COMMONCX LDY #151 + LDX XMELTOK + LDA XMELTOK+1 + JSR DRAWSHAP + LDA #%10000000 + STA CLRFLAG + LDA #%00000000 + STA XORFLAG + RTS + diff --git a/story.s b/story.s new file mode 100755 index 0000000..118da80 --- /dev/null +++ b/story.s @@ -0,0 +1,274 @@ +* External references + ; graphics.s +HGRCLEAR EXT + +******************************** +* The story behind the Jewel * +* of Kaldun along with the * +* instructions for play. * +* Uses: IO * +* IO.MAC * +* CASTLES * +******************************** + +STORY JSR CLRSCRN + LDA #0 + STA TLINE + JSR TEXTADDR + CENTER TITLE00 + PRINT STORYP1 + JSR GETRET + JSR CLRMID + PRINT STORYP2 + JSR HGRCLEAR + JSR CASTLE1 + JSR GETRET + JSR CLRMID + JSR SETHGR + PRINT STORYP3 + JSR GETRET + JSR CLRMID + PRINT STORYP4 + JSR DRAWBRID + JSR GETRET + JSR CLRMID + PRINT STORYP5 + JSR LEAVEC1 + JSR GETRET + JSR CLRMID + JSR TEXT + PRINT STORYP6 + JSR GETRET + JSR CLRMID + PRINT STORYP7 + JSR HGRCLEAR + JSR CASTLE2 + JSR GETRET + JSR CLRMID + JSR SETHGR + PRINT STORYP8 + JSR ARRIVEC2 + JSR GETRET + JSR CLRSCRN + PRINT STORYP9 + LDA #%10000000 + STA ESCABORT + JSR GETRET + JSR CLRSCRN + JSR TEXT + LDA #0 + STA TLINE + JSR TEXTADDR + CENTER INSTR00 + PRINT INSTRP1 + JSR GETRET + JSR CLRMID + PRINT INSTRP2 + JSR GETRET + JSR CLRMID + PRINT INSTRP3 + JSR GETRET + JSR CLRMID + PRINT INSTRP4 + LDA #%10000000 + STA ESCABORT + JSR GETRET + JSR CLRSCRN + LDA #0 + STA TLINE + JSR TEXTADDR + CENTER PLAY00 + PRINT PLAYP1 + LDA #%10000000 + STA ESCABORT + JSR GETRET + JSR CLRSCRN + LDA #0 + STA TLINE + JSR TEXTADDR + CENTER GPL00 + PRINT GPLP1 + LDA #%10000000 + STA ESCABORT + JSR GETRET + JSR CLRSCRN + RTS + +GPL00 ASC "CONTACT & LICENSE"00 +PLAY00 ASC "PLAYING NOTES"00 +INSTR00 ASC "INSTRUCTIONS"00 +TITLE00 ASC "THE STORY"00 +STORYP1 HEX 43 + ASC "For many years, there had been a legend"8D + ASC "of a magical emerald, entitled the"8D + ASC "'Jewel of Kaldun.' This gem had been"8D + ASC "lost in a deserted castle that was once"8D + ASC "occupied by the great magician Kaldun."8D + HEX 8D + ASC "This castle is rumored to be haunted"8D + ASC "with ghosts, zombies and magical bats,"8D + ASC "and has been acclaimed as being 'fates"8D + ASC "friend or foe.' It has been said that"8D + ASC "whatever kingdom possesses this 'Jewel"8D + ASC "of Kaldun' shall have only peace and"8D + ASC "health for the rest of its days."8D + HEX 8D + ASC "King Aradea was ruling during troubled"8D + ASC "times. Famine and disease plagued his"8D + ASC "kingdom. When he heard of this jewel,"8D + ASC "he announced the following proclamation:"8D00 +STORYP2 HEX 4305 + ASC "Whosoever finds the Jewel of"8D05 + ASC "Kaldun shall be given the hand"8D05 + ASC "of my beautiful daughter Lydia"8D05 + ASC "in marriage and will follow as"8D05 + ASC "my successor. However, there"8D05 + ASC "is one stipulation to this"8D05 + ASC "quest: he whoever tries must"8D05 + ASC "begin his search in the deserted"8D05 + ASC "castle at sunset and return to"8D05 + ASC "me by noon the following day."8D05 + ASC "For whosoever accomplishes this"8D05 + ASC "task must be quick of mind and"8D05 + ASC "stout of heart. The one who is"8D05 + ASC "capable of this task will be"8D05 + ASC "worthy of my daughter, and of my"8D05 + ASC "kingdom."8D14 + ASC "- King Aradea"00 +STORYP3 HEX 54 + ASC "The kingdom stirred with hope and"8D + ASC "intrigue. Many men attempted the quest"8D + ASC "and were never seen again."00 +STORYP4 HEX 54 + ASC "One day a local peasant named Meltok"8D + ASC "decided to undertake the proclaimed"8D + ASC "search."00 +STORYP5 HEX 54 + ASC "After telling King Aradea of his plans,"8D + ASC "he leaves the castle in hopes of the"8D + ASC "Jewel of Kaldun ..."00 +STORYP6 HEX 43 + ASC "As Meltok left the castle, he realized"8D + ASC "that he needed to know more about this"8D + ASC "castle and the wizard, Kaldun..."8D + HEX 8D + ASC "As you talk to your fellow peasants,"8D + ASC "you notice that noone really knows of"8D + ASC "the wizard Kaldun -- it's all made up!"8D + HEX 8D + ASC "However, about the Castle of Kaldun and"8D + ASC "the Jewel of Kaldun, there is plenty to"8D + ASC "tell. For one, it is said that the"8D + ASC "castle lies deserted. However, it is"8D + ASC "also told that the moment a live creature"8D + ASC "sets foot upon the castles' ground,"8D + ASC "monsters begin to appear. From where,"8D + ASC "noone can tell..."00 +STORYP7 HEX 43 + ASC "There is a rumor that makes you stop"8D + ASC "in your tracks. 'It is said,' an old"8D + ASC "man says, 'that if the Jewel of Kaldun"8D + ASC "is removed from the castle, the land"8D + ASC "will prosper but a few years before all"8D + ASC "of mankind is lost! Be careful, my"8D + ASC "son.' And with that, he leaves you."8D + ASC "When you look around for the man, he is"8D + ASC "no where to be seen..."00 +STORYP8 HEX 55 + ASC "Finally, Meltok arrived at the Castle of"8D + ASC "Kaldun."00 +STORYP9 HEX 54 + ASC "It is time for you to help Meltok find"8D + ASC "the Jewel of Kaldun. Are you capable"8D + ASC "of this formidable task?"00 + +INSTRP1 HEX 43 + ASC "To move Meltok, use the I, J, K, and M"8D + ASC "keys:"8D83 + ASC "(north)"8D83 + ASC "I"8D83 + ASC "(west) J K (east)"8D83 + ASC "M"8D83 + ASC "(south)"8D + HEX 8D + ASC "When Meltok is on a ladder, press:"8D05 + ASC "[A] to ascend (go up) and"8D05 + ASC "[D] to descend (go down)"8D + HEX 8D + ASC "When you are unsure of what an item on"8D + ASC "the screen is, press [L] for look."8D + HEX 8D + ASC "To open a chest, press [O], but beware:"8D + ASC "Some treasure chests have traps in them"8D + ASC "that can hurt Meltok!"00 +INSTRP2 HEX 43 + ASC "To search for secret doors, press [S]"8D + ASC "and the direction you wish to search in."8D + HEX 8D + ASC "When Meltok has found keys, he may"8D + ASC "unlock some of the locked doors in the"8D + ASC "castle by pressing [U] and the direction"8D + ASC "of the door. (There are some special"8D + ASC "doors that will not be opened by the"8D + ASC "general keys ... you must find those.)"8D + HEX 8D + ASC "To heal Meltok, press [R] to rest him."8D + ASC "Hit Points will slowly heal."8D + HEX 8D + ASC "When the JEWEL OF KALDUN is found, press"8D + ASC "[T] and the direction of the gem to take"8D + ASC "it."00 +INSTRP3 HEX 43 + ASC "To get a numerical status, press:"8D05 + ASC "[H] for health, or"8D05 + ASC "[W] for wealth"8D + ASC "Health consists of Hit Points, Exper-"8D + ASC "ience and level. Wealth consists of"8D + ASC "Gold Pieces, Keys, and any special"8D + ASC "items."8D + HEX 8D + ASC "When Meltok encounters those vile"8D + ASC "creatures that inhabit the Castle of"8D + ASC "Kaldun, press [F] and a direction key"8D + ASC "to fight them. You will do more damage"8D + ASC "as you go up levels, and will even gain"8D + ASC "automatic hits -- if you live that long."00 +INSTRP4 HEX 43 + ASC "Whenever you are asked for the direc-"8D + ASC "tion you wish to perform an action in,"8D + ASC "use the movement keys to indicate the"8D + ASC "direction (I, J, K, and M)."8D + HEX 8D + ASC "To get a summary of the commands"8D + ASC "available to Meltok, press [?]."8D + HEX 8D83 + ASC "We hope you enjoy the Jewel of Kaldun!"8D83 + ASC "A2 Geek / BShagle"00 + +PLAYP1 HEX 43 + ASC "For those of you interested, here are"8D + ASC "all of the monster statistics:"8D + HEX 8D05 + ASC "Name HP XP Movement"8D05 + ASC "------- -- -- --------"8D05 + ASC "Blob 2 10 4"8D05 + ASC "Zombie 16 75 1"8D05 + ASC "Ghost 8 30 2"8D + HEX 8D + ASC "Movement is how many turns Meltok can"8D + ASC "make before the monster will move. It"8D + ASC "should be said, however, that the mon-"8D + ASC "sters can attack on every move!!"00 + +GPLP1 HEX 43 + ASC "This program is licensed under the GPL."8D + ASC "Please see the LICENSE file available"8D + ASC "in the source code."8D + HEX 8D + ASC "Visit us to report bugs, make"8D + ASC "suggestions, or to just grab the code"8D + ASC "to hack on!"8D + HEX 8D83 + ASC "github.com/a2geek/jewel-of-kaldun"8D + HEX 00 + diff --git a/title.s b/title.s new file mode 100755 index 0000000..fdd8eb4 --- /dev/null +++ b/title.s @@ -0,0 +1,472 @@ +******************************** +* Jewel of Kaldun title page. * +* Uses: MATH.MAC * +* MATH * +* SHAPES * +* GENERAL.MAC * +* GRAPHICS * +******************************** + +TITLEPG JSR SETHGR + STA $C052 ; full page graphics + JSR DRAWBKGD + LDY #15 +:PAUSE LDX ROL_CTR + INC ROL_CTR + LDA ROL_CTR,X + TAX +:XXX DEX + BNE :XXX + STA SPEAKER + DEY + BNE :PAUSE + JSR ROLJEWEL + LDA #%00000000 + STA CLRFLAG + STA XORFLAG + +DRAWLETS MOVW #TTABLE;PTR +:PREPARE LDY #0 + LDA (PTR),Y + BNE :GO + JMP :FINISHD +:GO STA TITINCR + JSR PTRINC + LDA (PTR),Y + STA SNUM + JSR PTRINC + LDA (PTR),Y + STA TITLECTR + JSR PTRINC + LDA (PTR),Y + STA TITDELAY + JSR PTRINC + LDA (PTR),Y + STA TITX + LDA #0 + STA TITX+1 + JSR PTRINC + LDA (PTR),Y + STA TITY + JSR PTRINC + IMULW TITINCR;TITX;TITX + IMULW TITINCR;TITY;TITY + JMP :START +:LOOP MOVB TITINCR;LINECTR + LDY #0 + LDA (PTR),Y + STA DIRX + JSR PTRINC + LDA (PTR),Y + STA DIRY + JSR PTRINC +:DRAW LDA TITX+1 + LDX TITX + LDY TITY + JSR DRAWSHAP + LDA DIRX + CMP #-1 + BEQ :XDEC + CLC + ADC TITX + STA TITX + BNE :YTEST + INC TITX+1 + JMP :YTEST +:XDEC DEC TITX + LDA TITX + CMP #-1 + BNE :YTEST + DEC TITX+1 +:YTEST LDA DIRY ; y is only 1 byte + CLC + ADC TITY + STA TITY + DEC LINECTR + BNE :DRAW +:START DEC TITLECTR + BNE :LOOP + JMP :PREPARE +:FINISHD LDA #%10000000 + STA CLRFLAG + RTS + +WAIT ENT + SEC +:1 PHA +:0 SBC #1 + BNE :0 + PLA + SBC #1 + BNE :1 + RTS + +PTRINC INC PTR + BNE :0 + INC PTR+1 +:0 RTS + +TITLECTR HEX 00 +LINECTR HEX 00 +TITX HEX 0000 +TITY HEX 0000 +DIRX HEX 00 +DIRY HEX 00 +TITINCR HEX 0000 +TITDELAY HEX 00 + +******************************** +* Table of (x,y) on a 35x20 * +* grid for title page. * +******************************** + +TTABLE DFB 2,16,41 ; "the", 39 points, 2x2 + DFB 100,17,4 ; beginning + DFB 0,1,0,1,0,1,0,1,0,1,1,1,1,0,1,-1,1,-1,0,-1,0,-1 + DFB 0,-1,0,-1,0,1,0,1,0,1,0,1,0,1,0,1,0,-1,0,-1 + DFB 0,-1,1,-1,1,0,1,1,0,1,0,1,1,1,1,0,1,-1,1,-1 + DFB 1,-1,-1,-1,-1,0,-1,1,0,1,0,1,1,1,1,0,1,0 + DFB 2,16,4 ; cross the "t", 2x2, 4 pts + DFB 100,16,6 + DFB 1,0,1,0,1,0 + DFB 8,15,11 ; "J", 11 points, 8x8 + DFB 50,6,6 ; beginning (x,y) + DFB 1,1,1,0,1,0,1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1,0 + DFB 8,15,15 ; "e", 15 points, 8x8 + DFB 50,12,5 + DFB 1,0,1,0,1,0,0,-1,-1,-1,-1,0,-1,0,-1,1,0,1,0,1 + DFB 1,1,1,0,1,0,1,0 + DFB 8,15,13 ; "w", 13 points, 8x8 + DFB 50,16,3 + DFB 0,1,0,1,0,1,1,1,1,-1,0,-1,0,1,1,1,1,-1,0,-1 + DFB 0,-1,0,-1 + DFB 8,15,15 ; "e", 15 points, 8x8 + DFB 50,22,5 + DFB 1,0,1,0,1,0,0,-1,-1,-1,-1,0,-1,0,-1,1,0,1,0,1 + DFB 1,1,1,0,1,0,1,0 + DFB 8,15,11 ; "l", 11 points, 8x8 + DFB 50,26,1 + DFB 1,0,0,1,0,1,0,1,0,1,0,1,-1,1,1,0,1,0,-1,-1 + DFB 2,16,41 ; "of", 44 pts, 2x2 + DFB 100,111,4 + DFB 1,1,1,0,1,-1,1,0,-1,0,-1,1,0,1,0,1,1,1 + DFB 1,0,1,0,1,-1,0,-1,0,-1,-1,-1,1,1,1,1,1,1,1,0 + DFB 1,-1,0,-1,0,-1,0,-1,-1,-1,-1,1,0,1,0,1 + DFB 0,1,0,1,0,1,0,1,0,1,1,1,1,-1,0,-1,0,-1,-1,-1 + DFB 1,0,1,0,1,-1 + DFB 8,15,7 ; "K", left line, 8x8 + DFB 50,4,9 + DFB 0,1,0,1,0,1,0,1,0,1,0,1 + DFB 8,15,7 ; "K", finish it off, 8x8 + DFB 50,7,9 + DFB -1,1,-1,1,-1,1,1,1,1,1,1,1 + DFB 8,15,14 ; "a", 14 points, 8x8 + DFB 50,9,11 + DFB 1,0,1,0,1,1,0,1,0,1,0,1,-1,0,-1,0,-1,0,-1,-1 + DFB 1,-1,1,0,1,0 + DFB 8,15,11 ; "l", 11 points, 8x8 + DFB 50,13,9 + DFB 1,0,0,1,0,1,0,1,0,1,0,1,-1,1,1,0,1,0,-1,-1 + DFB 8,15,16 ; "d", 16 points, 8x8 + DFB 50,20,9 + DFB 0,1,0,1,0,1,0,1,0,1,0,1,-1,0,-1,0,-1,0,-1,-1 + DFB 0,-1,0,-1,1,-1,1,0,1,0 + DFB 8,15,14 ; "u", 14 points, 8x8 + DFB 50,21,11 + DFB 0,1,0,1,0,1,1,1,1,0,1,-1,1,-1,0,-1,0,-1,0,1 + DFB 0,1,0,1,0,1 + DFB 8,15,14 ; "n", 14 points, 8x8 + DFB 50,26,11 + DFB 0,1,0,1,0,1,0,1,0,-1,0,-1,1,-1,1,-1,1,0,1,1 + DFB 0,1,0,1,0,1 + DFB 0 ; end + +******************************** +* Draw Background routine. * +* Leave bit set for blue, or * +* strip it off for purple. * +******************************** +DRAWBKGD LDA #0 + STA HLINE + LDA #2 + STA HLINE2 +:LOOP JSR HADDR + JSR HADDR2 + BCS :ALLDONE + JSR BKLINE12 + ADDB #4;HLINE;HLINE + ADDB #4;HLINE2;HLINE2 + LDA HLINE + CMP #180 + BLT :LOOP +:ALLDONE RTS + +BKLINE12 LDY #0 +:1 LDX #0 +:0 LDA BACKGND1,X + STA (HPTR),Y + LDA BACKGND2,X + STA (HPTR2),Y + INX + INY + CPX #8 + BLT :0 + CPY #40 + BLT :1 + RTS +BACKGND1 HEX 858A94A8D0A0C182 ; high bit is set.. +BACKGND2 HEX D0A0C182858A94A8 ; blue background. + +******************************** +* Roll Jewel of Kaldun onto * +* the graphics screen. * +* Jewel picture is stored * +* in hi-res page 2, or * +* locations $4000-$5FFF * +******************************** +ROLJEWEL LDA #0 + STA ROL_CTR + LDA #174 + STA ROLSTART +:LOOP STA HLINE2 ; on page one + LDA #14 + STA HLINE ; on page two +:SCROLL JSR HADDR + JSR HADDR2 + ADDB #$20;HPTR+1;HPTR+1 ; make page 2 hires + LDY #8 +:COPY LDA (HPTR),Y ; copy a line of the jewel + STA (HPTR2),Y ; onto the graphics page. + INY + CPY #32 + BLT :COPY + INC HLINE ; increas copying until + INC HLINE2 ; at bottom of window +*------------------------------- + LDX ROL_CTR + INC ROL_CTR + LDY $FF00,X +:0TEST0 DEY + BNE :0TEST0 +*------------------------------- + STA SPEAKER + LDA HLINE2 ; on page 1. + CMP #177 + BLT :SCROLL + STA SPEAKER + LDY ROLSTART ; do a pause that decreases +:PAUSE LDA #20 ; as jewel moves farther + JSR WAIT ; onto the page + DEY + BNE :PAUSE + LDA ROLSTART ; check if we are already + CMP #14 ; finished + BEQ :EXIT + DEC ROLSTART ; move jewel up a bit + DEC ROLSTART + DEC ROLSTART + DEC ROLSTART + LDA ROLSTART + CMP #14 ; if.lt.14, we have final + BGE :LOOP ; if.ge.14, keep on going + LDA #14 ; show at top. + BNE :LOOP ; always +:EXIT RTS +ROLSTART HEX 00 ; where we are on scroll +ROL_CTR HEX 00 ; ----- + +******************************** +* Fade the Castle wall in for * +* the title page. * +******************************** + +WALLFADE STA $C052 + MOVW #WFTABLE;PTR + MOVB #246;TITLECTR + LDA #%00000000 + STA CLRFLAG + LDA #%00000000 + STA XORFLAG +:REPEAT JSR TITBUZZ + NILW TITX + NILW TITY + MOVB #18;SNUM + LDY #0 + LDA (PTR),Y + STA TITX + JSR PTRINC + LDA (PTR),Y + BPL :0 + PHA + MOVB #17;SNUM + PLA + AND #%01111111 +:0 STA TITY + JSR PTRINC + DEC TITY + DEC TITX + IMULW #8;TITX;TITX + IMULW #8;TITY;TITY + LDY TITY + LDX TITX + LDA TITX+1 + STA SPEAKER + JSR DRAWSHAP + DEC TITLECTR + BEQ :DONE + JMP :REPEAT +:DONE LDA #%10000000 + STA CLRFLAG + LDA #%00000000 + STA XORFLAG + RTS + +TITBUZZ STA SPEAKER + LDX ROL_CTR + INC ROL_CTR +:REPEAT DEX + BNE :REPEAT + STA SPEAKER + RTS + +******************************** +* Data for fade in of castle * +* wall. These are randomly * +* generated locations. High * +* bit on the Y coordinate * +* determines the shape number. * +* ON = shape #17 * +* OFF= shape #18 * +******************************** + +WFTABLE DFB 33,149,24,149,28,22,25,148,2,22,23,151 + DFB 13,151,3,149,22,21,29,21,2,150,4,21 + DFB 29,20,33,23,27,149,12,151,24,150,7,148 + DFB 11,21,17,21,30,150,34,21,33,148,11,149 + DFB 33,151,2,151,9,20,16,23,16,150,16,22 + DFB 7,151,14,150,23,23,26,151,8,21,34,22 + DFB 1,22,21,20,8,149,3,21,6,150,22,149,21,151 + DFB 32,22,31,23,8,22,10,149,21,150,26,23 + DFB 27,20,6,151,8,23,35,148,10,23,34,151 + DFB 23,148,21,23,25,21,24,22,26,22,5,150 + DFB 8,150,14,151,13,148,16,149,11,148,28,151 + DFB 17,151,14,21,18,149,34,23,19,20,19,151 + DFB 19,149,28,23,20,150,5,20,7,23,4,151 + DFB 14,23,9,22,29,150,33,150,32,149,9,151 + DFB 1,21,5,22,1,23,35,151,9,21,2,21 + DFB 1,20,18,23,13,22,34,149,17,20,20,151 + DFB 9,148,22,22,3,150,25,22,15,150,15,21 + DFB 3,22,23,20,30,23,27,21,31,22,12,22 + DFB 20,22,22,23,3,23,13,149,5,148,16,151 + DFB 1,148,3,148,17,148,29,151,31,148,27,151 + DFB 27,22,9,149,13,23,5,23,5,149,19,148 + DFB 15,148,3,151,11,23,30,151,6,149,35,21 + DFB 10,150,6,22,9,23,30,21,5,151,19,150 + DFB 25,23,32,151,17,23,32,23,26,150,26,149 + DFB 28,150,25,20,23,150,16,21,6,21,7,22 + DFB 7,150,17,149,23,22,14,22,25,150,27,150 + DFB 17,150,13,21,31,21,19,23,20,149,33,22 + DFB 19,21,22,151,35,149,30,22,28,21,12,149 + DFB 29,22,1,151,35,150,20,21,26,21,7,149 + DFB 15,151,35,22,30,149,12,23,4,150,19,22 + DFB 18,150,10,151,7,21,29,148,11,22,27,148 + DFB 15,20,3,20,9,150,11,151,2,23,21,149 + DFB 22,150,12,21,28,149,25,151,21,148,5,21 + DFB 33,20,7,20,13,20,15,23,27,23,4,149 + DFB 1,150,1,149,29,149,12,150,35,20,13,150 + DFB 21,22,2,149,31,151,15,149,29,23,17,22 + DFB 34,150,10,21,20,23,32,21,15,22,18,151 + DFB 24,21,24,151,14,149,11,150,32,150,25,149 + DFB 4,22,4,23,24,23,33,21,23,21,6,23 + DFB 31,20,31,149,18,21,23,149,10,22,8,151 + DFB 21,21,11,20,18,22,31,150,35,23 + +******************************** +* Prepare for scrolling: * +******************************** + +LINE21 = $650 +LINE22 = $6D0 +LINE23 = $750 + +SCPREP JSR CLRSCRN + LDY #40 + LDA #$20 ; inverse space +:0 STA LINE21-1,Y + STA LINE22-1,Y + STA LINE23-1,Y + DEY + BPL :0 + STA $C053 + RTS + +******************************** +* Scrolling line: * +******************************** + +SCLINE INV " " + INV "... THE JEWEL OF KALDUN " + INV "... PROGRAMMED BY A2GEEK " + INV "... STORY BY BSHAGE " + INV "... PRESS TO PLAY " + INV "... PRESS FOR INSTRUCTIONS AND INFORMATION " + INV "..." + HEX 00 + +******************************** +* Scroll that line, and check * +* to see if a RETURN or I has * +* been pressed. (or Q) * +******************************** + +SCROLL LDA #0 + STA KEYSTROB +:REPEAT TAY + PHA + LDX #0 +:1 LDA SCLINE,Y + BNE :0 + LDY #0 + BEQ :1 +:0 STA LINE22,X + INY + INX + CPX #40 + BLT :1 + LDA #220 + JSR WAIT + LDA KEYBOARD + BMI :KEY +:RESUME PLA + TAY + INY + LDA SCLINE,Y + BEQ SCROLL + TYA + JMP :REPEAT +:KEY STA KEYSTROB + CMP #$8D + BEQ :EXIT + CMP #"Q" + BEQ :EXIT + CMP #"q" + BEQ :EXIT + CMP #"I" + BEQ :EXIT + CMP #"i" + BEQ :EXIT + DEC RANDOM1 ; delay until all three + BNE :RESUME ; bytes of RANDOM (aka + DEC RANDOM2 ; counter) become + BNE :RESUME ; zero once again. +**** DEC RANDOM3 ; Then, trick the program +**** BNE :RESUME ; into thinking that "I" + LDA #"I" ; has been pressed. +:EXIT PHA + JSR SCPREP ; clear out scrolling region. + PLA + TAY ; do this to preserve + PLA ; keypress... + TYA + RTS +