mirror of
https://github.com/a2-4am/dhrslide.git
synced 2024-11-04 19:05:02 +00:00
initial import
This commit is contained in:
commit
5f27aeb2fb
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.DS_Store
|
||||
/build/
|
32
Makefile
Normal file
32
Makefile
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# DHRSLIDE.SYSTEM Makefile
|
||||
# assembles source code, optionally builds a disk image and mounts it
|
||||
#
|
||||
# original by Quinn Dunki on 2014-08-15
|
||||
# One Girl, One Laptop Productions
|
||||
# http://www.quinndunki.com/blondihacks
|
||||
#
|
||||
# adapted by 4am on 2018-01-08
|
||||
#
|
||||
|
||||
# third-party tools required to build
|
||||
# https://sourceforge.net/projects/acme-crossass/
|
||||
ACME=acme
|
||||
# https://sourceforge.net/projects/applecommander/
|
||||
AC=bin/AppleCommander.jar
|
||||
|
||||
BUILDDISK=build/dhrslide.po
|
||||
|
||||
asm:
|
||||
mkdir -p build
|
||||
cd src && $(ACME) -r ../build/dhrslide.lst dhrslide.system.a
|
||||
cp res/work.po $(BUILDDISK)
|
||||
java -jar $(AC) -p $(BUILDDISK) "DHRSLIDE.SYSTEM" sys 0x2000 < "build/DHRSLIDE.SYSTEM#FF2000"
|
||||
|
||||
clean:
|
||||
rm -rf build/
|
||||
|
||||
mount:
|
||||
osascript bin/V2Make.scpt "`pwd`" $(BUILDDISK)
|
||||
|
||||
all: clean asm mount
|
BIN
bin/AppleCommander.jar
Normal file
BIN
bin/AppleCommander.jar
Normal file
Binary file not shown.
BIN
bin/V2Make.scpt
Normal file
BIN
bin/V2Make.scpt
Normal file
Binary file not shown.
BIN
res/work.po
Normal file
BIN
res/work.po
Normal file
Binary file not shown.
414
src/dhrslide.system.a
Normal file
414
src/dhrslide.system.a
Normal file
@ -0,0 +1,414 @@
|
||||
!cpu 6502
|
||||
!to "../build/DHRSLIDE.SYSTEM#FF2000",plain
|
||||
*=$2000
|
||||
;
|
||||
; DHRSLIDE.SYSTEM
|
||||
; (c) 2018 by 4am
|
||||
; a small DHGR graphics slideshow
|
||||
; loads first .a2fc file in current directory,
|
||||
; displays it,
|
||||
; waits,
|
||||
; finds next .a2fc file in same directory,
|
||||
; repeats endlessly until keypress,
|
||||
; quits via MLI
|
||||
;
|
||||
; known bugs:
|
||||
; - does not reconnect /RAM properly, not sure why
|
||||
;
|
||||
|
||||
;
|
||||
; application-specific addresses
|
||||
;
|
||||
entry = $82
|
||||
aDirData = $1600
|
||||
aDirBuff = $1800
|
||||
aFileBuff = $1C00
|
||||
;
|
||||
; application constants
|
||||
;
|
||||
TRUE = $00
|
||||
FALSE = $FF
|
||||
;
|
||||
; ProDOS addresses
|
||||
;
|
||||
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
|
||||
;
|
||||
; ProDOS constants
|
||||
;
|
||||
kMLIGetPrefix = $C7
|
||||
kMLIGetPrefixCount = 1
|
||||
kMLIOpen = $C8
|
||||
kMLIOpenCount = 3
|
||||
kMLIRead = $CA
|
||||
kMLIReadCount = 4
|
||||
kMLIClose = $CC
|
||||
kMLICloseCount = 1
|
||||
kMLISetMark = $CE
|
||||
kMLISetMarkCount = 2
|
||||
kMLIQuit = $65
|
||||
kMLIQuitCount = 4
|
||||
;
|
||||
; ROM addresses
|
||||
;
|
||||
ROM80STOREOFF = $C000
|
||||
KEY = $C000
|
||||
WRITEMAINMEM = $C004
|
||||
WRITEAUXMEM = $C005
|
||||
;
|
||||
; memory map
|
||||
;
|
||||
; 0800..0AFF relocated program code
|
||||
; 0800..0AFF[aux] copy of program code
|
||||
; 1600..17FF buffer for directory block
|
||||
; 1800..1BFF ProDOS file buffer for reading directory
|
||||
; 1C00..1FFF ProDOS file buffer for reading file
|
||||
; 2000..3FFF graphics page 1 [shown]
|
||||
; 2000..3FFF[aux] graphics page 1 [shown]
|
||||
; 4000..5FFF offscreen buffer for next graphic file
|
||||
; 4000..5FFF[aux] offscreen buffer for next graphic file
|
||||
;
|
||||
|
||||
jmp Start ; magic jump
|
||||
!byte $EE,$EE ; magic bytes
|
||||
!byte $40 ; length of inputbuffer
|
||||
inputbuffer
|
||||
!fill $40
|
||||
Start
|
||||
!cpu 65816
|
||||
sep #2 ; set Z flag on 65816 only
|
||||
!cpu 6502
|
||||
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
|
||||
+
|
||||
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
|
||||
noRAMdisk
|
||||
sta ROM80STOREOFF
|
||||
ldx #$00 ; copy code to lower memory so we can load graphic at $2000
|
||||
- lda CodeStart, x
|
||||
sta $0800, x
|
||||
lda CodeStart+$100, x
|
||||
sta $0900, x
|
||||
lda CodeStart+$200, x
|
||||
sta $0A00, x
|
||||
sta WRITEAUXMEM
|
||||
lda CodeStart, x ; also copy it to aux memory so fizzle fade can freely switch back and forth
|
||||
sta $0800, x
|
||||
lda CodeStart+$100, x
|
||||
sta $0900, x
|
||||
lda CodeStart+$200, x
|
||||
sta $0A00, x
|
||||
sta WRITEMAINMEM
|
||||
inx
|
||||
bne -
|
||||
|
||||
jmp $0800
|
||||
|
||||
CodeStart
|
||||
!pseudopc $800 {
|
||||
jsr CheckFor128K ; does not return if we have less than 128K
|
||||
lda #kMLIGetPrefix
|
||||
ldy #kMLIGetPrefixCount
|
||||
ldx #FALSE ; do not return to caller on error
|
||||
jsr CallMLI ; get current prefix
|
||||
|
||||
lda #kMLIOpen
|
||||
ldy #kMLIOpenCount
|
||||
ldx #FALSE ; do not return to caller on error
|
||||
jsr CallMLI ; open directory as file
|
||||
|
||||
lda mliparam+5 ; directory refnum
|
||||
sta saveDirRefnum
|
||||
ReadFirstDirectoryBlock
|
||||
lda foundAtLeastOne ; if we've gone through the entire directory and ended up
|
||||
beq + ; back here without ever finding a suitable file to display,
|
||||
jmp CloseAll ; just quit
|
||||
+ lda #FALSE
|
||||
sta foundAtLeastOne
|
||||
lda #$00
|
||||
sta entryLength
|
||||
sta mliparam+2 ; position for MLI_SET_MARK
|
||||
sta mliparam+3
|
||||
sta mliparam+4
|
||||
lda saveDirRefnum
|
||||
sta mliparam+1
|
||||
lda #kMLISetMark
|
||||
ldy #kMLISetMarkCount
|
||||
ldx #FALSE ; do not return to caller on error
|
||||
jsr CallMLI ; set mark of directory file back to the beginning (position 000000)
|
||||
ReadNextDirectoryBlock
|
||||
lda saveDirRefnum
|
||||
sta mliparam+1 ; refnum for directory-as-file
|
||||
lda #<aDirData
|
||||
sta mliparam+2
|
||||
lda #>aDirData+1
|
||||
sta mliparam+3 ; store in (aDirData)
|
||||
lda #$00
|
||||
sta mliparam+4
|
||||
lda #$02 ; read $0200 bytes (= 2 sectors, = 1 ProDOS block)
|
||||
sta mliparam+5
|
||||
lda #kMLIRead
|
||||
ldy #kMLIReadCount
|
||||
ldx #TRUE ; always return to caller, even if there is an error
|
||||
jsr CallMLI ; MLI_READ to read a directory block
|
||||
bcc firstTimeSetup ; check error manually
|
||||
cmp #$4C ; MLI error was EOF?
|
||||
beq ReadFirstDirectoryBlock;yes, start over at the beginning of directory
|
||||
bne CloseAll ; no, real error
|
||||
firstTimeSetup
|
||||
lda entryLength
|
||||
bne skipFirstTime
|
||||
lda aDirData+$23
|
||||
sta entryLength
|
||||
lda aDirData+$24
|
||||
sta entriesPerBlock
|
||||
skipFirstTime
|
||||
lda #<(aDirData+4)
|
||||
sta entry
|
||||
lda #>(aDirData+4)
|
||||
sta entry+1
|
||||
lda entriesPerBlock
|
||||
sta entriesRemaining
|
||||
GoToNextEntry
|
||||
dec entriesRemaining
|
||||
beq ReadNextDirectoryBlock
|
||||
lda entry
|
||||
clc
|
||||
adc entryLength
|
||||
sta entry
|
||||
lda entry+1
|
||||
adc #$00
|
||||
sta entry+1
|
||||
ldy #$00
|
||||
lda (entry), y
|
||||
and #$F0
|
||||
cmp #$00
|
||||
beq GoToNextEntry ; skip inactive entry
|
||||
cmp #$D0
|
||||
beq GoToNextEntry ; skip subdirectory
|
||||
ldy #$00
|
||||
lda (entry), y ; get filename length
|
||||
and #$0F
|
||||
sta (entry), y ; store actual length so we can use this as a length-prefixed string later
|
||||
cmp #$06
|
||||
bcc GoToNextEntry ; filename not long enough, skip entry
|
||||
tay
|
||||
ldx #$04
|
||||
- lda (entry), y
|
||||
cmp suffix, x ; match required suffix ('.A2FC')
|
||||
bne GoToNextEntry ; no match, skip entry
|
||||
dey
|
||||
dex
|
||||
bpl -
|
||||
lda #TRUE
|
||||
sta foundAtLeastOne
|
||||
jsr DisplayFile
|
||||
lda #$00
|
||||
ldy #$15
|
||||
.wait0 sec
|
||||
.wait1 pha
|
||||
.wait2 sbc #$01
|
||||
bne .wait2
|
||||
pla
|
||||
ldx KEY
|
||||
bmi CloseAll
|
||||
sbc #$01
|
||||
bne .wait1
|
||||
dey
|
||||
bpl .wait0
|
||||
bmi GoToNextEntry
|
||||
|
||||
CloseAll
|
||||
lda #$00
|
||||
sta mliparam+1 ; close all open files
|
||||
lda #kMLIClose
|
||||
ldy #kMLICloseCount
|
||||
ldx #TRUE ; always return to caller, even on error (which we will ignore)
|
||||
jsr CallMLI
|
||||
; execution falls through here
|
||||
|
||||
Quit
|
||||
lda saveRAMDiskUnit
|
||||
beq noReconnect
|
||||
ldy DEVCNT ; reconnect /RAM
|
||||
- lda DEVLST
|
||||
and #$F0
|
||||
cmp #$B0
|
||||
beq noReconnect
|
||||
dey
|
||||
bpl -
|
||||
lda saveRAMDiskDriver ; restore /RAM driver
|
||||
sta RAM32
|
||||
lda saveRAMDiskDriver+1
|
||||
sta RAM32+1
|
||||
inc DEVCNT ; insert /RAM unit into front of device list
|
||||
ldy DEVCNT
|
||||
- lda DEVLST-1, y
|
||||
sta DEVLST
|
||||
dey
|
||||
bne -
|
||||
lda #$03 ; format /RAM
|
||||
sta $42
|
||||
lda saveRAMDiskUnit
|
||||
sta DEVLST
|
||||
and #$F0
|
||||
sta $43
|
||||
lda #<aFileBuff
|
||||
sta $44
|
||||
lda #>aFileBuff
|
||||
sta $45
|
||||
lda $C08B
|
||||
lda $C08B
|
||||
jsr CallRAMDriver
|
||||
bit $C082
|
||||
noReconnect
|
||||
bit $C010 ; reset keyboard strobe on the way out
|
||||
lda #kMLIQuit
|
||||
ldy #kMLIQuitCount
|
||||
; execution falls through here
|
||||
|
||||
CallMLI
|
||||
sta mlicmd
|
||||
sty mliparam
|
||||
jsr MLI
|
||||
mlicmd !byte $00
|
||||
!word mliparam
|
||||
bcc + ; no MLI error, so return
|
||||
cpx #TRUE ; MLI error, so check if caller wants us to return or not
|
||||
bne CloseAll ; caller said don't return on error, so close and quit
|
||||
+ rts
|
||||
mliparam
|
||||
!byte 0
|
||||
!word inputbuffer
|
||||
!word aDirBuff
|
||||
!byte 0,0,0 ; extra space for MLI_READ (longest parameter block)
|
||||
|
||||
CheckFor128K
|
||||
lda MACHID
|
||||
and #$30
|
||||
cmp #$30
|
||||
bne Quit
|
||||
rts
|
||||
|
||||
!source "fizzledhgr.a"
|
||||
|
||||
DisplayFile
|
||||
lda entry
|
||||
sta mliparam+1 ; (entry) points to filename in aDirData
|
||||
lda entry+1
|
||||
sta mliparam+2
|
||||
lda #<aFileBuff
|
||||
sta mliparam+3
|
||||
lda #>aFileBuff
|
||||
sta mliparam+4
|
||||
lda #kMLIOpen
|
||||
ldy #kMLIOpenCount
|
||||
ldx #FALSE
|
||||
jsr CallMLI ; open .a2fc file
|
||||
lda KEY
|
||||
bpl +
|
||||
rts
|
||||
+ lda mliparam+5
|
||||
sta saveFileRefnum
|
||||
sta mliparam+1
|
||||
lda #$00
|
||||
sta mliparam+2
|
||||
sta mliparam+4
|
||||
lda #$40
|
||||
sta mliparam+3 ; read into $4000
|
||||
sta copya+2
|
||||
sta copyb+2
|
||||
lda #$20
|
||||
sta mliparam+5 ; $2000 bytes
|
||||
lda #kMLIRead
|
||||
ldy #kMLIReadCount
|
||||
ldx #FALSE
|
||||
jsr CallMLI ; read first half of .a2fc file (will copy to auxmem)
|
||||
lda KEY
|
||||
bpl +
|
||||
rts
|
||||
+ sta ROM80STOREOFF
|
||||
ldx #$20 ; copy $2000 bytes to auxmem
|
||||
ldy #$00
|
||||
copyToAux
|
||||
sta WRITEAUXMEM
|
||||
copya lda $FF00, y ; self-modified address
|
||||
copyb sta $FF00, y ; self-modified address
|
||||
iny
|
||||
bne copya
|
||||
sta WRITEMAINMEM
|
||||
inc copya+2
|
||||
inc copyb+2
|
||||
dex
|
||||
bne copyToAux
|
||||
lda #kMLIRead
|
||||
ldy #kMLIReadCount
|
||||
ldx #FALSE
|
||||
jsr CallMLI ; read second half of .a2fc file (stays in main memory)
|
||||
lda #kMLIClose
|
||||
ldy #kMLICloseCount
|
||||
ldx #FALSE
|
||||
jsr CallMLI
|
||||
jmp Fizzle ; fancy memory copy from page 2 to 1
|
||||
|
||||
CallRAMDriver
|
||||
jmp (RAM32)
|
||||
;
|
||||
; global variables
|
||||
;
|
||||
saveRAMDiskUnit
|
||||
!byte 0
|
||||
saveRAMDiskDriver
|
||||
!word 0
|
||||
entryLength
|
||||
!byte $00
|
||||
entriesPerBlock
|
||||
!byte $00
|
||||
entriesRemaining
|
||||
!byte $00
|
||||
foundAtLeastOne
|
||||
!byte TRUE
|
||||
saveDirRefnum
|
||||
!byte $00
|
||||
saveFileRefnum
|
||||
!byte $00
|
||||
suffix
|
||||
!text ".A2FC"
|
||||
}
|
||||
CodeEnd
|
83
src/fizzledhgr.a
Normal file
83
src/fizzledhgr.a
Normal file
@ -0,0 +1,83 @@
|
||||
;license:MIT
|
||||
;(c) 2017-2018 by qkumba
|
||||
;
|
||||
; assumes this code is in an identical location in auxmem
|
||||
; (currently taken care of in dhrslide.system.a)
|
||||
;
|
||||
Fizzle
|
||||
;graphics mode
|
||||
|
||||
sta $c00d
|
||||
sta $c057
|
||||
sta $c052
|
||||
sta $c050
|
||||
sta $c05e
|
||||
|
||||
;init RNG
|
||||
|
||||
ldx #1
|
||||
stx rndval1+1
|
||||
dex
|
||||
stx rndval2+1
|
||||
|
||||
;iterate
|
||||
|
||||
- ldy rndval1+1
|
||||
ldx rndval2+1
|
||||
lsr rndval2+1
|
||||
ror rndval1+1
|
||||
bcc +
|
||||
|
||||
;feedback polynomial forms #$2015 for period of 16383
|
||||
|
||||
lda rndval1+1
|
||||
eor #$15
|
||||
sta rndval1+1
|
||||
lda rndval2+1
|
||||
eor #$20
|
||||
sta rndval2+1
|
||||
|
||||
;little hack to avoid missing offset zero
|
||||
;screen hole at $xxFF is missed instead
|
||||
|
||||
+ tya
|
||||
eor #$ff
|
||||
sta $26
|
||||
sta $3c
|
||||
txa
|
||||
and #$1f
|
||||
|
||||
;target page 1
|
||||
|
||||
ora #$20
|
||||
sta $27
|
||||
eor #$60
|
||||
sta $3d
|
||||
|
||||
;copy pixel from other page to this page
|
||||
|
||||
ldy #0
|
||||
cpx #$20
|
||||
bcc +
|
||||
sta $c003
|
||||
sta $c005
|
||||
+ lda ($3c),y
|
||||
sta ($26),y
|
||||
sta $c002
|
||||
sta $c004
|
||||
|
||||
;check for keypress
|
||||
|
||||
lda $c000
|
||||
bmi fizzledone
|
||||
|
||||
;and exit condition
|
||||
|
||||
rndval2 lda #0
|
||||
bne -
|
||||
rndval1 lda #0
|
||||
cmp #1
|
||||
bne -
|
||||
|
||||
fizzledone
|
||||
rts
|
Loading…
Reference in New Issue
Block a user