home *** CD-ROM | disk | FTP | other *** search
- ;MEM.ASM
- code segment
- assume cs:code,ds:code
- org 100h
- start: jmp begin
- db 5 dup ('stack ')
- stack_area dw 0
-
- topline db ' CURSOR LOCATION: 00000 CONTENTS: 00',32,32,32
- help? db '(? FOR HELP) '
- find? db 'FIND:',32,32,32,32,32,32,32,32,32 ;because I'm using Qedit...
- jump? db 'JUMP TO:',32,32,32,32,32,32
- search db 'SEARCHING... '
- escmsg db 0,'Press ESC to QUIT',0,0
- db 0,'Arrow keys - move cursor',32,32,32,32,32,32,32,32,32,32,32,32
- db '(& Ctrl-Left Arrow & Ctrl-Right Arrow)',0
- db 0,'Home - left end of line',32,32,32,32,32,32,32,32,32,32,32,32,32
- db 'End - right end of line',0
- db 0,'Ctrl-Home - top of screen',32,32,32,32,32,32,32,32,32,32,32
- db 'Ctrl-End - bottom of screen',0
- db 0,'Ctrl-PgUp - beginning of memory',32,32,32,32,32
- db 'Ctrl-PgDn - end of memory',0
- db 0,'PgUp - previous screen',32,32,32,32,32,32,32,32,32,32,32,32,32,32
- db 'PgDn - next screen',0
- db 0,'Scroll Lock ON to scroll screen with Arrow Keys',0
- db 0,'Ctrl-F - Find string of characters',0
- db 0,'Ctrl-L - Continue to search for string',0
- db 0,'Ctrl-J - Jump to hexadecimal memory address',0
- db 0,0,'PRESS ANY KEY TO RETURN...',0
-
- db 'MEM.COM (c)1987 by Doug Cox '
- findstr db 32,32,32,32,32,32,32,32
- cursave dw 0
- saves dw 0
- strcnt dw 0
- oldcur dw 0
- chars dw 0
- curptr dw 0
- toplef dw 0
- mode db 0
-
- begin: lea ax,stack_area
- mov sp,ax
- mov ah,0fh ;function to check screen mode
- int 10h
- cmp al,0bh ;indicates display mode
- jb notega ;if monochrome or CGA
- jmp exit
- notega: mov mode,al ;save it
-
- mov ax,0b000h ;video memory address
- cmp mode,7
- je mono ;if monochrome display
- add ax,800h ;if CGA display
- mono: mov es,ax
- ;save old cursor location
- call getcur
- dec dh
- mov oldcur,dx ;row in dh / col in dl
- ;save old screen
- mov di,0
- lea si,oldscr
- oldlp0: mov cx,80 ;columns
- oldlp: mov al,es:[di]
- mov ds:[si],al
- inc di
- inc di
- inc si
- loop oldlp
- dec dh ;rows
- jnz oldlp0
-
- mov ah,0 ;function to set screen mode
- mov al,2 ;code for 25x80 B&W
- int 10h ;clear screen
-
- mov ah,1 ;function to change cursor shape
- mov cx,7 ;top & bottom row of cursor
- int 10h
-
- ;put top line on screen
- lea si,topline
- mov di,0 ;location on screen
- mov cx,53 ;for count
- mov ah,70 ;for screen attribute
- call movit ;move [si] into [di] & inc di cx times
-
- ;put memory contents on screen
- memtop: mov toplef,0 ;memory location (& data segment)
- mov curptr,0 ;cursor offset location in memory
- mov dx,0100h ;row 1/column 0
- call movcur ;initialize cursor at top left
- newscrn:mov ah,7 ;screen attribute
- mov si,0 ;offset of memory to put on screen
- mov di,160 ;top left of screen
- cmp toplef,0ff8ch ;last possible toplef
- jnc atend ;to not write past 0fffffh
- mov cx,1920 ;80*24 screen
- mov ds,toplef ;toplef is also data segment beginning
- call movit ;lodsb, stosw, loop
- new2: mov dx,cs
- mov ds,dx ;put data seg back
-
- ;put cursor location & contents at screen top
- locont: mov dx,toplef ;data segment
- mov bx,dx ;for first binihex call
- mov cl,4
- shl dx,cl
- add dx,curptr ;offset addr
- jnc locont2
- add bx,1000h ;increment 5th byte
- locont2:mov di,36 ;location on screen
- mov ch,1 ;for count
- call binihex ;show 5th byte of location
- mov bx,dx
- mov ch,4
- call binihex ;show other 4 bytes of location
-
- mov bx,curptr ;cursor location in memory
- mov ds,toplef
- mov bh,[bx] ;contents
- mov cx,cs
- mov ds,cx
- mov di,70 ;screen loc
- mov ch,2 ;2 chars
- call binihex
- ;read keyboard
- wait: mov ah,0 ;function to read keyboard
- int 16h ;program stays here, mostly
- cmp al,0
- je extended_code
-
- call case ;to jump to following subroutines
- db ctrls/3
- diff2 equ $
- db 10 ;^J
- dw jump
- db 6 ;^F
- dw find
- db 12 ;^L
- dw again
- db 3fh ;'?'
- dw emenu
- db 1bh ;ESC
- dw exit
- ctrls equ $-diff2
- dw wait
-
- ;if at last possible screen of memory
- atend: mov dx,toplef
- mov ds,dx ;don't change ds before getting ds:[toplef]
- mov cl,4
- shl dx,cl ;rotate left 1 byte
- mov cx,0ffffh
- sub cx,dx
- inc cx
- mov dx,1920 ;80*24
- sub dx,cx
- call movit ;put memory on screen, but put blanks past ffffh
- mov cx,dx
- mov ax,0700h ;attribute & blank
- rep stosw
- jmp new2
-
- extended_code:
- mov al,ah
- call case
- db extends/3 ;number of routines to check
- diff1 equ $
- db 71 ;Home
- dw lftside
- db 79 ;End
- dw rtside
- db 73 ;PgUp
- dw prev
- db 81 ;PgDn
- dw next
- db 72 ;Up arrow
- dw curup
- db 80 ;Down arrow
- dw curdn
- db 75 ;Left arrow
- dw curlft
- db 77 ;Right arrow
- dw currt
- db 116 ;Ctrl-Right arrow
- dw movrt
- db 115 ;Ctrl-Left arrow
- dw movlft
- db 132 ;Ctrl-PgUp
- dw memtop
- db 118 ;Ctrl-PgDn
- dw goend
- db 119 ;Ctrl-Home
- dw scrtop
- db 117 ;Ctrl-End
- dw scrbot
- extends equ $-diff1
- dw wait ;go there if not one of above
-
-
- ;'?'
- emenu: call savcur
- lea si,escmsg
- call menwrt
- cmp al,1bh ;ESC
- je jmpexit
- cmp al,3 ;^C
- je jmpexit
- mov dx,cursave
- call movcur
- jmp newscrn
-
- jmpexit:jmp exit
-
- ;Ctrl-Home
- scrtop: call getcur ;row in dh & col in dl
- mov al,80
- mul dh
- sub curptr,ax
- add curptr,80 ;because top row here is 1 not 0
- mov dh,1 ;top row
- call movcur
- jmp locont
-
- ;Ctrl-End
- scrbot: call getcur
- mov al,24 ;bottom row
- sub al,dh ;cursor row
- mov ah,80
- mul ah
- add curptr,ax
- ;now test for end of memory
- mov ax,toplef
- mov cl,4
- shl ax,cl
- add ax,curptr
- jnc scrbot2 ;if not past 0fffffh
- call curend
- jmp locont
-
- scrbot2:mov dh,24 ;bottom row
- call movcur
- jmp locont
-
- ;Ctrl-PgDn
- goend: mov toplef,0ff8ch ;last possible toplef
- mov curptr,1855 ;80*23+15
- mov dx,180fh ;row 24 col 15
- call movcur
- jmp newscrn
-
- ;Home
- lftside:call getcur
- push dx
- mov dh,0
- sub curptr,dx ;decrement curptr to 1st col
- pop dx
- mov dl,0
- call movcur
- jmp locont
-
- ;End
- rtside: mov ax,toplef
- cmp ax,0ff8ch ;last screen in memory
- jc rtside2
- mov cl,4
- shl ax,cl
- add ax,curptr
- cmp ax,0fff0h ;beginning of last line in memory
- jc rtside2
- call curend
- jmp locont
-
- rtside2:call getcur
- mov al,79
- sub al,dl
- mov ah,0
- add curptr,ax
- mov dl,79
- call movcur
- jmp locont
-
- ;PgUp
- prev: cmp toplef,0
- je jmpwait
- cmp toplef,78h ;1920d shifted right (24*80) screen
- jnc prev2 ;if not within 24*80 of beginning of memory
- jmp memtop
- prev2: sub toplef,78h
- gonew: jmp newscrn
-
- ;PgDn
- next: mov dx,toplef
- cmp dx,0ff8ch ;last possible toplef
- jnc jmpwait ;if at end of memory
- add dx,78h ;1920d shifted right
- mov toplef,dx
- mov cl,4
- shl dx,cl
- add dx,curptr
- jnc gonew ;if cursor won't be past 0fffffh
- call curend
- jmp newscrn
-
- curjmp: jmp locont
-
- ;Left Arrow
- curlft: call lftcur
- jnc curjmp
- jmp newscrn
-
- ;Right Arrow
- currt: call rtcur
- jnc curjmp
- jmp newscrn
-
- ;Ctrl-Right Arrow
- movrt: mov cx,10
- rtlp: push cx
- call rtcur
- pop cx
- loop rtlp
- jmp newscrn
-
- ;Ctrl-Left Arrow
- movlft: mov cx,10
- lftlp: push cx
- call lftcur
- pop cx
- loop lftlp
- jmp newscrn
-
- jmpwait:jmp wait
-
- ;Up Arrow
- curup: call scrlock
- jnz up ;if ScrollLock is ON
- call getcur
- cmp dh,1
- je curup2 ;if on top line
- dec dh
- call movcur
- sub curptr,80
- jmp locont
-
- curup2: cmp toplef,0
- jz jmpwait
- sub toplef,5
- jmp newscrn
-
- ;ScrollLock ON
- up: cmp toplef,0
- je jmpwait ;if at beginning of memory
- sub toplef,5
- call getcur
- cmp dh,24
- je downend ;If at bottom
- inc dh
- call movcur
- add curptr,80 ;because of toplef change
- jmp newscrn
-
- jmpwait2:jmp wait
-
- ;Down Arrow
- curdn: call scrlock
- jnz down ;if ScrollLock is ON
- cmp toplef,0ff8ch
- jc curdn3 ;if not at last screen in memory
- mov ax,toplef
- mov cl,4
- shl ax,cl
- add ax,curptr
- add ax,80
- jc jmpwait2 ;if move would put cursor past 0fffffh
- curdn3: call getcur
- cmp dh,24
- je curdn2 ;if on bottom line
- inc dh
- call movcur
- add curptr,80
- jmp locont
-
- curdn2: add toplef,5
- cmp toplef,0ff8ch
- jc downend ;if not at end of memory
- call curend
- jmp newscrn ;don't need to increment curptr
-
- ;ScrollLock ON
- down: cmp toplef,0ff8ch
- jnc jmpwait2 ;if at end of memory
- add toplef,5 ;80 shifted right
- call getcur
- cmp dh,1
- je downend ;if cursor is on top line
- dec dh
- call movcur
- sub curptr,80 ;because of toplef change
- downend:jmp newscrn
-
- ;jump to input hex address
- jump: call savcur
- lea si,jump?
- call top
- mov bp,96 ;for screen location in getstr
- call getstr ;get input
- cmp dx,0 ;input string length
- jnz jumpsk
- jmp find15 ;if no input
- jumpsk: mov si,di ;just after last input char on screen
- mov ax,0
- mov di,ax ;for offset address
- mov bx,ax ;for segment address
- mov dx,0004h ;dh for cl & dl for loop
- ;get offset address
- jumplp: dec si
- dec si
- cmp si,96 ;input screen location
- jl jumpxit ;if no good input
- mov al,es:[si]
- call hex2bin ;convert to binary
- jc jumplp ;if not hexadecimal
- mov cl,dh
- mov ah,0 ;rol changes it
- add dh,4 ;to rol ax to next nibble to left
- rol ax,cl
- or di,ax ;ta daa!
- dec dl
- jnz jumplp
- ;get segment address
- dec si
- dec si
- mov al,es:[si]
- call hex2bin
- jc jumpxit
- mov ah,0
- or bx,ax
- jumpxit:mov saves,es
- jmp find16 ;to jump to address
-
-
- find: call savcur
- lea si,find?
- call top
- mov bp,90
- call getstr
- ;put string in findstr
- cmp dx,0
- jne find12
- jmp find15 ;if no input
- find12: mov si,90
- lea di,findstr
- mov cx,8
- find5: mov al,es:[si]
- mov ds:[di],al
- inc si
- inc si
- inc di
- loop find5
- ;write 'SEARCHING...'
- lea si,search
- mov cx,12
- mov di,108
- mov ah,7
- call movit
- ;search for string
- mov di,0 ;beginning of memory offset
- mov bx,0
- mov saves,es
- mov strcnt,dx ;save it for again:
- mov cx,0ffffh ;for scasb count
- ;jumped to from again:
- find14: mov es,bx ;beginning of memory segment
- dec dx ;because cmpsb doesn't look at 1st char
- jnz find10
- ;if only one char to find
- mov al,findstr
- repnz scasb
- jmp short find11
- ;subroutine to increment segment
- find9: mov di,0
- mov cx,0ffffh
- add bx,1000h
- mov es,bx ;to next segment
- jc find7 ;if past last segment
- ;big find loop
- find10: lea si,findstr
- mov al,[si]
- repnz scasb ;repeat until z=true or cx=0
- jnz find9 ;if string not found in current segment (cx=0)
- mov bp,di ;save it
- push cx
- mov cx,dx ;for cmpsb count
- inc si ;point to remainder of string
- repz cmpsb ;compare strings (repeat until z=false or cx=0)
- pop cx ;get scasb count back
- mov di,bp ;get it back
- jnz find10 ;if string not found
- ;jump to address
- find11: dec di ;offset addr
- mov cl,4
- rol bx,cl ;move segment addr to right-most byte
- and bx,0fh ;clear all but right-most byte
- find16: mov dx,bx ;for div by word
- mov ax,di
- mov cx,80
- div cx ;remainder is in dx (& dl = column)
- mov curptr,dx ;column (dh=0)
- sub di,curptr ;to get toplef
- jnc find13
- dec bx
- find13: mov cl,4
- shr di,cl
- mov cl,4
- ror bx,cl ;back to previous shape
- add di,bx
- mov toplef,di ;ta-daa!
- mov dh,1 ;put cursor on first row
- mov cursave,dx ;for movcur
- ;clear message & exit
- find7: mov es,saves
- find15: mov ax,700h
- mov di,108
- mov cx,12
- rep stosw
- ;put '? FOR HELP' back
- lea si,help?
- call top
- mov dx,cursave
- call movcur
- jmp newscrn
-
- ;look for string again
- again: call savcur
- lea si,search
- mov cx,12
- mov di,108
- mov ah,7
- call movit
- mov dx,strcnt
- mov saves,es
- mov di,toplef
- mov bx,di
- mov cl,4
- rol di,cl
- and di,0fff0h ;clear right byte
- add di,curptr ;offset addr
- inc di ;start looking 1 byte beyond current location
- jnc againsk
- add bx,1000h
- againsk:and bx,0f000h ;clear all but left byte (for seg addr)
- mov cx,0ffffh
- sub cx,di ;for count to end of current segment
- jmp find14
-
-
- ;return to DOS
- exit: mov bh,0 ;page 0
- mov ah,bh ;function to set screen mode
- mov al,mode
- int 10h
- ;restore old cursor location
- mov dx,oldcur ;old cursor location
- dec dh
- call movcur
- ;restore old screen
- inc dh
- mov di,0
- lea si,oldscr
- exitlp: mov cx,80 ;columns
- mov ah,7
- call movit ;move [si] into [di] & inc di cx times
- dec dh ;rows
- jnz exitlp
- int 20h ;return to DOS
-
- ;***CALLED ROUTINES***
-
- top proc near
- mov cx,14
- mov di,78
- mov ah,70
- call movit
- ret
- top endp
-
- movit proc near
- movlp: lodsb
- stosw
- loop movlp
- ret
- movit endp
-
- ;save cursor location
- savcur proc near
- call getcur
- mov cursave,dx
- mov dx,1900h ;row 25,col 0
- jmp short movcur
- savcur endp
-
- ;move cursor to row in dh & col in dl
- movcur proc near
- mov ah,2
- jmp short cur
- movcur endp
-
- ;put row in dh & col in dl
- getcur proc near
- mov ah,3
- cur: mov bh,0
- int 10h
- ret
- getcur endp
-
- ;to jump to a subroutine (semi-trick)
- case proc near
- pop bx ;RET address
- mov cl,[bx] ;number of comparisons to make
- mov ch,0
- caslop: inc bx ;to a db
- cmp al,[bx]
- je go
- inc bx ;to a dw
- inc bx
- loop caslop
- go: inc bx ;to a dw
- mov bx,[bx]
- jmp bx
- case endp
-
- ;to change binary to hex
- binihex proc near
- binlp: mov cl,4
- rol bx,cl ;move left byte to right side
- mov al,bl ;this is necessary
- and al,0fh ;clear left byte
- add al,30h
- cmp al,3ah
- jl num
- add al,7
- num: stosb
- inc di
- dec ch
- jnz binlp
- ret
- binihex endp
-
- ;convert al from hex to binary
- hex2bin proc near
- cmp al,'0'
- jl badhex
- cmp al,'9'
- jle hex2 ;if number
- and al,0dfh ;make letters uppercase
- cmp al,'A'
- jl badhex
- cmp al,'F'
- jg badhex
- sub al,7
- hex2: sub al,30h
- clc
- ret
- badhex: stc
- ret
- hex2bin endp
-
- ;to put cursor at 0fffffh
- curend proc near
- mov dx,toplef
- mov cl,4
- shl dx,cl
- mov ax,0ffffh
- sub ax,dx
- mov curptr,ax
- mov cl,80
- div cl
- inc al
- mov dh,al ;quotient (answer) (for row)
- mov dl,ah ;remainder (for column)
- jmp short movcur
- curend endp
-
- lftcur proc near
- call getcur
- cmp dx,0100h
- je lfttop ;if at top left of screen
- dec curptr
- cmp dl,0
- je prevlin
- dec dl
- jmp short lftmov
- prevlin:dec dh
- mov dl,79
- lftmov: call movcur
- clc
- lftxit: ret
- lftcur endp
-
- lfttop: cmp toplef,0
- je lftxit ;if at beginning of memory
- mov dl,79
- call movcur
- sub toplef,5 ;80d shifted right
- add curptr,79 ;because of toplef change
- stc
- ret
-
- rtcur proc near
- cmp toplef,0ff8ch
- jc rtcur2 ;if not at last screen
- mov ax,toplef
- mov cl,4
- shl ax,cl
- inc ax
- add ax,curptr
- jc rtexit ;if cursor would go beyond 0fffffh
- rtcur2: inc curptr
- call getcur
- cmp dl,79
- je nexlin
- inc dl
- jmp short rtmov
- nexlin: cmp dh,24
- je rtbot
- inc dh
- mov dl,0
- rtmov: call movcur
- clc
- rtexit: ret
- rtcur endp
-
- rtbot: cmp toplef,0ff8ch ;last toplef in memory
- jnc rtexit
- mov dl,0
- call movcur
- add toplef,5
- sub curptr,80 ;because of toplef change
- stc
- ret
-
- scrlock proc near ;check ScrollLock on or off
- push es
- mov ax,0
- mov es,ax
- test byte ptr es:[417h],00010000b
- pop es
- ret
- scrlock endp
-
- ;get string to search for
- getstr proc near
- mov dx,0 ;for count in cmpsb, below
- mov di,bp
- find2: mov ah,0 ;read keyboard function
- int 16h
- cmp ah,14 ;Backspace key
- je find20
- cmp ah,83 ;Del key
- je find20
- cmp ah,75 ;Left Arrow key
- je find20
- cmp al,8
- jne find3 ;if no erase input
- ;erase char
- find20: cmp di,bp
- je find2 ;don't erase if at beginning of input location
- dec di
- dec di
- dec dx
- mov word ptr es:[di],4620h ;attribute & space
- jmp short find2
- ;put char on screen
- find3: cmp di,106 ;last input space
- je find4 ;exit
- cmp al,0dh ;Enter key
- je find4 ;exit
- stosb
- inc di
- inc dx
- jmp short find2
- find4: ret
- getstr endp
-
- menwrt proc near
- mov di,160
- mov ax,0
- mov cx,5
- rep stosw
- mov ah,7 ;for attribute
- mov dx,24 ;rows
- menlp0: mov cx,80 ;columns
- menlp: lodsb
- cmp al,0
- je mensk
- stosw
- loop menlp
- mensk: rep stosw
- cmp si,0
- jne mensk2
- add di,160
- mensk2: dec dx
- jnz menlp0
- mov ah,0
- int 16h ;read keyboard
- ret
- menwrt endp
-
- oldscr equ $
- code ends
- end start