* GS ALLIANCE'S BORDER SCROLL * BY MISTER Z * This routine is now : --> PUBLIC DOMAIN <-- * Not long ago, Joe Hack of ECC released a demo which included * a border scroll similar to this one.... * This demo also contained a lot of insults toward well-known members * of the Apple IIgs programming/cracking scene, trying to explain, that he, * JOE HACK, was the best around.... * I guess it's time to clear certain points.... * JOE HACK ! You know perfectly well that without my explanations * you would never have been able to do it.... * You wanted to talk about it, and I was foolish enough to show you * everything.... well, I guess I'm not the first one to make the mistake * with you.... you see, what hurts me most is not the fact that you hurried * to release it before we did, or even that you don't give proper credits, * it's the fact that you use this discovery to lower the other groups.. * all this is fake... I didn't want to believe certain rumors about you, but * now I'm becoming convinced that you ripped and modified most of the stuff * you're putting out.... * I don't think you made the right choice, cause now you'll probably have * the Europeans on your back, as well as most of the americans... * Learning to program on your own and a little bit of modesty wouldn't * hurt you... Hope we'll be able to teach you a lesson... * Mr.Z * Back to the routine : it scrolls characters in the border * Each character is made up of 3 by 7 elements * Each element is approx. 18 pixels large * The scroll moves to the left at a speed of approx 6 pixels/VBL * The way it works is very simple : each line take 65 miscroseconds * to be refreshed, so, all we have to do, is to force the GS to run at * at 1 MHZ (we'll see later why), to get synchronized with the VGC at * the beginning of a line and then to change to border color as often * as possible, with a timing of 65 cycles per line... * Let's take the steps one by one.... * The speed of 1 mhz is required, because at a higher speed, we cannot * know how many cycles an instruction will take !!!!! * As crazy as it may sound, it's true ! * The problem comes from memory refreshing : the GS is build up * in such a way, that if the processor tries to access a memory location * being refreshed, it takes one more cycle !!! * This problem doesn't exist at 1 mhz, for question of compatibility * with the Mega II and the hardware.... * Synchronization : first of all, we get synchronized vertically, using * $C02E and waiting for a particular value... Then, getting the horizontal * synchronization is a little bit harder, waiting for a particular $C02F * value won't help us much, since this counter runs faster than our * instructions ! (LDA + CMP + BNE equals at least 8 cycles...) * so, the only solution is to read $C02F, and depending on its value, * to have different timing routines, so that, at the end, a LDA $C02F * would always give the same value... * Size of shapes : one line takes 65 cycles, so the shortest element * (STA zp) represents 3/65th of a line, which approx. corresponds to 18 * SHGR pixels.... Now, we can move a whole line left with a step of 6 * pixels only by letting the routine as it is and just wait one less cycle * before jumping into it (1 cycle = 1/65th of a line = 6 pixels) * So, the complete scroll works this way : move 3 times the bottom border * left just by changing pre-temporisation, then move the code that * generate the letters itself one step left (=18 pixels), restore * temporisation to its first value and restart the cycle, thus making * a smooth 6 by 6 pixels border scroll * One last word, if you use this routine with a SHGR screen above, make * sure you go back to text ($C029:41) long enough before storing colors * on the border else you might have 'bleeding' letters, due to the change * of synchro signal coming from the VGC... also, you have to go back * to text, else weird pixels might appear at rightmost position of the * letters..... * I guess that with this kind of info, a lot of people * could have made the ECC demo... * later, * Mr.Z ORG $1000 MX %11 STOP = $00 BLANK MAC LUP 21 STZ $34 --^ NOP EOM CONV MAC LDY #$64 CMP #$11 BNE STOY LDY #$86 STOY TYA EOM SEC XCE JSR $FC58 CLC XCE SEP #$30 STZ $C034 LDA #$F6 STA $C022 STZ POS STZ STOP LDA #$03 STA TIMING REP #$30 ; Build a table with the adress of all chars LDX #$00 LDA #$0000 ]lp STA CHARAD2,X CLC ADC #$15 INX INX CPX #$68 BNE ]lp LDA #$0002 ; Timing for accurate (+/- 6 pixels) STA SHIFT ; Left/Right Position LDA #$0001 ; Width of a single char STA LLEN2 STZ CHARNB SEP #$30 START LDA #$80 ; Must be at 1 mhz !!!! TRB $C036 MAIN JSR VBL3 ; Waits for JSR SCROLLER LDA $C000 BPL MAIN BIT $C010 LDA STOP ; Stop = 1 means no scroll EOR #$01 STA STOP BRA MAIN VBL3 REP #$30 LDA #$C000 ; Direct page at $C000 so that we can adress TCD ; The softswitches with short ZP instructions SEP #$30 LDX #$0F ; Color of the chars ($0F=white) LDA #$E1 VERTLIN CMP $C02E ; Vertical synchro BNE VERTLIN NOP LDA $C02F ; Then, different temporisations depending CMP #$46 ; on the value of $C02F, this ensures that BEQ FIRST ; the 65816 is really synchronized with the VGC CMP #$48 BEQ SECOND CMP #$4A BEQ THIRD CMP #$4C BEQ FOURTH BIT $00 CMP #$47 BEQ FIFTH CMP #$49 BEQ SIXTH CMP #$4B BEQ SEVENTH CMP #$4D BEQ EIGHTH JMP VBL3 FIRST NOP NOP NOP SECOND NOP NOP NOP THIRD NOP NOP NOP FOURTH NOP FIFTH NOP NOP NOP SIXTH NOP NOP NOP SEVENTH NOP NOP NOP EIGHTH NOP NOP NOP NOP BIT $00 GOWAIT JSR TEMPO4 ; Crucial, Depending on the time this routine LN1 STZ $34 ; takes, we'll have the text moved left/right STZ $34 ; of approx +/- 6 pixels (1/64th of the width STZ $34 ; of a complete line, incl. left/right border) STZ $34 STZ $34 STZ $34 ; STZ = a black element STZ $34 ; STX = a colored element (white in this case) STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 ST1 STZ $34 NOP BLANK ; One line out of two is black (choice !) LN2 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 ST2 STZ $34 NOP BLANK LN3 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 ST3 STZ $34 NOP BLANK LN4 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 ST4 STZ $34 NOP BLANK LN5 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 ST5 STZ $34 NOP BLANK LN6 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 ST6 STZ $34 NOP BLANK LN7 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 STZ $34 ST7 STZ $34 STZ $34 ; Make sure the border will end up black REP #$30 ; Restore direct page adress LDA #$0000 TCD SEP #$30 RTS SCROLLER LDA STOP ; Stop = 1 means no scrolling BEQ SCROLLIT RTS SCROLLIT REP #$30 ; SHIFT = left/right fine position of the text LDA SHIFT BMI MV ; Minus --> time to scroll the text itself ASL TAX LDA TEMPOS,X ; else, get the correspoding timing routine adress STA GOWAIT+1 ; and poke it into the synchro routine DEC SHIFT BRL ENDSCRO MV LDA #$0001 ; Restore SHIFT STA SHIFT LDA #TEMPO4 ; And first tempo adress STA GOWAIT+1 SEP #$30 LDX #$00 ; Move every STZ or STX of the synchro routine SCRLEFT LDA LN1+2,X ; one step left... STA LN1,X LDA LN2+2,X STA LN2,X LDA LN3+2,X STA LN3,X LDA LN4+2,X STA LN4,X LDA LN5+2,X STA LN5,X LDA LN6+2,X STA LN6,X LDA LN7+2,X STA LN7,X INX INX CPX #$28 BNE SCRLEFT REP #$30 SEP #$20 LDX CHARNB ; Adress of current char LDA BORCHAR,X ; Get Char 'Bitmap' CONV ; Convert it into STZs and STXs STA ST1 ; Store it LDA BORCHAR+3,X CONV STA ST2 LDA BORCHAR+6,X CONV STA ST3 LDA BORCHAR+9,X CONV STA ST4 LDA BORCHAR+$C,X CONV STA ST5 LDA BORCHAR+$F,X CONV STA ST6 LDA BORCHAR+$12,X CONV STA ST7 REP #$30 INC CHARNB DEC LLEN2 ; finished with this char ? BPL ENDSCRO ; no LDA #$0003 STA LLEN2 ; yes, then restart Charlength SEP #$30 LDX #$64 ; Poke a 6 pixel 'SPACE' STX ST1 STX ST2 STX ST3 STX ST4 STX ST5 STX ST6 STX ST7 BRA GETCHAR2 ; And get the next char (Adress and so on...) MX %00 RESTART2 REP #$30 LDA #TEXT2 ; Back to the beginning STA GETCHAR2+1 NEWONE2 SEP #$30 GETCHAR2 LDA TEXT2 ; 00 means Restart BEQ RESTART2 INCIT2 INC GETCHAR2+1 BNE NOINC2 INC GETCHAR2+2 NOINC2 CMP #$A0 BCS INRANGE3 LDA #$A0 INRANGE3 CMP #$E0 BCC INRANGE4 LDA #$A0 INRANGE4 SEC SBC #$A0 TAX LDA CHARTB,X ; Convert ASCII value-$A0 REP #$30 ; into char position in the set AND #$00FF ASL TAX LDA CHARAD2,X ; Adress table... STA CHARNB ENDSCRO SEP #$30 RTS TEMPO2 NOP ; Two cycles tempo RTS TEMPO3 BIT $00 ; Three cycles tempo RTS TEMPO4 NOP ; Four cycles tempo NOP RTS TEMPOS DA TEMPO2 ; Adress table of the tempo routines DA TEMPO3 DA TEMPO4 CHARTB HEX 00,24,24,31,32,33,34,2A,2E,2F,37,00,2B,2C,28,27 HEX 26,1B,1C,1D,1E,1F,20,21,22,23,29,28,00,00,2B,25 HEX 2F,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F HEX 10,11,12,13,14,15,16,17,18,19,1A,2C,00,2D,00,00 TEXT2 ASC "GS ALLIANCE'S BORDER SCROLL... " ASC "PRESS SPACE TO FREEZE/RELEASE " ASC " MISTER Z, NOVEMBER 1990 " HEX 00 POS DS 2 TIMING DS 2 CHARNB DS 2 LLEN2 DS 2 SHIFT DS 2 DS \ BORCHAR HEX 000000 ; Characters Bitmap HEX 000000 ; 00=black element, 11=colored element HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 111111 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 111100 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 111100 HEX 111111 HEX 110000 HEX 110000 HEX 110000 HEX 110000 HEX 110000 HEX 111111 HEX 111100 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111100 HEX 111111 HEX 110000 HEX 110000 HEX 111111 HEX 110000 HEX 110000 HEX 111111 HEX 111111 HEX 110000 HEX 110000 HEX 111111 HEX 110000 HEX 110000 HEX 110000 HEX 111111 HEX 110000 HEX 110000 HEX 110000 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 111111 HEX 000011 HEX 000011 HEX 000011 HEX 000011 HEX 000011 HEX 000011 HEX 111100 HEX 110000 HEX 110011 HEX 110011 HEX 111100 HEX 111100 HEX 110011 HEX 110011 HEX 110000 HEX 110000 HEX 110000 HEX 110000 HEX 110000 HEX 110000 HEX 111111 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111100 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 111111 HEX 110011 HEX 110011 HEX 111111 HEX 110000 HEX 110000 HEX 110000 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111100 HEX 111111 HEX 110011 HEX 110011 HEX 111111 HEX 111100 HEX 110011 HEX 110011 HEX 111111 HEX 110000 HEX 110000 HEX 111111 HEX 000011 HEX 000011 HEX 111111 HEX 111111 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 001100 HEX 001100 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 001100 HEX 111111 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 001100 HEX 001100 HEX 001100 HEX 111111 HEX 111111 HEX 000011 HEX 001100 HEX 110000 HEX 111111 HEX 111111 HEX 001100 HEX 111100 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 111111 HEX 111111 HEX 000011 HEX 000011 HEX 111111 HEX 110000 HEX 110000 HEX 111111 HEX 111111 HEX 000011 HEX 000011 HEX 111111 HEX 000011 HEX 000011 HEX 111111 HEX 001100 HEX 110000 HEX 110000 HEX 110011 HEX 111111 HEX 000011 HEX 000011 HEX 111111 HEX 110000 HEX 110000 HEX 111111 HEX 000011 HEX 000011 HEX 111111 HEX 001100 HEX 110000 HEX 110000 HEX 111111 HEX 110011 HEX 110011 HEX 111111 HEX 111111 HEX 000011 HEX 000011 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 111111 HEX 110011 HEX 110011 HEX 111111 HEX 110011 HEX 110011 HEX 111111 HEX 111111 HEX 110011 HEX 110011 HEX 111111 HEX 000011 HEX 000011 HEX 111111 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 001100 HEX 000000 HEX 001100 HEX 111111 HEX 110011 HEX 000011 HEX 001100 HEX 001100 HEX 000000 HEX 001100 HEX 111100 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 110011 HEX 111111 HEX 000000 ; / HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 001100 HEX 001100 HEX 000000 HEX 001100 HEX 001100 HEX 000000 HEX 001100 HEX 001100 HEX 000000 HEX 001100 HEX 001100 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 001100 HEX 001100 HEX 110000 HEX 000000 HEX 000000 HEX 000000 HEX 111111 HEX 000000 HEX 000000 HEX 000000 HEX 000000 HEX 001100 HEX 001100 HEX 111111 HEX 001100 HEX 001100 HEX 000000 HEX 000011 HEX 001100 HEX 110000 HEX 110000 HEX 110000 HEX 001100 HEX 000011 HEX 110000 HEX 001100 HEX 000011 HEX 000011 HEX 000011 HEX 001100 HEX 110000 CHARAD2 DS $70