; Обработка BAT-файлов ; ;fhandle BAT_FM: db 0 ; дескр. bat-файла ;count: db 0 ; число прочит. байт из файла ; флаг echo-режима echo_mode: db true ; 1/0 on/off ; буфер bat-файла ;T98B9: ds 256 ;------------------------------------------------- ; Запуск bat-файла ; вход: hl=имя файла ;------------------------------------------------- A83E8: call BATCH jp c,A83DD ; ошибка откр. файла (cpp.asm) ret ; вход: b=число слов "ZERO".."NINE" MAKE_BATCH_PRM_ARRAY: dec hl .loop: inc hl ld a,(hl) or a ret z cp " " jr z,.loop cp 9 ; Tab jr z,.loop ex de,hl ld (hl),e inc hl ld (hl),d inc hl ex de,hl .B_FIND_SPACE: inc hl ld a,(hl) cp " "+1 jr nc,.B_FIND_SPACE ld (hl),0 or a ret z djnz .loop ret ;------------------------------------------------- ; Загрузка и выполнение BAT-файла ; вход: hl=имя файла ; выход: "CF" - ошибка откр. файла ;------------------------------------------------- BATCH: push hl ; сохр. имя bat-файла ld de,work_buffer ; 512 местный буфер call copy_string ; скопир. строку (с нулем) ld hl,work_buffer ; 512 местный буфер ld de,BAT_PRM_ARRAY ; таблица указат. на "ZERO".."NINE" ld b,BAT_PRM_ARRAY.TOTAL ; число слов "ZERO".."NINE" call MAKE_BATCH_PRM_ARRAY jr nz,.B_ALL_P ld hl,NULL ; ds 2*10 ex de,hl .B_CLR_P: ld (hl),e inc hl ld (hl),d inc hl djnz .B_CLR_P ex de,hl .B_ALL_P: pop hl ; восст. имя bat-файла ld a,Dss.Open.R ; на чтение ld c,Dss.Open ; открыть файл RST ToDSS push af ; сохр. код ошибки call c,restore_disk_path ; восст. тек. диск и путь ;R10 CALL Restore_Screen ;R10 pop af ret c ld (BAT_FM),a ; дескр. bat-файла ; выполн. команд bat-файла call NEWLINE xor a ret ;--------------------------------------------------- ; Выполнение команд BAT-файла ;--------------------------------------------------- NEWLINE: ld de,struct_input_line+5 ;!HARDCODE .ADDBAT: push de call READBAT ; прочитать 128 байт из файла в "work_buffer1" pop de or a ; a=число прочит. байт jr nz,.BATLINE ex de,hl ;ld de,T96AE ;;256 буфер (inline.asm) ld de,struct_input_line+5 sbc hl,de jr z,.exit; ;[x] Vasil, убран баг с незакрытым BAT-файлом ld a,l ld (struct_input_line+4),a ; длина строки call CMDMODE ; тест на bat-команды "rem","pause" .exit: ld a,(BAT_FM) ; дескр. bat-файла ld c,Dss.Close ; закрыть файл RST ToDSS ret ; .BATLINE: ;ld hl,T99B9 ; откуда, 128 буфер (ccp.asm) "work_buffer1" ld hl,work_buffer1 .loop: call MOVWORD ; скопир. work_buffer1 -> struct_input_line+5 jr c,.ADDBAT ld a,b ld (MOVWORD.count),a ; осталось пропарсить прочитанных байтов push hl ex de,hl ;ld de,T96AE ;;256 буфер (inline.asm) ld de,struct_input_line+5 ;ld de,work_buffer+256;; sbc hl,de ld a,l ;ld (D96AD),a ;; длина строки (inline.asm) ld (struct_input_line+4),a ; длина строки call CMDMODE ; тест на bat-команды "rem","pause" ;ld de,T96AE ;;256 буфер (inline.asm) ld de,struct_input_line+5 ;ld de,work_buffer+256;; pop hl jr .loop ;------------------------------------------------- ; Чтение данных (hl) -> (de), при необходимости ; подкачка из файла. ; ; вход: hl=откуда ; de=куда ;------------------------------------------------- MOVWORD: .count+1: ld a,0 ; (число прочит. байт из файла)/128 ld b,a .loop: ld a,(hl) ld (de),a cp " " jr c,.loop2 inc hl inc de djnz .loop scf ret ; прочитать доп. блок из файла .loop2: ld a,(hl) cp " " ret nc inc hl djnz .loop2 push de call READBAT ; прочитать 128 байт из файла pop de ;ld hl,BATBUFF ; 128 буфер (ccp.asm) "work_buffer1" ld hl,work_buffer1 ld b,a ; число прочит. байт or a jr nz,.loop2 scf ret ; прочитать 128 байт из файла READBAT: ;ld hl,T99B9 ; 128 буфер под данные (ccp.asm) "work_buffer1" ld hl,work_buffer1 ld de,128 ; сколько ld a,(BAT_FM) ; дескр. bat-файла ld c,Dss.Read ; чтение файла RST ToDSS ld a,e ld (MOVWORD.count),a ; (число прочит. байт из файла)/128 ret ; Тест на bat-команды "rem","pause" CMDMODE: ;xor a ;ld (D96A6),a ; (inline.asm) call EVALCMD ; (batch.asm) ;ld ix,T96AC ; нужно?? закоментарил (inline.asm) ;ld hl,T96AE ;;256 буфер (inline.asm) ld hl,struct_input_line+5 ;ld hl,work_buffer+256;; ld a,(hl) cp "@" ; 40h jr nz,A8240 dec hl ;ld hl,struct_input_line+4;; dec (hl) jr z,A825B ld c,(hl) ; длина строки inc hl ld b,0 ;ld hl,work_buffer+256;; ld d,h ld e,l inc hl ldir jr A825B ; A8240: ld a,(echo_mode) ; флаг echo-режима or a jr z,A825B ; off ; вывести сист. путь и строку содержимого bat-файла ;ld de,T96AE ;;256 буфер (inline.asm) ;ld de,struct_input_line+5 ;call A95DE ; вывод экран. пути с ">" (inline.asm) ; вывести экран. путь и введ. команду ld c,BIOS.LP_GET_PLACE ; узнать полож. курсора RST ToBIOS ld (YXpos),de ; Y/X начало ком-строки ld (cursor_position),de ; Y/X позиция курсора call print_compath ; вывести путь + новая ширина поля ввода ld de,(YXpos) ; Y/X начало ком-строки ld c,Dss.Locate ; уст. полож. курсора RST ToDSS ;ld hl,work_buffer+256;; ld hl,struct_input_line+4 ; длина строки ld a,(hl) ld b,a inc hl ;+5 push bc ld c,BIOS.LP_PRINT_LINE2 ; вывод строки без атрибутов RST ToBIOS pop bc ; b=длина строки ld a,(width_inpline) ; ширина поля ввода (76..48) sub b ei ret z ; правый край экрана jr c,A8250; ; строка больше ширины экрана ; заполнить строку до конца экрана dec a ; чтобы не сработал скроллинг экрана ;!FIXIT scroll ld b,a ; число вывод. символов ld a," " ; символ ld c,BIOS.LP_PRINT_SYM ; вывод символа без атрибута RST ToBIOS ei ;!TEST A8250: call newline ; ; ;ld a,(D96AD) ;; длина строки (inline.asm) ;ld a,(struct_input_line+4);- ;or a ;ret z ;call newline ;jr A8264 ; A825B: ;ld a,(D96AD) ;; длина строки (inline.asm) ld a,(struct_input_line+4) or a ret z ;A8264: ld hl,T96AE ;;256 буфер (inline.asm) ;ld hl,struct_input_line+5 ;dec hl ; убрать концевые пробелы строки ld hl,struct_input_line+4 ld c,(hl) ; hl=длина строки (inline.asm) ld b,0 inc hl ;ld hl,work_buffer+256;; A826C: ld a,(hl) cp " " jr nz,A8276 inc hl dec c jr nz,A826C ret ; A8276: ld d,h ld e,l add hl,bc ld (hl),b ; 0 в конец строки (первого конц. пробела) sbc hl,bc ld a,c ex af,af' ld a," " cpir jr nz,A8286 inc c A8286: ex af,af' sub c ld c,a ; длина слова или строки ? ld hl,BATLIST ; команды "pause","rem" + dos-команды ; de=struct_input_line+5, c=длина строки (без конц. пробелов) ; выполн. команду или запустить файл jp COMP004 ; должна убрать конц. пробелы и уст. длину строки, если урезалась EVALCMD: xor a ld hl,struct_input_line+4 ;!HARDCODE ld c,(hl) ld b,a inc hl add hl,bc ld (hl),a ; 0 в конец строки sbc hl,bc ld de,work_buffer2 ; 256 буфер call EVALSTR ld hl,work_buffer2 ;work_buffer+256 ld de,struct_input_line+5 ; куда ld bc,255 .loop: ld a,(hl) ldi inc b or a jr nz,.loop dec b ld a,b ld (struct_input_line+4),a ; длина строки (edline.asm) and a ret ; HL - STRING WITH %VAR% EVALSTR: ld a,(hl) cp "%" jr z,.TVARIABLE .VARL1: ldi or a jr nz,EVALSTR ld bc,0 ld (.TVAR_PNT),bc ret ; .TVARIABLE: .TVAR_PNT+1: ld bc,0 ld a,b or c ld a,"%" ld (.TVAR_PNT),de jr nz,.TVAR1 inc hl ld a,(hl) ;!FIXIT я в console.asm исправлял баг с параметром %A например. Тут мои правки или Василя? cp "9"+1 jr c,.TVAR0 .TVAR2: ld a,"%" ; > "9" dec hl jp .VARL1 .TVAR0: cp "0" jr c,.TVAR2 ; < "0" ; BATCH PARAM %0, %1, %2 ... inc hl push hl ld (.TVAR_PNT),bc sub "0" add a,a ld c,a ld hl,BAT_PRM_ARRAY ; таблица указат. на "ZERO".."NINE" add hl,bc ld a,(hl) inc hl ld h,(hl) ld l,a or h jr z,.NOBTP ; NO BATCH PARM call copy_string ; скопир. строку (с нулем) dec de .NOBTP: pop hl jp EVALSTR ; .TVAR1: push hl ld h,d ld l,e dec hl and a sbc hl,bc jr z,.TNOVAR ld a,"=" ld (de),a inc de xor a ld (de),a ld d,b ; de=буфер значения перем. ld e,c ld h,b ; hl=имя перем. ld l,c inc hl ld bc,Dss.Environ.Get*256 + Dss.Environ ; получить перем. окружения RST ToDSS .TNOVAR: pop hl inc hl ld bc,0 ld (.TVAR_PNT),bc jp EVALSTR ; !! Не делать одну команду > 256 символов)) !! ; ; BAT-команды (не отделять от дос-команд) BATLIST: DZ 'PAUSE' : DW cmd_pause ;CPAUSE DZ 'REM' : DW cmd_rem ;CREM ; ; DSS-команды CMDLIST: DZ 'CD' : DW cmd_chdir ;CCHDIR DZ 'DIR' : DW cmd_dir ;DIR DZ 'ECHO' : DW cmd_echo ;CECHO DZ 'ECHO.' : DW cmd_echoLN DZ 'PATH' : DW cmd_path ;CPATH DZ 'MD' : DW cmd_mkdir ;CMKDIR DZ 'REN' : DW cmd_rename ;CRENAM DZ 'DEL' : DW cmd_del ;CDELET DZ 'RD' : DW cmd_rmdir ;CRMDIR DZ 'SET' : DW cmd_set ;CSET DZ 'TIME' : DW cmd_time ;CTIME DZ 'DATE' : DW cmd_date ;CDATE DZ 'VER' : DW cmd_version ;VERS DZ 'CLS' : DW cmd_cls ;CLS DZ 'CHDIR' : DW cmd_chdir ;CCHDIR DZ 'MKDIR' : DW cmd_mkdir ;CMKDIR DZ 'RENAME' : DW cmd_rename ;CRENAM DZ 'ERASE' : DW cmd_del ;CDELET DZ 'RMDIR' : DW cmd_rmdir ;CRMDIR DZ 'HELP' : DW cmd_help ;HELP DZ 'VERSION' : DW cmd_version ;VERS DZ 'EXIT' : DW cmd_exit ;CEXIT DZ 'REBOOT' : DW cmd_reboot ;REBOOT DB #00 IZERO DB "ZERO",0 IONE DB "ONE",0 ITWO DB "TWO",0 ITHREE DB "THREE",0 IFOUR DB "FOUR",0 IFIVE DB "FIVE",0 ISIX DB "SIX",0 ISEVEN DB "SEVEN",0 IEIGHT DB "EIGHT",0 ININE DB "NINE",0 BAT_PRM_ARRAY: DW IZERO, IONE, ITWO, ITHREE, IFOUR, IFIVE, ISIX, ISEVEN, IEIGHT, ININE DW 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 10 число слов "ZERO".."NINE" .TOTAL EQU ($-BAT_PRM_ARRAY)/4 DISPLAY "First compilation test: 10 = ",/D, BAT_PRM_ARRAY.TOTAL ASSERT BAT_PRM_ARRAY.TOTAL = 10, "BAT_PRM_ARRAY.TOTAL" NULL: DB 0 ;TVAR_PNT: DW 0