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 00000000..6d8daf70 Binary files /dev/null and b/games/riven_hgr/graphics/maglev1.png differ diff --git a/games/riven_hgr/hardware.inc b/games/riven_hgr/hardware.inc new file mode 100644 index 00000000..eb28ede9 --- /dev/null +++ b/games/riven_hgr/hardware.inc @@ -0,0 +1,99 @@ +;; HARDWARE LOCATIONS + +KEYPRESS = $C000 +KEYRESET = $C010 + +;; SOFT SWITCHES +CLR80COL = $C000 ; PAGE1/PAGE2 normal +SET80COL = $C001 ; PAGE1/PAGE2 switches PAGE1 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 +CYAREG = $C036 ; iigs motor detect and clock speed +SET_GR = $C050 +SET_TEXT = $C051 +FULLGR = $C052 +TEXTGR = $C053 +PAGE1 = $C054 +PAGE2 = $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/riven_hgr/hardware_detect.s b/games/riven_hgr/hardware_detect.s new file mode 100644 index 00000000..34cfb1f9 --- /dev/null +++ b/games/riven_hgr/hardware_detect.s @@ -0,0 +1,153 @@ +;==================== +; Hardware Detect + +; we mostly care about the model type +; TODO: for hi-res we might want to detect language card + +; Things we care about +; + Original Apple II / II+ have horrible keyboard support +; for platformers (only keydown events). If we detect IIe or +; later we can do better +; + Apple IIgs before ROM3 has broken lo-res PAGE2 support. +; we can enable the software workaround but it's slow + +hardware_detect: + + ;======================= + ; Hardware Detect Model + ;======================= + ; Yes Michaelangel007 I will eventually update linux_logo 6502 + + jsr detect_appleii_model + + lda APPLEII_MODEL + cmp #'g' + bne not_iigs + +is_a_iigs: + + ; enable 1MHz mode + ; see hw.accel.a in 4cade +setspeed: + lda CYAREG + and #$7f + sta CYAREG + + ; gr/text page2 handling broken on early IIgs models (before ROM3) + ; this enables the workaround + + jsr ROM_TEXT2COPY ; set alternate display mode on IIgs + + + ; 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_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