Mercurial > hg > Members > kono > nitros9-code
diff 3rdparty/drivers/flash/flashpak.asm @ 0:6641a883d6b0
Initial revision
author | boisy |
---|---|
date | Thu, 04 Apr 2002 16:34:12 +0000 |
parents | |
children | 25aa4b22ade4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/drivers/flash/flashpak.asm Thu Apr 04 16:34:12 2002 +0000 @@ -0,0 +1,549 @@ +******************************************************************** +* FlashPak - FLASH Pak device driver based on Disto's RAM Pak driver +* Copyright 2001 by Agesino Primatic, Jr. +* Free for any use as long as this copyright message is included. +* +* $Id$ +* +* Ed. Comments Who YY/MM/DD +* ------------------------------------------------------------------ +* 1 Original version by A. Primatic AP 01/04/05 + + + nam FlashPak + ttl FLASH Pak device driver + + ifp1 + use defsfile + use systype.l2 + use rbfdefs + endc + +tylg set Drivr+Objct +atrv set ReEnt+rev +rev set $01 +edition set 1 + + + mod eom,name,tylg,atrv,start,size + + +* RBF Data Area + rmb 129 + + +* Free for driver use +ORGSlot rmb 1 +BlkAdr rmb 2 address of our 16K block of memory +CurPD rmb 2 our current path descriptor +CurLSN rmb 2 our current LSN + + +FOffset equ 0 +FLSNLo equ 1 +FLSNHi equ 2 +FData equ 3 + + +size equ . + fcb $FF + + +name fcs /FlashPak/ + fcb edition + + +start lbra Init + lbra Read + lbra Write + lbra GetStat + lbra SetStat + lbra Term + + +* Init +* +* Entry: +* Y = address of device descriptor +* U = address of device memory area +* +* Exit: +* CC = carry set on error +* B = error code +* +Init ldd #($FF*256)+3 this driver can handle 3 "disks" + stb V.NDRV,u + leax DRVBEG,u start at beginning of drive table of disk 0 + + +* For each B, compute total sectors... +InitLp sta V.TRAK,x initialize to 0xff so first seek gets LSN0 + pshs b,a + lda IT.CYL+1,y compute total sectors + ldb IT.SCT+1,y + mul + std DD.TOT+1,x fill in table + puls b,a + leax DRVMEM,x move to drive table of next disk + decb + bne InitLp + + +* Reserve 16K of memory for sector copies + ldd #$4000 request 16K bytes + pshs u save address of device memory area + os9 F$SRqMem Request System Memory + tfr u,x X = starting address of memory area + puls u restore address of device memory area + bcs InitErr branch if error + + + stx BlkAdr,u store starting address + clrb no errors here + + +InitErr rts all done with intialization + + +* Write +* +* Entry: +* B = MSB of the disk's LSN +* X = LSW of the disk's LSN +* Y = address of path descriptor +* U = address of device memory area +* +* Exit: +* CC = carry set on error +* B = error code +* +Write pshs cc save carry flags (including interrupt enable) +* orcc #IntMasks mask interrupts + lbsr SelSlot get to the proper MPI slot + stx CurLSN,u save LSN + tfr x,d now, D = LSN + ldx PD.BUF,y get address of path buffer + sty CurPD,u save path descriptor + ldy V.PORT,u get base address of FlashPak + sta FLSNHi,y write LSN hi byte to FlashPak + stb FLSNLo,y write LSN lo byte to FlashPak + clrb set up for 256 transfers + + +* First, we need to see if a write would work +WrLp1 stb FOffset,y write offset to FlashPak + lda ,x get what we want to write + coma data on flash is stored complemented +* nop + anda FData,y logical-and with data from FlashPak + coma get back uncomplemented version +* nop + cmpa ,x+ does result match with what we want to write? + bne WrErase if no, then we need to erase sector + + + incb go to next word + bne WrLp1 branch if not done + + +* At this point, write can proceed + ldx CurPD,u get back path descriptor + ldx PD.BUF,x get address of the path buffer + ldy V.PORT,u get base address of FlashPak + bsr WrBlock write 256-byte block + + +WrExit lbra RstSlot restore MPI slot + + +* WrBlock -- copies 256 bytes from memory to flash +* +* Entry: +* B = Offset into flash +* X = Address of first memory location +* CurLSN,u = current LSN (for WrByte) +* +* Exit: +* X = Address of next memory location +* +* Destroys: +* A, B +WrBlock clrb start at offset of 0 + pshs b push offset (of 0) on stack + + +WrLoop lda ,x+ get data from buffer + bsr WrByte write that byte + bcs WrBlkDn if there was an error, break out + + + inc ,s increment offset + ldb ,s get new offset + bne WrLoop + + +WrBlkDn leas 1,s remove offset from stack + rts + + +* WrByte +* +* Entry: +* A = Byte to write +* B = Offset to write +* Y = base address of FlashPak +* U = address of device memory area +* CurLSN,u = current LSN +* +* Destroys: +* B +* +WrByte pshs d,x save d and x for later + bsr DoAA55 + + + ldx #$55 flash[0x5555] = 0xa0 + ldd #$a055 + bsr XfrByte + + + puls d flash[addr] = ~data + coma data on flash is complemented +* nop + ldx CurLSN,u + bsr XfrByte + + + pshs a save byte that was written on stack + + +* Now, loop until done +WrBWait ldb FData,y get flash data + cmpb ,s does it match? + beq WrBDone if yes, write passed + + + bitb #$20 did we exceed the time limit? + beq WrBWait if no, try again + + +* We exceed time limit -- try one more time + ldb FData,y get flash data + cmpb ,s does it match? + beq WrBDone whew! just made it + + +* Write Failure + lbsr RstFlsh reset flash to read mode + comb set carry flag + ldb #E$Write set error code + bra WrBExit + + +WrBDone clrb no error here + + +WrBExit puls a,x restore stack + rts + + +* XfrByte -- transfers one byte to flash +* +* Entry: +* A = Byte to transfer +* B = Offset +* X = LSN +* Y = base address of FlashPak +XfrByte exg d,x get LSN into D + sta FLSNHi,y write LSN hi byte to FlashPak + stb FLSNLo,y write LSN lo byte to FlashPak + exg d,x get byte/offset into D + stb FOffset,y write offset to FlashPak + sta Fdata,y write data to FlashPak + rts all done + + +* DoAA55 Sends 0x5555=0xaa, then 0xaaaa=0x55 to flash +DoAA55 ldx #$55 flash[0x5555] = 0xaa + ldd #$aa55 + bsr XfrByte + + + ldx #$2a flash[0x2aaa] = 0x55 + ldd #$55aa + bra XfrByte will also return + + +* WrErase +* +* Entry: +* Y = base address of FlashPak +* U = address of device memory area +* CurLSN,u = current LSN +* +* First, we need to read the entire sector into BlkAdr +WrErase ldx BlkAdr,u Get start of BlkAddr + ldd CurLSN,u Get current LSN + sta FLSNHi,y write LSN hi byte to FlashPak + andb #$C0 Get to first LSN of this sector + + +WrErLp1 stb FLSNLo,y write LSN lo byte to FlashPak + pshs b save LSN_lsb on stack + lbsr RdBlock transfer 256 bytes from flash to memory + puls b get back LSN_lsb + incb go to next LSN + bitb #$3f are we done? + bne WrErLp1 if no, go back for some more + + +* Now, we have the entire sector copied into memory +* Replace the old LSN with the new one + ldx BlkAdr,u get start of BlkAddr + ldd CurLSN,u get current LSN + exg a,b + anda #$3f find offset + clrb start at beginning of LSN + leax d,x move to LSN in memory + ldy CurPD,u get back path descriptor + ldy PD.BUF,y get address of path buffer + + +WrErLp2 lda ,y+ get byte from path buffer + sta ,x+ put byte into BlkMem + incb move to next byte + bne WrErLp2 branch if not done + + +* Now, we have the entire sector with the new LSN in memory +* Erase sector + ldy V.PORT,u + bsr DoAA55 + + + ldx #$55 flash[0x5555] = 0x80 + ldd #$8055 + bsr XfrByte + + + bsr DoAA55 + + + ldd CurLSN,u flash[SectAddr] = 0x30 + andb #$C0 + tfr d,x + ldd #$3000 + bsr XfrByte + + +* Now, loop until done +WrEWait ldb FData,y get flash data + bmi WrEDone if DQ7 is set, then we're done + + + bitb #$20 did we exceed the time limit? + bne WrETime if yes, go on + + +* Sleep for 250ms + ldx #15 15 * 1/60 = 250ms + os9 F$Sleep + bra WrEWait go back for more + + +* We exceeded the time limit -- try one more time +WrETime ldb FData,y get flash data + bmi WrEDone whew! just made it + + +* Erase Failure + bsr RstFlsh reset flash to read mode + comb set carry flag + ldb #E$Write set error code + bra WrEExit + + +* Finally, we need to write the sector back +WrEDone ldx BlkAdr,u get pointer to memory version of sector + ldy V.PORT,u get base address of FlashPak + ldd CurLSN,u get current LSN + andb #$C0 get to beginning of sector + pshs b push LSN_lsb on stack + + +WrErLp3 stb CurLSN+1,u write new LSN lsb to CurLSN + lbsr WrBlock transfer 256 bytes from memory to flash + bcs WrEExit branch if error + + + inc ,s go to next LSB_lsb + ldb ,s get back LSN_lsb + bitb #$3f are we done? + bne WrErLp3 if no, go back for some more + + + clrb no error here + + +WrEExit leas 1,s remove LSN_lsb from stack + bra RstSlot will also return + + +* RstFlash -- Resets flash to read mode +* +RstFlsh lbsr DoAA55 + + + ldx #$55 flash[0x5555] = 0xf0 + ldd #$f055 + lbra XfrByte will also return + + +* Read +* +* Entry: +* B = MSB of the disk's LSN +* X = LSW of the disk's LSN +* Y = address of path descriptor +* U = address of device memory area +* +* Exit: +* CC = carry set on error +* B = error code +* +Read cmpx #$0000 check to see if we're reading LSN0 + beq RdLSN0 if we are, do special read + + +RdSect pshs cc save flags (including interrupt enable) +* orcc #IntMasks mask interrupts + bsr SelSlot select the proper MPI slot + tfr x,d now, D = LSN_lsw + ldx PD.BUF,y get address of the path buffer + ldy V.PORT,u get base address of FlashPak + sta FLSNHi,y write LSN hi byte to FlashPak + stb FLSNLo,y write LSN lo byte to FlashPak + bsr RdBlock go get the 256-byte block + + +* Restore the original MPI slot value we saved off +RstSlot lda >ORGSlot,u get original slot value + sta >MPI.Slct put it back + puls cc get back flags (including interrupt enable) + clrb no errors + rts we're done + + +* RdBlock -- copies 256 bytes from flash to memory +* +* Entry: +* B = Offset into flash +* X = Address of first memory location +* +* Exit: +* X = Address of next memory location +* +* Destroys: +* A, B +RdBlock clrb will do this 256 times + + +RdLoop stb FOffset,y write offset to FlashPak + lda FData,y get data from FlashPak + coma data on flash is stored complemented +* nop + sta ,x+ write it into buffer + incb go to next word + bne RdLoop branch if not done + + + rts all done with RdBlock + + +* Read LSN0 into our path descriptor +RdLSN0 pshs y save address of path descriptor + bsr RdSect go get the sector + puls y restore address of path descriptor + ldx PD.BUF,y get address of the path buffer + lda <PD.DRV,y get drive number + leay DRVBEG,u get address of beginning of drive table + ldb #DRVMEM + mul now, D = offset into table + leay d,y get address of byte following drive table + ldb #DD.SIZ-1 get size of device descriptor + + +* Copy LSN0 device descriptor to drive table +LSN0Lp lda b,x get byte from path buffer + sta b,y store byte in drive table + decb move to previous entry + bne LSN0Lp loop if not done + + + rts all done + + +* SelSlot - This routine selects the MPI slot +* +* Entry: +* None +* +* Exit: +* None +* +* Destroys: +* A, B +SelSlot lda >MPI.Slct get current selected slot + sta >ORGSlot,u save off + lda PD.DRV,y get drive no. + ldb #$11 + mul multiply drive no. times $11 + stb >MPI.Slct set new MPI slot no. + rts all done + + +* GetStat +* +* Entry: +* A = function code +* Y = address of path descriptor +* U = address of device memory area +* +* Exit: +* CC = carry set on error +* B = error code +* +GetStat comb + ldb #E$UnkSvc + rts + + +SetStat clrb + rts + + +* Term +* +* Entry: +* U = address of device memory area +* +* Exit: +* CC = carry set on error +* B = error code +* +Term + ldu BlkAdr,u release 16384-byte block + ldd #$2000 + os9 F$SRtMem + bcs TermErr + + + clrb no errors here + + +TermErr rts + + + emod +eom equ * + end