diff --git a/games/lemm/Makefile b/games/lemm/Makefile new file mode 100644 index 00000000..ccef4b20 --- /dev/null +++ b/games/lemm/Makefile @@ -0,0 +1,42 @@ +include ../../Makefile.inc + +DOS33 = ../../utils/dos33fs-utils/dos33 +DOS33_RAW = ../../utils/dos33fs-utils/dos33_raw +B2D = ../../utils/bmp2dhr/b2d +PNG2GR = ../../utils/gr-utils/png2gr +LZSA = ~/research/lzsa/lzsa/lzsa +TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft +EMPTY_DISK = ../../empty_disk/empty.dsk + +all: lemm.dsk + +lemm.dsk: HELLO LEMM_TEST + cp $(EMPTY_DISK) lemm.dsk + $(DOS33) -y lemm.dsk SAVE A HELLO + $(DOS33) -y lemm.dsk BSAVE -a 0x4000 LEMM_TEST + + +### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + +#### + +LEMM_TEST: lemm_test.o + ld65 -o LEMM_TEST lemm_test.o -C ../../linker_scripts/apple2_4000.inc + +lemm_test.o: lemm_test.s zp.inc hardware.inc \ + graphics/graphics_test.inc + ca65 -o lemm_test.o lemm_test.s -l lemm_test.lst + +#### + +graphics/graphics_test.inc: + cd graphics && make + +#### + +clean: + rm -f *~ *.o *.lst HELLO LEMM + diff --git a/games/lemm/decompress_fast_v2.s b/games/lemm/decompress_fast_v2.s new file mode 100644 index 00000000..fb2f24ad --- /dev/null +++ b/games/lemm/decompress_fast_v2.s @@ -0,0 +1,370 @@ +; note -- modified by Vince Weaver to assemble with ca65 +; in this case, A = page to decompress to +; getsrc_smc+1, getsrc_smc+2 is src location + +; ----------------------------------------------------------------------------- +; Decompress raw LZSA2 block. +; Create one with lzsa -r -f2 +; +; in: +; * LZSA_SRC_LO and LZSA_SRC_HI contain the compressed raw block address +; * LZSA_DST_LO and LZSA_DST_HI contain the destination buffer address +; +; out: +; * LZSA_DST_LO and LZSA_DST_HI contain the last decompressed byte address, +1 +; +; ----------------------------------------------------------------------------- +; Backward decompression is also supported, use lzsa -r -b -f2 +; To use it, also define BACKWARD_DECOMPRESS=1 before including this code! +; +; in: +; * LZSA_SRC_LO/LZSA_SRC_HI must contain the address of the last byte of compressed data +; * LZSA_DST_LO/LZSA_DST_HI must contain the address of the last byte of the destination buffer +; +; out: +; * LZSA_DST_LO/LZSA_DST_HI contain the last decompressed byte address, -1 +; +; ----------------------------------------------------------------------------- +; +; Copyright (C) 2019 Emmanuel Marty, Peter Ferrie +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. +; ----------------------------------------------------------------------------- + +;NIBCOUNT = $FC ; zero-page location for temp offset + +decompress_lzsa2_fast: + + sta LZSA_DST_HI + + ldy #$00 + sty LZSA_DST_LO + sty NIBCOUNT + +decode_token: + jsr getsrc ; read token byte: XYZ|LL|MMM + pha ; preserve token on stack + + and #$18 ; isolate literals count (LL) + beq no_literals ; skip if no literals to copy + cmp #$18 ; LITERALS_RUN_LEN_V2? + bcc prepare_copy_literals ; if less, count is directly embedded in token + + jsr getnibble ; get extra literals length nibble + ; add nibble to len from token + adc #$02 ; (LITERALS_RUN_LEN_V2) minus carry + cmp #$12 ; LITERALS_RUN_LEN_V2 + 15 ? + bcc prepare_copy_literals_direct ; if less, literals count is complete + + jsr getsrc ; get extra byte of variable literals count + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + sbc #$EE ; overflow? + jmp prepare_copy_literals_direct + +prepare_copy_literals_large: + ; handle 16 bits literals count + ; literals count = directly these 16 bits + jsr getlargesrc ; grab low 8 bits in X, high 8 bits in A + tay ; put high 8 bits in Y + bcs prepare_copy_literals_high ; (*same as JMP PREPARE_COPY_LITERALS_HIGH but shorter) + +prepare_copy_literals: + lsr ; shift literals count into place + lsr + lsr + +prepare_copy_literals_direct: + tax + bcs prepare_copy_literals_large ; if so, literals count is large + +prepare_copy_literals_high: + txa + beq copy_literals + iny + +copy_literals: + jsr getput ; copy one byte of literals + dex + bne copy_literals + dey + bne copy_literals + +no_literals: + pla ; retrieve token from stack + pha ; preserve token again + asl + bcs repmatch_or_large_offset ; 1YZ: rep-match or 13/16 bit offset + + asl ; 0YZ: 5 or 9 bit offset + bcs offset_9_bit + + ; 00Z: 5 bit offset + + ldx #$FF ; set offset bits 15-8 to 1 + + jsr getcombinedbits ; rotate Z bit into bit 0, read nibble for bits 4-1 + ora #$E0 ; set bits 7-5 to 1 + bne got_offset_lo ; go store low byte of match offset and prepare match + +offset_9_bit: ; 01Z: 9 bit offset + ;;asl ; shift Z (offset bit 8) in place + rol + rol + and #$01 + eor #$FF ; set offset bits 15-9 to 1 + bne got_offset_hi ; go store high byte, read low byte of match offset and prepare match + ; (*same as JMP GOT_OFFSET_HI but shorter) + +repmatch_or_large_offset: + asl ; 13 bit offset? + bcs repmatch_or_16bit ; handle rep-match or 16-bit offset if not + + ; 10Z: 13 bit offset + + jsr getcombinedbits ; rotate Z bit into bit 8, read nibble for bits 12-9 + adc #$DE ; set bits 15-13 to 1 and substract 2 (to substract 512) + bne got_offset_hi ; go store high byte, read low byte of match offset and prepare match + ; (*same as JMP GOT_OFFSET_HI but shorter) + +repmatch_or_16bit: ; rep-match or 16 bit offset + ;;ASL ; XYZ=111? + bmi rep_match ; reuse previous offset if so (rep-match) + + ; 110: handle 16 bit offset + jsr getsrc ; grab high 8 bits +got_offset_hi: + tax + jsr getsrc ; grab low 8 bits +got_offset_lo: + sta OFFSLO ; store low byte of match offset + stx OFFSHI ; store high byte of match offset + +rep_match: +.ifdef BACKWARD_DECOMPRESS + + ; Backward decompression - substract match offset + + sec ; add dest + match offset + lda putdst+1 ; low 8 bits +OFFSLO = *+1 + sbc #$AA + sta copy_match_loop+1 ; store back reference address + lda putdst+2 +OFFSHI = *+1 + sbc #$AA ; high 8 bits + sta copy_match_loop+2 ; store high 8 bits of address + sec + +.else + + ; Forward decompression - add match offset + + clc ; add dest + match offset + lda putdst+1 ; low 8 bits +OFFSLO = *+1 + adc #$AA + sta copy_match_loop+1 ; store back reference address +OFFSHI = *+1 + lda #$AA ; high 8 bits + adc putdst+2 + sta copy_match_loop+2 ; store high 8 bits of address +.endif + + pla ; retrieve token from stack again + and #$07 ; isolate match len (MMM) + adc #$01 ; add MIN_MATCH_SIZE_V2 and carry + cmp #$09 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2? + bcc prepare_copy_match ; if less, length is directly embedded in token + + jsr getnibble ; get extra match length nibble + ; add nibble to len from token + adc #$08 ; (MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2) minus carry + cmp #$18 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15? + bcc prepare_copy_match ; if less, match length is complete + + jsr getsrc ; get extra byte of variable match length + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + sbc #$E8 ; overflow? + +prepare_copy_match: + tax + bcc prepare_copy_match_y ; if not, the match length is complete + beq decompression_done ; if EOD code, bail + + ; Handle 16 bits match length + jsr getlargesrc ; grab low 8 bits in X, high 8 bits in A + tay ; put high 8 bits in Y + +prepare_copy_match_y: + txa + beq copy_match_loop + iny + +copy_match_loop: + lda $AAAA ; get one byte of backreference + jsr putdst ; copy to destination + +.ifdef BACKWARD_DECOMPRESS + + ; Backward decompression -- put backreference bytes backward + + lda copy_match_loop+1 + beq getmatch_adj_hi +getmatch_done: + dec copy_match_loop+1 + +.else + + ; Forward decompression -- put backreference bytes forward + + inc copy_match_loop+1 + beq getmatch_adj_hi +getmatch_done: + +.endif + + dex + bne copy_match_loop + dey + bne copy_match_loop + jmp decode_token + +.ifdef BACKWARD_DECOMPRESS + +getmatch_adj_hi: + dec copy_match_loop+2 + jmp getmatch_done + +.else + +getmatch_adj_hi: + inc copy_match_loop+2 + jmp getmatch_done +.endif + +getcombinedbits: + eor #$80 + asl + php + + jsr getnibble ; get nibble into bits 0-3 (for offset bits 1-4) + plp ; merge Z bit as the carry bit (for offset bit 0) +combinedbitz: + rol ; nibble -> bits 1-4; carry(!Z bit) -> bit 0 ; carry cleared +decompression_done: + rts + +getnibble: +NIBBLES = *+1 + lda #$AA + lsr NIBCOUNT + bcc need_nibbles + and #$0F ; isolate low 4 bits of nibble + rts + +need_nibbles: + inc NIBCOUNT + jsr getsrc ; get 2 nibbles + sta NIBBLES + lsr + lsr + lsr + lsr + sec + rts + +.ifdef BACKWARD_DECOMPRESS + + ; Backward decompression -- get and put bytes backward + +getput: + jsr getsrc +putdst: +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 + sta $AAAA + lda putdst+1 + beq putdst_adj_hi + dec putdst+1 + rts + +putdst_adj_hi: + dec putdst+2 + dec putdst+1 + rts + +getlargesrc: + jsr getsrc ; grab low 8 bits + tax ; move to X + ; fall through grab high 8 bits + +getsrc: +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 + lda $AAAA + pha + lda getsrc+1 + beq getsrc_adj_hi + dec getsrc+1 + pla + rts + +getsrc_adj_hi: + dec getsrc+2 + dec getsrc+1 + pla + rts + +.else + + ; Forward decompression -- get and put bytes forward + +getput: + jsr getsrc +putdst: +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 + sta $AAAA + inc putdst+1 + beq putdst_adj_hi + rts + +putdst_adj_hi: + inc putdst+2 + rts + +getlargesrc: + jsr getsrc ; grab low 8 bits + tax ; move to X + ; fall through grab high 8 bits + +getsrc: +getsrc_smc: +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 + lda $AAAA + inc getsrc+1 + beq getsrc_adj_hi + rts + +getsrc_adj_hi: + inc getsrc+2 + rts +.endif + diff --git a/games/lemm/graphics/Makefile b/games/lemm/graphics/Makefile new file mode 100644 index 00000000..16d27ece --- /dev/null +++ b/games/lemm/graphics/Makefile @@ -0,0 +1,48 @@ +PNG2RLE = ../../../utils/gr-utils/png2rle +PNG2GR = ../../../utils/gr-utils/png2gr +PNG2HGR = ../../../utils/hgr-utils/png2hgr +LZSA = ~/research/lzsa/lzsa/lzsa +B2D = ../../../utils/bmp2dhr/b2d + +all: graphics_test.inc + +### + +graphics_test.inc: \ + level1.lzsa \ + level2.lzsa \ + level2_actual.lzsa + echo "level1_lzsa: .incbin \"level1.lzsa\"" > graphics_test.inc + echo "level2_lzsa: .incbin \"level2.lzsa\"" >> graphics_test.inc + echo "level2_actual_lzsa: .incbin \"level2_actual.lzsa\"" >> graphics_test.inc + +### + +level1.lzsa: level1.hgr + $(LZSA) -r -f2 level1.hgr level1.lzsa + +level1.hgr: level1.png + $(PNG2HGR) level1.png > level1.hgr + +### + +level2.lzsa: level2.hgr + $(LZSA) -r -f2 level2.hgr level2.lzsa + +level2.hgr: level2.png + $(PNG2HGR) level2.png > level2.hgr + +### + +level2_actual.lzsa: level2_actual.hgr + $(LZSA) -r -f2 level2_actual.hgr level2_actual.lzsa + +level2_actual.hgr: level2_actual.png + $(PNG2HGR) level2_actual.png > level2_actual.hgr + +#### + +clean: + rm -f *~ graphics_test.inc \ + *.lzsa *.gr *.hgr + diff --git a/games/lemm/graphics/level1.png b/games/lemm/graphics/level1.png new file mode 100644 index 00000000..3416f8c9 Binary files /dev/null and b/games/lemm/graphics/level1.png differ diff --git a/games/lemm/graphics/level2.png b/games/lemm/graphics/level2.png new file mode 100644 index 00000000..71252073 Binary files /dev/null and b/games/lemm/graphics/level2.png differ diff --git a/games/lemm/graphics/level2_actual.png b/games/lemm/graphics/level2_actual.png new file mode 100644 index 00000000..7e6df58f Binary files /dev/null and b/games/lemm/graphics/level2_actual.png differ diff --git a/games/lemm/hardware.inc b/games/lemm/hardware.inc new file mode 100644 index 00000000..905b8dd8 --- /dev/null +++ b/games/lemm/hardware.inc @@ -0,0 +1,98 @@ +;; HARDWARE LOCATIONS + +KEYPRESS = $C000 +KEYRESET = $C010 + +;; SOFT SWITCHES +CLR80COL = $C000 ; PAGE0/PAGE1 normal +SET80COL = $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead +EIGHTYCOLOFF = $C00C +EIGHTYCOLON = $C00D +TBCOLOR = $C022 ; IIgs text foreground / background colors +NEWVIDEO = $C029 ; IIgs graphics modes +SPEAKER = $C030 +CLOCKCTL = $C034 ; bits 0-3 are IIgs border color +SET_GR = $C050 +SET_TEXT = $C051 +FULLGR = $C052 +TEXTGR = $C053 +PAGE0 = $C054 +PAGE1 = $C055 +LORES = $C056 ; Enable LORES graphics +HIRES = $C057 ; Enable HIRES graphics +AN3 = $C05E ; Annunciator 3 + + + + + + + +PADDLE_BUTTON0 = $C061 +PADDL0 = $C064 +PTRIG = $C070 + +;; BASIC ROUTINES + +NORMAL = $F273 + +;; MONITOR ROUTINES + +HLINE = $F819 ;; HLINE Y,$2C at A +VLINE = $F828 ;; VLINE A,$2D at Y +CLRSCR = $F832 ;; Clear low-res screen +CLRTOP = $F836 ;; clear only top of low-res screen +SETCOL = $F864 ;; COLOR=A +ROM_TEXT2COPY = $F962 ;; iigs +TEXT = $FB36 +TABV = $FB5B ;; VTAB to A +ROM_MACHINEID = $FBB3 ;; iigs +BELL = $FBDD ;; ring the bell +BASCALC = $FBC1 ;; +VTAB = $FC22 ;; VTAB to CV +HOME = $FC58 ;; Clear the text screen +WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us +CROUT1 = $FD8B +SETINV = $FE80 ;; INVERSE +SETNORM = $FE84 ;; NORMAL +COUT = $FDED ;; output A to screen +COUT1 = $FDF0 ;; output A to screen + + + + + + + +COLOR_BLACK = 0 +COLOR_RED = 1 +COLOR_DARKBLUE = 2 +COLOR_PURPLE = 3 +COLOR_DARKGREEN = 4 +COLOR_GREY = 5 +COLOR_MEDIUMBLUE = 6 +COLOR_LIGHTBLUE = 7 +COLOR_BROWN = 8 +COLOR_ORANGE = 9 +COLOR_GREY2 = 10 +COLOR_PINK = 11 +COLOR_LIGHTGREEN = 12 +COLOR_YELLOW = 13 +COLOR_AQUA = 14 +COLOR_WHITE = 15 + +COLOR_BOTH_BLACK = $00 +COLOR_BOTH_RED = $11 +COLOR_BOTH_DARKBLUE = $22 +COLOR_BOTH_DARKGREEN = $44 +COLOR_BOTH_GREY = $55 +COLOR_BOTH_MEDIUMBLUE = $66 +COLOR_BOTH_LIGHTBLUE = $77 +COLOR_BOTH_BROWN = $88 +COLOR_BOTH_ORANGE = $99 +COLOR_BOTH_PINK = $BB +COLOR_BOTH_LIGHTGREEN = $CC +COLOR_BOTH_YELLOW = $DD +COLOR_BOTH_AQUA = $EE +COLOR_BOTH_WHITE = $FF + diff --git a/games/lemm/hello.bas b/games/lemm/hello.bas new file mode 100644 index 00000000..6ce4ca9f --- /dev/null +++ b/games/lemm/hello.bas @@ -0,0 +1,15 @@ +5 HOME +10 PRINT "LOADING LEMM V0.01" +20 PRINT " LEMM PROOF-OF-CONCEPT DEMAKE" +30 PRINT:PRINT +70 PRINT "BASED ON LEMMINGS BY DMA DESIGN" +75 PRINT:PRINT +80 PRINT "APPLE II PORT: VINCE WEAVER" +90 PRINT "DISK CODE : QKUMBA" +94 PRINT "LZSA CODE : EMMANUEL MARTY" +95 PRINT +100 PRINT " ______" +110 PRINT " A \/\/\/ SOFTWARE PRODUCTION" +115 PRINT +120 PRINT " HTTP://WWW.DEATER.NET/WEAVE/VMWPROD" +130 PRINT CHR$(4)"CATALOG" diff --git a/games/lemm/lemm_test.s b/games/lemm/lemm_test.s new file mode 100644 index 00000000..658868b5 --- /dev/null +++ b/games/lemm/lemm_test.s @@ -0,0 +1,233 @@ +; Lemm Test + +; by deater (Vince Weaver) + +; Zero Page + .include "zp.inc" + .include "hardware.inc" + +lemm_test_start: + ;=================== + ; init screen + ;=================== + + jsr TEXT + jsr HOME + bit KEYRESET + + bit SET_GR + bit PAGE0 + bit HIRES + bit FULLGR + + ;=================== + ; machine workarounds + ;=================== + ; mostly IIgs + ;=================== + ; thanks to 4am who provided this code from Total Replay + + lda ROM_MACHINEID + cmp #$06 + bne not_a_iigs + sec + jsr $FE1F ; check for IIgs + bcs not_a_iigs + + ; gr/text page2 handling broken on early IIgs models + ; this enables the workaround + + jsr ROM_TEXT2COPY ; set alternate display mode on IIgs + cli ; enable VBL interrupts + + ; also set background color to black instead of blue + lda NEWVIDEO + and #%00011111 ; bit 7 = 0 -> IIgs Apple II-compat video modes + ; bit 6 = 0 -> IIgs 128K memory map same as IIe + ; bit 5 = 0 -> IIgs DHGR is color, not mono + ; bits 0-4 unchanged + sta NEWVIDEO + lda #$F0 + sta TBCOLOR ; white text on black background + lda #$00 + sta CLOCKCTL ; black border + sta CLOCKCTL ; set twice for VidHD + +not_a_iigs: + + ;=================== + ; Load hires graphics + ;=================== +load_graphics_loop: + + lda #level1_lzsa + sta getsrc_smc+2 ; LZSA_SRC_HI + + lda #$20 + + jsr decompress_lzsa2_fast + + jsr wait_until_keypress + + lda #level2_lzsa + sta getsrc_smc+2 ; LZSA_SRC_HI + + lda #$20 + + jsr decompress_lzsa2_fast + + jsr wait_until_keypress + + lda #level2_actual_lzsa + sta getsrc_smc+2 ; LZSA_SRC_HI + + lda #$20 + + jsr decompress_lzsa2_fast + + jsr wait_until_keypress + + + + jmp load_graphics_loop + + ;=================================== + ; detect if we have a language card + ; and load sound into it if possible + ;=================================== + +; lda #0 +; sta SOUND_STATUS ; clear out, sound enabled + +; jsr detect_language_card +; bcs no_language_card + + ; update sound status +; lda SOUND_STATUS +; ora #SOUND_IN_LC +; sta SOUND_STATUS + + ; load sounds into LC + + ; read ram, write ram, use $d000 bank1 +; bit $C08B +; bit $C08B + +; lda #linking_noise_compressed +; sta getsrc_smc+2 + +; lda #$D0 ; decompress to $D000 + +; jsr decompress_lzsa2_fast + +;blah: + + ; read rom, nowrite, use $d000 bank1 +; bit $C08A + +no_language_card: + + ;=================================== + ; Setup Mockingboard + ;=================================== +; lda #0 +; sta DONE_PLAYING +; sta LOOP + + ; detect mockingboard +; jsr mockingboard_detect + +; bcc mockingboard_notfound + +mockingboard_found: +;; jsr mockingboard_patch ; patch to work in slots other than 4? + +; lda SOUND_STATUS +; ora #SOUND_MOCKINGBOARD +; sta SOUND_STATUS + + ;======================= + ; Set up 50Hz interrupt + ;======================== + +; jsr mockingboard_init +; jsr mockingboard_setup_interrupt + + ;============================ + ; Init the Mockingboard + ;============================ + +; jsr reset_ay_both +; jsr clear_ay_both + + ;================== + ; init song + ;================== + +; jsr pt3_init_song + +; jmp done_setup_sound + + +mockingboard_notfound: + + +done_setup_sound: + + + + + ;========================== + ; includes + ;========================== + +; .include "gr_pageflip.s" +; .include "gr_copy.s" +; .include "wait_a_bit.s" +; .include "gr_offsets.s" + .include "decompress_fast_v2.s" + + .include "wait_keypress.s" + +; .include "print_help.s" +; .include "gr_fast_clear.s" +; .include "text_print.s" + +; .include "init_vars.s" +; .include "graphics_title/title_graphics.inc" +; .include "lc_detect.s" + + + ; pt3 player +; .include "pt3_lib_core.s" +; .include "pt3_lib_init.s" +; .include "interrupt_handler.s" +; .include "pt3_lib_mockingboard_detect.s" +; .include "pt3_lib_mockingboard_setup.s" + +new_title: +.include "graphics/graphics_test.inc" + + + + + + + + + + +;PT3_LOC = theme_music + +;.align $100 +;theme_music: +;.incbin "audio/theme.pt3" + diff --git a/games/lemm/music/Lemmings5.ym b/games/lemm/music/Lemmings5.ym new file mode 100644 index 00000000..eb177a11 Binary files /dev/null and b/games/lemm/music/Lemmings5.ym differ diff --git a/games/lemm/music/Makefile b/games/lemm/music/Makefile new file mode 100644 index 00000000..bd18bd43 --- /dev/null +++ b/games/lemm/music/Makefile @@ -0,0 +1,72 @@ +LZSA = ~/research/lzsa/lzsa/lzsa +YM5_TO_RAW = ~/research/vmw-meter.git/ay-3-8910/conversion_tools/ym5_to_raw + + + + +all: lemmings5.part1.lzsa lemmings5.part2.lzsa lemmings5.part3.lzsa \ + lemmings5.part4.lzsa lemmings5.part5.lzsa lemmings5.part6.lzsa \ + lemmings5.part7.lzsa lemmings5.part8.lzsa + +Lemmings5.raw: Lemmings5.ym + $(YM5_TO_RAW) ./Lemmings5.ym > Lemmings5.raw + + +lemmings5.part1: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part1 bs=4096 count=1 seek=0 skip=0 + +lemmings5.part1.lzsa: lemmings5.part1 + $(LZSA) -r -f2 lemmings5.part1 lemmings5.part1.lzsa + + +lemmings5.part2: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part2 bs=4096 count=1 seek=1 skip=1 + +lemmings5.part2.lzsa: lemmings5.part2 + $(LZSA) -r -f2 lemmings5.part2 lemmings5.part2.lzsa + + +lemmings5.part3: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part3 bs=4096 count=1 seek=2 skip=2 + +lemmings5.part3.lzsa: lemmings5.part3 + $(LZSA) -r -f2 lemmings5.part3 lemmings5.part3.lzsa + + +lemmings5.part4: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part4 bs=4096 count=1 seek=3 skip=3 + +lemmings5.part4.lzsa: lemmings5.part4 + $(LZSA) -r -f2 lemmings5.part4 lemmings5.part4.lzsa + + +lemmings5.part5: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part5 bs=4096 count=1 seek=4 skip=4 + +lemmings5.part5.lzsa: lemmings5.part5 + $(LZSA) -r -f2 lemmings5.part5 lemmings5.part5.lzsa + + +lemmings5.part6: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part6 bs=4096 count=1 seek=5 skip=5 + +lemmings5.part6.lzsa: lemmings5.part6 + $(LZSA) -r -f2 lemmings5.part1 lemmings5.part1.lzsa + + +lemmings5.part7: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part7 bs=4096 count=1 seek=6 skip=6 + +lemmings5.part7.lzsa: lemmings5.part7 + $(LZSA) -r -f2 lemmings5.part7 lemmings5.part7.lzsa + + +lemmings5.part8: Lemmings5.raw + dd conv=notrunc if=Lemmings5.raw of=lemmings5.part8 bs=4096 count=1 seek=7 skip=7 + +lemmings5.part8.lzsa: lemmings5.part8 + $(LZSA) -r -f2 lemmings5.part8 lemmings5.part8.lzsa + + +clean: + rm -f *.lzsa *.part1 *.part2 *.part3 *.part4 *.part5 *.part6 *.part7 *.part8 diff --git a/games/lemm/wait_keypress.s b/games/lemm/wait_keypress.s new file mode 100644 index 00000000..444d2074 --- /dev/null +++ b/games/lemm/wait_keypress.s @@ -0,0 +1,5 @@ +wait_until_keypress: + lda KEYPRESS ; 4 + bpl wait_until_keypress ; 3 + bit KEYRESET ; clear the keyboard buffer + rts ; 6 diff --git a/games/lemm/zp.inc b/games/lemm/zp.inc new file mode 100644 index 00000000..79c4e7db --- /dev/null +++ b/games/lemm/zp.inc @@ -0,0 +1,200 @@ +;; Zero Page + +;; LZSA addresses +NIBCOUNT = $00 + +;; Zero page monitor routines addresses + +WNDLFT = $20 +WNDWDTH = $21 +WNDTOP = $22 +WNDBTM = $23 +CH = $24 +CV = $25 +GBASL = $26 +GBASH = $27 +BASL = $28 +BASH = $29 +H2 = $2C +X_LEFT = $2C +V2 = $2D +MASK = $2E +COLOR_MASK = $2F +COLOR = $30 + +SEEDL = $4e +SEEDH = $4f +XMAX = $50 + + + +; MIST zero page addresses + +FRAMEL = $60 +FRAMEH = $61 +;CURSOR_X = $62 +;CURSOR_Y = $63 +XPOS = $64 +YPOS = $65 +LOCATION_STRUCT_L = $66 +LOCATION_STRUCT_H = $67 +IN_SPECIAL = $68 +CURSOR_VISIBLE = $69 +IN_LEFT = $6A +IN_RIGHT = $6B +BTC_L = $6C +BTC_H = $6D + +; pt3 player registers +REGISTER_DUMP = $70 +AY_REGISTERS = $70 +A_FINE_TONE = $70 +A_COARSE_TONE = $71 +B_FINE_TONE = $72 +B_COARSE_TONE = $73 +C_FINE_TONE = $74 +C_COARSE_TONE = $75 +NOISE = $76 +ENABLE = $77 +PT3_MIXER_VAL = $77 +A_VOLUME = $78 +B_VOLUME = $79 +C_VOLUME = $7A +ENVELOPE_FINE = $7B +ENVELOPE_COARSE = $7C +ENVELOPE_SHAPE = $7D +COPY_OFFSET = $7E +DECODER_STATE = $7F + +PATTERN_L = $7E +PATTERN_H = $7F + + +; note 70-7f also used by disk code + +; note: rest are up at $f0 + +; We have to save/restore the following values +; when loading/storing from disk + +WHICH_LOAD = $80 ; which file to load + +DUKE_XL = $81 +DUKE_X = $82 ; location of protagonist +DUKE_Y = $83 +DUKE_DIRECTION = $84 +DUKE_WALKING = $85 +DUKE_JUMPING = $86 + +LASER_OUT = $87 +LASER_X = $88 +LASER_Y = $89 +LASER_DIRECTION = $8A +TILEMAP_X = $8B +TILEMAP_Y = $8C + +DUKE_FOOT_OFFSET = $8D + +FIREPOWER = $8E +INVENTORY = $8F + INV_RED_KEY = $80 + INV_BLUE_KEY = $20 + INV_SHOE = $08 + INV_GRIP = $02 +HEALTH = $90 +SCORE0 = $91 +SCORE1 = $92 +SCORE2 = $93 +UPDATE_STATUS = $94 + +DUKE_FALLING = $95 +DUKE_SHOOTING = $96 +KICK_UP_DUST = $97 +SUPPRESS_WALK = $98 +ENEMY_DATAL = $99 +ENEMY_DATAH = $9A +DOOR_ACTIVATED = $9B +LASER_TILE = $9C +TILE_TEMP = $9D + +; done game puzzle state + + +WHICH_SLOT = $DA +JS_BUTTON_STATE = $DB +CURRENT_DISK = $DC +JOYSTICK_ENABLED= $DD +SOUND_STATUS = $DE + SOUND_DISABLED = $80 + SOUND_IN_LC = $01 ; $01 sound effects in language card + SOUND_MOCKINGBOARD = $02 ; mockingboard detected + +GRID_PAGE = $DF +ANIMATE_FRAME = $E0 +LEVEL_OVER = $E1 + GAME_OVER = $FF + NEXT_LEVEL = $01 +LOCATIONS_L = $E2 +LOCATIONS_H = $E3 + +; temp var per-world define +LONG_FRAME = $E4 ; nibel +CURRENT_DISPLAY = $E4 ; selena +LAST_PLAYED = $E4 ; selena + +DISP_PAGE = $ED ; ALL +DRAW_PAGE = $EE ; ALL + +; rest of pt3_player +MB_DETECTED = $EF +WHICH_CHUNK = $F0 +MB_CHUNK_OFFSET = $F1 +LOOP = $F4 +MB_VALUE = $F5 +MB_ADDR_L = $F6 +MB_ADDR_H = $F7 +DONE_PLAYING = $F8 +DONE_SONG = $F9 + +; rest of pt3_player +PT3_TEMP = $EF +ORNAMENT_L = $F0 +ORNAMENT_H = $F1 +SAMPLE_L = $F2 +SAMPLE_H = $F3 + + + + + + +TEMP = $FA +TEMPY = $FB +INL = $FC +INH = $FD +OUTL = $FE +OUTH = $FF + +; read any file slot 6 version +; based on FASTLD6 and RTS copyright (c) Peter Ferrie 2011-2013,2018 + +; modified to assemble with ca65 -- vmw +; added code to patch it to run from current disk slot -- vmw + + + adrlo = $26 ; constant from boot prom + adrhi = $27 ; constant from boot prom + tmpsec = $3c ; constant from boot prom + reqsec = $3d ; constant from boot prom + sizelo = $44 + sizehi = $45 + secsize = $46 + + ldsizel = $70 + ldsizeh = $71 + namlo = $7b + namhi = $7c + step = $7d ; state for stepper motor + tmptrk = $7e ; temporary copy of current track + phase = $7f ; current phase for /seek +