flat assembler
Message board for the users of flat assembler.

Index > Linux > Porting 16-bit .com assembly to 64-bit Linux counterpart

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 08 Jul 2017, 07:28
I would like to port my .com game written 12 years ago to 64-bit Linux, which, I believe, is a good exercise to brush up my rusty assembly programming skills.

I quickly encountered a problem -- the code related to the 80x25 TEXT video mode could not be directly converted. After some digging, I found the following links:

Fastest and very "assembly" way to draw in Linux
https://board.flatassembler.net/topic.php?t=17752

very simple example creating a window/displaying graphics
https://board.flatassembler.net/topic.php?t=13567

Frankly, doing graphics on X Window or Linux seems to be quite troublesome.

So, my question is: What is the simplest/easiest way to do 80x25 TEXT on X Window or Linux? I don't need any fancy graphics.

Thanks in advance!

Wink

Preemptive strike:

@Furs: No need to suggest using a sandbox or emulator. 64-bit Linux is my workhorse OS; I would like to run my program natively.

@revolution: Nope. Your fake website does not contain any useful information. Do NOT confuse clickbaits with jokes.
Post 08 Jul 2017, 07:28
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 08 Jul 2017, 22:04
I'm not sure whether my library's TUI goods are "simple" exactly, but I coded up a short and sweet "demo" of drawing/moving an X with cursor keys across a background in text mode/terminal window
Code:
include '../../ht_defaults.inc'
include '../../ht.inc'

globals
{
        x       dd      0
        y       dd      0
}

falign
our_draw:
        prolog  our_draw
        push    rdi
        call    tui_background$nvfill
        pop     rdi
        cmp     dword [rdi+tui_width_ofs], 0
        je      .nothingtodo
        cmp     dword [rdi+tui_height_ofs], 0
        je      .nothingtodo
        mov     eax, [rdi+tui_width_ofs]
        mov     r8, [rdi+tui_text_ofs]
        mov     r9, [rdi+tui_attr_ofs]
        mov     ecx, [y]
        mul     ecx
        add     eax, [x]
        shl     eax, 2
        ansi_colors r10d, 'red', 'blue'
        mov     dword [r8+rax], 'X'
        mov     dword [r9+rax], r10d
.nothingtodo:
        mov     rsi, [rdi]              ; load the vtable
        call    qword [rsi+tui_vupdatedisplaylist]
        epilog


        ; three arguments: rdi == our tui_background, esi == key, edx == esc_key
        ; NOTE: return zero in eax if firekeyevent should keep walking up "bubbling"
        ; and return nonzero in eax if firekeyevent should STOP
falign
our_keyevent:
        prolog  our_keyevent
        ; check for cursor keys
        mov     r8d, [rdi+tui_width_ofs]
        mov     r9d, [rdi+tui_height_ofs]
        cmp     edx, 0x41                       ; up arrow
        je      .uparrow
        cmp     edx, 0x42                       ; down arrow
        je      .downarrow
        cmp     edx, 0x43                       ; right arrow
        je      .rightarrow
        cmp     edx, 0x46                       ; end, well, shift-end
        je      .shiftend
        cmp     edx, 0x44                       ; left arrow
        je      .leftarrow
.bailout:
        xor     eax, eax
        epilog
.uparrow:
        cmp     [y], 0
        je      .bailout
        sub     [y], 1
        jmp     .redraw
.downarrow:
        cmp     [y], r9d
        jae     .bailout
        add     [y], 1
        jmp     .redraw
.rightarrow:
        cmp     [x], r8d
        jae     .bailout
        add     [x], 1
        jmp     .redraw
.shiftend:
        mov     [x], r8d
        sub     [x], 1
        jmp     .redraw
.leftarrow:
        cmp     [x], 0
        je      .bailout
        sub     [x], 1
.redraw:
        call    our_draw
        mov     eax, 1
        epilog

; a modified copy of tui_background$vtable so we can catch input and customise
; the draw method:
dalign
our_vtable:
        dq      tui_object$cleanup, tui_background$clone, our_draw, tui_object$redraw, tui_object$updatedisplaylist, tui_object$sizechanged
        dq      tui_object$timer, tui_object$layoutchanged, tui_object$move, tui_object$setfocus, tui_object$gotfocus, tui_object$lostfocus
        dq      our_keyevent, tui_object$domodal, tui_object$endmodal, tui_object$exit, tui_object$calcbounds, tui_object$calcchildbounds
        dq      tui_object$appendchild, tui_object$appendbastard, tui_object$prependchild, tui_object$contains, tui_object$getchildindex
        dq      tui_object$removechild, tui_object$removebastard, tui_object$removeallchildren, tui_object$removeallbastards
        dq      tui_object$getobjectsunderpoint, tui_object$flatten, tui_object$firekeyevent, tui_object$ontab, tui_object$onshifttab
        dq      tui_object$setcursor, tui_object$showcursor, tui_object$hidecursor, tui_object$click, tui_object$clicked


public _start
calign
_start:
        ; initialise HeavyThing...
        call    ht$init
        ; allocate enough room for our tui_background
        mov     edi, tui_background_size
        call    heap$alloc
        mov     rbx, rax                        ; save it
        mov     rdx, our_vtable                 ; use our custom vtable
        mov     [rax], rdx                      ; save vtable
        mov     rdi, rax                        ; setup for call to init_dd
        movq    xmm0, [_math_onehundred]        ; 100% width
        movq    xmm1, [_math_onehundred]        ; 100% height
        mov     esi, '.'                        ; fillchar
        ansi_colors edx, 'lightgray', 'blue'    ; colours
        call    tui_background$init_dd

        mov     rdi, rbx
        call    tui_terminal$new
        call    epoll$run               ; doesn't come back

include '../../ht_data.inc'
    
Check out the other TUI examples I did for the library as well: https://2ton.com.au/library_as_html/examples/tuieffects/tuieffects.asm.html

Edit: Suppose I should explain that the library exposes what amounts to two flat 32bit buffers, one for characters and the other for attributes. So the above example just uses the global variables in [x] and [y] to determine where to put the X, and places the red foreground and blue background attributes at the same location/offset into the buffers. When the draw method calls updatedisplaylist, that triggers the library's "differential" ansi output sequences (such that it is not actually drawing the entire "screen" each and every keypress, only the parts of the screen that changed since its last update). Resizing the terminal window works as you'd expect, etc. etc.

While I could have fixed the tui_background size to 80x25, having it auto-fill a terminal window is better IMO Smile The other two library pieces I wrote, sshtalk and hnwatch both make heavy use of the tui_* components for further examples.

Let me know if you'd like me to explain further Smile

_________________
2 Ton Digital - https://2ton.com.au/
Post 08 Jul 2017, 22:04
View user's profile Send private message Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 09 Jul 2017, 03:06
redsock wrote:
Let me know if you'd like me to explain further Smile
There are three "include" lines in the presented code. Where are the ".inc" files? Rolling Eyes

Ah ... I see. I need to download the HeavyThing library and then place the needed ".inc" files in the appropriate directory.

Okay. I will give it a try.

Thanks!

Wink
Post 09 Jul 2017, 03:06
View user's profile Send private message Visit poster's website Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 09 Jul 2017, 03:29
Just tried and had a compilation error:

flat assembler version 1.71.63 (16384 kilobytes memory, x64)
error: out of memory.

The error might be caused by some bug in the 64-bit fasm compiler, but I am not sure.

Note that the compiler did compile the 64-bit "Hello World" example without any problem.

Sad
Post 09 Jul 2017, 03:29
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 09 Jul 2017, 04:01
YONG wrote:
error: out of memory.
try:
Code:
fasm -m 262144 yoursource.asm && ld -o yoursource yoursource.o    

_________________
2 Ton Digital - https://2ton.com.au/
Post 09 Jul 2017, 04:01
View user's profile Send private message Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 09 Jul 2017, 04:31
redsock wrote:
try:
Code:
fasm -m 262144 yoursource.asm && ld -o yoursource yoursource.o    
Yes, it worked! Thanks! Smile

It seems that the 64-bit fasm compiler has some memory management issue. Anyway.

The generated terminal has 80 columns but more than 25 rows (I don't know how many). Besides, navigating the "X" with the arrow keys seems to have some issues. But overall, the generated terminal is what I need.

Now, I would have to study the code in detail and see if I can make sense of it.

Wink
Post 09 Jul 2017, 04:31
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 09 Jul 2017, 04:56
YONG wrote:
Besides, navigating the "X" with the arrow keys seems to have some issues.
Smile I didn't spend any time validating the bounds checking/etc, but figured it would serve demonstration purposes well Smile let me know how you go.

_________________
2 Ton Digital - https://2ton.com.au/
Post 09 Jul 2017, 04:56
View user's profile Send private message Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 09 Jul 2017, 13:01
redsock wrote:
let me know how you go.
Do you maintain a full list of "reserved" names for the HeavyThing library? For example, I suspect that calign, dalign, and falign are some built-in routines for properly aligning code, data, and functions. But that is just my guess.

How about ansi_colors?

If there is a fully-documented hierarchy of functions/routines (which also shows the dependencies of the .inc files), it will be great!

Well, I know that I am asking for too much.

Wink
Post 09 Jul 2017, 13:01
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8353
Location: Kraków, Poland
Tomasz Grysztar 09 Jul 2017, 13:39
YONG wrote:
It seems that the 64-bit fasm compiler has some memory management issue. Anyway.
fasm for Linux/Unix always allocates exactly 16 MB of memory by default, for it to use more memory you have to specify the right amount with the switch. This is a general quirk of fasm's memory management, not related to 64 bits.
Post 09 Jul 2017, 13:39
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 09 Jul 2017, 21:47
YONG wrote:
Do you maintain a full list of "reserved" names for the HeavyThing library? For example, I suspect that calign, dalign, and falign are some built-in routines for properly aligning code, data, and functions. But that is just my guess.

How about ansi_colors?

If there is a fully-documented hierarchy of functions/routines (which also shows the dependencies of the .inc files), it will be great!
Smile The only "master function list" is maintained via javascript on the upper-right corner of my site's search feature (it is scraped when the static pages for the site are constructed).

Outside that, the ht_defaults.inc file is the "settings" for the library, and by copying and/or modifying the settings, you can affect how various things are compiled/generated including those alignment macros (which are in align_macros.inc). Since I maintain those alignment standards throughout the library, it is enlightening (IMO) to know whether 16-byte aligned jump targets on a given architecture throughout the entirety of a codebase affect performance, similarly with data, only-function-targets, etc. Smile

_________________
2 Ton Digital - https://2ton.com.au/
Post 09 Jul 2017, 21:47
View user's profile Send private message Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 09 Jul 2017, 21:57
Morning coffee today resulted in a quick modification of the demo (noting I still didn't mess with bounds checking haha), this one randomly moves the X every 100ms Smile
Code:
include '../../ht_defaults.inc'
include '../../ht.inc'

globals
{
        x       dd      0
        y       dd      0
        bg      dq      0
}

falign
our_draw:
        prolog  our_draw
        push    rdi
        call    tui_background$nvfill
        pop     rdi
        cmp     dword [rdi+tui_width_ofs], 0
        je      .nothingtodo
        cmp     dword [rdi+tui_height_ofs], 0
        je      .nothingtodo
        mov     eax, [rdi+tui_width_ofs]
        mov     r8, [rdi+tui_text_ofs]
        mov     r9, [rdi+tui_attr_ofs]
        mov     ecx, [y]
        mul     ecx
        add     eax, [x]
        shl     eax, 2
        ansi_colors r10d, 'red', 'blue'
        mov     dword [r8+rax], 'X'
        mov     dword [r9+rax], r10d
.nothingtodo:
        mov     rsi, [rdi]              ; load the vtable
        call    qword [rsi+tui_vupdatedisplaylist]
        epilog


        ; three arguments: rdi == our tui_background, esi == key, edx == esc_key
        ; NOTE: return zero in eax if firekeyevent should keep walking up "bubbling"
        ; and return nonzero in eax if firekeyevent should STOP
falign
our_keyevent:
        prolog  our_keyevent
        ; check for cursor keys
        mov     r8d, [rdi+tui_width_ofs]
        mov     r9d, [rdi+tui_height_ofs]
        cmp     edx, 0x41                       ; up arrow
        je      .uparrow
        cmp     edx, 0x42                       ; down arrow
        je      .downarrow
        cmp     edx, 0x43                       ; right arrow
        je      .rightarrow
        cmp     edx, 0x46                       ; end, well, shift-end
        je      .shiftend
        cmp     edx, 0x44                       ; left arrow
        je      .leftarrow
.bailout:
        xor     eax, eax
        epilog
.uparrow:
        cmp     [y], 0
        je      .bailout
        sub     [y], 1
        jmp     .redraw
.downarrow:
        cmp     [y], r9d
        jae     .bailout
        add     [y], 1
        jmp     .redraw
.rightarrow:
        cmp     [x], r8d
        jae     .bailout
        add     [x], 1
        jmp     .redraw
.shiftend:
        mov     [x], r8d
        sub     [x], 1
        jmp     .redraw
.leftarrow:
        cmp     [x], 0
        je      .bailout
        sub     [x], 1
.redraw:
        call    our_draw
        mov     eax, 1
        epilog

; a modified copy of tui_background$vtable so we can catch input and customise
; the draw method:
dalign
our_vtable:
        dq      tui_object$cleanup, tui_background$clone, our_draw, tui_object$redraw, tui_object$updatedisplaylist, tui_object$sizechanged
        dq      tui_object$timer, tui_object$layoutchanged, tui_object$move, tui_object$setfocus, tui_object$gotfocus, tui_object$lostfocus
        dq      our_keyevent, tui_object$domodal, tui_object$endmodal, tui_object$exit, tui_object$calcbounds, tui_object$calcchildbounds
        dq      tui_object$appendchild, tui_object$appendbastard, tui_object$prependchild, tui_object$contains, tui_object$getchildindex
        dq      tui_object$removechild, tui_object$removebastard, tui_object$removeallchildren, tui_object$removeallbastards
        dq      tui_object$getobjectsunderpoint, tui_object$flatten, tui_object$firekeyevent, tui_object$ontab, tui_object$onshifttab
        dq      tui_object$setcursor, tui_object$showcursor, tui_object$hidecursor, tui_object$click, tui_object$clicked


falign
our_timer:
        prolog  our_timer
        xor     edi, edi
        mov     esi, 3
        call    rng$int
        mov     rdi, [bg]
        xor     esi, esi
        mov     edx, [.keys+rax*4]
        call    our_keyevent
        ; keep the timer going:
        xor     eax, eax
        epilog
dalign
.keys:
        dd      0x41, 0x42, 0x43, 0x44

; a modified copy of epoll$default_vtable so we can catch timer events
dalign
timer_vtable:
        dq      epoll$destroy, epoll$clone, io$connected, epoll$send, epoll$receive, io$error, our_timer


public _start
calign
_start:
        ; initialise HeavyThing...
        call    ht$init
        ; allocate enough room for our tui_background
        mov     edi, tui_background_size
        call    heap$alloc
        mov     rbx, rax                        ; save it
        mov     [bg], rax                       ; and in a global
        mov     rdx, our_vtable                 ; use our custom vtable
        mov     [rax], rdx                      ; save vtable
        mov     rdi, rax                        ; setup for call to init_dd
        movq    xmm0, [_math_onehundred]        ; 100% width
        movq    xmm1, [_math_onehundred]        ; 100% height
        mov     esi, '.'                        ; fillchar
        ansi_colors edx, 'lightgray', 'blue'    ; colours
        call    tui_background$init_dd

        ; create a "dummy" epoll object for our timer
        mov     rdi, timer_vtable
        xor     esi, esi
        call    epoll$new
        mov     edi, 100                        ; 100ms timer
        mov     rsi, rax                        ; epoll object it needs
        call    epoll$timer_new

        mov     rdi, rbx
        call    tui_terminal$new
        call    epoll$run               ; doesn't come back

include '../../ht_data.inc'
    


Cheers

_________________
2 Ton Digital - https://2ton.com.au/
Post 09 Jul 2017, 21:57
View user's profile Send private message Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 10 Jul 2017, 04:05
Tomasz Grysztar wrote:
YONG wrote:
It seems that the 64-bit fasm compiler has some memory management issue. Anyway.
fasm for Linux/Unix always allocates exactly 16 MB of memory by default, for it to use more memory you have to specify the right amount with the switch. This is a general quirk of fasm's memory management, not related to 64 bits.
How do the user know, in advance, how much memory the compiler needs to get the job done? Rolling Eyes

Besides, why set the limit at 16 MB? Shouldn't the compiler be able to use as much memory as it needs? Rolling Eyes

The compiler should only be bounded by the available physical memory.

Wink
Post 10 Jul 2017, 04:05
View user's profile Send private message Visit poster's website Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 10 Jul 2017, 04:13
redsock wrote:
The only "master function list" is maintained via javascript on the upper-right corner of my site's search feature (it is scraped when the static pages for the site are constructed).
Without such a master list, it would take quite some time to fully understand the inner workings of the built-in routines, function calls, and so on. Anyway.

One quick question: Where can I set the values for # of columns (80) and # of rows (25)?

Wink
Post 10 Jul 2017, 04:13
View user's profile Send private message Visit poster's website Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 10 Jul 2017, 06:36
redsock wrote:
Morning coffee today resulted in a quick modification of the demo (noting I still didn't mess with bounds checking haha), this one randomly moves the X every 100ms Smile
There is no need to have bounds checking in the demo, as the relevant keystrokes will be taken care of in my program. But it is nice to see how to do a "delay" timer with the HT library. Thanks.

Wink
Post 10 Jul 2017, 06:36
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 10 Jul 2017, 07:20
YONG wrote:
One quick question: Where can I set the values for # of columns (80) and # of rows (25)?
If you look in the source file tui_background.inc, you'll see the function that I referenced called init_dd (which is to say, double and double for the width and height arguments).

If OTOH you choose init_ii as the call, then the width and height are not percentage based (but the parameter order/registers changes obviously). The comments above the init_ii function will tell you which registers to fill with the integer width and height and you can omit the references to xmm regs from my demo.

Smile

_________________
2 Ton Digital - https://2ton.com.au/
Post 10 Jul 2017, 07:20
View user's profile Send private message Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 10 Jul 2017, 10:15
redsock wrote:
[If OTOH you choose init_ii as the call, ...
I just tried using init_ii instead of init_dd. It worked. But resizing the terminal window resulted in black margins in the right and at the bottom. Can that issue be fixed? If not, can the terminal window be rendered "not resizable"?

Wink
Post 10 Jul 2017, 10:15
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 10 Jul 2017, 21:26
At least with all of the terminals I have tried over the years, resizing is always allowed unless you are on the console itself in runlevel 3 (which probably isn't what you want Smile)

The black margins on the right and bottom are correct if your terminal size is >80x25.

There are a number of ways to deal with that... if it were me, I would be inclined to center your 80x25 onscreen. The HT library makes use of a "panel-based" layout, whereby you can mix up percentage-based dynamic components and fixed size ones. Using the simple_vtable and tui_object itself you can create "spacer/container" objects to fill space as needed.

The tui_simpleauth component I did does a similar thing to center its "enter your user/pass" space, if you look at tui_simpleauth$new and tui_simpleauth$nvsetup you can see how I constructed the layouts there.

_________________
2 Ton Digital - https://2ton.com.au/
Post 10 Jul 2017, 21:26
View user's profile Send private message Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 11 Jul 2017, 03:13
redsock wrote:
There are a number of ways to deal with that... if it were me, I would be inclined to center your 80x25 onscreen. The HT library makes use of a "panel-based" layout, whereby you can mix up percentage-based dynamic components and fixed size ones. Using the simple_vtable and tui_object itself you can create "spacer/container" objects to fill space as needed.

The tui_simpleauth component I did does a similar thing to center its "enter your user/pass" space, if you look at tui_simpleauth$new and tui_simpleauth$nvsetup you can see how I constructed the layouts there.
Okay, I will take a look at the tui_simpleauth component.

Thanks!

Wink
Post 11 Jul 2017, 03:13
View user's profile Send private message Visit poster's website Reply with quote
YONG



Joined: 16 Mar 2005
Posts: 7997
Location: 22° 15' N | 114° 10' E
YONG 15 Jul 2017, 09:52
@redsock:

Just a couple of quick questions:

I tried to use the search at the upper right corner of your website. But nothing happened for a number of inputs: "prolog", "ansi_colors", and even "ht$init". Does the search support only a "selected" list of functions and/or routines?

I tried to change the background color and the default character. It worked. But the upper left corner of the terminal always showed the initial blue box, even after moving the "X" away from it. Where can I set the default color for the initial blue box?

Thanks in advance!

Wink
Post 15 Jul 2017, 09:52
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 15 Jul 2017, 23:52
I modified the original example again Smile

I fixed the size to 80x25, centered on a black background 100%x100% terminal. Fixed the bounds checking, and it now correctly hides the cursor.

Does this version fixup what you were after?
Code:
include '../../ht_defaults.inc'
include '../../ht.inc'

globals
{
        x       dd      0
        y       dd      0
}

falign
our_draw:
        prolog  our_draw
        push    rdi
        ; ensure the cursor is hidden:
        mov     rsi, [rdi]
        call    qword [rsi+tui_vhidecursor]
        ; call tui_background's non-virtual fill:
        mov     rdi, [rsp]
        call    tui_background$nvfill
        pop     rdi
        cmp     dword [rdi+tui_width_ofs], 0
        je      .nothingtodo
        cmp     dword [rdi+tui_height_ofs], 0
        je      .nothingtodo
        mov     eax, [rdi+tui_width_ofs]
        mov     r8, [rdi+tui_text_ofs]
        mov     r9, [rdi+tui_attr_ofs]
        mov     ecx, [y]
        mul     ecx
        add     eax, [x]
        shl     eax, 2
        ansi_colors r10d, 'red', 'darkblue'
        mov     dword [r8+rax], 'X'
        mov     dword [r9+rax], r10d
.nothingtodo:
        mov     rsi, [rdi]              ; load the vtable
        call    qword [rsi+tui_vupdatedisplaylist]
        epilog


        ; three arguments: rdi == our tui_background, esi == key, edx == esc_key
        ; NOTE: return zero in eax if firekeyevent should keep walking up "bubbling"
        ; and return nonzero in eax if firekeyevent should STOP
falign
our_keyevent:
        prolog  our_keyevent
        ; check for cursor keys
        mov     r8d, [rdi+tui_width_ofs]
        mov     r9d, [rdi+tui_height_ofs]
        sub     r8d, 1
        sub     r9d, 1
        cmp     edx, 0x41                       ; up arrow
        je      .uparrow
        cmp     edx, 0x42                       ; down arrow
        je      .downarrow
        cmp     edx, 0x43                       ; right arrow
        je      .rightarrow
        cmp     edx, 0x46                       ; end, well, shift-end
        je      .shiftend
        cmp     edx, 0x44                       ; left arrow
        je      .leftarrow
.bailout:
        xor     eax, eax
        epilog
.uparrow:
        cmp     [y], 0
        je      .bailout
        sub     [y], 1
        jmp     .redraw
.downarrow:
        cmp     [y], r9d
        je      .bailout
        add     [y], 1
        jmp     .redraw
.rightarrow:
        cmp     [x], r8d
        je      .bailout
        add     [x], 1
        jmp     .redraw
.shiftend:
        mov     [x], r8d
        sub     [x], 1
        jmp     .redraw
.leftarrow:
        cmp     [x], 0
        je      .bailout
        sub     [x], 1
.redraw:
        call    our_draw
        mov     eax, 1
        epilog

; a modified copy of tui_background$vtable so we can catch input and customise
; the draw method:
dalign
our_vtable:
        dq      tui_object$cleanup, tui_background$clone, our_draw, tui_object$redraw, tui_object$updatedisplaylist, tui_object$sizechanged
        dq      tui_object$timer, tui_object$layoutchanged, tui_object$move, tui_object$setfocus, tui_object$gotfocus, tui_object$lostfocus
        dq      our_keyevent, tui_object$domodal, tui_object$endmodal, tui_object$exit, tui_object$calcbounds, tui_object$calcchildbounds
        dq      tui_object$appendchild, tui_object$appendbastard, tui_object$prependchild, tui_object$contains, tui_object$getchildindex
        dq      tui_object$removechild, tui_object$removebastard, tui_object$removeallchildren, tui_object$removeallbastards
        dq      tui_object$getobjectsunderpoint, tui_object$flatten, tui_object$firekeyevent, tui_object$ontab, tui_object$onshifttab
        dq      tui_object$setcursor, tui_object$showcursor, tui_object$hidecursor, tui_object$click, tui_object$clicked


public _start
calign
_start:
        ; initialise HeavyThing...
        call    ht$init

        ; allocate one 100%x100% background to hold everything
        mov     edi, tui_background_size
        call    heap$alloc
        movq    xmm0, [_math_onehundred]
        movq    xmm1, [_math_onehundred]
        mov     rdi, rax
        mov     esi, ' '
        ansi_colors edx, 'lightgray', 'black'
        mov     r12, rax
        call    tui_background$init_dd
        ; make sure it aligns its children centered horizontally:
        mov     dword [r12+tui_horizalign_ofs], tui_align_center
        ; use the default vtable
        mov     qword [r12], tui_background$vtable

        ; default layout is vertical, so add a 50% high empty object
        mov     edi, tui_object_size
        call    heap$alloc
        push    rax
        mov     rdi, rax
        movq    xmm0, [_math_onehundred]
        movq    xmm1, [.half]
        call    tui_object$init_dd
        pop     rsi
        mov     qword [rsi], tui_object$simple_vtable
        mov     rdi, r12
        mov     rdx, [r12]
        call    qword [rdx+tui_vappendchild]

        ; add our horizontally-centered 80x25 fixed size object next

        ; allocate enough room for our tui_background
        mov     edi, tui_background_size
        call    heap$alloc
        mov     rbx, rax                        ; save it
        mov     rdi, rax                        ; setup for call to init_dd
        mov     esi, 80                         ; width
        mov     edx, 25                         ; height
        mov     ecx, ' '                        ; fillchar
        ansi_colors r8d, 'lightgray', 'darkblue'        ; colours
        call    tui_background$init_ii
        mov     qword [rbx], our_vtable         ; use our custom vtable
        
        mov     rdi, r12
        mov     rsi, rbx
        mov     rdx, [r12]
        call    qword [rdx+tui_vappendchild]

        ; and finally another 50% high padding below
        mov     edi, tui_object_size
        call    heap$alloc
        push    rax
        mov     rdi, rax
        movq    xmm0, [_math_onehundred]
        movq    xmm1, [.half]
        call    tui_object$init_dd
        pop     rsi
        mov     qword [rsi], tui_object$simple_vtable
        mov     rdi, r12
        mov     rdx, [r12]
        call    qword [rdx+tui_vappendchild]


        mov     rdi, r12
        call    tui_terminal$new
        call    epoll$run               ; doesn't come back
dalign
.half   dq      50.0f

include '../../ht_data.inc'
    

_________________
2 Ton Digital - https://2ton.com.au/
Post 15 Jul 2017, 23:52
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.