; Initialization and setup routines for the second background _InitBG1 jsr _ApplyBG1YPos jsr _ApplyBG1XPos rts ; Copy a binary image data file into BG1. Assumes the file is the correct size (328 x 208) ; ; A=low word of picture address ; X=high word of pixture address ; Y=high word of BG1 bank _CopyBinToBG1 :src_width equ tmp6 :src_height equ tmp7 :src_flags equ tmp9 clc adc #8 ; Advance over the header pha lda #164 sta :src_width lda #208 sta :src_height lda #COPY_PIC_NORMAL sta :src_flags pla jmp _CopyToBG1 ; Reset the BG1 Y-table depending on the rendering mode ; ; A = mode ; 0 = default (base = $1800, stride = 256) ; 1 = scanline (base = $0, stride = 327) _ResetBG1YTable :base equ tmp0 :stride equ tmp1 cmp #1 ; scanline mode? bne :default lda #0 sta :base lda #327 sta :stride bra :begin :default lda #$1800 sta :base lda #256 sta :stride :begin ldx #0 lda :base :loop sta BG1YTable,x sta BG1YTable+{208*2},x clc adc :stride inx inx cpx #{208*2} bcc :loop rts ; Copy a IIgs $C1 picture into BG1. Assumes the file is the correct size (320 x 200) ; ; A=low word of picture address ; X=high word of pixture address ; Y=high word of BG1 bank _CopyPicToBG1 :src_width equ tmp6 :src_height equ tmp7 :src_stride equ tmp8 :src_flags equ tmp9 pha lda #160 sta :src_width sta :src_stride lda #200 sta :src_height lda #COPY_PIC_NORMAL sta :src_flags pla jmp _CopyToBG1 ; Generic routine to copy image data into BG1 _CopyToBG1 :srcptr equ tmp0 :line_cnt equ tmp2 :dstptr equ tmp3 :col_cnt equ tmp5 :src_width equ tmp6 :src_height equ tmp7 :src_stride equ tmp8 :src_flags equ tmp9 :dstptr2 equ tmp10 ; scanline mode is tricky -- there's not enough space to make two full copies of a 328x200 bitmap buffer, but we can ; *barely* fit a (164 + 163) x 200 buffer. And, since the zero offset could use either end, this covers all of the cases. sta :srcptr stx :srcptr+2 sty :dstptr+2 ; Everything goes into this bank sty :dstptr2+2 ; "Normal" BG1 mode as a stride of 164 bytes and mirrors the BG0 size (328 x 208) ; In "Scanline" mode, the BG1 is treated as a 328x200 bitfield with each horizontal line doubled lda :src_flags cmp #COPY_PIC_NORMAL bne *+5 jmp :_CopyToBG1Normal cmp #COPY_PIC_SCANLINE bne *+5 jmp :_CopyToBG1SCanline rts ; Flag do not match a known copy mode :_CopyToBG1SCanline lda #0 ; Start a byte 1 because odd offsets might go back 1 byte and don't want to wrap around sta :dstptr clc adc #164 ; The first part is 1-byte short, the second part is a full 164 bytes sta :dstptr2 lda :src_width min #164 sta :src_width lda :src_height min #200 sta :src_height stz :line_cnt :rloop ldy #0 ; move forward in the image data and image data ; Handle first word as a special case lda [:srcptr],y sta [:dstptr2],y ; copy directly into the 164-byte buffer iny xba sep #$20 sta [:dstptr],y ; only copy the high byte because the previous line occupies the low byte rep #$20 iny :cloop lda [:srcptr],y sta [:dstptr],y sta [:dstptr2],y iny iny cpy :src_width bcc :cloop lda :dstptr clc adc #327 sta :dstptr adc #164 sta :dstptr2 lda :srcptr clc adc :src_stride sta :srcptr inc :line_cnt lda :line_cnt cmp :src_height bcc :rloop rts :_CopyToBG1Normal stz :line_cnt :rloop2 lda :line_cnt ; get the pointer to the code field line asl tax lda BG1YTable,x sta :dstptr clc adc #164 sta :dstptr2 ldy #0 ; move forward in the image data and image data :cloop2 lda [:srcptr],y sta [:dstptr],y iny iny cpy :src_width bcc :cloop2 ldy #0 lda [:dstptr],y ; Duplicate the last couple of words in the extra space at the end of the line sta [:dstptr2],y ldy #2 lda [:dstptr],y sta [:dstptr2],y lda :srcptr clc adc :src_stride sta :srcptr inc :line_cnt lda :line_cnt cmp :src_height bcc :rloop2 rts _SetBG1XPos cmp BG1StartX beq :out ; Easy, if nothing changed, then nothing changes ldx BG1StartX ; Load the old value (but don't save it yet) sta BG1StartX ; Save the new position lda #DIRTY_BIT_BG1_X tsb DirtyBits ; Check if the value is already dirty, if so exit bne :out ; without overwriting the original value stx OldBG1StartX ; First change, so preserve the value :out rts _SetBG1YPos cmp BG1StartY beq :out ; Easy, if nothing changed, then nothing changes ldx BG1StartY ; Load the old value (but don't save it yet) sta BG1StartY ; Save the new position lda #DIRTY_BIT_BG1_Y tsb DirtyBits ; Check if the value is already dirty, if so exit bne :out ; without overwriting the original value stx OldBG1StartY ; First change, so preserve the value :out rts ; Everytime either BG1 or BG0 X-position changes, we have to update the direct page values. We ; *could* do this by adjusting the since the address offset, but we have to change up to 200 values ; when the vertical position changes, and only 41 when the horizontal value changes. Plus ; these are all direct page values ; ; Note: This routine can be optimized as an unrolled loop of PEI instructions _ApplyBG1XPosPre lda BG1StartX ; This is the starting byte offset (0 - 163) jsr Mod164 sta BG1StartXMod164 rts ; Save as _ApplyBG1XPos, but we pretend that StartXMod164 is always zero and deal with the per-line offset adjustment in ; _ApplyScanlineBG1YPos. The tweak here is that the buffer is only 160 bytes wide in scanine mode, instead of 164 bytes wide _ApplyScanlineBG1XPos lda BG1StartXMod164 ; How far into the BG1 buffer is the left edge? tay phd ; save the direct page because we are going to switch to the lda BlitterDP ; blitter direct page space and fill in the addresses tcd ldx #0 ; tya lda #0 :loop sta 00,x ; store the value inc inc cmp #164 bcc *+5 sbc #164 inx inx cpx #164 bcc :loop pld rts _ApplyBG1XPos lda #162 sec sbc StartXMod164 ; Need to compensate for both BG0 and BG1 positions bpl *+6 clc adc #164 clc adc BG1StartXMod164 cmp #164 bcc *+5 sbc #164 tay phd ; save the direct page because we are going to switch to the lda BlitterDP ; blitter direct page space and fill in the addresses tcd ldx #162 tya :loop sta 00,x ; store the value dec dec bpl :nowrap clc adc #164 :nowrap dex dex bpl :loop pld rts _ClearBG1Buffer phb pha sep #$20 lda BG1DataBank pha plb rep #$20 pla ldx #0 :loop sta: $0000,x inx inx cpx #0 bne :loop plb rts ; Variation to take care of horizontal adjustments within the BG1 buffer to compensate for the ; per-scanline BG0 displacement. It is up to the caller to manage the memeory layout to make ; this visually work. ; ; In the scanline mode we have to be able to adjust the base address of each BG1 line up to ; a full screen, so scanline mode treats bank as a 640x200 pixel bitmap (64000 byte). ; ; This is just a limitation of scanline displacement mode that there is no extra vertical space. _ApplyScanlineBG1YPos :stk_save equ tmp0 :virt_line_x2 equ tmp1 :lines_left_x2 equ tmp2 :draw_count_x2 equ tmp3 :ytbl_idx_x2 equ tmp4 :shift_value equ tmp5 ; Avoid local var collision :ptr2 equ tmp8 :ytbl_idx_pos_x2 equ tmp10 :virt_line_pos_x2 equ tmp11 :total_left_x2 equ tmp12 :current_count_x2 equ tmp13 :ptr equ tmp14 lda StartXMod164Tbl sta :ptr lda StartXMod164Tbl+2 sta :ptr+2 lda BG1StartXMod164Tbl sta :ptr2 lda BG1StartXMod164Tbl+2 sta :ptr2+2 ora :ptr2 lda BG1StartY jsr Mod208 sta BG1StartYMod208 asl sta :ytbl_idx_pos_x2 ; Start copying from the first entry in the table lda StartYMod208 ; This is the base line of the virtual screen asl sta :virt_line_pos_x2 tay lda ScreenHeight asl sta :total_left_x2 :loop0 lda [:ptr],y tax and #$FF00 ; Determine how many sequential lines have this mod value xba inc asl min :total_left_x2 ; Don't draw more than the number of lines that are left to process sta :current_count_x2 ; Save a copy for later sta :lines_left_x2 ; Set the parameter lda :ytbl_idx_pos_x2 ; Set the parameter sta :ytbl_idx_x2 sty :virt_line_x2 ; Set the parameter txa ; Put the X mod 164 value in the offset value and #$00FF sta :shift_value jsr :_ApplyConstBG1YPos ; Shift this range by a constant amount clc lda :virt_line_pos_x2 adc :current_count_x2 cmp #208*2 ; Do the modulo check in this loop bcc *+5 sbc #208*2 sta :virt_line_pos_x2 tay clc lda :ytbl_idx_pos_x2 adc :current_count_x2 sta :ytbl_idx_pos_x2 lda :total_left_x2 sec sbc :current_count_x2 sta :total_left_x2 bne :loop0 rts :_ApplyConstBG1YPos lda #164 sec sbc :shift_value clc adc BG1StartXMod164 cmp #164+1 bcc *+5 sbc #164 sta :shift_value ; Base shift value cmp #165 bcc *+4 brk $04 phb ; Save the existing bank tsc sta :stk_save :loop ldx :virt_line_x2 ldal BTableHigh,x ; Get the bank pha plb ldal BTableLow,x ; Get the address of the first code field line tay txa ; Calculate number of lines to draw on this iteration and #$001E eor #$FFFF sec adc #32 min :lines_left_x2 sta :draw_count_x2 tax lda :ytbl_idx_x2 ; Read from this location in the BG1YTable ; clc ; CopyBG1YTableToBG1Addr3 :shift_value CopyBG1YTableToBG1Addr4 :shift_value;blttmp lda :virt_line_x2 ; advance to the virtual line after adc :draw_count_x2 ; filled in sta :virt_line_x2 lda :ytbl_idx_x2 adc :draw_count_x2 sta :ytbl_idx_x2 lda :lines_left_x2 ; subtract the number of lines we just completed sec sbc :draw_count_x2 sta :lines_left_x2 jne :loop lda :stk_save tcs plb rts ; Everytime either BG1 or BG0 Y-position changes, we have to update the Y-register ; value in all of the code fields (within the visible screen) _ApplyBG1YPos :virt_line equ tmp0 :lines_left equ tmp1 :draw_count equ tmp2 :ytbl_idx equ tmp3 phb ; Save the bank lda BG1StartY jsr Mod208 sta BG1StartYMod208 sta :ytbl_idx ; Start copying from the first entry in the table lda StartYMod208 ; This is the base line of the virtual screen sta :virt_line ; Keep track of it lda ScreenHeight sta :lines_left :loop lda :virt_line asl tax ldal BTableLow,x ; Get the address of the first code field line tay sep #$20 ldal BTableHigh,x pha ; push the bank on the stack plb rep #$20 lda :virt_line and #$000F eor #$FFFF inc clc adc #16 min :lines_left sta :draw_count ; Do this many lines asl tax lda RenderFlags bit #RENDER_BG1_HORZ_OFFSET ; Are we using horizontal displacement? beq :no_displacement lda :ytbl_idx ; Read from this location in the BG1YTable asl jsr CopyBG1YTableToBG1Addr2 bra :next_step :no_displacement lda :ytbl_idx ; Read from this location in the BG1YTable asl jsr CopyBG1YTableToBG1Addr ; or CopyBG1YTableToBG1Addr2 :next_step lda :virt_line ; advance to the virtual line after the segment we just clc ; filled in adc :draw_count sta :virt_line lda :ytbl_idx ; advance the index into the YTable adc :draw_count sta :ytbl_idx lda :lines_left ; subtract the number of lines we just completed sec sbc :draw_count sta :lines_left jne :loop plb rts ; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position. ; ; A = index into the BG1YTable array (x2) ; Y = starting line * $1000 ; X = number of lines (x2) CopyBG1YTableToBG1Addr jmp (:tbl,x) :tbl da :none da :do01,:do02,:do03,:do04 da :do05,:do06,:do07,:do08 da :do09,:do10,:do11,:do12 da :do13,:do14,:do15,:do16 :do15 tax bra :x15 :do14 tax bra :x14 :do13 tax bra :x13 :do12 tax bra :x12 :do11 tax bra :x11 :do10 tax bra :x10 :do09 tax bra :x09 :do08 tax bra :x08 :do07 tax bra :x07 :do06 tax bra :x06 :do05 tax bra :x05 :do04 tax bra :x04 :do03 tax bra :x03 :do02 tax bra :x02 :do01 tax bra :x01 :do16 tax ldal BG1YTable+30,x sta BG1_ADDR+$F000,y :x15 ldal BG1YTable+28,x sta BG1_ADDR+$E000,y :x14 ldal BG1YTable+26,x sta BG1_ADDR+$D000,y :x13 ldal BG1YTable+24,x sta BG1_ADDR+$C000,y :x12 ldal BG1YTable+22,x sta BG1_ADDR+$B000,y :x11 ldal BG1YTable+20,x sta BG1_ADDR+$A000,y :x10 ldal BG1YTable+18,x sta BG1_ADDR+$9000,y :x09 ldal BG1YTable+16,x sta BG1_ADDR+$8000,y :x08 ldal BG1YTable+14,x sta BG1_ADDR+$7000,y :x07 ldal BG1YTable+12,x sta BG1_ADDR+$6000,y :x06 ldal BG1YTable+10,x sta BG1_ADDR+$5000,y :x05 ldal BG1YTable+08,x sta: BG1_ADDR+$4000,y :x04 ldal BG1YTable+06,x sta BG1_ADDR+$3000,y :x03 ldal BG1YTable+04,x sta BG1_ADDR+$2000,y :x02 ldal BG1YTable+02,x sta BG1_ADDR+$1000,y :x01 ldal BG1YTable+00,x sta: BG1_ADDR+$0000,y :none rts ; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position ; with a constant shift applied ; ; A = index into the BG1YTable array (x2) ; Y = starting line * $1000 ; X = number of lines (x2) ; ]1 = offset CopyBG1YTableToBG1Addr3 mac jmp (tbl,x) tbl da none da do01,do02,do03,do04 da do05,do06,do07,do08 da do09,do10,do11,do12 da do13,do14,do15,do16 do15 tax jmp x15 do14 tax jmp x14 do13 tax jmp x13 do12 tax jmp x12 do11 tax jmp x11 do10 tax jmp x10 do09 tax jmp x09 do08 tax jmp x08 do07 tax jmp x07 do06 tax jmp x06 do05 tax jmp x05 do04 tax jmp x04 do03 tax jmp x03 do02 tax jmp x02 do01 tax jmp x01 do16 tax ldal BG1YTable+30,x adc ]1 sta BG1_ADDR+$F000,y x15 ldal BG1YTable+28,x adc ]1 sta BG1_ADDR+$E000,y x14 ldal BG1YTable+26,x adc ]1 sta BG1_ADDR+$D000,y x13 ldal BG1YTable+24,x adc ]1 sta BG1_ADDR+$C000,y x12 ldal BG1YTable+22,x adc ]1 sta BG1_ADDR+$B000,y x11 ldal BG1YTable+20,x adc ]1 sta BG1_ADDR+$A000,y x10 ldal BG1YTable+18,x adc ]1 sta BG1_ADDR+$9000,y x09 ldal BG1YTable+16,x adc ]1 sta BG1_ADDR+$8000,y x08 ldal BG1YTable+14,x adc ]1 sta BG1_ADDR+$7000,y x07 ldal BG1YTable+12,x adc ]1 sta BG1_ADDR+$6000,y x06 ldal BG1YTable+10,x adc ]1 sta BG1_ADDR+$5000,y x05 ldal BG1YTable+08,x adc ]1 sta: BG1_ADDR+$4000,y x04 ldal BG1YTable+06,x adc ]1 sta BG1_ADDR+$3000,y x03 ldal BG1YTable+04,x adc ]1 sta BG1_ADDR+$2000,y x02 ldal BG1YTable+02,x adc ]1 sta BG1_ADDR+$1000,y x01 ldal BG1YTable+00,x adc ]1 sta: BG1_ADDR+$0000,y none <<< ; Copy routine to move BG1YTable entries into BG1_ADDR position with an additional ; shift on every line form the user-provided BG1StartXMod164Tbl. ; ; A = index into the BG1YTable array (x2) ; Y = starting line * $1000 ; X = number of lines (x2) ; ; ]1 = constant shift value ; ]2 = temp storage space CopyBG1YTableToBG1Addr4 mac phy ; save the registers phx phb pha jsr _SetDataBank ; Set to toolbox data bank clc lda 1,s ; virtual_index_x2 adc BG1StartXMod164Tbl ; Get the starting address in the array for this chunk tay lda BG1StartXMod164Tbl+1 ; Set the bank to the array location pha plb plb pla ; POp back the original value ApplyBG1ModXToShift ]1;]2 ; Copy the array into direct page storage and apply the shift plb ; Restore the code field bank plx ; x is used directly in this routine ply ApplyBG1ShiftToCode ]2 <<< ; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position with an additional ; shift on every line. This has to be split into two ; ; A = index into the BG1YTable array (x2) ; Y = starting line * $1000 ; X = number of lines (x2) CopyBG1YTableToBG1Addr2 phy ; save the registers phx phb pha jsr _SetDataBank ; Set to toolbox data bank pla ldy BG1OffsetIndex ; Get the offset and save the values jsr SaveBG1OffsetValues plb plx ; x is used directly in this routine ply jmp ApplyBG1OffsetValues SaveBG1OffsetValues jmp (:tbl,x) :tbl da :none da :do01,:do02,:do03,:do04 da :do05,:do06,:do07,:do08 da :do09,:do10,:do11,:do12 da :do13,:do14,:do15,:do16 :do15 tax bra :x15 :do14 tax bra :x14 :do13 tax bra :x13 :do12 tax bra :x12 :do11 tax bra :x11 :do10 tax bra :x10 :do09 tax bra :x09 :do08 tax bra :x08 :do16 tax lda BG1YTable+30,x adc BG1YOffsetTable+30,y sta BG1YCache+30 :x15 lda BG1YTable+28,x adc BG1YOffsetTable+28,y sta BG1YCache+28 :x14 lda BG1YTable+26,x adc BG1YOffsetTable+26,y sta BG1YCache+26 :x13 lda BG1YTable+24,x adc BG1YOffsetTable+24,y sta BG1YCache+24 :x12 lda BG1YTable+22,x adc BG1YOffsetTable+22,y sta BG1YCache+22 :x11 lda BG1YTable+20,x adc BG1YOffsetTable+20,y sta BG1YCache+20 :x10 lda BG1YTable+18,x adc BG1YOffsetTable+18,y sta BG1YCache+18 :x09 lda BG1YTable+16,x adc BG1YOffsetTable+16,y sta BG1YCache+16 :x08 lda BG1YTable+14,x adc BG1YOffsetTable+14,y sta BG1YCache+14 :x07 lda BG1YTable+12,x adc BG1YOffsetTable+12,y sta BG1YCache+12 :x06 lda BG1YTable+10,x adc BG1YOffsetTable+10,y sta BG1YCache+10 :x05 lda BG1YTable+08,x adc BG1YOffsetTable+08,y sta BG1YCache+08 :x04 lda BG1YTable+06,x adc BG1YOffsetTable+06,y sta BG1YCache+06 :x03 lda BG1YTable+04,x adc BG1YOffsetTable+04,y sta BG1YCache+04 :x02 lda BG1YTable+02,x adc BG1YOffsetTable+02,y sta BG1YCache+02 :x01 lda BG1YTable+00,x adc BG1YOffsetTable+00,y sta BG1YCache+00 :none rts :do07 tax bra :x07 :do06 tax bra :x06 :do05 tax bra :x05 :do04 tax bra :x04 :do03 tax bra :x03 :do02 tax bra :x02 :do01 tax bra :x01 ApplyBG1OffsetValues jmp (:tbl,x) :tbl da :none da :do01,:do02,:do03,:do04 da :do05,:do06,:do07,:do08 da :do09,:do10,:do11,:do12 da :do13,:do14,:do15,:do16 :do16 ldal BG1YCache+30 sta BG1_ADDR+$F000,y :do15 ldal BG1YCache+28 sta BG1_ADDR+$E000,y :do14 ldal BG1YCache+26 sta BG1_ADDR+$D000,y :do13 ldal BG1YCache+24 sta BG1_ADDR+$C000,y :do12 ldal BG1YCache+22 sta BG1_ADDR+$B000,y :do11 ldal BG1YCache+20 sta BG1_ADDR+$A000,y :do10 ldal BG1YCache+18 sta BG1_ADDR+$9000,y :do09 ldal BG1YCache+16 sta BG1_ADDR+$8000,y :do08 ldal BG1YCache+14 sta BG1_ADDR+$7000,y :do07 ldal BG1YCache+12 sta BG1_ADDR+$6000,y :do06 ldal BG1YCache+10 sta BG1_ADDR+$5000,y :do05 ldal BG1YCache+08 sta: BG1_ADDR+$4000,y :do04 ldal BG1YCache+06 sta BG1_ADDR+$3000,y :do03 ldal BG1YCache+04 sta BG1_ADDR+$2000,y :do02 ldal BG1YCache+02 sta BG1_ADDR+$1000,y :do01 ldal BG1YCache+00 sta: BG1_ADDR+$0000,y :none rts ; Apply the per-scanline shift from the BG1StartXMod164Tbl pointer. Save the relevant values to the ; direct page since the array could be in any bank. ; ; This does bounds checking to make sure the shift value remains in the valid range ; ; ]1 = source array offset ; ]2 = constant shift value ; ]3 = destination address _BG1ShiftTemplate mac lda ]1,y ; Load the value from the array adc ]2 ; Add to the direct page shift_value cmp #165 ; If below this value, we're good bcc *+6 sbc #164 clc adcl BG1YTable+]1,x sta ]3+]1 <<< AToX mac tax brl ]1 <<< ApplyBG1ModXToShift mac jmp (agmxts_tbl,x) agmxts_tbl da none da do01,do02,do03,do04 da do05,do06,do07,do08 da do09,do10,do11,do12 da do13,do14,do15,do16 do16 AToX o16 do15 AToX o15 do14 AToX o14 do13 AToX o13 do12 AToX o12 do11 AToX o11 do10 AToX o10 do09 AToX o09 do08 AToX o08 do07 AToX o07 do06 AToX o06 do05 AToX o05 do04 AToX o04 do03 AToX o03 do02 AToX o02 do01 AToX o01 o16 _BG1ShiftTemplate 30;]1;]2 o15 _BG1ShiftTemplate 28;]1;]2 o14 _BG1ShiftTemplate 26;]1;]2 o13 _BG1ShiftTemplate 24;]1;]2 o12 _BG1ShiftTemplate 22;]1;]2 o11 _BG1ShiftTemplate 20;]1;]2 o10 _BG1ShiftTemplate 18;]1;]2 o09 _BG1ShiftTemplate 16;]1;]2 o08 _BG1ShiftTemplate 14;]1;]2 o07 _BG1ShiftTemplate 12;]1;]2 o06 _BG1ShiftTemplate 10;]1;]2 o05 _BG1ShiftTemplate 8;]1;]2 o04 _BG1ShiftTemplate 6;]1;]2 o03 _BG1ShiftTemplate 4;]1;]2 o02 _BG1ShiftTemplate 2;]1;]2 o01 _BG1ShiftTemplate 0;]1;]2 none <<< ; After the values are saved, the data bank can be repointed at the current code bank and the values copied in ; from the direct page ; ; ]1 = offset in temp buffer ; ]2 = address of temp buffer ; ]3 = 4k offset in code buffer _BG1ShiftToCodeTemplate mac lda ]2+]1 sta: BG1_ADDR+]3,y <<< ApplyBG1ShiftToCode mac jmp (abstc_tbl,x) abstc_tbl da none da do01,do02,do03,do04 da do05,do06,do07,do08 da do09,do10,do11,do12 da do13,do14,do15,do16 do16 _BG1ShiftToCodeTemplate 30;]1;$F000 do15 _BG1ShiftToCodeTemplate 28;]1;$E000 do14 _BG1ShiftToCodeTemplate 26;]1;$D000 do13 _BG1ShiftToCodeTemplate 24;]1;$C000 do12 _BG1ShiftToCodeTemplate 22;]1;$B000 do11 _BG1ShiftToCodeTemplate 20;]1;$A000 do10 _BG1ShiftToCodeTemplate 18;]1;$9000 do09 _BG1ShiftToCodeTemplate 16;]1;$8000 do08 _BG1ShiftToCodeTemplate 14;]1;$7000 do07 _BG1ShiftToCodeTemplate 12;]1;$6000 do06 _BG1ShiftToCodeTemplate 10;]1;$5000 do05 _BG1ShiftToCodeTemplate 8;]1;$4000 do04 _BG1ShiftToCodeTemplate 6;]1;$3000 do03 _BG1ShiftToCodeTemplate 4;]1;$2000 do02 _BG1ShiftToCodeTemplate 2;]1;$1000 do01 _BG1ShiftToCodeTemplate 0;]1;$0000 none <<<