Аппаратный VGA Text Mode IO в старом DOS сборке Выпуск - PullRequest
3 голосов
/ 29 июля 2011

Прочитав, по крайней мере, первые 3 или 4 главы о 4 разных книгах по программированию на ассемблере, я подошел к этапу, когда я могу поместить «Hello World» в консоль dosbox, используя MASM 6.11.Вообразите мое восхищение !!

Первая версия моей программы использовала функцию DOS 13h.Вторая версия моей программы использовала функцию BIOS 10h

Теперь я хочу сделать третью версию с использованием прямого аппаратного вывода.Я прочитал части книг, в которых объясняется, что экран на VGA-мониторах разделен на 80x25 (не беспокоит обнаружение CGA и все такое, поэтому моя программа использует адрес памяти 0B800h для цветного VGA, потому что DOSBox отличный и все, и мое желаниеперейти на Win Assembler раньше, чем мне исполнилось 90 лет).Я прочитал, что каждый символ на аппаратном экране составляет 2 байта (1 для атрибута и один для самого символа, поэтому у вас есть 80x25x2 = 4000 байтов).Нечетные байты описывают атрибут, а четные байты символ ASCII.

Но моя проблема заключается в следующем.Независимо от того, как я стараюсь, я не могу заставить свою программу выводить простую черно-белую (что является просто атрибутом, я предполагаю, что я могу достаточно легко изменить) строку (которая является просто массивом байтов) в 5 строках сверхуэкран и 20 символов от левого края (это просто количество пустых символов от нулевого индекса с длиной 4000 байтов).(если мой расчет верен, то есть 5x80 = 400 + 20 = 420x2 = 840 - это начальная позиция моей строки в массиве 4000 байтов)

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

Я пытался поискать в Интернете этот, казалось бы, простой вопрос, но не смог найти решение.Есть ли кто-нибудь, кто программировал в DOS и x86 Assembly, кто может сказать мне, как сделать эту простую маленькую программу, не используя функции BIOS или DOS, только с помощью аппаратного обеспечения.

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

Я пытаюсь создать библиотеку подпрограмм, которая будетупростить изучение ассемблера, чтобы людям не приходилось работать, хотя все от 3 до 6 глав в 10 книгах по теории снова и снова объясняют одно и то же, когда на самом деле все, что нужно, достаточно, чтобы знать, как получить какой-то результат, назначить значения дляпеременные, получить некоторый вклад, и сделать несколько циклов и решений.Теория может появиться позже, и к тому времени, когда они придут к циклам и решениям, большинство людей сделают достаточно ассемблера, чтобы в любом случае иметь всю теорию.Я верю, что ассемблеру нужно учить ничем не отличающемуся от любого другого языка, начиная с простой программы hello world и заканчивая вводной информацией.Я хочу сделать это возможным.Но, эй, я только новичок, может быть, мои уловки изменятся, когда я узнаю больше.

Еще одно замечание, я точно знаю, что проблема не в DOSBox, так как у меня очень старый ПК, работающий верноMS-DOS V6.2 и программа по-прежнему не работают (но выдают практически идентичный вывод).На самом деле, DOSBox запускает некоторые из моих старых программ даже лучше, чем True DOS.Gem Desktop является одним из примеров.Просто хотел, чтобы это очистили, прежде чем люди попробуют предположить, что это проблема с эмулятором.Не может быть, не с такими простыми программами.Не боюсь, проблема в том, что мой маленький мозг не совсем понимает, что нужно.

Может кто-нибудь там помочь, пожалуйста !!


Ниже приведена программа, которую я использовал (MASM 6.1 в DOSBox на Win 7 64-bit).Он использует BIOS Intrrupt 10h Функция 13h Подфункция 0. Я хочу сделать то же самое, используя прямой аппаратный ввод-вывод.


.model small
.stack
.data           ;part of the program containing data
    ;Constants - None
    ;Variables
    MyMsg   db    'Hello World'

.code
Main:
GetAddress:
    mov ax,@data        ;Gets address of data segment
    mov es,ax           ;Loads segment address into es regrister
    mov bp,OFFSET MyMsg ;Load Offset into DX

SetAttributes:
    mov bl,01001111b    ;BG/FG Colour attributes
    mov cx,11           ;Length of string in data segment

SetRowAndCol:
    mov dh,24       ;Set the row to start printing at
    mov dl,68       ;Set the column to start printing at

GetFunctionAndSub:
    mov ah,13h      ;BIOS Function 10h - String Output
    mov al,0        ;BIOS Sub-Function (0-3)

Execute:
    int 10h         ;BIOS Interrupt 10h

EndProg:
    mov ax,4c00h    ;Terminate program return 0 to OS
    int 21h         ;DOS Interrupt 21h

end Main
end

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


.model small
.stack
.data
    ;Constants
    ScreenSeg   equ     0B800h

    ;Variables
    MyMsg   db  'Hello World'
    StrLen  equ $-MyMsg

.code
Main:               

SetSeg:
    mov ax, ScreenSeg   ;set segment register:
    mov ds, ax

InitializeStringLoop:   ;Display all characters: - Not working :( Y!
    mov cx, StrLen      ;number of characters.
    mov di, 00h         ;start from byte 'h'

OutputString:
    mov [di], offset byte ptr MyMsg[di]
    add di, 2           ;skip over next attribute code in vga memory.
    loop OutputString

InitializeAttributeLoop:;Color all characters: - Atributes are working fine.
    mov cx, StrLen      ;number of characters.
    mov di, 01h         ;start from byte after 'h'

;Assuming I have all chars with same attributes - fine for now - later I would make this
;into a procedure that I will just pass the details into. - But for now I just want a
;basic output tutorial.

OutputAttributes:
    mov [di], 11101100b     ;light red(1100) on yellow(1110)
    add di, 2               ;skip over next ascii code in vga memory.
    loop OutputAttributes

EndPrg:
    mov ax, 4C00h
    int 21h
end Main

Конечно, я хочу сократить инструкции, используемые до базовых предметов.(для правильных целей обучения, меньше, чтобы покрыть, обучая других).Я понял причину, по которой я не использовал MOVSB ​​/ W / D и т. Д. С REP.Вместо этого я выбрал простой для объяснения ручной цикл, используя стандартные MOV, INC, ADD и т. Д.Это достаточно простые инструкции, которые легко объяснить новичкам.Поэтому, если возможно, я бы хотел, чтобы это было как можно ближе к этому.

Я знаю, по сути, все, что кажется неправильным - это цикл для фактического обработчика строк.Это не позволяет мне увеличивать адрес так, как я хочу.Это меня смущает, потому что я на самом деле неплохой программист, использующий C ++, C #, VB и Delphi (еще когда)).Я знаю, что вы не подумали бы, что, учитывая, что я не могу даже получить правильную петлю в ассемблере, но это такой другой язык.В языках высокого уровня есть 2 или 3 цикла, и, кажется, существует бесконечная комбинация способов создания циклов в ассемблере в зависимости от инструкций.Поэтому я говорю «Простая петля», но на самом деле в этом мало простого.

Я надеюсь, что кто-то может помочь мне с этим, вы спасете мою сборочную карьеру и обеспечите, чтобы я в конечном итоге стал хорошим учителем сборки.,Спасибо заранее, и особенно за чтение этого далеко.

Ответы [ 3 ]

2 голосов
/ 05 февраля 2012

Я бы предложил получить пакет Masm32 , если у вас его еще нет.Он в основном ориентирован на простое использование языка ассемблера в «Windows сегодня», что очень приятно, но также многому научит вас в Asm, а также покажет, где можно найти руководства по чипам Intel, упомянутые в предыдущем ответе, которые необходимы.

Я начал программировать в 80-х годах, и теперь я понимаю, почему вы так интересуетесь этим, я знаю, что скучаю по нему.Если бы больше людей начали там, это им очень окупилось бы.Вы делаете отличный сервис!

Я играю именно с тем, о чем вы говорите, с Direct Hardware, и я также узнал, что Windows изменила некоторые службы DOS и службы BIOS, так что некоторые больше не работают,На самом деле я пишу небольшую программу .com и запускаю ее из Win7 в окне командной строки. Печатает сообщение и ждет ключа. Довольно круто, учитывая, что это Win7 в 2012 году!

Фактически это был BIOS 10h- 0Eh это не сработало, и поэтому я попытался Dos 21h 02h, чтобы записать на экран, и это сработало.Код ниже, потому что это .com (командная программа), я подумал, что он может быть вам полезен.

;Это делает программу .com (64k Limit, Code, Data и все; должна помещаться в этом пространстве. Используется для небольших утилит и; хороша для очень быстрых задач. На самом деле DOS-команды в основном; небольшие программы .com, подобные этой (кромеболее полезно)!;; Собрать с помощью Masm с помощью; c: \ masm32 \ bin \ ml / AT / c bfc.asm; Установить связь с Masm Link16 с помощью; c: \ masm32 \ bin \ link16 bfc.obj, bfc.com;;; Link16 - это ключ к созданию 16-битного .com (командного) файла

SEGMT SEGMENT
org 100h

Start:
        push    CS
        pop     DS

        MOV SI, OFFSET Message
Next:
        MOV ah, 02h             ; Write Char to Standard out
        MOV dl, [si]            ; Char
        INT 21h                 ; Write it
        INC si                  ; Next Char
        CMP byte ptr[si], 0     ; Done?
        JNE Next                ; Nope

WaitKey:
        XOR ah, ah              ; 0
        INT 16h                 ; Wait for any Key
ExitHere:        
        MOV ah, 4Ch             ; Exit with Return Code
        xor al, al              ; Return Code
        INT 21h

Message db  "It Works in Windows 7!", 0

SEGMT ENDS
END Start
2 голосов
/ 29 июля 2011

Типичным условием будет использование ds:si в качестве источника и es:di в качестве пункта назначения.

Таким образом, в конечном итоге оно будет похоже на (не проверено):

  mov ax, @data
  mov ds, ax
  mov ax, ScreenSeg
  mov es, ax
  ...
  mov si, offset MyMsg
OutputString:
  mov al, byte ptr ds:[si]
  mov byte ptr es:[di], al
  add si, 1           ; next character from string
  add di, 2           ; skip over next attribute code in vga memory.
  loop OutputString
0 голосов
/ 29 июля 2011

Раньше я делал все, о чем ты говоришь.Пытаясь вспомнить детали.Майкл Абраш - это имя, за которым вы должны поискать.Mode-X, например, режим 200 на 240 (240x200?) 256 цветов был очень популярен, поскольку он нарушал границу 16 цветов, и в то время игры выглядели действительно хорошо.

Я думаю, что на металлепрограммирование регистров было выполнимым, но болезненным, и вам, вероятно, нужно получить справочную информацию / таблицу данных для интересующего вас чипа. Со временем от CGA до EGA, от VGA до VESA изменились и способы работы.Я думаю, что обычно вы используете int что-то для получения доступа к фрейму страницы, тогда вы можете заполнить его напрямуюVESA Я думаю, что сработало так, VESA был большим спасением, когда дело дошло до поддержки видеокарт, раньше вам приходилось писать собственные драйверы для каждого чипа (если вы не хотели уродливых стандартных режимов).

Я бы посмотрел на mode-x или vesa и пошел бы оттуда.В любом случае, вам нужно немного хакера, чтобы разобраться с этим, очень редко можно найти справочное руководство для специалиста / программиста, которое является полным и точным, вам всегда нужно просто протолкнуть несколько байтов, чтобы увидеть, что происходит.Начните заполнять те блоки памяти, которые должны быть кадрами страницы, пока вы не увидите, что что-то меняется на экране ...

Я не вижу каких-либо конкретных книг по графическому программированию в моей библиотеке, кроме книг по абразивам, таких как графическое программированиеЧерная книга, которая была в конце этого периода времени.У меня есть ссылки на BIOS и DOS программисты, а также список Ральфа Брауна.Я уверен, что у меня были копии руководств по популярным видеочипам (до того, как в интернете вспомнили, что вы звонили человеку по телефону, из него висел шнур, человек взял печатное руководство, иногда просто переплетенное, иногда просто скрепку).в углу, если так, положите его в конверт и отправьте по почте вам, и это была ваша единственная копия, если вы не пропустили ее через копир).У меня есть стопки печатных материалов, которые, к сожалению, не собираюсь пройти, чтобы ответить на этот вопрос.Хотя я буду держать этот вопрос в уме и еще раз поищу информацию, на самом деле у меня могут быть под рукой некоторые из моих старых программ, рисующие фракталы и другие подобные вещи (прямые на видеокарту / память).

РЕДАКТИРОВАТЬ.

Я знаю, что вы ищете текстовый режим, и это графический режим, но он может или не может пролить свет на то, что вы пытаетесь сделать.комбинация вызовов int и непосредственного заполнения страниц и памяти палитры.

http://dwelch.s3.amazonaws.com/fly.tar.gz

...