?login_element?

Subversion Repositories NedoOS

Rev

Rev 1850 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.         DEVICE ZXSPECTRUM128
  2.         include "../_sdk/sys_h.asm"
  3.  
  4. STACK=0x4000
  5.  
  6. LISTBUF         equ     0x4400
  7. LISTBUFsz       equ     0x200
  8.  
  9. DISKBUF=0xc000
  10. DISKBUFsz=0x4000
  11.  
  12.  
  13.         org PROGSTART
  14. cmd_begin
  15.         ld sp,STACK
  16.         call initstdio
  17.  
  18.                 call    CS_PREPARE
  19.  
  20.  
  21.                 ;get name of the prog as it was called from shell
  22.                 ld      hl,COMMANDLINE
  23.        
  24.                 call    skipspaces
  25.                 or      a
  26.                 jp      z,fatal_err     ;can't find first non-' ' char -- fatal error
  27.  
  28.                 ld      [name_ptr],hl   ;program name
  29.  
  30.                 call    skipword
  31.                 or      a
  32.                 jp      z,got_no_args
  33.                 ld      [hl],0          ;zero-terminate program name
  34.                 inc     hl
  35.                 call    skipspaces
  36.                 or      a
  37.                 jp      z,got_no_args
  38.  
  39.                 ;now HL points to first real arg, start arg parsing loop
  40. parse_args:
  41.                 ld      [curr_arg],hl
  42.                 ;find end of arg and zero-terminate
  43.                 call    skipword
  44.                 or      a
  45.                 push    af
  46.                 push    hl
  47.                 ld      [hl],0
  48.  
  49.                 call    process_arg
  50.  
  51.                 pop     hl
  52.                 pop     af
  53.                 jr      z,successful_exit
  54.                 inc     hl
  55.                 call    skipspaces
  56.                 or      a
  57.                 jr      nz,parse_args
  58. successful_exit:
  59.                 ld      hl,0
  60.                 QUIT
  61.  
  62.  
  63. AST_DFLT        equ     0
  64. AST_FILES       equ     1
  65. AST_CHK         equ     2
  66.  
  67. process_arg:    ;args parsing routine, has state
  68.                 ;in: HL=asciiz of current argument
  69.  
  70.                 ld      a,[argp_state]
  71.                 or      a
  72.                 jr      nz,.no_dflt
  73.  
  74. ;DFLT - wait for switches
  75.  
  76.                 ; check for -h or --help
  77.                 ld      hl,[curr_arg]
  78.                 push    hl
  79.                 ld      de,help_arg
  80.                 call    strcmp
  81.                 jr      z,.arg_help
  82.  
  83.                 pop     hl
  84.                 ld      de,chk_arg
  85.                 call    strcmp
  86.                 jr      z,.arg_chk
  87.  
  88.                 ; set FILES mode
  89.                 ld      a,AST_FILES
  90.                 ld      [argp_state],a
  91. .chksum_arg
  92.                 ld      hl,[curr_arg]
  93.                 xor     a
  94.                 jp      process_file
  95. .no_dflt
  96.                 dec     a
  97.                 jr      z,.chksum_arg
  98.                 ; FILES mode -- go to .chksum_arg
  99. .no_files
  100.                 dec     a
  101.                 jr      nz,.no_check
  102.                 ;CHECK mode
  103.                 call    process_list
  104.                 ret
  105. .no_check
  106.                 jp      error_exit
  107.  
  108.  
  109.  
  110. .arg_help       ;print help, exit
  111.                 ld      hl,help_msg1
  112.                 call    prtext
  113.                 ld      hl,[name_ptr]
  114.                 call    prtext
  115.                 ld      hl,help_msg2
  116.                 call    prtext
  117.                 jr      successful_exit
  118.  
  119.  
  120. .arg_chk        ;check mode
  121.  
  122.                 ld      a,AST_CHK
  123.                 ld      [argp_state],a
  124.                 ret
  125.  
  126.  
  127.  
  128.  
  129. process_list:   ;argument = filename, open it, read crcs and filenames, check
  130.  
  131.                 ;open file by name
  132.                 ;
  133.                 ld      de,[curr_arg]
  134.                 OS_OPENHANDLE
  135.                 ;b - handle, a!=0 - error
  136.                 or      a
  137.                 jp      nz,.error_open
  138.                 ld      a,b
  139.                 ld      [list_hndl],a
  140.  
  141.                 ;initialize getc/ungetc state
  142.                 xor     a
  143.                 ld      [lpush],a       ;nothing ungetc'ed
  144.                 ld      h,a
  145.                 ld      l,a
  146.                 ld      [lsz],hl        ;nothing in buffer
  147.  
  148.  
  149.  
  150.                 ;main loop: FSM to parse the file with checksums and filenames.
  151.                 ;format:
  152.                 ;
  153.                 ;<BOL>XXXXXXXX<space><space><filename><EOL>
  154.                 ;
  155.                 ;<BOL> -- not a real symbol, just an indication that this is the beginning of line
  156.                 ;XXXXXXXX -- checksum in hex, must be of predefined length (8 for CRC32)
  157.                 ;<space> -- 0x20
  158.                 ;<filename> -- file that will be attempted to open.
  159.                 ;<EOL> -- <crlf> or <cr> or <lf>, last line from file is not obliged to end with these
  160.  
  161. .new_line
  162.                 ;check for EOF
  163.                 call    my_getc
  164.                 jr      nc,.have_bytes
  165.  
  166. .full_end       ;correct end of the file
  167.                 ld      a,[list_hndl]
  168.                 ld      b,a
  169.                 OS_CLOSEHANDLE
  170.                 ret
  171.  
  172. .have_bytes     call    my_ungetc
  173.  
  174.                 ;parse checksum
  175.                 ld      b,CS_SYMLEN
  176.                 ld      hl,CHKSUM
  177. .chksum_loop
  178.                 call    my_getc
  179.                 jp      c,.line_unexp_end
  180.                 call    is_hex
  181.                 jp      c,.line_format_error
  182.  
  183.                 ld      [hl],a
  184.                 inc     hl
  185.                 djnz    .chksum_loop
  186.                 ld      [hl],0
  187.  
  188.                 ;parse two spaces
  189.                 ld      b,2
  190. .chkspc_loop
  191.                 call    my_getc
  192.                 jr      c,.line_unexp_end
  193.                 cp      ' '
  194.                 jr      nz,.line_format_error
  195.                 djnz    .chkspc_loop
  196.  
  197.                 ;parse filepath/name
  198.                 ld      b,MAXPATH_sz&255 ;now it is 256
  199.                 ld      hl,FNAME
  200. .chkfname_loop
  201.                 call    my_getc
  202.                 jr      c,.line_last_end
  203.                 cp      ' '     ;space -- end of path/fname
  204.                 jr      z,.end_fname
  205.                 cp      13      ;13 or 10 -- end of path/fname
  206.                 jr      z,.end_fname
  207.                 cp      10
  208.                 jr      z,.end_fname
  209.                
  210.                 ld      [hl],a
  211.                 inc     hl
  212.                 djnz    .chkfname_loop
  213.                 ld      [hl],0
  214.  
  215.                 ;check whether there's more in input stream
  216.                 call    my_getc
  217.                 jr      c,.line_last_end
  218.                 cp      ' '
  219.                 jr      z,.end_fname
  220.                 cp      13
  221.                 jr      z,.end_fname
  222.                 cp      10
  223.                 jr      z,.end_fname
  224.  
  225. .fname_error    ;if path/filename seems to be greater than MAXPATH_sz or zero-sized
  226.                 jr      $       ;STUB
  227.  
  228. .line_last_end  ;here if EOF condition while parsing '-c filename'
  229.                 ld      [hl],0
  230.  
  231.                 ;check for zero-length path/filename
  232.                 exd    
  233.                 ld      hl,FNAME
  234.                 or      a
  235.                 sbc     hl,de
  236.                 exd
  237.                 jr      z,.fname_error
  238.                 jr      .no_errs
  239.  
  240. .end_fname
  241.                 call    my_ungetc       ;return space/13/10 to the input stream;
  242.                                         ;will be used later as to look for a new line
  243.                
  244.                 ;check for zero-length path/filename
  245.                 exd
  246.                 ld      hl,FNAME
  247.                 or      a
  248.                 sbc     hl,de
  249.                 exd
  250.                 jr      z,.fname_error
  251.  
  252.                 ;no errors here
  253. .no_errs        ;hl=FNAME
  254.                 ld      [hl],0
  255.                 ld      hl,FNAME
  256.                 ld      a,1
  257.                 call    process_file
  258.  
  259. .skip_line      ;scan till end of filename/whatever, skip extra spaces/etc., skip line end
  260.                 call    my_getc
  261.                 jp      c,.full_end
  262.                 cp      13
  263.                 jr      z,.eol_13
  264.                 cp      10
  265.                 jr      nz,.skip_line
  266. .eol_10
  267.                 jr      .new_line2
  268. .eol_13
  269.                 call    my_getc
  270.                 cp      10
  271.                 jr      z,.new_line2
  272.                 call    my_ungetc
  273. .new_line2
  274.                 jp      .new_line
  275.  
  276.  
  277.  
  278. .line_format_error
  279. .line_unexp_end
  280.                 ld      hl,[name_ptr]
  281.                 call    prtext
  282.                 ld      hl,name_to_file
  283.                 call    prtext
  284.                 ld      hl,[curr_arg]
  285.                 call    prtext
  286.                 ld      hl,format_error
  287.                 jr      .prtext2
  288.  
  289.  
  290.  
  291. .error_open
  292.                 ld      hl,[name_ptr]
  293.                 call    prtext
  294.                 ld      hl,name_to_file
  295.                 call    prtext
  296.                 ld      hl,[curr_arg]
  297.                 call    prtext
  298.                 ld      hl,file_error
  299. .prtext2
  300.                 jp      prtext
  301.  
  302.  
  303.  
  304.  
  305.  
  306. my_getc:        ;get a symbol from list_hdnl:lptr:lsz:etc. construction
  307.                 ;
  308.                 ;out: A - symbol
  309.                 ;     cy=1 - no more symbols or error
  310.  
  311.                 ld      a,[lpush]       ;was smth ungetc'ed?
  312.                 or      a
  313.                 jr      z,.no_ununget
  314.                 ;
  315.                 xor     a
  316.                 ld      [lpush],a
  317.                 ld      a,[lpbyte]      ;if was, getc it back
  318.                 ret
  319. .no_ununget
  320.                 push    hl
  321.                 ld      hl,[lsz]
  322.                 ld      a,h
  323.                 or      l
  324.                 jr      z,.buf_empty    ;smth in the buffer?
  325. .no_ununget2
  326.                 dec     hl              ;get from buffer
  327.                 ld      [lsz],hl
  328.                 ld      hl,[lptr]
  329.                 ld      a,[hl]
  330.                 inc     hl
  331.                 ld      [lptr],hl
  332.                 pop     hl
  333.                 ret
  334. .buf_empty
  335.                 push    ix              ;was nothing in buffer, read from file
  336.                 push    iy
  337.                 push    bc
  338.                 push    de
  339.                
  340.                 ld      a,[list_hndl]
  341.                 ld      b,a
  342.                 ld      de,LISTBUF
  343.                 ld      [lptr],de
  344.                 ld      hl,LISTBUFsz
  345.                 OS_READHANDLE
  346.                 ;currently there's only single indication of both error and EOF:
  347.                 ; HL=0, A!=0
  348. .noerr
  349.                 ld      a,h
  350.                 or      l
  351.                 ld      [lsz],hl
  352.                
  353.                 pop     de
  354.                 pop     bc
  355.                 pop     iy
  356.                 pop     ix
  357.                
  358.                 jr      nz,.no_ununget2
  359. .nothing_more
  360.                 pop     hl
  361.                 scf
  362.                 ret
  363.  
  364.  
  365.  
  366. my_ungetc:      ;'ungetc' a symbol (there can be only a single ungot symbol!)
  367.                 ;in: A - symbol
  368.  
  369.                 push    af
  370.                 ld      a,[lpush]
  371.                 or      a
  372.                 jr      nz,$
  373.                 inc     a
  374.                 ld      [lpush],a
  375.                 pop     af
  376.                 ld      [lpbyte],a
  377.                 ret
  378.  
  379.  
  380.  
  381. is_hex:         ;check that A is hex, i.e. [0-9][A-F][a-f]
  382.                 ;in: A
  383.                 ;out: cy=1: *NOT* hex. A is saved
  384.  
  385.                 cp      '0'
  386.                 ret     c
  387.                 cp      '9'+1
  388.                 ccf
  389.                 ret     nc
  390.  
  391.                 cp      'A'
  392.                 ret     c
  393.                 cp      'F'+1
  394.                 ccf
  395.                 ret     nc
  396.                
  397.                 cp      'a'
  398.                 ret     c
  399.                 cp      'f'+1
  400.                 ccf
  401.                 ret
  402.  
  403.  
  404. process_file:   ;hl - asciiz filename
  405.                 ;a  - mode, 0 print, 1 check
  406.  
  407.                 ld      [.mode+1],a
  408.                 ld      [file_name],hl
  409.  
  410.                 ;in mode 0 (print CRCs), the name '-'
  411.                 ; is treated as stdin
  412.                 or      a
  413.                 jr      nz,.dofile
  414.  
  415.                 ld      de,stdin_arg
  416.                 call    strcmp
  417.                 jr      nz,.dofile
  418.  
  419.                 ;get STDIN
  420.                 OS_GETSTDINOUT
  421.                 ld      a,e
  422.                 ld      [file_hndl],a
  423.                 jr      .dohandle
  424. .dofile
  425.                 ld      de,[file_name]
  426.                 OS_OPENHANDLE
  427.                 or      a
  428.                 jp      nz,.file_error
  429.                 ld      a,b
  430.                 ld      [file_hndl],a
  431. .dohandle
  432.                 call    CS_START
  433.  
  434. .readloop0
  435.         ld de,DISKBUF
  436.         ld hl,DISKBUFsz
  437. ;de=buf
  438. ;hl=size
  439.         ld      a,[file_hndl]
  440.         ld      b,a
  441.         OS_READHANDLE
  442.         ;no difference between EOF and error in nedoos, so always treat as an EOF
  443.         ld a,h
  444.         or l
  445.         jr z,.closequit
  446.         ld b,h
  447.         ld c,l
  448.        
  449.         ;BC -- size
  450.         ld      hl,DISKBUF
  451.         call    CS_APPEND
  452.  
  453.         jr      .readloop0
  454. .closequit
  455.                 ld      a,[file_hndl]
  456.                 ld      b,a
  457.                 OS_CLOSEHANDLE
  458.  
  459.  
  460.                 ld      hl,CALCSUM
  461.                 push    hl
  462.                 call    CS_FINALIZE
  463.  
  464.  
  465. .mode           ld      a,#2E
  466.                 or      a
  467.  
  468.                 jr      z,.print
  469.  
  470.                 ;compare: first print filename
  471.                 ld      hl,[file_name]
  472.                 call    prtext
  473.                 ld      hl,txtcds
  474.                 call    prtext
  475.  
  476.                 pop     hl
  477.                 ld      de,CHKSUM
  478.                 call    strcasecmp
  479.  
  480.                 ld      hl,txtOK
  481.                 jr      z,.nofail
  482.                 ld      hl,txtFAIL
  483. .nofail
  484.                 jr      .prtext
  485. .print
  486.                 pop     hl
  487.                 call    prtext
  488.  
  489.                 ld      hl,txtdblspc
  490.                 call    prtext
  491.  
  492.                 ld      hl,[curr_arg]
  493.                 call    prtext
  494.  
  495.                 ld      hl,txtcrlf
  496.                 jr      .prtext
  497.  
  498. .file_error
  499.                 ld      hl,[file_name]
  500.                 call    prtext
  501.                 ld      hl,file_error
  502. .prtext
  503.                 jp      prtext
  504.  
  505.  
  506.  
  507. fatal_err:              ; fatal error so that we can't print even error message
  508.                 ld      hl,2
  509.                 QUIT
  510.  
  511.  
  512.  
  513. got_no_args:    ; no args given, print short help
  514.        
  515.                 ld      hl,[name_ptr]
  516.                 push    hl
  517.                 call    prtext
  518.                 ld      hl,noargs_msg1
  519.                 call    prtext
  520.                 pop     hl
  521.                 call    prtext
  522.                 ld      hl,noargs_msg2
  523.                 call    prtext
  524. error_exit:
  525.                 ld      hl,1
  526.                 QUIT
  527.  
  528.  
  529. noargs_msg1:    db      ": no args given",13,10
  530.                 db      "Try '",0
  531. noargs_msg2:    db      " -h' for more information",13,10,0
  532.  
  533. help_msg1:      db      "CRC rev."
  534.  
  535. SV=SVNREVISION+1
  536. BEG=$
  537.         WHILE   SV>0
  538.                 db      '0'+(SV%10)
  539. SV=SV/10
  540.         ENDW
  541. CONTINUE=$
  542. END=$-1
  543.         WHILE   BEG<END
  544. V1={b BEG}
  545. V2={b END}
  546.         org     BEG
  547.         db      V2
  548.         org     END
  549.         db      V1
  550. BEG=BEG+1
  551. END=END-1
  552.         ENDW
  553.  
  554.                 org     CONTINUE
  555.                 db      13,10
  556.  
  557.                 db      "Usage: ",0
  558. help_msg2:      db      " [OPTION] [FILE]...",13,10
  559.                 db      "Print CRC-32 (0xEDB88320) checksums.",13,10,13,10
  560.                 db      "When filename is -, read standard input.",13,10
  561.                 db      "Options:",13,10
  562.                 db      "  -c   read CRCs from the FILE(s), but not stdin, and check them.",13,10
  563.                 db      "       file format: ^<CRC><space><space><filename><EOL>",13,10
  564.                 db      "  -h   display this help and exit",13,10
  565.                 db      13,10
  566.                 db      0
  567.  
  568. stdin_arg:      db      "-",0
  569. help_arg:       db      "-h",0
  570. chk_arg:        db      "-c",0
  571.  
  572. txtcds:         db      ":"     ;colon, double space
  573. txtdblspc:      db      "  ",0
  574. txtcrlf:        db      13,10,0
  575.  
  576. txtOK:          db      "OK!",13,10,0
  577. txtFAIL:        db      "fail!",13,10,0
  578.  
  579. file_error:     db      ": Error opening or reading file",13,10,0
  580. format_error:   db      ": File format error",13,10,0
  581.  
  582. name_to_file:   db      ": ",0
  583.  
  584.  
  585.  
  586. strcmp:         ;compare strings pointed by HL and DE, case-sensitive.
  587.                 ;in: hl, de -- ptr to asciiz,
  588.                 ;out: Z,NC if equal, NZ,NC if str(DE)>str(HL), NZ,C if str(DE)<str(HL)
  589.                 ;kills: af,de,hl
  590.                 ;
  591.                 ld      a,[hl]
  592.                 or      a
  593.                 ld      a,[de]
  594.                 jr      z,.lastcmp
  595.                 or      a
  596.                 jr      z,.lastcmp
  597.                
  598.                 cp      [hl]
  599.                 inc     hl
  600.                 inc     de
  601.                 jr      z,strcmp
  602.                 ret
  603. .lastcmp
  604.                 cp      [hl]
  605.                 ret
  606.  
  607. strcasecmp:     ;same as strcmp, but english letters are compared without case
  608.                 ;kills: af,bc,de,hl
  609.  
  610.                 ld      c,'a'
  611. .loop
  612.                 ld      a,[hl]
  613.                 or      a
  614.                 jr      z,.hl_zero
  615.  
  616.                 cp      c       ;'a'
  617.                 jr      c,.hl_nonlower
  618.                 cp      'z'+1
  619.                 jr      nc,.hl_nonlower
  620.                 sub     'a'-'A'
  621. .hl_nonlower
  622.                 ld      b,a
  623.  
  624.                 ld      a,[de]
  625.                 or      a
  626.                 jr      z,.de_zero
  627.  
  628.                 cp      c       ;'a'
  629.                 jr      c,.de_nonlower
  630.                 cp      'z'+1
  631.                 jr      nc,.de_nonlower
  632.                 sub     'a'-'A'
  633. .de_nonlower
  634.                 cp      b
  635.                 inc     hl
  636.                 inc     de
  637.                 jr      z,.loop
  638.                 ret
  639. .hl_zero
  640.                 ld      a,[de]
  641.                 cp      [hl]    ;cp 0
  642.                 ret
  643. .de_zero
  644.                 cp      b
  645.                 ret
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652. skipword
  653. ;hl=string
  654. ;out: hl=terminator/space addr
  655. getword0
  656.         ld a,(hl)
  657.         or a
  658.         ret z
  659.         cp ' '
  660.         ret z
  661.         inc hl
  662.         jr getword0
  663.  
  664. skipspaces
  665. ;hl=string
  666. ;out: hl=after last space
  667.         ld a,(hl)
  668.         cp ' '
  669.         ret nz
  670.         inc hl
  671.         jr skipspaces
  672.  
  673.  
  674. prtext
  675.         ld a,(hl)
  676.         or a
  677.         ret z
  678.         push hl
  679.         push iy
  680.         PRCHAR_
  681.         pop iy
  682.         pop hl
  683.         inc hl
  684.         jr prtext
  685.        
  686.  
  687.  
  688. name_ptr:       dw      0
  689. curr_arg:       dw      0
  690. file_name:      dw      0
  691. argp_state:     db      0
  692.  
  693. file_hndl:      db      0
  694. list_hndl:      db      0
  695.  
  696. lpush:          db      0
  697. lpbyte:         db      0
  698. lptr:           dw      0
  699. lsz:            dw      0
  700.  
  701.  
  702.  
  703.  
  704.  
  705.         include "../_sdk/file.asm"
  706.         include "../_sdk/stdio.asm"
  707.  
  708. CALCSUM ds      CS_SYMLEN+1     ;checksum calculated by algorithm
  709.  
  710. CHKSUM  ds      CS_SYMLEN+1     ;checksum to check, taken from '-c filename' file
  711. FNAME   ds      MAXPATH_sz+1    ;file/path to check, taken from '-c filename' file
  712.  
  713.         IFNDEF  MODULE
  714.         define  MODULE "crc.asm"
  715.         ENDIF
  716.         include MODULE ;"crc.asm"
  717.  
  718. cmd_end
  719.  
  720.         display "Size ",/d,cmd_end-cmd_begin," bytes"
  721.  
  722.         IFNDEF  OUTFNAME
  723.         define  OUTFNAME "crc.com"
  724.         ENDIF
  725.         savebin OUTFNAME,cmd_begin,cmd_end-cmd_begin
  726.        
  727.         LABELSLIST "../../us/user.l"
  728.