home *** CD-ROM | disk | FTP | other *** search
-
- ; 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 *******************
-