; PROGRAM: Dynamic RAM Basics (DRAM.SRC) ; ; works with "RAS before CAS" DRAMs ; ; Written December 29, 1993 ; Revised February 24, 1996 ; Upon power up or reset, this program starts sampling pin ra.0 and ; recording its state in sequential addresses of a 1Mb dynamic RAM. ; When the DRAM is full, the program plays back the recorded bits ; in a continuous loop. device pins28,xt_osc,wdt_off,turbo,stackx,optionx reset start Sin = ra.0 ; Signal generator input RAS = ra.1 ; DRAM row-address strobe WR = ra.2 ; DRAM write line (0 = write) Dout = ra.3 ; DRAM data line CAS = rc.3 ; DRAM column-address strobe adrb_lo = rb ; Low bits of address bus adrb_hi = rc ; High bits of address bus Din = rc.2 ; DRAM Q line Sout = rc.5 ; Signal out to speaker org 8 ; Start of available RAM r_ctr ds 1 ; Refresh counter row_lo ds 1 ; Eight LSBs of row address row_hi ds 1 ; Two MSBs of row address col_lo ds 1 ; Eight LSBs of column address col_hi ds 1 ; Two MSBs of column address flags ds 1 ; Holder for bit variable flag flag = flags.0 ; Overflow flag for 20-bit address org 0 ; Start of code space start setb RAS ; Disable RAS and CAS before setb CAS ; setting ports to output. mov !ra,#1 ; Make ra.0 (Sin) an input. mov !rb,#0 ; Make rb (low addresses) output. mov !rc,#00000100b ; Make rc.2 (Din) an input. clr flags ; Clear the variables. clr row_lo clr row_hi clr col_lo clr col_hi call refresh ; Initialize DRAM. :record call refresh ; Refresh the DRAM. call write ; Write Sin bit to DRAM. call inc_xy ; Increment row and col addresses. jnb flag,:record ; Repeat until address overflows. :play call refresh ; Refresh the DRAM. call read ; Retrieve bit and write to Sout) call inc_xy ; Increment row and col addresses. JMP :play ; Loop until reset. write mov adrb_lo,row_lo ; Put LSBs of row addr onto bus (rb). AND adrb_hi,#11111100b ; Clear bits adrb_hi.0 and .1. OR adrb_hi,row_hi ; Put MSBs of row addr onto bus (rc). clrb RAS ; Strobe in the row address. movb Dout,Sin ; Supply the input bit to the DRAM, movb Sout,Sin ; and echo it to the speaker. mov adrb_lo,col_lo ; Put LSBs of col addr onto bus (rb). AND adrb_hi,#11111100b ; Clear bits adrb_hi.0 and .1. OR adrb_hi,col_hi ; Put MSBs of col addr onto bus (rc). clrb WR ; Set up to write. clrb CAS ; Strobe in the column address. setb WR ; Conclude the transaction by setb RAS ; restoring WR, RAS, and CAS high setb CAS ; (inactive). ret read mov adrb_lo,row_lo ; Put LSBs of row addr onto bus (rb). AND adrb_hi,#11111100b ; Clear bits adrb_hi.0 and .1. OR adrb_hi,row_hi ; Put MSBs of row addr onto bus (rc). clrb RAS ; Strobe in the row address. mov adrb_lo,col_lo ; Put LSBs of col addr onto bus (rb). AND adrb_hi,#11111100b ; Clear bits adrb_hi.0 and .1. OR adrb_hi,col_hi ; Put MSBs of col addr onto bus (rc). clrb CAS ; Strobe in the column address. movb Sout,Din ; Copy the DRAM data to the speaker. setb RAS ; Conclude the transaction by restoring setb CAS ; RAS and CAS high (inactive). ret ; This routine implements a CAS-before-RAS refresh. The DRAM has an onboard ; counter to keep track of row addresses, so the status of the external ; address bus doesn't matter. The DRAM requires 512 row addresses be refreshed ; each 8 ms, so this routine must be called once every 125 microseconds. ; Changing the initial value moved into r_ctr will alter the refresh schedule. ; For example, to refresh the entire DRAM, move #0 into r_ctr (256 loops) and ; call the routine twice in a row (512). refresh mov r_ctr,#8 :loop clrb CAS ; Activate column strobe. clrb RAS ; Activate row strobe. setb CAS ; Deactivate column strobe. setb RAS ; Deactivate row strobe. djnz r_ctr,:loop ; Repeat. ret ; This routine increments a 20-bit number representing the 1,048,576 addresses ; of the DRAM. For convenience, the number is broken into two 10-bit numbers, ; which are each stored in a pair of byte variables. Note that wherever the ; routine relies on the carry bit to indicate a byte overflow, it uses ; the syntax "add variable,#1" not "inc variable." Inc does not set or clear ; the carry flag. inc_xy add row_lo,#1 ; Add 1 to eight LSBs of row addr. sc ; If carry, add 1 to MSB, else return. ret inc row_hi ; Increment MSBs of row address. sb row_hi.2 ; If we've overflowed 10 bits, clear ret ; row_ hi and add 1 to column clr row_hi ; address, else return. add col_lo,#1 sc ; If carry, add 1 to MSB, else return. ret inc col_hi ; Increment MSBs of col address. sb col_hi.2 ; If we've overflowed 10 bits, clear ret ; col_ hi and set the flag to signal clr col_hi ; main program that we've reached the setb flag ; end of available memory, then return. ret