X86-16 Function 01 -> Change destination and/or display pages

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












This code is intended to be included with X86-16 writing ASCIIZ strings directly to video and is dependent upon some of the declarations in that code. When combined with that code a string declared @ 1000:0 in the following manner would;



AscTxt: db 01, 84H ; View page 0 output to 4
db 'This is an example', 01, 40H ; View page 4 output to 0
db 'This is replacing whatever is on top line of page 0'
db 0, 01, 0FH, 0, 0 ; Waits for response then view page 0


As an example, let's start with this.



Page 0



This is the next thing you would see after entering your .COM filename @ command prompt.



enter image description here



Notice how the cursor has not moved to EOS. That is by design. Then after pressing any key except ESC, we'll revert back to page 0 with top line being replaced.



enter image description here



; =============================================================================================
; Change display and/or destination page

; ENTER: 00 - 7 = Set do not change current page being displayed
; 6-4 = Display page. Ignored if equal to active or but 7 set
; 3 = Set, do not change display page
; 2-0 = Destination page. Ignored if already pointing there or bit 3 set.

; LEAVE: DI = New pointer when applicable
; DX = volatile, all others unchanged.

; FLAGS: Undefined
; ---------------------------------------------------------------------------------------------

F01: cmp al, 1
jnz F02
lodsb ; Read only parameter for this function

; Real mode has a few limitations in addressing far data, so this just seems to be the
; most practical way of addressing data in BDA

push bx

; Test bit 7 to determine if display page should be changed. If so, then bits 6-4 are
; ignored.

test al, 10000000B ; Is bit 7 on
jnz .cDest ; if so we are not changing display page

push ax ; Still going to need low nibble
shr ax, 4 ; Shift page number into low nibble
cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
jz .cDest - 1 ; Already on that page

; The intent of procedurd e as a whole is to avoid BIOS as much as possible, but I
; did not want to implement code to manipulate controller.

mov ah, SAP
int VIDEO
pop ax ; Restore value in low nibble

.cDest: test al, 1000B ; Is bit 3 on
jnz .exit ; if so we are not changing destination page ; Return to instruction just before label .next

; Check if there is any need to do anything by determining if destination video segment
; is already being pointed too.

and al, 7
mov dx, es ; Get current video segment
mov dl, al
add dl, 0B8H
cmp dh, dl ; ZF will be set if same segments
jz .exit

; Set new segment and then determine offset based on that pages cursor position from
; x/y coordinates specified in BDA.

shl dx, 8
mov es, dx ; Set new segment

; Caret position of new page or even one that has been written to before is assumed
; to be the starting point of next write.

mov bx, Cursors ; Point to beginning of array of vectors
shl ax, 1
add bl, al
mov dx, [bx] ; Points into arrary of vectors in BDA

mov di, dx ; Just in case we are already at 0,0.
or dx, dx
jz .exit

; If position is top/left, not much point multiplying by zero

mov al, dh
imul ax, 80 ; 80 x 25 x 16 color assumed
and di, 0FFH
add di, ax
shl di, 1 ; ES:DI set to new page & offset

; Restore non-volatile

.exit: pop bx
ret

F02: ret






share|improve this question



























    up vote
    1
    down vote

    favorite












    This code is intended to be included with X86-16 writing ASCIIZ strings directly to video and is dependent upon some of the declarations in that code. When combined with that code a string declared @ 1000:0 in the following manner would;



    AscTxt: db 01, 84H ; View page 0 output to 4
    db 'This is an example', 01, 40H ; View page 4 output to 0
    db 'This is replacing whatever is on top line of page 0'
    db 0, 01, 0FH, 0, 0 ; Waits for response then view page 0


    As an example, let's start with this.



    Page 0



    This is the next thing you would see after entering your .COM filename @ command prompt.



    enter image description here



    Notice how the cursor has not moved to EOS. That is by design. Then after pressing any key except ESC, we'll revert back to page 0 with top line being replaced.



    enter image description here



    ; =============================================================================================
    ; Change display and/or destination page

    ; ENTER: 00 - 7 = Set do not change current page being displayed
    ; 6-4 = Display page. Ignored if equal to active or but 7 set
    ; 3 = Set, do not change display page
    ; 2-0 = Destination page. Ignored if already pointing there or bit 3 set.

    ; LEAVE: DI = New pointer when applicable
    ; DX = volatile, all others unchanged.

    ; FLAGS: Undefined
    ; ---------------------------------------------------------------------------------------------

    F01: cmp al, 1
    jnz F02
    lodsb ; Read only parameter for this function

    ; Real mode has a few limitations in addressing far data, so this just seems to be the
    ; most practical way of addressing data in BDA

    push bx

    ; Test bit 7 to determine if display page should be changed. If so, then bits 6-4 are
    ; ignored.

    test al, 10000000B ; Is bit 7 on
    jnz .cDest ; if so we are not changing display page

    push ax ; Still going to need low nibble
    shr ax, 4 ; Shift page number into low nibble
    cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
    jz .cDest - 1 ; Already on that page

    ; The intent of procedurd e as a whole is to avoid BIOS as much as possible, but I
    ; did not want to implement code to manipulate controller.

    mov ah, SAP
    int VIDEO
    pop ax ; Restore value in low nibble

    .cDest: test al, 1000B ; Is bit 3 on
    jnz .exit ; if so we are not changing destination page ; Return to instruction just before label .next

    ; Check if there is any need to do anything by determining if destination video segment
    ; is already being pointed too.

    and al, 7
    mov dx, es ; Get current video segment
    mov dl, al
    add dl, 0B8H
    cmp dh, dl ; ZF will be set if same segments
    jz .exit

    ; Set new segment and then determine offset based on that pages cursor position from
    ; x/y coordinates specified in BDA.

    shl dx, 8
    mov es, dx ; Set new segment

    ; Caret position of new page or even one that has been written to before is assumed
    ; to be the starting point of next write.

    mov bx, Cursors ; Point to beginning of array of vectors
    shl ax, 1
    add bl, al
    mov dx, [bx] ; Points into arrary of vectors in BDA

    mov di, dx ; Just in case we are already at 0,0.
    or dx, dx
    jz .exit

    ; If position is top/left, not much point multiplying by zero

    mov al, dh
    imul ax, 80 ; 80 x 25 x 16 color assumed
    and di, 0FFH
    add di, ax
    shl di, 1 ; ES:DI set to new page & offset

    ; Restore non-volatile

    .exit: pop bx
    ret

    F02: ret






    share|improve this question























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      This code is intended to be included with X86-16 writing ASCIIZ strings directly to video and is dependent upon some of the declarations in that code. When combined with that code a string declared @ 1000:0 in the following manner would;



      AscTxt: db 01, 84H ; View page 0 output to 4
      db 'This is an example', 01, 40H ; View page 4 output to 0
      db 'This is replacing whatever is on top line of page 0'
      db 0, 01, 0FH, 0, 0 ; Waits for response then view page 0


      As an example, let's start with this.



      Page 0



      This is the next thing you would see after entering your .COM filename @ command prompt.



      enter image description here



      Notice how the cursor has not moved to EOS. That is by design. Then after pressing any key except ESC, we'll revert back to page 0 with top line being replaced.



      enter image description here



      ; =============================================================================================
      ; Change display and/or destination page

      ; ENTER: 00 - 7 = Set do not change current page being displayed
      ; 6-4 = Display page. Ignored if equal to active or but 7 set
      ; 3 = Set, do not change display page
      ; 2-0 = Destination page. Ignored if already pointing there or bit 3 set.

      ; LEAVE: DI = New pointer when applicable
      ; DX = volatile, all others unchanged.

      ; FLAGS: Undefined
      ; ---------------------------------------------------------------------------------------------

      F01: cmp al, 1
      jnz F02
      lodsb ; Read only parameter for this function

      ; Real mode has a few limitations in addressing far data, so this just seems to be the
      ; most practical way of addressing data in BDA

      push bx

      ; Test bit 7 to determine if display page should be changed. If so, then bits 6-4 are
      ; ignored.

      test al, 10000000B ; Is bit 7 on
      jnz .cDest ; if so we are not changing display page

      push ax ; Still going to need low nibble
      shr ax, 4 ; Shift page number into low nibble
      cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
      jz .cDest - 1 ; Already on that page

      ; The intent of procedurd e as a whole is to avoid BIOS as much as possible, but I
      ; did not want to implement code to manipulate controller.

      mov ah, SAP
      int VIDEO
      pop ax ; Restore value in low nibble

      .cDest: test al, 1000B ; Is bit 3 on
      jnz .exit ; if so we are not changing destination page ; Return to instruction just before label .next

      ; Check if there is any need to do anything by determining if destination video segment
      ; is already being pointed too.

      and al, 7
      mov dx, es ; Get current video segment
      mov dl, al
      add dl, 0B8H
      cmp dh, dl ; ZF will be set if same segments
      jz .exit

      ; Set new segment and then determine offset based on that pages cursor position from
      ; x/y coordinates specified in BDA.

      shl dx, 8
      mov es, dx ; Set new segment

      ; Caret position of new page or even one that has been written to before is assumed
      ; to be the starting point of next write.

      mov bx, Cursors ; Point to beginning of array of vectors
      shl ax, 1
      add bl, al
      mov dx, [bx] ; Points into arrary of vectors in BDA

      mov di, dx ; Just in case we are already at 0,0.
      or dx, dx
      jz .exit

      ; If position is top/left, not much point multiplying by zero

      mov al, dh
      imul ax, 80 ; 80 x 25 x 16 color assumed
      and di, 0FFH
      add di, ax
      shl di, 1 ; ES:DI set to new page & offset

      ; Restore non-volatile

      .exit: pop bx
      ret

      F02: ret






      share|improve this question













      This code is intended to be included with X86-16 writing ASCIIZ strings directly to video and is dependent upon some of the declarations in that code. When combined with that code a string declared @ 1000:0 in the following manner would;



      AscTxt: db 01, 84H ; View page 0 output to 4
      db 'This is an example', 01, 40H ; View page 4 output to 0
      db 'This is replacing whatever is on top line of page 0'
      db 0, 01, 0FH, 0, 0 ; Waits for response then view page 0


      As an example, let's start with this.



      Page 0



      This is the next thing you would see after entering your .COM filename @ command prompt.



      enter image description here



      Notice how the cursor has not moved to EOS. That is by design. Then after pressing any key except ESC, we'll revert back to page 0 with top line being replaced.



      enter image description here



      ; =============================================================================================
      ; Change display and/or destination page

      ; ENTER: 00 - 7 = Set do not change current page being displayed
      ; 6-4 = Display page. Ignored if equal to active or but 7 set
      ; 3 = Set, do not change display page
      ; 2-0 = Destination page. Ignored if already pointing there or bit 3 set.

      ; LEAVE: DI = New pointer when applicable
      ; DX = volatile, all others unchanged.

      ; FLAGS: Undefined
      ; ---------------------------------------------------------------------------------------------

      F01: cmp al, 1
      jnz F02
      lodsb ; Read only parameter for this function

      ; Real mode has a few limitations in addressing far data, so this just seems to be the
      ; most practical way of addressing data in BDA

      push bx

      ; Test bit 7 to determine if display page should be changed. If so, then bits 6-4 are
      ; ignored.

      test al, 10000000B ; Is bit 7 on
      jnz .cDest ; if so we are not changing display page

      push ax ; Still going to need low nibble
      shr ax, 4 ; Shift page number into low nibble
      cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
      jz .cDest - 1 ; Already on that page

      ; The intent of procedurd e as a whole is to avoid BIOS as much as possible, but I
      ; did not want to implement code to manipulate controller.

      mov ah, SAP
      int VIDEO
      pop ax ; Restore value in low nibble

      .cDest: test al, 1000B ; Is bit 3 on
      jnz .exit ; if so we are not changing destination page ; Return to instruction just before label .next

      ; Check if there is any need to do anything by determining if destination video segment
      ; is already being pointed too.

      and al, 7
      mov dx, es ; Get current video segment
      mov dl, al
      add dl, 0B8H
      cmp dh, dl ; ZF will be set if same segments
      jz .exit

      ; Set new segment and then determine offset based on that pages cursor position from
      ; x/y coordinates specified in BDA.

      shl dx, 8
      mov es, dx ; Set new segment

      ; Caret position of new page or even one that has been written to before is assumed
      ; to be the starting point of next write.

      mov bx, Cursors ; Point to beginning of array of vectors
      shl ax, 1
      add bl, al
      mov dx, [bx] ; Points into arrary of vectors in BDA

      mov di, dx ; Just in case we are already at 0,0.
      or dx, dx
      jz .exit

      ; If position is top/left, not much point multiplying by zero

      mov al, dh
      imul ax, 80 ; 80 x 25 x 16 color assumed
      and di, 0FFH
      add di, ax
      shl di, 1 ; ES:DI set to new page & offset

      ; Restore non-volatile

      .exit: pop bx
      ret

      F02: ret








      share|improve this question












      share|improve this question




      share|improve this question








      edited Feb 6 at 13:24









      200_success

      123k14143401




      123k14143401









      asked Feb 6 at 11:56









      Shift_Left

      46929




      46929




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          -1
          down vote













          The initial comment: not clear what is entering (deducting it's about byte [ds:si]) and I would rather use "arguments" or "input" word. Not clear the description is about bits. Not all arguments are described (the code does use also ds:si address for lodsb). Typos. Modified registers are incomplete too (again si). Etc..




          F01: cmp al, 1
          jnz F02


          Why name like F01? Was it just for this review, or is it actual label? Use rather something more descriptive.




          Why does the function end when al is not equal to 1? That should be mentioned in description, that al must be 1 to make it work.




          I would move push bx lot more closer to the area where it's modified, so it can be easily seen with eye, where the whole push/pop block is, and span over fewer branching points (which is always error prone, to keep correct stack across some branching). You can actually surround just few instructions with push/pop bx, not having any branching at all.




           push ax ; Still going to need low nibble
          shr ax, 4 ; Shift page number into low nibble
          cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
          jz .cDest - 1 ; Already on that page


          Bug: if ah contains some low bits, you will get wrong display page value. Should be shr al,4 instead.



          Why .cDest-1? First why cDest, that's not English, and why -1, you are on x86 powerful machine, there absolutely no reason to save bytes on symbol names or amount of symbols. 1988 called, they want your habits back.




          Some more typos... don't you have spellcheck in your editor? :-o (I'm using simple kate for NASM sources, and Shift+Ctrl+O will switch spellchecking on/off, so it doesn't bother me on instructions, but I can use it to review comments from time to time).




           mov ah, SAP
          int VIDEO


          This will not compile, you should rather provide working source for review. By building it yourself before posting you will prevent some kind of accident, like cutting out more than you did want. Also I have no idea what is SAP or VIDEO, so no way to review it and put any advice on that. Except stop using cryptic short symbol names which can't be comprehended by reading like plain English.




           mov bx, Cursors ; Point to beginning of array of vectors
          shl ax, 1
          add bl, al


          Do just shl al, 1 if you are using only al later. This at first did look as bug to me, because you have anything in ah, then I realized you will avoid that by using al only.



          Actually this will fail if Cursors array spans over 256B boundary, then the add bl,al will produce wrong address.



          But you didn't show how you define Cursors, maybe you are sure it is well aligned and will always fit into 256B "page".



          Still maybe consider more robust version doing whole and ax,7 add ax,ax add bx,ax to calculate with full 16b values.




          And the whole set cursor code is a bit fishy, I mean the calculation of di based on [x, y], don't you have such code already somewhere?



          Are you optimizing for speed that you can't afford to call that? (probably not, as you are still in real mode)



          Also imul ax, 80 is again risky as you don't specify ah content (would work with my modification above to and ax,7).



          I would probably write separate subroutine to calculate di based on [x, y] coordinates, like for example:



          ; input: dh:dl = y:x of cursor
          ; output: di = text mode offset for cursor position
          getDiForCursorPosition:
          push dx
          movzx di, dh ; di = y
          imul di, 80 ; di = 80 * y
          movzx dx, dl ; dx = x
          add di, dx ; di = 80 * y + x
          add di, di ; di = (80 * y + x) * 2
          pop dx
          ret


          And use that from everywhere (after you will check it works as expected, I didn't debug it :) ).






          share|improve this answer





















          • I had hoped the first sentence was informative enough that the code from that link needed to be included in order this snippet be fully functional. Labels are not meant to be human readable. They are simply a means by which the assembler can calculate offsets and addresses and it would be nice if NASM incorporated something like @@: as in MASM. Case in point, in STDLIB you'll see atoi not ascii_to_unsigned_or_signed_integer.
            – Shift_Left
            Feb 7 at 23:56










          • @Shift_Left: if you don't want them read by human, why do you post on code review site? atoi is from different century. Literally.
            – Ped7g
            Feb 8 at 0:06











          • The operative word in programming is CODE defined as; a system used for brevity or secrecy of communication, in which arbitrarily chosen words, letters, or symbols are assigned definite meanings. To that end, the comments you made about code are relevant and directly related to the process of reviewing code, and its functionality. Your personal idiosyncrasy's though as to how labels should be named are not. That being said, the comments you made about my comments is valid, as those are intended to be human readable and understandable.
            – Shift_Left
            Feb 8 at 0:31











          • Look, whatever. We did use labels a, b, c, d, ..., aa, ab, ac, ... on ZX Spectrum to make it fit into ~40kB RAM (with huge 5-10kB source), and I had sheet of paper next to computer with the meanings of labels. Then with TASM I had 360kB ASM file, with every label being readable and comprehended without any guessing. Why? Because it did compile, and it made debugging and reviewing much easier, so it did save me time (although letting that part of project to grow to 300+kB ASM was huge mistake). I'm now offering you this advice, how to write asm code faster... apply as you wish. :)
            – Ped7g
            Feb 8 at 0:39






          • 1




            @Shift_Left "messy" may be editor, plus the 256B effort really doesn't help to write code in simple way (but at least it is short). My non-size code is usually using simpler/more-straightforward constructs. Anyway, I wrote this answer to help you, and it is perfectly fine if you cherry pick, what is truly helping you, and reject the rest, sorry for me being a bit cocky, in the end I'm happy if you are happy with your code, so take my comments like some sort of a bit heated discussion, but done in good faith, and enjoy your project. :) Good luck.
            – Ped7g
            Feb 8 at 9:31










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186911%2fx86-16-function-01-change-destination-and-or-display-pages%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          -1
          down vote













          The initial comment: not clear what is entering (deducting it's about byte [ds:si]) and I would rather use "arguments" or "input" word. Not clear the description is about bits. Not all arguments are described (the code does use also ds:si address for lodsb). Typos. Modified registers are incomplete too (again si). Etc..




          F01: cmp al, 1
          jnz F02


          Why name like F01? Was it just for this review, or is it actual label? Use rather something more descriptive.




          Why does the function end when al is not equal to 1? That should be mentioned in description, that al must be 1 to make it work.




          I would move push bx lot more closer to the area where it's modified, so it can be easily seen with eye, where the whole push/pop block is, and span over fewer branching points (which is always error prone, to keep correct stack across some branching). You can actually surround just few instructions with push/pop bx, not having any branching at all.




           push ax ; Still going to need low nibble
          shr ax, 4 ; Shift page number into low nibble
          cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
          jz .cDest - 1 ; Already on that page


          Bug: if ah contains some low bits, you will get wrong display page value. Should be shr al,4 instead.



          Why .cDest-1? First why cDest, that's not English, and why -1, you are on x86 powerful machine, there absolutely no reason to save bytes on symbol names or amount of symbols. 1988 called, they want your habits back.




          Some more typos... don't you have spellcheck in your editor? :-o (I'm using simple kate for NASM sources, and Shift+Ctrl+O will switch spellchecking on/off, so it doesn't bother me on instructions, but I can use it to review comments from time to time).




           mov ah, SAP
          int VIDEO


          This will not compile, you should rather provide working source for review. By building it yourself before posting you will prevent some kind of accident, like cutting out more than you did want. Also I have no idea what is SAP or VIDEO, so no way to review it and put any advice on that. Except stop using cryptic short symbol names which can't be comprehended by reading like plain English.




           mov bx, Cursors ; Point to beginning of array of vectors
          shl ax, 1
          add bl, al


          Do just shl al, 1 if you are using only al later. This at first did look as bug to me, because you have anything in ah, then I realized you will avoid that by using al only.



          Actually this will fail if Cursors array spans over 256B boundary, then the add bl,al will produce wrong address.



          But you didn't show how you define Cursors, maybe you are sure it is well aligned and will always fit into 256B "page".



          Still maybe consider more robust version doing whole and ax,7 add ax,ax add bx,ax to calculate with full 16b values.




          And the whole set cursor code is a bit fishy, I mean the calculation of di based on [x, y], don't you have such code already somewhere?



          Are you optimizing for speed that you can't afford to call that? (probably not, as you are still in real mode)



          Also imul ax, 80 is again risky as you don't specify ah content (would work with my modification above to and ax,7).



          I would probably write separate subroutine to calculate di based on [x, y] coordinates, like for example:



          ; input: dh:dl = y:x of cursor
          ; output: di = text mode offset for cursor position
          getDiForCursorPosition:
          push dx
          movzx di, dh ; di = y
          imul di, 80 ; di = 80 * y
          movzx dx, dl ; dx = x
          add di, dx ; di = 80 * y + x
          add di, di ; di = (80 * y + x) * 2
          pop dx
          ret


          And use that from everywhere (after you will check it works as expected, I didn't debug it :) ).






          share|improve this answer





















          • I had hoped the first sentence was informative enough that the code from that link needed to be included in order this snippet be fully functional. Labels are not meant to be human readable. They are simply a means by which the assembler can calculate offsets and addresses and it would be nice if NASM incorporated something like @@: as in MASM. Case in point, in STDLIB you'll see atoi not ascii_to_unsigned_or_signed_integer.
            – Shift_Left
            Feb 7 at 23:56










          • @Shift_Left: if you don't want them read by human, why do you post on code review site? atoi is from different century. Literally.
            – Ped7g
            Feb 8 at 0:06











          • The operative word in programming is CODE defined as; a system used for brevity or secrecy of communication, in which arbitrarily chosen words, letters, or symbols are assigned definite meanings. To that end, the comments you made about code are relevant and directly related to the process of reviewing code, and its functionality. Your personal idiosyncrasy's though as to how labels should be named are not. That being said, the comments you made about my comments is valid, as those are intended to be human readable and understandable.
            – Shift_Left
            Feb 8 at 0:31











          • Look, whatever. We did use labels a, b, c, d, ..., aa, ab, ac, ... on ZX Spectrum to make it fit into ~40kB RAM (with huge 5-10kB source), and I had sheet of paper next to computer with the meanings of labels. Then with TASM I had 360kB ASM file, with every label being readable and comprehended without any guessing. Why? Because it did compile, and it made debugging and reviewing much easier, so it did save me time (although letting that part of project to grow to 300+kB ASM was huge mistake). I'm now offering you this advice, how to write asm code faster... apply as you wish. :)
            – Ped7g
            Feb 8 at 0:39






          • 1




            @Shift_Left "messy" may be editor, plus the 256B effort really doesn't help to write code in simple way (but at least it is short). My non-size code is usually using simpler/more-straightforward constructs. Anyway, I wrote this answer to help you, and it is perfectly fine if you cherry pick, what is truly helping you, and reject the rest, sorry for me being a bit cocky, in the end I'm happy if you are happy with your code, so take my comments like some sort of a bit heated discussion, but done in good faith, and enjoy your project. :) Good luck.
            – Ped7g
            Feb 8 at 9:31














          up vote
          -1
          down vote













          The initial comment: not clear what is entering (deducting it's about byte [ds:si]) and I would rather use "arguments" or "input" word. Not clear the description is about bits. Not all arguments are described (the code does use also ds:si address for lodsb). Typos. Modified registers are incomplete too (again si). Etc..




          F01: cmp al, 1
          jnz F02


          Why name like F01? Was it just for this review, or is it actual label? Use rather something more descriptive.




          Why does the function end when al is not equal to 1? That should be mentioned in description, that al must be 1 to make it work.




          I would move push bx lot more closer to the area where it's modified, so it can be easily seen with eye, where the whole push/pop block is, and span over fewer branching points (which is always error prone, to keep correct stack across some branching). You can actually surround just few instructions with push/pop bx, not having any branching at all.




           push ax ; Still going to need low nibble
          shr ax, 4 ; Shift page number into low nibble
          cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
          jz .cDest - 1 ; Already on that page


          Bug: if ah contains some low bits, you will get wrong display page value. Should be shr al,4 instead.



          Why .cDest-1? First why cDest, that's not English, and why -1, you are on x86 powerful machine, there absolutely no reason to save bytes on symbol names or amount of symbols. 1988 called, they want your habits back.




          Some more typos... don't you have spellcheck in your editor? :-o (I'm using simple kate for NASM sources, and Shift+Ctrl+O will switch spellchecking on/off, so it doesn't bother me on instructions, but I can use it to review comments from time to time).




           mov ah, SAP
          int VIDEO


          This will not compile, you should rather provide working source for review. By building it yourself before posting you will prevent some kind of accident, like cutting out more than you did want. Also I have no idea what is SAP or VIDEO, so no way to review it and put any advice on that. Except stop using cryptic short symbol names which can't be comprehended by reading like plain English.




           mov bx, Cursors ; Point to beginning of array of vectors
          shl ax, 1
          add bl, al


          Do just shl al, 1 if you are using only al later. This at first did look as bug to me, because you have anything in ah, then I realized you will avoid that by using al only.



          Actually this will fail if Cursors array spans over 256B boundary, then the add bl,al will produce wrong address.



          But you didn't show how you define Cursors, maybe you are sure it is well aligned and will always fit into 256B "page".



          Still maybe consider more robust version doing whole and ax,7 add ax,ax add bx,ax to calculate with full 16b values.




          And the whole set cursor code is a bit fishy, I mean the calculation of di based on [x, y], don't you have such code already somewhere?



          Are you optimizing for speed that you can't afford to call that? (probably not, as you are still in real mode)



          Also imul ax, 80 is again risky as you don't specify ah content (would work with my modification above to and ax,7).



          I would probably write separate subroutine to calculate di based on [x, y] coordinates, like for example:



          ; input: dh:dl = y:x of cursor
          ; output: di = text mode offset for cursor position
          getDiForCursorPosition:
          push dx
          movzx di, dh ; di = y
          imul di, 80 ; di = 80 * y
          movzx dx, dl ; dx = x
          add di, dx ; di = 80 * y + x
          add di, di ; di = (80 * y + x) * 2
          pop dx
          ret


          And use that from everywhere (after you will check it works as expected, I didn't debug it :) ).






          share|improve this answer





















          • I had hoped the first sentence was informative enough that the code from that link needed to be included in order this snippet be fully functional. Labels are not meant to be human readable. They are simply a means by which the assembler can calculate offsets and addresses and it would be nice if NASM incorporated something like @@: as in MASM. Case in point, in STDLIB you'll see atoi not ascii_to_unsigned_or_signed_integer.
            – Shift_Left
            Feb 7 at 23:56










          • @Shift_Left: if you don't want them read by human, why do you post on code review site? atoi is from different century. Literally.
            – Ped7g
            Feb 8 at 0:06











          • The operative word in programming is CODE defined as; a system used for brevity or secrecy of communication, in which arbitrarily chosen words, letters, or symbols are assigned definite meanings. To that end, the comments you made about code are relevant and directly related to the process of reviewing code, and its functionality. Your personal idiosyncrasy's though as to how labels should be named are not. That being said, the comments you made about my comments is valid, as those are intended to be human readable and understandable.
            – Shift_Left
            Feb 8 at 0:31











          • Look, whatever. We did use labels a, b, c, d, ..., aa, ab, ac, ... on ZX Spectrum to make it fit into ~40kB RAM (with huge 5-10kB source), and I had sheet of paper next to computer with the meanings of labels. Then with TASM I had 360kB ASM file, with every label being readable and comprehended without any guessing. Why? Because it did compile, and it made debugging and reviewing much easier, so it did save me time (although letting that part of project to grow to 300+kB ASM was huge mistake). I'm now offering you this advice, how to write asm code faster... apply as you wish. :)
            – Ped7g
            Feb 8 at 0:39






          • 1




            @Shift_Left "messy" may be editor, plus the 256B effort really doesn't help to write code in simple way (but at least it is short). My non-size code is usually using simpler/more-straightforward constructs. Anyway, I wrote this answer to help you, and it is perfectly fine if you cherry pick, what is truly helping you, and reject the rest, sorry for me being a bit cocky, in the end I'm happy if you are happy with your code, so take my comments like some sort of a bit heated discussion, but done in good faith, and enjoy your project. :) Good luck.
            – Ped7g
            Feb 8 at 9:31












          up vote
          -1
          down vote










          up vote
          -1
          down vote









          The initial comment: not clear what is entering (deducting it's about byte [ds:si]) and I would rather use "arguments" or "input" word. Not clear the description is about bits. Not all arguments are described (the code does use also ds:si address for lodsb). Typos. Modified registers are incomplete too (again si). Etc..




          F01: cmp al, 1
          jnz F02


          Why name like F01? Was it just for this review, or is it actual label? Use rather something more descriptive.




          Why does the function end when al is not equal to 1? That should be mentioned in description, that al must be 1 to make it work.




          I would move push bx lot more closer to the area where it's modified, so it can be easily seen with eye, where the whole push/pop block is, and span over fewer branching points (which is always error prone, to keep correct stack across some branching). You can actually surround just few instructions with push/pop bx, not having any branching at all.




           push ax ; Still going to need low nibble
          shr ax, 4 ; Shift page number into low nibble
          cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
          jz .cDest - 1 ; Already on that page


          Bug: if ah contains some low bits, you will get wrong display page value. Should be shr al,4 instead.



          Why .cDest-1? First why cDest, that's not English, and why -1, you are on x86 powerful machine, there absolutely no reason to save bytes on symbol names or amount of symbols. 1988 called, they want your habits back.




          Some more typos... don't you have spellcheck in your editor? :-o (I'm using simple kate for NASM sources, and Shift+Ctrl+O will switch spellchecking on/off, so it doesn't bother me on instructions, but I can use it to review comments from time to time).




           mov ah, SAP
          int VIDEO


          This will not compile, you should rather provide working source for review. By building it yourself before posting you will prevent some kind of accident, like cutting out more than you did want. Also I have no idea what is SAP or VIDEO, so no way to review it and put any advice on that. Except stop using cryptic short symbol names which can't be comprehended by reading like plain English.




           mov bx, Cursors ; Point to beginning of array of vectors
          shl ax, 1
          add bl, al


          Do just shl al, 1 if you are using only al later. This at first did look as bug to me, because you have anything in ah, then I realized you will avoid that by using al only.



          Actually this will fail if Cursors array spans over 256B boundary, then the add bl,al will produce wrong address.



          But you didn't show how you define Cursors, maybe you are sure it is well aligned and will always fit into 256B "page".



          Still maybe consider more robust version doing whole and ax,7 add ax,ax add bx,ax to calculate with full 16b values.




          And the whole set cursor code is a bit fishy, I mean the calculation of di based on [x, y], don't you have such code already somewhere?



          Are you optimizing for speed that you can't afford to call that? (probably not, as you are still in real mode)



          Also imul ax, 80 is again risky as you don't specify ah content (would work with my modification above to and ax,7).



          I would probably write separate subroutine to calculate di based on [x, y] coordinates, like for example:



          ; input: dh:dl = y:x of cursor
          ; output: di = text mode offset for cursor position
          getDiForCursorPosition:
          push dx
          movzx di, dh ; di = y
          imul di, 80 ; di = 80 * y
          movzx dx, dl ; dx = x
          add di, dx ; di = 80 * y + x
          add di, di ; di = (80 * y + x) * 2
          pop dx
          ret


          And use that from everywhere (after you will check it works as expected, I didn't debug it :) ).






          share|improve this answer













          The initial comment: not clear what is entering (deducting it's about byte [ds:si]) and I would rather use "arguments" or "input" word. Not clear the description is about bits. Not all arguments are described (the code does use also ds:si address for lodsb). Typos. Modified registers are incomplete too (again si). Etc..




          F01: cmp al, 1
          jnz F02


          Why name like F01? Was it just for this review, or is it actual label? Use rather something more descriptive.




          Why does the function end when al is not equal to 1? That should be mentioned in description, that al must be 1 to make it work.




          I would move push bx lot more closer to the area where it's modified, so it can be easily seen with eye, where the whole push/pop block is, and span over fewer branching points (which is always error prone, to keep correct stack across some branching). You can actually surround just few instructions with push/pop bx, not having any branching at all.




           push ax ; Still going to need low nibble
          shr ax, 4 ; Shift page number into low nibble
          cmp al, [fs:DispPg] ; Check BDA if anything actually needs done
          jz .cDest - 1 ; Already on that page


          Bug: if ah contains some low bits, you will get wrong display page value. Should be shr al,4 instead.



          Why .cDest-1? First why cDest, that's not English, and why -1, you are on x86 powerful machine, there absolutely no reason to save bytes on symbol names or amount of symbols. 1988 called, they want your habits back.




          Some more typos... don't you have spellcheck in your editor? :-o (I'm using simple kate for NASM sources, and Shift+Ctrl+O will switch spellchecking on/off, so it doesn't bother me on instructions, but I can use it to review comments from time to time).




           mov ah, SAP
          int VIDEO


          This will not compile, you should rather provide working source for review. By building it yourself before posting you will prevent some kind of accident, like cutting out more than you did want. Also I have no idea what is SAP or VIDEO, so no way to review it and put any advice on that. Except stop using cryptic short symbol names which can't be comprehended by reading like plain English.




           mov bx, Cursors ; Point to beginning of array of vectors
          shl ax, 1
          add bl, al


          Do just shl al, 1 if you are using only al later. This at first did look as bug to me, because you have anything in ah, then I realized you will avoid that by using al only.



          Actually this will fail if Cursors array spans over 256B boundary, then the add bl,al will produce wrong address.



          But you didn't show how you define Cursors, maybe you are sure it is well aligned and will always fit into 256B "page".



          Still maybe consider more robust version doing whole and ax,7 add ax,ax add bx,ax to calculate with full 16b values.




          And the whole set cursor code is a bit fishy, I mean the calculation of di based on [x, y], don't you have such code already somewhere?



          Are you optimizing for speed that you can't afford to call that? (probably not, as you are still in real mode)



          Also imul ax, 80 is again risky as you don't specify ah content (would work with my modification above to and ax,7).



          I would probably write separate subroutine to calculate di based on [x, y] coordinates, like for example:



          ; input: dh:dl = y:x of cursor
          ; output: di = text mode offset for cursor position
          getDiForCursorPosition:
          push dx
          movzx di, dh ; di = y
          imul di, 80 ; di = 80 * y
          movzx dx, dl ; dx = x
          add di, dx ; di = 80 * y + x
          add di, di ; di = (80 * y + x) * 2
          pop dx
          ret


          And use that from everywhere (after you will check it works as expected, I didn't debug it :) ).







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Feb 7 at 20:43









          Ped7g

          6511312




          6511312











          • I had hoped the first sentence was informative enough that the code from that link needed to be included in order this snippet be fully functional. Labels are not meant to be human readable. They are simply a means by which the assembler can calculate offsets and addresses and it would be nice if NASM incorporated something like @@: as in MASM. Case in point, in STDLIB you'll see atoi not ascii_to_unsigned_or_signed_integer.
            – Shift_Left
            Feb 7 at 23:56










          • @Shift_Left: if you don't want them read by human, why do you post on code review site? atoi is from different century. Literally.
            – Ped7g
            Feb 8 at 0:06











          • The operative word in programming is CODE defined as; a system used for brevity or secrecy of communication, in which arbitrarily chosen words, letters, or symbols are assigned definite meanings. To that end, the comments you made about code are relevant and directly related to the process of reviewing code, and its functionality. Your personal idiosyncrasy's though as to how labels should be named are not. That being said, the comments you made about my comments is valid, as those are intended to be human readable and understandable.
            – Shift_Left
            Feb 8 at 0:31











          • Look, whatever. We did use labels a, b, c, d, ..., aa, ab, ac, ... on ZX Spectrum to make it fit into ~40kB RAM (with huge 5-10kB source), and I had sheet of paper next to computer with the meanings of labels. Then with TASM I had 360kB ASM file, with every label being readable and comprehended without any guessing. Why? Because it did compile, and it made debugging and reviewing much easier, so it did save me time (although letting that part of project to grow to 300+kB ASM was huge mistake). I'm now offering you this advice, how to write asm code faster... apply as you wish. :)
            – Ped7g
            Feb 8 at 0:39






          • 1




            @Shift_Left "messy" may be editor, plus the 256B effort really doesn't help to write code in simple way (but at least it is short). My non-size code is usually using simpler/more-straightforward constructs. Anyway, I wrote this answer to help you, and it is perfectly fine if you cherry pick, what is truly helping you, and reject the rest, sorry for me being a bit cocky, in the end I'm happy if you are happy with your code, so take my comments like some sort of a bit heated discussion, but done in good faith, and enjoy your project. :) Good luck.
            – Ped7g
            Feb 8 at 9:31
















          • I had hoped the first sentence was informative enough that the code from that link needed to be included in order this snippet be fully functional. Labels are not meant to be human readable. They are simply a means by which the assembler can calculate offsets and addresses and it would be nice if NASM incorporated something like @@: as in MASM. Case in point, in STDLIB you'll see atoi not ascii_to_unsigned_or_signed_integer.
            – Shift_Left
            Feb 7 at 23:56










          • @Shift_Left: if you don't want them read by human, why do you post on code review site? atoi is from different century. Literally.
            – Ped7g
            Feb 8 at 0:06











          • The operative word in programming is CODE defined as; a system used for brevity or secrecy of communication, in which arbitrarily chosen words, letters, or symbols are assigned definite meanings. To that end, the comments you made about code are relevant and directly related to the process of reviewing code, and its functionality. Your personal idiosyncrasy's though as to how labels should be named are not. That being said, the comments you made about my comments is valid, as those are intended to be human readable and understandable.
            – Shift_Left
            Feb 8 at 0:31











          • Look, whatever. We did use labels a, b, c, d, ..., aa, ab, ac, ... on ZX Spectrum to make it fit into ~40kB RAM (with huge 5-10kB source), and I had sheet of paper next to computer with the meanings of labels. Then with TASM I had 360kB ASM file, with every label being readable and comprehended without any guessing. Why? Because it did compile, and it made debugging and reviewing much easier, so it did save me time (although letting that part of project to grow to 300+kB ASM was huge mistake). I'm now offering you this advice, how to write asm code faster... apply as you wish. :)
            – Ped7g
            Feb 8 at 0:39






          • 1




            @Shift_Left "messy" may be editor, plus the 256B effort really doesn't help to write code in simple way (but at least it is short). My non-size code is usually using simpler/more-straightforward constructs. Anyway, I wrote this answer to help you, and it is perfectly fine if you cherry pick, what is truly helping you, and reject the rest, sorry for me being a bit cocky, in the end I'm happy if you are happy with your code, so take my comments like some sort of a bit heated discussion, but done in good faith, and enjoy your project. :) Good luck.
            – Ped7g
            Feb 8 at 9:31















          I had hoped the first sentence was informative enough that the code from that link needed to be included in order this snippet be fully functional. Labels are not meant to be human readable. They are simply a means by which the assembler can calculate offsets and addresses and it would be nice if NASM incorporated something like @@: as in MASM. Case in point, in STDLIB you'll see atoi not ascii_to_unsigned_or_signed_integer.
          – Shift_Left
          Feb 7 at 23:56




          I had hoped the first sentence was informative enough that the code from that link needed to be included in order this snippet be fully functional. Labels are not meant to be human readable. They are simply a means by which the assembler can calculate offsets and addresses and it would be nice if NASM incorporated something like @@: as in MASM. Case in point, in STDLIB you'll see atoi not ascii_to_unsigned_or_signed_integer.
          – Shift_Left
          Feb 7 at 23:56












          @Shift_Left: if you don't want them read by human, why do you post on code review site? atoi is from different century. Literally.
          – Ped7g
          Feb 8 at 0:06





          @Shift_Left: if you don't want them read by human, why do you post on code review site? atoi is from different century. Literally.
          – Ped7g
          Feb 8 at 0:06













          The operative word in programming is CODE defined as; a system used for brevity or secrecy of communication, in which arbitrarily chosen words, letters, or symbols are assigned definite meanings. To that end, the comments you made about code are relevant and directly related to the process of reviewing code, and its functionality. Your personal idiosyncrasy's though as to how labels should be named are not. That being said, the comments you made about my comments is valid, as those are intended to be human readable and understandable.
          – Shift_Left
          Feb 8 at 0:31





          The operative word in programming is CODE defined as; a system used for brevity or secrecy of communication, in which arbitrarily chosen words, letters, or symbols are assigned definite meanings. To that end, the comments you made about code are relevant and directly related to the process of reviewing code, and its functionality. Your personal idiosyncrasy's though as to how labels should be named are not. That being said, the comments you made about my comments is valid, as those are intended to be human readable and understandable.
          – Shift_Left
          Feb 8 at 0:31













          Look, whatever. We did use labels a, b, c, d, ..., aa, ab, ac, ... on ZX Spectrum to make it fit into ~40kB RAM (with huge 5-10kB source), and I had sheet of paper next to computer with the meanings of labels. Then with TASM I had 360kB ASM file, with every label being readable and comprehended without any guessing. Why? Because it did compile, and it made debugging and reviewing much easier, so it did save me time (although letting that part of project to grow to 300+kB ASM was huge mistake). I'm now offering you this advice, how to write asm code faster... apply as you wish. :)
          – Ped7g
          Feb 8 at 0:39




          Look, whatever. We did use labels a, b, c, d, ..., aa, ab, ac, ... on ZX Spectrum to make it fit into ~40kB RAM (with huge 5-10kB source), and I had sheet of paper next to computer with the meanings of labels. Then with TASM I had 360kB ASM file, with every label being readable and comprehended without any guessing. Why? Because it did compile, and it made debugging and reviewing much easier, so it did save me time (although letting that part of project to grow to 300+kB ASM was huge mistake). I'm now offering you this advice, how to write asm code faster... apply as you wish. :)
          – Ped7g
          Feb 8 at 0:39




          1




          1




          @Shift_Left "messy" may be editor, plus the 256B effort really doesn't help to write code in simple way (but at least it is short). My non-size code is usually using simpler/more-straightforward constructs. Anyway, I wrote this answer to help you, and it is perfectly fine if you cherry pick, what is truly helping you, and reject the rest, sorry for me being a bit cocky, in the end I'm happy if you are happy with your code, so take my comments like some sort of a bit heated discussion, but done in good faith, and enjoy your project. :) Good luck.
          – Ped7g
          Feb 8 at 9:31




          @Shift_Left "messy" may be editor, plus the 256B effort really doesn't help to write code in simple way (but at least it is short). My non-size code is usually using simpler/more-straightforward constructs. Anyway, I wrote this answer to help you, and it is perfectly fine if you cherry pick, what is truly helping you, and reject the rest, sorry for me being a bit cocky, in the end I'm happy if you are happy with your code, so take my comments like some sort of a bit heated discussion, but done in good faith, and enjoy your project. :) Good luck.
          – Ped7g
          Feb 8 at 9:31












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186911%2fx86-16-function-01-change-destination-and-or-display-pages%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation