launching games works but always chooses the first version

This commit is contained in:
4am 2018-02-07 16:02:14 -05:00
parent a05e5d9ae6
commit b2c8e51d15
10 changed files with 371 additions and 86 deletions

View File

@ -815,6 +815,9 @@ Flathead the Excessive. Now bordering on senility, the Wizard is still a
force to be reckoned with. Your goal, as you venture into the Wizard's
realm, is to avoid his capricious tricks and learn to control his magic.
Because each part of the ZORK saga is a completely independent story, you
can explore them in any order.
[versions]
R48.840904.Z3=r48 / 840904
R23.830411.Z3=r23 / 830411
@ -843,6 +846,9 @@ confronts you with predicaments and perils. Your quest hinges upon
discovering his secret purpose, even as he oversees your ultimate triumph -
or destruction!
Because each part of the ZORK saga is a completely independent story, you
can explore them in any order.
[versions]
R17.840727.Z3=r17 / 840727
R16.830410.Z3=r16 / 830410

Binary file not shown.

Binary file not shown.

View File

@ -14,6 +14,7 @@
.keys
!byte $D0,ID_PLAY ; P
!byte $F0,ID_PLAY ; p
!byte $8D,ID_PLAY ; Return
!byte $C3,ID_CLUES ; C
!byte $E3,ID_CLUES ; c
!byte $C2,ID_BOXART ; B
@ -22,8 +23,17 @@
!byte $EF,ID_OPTIONS ; o
!byte $D6,ID_PREVIOUS ; V
!byte $F6,ID_PREVIOUS ; v
!byte $88,ID_PREVIOUS ; left arrow
!byte $CE,ID_NEXT ; N
!byte $EE,ID_NEXT ; n
!byte $95,ID_NEXT ; right arrow
; IDs of actions that do not correspond to WeeGUI view IDs have high bit set
ID_QUIT = $80
ID_SCROLLUP = $81
ID_SCROLLDOWN = $82
!byte $9B,ID_QUIT ; Esc
!byte $8B,ID_SCROLLUP ; up arrow
!byte $8A,ID_SCROLLDOWN ; down arrow
.endkeys
;------------------------------------------------------------------------------
@ -37,29 +47,55 @@
; all registers and other flags clobbered
;------------------------------------------------------------------------------
HandleKey
cmp #$9B
bne +
sec
rts
+ ldx #$16
ldx #.endkeys-.keys
- cmp .keys,x
beq +
beq .foundKey
dex
dex
bpl -
clc
rts
+ lda .keys+1,x
bra .unhandled
.foundKey
lda .keys+1,x
bpl .activateView
cmp #ID_SCROLLUP
beq .handleScrollUp
cmp #ID_SCROLLDOWN
beq .handleScrollDown
cmp #ID_QUIT
beq .tellCallerToQuit
bra .unhandled
.handleScrollUp
lda #$01
!byte $2C ; hide next LDA
.handleScrollDown
lda #$FF
pha
.handleScroll
ldx #WGSelectView
lda #ID_DESCRIPTION
jsr WeeGUI
ldx #WGScrollYBy
pla
jsr WeeGUI
bra .focusAndDoAction
.activateView
ldx #WGSelectView
jsr WeeGUI
.focusAndDoAction
ldx #WGViewFocus
jsr WeeGUI
ldx #WGViewFocusAction
jsr WeeGUI
ldx #WGViewUnfocus
jsr WeeGUI
.unhandled
clc
rts
.tellCallerToQuit
sec
rts
;------------------------------------------------------------------------------
callback_previous
lda gCurrentGame
@ -78,10 +114,60 @@ callback_next
.loadNewGameInfoAndRepaint
jsr LoadGameInfo
jmp RepaintSomeViews
jmp $ff59
callback_play
jmp LaunchInterpreter
callback_clues
callback_boxart
callback_options
rts
LaunchInterpreter
jsr ResetPath
lda #<.interpreterFilename
ldy #>.interpreterFilename
jsr AddToPath
jsr LoadFile ; load interpreter at $2000
!word gPathname
!word $2000
!word $2000
!word $1C00
bcs .nope
; change prefix to folder of file we want the interpreter to open
jsr ResetPath
lda #<kGameRootDirectory
ldy #>kGameRootDirectory
jsr AddToPath
lda gCurrentGame
asl
tax
lda GAMES,x
ldy GAMES+1,x
jsr AddToPath
jsr SetPrefix
!word gPathname
; put .z3 filename at $2006
ldy #0
lda addrVersions
sta $00
lda addrVersions+1
sta $01
- lda ($00),y
cmp #$BD ; '='
beq .doneBuildingFilename
iny
and #$7F
sta $2006,y
bra -
.doneBuildingFilename
sty $2006
jsr ExitWeeGUI
jmp $2000
.nope sec
rts
.interpreterFilename
!byte 18
!raw "BIN/INTERPP.SYSTEM"
}

View File

@ -5,26 +5,28 @@
;
; Public functions
; - LoadGameInfo
; - AddToPath
;
; Public variables
; - gCurrentGame
;
gCurrentGame
!byte $FD ; set at runtime
; Public constants
; - kNumberOfGames
; - kGameRootDirectory
; - GAMES
;
!zone {
; application-specific constants and strings
kNumberOfGames = 25
kGameDirectory ; length-prefixed pathname of where game subdirectories are stored
gCurrentGame
!byte $FD ; set at runtime
kGameRootDirectory ; length-prefixed pathname of where game subdirectories are stored
!byte 14
!raw "/PITCH.DARK/Z/" ; TODO use relative path ('Z/') for final release
kInfoFilename ; length-prefixed partial pathname of game info file, starting with '/' because reasons
.infoFilename ; length-prefixed partial pathname of game info file, starting with '/' because reasons
!byte 5
!raw "/INFO"
subdirectories ; length of this array must = kNumberOfGames, there is no range checking
GAMES ; length of this array must = kNumberOfGames, there is no range checking
!word .ballyhoo
!word .cutthroats
!word .deadline
@ -159,22 +161,22 @@ addrVersions
; all other registers and flags clobbered
;------------------------------------------------------------------------------
LoadGameInfo
stz .path
lda #<kGameDirectory
ldy #>kGameDirectory
jsr .addToPath
jsr ResetPath
lda #<kGameRootDirectory
ldy #>kGameRootDirectory
jsr AddToPath
lda gCurrentGame
asl
tax
lda subdirectories,x
ldy subdirectories+1,x
jsr .addToPath
lda #<kInfoFilename
ldy #>kInfoFilename
jsr .addToPath
lda GAMES,x
ldy GAMES+1,x
jsr AddToPath
lda #<.infoFilename
ldy #>.infoFilename
jsr AddToPath
jsr LoadFile
!word .path
!word gPathname
!word $0800
!word $1400
!word $1C00
@ -291,25 +293,4 @@ parseloop
rts
+ sec
rts
.addToPath
sta $00
sty $01
ldx .path ; current pathname length
lda ($00) ; length of this segment
inc
sta .a+1
ldy #$01
- lda ($00),y
sta .pathbuffer,x
inx
iny
.a cpy #$FD ; set at runtime
bcc -
stx .path
rts
.path
!byte $FD ; set at runtime
.pathbuffer
!fill 64 ; enough zeroes for any ProDOS pathname
}

View File

@ -117,6 +117,7 @@ PaintAllViews
;------------------------------------------------------------------------------
RepaintSomeViews
jsr .paintInfoView
jsr .resetDescriptionViewScrolling
jmp .paintDescriptionView
;------------------------------------------------------------------------------
@ -135,17 +136,6 @@ RepaintSomeViews
jsr NORMAL
rts
.paintInfoView
ldx #WGSelectView
lda #12
jsr WeeGUI
ldx #WGEraseViewContents
jsr WeeGUI
lda addrInfo
ldy addrInfo+1
ldx #0
bra .multiPrint
.paintDescriptionView
ldx #WGSelectView
lda #13
@ -155,6 +145,23 @@ RepaintSomeViews
lda addrDescription
ldy addrDescription+1
ldx #1
jsr .multiPrint
lda .vtab+1
cmp #10
bcs +
lda #10
+ sta $59B6 ; HACKHACKHACK set view height inside WeeGUI internals (WG_VIEWRECORDS)
rts
.paintInfoView
ldx #WGSelectView
lda #12
jsr WeeGUI
ldx #WGEraseViewContents
jsr WeeGUI
lda addrInfo
ldy addrInfo+1
ldx #0
; note: execution falls through here
.multiPrint
@ -163,6 +170,8 @@ RepaintSomeViews
stx .htab+1
stx .vtab+1
.printLoop
lda ($00)
beq .printDone
ldx #WGSetCursor
.htab lda #$FD ; set at runtime
sta PARAM0
@ -179,15 +188,14 @@ RepaintSomeViews
bit #%00000000
- lda ($00)
bne +
bit MAGICRTS
bit MAGICRTS ; set overflow bit
+ inc $00
bne +
inc $01
+ bvc -
inc .vtab+1
lda .vtab+1
cmp #$06
bne .printLoop
.printDone
rts
.createButton
@ -212,10 +220,21 @@ RepaintSomeViews
ldx #WGCreateButton
jsr WeeGUI
ldx #WGViewSetRawTitle
lda #RAW
lda #1
sta PARAM0
jmp WeeGUI
.resetDescriptionViewScrolling
ldx #WGSelectView
lda #ID_DESCRIPTION
jsr WeeGUI
ldx #WGScrollX
lda #0
jsr WeeGUI
ldx #WGScrollY
lda #0
jmp WeeGUI
.viewTitle
!byte ID_TITLE ; view ID
!byte 0 ; style
@ -309,9 +328,11 @@ RepaintSomeViews
!byte ID_DESCRIPTION ; view ID
!byte 2 ; style
!byte 1 ; left
.viewDescriptionMinHeight
!byte 15 ; top
!byte 77 ; visible width
!byte 8 ; visible height
!byte 77 ; width
!byte 17 ; height
.viewDescriptionHeight
!byte 39 ; height
}

51
src/path.a Normal file
View File

@ -0,0 +1,51 @@
;license:MIT
;(c) 2018 by 4am
;
; Functions to build a ProDOS pathname from length-prefixed strings
;
; Public functions
; - ResetPath
; - AddToPath
;
; Public variables
; - gPathname
;
;------------------------------------------------------------------------------
; ResetPath
; reset gPathname to length 0
;
; in: none
; out: all registers preserved
;------------------------------------------------------------------------------
ResetPath
stz gPathname
rts
;------------------------------------------------------------------------------
; AddToPath
; append a length-prefixed string to gPathname
;
; in: A contains low byte of address of length-prefixed string to append
; Y contains high byte of address of length-prefixed string to append
; out: all registers and flags clobbered
;------------------------------------------------------------------------------
AddToPath
sta $00
sty $01
ldx gPathname ; current pathname length
lda ($00) ; length of this segment
inc
sta .a+1
ldy #$01
- lda ($00),y
sta gPathname+1,x
inx
iny
.a cpy #$FD ; set at runtime
bcc -
stx gPathname
rts
gPathname
!fill 65 ; enough zeroes for any ProDOS pathname

View File

@ -6,37 +6,50 @@
!to "../build/PITCHDRK.SYSTEM#FF2000",plain
*=$2000
; application constants
RAW = 1
!zone {
jmp .start
ldx #$20
ldy #$00
.copya lda CodeStart,y
.copyb sta $6000,y
iny
bne .copya
inc .copya+2
inc .copyb+2
dex
bne .copya
!cpu 65816
sep #2 ; set Z flag on 65816 only
!cpu 65c02
bne + ; skip GS-specific code on non-GS machines (required, will crash on //c, grr)
lda $C029
and #$1F
sta $C029 ; set GS NEWVIDEO mode to turn off linearize
+ jmp Start
CodeStart
!pseudopc $6000 {
.weeguiFilename
!byte 10
!raw "BIN/WEEGUI"
!source "WeeGUI_MLI.s"
.weeguiFilename
!byte 6
!raw "WEEGUI"
!source "prodos.a"
!source "ramdisk.a"
!source "path.a"
!source "config.a"
!source "action.a"
!source "paint.a"
.start
Start
lda MACHID
and #$30
cmp #$30 ; 128K?
beq + ; yes, continue
jmp QuitToProDOS
+
bit $c010
+ jsr DisconnectRAM32 ; disconnect /RAM in S3,D2 so we can use DHGR
bit $C010
jsr LoadFile ; load WEEGUI binary at $4000
!word .weeguiFilename
!word $4000
!word $2000
!word $1C00
jsr $4000 ; initialize WeeGUI
lda #22 ; TODO load this from a prefs file instead
@ -44,14 +57,11 @@ RAW = 1
jsr LoadGameInfo ; load and parse game description text
jsr CreateViews ; create all WeeGUI views (UI elements)
ldx #WGClearScreen ; clear screen
jsr WeeGUI
jsr PaintAllViews ; draw all UI elements
ldx #WGEnableMouse ; enable mouse support
jsr WeeGUI
.runLoop
ldx #WGPendingViewAction
jsr WeeGUI
@ -61,9 +71,12 @@ RAW = 1
jsr HandleKey
bcc .runLoop
jsr ExitWeeGUI
jmp QuitToProDOS ; quit via ProDOS MLI
ExitWeeGUI
ldx #WGDisableMouse ; disable mouse support before quitting
jsr WeeGUI
ldx #WGExit ; clean up WeeGUI
jsr WeeGUI
jmp QuitToProDOS ; quit via ProDOS MLI
jmp WeeGUI
}

View File

@ -6,6 +6,7 @@
; Public functions
; - LoadFile
; - SaveFile
; - SetPrefix
; - QuitToProDOS
;
@ -13,6 +14,7 @@
CMD_QUIT = $65 ; quit to ProDOS
CMD_CREATE = $C0 ; create new file
CMD_DESTROY = $C1 ; delete a file
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
@ -22,6 +24,7 @@ CMD_CLOSE = $CC ; close an open file
PC_QUIT = $04
PC_CREATE = $07
PC_DESTROY = $01
PC_SETPREFIX = $01
PC_OPEN = $03
PC_READ = $04
PC_WRITE = $04
@ -189,6 +192,42 @@ SaveFile
rts
}
;-------------------------------
; 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
;-------------------------------
!zone {
SetPrefix
pla
sta $00
plx
stx $01
lda #$02
clc
adc $00
bcc +
inx
+ phx
pha
ldy #$01
lda ($00),y ; lo byte of pathname
sta mliparam+1
iny
lda ($00),y ; hi byte of pathname
sta mliparam+2
jmp _setprefix
}
;-------------------------------
; open file via ProDOS MLI
;
@ -301,6 +340,21 @@ _deletefile
jsr mli
rts
;-------------------------------
; change current directory (set prefix)
; using ProDOS MLI
; in: caller has filled @mliparam
; with address of pathname
; out: if error, C set and A contains error code
; if success, C clear
;-------------------------------
_setprefix
lda #CMD_SETPREFIX
ldy #PC_SETPREFIX
jsr mli
rts
;-------------------------------
QuitToProDOS
lda #CMD_QUIT
ldy #PC_QUIT

73
src/ramdisk.a Normal file
View File

@ -0,0 +1,73 @@
;license:MIT
;(c) 2018 by 4am
;
; /RAM routines
; see ProDOS TechNote #26 Polite Use of Auxiliary Memory
; and ProDOS 8 Technical Reference Manual 5.2.2.2 Disconnecting /RAM
;
; Public functions
; - DisconnectRAM32
;
; TODO reconnect on exit
;
MLI = $BF00 ; ProDOS MLI entry point
NODEV = $BF10 ; means 'no device connected'
RAM32 = $BF26 ; S3,D2 /RAM device
DEVCNT = $BF31 ; ProDOS device count
DEVLST = $BF32 ; ProDOS device list
MACHID = $BF98 ; machine identification byte
;------------------------------------------------------------------------------
; DisconnectRAM32
; disconnect ProDOS /RAM disk in S3,D2
; (does not affect other RAM disks like RAMWorks or RAMFactor)
;
; in: ProDOS in memory
; out: C clear if /RAM was found and disconnected
; C set if /RAM was not found or could not be disconnected
; all other registers and flags clobbered
;------------------------------------------------------------------------------
!zone {
DisconnectRAM32
lda RAM32 ; search for /RAM and disconnect if found
cmp NODEV
bne +
lda RAM32+1
cmp NODEV+1
beq .noRAMdisk
+ ldy DEVCNT
- lda DEVLST, y
and #$F3
cmp #$B3
beq .foundRAMdisk
dey
bpl -
bmi .noRAMdisk
.foundRAMdisk
lda DEVLST, y
sta saveRAMDiskUnit ; save RAM disk unit number
- lda DEVLST+1, y ; move other devices up in list
sta DEVLST, y
beq + ; device list is zero-terminated
iny
bne - ; always branches
+
lda RAM32
sta saveRAMDiskDriver ; save RAM disk device address
lda RAM32+1
sta saveRAMDiskDriver+1
lda NODEV ; tell ProDOS there's no RAM disk anymore
sta RAM32
lda NODEV+1
sta RAM32+1
dec DEVCNT ; reduce ProDOS device count
clc
rts
.noRAMdisk
sec
rts
saveRAMDiskUnit
!byte 0
saveRAMDiskDriver
!word 0
}