?login_element?

Subversion Repositories NedoOS

Rev

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

  1. ;TODO в батнике %0 (параметры запуска), %1 ...
  2. ;TODO %~dp0 (драйв и путь запуска)
  3. ;TODO %~t1 (дата-время 1-го параметра)
  4. ;TODO goto и метки :label
  5. ;TODO if ???==??? goto
  6. ;TODO for
  7. ;TODO PATH (где хранить? должна подгружаться при старте новой копии cmd)
  8.  
  9.         DEVICE ZXSPECTRUM128
  10.         include "../_sdk/sys_h.asm"
  11. MAXCMDSZ=COMMANDLINE_sz-1;127 ;не считая терминатора
  12. txtscrhgt=25
  13. txtscrwid=80
  14. CMDLINEY=24
  15.  
  16. _COLOR=0x0007;7
  17. _ERRORCOLOR=0x0009;0x42
  18.  
  19.         org PROGSTART
  20. cmd_begin
  21.         ld sp,0x4000 ;не должен опускаться ниже 0x3b00! иначе возможна порча OS        
  22.         call initstdio
  23.  
  24.         OS_GETSTDINOUT ;e=stdin, d=stdout, h=stderr
  25.         ld (stdouthandle_wasatstart),a
  26.  
  27.         OS_GETMAINPAGES
  28. ;dehl=номера страниц в 0000,4000,8000,c000
  29.         push hl
  30.         OS_DELPAGE
  31.         pop hl
  32.         push hl
  33.         ld e,h
  34.         OS_DELPAGE
  35.         pop hl
  36.         ld e,l
  37.         OS_DELPAGE
  38.        
  39.         ld hl,COMMANDLINE ;command line
  40.         ld de,wordbuf
  41.         call getword
  42.         call skipspaces
  43.         ld (cmdlineword2),hl
  44.         ld a,(hl)
  45.         or a
  46.         jr z,cmd_interactive
  47. ;command line = "cmd <command to run>"
  48.         ld de,cmdbuf
  49.         call strcopy
  50.        
  51.         call makeprompt ;иначе запустится из неправильной директории
  52.        
  53.         call execcmd_maybepipes ;can show errors ;a!=0: no such internal command
  54.         or a
  55.         call nz,callcmd;strcpexec_tryrun ;запускает по фону
  56.         YIELD ;чтобы запущенная задача успела захватить фокус ;???
  57. ;если командная строка была со словом autoexec.bat в параметре, то это начальный запуск autoexec.bat, из него надо входить в интерактивный режим
  58.         ld hl,tautoexecbat
  59. cmdlineword2=$+1
  60.         ld de,0
  61.         call strcp ;z=yes
  62.         jr z,cmd_interactive
  63. cmd_exit
  64.         QUIT
  65.        
  66. tautoexecbat
  67.         db "autoexec.bat",0
  68.  
  69. cmd_interactive
  70.        
  71. cmdmainloop
  72.         call makeprompt
  73.         call editcmd
  74.         call prcrlf
  75.        
  76.         ld hl,cmdbuf
  77.         ld de,oldcmd
  78.         ld bc,MAXCMDSZ+1
  79.         ldir
  80.  
  81.         call execcmd_maybepipes
  82.         or a
  83.         call nz,callcmd;strcpexec_tryrun ;запускает по фону
  84.         ld hl,cmdbuf
  85.         ld (hl),0
  86.         jp cmdmainloop
  87.  
  88. execcmd_maybepipes
  89. ;out:a!=0: no such internal command
  90. ;если command pars >file, то create file, перенаправить вывод в него, execcmd, close file, перенаправить вывод обратно
  91.         ld hl,cmdbuf
  92.         ld a,'>'
  93.         ld bc,MAXCMDSZ
  94.         cpir
  95.         jp nz,execcmd ;jr nz,cmd_noexeccmdtofile
  96.         dec hl
  97.         ld (hl),0
  98.         inc hl
  99.         ex de,hl ;de=filename
  100.         OS_CREATEHANDLE
  101.         ld a,b
  102.         ld (execcmdtofile_handle),a
  103.         call setstdouthandle
  104.        
  105.         call execcmd ;can show errors ;a!=0: no such internal command
  106.         push af
  107.  
  108. execcmdtofile_handle=$+1
  109.         ld b,0
  110.         OS_CLOSEHANDLE
  111. stdouthandle_wasatstart=$+1
  112.         ld a,0
  113.         call setstdouthandle
  114.  
  115.         pop af
  116.         ret;jr cmd_noexeccmdtofileq
  117. ;cmd_noexeccmdtofile
  118. ;        jp execcmd ;a!=0: no such internal command
  119. ;cmd_noexeccmdtofileq
  120. ;        ret
  121.  
  122. ;;;;;;;;;;;;;;;;;;
  123.        
  124. editcmd_up
  125.         ld de,cmdbuf
  126.         ld hl,oldcmd
  127.         ld bc,MAXCMDSZ+1
  128.         ldir
  129.         ;jp editcmd
  130.  
  131. editcmd
  132.         ld hl,cmdbuf
  133.         call strlen
  134.         ld a,l
  135.         ld (curcmdx),a
  136. editcmd0
  137.         call fixscroll_prcmd
  138.         call cmdcalccurxy
  139.         SETXY_
  140.         ;ld e,CURSORCOLOR;0x38
  141.         ;OS_PRATTR ;нарисовать курсор
  142.         call yieldgetkeyloop ;YIELDGETKEYLOOP
  143.          ;ld a,c ;keynolang
  144.         ;push af
  145.         ;call cmdcalccurxy
  146.         ;SETXY_
  147.         ;ld e,COLOR;7
  148.         ;OS_PRATTR ;стереть курсор
  149.         ;pop af
  150.         cp key_enter
  151.         ret z
  152.         cp key_up
  153.         jr z,editcmd_up
  154.          ld hl,editcmd0
  155.          push hl
  156.         ;ld hl,cmdbuf
  157.         cp key_backspace
  158.         jr z,editcmd_backspace
  159.         cp key_left
  160.         jr z,editcmd_left
  161.         cp key_right
  162.         jr z,editcmd_right
  163.         cp 0x20
  164.         ret c ;jr c,editcmdok ;прочие системные кнопки не нужны
  165. ;type in
  166. editcmdtypein
  167.         ld e,a
  168.         ld hl,cmdbuf
  169.         call strlen ;hl=length
  170.         ld bc,MAXCMDSZ
  171.         or a
  172.         sbc hl,bc
  173.         ret nc ;jr nc,editcmdok ;некуда вводить
  174.         call cmdcalctextaddr ;hl=addr, a=curcmdx
  175.         inc a
  176.         ld (curcmdx),a
  177.         jp strinsch ;e=ch
  178.        
  179. editcmd_backspace
  180.         call cmdcalctextaddr ;hl=addr, a=curcmdx
  181.         or a
  182.         ret z ;jr z,editcmdok ;нечего удалять
  183.         dec a
  184.         ld (curcmdx),a
  185.         jp strdelch ;удаляет предыдущий символ
  186.      
  187. editcmd_left
  188.         ld a,(curcmdx)
  189.         or a
  190.         ret z ;jr z,editcmdok ;некуда влево
  191.         dec a
  192.         ld (curcmdx),a
  193.         ret
  194.      
  195. editcmd_right
  196.         call cmdcalctextaddr ;hl=addr, a=curcmdx
  197.         inc (hl)
  198.         dec (hl)
  199.         ret z ;jr z,editcmdok ;некуда право, стоим на терминаторе
  200.         inc a
  201.         ld (curcmdx),a
  202.         ret
  203.  
  204. getword
  205. ;hl=string
  206. ;de=wordbuf
  207. ;out: hl=terminator/space addr
  208. getword0
  209.         ld a,(hl)
  210.         or a
  211.         jr z,getwordq
  212.         sub ' '
  213.         jr z,getwordq
  214.         ldi
  215.         jp getword0
  216. getwordq
  217.         ;xor a
  218.         ld (de),a
  219.         ret
  220.  
  221. execcmd
  222. ;a=0: command executed
  223. ;a!=0: no such internal command
  224.         ld hl,cmdbuf
  225.         ld a,(hl)
  226.         or a
  227.         ret z
  228.                 ;display $
  229.                 ;display wordbuf
  230.         ld de,wordbuf
  231.         call getword ;hl=terminator/space addr
  232.         call skipspaces
  233.         ld (execcmd_pars),hl
  234.                 inc hl
  235.                 ld a,(wordbuf+1)
  236.                 cp ':'
  237.                 jp nz,execcmd0
  238.                 ld a,(wordbuf+2)
  239.                 or a
  240.                 jp z,cmd_t0
  241. execcmd0
  242.         ld hl,commandslist ;list of internal commands
  243. strcpexec0
  244.         ld c,(hl)
  245.         inc hl
  246.         ld b,(hl)
  247.         inc hl
  248.         ld a,b
  249.         cp -1
  250.         ret z ;jr z,strcpexec_tryrun ;a!=0: no such internal command
  251.         ld de,wordbuf
  252.         push hl
  253.         call strcp
  254.         pop hl
  255.         jr nz,strcpexec_fail
  256.         ld h,b
  257.         ld l,c
  258.         call jphl ;execute command
  259.         xor a
  260.         ret ;a=0: command executed
  261. jphl
  262.         jp (hl) ;run internal command
  263. strcpexec_fail
  264.         ld b,-1 ;чтобы точно найти терминатор
  265.         xor a
  266.         cpir ;найдём обязательно
  267.         jr strcpexec0
  268.  
  269. cmd_start
  270. ;выполнить командную строку по фону (нужно из .bat)
  271.         ld hl,cmdbuf
  272.         ld a,(hl)
  273.         or a
  274.         ret z
  275.         ld de,wordbuf
  276.         call getword ;hl=terminator/space addr
  277.         call skipspaces
  278.         ld de,cmdbuf
  279.         ld bc,MAXCMDSZ+1
  280.         ldir
  281.         call strcpexec_tryrun ;выполнить файл с именем cmdbuf или SYSDIR/cmdbuf и параметрами там, e=id, nz=error
  282.         ret z
  283. execcmd_error
  284.         ld hl,tunknowncommand
  285.         jp cmderror
  286.        
  287. strcpexec_tryrun
  288. ;выполнить файл с именем cmdbuf или SYSDIR/cmdbuf и параметрами там, e=id, nz=error
  289.         call loadapp ;загрузить файл с именем cmdbuf, e=id, nz=error, cy=end of .bat
  290.         jr nz,execcmd_tryrunerror
  291. execcmd_tryrunok
  292.         ret c ;cy=end of .bat
  293.         push de
  294.         OS_RUNAPP ;e=id
  295.         pop de
  296.          xor a ;z
  297.         ret
  298.  
  299. execcmd_tryrunerror
  300. ;выполнить файл с именем SYSDIR/cmdbuf и параметрами там
  301.         call loadapp_keeppath
  302.         OS_SETSYSDRV
  303.         ld de,sysdir
  304.         push de
  305.         OS_GETPATH
  306.         call loadapp_setoldpath ;TODO из prompt
  307.          ;OS_SETSYSDRV
  308.          ;ld de,wordbuf2
  309.          ;OS_GETPATH
  310.         ;ld de,cmdprompt
  311.         ;OS_CHDIR
  312.         ;call makeprompt
  313.         ;ld de,cmdprompt
  314.         ;OS_CHDIR
  315.         pop hl
  316.         push hl
  317. ;если в конце нет слеша, то добавим:
  318.         ;ld bc,0 ;чтобы точно найти терминатор
  319.         xor a
  320.         ld b,a
  321.         ld c,a;0
  322.         cpir ;найдём обязательно, если длина=0, то bc=-1 и т.д.
  323.         dec hl ;на терминаторе
  324.         dec hl ;перед терминатором
  325.         ld a,'/'
  326.         cp (hl)
  327.         jr z,$+2+5
  328.          inc hl
  329.          ld (hl),a
  330.          inc hl
  331.          ld (hl),0
  332.         pop hl ;sysdir
  333.         call strlen
  334.         ld b,h
  335.         ld c,l ;bc=SYSDIR_size
  336.          push bc ;SYSDIR_size
  337.         ld hl,MAXCMDSZ+1
  338.         or a
  339.         sbc hl,bc
  340.         push hl ;MAXCMDSZ+1-SYSDIR_size
  341. ;bc=SYSDIR_size
  342.         ld hl,cmdbuf+MAXCMDSZ;+1
  343.         or a
  344.         sbc hl,bc
  345.         ld de,cmdbuf+MAXCMDSZ;+1
  346.         pop bc ;MAXCMDSZ+1-SYSDIR_size
  347.         lddr
  348.         ld hl,sysdir
  349.         ld de,cmdbuf
  350.          pop bc ;SYSDIR_size
  351.         ldir ;нельзя strcopy, т.к. не нужен терминатор
  352.          ;ld hl,sysdir
  353.          ;ld de,oldpath
  354.          ;ld bc,MAXPATH_sz;MAXCMDSZ+1
  355.          ;ldir ;TODO рекурсивно (для .bat)
  356.          ;jr $
  357.         call loadapp ;загрузить файл с именем cmdbuf, e=id, nz=error, cy=end of .bat
  358.         jr z,execcmd_tryrunok
  359.         ret ;nz=error
  360.        
  361. callcmd
  362. ;call command (cmdbuf) with waiting
  363.         call execcmd ;a!=0: no such internal command
  364.         or a
  365.         ret z ;command executed
  366.         ;call loadapp ;загрузить файл с именем cmdbuf, e=id
  367.         call strcpexec_tryrun ;загрузить файл с именем cmdbuf или SYSDIR/cmdbuf, e=id, nz=error
  368.         jr nz,execcmd_error
  369.         ;push de
  370.         ;OS_RUNAPP
  371.         ;pop de
  372.         WAITPID
  373.         ret
  374.  
  375. loadapp_keeppath
  376.         ld hl,cmdprompt
  377.         ld de,oldpath
  378.         ld bc,MAXPATH_sz;MAXCMDSZ+1
  379.         ldir ;TODO рекурсивно (для .bat)
  380.         ret
  381.  
  382. loadapp_setoldpath
  383.         push de
  384.         ld de,oldpath ;TODO рекурсивно (для .bat)
  385.         OS_CHDIR
  386.         pop de
  387.         xor a
  388.         ret ;Z
  389.        
  390. loadapp
  391. ;out: nz=error, cy=end of .bat, or else e=id
  392.         ld hl,cmdbuf
  393.         ld de,wordbuf
  394.         call getword
  395. ;учесть путь в имени (TODO использовать OS_OPENHANDLE)
  396.         ld hl,wordbuf
  397.         push hl
  398.         call findlastslash. ;de=after last slash or beginning of path
  399.         pop hl
  400.  
  401.         ;push hl
  402. ;ищем точку, проверяем, что после неё стоит .com или .bat
  403. loadapp_finddot0
  404.         ld a,(hl)
  405.         or a
  406.         jr z,loadapp_nodot
  407.         cp '.'
  408.         inc hl
  409.         jr nz,loadapp_finddot0
  410. ;проверяем, что после неё стоит .com или .bat
  411.         ld a,(hl)
  412.         or 0x20
  413.         cp 'b'
  414. ; TODO где проверка на остальные буквы?
  415.         jr z,strcpexec_tryrun_bat
  416. ;считаем, что написано .com (в принципе расширение безразлично - просто запускаем)
  417.         jr loadapp_finddotok
  418. loadapp_nodot
  419. ;a=0
  420.         ld (hl),'.'
  421.         inc hl
  422.         ld (hl),'c'
  423.         inc hl
  424.         ld (hl),'o'
  425.         inc hl
  426.         ld (hl),'m'
  427.         inc hl
  428.         ld (hl),a ;0        
  429. loadapp_finddotok
  430.         ld de,wordbuf ;pop de
  431.         OS_OPENHANDLE
  432.         or a
  433.          push af
  434.         ld a,b
  435.         ld (curhandle),a
  436.          call loadapp_setoldpath
  437.          pop af
  438.         ret nz ;jr nz,execcmd_error
  439.         OS_NEWAPP ;на момент создания должна быть включена текущая директория!!!
  440.         or a
  441.         ret nz ;error
  442. ;dehl=номера страниц в 0000,4000,8000,c000 нового приложения, b=id, a=error
  443.         push bc ;b=id
  444.         ld a,d
  445.         SETPG32KHIGH
  446.         push de
  447.         push hl
  448.         ld hl,cmdbuf
  449.         ld de,0xc000+COMMANDLINE
  450.         ld bc,COMMANDLINE_sz
  451.         ldir ;command line
  452.         pop hl
  453.         pop de
  454.         call readfile_pages_dehl
  455.  
  456.         ld a,(curhandle)
  457.         ld b,a
  458.         OS_CLOSEHANDLE
  459.         pop de
  460.         ld e,d ;e=id
  461.         xor a
  462.         ret ;Z
  463.        
  464. strcpexec_tryrun_bat
  465.         ;display "strcpexec_tryrun_bat",strcpexec_tryrun_bat
  466. ;out: nz=error, cy=end of .bat
  467. ;open .bat
  468. ;filename in wordbuf
  469.         ld de,wordbuf ;pop de
  470.         OS_OPENHANDLE
  471.         or a
  472.         ld a,b
  473.         ld (curbathandle),a    
  474.         ret nz ;jp nz,execcmd_error
  475.        
  476.          ld a,0x3c ;"inc a"
  477.          ld (readbyte_readbuf_last),a
  478.         ld iy,file_buf_end
  479. strcpexec_tryrun_bat0
  480. ;load line to cmdbuf
  481.         ld hl,cmdbuf
  482.         LD (hl),0
  483.         call readstr ;nz=EOF
  484.         push af ;jr nz,strcpexec_tryrun_batq ;чтобы последнюю строку всё-таки выполнить
  485.  
  486.         push iy
  487.         ld hl,cmdbuf
  488.         call prtext
  489.         call prcrlf
  490.         pop iy
  491.        
  492. ;call command in cmdbuf
  493.         push iy
  494.         call callcmd
  495.         pop iy
  496.        
  497.         pop af
  498.         jr z,strcpexec_tryrun_bat0 ;nz=EOF
  499. strcpexec_tryrun_batq
  500. ;close .bat
  501.         ld a,(curbathandle)
  502.         ld b,a
  503.         OS_CLOSEHANDLE
  504.         xor a
  505.          scf ;чтобы на выходе не делать RUNAPP
  506.         ret ;Z
  507.  
  508.         macro READBYTE_A
  509. ;out: z=EOF
  510.         inc ly
  511.         call m,readbyte_readbuf
  512.         ld a,(iy)
  513.         endm
  514.  
  515. readstr
  516. ;out: nz=EOF
  517. ;skips empty lines!
  518.         READBYTE_A ;z=EOF
  519.         jr z,readstrEOF
  520.         cp 0x0d
  521.         jr z,readstr ;empty string - retry
  522.         cp 0x0a
  523.         jr z,readstr ;empty string - retry
  524.         ld b,MAXCMDSZ
  525.         jr readstr0go
  526. readstr0
  527.         READBYTE_A ;z=EOF
  528.         jr z,readstrEOF ;возвращает NZ
  529.         ;jr z,readstrq ;возвращает Z
  530.         cp 0x0d
  531.         jr z,readstrq
  532.         cp 0x0a
  533.         jr z,readstrq
  534. readstr0go
  535.         ld (hl),a
  536.         inc hl
  537.         djnz readstr0
  538. readstrq
  539.         xor a ;Z
  540.         ld (hl),a
  541.         inc hl
  542.         ret ;Z
  543. readstrEOF
  544.         xor a
  545.         ld (hl),a
  546.         inc hl
  547.         dec a
  548.         ret ;NZ
  549.  
  550. readbyte_readbuf
  551. ;out: z=EOF
  552.         push bc
  553.         push de
  554.         push hl
  555.         push ix
  556.          ;jr $
  557.         xor a
  558. readbyte_readbuf_last=$ ;TODO keep if recursive!
  559.         inc a ;/nop(z)=last, inc a(nz)=not last
  560.         jr z,readbyte_readbufq
  561.  
  562.         if 1==1
  563. ;B = file handle, DE = Buffer address, HL = Number of bytes to read
  564. curbathandle=$+1
  565.         ld b,0
  566.         ld de,file_buf
  567.         push de
  568.         ld hl,128
  569.         OS_READHANDLE
  570.         pop iy
  571. ;HL = Number of bytes actually read, A=error
  572.         ;sub 1
  573.         ;sbc a,a ;error=0 => a=255, else a=0 (Z)
  574.         ;jr z,readbyte_readbufq ;error (=>EOF)
  575.          ;jr $
  576.         ld a,l
  577.         or a
  578.         jr z,readbyte_readbufq ;0 bytes (=>EOF)
  579.         jp m,readbyte_readbufq ;128 bytes (NZ no EOF) (not last block)
  580.        
  581.         else ;CP/M-like
  582.        
  583.         ld de,file_buf
  584.         push de
  585.         OS_SETDTA ;set disk transfer address = de
  586.         ld de,fcb_bat
  587.         OS_FREAD
  588.         pop iy
  589.         xor 128 ;a = bytes read
  590.         jr z,readbyte_readbufq
  591.         jp m,readbyte_readbufq ;full block = not last block
  592.        
  593.         endif
  594.        
  595. ;last block: shift data to the end of buf, mark last
  596.         ld c,a ;1..128
  597.         ld b,0 ;nz!
  598.         ld a,b
  599.         ld (readbyte_readbuf_last),a ;last block
  600.         ld hl,file_buf
  601.         add hl,bc
  602.         dec hl ;end of data
  603.         ld de,file_buf+127
  604.         lddr
  605.         inc de
  606.         push de
  607.         pop iy
  608.         ;nz!
  609. readbyte_readbufq
  610. ;iy=addr
  611. ;z=EOF
  612.         pop ix
  613.         pop hl
  614.         pop de
  615.         pop bc
  616.         ret
  617.  
  618. readfile_pages_dehl
  619.         ld a,d
  620.         SETPG32KHIGH
  621.         ld a,+(0xc000+PROGSTART)/256
  622.         call cmd_loadpage
  623.         or a
  624.         ret nz
  625.        
  626.         ld a,e
  627.         SETPG32KHIGH
  628.         ld a,0xc000/256
  629.         call cmd_loadpage
  630.         or a
  631.         ret nz
  632.        
  633.         ld a,h
  634.         SETPG32KHIGH
  635.         ld a,0xc000/256
  636.         call cmd_loadpage
  637.         or a
  638.         ret nz
  639.        
  640.         ld a,l
  641.         SETPG32KHIGH
  642.         ld a,0xc000/256
  643.         jp cmd_loadpage
  644.  
  645. cmd_dir
  646.         ld de,fcb
  647.         OS_SETDTA ;set disk transfer address = de
  648.         ;call makeemptymask
  649.         ld de,fcbmask
  650.         OS_FSEARCHFIRST
  651.         or a
  652.         ld bc,0 ;nfiles
  653.         jp nz,loaddir_error
  654. loaddir0
  655.        push bc ;nfiles
  656.        
  657.         ld hl,fcb+FCB_FNAME
  658.        
  659.          ld de,dirfnbuf
  660.         push de
  661.          ld bc,8
  662.          ldir
  663.          ld a,(fcb+FCB_FATTRIB)
  664.          and FATTRIB_DIR
  665.          xor '.'
  666.          ld (de),a
  667.          inc de
  668.          ld c,3
  669.          ldir
  670.         pop hl
  671.         ld de,8+1+3+1
  672.         call cmdprNchars
  673.  
  674.         ; ld de,8
  675.         ;call cmdprNchars
  676.         ;ld a,(fcb+FCB_FATTRIB)
  677.         ;and FATTRIB_DIR
  678.         ;xor '.'
  679.         ;push hl
  680.         ;PRCHAR_
  681.         ;pop hl
  682.         ;ld de,3
  683.         ;call cmdprNchars
  684.         ;ld a,' '
  685.         ;PRCHAR_
  686.  
  687.         ld hl,(fcb+FCB_FSIZE+2)
  688.         exx
  689.         ld hl,(fcb+FCB_FSIZE)
  690.         call prdword
  691.         ld a,' '
  692.         PRCHAR_
  693.         ld ix,(fcb+FCB_FDATE)
  694.         ld hl,(fcb+FCB_FTIME)
  695.         call prdate_time
  696.         call prcrlf
  697.         ld de,fcb
  698.         OS_SETDTA ;set disk transfer address = de
  699.          ;call makeemptymask ;в CP/M не нужно, но отсутствие вредит многозадачности
  700.          ld de,fcbmask ;в CP/M не нужно, но отсутствие вредит многозадачности
  701.         OS_FSEARCHNEXT
  702.        
  703.        pop bc ;nfiles
  704.         inc bc ;nfiles
  705.         or a
  706.         jp z,loaddir0
  707. loaddir_error
  708. loaddirq
  709. ;bc=nfiles
  710.         ld h,b
  711.         ld l,c
  712.         call prword
  713.         ld hl,t_files_crlf
  714.         jp prtext
  715.  
  716. dirfnbuf
  717.         db "filename.ext "
  718.  
  719. prdate_time
  720. ;ix=date, hl=time
  721.         ld de,datetimebuf
  722.        push de
  723.        push hl ;time
  724.         ;push ix ;date
  725.         ld a,hx
  726.         srl a
  727.         sub 20
  728.         jr nc,$+4
  729.         add a,100 ;XX century
  730.         call prNNcmd ;year
  731.         ;ld a,'-'
  732.         ;PRCHAR_
  733.          inc de
  734.         ;pop hl
  735.         ld a,lx
  736.         push af
  737.         add ix,ix
  738.         add ix,ix
  739.         add ix,ix
  740.         ld a,hx
  741.         and 0x0f
  742.         call prNNcmd ;month
  743.         ;ld a,'-'
  744.         ;PRCHAR_
  745.          inc de
  746.         pop af
  747.         and 0x1f
  748.         call prNNcmd ;day
  749.  
  750.         ;ld a,' '
  751.         ;PRCHAR_
  752.          inc de
  753.        pop hl ;time
  754.         push hl
  755.         ld a,h
  756.         rra
  757.         rra
  758.         rra
  759.         and 0x1f
  760.         call prNNcmd ;hour
  761.         ;ld a,':'
  762.         ;PRCHAR_
  763.          inc de
  764.         pop hl
  765.         ld a,l
  766.         push af
  767.         add hl,hl
  768.         add hl,hl
  769.         add hl,hl
  770.         ld a,h
  771.         and 0x3f
  772.         call prNNcmd ;minute
  773.         ;ld a,':'
  774.         ;PRCHAR_
  775.          inc de
  776.         pop af
  777.         add a,a
  778.         and 0x3f
  779.         call prNNcmd ;second
  780.        pop hl
  781.         ld de,8+1+8
  782.         jp cmdprNchars
  783.  
  784. prNNcmd
  785. ;a=NN
  786. ;de=buf
  787.         ld bc,10+(256*('0'-1))
  788.         sub c
  789.         inc b
  790.         jr nc,$-2
  791.          ex de,hl
  792.          ld (hl),b
  793.          ex de,hl
  794.          inc de
  795.         add a,'0'+10
  796.          ld (de),a
  797.          inc de
  798.         ret
  799.  
  800. datetimebuf
  801.         db "00-00-00 00:00:00"
  802.        
  803. skipspaces
  804. ;hl=string
  805. ;out: hl=after last space
  806.         ld a,(hl)
  807.         cp ' '
  808.         ret nz
  809.         inc hl
  810.         jr skipspaces
  811.  
  812. strcopy
  813. ;hl->de
  814. strcopy0
  815.         ld a,(hl)
  816.         ldi
  817.         or a
  818.         jr nz,strcopy0
  819.         ret
  820.  
  821. cmd_cd
  822. execcmd_pars=$+1
  823.         ld hl,0
  824.         ld a,(hl)
  825.         or a
  826.         jr z,cmd_error_nopars
  827.         ex de,hl ;de=path
  828.         OS_CHDIR
  829.         or a
  830.         ret z
  831.         ld hl,twrongpath
  832.         jp cmderror
  833.        
  834. cmd_error_nopars
  835.         ld hl,tnopars
  836.         jp cmderror
  837. cmd_error_notenoughpars
  838.         ld hl,tnotenoughpars
  839.         jp cmderror
  840.  
  841. cmd_md
  842.         ld hl,(execcmd_pars)
  843.         ld a,(hl)
  844.         or a
  845.         jr z,cmd_error_nopars
  846.         ex de,hl ;de=dirname
  847.         OS_MKDIR
  848.         or a
  849.         ret z
  850. cmd_error_cantmakedir
  851.         ld hl,tcantmakedir
  852.         jp cmderror
  853.        
  854. cmd_del
  855.         ld hl,(execcmd_pars)
  856.         ld a,(hl)
  857.         or a
  858.         jr z,cmd_error_nopars
  859.         ex de,hl
  860.         OS_DELETE
  861.         or a
  862.         ret z
  863. cmd_error_wrongfile
  864.         ld hl,twrongfile
  865.         jp cmderror
  866.        
  867. cmd_ren
  868.         ld hl,(execcmd_pars)
  869.         ld a,(hl)
  870.         or a
  871.         jr z,cmd_error_nopars
  872.         ld de,wordbuf
  873.         call getword ;hl=terminator/space addr
  874.         call skipspaces
  875.         ld a,(hl)
  876.         or a
  877.         jr z,cmd_error_notenoughpars
  878.         ld de,wordbuf2
  879.         call getword ;hl=terminator/space addr
  880.         ld de,wordbuf
  881.         ld hl,wordbuf2
  882.         OS_RENAME
  883.         or a
  884.         ret z
  885.         ld hl,tcantrename
  886.         jp cmderror
  887.        
  888. cmd_copy
  889.         ld hl,(execcmd_pars)
  890.         ld a,(hl)
  891.         or a
  892.         jr z,cmd_error_nopars
  893.         ld de,filenamebuf;wordbuf
  894.         call getword ;hl=terminator/space addr
  895.         call skipspaces
  896.         ld a,(hl)
  897.         or a
  898.         jr z,cmd_error_notenoughpars
  899.         ld de,filenamebuf2;wordbuf2
  900.         call getword ;hl=terminator/space addr
  901.  
  902.         ld de,filenamebuf;wordbuf ;de=drive/path/file
  903.         OS_OPENHANDLE
  904.         or a
  905.         jp nz,cmd_error_wrongfile
  906.         ld a,b
  907.         ld (close_file1_handle),a
  908.         ld hl,close_file1
  909.         push hl
  910.        
  911.         ld de,filenamebuf2;wordbuf2 ;de=drive/path/file
  912.         OS_CREATEHANDLE
  913.         or a
  914.         jp nz,cmd_error_cant_copy
  915.         ld a,b
  916.         ld (cmd_copy_close_file2_handle),a
  917.         ld hl,cmd_copy_close_file2
  918.         push hl
  919. cmd_copy0
  920.         ld hl,copybuf_sz
  921.         ld de,copybuf
  922.         ld a,(close_file1_handle)
  923.         ld b,a
  924. ;B = file handle, DE = Buffer address, HL = Number of bytes to read
  925.         push de
  926.         OS_READHANDLE
  927. ;HL = Number of bytes actually read, A=error
  928.         pop de
  929.         ld a,h
  930.         or l
  931.         ret z ;0 bytes remain
  932.         ld a,(cmd_copy_close_file2_handle)
  933.         ld b,a
  934. ;B = file handle, DE = Buffer address, HL = Number of bytes to write
  935.         OS_WRITEHANDLE
  936.         jr cmd_copy0
  937.        
  938. close_file1
  939. close_file1_handle=$+1
  940.         ld b,0
  941.         OS_CLOSEHANDLE
  942.         ret
  943.        
  944. cmd_copy_close_file2
  945. cmd_copy_close_file2_handle=$+1
  946.         ld b,0
  947.         OS_CLOSEHANDLE
  948.         ld de,filenamebuf;wordbuf;filenametext
  949.         OS_GETFILETIME ;ix=date, hl=time
  950.         ld de,filenamebuf2;wordbuf2
  951.         OS_SETFILETIME
  952.         ret      
  953.        
  954. cmd_error_cant_copy
  955.         ld hl,tcantcopy
  956.         jp cmderror
  957.  
  958. cmd_rem
  959.         ret
  960.        
  961. cmd_mem
  962.         ld hl,tfree
  963.         call prtext
  964.         ld b,0
  965. cmd_mem0
  966.         push bc
  967.         OS_NEWPAGE
  968.         pop bc
  969.         or a
  970.         jr nz,cmd_mem_del
  971.         inc b
  972.         push de
  973.         jr cmd_mem0
  974. cmd_mem_del
  975.         ld c,b
  976.         inc b
  977.         dec b
  978.         jr z,cmd_mem_q
  979. cmd_mem_del0
  980.         pop de
  981.         push bc
  982.         OS_DELPAGE
  983.         pop bc
  984.         djnz cmd_mem_del0
  985. cmd_mem_q
  986. ;c=free pages
  987.         ld l,c
  988.         ld h,0
  989.         call prword
  990.         jp prcrlf
  991.  
  992. cmd_drop
  993.         ld hl,(execcmd_pars)
  994.         ld a,(hl)
  995.         or a
  996.         jp z,cmd_error_nopars
  997.         xor a
  998.         ld d,a
  999. cmd_drop_par0
  1000.         add a,d
  1001.         ld e,a ;id
  1002.         add a,a
  1003.         add a,a
  1004.         add a,e
  1005.         add a,a
  1006.         ld d,a ;d=e*10
  1007.         ld a,(hl)
  1008.         inc hl
  1009.         sub '0'
  1010.         cp 10
  1011.         jr c,cmd_drop_par0
  1012.         ;e=id
  1013.         OS_DROPAPP
  1014.         or a
  1015.         ret z
  1016.         ld hl,twrongid
  1017.         jp cmderror
  1018.        
  1019. cmd_proc
  1020.         ld e,1 ;no id 0
  1021. cmd_proc0
  1022.         push de
  1023.         OS_GETAPPMAINPAGES ;d,e,h,l=pages in 0000,4000,8000,c000, c=flags
  1024.         or a
  1025.         jr nz,cmd_proc_skip
  1026.         ld a,d
  1027.         pop de
  1028.         push de
  1029.          push bc
  1030.         push af
  1031.         ex de,hl
  1032.         ld h,0
  1033.         call prword
  1034.         ld a,' '
  1035.         PRCHAR_
  1036.         pop af ;main page
  1037.         SETPG32KHIGH
  1038.          pop bc ;c=flags
  1039.          push bc
  1040.          bit factive,c
  1041.          ld a,'-'
  1042.          jr z,$+4
  1043.          ld a,'+'
  1044.          PRCHAR_
  1045.          pop bc
  1046.          push bc
  1047.          bit fgfx,c
  1048.          ld a,' '
  1049.          jr z,$+4
  1050.          ld a,'g'
  1051.          PRCHAR_
  1052.          pop bc
  1053.           bit fwaiting,c
  1054.           ld a,' '
  1055.           jr z,$+4
  1056.           ld a,'w'
  1057.           PRCHAR_
  1058.          ld a,' '
  1059.          PRCHAR_
  1060.         ld hl,0xc000+COMMANDLINE
  1061.         call prtext
  1062.         call prcrlf
  1063. cmd_proc_skip
  1064.         pop de
  1065.         inc e
  1066.         ld a,e
  1067.         inc a ;no id 0xff
  1068.         jr nz,cmd_proc0
  1069.         ret
  1070.  
  1071. cmd_date
  1072.         OS_GETTIME ;ix=date, hl=time
  1073.         call prdate_time
  1074.         jp prcrlf
  1075.        
  1076. cmd_t0
  1077.         ld a,(wordbuf)
  1078.         and 0xdf
  1079.         sub 'A'
  1080.         call cmdsetdrive
  1081.         or a
  1082.         ret z
  1083.         ld hl,tdrivenotfound
  1084.         jp cmderror
  1085.        
  1086. cmderror
  1087.         push hl
  1088.         ld de,_ERRORCOLOR
  1089.         SETCOLOR_
  1090.         pop hl
  1091.         call prtext
  1092.         ld de,_COLOR
  1093.         SETCOLOR_
  1094. prcrlf
  1095.         ;ld a,0x0d
  1096.         ;PRCHAR_
  1097.         ;ld a,0x0a
  1098.         ;PRCHAR_
  1099.         ld hl,crlfbuf
  1100.         ld de,2
  1101.         jp cmdprNchars
  1102. crlfbuf
  1103.         db 0x0d,0x0a
  1104.        
  1105. cmdsetdrive
  1106.         ld e,a
  1107.         OS_SETDRV
  1108.         ret
  1109.  
  1110. cmd_type
  1111.         ld hl,(execcmd_pars)
  1112.         ld a,(hl)
  1113.         or a
  1114.         jp z,cmd_error_nopars
  1115.         ld de,wordbuf
  1116.         call getword ;hl=terminator/space addr
  1117.  
  1118.         ld de,wordbuf ;de=drive/path/file
  1119.         OS_OPENHANDLE
  1120.         or a
  1121.         jp nz,cmd_error_wrongfile
  1122.         ld a,b
  1123.         ld (close_file1_handle),a
  1124.         ld hl,close_file1
  1125.         push hl
  1126.        
  1127. cmd_type0
  1128. ;B = file handle, DE = Buffer address, HL = Number of bytes to read
  1129.         push bc
  1130.         ld de,cmd_type_buf
  1131.         ld hl,1
  1132.         OS_READHANDLE
  1133. ;HL = Number of bytes actually read, A=error
  1134.         pop bc
  1135.         ld a,h
  1136.         or l
  1137.         ret z ;0 bytes remain
  1138.         push bc
  1139. cmd_type_buf=$+1
  1140.         ld a,0
  1141.         PRCHAR_
  1142.         pop bc
  1143.         jr cmd_type0
  1144.        
  1145. cmd_tee
  1146. ;tee filename
  1147. ;copy sdtin to filename and to stdout
  1148.         ld hl,(execcmd_pars)
  1149.         ld a,(hl)
  1150.         or a
  1151.         jp z,cmd_error_nopars
  1152.         ld de,wordbuf
  1153.         call getword ;hl=terminator/space addr
  1154.  
  1155.         ld de,wordbuf ;de=drive/path/file
  1156.         OS_CREATEHANDLE
  1157.         or a
  1158.         jp nz,cmd_error_wrongfile
  1159.         ld a,b
  1160.         ld (close_file1_handle),a
  1161.         ld hl,close_file1
  1162.         push hl
  1163.        
  1164. cmd_tee0
  1165.         push bc
  1166.         GETKEY_
  1167.         ld (cmd_type_buf),a
  1168.         pop bc
  1169.         ret c ;input pipe closed
  1170.         ld a,(cmd_type_buf)
  1171.         PRCHAR_
  1172. ;B = file handle, DE = Buffer address, HL = Number of bytes to read
  1173.         push bc
  1174.         ld de,cmd_type_buf
  1175.         ld hl,1 ;TODO набивать буфер, потом писать много
  1176.         OS_WRITEHANDLE
  1177. ;HL = Number of bytes actually written, A=error?
  1178.         pop bc
  1179.         jr cmd_tee0
  1180.        
  1181. cmd_echo
  1182.         ld hl,(execcmd_pars)
  1183.         call prtext
  1184.         jp prcrlf
  1185.        
  1186. cmd_pause
  1187.         call yieldgetkeyloop ;YIELDGETKEYLOOP
  1188.          cp key_redraw
  1189.          jr z,cmd_pause
  1190.         ret
  1191.  
  1192. cmd_copydir
  1193.         ld hl,(execcmd_pars)
  1194.         ld a,(hl)
  1195.         or a
  1196.         jp z,cmd_error_nopars
  1197.         ld de,wordbuf
  1198.         call getword ;hl=terminator/space addr
  1199.         call skipspaces
  1200.         ld a,(hl)
  1201.         or a
  1202.         jp z,cmd_error_notenoughpars
  1203.         ld de,wordbuf2
  1204.         call getword ;hl=terminator/space addr
  1205.  
  1206. cmd_copydir_go
  1207.         ld hl,wordbuf
  1208.         call prtext
  1209.         ld a,'>'
  1210.         PRCHAR_
  1211.         ld hl,wordbuf2
  1212.         call prtext
  1213.         call prcrlf
  1214.        
  1215.         ld de,wordbuf2
  1216.         OS_MKDIR
  1217.  
  1218.         ld bc,0 ;номер файла в директории
  1219. cmd_copydir0
  1220.         push bc
  1221.         ld de,cmdprompt
  1222.         OS_CHDIR
  1223.         ld de,wordbuf
  1224.         OS_CHDIR
  1225.         pop bc
  1226.         push bc
  1227.         call getdirfcb_bc
  1228.         pop bc
  1229.         ret nz ;jr nz,cmd_copydirq
  1230.  
  1231.         ld a,(fcb_filename)
  1232.         cp '.'
  1233.         jr z,cmd_copydir0_skip
  1234.         ld a,(fcb+FCB_FATTRIB)
  1235.         and FATTRIB_DIR
  1236.         jr nz,cmd_copydir0_recursive
  1237.        
  1238.         push bc
  1239.         ld hl,fcb_filename
  1240.         ld de,filenamebuf
  1241.         call cpmname_to_dotname
  1242.         call open_setdir2_create_copy
  1243.         pop bc
  1244. cmd_copydir0_skip
  1245.         inc bc
  1246.         jr cmd_copydir0
  1247.  
  1248.         macro STRPUSH
  1249. ;hl=string addr
  1250.         xor a
  1251.         push af
  1252.          ld a,(hl)
  1253.          inc hl
  1254.          or a
  1255.          push af
  1256.         jr nz,$-4
  1257.         pop af
  1258. ;в стеке лежит \0, текст (без терминатора)
  1259.         endm
  1260.        
  1261.         macro STRPOP
  1262. ;hl=string addr
  1263.         ld d,h
  1264.         ld e,l
  1265.          pop af
  1266.          ld (hl),a
  1267.          inc hl
  1268.          or a
  1269.         jr nz,$-4
  1270.         ex de,hl
  1271.         call strmirror
  1272.         endm
  1273.        
  1274. strmirror
  1275. ;hl=string addr
  1276.         ld d,h
  1277.         ld e,l
  1278.         call strlen
  1279.         ld b,h
  1280.         ld c,l
  1281.          ld a,b
  1282.          or c
  1283.          ret z
  1284. ;de=начало, bc=hl=длина
  1285.         ;ld h,b
  1286.         ;ld l,c
  1287.         add hl,de ;hl=конец+1
  1288.         srl b
  1289.         rr c ;bc=wid/2
  1290. mirrorbytes0
  1291.         dec hl
  1292.         ld a,(de)
  1293.         ldi
  1294.         dec hl
  1295.         ld (hl),a
  1296.         jp pe,mirrorbytes0
  1297.         ret
  1298.        
  1299. cmd_copydir0_recursive
  1300. ;recursive copydir <wordbuf>/<filename> <wordbuf2>/<filename>
  1301.         push bc
  1302.         ld hl,wordbuf
  1303.         STRPUSH
  1304.         ld hl,wordbuf2
  1305.         STRPUSH
  1306.         ;ld hl,cmdprompt
  1307.         ;STRPUSH
  1308.  
  1309.         ld hl,wordbuf
  1310.         ld bc,0
  1311.         xor a
  1312.         cpir
  1313.         dec hl ;hl=terminator addr
  1314.         ld (hl),'/'
  1315.         inc hl
  1316.         ex de,hl
  1317.         ld hl,fcb_filename
  1318.         ;ld de,filenamebuf
  1319.         call cpmname_to_dotname
  1320.        
  1321.         ld hl,wordbuf2
  1322.         ld bc,0
  1323.         xor a
  1324.         cpir
  1325.         dec hl ;hl=terminator addr
  1326.         ld (hl),'/'
  1327.         inc hl
  1328.         ex de,hl
  1329.         ld hl,fcb_filename
  1330.         ;ld de,filenamebuf
  1331.         call cpmname_to_dotname
  1332.        
  1333.         call cmd_copydir_go
  1334.  
  1335. ;restore dirnames, file #
  1336.         ;ld hl,cmdprompt
  1337.         ;STRPOP
  1338.         ld hl,wordbuf2
  1339.         STRPOP
  1340.         ld hl,wordbuf
  1341.         STRPOP
  1342.         pop bc
  1343.         jp cmd_copydir0_skip
  1344.        
  1345. open_setdir2_create_copy
  1346.         ;open....
  1347.         ld de,filenamebuf;wordbuf ;de=drive/path/file
  1348.         OS_OPENHANDLE
  1349.         or a
  1350.         jp nz,cmd_error_wrongfile
  1351.         ld a,b
  1352.         ld (close_file1_handle),a
  1353.         ld hl,close_file1
  1354.         push hl
  1355.  
  1356.         ;set dir2...
  1357.         ld de,cmdprompt
  1358.         OS_CHDIR
  1359.         ld de,wordbuf2
  1360.         OS_CHDIR
  1361.  
  1362.         ;create....
  1363.         ld de,filenamebuf;2;wordbuf2 ;de=drive/path/file
  1364.         OS_CREATEHANDLE
  1365.         or a
  1366.         jp nz,cmd_error_cant_copy
  1367.         ld a,b
  1368.         ld (cmd_copy_close_file2_handle),a
  1369.         ld hl,cmd_copy_close_file2
  1370.         push hl
  1371.  
  1372.         ;copy....
  1373.         jp cmd_copy0
  1374.        
  1375.        
  1376. getdirfcb_bc
  1377. ;bc=file number in current dir to read to fcb
  1378. ;nz=error
  1379.         push bc
  1380.         ld de,fcb
  1381.         OS_SETDTA
  1382.         ld de,fcbmask
  1383.         OS_FSEARCHFIRST ;de = pointer to unopened FCB (filename with ????????), read matching FCB to DTA
  1384.         pop bc
  1385.         or a
  1386.         ret nz
  1387.        
  1388. getdirfcb_bc0
  1389.         ld a,b
  1390.         or c
  1391.         ret z
  1392.         dec bc
  1393.         push bc
  1394.         ld de,fcb
  1395.         OS_SETDTA
  1396.         ld de,fcbmask
  1397.         OS_FSEARCHNEXT ;(NOT CP/M!!!)de = pointer to unopened FCB (filename with ????????), read matching FCB to DTA
  1398.         pop bc
  1399.         or a
  1400.         jr z,getdirfcb_bc0
  1401.         ret        
  1402.        
  1403. ;hl = poi to filename in string
  1404. findlastslash.
  1405. nfopenfnslash.
  1406.         ld d,h
  1407.         ld e,l ;de = after last slash
  1408. ;find last slash
  1409. nfopenfnslash0.
  1410.         ld a,[hl]
  1411.         inc hl
  1412.         or a
  1413.         jr z,nfopenfnslashq.
  1414.         cp '/'
  1415.         jr nz,nfopenfnslash0.
  1416.         jr nfopenfnslash.
  1417. nfopenfnslashq.
  1418. ;de = after last slash
  1419.         ret
  1420.  
  1421. commandslist
  1422.         dw cmd_dir
  1423.         db "ls",0
  1424.         dw cmd_dir
  1425.         db "dir",0
  1426.         dw cmd_del
  1427.         db "del",0
  1428.         dw cmd_del
  1429.         db "rm",0
  1430.         dw cmd_exit
  1431.         db "exit",0
  1432.         dw cmd_cd
  1433.         db "cd",0
  1434.         dw cmd_copy
  1435.         db "copy",0
  1436.         dw cmd_copy
  1437.         db "cp",0
  1438.         dw cmd_rem
  1439.         db "rem",0
  1440.         dw cmd_md
  1441.         db "md",0
  1442.         dw cmd_md
  1443.         db "mkdir",0
  1444.         dw cmd_ren
  1445.         db "ren",0
  1446.         dw cmd_ren
  1447.         db "mv",0
  1448.         dw cmd_mem
  1449.         db "mem",0
  1450.         dw cmd_mem
  1451.         db "free",0
  1452.         dw cmd_proc
  1453.         db "proc",0
  1454.         dw cmd_proc
  1455.         db "ps",0
  1456.         dw cmd_tee
  1457.         db "tee",0
  1458.         dw cmd_drop
  1459.         db "drop",0
  1460.         dw cmd_drop
  1461.         db "kill",0
  1462.         dw cmd_date
  1463.         db "date",0
  1464.         dw cmd_start
  1465.         db "start",0
  1466.         dw cmd_copydir
  1467.         db "copydir",0
  1468.         dw cmd_type
  1469.         db "type",0
  1470.         dw cmd_type
  1471.         db "cat",0
  1472.         dw cmd_echo
  1473.         db "echo",0
  1474.         dw cmd_pause
  1475.         db "pause",0
  1476.        
  1477.         dw -1 ;конец таблицы команд
  1478.  
  1479. tunknowncommand
  1480.         db "Unknown command",0
  1481. tdrivenotfound
  1482.         db "Drive not found",0
  1483. tnopars
  1484.         db "No parameters",0
  1485. tnotenoughpars
  1486.         db "Not enough parameters",0
  1487. tcantcopy
  1488.         db "Can't copy",0
  1489. tcantwrite
  1490.         db "Can't write",0
  1491. twrongpath
  1492.         db "Wrong path",0
  1493. twrongfile
  1494.         db "Wrong file",0
  1495. tcantmakedir
  1496.         db "Can't make the directory",0
  1497. tcantrename
  1498.         db "Can't rename",0
  1499. t_files_crlf
  1500.         db " files",0x0d,0x0a,0
  1501. tfree
  1502.         db "free pages=",0
  1503. twrongid
  1504.         db "Wrong ID",0
  1505.        
  1506. ;oldtimer
  1507. ;        dw 0
  1508.        
  1509.         db 0 ;для запарывания на случай отсутствия пути
  1510. wordbuf
  1511.         ds MAXCMDSZ+1
  1512. wordbuf2
  1513.         ds MAXCMDSZ+1
  1514. filenamebuf
  1515.         ds MAXCMDSZ+1
  1516. filenamebuf2
  1517.         ds MAXCMDSZ+1
  1518.  
  1519. fcb
  1520.         ds FCB_sz
  1521. fcb_filename=fcb+FCB_FNAME        
  1522.  
  1523. fcbmask
  1524.         db 0
  1525.         db "???????????"
  1526.         ds FCB_sz-11-1
  1527. fcbmask_filename=fcbmask+FCB_FNAME
  1528.  
  1529. fcb2
  1530.         ds FCB_sz
  1531. fcb2_filename=fcb2+FCB_FNAME        
  1532.  
  1533. fcb_bat
  1534.         ds FCB_sz
  1535. fcb_bat_filename=fcb_bat+FCB_FNAME        
  1536.  
  1537. oldpath ;TODO убрать (когда будет loadapp через OPENHANDLE)
  1538.         ds MAXPATH_sz;MAXCMDSZ+1
  1539.  
  1540. sysdir
  1541.         ds MAXPATH_sz
  1542.        
  1543. oldcmd
  1544.         ds MAXCMDSZ+1
  1545.        
  1546. copybuf
  1547.         ds 128
  1548. copybuf_sz=$-copybuf
  1549.  
  1550.         align 256
  1551. file_buf
  1552.         ds 128
  1553. file_buf_end=$-1
  1554.  
  1555. cmd_loadpage
  1556. ;a=loadaddr/256
  1557. ;out: a=error, bc=bytes read
  1558. ;keeps hl,de
  1559.         push de
  1560.         push hl
  1561.         ld d,a
  1562.         xor a
  1563.         ld l,a
  1564.         ld e,a
  1565.         sub d
  1566.         ld h,a ;de=buffer, hl=size
  1567. curhandle=$+1
  1568.         ld b,0
  1569.         OS_READHANDLE
  1570.         ld b,h
  1571.         ld c,l
  1572.         pop hl
  1573.         pop de
  1574.         ret
  1575.  
  1576.         include "prdword.asm"
  1577.         include "cmdpr.asm"
  1578.         include "../_sdk/stdio.asm"
  1579.  
  1580. cmd_end
  1581.  
  1582.         ;display "cmd size ",/d,cmd_end-cmd_begin," bytes"
  1583.  
  1584.         savebin "cmd.com",cmd_begin,cmd_end-cmd_begin
  1585.        
  1586.         LABELSLIST "..\..\us\user.l"
  1587.