************************************************* * code to compute Thue Morse constant to > 10^300000 digits * Chris Lomont Jul 2007 www.lomont.org ************************************************* SCREENSIZE equ $240 TEMP equ $8000+SCREENSIZE * place to store vars, about 9 bytes SLOW equ 0 * define to be 0 or 1 for fast or slow version org 16384 * program start for running mode - on entry U=Y=D=$FFFF and S points past bytes to erase app pshs y,d,u * set 6 bytes pshs y,d,u * set 6 bytes ldy #$8000 * Y holds next digit pos at all times clra * A holds parity - todo use lda for later debugging * here is the infinite loop - start by computing the next parity infloop ldx #SCREENSIZE+zeros-app * start past code on page $30 ldb #$30 if SLOW dly ldu #8000 * delay loop in SLOW version ! leau -1,u cmpu #0 bne < endif npage stb #$FFA0 * next page in, X must point to start carry eora ,x inc ,x eora ,x+ * A has parity change cmpx #$2000 beq bound * out of bounds tst -1,x * beq carry * we have carry, continue bound tst -1,x bne done ldx #0 * start at top incb cmpb #$40 blt npage * go to next page and continue * at this point, A holds parity in the byte, so pack down to the low bit done ldb #7 sta TEMP * ! lsra eora TEMP decb bne < ldb #$30 * prepare to output a digit - text digit 0 anda #1 * now A has parity in low bit beq > incb * text digit 1 * now write to screen ! stb ,y+ cmpy #$8000+256 * last digit position on screen bge > * wraparound - do a page increment if SLOW ldb #$2A * multiply * symbol stb ,y * show space endif bra infloop ! ldy #$8000 * top digit if SLOW ldb #$2A * multiply * symbol stb ,y * show space endif ** check for pause and do ! ldb $FF00 * read output * comb * reverse bits to high to see what was pressed * andb #$7F * strip unused high bit, all 0 means no keys down incb * todo - may fail with joysticks? bne < * loop if key down - 0 bit means not down * increment page counter * uses registers B,X ldx #$81FF * last digit ! ldb #$3A * overflow inc ,x cmpb ,x * overflow test bgt infloop * no overflow, done ldb #$30 stb ,x leax -1,x cmpx #$8200-32 bgt < bra infloop ************ The end of the main application, here is where digits start in memory zeros fzb 10 * zeroed bytes endapp fzb 10 * NOTE: Fast version gives * first counting byte is 02AA on page $30, * giving $2000-$02AA+1 + 15*($2000) = 130391 bytes, s0 * this can compute 2^(130391*8) digits, approximately * 10^314013 digits! * * Slow version gives * first counting byte is 02BD on page $30, * giving $2000-$02BD+1 + 15*($2000) = 130372 bytes, s0 * this can compute 2^(130372*8) digits, approximately * 10^313967 digits! ******* initial screen ********************************** *****************12345678901234567890123456789012******** msg fcc " " * 1 fcc " " * 2 fcc " " * 3 fcc " " * 4 fcc " " * 5 fcc " " * 6 fcc " " * 7 fcc " " * 8 fcc "--------------------------------" * 9 if SLOW fcc "Thue-Morse constant to 10^313967" * 10 endif if SLOW=0 fcc "Thue-Morse constant to 10^314013" * 10 endif fcc "digits in base 2,by Chris Lomont" * 11 fcc " WWW.LOMONT.ORG, 2007 " * 12 fcc " A CoCo3 digit record !!! " * 13 fcc " Press and hold a key to pause. " * 14 fcc " Each page is 256 digits. Page# " * 15 fcc "00000000000000000000000000000000" * 16 fcc " " * 17 fcc "--------------------------------" * 18 * Steps: * 1. start initialization - speed, interrupts, mem page, video * 2. copy program to high memory and jump there * 3. erase uneeded part of program * 4. jump to running mode * entry point for Step 1 and EXEC entrypt orcc #$50 * turn off interrupts sta $FFD9 * high speed poke lda #$68 * 0b0110 1000 = 0x40 sta $FF90 * enable MMU, disable GIME interrupts lda #$30 * GIME page $30 - bottom 128K page sta $FFA4 * map to CPU $8000 * copy prog to after video ram and jump there ldx #$8000+SCREENSIZE leay app,pcr ! lda ,y+ sta ,x+ cmpx #$A000 * plenty of size copied - todo dynamic sized? blt < lbra #begin-app+$8000+SCREENSIZE * jump to start in $8000 block begin nop * after prog copied, jump here, todo - make useful * prepare keyboard for reading keys clr $FF01 * clear control register A clr $FF03 * clear control register B clr $FF00 * set side PIA0 side A to input ldd #$FF34 sta $FF02 * set PIA0 side B to output stb $FF01 stb $FF03 clrb * ground all bits stb $FF02 * set column strobe * load screen ldx #$8000 * new screen location leay msg,pcr * get initial screen msgloop lda ,y+ ! sta ,x+ cmpx #$8000+SCREENSIZE bne msgloop * set videopage to $8000 * sta $FFC6 * set text screen start to CPU $8000 * sta $FFC8 * todo - do after screen drawn there * sta $FFCA * sta $FFCC * sta $FFCE * sta $FFD0 * sta $FFD3 * set CoCo3 video mode and text start to $8000 - page $30 * set CoCo3 video mode and text start to $8000 - page $30 lda #$26 * 0b0010 0110 - text, color, 12 lines per char sta $FF98 * set video mode lda #0 * 0b00000000 sta $FF99 * video resolution lda #$00 sta $FF9C * Vertical scroll to 0 ldd #$C000 * $60000/8 std $FF9D * set white letters on black screen? clra * black sta $FFB0 * background black lda #48 * 48 for CMP, 64 for RGB todo sta $FFB8 * foreground *** clear GIME memory pages $31 through $3F lda #$31 * pages $31-$3F ldb #$FF clrmem sta $FFA0 * map to addresses $0000-$1FFF ldx #0 ! stb ,x+ cmpx #$2000 blt < inca cmpa #$40 blt clrmem lda #$80 tfr a,dp * set DP for smaller, faster code * clear page $30 except for vidmem and program in use, page $30 at $8000 right now ldd #$FFFF * init some registers ldy #$FFFF ldu #$FFFF leas final,pcr * prepare for clearing with PSHS leax final,pcr * clear rest of page ! std ,x++ cmpx #$A000 blt < leax zeros,pcr * start clearing here clrstop nop ! std ,x++ * clear cmpx #$8000+SCREENSIZE+clrstop-app blt < lbra app * 3 bytes run the main application final end entrypt * set BASIC exec address ************************************************* * End of file *************************************************