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 +