prorwts: sort of figured out what proboothd is doing

This commit is contained in:
Vince Weaver 2024-07-15 16:31:49 -04:00
parent 82e952bdfb
commit 491eb4ca4e
4 changed files with 579 additions and 124 deletions

View File

@ -19,15 +19,15 @@ prorwts_ca65.o: prorwts_ca65.s
###
prorwts_test.2mg: \
PROBOOTHD
PROBOOTHD SEASONS
$(CADIUS) CREATEVOLUME prorwts_test.2mg Test 32MB
dd conv=notrunc if=PROBOOTHD of=prorwts_test.2mg bs=512 count=1
dd conv=notrunc if=PROBOOTHD of=prorwts_test.2mg bs=1 count=512 oseek=64
# $(CADIUS) CREATEFOLDER prorwts_test.2mg /Test/DISK01
# $(CADIUS) CREATEFOLDER prorwts_test.2mg /Test/DISK39
# $(CADIUS) CREATEFOLDER prorwts_test.2mg /Test/DISK40
# $(CADIUS) CREATEFOLDER prorwts_test.2mg /Test/DISK41
# $(CADIUS) CREATEFOLDER prorwts_test.2mg /Test/DISK43
# $(CADIUS) ADDFILE prorwts_test.2mg /Test/DISK01/ disk01_files/LEVEL_ARRIVAL
$(CADIUS) ADDFILE prorwts_test.2mg /Test/ SEASONS#061000
###
@ -39,5 +39,14 @@ proboothd.o: proboothd.s
####
SEASONS: seasons.o
ld65 -o SEASONS seasons.o -C ../../linker_scripts/apple2_1000.inc
seasons.o: seasons.s
ca65 -o seasons.o seasons.s -l seasons.lst
####
clean:
rm -f *~ *.o *.lst
rm -f *~ *.o *.lst PROBOOTHD SEASONS

99
disk/prorwts/hardware.inc Normal file
View File

@ -0,0 +1,99 @@
;; HARDWARE LOCATIONS
KEYPRESS = $C000
KEYRESET = $C010
;; SOFT SWITCHES
CLR80COL = $C000 ; (w) PAGE1/PAGE2 normal
SET80COL = $C001 ; (w) PAGE1/PAGE2 switches PAGE1 in Aux instead
READMAINMEM = $C002 ; (w) to read from main mem ($0200..$BFFF)
READAUXMEM = $C003 ; (w) to read from aux mem ($0200..$BFFF)
WRITEMAINMEM = $C004 ; (w) to write to main mem ($0200..$BFFF)
WRITEAUXMEM = $C005 ; (w)to write to aux mem ($0200..$BFFF)
SETSTDZP = $C008 ; (w) to use main mem stack/zp ($00FF-$01FF)
EIGHTYCOLOFF = $C00C ; (w) use 40 cols / exit DHGR
EIGHTYCOLON = $C00D
PRIMARYCHARSET = $C00E ; (w) to disable mousetext
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
; $C081 for setting language card
; $C082 for setting READ_ROM_NOWRITE
;; 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
INIT_TEXT = $FB2F ; set lo-res/page1 and call text
TEXT = $FB36
GR = $FB40
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
SETKBD = $FE89 ; set input to keyboard
SETVID = $FE93 ; set output to video 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

View File

@ -5,65 +5,104 @@
;
;copyright (c) Peter Ferrie 2016-2019
.include "hardware.inc"
PROBOOTENTRY = $2000
; zpage usage, arbitrary selection except for the "ProDOS constant" ones
command = $42 ;ProDOS constant
unit = $43 ;ProDOS constant
adrlo = $44 ;ProDOS constant
adrhi = $45 ;ProDOS constant
bloklo = $46 ;ProDOS constant
blokhi = $47 ;ProDOS constant
command = $42 ; ProDOS constant
UNIT = $43 ; ProDOS constant
ADRLO = $44 ; ProDOS constant
ADRHI = $45 ; ProDOS constant
BLOKLO = $46 ; ProDOS constant
BLOKHI = $47 ; ProDOS constant
A2L = $3e
A2H = $3f
sizehi = $53
;constants
scrn2p2 = $f87b
SCRN2P2 = $f87b ; shifts top nibble to bottom
dirbuf = $1e00 ;for size-optimisation
; start of boot sector, how many sectors to load
; start of boot sector, presumably how many sectors to load
; 512 bytes on prodos/hard-disk(???)
.byte 1
proboot_start:
txa
pha
pha ; save slot for later
lda #'A'+$80
sta $400 ; write A to upper-left of screen
; init. is all this necessary?
; originally "4cade.init.machine.a"
forever:
jmp forever
cld ; clear direction flag
sta $C082 ; read rom / no write (language card)
sta PRIMARYCHARSET ; turn off mouse text
sta EIGHTYCOLOFF ; disable 80-col mode
sta CLR80COL
sta READMAINMEM ; make sure not using aux mem
sta WRITEMAINMEM
sta SETSTDZP
; more init
; originally "4cade.init.screen.a"
; initializes and clears screen using ROM routines
jsr INIT_TEXT ; setup text mode
jsr HOME ; clear screen
jsr SETNORM ; normal text
jsr SETKBD ; keyboard input
jsr SETVID ; video output
; set up disk stuff?
pla ; restore slot
sta UNIT ; save for later
tax
; X = boot slot x16
; Y = 0
; 4cade calls a print-title routine here that exits with Y=0
ldy #0
; set up ProDOS shim
; from IIgs smartport firmware manual
; prodos entry point is $CX00+($CXFF)
; so if slot 7, $C700 + value in $C7ff (say, A) so $C70A
; smartport entry point is $CX00+(CXFF)+3
;src "src/4cade.init.machine.a"
setup_loop:
txa
jsr SCRN2P2 ; shift top nibble of A to bottom
and #7
ora #$c0
sta $be30, Y ; ????
sta slot_smc+2
sta entry_smc+2 ; set up smartport/prodos entry point
; src "src/4cade.init.screen.a"
slot_smc:
lda $cfff
sta entry_smc+1 ; set up rest of smartport/prodos entry
lda fakeMLI_e-$100, Y
sta $be00+fakeMLI_e-fakeMLI, Y
iny
bne setup_loop ; ?????
; pla
; sta unit
; tax
; ; X = boot slot x16
; ; Y = 0
; set up ProDOS shim
;- txa
; jsr scrn2p2
; and #7
; ora #$c0
; sta $be30, y
; sta slot+2
; sta entry+2
;slot lda $cfff
; sta entry+1
; lda fakeMLI_e-$100, y
; sta $be00+fakeMLI_e-fakeMLI, y
; iny
; bne -
; sty adrlo
; stx $bf30
; sty $200
; Y is 0 here
; ldy #0
sty ADRLO
stx $bf30 ; ?????
sty $200 ; ?????
opendir:
; read volume directory key block
@ -72,116 +111,155 @@ opendir:
; include volume directory header in count
firstent:
lda #>dirbuf
sta adrhi
lda #>dirbuf ; load volume block to ADDRH/L (dirbuf/$1e00)
sta ADRHI
sta A2H
jsr seekread
lda #4
lda #4 ; start at filename offset
sta A2L
nextent:
ldy #0
; match name lengths before attempting to match names
; first byte, bottom nibble is length
; lda (A2L), y
; and #$0f
; tax
; inx
;- cmp filename, y
; beq foundname
lda (A2L), Y
and #$0f
tax
inx
;move to next directory in this block
try_again:
cmp filename, Y
beq filename_char_match
; clc
; lda A2L
; adc #$27
; sta A2L
; bcc +
; move to next directory in this block
not_found:
clc
lda A2L
adc #$27
sta A2L
bcc no_cross_page
;there can be only one page crossed, so we can increment instead of adc
; there can be only one page crossed,
; so we can increment instead of adc
; inc A2H
;+ cmp #$ff ;4+($27*$0d)
; bne nextent
inc A2H
no_cross_page:
cmp #$ff ; 4+($27*$0d)
bne nextent
;read next directory block when we reach the end of this block
; read next directory block when we reach the end of this block
; ldx dirbuf+2
; ldy dirbuf+3
; bcs firstent
ldx dirbuf+2
ldy dirbuf+3
bcs firstent
foundname:
; iny
; lda (A2L), y
; dex
; bne -
; stx $ff
filename_char_match:
iny ; point to next char
lda (A2L), Y ; grab value
dex ; countdown filename length
bne try_again ; if not full match, keep going
;cache KEY_POINTER
; ldy #$11
; lda (A2L), y
; tax
; iny
; lda (A2L), y
; tay
stx $ff ; set address $FF in zero page to zero?
; bytes $11 and $12 in the file entry are the "key pointer"
ldy #$11
lda (A2L), Y
tax
iny
lda (A2L), Y
tay
; seedling files = less than 512 bytes, contents are simply key block
; storage type is $1
; sapling files = 512B - 128k
; key block has low bytes of addrss in 0..255 and high in 256..512
; storage type is $2
; tree files = 128k - 16M
; read the 512-byte block at key pointer into memory
; will only work for a "sapling" file?
readfile:
; jsr seekread
; inc adrhi
; inc adrhi
jsr seekread
;fetch data block and read it
inc ADRHI ; point destination past it (so at $2000)
inc ADRHI
; fetch contents of file?
; just keep reading 512-byte blocks until done?
; this means file will be at $2000?
blockind:
; ldy $ff
; inc $ff
; ldx dirbuf, y
; lda dirbuf+256, y
; tay
; bne readfile
; txa
; bne readfile
ldy $ff ; use $ff as block index?
inc $ff ;
ldx dirbuf, Y ; low byte of block#
lda dirbuf+256, Y ; high byte of block#
tay
bne readfile ; if high byte!=0, read another block
txa ; if high byte=0 and low_byte=0, done
bne readfile
readdone:
; jmp ProBootEntry
jmp PROBOOTENTRY ; would be $2000 if sapling
;================================
; seek read
;================================
; Y:X = block number to load (???)
; A = page to load to?
seekread:
; stx bloklo
; sty blokhi
; lda #1
; sta command
; lda adrhi
; pha
;entry jsr $d1d1
; pla
; sta adrhi
; rts
stx BLOKLO
sty BLOKHI
lda #1
sta command
lda ADRHI
pha
entry_smc:
jsr $d1d1
pla
sta ADRHI
rts
;fakeMLI bne retcall
;readblk dey
; dey
; sty adrhi
; tay
; jsr $bf00+seekread-fakeMLI
;retcall pla
; tax
; inx
; inx
; inx
; txa
; pha
;- rts
;fakeMLI_e
fakeMLI:
bne retcall
readblk:
dey
dey
sty ADRHI
tay
jsr $bf00+seekread-fakeMLI
retcall:
pla
tax
inx
inx
inx
txa
pha
;-:
rts
fakeMLI_e:
;filename +PSTRING "LAUNCHER.SYSTEM"
filename:
; expects PASCAL-string filename
; first byte size (max 15)
.byte 7,"SEASONS"
; !src "src/4cade.branding.a"
;!if (* > $9f7) {
; !serious "Bootloader is too large"
;}
;.if (* > $9f7)
; .error "Bootloader is too large"
;.endif
;*=$9f8
;!byte $D3,$C1,$CE,$A0,$C9,$CE,$C3,$AE

269
disk/prorwts/seasons.s Normal file
View File

@ -0,0 +1,269 @@
; Apple II Seasons -=DESiRE=- 128B Demo for Outline 2020
; based on the code in Hellmood's 64B x86 demo "Autumn"
; by deater (Vince Weaver) <vince@deater.net>
; DOS version is 64 bytes
; original Apple II 6502 port was 167 bytes
; I got it down to 126 bytes
; qkumba got it down to 116
; color-cycling brought it back up to 127 bytes
; To save space, runs from the zero page starting at $50
; need to avoid $E0-$E5 used by the hgr/hplot routines
; Zero Page Addresses
XCOORDL = $F3
XCOORDH = $F4
YCOORDL = $F5
YCOORDH = $F6
EBP1 = $F7
EBP2 = $F8
EBP3 = $F9
EBP4 = $FA
COLORL = $FB
COLORH = $FC
SOUND = $FD
FRAMEL = $FE
FRAMEH = $FF
; Soft Switches
KEYPRESS= $C000
KEYRESET= $C010
SPEAKER = $C030
; ROM routines
; Some of these are in the Applesoft ROMs so need at least an Apple II+
; or later to run
TEXT = $FB36 ; Set text mode
HGR2 = $F3D8 ; Set full-screen hi-res mode using page 2 ($4000)
; 280x192 6-colors
HPLOT0 = $F457 ; Plot point, (Y,X) = Horizontal, (A=Vertical)
HCOLOR = $F6EC ; Set color in X, must be 0..7
; use zero-page addressing to save space
;.zeropage
seasons:
;===================
; init screen ; Instruction Length
jsr HGR2 ; 3
; init vars to zero. Apple II doesn't clear RAM
; some of these might be necessary?
; should we make this a loop?
; ldx #0 ; 2
; stx XCOORDL ; 2
; stx YCOORDL ; 2
; stx XCOORDH ; 2
; stx YCOORDH ; 2
; stx EBP1 ; 2
; stx EBP2 ; 2
; stx EBP3 ; 2
; stx EBP4 ; 2
; stx COLORH ; 2
seasons_forever:
; save old Xcoord value to X/Y for later
; push/pop is 1 byte each but have to get
; value into accumulator first
ldx XCOORDL ; 2
ldy XCOORDH ; 2
; 16-bit subtraction x=x-y
; need to set carry before subtraction on 6502
txa ; 1 (xcoordl in X)
sec ; 1
sbc YCOORDL ; 2
sta XCOORDL ; 2
tya ; 1 (xcoordh in Y)
sbc YCOORDH ; 2
; 16-bit arithmatic shift right of X
; 6502 has no asr instruction
; cmp #$80 sets carry if high bit set
cmp #$80 ; 2 ; XCOORDH still in A from before
ror ; 1
sta XCOORDH ; 2
ror XCOORDL ; 2
; 16-bit add, ycoord=ycoord+oldx
clc ; 1
txa ; 1
adc YCOORDL ; 2
sta YCOORDL ; 2
tya ; 1
adc YCOORDH ; 2
; 16-bit arithmatic shift right of y-coord
cmp #$80 ; 2 ; YCOORDH still in A from before
ror ; 1
sta YCOORDH ; 2
ror YCOORDL ; 2
; 32 bit rotate of low bit shifted out of Y-coordinate
ror EBP1 ; 2
ror EBP2 ; 2
ror EBP3 ; 2
ror EBP4 ; 2
; branch if carry set
bcs label_11f ; 2
; 16-bit increment of color
inc COLORL ; 2
bne no_oflo ; 2
inc COLORH ; 2
no_oflo:
; 16-bit add of X-coord by 0x80
; this keeps the drawing roughly to the 280x192 screen
; carry should still be clear (inc doesn't set it)
lda XCOORDL ; 2
adc #$80 ; 2
sta XCOORDL ; 2
bcc no_oflo2 ; 2
inc XCOORDH ; 2
no_oflo2:
; 16-bit negate of Y-coord
sec ; 1
lda #0 ; 2
sbc YCOORDL ; 2
sta YCOORDL ; 2
lda #0 ; 2
sbc YCOORDH ; 2
sta YCOORDH ; 2
label_11f:
; skipping the color manipulation done here by original
; mix colors a bit?
; 16-bit shift of color
; 2nd is a rotate as asl doesn't shift in cary
lda COLORL ; 2
asl ; 1 ; shl %ax
rol COLORH ; 2
eor COLORH ; 2
sta COLORL ; 2
; get color mapping
; using a color lookup table looks best but too many bytes
; you can approximate something close to the lookup with
; two extra instructions
and #$7 ; 2
smc:
ora #$2 ; 2
tax ; 1
; if using color lookup table
; tay ; 1
; ldx color_lookup,Y ; 3 (could be 2 if we run in zero page)
; if ycoord negative, loop
lda YCOORDH ; 2
bmi seasons_forever ; 2
; if top bits of xcoord, loop
lda XCOORDH ; 2
and #$f0 ; 2
bne seasons_forever ; 2
put_pixel:
; actually set the color
jsr HCOLOR ; 3 ; color is in X
; set up paramaters for HPLOT ROM call
ldx XCOORDL ; 2 ; x coord in (y:x)
ldy XCOORDH ; 2
lda YCOORDL ; 2 ; y coord in A
jsr HPLOT0 ; 3
; flip palettes when color at $4200 (roughly 0,32 on screen)
; changes. This is sort of arbitrary, but having a 16-bit counter
; takes too many instructions and Apple II doesn't have a
; programmable timer
lda $4200 ; 3 ; check colors at 0,32
bmi seasons_forever ; 2
; flip between blue/purple and orange/green palettes
; with self-modifying code. 2 bytes are saved when
; we execute in the zero page
lda smc+1 ; 2
eor #$3 ; 2
sta smc+1 ; 2
; the adc/sbc in HPLOT0 leave the V flag clear
; so we can save a byte (over jump) by using bvc
bvc seasons_forever ; 2
; Thankfully not necessary for a 128B demo?
; lda KEYPRESS ; 3 ; see if key pressed
; bpl seasons_forever ; 2 ; loop if not
; bit KEYRESET
exit_to_prompt:
; jsr TEXT ; 3 ; return to text mode
; jmp $3D0 ; 3 ; return to Applesoft prompt
;========================================================
;========================================================
; color lookup tables used when testing
; some of them look better, but make the executable bigger
; than the AND/OR version of setting colors
; Apple II Hi-Res Colors
; It's all NTSC artifacting and complex
; There can be color-clash at a 3.5 pixel level
; Adjacent on pixels make white, adjacent off make black
; Simplistic summary, you can have these 8 colors (6 unique)
; 0 = Black0
; 1 = Green
; 2 = Purple
; 3 = White0
; 4 = Black1
; 5 = Orange
; 6 = Blue
; 7 = White2
color_lookup:
; colorful palette
; .byte $01,$01,$02,$03, $05,$05,$06,$07
; blue and purple palette
; .byte $02,$02,$03,$06, $06,$06,$02,$07
; qkumba ora2 white/blue/purple
; .byte $02,$03,$02,$03, $06,$07,$06,$07
; ora1 white/orange/green
; .byte $01,$01,$03,$03, $05,$05,$07,$07
; better mixed orange/green/white
; .byte $01,$03,$03,$03, $05,$05,$07,$07
; orange and green palette
; .byte $01,$01,$03,$05, $05,$05,$01,$07
; .byte $01,$00,$01,$00, $05,$00,$05,$00
; "Leaf" Locations
; TOP-LEFT ?? CENTER-TOP TOP-RIGHT LEFT ?? CENTER-BOTTOM ??