Jump to content

draw a pixel

- - - - -

  • Please log in to reply
8 replies to this topic

#1
untitled_1

untitled_1

    Learning Programmer

  • Members
  • PipPipPip
  • 89 posts
Hey all, does anyone know which interrrupt and function I can use to draw a single pixel on screen.
I am using Linux. I tried to google it but it only came up with results related to DOS( yawn )

thanks

#2
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Do you mean in regular desktop mode, or in the terminal? You'll need to use the OpenGL libraries or something along those lines if you're in the actual system.
sudo rm -rf /

#3
untitled_1

untitled_1

    Learning Programmer

  • Members
  • PipPipPip
  • 89 posts
I want to do it through the terminal, must I use OpenGL functions and dynamic linking? I would prefer not to, I just want to write my own graphic function. Just to experiment

#4
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
You don't have to use dynamic linking. But yes, if you're going to be in a userland program you're going to have to use a graphics library, sorry. Either that or you can create your own little OS. It's fun, I might add.
sudo rm -rf /

#5
untitled_1

untitled_1

    Learning Programmer

  • Members
  • PipPipPip
  • 89 posts
But I remember with dos there was a way to do it using int 10h, passing X-coordinate in bx and passing y-coordinate in cx ( if I remember correctly ). This would draw a single pixel. Int 10h also had a function changed command prompt to graphics mode and back again. There should be a way with Linux, I hope...else I will have to dust off the old xp cd

#6
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Yes, that's DOS. I can give you a more detailed explanation as to why if you like, but in the most basic of nutshells: operating systems have advanced a ,lot since DOS and exert tighter control over what you can and can't do from user programs. You can use Bochs inside of Linux to simulate a real-mode system and run your graphics program there, if you like.

XP won't allow you to do pixel drawing like that either unless you're writing a COM program, which is a 16-bit real mode program limited to 64K, including code, stack, and memory. In that case a small terminal will open and you can do (almost) whatever DOS stuff you like in there. Either way, you won't be able to full-screen anything.
sudo rm -rf /

#7
untitled_1

untitled_1

    Learning Programmer

  • Members
  • PipPipPip
  • 89 posts
I see I understand now. When I used dos it was a .com program , thank you. I will try my hand at writing a very simple OS, I will see if I can pull it off lol

#8
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Here's my generic bootloader, so you can write your program and not have to worry about the details. Note that the FAT descriptor is for a 1.44MB floppy only.

org 0x7c00


%define STAGE2_SECTORS  8   ; Must be >= 1 for FAT12/16, >= 32 for FAT32


boot_sector:
    jmp   short loader
    nop
    db    "dargueta"        ; OEM name
    dw    512               ; Bytes per sector
    db    8                 ; Sectors per cluster: 8K clusters
    dw    STAGE2_SECTORS    ; Reserved sectors (for stage 2)
    db    2                 ; Number of FAT copies
    dw    224               ; Maximum number of root dir entries
    dw    2880              ; Number of sectors (small)
    db    0xf0              ; Floppy descriptor
    dw    4                 ; Sectors per FAT
    dw    18                ; Sectors per track
    dw    2                 ; Number of heads
    dd    0                 ; Number of hidden sectors
    dd    0                 ; Number of sectors  (large)
    db    0                 ; Physical drive number of partition
    db    0                 ; Reserved
    db    0x29              ; Extended signature
    dd    0DEADBABEh        ; Serial number of partition
    db    "VOLUME NAME"     ; Volume name of partition
    db    "FAT16   "        ; FAT name


; Begin executable code
loader:
    mov   [disk_num], dl    ; BIOS gives us the drive # in DL. Save it.


    mov   ax, cs
    mov   ds, ax
    mov   ss, ax
    mov   sp, 0x7b00        ; start stack below code


    mov   ax, 0xb800        ; ES points to base of video memory
    mov   es, ax
    xor   di, di            ; DI points to first character/attribute pair


    ; Three tries to read:
    mov   cx, 3


    .try_load:
        push  cx


        ; Reset disk system for reading
        mov   ah, 0
        mov   dl, [disk_num]
        int   0x13
        jc    failed


        push  es
    
        ; Attempt to load the sectors into memory.
        les   bx, [load_address]          ; ES:[BX] points to the loading address
        mov   ax, 0x02                     
        mov   al, STAGE2_SECTORS          ; Read in the second stage
        mov   cx, 00000000_00_000010b     ; Disk cylinder | High cylinders | Sector
        mov   dh, 0                       ; Head = 0
        mov   dl, [disk_num]              ; DL = drive number
        int   0x13


        pop   es
        jnc   .load_ok


        cmp   ah, 0x04
        je    .error_read


        cmp   ah, 0x20
        je    .error_controller


        jmp   .unknown_error


        .error_read:
            mov   si, str_readerror
            call  print
            jmp   .try_again


        .error_controller:
            mov   si, str_ctrlerror
            call  print
            jmp   .try_again


        .unknown_error:
            mov   si, str_failed
            call  print


        .try_again:
            pop   cx
            loop  .try_load


        jmp   failed


    .load_ok:
        mov   si, str_ok
        call  print


        jmp   [load_address]


failed:
    mov   si, str_failed
    call  print
    cli
    hlt


print:
    cld
    mov   ah, 0x70


    .write_loop:
        lodsb


        cmp   al, 0
        je    .done


        cmp   al, 0x0d
        je    .cr


        cmp   al, 0x0a
        je    .lf


    .write_char:
        stosw
        jmp   .write_loop


    .cr:
        mov   BYTE [cursor_x], 0
        call  update_pointer
        jmp   .write_loop


    .lf:
        cmp   BYTE [cursor_y], 24
        je    .write_loop
        inc   BYTE [cursor_y]
        call  update_pointer
        jmp   .write_loop


    .done:
        ret


update_pointer:
    push  ax
    push  cx


    mov   al, 160
    mul   BYTE [cursor_y]
    mov   ch, 0
    mov   cl, [cursor_x]
    shl   cx, 1
    add   ax, cx
    mov   di, ax


    pop   cx
    pop   ax
    ret


str_failed:     db "FAILED", 0x0d, 0x0a, 0
str_readerror:  db "Read error.", 0x0d, 0x0a, 0
str_ctrlerror:  db "Controller error.", 0x0d, 0x0a, 0
str_ok:         db "OK", 0x0d, 0x0a, 0
cursor_x:       db 0
cursor_y:       db 0
disk_num:       db 0


load_address:
    load_offs:  dw LOAD_OFFSET
    load_seg:   dw LOAD_SEGMENT


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Fill up boot sector
times  510-($-$$)   db  0x90


; Executable signature
db  0x55, 0xAA

All you need to do is put your program in the sectors following this and change STAGE2_SECTORS to suit the size of your program. LOAD_SEGMENT and LOAD_OFFSET must also be defined. I typically use 0000:8000H.
sudo rm -rf /

#9
untitled_1

untitled_1

    Learning Programmer

  • Members
  • PipPipPip
  • 89 posts
Ok, thanks. I will give it try, I will ask if I get stuck...




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users