From 491eb4ca4eac0154fc57d7ee0f2a9b75c46d5dc7 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 15 Jul 2024 16:31:49 -0400 Subject: [PATCH] prorwts: sort of figured out what proboothd is doing --- disk/prorwts/Makefile | 17 +- disk/prorwts/hardware.inc | 99 ++++++++++++ disk/prorwts/proboothd.s | 318 ++++++++++++++++++++++++-------------- disk/prorwts/seasons.s | 269 ++++++++++++++++++++++++++++++++ 4 files changed, 579 insertions(+), 124 deletions(-) create mode 100644 disk/prorwts/hardware.inc create mode 100644 disk/prorwts/seasons.s diff --git a/disk/prorwts/Makefile b/disk/prorwts/Makefile index 246ff1a5..526a5076 100644 --- a/disk/prorwts/Makefile +++ b/disk/prorwts/Makefile @@ -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 diff --git a/disk/prorwts/hardware.inc b/disk/prorwts/hardware.inc new file mode 100644 index 00000000..3c85fd67 --- /dev/null +++ b/disk/prorwts/hardware.inc @@ -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 + diff --git a/disk/prorwts/proboothd.s b/disk/prorwts/proboothd.s index c4139def..beea7fc0 100644 --- a/disk/prorwts/proboothd.s +++ b/disk/prorwts/proboothd.s @@ -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 diff --git a/disk/prorwts/seasons.s b/disk/prorwts/seasons.s new file mode 100644 index 00000000..2e9928fd --- /dev/null +++ b/disk/prorwts/seasons.s @@ -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) + +; 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 ?? + +