home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
mem.asm
< prev
next >
Wrap
Assembly Source File
|
1987-07-07
|
17KB
|
814 lines
;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