Mercurial > hg > Members > kono > nitros9-code
view 3rdparty/utils/tlindner/sdir.asm @ 3023:dfc911234945
Added dash command to sdir to list mounted images
author | tlindner |
---|---|
date | Sun, 07 Dec 2014 16:02:18 -0800 |
parents | 0f1a7fcddb00 |
children | 102fe4086f0c |
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 parameterTooLong fcc /Parameter too long./ fcb C$LF fcb C$CR parameterTooLongL equ *-parameterTooLong 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 memory. 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 lbsr SkipSpcs * create path string in buffer area ldd ,x load first two parameter characters cmpd #$2d0d test ascii: hyphen, return lbeq displayMountedInfo cmpa #$0d beq noParameters copyParameterArea pshs u,x leax basepath,pc ldd ,x++ copy 'L:' std ,u++ puls x ldb #2 cpa1 lda ,x+ cmpa #$0d beq cpa2 sta ,u+ addb #1 lbcs parameterToLongError bra cpa1 cpa2 clra sta ,u puls u bra printHeader noParameters leax basepath,pc ldd ,x++ copy 'L:' std ,u++ ldd ,x++ copy '*.' std ,u++ ldd ,x++ copy '*' and Null std ,u++ leau -6,u ldd #5 printHeader leas ,y clobber parameter area, put stack at top, giving us as much RAM as possible pshs d save path character count lda #1 Output path (stdout) ldy #headerL leax header,pc header in x os9 I$Write * print path puls y restore character count 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 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 leax 256*2,x tfr s,d pshs d cmpx ,s++ bhi noteTruncate leax -256,x getBuffer 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 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 clrb clear error lbra ExitNow parameterToLongError leax >parameterTooLong,pcr ldy #parameterTooLongL bra genErr targetDirectoryNotFoundError leax >dirNotFound,pcr ldy #dirNotFoundL bra genErr miscellaneousHardwareError leax >miscHardwareError,pcr ldy #miscHardwareErrorL bra genErr pathNameInvalidError leax >pathNameInvalid,pcr ldy #pathNameInvalidL bra genErr notInitiatedError leax >notInitiated,pcr ldy #notInitiatedL bra genErr * Check buffer for nulled entry. This signifies the end checkBuffer lda #16 leau ,x go back to start of buffer cbLoop ldb ,u beq printBuffer leau 16,u deca beq getNextDirectoryPage bra cbLoop noteTruncate 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 bra pName printBuffer clr CTRLATCH andcc #^IntMasks unmask interrupts * print filename pName * Get screen width lda #1 Output Path (stdout) ldb #SS.ScSiz Request screen size os9 I$Getstt Make screen size request ldd #$0303 cmpx #75 bhi ssDone ldd #$0202 cmpx #42 bhi ssDone ldd #$0101 * push column count to stack ssDone pshs d * reset reg u back to the start of the buffer 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 * print directory token ldy #dirStringL leax >dirString,pcr buffer in x os9 I$Write bra pfCR * print size pfSize leax 12,u bsr PrintFileSize * print carrage return and do next directory entry pfCR dec ,s beq pfDoCR bra pdCRSkip pfDoCR ldy #2 length of buffer leax >carrigeReturn,pcr buffer in x os9 I$Write ldb 1,s stb ,s pdCRSkip leau 16,u ldb ,u beq ExitOK lbra pbLoop ExitOk ldy #2 length of buffer leax >carrigeReturn,pcr buffer in x os9 I$Write clrb Exit clr CTRLATCH andcc #^IntMasks unmask interrupts ExitNow os9 F$Exit ********************************************************************* * PrintFileSize ********************************************************************* * ENTRY: * X = Address of 4 byte file size * String buffer at -11,x * String buffer index at -12,x * * EXIT: * PrintFileSize pshs u leau ,x * start with a space lda #$20 space character * store U offset in -11,u ldb #-11 stb -12,u sta b,u incb stb -12,u lda ,u beq ps1 * Very large number: load offset 0 and 1, shift right 4 bits, print decimal as mega bytes ldb 1,u lsra rorb lsra rorb lsra rorb lsra rorb bsr L09BA write ascii value of D to buffer lda #'M bra psUnit ps1 lda 1,u beq ps2 * Kind of large number: load offsets 1 and 2, shift right 2 bits, print decimal as kilo bytes ldb 2,u lsra rorb lsra rorb bsr L09BA write ascii value of D to buffer lda #'K bra psUnit ps2 ldd 2,u * number: load offsetprint 14 and 15, print decimal as bytes bsr L09BA write ascii value of D to buffer lda #'B bra psUnit * print unit to buffer psUnit ldb -12,u sta b,u lda #$20 incb sta b,u incb sta b,u incb sta b,u incb sta b,u incb sta b,u lda #1 ldy #8 leax -11,u os9 I$Write puls u rts * 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 ldb -12,u Write A to output buffer sta b,u incb stb -12,u ldx #$2F01 Reset X differently bra L09C4 Go do again L09E6 ldb -12,u Write A to output buffer sta b,u incb stb -12,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 * Done sending data, wait for result ldx #0 ; wait for result comb ; assume error txWait ldb -2,y ; load status bmi txExit ; branch if failed lsrb ; clear carry if not busy bcc txExit ; test ready bit leax -1,x ; decrememnt timeout counter bne txWait ; loop back until timeout 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 ********************************************************************* * 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 ********************************************************************* * This subroutine prints a 8 character file name and three character extension * With a space * Buffer is destroyed ********************************************************************* * Entry: * X = string buffer address * * Exit: * A = 1 * B = $20 * Y = 1 * X = X + 7 PrintFilenameAndExtension ldy #8 lda #1 os9 I$Write leax 7,x ldb #$20 stb ,x ldy #4 os9 I$Write ldy #1 os9 I$Write rts ********************************************************************* * This subroutine prints string to stdout ********************************************************************* * Entry: * X = string buffer address * Y = string length * Exit: * A = 1 PrintString lda #1 os9 I$Write rts ********************************************************************* * This subroutine prints Mounted Attributes String * Uses 11 characters of memory before attribute byte to build string ********************************************************************* * Entry: * X = Address of attributes byte * Exit: * a, b, x, y modified PrintMountedAttributes ldb ,x leax -11,x lda #'- bitb #$10 beq next1 lda #'D next1 sta ,x lda #'- bitb #04 beq next2 lda #'S next2 sta 1,x lda #'- bitb #$02 beq next3 lda #'H next3 sta 2,x lda #'- bitb #$01 beq next4 lda #'L next4 sta 3,x lda #$20 sta 4,x sta 5,x lda #1 ldy #6 os9 I$Write rts ********************************************************************* InfoTitle fcc /CoCo SDC Mounted Images:/ fcb C$LF fcb C$CR fcc /Slot 0: / InfoTitleL equ *-InfoTitle S1Title fcb C$LF fcb C$CR fcc /Slot 1: / S1TitleL equ *-S1Title EmptyTitle fcc /Empty./ fcb C$LF fcb C$CR EmptyTitleL equ *-EmptyTitle displayMountedInfo orcc #IntMasks mask interrupts lbsr CmdSetup bcc getInfo ldb #$f6 Not ready error code lbra Exit getInfo ldb #'I stb PREG1 ldb #$c0 load mounted image info for slot 0 stb CMDREG send to SDC command register exg a,a wait leax buffer,u point to transfer bufer lbsr rxData Retrieve 256 bytes pshs b save flag ldb #'I stb PREG1 ldb #$c1 load mounted image info for slot 1 stb CMDREG send to SDC command register exg a,a wait leax 32,x lbsr rxData Retrieve 256 bytes pshs b save slag clr CTRLATCH andcc #^IntMasks unmask interrupts leax >InfoTitle,pcr ldy #InfoTitleL lbsr PrintString ldb 1,s bmi PrintEmptySlot0 leax ,u lbsr PrintFilenameAndExtension leax 11,u lbsr PrintMountedAttributes leax 28,u lbsr PrintFileSize bra DoSlot1 PrintEmptySlot0 leax >EmptyTitle,pcr ldy #EmptyTitleL lbsr PrintString DoSlot1 leax >S1Title,pcr ldy #S1TitleL lbsr PrintString ldb ,s bmi PrintEmptySlot1 leax 32+0,u lbsr PrintFilenameAndExtension leax 32+11,u lbsr PrintMountedAttributes leax 32+28,u lbsr PrintFileSize bra MountedDone PrintEmptySlot1 leax >EmptyTitle,pcr ldy #EmptyTitleL lbsr PrintString MountedDone leas 2,s lbra ExitOK emod eom equ * end