Mercurial > hg > Members > kono > nitros9-code
view 3rdparty/utils/tlindner/sdir.asm @ 3129:ce9f4ff0a380
l1 rel.asm: Do the module padding in a more portable way
Add comments to describe what's happening and why.
author | Neal Crook <foofoobedoo@gmail.com> |
---|---|
date | Wed, 30 Nov 2016 22:10:56 +0000 |
parents | ae77b55c1414 |
children |
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. * 2 2015/02/07 tim lindner * Refactored code to use llcocosdc. nam sdir ttl Print directory of SDC card ifp1 use defsfile use cocosdc.d endc * Here are some tweakable options 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 mod eom,name,tylg,atrv,start,size org 0 pathnumber rmb 1 count rmb 1 flag rmb 1 columns rmb 2 buffer rmb 256 * 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 basepathL equ *-basepath-1 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 sdcPathName fcc ./sd0@. fcb C$CR sdcNotFound fcc "SDC Driver or /sd0 not found." fcb C$LF fcb C$CR sdcNotFoundL equ *-sdcNotFound mounted_header fcc "CoCo SDC mounted images:" fcb C$LF fcb C$CR mounted_headerL equ *-mounted_header mount_zero fcc "0: " mount_zeroL equ *-mount_zero mount_one fcc "1: " mount_oneL equ *-mount_one not_mounted fcc "Not Mounted" fcb C$LF fcb C$CR not_mountedL equ *-not_mounted * * 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 list_mounted_images puls d lda #1 sta flag,u set "first time" flag leax mounted_header,pcr ldy #mounted_headerL lda #1 standard output os9 I$Write lbsr open_path_to_driver leax mount_zero,pcr ldy #mount_zeroL ldb #$c0 set command code for first slot get_next_image lda #1 standard output os9 I$Write get_mounted_image lda pathnumber,u leax buffer,u output buffer pshs u ldu #'I parameter OS9 I$Getstt puls u bcc parse_mounted_image tsta lbeq timeOut bita #$80 bne print_not_mounted tfr a,b lbra exit_now parse_mounted_image leax buffer,u lbsr PrintFileName * print mounted flags leax buffer,u lda #$20 sta ,x ldb 11,x lda #'- bitb #$10 beq pmf1 lda #'D pmf1 sta 1,x lda #'- bitb #$4 beq pmf2 lda #'S pmf2 sta 2,x lda #'- bitb #$2 beq pmf3 lda #'H pmf3 sta 3,x lda #'- bitb #$1 beq pmf4 lda #'L pmf4 sta 4,x lda #1 ldy #5 a space then four characters os9 I$Write print_mounted_size leax buffer+28,u lbsr PrintFileSize leax carrigeReturn,pc ldy #2 lda #1 standard output os9 I$Write bra next_mounted_image print_not_mounted leax not_mounted,pcr ldy #not_mountedL lda #1 standard output os9 I$Write next_mounted_image lda flag,u lbeq exit_ok if flag zero, we are done. dec flag,u leax mount_one,pcr ldy #mount_oneL ldb #$c1 set command code for second slot lbra get_next_image * error printers timeOut leax >timoutError,pcr point to help message ldy #timoutErrorL get length genErr lda #$02 std error os9 I$Write ldb #1 lbra exit_now noDriverError leax >sdcNotFound,pcr ldy #sdcNotFoundL lda #$02 std error os9 I$Write lbra exit_now 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 * open path to driver * uses A, X open_path_to_driver leax sdcPathName,pc lda READ.+PREAD. open for reading os9 I$Open lbcs noDriverError Fail if not opened sta pathnumber,u rts * The start of the program is here. start pshs d * check for hyphen lda ,x cmpa #'- lbeq list_mounted_images * print header pshs x,y lda #1 standard output leax header,pc ldy #headerL os9 I$Write puls x,y puls d * check for zero parameters cmpd #1 beq use_base_path * check for prefix on user supplied parameter string clr -1,y place null at end of parameter area subb #1 sbca #0 decrement reg d tfr d,y store parameter length in reg y ldd ,x cmpd #$4c3a "L:" beq print_path * stack ascii characters to prepend "L:" to user supplied base path ldd #$4c3a pshs d leay 2,y increase parameter length by 2 * point reg x to base path string tfr s,x bra print_path use_base_path leax basepath,pc ldy #basepathL print_path pshs x lda #1 standard output os9 I$Write leax carrigeReturn,pc ldy #2 os9 I$Write bsr open_path_to_driver * Get screen width lda #1 Output Path (stdout) ldb #SS.ScSiz Request screen size os9 I$Getstt Make screen size request ldd #$0403 cmpx #75 bhi save_screen ldd #$0302 cmpx #42 bhi save_screen ldd #$0201 save_screen std columns,u Save Column information * ask driver to initiate directory transfer * path buffer must be on stack puls x lda pathnumber,u ldb #$e0 pshs u OS9 I$Getstt puls u bcc get_diretory_block tsta lbeq timeOut bita #$10 lbne targetDirectoryNotFoundError bita #$08 lbne miscellaneousHardwareError bita #$04 lbne pathNameInvalidError tfr a,b lbra exit_now get_diretory_block lda pathnumber,u ldb #$c0 Command code leax buffer,u output buffer pshs u ldu #$3e parameter OS9 I$Getstt puls u bcc parse_directory_block tsta lbeq timeOut bita #$80 lbne miscellaneousHardwareError bita #$08 lbne notInitiatedError tfr a,b bra exit_now parse_directory_block ldb #-1 stb count,u check_if_done dec columns,u bne print_continue lda columns+1,u sta columns,u print_return leax carrigeReturn,pc ldy #2 lda #1 os9 I$Write print_continue ldb count,u incb stb count,u cmpb #16 beq get_diretory_block go get another block lda #16 * calculate directory record address mul leax buffer,u abx lda ,x cmpa #0 beq exit_ok bsr PrintFileName * print flags ldb 4,x 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 print_size * print directory token leax >dirString,pcr ldy #dirStringL os9 I$Write bra end_print print_size leax 5,x bsr PrintFileSize end_print bra check_if_done exit_ok clrb exit_now os9 F$Exit ********************************************************************* * PrintFileName ********************************************************************* * ENTRY: * X = Address of 10 byte filename and extension * * EXIT: * PrintFileName lda #1 standard output ldy #8 filename length os9 I$Write ldb #$20 leax 7,x stb ,x ldy #4 os9 I$Write rts ********************************************************************* * 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 emod eom equ * end