Recent Posts

Pages: 1 [2] 3 4 ... 10
11
Example Code / Re: MSDOS screensaver TSR example
« Last post by vitsoft on September 11, 2022, 07:52:42 PM »
Another example of TSR program displays the current time in the topright corner of textmode screen. It shouldn't be difficult to port it for NASM.
12
Programming with NASM / Re: Converting DOS TSR example from MASM to NASM
« Last post by tysonprogrammer on September 07, 2022, 11:20:18 PM »
thanks Fred, it now builds and runs without causing a crash.  Once I get it cleaned up I will post for others to enjoy.

Tyson
13
Programming with NASM / Re: Converting DOS TSR example from MASM to NASM
« Last post by fredericopissarra on September 07, 2022, 01:09:42 PM »
Another thing:
Code: [Select]
jmp [cs:old_interrupt9]Is an NEAR absolute indirect jump (uses the same CS and takes the offset from the address). What you need is a FAR absolute indirect jump (takes CS and the offset from the address). The correct instruction should be:
Code: [Select]
jmp far [cs:old_interrupt9]
Yet another thing: This
Code: [Select]
and ah,!ctrl_keyWon't do what you thing it does... ! operador is a BOOLEAN operator (as in C) and results in 0 or 1, always. What you are searching for is ~ (BINARY NOT operator). The correct instruction is:
Code: [Select]
and ah,~ctrl_keyHere's your code with some corrections and comments of mine:
Code: [Select]
  bits  16

  org   0x100

; Notice: NO segments needed!

; This program disables the usual DOS reset command
; (Ctrl-Alt-Del), by intercepting the INT 9 keyboard
; hardware interrupt.  It checks the shift status bits
; in the MS-DOS keyboard flag and changes any Ctrl-Alt-Del
; to Alt-Del.  The computer can only be rebooted by
; typing Ctrl+Alt+Right shift+Del.
;
; Use NASM -fbin prog.asm -o prog.com

RT_SHIFT   EQU 0x01     ; Right shift key: bit 0
CTRL_KEY   EQU 0x04     ; CTRL key: bit 2
ALT_KEY    EQU 0x08     ; ALT key: bit 3
DEL_KEY    EQU 0x53     ; scan code for DEL key
KEYB_PORT  EQU 0x60     ; keyboard input port

  jmp   setup           ; jump to TSR installation

;   Memory-resident code begins here
int9_handler:
  sti                   ; enable hardware interrupts
  pushf                 ; save regs & flags
  push  ds              ; Using DS instead of ES to avoid prefixes
  push  ax
  push  bx              ; Using BX as base address (not DI), just to
                        ; be compliant to 8086 effective addresses standard.

  ; Point DS:BX to the BIOS data area keyboard flag (0x40:0x17) byte
  mov   ax,0x40
  mov   ds,ax
  mov   bx,0x17

  mov   ah,[bx]               ; copy keyboard flag into AH

  ; Test for the CTRL and ALT keys:
  test  ah,CTRL_KEY           ; CTRL key held down?
  jz    .exit                 ; no: exit
  test  ah,ALT_KEY            ; ALT key held down?
  jz    .exit                 ; no: exit

  ; Test for the DEL and Right-shift keys:
  in    al,KEYB_PORT          ; read keyboard port
  cmp   al,DEL_KEY            ; DEL key pressed?
  jne   .exit                 ; no: exit
  test  ah,RT_SHIFT           ; right shift key pressed?
  jnz   .exit                 ; yes: allow system reset

  ; FIXED: !CTRL_KEY will result in 0, not 0xFB. ! is a BOOLEAN NOT operator. ~ is a BINARY NOT.
  and   ah,~CTRL_KEY          ; no: turn off bit for CTRL
  mov   [bx],ah               ; store modified keyboard_flag

.exit:
  pop   bx                    ; restore regs & flags
  pop   ax
  pop   ds
  popf

  ; FIXED: Must be a far jump!
  jmp   far [cs:old_interrupt9]   ; jump to INT 9 routine

old_interrupt9:
  align 2
  dd    0
service_end:

; --------------- (end of TSR program) ------------------
;   Save a copy of the original INT 9 vector, and set up
;   the address of our program as the new vector.  Terminate
;   this program and leave the int9_handler procedure in memory.

setup:
  cli                       ; Disable interrupts to NOT allow
                            ; IVT changes when we are tring to
                            ; change it.

  mov ax,0x3509             ; get old INT 9 vector
  int 0x21
  mov [old_interrupt9],bx
  mov [old_interrupt9+2],es

  ; In tiny model DS=CS.
  mov ax,0x2509             ; set new int 9 vector
  mov dx,int9_handler
  int 0x21

  ; Calculate # of paragraphs...
  mov dx,service_end        ; point to end of resident code
                            ; this works only because the initial offset is
                            ; always zero.
  mov ah,dl
  mov cl,4
  shr dx,cl                 ; OBS: shr dx,4 ISN'T an 8086 instruction!
  test ah,0x0f              ; Any bytes remaining in the last paragraph?
  jz  .skip                 ; No, ok...
  inc dx                    ; Yes. Add an extra paragraph
.skip:

  mov ax,0x3100             ; terminate and stay resident
  int 0x21
14
Programming with NASM / Re: Converting DOS TSR example from MASM to NASM
« Last post by Frank Kotler on September 06, 2022, 10:54:25 PM »
Hi Tyson,

There are "known" section names. ".text" (lower case!) is one, "code" is not. I don't think ut makes any difference in this case, but...

I think Nasm likes everything inside the brackets:
Code: [Select]
call [cs: old_interrupt9]
cs" on the previous line might also work.

Sorry we didn't have that other TSR you were looking for.

Best,
Frank

15
Programming with NASM / Re: Optimizing NASM Assembler codes in Windows x86
« Last post by tysonprogrammer on September 06, 2022, 09:56:50 PM »
I chuckled at the username and it was a bit suspicious because of it :)
16
Programming with NASM / Converting DOS TSR example from MASM to NASM
« Last post by tysonprogrammer on September 06, 2022, 09:54:01 PM »
Hello,

I am trying to convert an example DOS TSR from MASM to NASM. I think I have most of it. Only thing I am not sure about is the part calling the old interrupt

Here is the original MASM version

Code: [Select]
TITLE Reset-Disabling program                  (No_Reset.asm)

; This program disables the usual DOS reset command
; (Ctrl-Alt-Del), by intercepting the INT 9 keyboard
; hardware interrupt.  It checks the shift status bits
; in the MS-DOS keyboard flag and changes any Ctrl-Alt-Del
; to Alt-Del.  The computer can only be rebooted by
; typing Ctrl+Alt+Right shift+Del.  Assemble, link,
; and convert to a COM program by including the /T
; command on the Microsoft LINK command line.
; Last update: 12/12/2004

.model tiny
.386
.code
rt_shift   EQU 01h ; Right shift key: bit 0
ctrl_key   EQU 04h ; CTRL key: bit 2
alt_key    EQU 08h ; ALT key: bit 3
del_key    EQU 53h ; scan code for DEL key
kybd_port  EQU 60h ; keyboard input port

ORG   100h        ; this is a COM program
start:
jmp   setup      ; jump to TSR installation

;   Memory-resident code begins here
int9_handler PROC FAR
sti                ; enable hardware interrupts
pushf ; save regs & flags
push  es
push  ax
push  di

;   Point ES:DI to the DOS keyboard flag byte:
L1: mov   ax,40h              ; DOS data segment is at 40h
mov   es,ax
mov   di,17h              ; location of keyboard flag
mov   ah,es:[di]          ; copy keyboard flag into AH

;   Test for the CTRL and ALT keys:
L2: test  ah,ctrl_key        ; CTRL key held down?
jz    L5                  ; no: exit
test  ah,alt_key          ; ALT key held down?
jz    L5                  ; no: exit

;   Test for the DEL and Right-shift keys:
L3: in    al,kybd_port        ; read keyboard port
cmp   al,del_key          ; DEL key pressed?
jne   L5                  ; no: exit
test  ah,rt_shift        ; right shift key pressed?
jnz   L5                  ; yes: allow system reset

L4: and   ah,NOT ctrl_key    ; no: turn off bit for CTRL
mov   es:[di],ah          ; store keyboard_flag

L5: pop   di                  ; restore regs & flags
pop   ax
pop   es
popf
; here is the code I am not sure about
jmp   cs:[old_interrupt9] ; jump to INT 9 routine

old_interrupt9 DWORD ?

int9_handler ENDP
end_ISR label BYTE

; --------------- (end of TSR program) ------------------
;   Save a copy of the original INT 9 vector, and set up
;   the address of our program as the new vector.  Terminate
;   this program and leave the int9_handler procedure in memory.

setup:
mov ax,3509h            ; get INT 9 vector
int 21h
mov word ptr old_interrupt9,bx ; save INT 9 vector
mov word ptr old_interrupt9+2,es

mov ax,2509h            ; set interrupt vector, INT 9
mov dx,offset int9_handler
int 21h

mov ax,3100h ; terminate and stay resident
mov dx,OFFSET end_ISR  ; point to end of resident code
shr dx,4 ; divide by 16
inc dx ; round upward to next paragraph
int 21h                ; execute MS-DOS function
END start

Here is my NASM port
Code: [Select]
; TITLE Reset-Disabling Program
section code
%define syscall int 0x21

rt_shift            EQU 0x01
ctrl_key            EQU 0x04
alt_key             EQU 0x08
del_key             EQU 0x53
keybd_port          EQU 0x60

org 0x100
start:
    jmp setup

; memory resident code starts here
int9_handler:
    sti                                         ; enable hardwrae interrupts
    ; save registers and CPU flags
    pushf                       
    push es
    push ax
    push di
; Point ES_DI to the DOS keyboard flag byte
L1:
    mov ax, 0x40                                ; DOS data segment is at 0x40
    mov es, ax                                  ; set es to the data segment
    mov di, 0x17                                ; location of keyboard flag
    mov ah, [es:di]                             ; copy the keyboard flag to ah
; Test for the CTRL and ALT keys
L2:
    test ah, ctrl_key                           ; is CTRL key down?
    jz L5                                       ; no: exit
    test ah, alt_key                            ; is ALT key down
    jz L5                                       ; no: exit
; Test for DEL and Right Shift keys
L3:
    in al, keybd_port
    cmp al, del_key                             ; is DEL key down?
    jz L5                                       ; no: exit
    test ah, rt_shift                           ; is Right shft down
    jnz L5                                      ; no: exit
L4:
    and ah,!ctrl_key                            ; no turn off bit for ctrl 
    mov [es:di], ah                             ; store keyboard flag
L5:
    pop di
    pop ax
    pop es
    popf
-- here is my version
    jmp [cs:old_interrupt9]
old_interrupt9: dd 0x00000000
end_ISR:        db 0

; ------ end of TSR program -------
; Save a copy of the original interrupt vector and set up
; the address of our program as the new vector, Terminate
; this program and save the int9_handler procedure in memory.
setup:
    mov ax, 0x3509                              ; get int9 vector
    syscall

    mov word [old_interrupt9], bx               ; Save old interrupt vector
    mov word [old_interrupt9+2], es             ; Save old interrupt segment
    mov ax, 0x2509                              ; set interrupt vector
    mov dx, int9_handler
    syscall
   
    mov ax, 0x3100                              ; terminate and stay resident
    mov dx, end_ISR                             ; set end of ISR
    shr dx, 4                                   ; divide by 16
    inc dx                                      ; move upword to next paragraph
    syscall                                     ; excute DOS function

What I not sure about is jmp cs:[old_interrupt9]

Any help would be appreciated.

Tyson
17
Other Discussion / Re: Looking for .COM program sources in NASM Assembly
« Last post by fredericopissarra on September 06, 2022, 12:15:41 PM »
Thanks Frederico, .COM files not being used anymore isn't an issue as I'm learning 8086 Assembly mostly for my interest in retrocomputing.

I see an interesting differences between your hello world code and the similar demo in Wikipedia's NASM entry: your code doesn't declare sectons.
As I said before: COM files don't have sections.
You CAN use sections, but `.text` (or _TEXT) must be the first one, and ORG 0x100 must be there. AND all the sections must be mapped in a single segment.
18
Example Code / Re: MSDOS screensaver TSR example
« Last post by tysonprogrammer on September 05, 2022, 10:32:03 PM »


Can you repost this code? It no longer exists. I am trying to write a TSR using NASM and am having trouble so would like to see an example.

thanks,
Tyson
19
Other Discussion / Re: Looking for .COM program sources in NASM Assembly
« Last post by amoroso on September 05, 2022, 07:48:49 PM »
Thanks Frederico, .COM files not being used anymore isn't an issue as I'm learning 8086 Assembly mostly for my interest in retrocomputing.

I see an interesting differences between your hello world code and the similar demo in Wikipedia's NASM entry: your code doesn't declare sectons.
20
Other Discussion / Re: Looking for .COM program sources in NASM Assembly
« Last post by fredericopissarra on September 05, 2022, 05:08:23 PM »
MS-DOS COM files are nothing more than a single binary with only ONE segment. All selectors points to the same segment (CS = DS = ES = SS) and there are no additional sections.

COM files are inherited from the old CP/M and not used anymore (it's not even supported on Win10 anymore!).

The first 256 bytes of this segment is reserved to PSP (Program Segment Prefix), where you can get the command line, and other things. The source code structure is very simple on NASM:
Code: [Select]
  bits 16

  org  0x100    ; skip the PSP

  ; Your program start here
_start:
  ...
Here a simple 'Hello, World' in COM format:
Code: [Select]
  bits  16

  org   0x100

  ; start here
  lea   dx,[msg]
  mov   ah,9        ; PrintStr (DOS service).
  int   0x21

  mov   ax,0x4c00   ; Exit (DOS service)
  int   0x21

msg:
  db    `Hello, world\r\n$`
Pages: 1 [2] 3 4 ... 10
SMF spam blocked by CleanTalk