From 064fd3bf10a531b1029c5629d180f413ba5503d8 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sun, 12 May 2024 22:21:30 -0400 Subject: [PATCH] riven_hgr: poc --- games/riven_hgr/Makefile | 65 +++ games/riven_hgr/common_defines.inc | 4 + games/riven_hgr/graphics/Makefile | 36 ++ games/riven_hgr/graphics/maglev1.png | Bin 0 -> 8354 bytes games/riven_hgr/hardware.inc | 99 ++++ games/riven_hgr/hardware_detect.s | 153 ++++++ games/riven_hgr/hello.bas | 14 + games/riven_hgr/hgr_sprite.s | 88 ++++ games/riven_hgr/hgr_tables.s | 146 ++++++ games/riven_hgr/loader.s | 750 +++++++++++++++++++++++++++ games/riven_hgr/main.s | 518 ++++++++++++++++++ games/riven_hgr/zp.inc | 249 +++++++++ games/riven_hgr/zx02_optim.s | 163 ++++++ 13 files changed, 2285 insertions(+) create mode 100644 games/riven_hgr/Makefile create mode 100644 games/riven_hgr/common_defines.inc create mode 100644 games/riven_hgr/graphics/Makefile create mode 100644 games/riven_hgr/graphics/maglev1.png create mode 100644 games/riven_hgr/hardware.inc create mode 100644 games/riven_hgr/hardware_detect.s create mode 100644 games/riven_hgr/hello.bas create mode 100644 games/riven_hgr/hgr_sprite.s create mode 100644 games/riven_hgr/hgr_tables.s create mode 100644 games/riven_hgr/loader.s create mode 100644 games/riven_hgr/main.s create mode 100644 games/riven_hgr/zp.inc create mode 100644 games/riven_hgr/zx02_optim.s diff --git a/games/riven_hgr/Makefile b/games/riven_hgr/Makefile new file mode 100644 index 00000000..f9b9624f --- /dev/null +++ b/games/riven_hgr/Makefile @@ -0,0 +1,65 @@ +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: riven_hgr.dsk + +riven_hgr.dsk: HELLO LOADER MAIN + cp $(EMPTY_DISK) riven_hgr.dsk + $(DOS33) -y riven_hgr.dsk SAVE A HELLO + $(DOS33) -y riven_hgr.dsk BSAVE -a 0x1000 LOADER + $(DOS33) -y riven_hgr.dsk BSAVE -a 0x4000 MAIN +# $(DOS33) -y riven_hgr.dsk BSAVE -a 0x4000 MARS + +### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + +#### + +LOADER: loader.o + ld65 -o LOADER loader.o -C ../../linker_scripts/apple2_1000.inc + +loader.o: loader.s hardware_detect.s + ca65 -o loader.o loader.s -l loader.lst + +#### + +MAIN: main.o + ld65 -o MAIN main.o -C ../../linker_scripts/apple2_4000.inc + +main.o: main.s zp.inc hardware.inc \ + zx02_optim.s \ + hgr_sprite.s hgr_tables.s \ + graphics/maglev1.hgr.zx02 + ca65 -o main.o main.s -l main.lst + +#### + +#MARS: mars.o +# ld65 -o MARS mars.o -C ../../linker_scripts/apple2_4000.inc + +#mars.o: mars.s zp.inc hardware.inc game_over.s \ +# gr_fade.s \ +# mars_keyboard.s draw_tilemap.s \ +# mars_sfx.s longer_sound.s \ +# text_help.s tilemap_lookup.s \ +# maps/mars_map.zx02 graphics/parts.gr.zx02 +# ca65 -o mars.o mars.s -l mars.lst + +#### + +clean: + rm -f *~ *.o *.lst HELLO LOADER MAIN +# cd graphics && make clean +# cd maps && make clean +# cd title && make clean +# cd sprites && make clean diff --git a/games/riven_hgr/common_defines.inc b/games/riven_hgr/common_defines.inc new file mode 100644 index 00000000..6ce1e663 --- /dev/null +++ b/games/riven_hgr/common_defines.inc @@ -0,0 +1,4 @@ +LOAD_TITLE = 0 +LOAD_MAIN = 1 + + diff --git a/games/riven_hgr/graphics/Makefile b/games/riven_hgr/graphics/Makefile new file mode 100644 index 00000000..1a5fe14c --- /dev/null +++ b/games/riven_hgr/graphics/Makefile @@ -0,0 +1,36 @@ +include ../../../Makefile.inc + +ZX02 = ~/research/6502_compression/zx02.git/build/zx02 -f +PNG_TO_HGR = ../../../utils/hgr-utils/png2hgr +LINKER_SCRIPTS = ../../../linker_scripts +DOS33 = ../../../utils/dos33fs-utils/dos33 +EMPTY_DISK = ../../../empty_disk/empty.dsk +TOKENIZE = ../../../utils/asoft_basic-utils/tokenize_asoft +PNG2GR = ../../../utils/gr-utils/png2gr +PNG2SPRITES = ../../../utils/gr-utils/png2sprites +HGR_SPRITE = ../../../utils/hgr-utils/hgr_make_sprite + +all: maglev1.hgr.zx02 + +#### + +#title_sprites.inc: title_sprites.png +# $(HGR_SPRITE) -s -l title_sprite title_sprites.png 0 0 167 95 > title_sprites.inc +# $(HGR_SPRITE) -s -l ball_bg title_sprites.png 0 96 6 104 >> title_sprites.inc +# $(HGR_SPRITE) -s -l ball0 title_sprites.png 0 105 6 113 >> title_sprites.inc +# $(HGR_SPRITE) -s -l ball1 title_sprites.png 0 114 6 122 >> title_sprites.inc +# $(HGR_SPRITE) -s -l ball2 title_sprites.png 0 123 6 131 >> title_sprites.inc + +#### + +maglev1.hgr.zx02: maglev1.hgr + $(ZX02) maglev1.hgr maglev1.hgr.zx02 + +maglev1.hgr: maglev1.png + $(PNG_TO_HGR) maglev1.png > maglev1.hgr + +#### + +clean: + rm -f *~ *.o *.lst *.zx02 *.hgr + diff --git a/games/riven_hgr/graphics/maglev1.png b/games/riven_hgr/graphics/maglev1.png new file mode 100644 index 0000000000000000000000000000000000000000..6d8daf705c1104339f61c4c929b87453747c850a GIT binary patch literal 8354 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 h!NE#8W?~C)_6hzT{!z~i 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_iigs: + + + + ;=========================== + ; Check Apple II model + ;=========================== + ; this is mostly for IIc support + ; as it does interrupts differently + + ; some of this info from the document: + ; Apple II Family Identification Routines 2.2 + ; + + ; ' ' = Apple II + ; '+' = Apple II+ + ; 'e' = Apple IIe + ; 'c' = Apple IIc + ; 'g' = Apple IIgs + ; 'm' = mac L/C with board + ; 'j' = jplus + ; '3' = Apple III + +detect_appleii_model: + lda #' ' + + ldx $FBB3 + + ; II is $38 + ; J-plus is $C9 + ; II+ is $EA (so is III) + ; IIe and newer is $06 + + cpx #$38 ; ii + beq done_apple_detect + + + ; ii+ is EA FB1E=AD + ; iii is EA FB1E=8A 00 + + cpx #$EA + bne not_ii_iii +ii_or_iii: + + lda #'+' ; ii+/iii + + ldx $FB1E + cpx #$AD + beq done_apple_detect ; ii+ + + lda #'3' + bne done_apple_detect ; bra iii + +not_ii_iii: + lda #'j' ; jplus + cpx #$C9 + beq done_apple_detect + + + cpx #$06 + bne done_apple_detect + +apple_iie_or_newer: + + + + ldx $FBC0 ; $EA on a IIe + ; $E0 on a IIe enhanced + ; $00 on a IIc/IIc+ + + ; $FE1F = $60, IIgs + + beq apple_iic + + lda #'e' + cpx #$EA + beq done_apple_detect +; cpx #$E0 +; beq done_apple_detect + + ; should do something if not $E0 + + ; GS and IIe enhanced are the same, need to check + + sec ; set carry + jsr $FE1F + bcs done_apple_detect ;If carry then IIe enhanced + + ; get here we're a IIgs? + + lda #'g' + bne done_apple_detect + +apple_iic: + lda #'c' + +done_apple_detect: + sta APPLEII_MODEL + rts diff --git a/games/riven_hgr/hello.bas b/games/riven_hgr/hello.bas new file mode 100644 index 00000000..cf1788d9 --- /dev/null +++ b/games/riven_hgr/hello.bas @@ -0,0 +1,14 @@ +5 HOME +10 PRINT "LOADING KEEN V0.08" +20 PRINT " KEEN1 PROOF-OF-CONCEPT DEMAKE" +30 PRINT:PRINT +70 PRINT "BASED ON KEEN1 BY ID" +75 PRINT:PRINT +80 PRINT "APPLE II PORT: VINCE WEAVER" +90 PRINT "DISK CODE : QKUMBA" +95 PRINT +100 PRINT " ______" +110 PRINT " A \/\/\/ SOFTWARE PRODUCTION" +115 PRINT +120 PRINT " HTTP://WWW.DEATER.NET/WEAVE/VMWPROD" +130 PRINT CHR$(4);"BRUN LOADER" diff --git a/games/riven_hgr/hgr_sprite.s b/games/riven_hgr/hgr_sprite.s new file mode 100644 index 00000000..7d8fab18 --- /dev/null +++ b/games/riven_hgr/hgr_sprite.s @@ -0,0 +1,88 @@ + ;=========================================== + ; hgr draw sprite (only at 7-bit boundaries) + ;=========================================== + ; SPRITE in INL/INH + ; Location at SPRITE_X SPRITE_Y + + ; xsize, ysize in first two bytes + + ; sprite AT INL/INH + +hgr_draw_sprite: + + ldy #0 + lda (INL),Y ; load xsize + clc + adc SPRITE_X + sta sprite_width_end_smc+1 ; self modify for end of line + + iny ; load ysize + lda (INL),Y + sta sprite_ysize_smc+1 ; self modify + + ; point smc to sprite + lda INL ; 16-bit add + sta sprite_smc1+1 + lda INH + sta sprite_smc1+2 + + + ldx #0 ; X is pointer offset + stx CURRENT_ROW ; actual row + + ldx #2 + +hgr_sprite_yloop: + + lda CURRENT_ROW ; row + + clc + adc SPRITE_Y ; add in cursor_y + + ; calc GBASL/GBASH + + tay ; get output ROW into GBASL/H + lda hposn_low,Y + sta GBASL + lda hposn_high,Y + + ; eor #$00 draws on page2 + ; eor #$60 draws on page1 +;hgr_sprite_page_smc: +; eor #$00 + clc + adc DRAW_PAGE + sta GBASH +; eor #$60 +; sta INH + + ldy SPRITE_X + +sprite_inner_loop: + + +sprite_smc1: + lda $f000,X ; load sprite data + sta (GBASL),Y ; store to screen + + inx ; increment sprite offset + bne not_oflo + inc sprite_smc1+2 +not_oflo: + iny ; increment output position + + +sprite_width_end_smc: + cpy #6 ; see if reached end of row + bne sprite_inner_loop ; if not, loop + + + inc CURRENT_ROW ; row + lda CURRENT_ROW ; row + +sprite_ysize_smc: + cmp #31 ; see if at end + bne hgr_sprite_yloop ; if not, loop + + rts + diff --git a/games/riven_hgr/hgr_tables.s b/games/riven_hgr/hgr_tables.s new file mode 100644 index 00000000..d98f96f8 --- /dev/null +++ b/games/riven_hgr/hgr_tables.s @@ -0,0 +1,146 @@ +;div7_table = $9C00 +;mod7_table = $9D00 +;hposn_high = $9E00 +;hposn_low = $9F00 + + + + ;===================== + ; make /7 %7 tables + ;===================== + + + ; HGR_PAGE should be $20/$40 to select if default for hposn + ; is page1 or page2 + +hgr_make_tables: + + ldy #0 + lda #0 + ldx #0 +div7_loop: + sta div7_table,Y + + inx + cpx #7 + bne div7_not7 + + clc + adc #1 + ldx #0 +div7_not7: + iny + bne div7_loop + + + ldy #0 + lda #0 +mod7_loop: + sta mod7_table,Y + clc + adc #1 + cmp #7 + bne mod7_not7 + lda #0 +mod7_not7: + iny + bne mod7_loop + + + ; Hposn table + + lda #0 +hposn_loop: + ldy #0 + ldx #0 + pha + jsr hposn ; (Y,X),(A) + pla + tax + + lda GBASL + sta hposn_low,X + + lda GBASH + sta hposn_high,X + + inx + txa + + cmp #192 + bne hposn_loop + + rts + + ; left masks + ; in memory on screen + ; x111 1111 1111111 start at 0 + ; x111 1110 0111111 start at 1 + ; x111 1100 0011111 start at 2 + ; ... + ; x100 0000 0000001 start at 6 + +left_masks: + .byte $FF,$FE,$FC,$F8, $F0,$E0,$C0 + + ; right masks + ; in memory on screen + ; x000 0001 1000000 end at 0 + ; x000 0011 1100000 end at 1 + ; x000 0111 1110000 end at 2 + ; ... + ; x011 1111 1111110 end at 5 + ; x111 1111 1111111 end at 6 +right_masks: + .byte $81,$83,$87, $8F,$9F,$BF,$FF + + + + + ; from the Apple II firmware +hposn: +; sta HGR_Y ; save Y and X positions +; stx HGR_X +; sty HGR_X+1 + + pha ; Y pos on stack + + and #$C0 ; calc base addr for Y-pos + + sta GBASL + lsr + lsr + ora GBASL + sta GBASL + pla + + sta GBASH + asl + asl + asl + rol GBASH + asl + rol GBASH + asl + ror GBASL + lda GBASH + + and #$1F + + ora HGR_PAGE ; default is $40 in this game + + sta GBASH + +; txa +; cpy #0 +; beq xpos_lessthan_256 +; ldy #35 +; adc #4 +;label_1: +; iny +;xpos_lessthan_256: +; sbc #7 +; bcs label_1 + + rts + diff --git a/games/riven_hgr/loader.s b/games/riven_hgr/loader.s new file mode 100644 index 00000000..467fc7ed --- /dev/null +++ b/games/riven_hgr/loader.s @@ -0,0 +1,750 @@ +; Loader for DUKE + +.include "zp.inc" +.include "hardware.inc" +.include "common_defines.inc" + +nibtbl = $300 ; nothing uses the bottom 128 bytes of $300, do they? +bit2tbl = $380 ; bit2tbl: .res 86 ; = nibtbl+128 +filbuf = $3D6 ; filbuf: .res 4 ; = bit2tbl+86 + +; read any file slot 6 version +; based on FASTLD6 and RTS copyright (c) Peter Ferrie 2011-2013,2018 + +; modified to assembled with ca65 -- vmw +; added code to patch it to run from current disk slot -- vmw + +; WHICH_LOAD = $7E ; thing to load +; 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 +; namlo = $f8 +; namhi = $f9 +; TEMPY = $fa +; step = $fd ; state for stepper motor +; tmptrk = $fe ; temporary copy of current track +; phase = $ff ; current phase for /seek +; OUTL = $fe ; for picking filename +; OUTH = $ff + + dirbuf = $c00 + ; note, don't put this immediately below + ; the value being read as destaddr-4 + ; is temporarily overwritten during read + ; process + + + FILENAME = $280 + + ;=================================================== + ;=================================================== + ; START / INIT + ;=================================================== + ;=================================================== + +loader_start: + + jsr hardware_detect + + lda #model_string + sta OUTH + + lda APPLEII_MODEL + sta model_string+17 + + cmp #'g' + bne go_print + + lda #'s' + sta model_string+18 + +go_print: + + ldy #0 +print_model: + lda (OUTL),Y + beq print_model_done + ora #$80 + sta $7d0,Y + iny + jmp print_model +print_model_done: + + + + + lda #LOAD_TITLE + sta WHICH_LOAD + + jsr init ; unhook DOS, init nibble table + + + ;=================================================== + ;=================================================== + ; SETUP THE FILENAME + ;=================================================== + ;=================================================== + +which_load_loop: + + ; update the which-file error message +; lda WHICH_LOAD +; tay +; lda which_disk,Y +; sta error_string+19 + + +; lda WHICH_LOAD +; cmp #2 +; bcc skip_engine_load +;engine_load: +; +; lda #engine_filename +; sta OUTH + +; jsr opendir_filename + +skip_engine_load: + + lda WHICH_LOAD + asl + + tay + lda filenames,Y + sta OUTL + lda filenames+1,Y + sta OUTH + +; lda WHICH_LOAD +; bne load_other + +load_intro: + lda #<$4000 + sta entry_smc+1 + lda #>$4000 + sta entry_smc+2 +; jmp actual_load + +;load_other: +; lda #<$2000 +; sta entry_smc+1 +; lda #>$2000 +; sta entry_smc+2 + +actual_load: + + ;=================================================== + ;=================================================== + ; SET UP DOS3.3 FILENAME + ;=================================================== + ;=================================================== + +load_file_and_execute: + + jsr opendir_filename + +entry_smc: + jsr $1000 ; jump to common entry point + + ; hope they updated the WHICH_LOAD value + + jmp which_load_loop + + + ;============================== + ; setup filename then open/load + +opendir_filename: + + ; clear out the filename with $A0 (space) + + lda #FILENAME + sta namhi + + ldy #29 +wipe_filename_loop: + lda #$A0 + sta (namlo),Y + dey + bpl wipe_filename_loop + + ldy #0 +copy_filename_loop: + lda (OUTL),Y + beq copy_filename_done + ora #$80 + sta (namlo),Y + iny + bne copy_filename_loop + +copy_filename_done: + jsr opendir ; open and read entire file into memory + + rts + +filenames: + .word main_filename + +main_filename: + .byte "MAIN",0 + + + ;=================================================== + ;=================================================== + ; INIT (build nibble table) + ;=================================================== + ;=================================================== + + ;unhook DOS and build nibble table + +init: + ; patch to use current drive + + ; locate input paramater list + jsr $3E3 + ; result is in A:Y + sta $FF + sty $FE + ldy #1 + lda ($FE),y + + ; list+1 should have slot<<8 + + + ora #$80 ; add in $80 + + ; c0e0 + sta mlsmc06+1 + + ; c0e8 + clc + adc #8 + sta mlsmc02+1 + sta mlsmc07+1 + + ; c0e9 + clc + adc #1 + sta mlsmc01+1 + + ; c0ec + clc + adc #3 + sta mlsmc03+1 + sta mlsmc04+1 + sta mlsmc05+1 + + jsr $fe93 ; clear COUT + jsr $fe89 ; clear KEYIN + + ;======================== + ; Create nibble table + ; Note: the table starts 16 bytes in, and is sparse + ; so it doesn't entirely look like the DOS33 table at + + ldy #0 + ldx #3 +L1: stx $3c ; store tempx (3?) + txa ; a=x (a=3) + asl ; a*=2 (a=6) + bit $3c ; a&tempx, set N/V (a=6) + beq L3 ; if 0, skip to L3 + ora $3c ; a|=tempx (a=7) + eor #$ff ; a=~a (a=f8) + and #$7e ; a&=0x7e 0111 1110 (a=78) +L2: bcs L3 ; this set way back at asl?? + lsr ; a>>1 a=3c c=0 + ; a=1e c=0 + ; a=0f c=0 + ; a=07 c=1 + bne L2 ; if a!=0 goto l2 + tya ; if a==0, a=y + sta nibtbl, x ; write out to table + iny ; increment y +L3: inx ; increment x x=4, a=0f + bpl L1 ; loop while high bit not set + + rts + + + ;=================================================== + ;=================================================== + ; file not found + ;=================================================== + ;=================================================== + +file_not_found: + +mlsmc07:lda $c0e8 ; turn off drive motor? + + jsr TEXT + jsr HOME + + ldy #0 + + lda #error_string + sta OUTH + +quick_print: + lda (OUTL),Y + beq quick_print_done + jsr COUT1 + iny +; jmp quick_print + +quick_print_done: + rts + +; jsr quick_print + +fnf_keypress: + lda KEYPRESS + bpl fnf_keypress + bit KEYRESET + + jmp which_load_loop + +; offset for disk number is 19 +error_string: +.byte "PLEASE INSERT DISK 1, PRESS RETURN",0 + +model_string: +.byte "DETECTED APPLE II",0,0,0 + + + + + ;=================================================== + ;=================================================== + ; OPENDIR: actually load the file + ;=================================================== + ;=================================================== + + ; turn on drive and read volume table of contents +opendir: +mlsmc01:lda $c0e9 ; turn slot#6 drive on + ldx #0 + stx adrlo ; zero out adrlo + stx secsize ; zero out secsize + lda #$11 ; a=$11 (VTOC) + jsr readdirsec +firstent: + + lda dirbuf+1 + + ; lock if entry not found +entry_not_found: + beq file_not_found + + ; read directory sector + + ldx dirbuf+2 + jsr seekread1 + ldy #7 ;number of directory entries in a sector + ldx #$2b ;offset of filename in directory entry +nextent: + tya + pha ; was **phy** + txa + pha ; was **phx** + ldy #$1d + + ; match name backwards (slower but smaller) + +L4: + lda (namlo), y + cmp dirbuf, x + beq foundname + pla + + ; move to next directory in this block, if possible + + clc + adc #$23 + tax + pla + tay ; was **ply** + dey + bne nextent + beq firstent ; was **bra** + +foundname: + dex + dey + bpl L4 + pla + tay ; was **ply** + pla + + ; read track/sector list + + lda dirbuf-32, y + ldx dirbuf-31, y + jsr seekread1 + + ; read load offset and length info only, initially + + lda #filbuf + jsr seekread + + ; reduce load offset by 4, to account for offset and length + + sec + lda filbuf + sbc #4 + sta adrlo + + lda filbuf+1 + sbc #0 + sta adrhi + + ; save on stack bytes that will be overwritten by extra read + + ldy #3 +L5: + lda (adrlo), y + pha + dey + bpl L5 + + lda adrhi + pha + lda adrlo + pha + + ; increase load size by 4, to account for offst and length + + lda filbuf+2 + adc #3 + sta sizelo + sta secsize + + lda filbuf+3 + adc #0 + sta sizehi + beq readfirst + lda #0 ; was **stz secsize** + sta secsize + +readfirst: + ldy #$0c + + ; read a file sector + +readnext: + tya + pha + lda dirbuf, y ; A = track + ldx dirbuf+1, y ; x = sector + jsr seekread1 + pla + tay + + ; if low count is non-zero then we are done + ; (can happen only for partial last block) + + lda secsize + bne readdone + + ; continue if more than $100 bytes left + + dec sizehi + bne L6 + + ; set read size to min(length, $100) + + lda sizelo + beq readdone + sta secsize +L6: + inc adrhi + iny + iny + bne readnext + + ; save current address for after t/s read + + lda adrhi + pha + lda adrlo + pha + lda #0 + sta adrlo ; was **stz adrlo** + + ; read next track/sector sector + + lda dirbuf+1 + ldx dirbuf+2 + jsr readdirsec + clc + + ; restore current address +readdone: + pla + sta adrlo ; code originally had this backwards + pla + sta adrhi + bcc readfirst + +mlsmc02:lda $c0e8 + + ; restore from stack bytes that were overwritten by extra read + + ldx #3 + ldy #0 +L7: + pla + sta (adrlo), y + iny + dex + bpl L7 + rts + + + ;====================== + ; readdirsec + ;====================== + ; a = track? + ; x = sector? +readdirsec: + ldy #>dirbuf +seekread: + sty adrhi +seekread1: + sta phase + lda sectbl, x + sta reqsec + jsr readadr + + ; if track does not match, then seek + + cpx phase + beq checksec + jsr seek + + + ;========================================= + ; re merge in with qkumba's recent changes + ; to fix seek problem? + ;========================================= + + ; [re-]read sector + +re_read_addr: + jsr readadr +checksec: + cmp reqsec + bne re_read_addr + + ;========================= + ; read sector data + ;========================= + +readdata: + jsr readd5aa + eor #$ad ; zero A if match + bne re_read_addr + +L12: +mlsmc03:ldx $c0ec ; read until valid data (high bit set) + bpl L12 + eor nibtbl-$80, x + sta bit2tbl-$aa, y + iny + bne L12 +L13: +mlsmc04:ldx $c0ec ; read until valid data (high bit set) + bpl L13 + eor nibtbl-$80, x + sta (adrlo), y ; the real address + iny + cpy secsize + bne L13 + ldy #0 +L14: + ldx #$a9 +L15: + inx + beq L14 + lda (adrlo), y + lsr bit2tbl-$aa, x + rol + lsr bit2tbl-$aa, x + rol + sta (adrlo), y + iny + cpy secsize + bne L15 + rts + + ; no tricks here, just the regular stuff + + ;======================= + ; readaddr -- read the address field + ;======================= + ; Find address field, put track in cutrk, sector in tmpsec + +readadr: + jsr readd5aa + cmp #$96 + bne readadr + ldy #3 ; three? + ; first read volume/volume + ; then track/track + ; then sector/sector? +adr_read_two_bytes: + tax + jsr readnib + rol + sta tmpsec + jsr readnib + and tmpsec + dey + bne adr_read_two_bytes + rts + + ;======================== + ; make sure we see the $D5 $AA pattern + +readd5aa: +L16: + jsr readnib +L17: + cmp #$d5 + bne L16 + jsr readnib + cmp #$aa + bne L17 + tay ; we need Y=#$AA later + +readnib: +mlsmc05:lda $c0ec ; read until valid (high bit set) + bpl readnib + +seekret: + rts + + ;===================== + ; SEEK + ;===================== + ; current track in X? + ; desired track in phase + +seek: + ldy #0 + sty step + asl phase ; multiply by two + txa ; current track? + asl ; mul by two +copy_cur: + tax + sta tmptrk + sec + sbc phase + beq L22 + bcs L18 + eor #$ff + inx + bcc L19 +L18: + sbc #1 + dex +L19: + cmp step + bcc L20 + lda step +L20: + cmp #8 + bcs L21 + tay + sec +L21: + txa + pha + ldx step1, y +L22: + php + bne L24 +L23: + clc + lda tmptrk + ldx step2, y +L24: + stx tmpsec + and #3 + rol + tax + lsr +mlsmc06:lda $c0e0, x +L25: + ldx #$12 +L26: + dex + bpl L26 + dec tmpsec + bne L25 + bcs L23 + plp + beq seekret + pla + inc step + bne copy_cur + + + +step1: .byte $01, $30, $28, $24, $20, $1e, $1d, $1c +step2: .byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c + +sectbl: .byte $00,$0d,$0b,$09,$07,$05,$03,$01,$0e,$0c,$0a,$08,$06,$04,$02,$0f + + +.include "hardware_detect.s" + +; From $BA96 of DOS33 +;nibtbl: .res 128 ; = * +; .byte $00,$01,$98,$99,$02,$03,$9C,$04 ; $BA96 ; 00 +; .byte $05,$06,$A0,$A1,$A2,$A4,$A4,$A5 ; $BA9E ; 08 +; .byte $07,$08,$A8,$A9,$AA,$09,$0A,$0B ; $BAA6 ; 10 +; .byte $0C,$0D,$B0,$B1,$0E,$0F,$10,$11 ; $BAAE ; 18 +; .byte $12,$13,$B8,$14,$15,$16,$17,$18 ; $BAB6 ; 20 +; .byte $19,$1A,$C0,$C1,$C2,$C3,$C4,$C5 ; $BABE ; 28 +; .byte $C6,$C7,$C8,$C9,$CA,$1B,$CC,$1C ; $BAC6 ; 30 +; .byte $1D,$1E,$D0,$D1,$D2,$1E,$D4,$D5 ; $BACE ; 38 +; .byte $20,$21,$D8,$22,$23,$24,$25,$26 ; $BAD6 ; 40 +; .byte $27,$28,$E0,$E1,$E2,$E3,$E4,$29 ; $BADE ; 48 +; .byte $2A,$2B,$E8,$2C,$2D,$2E,$2F,$30 ; $BAE6 ; 50 +; .byte $31,$32,$F0,$F1,$33,$34,$35,$36 ; $BAEE ; 58 +; .byte $37,$38,$F8,$39,$3A,$3B,$3C,$3D ; $BAF6 ; 60 +; .byte $3E,$3F,$13,$00,$01,$02,$01,$00 ; $BAFE ; 68 +; .byte $00,$00,$00,$00,$00,$00,$00,$00 +; .byte $00,$00,$00,$00,$00,$00,$00,$00 + + +;bit2tbl: .res 86 ; = nibtbl+128 +;filbuf: .res 4 ; = bit2tbl+86 + + + ;dataend = filbuf+4 + + +loader_end: + +.assert (16, error, "loader too big" diff --git a/games/riven_hgr/main.s b/games/riven_hgr/main.s new file mode 100644 index 00000000..02edfcd6 --- /dev/null +++ b/games/riven_hgr/main.s @@ -0,0 +1,518 @@ +; Riven graphics + +; by deater (Vince Weaver) + +; Zero Page + .include "zp.inc" + .include "hardware.inc" + .include "common_defines.inc" + +div7_table = $9C00 +mod7_table = $9D00 +hposn_high = $9E00 +hposn_low = $9F00 + +riven_hgr: + + ;=================== + ; init screen + ;=================== + + jsr TEXT + jsr HOME + bit KEYRESET + + bit SET_GR + bit PAGE1 + 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 + ;=================== +reload_everything: + + lda #new_title + sta ZX0_src+1 + + lda #$20 ; decompress to hgr page1 + + jsr full_decomp + + ;=================================== + ; 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: + + + ;=================================== + ; init + ;=================================== + + lda #$0 + sta HGR_PAGE + jsr hgr_make_tables + +blah: + jmp blah + +.if 0 + ;=================================== + ; Do Intro Sequence + ;=================================== + + ; wait a bit at LOAD screen + + lda #100 + jsr wait_a_bit + + + ;=================================== + ; Draw title message + ;=================================== + + lda #title_sprite + sta INH + + lda #8 + sta SPRITE_X + + lda #48 + sta SPRITE_Y + + lda #$20 + sta DRAW_PAGE + + jsr hgr_draw_sprite + + ;=========================== + ; title loop + ;========================== + + lda #0 + sta WHICH_CURSOR + sta FRAMEL + sta FRAMEH + sta MENU_OPTION +title_loop: + + lda KEYPRESS + bpl done_title_keyboard + + bit KEYRESET + + and #$7f ; clear high bit + and #$df ; convert to uppercase + + cmp #13 ; exit if enter pressed + beq done_intro + + cmp #'H' + bne not_help + + jsr print_help +not_help: + +check_up: + cmp #'W' + beq up_pressed + cmp #$0B ; up key + bne check_down +up_pressed: + + lda MENU_OPTION + beq done_title_keyboard + + jsr erase_marker + + dec MENU_OPTION + + jsr draw_marker + + jmp done_title_keyboard + +check_down: + cmp #'S' + beq down_pressed + cmp #$0A ; down key + bne done_title_keyboard + +down_pressed: + + lda MENU_OPTION + cmp #7 + beq done_title_keyboard + + jsr erase_marker + + inc MENU_OPTION + + jsr draw_marker + + jmp done_title_keyboard + + +done_title_keyboard: + inc FRAMEL + bne noframeoflo + inc FRAMEH +noframeoflo: + lda FRAMEL + bne no_adjust_cursor + + lda FRAMEH + and #$0f + bne no_adjust_cursor + + clc + lda WHICH_CURSOR + adc #1 + cmp #3 + bne no_cursor_oflo + lda #0 + +no_cursor_oflo: + sta WHICH_CURSOR + + jsr draw_marker + +no_adjust_cursor: + jmp title_loop + +done_intro: + + ; restore to full screen (no text) + + lda MENU_OPTION + cmp #0 + beq new_game ; new game + cmp #1 + beq nothing ; continue game + cmp #2 + beq do_story + +nothing: + jmp title_loop + + ;===================== + ;===================== + ; do story + ;===================== + ;===================== +do_story: + bit FULLGR + bit LORES + + lda #LOAD_STORY + sta WHICH_LOAD ; assume new game (mars map) + + rts + + ;===================== + ;===================== + ; new game + ;===================== + ;===================== +new_game: +init_vars: + bit FULLGR + bit LORES + + + + + lda #0 + sta ANIMATE_FRAME + sta FRAMEL + sta FRAMEH + sta JOYSTICK_ENABLED + sta LEVEL_OVER + + sta SCORE0 ; set score to 0 + sta SCORE1 + sta SCORE2 + + sta RAYGUNS ; number of laser blasts + sta KEYCARDS + sta SHIP_PARTS + sta POGO + + lda #4 ; number of lives + sta KEENS + + + ;============================ + ; set up initial location + + lda #10 + sta MARS_TILEX + lda #34 + sta MARS_TILEY + + lda #0 + sta MARS_X + sta MARS_Y + + lda #LOAD_MARS + sta WHICH_LOAD ; assume new game (mars map) + + rts + +.endif + + ;========================== + ; includes + ;========================== + +; .include "gr_pageflip.s" +; .include "gr_copy.s" +; .include "wait_a_bit.s" +; .include "gr_offsets.s" + .include "zx02_optim.s" + +; .include "text_help.s" +; .include "gr_fast_clear.s" +; .include "text_print.s" +; .include "hgr_sprite.s" + .include "hgr_tables.s" + +; .include "lc_detect.s" + + + +new_title: +.incbin "graphics/maglev1.hgr.zx02" + +.if 0 + +.include "graphics/title_sprites.inc" + + + ;==================================== + ; wait for keypress or a few seconds + ;==================================== + +wait_a_bit: + + bit KEYRESET + tax + +keyloop: + lda #200 ; delay a bit + jsr WAIT + + lda KEYPRESS + bmi done_keyloop + +; bmi keypress_exit + + dex + bne keyloop + +done_keyloop: + bit KEYRESET + + cmp #'H'|$80 + bne really_done_keyloop + + + lda #$04 + sta DRAW_PAGE + jsr print_help + bit SET_GR + lda #$20 + sta DRAW_PAGE + bit PAGE1 + + ldx #100 + + jmp keyloop + +really_done_keyloop: + + + rts + + ;============================= + ; erase + ;============================= +erase_marker: + lda #ball_bg + sta INH + + lda #12 + sta SPRITE_X + + lda MENU_OPTION + asl + asl + asl + clc + adc #55 + sta SPRITE_Y + +; lda #$20 +; sta DRAW_PAGE + + jsr hgr_draw_sprite + + rts + + + + ;============================= + ; draw + ;============================= +draw_marker: + ldx WHICH_CURSOR + lda cursor_lookup_l,X + sta INL + lda cursor_lookup_h,X + sta INH + + lda #12 + sta SPRITE_X + + lda MENU_OPTION + asl + asl + asl + clc + adc #55 + sta SPRITE_Y + +; lda #$20 +; sta DRAW_PAGE + + jsr hgr_draw_sprite + + rts + +cursor_lookup_h: + .byte >ball0,>ball1,>ball2 +cursor_lookup_l: + .byte