IX.5.1. Р а б о т а с п р о г р а м м н ы м и ф а й л а м и В этом пункте описаны команды SAVE, LOAD, MERGE, RUN. А. Команда ┌─────────────────┐ │ SAVE α [,A] │ , └─────────────────┘ где: SAVE - служебное слово; α - строковое выражение; записывает в формате ASCII на магнитную ленту программу из оперативной па- мяти. Имя программы формируется из первых 6 символов значения строкового вы- ражения α. Оно должно начинаться префиксом "CAS:", который в этом случае рассматривается как и м я у с т р о й с т в а и не учитывается при под- счете длины α, например: SAVE"CAS:СОСНА" , SAVE"CAS:анкета",A . Заметим, что имя программы может быть опущено. Например: SAVE"CAS:" В. Выполнение команды ┌─────────────────┐ │ LOAD α [,R] │ , └─────────────────┘ где: LOAD - служебное слово; α - строковое выражение, значение которого определяет имя файла; наличие параметра R приводит к автоматическому запуску загруженной программы на счет, начинается с закрытия всех файлов и чистки оперативной памяти от программ и данных. Далее программа, записаная на ленте в формате ASCII под именем, равным значению строкового выражения α, считывается в память. Например: LOAD"CAS:труба" , LOAD"CAS:King",R . Поиск конкретной программы на ленте сопровождается индикацией сообще- ний обо всех "попавшихся под руку" при этом файлах с другими именами, за- писанных в формате ASCII. Приведем пример сообщения на экране дисплея при выполнении команды LOAD (учтите, что: "to skip"-"перескочить", "to found" - "находить"): α) Skip:PRIM1 Skip: ◀── встретилась программа без имени Found:PRIM3 β) Found: ◀── найдена и загружается программа без имени. ┌───────────────────────┐ Команда │ LOAD"CAS:" [,R] │ └───────────────────────┘ считывает в память первую встреченную на ленте программу в формате ASCII. ┌───────────────────────┐ C. │ RUN α │ └───────────────────────┘ Эта команда, если в ней указаны имя устройства и имя программы,загружа- ет и запускает на выполнение программу, сохраненную в формате ASCII. Она похожа на команду LOAD (с параметром R), за тем исключением,что она загру- жает программы только в формате ASCII и закрывает все открытые файлы. В обоих случаях перед загрузкой программы автоматически выполняется ко- манда NEW. П р и м е р. Команда RUN"CAS:PROG1" загружает и запускает программу ─────────── с именем "PROG1",сохраненную на магнитной ленте командой SAVE"CAS:PROG1" D. При выполнении команды ┌──────────┐ │ MERGE α │ , └──────────┘ где: MERGE - служебное слово; α - строковое выражение, значение которого определяет имя файла, закрываются файлы и организуется "чистка" оперативной памяти от данных. Затем, программа, записанная на ленте в формате ASCII под именем, рав- ным значению строкового выражения α, "сливается" с программой β, находя- щейся в памяти. При этом,если в α и β совпадают некоторые номера строк,то сохраняются лишь соответствующие строки загружаемой программы α. Например: MERGE"CAS:Мама!" Выдача сообщений на экране при поиске программы α здесь такая же,как и в случае с командой LOAD. ┌───────────────┐ Команда │ MERGE"CAS:" │ └───────────────┘ подгружает в память первую встреченную на ленте в формате ASCII программу. Обратите внимание на тот факт,что программы, вызываемые командой MERGE, имеют более высокий приоритет, по сравнению с программами, находящимися в памяти компьютера. Поэтому если в объединяемых программах имеются строки с одинаковыми номерами, то строки программы в памяти компьютера будут за- менены соответствующими строками "добавляемой" программы. А. Команда (оператор) CSAVE "сохраняет"программу, записывая ее на кас- сету магнитной ленты. Формат оператора: ┌───────────────┐ │ CSAVE β;[S] │ , └───────────────┘ где: CSAVE("Casette SAVE"-"запись на кассету") - служебное слово; β - строковое выражение, значение которого определяет имя файла, в имени программы допускается использование любых символов, причем значащи- ми в имени являются только первые шесть символов; S - арифметическое выражение, целая часть значения которого равна 1 или 2 и определяет скорость записи данных (по умолчанию значение парамет- ра S равнo 1): ┌──────────────────────────────┐ │ 1 ──▶ 1200 бод (1200 бит/с) │ │ 2 ──▶ 2400 бод (2400 бит/с) │ └──────────────────────────────┘ Скорость 2400 бод требует использования хорошего магнитофона и высоко- качественной ленты.Скорость работы по умолчанию может быть переопределена в операторе SCREEN (см.раздел V.7.). ┌───────────────────────────────────────────────────────────────────────┐ │ Команда CSAVE "сохраняет" программу во в н у т р е н н е м формате,│ │ т.е. в том виде, в каком она хранится в памяти компьютера. │ └───────────────────────────────────────────────────────────────────────┘ П р и м е р ы: ───────────── α) команда CSAVE"PROG1" сохраняет файл, имя которого "PROG1", во внут- реннем формате со скоростью 1200 бод (или со скоростью, определенной опе- ратором SCREEN); β) команда CSAVE"PROG2",2 сохраняет файл с именем "PROG2" на кассетной ленте во внутреннем формате со скоростью 2400 бод. ┌────────────────┐ B. Команда │ CLOAD β │ , └────────────────┘ где: CLOAD ("Cassette LOAD"-"загрузка с кассеты") - служебное слово; β - строковое выражение, значение которого определяет имя файла, позволяет загружать программу, сохраненную на кассетной ленте во внутрен- нем формате (с помощью команды CSAVE). Загрузка выполняется на той же ско- рости, на которой программа была сохранена. Таким образом, Вам не нужно повторно указывать скорость. Если имя программы не указано в операторе,то будет загружена первая же программа, сохраненная во внутренем формате. Если Вы указываете имя программы,то следите за правильностью ввода име- ни (т.е.,например, если Вы использовали прописные буквы при написании име- ни, Вы должны ввести имя программы также прописными буквами). ┌───────────────────────────────────────────────────────────────────┐ │ Заметим, что оператор CLOAD автоматически выполняет команду NEW │ │ перед началом загрузки в память найденной программы │ └───────────────────────────────────────────────────────────────────┘ С. Оператор CLOAD? проверяет правильность сохранения программы на кас- сетной ленте.После сохранения программы перемотайте ленту назад и введите команду ┌──────────────┐ │ CLOAD? β │ , └──────────────┘ где: CLOAD?("Casette LOAD verify"-"загрузка с ленты") - служебное слово; β - строковое выражение, значение которого определяет имя файла. Записанная программа, имя которой указано в операторе, сравнивается байт за байтом с текстом программы в памяти компьютера. При обнаружении несов- падения эта процедура прекращается и на экране появляется сообщение об ошибке: "Verify error" ("О ш и б к а в е р и ф и к а ц и и"). Имя программы может быть опущено. В этом случае с содержимым памяти бу- дет сравниваться первая введенная с ленты программа. Если имя программы не совпадает с именем, указанным в операторе, поиск программы с указанным именем будет продолжен. На экране дисплея появится следующее сообщение: Skip:имя программы В нем указано имя найденной "по пути" программы или файла данных. ┌─────────────────────────┐ D. По команде │ BSAVE α,β1,β2[,β3] │ , └─────────────────────────┘ где: BSAVE ("Binary SAVE") - служебное слово; α - строковое выражение; β1,β2,β3 - арифметические выражения, значения которых задают адреса в RAM, содержимое оперативной памяти от β1 и до β2 записывается во внут- реннем представлении на ленту под именем, равным значению строкового выра- жения α. Значение выражения β3 определяет адрес,с которого программа при загрузке ее в память будет запускаться на счет (по умолчанию значение β3 равно значению β1). Если вывод осуществляется не на дисковод А, то следует указать имя устройства. Затем укажите: α) имя файла, β) начальный адрес сохраняемых данных, γ) конечный адрес сохраняемых данных и, возможно, δ) адрес выполнения; если последний пропущен, то адрес, отмечающий на- чало данных, будет автоматически рассматриваться как адрес выполнения при загрузке этих данных (эта часть информации полезна только в том случае,ес- ли сохраняются подпрограммы на машинном языке). П р и м е р ы. 1) BSAVE "CAS:ГОСТ",&HF000,&HF0EE ───────────── 2) BSAVE "CAS:" A,B,C Команда BSAVE позволяет сохранить часть оперативной памяти на ленте или дискете. Это может быть подпрограмма на MSX-BASIC, данные, подпрограм- мы ROM, рабочая область. ┌─────────────────────────────────────────────────────────────────────┐ │ Оператором BSAVE может быть сохранена часть памяти между ячейками │ │ с адресами &H0 и &HFFFF │ └─────────────────────────────────────────────────────────────────────┘ На компьютерах MSX-2 возможна и другая форма записи оператора BSAVE: ┌────────────────────────────────────────┐ │ BSAVE"CAS: и м я ф а й л а",β1,β2,S │. └────────────────────────────────────────┘ Этот оператор сохраняет на кассетной ленте содержимое видеопамяти. ┌────────────────────┐ E. По команде │ BLOAD α,[,R][,β] │ , └────────────────────┘ где: BLOAD ("Binary LOAD") - служебное слово; α - строковое выражение; R - параметр; β - арифметическое выражение;значение параметра β должно быть целым, оно определяет величину смещения адресов β1, β2 и β3 загрузки и запуска (по умолчанию β=0), в оперативную память загружается файл, записанный на ленте во внутреннем представлении под именем, равным значению выражения α.При наличии парамет- ра R прочитанная программа автоматически запускается на счет. П р и м е р ы. 1) BLOAD "CAS:DD" ───────────── 2) BLOAD "CAS:LEN", &H1500 3) BLOAD "CAS:TEST", R 4) BLOAD "CAS:",R 5) 5 'Инициализация компьютера. 10 CALL NETEND 'Для компьютеров серии MSX-2 20 BSAVE"CAS:initio",0,3 30 BLOAD"CAS:initio",R,&HA000 В последнем примере подпрограмма ROM, расположенная между адресами &h0 и &h3, загружается в RAM по адресу &HA000 и запускается на выполнение. Команда BLOAD позволяет загрузить данные, сохраненные командой BSAVE. Должно быть указано имя устройства, если это не дисковод А, и имя файла. Может присутствовать параметр R, если данные относятся к программе на ма- шинном языке. В этом случае программа запустится после загрузки.Данные за- гружаются на то место, которое они занимали перед сохранением,если не ука- зан адрес смещения. В этом случае данное число добавляется к начальному, конечному и адресу смещения, заданным в команде BSAVE. На компьютерах MSX-2 возможна и другая форма записи оператора BLOAD: ┌─────────────────────────────────────────────┐ │ BLOAD"CAS: и м я ф а й л а",S │ └─────────────────────────────────────────────┘ Содержимое файла будет скопировано в видеопамять. Обратите внимание, что BLOAD может использоваться в программе, не вызы- вая выполнения команды NEW или возврата в командный режим. Этот оператор может использоваться также для загрузки частей программы на MSX-BASIC. П р и м е р 1. Приведем программу, которая позволяет указать начальный ───────────── и конечный адреса загрузки двоичного файла. 1 INPUT"Имя файла";A$ 10 OPEN A$ FOR INPUT AS#1 20 FOR I=1 TO 7 30 I$(I)=INPUT$(1,#1) 40 PRINT ASC(I$(I)),HEX$(ASC(I$(I))) 50 NEXT 60 CLOSE 65 IF I$(1)<>"Ч" THEN PRINT"Это не BLO-файл! ":END 66 PRINT"Вы хотите вывести адреса на принтер (д/н)?" 67 Y$=INKEY$:IF Y$="" THEN 67 68 IF Y$="д" OR Y$="Д" THEN LPRINT A$ 69 A1=256*ASC(I$(3))+ASC(I$(2)) 70 PRINT "Начальный адрес:";HEX$(A1);" или";A1 71 IF Y$="д"OR Y$="Д" THEN LPRINT"Начальный адрес:";HEX$(A1);" или";A1 79 A2=256*ASC(I$(5))+ASC(I$(4)) 80 PRINT "Конечный адрес:";HEX$(A2);" или";A2 81 IF Y$="д" OR Y$="Д" THEN LPRINT"Конечный адрес:";HEX$(A2);" или";A2 89 A3=256*ASC(I$(7))+ASC(I$(6)) 90 PRINT "Адрес запуска:";HEX$(A3);" или";A3 91 IF Y$="д" OR Y$="Д" THEN LPRINT"Адрес запуска:";HEX$(A3);" или";A3 З а м е ч а н и е. Команды BSAVE и BLOAD можно применять и для работы с произвольными дисковыми файлами (устройства A: и B:). П р и м е р 2. Запись компьютерных игр с дискеты на магнитную ленту. ───────────── 1) Загрузите программу с дискеты в оперативную память командой BLOAD "имя файла" 2) Включите Ваш магнитофон на запись, затем выполните команду BSAVE "CAS:имя файла",α,β,γ где: α - ш е с т н а д ц а т е р и ч н ы й начальный адрес; β - ш е с т н а д ц а т е р и ч н ы й конечный адрес; γ - ш е с т н а д ц а т е р и ч н ы й адрес загрузки. Значения α,β,γ Вы можете найти с помощью программы из примера 1. П р и м е р 3. Загрузка компьютерных игр с магнитной ленты в оператив- ───────────── ную память. 1. Включите магнитофон 2. Выполните команду BLOAD "CAS: И м я ф а й л а",R 3. На экране появится надпись: Found: И м я ф а й л а (без расширения) 4. ...И "игрушка" запустится! IX.5.2. Р а б о т а с ф а й л а м и д а н н ы х Команда OPEN для устройства CAS: имеет следующий вид: ┌─────────────────────────────────┐ │ OPEN β FOR {INPUT } AS #n │ │ {OUTPUT} │ , └─────────────────────────────────┘ Здесь β должно начинаться с символов "CAS:" и, кроме того, отсутствует возможность, предоставляемая параметром APPEND для "наращивания" файлов. Все остальное полностью аналогично работе с дисковыми файлами (устройства A:, B: и MEM:). П р и м е р. Строки 10÷30 создают файл данных на магнитной ленте. Для ─────────── его считывания в память требуется запустить этот фрагмент со строки 50. 10 OPEN"CAS:хи-хи" FOR OUTPUT AS #1 20 FOR K=1 TO 500:PRINT #1,K;:NEXT 30 CLOSE #1 40 STOP 50 CLEAR 1000 60 OPEN"CAS:хи-хи" FOR INPUT AS #1 70 LINE INPUT #1,M$:PRINT M$; 80 IF NOT EOF(1) THEN 70 90 END 9.6. Д о п о л н е н и е. Три очень п о л е з н ы х программы 1. Программа, осуществляющая посекторное копирование диска на кассету. 6 CLS:PRINT:PRINT"<<Посекторное копирование диска на кассету>>":PRINT: PRINT 11 DEFINT A-Z:GOSUB 51:I=&H9000:DEFUSR=I:J=&HA000:DEFUSR1=J:PRINT"Скол ько минут протягивается одна сторона кассеты ??":INPUT CT:PRINT:PRINT" С какого по какой сектор копировать S1, S2 (0-1500)??":INPUT S1,S2 16 READ D$:IF D$<>"#" THEN POKE I,VAL("&h"+D$):I=I+1:GOTO 16 21 DATA 2A,51,F3,11,00,00,01,00,02,CD,5C,00,C9,# 22 READ D$:IF D$<>"#" THEN POKE J,VAL("&h"+D$):J=J+1:GOTO 22 23 DATA 2A,51,F3,11,00,B0,01,00,02,ED,B0,C9,# 31 FOR S=S1 TO S2:D$=DSKI$(1,S):CLS:U=USR(0):LOCATE 0,17:PRINT "Сектор N";S:I=USR1(0):BSAVE"CAS:С"+STR$(S),&HB000,&HB1FF:GOSUB46:IF T>CT-5 TH EN GOSUB 56 36 NEXT:END 46 GET TIME T$:KEY 2,T$:C1$=LEFT$(T$,2):C1=VAL(C1$)-C:M1$=MID$(T$,4,2) :M1=VAL(M1$)-M:T=C1*60+M1:RETURN 51 GET TIME T$:KEY1,T$:C$=LEFT$(T$,2):C=VAL(C$):M$=MID$(T$,4,2):M=VAL( M$):RETURN 56 CLS:LOCATE 10,10:PRINT "Проверь ленту":LOCATE 10,12:PRINT"Кончилась ??? (D/N)":SET BEEP 4,4 61 BEEP:O$=INKEY$:IF O$="" THEN 61 ELSE ON INSTR("@@@DdдДNnнН",O$)\4 G OTO 66,76:GOTO 61 66 PRINT "Вставил новую ? (D)":SET BEEP 3,4 71 BEEP:O$=INKEY$:IF O$="" THEN 71 ELSE IF INSTR("DdдД",O$)THEN GOSUB 51:RETURN ELSE 71 76 RETURN 2. Программа,осуществляющая посекторное восстановление диска с кассеты. 6 CLS:PRINT:PRINT"<<Посекторное восстановление диска с кассеты>>":PRIN T:PRINT 11 DEFINT A-Z:GOSUB 51:I=&H9000:DEFUSR=I:J=&HA000:DEFUSR1=J:PRINT"Скол ько минут протягивается одна сторона кассеты ??":INPUT CT:PRINT:PRINT" С какого по какой сектор копировать S1, S2 (0-1500) ??":INPUT S1,S2 16 READ D$:IF D$<>"#" THEN POKE I,VAL("&h"+D$):I=I+1:GOTO 16 21 DATA 21,00,B0,11,00,00,01,00,02,CD,5C,00,C9,# 22 READ D$:IF D$<>"#" THEN POKE J,VAL("&h"+D$):J=J+1:GOTO 22 23 DATA 01,00,02,2A,51,F3,54,5D,21,00,B0,ED,B0,C9,# 31 FOR S=S1 TO S2:BLOAD"CAS:С"+STR$(S):CLS:U=USR(0):LOCATE 0,17:PRINT "Сектор N";S:I=USR1(0):DSKO$ 1,S:GOSUB 46:IF T>CT-5 THEN GOSUB 56 36 NEXT:END 46 GET TIME T$:KEY 2,T$:C1$=LEFT$(T$,2):C1=VAL(C1$)-C:M1$=MID$(T$,4,2) :M1=VAL(M1$)-M:T=C1*60+M1:RETURN 51 GET TIME T$:KEY 1,T$:C$=LEFT$(T$,2):C=VAL(C$):M$=MID$(T$,4,2):M=VAL (M$):RETURN 56 CLS:LOCATE 10,10:PRINT "Проверь ленту":LOCATE 10,12:PRINT "Кончилас ь ??? (D/N)":SET BEEP 4,4 61 BEEP:O$=INKEY$:IF O$="" THEN 61 ELSE ON INSTR("@@@DdдДNnнН",O$)\4 G OTO 66,76:GOTO 61 66 PRINT "Вставил новую ?(D)":SET BEEP 3,4 71 BEEP:O$=INKEY$:IF O$="" THEN 71 ELSE IF INSTR("DdдД",O$)THEN GOSUB 51:RETURN ELSE 71 76 RETURN 3. Программа, позволяющая определить тип файла на кассете. В н и м а н и е! При наборе программы с т р о г о соблюдайте пробелы между символами и нумерацию строк. 1 WIDTH40:PRINT"<<< FORMAT FILES ON CASSETTE >>>":PRINT:KEYOFF: PRINT"<<< BY LEO BOYARSKY (c) 1988 >>>":POKE&H80CA,143'  2 CLEAR1000:MAXFILES=1:ONSTOPGOSUB15:STOPON:ONERRORGOTO14:RESTORE 4:A=VARPTR(#1):NEW' 3 DEFFNA$(I)=RIGHT$("000"+HEX$(PEEK(I)+256*PEEK(I+1)),4) 4 FORI=0TO8:READX:POKEA+I,X:NEXT:DATA1,0,0,0,255,0,0,0,0'  5 DATA&HDB,&HC3,&H32,&H58,&HD3,&HC3,&H74,&H42 6 PRINT:X$=INPUT$(255,1) 7 W$="":FORI=A+9 TOA+18:W=PEEK(I):W$=W$+CHR$(W):NEXT 8 N$="":FORI=A+19TOA+24:N=PEEK(I):N$=N$+CHR$(N):NEXT 9 IFW$="сссссссссс"THENW$="BASIC (cload)":GOSUB11ELSEIFW$="ЙЙЙЙЙ ЙЙЙЙЙ"THENW$="BASIC ( load)":GOSUB11ELSEIFW$="пппппппппп"THENW$= "OBJEKT (bload)":GOSUB11:I=A+25:GOSUB12 10 PRINT:PRINT"<<< Checking next file >>>":RUN2 11 S$=" The "+N$+" is "+W$+" file.":PRINTS$:RETURN 12 SA$=FNA$(I):IFNOT(("8"<=SA$)AND(SA$<="F380"))THEN13ELSEEA$=FNA $(I+2):IFNOT(("8"<=EA$)AND(EA$<="F380"))THEN13ELSERA$=FNA$(I+4):I FNOT(("8"<=RA$)AND(RA$<="F380"))THEN13ELSES$=S$+CHR$(13)+"Start: &h"+SA$+"; End: &h"+EA$+"; Run: &h"+RA$:PRINTS$:RETURN 13 I=I+1:IFI>A+255THENPRINT:PRINT"Don't check address !":RETURNEL SE12 14 RESUMENEXT 15 KEYON:POKE&H80CA,58' 16 END