diff --git a/Makefile b/Makefile index 9fa689e1c..c912e476e 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ dsk: md asm cp res/_FileInformation.txt build/ $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/PRODOS" >/dev/null $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "build/LAUNCHER.SYSTEM" >/dev/null - $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/games.conf" >/dev/null + $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/GAMES.CONF" >/dev/null $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/COVER" >/dev/null $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/COVER.A2FC" >/dev/null $(CADIUS) CREATEFOLDER build/"$(DISK)" "/${VOLUME}/X/" >/dev/null diff --git a/res/_FileInformation.txt b/res/_FileInformation.txt index a30324116..70a531af5 100644 --- a/res/_FileInformation.txt +++ b/res/_FileInformation.txt @@ -2,3 +2,4 @@ PRODOS=Type(FF),AuxType(0000),Access(C3) LAUNCHER.SYSTEM=Type(FF),AuxType(2000),Access(C3) COVER=Type(06),AuxType(2000),Access(C3) COVER.A2FC=Type(06),AuxType(2000),Access(C3) +GAMES.CONF=Type(04),AuxType(4000),Access(C3) diff --git a/res/games.conf b/res/games.conf index 8c196fc47..1a07c276b 100644 --- a/res/games.conf +++ b/res/games.conf @@ -1 +1 @@ -# # 4cade master game list # # Format: # AB,name=directory # # A=1 if game requires joystick, 0 if playable on keyboard # B=1 if game requires 128K, 0 if playable on 64K # all other values for A or B -> ignore entire line # 00,Agent USA=AGENT.USA 11,Airheart=AIRHEART 00,Alcazar=ALCAZAR 00,Alien Downpour=ALIEN.DOWNPOUR # TODO: Alien Rain volume name and executable filename do not match (one has period, one doesn't) 00,Alien Rain=ALIENRAIN 00,Ankh=ANKH 00,Apple Panic=APPLE.PANIC 00,Aquatron=AQUATRON 10,Arkanoid=ARKANOID 00,Battlezone=BATTLEZONE 10,BC's Quest For Tires=BCS.QUEST 00,Beer Run=BEER.RUN 00,Bellhop=BELLHOP 00,Bill Budge's Trilogy=BUDGETRILOGY 00,Blister Ball=BLISTER.BALL 00,Bolo=BOLO 00,Brainteaser Boulevard=BRAINTEASERBLVD 00,BurgerTime=BURGERTIME 00,Cannonball Blitz=CANNONBALL.BLTZ 00,Canyon Climber=CANYON.CLIMBER 00,Centipede=CENTIPEDE 10,Choplifter=CHOPLIFTER 00,Commando=COMMANDO 00,Conan=CONAN 10,Crisis Mountain=CRISIS.MOUNTAIN 00,Crossfire=CROSSFIRE 01,D-Generation=D.GENERATION 10,David's Midnight Magic=DAVIDS.MAGIC 10,Defender=DEFENDER 00,Dig Dug=DIG.DUG 10,Dino Eggs=DINO.EGGS 10,Donkey Kong=DONKEY.KONG 10,Drelbs=DRELBS 00,Drol=DROL 00,Epoch=EPOCH 00,Falcons=FALCONS 00,Flight Simulator I=FS1 00,Flip Out=FLIP.OUT 10,Formula 1 Racer=FORMULA.1 00,Frogger=FROGGER 10,Galaxian=GALAXIAN 10,The Goonies=GOONIES 00,Gremlins=GREMLINS 10,H.E.R.O.=HERO 00,Hard Hat Mack=HARD.HAT.MACK 00,Head On=HEAD.ON 00,High Rise=HIGH.RISE 00,Hungry Boy=HUNGRYBOY 10,Impossible Mission=IMPOSSIBLE.MISS 00,Joust=JOUST 00,Jungle Hunt=JUNGLE.HUNT 00,Karateka=KARATEKA 00,Lady Tut=LADY.TUT 10,Lost Tomb=LOST.TOMB 10,Mad Bomber=MAD.BOMBER 00,Mario Bros=MARIO.BROS 00,Montezuma's Revenge=MONTEZUMA 00,Moon Patrol=MOON.PATROL 00,Mr. Cool=MR.COOL 10,Mr. Do=MR.DO 00,Mr. Robot=MR.ROBOT 00,Ms. Pacman=MS.PACMAN 00,Nibbler=NIBBLER 00,Night Stalker=NIGHT.STALKER 00,Nightmare Gallery=NIGHTMARE 00,NORAD=NORAD 00,O'Riley's Mine=ORILEYS.MINE 00,Outpost=OUTPOST 00,Pac-Man=PAC.MAN 00,Paperboy=PAPERBOY 00,Pest Patrol=PEST.PATROL 00,Pie-Man=PIEMAN 00,Pit Stop II=PITSTOP.II 10,Pitfall II=PITFALL.II 00,Plasmania=PLASMANIA 00,Pooyan=POOYAN 01,Prince of Persia=PRINCEUNP 00,Puckman=PUCK.MAN 11,Qix=QIX 01,Radwarrior=RADWARRIOR 00,Repton=REPTON 00,Ribbit=RIBBIT 00,Robotron 2084=ROBOTRON.2084 00,Sabotage=SABOTAGE 00,Serpentine=SERPENTINE 10,Shamus=SHAMUS 00,Snack Attack=SNACK.ATTACK 00,Snake Byte=SNAKE.BYTE 00,Sneakers=SNEAKERS 00,Snoggle=SNOGGLE 00,Space Raiders=SPACE.RAIDERS 00,Spider Raid=SPIDER.RAID 01,Spiderbot=SPIDERBOT 00,Spy Hunter=SPY.HUNTER 00,Spy's Demise=SPYS.DEMISE 10,Starblaster=STARBLASTER 10,Stargate=STARGATE 00,Stellar 7=STELLAR.7 00,Succession=SUCCESSION 00,Swashbuckler=SWASHBUCKLER 00,Tag Team Wrestling=TAG.TEAM 00,Tapper=TAPPER 00,Thief=THIEF 00,Thunder Bombs=THUNDERBOMBS 10,Tomahawk=TOMAHAWK 00,Track N Field=TRACK.AND.FIELD 10,Tubeway ][=TUBEWAY 01,Victory Road=VICTORY.ROAD 00,Wavy Navy=WAVY.NAVY [eof] \ No newline at end of file +# # 4cade master game list # # Format: # AB,name=directory # # A=1 if game requires joystick, 0 if playable on keyboard # B=1 if game requires 128K, 0 if playable on 64K # all other values for A or B -> ignore entire line (like this one!) # 00,Agent USA=AGENT.USA 11,Airheart=AIRHEART 00,Alcazar=ALCAZAR 00,Alien Downpour=ALIEN.DOWNPOUR # TODO: Alien Rain volume name and executable filename do not match (one has period, one doesn't) 00,Alien Rain=ALIENRAIN 00,Ankh=ANKH 00,Apple Panic=APPLE.PANIC 00,Aquatron=AQUATRON 10,Arkanoid=ARKANOID 00,Battlezone=BATTLEZONE 10,BC's Quest For Tires=BCS.QUEST 00,Beer Run=BEER.RUN 00,Bellhop=BELLHOP 00,Bill Budge's Trilogy=BUDGETRILOGY 00,Blister Ball=BLISTER.BALL 00,Bolo=BOLO 00,Brainteaser Boulevard=BRAINTEASERBLVD 00,BurgerTime=BURGERTIME 00,Cannonball Blitz=CANNONBALL.BLTZ 00,Canyon Climber=CANYON.CLIMBER 00,Centipede=CENTIPEDE 10,Choplifter=CHOPLIFTER 00,Commando=COMMANDO 00,Conan=CONAN 10,Crisis Mountain=CRISIS.MOUNTAIN 00,Crossfire=CROSSFIRE 01,D-Generation=D.GENERATION 10,David's Midnight Magic=DAVIDS.MAGIC 10,Defender=DEFENDER 00,Dig Dug=DIG.DUG 10,Dino Eggs=DINO.EGGS 10,Donkey Kong=DONKEY.KONG 10,Drelbs=DRELBS 00,Drol=DROL 00,Epoch=EPOCH 00,Falcons=FALCONS 00,Flight Simulator I=FS1 00,Flip Out=FLIP.OUT 10,Formula 1 Racer=FORMULA.1 00,Frogger=FROGGER 10,Galaxian=GALAXIAN 10,The Goonies=GOONIES 00,Gremlins=GREMLINS 10,H.E.R.O.=HERO 00,Hard Hat Mack=HARD.HAT.MACK 00,Head On=HEAD.ON 00,High Rise=HIGH.RISE 00,Hungry Boy=HUNGRYBOY 10,Impossible Mission=IMPOSSIBLE.MISS 00,Joust=JOUST 00,Jungle Hunt=JUNGLE.HUNT 00,Karateka=KARATEKA 00,Lady Tut=LADY.TUT 10,Lost Tomb=LOST.TOMB 10,Mad Bomber=MAD.BOMBER 00,Mario Bros=MARIO.BROS 00,Montezuma's Revenge=MONTEZUMA 00,Moon Patrol=MOON.PATROL 00,Mr. Cool=MR.COOL 10,Mr. Do=MR.DO 00,Mr. Robot=MR.ROBOT 00,Ms. Pacman=MS.PACMAN 00,Nibbler=NIBBLER 00,Night Stalker=NIGHT.STALKER 00,Nightmare Gallery=NIGHTMARE 00,NORAD=NORAD 00,O'Riley's Mine=ORILEYS.MINE 00,Outpost=OUTPOST 00,Pac-Man=PAC.MAN 00,Paperboy=PAPERBOY 00,Pest Patrol=PEST.PATROL 00,Pie-Man=PIEMAN 00,Pit Stop II=PITSTOP.II 10,Pitfall II=PITFALL.II 00,Plasmania=PLASMANIA 00,Pooyan=POOYAN 01,Prince of Persia=PRINCEUNP 00,Puckman=PUCK.MAN 11,Qix=QIX 01,Radwarrior=RADWARRIOR 00,Repton=REPTON 00,Ribbit=RIBBIT 00,Robotron 2084=ROBOTRON.2084 00,Sabotage=SABOTAGE 00,Serpentine=SERPENTINE 10,Shamus=SHAMUS 00,Snack Attack=SNACK.ATTACK 00,Snake Byte=SNAKE.BYTE 00,Sneakers=SNEAKERS 00,Snoggle=SNOGGLE 00,Space Raiders=SPACE.RAIDERS 00,Spider Raid=SPIDER.RAID 01,Spiderbot=SPIDERBOT 00,Spy Hunter=SPY.HUNTER 00,Spy's Demise=SPYS.DEMISE 10,Starblaster=STARBLASTER 10,Stargate=STARGATE 00,Stellar 7=STELLAR.7 00,Succession=SUCCESSION 00,Swashbuckler=SWASHBUCKLER 00,Tag Team Wrestling=TAG.TEAM 00,Tapper=TAPPER 00,Thief=THIEF 00,Thunder Bombs=THUNDERBOMBS 10,Tomahawk=TOMAHAWK 00,Track N Field=TRACK.AND.FIELD 10,Tubeway ][=TUBEWAY 01,Victory Road=VICTORY.ROAD 00,Wavy Navy=WAVY.NAVY [eof] \ No newline at end of file diff --git a/src/4cade.a b/src/4cade.a index fe1bf76e5..9224db586 100644 --- a/src/4cade.a +++ b/src/4cade.a @@ -5,8 +5,33 @@ !source "src/constants.a" !source "src/macros.a" +Init jsr Has64K ; check for 64K (required) - bcc @found64K + bcs @no64K + jsr DisableAccelerator ; set to 1 MHz + jsr Has128K ; check for 128K (absence is OK, we just filter out some games) + ror MachineStatus + jsr HasJoystick ; check for joystick (absence is OK, we just filter out some games) + ror MachineStatus + + +READ_ROM_WRITE_RAM1 + ldx #$00 ; relocate rest of program to RAM bank 1 in language card +@FM lda FirstMover,x + sta $D000,x + inx + bne @FM + lda @FM+2 + cmp #>LastMover + bcs + + inc @FM+2 + inc @FM+5 + bne @FM ++ + jsr init ; initialize ProRWTS2 (bye bye ProDOS) + +READ_RAM1_WRITE_RAM1 + jmp Start + +@no64K jsr $FB2F jsr $FC58 ldy #@no64Klen @@ -18,85 +43,53 @@ @s_no64K !raw "REQUIRES 64K" @no64Klen=*-@s_no64K -@found64K - jsr DisableAccelerator ; set to 1 MHz - jsr Has128K ; check for 128K (absence is OK, we just filter out some games) - ror MachineStatus - jsr HasJoystick ; check for joystick (absence is OK, we just filter out some games) - ror MachineStatus - - lda LCBANK1WRITE ; read ROM / write LC bank 1 - lda LCBANK1WRITE - ldx #$00 -FM lda FirstMover,x - sta $D000,x - inx - bne FM -; inc FM+2 -; inc FM+5 -; lda FM+5 -; cmp #>LastMover -; bcc FM - - jsr init ; initialize ProRWTS2 (bye bye ProDOS) - lda LCBANK1 ; read/write LC bank 1 - lda LCBANK1 - jmp Start - + ; these routines will only be called once, from main memory, before relocating to language card !source "src/memcheck.a" !source "src/joystick.a" !source "src/normfast.a" + ; ProRWTS2 has its own function to relocate itself !source "src/prorwts2.a" FirstMover !pseudopc $D000 { !zone Start - lda #$00 ; read first $2000 bytes - sta sizelo - lda #$20 - sta sizehi - lda #0 ; 0 = read into main memory - sta auxreq - lda #cmdread ; read (instead of write) - sta reqcmd bit MachineStatus - bvs @ShowCover128K - lda #cover64 - sta namhi - jsr hddopendir ; call ProRWTS2 + bvs @Load128 + jsr LoadFile + !word cover64 clc bcc @Show -@ShowCover128K - inc auxreq ; 1 = read into aux memory - lda #cover128 - sta namhi - jsr hddopendir ; call ProRWTS2 - lda #$20 ; read next $2000 bytes - sta sizehi - dec auxreq ; 0 = read into main memory - jsr hddrdwrpart ; call ProRWTS2 - - sta $C000 ; display double hi-res page 1 +@Load128 + jsr LoadDHRFile + !word cover128 + sta $C000 ; double hi-res mode sta $C00D sta $C05E sta $C001 @Show - sta $C057 + sta $C057 ; show graphics page 1 (HGR or DHGR) sta $C052 sta $C054 sta $C050 + jsr LoadFile +- !word gamesconf + jsr ParseGamesList + !word gGamesListStore + !word - + bit $C010 - lda $C000 bpl - bit $C010 brk +gamesconf + !byte gamesconf_e-gamesconf_b +gamesconf_b + !text "GAMES.CONF" +gamesconf_e cover64 !byte cover64_e-cover64_b cover64_b @@ -107,24 +100,11 @@ cover128 cover128_b !text "COVER.A2FC" cover128_e + ; these routines will only be called after relocating to language card + !source "src/glue.prorwts2.a" !source "src/okvs.a" + !source "src/parse.games.a" +gGamesListStore + !word *+2 ; address of first okvs store } LastMover - -;LoadDHGR -; sta $C000 -; ldx #$20 ; copy $2000 bytes to auxmem -; stx @copya+2 -; stx @copyb+2 -; ldy #0 -;@writeToAuxLoop -; sta $C005 -;@copya lda $FF00, y -;@copyb sta $FF00, y -; iny -; bne @copya -; sta $C004 -; inc @copya+2 -; inc @copyb+2 -; dex -; bne @writeToAuxLoop diff --git a/src/constants.a b/src/constants.a index ef957ee25..db01a8c99 100644 --- a/src/constants.a +++ b/src/constants.a @@ -3,25 +3,14 @@ ; ; soft switches -STOREOFF = $C000 ; write to use following flags: +STOREOFF = $C000 ; write to use following 4 flags: READMAINMEM = $C002 ; write to R main mem READAUXMEM = $C003 ; write to R aux mem WRITEMAINMEM = $C004 ; write to W main mem WRITEAUXMEM = $C005 ; write to W aux mem -SETMAINZP = $C008 ; write to R/W main mem zero page -SETAUXZP = $C009 ; write to R/W aux mem zero page -AUXMEMSTATUS = $C013 ; read high bit only -AUXZPSTATUS = $C016 ; read high bit only +; SLOT3STATUS = $C017 ; read high bit only -LCBANK2READ = $C080 ; read once to R RAM bank 2 / no write -ROMIN = $C081 ; read twice to R ROM / W RAM bank 2 -ROMONLY = $C082 ; read once to R ROM / no write -;LCBANK2 = $C083 ; read twice to R/W RAM bank 2 -LCBANK1READ = $C088 ; read once to R RAM bank 1 / no write -LCBANK1WRITE = $C089 ; read twice to R ROM / W RAM bank 1 -LCBANK1 = $C08B ; read twice to R/W RAM bank 1 - ; ROM MACHINEID = $FBB3 @@ -31,5 +20,13 @@ PTR = $02 SRC = $04 DEST = $06 SAVE = $08 -MachineStatus =$FF ; bit 7 = 1 if machine has joystick +MachineStatus =$F0 ; bit 7 = 1 if machine has joystick ; bit 6 = 1 if machine has 128K +; $FE ; used by ParseGamesList +; $FF ; used by ParseGamesList + +; main memory +gKeyLen = $1F00 ; used by ParseGamesList +gKey = $1F01 +gValLen = $1F80 +gVal = $1F81 diff --git a/src/glue.prorwts2.a b/src/glue.prorwts2.a new file mode 100644 index 000000000..067dd9f79 --- /dev/null +++ b/src/glue.prorwts2.a @@ -0,0 +1,63 @@ +;license:MIT +;(c) 2017-8 by 4am +; +; ProRWTS2 glue functions +; +; Public functions +; - LoadFile +; + +;------------------------------------------------------------------------------ +; LoadFile +; load a file into memory all at once, using ProRWTS2 +; uses file's load address +; +; in: stack contains 2 bytes of parameters: +; +1 address of filename +; out: all flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------------------------------------------------------ +LoadFile + +PARAMS_ON_STACK 2 + +LDPARAM 1 + +STAY namlo ; set filename + lda #$FF ; read entire file (ProRWTS2 will figure out exact size) + sta sizelo + sta sizehi + lda #0 ; 0 = read into main memory + sta auxreq + lda #cmdread ; read (instead of write) + sta reqcmd + jmp hddopendir ; exit via ProRWTS2 + +;------------------------------------------------------------------------------ +; LoadDHRFile +; load .A2FC file (uncompressed double hi-res graphics) into memory +; all at once, using ProRWTS2 +; first $2000 bytes of file are loaded into auxiliary memory $2000..$3FFF +; second $2000 bytes of file are loaded into main memory $2000..$3FFF +; +; in: stack contains 2 bytes of parameters: +; +1 address of filename +; out: all flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------------------------------------------------------ +LoadDHRFile + +PARAMS_ON_STACK 2 + +LDPARAM 1 + +STAY namlo ; set filename + lda #$00 ; read first $2000 bytes + sta sizelo + lda #$20 + sta sizehi + lda #1 ; 1 = read into aux memory + sta auxreq + lda #cmdread ; read (instead of write) + sta reqcmd + jsr hddopendir ; call ProRWTS2 + lda #$20 ; read next $2000 bytes + sta sizehi + dec auxreq ; 0 = read into main memory + jmp hddrdwrpart ; call ProRWTS2 diff --git a/src/macros.a b/src/macros.a index 03c983a94..c635d9671 100644 --- a/src/macros.a +++ b/src/macros.a @@ -66,3 +66,18 @@ !macro HIDE_NEXT_2_BYTES { !byte $2C } + +; various language card configurations +!macro READ_RAM1_WRITE_RAM1 { + bit $C08B + bit $C08B +} + +!macro READ_ROM_WRITE_RAM1 { + bit $C089 + bit $C089 +} + +!macro READ_ROM_NO_WRITE { + bit $C082 +} diff --git a/src/memcheck.a b/src/memcheck.a index 790139335..251e7d0e6 100644 --- a/src/memcheck.a +++ b/src/memcheck.a @@ -9,8 +9,7 @@ ; ROM in memory (not LC RAM bank) ;------------------------------------------------------------------------------ Has64K - lda LCBANK1 ; read/write LC RAM bank 1 - lda LCBANK1 + +READ_RAM1_WRITE_RAM1 lda #$AA ; test #1 for $D0 page sta $D000 eor $D000 @@ -22,7 +21,7 @@ Has64K clc +HIDE_NEXT_BYTE @no sec - sta ROMONLY + +READ_ROM_NO_WRITE rts ;------------------------------------------------------------------------------ @@ -41,7 +40,8 @@ Has64K ; https://github.com/jmechner/Prince-of-Persia-Apple-II/blob/master/01%20POP%20Source/Source/BOOT.S#L119 ;------------------------------------------------------------------------------ Has128K - sta ROMONLY ; need ROM for machine ID byte + +READ_ROM_NO_WRITE + sta STOREOFF lda MACHINEID cmp #6 bne @no ; earlier than //e -> no 128K diff --git a/src/parse.games.a b/src/parse.games.a new file mode 100644 index 000000000..da1534e80 --- /dev/null +++ b/src/parse.games.a @@ -0,0 +1,129 @@ +;license:MIT +;(c) 2018 by 4am +; +; GAMES.CONF parser +; +; Public functions: +; - ParseGamesList +; + +;------------------------------------------------------------------------------ +; ParseGamesList +; parse buffer with AB,KEY=VALUE lines of text into an okvs +; keys and values limited to 127 characters, which should be enough for anyone +; '[' character at beginning of line ends the parsing +; (see games.conf file for more format information) +; +; in: stack contains 4 bytes of parameters: +; +1 [word] handle to storage space for okvs +; +3 [word] handle to buffer containing contents of GAMES.CONF +; out: all registers and flags clobbered +; $1F00..$1FFF clobbered +; $00/$01 clobbered +; $02/$03 clobbered +; $04/$05 has the address of the next available byte after the okvs +; $FE/$FF clobbered +;------------------------------------------------------------------------------ +ParseGamesList + +PARAMS_ON_STACK 4 + + +LDPARAM 1 + +STAY @store1 + +STAY @store2 + + +LDPARAM 3 + +STAY $FE + + ldy #0 + lda ($FE),y + pha + iny + lda ($FE),y + tay + pla + sec + sbc #$01 + sta $FE + bcs + + dey ++ sty $FF + jsr okvs_init ; reset key/value store +@store1 !word $FDFD ; SMC + + ldy #$00 ; index into ($FE) pointing to current character +@newkey ldx #$00 ; X = index into current key + jsr IncAndGetChar ; get first filter character ('1' if game requires joystick) + cmp #$0D ; ignore blank line + beq @newkey + cmp #$5B ; '[' ends the parsing + beq .parseKeyValueDone + cmp #$30 ; '0' -> no filtering on joystick + beq @filterOnMemory + cmp #$31 ; not '0' or '1' or '[' or CR -> ignore entire line (e.g. comment) + bne @skipLine + bit MachineStatus + bpl @skipLine ; game requires joystick but we don't have one, so ignore entire line +@filterOnMemory + jsr IncAndGetChar ; get second filter character ('1' if game requires 128K) + cmp #$30 ; '0' -> no filtering on memory + beq @swallowComma + cmp #$31 ; not '0' or '1' -> ignore entire line + bne @skipLine + bit MachineStatus + bvc @skipLine ; game requires 128K but we only have 64K, so ignore entire line +@swallowComma + jsr IncAndGetChar + cmp #$2C ; ',' delimiter (required) + bne @skipLine +@gatherKey + jsr IncAndGetChar + cmp #$3D ; '=' ends the key + beq @endKey + sta gKey,x + inx + bpl @gatherKey +@endKey stx gKeyLen + ldx #$00 ; now X = index into the current value +@gatherValue + jsr IncAndGetChar + cmp #$0D ; CR ends the value + beq @endValue + sta gVal,x + inx + bpl @gatherValue +@endValue + stx gValLen + tya + pha ; okvs functions clobber everything but we need Y + jsr okvs_append +@store2 !word $FDFD ; SMC + !word gKeyLen + !word gValLen + !byte 0 + pla + tay + clc + bcc @newkey ; always branches + +@skipLine ; skip to CR + jsr IncAndGetChar + cmp #$0D ; CR + bne @skipLine + beq @newkey ; always branches + +;------------------------------------------------------------------------------ +; IncAndGetChar +; +; in: Y = index into ($FE) +; ($FE) -> buffer +; out: A contains next byte from buffer +; Y incremented +; $FF possibly incremented +;------------------------------------------------------------------------------ +IncAndGetChar + iny + bne + + inc $FF ++ lda ($FE),y +.parseKeyValueDone + rts diff --git a/src/prodos.mli.a b/src/prodos.mli.a deleted file mode 100644 index fb9cb3e1e..000000000 --- a/src/prodos.mli.a +++ /dev/null @@ -1,455 +0,0 @@ -;license:MIT -;(c) 2017-8 by 4am -; -; ProDOS - file and other MLI routines -; -; Public functions -; - LoadFile -; - LoadDHRFile -; - LoadSHRFile -; - SaveFile -; - SetPrefix -; - GetFileInfo -; - -; MLI command codes -CMD_QUIT = $65 ; quit to ProDOS -CMD_CREATE = $C0 ; create new file -CMD_DESTROY = $C1 ; delete a file -CMD_SETFILEINFO= $C3 ; set file info -CMD_GETFILEINFO= $C4 ; get file (or volume) info -CMD_SETPREFIX = $C6 ; change default pathname prefix -CMD_OPEN = $C8 ; open a file -CMD_READ = $CA ; read an open file -CMD_WRITE = $CB ; write to an open file -CMD_CLOSE = $CC ; close an open file - -; MLI parameter counts -PC_QUIT = $04 -PC_CREATE = $07 -PC_DESTROY = $01 -PC_SETFILEINFO = $07 -PC_GETFILEINFO = $0A -PC_SETPREFIX = $01 -PC_OPEN = $03 -PC_READ = $04 -PC_WRITE = $04 -PC_CLOSE = $01 - -; ROM addresses -PRODOSMLI = $BF00 ; [callable] MLI entry point -MACHID = $BF98 ; machine identification byte - -kAccessBits = $C3 ; full access (used in SaveFile) - -;------------------------------- -; LoadFile -; load a file into memory all at once, using ProDOS MLI calls -; -; in: stack contains 6 bytes of parameters: -; +1 address of pathname -; +3 address of data buffer (to receive file contents) -; +5 address of ProDOS file buffer -; out: if C set, load failed and A contains error code -; from open or read -; if C clear, load succeeded and ($02) contains -; data loaded from file -; all other flags clobbered -; all registers clobbered -; stack set to next instruction after parameters -;------------------------------- -LoadFile - +PARAMS_ON_STACK 6 - - +LDPARAM 1 - +STAY mliparam+1 ; pathname - +LDPARAM 5 - +STAY mliparam+3 ; ProDOS file buffer - - jsr _openfile - bcs @exit ; C set on error - - pha ; push file reference number - +LDPARAM 3 - +STAY mliparam+2 ; data buffer - lda #$FF - sta mliparam+4 ; max data length (unlimited, YOLO) - sta mliparam+5 - pla ; pull file reference number - jsr _readfile - php ; save flags from readfile - pha - jsr _closefile ; always close whether read worked or not - pla - plp ; restore flags from readfile - ; (so caller gets codes from read attempt, - ; not close) -@exit rts - -;------------------------------- -; LoadDHRFile -; load uncompressed DHR file into memory from .A2FC file -; 1. load first half ($2000 bytes) -; 2. copy to auxmem -; 3. load second half ($2000 bytes) -; -; always loads into graphics page 1 ($2000/main and $2000/aux) -; -; in: stack contains 4 bytes of parameters: -; +1 address of pathname -; +3 address of ProDOS file buffer -; out: if C set, load failed -; if C clear, load succeeded -; all other flags clobbered -; all registers clobbered -; stack set to next instruction after parameters -;------------------------------- -LoadDHRFile - +PARAMS_ON_STACK 4 - - ldy #$04 -- lda (PARAM),y - sta mliparam,y - dey - bne - - - jsr _openfile - bcs @exit ; C set on error - sta @saverefnum ; store file refnum - - ldy #$20 - stz mliparam+2 ; read into $2000 in main mem - sty mliparam+3 - stz mliparam+4 ; read length = $2000 bytes (first half of file) - sty mliparam+5 - - jsr _readfile - bcs @close - - sta $C000 - ldx #$20 ; copy $2000 bytes to auxmem - stx @copya+2 - stx @copyb+2 - ldy #0 -@writeToAuxLoop - sta $C005 -@copya lda $FF00, y -@copyb sta $FF00, y - iny - bne @copya - sta $C004 - inc @copya+2 - inc @copyb+2 - dex - bne @writeToAuxLoop - - lda @saverefnum - jsr _readfile ; read another $2000 bytes into $2000 (stays in main mem) - -@close php ; save flags from readfile -@saverefnum=*+1 - lda #$FD ; file refnum (SMC) - jsr _closefile - plp ; restore flags from readfile -@exit rts - -;------------------------------- -; LoadSHRFile -; load uncompressed SHR file into memory from .PIC file -; 1. load first quarter ($2000 bytes) -; 2. copy to graphics memory -; 3. load second quarter ($2000 bytes) -; 4. copy to graphics memory -; 5. load third quarter ($2000 bytes) -; 6. copy to graphics memory -; 7. load fourth quarter ($2000 bytes) -; 8. copy to graphics memory -; -; in: stack contains 4 bytes of parameters: -; +1 address of pathname -; +3 address of ProDOS file buffer -; out: if C set, load failed -; if C clear, load succeeded -; all other flags clobbered -; all registers clobbered -; stack set to next instruction after parameters -;------------------------------- -LoadSHRFile - +PARAMS_ON_STACK 4 - - ldy #$04 -- lda (PARAM),y - sta mliparam,y - dey - bne - - - jsr _openfile - bcs @exit ; C set on error - sta @saverefnum ; store file refnum - - ldy #$20 - stz mliparam+2 ; read into $2000 in main mem - sty mliparam+3 - stz mliparam+4 ; read length = $2000 bytes (one quarter of file) - sty mliparam+5 - sty @shrdest+2 - - ldx #4 ; four quarters -- lda @saverefnum ; file refnum - jsr _readfile - bcs @close - phx - -!cpu 65816 - xce - rep #$30 -!rl -!al - lda #$1FFF - tax - inx -@shrdest ldy #$FD00 ; SMC - phb - mvn 0,$E1 - plb - sty @shrdest+1 -!as -!rs - sec - xce -!cpu 65C02 - - plx - dex - bne - - -@close php ; save flags from readfile -@saverefnum=*+1 - lda #$FD ; file refnum (SMC) - jsr _closefile - plp ; restore flags from readfile -@exit rts - -;------------------------------- -; SaveFile -; save a file to disk all at once, using ProDOS MLI calls -; -; in: stack contains 11 ($0B) bytes of parameters: -; +1 address of pathname -; +3 [byte] file type -; +4 [word] aux file type -; +6 address of data buffer -; +8 [word] length of data buffer -; +A address of ProDOS file buffer -; out: if C set, save failed -; if C clear, save succeeded -; all other flags clobbered -; all registers clobbered -; stack set to next instruction after parameters -;------------------------------- -SaveFile - +PARAMS_ON_STACK $0B - +LDPARAM 1 - +STAY mliparam+1 ; pathname - lda #CMD_DESTROY ; MLI destroy command - ldy #PC_DESTROY ; number of parameters for 'destroy' command - jsr mli ; don't care if this fails - - ldy #$03 - lda (PARAM),y ; file type - sta mliparam+4 - +LDPARAM 4 - +STAY mliparam+5 ; aux file type - lda #kAccessBits - sta mliparam+3 ; access bits (full access) - ldy #1 - sty mliparam+7 ; storage type (file) - dey - sty mliparam+8 ; creation date (current) - sty mliparam+9 - sty mliparam+10 ; creation time (current) - sty mliparam+11 - lda #CMD_CREATE ; MLI create command - ldy #PC_CREATE ; number of parameters for 'create' command - jsr mli - bcs @exit - - +LDPARAM 10 - +STAY mliparam+3 ; PrODOS file buffer - jsr _openfile - bcs @exit - - sta mliparam+1 ; store file reference number - +LDPARAM 6 - +STAY mliparam+2 ; data buffer - +LDPARAM 8 - +STAY mliparam+4 ; data length - lda #CMD_WRITE ; MLI write command - ldy #PC_WRITE ; number of parameters for 'write' command - jsr mli - php ; save flags from write command - jsr _closefile ; always close whether write worked or not - plp ; restore flags from write - ; (so caller gets codes from write attempt, - ; not close) -@exit rts - -;------------------------------- -; SetAuxFileType -; set auxiliary file information only -; access bits and file-type are hard-coded -; intended for updating save-games only -; -; in: stack contains 4 bytes of parameters: -; +1 address of pathname -; +3 auxiliary type to set -; out: if C set, MLI call failed and A contains error code -; from set -; if C clear, MLI call succeeded -; all other flags clobbered -; all registers clobbered -; stack set to next instruction after parameters -;------------------------------- -SetAuxFileType - +PARAMS_ON_STACK 4 - +LDPARAM 1 - +STAY mliparam+1 ; pathname - +LDPARAM 3 - +STAY mliparam+5 ; aux type - lda #%11000011 - sta mliparam+3 ; access bits - lda #4 - sta mliparam+4 ; file type - lda #0 - sta extra+0 ; date - sta extra+1 ; date - sta extra+2 ; time - sta extra+3 ; time - lda #CMD_SETFILEINFO ; MLI command - ldy #PC_SETFILEINFO ; number of parameters for 'setfileinfo' command - bra mli - -;------------------------------- -; SetPrefix -; set current directory -; -; in: stack contains 2 bytes of parameters: -; +1 address of pathname -; out: if C set, call failed and A contains error code -; if C clear, call succeeded -; all other flags clobbered -; all registers clobbered -; stack set to next instruction after parameters -;------------------------------- -SetPrefix - +PARAMS_ON_STACK 2 - +LDPARAM 1 - +STAY mliparam+1 ; pathname - lda #CMD_SETPREFIX - ldy #PC_SETPREFIX - bra mli - -;------------------------------- -; GetFileInfo -; just what it says on the tin -; -; in: stack contains 2 bytes of parameters: -; +1 address of pathname -; out: if C set, MLI call failed and A contains error code -; from open or read -; if C clear, MLI call succeeded and mliparam contains -; all the info -; all other flags clobbered -; all registers clobbered -; stack set to next instruction after parameters -;------------------------------- -GetFileInfo - +PARAMS_ON_STACK 2 - +LDPARAM 1 - +STAY mliparam+1 ; pathname - lda #CMD_GETFILEINFO ; MLI command - ldy #PC_GETFILEINFO ; number of parameters for 'getfileinfo' command - bra mli - -;------------------------------- -; open file via ProDOS MLI -; -; in: caller has filled @mliparam with address of -; pathname, address of data buffer, and maximum -; data length -; out: if C set, open failed and A contains error code -; if C clear, open succeeded and A contains -; file reference number -;------------------------------- -_openfile - lda #CMD_OPEN ; MLI command - ldy #PC_OPEN ; number of parameters for 'open' command - jsr mli - bcs @exit - lda refnum ; caller should save file reference number - ; as this memory location may be - ; overwritten by later MLI calls -@exit rts - -;------------------------------- -; read an open file via ProDOS MLI -; -; in: A = file reference number -; caller has filled @mliparam with address of -; data buffer and maximum data length -; out: if C set, read failed and A contains error code -; if C clear, read succeeded and A contains the same -; file reference number that was passed in -;------------------------------- -_readfile - sta mliparam+1 ; store file reference number - lda #CMD_READ ; MLI read command - ldy #PC_READ ; number of parameters for 'read' command - jsr mli - bcs @exit - lda mliparam+1 ; if no error, return file reference number -@exit rts - -;------------------------------- -; close an open file -; in: A = file reference number -; out: if error, C set and A contains error code -; if success, C clear -;------------------------------- -_closefile - sta mliparam+1 ; store file reference number - lda #CMD_CLOSE ; MLI close command - ldy #PC_CLOSE ; number of parameters for 'close' command - bra mli - -QuitToProDOS - lda #CMD_QUIT - ldy #PC_QUIT - ; execution falls through here -;------------------------------- -; low-level MLI wrapper -; in: A = MLI command code -; Y = number of MLI parameters -; caller has filled @mliparam -; with all relevant parameters -; out: returns immediately after -; calling MLI, so whatever -; state the MLI routine sets, -; the caller will see it -; verbatim -;------------------------------- -mli sta mlicmd ; store command code - sty mliparam ; number of parameters - jsr PRODOSMLI ; call ProDOS -mlicmd !byte 00 ; command number - !word mliparam ; address of parameter table - rts -mliparam !byte $FE,$FE,$FE,$FE -filetype !byte $FE ; file type (set by MLI get_file_info) -auxtype ; auxiliary file type (2 bytes, set by MLI get_file_info) -refnum !byte $FE ; file refnum (set by MLI open) -mlilen !byte $FE,$FE ; file length (set by MLI read) -blocks !byte $FE,$FE ; blocks used (set by getvolumeinfo/getfileinfo) - ; member is also used by createfile -extra !byte $FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE - ; used by get_file_info