************************************************* * code to compute e constant to 287273 digits * Chris Lomont Jul 2007 www.lomont.org ************************************************* SCREENSIZE equ $240 * screensize in bytes TEMP equ $8000+SCREENSIZE * 2 bytes, temp storage CARRY equ TEMP+2 * 1 byte for carry amount MODULUS equ CARRY+1 * 2 byte modulus PAGEVAL equ MODULUS+2 * 1 byte for current memory page $30-$3F TOPBYTE equ PAGEVAL+1 * 1 byte for extended 3 byte math org 16384 * program start for running mode - on entry U=Y=D=0 and S points past bytes to erase app pshs y,d,u * set 6 bytes pshs y,d,u * set 6 bytes ldy #$8002 * Y holds next digit pos at all times * here is the digit loop - start by computing the next digit by processing all 128K of RAM infloop ldx #61441 * initial modulus for 15 pages - modified by loader stx MODULUS ldx #0 * start past code on page $30 - modified by loader ldb #$30 * start on page $30 stb PAGEVAL clr CARRY * start with no carry byte npage stb #$FFA0 * next page in, X must point to start * Compute 10 * value in ,X xloop clr TOPBYTE * 0 the high byte ldd ,x * the value, need 10*X rolb rola * 2*X bcc > * overflow? inc TOPBYTE * if so, increment top byte ! std TEMP * save this rolb rola * 4*X bcc > inc TOPBYTE ! rolb rola * 8*X bcc > inc TOPBYTE ! addd TEMP * 8*X + 2*X = 10*X bcc > inc TOPBYTE ! std TEMP * now add in the carry clra ldb CARRY addd TEMP bcc timesok inc TOPBYTE timesok clr CARRY * erase this, and prepare to refill it * now D holds 10*X+CARRY, must reduce mod MODULUS reduce tst TOPBYTE * if not zero, must reduce mod M beq reduce2 inc CARRY subd MODULUS * reduce bcc reduce dec TOPBYTE bra reduce reduce2 cmpd MODULUS bmi reduced subd MODULUS inc CARRY bra reduce2 reduced std ,x++ * the new x value ldd MODULUS subd #1 std MODULUS * new modulus cmpx #$2000 * new page? bne xloop * no, do the next pass inc PAGEVAL * get the next page to process ldb PAGEVAL ldx #0 * reset the pointer cmpb #$40 * see if done blt npage * at this point, CARRY has a value 0-9 for the next digit * now write to screen ldb CARRY addb #$30 * value ! stb ,y+ cmpy #$8000+256 * last digit position on screen blt > * wraparound - do a page increment ldy #$8000 * top digit ! ldb #$2A * multiply * symbol stb ,y * show space * increment digit counter * uses registers B,X ldx #$81FF-7 * last digit ! ldb #$3A * overflow inc ,x cmpb ,x * overflow test bgt bound * no overflow, done ldb #$30 stb ,x leax -1,x cmpx #$8200-32 * todo - check for largest digit and stop bgt < * compare to final digit, stop if hit match bound ldx #$8200-6 ldu #$8200-13 ldd ,x++ cmpd ,u++ bne pause ldd ,x++ cmpd ,u++ bne pause ldd ,x++ cmpd ,u++ bne pause bra bound ** check for pause and do pause 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 pause * loop if key down - 0 bit means not down nxtpass lbra infloop ************ The end of the main application, here is where digits start in memory even * make sure aligned on even address data fdb 1,1,1,1,1,1,1,1,1,1 * initialized words ******* initial screen ********************************** *****************12345678901234567890123456789012******** msg fcc "2. " * 1 fcc " " * 2 fcc " " * 3 fcc " " * 4 fcc " " * 5 fcc " " * 6 fcc " " * 7 fcc " " * 8 fcc "--------------------------------" * 9 fcc "Computing Euler's natural base e" * 10 fcc "to 287273 digits,by Chris Lomont" * 11 fcc " WWW.LOMONT.ORG, 2007 " * 12 fcc " A CoCo3 record for e!!! " * 13 fcc " Press and hold a key to pause. " * 14 fcc "Check out my site for more items" * 15 fcc "Digits completed 000001/287300" * 16 fcc "e is approx 2.718281828459045..." * 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, 63 for RGB todo sta $FFB8 * foreground *** initialize GIME memory pages $31 through $3F lda #$31 * pages $31-$3F ldy #1 clrmem sta $FFA0 * map to addresses $0000-$1FFF ldx #0 ! sty ,x++ cmpx #$2000 blt < inca cmpa #$40 blt clrmem lda #$80 tfr a,dp * set DP for smaller, faster code - todo - use well * initialize page $30 except for vidmem and program in use, page $30 at $8000 right now * this has to be aligned to word, and above code needs set leas final,pcr * prepare for cleaning with PSHS, even aligned tfr s,d andb #1 * see if even beq > * was even, nothing to do leas 1,s * bump one place ! tfr s,d * compute initial modulus, overwrite code ldd #8192 * bytes per page subd #SCREENSIZE+data-app * bytes left to work with addd #1 * round up rora rorb * divide by two - number of words free addd #61440+1 * # of words in other pages + offset of 1 std TEMP+9 * overwrite modulus code ldd #SCREENSIZE+data-app std TEMP+15 * overwrite memory start ldd #$0001 * initial value for some registers tfr d,y * store 1 in each word tfr d,u * leax final,pcr * clear rest of page ! std ,x++ cmpx #$A000 blt < leax data,pcr * start clearing here clrstop nop ! std ,x++ * must store 2 bytes at a time cmpx #$8000+SCREENSIZE+clrstop-app blt < lbra app * 3 bytes run the main application even final end entrypt * set BASIC exec address ************************************************* * End of file *************************************************