程序集8086中的图形模式

时间:2018-02-06 17:20:20

标签: assembly graphics emu8086 vga

我有一个名为import request from 'request' // obtain by npm install --save request class App extends Component { constructor() { super(); this.state = { items: [] }; } componentDidMount() { request(`http://example.com/api`, (error, response, body) => { this.setState({ items: JSON.parse(body) }; }); } render() { var listItems = this.state.items.map(item => <HelloComponent name= {item.login} />); // worked!!! return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to React</h1> </header> <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. {listItems} </p> </div> ); } } 的变量,在我的average中,它每次都会更改,因为用户每次都输入不同的输入。我想要做的是进入图形模式(VGA),然后在那里打印您的平​​均值是:然后平均我知道如何更改为这样的图形模式:

DATASEG

如果平均值高于75 打印平均值后我想在下面打印你是一个好学生,保持良好的工作,如果没有。不要担心你会好起来的! 提前谢谢。

1 个答案:

答案 0 :(得分:3)

我假设: PC VGA x86 MS DOS 平台

除非你想要低级别 IO 访问,这可能无法正常进行仿真,如 DOSBOX ......

  1. 视频/文字模式

    因此,要在视频和文本模式之间切换,您需要使用VGA BIOS:

    mov ax,mode ; here select which mode you want
    int 16      ; this calls EGA/VGA/VESA BIOS
    

    这里有两个非常重要的video modes

    mode | type  | segment | resolution         | align
    ----------------------------------------------------
    03   | text  | B800h   | 80x25 chars        | 2 Byte
    19   | video | A000h   | 320x200x256 colors | 1 Byte
    

    在视频模式19中,您可以通过访问段A000h处的内存来打印/查看像素,其中偏移量计算如下:

    offset = 320*y + x
    

    320x200模式完全适合64 KByte段,因此您无需切换页面。这使它成为简单的asm gfx程序的理想选择......

    模式3是文本模式,其中每个字符都有2 BYTEs一个是颜色,另一个是扩展的 ASCII 代码。再次打印/查看是通过访问段WORD处的B800h来完成的,其中offset为:

    offset = (80*y + x) * 2
    

    不确定这两个字节的顺序是多久以前的,但您可以轻松测试A处的0B800:0000是否会在左上角呈现A或{{1相反。文本模式下的IIRC颜色只是调色板中的前16种颜色,颜色字节编码墨水纸的亮度和闪光。此文本模式也是 MS-DOS shell正在使用的默认模式,因此您应该在程序退出之前将其设置回来。

    所以你的程序应该是这样的:

    0B800:0001
  2. 打印字符串

    对于初学者,您可以组合文字和视频模式......就像我在这里:

    这是一个简单的游戏,其中菜单处于文本模式(打印很简单,只需将字符串复制到 VRAM ),精灵图形游戏处于start: mov ax,19 ; set video mode int 16 mainloop: ; here your stuff exit: mov ax,3 int 16 ret 视频模式

    如果要以gfx模式打印,首先需要在内存中包含一些字体。如果您查看 EGA / VGA BIOS 文档,您可以获得 EGA / VGA ROM中的字体并直接使用它。我还创建了这个图像(IIRC使用Trident 9000 256 / 512KB VGA字体),我用它作为 OpenGL 的单间距字体和其他东西(访问 VGA BIOS 是不可能或不想要......)

    font

    此处GLSL example of using it for printing您可以将其移植到 CPU / VGA / asm,但 CPU 上的打印要简单得多需要像 GLSL 片段这样可怕的事情。

    因此,您只需要从 ASCII 代码计算图像位置,并将其像素复制到 VRAM 。粗糙的asm中的位图并不容易,更容易直接以二进制形式(如320x200x256c的集合),所以你可以编写一些简单的 C ++ (或其他)脚本加载图像并将其转换为asm源...

    以下是我在 NASM 之前写过的一些古老的db打印文章(直接使用 EGA / VGA 字体):

    320x200x256 colors

    所以要使用它,程序应该是:

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;GFX mode 13h print librrary ver:1.0
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;txti       init font adress
    ;char       cx=color,al=ASCII,scr:di<=al ;cl=ch => no background
    ;print      scr:di <= ds:si ,cx=color cl=ch => no background
    ;printl     scr:di text after call ,cx=color ...
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    txti:   pusha           ;init font adress
        push es
        mov ax,1130h    ; VGA BIOS - font info
        mov bh,3        ; font 8 x 8 pixels
        int 10h         ; ES:BP returns font address
        mov [cs:fonts],es   ;get font adr
        mov [cs:fonto],bp
        pop es
        popa
        ret
    fonts   dw 0        ; font address for printing ...
    fonto   dw 0
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    char:   pusha       ;cx=color,al=ASCII,scr:di<=al ;cl=ch => no background
        push    ds
        push    es
        push    word 0A000h
        pop es
        sub     ah,ah
        shl     ax,3
        mov     ds,[cs:fonts]
        mov     si,[cs:fonto]
        add     si,ax
        mov     dh,8
    .char0: mov     dl,8
        lodsb
        mov     ah,al
    .char1: mov     al,cl
        rcl     ah,1
        jc  .char2
        mov     al,ch
    .char2: cmp     cl,ch
        jz  .char3
        mov     [es:di],al
    .char3: inc     di
        dec     dl
        jnz     .char1
        add     di,320-8
        dec     dh
        jnz     .char0
        pop es
        pop     ds
        popa
        ret
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    print:  pusha       ;scr:di <= ds:si ,cx=color cl=ch => no background
    .l0:    lodsb
        or  al,al
        jz  .esc
        call    char
        add     di,8
        jmp     short .l0
    .esc:   popa
        ret
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    printl: mov [cs:.dat],si    ;scr:di text after call ,cx=color ...
        pop si
        push    ax
        push    di
        push    ds
        push    cs
        pop ds
    .l0:    lodsb
        or  al,al
        jz  .esc
        call    char
        add     di,8
        jmp     short .l0
    .esc:   pop ds
        pop di
        pop ax
        push    si
        add di,9*320
        mov si,[cs:.dat]
        ret
    .dat:   dw  0
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;; end. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    

    设置start: call txti ; just once at program startup mov di,50+320*10 mov cx,127 call printl db 'SPEKTRA software & hardware',0 mov di,50+320*30 mov cx,127 call printl db 'print test',0 使用print,因此它指向空终止字符串。正如您所看到的,ds,si不需要它,因为它在printl调用之后直接使用字符串,并且程序在它之后继续...这样您就不需要指针设置指令也不需要任何额外的实验。颜色在printl中,一个是墨水,另一个是纸张。如果cl,ch那么,如果在文本后面有图像或gfx背景,那么只有墨水像素才会被渲染...颜色的值可能不可见我从我的一个游戏中获取颜色设置自己的调色板,以便在看不到任何内容时尝试设置不同的cl==ch,如cl,ch看看这个:

  3. 打印数字

    打印非负整数值是将数字除以基数(10)并以相反的顺序打印mov cx,0305h作为字符...

    remainder + '0'中,它更容易,因为每个数字对应于半字节hex,因此对于16位,您可以通过<0-15>表或添加{{xlat将最高4位转换为char。 1}}或'0'取决于值是否低于'A' ...所以没有除法只是位移/掩码...打印字符并将值向左移位4位以处理下一位数字。

    在gfx模式下,btw通常更好,用户友好,而不是打印一个值作为数字渲染进度条,而不是更容易的东西......折叠到单循环渲染H或V线.. 。像10 :) ...