home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
cpu
/
vu_xm1c
/
view-xm.asm
< prev
next >
Wrap
Assembly Source File
|
1990-05-01
|
9KB
|
358 lines
; file = view-xm.asm
; View eXtended memory (or low memory),
; while in REAL mode, using the 80286 Loadall instruction.
;
; written by Terrance Hodgins, 1990
page 60,132
title View Xmem using LOADALL
; copyright (C) 1990 by Terrance E. Hodgins,
; dba Semi-Intelligent Systems (r). All rights reserved.
;
; Semi-Intelligent Systems is a registered trademark of
; Terrance E. Hodgins.
; Disclaimer of Warranty
;
; TERRANCE E. HODGINS, AND SEMI-INTELLIGENT
; SYSTEMS, EXCLUDE ANY AND ALL IMPLIED WARRANTIES,
; INCLUDING WARRANTIES OF MERCHANTABILITY AND
; FITNESS FOR A PARTICULAR PURPOSE.
;
; NEITHER TERRANCE E. HODGINS, NOR SEMI-INTELLIGENT
; SYSTEMS, MAKE ANY WARRANTY OF REPRESENTATION,
; EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS
; PROGRAM, ITS QUALITY, PERFORMANCE,
; MERCHANTABILITY, OR FITNESS FOR A PARTICULAR
; PURPOSE.
;
; NEITHER TERRANCE E. HODGINS, NOR SEMI-INTELLIGENT
; SYSTEMS, SHALL HAVE ANY LIABILITY FOR SPECIAL,
; INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
; OF OR RESULTING FROM THE USE OR MODIFICATION OF
; THIS PROGRAM.
;
; THE USE OF THE 80286 LOADALL INSTRUCTION IS
; INHERENTLY DANGEROUS, AND CAN RESULT IN PROGRAM
; CRASHES, OR RUN-AWAY PROGRAMS, WHICH CAN ALTER,
; DAMAGE, OR DESTROY COMPUTER DATA, AND WHICH CAN
; DAMAGE OR DESTROY COMPUTER HARDWARE.
; USE ONLY AT YOUR OWN RISK.
.model small,c
.286p
include save2new.inc
; size of buffer to fill with XM data, each time we copy a block
; down from upstairs.
BUFFSIZE equ 100h ; 256 bytes
extrn a20_on:near
extrn a20_off:near
extrn do_loadall:near
extrn prnt_chr:near
extrn prnt_hex:near
extrn prnts:near
extrn ha_displa:near
extrn start_prog:near
extrn fini_prog:near
extrn save_80:near
extrn restor_80:near
extrn kget_xmaddr:near
extrn exitflag:byte
extrn Target:word
extrn TargLo:word
extrn TargHi:word
.code
main proc
; start up program: set up segments (DS=ES=SS), relocate stack,
; print header info.
call start_prog
; save the current machine state in a "new" loadall table,
call save2new
mainloop:
; get address to peek at, from keyboard.
call kget_xmaddr
; see if user wants to exit.
test byte ptr exitflag,0FFh
jne getout
call set_new ; set up addresses in "new" loadall table
call a20_on ; enable gate A20
call do_1_lda ; go do a loadall
; we don't come back here until after a loadall has
; been done, and we have jumped all over the place.
call a20_off ; disable gate A20
; now look at the data we got
call showdata
jmp short mainloop ; loop back for more
getout:
call fini_prog ; finish up for exit
mov ax,4C00h
int 21h ; DOS call to exit
main endp
; ----------------------------------------------
; ----------------------------------------------
; set up the table of values to be loaded into the registers
; by the first loadall. IE: new machine state.
; This is the routine that you mung to get to wierd
; and wonderful new machine states.
;
; Currently, in this demo, we are setting the data segment
; to point way up in extended memory.
set_new proc near
pusha
push es
push ds
; since we have already gone through all the work of
; setting up a whole table, the "new_Reg_Buf" table,
; we can just mung the new table...
; *** we will set DS to point where user wants to see,
; possibly way above 1 MB ***
; this combines with the setting of newDSDC
mov ax,Target
mov newDS,ax
; set up the Data Segment Descriptor Cache
mov ax,TargLo ; the low 2 bytes
mov word ptr newDSDC,ax
mov ax,TargHi ; the highest byte
mov byte ptr newDSDC + 2,al
pop ds
pop es
popa
ret
set_new endp
; -----------------------------------------------
; this routine first saves the block of low-memory data
; at 80:0, and then invokes a loadall, to warp
; the machine to its new state.
do_1_lda proc near
call save_80 ; save area 80:0
; set the new instruction pointer to point to the routine
; which is to start after the loadall.
mov si,offset after_ldall
mov newIP,si
; now save current sp, with 1 return addr on stack
mov newSP,sp
; set ds:si to point to the new loadall register table
; ds should be okay without changes
mov si,offset new_Reg_Buf
jmp do_loadall
do_1_lda endp
; ---------------------------------------------------
; this is the code that starts executing after doing
; the first loadall.
; The Data Segment is now way out there, by the way.
after_ldall proc near
; Let's go peek at the ram disk through the back door...
; get a block of data down from extended memory
call get_hi_data
; now go un-do everything.
; This jump to the following code may seem superfluous,
; but it does two things:
;
; 1. tests that CS is set correctly. If we have a bad newCS
; setting, but a good newCSDC setting, and a good newIP
; setting, we will still get here, but will die when
; the first jump occurs.
;
; 2. allows moving subroutines around in later versions
; of this code.
jmp unldall
after_ldall endp
; ---------------------------------------------------------------
; This is the code that restores the original
; state of the machine.
unldall proc near
; GET THIS!
; This is tricky: if we were going to copy another
; loadall table down to low memory, to do a 2nd loadall
; to restore the original state of the machine,
; we would need to set DS to point to
; the segment containing the old loadall table of original
; values, to copy it down to low ram, for the next loadall,
; to restore the machine state back to normal.
; That is, copy a block of data from DS:SI to ES:DI.
;
; But we can't, because DS currently points to outer
; space: way above 1 MB (like to 2 or 3 MB), so there
; is NO way that DS can point to the loadall table.
; So we can't copy the table down to low ram,
; to get home again.
;
; But there is a work-around: and it's so simple, it's
; unfortunate: any time we change a segment in our
; currently warped state, we loose the highest 4 address
; bits in the corresponding Descriptor Cache.
; Since the current ES is the same as the old DS,
; we just do this:
mov ax,ES
mov DS,ax
; NOW we can get at our original data segment.
; But wait a minute: if that is all there is
; to getting DS back to normal space, and we just got
; DS back to normal, why do we have to do another
; loadall to get DS back to normal?
; We don't. And we won't. We're already there.
; just restore the block of DOS data to 80:0
call restor_80
; and re-enable interrupts
sti
; and we're back from OZ.
; now return, using the return address that has been left
; sitting on the stack all this while...
; We go back to main, after the call to lda_1
ret
unldall endp
; --------------------------------------------------
; copy a block of data from extended memory to local buff.
; ES has already been set up with the local data segment.
; DS is in outer space.
get_hi_data proc near
pusha
mov di,offset testbuff ; point to destination buffer
xor si,si ; start reading at block start
; from ds:si to es:di
; ds is way out there, si is zero
; es:di is local buff
mov cx,BUFFSIZE ; set size of area
rep movsw
popa
ret
get_hi_data endp
; ---------------------------------------------------------------
; show data
showdata proc near
pusha
; we must push these vars on the stack like this:
; the display routine was written in C.
push TargHi ; addr the data came from, hi part
push TargLo ; same, low part
push offset testbuff ; where the data is now.
call ha_displa ; do screen display
add sp,6 ; clean up stack
popa
ret
showdata endp
even
; ----------------------------------------------------
; ----------------------------------------------------
.data
; buffer for yanking down stuff from extended
; memory (or where-ever), and seeing what you got.
testbuff dw BUFFSIZE dup (0)
; ****************************************************
; temporary start-up and exit stack,
; to keep everybody else happy
.stack 16
end main
; ***************** end of file *******************