( driver.4th - FLASH code for TAPS-NG ( 20 May 2007 cold hex ( begin by finding a starting point in flash for the code : flblank f800 f800 8000 do ff i 10 over + swap do i c@ and loop ff = if drop i leave then 100 +loop dup f800 = if cr ." flash is full" cr else dup cr u. cr then ; flblank fdp ! forget flblank ( ------------------------------------------------------------------- ( next, re-define some words to put code in flash, data in exram ( begin by re-defining ';' to include flword : ; [compile] ; flword ; immediate flword ( now re-define constant def'ns to put addresses in FLASH ( that point to EXRAM : constant constant flword ; : is constant ; : fis fconstant flword ; : ccreate here constant ; : variable ccreate 2 allot ; : 2variable ccreate 4 allot ; : fvariable 2variable ; exram ( hopefully, this is redundant decimal variable source 2variable fadr variable killme variable newprog variable checksum ( registers hex 0056 is portp ( port p data register 0057 is ddrp ( port p data direction register 006f is portad ( on-board adc data register 00ae is portt ( port t data register 00af is ddrt ( port t data direction register 00fe is pdlc ( port dlc data register 00ff is ddrdlc ( port dlc data direction register 00c0 is baud-reg ( serial baud rate reg - 16 bits 00d0 is spocr1 ( spi 1 control register 00d1 is spocr2 ( spi 2 control register 00d2 is spobr ( spi baud rate register 00d3 is sposr ( spi status register 00d5 is spodr ( spi data register 00d6 is ports ( port s data register 00d7 is ddrs ( port s data direction register 0080 is tios ( timer i/o select register 0084 is tcntr ( timer counter register 0086 is tscr ( timer system control register 008b is tctl4 ( timer control register 4 008d is tmsk2 ( timer interrupt mask register 2 008e is tflg1 ( timer interrupt flag register 1 008f is tflg2 ( timer interrupt flag register 2 0090 is tc0 ( timer input compare register 1 0091 is tc1 ( timer input compare register 2 e00 is mycals ( eeprom region for ops parms 7e00 is cfbase ( memory-mapped window to cf ram ( addresses decoded to r/w to cf: $7ea0 - 7eaf 7ea0 is cfdata ( byte-port to flash 7ea1 is cferror ( read-only 7ea1 is features ( write only 7ea2 is sctrcnt ( sector count register 7ea3 is lba0 ( lba0:7 = sector number 7ea4 is lba1 ( lba8:15 = cylinder low 7ea5 is lba2 ( lba16:23 = cylinder high 7ea6 is head ( byte value for head count head is lba3 ( alternate name 7ea7 is status ( read only 7ea7 is command ( write only 7eae is dev-ctrl ( write only 7e90 is config ( r/w config register 7e96 is socket ( r/w socket & copy register decimal -1 is true 0 is false ( ==================== power control ============================ hex code-sub trans-off 4dfe , 20 c, ( bclr pdlc,#$20 ; disable trans power 3d c, ( rts end-code flword code-sub inst-off 4dfe , 40 c, ( bclr pdlc,#$40 ; disable insts power 3d c, ( rts end-code flword code-sub spi-off 4dd0 , 40 c, ( bclr spocr1,#$40 ; disable spi 3d c, end-code flword code-sub iob-off 180b , 02 c, portp , ( movb #$0a,portp ; power off 3d c, ( rts end-code flword : power-off trans-off inst-off ; ( ===================== compact flash ram routines ==================== code-sub read-cf 3b c, ( pshd ; save D accumulator 34 c, ( pshx ; save X register ec40 , ( ldd 0,y ; read source address 7c c, source , ( std source 02 c, ( iny 02 c, ( iny ; adjust stack pointer 35 c, ( pshy ( ; Setup Sector Address values 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high 8601 , ( ldaa #01 7a c, sctrcnt , ( staa sctrcnt cd c, FADR , ( ldy #FADR ; point Y at FLASH address 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high a643 , ( ldaa 3,y ; LB of address 7a c, lba0 , ( staa lba0 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high a642 , ( ldaa 2,y ; ML byte of address 7a c, lba1 , ( staa lba1 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high a641 , ( ldaa 1,y ; set Low byte of ADR 7a c, lba2 , ( staa lba2 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high a640 , ( ldaa 0,y ; set High byte of ADR 840f , ( anda #$0f ; only use low 4 bits 8ae0 , ( ora #$e0 ; set CF1, LBA enabled 7a c, lba3 , ( staa lba3 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high 8620 , ( ldaa #read 7a c, command , ( staa command ; set mode to WRITE ( Write a block of 512 bytes into RAM, checking RDY=1 before each write fd c, source , ( ldy source ; Y points at data source c600 , ( ldb #256 ; B counts words ( wordmove: 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high b6 c, cfdata , ( ldaa cfdata ; read a byte 6a40 , ( staa 0,y ; save to BUFFER 4f6f , 01fc , ( brclr portad,#$01,* ; ensure RDY is high b6 c, cfdata , ( ldaa cfdata 6a41 , ( staa 1,y 0202 , ( iny 2X 04 c, 31e9 , ( dbne b,wordmove ; continue till all are moved 31 c, ( puly 30 c, ( pulx ; recover registers 3a c, ( puld ; and accumulator 3d c, ( rts end-code flword ( ======================= forth code ================================= : wait-test 15000 0 do i drop loop ; ( ------------------- compact flash ram routines ----------------------- hex : busy? ( - ) 100 0 do status c@ ( read status register 80 and ( mask bit 7 0= ( is it clear? if leave then ( if so, quit loop loop ; : setup-cf busy? 01 features c! ( enable 8-bit data transfer busy? fadr c@ lba3 c! busy? fadr 1+ c@ lba2 c! busy? fadr 2 + c@ lba1 c! busy? fadr 3 + c@ f0 and e0 or lba0 c! busy? ef command c! ( execute commands just loaded busy? ; : inc-sector ( - ) ( increment sector address by one fadr 2@ 1. d+ fadr 2! ; ( Read 56 sectors into RAM from CF; start sector in FADR : read56 ( - ) 38 0 do ." ." 1000 200 I * + read-cf inc-sector loop cr ; ( Compute checksum over program space and store program to CF hex : byte-checksum ( - sum ) 0 checksum ! 4b00 3b00 do i @ checksum +! loop checksum @ ; ( ------------------ initialization routines ------------------------ hex : init exram ( hopefully redundant 02 portp c! ( set cpu peripheral power off 00 pdlc c! ( set external power off 00 portt c! ( set mux to ch 0, gain to 0 ff ddrp c! ( set port p ddr 7e ddrdlc c! ( set port dlc ddr fc ddrt c! ( set port t ddr; bits 0-1 are inputs fc tios c! ( set port t tios same 86 c@ 80 and 86 c! ( set ten bit of tscr, start timer 01 tios c! ( set output compare timer 1 power-off ( disable external board power iob-off spi-off 0c dev-ctrl c! ( soft reset of cf 08 dev-ctrl c! setup-cf ( setup the compact-flash card false killme ! ( preset flags false newprog ! exram ( enable external RAM decimal cr ; hex : load-code cr ." loading code into RAM ... " mycals @ ( read mode code 0 max 5 min ( make sure valid range dup mycals ee! dup 0 = if ( is it cast mode? cr ." loading CAST MODE code " 100. fadr 2! read56 then dup 1 = if ( is it ext sounder mode? cr ." loading EXT SOUNDER MODE code " 200. fadr 2! read56 then dup 2 = if ( is it no tvg sounder mode? cr ." loading NO TVG SOUNDER MODE code " 300. fadr 2! read56 then dup 3 = if ( is it int sounder mode? cr ." loading INSTRUMENT MODE code " 400. fadr 2! read56 then dup 4 = if ( is it raw cast mode? cr ." loading RAW CAST MODE code " 500. fadr 2! read56 then 5 = if ( is it test mode? cr ." loading TEST MODE code " 600. fadr 2! read56 then 1000 @ execute ; : menu ." MODES " cr ." 0 CAST" cr ." 1 EXTERNAL SOUNDER " cr ." 2 NO TVG SOUNDER " cr ." 3 INSTRUMENT" cr ." 4 RAW CAST" cr ." 5 TEST" cr ; hex : change-mode cr ." Current mode is " mycals @ dup . ." - " dup 0 = if ." cast" then dup 1 = if ." external sounder" then dup 2 = if ." no-tvg external sounder" then dup 3 = if ." instrument" then dup 4 = if ." raw cast" then 5 = if ." test mode" then cr ." Do you want to change modes (y/n)? " key 59 = swap 79 = or ( Y or y? if cr menu cr ." Enter new mode code: " key dup emit cr 30 - mycals ee! ( save new mode code load-code ( and load code from CF else cr then ; hex : main ( - ) init ." press any key to change modes, k to exit program" 7fff 0 do 10 0 do i drop loop ( kill some time ?terminal if key dup emit cr dup 4b = swap 6b = or ( K or k? if ." Do you want to exit to FORTH [y/n]? " key dup emit cr dup 59 = swap 79 = or ( Y or y? if true killme ! ( set kill flag 0 1002 ! ( clear checksum leave ( and end loop then else true newprog ! ( set newprog flag leave ( and end loop then then loop cr newprog @ if change-mode ( select new mode, zero checksum then ( Now check to see if loaded program is ok to run 1002 @ byte-checksum = ( checksums agree? if 1000 @ execute ( yes, run existing code then ; ( driver.4th - 20 May 2007 ( Check for valid checksum at $1002, executes @ $1000 if ok ( Otherwise, loads operating code from CF to RAM hex a44a d00 ee! ( set auto-run flag in eeprom ' main cfa d02 ee!