Skip to navigation


Bank 6 (Part 2 of 3)

[NES version]

Name: tuneData [Show more] Type: Variable Category: Sound Summary: Data for the tunes played in the game Deep dive: Music in NES Elite
Context: See this variable on its own page References: This variable is used as follows: * ChooseMusic uses tuneData
.tuneData .tune0Data EQUB 47 EQUW tune0Data_SQ1 EQUW tune0Data_SQ2 EQUW tune0Data_TRI EQUW tune0Data_NOISE .tune1Data EQUB 59 EQUW tune1Data_SQ1 EQUW tune1Data_SQ2 EQUW tune1Data_TRI EQUW tune1Data_NOISE .tune2Data EQUB 60 EQUW tune2Data_SQ1 EQUW tune2Data_SQ2 EQUW tune2Data_TRI EQUW tune2Data_NOISE .tune3Data EQUB 60 EQUW tune3Data_SQ1 EQUW tune3Data_SQ2 EQUW tune3Data_TRI EQUW tune3Data_NOISE .tune4Data EQUB 60 EQUW tune4Data_SQ1 EQUW tune4Data_SQ2 EQUW tune4Data_TRI EQUW tune4Data_NOISE .tune1Data_SQ1 EQUW tune1Data_SQ1_0 EQUW 0 .tune1Data_TRI EQUW tune1Data_TRI_0 EQUW 0 .tune1Data_SQ2 EQUW tune1Data_SQ2_0 EQUW 0 .tune1Data_NOISE EQUW tune1Data_NOISE_0 EQUW 0 .tune1Data_SQ1_0 EQUB $FA, $B0, $F7, $05, $F6, $0F, $6B, $F8 EQUB $63, $F6, $02, $0E, $F6, $07, $1E, $1E EQUB $F6, $02, $0E, $F6, $07, $1E, $1E, $F6 EQUB $02, $0E, $F6, $07, $1A, $1A, $F6, $02 EQUB $0E, $F6, $07, $1A, $1A, $F6, $02, $10 EQUB $F6, $07, $19, $19, $F6, $02, $10, $F6 EQUB $07, $19, $19, $F6, $02, $10, $F6, $07 EQUB $19, $19, $F6, $02, $10, $F6, $07, $15 EQUB $15, $F6, $02, $09, $F6, $07, $1F, $1F EQUB $F6, $02, $09, $F6, $07, $19, $19, $F6 EQUB $02, $09, $F6, $07, $15, $15, $F6, $02 EQUB $09, $F6, $07, $15, $13, $F6, $02, $0E EQUB $F6, $07, $1E, $1E, $F6, $02, $0E, $F6 EQUB $07, $1E, $1E, $F6, $02, $0E, $F6, $07 EQUB $1A, $1A, $F6, $02, $0E, $F6, $07, $1A EQUB $1A, $F6, $02, $12, $F6, $07, $1E, $1E EQUB $F6, $02, $12, $F6, $07, $1E, $1E, $F6 EQUB $02, $12, $F6, $07, $1A, $1A, $F6, $02 EQUB $12, $F6, $07, $15, $15, $F6, $02, $13 EQUB $F6, $07, $1C, $1C, $F6, $02, $13, $F6 EQUB $07, $1A, $1A, $F6, $06, $67, $10, $63 EQUB $10, $10, $13, $61, $17, $F8, $63, $F6 EQUB $02, $10, $F6, $07, $1C, $1C, $F6, $02 EQUB $09, $F6, $07, $14, $15, $F6, $02, $0E EQUB $F6, $07, $1E, $1E, $F6, $02, $0E, $F6 EQUB $07, $1E, $1E, $F6, $02, $6B, $10, $13 EQUB $62, $15, $F8, $61, $15, $63, $15, $62 EQUB $0E, $60, $F8, $F6, $05, $63, $1E, $F8 EQUB $F6, $02, $10, $F6, $07, $1A, $1A, $F6 EQUB $02, $10, $F6, $07, $1A, $19, $F6, $02 EQUB $10, $F6, $07, $1A, $1A, $F6, $02, $10 EQUB $F6, $07, $1A, $1A, $F6, $02, $09, $F6 EQUB $07, $1C, $1C, $F6, $02, $09, $F6, $07 EQUB $19, $19, $F6, $02, $09, $F6, $07, $15 EQUB $15, $F6, $02, $09, $F6, $07, $19, $19 EQUB $F6, $02, $10, $F6, $07, $1A, $1A, $F6 EQUB $02, $10, $F6, $07, $1A, $19, $F6, $02 EQUB $10, $F6, $07, $1A, $1A, $F6, $02, $10 EQUB $F6, $07, $17, $17, $F6, $06, $12, $F9 EQUB $15, $65, $17, $F8, $63, $10, $14, $10 EQUB $65, $09, $F8, $6B, $1C, $15, $1C, $63 EQUB $15, $F8, $F6, $04, $15, $F6, $02, $10 EQUB $F6, $07, $19, $19, $F6, $02, $10, $F6 EQUB $07, $19, $19, $F6, $02, $10, $F6, $07 EQUB $19, $19, $F6, $02, $10, $F6, $07, $19 EQUB $19, $F6, $02, $0E, $F6, $07, $1E, $1E EQUB $F6, $02, $0E, $F6, $07, $1E, $1E, $F6 EQUB $02, $0E, $F6, $07, $1E, $1E, $F6, $02 EQUB $0E, $F6, $07, $1E, $21, $F6, $02, $10 EQUB $F6, $07, $19, $19, $F6, $02, $10, $F6 EQUB $07, $19, $19, $F6, $02, $10, $F6, $07 EQUB $19, $19, $F6, $02, $10, $F6, $07, $19 EQUB $19, $F6, $04, $63, $1A, $19, $18, $F6 EQUB $06, $67, $1B, $F6, $04, $61, $1C, $F8 EQUB $F6, $02, $63, $09, $15, $09, $0E, $F8 EQUB $F6, $04, $61, $0E, $F8, $63, $F6, $02 EQUB $0A, $F6, $07, $1D, $1D, $F6, $02, $0A EQUB $F6, $07, $1D, $1D, $F6, $02, $0F, $F6 EQUB $07, $18, $18, $F6, $02, $0F, $F6, $07 EQUB $18, $18, $F6, $02, $15, $F6, $07, $1D EQUB $1D, $F6, $02, $11, $F6, $07, $1D, $1D EQUB $F6, $02, $16, $F6, $07, $1D, $1D, $F6 EQUB $02, $11, $F6, $07, $1D, $1D, $F6, $02 EQUB $0A, $F6, $07, $1D, $1D, $F6, $02, $0A EQUB $F6, $07, $1D, $1D, $F6, $02, $0F, $F6 EQUB $07, $18, $18, $F6, $02, $10, $F6, $07 EQUB $19, $19, $F6, $02, $0E, $F6, $07, $1A EQUB $1A, $F6, $02, $0E, $F6, $07, $16, $16 EQUB $F6, $04, $15, $15, $15, $15, $15, $15 EQUB $F6, $02, $10, $F6, $07, $19, $19, $F6 EQUB $02, $09, $F6, $07, $19, $19, $F6, $02 EQUB $15, $F6, $07, $19, $19, $F6, $02, $09 EQUB $F6, $07, $19, $19, $F6, $02, $0E, $F6 EQUB $07, $1E, $1E, $F6, $02, $0E, $F6, $07 EQUB $1E, $1E, $F6, $02, $0E, $F6, $07, $1E EQUB $1E, $F6, $02, $0E, $F6, $07, $1E, $21 EQUB $F6, $02, $10, $F6, $07, $19, $19, $F6 EQUB $02, $09, $F6, $07, $19, $19, $F6, $02 EQUB $15, $F6, $07, $19, $19, $F6, $02, $09 EQUB $F6, $07, $19, $19, $F6, $04, $63, $1A EQUB $19, $18, $F6, $06, $67, $1B, $F6, $04 EQUB $61, $1C, $F8, $F6, $02, $63, $09, $15 EQUB $09, $0E, $F8, $F6, $04, $61, $1A, $F8 EQUB $FF .tune1Data_TRI_0 EQUB $FC, $0C, $6B, $F8, $63, $F6, $08, $F7 EQUB $03, $0E, $1A, $1A, $0E, $1A, $1A, $0E EQUB $15, $15, $0E, $15, $15, $10, $15, $15 EQUB $10, $15, $15, $10, $15, $15, $10, $10 EQUB $10, $09, $19, $19, $09, $13, $13, $09 EQUB $13, $13, $09, $15, $0D, $0E, $1A, $1A EQUB $0E, $1A, $1A, $0E, $15, $15, $0E, $15 EQUB $1A, $12, $1A, $1A, $12, $1A, $1A, $12 EQUB $15, $15, $12, $0E, $0E, $13, $1A, $1A EQUB $13, $17, $17, $67, $0E, $63, $10, $10 EQUB $13, $61, $17, $F8, $63, $10, $19, $19 EQUB $09, $19, $19, $0E, $1A, $1A, $0E, $1A EQUB $1A, $6B, $0E, $10, $62, $12, $F8, $61 EQUB $12, $63, $12, $62, $15, $60, $F8, $63 EQUB $F8, $F8, $10, $14, $14, $10, $14, $13 EQUB $10, $1C, $1C, $10, $1C, $1C, $6B, $F6 EQUB $34, $10, $12, $13, $12, $F6, $08, $63 EQUB $10, $1C, $1C, $10, $1C, $13, $10, $1C EQUB $1C, $10, $1A, $1A, $19, $F9, $15, $65 EQUB $1A, $F8, $61, $1A, $1A, $1A, $F8, $1A EQUB $F8, $65, $10, $F8, $6B, $F6, $34, $1F EQUB $1C, $1F, $F6, $08, $63, $1C, $F8, $21 EQUB $F7, $00, $19, $61, $2A, $2B, $63, $2D EQUB $19, $61, $2A, $2B, $63, $2D, $1E, $61 EQUB $2A, $2B, $63, $2D, $2D, $1C, $15, $1E EQUB $61, $2A, $2B, $63, $2D, $1E, $61, $2A EQUB $2B, $63, $2D, $1C, $61, $2A, $2B, $63 EQUB $2D, $2D, $1A, $15, $1F, $61, $2A, $2B EQUB $63, $2D, $1F, $61, $2A, $2B, $63, $2D EQUB $1E, $61, $2A, $2B, $63, $2D, $2D, $1C EQUB $13, $F7, $03, $63, $1A, $1C, $1E, $67 EQUB $21, $63, $1F, $61, $1E, $1E, $1E, $F8 EQUB $1C, $F8, $63, $1A, $F8, $F8, $63, $0A EQUB $1A, $1A, $0A, $1A, $1A, $0F, $13, $13 EQUB $0F, $13, $13, $15, $1B, $1B, $11, $15 EQUB $15, $16, $1A, $1A, $11, $1A, $1A, $0A EQUB $1A, $1A, $0A, $16, $16, $0F, $1B, $1B EQUB $10, $13, $13, $0E, $15, $12, $0E, $13 EQUB $13, $15, $12, $F8, $F8, $F8, $F8, $F7 EQUB $00, $1C, $61, $2A, $2B, $63, $2D, $15 EQUB $61, $2A, $2B, $63, $2D, $21, $61, $2A EQUB $2B, $63, $2D, $15, $1C, $15, $1A, $61 EQUB $2A, $2B, $63, $2D, $1A, $61, $2A, $2B EQUB $63, $2D, $1A, $61, $2A, $2B, $63, $2D EQUB $1A, $1A, $15, $1C, $61, $2A, $2B, $63 EQUB $2D, $15, $61, $2A, $2B, $63, $2D, $21 EQUB $61, $2A, $2B, $63, $2D, $15, $1C, $13 EQUB $F7, $03, $63, $1A, $1C, $1E, $67, $21 EQUB $61, $1F, $F8, $61, $1E, $1E, $1E, $F8 EQUB $1C, $F8, $63, $1A, $F8, $F8, $FF .tune1Data_SQ2_0 EQUB $FA, $B0, $F7, $01, $F6, $04, $63, $1A EQUB $1E, $62, $21, $60, $F8, $67, $21, $FA EQUB $F0, $62, $21, $60, $F8, $67, $21, $62 EQUB $1E, $60, $F8, $67, $1E, $FA, $B0, $62 EQUB $1A, $60, $F8, $63, $1A, $1E, $62, $21 EQUB $60, $F8, $67, $21, $FA, $F0, $62, $21 EQUB $60, $F8, $67, $21, $62, $1F, $60, $F8 EQUB $67, $1F, $FA, $B0, $62, $19, $60, $F8 EQUB $63, $19, $1C, $62, $23, $60, $F8, $67 EQUB $23, $FA, $F0, $62, $23, $60, $F8, $67 EQUB $23, $62, $1F, $60, $F8, $67, $1F, $FA EQUB $B0, $62, $19, $60, $F8, $63, $19, $1C EQUB $62, $23, $60, $F8, $67, $23, $FA, $F0 EQUB $62, $23, $60, $F8, $67, $23, $62, $1E EQUB $60, $F8, $67, $1E, $FA, $B0, $62, $1A EQUB $60, $F8, $63, $1A, $1E, $21, $67, $26 EQUB $FA, $F0, $62, $26, $60, $F8, $67, $26 EQUB $62, $21, $60, $F8, $67, $21, $FA, $B0 EQUB $62, $1A, $60, $F8, $63, $1A, $1E, $21 EQUB $67, $26, $FA, $F0, $62, $26, $60, $F8 EQUB $67, $26, $62, $23, $60, $F8, $65, $23 EQUB $61, $F9, $FA, $B0, $61, $1C, $F8, $63 EQUB $1C, $1F, $61, $23, $F8, $6B, $23, $63 EQUB $F9, $20, $21, $6B, $2A, $63, $F9, $26 EQUB $1E, $F6, $06, $67, $1E, $61, $1C, $F8 EQUB $67, $23, $61, $21, $F8, $62, $1A, $F8 EQUB $61, $1A, $63, $1A, $62, $1A, $60, $F8 EQUB $FA, $F0, $F6, $04, $63, $26, $62, $25 EQUB $60, $F8, $F6, $06, $63, $25, $62, $23 EQUB $60, $F8, $63, $23, $F8, $23, $62, $22 EQUB $60, $F8, $63, $22, $62, $23, $60, $F8 EQUB $63, $23, $F8, $1C, $1C, $1E, $F9, $1C EQUB $F8, $1C, $1C, $23, $F9, $21, $F8, $26 EQUB $62, $25, $60, $F8, $63, $25, $62, $23 EQUB $60, $F8, $63, $23, $F8, $23, $25, $28 EQUB $26, $26, $F8, $20, $23, $23, $F9, $21 EQUB $65, $20, $61, $1E, $1A, $17, $61, $1E EQUB $1E, $63, $1E, $1C, $FA, $B0, $F6, $06 EQUB $65, $15, $F8, $F6, $07, $F7, $03, $FA EQUB $30, $60, $2F, $2D, $2F, $2D, $2F, $2D EQUB $2F, $2D, $2F, $2D, $2F, $2D, $2F, $2D EQUB $2F, $2D, $2F, $2D, $2F, $2D, $2F, $2D EQUB $2F, $2D, $2F, $2D, $2F, $2D, $2F, $2D EQUB $2F, $2D, $2F, $2D, $2F, $2D, $F6, $06 EQUB $63, $2D, $F8, $F7, $01, $FA, $B0, $62 EQUB $21, $60, $F8, $F6, $04, $67, $1F, $61 EQUB $21, $F8, $67, $1F, $61, $21, $F8, $6B EQUB $2A, $63, $F8, $28, $21, $67, $1E, $61 EQUB $21, $F8, $67, $1E, $61, $21, $F8, $6B EQUB $28, $63, $F8, $26, $21, $67, $1F, $61 EQUB $21, $F8, $67, $1F, $61, $21, $F8, $6B EQUB $2A, $63, $F8, $28, $21, $26, $28, $2A EQUB $F6, $06, $67, $2D, $F6, $04, $61, $2B EQUB $F8, $61, $2A, $2A, $63, $2A, $28, $F6 EQUB $06, $65, $26, $61, $F8, $F6, $04, $FA EQUB $F0, $61, $26, $F8, $6F, $26, $63, $27 EQUB $26, $24, $22, $21, $69, $1F, $61, $F8 EQUB $65, $24, $61, $F8, $65, $24, $61, $1D EQUB $65, $1F, $61, $1D, $F6, $06, $FA, $30 EQUB $63, $1D, $1A, $1D, $1B, $1A, $18, $F6 EQUB $04, $FA, $F0, $65, $26, $61, $F8, $67 EQUB $26, $63, $27, $26, $24, $22, $21, $69 EQUB $1F, $61, $F8, $65, $1E, $61, $F8, $67 EQUB $1E, $65, $1F, $61, $22, $6F, $21, $63 EQUB $F8, $FA, $B0, $F6, $06, $61, $21, $F8 EQUB $67, $1F, $61, $21, $F8, $67, $1F, $61 EQUB $21, $F8, $6F, $2A, $61, $28, $F8, $21 EQUB $F8, $F6, $04, $67, $1E, $61, $21, $F8 EQUB $67, $1E, $61, $21, $F8, $6F, $28, $61 EQUB $26, $F8, $21, $F8, $F6, $06, $67, $1F EQUB $61, $21, $F8, $67, $1F, $61, $21, $F8 EQUB $6B, $2A, $F4, $3A, $63, $F9, $61, $28 EQUB $F8, $21, $F8, $F4, $39, $61, $26, $F8 EQUB $28, $F8, $2A, $F8, $F4, $38, $67, $2D EQUB $61, $2B, $F8, $F4, $37, $2A, $2A, $2A EQUB $F4, $33, $F8, $28, $F8, $26, $69, $F8 EQUB $F4, $3B, $FF .tune0Data_SQ1 EQUW tune0Data_SQ1_0 EQUW tune0Data_SQ1_0 EQUW tune0Data_SQ1_1 EQUW tune0Data_SQ1_2 EQUW tune0Data_SQ1_1 EQUW tune0Data_SQ1_2 EQUW tune0Data_SQ1_1 EQUW tune0Data_SQ1_3 EQUW tune0Data_SQ1_1 EQUW tune0Data_SQ1_4 EQUW 0 .tune0Data_TRI EQUW tune0Data_TRI_0 EQUW tune0Data_TRI_0 EQUW tune0Data_TRI_1 EQUW tune0Data_TRI_2 EQUW tune0Data_TRI_1 EQUW tune0Data_TRI_2 EQUW tune0Data_TRI_1 EQUW tune0Data_TRI_1 EQUW 0 .tune0Data_SQ2 EQUW tune0Data_SQ2_0 EQUW tune0Data_SQ2_0 EQUW tune0Data_SQ2_1 EQUW tune0Data_SQ2_2 EQUW tune0Data_SQ2_1 EQUW tune0Data_SQ2_3 EQUW tune0Data_SQ2_1 EQUW tune0Data_SQ2_1 EQUW 0 .tune0Data_NOISE EQUW tune0Data_NOISE_0 EQUW 0 .tune0Data_SQ1_0 EQUB $FA, $70, $F7, $05, $F6, $09, $65, $0C EQUB $0C, $0C, $63, $07, $61, $07, $63, $07 EQUB $07, $FF .tune0Data_SQ1_1 EQUB $FA, $70, $65, $0C, $0C, $63, $0C, $61 EQUB $F9, $63, $07, $61, $07, $63, $07, $07 EQUB $65, $0C, $0C, $63, $0C, $65, $07, $07 EQUB $61, $07, $07, $65, $0C, $0C, $63, $0C EQUB $61, $07, $63, $05, $65, $0C, $63, $04 EQUB $65, $02, $04, $63, $05, $07, $07, $07 EQUB $07, $65, $00, $0C, $63, $0C, $65, $07 EQUB $07, $63, $07, $65, $0C, $0C, $63, $0C EQUB $65, $0E, $0E, $61, $0E, $0E, $63, $0E EQUB $10, $11, $12, $61, $07, $60, $07, $07 EQUB $61, $07, $65, $07, $63, $07, $65, $0C EQUB $65, $13, $63, $13, $63, $0C, $61, $13 EQUB $0C, $F8, $0C, $0A, $09, $FF .tune0Data_SQ1_2 EQUB $FA, $B0, $65, $07, $F7, $07, $09, $63 EQUB $0A, $61, $F9, $65, $F7, $05, $13, $63 EQUB $F7, $07, $09, $0A, $65, $09, $0B, $63 EQUB $0C, $65, $09, $09, $63, $09, $65, $F7 EQUB $05, $07, $F7, $07, $09, $63, $0A, $61 EQUB $F9, $65, $F7, $05, $07, $F7, $07, $63 EQUB $09, $0A, $65, $09, $0B, $63, $0C, $65 EQUB $09, $0B, $63, $0D, $65, $09, $0B, $63 EQUB $0C, $61, $F9, $65, $F7, $06, $0E, $63 EQUB $10, $12, $65, $F7, $07, $0A, $0C, $63 EQUB $0D, $61, $F9, $65, $F7, $06, $0F, $63 EQUB $11, $13, $65, $F7, $07, $0B, $0D, $63 EQUB $0E, $61, $F9, $65, $F7, $06, $10, $63 EQUB $12, $14, $65, $14, $14, $63, $14, $61 EQUB $F9, $13, $13, $13, $13, $13, $13, $13 EQUB $FF .tune0Data_TRI_0 EQUB $61, $F6, $05, $F7, $03, $28, $28, $28 EQUB $28, $28, $28, $28, $28, $28, $29, $29 EQUB $29, $29, $29, $29, $29, $FF .tune0Data_TRI_1 EQUB $28, $28, $28, $28, $28, $28, $28, $28 EQUB $28, $29, $29, $29, $29, $29, $29, $29 EQUB $28, $28, $28, $28, $28, $28, $28, $28 EQUB $F8, $29, $29, $29, $29, $29, $29, $29 EQUB $28, $28, $28, $28, $28, $28, $28, $28 EQUB $2B, $63, $F6, $10, $29, $65, $28, $63 EQUB $28, $F6, $05, $61, $26, $26, $26, $26 EQUB $26, $26, $26, $26, $29, $F6, $10, $63 EQUB $28, $24, $21, $61, $1F, $F6, $05, $28 EQUB $28, $28, $28, $28, $28, $28, $28, $28 EQUB $29, $29, $29, $29, $29, $29, $29, $28 EQUB $28, $28, $28, $28, $28, $28, $28, $26 EQUB $26, $26, $26, $26, $26, $26, $26, $29 EQUB $29, $29, $29, $29, $29, $29, $29, $2B EQUB $60, $F6, $03, $2B, $2B, $67, $F6, $20 EQUB $2B, $F6, $10, $63, $2B, $F6, $05, $61 EQUB $28, $28, $28, $29, $29, $29, $29, $29 EQUB $28, $28, $29, $28, $F8, $24, $22, $21 EQUB $FF .tune0Data_TRI_2 EQUB $61, $F8, $29, $29, $F8, $29, $29, $F8 EQUB $29, $29, $F8, $29, $29, $F8, $29, $F8 EQUB $29, $F8, $28, $28, $F8, $28, $28, $F8 EQUB $28, $28, $F8, $28, $28, $F8, $28, $F8 EQUB $28, $F8, $29, $29, $F8, $29, $29, $F8 EQUB $29, $29, $F8, $29, $29, $F8, $29, $F8 EQUB $29, $F8, $28, $28, $F8, $28, $28, $F8 EQUB $28, $28, $F8, $28, $28, $F8, $28, $F8 EQUB $28, $F8, $26, $26, $F8, $26, $26, $F8 EQUB $26, $26, $F8, $26, $26, $F8, $26, $F8 EQUB $26, $F8, $27, $27, $F8, $27, $27, $F8 EQUB $27, $27, $F8, $27, $27, $F8, $27, $F8 EQUB $27, $F8, $28, $28, $F8, $28, $28, $F8 EQUB $28, $28, $F8, $28, $28, $F8, $28, $F8 EQUB $28, $29, $29, $29, $29, $29, $29, $29 EQUB $29, $2B, $2B, $2B, $2B, $2B, $2B, $2B EQUB $2B, $FC, $00, $FF .tune0Data_SQ2_0 EQUB $FA, $70, $F7, $01, $F6, $07, $61, $18 EQUB $18, $18, $18, $18, $18, $18, $18, $18 EQUB $18, $18, $18, $18, $18, $18, $18, $FF .tune0Data_SQ2_1 EQUB $FA, $B0, $F6, $01, $F7, $01, $61, $F8 EQUB $60, $1F, $1F, $61, $24, $28, $67, $2B EQUB $61, $F9, $60, $26, $26, $61, $29, $2B EQUB $2D, $2B, $28, $26, $28, $24, $1F, $69 EQUB $1F, $61, $F9, $6D, $F8, $61, $F8, $60 EQUB $1F, $1F, $61, $24, $28, $65, $2B, $60 EQUB $2B, $2D, $61, $2E, $63, $2D, $2B, $61 EQUB $28, $2B, $2D, $6F, $26, $6D, $F9, $61 EQUB $F8, $F8, $60, $1F, $1F, $61, $24, $28 EQUB $67, $2B, $61, $F9, $60, $26, $26, $61 EQUB $29, $2B, $2D, $2B, $28, $26, $28, $24 EQUB $1F, $65, $2B, $63, $2D, $6B, $26, $61 EQUB $F8, $60, $26, $28, $61, $29, $63, $28 EQUB $61, $24, $29, $63, $28, $61, $24, $61 EQUB $2B, $60, $2B, $2B, $65, $2B, $61, $F8 EQUB $63, $2B, $6F, $30, $67, $F9, $F8, $FA EQUB $70, $FF .tune0Data_SQ2_3 EQUB $FA, $30 .tune0Data_SQ2_2 EQUB $61, $F8, $F6, $00, $F7, $05, $60, $0C EQUB $0C, $61, $0E, $11, $67, $16, $6A, $F9 EQUB $60, $F8, $63, $16, $64, $18, $60, $F8 EQUB $61, $15, $6B, $18, $60, $F6, $05, $F7 EQUB $03, $39, $37, $34, $30, $2D, $2B, $28 EQUB $24, $21, $1F, $1C, $18, $61, $F8, $F6 EQUB $00, $F7, $05, $60, $0A, $0A, $61, $0E EQUB $11, $67, $16, $66, $F9, $60, $F8, $63 EQUB $16, $18, $6F, $19, $6A, $F9, $60, $F8 EQUB $63, $19, $67, $1A, $15, $66, $F9, $60 EQUB $F8, $63, $15, $1A, $67, $1B, $16, $66 EQUB $F9, $60, $F8, $63, $16, $1B, $67, $1C EQUB $17, $66, $F9, $60, $F8, $62, $17, $1C EQUB $61, $17, $6A, $1D, $60, $F8, $61, $1C EQUB $1D, $66, $1F, $60, $F8, $65, $1F, $60 EQUB $1C, $1A, $FF .tune0Data_NOISE_0 EQUB $F6, $11, $65, $04, $04, $04, $63, $04 EQUB $61, $04, $63, $04, $04, $65, $04, $04 EQUB $04, $63, $04, $61, $04, $63, $04, $61 EQUB $04, $04, $FF .tune4Data_SQ1 EQUW tune4Data_SQ1_0 EQUW tune4Data_SQ1_0 EQUW tune4Data_SQ1_1 EQUW tune4Data_SQ1_2 .tune2Data_SQ1 EQUW tune2Data_SQ1_0 EQUW tune2Data_SQ1_1 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_4 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_4 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_1 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_5 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_4 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_4 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_2 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_3 EQUW tune2Data_SQ1_0 EQUW 0 .tune4Data_TRI EQUW tune4Data_TRI_0 EQUW tune4Data_TRI_0 EQUW tune4Data_TRI_1 EQUW tune4Data_TRI_2 .tune2Data_TRI EQUW tune2Data_TRI_0 EQUW tune2Data_TRI_1 EQUW tune2Data_TRI_1 EQUW 0 .tune4Data_SQ2 EQUW tune4Data_SQ2_0 EQUW tune4Data_SQ2_0 EQUW tune4Data_SQ2_1 EQUW tune4Data_SQ2_2 .tune2Data_SQ2 EQUW tune2Data_SQ2_0 EQUW tune2Data_SQ2_1 EQUW tune2Data_SQ2_2 EQUW 0 .tune4Data_NOISE EQUW tune4Data_NOISE_0 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_0 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_0 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_0 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_1 EQUW tune4Data_NOISE_2 EQUW tune4Data_NOISE_3 .tune2Data_NOISE EQUW tune2Data_NOISE_0 EQUW 0 .tune2Data_SQ1_1 EQUB $FA, $B0, $F7, $05, $F6, $0B, $61 .tune2Data_SQ1_2 EQUB $0C, $0C, $0C, $0C, $0C, $0C, $0C, $07 EQUB $FF .tune2Data_SQ1_4 EQUB $05, $05, $05, $05, $05, $05, $05, $07 EQUB $FF .tune2Data_SQ1_3 EQUB $07, $07, $07, $07, $07, $07, $07, $13 EQUB $FF .tune2Data_TRI_0 EQUB $F6, $FF, $F7, $01, $7F, $24, $22, $24 EQUB $6F, $22, $1F, $7F, $24, $22, $24, $1F EQUB $FF .tune2Data_TRI_1 EQUB $77, $1C, $67, $1F, $77, $22, $67, $1D EQUB $6F, $1C, $24, $21, $23, $7F, $1C, $6F EQUB $1A, $1D, $7F, $1C, $6F, $1A, $26, $FF .tune2Data_SQ2_0 EQUB $FA, $B0, $F7, $05, $F6, $0C, $FC, $F4 EQUB $63, $1C, $1C, $1C, $61, $1C, $13, $63 EQUB $1C, $1C, $1C, $61, $1C, $1F, $63, $1B EQUB $1B, $1B, $61, $1B, $13, $63, $1B, $1B EQUB $1B, $61, $1B, $1F, $63, $1C, $1C, $1C EQUB $61, $1C, $13, $63, $1C, $1C, $1C, $61 EQUB $1C, $1F, $63, $16, $16, $16, $61, $16 EQUB $15, $63, $16, $16, $16, $61, $16, $13 EQUB $63, $FC, $00, $F7, $01, $1C, $1C, $1C EQUB $61, $1C, $13, $63, $1C, $1C, $1C, $61 EQUB $1C, $1F, $63, $1B, $1B, $1B, $61, $1B EQUB $13, $63, $1B, $1B, $1B, $61, $1B, $1F EQUB $63, $1C, $1C, $1C, $61, $1C, $13, $63 EQUB $1C, $1C, $1C, $61, $1C, $1F, $63, $16 EQUB $16, $16, $61, $16, $15, $63, $16, $16 EQUB $16, $61, $16, $13, $FF .tune2Data_SQ2_1 EQUB $FA, $B0, $F7, $05, $FC, $F4 .tune2Data_SQ2_2 EQUB $F6, $0A, $63, $24, $24, $61, $22, $65 EQUB $21, $63, $24, $24, $61, $22, $63, $1C EQUB $22, $22, $21, $22, $24, $22, $21, $63 EQUB $22, $61, $16, $63, $24, $24, $61, $22 EQUB $65, $21, $63, $24, $24, $61, $26, $63 EQUB $27, $F7, $01, $29, $29, $27, $29, $F6 EQUB $08, $71, $2B, $77, $2B, $67, $2D, $77 EQUB $2E, $67, $2D, $77, $28, $67, $2B, $6F EQUB $2E, $F6, $08, $22, $FA, $F0, $FF .tune2Data_NOISE_0 EQUB $61, $F6, $10, $08, $02, $F6, $0E, $07 EQUB $F6, $10, $02, $FF .tune3Data_SQ1 EQUW tune3Data_SQ1_0 EQUW tune3Data_SQ1_0 EQUW tune3Data_SQ1_1 EQUW 0 .tune3Data_TRI EQUW tune3Data_TRI_0 EQUW tune3Data_TRI_0 EQUW tune3Data_TRI_1 EQUW 0 .tune3Data_SQ2 EQUW tune3Data_SQ2_0 EQUW tune3Data_SQ2_0 EQUW tune3Data_SQ2_1 EQUW 0 .tune3Data_NOISE EQUW tune3Data_NOISE_0 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_0 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_0 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_0 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_1 EQUW tune3Data_NOISE_2 EQUW 0 .tune3Data_SQ1_0 .tune4Data_SQ1_0 EQUB $FA, $B0, $F7, $05, $F6, $0F, $63, $F8 EQUB $F6, $08, $67, $0D, $F6, $02, $63, $0D EQUB $65, $11, $61, $11, $67, $11, $65, $0F EQUB $61, $0F, $67, $0F, $65, $11, $61, $11 EQUB $63, $11, $61, $11, $11, $F6, $0D, $63 EQUB $0D, $F6, $02, $67, $0D, $63, $0D, $65 EQUB $11, $61, $11, $67, $11, $65, $0F, $61 EQUB $0F, $67, $0F, $63, $11, $13, $14, $16 EQUB $FF .tune3Data_SQ1_1 .tune4Data_SQ1_1 EQUB $65, $0C, $69, $0C, $65, $0C, $69, $0C EQUB $65, $0C, $69, $0C, $63, $0C, $0C, $0C EQUB $0C, $6F, $0C, $FF .tune3Data_TRI_0 .tune4Data_TRI_0 EQUB $F7, $05, $FC, $0C, $F6, $00, $63, $F8 EQUB $F6, $28, $6A, $1B, $60, $F8, $F6, $08 EQUB $61, $1B, $F6, $10, $63, $18, $F6, $48 EQUB $68, $18, $60, $F8, $F6, $10, $63, $1B EQUB $1B, $F6, $08, $61, $1B, $F6, $10, $63 EQUB $1B, $61, $1B, $F9, $F6, $08, $61, $1D EQUB $F6, $60, $6B, $1D, $63, $F8, $F6, $28 EQUB $6A, $1B, $60, $F8, $F6, $08, $61, $1B EQUB $F6, $10, $63, $18, $F6, $48, $68, $18 EQUB $60, $F8, $F6, $10, $63, $1B, $1B, $F6 EQUB $08, $61, $1B, $F6, $10, $63, $1B, $F6 EQUB $80, $61, $1D, $6F, $F9, $FF .tune3Data_TRI_1 .tune4Data_TRI_1 EQUB $6F, $F6, $80, $13, $16, $13, $10, $63 EQUB $F9, $6B, $F8, $FC, $00, $FF .tune3Data_SQ2_0 .tune4Data_SQ2_0 EQUB $FA, $B0, $F7, $05, $F6, $0F, $63, $F8 EQUB $F6, $13, $6A, $1D, $60, $F8, $61, $1D EQUB $63, $1D, $68, $1D, $60, $F8, $63, $1F EQUB $1F, $61, $1F, $63, $1F, $61, $1F, $F9 EQUB $61, $20, $6B, $20, $63, $F8, $6A, $1D EQUB $60, $F8, $61, $1D, $63, $1D, $68, $1D EQUB $60, $F8, $63, $1F, $1F, $61, $1F, $63 EQUB $1F, $61, $20, $6F, $F9, $FF .tune3Data_SQ2_1 .tune4Data_SQ2_1 EQUB $FA, $70, $6F, $F6, $05, $18, $F6, $04 EQUB $1C, $F6, $06, $1F, $F6, $01, $22, $63 EQUB $F9, $6B, $F8, $FF .tune3Data_NOISE_0 .tune4Data_NOISE_0 EQUB $F6, $0F, $63, $F8, $67, $F6, $02, $07 EQUB $F6, $11, $63, $04, $FF .tune3Data_NOISE_1 .tune4Data_NOISE_1 EQUB $61, $F6, $10, $08, $02, $F6, $12, $07 EQUB $F6, $10, $02, $FF .tune3Data_NOISE_2 .tune4Data_NOISE_2 EQUB $63, $F6, $11, $02, $F6, $12, $02, $F6 EQUB $11, $02, $F6, $12, $02, $F6, $11, $02 EQUB $F6, $12, $02, $F6, $11, $02, $F6, $12 EQUB $02, $F6, $11, $02, $F6, $12, $02, $F6 EQUB $11, $02, $F6, $12, $02, $F6, $12, $02 EQUB $02, $02, $02, $6F, $04, $FF .tune4Data_SQ1_2 EQUB $F5 EQUW tune2Data_SQ1 .tune4Data_TRI_2 EQUB $F5 EQUW tune2Data_TRI .tune4Data_SQ2_2 EQUB $F5 EQUW tune2Data_SQ2 .tune4Data_NOISE_3 EQUB $F5 EQUW tune2Data_NOISE .tune0Data_SQ1_4 EQUB $FB, $00, $FF .tune0Data_SQ1_3 EQUB $FB, $01, $FF .tune2Data_SQ1_0 EQUB $FB, $03, $FF .tune2Data_SQ1_5 EQUB $FB, $04, $FF .tune1Data_NOISE_0 EQUB $7F, $F6, $0F, $F8, $FF, $EA
Name: DrawGlasses [Show more] Type: Subroutine Category: Status Summary: Draw a pair of dark glasses on the commander image
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawCmdrImage calls DrawGlasses
.DrawGlasses LDA #104 ; Set the pattern number for sprite 8 to 104, which is STA pattSprite8 ; the left part of the dark glasses LDA #%00000000 ; Set the attributes for sprite 8 as follows: STA attrSprite8 ; ; * Bits 0-1 = sprite palette 0 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA #203 ; Set the x-coordinate for sprite 8 to 203 STA xSprite8 LDA languageNumber ; If bit 2 of languageNumber is clear then the chosen AND #%00000100 ; language is not French, so jump to glas1 with A = 0 BEQ glas1 LDA #16 ; The chosen language is French, so the commander image ; is 16 pixels lower down the screen, so set A = 16 to ; add to the y-coordinate of the glasses .glas1 CLC ; Set the y-coordinate for sprite 8 to 90, plus the ADC #90+YPAL ; margin we just set in A STA ySprite8 LDA #105 ; Set the pattern number for sprite 9 to 105, which is STA pattSprite9 ; the middle part of the dark glasses LDA #%00000000 ; Set the attributes for sprite 9 as follows: STA attrSprite9 ; ; * Bits 0-1 = sprite palette 0 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA #211 ; Set the x-coordinate for sprite 9 to 211 STA xSprite9 LDA languageNumber ; If bit 2 of languageNumber is clear then the chosen AND #%00000100 ; language is not French, so jump to glas2 with A = 0 BEQ glas2 LDA #16 ; The chosen language is French, so the commander image ; is 16 pixels lower down the screen, so set A = 16 to ; add to the y-coordinate of the glasses .glas2 CLC ; Set the y-coordinate for sprite 9 to 90, plus the ADC #90+YPAL ; margin we just set in A STA ySprite9 LDA #106 ; Set the pattern number for sprite 10 to 106, which is STA pattSprite10 ; the right part of the dark glasses LDA #%00000000 ; Set the attributes for sprite 10 as follows: STA attrSprite10 ; ; * Bits 0-1 = sprite palette 0 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA #219 ; Set the x-coordinate for sprite 10 to 219 STA xSprite10 LDA languageNumber ; If bit 2 of languageNumber is clear then the chosen AND #%00000100 ; language is not French, so jump to glas3 with A = 0 BEQ glas3 LDA #16 ; The chosen language is French, so the commander image ; is 16 pixels lower down the screen, so set A = 16 to ; add to the y-coordinate of the glasses .glas3 CLC ; Set the y-coordinate for sprite 10 to 90, plus the ADC #90+YPAL ; margin we just set in A STA ySprite10 RTS ; Return from the subroutine
Name: DrawRightEarring [Show more] Type: Subroutine Category: Status Summary: Draw an earring in the commander's right ear (i.e. on the left side of the commander image
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawCmdrImage calls DrawRightEarring
.DrawRightEarring LDA #107 ; Set the pattern number for sprite 11 to 107, which is STA pattSprite11 ; the right earring LDA #%00000010 ; Set the attributes for sprite 11 as follows: STA attrSprite11 ; ; * Bits 0-1 = sprite palette 2 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA #195 ; Set the x-coordinate for sprite 11 to 195 STA xSprite11 LDA languageNumber ; If bit 2 of languageNumber is clear then the chosen AND #%00000100 ; language is not French, so jump to earr1 with A = 0 BEQ earr1 LDA #16 ; The chosen language is French, so the commander image ; is 16 pixels lower down the screen, so set A = 16 to ; add to the y-coordinate of the earring .earr1 CLC ; Set the y-coordinate for sprite 11 to 98, plus the ADC #98+YPAL ; margin we just set in A STA ySprite11 RTS ; Return from the subroutine
Name: DrawLeftEarring [Show more] Type: Subroutine Category: Status Summary: Draw an earring in the commander's left ear (i.e. on the right side of the commander image
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawCmdrImage calls DrawLeftEarring
.DrawLeftEarring LDA #108 ; Set the pattern number for sprite 12 to 108, which is STA pattSprite12 ; the left earring LDA #%00000010 ; Set the attributes for sprite 12 as follows: STA attrSprite12 ; ; * Bits 0-1 = sprite palette 2 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA #227 ; Set the x-coordinate for sprite 12 to 227 STA xSprite12 LDA languageNumber ; If bit 2 of languageNumber is clear then the chosen AND #%00000100 ; language is not French, so jump to earl1 with A = 0 BEQ earl1 LDA #16 ; The chosen language is French, so the commander image ; is 16 pixels lower down the screen, so set A = 16 to ; add to the y-coordinate of the earring .earl1 CLC ; Set the y-coordinate for sprite 12 to 98, plus the ADC #98+YPAL ; margin we just set in A STA ySprite12 RTS ; Return from the subroutine
Name: DrawMedallion [Show more] Type: Subroutine Category: Status Summary: Draw a medallion on the commander image
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawCmdrImage calls DrawMedallion
.DrawMedallion ; We draw the medallion image from sprites with ; sequential patterns, so first we configure the ; variables to pass to the DrawSpriteImage routine LDA #3 ; Set K = 5, to pass as the number of columns in the STA K ; image to DrawSpriteImage below LDA #2 ; Set K+1 = 2, to pass as the number of rows in the STA K+1 ; image to DrawSpriteImage below LDA #111 ; Set K+2 = 111, so we draw the medallion using pattern STA K+2 ; #111 onwards LDA #15 ; Set K+3 = 15, so we build the image from sprite 15 STA K+3 ; onwards LDX #11 ; Set X = 11 so we draw the image 11 pixels into the ; (XC, YC) character block along the x-axis LDY #49 ; Set Y = 49 so we draw the image 49 pixels into the ; (XC, YC) character block along the y-axis LDA #%00000010 ; Set the attributes for the sprites we create in the ; DrawSpriteImage routine as follows: ; ; * Bits 0-1 = sprite palette 2 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically JMP DrawSpriteImage+2 ; Draw the medallion image from sprites, using pattern ; #111 onwards and the sprite attributes in A
Name: DrawCmdrImage [Show more] Type: Subroutine Category: Status Summary: Draw the commander image as a coloured face image in front of a greyscale headshot image, with optional embellishments
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawCmdrImage_b6 calls DrawCmdrImage
.DrawCmdrImage ; The commander image is made up of two layers and some ; optional embellishments: ; ; * A greyscale headshot (i.e. the head and shoulders) ; that's displayed as a background using the ; nametable tiles, whose patterns are extracted into ; the pattern buffers by the GetHeadshot routine ; ; * A colourful face that's displayed in the ; foreground as a set of sprites, whose patterns are ; sent to the PPU by the GetCmdrImage routine, from ; pattern 69 onwards ; ; * A pair of dark glasses (if we are a fugitive) ; ; * Left and right earrings and a medallion, depending ; on how rich we are ; ; We start by drawing the background into the nametable ; buffers LDX #6 ; Set X = 6 to use as the number of columns in the image LDY #8 ; Set Y = 8 to use as the number of rows in the image STX K ; Set K = X, so we can pass the number of columns in the ; image to DrawBackground below STY K+1 ; Set K+1 = Y, so we can pass the number of rows in the ; image to DrawBackground below LDA firstFreePattern ; Set picturePattern to the number of the next free STA picturePattern ; pattern in firstFreePattern ; ; We use this when setting K+2 below, so the call to ; DrawBackground displays the patterns at ; picturePattern, and it's also used to specify where to ; load the system image data when we call GetCmdrImage ; from SendViewToPPU when showing the Status screen CLC ; Add 48 to firstFreePattern, as we are going to use 48 ADC #48 ; patterns for the system image (8 rows of 6 tiles) STA firstFreePattern LDX picturePattern ; Set K+2 to the value we stored above, so K+2 is the STX K+2 ; number of the first pattern to use for the commander ; image's greyscale headshot JSR DrawBackground_b3 ; Draw the background by writing the nametable buffer ; entries for the greyscale part of the commander image ; (this is the image that is extracted into the pattern ; buffers by the GetSystemBack routine) ; Now that the background is drawn, we move on to the ; sprite-based foreground, which contains the face image ; ; We draw the face image from sprites with sequential ; patterns, so now we configure the variables to pass ; to the DrawSpriteImage routine LDA #5 ; Set K = 5, to pass as the number of columns in the STA K ; image to DrawSpriteImage below LDA #7 ; Set K+1 = 7, to pass as the number of rows in the STA K+1 ; image to DrawSpriteImage below LDA #69 ; Set K+2 = 69, so we draw the face image using STA K+2 ; pattern 69 onwards LDA #20 ; Set K+3 = 20, so we build the image from sprite 20 STA K+3 ; onwards LDX #4 ; Set X = 4 so we draw the image four pixels into the ; (XC, YC) character block along the x-axis LDY #0 ; Set Y = 0 so we draw the image at the top of the ; (XC, YC) character block along the y-axis JSR DrawSpriteImage_b6 ; Draw the face image from sprites, using pattern 69 ; onwards ; Next, we draw a pair of smooth-criminal dark glasses ; in front of the face if we have got a criminal record LDA FIST ; If our legal status in FIST is less than 40, then we CMP #40 ; are either clean or an offender, so jump to cmdr1 to BCC cmdr1 ; skip the following instruction, as we aren't bad ; enough to wear shades JSR DrawGlasses ; If we get here then we are a fugitive, so draw a pair ; of dark glasses in front of the face .cmdr1 ; We now embellish the commander image, depending on how ; much cash we have ; ; Note that the CASH amount is stored as a big-endian ; four-byte number with the most significant byte first, ; i.e. as CASH(0 1 2 3) LDA CASH ; If CASH >= $01000000 (1,677,721.6 CR), jump to cmdr2 BNE cmdr2 LDA CASH+1 ; If CASH >= $00990000 (1,002,700.8 CR), jump to cmdr2 CMP #$99 BCS cmdr2 CMP #0 ; If CASH >= $00010000 (6,553.6 CR), jump to cmdr3 BNE cmdr3 LDA CASH+2 ; If CASH >= $00004F00 (2,022.4 CR), jump to cmdr3 CMP #$4F BCS cmdr3 CMP #$28 ; If CASH < $00002800 (1,024.0 CR), jump to cmdr5 BCC cmdr5 BCS cmdr4 ; Jump to cmdr4 (this BCS is effectively a JMP as we ; just passed through a BCC) .cmdr2 JSR DrawMedallion ; If we get here then we have more than 1,002,700.8 CR, ; so call DrawMedallion to draw a medallion on the ; commander image .cmdr3 JSR DrawRightEarring ; If we get here then we have more than 2,022.4 CR, so ; call DrawLeftEarring to draw an earring in the ; commander's right ear (i.e. on the left side of the ; commander image .cmdr4 JSR DrawLeftEarring ; If we get here then we have more than 1,024.0 CR, so ; call DrawRightEarring to draw an earring in the ; commander's left ear (i.e. on the right side of the ; commander image .cmdr5 LDX XC ; We just drew the image at (XC, YC), so decrement them DEX ; both so we can pass (XC, YC) to the DrawImageFrame STX XC ; routine to draw a frame around the image, with the LDX YC ; top-left corner one block up and left from the image DEX ; corner STX YC LDA #7 ; Set K = 7 to pass to the DrawImageFrame routine as the STA K ; frame width minus 1, so the frame is eight tiles wide, ; to cover the image which is six tiles wide LDA #10 ; Set K+1 = 10 to pass to the DrawImageFrame routine as STA K+1 ; the frame height, so the frame is ten tiles high, ; to cover the image which is eight tiles high JMP DrawImageFrame_b3 ; Call DrawImageFrame to draw a frame around the ; commander image, returning from the subroutine using a ; tail call
Name: DrawSpriteImage [Show more] Type: Subroutine Category: Drawing sprites Summary: Draw an image out of sprites using patterns in sequential tiles in the pattern buffer Deep dive: Sprite usage in NES Elite
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawSpriteImage_b6 calls DrawSpriteImage * DrawMedallion calls via DrawSpriteImage+2

Arguments: K The number of columns in the image (i.e. the number of tiles in each row of the image) K+1 The number of tile rows in the image K+2 The pattern number of the start of the image pattern data in the pattern table K+3 Number of the first free sprite in the sprite buffer, where we can build the sprites to make up the image XC The text column of the top-left corner of the image YC The text row of the top-left corner of the image X The pixel x-coordinate of the top-left corner of the image within the text block at (XC, YC) Y The pixel y-coordinate of the top-left corner of the image within the text block at (XC, YC)
Other entry points: DrawSpriteImage+2 Set the attributes for the sprites in the image to A
.DrawSpriteImage LDA #%00000001 ; Set S to use as the attribute for each of the sprites STA S ; in the image, so each sprite is set as follows: ; ; * Bits 0-1 = sprite palette 1 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA XC ; Set SC = XC * 8 + X ASL A ; = XC * 8 + 6 ASL A ; ASL A ; So SC is the pixel x-coordinate of the top-left corner ADC #0 ; of the image we want to draw, as each text character STA SC ; in XC is 8 pixels wide and X contains the x-coordinate TXA ; within the character block ADC SC STA SC LDA YC ; Set SC+1 = YC * 8 + 6 + Y ASL A ; = YC * 8 + 6 + 6 ASL A ; ASL A ; So SC+1 is the pixel y-coordinate of the top-left ADC #6+YPAL ; corner of the image we want to draw, as each text row STA SC+1 ; in YC is 8 pixels high and Y contains the y-coordinate TYA ; within the character block ADC SC+1 STA SC+1 LDA K+3 ; Set Y = K+3 * 4 ASL A ; ASL A ; So Y contains the offset of the first free sprite's TAY ; four-byte block in the sprite buffer, as each sprite ; consists of four bytes, so this is now the offset ; within the sprite buffer of the first sprite we can ; use to build the sprite image LDA K+2 ; Set A to the pattern number of the first tile in K+2 LDX K+1 ; Set T = K+1 to use as a counter for each row in the STX T ; image .drsi1 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDX SC ; Set SC2 to the pixel x-coordinate for the start of STX SC2 ; each row, so we can use it to move along the row as we ; draw the sprite image LDX K ; Set X to the number of tiles in each row of the image ; (in K), so we can use it as a counter as we move along ; the row .drsi2 LDA K+2 ; Set the pattern for sprite Y to K+2, which is the STA pattSprite0,Y ; pattern number in the PPU's pattern table to use for ; this part of the image LDA S ; Set the attributes for sprite Y to S, which we set STA attrSprite0,Y ; above as follows: ; ; * Bits 0-1 = sprite palette 1 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA SC2 ; Set the x-coordinate for sprite Y to SC2 STA xSprite0,Y CLC ; Set SC2 = SC2 + 8 ADC #8 ; STA SC2 ; So SC2 contains the x-coordinate of the next tile ; along the row LDA SC+1 ; Set the y-coordinate for sprite Y to SC+1 STA ySprite0,Y TYA ; Add 4 to the sprite number in Y, to move on to the CLC ; next sprite in the sprite buffer (as each sprite ADC #4 ; consists of four bytes of data) BCS drsi3 ; If the addition overflowed, then we have reached the ; end of the sprite buffer, so jump to drsi3 to return ; from the subroutine, as we have run out of sprites TAY ; Otherwise set Y to the offset of the next sprite in ; the sprite buffer INC K+2 ; Increment the tile counter in K+2 to point to the next ; pattern DEX ; Decrement the tile counter in X as we have just drawn ; a tile BNE drsi2 ; If X is non-zero then we still have more tiles to ; draw on the current row, so jump back to drsi2 to draw ; the next one LDA SC+1 ; Otherwise we have reached the end of this row, so add ADC #8 ; 8 to SC+1 to move the y-coordinate down to the next STA SC+1 ; tile row (as each tile row is 8 pixels high) DEC T ; Decrement the number of rows in T as we just finished ; drawing a row BNE drsi1 ; Loop back to drsi1 until we have drawn all the rows in ; the image .drsi3 RTS ; Return from the subroutine
Name: PauseGame [Show more] Type: Subroutine Category: Icon bar Summary: Pause the game and process choices from the pause menu until the game is unpaused by another press of Start
Context: See this subroutine on its own page References: This subroutine is called as follows: * PauseGame_b6 calls PauseGame

Returns: X X is preserved Y Y is preserved nmiTimer nmiTimer is preserved nmiTimerHi nmiTimerHi is preserved nmiTimerLo nmiTimerLo is preserved showIconBarPointer showIconBarPointer is preserved iconBarType iconBarType is preserved
.PauseGame TYA ; Store X and Y on the stack so we can retrieve them PHA ; below TXA PHA JSR WaitForNMI ; Wait until the next NMI interrupt has passed (i.e. the ; next VBlank) LDA nmiTimer ; Store nmiTimer and (nmiTimerHi nmiTimerLo) on the PHA ; stack so we can retrieve them below LDA nmiTimerLo PHA LDA nmiTimerHi PHA JSR WaitForPPUToFinish ; Wait until both bitplanes of the screen have been ; sent to the PPU, so the screen is fully updated and ; there is no more data waiting to be sent to the PPU LDA showIconBarPointer ; Store showIconBarPointer on the stack so we can PHA ; retrieve it below LDA iconBarType ; Store iconBarType on the stack so we can retrieve it PHA ; below LDA #$FF ; Set showIconBarPointer = $FF to indicate that we STA showIconBarPointer ; should show the icon bar pointer LDA #3 ; Show icon bar type 3 (Pause) on-screen JSR ShowIconBar_b3 .paug1 LDY #4 ; Wait until four NMI interrupts have passed (i.e. the JSR DELAY ; next four VBlanks) JSR SetKeyLogger_b6 ; Populate the key logger table with the controller ; button presses and return the button number in X ; if an icon bar button has been chosen TXA ; Set A to the button number if an icon bar button has ; been chosen CMP #80 ; If the Start button was pressed to pause the game then BNE paug2 ; A will be 80, so jump to paug2 to process choices from ; the pause menu ; Otherwise the Start button was pressed for a second ; time (which returns X = 0 from SetKeyLogger), so now ; we remove the pause menu PLA ; Retrieve iconBarType from the stack into A JSR ShowIconBar_b3 ; Show icon bar type A on-screen, so we redisplay the ; icon bar that was on the screen before the game was ; paused PLA ; Set showIconBarPointer to the value we stored on the STA showIconBarPointer ; stack above, so it is preserved JSR WaitForNMI ; Wait until the next NMI interrupt has passed (i.e. the ; next VBlank) PLA ; Set nmiTimer and (nmiTimerHi nmiTimerLo) to the values STA nmiTimerHi ; we stored on the stack above, so they are preserved PLA STA nmiTimerLo PLA STA nmiTimer PLA ; Set X and Y to the values we stored on the stack TAX ; above, so they are preserved PLA TAY RTS ; Return from the subroutine .paug2 ; If we get here then an icon bar button has been chosen ; and the button number is in A CMP #52 ; If the Sound toggle button was not chosen, jump to BNE paug3 ; paug3 to keep checking LDA DNOIZ ; The Sound toggle button was chosen, so flip the value EOR #$FF ; of DNOIZ to toggle between sound on and sound off STA DNOIZ JMP paug11 ; Jump to paug11 to update the icon bar and loop back to ; keep listening for button presses .paug3 CMP #51 ; If the Music toggle button was not chosen, jump to BNE paug6 ; paug6 to keep checking LDA disableMusic ; The Music toggle button was chosen, so flip the value EOR #$FF ; of disableMusic to toggle between music on and music STA disableMusic ; off BPL paug4 ; If the toggle was flipped to 0, then music is enabled ; so jump to paug4 to start the music playing (if a tune ; is configured) JSR StopSounds_b6 ; Otherwise music has just been enabled, so call ; StopSounds to stop any sounds that are being made ; (music or sound effects) JMP paug11 ; Jump to paug11 to update the icon bar and loop back to ; keep listening for button presses .paug4 ; If we get here then music was just enabled LDA newTune ; If newTune = 0 then no tune is configured to play, so BEQ paug5 ; jump to paug5 to skip the following AND #%01111111 ; Clear bit 7 of newTune to extract the tune number that ; is configured to play JSR ChooseMusic_b6 ; Call ChooseMusic to start playing the tune in A .paug5 JMP paug11 ; Jump to paug11 to update the icon bar and loop back to ; keep listening for button presses .paug6 CMP #60 ; If the Restart button was not chosen, jump to paug7 BNE paug7 ; The Restart button was just chosen, so we now restart ; the game PLA ; Retrieve iconBarType from the stack into A (and ignore ; it) PLA ; Set showIconBarPointer to the value we stored on the STA showIconBarPointer ; stack above, so it is preserved JMP DEATH2_b0 ; Jump to DEATH2 to restart the game (which also resets ; the stack pointer, so we can ignore all the other ; values that we put on the stack above) .paug7 CMP #53 ; If the Number of Pilots button was not chosen, jump BNE paug8 ; to paug8 to keep checking LDA numberOfPilots ; The Number of Pilots button was chosen, so flip the EOR #1 ; value of numberOfPilots between 0 and 1 to change the STA numberOfPilots ; number of pilots between 1 and 2 JMP paug11 ; Jump to paug11 to update the icon bar and loop back to ; keep listening for button presses .paug8 CMP #49 ; If the "Direction of y-axis" toggle button was not BNE paug9 ; chosen, jump to paug9 to keep checking LDA JSTGY ; The "Direction of y-axis" toggle button was chosen, so EOR #$FF ; flip the value of JSTGY to toggle the direction of the STA JSTGY ; controller y-axis JMP paug11 ; Jump to paug11 to update the icon bar and loop back to ; keep listening for button presses .paug9 CMP #50 ; If the Damping toggle button was not chosen, jump to BNE paug10 ; paug10 to keep checking LDA DAMP ; The Damping toggle button was chosen, so flip the EOR #$FF ; value of DAMP to toggle between damping on and damping STA DAMP ; off JMP paug11 ; Jump to paug11 to update the icon bar and loop back to ; keep listening for button presses .paug10 JMP paug1 ; Jump back to paug1 to keep listening for button ; presses .paug11 JSR UpdateIconBar_b3 ; Update the icon bar to show updated icons for any ; changed options JMP paug1 ; Jump back to paug1 to keep listening for button ; presses
Name: DILX [Show more] Type: Subroutine Category: Dashboard Summary: Update a bar-based indicator on the dashboard
Context: See this subroutine on its own page References: This subroutine is called as follows: * DIALS calls DILX * DIALS calls via DILX+2

The range of values shown on the indicator depends on which entry point is called. For the default entry point of DILX, the range is 0-255 (as the value passed in A is one byte). The other entry points are shown below. This routine does a similar job to the routine of the same name in the BBC Master version of Elite, but the code is significantly different.
Arguments: A The value to be shown on the indicator (so the larger the value, the longer the bar) SC(1 0) The address of the tile at the left end of the indicator in nametable buffer 0 K The lower end of the safe range, so safe values are in the range K <= A < K+1 (and other values are dangerous) K+1 The upper end of the safe range, so safe values are in the range K <= A < K+1 (and other values are dangerous)
Returns: SC(1 0) The address of the tile at the left end of the next indicator down
Other entry points: DILX+2 The range of the indicator is 0-64 (for the fuel and speed indicators)
.DILX LSR A ; If we call DILX, we set A = A / 16, so A is 0-31 LSR A LSR A ; If we call DILX+2, we set A = A / 4, so A is 0-31 CMP #31 ; If A < 31 then jump to dilx1 to skip the following BCC dilx1 ; instruction LDA #30 ; Set A = 30, so the maximum value of the value to show ; on the indicator in A is 30 .dilx1 LDY #0 ; We are going to draw the indicator as a row of tiles, ; so set an index in Y to count the tiles as we work ; from left to right CMP K ; If A < K then this value is lower than the lower end BCC dilx8 ; of the safe range, so jump to dilx8 to flash the ; indicator bar between colour 4 and colour 2, to ; indicate a dangerous value CMP K+1 ; If A >= K+1 then this value is higher than the upper BCS dilx8 ; end of the safe range, so jump to dilx8 to draw the ; indicator bar between colour 4 and colour 2, to ; indicate a dangerous value STA Q ; Store the value we want to draw on the indicator in Q .dilx2 LSR A ; Set A = A / 8 LSR A ; LSR A ; Each indicator consists of four tiles that we use to ; show a value from 0 to 30, so this gives us the number ; of sections we need to fill with a full bar (in the ; range 0 to 3, as A is in the range 0 to 30) BEQ dilx4 ; If the result is 0 then the value is too low to need ; any full bars, so jump to dilx4 to draw the end cap of ; the indicator bar and any blank space to the right TAX ; Set X to the number of sections that we need to fill ; with a full bar, so we can use it as a loop counter to ; draw the correct number of full bars LDA #236 ; Set A = 236, which is the pattern number of the fully ; filled bar in colour 4 (for a safe value) .dilx3 STA (SC),Y ; Set the Y-th tile of the indicator to A to show a full ; bar INY ; Increment the tile number in Y to move to the next ; tile in the indicator DEX ; Decrement the loop counter in X BNE dilx3 ; Loop back until we have drawn the correct number of ; full bars .dilx4 ; We now draw the correct end cap on the right end of ; the indicator bar LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above AND #7 ; Set A = A mod 8, which gives us the remaining value ; once we've taken off any fully filled tiles (as each ; of the four tiles that make up the indicator ; represents a value of 8) CLC ; Set A = A + 237 ADC #237 ; ; The eight patterns from 237 to 244 contain the end cap ; patterns in colour 4 (for a safe value), ranging ; from the smallest cap to the largest, so this sets A ; to the correct pattern number to use as the end cap ; for displaying the remainder in A STA (SC),Y ; Set the Y-th tile of the indicator to A to show the ; end cap INY ; Increment the tile number in Y to move to the next ; tile in the indicator ; We now fill the rest of the four tiles with a blank ; indicator tile, if required LDA #85 ; Set A = 85, which is the pattern number of an empty ; tile in an indicator .dilx5 CPY #4 ; If Y = 4 then we have just drawn the last tile in BEQ dilx6 ; the indicator, so jump to dilx6 to finish off, as we ; have now drawn the entire indicator STA (SC),Y ; Otherwise set the Y-th tile of the indicator to A to ; fill the space to the right of the indicator bar with ; the blank indicator pattern INY ; Increment the tile number in Y to move to the next ; tile in the indicator BNE dilx5 ; Loop back to dilx5 to draw the next tile (this BNE is ; effectively a JMP as Y won't ever wrap around to 0) .dilx6 LDA SC ; Set SC(1 0) = SC(1 0) + 32 CLC ; ADC #32 ; Starting with the low bytes STA SC BCC dilx7 ; And then the high bytes INC SC+1 ; ; This points SC(1 0) to the nametable entry for the ; next indicator on the row below, as there are 32 tiles ; in each row .dilx7 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 RTS ; Return from the subroutine .dilx8 STA Q ; Store the value we want to draw on the indicator in Q LDA MCNT ; Fetch the main loop counter and jump to dilx10 if bit AND #%00001000 ; 3 is set, which will be true half of the time, with BNE dilx10 ; the bit being 0 for eight iterations around the main ; loop, and 1 for the next eight iterations ; ; If we jump to dilx10 then the indicator is shown in ; red, and if we don't jump it is shown in the normal ; colour, so this flashes the indicator bar between red ; and the normal colour, changing the colour every eight ; iterations of the main loop LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above JMP dilx2 ; Jump back to dilx2 to draw the indicator in the normal ; colour scheme LDY #0 ; These instructions are never run and have no effect BEQ dilx13 .dilx10 ; If we get here then we show the indicator in red LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above LSR A ; Set A = A / 8 LSR A ; LSR A ; Each indicator consists of four tiles that we use to ; show a value from 0 to 30, so this gives us the number ; of sections we need to fill with a full bar (in the ; range 0 to 3, as A is in the range 0 to 30) BEQ dilx12 ; If the result is 0 then the value is too low to need ; any full bars, so jump to dilx12 to draw the end cap ; of the indicator bar and any blank space to the right TAX ; Set X to the number of sections that we need to fill ; with a full bar, so we can use it as a loop counter to ; draw the correct number of full bars LDA #227 ; Set A = 237, which is the pattern number of the fully ; filled bar in colour 2 (for a dangerous value) .dilx11 STA (SC),Y ; Set the Y-th tile of the indicator to A to show a full ; bar INY ; Increment the tile number in Y to move to the next ; tile in the indicator DEX ; Decrement the loop counter in X BNE dilx11 ; Loop back until we have drawn the correct number of ; full bars .dilx12 ; We now draw the correct end cap on the right end of ; the indicator bar LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above AND #7 ; Set A = A mod 8, which gives us the remaining value ; once we've taken off any fully filled tiles (as each ; of the four tiles that make up the indicator ; represents a value of 8) CLC ; Set A = A + 228 ADC #228 ; ; The eight patterns from 228 to 235 contain the end cap ; patterns in colour 2 (for a dangerous value), ranging ; from the smallest cap to the largest, so this sets A ; to the correct pattern number to use as the end cap ; for displaying the remainder in A STA (SC),Y ; Set the Y-th tile of the indicator to A to show the ; end cap INY ; Increment the tile number in Y to move to the next ; tile in the indicator .dilx13 ; We now fill the rest of the four tiles with a blank ; indicator tile, if required LDA #85 ; Set A = 85, which is the pattern number of an empty ; tile in an indicator .dilx14 CPY #4 ; If Y = 4 then we have just drawn the last tile in BEQ dilx15 ; the indicator, so jump to dilx6 to finish off, as we ; have now drawn the entire indicator STA (SC),Y ; Otherwise set the Y-th tile of the indicator to A to ; fill the space to the right of the indicator bar with ; the blank indicator pattern INY ; Increment the tile number in Y to move to the next ; tile in the indicator BNE dilx14 ; Loop back to dilx14 to draw the next tile (this BNE is ; effectively a JMP as Y won't ever wrap around to 0) .dilx15 LDA SC ; Set SC(1 0) = SC(1 0) + 32 CLC ; ADC #32 ; Starting with the low bytes STA SC BCC dilx16 ; And then the high bytes INC SC+1 ; ; This points SC(1 0) to the nametable entry for the ; next indicator on the row below, as there are 32 tiles ; in each row .dilx16 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 RTS ; Return from the subroutine
Name: DIALS [Show more] Type: Subroutine Category: Dashboard Summary: Update the dashboard Deep dive: Sprite usage in NES Elite
Context: See this subroutine on its own page References: This subroutine is called as follows: * DIALS_b6 calls DIALS

This routine does a similar job to the routine of the same name in the BBC Master version of Elite, but the code is significantly different.
.DIALS LDA drawingBitplane ; If the drawing bitplane is 1, jump to dial1 so we only BNE dial1 ; update the bar indicators every other frame, to save ; time LDA #HI(nameBuffer0+23*32+2) ; Set SC(1 0) to the address of the third tile STA SC+1 ; on tile row 23 in nametable buffer 0, which is LDA #LO(nameBuffer0+23*32+2) ; the leftmost tile in the fuel indicator at the STA SC ; top-left corner of the dashboard LDA #0 ; Set the indicator's safe range from 0 to 255 by STA K ; setting K to 0 and K+1 to 255, so all values are safe LDA #255 STA K+1 LDA QQ14 ; Draw the fuel level indicator using a range of 0-63, JSR DILX+2 ; and increment SC to point to the next indicator (the ; forward shield) LDA #8 ; Set the indicator's safe range from 8 to 255 by STA K ; setting K to 8 and K+1 to 255, so all values are safe LDA #255 ; except those below 8, which are dangerous STA K+1 LDA FSH ; Draw the forward shield indicator using a range of JSR DILX ; 0-255, and increment SC to point to the next indicator ; (the aft shield) LDA ASH ; Draw the aft shield indicator using a range of 0-255, JSR DILX ; and increment SC to point to the next indicator (the ; energy banks) LDA ENERGY ; Draw the energy bank indicator using a range of 0-255, JSR DILX ; and increment SC to point to the next indicator (the ; cabin temperature) LDA #0 ; Set the indicator's safe range from 0 to 23 by STA K ; setting K to 0 and K+1 to 24, so values from 0 to 23 LDA #24 ; are safe, while values of 24 or more are dangerous STA K+1 LDA CABTMP ; Draw the cabin temperature indicator using a range of JSR DILX ; 0-255, and increment SC to point to the next indicator ; (the laser temperature) LDA GNTMP ; Draw the laser temperature indicator using a range of JSR DILX ; 0-255 LDA #HI(nameBuffer0+27*32+28) ; Set SC(1 0) to the address of the 28th tile STA SC+1 ; on tile row 27 in nametable buffer 0, which is LDA #LO(nameBuffer0+27*32+28) ; the leftmost tile in the speed indicator in STA SC ; the bottom-right corner of the dashboard LDA #0 ; Set the indicator's safe range from 0 to 255 by STA K ; setting K to 0 and K+1 to 255, so all values are safe LDA #255 STA K+1 LDA DELTA ; Fetch our ship's speed into A, in the range 0-40 LSR A ; Set A = A / 2 + DELTA ADC DELTA ; = 1.5 * DELTA JSR DILX+2 ; Draw the speed level indicator using a range of 0-63, ; and increment SC to point to the next indicator ; (altitude) LDA #8 ; Set the indicator's safe range from 8 to 255 by STA K ; setting K to 8 and K+1 to 255, so all values are safe LDA #255 ; except those below 8, which are dangerous STA K+1 LDA ALTIT ; Draw the altitude indicator using a range of 0-255 JSR DILX .dial1 ; We now set up sprite 10 to use for the ship status ; indicator LDA #186+YPAL ; Set the y-coordinate of sprite 10 to 186 STA ySprite10 LDA #206 ; Set the x-coordinate of sprite 10 to 206 STA xSprite10 JSR GetStatusCondition ; Set X to our ship's status condition (0 to 3) LDA conditionAttrs,X ; Set the sprite's attributes to the corresponding STA attrSprite10 ; entry from the conditionAttrs table, so the correct ; colour is set for the ship's status condition LDA conditionPatts,X ; Set the pattern to the corresponding entry from the STA pattSprite10 ; conditionPatts table, so the correct pattern is used ; for the ship's status condition ; And finally we update the active missile indicator ; and the square targeting reticle LDA QQ12 ; If we are docked then QQ12 is non-zero, so jump to BNE dial2 ; dial2 to hide the square targeting reticle in sprite 9 LDA MSTG ; If MSTG does not contain $FF then the active missile BPL dial4 ; has a target lock (and MSTG contains a slot number), ; so jump to dial4 to show the square targeting reticle ; in the middle of the laser sights LDA MSAR ; If MSAR = 0 then the missile is not looking for a BEQ dial2 ; target, so jump to dial2 to hide the square targeting ; reticle in sprite 9 ; We now flash the active missile indicator between ; black and red, and flash the square targeting reticle ; in sprite 9 on and off, to indicate that the missile ; is searching for a target LDX NOMSL ; Fetch the current number of missiles from NOMSL into X ; (which is also the number of the active missile) LDY #109 ; Set Y = 109 to use as the pattern for the red missile ; indicator LDA MCNT ; Fetch the main loop counter and jump to dial3 if bit 3 AND #%00001000 ; is set, which will be true half of the time, with the BNE dial3 ; bit being 0 for eight iterations around the main loop, ; and 1 for the next eight iterations ; ; If we jump to dial3 then the indicator is shown in ; red, and if we don't jump it is shown in black, so ; this flashes the missile indicator between red and ; black, changing the colour every eight iterations of ; the main loop LDY #108 ; Set the pattern for the missile indicator at position JSR MSBAR_b6 ; X to 108, which is a black indicator .dial2 LDA #240 ; Hide sprite 9 (the square targeting reticle) by moving STA ySprite9 ; sprite 9 to y-coordinate 240, off the bottom of the ; screen RTS ; Return from the subroutine .dial3 JSR MSBAR_b6 ; Set the pattern for the missile indicator at position ; X to pattern Y, which we set to 109 above, so this ; sets the indicator to red .dial4 ; If we get here then our missile is targeted, so show ; the square targeting reticle in the middle of the ; laser sights LDA #248 ; Set the pattern for sprite 9 to 248, which is a square STA pattSprite9 ; outline LDA #%00000001 ; Set the attributes for sprite 9 as follows: STA attrSprite9 ; ; * Bits 0-1 = sprite palette 1 ; * Bit 5 clear = show in front of background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically LDA #126 ; Set the x-coordinate for sprite 9 to 126 STA xSprite9 LDA #83+YPAL ; Set the y-coordinate for sprite 9 to 126 STA ySprite9 RTS ; Return from the subroutine
Name: conditionAttrs [Show more] Type: Variable Category: Dashboard Summary: Sprite attributes for the status condition indicator on the dashboard
Context: See this variable on its own page References: This variable is used as follows: * DIALS uses conditionAttrs
.conditionAttrs EQUB %00100001 ; Attributes for sprite when condition is docked: ; ; * Bits 0-1 = sprite palette 1 ; * Bit 5 set = show behind background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically EQUB %00100000 ; Attributes for sprite when condition is green: ; ; * Bits 0-1 = sprite palette 0 ; * Bit 5 set = show behind background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically EQUB %00100010 ; Attributes for sprite when condition is yellow ; ; * Bits 0-1 = sprite palette 2 ; * Bit 5 set = show behind background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically EQUB %00100010 ; Attributes for sprite when condition is red ; ; * Bits 0-1 = sprite palette 2 ; * Bit 5 set = show behind background ; * Bit 6 clear = do not flip horizontally ; * Bit 7 clear = do not flip vertically
Name: conditionPatts [Show more] Type: Variable Category: Dashboard Summary: Pattern numbers for the status condition indicator on the dashboard
Context: See this variable on its own page References: This variable is used as follows: * DIALS uses conditionPatts
.conditionPatts EQUB 249 ; Docked EQUB 250 ; Green EQUB 250 ; Yellow EQUB 249 ; Red
Name: MSBAR_b6 [Show more] Type: Subroutine Category: Dashboard Summary: Draw a specific indicator in the dashboard's missile bar
Context: See this subroutine on its own page References: This subroutine is called as follows: * DIALS calls MSBAR_b6

Arguments: X The number of the missile indicator to update (counting from bottom-right to bottom-left, then top-left and top-right, so indicator NOMSL is the top-right indicator) Y The pattern number for the new missile indicator: * 133 = no missile indicator * 109 = red (armed and locked) * 108 = black (disarmed) The armed missile flashes black and red, so the tile is swapped between 108 and 109 in the main loop
Returns: X X is preserved Y Y is set to 0
.MSBAR_b6 TYA ; Store the pattern number on the stack so we can PHA ; retrieve it later LDY missileNames_b6,X ; Set Y to the X-th entry from the missileNames table, ; so Y is the offset of missile X's indicator in the ; nametable buffer, from the start of row 22 PLA ; Set the nametable buffer entry to the pattern number STA nameBuffer0+22*32,Y LDY #0 ; Set Y = 0 to return from the subroutine (so this ; routine behaves like the same routine in the other ; versions of Elite) RTS ; Return from the subroutine
Name: missileNames_b6 [Show more] Type: Variable Category: Dashboard Summary: Tile numbers for the four missile indicators on the dashboard, as offsets from the start of tile row 22
Context: See this variable on its own page References: This variable is used as follows: * MSBAR_b6 uses missileNames_b6

The active missile (i.e. the one that is armed and fired first) is the one with the highest number, so missile 4 (top-left) will be armed before missile 3 (top-right), and so on.
.missileNames_b6 EQUB 0 ; Missile numbers are from 1 to 4, so this value is ; never used EQUB 95 ; Missile 1 (bottom-right) EQUB 94 ; Missile 2 (bottom-left) EQUB 63 ; Missile 3 (top-right) EQUB 62 ; Missile 4 (top-left)
Name: SetEquipmentSprite [Show more] Type: Subroutine Category: Equipment Summary: Set up the sprites in the sprite buffer for a specific bit of equipment to show on our Cobra Mk III on the Equip Ship screen
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawEquipment calls SetEquipmentSprite

Arguments: X The number of sprites to set up for the equipment Y The offset into the equipSprites table where we can find the data for the first sprite to set up for this piece of equipment (i.e. the equipment sprite number * 4)
.SetEquipmentSprite LDA #0 ; Set A = 0 to set as the laser offset in SetLaserSprite ; so we just draw the equipment's sprites ; Fall through into SetLaserSprite to draw the sprites ; for the equipment specified in Y
Name: SetLaserSprite [Show more] Type: Subroutine Category: Equipment Summary: Set up the sprites in the sprite buffer for a specific laser to show on our Cobra Mk III on the Equip Ship screen
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawEquipment calls SetLaserSprite

Arguments: A The pattern number for the first sprite for this type of laser, minus 0: * 0 (for pattern 140) for the mining laser * 4 (for pattern 144) for the beam laser * 8 (for pattern 148) for the pulse laser * 12 (for pattern 152) for the military laser This routine is used to set up equipment sprites for all types of equipment, so this should be set to 0 for setting up non-laser sprites X The number of sprites to set up for the equipment Y The offset into the equipSprites table where we can find the data for the first sprite to set up for this piece of equipment (i.e. the equipment sprite number * 4)
.SetLaserSprite STA V ; Set V to the sprite offset (which is only used for ; laser sprites) STX V+1 ; Set V+1 to the number of sprites to set up .slas1 LDA equipSprites+3,Y ; Extract the offset into the sprite buffer of the AND #%11111100 ; sprite we need to set up, which is in bits 2 to 7 of TAX ; byte #3 for this piece of equipment in the ; equipSprites table, and store it in X ; ; Because bits 0 and 1 are cleared, the offset is a ; multiple of four, which means we can use X as an ; index into the sprite buffer as each sprite in the ; sprite buffer takes up four bytes ; ; In other words, to set up this sprite in the sprite ; buffer, we need to write the sprite's configuration ; into xSprite0 + X, ySprite0 + X, pattSprite0 + X and ; attrSprite0 + X LDA equipSprites+3,Y ; Extract the palette number to use for this sprite, AND #%00000011 ; which is in bits 0 to 1 of byte #3 for this piece of STA T ; equipment in the equipSprites table LDA equipSprites,Y ; Extract the vertical and horizontal flip flags from AND #%11000000 ; bits 7 and 6 of byte #0 for this piece of equipment ; in the equipSprites table, into A ORA T ; Set bits 0 and 1 of A to the palette number that we ; extracted into T above STA attrSprite0,X ; Set the attributes for our sprite as follows: ; ; * Bits 0-1 = sprite palette in T ; * Bit 5 clear = show in front of background ; * Bit 6 = bit 6 from byte #3 in equipSprites ; * Bit 7 = bit 7 from byte #3 in equipSprites ; ; So the sprite's attributes are set correctly LDA equipSprites,Y ; Extract the sprite's pattern number from bits 0 to 5 AND #%00111111 ; of byte #0 for this piece of equipment in the CLC ; equipSprites table and add 140 ADC #140 ADC V ; If this is a laser sprite then V will be the offset ; that we add to 140 to get the correct pattern for the ; specific laser type, so we also add this to A (if this ; is not a laser then V will be 0) STA pattSprite0,X ; Set the pattern number for our sprite to the result ; in A LDA equipSprites+1,Y ; Set our sprite's x-coordinate to byte #1 for this STA xSprite0,X ; piece of equipment in the equipSprites table LDA equipSprites+2,Y ; Set our sprite's y-coordinate to byte #2 for this STA ySprite0,X ; piece of equipment in the equipSprites table INY ; Increment the index in Y to point to the next entry INY ; in the equipSprites table, in case there are any more INY ; sprites to set up INY DEC V+1 ; Decrement the sprite counter in V+1 BNE slas1 ; Loop back to set up the next sprite until we have set ; up V+1 sprites for this piece of equipment RTS ; Return from the subroutine
Name: GetLaserPattern [Show more] Type: Subroutine Category: Equipment Summary: Get the pattern number for a specific laser's equipment sprite
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawEquipment calls GetLaserPattern

Arguments: X The laser power
Returns: A The pattern number for the first sprite for this type of laser, minus 140, so we return: * 0 (for pattern 140) for the mining laser * 4 (for pattern 144) for the beam laser * 8 (for pattern 148) for the pulse laser * 12 (for pattern 152) for the military laser
.GetLaserPattern LDA #0 ; Set A to the return value for pattern 140 (for the ; mining laser) CPX #Armlas ; If the laser power in X is equal to a military laser, BEQ glsp3 ; jump to glsp3 to the return value for pattern 152 CPX #POW+128 ; If the laser power in X is equal to a beam laser, BEQ glsp2 ; jump to glsp2 to the return value for pattern 144 CPX #Mlas ; If the laser power in X is equal to a mining laser, BNE glsp1 ; jump to glsp2 to the return value for pattern 140 LDA #8 ; If we get here then this must be a pulse laser, so ; set A to the return value for pattern 148 .glsp1 RTS ; Return from the subroutine .glsp2 LDA #4 ; This is a beam laser, so set A to the return value for ; pattern 145 RTS ; Return from the subroutine .glsp3 LDA #12 ; This is a military laser, so set A to the return value ; for pattern 152 RTS ; Return from the subroutine
Name: equipSprites [Show more] Type: Variable Category: Equipment Summary: Sprite configuration data for the sprites that show the equipment fitted to our Cobra Mk III on the Equip Ship screen Deep dive: Sprite usage in NES Elite
Context: See this variable on its own page References: This variable is used as follows: * SetLaserSprite uses equipSprites

Each equipment sprite is described by four entries in the table, as follows: * Byte #0: %vhyyyyyy, where: * %v is the vertical flip flag (0 = no flip, 1 = flip vertically) * %h is the horizontal flip flag (0 = no flip, 1 = flip horizontally) * %yyyyyy is the sprite's pattern number, which is added to 140 to give the final pattern number * Byte #1: Pixel x-coordinate of the sprite's position on the Cobra Mk III * Byte #2: Pixel y-coordinate of the sprite's position on the Cobra Mk III * Byte #3: %xxxxxxyy, where: * %xxxxxx00 is the offset of the sprite to use in the sprite buffer * %yy is the sprite palette (0 to 3)
.equipSprites ; Equipment sprite 0: E.C.M. (1 of 3) EQUB %00011111 ; v = 0, h = 0, pattern = 31 EQUB 85 ; x-coordinate = 85 EQUB 182 + YPAL ; y-coordinate = 182 EQUB %00010100 ; sprite number = 5, sprite palette = 0 ; Equipment sprite 1: E.C.M. (2 of 3) EQUB %00100000 ; v = 0, h = 0, pattern = 32 EQUB 156 ; x-coordinate = 156 EQUB 156 + YPAL ; y-coordinate = 156 EQUB %00011000 ; sprite number = 6, sprite palette = 0 ; Equipment sprite 2: E.C.M. (3 of 3) EQUB %00100001 ; v = 0, h = 0, pattern = 33 EQUB 156 ; x-coordinate = 156 EQUB 164 + YPAL ; y-coordinate = 164 EQUB %00011100 ; sprite number = 7, sprite palette = 0 ; Equipment sprite 3: Front laser (1 of 2) EQUB %00000111 ; v = 0, h = 0, pattern = 7 EQUB 68 ; x-coordinate = 68 EQUB 161 + YPAL ; y-coordinate = 161 EQUB %00100000 ; sprite number = 8, sprite palette = 0 ; Equipment sprite 4: Front laser (2 of 2) EQUB %00001010 ; v = 0, h = 0, pattern = 10 EQUB 171 ; x-coordinate = 171 EQUB 172 + YPAL ; y-coordinate = 172 EQUB %00100100 ; sprite number = 9, sprite palette = 0 ; Equipment sprite 5: Left laser (1 of 2), non-military EQUB %00001001 ; v = 0, h = 0, pattern = 9 EQUB 20 ; x-coordinate = 20 EQUB 198 + YPAL ; y-coordinate = 198 EQUB %00101000 ; sprite number = 10, sprite palette = 0 ; Equipment sprite 6: Left laser (2 of 2), non-military EQUB %00001001 ; v = 0, h = 0, pattern = 9 EQUB 124 ; x-coordinate = 124 EQUB 170 + YPAL ; y-coordinate = 170 EQUB %00101100 ; sprite number = 11, sprite palette = 0 ; Equipment sprite 7: Right laser (1 of 2), non-military EQUB %01001001 ; v = 0, h = 1, pattern = 9 EQUB 116 ; x-coordinate = 116 EQUB 198 + YPAL ; y-coordinate = 198 EQUB %00110000 ; sprite number = 12, sprite palette = 0 ; Equipment sprite 8: Right laser (2 of 2), non-military EQUB %01001001 ; v = 0, h = 1, pattern = 9 EQUB 220 ; x-coordinate = 220 EQUB 170 + YPAL ; y-coordinate = 170 EQUB %00110100 ; sprite number = 13, sprite palette = 0 ; Equipment sprite 9: Rear laser (1 of 1) EQUB %10000111 ; v = 1, h = 0, pattern = 7 EQUB 68 ; x-coordinate = 68 EQUB 206 + YPAL ; y-coordinate = 206 EQUB %01110100 ; sprite number = 29, sprite palette = 0 ; Equipment sprite 10: Left military laser (1 of 2) EQUB %00010101 ; v = 0, h = 0, pattern = 21 EQUB 16 ; x-coordinate = 16 EQUB 198 + YPAL ; y-coordinate = 198 EQUB %00101000 ; sprite number = 10, sprite palette = 0 ; Equipment sprite 11: Left military laser (2 of 2) EQUB %00010101 ; v = 0, h = 0, pattern = 21 EQUB 121 ; x-coordinate = 121 EQUB 170 + YPAL ; y-coordinate = 170 EQUB %00101100 ; sprite number = 11, sprite palette = 0 ; Equipment sprite 12: Right military laser (1 of 2) EQUB %01010101 ; v = 0, h = 1, pattern = 21 EQUB 118 ; x-coordinate = 118 EQUB 198 + YPAL ; y-coordinate = 198 EQUB %00110000 ; sprite number = 12, sprite palette = 0 ; Equipment sprite 13: Right military laser (2 of 2) EQUB %01010101 ; v = 0, h = 1, pattern = 21 EQUB 222 ; x-coordinate = 222 EQUB 170 + YPAL ; y-coordinate = 170 EQUB %00110100 ; sprite number = 13, sprite palette = 0 ; Equipment sprite 14: Fuel scoops (1 of 2) EQUB %00011110 ; v = 0, h = 0, pattern = 30 EQUB 167 ; x-coordinate = 167 EQUB 185 + YPAL ; y-coordinate = 185 EQUB %00111101 ; sprite number = 15, sprite palette = 1 ; Equipment sprite 15: Fuel scoops (2 of 2) EQUB %01011110 ; v = 0, h = 1, pattern = 30 EQUB 175 ; x-coordinate = 175 EQUB 185 + YPAL ; y-coordinate = 185 EQUB %01000001 ; sprite number = 16, sprite palette = 1 ; Equipment sprite 16: Naval energy unit (1 of 2) EQUB %00011010 ; v = 0, h = 0, pattern = 26 EQUB 79 ; x-coordinate = 79 EQUB 196 + YPAL ; y-coordinate = 196 EQUB %10101100 ; sprite number = 43, sprite palette = 0 ; Equipment sprite 17: Naval energy unit (2 of 2) EQUB %00011011 ; v = 0, h = 0, pattern = 27 EQUB 79 ; x-coordinate = 79 EQUB 196 + YPAL ; y-coordinate = 196 EQUB %10110001 ; sprite number = 44, sprite palette = 1 ; Equipment sprite 18: Standard energy unit (1 of 2) EQUB %00011010 ; v = 0, h = 0, pattern = 26 EQUB 56 ; x-coordinate = 56 EQUB 196 + YPAL ; y-coordinate = 196 EQUB %01000100 ; sprite number = 17, sprite palette = 0 ; Equipment sprite 19: Standard energy unit (2 of 2) EQUB %00011011 ; v = 0, h = 0, pattern = 27 EQUB 56 ; x-coordinate = 56 EQUB 196 + YPAL ; y-coordinate = 196 EQUB %01001001 ; sprite number = 18, sprite palette = 1 ; Equipment sprite 20: Missile 1 (1 of 2) EQUB %00000000 ; v = 0, h = 0, pattern = 0 EQUB 29 ; x-coordinate = 29 EQUB 187 + YPAL ; y-coordinate = 187 EQUB %01001101 ; sprite number = 19, sprite palette = 1 ; Equipment sprite 21: Missile 1 (2 of 2) EQUB %00000001 ; v = 0, h = 0, pattern = 1 EQUB 208 ; x-coordinate = 208 EQUB 176 + YPAL ; y-coordinate = 176 EQUB %01010001 ; sprite number = 20, sprite palette = 1 ; Equipment sprite 22: Missile 2 (1 of 2) EQUB %01000000 ; v = 0, h = 1, pattern = 0 EQUB 108 ; x-coordinate = 108 EQUB 187 + YPAL ; y-coordinate = 187 EQUB %01010101 ; sprite number = 21, sprite palette = 1 ; Equipment sprite 23: Missile 2 (2 of 2) EQUB %01000001 ; v = 0, h = 1, pattern = 1 EQUB 136 ; x-coordinate = 136 EQUB 176 + YPAL ; y-coordinate = 176 EQUB %01011001 ; sprite number = 22, sprite palette = 1 ; Equipment sprite 24: Missile 3 (1 of 2) EQUB %00000000 ; v = 0, h = 0, pattern = 0 EQUB 22 ; x-coordinate = 22 EQUB 192 + YPAL ; y-coordinate = 192 EQUB %01011101 ; sprite number = 23, sprite palette = 1 ; Equipment sprite 25: Missile 3 (2 of 2) EQUB %00000001 ; v = 0, h = 0, pattern = 1 EQUB 214 ; x-coordinate = 214 EQUB 175 + YPAL ; y-coordinate = 175 EQUB %01100001 ; sprite number = 24, sprite palette = 1 ; Equipment sprite 26: Missile 4 (1 of 2) EQUB %01000000 ; v = 0, h = 1, pattern = 0 EQUB 115 ; x-coordinate = 115 EQUB 192 + YPAL ; y-coordinate = 192 EQUB %01100101 ; sprite number = 25, sprite palette = 1 ; Equipment sprite 27: Missile 4 (2 of 2) EQUB %01000001 ; v = 0, h = 1, pattern = 1 EQUB 130 ; x-coordinate = 130 EQUB 175 + YPAL ; y-coordinate = 175 EQUB %01101001 ; sprite number = 26, sprite palette = 1 ; Equipment sprite 28: Energy bomb (1 of 3) EQUB %00010111 ; v = 0, h = 0, pattern = 23 EQUB 64 ; x-coordinate = 64 EQUB 206 + YPAL ; y-coordinate = 206 EQUB %01101100 ; sprite number = 27, sprite palette = 0 ; Equipment sprite 29: Energy bomb (2 of 3) EQUB %00011000 ; v = 0, h = 0, pattern = 24 EQUB 72 ; x-coordinate = 72 EQUB 206 + YPAL ; y-coordinate = 206 EQUB %01110000 ; sprite number = 28, sprite palette = 0 ; Equipment sprite 30: Energy bomb (3 of 3) EQUB %00011001 ; v = 0, h = 0, pattern = 25 EQUB 68 ; x-coordinate = 68 EQUB 206 + YPAL ; y-coordinate = 206 EQUB %00111010 ; sprite number = 14, sprite palette = 2 ; Equipment sprite 31: Large cargo bay (1 of 2) EQUB %00000010 ; v = 0, h = 0, pattern = 2 EQUB 153 ; x-coordinate = 153 EQUB 184 + YPAL ; y-coordinate = 184 EQUB %01111000 ; sprite number = 30, sprite palette = 0 ; Equipment sprite 32: Large cargo bay (2 of 2) EQUB %01000010 ; v = 0, h = 1, pattern = 2 EQUB 188 ; x-coordinate = 188 EQUB 184 + YPAL ; y-coordinate = 184 EQUB %01111100 ; sprite number = 31, sprite palette = 0 ; Equipment sprite 33: Escape pod (1 of 1) EQUB %00011100 ; v = 0, h = 0, pattern = 28 EQUB 79 ; x-coordinate = 79 EQUB 178 + YPAL ; y-coordinate = 178 EQUB %10000000 ; sprite number = 32, sprite palette = 0 ; Equipment sprite 34: Docking computer (1 of 8) EQUB %00000011 ; v = 0, h = 0, pattern = 3 EQUB 52 ; x-coordinate = 52 EQUB 172 + YPAL ; y-coordinate = 172 EQUB %10000100 ; sprite number = 33, sprite palette = 0 ; Equipment sprite 35: Docking computer (2 of 8) EQUB %00000100 ; v = 0, h = 0, pattern = 4 EQUB 60 ; x-coordinate = 60 EQUB 172 + YPAL ; y-coordinate = 172 EQUB %10001000 ; sprite number = 34, sprite palette = 0 ; Equipment sprite 36: Docking computer (3 of 8) EQUB %00000101 ; v = 0, h = 0, pattern = 5 EQUB 52 ; x-coordinate = 52 EQUB 180 + YPAL ; y-coordinate = 180 EQUB %10001100 ; sprite number = 35, sprite palette = 0 ; Equipment sprite 37: Docking computer (4 of 8) EQUB %00000110 ; v = 0, h = 0, pattern = 6 EQUB 60 ; x-coordinate = 60 EQUB 180 + YPAL ; y-coordinate = 180 EQUB %10010000 ; sprite number = 36, sprite palette = 0 ; Equipment sprite 38: Docking computer (5 of 8) EQUB %01000100 ; v = 0, h = 1, pattern = 4 EQUB 178 ; x-coordinate = 178 EQUB 156 + YPAL ; y-coordinate = 156 EQUB %10010100 ; sprite number = 37, sprite palette = 0 ; Equipment sprite 39: Docking computer (6 of 8) EQUB %01000011 ; v = 0, h = 1, pattern = 3 EQUB 186 ; x-coordinate = 186 EQUB 156 + YPAL ; y-coordinate = 156 EQUB %10011000 ; sprite number = 38, sprite palette = 0 ; Equipment sprite 40: Docking computer (7 of 8) EQUB %01000110 ; v = 0, h = 1, pattern = 6 EQUB 178 ; x-coordinate = 178 EQUB 164 + YPAL ; y-coordinate = 164 EQUB %10011100 ; sprite number = 39, sprite palette = 0 ; Equipment sprite 41: Docking computer (8 of 8) EQUB %01000101 ; v = 0, h = 1, pattern = 5 EQUB 186 ; x-coordinate = 186 EQUB 164 + YPAL ; y-coordinate = 164 EQUB %10100000 ; sprite number = 40, sprite palette = 0 ; Equipment sprite 42: Galactic hyperdrive (1 of 2) EQUB %00011101 ; v = 0, h = 0, pattern = 29 EQUB 64 ; x-coordinate = 64 EQUB 190 + YPAL ; y-coordinate = 190 EQUB %10100110 ; sprite number = 41, sprite palette = 2 ; Equipment sprite 43: Galactic hyperdrive (1 of 2) EQUB %01011101 ; v = 0, h = 1, pattern = 29 EQUB 74 ; x-coordinate = 74 EQUB 190 + YPAL ; y-coordinate = 190 EQUB %10101010 ; sprite number = 42, sprite palette = 2
Name: DrawEquipment [Show more] Type: Subroutine Category: Equipment Summary: Draw the currently fitted equipment onto the Cobra Mk III image on the Equip Ship screen
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawEquipment_b6 calls DrawEquipment
.DrawEquipment JSR WaitForNMI ; Wait until the next NMI interrupt has passed (i.e. the ; next VBlank) LDA ECM ; If we do not have E.C.M. fitted, jump to dreq1 to move BEQ dreq1 ; on to the next piece of equipment LDY #0 ; Set Y = 0 so we set up the sprites using data from ; sprite 0 onwards in the equipSprites table LDX #3 ; Set X = 3 so we draw three sprites, i.e. equipment ; sprites 0 to 2 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; E.C.M. on our Cobra Mk III .dreq1 LDX LASER ; If we do not have a laser fitted to the front view, BEQ dreq2 ; jump to dreq2 to move on to the next piece of ; equipment JSR GetLaserPattern ; Set A to the pattern number of the laser's equipment ; sprite for the type of laser fitted, to pass to the ; SetLaserSprite routine LDY #3 * 4 ; Set Y = 3 * 4 so we set up the sprites using data ; from sprite 3 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 3 and 4 from the equipSprites table JSR SetLaserSprite ; Set up the sprites in the sprite buffer to show the ; front view laser on our Cobra Mk III JMP dreq2 ; This instruction has no effect (presumably it is left ; over from code that was later removed) .dreq2 LDX LASER+1 ; If we do not have a laser fitted to the rear view, BEQ dreq3 ; jump to dreq3 to move on to the next piece of ; equipment JSR GetLaserPattern ; Set A to the pattern number of the laser's equipment ; sprite for the type of laser fitted, to pass to the ; SetLaserSprite routine LDY #9 * 4 ; Set Y = 9 * 4 so we set up the sprites using data ; from sprite 9 onwards in the equipSprites table LDX #1 ; Set X = 1 so we draw one sprite, i.e. equipment ; sprite 9 from the equipSprites table JSR SetLaserSprite ; Set up the sprites in the sprite buffer to show the ; rear view laser on our Cobra Mk III JMP dreq3 ; This instruction has no effect (presumably it is left ; over from code that was later removed) .dreq3 LDX LASER+2 ; If we do not have a laser fitted to the left view, BEQ dreq5 ; jump to dreq5 to move on to the next piece of ; equipment CPX #Armlas ; If the laser fitted to the left view is a military BEQ dreq4 ; laser, jump to dreq4 to show the laser using ; equipment sprites 10 and 11 JSR GetLaserPattern ; Set A to the pattern number of the laser's equipment ; sprite for the type of laser fitted, to pass to the ; SetLaserSprite routine LDY #5 * 4 ; Set Y = 5 * 4 so we set up the sprites using data ; from sprite 5 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 5 and 6 from the equipSprites table JSR SetLaserSprite ; Set up the sprites in the sprite buffer to show the ; left view laser on our Cobra Mk III JMP dreq5 ; Jump to dreq5 to move on to the next piece of ; equipment .dreq4 LDY #10 * 4 ; Set Y = 10 * 4 so we set up the sprites using data ; from sprite 10 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 10 and 11 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; left view military laser on our Cobra Mk III .dreq5 LDX LASER+3 ; If we do not have a laser fitted to the right view, BEQ dreq7 ; jump to dreq7 to move on to the next piece of ; equipment CPX #Armlas ; If the laser fitted to the left view is a military BEQ dreq6 ; laser, jump to dreq6 to show the laser using ; equipment sprites 12 and 13 JSR GetLaserPattern ; Set A to the pattern number of the laser's equipment ; sprite for the type of laser fitted, to pass to the ; SetLaserSprite routine LDY #7 * 4 ; Set Y = 7 * 4 so we set up the sprites using data ; from sprite 7 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 7 and 8 from the equipSprites table JSR SetLaserSprite ; Set up the sprites in the sprite buffer to show the ; right view laser on our Cobra Mk III JMP dreq7 ; Jump to dreq7 to move on to the next piece of ; equipment .dreq6 LDY #12 * 4 ; Set Y = 12 * 4 so we set up the sprites using data ; from sprite 12 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 12 and 13 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; right view military laser on our Cobra Mk III .dreq7 LDA BST ; If we do not have fuel scoops fitted, jump to dreq8 to BEQ dreq8 ; move on to the next piece of equipment LDY #14 * 4 ; Set Y = 14 * 4 so we set up the sprites using data ; from sprite 14 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 14 and 15 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; fuel scoops on our Cobra Mk III .dreq8 LDA ENGY ; If we do not have an energy unit fitted, jump to BEQ dreq10 ; dreq10 to move on to the next piece of equipment LSR A ; If ENGY is 2 or more, then we have the naval energy BNE dreq9 ; unit fitted, to jump to dreq9 to display the four ; sprites for the naval version LDY #18 * 4 ; Set Y = 18 * 4 so we set up the sprites using data ; from sprite 18 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 18 and 19 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; standard energy unit on our Cobra Mk III JMP dreq10 ; Jump to dreq10 to move on to the next piece of ; equipment .dreq9 ; The naval energy unit consists of the two sprites ; for the standard energy unit (sprites 18 and 19), ; plus two extra sprites (16 and 17) LDY #16 * 4 ; Set Y = 16 * 4 so we set up the sprites using data ; from sprite 16 onwards in the equipSprites table LDX #4 ; Set X = 4 so we draw four sprites, i.e. equipment ; sprites 16 to 19 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; naval energy unit on our Cobra Mk III .dreq10 LDA NOMSL ; If we do not have any missiles fitted, jump to dreq11 BEQ dreq11 ; to move on to the next piece of equipment ; We start by setting up the sprites for missile 2 LDY #20 * 4 ; Set Y = 20 * 4 so we set up the sprites using data ; from sprite 20 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 20 and 21 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; first missile on our Cobra Mk III LDA NOMSL ; If the number of missiles in NOMSL is 1, jump to LSR A ; dreq11 to move on to the next piece of equipment BEQ dreq11 ; We now set up the sprites for missile 2 LDY #22 * 4 ; Set Y = 22 * 4 so we set up the sprites using data ; from sprite 22 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 22 and 23 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; second missile on our Cobra Mk III LDA NOMSL ; If the number of missiles in NOMSL is 2, jump to CMP #2 ; dreq11 to move on to the next piece of equipment BEQ dreq11 ; We now set up the sprites for missile 3 LDY #24 * 4 ; Set Y = 24 * 4 so we set up the sprites using data ; from sprite 24 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 24 and 25 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; third missile on our Cobra Mk III LDA NOMSL ; If the number of missiles in NOMSL is not 4, then it CMP #4 ; must be 3, so jump to dreq11 to move on to the next BNE dreq11 ; piece of equipment ; We now set up the sprites for missile 4 LDY #26 * 4 ; Set Y = 26 * 4 so we set up the sprites using data ; from sprite 26 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 26 and 27 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; fourth missile on our Cobra Mk III .dreq11 LDA BOMB ; If we do not have an energy bomb fitted, jump to BEQ dreq12 ; dreq12 to move on to the next piece of equipment LDY #28 * 4 ; Set Y = 28 * 4 so we set up the sprites using data ; from sprite 28 onwards in the equipSprites table LDX #3 ; Set X = 3 so we draw three sprites, i.e. equipment ; sprites 28 to 30 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; energy bomb on our Cobra Mk III .dreq12 LDA CRGO ; If we do not have a large cargo bay fitted (i.e. our CMP #37 ; cargo capacity in CRGO is not the larger capacity of BNE dreq13 ; 37), jump to dreq13 to move on to the next piece of ; equipment LDY #31 * 4 ; Set Y = 31 * 4 so we set up the sprites using data ; from sprite 31 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 31 and 32 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; large cargo bay on our Cobra Mk III .dreq13 LDA ESCP ; If we do not have an escape pod fitted, jump to BEQ dreq14 ; dreq14 to move on to the next piece of equipment LDY #33 * 4 ; Set Y = 33 * 4 so we set up the sprites using data ; from sprite 33 onwards in the equipSprites table LDX #1 ; Set X = 1 so we draw one sprite, i.e. equipment ; sprite 33 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; escape pod on our Cobra Mk III .dreq14 LDA DKCMP ; If we do not have a docking computer fitted, jump to BEQ dreq15 ; dreq15 to move on to the next piece of equipment LDY #34 * 4 ; Set Y = 34 * 4 so we set up the sprites using data ; from sprite 34 onwards in the equipSprites table LDX #8 ; Set X = 8 so we draw eight sprites, i.e. equipment ; sprites 34 to 41 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; docking computer on our Cobra Mk III .dreq15 LDA GHYP ; If we do not have a galactic hyperdrive fitted, jump BEQ dreq16 ; to dreq16 to return from the subroutine, as we have ; now drawn all our equipment LDY #42 * 4 ; Set Y = 42 * 4 so we set up the sprites using data ; from sprite 24 onwards in the equipSprites table LDX #2 ; Set X = 2 so we draw two sprites, i.e. equipment ; sprites 42 and 43 from the equipSprites table JSR SetEquipmentSprite ; Set up the sprites in the sprite buffer to show the ; galactic hyperdrive on our Cobra Mk III .dreq16 RTS ; Return from the subroutine
Name: ShowScrollText [Show more] Type: Subroutine Category: Combat demo Summary: Show a scroll text and start the combat demo Deep dive: The NES combat demo
Context: See this subroutine on its own page References: This subroutine is called as follows: * ShowScrollText_b6 calls ShowScrollText

Arguments: A The scroll text to show: * 0 = show the first scroll text and start combat practice * 1 = show the second scroll text, including the time taken for combat practice * 2 = show the credits scroll text
.ShowScrollText PHA ; Store the value of A on the stack so we can retrieve ; it later to check which scroll text to show LDA QQ11 ; If this is not the space view, then jump to scro1 to BNE scro1 ; set up the space view for the demo JSR ClearScanner ; This is already the space view, so remove all ships ; from the scanner and hide the scanner sprites JMP scro4 ; Jump to scro4 to move on to the scroll text part, as ; the view is already set up .scro1 ; If we get here then we need to set up the space view ; for the demo JSR FadeToBlack_b3 ; Fade the screen to black over the next four VBlanks LDY #NOST ; Set Y to the number of stardust particles in NOST ; (which is 20 in the space view), so we can use it as a ; counter as we set up the stardust below STY NOSTM ; Set the number of stardust particles to NOST (which is ; 20 for the normal space view) STY RAND+1 ; Set RAND+1 to NOST to seed the random number generator LDA nmiCounter ; Set the random number seed to a fairly random state STA RAND ; that's based on the NMI counter (which increments ; every VBlank, so will be pretty random) .scro2 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 ; We now set up the coordinates of stardust particle Y JSR DORND ; Set A and X to random numbers ORA #8 ; Set A so that it's at least 8 STA SZ,Y ; Store A in the Y-th particle's z_hi coordinate at ; SZ+Y, so the particle appears in front of us STA ZZ ; Set ZZ to the particle's z_hi coordinate JSR DORND ; Set A and X to random numbers STA SX,Y ; Store A in the Y-th particle's x_hi coordinate at ; SX+Y, so the particle appears in front of us JSR DORND ; Set A and X to random numbers STA SY,Y ; Store A in the Y-th particle's y_hi coordinate at ; SY+Y, so the particle appears in front of us DEY ; Decrement the counter to point to the next particle of ; stardust BNE scro2 ; Loop back to scro2 until we have randomised all the ; stardust particles LDX #NOST ; Set X to the maximum number of stardust particles, so ; we loop through all the particles of stardust in the ; following LDY #152 ; Set Y to the starting index in the sprite buffer, so ; we start configuring from sprite 152 / 4 = 38 (as each ; sprite in the buffer consists of four bytes) .scro3 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 ; We now set up the sprite for stardust particle Y LDA #210 ; Set the sprite to use pattern number 210 for the STA pattSprite0,Y ; largest particle of stardust (the stardust particle ; patterns run from pattern 210 to 214, decreasing in ; size as the number increases) TXA ; Take the particle number, which is between 1 and 20 LSR A ; (as NOST is 20), and rotate it around from %76543210 ROR A ; to %10xxxxx3 (where x indicates a zero), storing the ROR A ; result as the sprite attribute AND #%11100001 ; STA attrSprite0,Y ; This sets the flip horizontally and flip vertically ; attributes to bits 0 and 1 of the particle number, and ; the palette to bit 3 of the particle number, so the ; reset stardust particles have a variety of reflections ; and palettes INY ; Add 4 to Y so it points to the next sprite's data in INY ; the sprite buffer INY INY DEX ; Decrement the loop counter in X BNE scro3 ; Loop back until we have configured 20 sprites JSR STARS_b1 ; Call STARS1 to process the stardust for the front view .scro4 LDA #0 ; Remove the laser from our ship, so we can't fire it STA LASER ; during the scroll text STA QQ12 ; Set QQ12 = 0 to indicate that we are not docked LDA #$10 ; Clear the screen and set the view type in QQ11 to $10 JSR ChangeToView_b0 ; (Space view with the normal font loaded) LDA #$FF ; Set showIconBarPointer = $FF to indicate that we STA showIconBarPointer ; should show the icon bar pointer LDA #240 ; Set A to the y-coordinate that's just below the bottom ; of the screen, so we can hide the sight sprites by ; moving them off-screen STA ySprite5 ; Set the y-coordinates for the five laser sight sprites STA ySprite6 ; to 240, to move them off-screen STA ySprite7 STA ySprite8 STA ySprite9 ; We are going to draw the scroll text into the pattern ; buffers, so now we calculate the addresses of the ; first available tiles in the buffers LDA #0 ; Set the high byte of SC(1 0) to 0 STA SC+1 LDA firstFreePattern ; Set SC(1 0) = firstFreePattern * 8 ASL A ROL SC+1 ; We use this to calculate the address of the pattern ASL A ; for the first free pattern in the pattern buffers ROL SC+1 ; below ASL A ROL SC+1 STA SC STA SC2 ; Set SC2(1 0) = pattBuffer1 + SC(1 0) LDA SC+1 ; = pattBuffer1 + firstFreePattern * 8 ADC #HI(pattBuffer1) ; STA SC2+1 ; So SC2(1 0) contains the address of the pattern of the ; first free tile in pattern buffer 1, as each pattern ; in the buffer contains eight bytes LDA SC+1 ; Set SC(1 0) = pattBuffer0 + SC(1 0) ADC #HI(pattBuffer0) ; = pattBuffer0 + firstFreePattern * 8 STA SC+1 ; ; So SC2(1 0) contains the address of the pattern of the ; first free tile in pattern buffer 0 ; We now clear the patterns in both pattern buffers for ; the free tile and all the other tiles to the end of ; the buffers LDX firstFreePattern ; Set X to the number of the first free pattern so we ; start clearing patterns from this point onwards LDY #0 ; Set Y to use as a byte index for zeroing the pattern ; bytes in the pattern buffers .scro5 LDA #0 ; Set A = 0 so we zero the pattern STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY STA (SC),Y ; Zero the Y-th pixel row of pattern X in both of the STA (SC2),Y ; pattern buffers and increment the index in Y INY BNE scro6 ; If Y just incremented to 0, increment the high bytes INC SC+1 ; of SC(1 0) and SC2(1 0) so they point to the next page INC SC2+1 ; in memory .scro6 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 INX ; Increment the pattern number in X BNE scro5 ; Loop back until we have cleared all patterns up to and ; including pattern 255 LDA #0 ; Set ALPHA and ALP1 to 0, so our roll angle is 0 STA ALPHA STA ALP1 STA DELTA ; Set our ship's speed to zero so the scroll text stays ; where it is LDA nmiCounter ; Set the random number seed to a fairly random state CLC ; that's based on the NMI counter (which increments ADC RAND+1 ; every VBlank, so will be pretty random) STA RAND+1 JSR DrawScrollInNMI ; Configure the NMI handler to draw the scroll text ; screen, which will clear the screen as we just blanked ; out all the patterns in the pattern buffers PLA ; Retrieve the argument that we stored on the stack at BNE scro7 ; the start of the routine, which contains the scroll ; text that we should be showing and if it is non-zero, ; jump to scro7 to skip playing the combat part of the ; demo, as we are either showing the results of combat ; practice, or we are showing the credits ; If we get here then A = 0 and we are show the first ; scroll text before starting the combat demo LDX languageIndex ; Set (Y X) to the address of the text for the first LDA scrollText1Lo,X ; scroll text for the chosen language LDY scrollText1Hi,X TAX LDA #2 ; Draw the first scroll text at scrollText1, which has JSR DrawScrollText ; six lines (so we set A = 2, as it needs to contain ; the number of lines minus 4) ; We are now ready to start the combat part of the ; combat demo LDA #$00 ; Set the view type in QQ11 to $00 (Space view with STA QQ11 ; no fonts loaded) JSR SetLinePatterns_b3 ; Load the line patterns for the new view into the ; pattern buffers LDA #37 ; Tell the NMI handler to send pattern entries from STA firstPattern ; pattern 37 in the buffer JSR DrawScrollInNMI ; Configure the NMI handler to draw the scroll text ; screen, which will draw the scroll text on-screen LDA #60 ; Tell the NMI handler to send pattern entries from STA firstPattern ; pattern 60 in the buffer JMP PlayDemo_b0 ; Play the combat demo, returning from the subroutine ; using a tail call .scro7 CMP #2 ; If we called this routine with A = 2 then jump to BEQ scro14 ; scro14 to show the credits scroll text ; Otherwise A = 1, so we show the second scroll text, ; including the time taken for combat practice, so we ; start by calculating the time taken and storing the ; results in K5, so the GRIDSET routine can draw the ; correct characters for the time taken ; ; Specifically, the second scroll text in scrollText2 ; expects the characters to be set as follows: ; ; * $83 is the first digit of the minutes ; ; * $82 is the second digit of the minutes ; ; * $81 is the first digit of the seconds ; ; * $80 is the second digit of the seconds ; ; while GRIDSET expect to find these values at the ; following locations: ; ; * Character $83 refers to location K5+3 ; ; * Character $82 refers to location K5+2 ; ; * Character $81 refers to location K5+1 ; ; * Character $80 refers to location K5 ; ; Finally, the number of seconds that we need to display ; is in (nmiTimerHi nmiTimerLo), so we need to convert ; this into minutes and seconds, and then set the values ; in K5 to the correct ASCII characters that represent ; the digits of this time LDA #'0' ; Set all the digits to 0 except the second digit of the STA K5+1 ; seconds (as we will set this later) STA K5+2 STA K5+3 LDA #100 ; Set nmiTimer = 100 so (nmiTimerHi nmiTimerLo) will not STA nmiTimer ; change during the following calculation (as nmiTimer ; has to tick down to zero for that to happen, so this ; gives us 100 VBlanks to complete the calculation ; before (nmiTimerHi nmiTimerLo) changes) ; We start with the first digit of the minute count (the ; "tens" digit) SEC ; Set the C flag for the following subtraction .scro8 LDA nmiTimerLo ; Set (A X) = (nmiTimerHi nmiTimerLo) - $0258 SBC #$58 ; = (nmiTimerHi nmiTimerLo) - 600 TAX LDA nmiTimerHi SBC #$02 BCC scro9 ; If the subtraction underflowed then we know that ; (nmiTimerHi nmiTimerLo) < 600, so jump to scro9 to ; move on to the next digit ; If we get here then (nmiTimerHi nmiTimerLo) >= 600, ; so the time in (nmiTimerHi nmiTimerLo) is at least ; ten minutes, so we increment the first digit of the ; minute count in K5+3, update the time in ; (nmiTimerHi nmiTimerLo) to (A X), and loop back to ; try subtracting another 10 minutes STA nmiTimerHi ; Set (nmiTimerHi nmiTimerLo) = (A X) STX nmiTimerLo ; ; So this updates (nmiTimerHi nmiTimerLo) with the new ; value, which is ten minutes less than the original ; value INC K5+3 ; Increment the first digit of the minute count in K5+3 ; to bump it up from, say, "0" to "1" BCS scro8 ; Loop back to scro8 to try subtracting another ten ; minutes (this BCS is effectively a JMP as we just ; passed through a BCC) .scro9 ; Now for the second digit of the minute count (the ; "ones" digit) SEC ; Set the C flag for the following subtraction LDA nmiTimerLo ; Set (A X) = (nmiTimerHi nmiTimerLo) - $003C SBC #$3C ; = (nmiTimerHi nmiTimerLo) - 60 TAX LDA nmiTimerHi SBC #$00 BCC scro10 ; If the subtraction underflowed then we know that ; (nmiTimerHi nmiTimerLo) < 60, so jump to scro10 to ; move on to the next digit ; If we get here then (nmiTimerHi nmiTimerLo) >= 60, ; so the time in (nmiTimerHi nmiTimerLo) is at least ; one minute, so we increment the second digit of the ; minute count in K5+2, update the time in ; (nmiTimerHi nmiTimerLo) to (A X), and loop back to ; try subtracting another minute STA nmiTimerHi ; Set (nmiTimerHi nmiTimerLo) = (A X) STX nmiTimerLo ; ; So this updates (nmiTimerHi nmiTimerLo) with the new ; value, which is one minute less than the original ; value INC K5+2 ; Increment the second digit of the minute count in K5+2 ; to bump it up from, say, "0" to "1" BCS scro9 ; Loop back to scro8 to try subtracting another minute ; (this BCS is effectively a JMP as we just passed ; through a BCC) .scro10 ; Now for the first digit of the second count (the ; "tens" digit) ; ; By this point we know that (nmiTimerHi nmiTimerLo) is ; less than 60, so we can ignore the high byte as it is ; zero by now SEC ; Set the C flag for the following subtraction LDA nmiTimerLo ; Set A to the number of seconds we want to display .scro11 SBC #10 ; Set A = nmiTimerLo - 10 BCC scro12 ; If the subtraction underflowed then we know that ; nmiTimerLo < 10, so jump to scro12 to move on to the ; final digit ; If we get here then nmiTimerLo >= 10, so the time in ; nmiTimerLo is at least ten seconds, so we increment ; the first digit of the seconds count in K5+1 and loop ; back to try subtracting another ten seconds INC K5+1 ; Increment the first digit of the seconds count in K5+1 ; to bump it up from, say, "0" to "1" BCS scro11 ; Loop back to scro8 to try subtracting another ten ; seconds (this BCS is effectively a JMP as we just ; passed through a BCC) .scro12 ; By this point A contains the number of seconds left ; after subtracting the final ten seconds, so it is ; ten less than the value we want to display ADC #'0'+10 ; Set the character for the second digit of the seconds STA K5 ; count in K5 to the value in A, plus the ten that we ; subtracted before we jumped here, plus ASCII "0" to ; convert it into a character ; Now that the practice time is set up, we can show the ; second scroll text to report the results LDX languageIndex ; Set (Y X) to the address of the text for the second LDA scrollText2Lo,X ; scroll text for the chosen language LDY scrollText2Hi,X TAX LDA #6 ; We are now going to draw the second scroll text ; at scrollText2, which has ten lines, so we set ; A = 6 to pass to DrawScrollText, as it needs to ; contain the number of lines minus 4 .scro13 JSR DrawScrollText ; Draw the scroll text at (Y X), which will either be ; the second scroll text at scrollText2 or the third ; credits scroll text at creditsText3, depending on how ; we get here JSR FadeToBlack_b3 ; Fade the screen to black over the next four VBlanks JMP StartGame_b0 ; Jump to StartGame to reset the stack and go to the ; docking bay (i.e. show the Status Mode screen) .scro14 ; If we get here then we show the credits scroll text, ; which is in three parts LDX languageIndex ; Set (Y X) to the address of the text for the first LDA creditsText1Lo,X ; credits scroll text for the chosen language LDY creditsText1Hi,X TAX LDA #6 ; Draw the first credits scroll text at creditsText1, JSR DrawScrollText ; which has ten lines (so we set A = 6, as it needs to ; contain the number of lines minus 4) JSR WaitForNMI ; Wait until the next NMI interrupt has passed (i.e. the ; next VBlank) LDX languageIndex ; Set (Y X) to the address of the text for the second LDA creditsText2Lo,X ; credits scroll text for the chosen language LDY creditsText2Hi,X TAX LDA #5 ; Draw the second credits scroll text at creditsText2, JSR DrawScrollText ; which has nine lines (so we set A = 5, as it needs to ; contain the number of lines minus 4) JSR WaitForNMI ; Wait until the next NMI interrupt has passed (i.e. the ; next VBlank) LDX languageIndex ; Set (Y X) to the address of the text for the third LDA creditsText3Lo,X ; credits scroll text for the chosen language LDY creditsText3Hi,X TAX LDA #3 ; We are now going to draw the third credits scroll text ; at creditsText3, which has seven lines, so we set ; A = 3 to pass to DrawScrollText, as it needs to ; contain the number of lines minus 4 BNE scro13 ; Jump to scro13 to draw the third credits scroll text ; at creditsText3 (this BNE is effectively a JMP as A is ; never zero
Name: DrawScrollInNMI [Show more] Type: Subroutine Category: Combat demo Summary: Configure the NMI handler to draw the scroll text screen
Context: See this subroutine on its own page References: This subroutine is called as follows: * ShowScrollText calls DrawScrollInNMI
.DrawScrollInNMI JSR WaitForPPUToFinish ; Wait until both bitplanes of the screen have been ; sent to the PPU, so the screen is fully updated and ; there is no more data waiting to be sent to the PPU LDA #254 ; Tell the NMI handler to send data up to pattern 254, STA firstFreePattern ; so all the patterns get updated LDA #%11001000 ; Set both bitplane flags as follows: STA bitplaneFlags ; STA bitplaneFlags+1 ; * Bit 2 clear = send tiles up to configured numbers ; * Bit 3 set = clear buffers after sending data ; * Bit 4 clear = we've not started sending data yet ; * Bit 5 clear = we have not yet sent all the data ; * Bit 6 set = send both pattern and nametable data ; * Bit 7 set = send data to the PPU ; ; Bits 0 and 1 are ignored and are always clear ; ; The NMI handler will now start sending data to the PPU ; according to the above configuration, splitting the ; process across multiple VBlanks if necessary RTS ; Return from the subroutine
Name: GRIDSET [Show more] Type: Subroutine Category: Combat demo Summary: Populate the line coordinate tables with the pixel lines for one 21-character line of scroll text Deep dive: The 6502 Second Processor demo mode The NES combat demo
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawScrollText calls GRIDSET * CalculateGridLines calls via GRIDSET+5

This routine populates the X-th byte in the X1TB, Y1TB and X2TB tables (the TB tables) with the line coordinates that make up each character in a single line of scroll text that we want to display (where each line of text contains 21 characters).
Arguments: INF(1 0) The contents of the scroll text to display XC The offset within INF(1 0) of the 21-character line of text to display
Other entry points: GRIDSET+5 Use the y-coordinate in YP so the scroll text starts at (0, YP) rather than (0, 6)
.GRIDSET LDX #6 ; Set YP = 6 STX YP SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDX #21 ; Each line of text in the scroll text contains 21 STX CNT ; characters (padded out with spaces if required), so ; set CNT = 21 to use as a counter to work through the ; line of text at INF(1 0) + XC LDX #0 ; Set XP = 0, so we now have (XP, YP) = (0, 6) STX XP ; ; (XP, YP) is the coordinate in space where we start ; drawing the lines that make up the scroll text, so ; this effectively moves the scroll text cursor to the ; top-left corner (as these are space coordinates where ; higher y-coordinates are further up the screen) LDY XC ; Set Y = XC, to act as an index into the text we want ; to display, pointing to the character we are currently ; processing and starting from character XC .GSL1 LDA (INF),Y ; Load the Y-th character from the text we want to ; display into A, so A now contains the ASCII code of ; the character we want to process BPL grid1 ; If bit 7 of the character is clear, jump to grid1 to ; slip the following TAX ; Bit 7 of the character is set, so set A to character LDA K5-128,X ; X - 128 from K5 ; ; So character $80 refers to location K5, $81 to K5+1, ; $82 to K5+2 and $83 to K5+3, which is where we put the ; results for the time taken in the combat demo, so this ; allows us to display the time in the scroll text .grid1 SEC ; Set S = A - ASCII " ", as the table at LTDEF starts SBC #' ' ; with the lines needed for a space, so A now contains STA S ; the number of the entry in LTDEF for this character ASL A ; Set Y = S + 4 * A ASL A ; = A + 4 * A ADC S ; = 5 * A BCS grid2 ; TAY ; so Y now points to the offset of the definition in the ; LTDEF table for the character in A, where the first ; character in the table is a space and each definition ; in LTDEF consists of five bytes ; ; If the addition overflows, jump to grid2 to do the ; same as the following, but with an extra $100 added ; to the addresses to cater for the overflow LDA LTDEF,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; first line into the TB tables LDA LTDEF+1,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; second line into the TB tables LDA LTDEF+2,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; third line into the TB tables LDA LTDEF+3,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; fourth line into the TB tables LDA LTDEF+4,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; fifth line into the TB tables INC XC ; Increment the character index to point to the next ; character in the text we want to display LDY XC ; Set Y to the updated character index LDA XP ; Set XP = XP + #W2 CLC ; ADC #W2 ; to move the x-coordinate along by #W2 (the horizontal STA XP ; character spacing for the scroll text) DEC CNT ; Decrement the loop counter in CNT BNE GSL1 ; Loop back to process the next character until we have ; done all 21 RTS ; Return from the subroutine .grid2 ; If we get here then the addition overflowed when ; calculating A, so we need to add an extra $100 to A ; to get the correct address in LTDEF TAY ; Copy A to Y, so Y points to the offset of the ; definition in the LTDEF table for the character in A LDA LTDEF+$100,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; first line into the TB tables LDA LTDEF+$101,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; second line into the TB tables LDA LTDEF+$102,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; third line into the TB tables LDA LTDEF+$103,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; fourth line into the TB tables LDA LTDEF+$104,Y ; Call GRS1 to put the coordinates of the character's JSR GRS1 ; fifth line into the TB tables INC XC ; Increment the character index to point to the next ; character in the text we want to display LDY XC ; Set Y to the updated character index LDA XP ; Set XP = XP + #W2 CLC ; ADC #W2 ; to move the x-coordinate along by #W2 (the horizontal STA XP ; character spacing for the scroll text) DEC CNT ; Decrement the loop counter in CNT BNE GSL1 ; Loop back to process the next character until we have ; done all 21 RTS ; Return from the subroutine
Name: GRS1 [Show more] Type: Subroutine Category: Combat demo Summary: Populate the line coordinate tables with the lines for a single scroll text character Deep dive: The 6502 Second Processor demo mode
Context: See this subroutine on its own page References: This subroutine is called as follows: * GRIDSET calls GRS1

This routine populates the X-th byte in the X1TB, Y1TB and X2TB tables (the TB tables) with the coordinates for the lines that make up the character whose definition is given in A.
Arguments: A The value from the LTDEF table for the character (XP, YP) The coordinate where we should draw this character X The index of the character within the scroll text
Returns: X X gets incremented to point to the next character Y Y is preserved
.GRS1 BEQ GRR1 ; If A = 0, jump to GRR1 to return from the subroutine ; as 0 denotes no line segment STA R ; Store the value from the LTDEF table in R STY P ; Store the offset in P, so we can preserve it through ; calls to GRS1 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 .gris1 LDA Y1TB,X ; If the Y1 coordinate for character X is zero then it BEQ gris2 ; is empty and can be used, so jump to gris2 to get on ; with the calculation INX ; Otherwise increment the byte pointer in X to check the ; next entry in the coordinate table CPX #240 ; If X <> 240 then we have not yet reached the end of BNE gris1 ; the coordinate table (as each of the X1TB, X2TB and ; Y1TB tables is 240 bytes long), so loop back to gris1 ; to check the next entry to see if it is free LDX #0 ; Otherwise set X = 0 so we wrap around to the start of ; the table .gris2 LDA R ; Set A to bits 0-3 of the LTDEF table value, i.e. the AND #%00001111 ; low nibble TAY ; Set Y = A LDA NOFX,Y ; Set X1TB+X = XP + NOFX+Y CLC ; ADC XP ; so the X1 coordinate is XP + the NOFX entry given by STA X1TB,X ; the low nibble of the LTDEF table value LDA YP ; Set Y1TB+X = YP - NOFY+Y SEC ; SBC NOFY,Y ; so the Y1 coordinate is YP - the NOFY entry given by STA Y1TB,X ; the low nibble of the LTDEF table value LDA R ; Set Y to bits 4-7 of the LTDEF table value, i.e. the LSR A ; high nibble LSR A LSR A LSR A TAY LDA NOFX,Y ; Set X2TB+X = XP + NOFX+Y CLC ; ADC XP ; so the X2 coordinate is XP + the NOFX entry given by STA X2TB,X ; the high nibble of the LTDEF table value LDA YP ; Set A = YP - NOFY+Y SEC ; SBC NOFY,Y ; so the value in A is YP - the NOFY entry given by the ; high nibble of the LTDEF table value ASL A ; Shift the result from the low nibble of A into the top ASL A ; nibble ASL A ASL A ORA Y1TB,X ; Stick the result into the high nibble of Y1TB+X, so STA Y1TB,X ; the Y1TB coordinate contains both y-coordinates, with ; Y1 in the low nibble and Y2 in the high nibble LDY P ; Restore Y from P so it gets preserved through calls to ; GRS1 .GRR1 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 RTS ; Return from the subroutine
Name: CalculateGridLines [Show more] Type: Subroutine Category: Combat demo Summary: Reset the line coordinate tables and populate them with the characters for a specified scroll text
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawScrollText calls CalculateGridLines

Arguments: (Y X) The content of the scroll text to display
Returns: INF(1 0) The content of the scroll text to display
.CalculateGridLines STX INF ; Set INF(1 0) = (Y X) STY INF+1 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 ; We start by clearing out the buffer at Y1TB LDY #240 ; The buffer contains 240 bytes, so set a byte counter ; in Y LDA #0 ; Set A = 0 so we can zero the buffer .resg1 STA Y1TB-1,Y ; Zero the entry Y - 1 in Y1TB DEY ; Decrement the byte counter BNE resg1 ; Loop back until we have reset the whole Y1TB buffer ; We now populate the grid line buffer with the lines ; for the scroll text at INF(1 0) LDX #0 ; Set XP = 0, so the scroll text starts at x-coordinate STX XP ; 0, on the left of the screen LDA #5*W2Y ; Set YP so the scroll text starts five lines of scroll STA YP ; text down the screen (as W2Y is the height of each ; line in scroll text coordinates) LDY #0 ; Set XC = 0, so we start from the first character of STY XC ; INF(1 0) LDA #4 ; Set LASCT = 4, so we process four lines of text in the STA LASCT ; following loop .resg2 JSR GRIDSET+5 ; Populate the line coordinate tables with the pixel ; lines for one 21-character line of scroll text, ; drawing the line at (0, YP) LDA YP ; Set YP = YP - W2Y SEC ; SBC #W2Y ; So YP moves down the screen by one line (as W2Y is the STA YP ; height of each line in scroll text coordinates) DEC LASCT ; Decrement the loop counter in LASCT BNE resg2 ; Loop back until we have processed LASCT lines of ; scroll text RTS ; Return from the subroutine
Name: GetScrollDivisions [Show more] Type: Subroutine Category: Combat demo Summary: Set up the division calculations for the scroll text
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawScrollFrame calls GetScrollDivisions

This routine sets up a division table to use in the calculations for drawing the scroll text in DrawScrollFrame.
.GetScrollDivisions LDY #15 ; We are going to populate 16 bytes in the buffer at BUF ; and another 16 in the buffer at BUF+16, so set a loop ; counter in Y .sdiv1 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 STY T ; Store the loop counter in T (though we don't read this ; again, so this has no effect) TYA ; Set R = Y * 2 ASL A STA R ASL A ; Set S = Y * 4 STA S ASL A ; Set the Y-th entry in BUF+16 to the following: ADC #31 ; SBC scrollProgress ; Y * 8 + 31 - scrollProgress STA BUF+16,Y ; ; We know the C flag is clear because Y is a maximum of ; 15 so the three ASL A instructions will shift zeroes ; into the C flag each time BPL sdiv4 ; If A < 128, jump to sdiv4 to set Q and A as follows, ; but with both scaled up as far as possible to make the ; calculation more accurate STA Q ; Set Q = A LDA scrollProgress ; Set A = 37 + scrollProgress / 4 - R LSR A ; = 37 + scrollProgress / 4 - Y * 2 LSR A ADC #37 SBC R .sdiv2 CMP Q ; If A >= Q, jump to sdiv3 to store 255 as the result BCS sdiv3 ; in the Y-th byte of BUF JSR LL28 ; Call LL28 to calculate: ; ; R = 256 * A / Q ; ; = 37 - Y * 2 + scrollProgress / 4 ; ------------------------------- ; 31 + Y * 8 - scrollProgress LSR R ; Set R = R / 2 ; ; = 37 - Y * 2 + scrollProgress / 4 ; --------------------------------- ; 2 * (31 + Y * 8 - scrollProgress) LDA #72 ; Set the Y-th entry in BUF to 72 + R CLC ADC R STA BUF,Y DEY ; Decrement the loop counter in Y BPL sdiv1 ; Loop back until we have calculated all 16 values RTS ; Return from the subroutine .sdiv3 LDA #255 ; Set the Y-th entry in BUF to 255 STA BUF,Y DEY ; Decrement the loop counter in Y BPL sdiv1 ; Loop back until we have calculated all 16 values RTS ; Return from the subroutine .sdiv4 ASL A ; Set A = A * 2 BPL sdiv5 ; If A < 128, jump to sdiv5 STA Q ; Set Q = A * 2 LDA scrollProgress ; Set A = 73 + scrollProgress / 2 - Y * 4 LSR A ADC #73 SBC S ; So we have: ; ; Q = A * 2 ; ; A = 73 + scrollProgress / 2 - Y * 4 ; ; So when we divide them at sdiv2 above, this is the ; same as having: ; ; Q = A ; ; A = 37 + scrollProgress / 4 - Y * 2 ; ; but with both the numerator and denominator scaled up ; by the same factor of 2 JMP sdiv2 ; Jump to sdiv2 to continue the calculation with these ; scaled up values of Q and A .sdiv5 ASL A ; Set Q = A * 4 STA Q LDA scrollProgress ; Set A = 144 + scrollProgress - Y * 2 ADC #144 SBC S SBC S ; So we have: ; ; Q = A * 4 ; ; A = 144 + scrollProgress - Y * 2 ; ; So when we divide them at sdiv2 above, this is the ; same as having: ; ; Q = A ; ; A = 37 + scrollProgress / 4 - Y * 2 ; ; but with both the numerator and denominator scaled up ; by the same factor of 4 JMP sdiv2 ; Jump to sdiv2 to continue the calculation with these ; scaled up values of Q and A
Name: DrawScrollText [Show more] Type: Subroutine Category: Combat demo Summary: Display a Star Wars scroll text Deep dive: The NES combat demo
Context: See this subroutine on its own page References: This subroutine is called as follows: * ShowScrollText calls DrawScrollText

Arguments: A The number of lines in the middle part of the scroll text, which is the total number of text lines minus 4: * 2 for scrollText1 (6 lines) * 6 for scrollText2 and creditsText1 (10 lines) * 5 for creditsText2 (9 lines) * 3 for creditsText3 (7 lines)
.DrawScrollText PHA ; Store the number of lines in the scroll text on the ; stack so we can retrieve it later JSR CalculateGridLines ; Reset the line coordinate tables and populate them ; with the characters for the scroll text at (Y X), ; setting INF(1 0) to the scroll text in the process LDA #$28 ; Set the visible colour to orange ($28) so the scroll STA visibleColour ; text appears in this colour LDA #0 ; Clear bits 6 and 7 of allowInSystemJump to allow STA allowInSystemJump ; in-system jumps, so the call to UpdateIconBar displays ; the fast-forward icon (though choosing this in the ; demo doesn't do an in-system jump, but skips the rest ; of the demo instead) LDA #2 ; Set the scroll text speed to 2 (normal speed) STA scrollTextSpeed JSR UpdateIconBar_b3 ; Update the icon bar to show the correct buttons for ; the scroll text LDA #40 ; Tell the NMI handler to send nametable entries from STA firstNameTile ; tile 40 * 8 = 320 onwards (i.e. from the start of tile ; row 10) ; We now draw the scroll text and move it up the screen, ; which we do in three stages ; ; * Stage 1 moves the first few lines of the scroll ; text up the screen until the first line reaches ; the middle of the screen (i.e. just before it will ; start to disappear into the distance); stage 1 is ; always 81 frames long at normal speed ; ; * Stage 2 then draws the rest of the scroll text ; on-screen while moving everything up the screen, ; reusing lines in the line coordinate tables as ; they disappear into the distance; stage 2 is ; longer with longer scroll texts ; ; * Stage 3 takes over when everything has been drawn, ; and just concentrates on moving the scroll text ; into the distance without drawing anything new; ; stage 3 is always 48 frames long at normal speed ; ; We start with stage 1 LDA #160 ; Set the size of the scroll text to 160 to pass to STA scrollProgress ; DrawScrollFrames ; ; This equates to 81 frames at normal speed, with each ; frame taking scrollTextSpeed off the value of ; scrollProgress (i.e. subtracting 2), and only ; stopping when the subtraction goes past zero JSR DrawScrollFrames ; Draw the frames for stage 1, so the scroll text gets ; drawn and moves up the screen ; We now move on to stage 2 ; ; Stage 2 takes longer for longer scroll texts, and its ; length is based on the value of A passed to the ; routine (which contains the total number of text lines ; minus 4) ; ; Specifically, stage 2 loop around A times, with each ; loop taking a scrollProgress of 23 (which is 12 frames ; at normal speed) ; ; Each loop draws an extra line of text in the scroll ; text, and scrolls up by one line of text PLA ; Set LASCT to the value that we stored on the stack, so STA LASCT ; LASCT contains the number of lines in the scroll text .dscr1 LDA #23 ; Set the size of the scroll text to 23 to pass to STA scrollProgress ; DrawScrollFrames JSR ScrollTextUpScreen ; Scroll the scroll text up the screen by one full line ; of text JSR GRIDSET ; Call GRIDSET to populate the line coordinate tables at ; X1TB, Y1TB and X2TB (the TB tables) with the lines for ; the scroll text in INF(1 0) at offset XC JSR DrawScrollFrames ; Draw the frames for stage 2, so the scroll text gets ; drawn and moves up the screen by one text line DEC LASCT ; Loop back until we have done LASCT loops around the BNE dscr1 ; above ; We now move on to stage 3 ; ; Stage 3 loops around four times, with each loop taking ; a scrollProgress of 23 (which is 12 frames at normal ; speed), so that's a grand total of 48 frames at normal ; speed LDA #4 ; Set LASCT = 4 so we do the following loop four times STA LASCT .dscr2 LDA #23 ; Set the size of the scroll text to 23 to pass to STA scrollProgress ; DrawScrollFrames JSR ScrollTextUpScreen ; Scroll the scroll text up the screen by one full line ; of text JSR DrawScrollFrames ; Draw the frames for stage 3, so the scroll text moves ; off-screen one text line at a time DEC LASCT ; Loop back until we have done LASCT loops around the BNE dscr2 ; above ; The scroll text is now done and is no longer on-screen LDA #0 ; Reset the scroll speed to zero (though this isn't read STA scrollTextSpeed ; again, so this has no effect) LDA #$2C ; Set the visible colour back to cyan ($2C) STA visibleColour RTS ; Return from the subroutine
Name: DrawScrollFrames [Show more] Type: Subroutine Category: Combat demo Summary: Draw a scroll text over multiple frames Deep dive: The NES combat demo
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawScrollText calls DrawScrollFrames
.DrawScrollFrames LDA controller1A ; If the A button is being pressed on controller 1, jump BMI scfr1 ; to scfr1 to speed up the scroll text LDA iconBarChoice ; If the fast-forward button has not been chosen on the CMP #12 ; icon bar, jump to scfr2 to leave the speed as it is BNE scfr2 LDA #0 ; Set iconBarChoice = 0 to clear the icon button choice STA iconBarChoice ; so we don't process it again .scfr1 ; If we get here then either the A button has been ; pressed or the fast-forward button has been chosen on ; the icon bar LDA #9 ; Set the scroll text speed to 9 (fast) STA scrollTextSpeed .scfr2 JSR FlipDrawingPlane ; Flip the drawing bitplane so we draw into the bitplane ; that isn't visible on-screen JSR DrawScrollFrame ; Draw one frame of the scroll text JSR DrawBitplaneInNMI ; Configure the NMI to send the drawing bitplane to the ; PPU after drawing the box edges and setting the next ; free tile number LDA iconBarChoice ; If no buttons have been pressed on the icon bar while BEQ scfr3 ; drawing the frame, jump to scfr3 to skip the following ; instruction JSR CheckForPause_b0 ; If the Start button has been pressed then process the ; pause menu and set the C flag, otherwise clear it .scfr3 LDA scrollProgress ; Set scrollProgress = scrollProgress - scrollTextSpeed SEC ; SBC scrollTextSpeed ; So we update the scroll text progress STA scrollProgress BCS DrawScrollFrames ; If the subtraction didn't underflow then the value of ; scrollProgress is still positive and there is more ; scrolling to be done, so loop back to the start of ; the routine to keep going RTS ; Return from the subroutine
Name: ScrollTextUpScreen [Show more] Type: Subroutine Category: Combat demo Summary: Go through the line y-coordinate table at Y1TB, moving each line coordinate up the screen by W2Y (i.e. by one full line of text)
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawScrollText calls ScrollTextUpScreen
.ScrollTextUpScreen SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 ; We now work our way through every y-coordinate in the ; Y1TB table (so that's the y-coordinate of each line in ; the line coordinate tables), adding 51 to each of them ; to move the scroll text up the screen, and removing ; any lines that move off the top of the scroll text LDY #16 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 239 down to ; entry 224 .sups1 LDA Y1TB+223,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups3 ; If A = 0 then this entry is already empty, so jump to ; sups3 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups2 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups2 STA Y1TB+223,Y ; Store the updated y-coordinate back in the Y1TB table .sups3 DEY ; Decrement the loop counter in Y BNE sups1 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDY #32 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 223 down to ; entry 192 .sups4 LDA Y1TB+191,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups6 ; If A = 0 then this entry is already empty, so jump to ; sups6 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups5 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups5 STA Y1TB+191,Y ; Store the updated y-coordinate back in the Y1TB table .sups6 DEY ; Decrement the loop counter in Y BNE sups4 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDY #32 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 191 down to ; entry 160 .sups7 LDA Y1TB+159,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups9 ; If A = 0 then this entry is already empty, so jump to ; sups9 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups8 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups8 STA Y1TB+159,Y ; Store the updated y-coordinate back in the Y1TB table .sups9 DEY ; Decrement the loop counter in Y BNE sups7 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDY #32 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 159 down to ; entry 128 .sups10 LDA Y1TB+127,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups12 ; If A = 0 then this entry is already empty, so jump to ; sups12 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups11 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups11 STA Y1TB+127,Y ; Store the updated y-coordinate back in the Y1TB table .sups12 DEY ; Decrement the loop counter in Y BNE sups10 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDY #32 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 127 down to ; entry 96 .sups13 LDA Y1TB+95,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups15 ; If A = 0 then this entry is already empty, so jump to ; sups15 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups14 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups14 STA Y1TB+95,Y ; Store the updated y-coordinate back in the Y1TB table .sups15 DEY ; Decrement the loop counter in Y BNE sups13 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDY #32 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 95 down to ; entry 64 .sups16 LDA Y1TB+63,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups18 ; If A = 0 then this entry is already empty, so jump to ; sups18 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups17 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups17 STA Y1TB+63,Y ; Store the updated y-coordinate back in the Y1TB table .sups18 DEY ; Decrement the loop counter in Y BNE sups16 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDY #32 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 63 down to ; entry 32 .sups19 LDA Y1TB+31,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups21 ; If A = 0 then this entry is already empty, so jump to ; sups21 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups20 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups20 STA Y1TB+31,Y ; Store the updated y-coordinate back in the Y1TB table .sups21 DEY ; Decrement the loop counter in Y BNE sups19 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDY #32 ; Set Y as a loop counter so we work our way through ; the y-coordinates in Y1TB, from entry 31 down to ; entry 0 .sups22 LDA Y1TB-1,Y ; Set A to the Y-th y-coordinate in this section of the ; Y1TB table BEQ sups24 ; If A = 0 then this entry is already empty, so jump to ; sups24 to move on to the next entry CLC ; Otherwise this is a valid y-coordinate, so add W2Y to ADC #(W2Y<<4 + W2Y) ; the high nibble and W2Y to the low nibble, so we add ; W2Y to both of the y-coordinates stored in this entry BCC sups23 ; If the addition overflowed, set A = 0 to remove this LDA #0 ; entry from the table, as the line no longer fits CLC ; on-screen (we also clear the C flag, though this ; doesn't appear to be necessary) .sups23 STA Y1TB-1,Y ; Store the updated y-coordinate back in the Y1TB table .sups24 DEY ; Decrement the loop counter in Y BNE sups22 ; Loop back until we have processed all the entries in ; this section of the Y1TB table SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 RTS ; Return from the subroutine
Name: ProjectScrollText [Show more] Type: Subroutine Category: Combat demo Summary: Project a scroll text coordinate onto the screen
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawScrollFrame calls ProjectScrollText * DrawScrollFrame calls via RTS10

Calculate the following: (A X) = 128 + 256 * (A - 32) / Q
Arguments: A The x-coordinate to project
Other entry points: RTS10 Contains an RTS
.ProjectScrollText SEC ; Set A = A - 32 SBC #32 BCS proj1 ; If the subtraction didn't underflow then the result is ; positive, so jump to proj1 EOR #$FF ; Negate A using two's complement, so A is positive ADC #1 JSR LL28 ; Call LL28 to calculate: ; ; R = 256 * A / Q LDA #128 ; Set (A X) = 128 - R SEC ; SBC R ; Starting with the low bytes TAX LDA #0 ; And then the high bytes SBC #0 ; ; This gives us the result we want, as 128 + R is the ; same as 128 - (-R) RTS ; Return from the subroutine .proj1 JSR LL28 ; Call LL28 to calculate: ; ; R = 256 * A / Q LDA R ; Set (A X) = R + 128 CLC ; ADC #128 ; Starting with the low bytes TAX LDA #0 ; And then the high bytes ADC #0 .RTS10 RTS ; Return from the subroutine
Name: DrawScrollFrame [Show more] Type: Subroutine Category: Combat demo Summary: Draw one frame of the scroll text Deep dive: The NES combat demo
Context: See this subroutine on its own page References: This subroutine is called as follows: * DrawScrollFrames calls DrawScrollFrame

This routine draws each character on the scroll text by taking the character's line coordinates from the from the X1TB, X2TB and Y1TB line coordinate tables (i.e. X1, Y1, X2 and Y2) and projecting them onto a scroll that disappears into the distance, like the scroll text at the start of Star Wars. For a character line from (X1, Y1) to (X2, Y2), the calculation gives us coordinates of the line to draw on-screen from (x1, y1) to (x2, y2), as follows: 256 * (X1 - 32) x1 = XX15(1 0) = 128 + ---------------------------- Y1 * 8 + 31 - scrollProgress 256 * (X2 - 32) x2 = XX15(5 4) = 128 + ---------------------------- Y2 * 8 + 31 - scrollProgress 37 - Y1 * 2 + scrollProgress / 4 y1 = XX15(3 2) = 72 + ---------------------------------- 2 * (31 + Y1 * 8 - scrollProgress) 37 - Y2 * 2 + scrollProgress / 4 y2 = XX12(1 0) = 72 + ---------------------------------- 2 * (31 + Y2 * 8 - scrollProgress) The line then gets clipped to the screen by the CLIP_b1 routine and drawn.
.DrawScrollFrame JSR GetScrollDivisions ; Set up the division calculations for the scroll text ; and store then in the 16 bytes at BUF and the 16 bytes ; at BUF+16 LDY #$FF ; We are about to loop through the 240 bytes in the line ; coordinate tables, so set a coordinate counter in Y ; to start from 0, so set Y = -1 so the INY instruction ; at the start of the loop sets Y to 0 for the first ; coordinate .drfr1 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 INY ; Increment the coordinate counter in Y CPY #240 ; If Y = 240 then we have worked our way through all the BEQ RTS10 ; line coordinates, so jump to RTS10 to return from the ; subroutine LDA Y1TB,Y ; Set A to the y-coordinate byte that contains the start ; and end y-coordinates in the bottom and high nibbles ; respectively BEQ drfr1 ; If both y-coordinates are zero then this entry doesn't ; contain a line, so jump to drfr1 to move on to the ; next coordinate ; We now set up the following, so we can clip the line ; to the screen before drawing it: ; ; XX15(1 0) = X1 as a 16-bit coordinate (x1_hi x1_lo) ; ; XX15(3 2) = Y1 as a 16-bit coordinate (y1_hi y1_lo) ; ; XX15(5 4) = X2 as a 16-bit coordinate (x2_hi x2_lo) ; ; XX12(1 0) = Y2 as a 16-bit coordinate (y2_hi y2_lo) ; ; We calculate these values from the X1TB, X2TB and Y1TB ; line coordinate values for the line we want to draw ; (where Y1TB contains the Y1 and Y2 y-coordinates, one ; in each nibble) AND #$0F ; Set Y1 to the low nibble of A, which contains the STA Y1 ; y-coordinate of the start of the line, i.e. Y1 TAX ; Set X to the y-coordinate of the start of the line, Y1 ASL A ; Set A = A * 8 - scrollProgress ASL A ; = Y1 * 8 - scrollProgress ASL A SEC SBC scrollProgress BCC drfr1 ; If the subtraction underflowed then this coordinate is ; not on-screen, so jump to drfr1 to move on to the next ; coordinate STY YP ; Store the loop counter in YP, so we can retrieve it at ; the end of the loop LDA BUF+16,X ; Set Q to the entry from BUF+16 for the y-coordinate in STA Q ; X (which we set to Y1 above), so: ; ; Q = X * 8 + 31 - scrollProgress ; = Y1 * 8 + 31 - scrollProgress LDA X1TB,Y ; Set A to the x-coordinate of the start of the line, X1 JSR ProjectScrollText ; Set (A X) = 128 + 256 * (A - 32) / Q ; = 128 + 256 * (X1 - 32) / Q ; ; So (A X) is the x-coordinate of the start of the line, ; projected onto the scroll text so coordinates bunch ; together horizontally the further up the scroll text ; they are STX XX15 ; Set the low byte of XX15(1 0) to X LDX Y1 ; Set X = Y1, which we set to the y-coordinate of the ; start of the line, i.e. Y1 STA XX15+1 ; Set the high byte of XX15(1 0) to A, so we have: ; ; XX15(1 0) = (A X) ; 256 * (X1 - 32) ; = 128 + ---------------------------- ; Y1 * 8 + 31 - scrollProgress LDA BUF,X ; Set the low byte of XX15(3 2) to the entry from BUF+16 STA XX15+2 ; for the y-coordinate in X (which we set to Y1 above) LDA #0 ; Set the high byte of XX15(3 2) to 0 STA XX15+3 ; ; So we now have: ; ; 37 - Y1 * 2 + scrollProgress / 4 ; XX15(3 2) = 72 + ---------------------------------- ; 2 * (31 + Y1 * 8 - scrollProgress) LDA Y1TB,Y ; Set A to the combined y-coordinates of the start and ; end of the line, Y1 and Y2, with one in each nibble LSR A ; Set the high byte of XX12(1 0) to the high nibble of LSR A ; A, which contains the y-coordinate of the end of the LSR A ; line, i.e. Y2 LSR A STA XX12+1 TAX ; Set X to the y-coordinate of the end of the line, Y2 ASL A ; Set A = XX12+1 * 8 - scrollProgress ASL A ; = Y2 * 8 - scrollProgress ASL A SEC SBC scrollProgress BCC drfr1 ; If the subtraction underflowed then this coordinate is ; not on-screen, so jump to drfr1 to move on to the next ; coordinate LDA BUF,X ; Set the low byte of XX12(1 0) to the entry from BUF+16 STA XX12 ; for the y-coordinate in X (which we set to Y2 above) LDA #0 ; Set X to XX12+1, which we set to Y2 above, so X = Y2 LDX XX12+1 STA XX12+1 ; Set the high byte of XX12(1 0) to 0 ; ; So we now have: ; ; 37 - Y2 * 2 + scrollProgress / 4 ; XX12(1 0) = 72 + ---------------------------------- ; 2 * (31 + Y2 * 8 - scrollProgress) LDA BUF+16,X ; Set Q to the entry from BUF+16 for the y-coordinate in STA Q ; X (which we set to Y2 above), so: ; ; Q = X * 8 + 31 - scrollProgress ; = Y2 * 8 + 31 - scrollProgress SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDA X2TB,Y ; Set A to the x-coordinate of the end of the line, X2 JSR ProjectScrollText ; Set (A X) = 128 + 256 * (A - 32) / Q ; = 128 + 256 * (X1 - 32) / Q ; ; So (A X) is the x-coordinate of the end of the line, ; projected onto the scroll text so coordinates bunch ; together horizontally the further up the scroll text ; they are STX XX15+4 ; Set XX15(5 4) = (A X) STA XX15+5 ; 256 * (X2 - 32) ; = 128 + ---------------------------- ; Y2 * 8 + 31 - scrollProgress JSR CLIP_b1 ; Clip the following line to fit on-screen: ; ; XX15(1 0) = x1 as a 16-bit coordinate (x1_hi x1_lo) ; ; XX15(3 2) = y1 as a 16-bit coordinate (y1_hi y1_lo) ; ; XX15(5 4) = x2 as a 16-bit coordinate (x2_hi x2_lo) ; ; XX12(1 0) = y2 as a 16-bit coordinate (y2_hi y2_lo) ; ; and draw the line from (X1, Y1) to (X2, Y2) once it's ; clipped LDY YP ; Set Y to the loop counter that we stored in YP above JMP drfr1 ; Loop back to drfr1 to process the next coordinate