Mercurial > hg > Members > kono > nitros9-code
view 3rdparty/utils/tlindner/sdir.asm @ 3019:9abe4d732538
sdir nearly done
author | tlindner |
---|---|
date | Sat, 29 Nov 2014 18:50:29 -0800 |
parents | e7ffcda58117 |
children | 1c7b7f93138a |
line wrap: on
line source
******************************************************************** * sdir - Print directory of SDC card * * $Id$ * * Edt/Rev YYYY/MM/DD Modified by * Comment * ------------------------------------------------------------------ * 1 2014/11/20 tim lindner * Started writing code. nam sdir ttl Print directory of SDC card ifp1 use defsfile endc * Here are some tweakable options DOHELP set 0 1 = include help info STACKSZ set 32 estimated stack size in bytes PARMSZ set 256 estimated parameter size in bytes * Module header definitions tylg set Prgrm+Objct atrv set ReEnt+rev rev set $00 edition set 1 ********************************************************************* *** Hardware Addressing ********************************************************************* CTRLATCH equ $FF40 ; controller latch (write) CMDREG equ $FF48 ; command register (write) STATREG equ $FF48 ; status register (read) PREG1 equ $FF49 ; param register 1 PREG2 equ $FF4A ; param register 2 PREG3 equ $FF4B ; param register 3 DATREGA equ PREG2 ; first data register DATREGB equ PREG3 ; second data register ********************************************************************* *** STATUS BIT MASKS ********************************************************************* BUSY equ %00000001 READY equ %00000010 FAILED equ %10000000 mod eom,name,tylg,atrv,start,size org 0 buffer rmb 256*5 cleartop equ . everything up to here gets cleared at start * Finally the stack for any PSHS/PULS/BSR/LBSRs that we might do rmb STACKSZ+PARMSZ size equ . * The utility name and edition goes here name fcs /sdir/ fcb edition * Place constant strings here header fcc /SDC Directory: / headerL equ *-header basepath fcc /L:*.*/ fcb 0 timoutError fcc /Timeout./ carrigeReturn fcb C$LF fcb C$CR timoutErrorL equ *-timoutError dirNotFound fcc /Directory not found./ fcb C$LF fcb C$CR dirNotFoundL equ *-dirNotFound pathNameInvalid fcc /Pathname is invalid./ fcb C$LF fcb C$CR pathNameInvalidL equ *-pathNameInvalid miscHardwareError fcc /Miscellaneous hardware error./ fcb C$LF fcb C$CR miscHardwareErrorL equ *-miscHardwareError notInitiated fcc /Listing not initiated./ fcb C$LF fcb C$CR notInitiatedL equ *-notInitiated truncated fcc /Out of memroy. Listing trucated./ fcb C$LF fcb C$CR fcb C$LF fcb C$CR truncatedL equ *-truncated dirString fcc / <DIR>/ dirStringL equ *-dirString * * Here's how registers are set when this process is forked: * * +-----------------+ <-- Y (highest address) * ! Parameter ! * ! Area ! * +-----------------+ <-- X, SP * ! Data Area ! * +-----------------+ * ! Direct Page ! * +-----------------+ <-- U, DP (lowest address) * * D = parameter area size * PC = module entry point abs. address * CC = F=0, I=0, others undefined * The start of the program is here. * main program start equ * * create path string in buffer area decb pshs u,x,d leax basepath,pc ldd ,x++ copy 'L:' std ,u++ puls d cmpd #$0 bne copyParameterArea * use '*.*' if user suplied no parameter ldd ,x++ copy '*.*' and null std ,u++ ldd ,x++ std ,u++ puls x,u ldd #$5 Length of buffer bra printHeader copyParameterArea equ * puls x pshs d cpaLoop lda ,x+ sta ,u+ decb beq cpaDone bra cpaLoop cpaDone clra put null at end of parameter string sta ,u+ puls d addd #3 puls u leas 0,y clobber parameter area, put stack at top, giving us as much RAM as possible printHeader equ * pshs d lda #1 Output path (stdout) ldy #headerL leax header,pc header in x os9 I$Write * print path puls y leax buffer,u buffer in x os9 I$Write ldy #2 length of buffer leax >carrigeReturn,pcr buffer in x os9 I$Write * wait until our next tick to communicate with the SDC ldx #$1 os9 F$Sleep * setup SDC for directory processing orcc #IntMasks mask interrupts lbsr CmdSetup bcc sendCommand ldb #$f6 Not ready error code lbra Exit sendCommand equ * ldb #$e0 load initial directory listing command stb CMDREG send to SDC command register exg a,a wait leax buffer,u point to transfer bufer lbsr txData transmit buffer to SDC bcc getBuffer tstb beq timeOut bitb #$10 bne targetDirectoryNotFoundError bitb #$08 bne miscellaneousHardwareError bitb #$04 bne pathNameInvalidError lbra Exit getNextDirectoryPage equ * leax 256*2,x tfr s,d pshs d cmpx ,s++ bhi noteTruncate leax -256,x getBuffer equ * ldb #$3e set parameter #1 stb PREG1 ldb #$c0 set command code stb CMDREG send to SDC command register lbsr rxData bcc checkBuffer tstb beq timeOut bitb #$8 bne notInitiatedError lbra Exit timeOut equ * leax >timoutError,pcr point to help message ldy #timoutErrorL get length genErr clr CTRLATCH andcc #^IntMasks unmask interrupts lda #$02 std error os9 I$Write write it clrb clear error lbra ExitNow targetDirectoryNotFoundError equ * leax >dirNotFound,pcr ldy #dirNotFoundL bra genErr miscellaneousHardwareError equ * leax >miscHardwareError,pcr ldy #miscHardwareErrorL bra genErr pathNameInvalidError equ * leax >pathNameInvalid,pcr ldy #pathNameInvalidL bra genErr notInitiatedError equ * leax >notInitiated,pcr ldy #notInitiatedL bra genErr * Check buffer for nulled entry. This signifies the end checkBuffer equ * lda #16 leau ,x go back to start of buffer cbLoop ldb ,u beq printBuffer leau 16,u deca beq getNextDirectoryPage bra cbLoop noteTruncate equ * clr CTRLATCH andcc #^IntMasks unmask interrupts clr -256,x zero out last directory entry leax >truncated,pcr point to help message ldy #truncatedL get length lda #$02 std error os9 I$Write write it bra pName printBuffer equ * clr CTRLATCH andcc #^IntMasks unmask interrupts * print filename pName clrb tfr dp,a tfr d,u lda #1 Output path (stdout) pbLoop ldy #8 length of buffer leax ,u os9 I$Write * print file extension leax 7,u ldb #$20 stb ,x ldy #4 os9 I$Write * print flags leax 7,u ldb 11,u lda #'- bitb #2 beq pf1 lda #'H pf1 sta 1,x lda #'- bitb #1 beq pf2 lda #'L pf2 sta 2,x lda #1 ldy #3 os9 I$Write bitb #$10 beq pfSize ldy #dirStringL leax >dirString,pcr buffer in x os9 I$Write bra pfCR * print size pfSize * start with a space lda #$20 space character clrb stb 11,u sta b,u incb stb 11,u lda 12,u beq ps1 * Very large number: load offset 12 and 13, shift right 4 bits, print decimal as mega bytes ldb 13,u lsra rorb lsra rorb lsra rorb lsra rorb bsr L09BA write ascii value of D to buffer lda #'M bra psUnit ps1 lda 13,u beq ps2 * Kind of large number: load offsets 13 and 14, shift right 2 bits, print decimal as kilo bytes ldb 14,u lsra rorb lsra rorb bsr L09BA write ascii value of D to buffer lda #'K bra psUnit ps2 ldd 14,u cmpd #$1000 blo ps3 * Large number: load offset 14, shift right 2 bits, print decimal as kilo bytes tfr a,b lsrb lsrb clra bsr L09BA write ascii value of D to buffer lda #'K bra psUnit ps3 * number: load offsetprint 14 and 15, print decimal as bytes bsr L09BA write ascii value of D to buffer lda #'B bra psUnit psUnit ldb 11,u sta b,u lda #$20 incb sta b,u incb sta b,u incb sta b,u lda #1 ldy #8 leax ,u os9 I$Write * print carrage return and do next directory entry pfCR ldy #2 length of buffer leax >carrigeReturn,pcr buffer in x os9 I$Write leau 16,u ldb ,u beq ExitOK lbra pbLoop ExitOk clrb Exit clr CTRLATCH andcc #^IntMasks unmask interrupts ExitNow os9 F$Exit * Stolen from BASIC09 * Convert # in D to ASCII version (decimal) L09BA pshs y,x,d Preserve End of data mem ptr,?,Data mem size pshs d Preserve data mem size again leay <L09ED,pc Point to decimal table (for integers) L09C1 ldx #$2F00 L09C4 puls d Get data mem size L09C6 leax >$0100,x Bump X up to $3000 subd ,y Subtract value from table bhs L09C6 No underflow, keep subtracting current power of 10 addd ,y++ Restore to before underflow state pshs d Preserve remainder of this power ldd ,y Get next lower power of 10 tfr x,d Promptly overwrite it with X (doesn't chg flags) beq L09E6 If finished table, skip ahead cmpd #$3000 Just went through once? beq L09C1 Yes, reset X & do again * lbsr L1373 Go save A @ [<u0082] ldb 11,u Write A to output buffer sta b,u incb stb 11,u ldx #$2F01 Reset X differently bra L09C4 Go do again L09E6 * lbsr L1373 Go save A @ [<u0082] ldb 11,u Write A to output buffer sta b,u incb stb 11,u leas 2,s Eat stack puls pc,y,x,d Restore regs & return * Table of decimal values L09ED fdb $2710 10000 fdb $03E8 1000 fdb $0064 100 fdb $000A 10 fdb $0001 1 fdb $0000 0 ********************************************************************* * Setup Controller for Command Mode ********************************************************************* * EXIT: * Carry cleared on success, set on timeout * All other registers preserved * CmdSetup pshs x,a ; preserve registers lda #$43 ; put controller into.. sta CTRLATCH ; Command Mode ldx #0 ; long timeout counter = 65536 busyLp lda STATREG ; read status lsra ; move BUSY bit to Carry bcc setupExit ; branch if not busy leax -1,x ; decrement timeout counter bne busyLp ; loop if not timeout lda #0 ; clear A without clearing Carry sta CTRLATCH ; put controller back in emulation setupExit puls a,x,pc ; restore registers and return ********************************************************************* * Send 256 bytes of Command Data to SDC Controller ********************************************************************* * ENTRY: * X = Data Address * * EXIT: * B = Status * Carry set on failure or timeout * All other registers preserved * txData pshs u,y,x ; preserve registers ldy #DATREGA ; point Y at the data registers * Poll for Controller Ready or Failed. comb ; set carry in anticipation of failure ldx #0 ; max timeout counter = 65536 txPoll ldb -2,y ; read status register bmi txExit ; branch if FAILED bit is set bitb #READY ; test the READY bit bne txRdy ; branch if ready leax -1,x ; decrement timeout counter beq txExit ; exit if timeout bra txPoll ; poll again * Controller Ready. Send the Data. txRdy ldx ,s ; re-load data address into X ldb #128 ; 128 words to send (256 bytes) txWord ldu ,x++ ; get data word from source stu ,y ; send to controller decb ; decrement word loop counter bne txWord ; loop until done ldx #0 ; wait for result * Done sending data, wait for result comb ; assume error txWait ldb -2,y ; load status bmi txExit ; branch if failed bitb #READY ; test ready bit bne txExitOK ; branch if ready leax -1,x ; decrememnt timeout counter bne txWait ; loop back until timeout txExitOK andcc #^1 txExit puls x,y,u,pc ; restore registers and return ********************************************************************* * Retrieve 256 bytes of Response Data from SDC Controller ********************************************************************* * ENTRY: * X = Data Storage Address * * EXIT: * B = Status * Carry set on failure or timeout * All other registers preserved * rxData pshs u,y,x ; preserve registers ldy #DATREGA ; point Y at the data registers * Poll for Controller Ready or Failed. comb ; set carry in anticipation of failure ldx #0 ; max timeout counter = 65536 rxPoll ldb -2,y ; read status register bmi rxExit ; branch if FAILED bit is set bitb #READY ; test the READY bit bne rxRdy ; branch if ready leax -1,x ; decrement timeout counter beq rxExit ; exit if timeout bra rxPoll ; poll again * Controller Ready. Grab the Data. rxRdy ldx ,s ; re-load data address into X ldb #128 ; 128 words to read (256 bytes) rxWord ldu ,y ; read data word from controller stu ,x++ ; put into storage decb ; decrement word loop counter bne rxWord ; loop until done clrb ; success! clear the carry flag rxExit puls x,y,u,pc ; restore registers and return ********************************************************************* * This routine skip over spaces and commas ********************************************************************* * Entry: * X = ptr to data to parse * Exit: * X = ptr to first non-whitespace char * A = non-whitespace char SkipSpcs lda ,x+ cmpa #C$SPAC beq SkipSpcs leax -1,x rts emod eom equ * end