Процессор ЭВМ ЕС-1030. Блок управляющих регистров и блок прямого управления

в 11:43, , рубрики: ЕС ЭВМ, ЕС-1030

Блок управляющих регистров

Блок управляющих регистров (БУР) хранит слово состояния программы (PSW; в советской литературе обычно использовалась аббревиатура ССП), признаки причин программных прерываний, запросы прерываний других видов (кроме прерываний от схем контроля) и код выполняемой операции.

Регистр слова состояния программы

Регистр слова состояния программы РССП имеет размер 64 бита и хранит содержимое PSW в точности в том формате, который определён принципами работы Системы 360:

  • биты 0:6 — индивидуальные маски прерываний от каналов ввода-вывода с номерами 0–5, а также общая маска для всех каналов, начиная с имеющего номер 6: единица разрешает прерывание, нуль запрещает. Поскольку в ЕС-1030 имеется только четыре канала (мультиплексный с номером 0 и три селекторных с номерами 1–3), биты 4:6 не используются и лишь хранят занесённое в них значение;

  • бит 7 — маска внешних прерываний;

  • биты 8:11 — ключ доступа процессора к основной памяти;

  • бит 12 — кодировка, используемая для представления распакованных десятичных чисел: нуль задаёт использование ДКОИ (EBCDIC, расширенный кириллическими буквами), единица — КОИ-8;

  • бит 13 — маска прерываний от схем контроля;

  • бит 14 — когда установлен, процессор находится в состоянии «Ожидание» и не выполняет команды, но реагирует на разрешённые запросы прерываний; когда сброшен, процессор находится в состоянии «Счёт» и выполняет команды обычным образом;

  • бит 15 — нулевое значение задаёт состояние «Супервизор», единичное — «Задача»;

  • биты 16:31 — код прерывания;

  • биты 32:33 — код длины команды (ILC или КДК). По сути, это счётчик, сбрасываемый в нуль в момент начала выборки очередной команды и увеличиваемый на единицу при выборке каждого полуслова кода команды;

  • биты 34:35 — код условия, изменяемый при выполнении некоторых команд и отражающий их результат;

  • биты 36:39 — маски четырёх видов программных прерываний: по целочисленному переполнению (или, как тогда говорилось, по переполнению в операции с фиксированной запятой), по десятичному переполнению, по исчезновению порядка и по потере значимости в операциях с плавающей запятой;

  • биты 40:63 — адрес следующей выполняемой команды.

Приём информации в РССП[0/7], согласно [2], осуществляется из любого байта регистра Р5, входящего в состав арифметико-логического блока, для чего предусмотрены четыре микрооперации с самоочевидными мнемониками: РССП[0/7]:=Р5[0/7], РССП[0/7]:=Р5[8/15], РССП[0/7]:=Р5[16/23] и РССП[0/7]:=Р5[24/31] .

Информация в РССП[8/15] принимается из Р5[8/15] — надо полагать, микрооперацией РССП[8/15]:=Р5[8/15], хотя явным образом она в доступных источниках не упоминается.

Код прерывания в РССП[16/31] заносится в соответствии с приведённой схемой.

Схема занесения кода прерывания в РССП

Схема занесения кода прерывания в РССП

Как видно из схемы, РССП[16/31] имеет сигнал обнуления, однако неизвестно, используется ли он для упрощения схемотехники (сбросить содержимое регистра, а потом установить лишь определённые биты, что можно реализовать на простейших RS-триггерах, а не на более сложных защёлках или D-триггерах) или же применяется лишь при сбросе процессора.

Источниками информации для формирования кода прерывания могут служить:

  • Р5[16/31] — при программных прерываниях и прерываниях по вызову супервизора; в первом из этих случаев в Р5 заносится константа из микрокоманды, показывающая причину возникновения данного программного прерывания, а во втором сюда пересылается второй байт кода команды SVC;

  • из 3-го регистра внешних линий РВЛ3 (см. далее описание блока прямого управления) и из триггеров аварийного счёта времени ТАСВ и прерывания пульта управления ТППУ, что формирует код внешнего прерывания. Заметим здесь, что ничего аварийного в ТАСВ нет: он устанавливается, когда должно возникнуть прерывание от интервального таймера; вероятно, «аварийным» этот триггер стал из-за непонимания смысла английского термина alarm. ТППУ устанавливается при нажатии на пульте управления кнопки «Прерывание», что может тем или иным способом использоваться операционной системой (например, ОС ЕС при получении этого терминала пытается переключиться с одного консольного терминала на другой — это требуется, например, если текущая консоль вышла из строя);

  • из регистра адреса канала 1 РАК1 и коммутатора адреса подканала КМАП, формирующих код прерывания ввода-вывода (старший байт содержит номер канала, от которого поступило прерывание, и в данном случае его старшие шесть разрядов всегда будут нулевыми, поскольку машина имеет только четыре канала; младший байт содержит адрес устройства).

Как уже говорилось, код длины команды в РССП[32/33] в самом начале выборки команды обнуляется, для чего предусмотрена микрооперация РССП[32/33]:=0. При выборке из памяти очередного полуслова кода команды этот счётчик увеличивается на единицу, а адрес команды — на два, что выполняется единой микрооперацией РССП[32/33]:=+1, РССП[40/63]:=+2.

Код условия в РССП[34/35] изменяется при выполнении ряда команд процессора и характеризует полученный результат (равенство нулю, переполнение и т. п.). Технически его изменение осуществляется приёмом константы из разрядов регистра информации долговременного запоминающего устройства (т. е. из регистра микрокоманды) РИДЗУ[54/55] микрооперацией РССП[34/35]:=КОНСТ; соответственно, сам анализ результата выполнения команды выполняется чисто микропрограммными средствами и приводит к переходу на ту или иную микрокоманду для установки нужного кода условия

Кроме установки кода условия указанной микрооперацией, в процессе выполнения команд ввода-вывода он принимается прямо от общего канала, т. е. от общей части всех каналов, обеспечивающей их сопряжение с процессором и памятью (код условия в этих командах отражает состояние канала, подканала и устройства ввода-вывода, поэтому и формируется каналом), однако как именно это производится, информации нет.

Адрес команды в РССП[40/63] имеет самоочевидное назначение. Технически это 24-разрядный счётчик, увеличивающий своё значение на 2, что осуществляется уже упоминавшейся выше комбинированной микрооперацией РССП[32/33]:=+1, РССП[40/63]:=+2. Кроме своего прямого назначения, он используется для адресации памяти при записи состояния при сбоях машины и в процессе диагностики неисправностей, о чём будет сказано в соответствующих разделах.

Технически, как и другие счётчики, РССП[40/63] состоит из двух регистров-защёлок: собственно РССП[40/63], хранящего текущее значение, и его дублёра РССП"[40/63]. Согласно [1], при загрузке полностью нового значения адреса команды сначала выполняется сброс всего счётчика сигналом РССП[40/63]:=0, а затем приём в него новой информации из Р5[8/31], из регистра информации оперативной памяти РИОП[8/31] либо фиксированного десятичного значения 144. Первый из перечисленных случаев относится к выполнению команды LPSW (ЗАГРУЗКА PSW) и к обработке прерываний, для его реализации необходимы микрооперации РССП[40/63]:=0 и РССП[40/63]:=Р5[8/31], хотя явных упоминаний их существования в доступных источниках нет; возможно также, что существует лишь вторая из этих микроопераций, по которой в первом полутакте микрокоманды вырабатывается сигнал сброса, а во втором — сигнал приёма информации в регистр. Два других случая относятся к обработке сбоев процессора и его диагностике; по-видимому, соответствующие сигналы формируются чисто аппаратными средствами.

При инкременте адреса в РССП на 2 сначала производится пересылка в РССП"[40/63] текущего значения РССП[40/63], а затем приём в РССП[40/63] увеличенного на два значения РССП"[40/63], т. е. между РССП" и РССП находится схема прибавления двойки.

В [2] сообщается, что собственно РССП выполнен на ТЭЗах четырёх типов: ЕС-Т000/0002, ЕС-Т000/0003, ЕС-2030/0013 и ЕС-2030/0045, для реализации РССП[40/63] используются также ТЭЗы типа ЕС-Т000/0018. Общее количество ТЭЗов неизвестно.

Судя по не очень внятному описанию, на одном ТЭЗе типа ЕС-Т000/0003 собраны четыре разряда РССП[40/63], включая регистр-дублёр и цепи инкремента, причём сам ТЭЗ является достаточно универсальным, поддерживая, как минимум, инкремент и на 1, и на 2, иначе младший и остальные полубайты адреса команды пришлось бы реализовывать на разных типах ТЭЗов. Если принять во внимание «универсальный» (не привязанный к конкретной модели процессора) шифр этого ТЭЗа, можно предположить, что на нём собран четырёхразрядный счётчик, значение приращения которого задаётся внешними сигналами. Сами триггеры выполнены на микросхемах К155ЛА4. Функции ТЭЗов типа ЕС-Т000/0018 при работе РССП[40/63] никак не указаны. Конечно, всё это можно было бы узнать из функциональных и принципиальных схем, но они, в отличие от [2], отсутствуют.

Регистр ошибок центрального процессора РОЦ

Согласно [2], регистр ошибок центрального процессора РОЦ физически имеет 18 разрядов. Разряды 1:15, как говорят и [1], и [2], хранят не индикаторы аппаратных ошибок, как можно было бы решить из его названия, а признаки причин программных прерываний — в Системе 360 их как раз пятнадцать, и номера битов соответствуют кодам программных прерываний с теми же номерами. Остальные три бита регистра, согласно [2], не используются, что указывает на его реализацию на универсальных ТЭЗах — по 9 триггеров на одном ТЭЗе.

[1] и [2] упоминают несколько микроопераций, устанавливающих или проверяющих разряды РОЦ. Кроме того, в [2] приведён фрагмент содержимого памяти микропрограмм, в котором, среди прочего, имеются и несколько связанных с РОЦ микроопераций, две из которых прямо противоречат описанию этого регистра. Вот полный список обнаруженных в двух источниках микроопераций, относящихся к РОЦ:

  • РОЦ[1/3,7/21]:=0 — первая из «странных» микроопераций. Как легко догадаться, она обнуляет указанные разряды регистра, но «официально», как уже говорилось, в нём всего 18 разрядов;

  • РОЦ[4/6]:=0 — обнуление разрядов 4:6. Для чего понадобились две микрооперации обнуления, будет сказано ниже;

  • РОЦ[1/3,7/15]:=КОНСТ — приём в указанные разряды регистра признака особого случая, приводящего к программному прерыванию; этот признак задаётся полем константы из микрокоманды;

  • РОЦ[4/6]:=РОП — приём в указанные разряды РОЦ признаков особых случаев, возникших при обращении к основной памяти (регистр РОП относится к блоку обращения к оперативной памяти);

  • РОЦ[6]:=0, РОЦ[6]:=1 и РОЦ[6]:=1 (при усл.) — три микрооперации, явным образом управляющие указанным разрядом РОЦ;

  • РОЦ[1/10]=0 и РОЦ[4/6]≠0 — микрооперации анализа содержимого РОЦ, используемые для организации переходов в микропрограммах;

  • РОЦ[16,19,21]≠0 — «неправильная» микрооперация анализа, проверяющая значение разрядов, которых быть, вроде бы, не должно.

Как легко заметить, обе «странные» микрооперации работают с разрядами регистра РОЦ, которых существовать, согласно описанию, не может. Можно предположить, что в [2] допущены опечатки — тем более, что они там действительно встречаются, — однако смущает, что таких микроопераций две, причём во втором случае опечатка должна быть уж очень обширная.

Любые особые случаи, вызывающие появление программных прерываний, возникают в процессе выборки и выполнения команд. Перед началом выборки очередной команды все биты РОЦ сбрасываются; при возникновении того или иного случая соответствующий бит РОЦ устанавливается, выполнение команды прекращается и управление передаётся микропрограмме обработки программного прерывания. Разница в управлении битами 4:5, 6 и всеми остальными объясняется способами обнаружения особых случаев.

Биты 4 и 5 указывают соответственно на особый случай защиты и особый случай адресации. Оба они могут возникать только при обращении к памяти, обнаруживаются аппаратными средствами и фиксируются в регистре РОП. Бит 6 указывает на особый случай спецификации; он может возникать при обращении к памяти и в ряде других случаев. Микрооперация РОЦ[4/6]:=РОП заносит в РОЦ признаки этих трёх особых случаев, возникших при доступе к ОП, в дальнейшем с помощью микрооперации РОЦ[4/6]≠0 микропрограмма проверяет их наличие и либо продолжает нормальное выполнение, либо переходит на микропрограмму программного прерывания.

Микрооперации РОЦ[6]:=0, РОЦ[6]:=1 и РОЦ[6]:=1 (при усл.) позволяют микропрограммно управлять разрядом, указывающим на особый случай спецификации. Последняя встречается только в упомянутом выше фрагменте содержимого микропрограммной памяти и устанавливает бит 6 при соблюдении некоего условия — какого именно, неясно. Две другие микрооперации упоминаются в тексте.

Наличие микрооперации РОЦ[1/10]=0 в таком виде вызывает сомнения: если уж анализировать, то все 15 разрядов РОЦ, чтобы понять, возник какой-то особый случай или нет; для чего анализировать только десять разрядов, непонятно. Впрочем, неясно и то, зачем понадобились отдельные микрооперации сброса тех или иных разрядов РОЦ: по идее, достаточно сбросить сразу весь регистр перед началом выборки команды, ведь любой особый случай прекращает её выполнение.

Остальные биты РОЦ устанавливаются микрооперацией РОЦ[1/3,7/15]:=КОНСТ. В отличие от других микроопераций, заносящих в регистр само значение константы, в данном случае константа дешифруется специальной схемой и устанавливает лишь один разряд РОЦ, соответствующий коду прерывания (1–3, 7–15), заданного полем константы.

Регистры фиксации прерываний РФП и РФПД

Регистр фиксации прерываний РФП имеет четыре разряда и накапливает запросы прерываний: программных (бит 1), по вызову супервизора (бит 2), внешних (бит 3) и ввода-вывода (бит 4).

Биты 1 и 2 и устанавливаются, и сбрасываются микропрограммно. Установка запроса программного прерывания происходит в точке обнаружения соответствующего особого случая или в конце выполнения команды, если к этому моменту содержимое регистра РОЦ отличается от нуля — это зависит от ряда обстоятельств, включая конкретный вид особого случая и состояние масок программных прерываний. В частности, существует микрооперация РФП[1]:=1 (РОЦ≠0), устанавливающая бит 1 только в случае, если любой из разрядов РОЦ[1/3,7/15] отличен от нуля.

Установка бита 2 выполняется только в процессе выполнения команды SVC, для чего используется микрооперация РФП[2]:=1.

Бит РФП[3] устанавливается аппаратно по синхросигналу С1 при наличии единицы в любом разряде регистра внешних линий 3 РВЛ3 (см. описание блока прямого управления), в том числе если установлен триггер прерывания пульта управления ТППУ или триггер аварийного счёта времени ТАСВ, — т. е. при наличии хотя бы одного из запросов внешних прерываний.

Бит РФП[4] устанавливается аппаратно по сигналу от общего канала.

Сброс всех этих битов происходит в микропрограммах обработки соответствующих видов прерываний микрооперациями вида РФП[n]:=0. Кроме того, похоже, имеется отдельный сигнал сброса всего регистра при сбросе процессора с пульта управления.

В конце микропрограммы выполнения каждой команды микрооперацией РФПД:=РФП содержимое регистра РФП передаётся в дополнительный регистр РФПД. На его выходе собрана схема присвоения приоритета и формирования адреса микропрограммы обработки прерывания.

Полной ясности в том, как учитываются маски каналов и внешних прерываний, нет. С одной стороны, сброшенный бит маски может блокировать установку соответствующего разряда РФП. С другой стороны, биты масок могут анализироваться схемой присвоения приоритета и формирования адреса микропрограммы, игнорирующей запросы, если они замаскированы.

Регистр выполняемой операции РВО

Регистр выполняемой операции РВО хранит байт кода текущей выполняемой команды. Он заносится сюда микрооперацией РВО:=Р5[0/7], а впоследствии микрооперацией РАДЗУ:=РВО передаётся в младшие восемь разрядов регистра адреса долговременного запоминающего устройства РАДЗУ. Старшие четыре бита РАДЗУ при такой передаче обнуляются (неясно, по микрооперации РВО:=Р5[0/7] или каким-либо иным образом), и в результате формируется шестнадцатеричный адрес в диапазоне 000–0FF, определяющий точку входа в микропрограмму реализации той или иной команды процессора.

Технически сам РВО выполнен на одном ТЭЗе типа ЕС-Т000/0002, расположенном по адресу 1A07. Для передачи его содержимого в РАДЗУ служат ещё пять ТЭЗов по адресам 2A20, 1A08, 1D15, 2A08, 2A05, имеющих типы ЕС-2030/0069, ЕС-2030/0068, ЕС-2030/0066, ЕС-2030/0061 (и, возможно, ещё один тип: [2] говорит о пяти типах, но приводит шифры лишь четырёх из них).

В [2] упоминаются следующие анализы разрядов РВО, которые используются для ветвлений в микропрограммах: РВО[0/3]≠1111, РВО=44, РВО[5/6]≠0. Назначение анализа РВО=44 понятно: обнаружение команды EX (ВЫПОЛНЕНИЕ), имеющей шестнадцатеричный код 44. Это одна из наиболее необычных команд Системы 360. Она вычисляет адрес своего операнда и использует его как адрес подчинённой команды, производит выборку этой команды, модифицирует её второй байт и затем выполняет полученную команду; основное её назначение — дать возможность определять в командах типа «память-память» количество обрабатываемых байтов во время выполнения программы, а не в процессе её трансляции, без необходимости модифицировать сами команды в памяти машины.

Смысл двух других микроопераций анализа понятен из их обозначений, но конкретное применение неизвестно. Например, РВО[0/3]≠1111 позволяет выделить команды с кодами F0–FF, к которым относится большинство операций десятичной арифметики, но практическая польза от этого неясна, поскольку для таких операций используются и некоторые другие коды

Перечисленные анализы выполняются на ТЭЗе типа ЕС-2030/0046, расположенном по адресу 1A05.

Регистр общей блокировки РОБ

Регистр общей блокировки РОБ состоит из двух битов, причём бит 0 находится в процессоре, а бит 1 — в общем канале. Установка бита 0 микрооперацией РОБ[0]:=1 извещает канал, что процессор перешёл к обслуживанию прерывания ввода-вывода. Установив РОБ[0], процессор зацикливается, ожидая его сброса. Канал, обнаружив установку этого бита, выполняет свою часть обработки прерывания, после чего выдаёт сигнал сброса РОБ[0]. Обнаружив сброс, микропрограмма процессора продолжает обработку прерывания ввода-вывода.

Бит 1 извещает процессор, что канал отменил ранее выданный запрос прерывания ввода-вывода.

Блок прямого управления

Блок прямого управления (БПРУ) обеспечивает обмен информацией и управляющими сигналами между двумя ЭВМ или ЭВМ и каким-либо нестандартным оборудованием, используя так называемый интерфейс прямого управления. Он является необязательным расширением архитектуры Системы 360; в Системе 370 его объявили устаревшим, а позже полностью изъяли из архитектуры. Несмотря на свои недостатки, на ранних этапах развития архитектуры он сыграл важную роль в создании многопроцессорных и многомашинных систем, обеспечивая межпроцессорное взаимодействие.

Все советские ЕС ЭВМ располагали интерфейсом прямого управления в обязательном порядке: у нас, в отличие от IBM, почти все необязательные элементы архитектуры де-факто были обязательными.

Технически интерфейс включает:

  • восемь входных и восемь выходных информационных линий ШИН-1…ШИН-8;

  • восемь линий синхронизации ЛС;

  • шесть линий внешних сигналов ВС;

  • четыре линии управления ВЫХ-ЛЧТ, ВЫХ-ЛЗП, ВХ-ЛЧТ, ВХ-ЛЗП.

Блок-схема, показывающая сопряжение двух процессоров с помощью интерфейса прямого управления, приведена на рисунке.

Сопряжение двух процессоров или ЭВМ с помощью интерфейса прямого управления

Сопряжение двух процессоров или ЭВМ с помощью интерфейса прямого управления

С точки зрения программиста, интерфейс прямого управления даёт возможность отправить или получить байт данных, сопровождаемый сигналами синхронизации, для чего предусмотрены привилегированные команды ПРЯМОЕ ЧТЕНИЕ (RDD) и ПРЯМАЯ ЗАПИСЬ (WRD). Поступление сигналов синхронизации вызывает появление запроса внешнего прерывания.

Для управления интерфейсом в состав блока прямого управления входят регистры внешних линий РВЛ0–РВЛ3 и регистр внешних сигнальных линий РВСЛ. Кроме того, в процессоре ЭВМ ЕС-1030 к БПРУ отнесены триггер аварийного счёта времени ТАСВ и триггер прерывания пульта управления ТППУ, хотя логически они относятся к другим техническим средствам — интервальному таймеру и кнопке прерывания соответственно. Причина здесь в том, что и таймер, и кнопка, и линии внешних сигналов интерфейса прямого управления являются источниками внешних прерываний процессора.

Регистр РВЛ0 предназначен для выдачи на линии данных интерфейса одного байта информации по микрооперации РВЛ0:=Р5[0/7] в процессе выполнения команды WRD.

Регистр РВЛ1 принимает информацию, поступившую по линиям данных от другой ЭВМ. Он считывается микрооперацией Р7:=РВЛ1 в процессе выполнения команды RDD.

Регистр РВЛ2 служит для выдачи синхросигналов по соответствующим линиям интерфейса прямого управления. Информация в него заносится микрооперацией РВЛ2:=Р8 в процессе выполнения команд RDD и WRD: с помощью синхросигналов они уведомляют другой процессор о приёме или передаче байта информации.

В разрядах 2–7 регистра РВЛ3 по тактовому сигналу С1 фиксируется установленное состояние шести внешних линий синхронизации (2–7); двумя старшими битами этого регистра являются триггеры ТАСВ и ТППУ. При поступлении какого-либо внешнего сигнала, при нажатии кнопки прерывания или при срабатывании таймера соответствующий триггер РВЛ3 устанавливается и остаётся установленным до тех пор, пока этот регистр не будет очищен. Установленное состояние хотя бы одного из разрядов РВЛ3 является признаком запроса внешнего прерывания, а полное содержимое этого регистра — кодом этого прерывания, записываемым в составе старого PSW в процессе прерывания. Обнуление регистра происходит либо при сбросе процессора, либо в процессе внешнего прерывания.

Содержимое всех восьми разрядов РВЛ3 принимается в РССП[24/31], при этом в РССП[16/23] заносятся нули; эти действия задаются микрооперацией РССП[16/31]:= РВЛ3,ТППУ, обозначение которой известно из [2]. Сам РВЛ3, включая ТАСВ и ТППУ, должен сбрасываться в момент передачи информации в РССП, поскольку все запросы внешних прерываний, имевшие место на момент записи кода прерывания, должны быть в нём указаны, а все позднее поступившие запросы должны быть запомнены для последующей обработки. Как это достигается, имеющаяся литература не упоминает.

Заметим, что внешние линии синхронизации 0 и 1, выдаваемые через регистр РВЛ2 наравне с линиями 2–7, вторым процессором не принимаются и не могут использоваться для межпроцессорного взаимодействия, поскольку механизм внешних прерываний поддерживает лишь шесть внешних линий; они могут использоваться лишь специальным внешним устройством, подключаемым через интерфейс прямого управления.

Регистр РВСЛ состоит из двух триггеров, формирующих управляющие сигналы ВЫХ-ЛЗП и ВЫХ-ЛЧТ.

Сигнал ВЫХ-ЛЗП выдаётся в процессе выполнения команды WRD, чтобы на время переходных процессов на линиях информации и синхронизации предотвратить выполнение команды RDD второй ЭВМ: если RDD выполняется одновременно с WRD, она, обнаружив сигнал ВЫХ-ЛЗП (который для неё превращается в ВХ-ЛЗП), зацикливается, ожидая снятия этого сигнала, что будет свидетельствовать о стабилизации уровней линий интерфейса. Как следствие, команда RDD может «подвесить» абсолютно исправный процессор, если из строя вышел другой процессор или сам интерфейс прямого управления, и это стало одной из причин постепенного отказа от интерфейса прямого управления в Системе 370.

Регистры РВЛ0, РВЛ1 и РВЛ2 выполнены на трёх стандартных ТЭЗах типа ЕС-Т000/0002. Шесть разрядов регистра РВЛ3, отвечающих за хранение внешних сигналов, выполнены на ТЭЗе типа ЕС-2030/0068, а триггеры ТАСВ и ТППУ находятся на ТЭЗах типов ЕС-2030/0048 и ЕС-2030/0022.

Автор: SIISII

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js