Thanks PJ for pointing me to the right places.
This will let you have as many different versions of scrolling sky as you have rooms. Just edit layer 2 for a room in SMILE and this will make the first column of screens load in as scrolling sky. The bands' sizes and speeds can be edited in asm below. All the edits should be right in that first section on tables
lorom
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Custom Layer 2 scrolling sky by Amoeba
;
; Warning: this asm overwrites the built in scrolling sky routines. You will need to manually add a layer 2 and data in it to rooms that use scrolling sky.
; Rooms that use the alternate scrolling sky (ex. East Ocean) will crash as that is removed entirely.
;
; Use 91C9 for the room's setup asm (aka Layer1_2)
; Use C116 for the room's main asm. (aka FX2)
;
; Put the scrolling sky BG on a custom layer 2 for the room in the first olumn of screens. The rest of the screens aren't used.
; Edit/Add a scroll table to match the positions of the clouds / scrolling sections.
; Note: If th room goes past the end of the table, the remaining sections will inherit their X scroll properties from the room it. (Still fixed to one column.)
; Set the first tile's tile number to the scroll table index you want to use (000, 002, 004, etc.) this should be something in the CRE if it's sane.
; Note: The first row of tiles can never be visable.
; Note: you can save space in teh rom if you copy the scrolling sky to every column of layer 2. It will compress nicely.
;
org $8F91C9 ;Normal scrolling sky room setup code
JSL RoomSetupASM
RTS
org $8FC116 ;Normal scrolling sky room main asm
JSL RoomMainASM
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Add new tables here for each scrolling sky pattern needed
;
org $88F600 ;free space
ScrollingSkySectionTable_List:
DW ScrollingSkySectionTable_000, ScrollingSkySectionTable_002
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The first section should start at the top.
; Each next section must appear in order from top to bottom with increasing pixels locations.
; The last row should indicate the end of the last section and then have a null pointer for where to store the scroll value.
; The scroll values take 4 bytes to store. Only the highest word is actually read, so if you feel liek doing something tricky you could read something else if you set the speed to be 0.
; If you want to make the table really long, you'll have to allocate more space in bank $7F for storing scroll values.
; Columns: top pixel row of the section, sub-pixels/frame to move (pixels start at the high word), section scroll storage address
;
!repeated = "$00000000"
ScrollingSkySectionTable_000: ;optimized vanilla
DW $0000 : DD $00008000 : DW $9F80
DW $0010 : DD $0000C000 : DW $9F84
DW $0038 : DD !repeated : DW $9F80
DW $00D0 : DD !repeated : DW $9F84
DW $00E0 : DD !repeated : DW $9F80
DW $0120 : DD !repeated : DW $9F84
DW $01A0 : DD !repeated : DW $9F80
DW $01D8 : DD !repeated : DW $9F84
DW $0238 : DD $00014000 : DW $9F88
DW $0268 : DD !repeated : DW $9F84
DW $02A0 : DD !repeated : DW $9F80
DW $02E0 : DD !repeated : DW $9F88
DW $0300 : DD !repeated : DW $9F80
DW $0320 : DD !repeated : DW $9F84
DW $0350 : DD !repeated : DW $9F80
DW $0378 : DD !repeated : DW $9F84
DW $03C8 : DD !repeated : DW $9F80
DW $0440 : DD $00007000 : DW $9F8C
DW $0460 : DD !repeated : DW $9F84
DW $0480 : DD !repeated : DW $9F80
DW $0490 : DD $00000000 : DW $9F90
DW $0500 : DD $00000000 : DW $0000
ScrollingSkySectionTable_002: ;copy of vanilla
DW $0000 : DD $00008000 : DW $9F80
DW $0010 : DD $0000C000 : DW $9F84
DW $0038 : DD $00008000 : DW $9F88
DW $00D0 : DD $0000C000 : DW $9F8C
DW $00E0 : DD $00008000 : DW $9F90
DW $0120 : DD $0000C000 : DW $9F94
DW $01A0 : DD $00008000 : DW $9F98
DW $01D8 : DD $0000C000 : DW $9F9C
DW $0238 : DD $00008000 : DW $9FA0
DW $0268 : DD $0000C000 : DW $9FA4
DW $02A0 : DD $00008000 : DW $9FA8
DW $02E0 : DD $0000C000 : DW $9FA0
DW $0300 : DD $00008000 : DW $9FB0
DW $0320 : DD $0000C000 : DW $9FB4
DW $0350 : DD $00008000 : DW $9FB8
DW $0378 : DD $0000C000 : DW $9FBC
DW $03C8 : DD $00008000 : DW $9FC0
DW $0440 : DD $00007000 : DW $9FC4
DW $0460 : DD $0000C000 : DW $9FC8
DW $0480 : DD $00008000 : DW $9FCC
DW $0490 : DD $00000000 : DW $9FD0
DW $04A8 : DD $00000000 : DW $9FD4
DW $04B8 : DD $00000000 : DW $9FD8
DW $0500 : DD $00000000 : DW $0000
warnpc $88FFFF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Room Setup ASM
; A JSR->JSL shim at $8F91C9 call this.
; Creates the HDMA object that handles changing the x scroll based on the position of the screen
;
org $88A7D8
RoomSetupASM:
PHP
SEP #$30
LDA $091B
ORA #$01
STA $091B ;disable normal X scrolling graphics routines for layer 2
LDA $091C
ORA #$01
STA $091C ;disable normal Y scrolling graphics routines for layer 2
JSL $888435 ;spawn HDMA object
DB $42, $0F
DW ScrollInstructionList
REP #$30
LDA #$00E0
STA $059A
STZ $059C
SEP #$30
LDA #$4A
STA $59 ;BG2 tilemap base address = $4800, size = 32x64
REP #$30
LDA $0915 ;Screen's Y position in pixels
STA $0919 ;Screen's realtive Y position reference point in pixels
STA $B7 ;Value for $2110 (Y scroll of BG 2)
STZ $0923 ;Screen's relative Y position offset for transitions
JSL LoadFullBG
PLP
RTL
warnpc $88A81C
org $88AD76
ScrollInstructionList:
DW $8655 ;HDMA table bank = $7E
DB $7E
DW $866A ;Indirect HDMA data bank = $7E
DB $7E
DW $8570
DL ScrollPreInstruction ;$88ADB2 ; Pre-instruction
ScrollInstructionList_Loop:
DW $7000, $9F00
DW $85EC, ScrollInstructionList_Loop
ScrollPreInstruction:
REP #$30
LDA $0A78
BEQ ScrollPreInstruction_NotPaused
RTL
ScrollPreInstruction_NotPaused:
LDA $7F9602 ;First 16x16 tile of layer 2
AND #$03FE ;Use to look up which table to use
TAX
LDA ScrollingSkySectionTable_List,x
TAY
LDA $0006,y ;HDMA table entry address
UpdateScrollPositions_Loop:
TAX
LDA $0002,y ;sub-pixel/frame
CLC
ADC $7E0000,x
STA $7E0000,x
LDA $0004,y ;pixel/frame
ADC $7E0002,x
STA $7E0002,x
TYA
CLC
ADC #$0008
TAY
LDA $0006,y ;HDMA table entry address
BNE UpdateScrollPositions_Loop ;look for terminator
LDA #$0000
STA $7E9FD8
STA $7E9FDA
LDA #$001F
STA $7E9F00
LDA #$059E
STA $7E9F01 ;first entry int he HDMA table covers the section under the hud with a fixed scroll value
LDA $0915 ;Screen's Y position in pixels
CLC
ADC #$0020
STA $12 ;current first line (1 pixel below the hud)
CLC
ADC #$00C0
STA $14 ;last line
LDA $7F9602 ;First 16x16 tile of layer 2
AND #$03FE ;Use to look up which table to use
TAX
LDA ScrollingSkySectionTable_List,x
TAY ;Y = scrolling sky table index
LDX #$0003 ;X = indirect HDMA table index starting at the second entry
BuildIndirectHDMATable_Loop:
LDA $12 ;current first line
CMP $0000,y ;top of scrolling section
BMI BuildIndirectHDMATable_NotInView
CMP $0008,y ;top of next scrolling section
BMI ScrollingSection ;if the current first line in [top, top of next), go process this section
BuildIndirectHDMATable_NotInView:
TYA
CLC
ADC #$0008
TAY
LDA $0006,y ;HDMA table entry address
BNE BuildIndirectHDMATable_Loop ;look for terminator
;If we went past the bottom of the table we should treat the rest as a normal scrolling section
;Setup an entry to copy in the normal scroll value once and then leave the rest of the room below alone.
LDA #$0001
STA $7E9F00,x
LDA #$00B5
STA $7E9F01,x
LDA #$0000
STA $7E9F03,x ;terminate table
RTL
ScrollingSection:
LDA $0008,y ;top of next scrolling section
SEC
SBC $12 ;current first line
ScrollingSection_Loop:
STA $18 ;section height
CMP #$0080
BMI ScrollingSection_Last
LDA #$007F
STA $7E9F00,x
LDA $0006,y ;HDMA table entry address
INC A
INC A
STA $7E9F01,x
INX
INX
INX
LDA $18
SEC
SBC #$007F
BRA ScrollingSection_Loop
ScrollingSection_Last:
STA $7E9F00,x
LDA $0006,y ;HDMA table entry address
INC A
INC A
STA $7E9F01,x
LDA $18 ;section height
CLC
ADC $12 ;current first line
STA $12
INX
INX
INX
LDA $12 ;current first line
CMP $14 ;last line
BPL ScrollingSection_Exit
JMP BuildIndirectHDMATable_Loop
ScrollingSection_Exit:
LDA #$0000
STA $7E9F03,x ;terminate table
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Room Main ASM
; A JSR->JSL shim at $8FC116 call this.
; Copies the graphics for two 8x8 rows above and two 8x8 rows below the screen.
; Data is loaded from the first column of screens in the layer 2 level data.
;
RoomMainASM:
LDA $0A78 ;Pause timer, due to energy tank and x-ray scope.
BEQ RoomMainASM_NotPaused
LDA #$0000
STA $7E9F00
RTL
RoomMainASM_NotPaused:
REP #$30
LDA $0915 ;Screen's Y position in pixels
BIT #$0008
BNE HalfScroll
JSL CopyTilesFullScroll
BRA SetupGraphicsDMA
HalfScroll:
JSL CopyTilesHalfScroll
SetupGraphicsDMA:
LDA $0915 ;Screen's Y position in pixels
STA $B7 ;Value for $2110 (Y scroll of BG 2)
LDX $0330 ;'Stack' pointer for 00D0 table
LDA #$0040
;Table of entries to update graphics, 7 bytes: Size (2 bytes), source address (3 bytes), VRAM target (2 bytes)
STA $D0,x ;Graphics copy size 0
STA $D7,x ;Graphics copy size 1
STA $DE,x ;Graphics copy size 2
STA $E5,x ;Graphics copy size 3
LDA #$FB02
STA $D2,x ;Graphics copy source address 0
LDA #$FB42
STA $D9,x ;Graphics copy source address 1
LDA #$FB82
STA $E0,x ;Graphics copy source address 2
LDA #$FBC2
STA $E7,x ;Graphics copy source address 3
SEP #$20
LDA #$7F
STA $D4,x ;Graphics copy source bank 0
STA $DB,x ;Graphics copy source bank 1
STA $E2,x ;Graphics copy source bank 2
STA $E9,x ;Graphics copy source bank 3
REP #$20
LDA $59 ;Value for $2108 with 'A' BG 2 Address and Size
AND #$00FC ;Screen Base Address
XBA
STA $00
LDA $0915 ;Screen's Y position in pixels
SEC
SBC #$0010
AND #$01F8
ASL A
ASL A
CLC
ADC $00
STA $D5,x ;Graphics copy target address 0
CLC
ADC #$0020
STA $DC,x ;Graphics copy target address 1
LDA $0915
CLC
ADC #$00F0
AND #$01F8
ASL A
ASL A
CLC
ADC $00
STA $E3,x ;Graphics copy target address 2
CLC
ADC #$0020
STA $EA,x ;Graphics copy target address 3
TXA
CLC
ADC #$001C
STA $0330 ;'Stack' pointer for 00D0 table
RTL
print pc
warnpc $88B057
org $8AB180 ;Overwriting the tilemap that used to be used by scrolling sky
Copy8x8TileRowTop:
LDA $7F9602,x
PHX
PHA
AND #$03FF
ASL A
ASL A
ASL A
TAX
PLA
BIT #$0400
BNE Copy8x8TileRowTop_HorizontalFlip
BIT #$0800
BNE Copy8x8TileRowTop_VerticalFlip
Copy8x8TileRowTop_NoFlip:
LDA $7EA000,x
PHX
TYX
STA $7FFB02,x
PLX
LDA $7EA002,x
TYX
STA $7FFB04,x
Copy8x8TileRowTop_Next:
PLX
INX
INX
INY
INY
INY
INY
CPY $00
BMI Copy8x8TileRowTop
RTS
Copy8x8TileRowTop_HorizontalFlip:
BIT #$0800
BNE Copy8x8TileRowTop_BothFlip
LDA $7EA002,x
PHX
TYX
EOR #$4000
STA $7FFB02,x
PLX
LDA $7EA000,x
TYX
EOR #$4000
STA $7FFB04,x
BRA Copy8x8TileRowTop_Next
Copy8x8TileRowTop_VerticalFlip:
LDA $7EA004,x
PHX
TYX
EOR #$8000
STA $7FFB02,x
PLX
LDA $7EA006,x
TYX
EOR #$8000
STA $7FFB04,x
BRA Copy8x8TileRowTop_Next
Copy8x8TileRowTop_BothFlip:
LDA $7EA006,x
PHX
TYX
EOR #$C000
STA $7FFB02,x
PLX
LDA $7EA004,x
TYX
EOR #$C000
STA $7FFB04,x
BRA Copy8x8TileRowTop_Next
Copy8x8TileRowBottom:
LDA $7F9602,x
PHX
PHA
AND #$03FF
ASL A
ASL A
ASL A
TAX
PLA
BIT #$0400
BNE Copy8x8TileRowBottom_HorizontalFlip
BIT #$0800
BNE Copy8x8TileRowBottom_VerticalFlip
Copy8x8TileRowBottom_NoFlip:
LDA $7EA004,x
PHX
TYX
STA $7FFB02,x
PLX
LDA $7EA006,x
TYX
STA $7FFB04,x
Copy8x8TileRowBottom_Next:
PLX
INX
INX
INY
INY
INY
INY
CPY $00
BMI Copy8x8TileRowBottom
RTS
Copy8x8TileRowBottom_HorizontalFlip:
BIT #$0800
BNE Copy8x8TileRowBottom_BothFlip
LDA $7EA006,x
PHX
TYX
EOR #$4000
STA $7FFB02,x
PLX
LDA $7EA004,x
TYX
EOR #$4000
STA $7FFB04,x
BRA Copy8x8TileRowBottom_Next
Copy8x8TileRowBottom_VerticalFlip:
LDA $7EA000,x
PHX
TYX
EOR #$8000
STA $7FFB02,x
PLX
LDA $7EA002,x
TYX
EOR #$8000
STA $7FFB04,x
BRA Copy8x8TileRowBottom_Next
Copy8x8TileRowBottom_BothFlip:
LDA $7EA002,x
PHX
TYX
EOR #$C000
STA $7FFB02,x
PLX
LDA $7EA000,x
TYX
EOR #$C000
STA $7FFB04,x
BRA Copy8x8TileRowBottom_Next
CopyTilesFullScroll:
LDA $0915 ;Screen's Y position in pixels
LSR
LSR
LSR
LSR
DEC A
LDY $07A5 ;Current room's width in tiles
JSL $8082D6 ;multiply A*Y -> 32-bits starting at $05F1
LDA $05F1 ;low product
ASL A
TAX
STA $14 ;position of first tile to copy 8x8 tiles from
LDY #$0000
LDA #$0040
STA $00
JSR Copy8x8TileRowTop
LDX $14
LDY #$0040
LDA #$0080
STA $00
JSR Copy8x8TileRowBottom
LDA $0915 ;Screen's Y position in pixels
LSR
LSR
LSR
LSR
CLC
ADC #$000F ;one tile below screen
LDY $07A5 ;Current room's width in tiles
JSL $8082D6 ;multiply A*Y -> 32-bits starting at $05F1
LDA $05F1 ;low product
ASL A
TAX
STA $14 ;position of first tile to copy 8x8 tiles from
LDY #$0080
LDA #$00C0
STA $00
JSR Copy8x8TileRowTop
LDX $14
LDY #$00C0
LDA #$0100
STA $00
JSR Copy8x8TileRowBottom
RTL
CopyTilesHalfScroll:
LDA $07A5 ;Current room's width in tiles
ASL
STA $12
LDA $0915
LSR
LSR
LSR
LSR
DEC A
LDY $07A5 ;Current room's width in tiles
JSL $8082D6 ;multiply A*Y -> 32-bits starting at $05F1
LDA $05F1 ;low product
ASL A
TAX
STA $14 ;position of first tile to copy 8x8 tiles from
LDY #$0000
LDA #$0040
STA $00
JSR Copy8x8TileRowBottom
LDA $14
CLC
ADC $12
TAX
LDY #$0040
LDA #$0080
STA $00
JSR Copy8x8TileRowTop
LDA $0915 ;Screen's Y position in pixels
LSR
LSR
LSR
LSR
CLC
ADC #$000F ;one tile below screen
LDY $07A5 ;Current room's width in tiles
JSL $8082D6 ;multiply A*Y -> 32-bits starting at $05F1
LDA $05F1 ;low product
ASL A
TAX
STA $14 ;position of first tile to copy 8x8 tiles from
LDY #$0080
LDA #$00C0
STA $00
JSR Copy8x8TileRowBottom
LDA $14
CLC
ADC $12
TAX
LDY #$00C0
LDA #$0100
STA $00
JSR Copy8x8TileRowTop
RTL
LoadFullBG:
LDA #$0000
LoadFullBG_Loop:
CMP #$00F0
BMI LoadFullBG_Continue
JSL $808338 ;Wait for NMI
RTL
LoadFullBG_Continue:
STA $02
LDA $0915 ;Screen's Y position in pixels
CLC
ADC $02
LSR
LSR
LSR
LSR
LDY $07A5 ;Current room's width in tiles
JSL $8082D6 ;multiply A*Y -> 32-bits starting at $05F1
LDA $05F1 ;low product
ASL A
TAX
STA $14 ;position of first tile to copy 8x8 tiles from
LDY #$0000
LDA #$0040
STA $00
JSR Copy8x8TileRowTop
LDX $14
LDY #$0040
LDA #$0080
STA $00
JSR Copy8x8TileRowBottom
LDA $14
LSR
CLC
ADC $07A5 ;Current room's width in tiles
ASL
TAX
STA $14
LDY #$0080
LDA #$00C0
STA $00
JSR Copy8x8TileRowTop
LDX $14
LDY #$00C0
LDA #$0100
STA $00
JSR Copy8x8TileRowBottom
LDX $0330 ;'Stack' pointer for 00D0 table
LDA #$0040
;Table of entries to update graphics, 7 bytes: Size (2 bytes), source address (3 bytes), VRAM target (2 bytes)
STA $D0,x ;Graphics copy size 0
STA $D7,x ;Graphics copy size 1
STA $DE,x ;Graphics copy size 2
STA $E5,x ;Graphics copy size 3
LDA #$FB02
STA $D2,x ;Graphics copy source address 0
LDA #$FB42
STA $D9,x ;Graphics copy source address 1
LDA #$FB82
STA $E0,x ;Graphics copy source address 2
LDA #$FBC2
STA $E7,x ;Graphics copy source address 3
SEP #$20
LDA #$7F
STA $D4,x ;Graphics copy source bank 0
STA $DB,x ;Graphics copy source bank 1
STA $E2,x ;Graphics copy source bank 2
STA $E9,x ;Graphics copy source bank 3
REP #$20
LDA $59 ;Value for $2108 with 'A' BG 2 Address and Size
AND #$00FC ;Screen Base Address
XBA
STA $00
LDA $0915 ;Screen's Y position in pixels
CLC
ADC $02
AND #$01F8
ASL A
ASL A
CLC
ADC $00
STA $D5,x ;Graphics copy target address 0
LDA $0915 ;Screen's Y position in pixels
CLC
ADC $02
CLC
ADC #$0008
AND #$01F8
ASL A
ASL A
CLC
ADC $00
STA $DC,x ;Graphics copy target address 1
LDA $0915 ;Screen's Y position in pixels
CLC
ADC $02
CLC
ADC #$0010
AND #$01F8
ASL A
ASL A
CLC
ADC $00
STA $E3,x ;Graphics copy target address 2
LDA $0915 ;Screen's Y position in pixels
CLC
ADC $02
CLC
ADC #$0018
AND #$01F8
ASL A
ASL A
CLC
ADC $00
STA $EA,x ;Graphics copy target address 3
TXA
CLC
ADC #$001C
STA $0330 ;'Stack' pointer for 00D0 table
JSL $808338 ;Wait for NMI
LDA #$0020
CLC
ADC $02
JMP LoadFullBG_Loop
warnpc $8AE980