home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / cpu / vu_xm1c / view-xm.asm < prev    next >
Assembly Source File  |  1990-05-01  |  9KB  |  358 lines

  1.  
  2.     ;  file = view-xm.asm
  3.     ;  View eXtended memory (or low memory),
  4.     ;  while in REAL mode, using the 80286 Loadall instruction.
  5.     ;
  6.     ;  written by Terrance Hodgins, 1990
  7.  
  8.     page    60,132
  9.     title    View Xmem using LOADALL
  10.  
  11.     ;  copyright (C) 1990 by Terrance E. Hodgins,
  12.     ;  dba Semi-Intelligent Systems (r).  All rights reserved.
  13.     ;
  14.     ;  Semi-Intelligent Systems is a registered trademark of
  15.     ;  Terrance E. Hodgins.
  16.  
  17.  
  18.     ;  Disclaimer of Warranty
  19.     ;
  20.     ;  TERRANCE E. HODGINS, AND SEMI-INTELLIGENT
  21.     ;  SYSTEMS, EXCLUDE ANY AND ALL IMPLIED WARRANTIES,
  22.     ;  INCLUDING WARRANTIES OF MERCHANTABILITY AND
  23.     ;  FITNESS FOR A PARTICULAR PURPOSE.
  24.     ;
  25.     ;  NEITHER TERRANCE E. HODGINS, NOR SEMI-INTELLIGENT
  26.     ;  SYSTEMS, MAKE ANY WARRANTY OF REPRESENTATION,
  27.     ;  EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS
  28.     ;  PROGRAM, ITS QUALITY, PERFORMANCE,
  29.     ;  MERCHANTABILITY, OR FITNESS FOR A PARTICULAR
  30.     ;  PURPOSE.
  31.     ;
  32.     ;  NEITHER TERRANCE E. HODGINS, NOR SEMI-INTELLIGENT
  33.     ;  SYSTEMS, SHALL HAVE ANY LIABILITY FOR SPECIAL,
  34.     ;  INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  35.     ;  OF OR RESULTING FROM THE USE OR MODIFICATION OF
  36.     ;  THIS PROGRAM.
  37.     ;
  38.     ;  THE USE OF THE 80286 LOADALL INSTRUCTION IS
  39.     ;  INHERENTLY DANGEROUS, AND CAN RESULT IN PROGRAM
  40.     ;  CRASHES, OR RUN-AWAY PROGRAMS, WHICH CAN ALTER,
  41.     ;  DAMAGE, OR DESTROY COMPUTER DATA, AND WHICH CAN
  42.     ;  DAMAGE OR DESTROY COMPUTER HARDWARE.
  43.     ;  USE ONLY AT YOUR OWN RISK.
  44.  
  45.  
  46.     .model    small,c
  47.     .286p
  48.  
  49.  
  50. include        save2new.inc
  51.  
  52.  
  53. ; size of buffer to fill with XM data, each time we copy a block
  54. ; down from upstairs.
  55. BUFFSIZE    equ    100h        ; 256 bytes
  56.  
  57.  
  58.  
  59.     extrn    a20_on:near
  60.     extrn    a20_off:near
  61.  
  62.     extrn    do_loadall:near
  63.  
  64.     extrn    prnt_chr:near
  65.     extrn    prnt_hex:near
  66.  
  67.     extrn    prnts:near
  68.  
  69.     extrn    ha_displa:near
  70.     extrn    start_prog:near
  71.     extrn    fini_prog:near
  72.  
  73.     extrn    save_80:near
  74.     extrn    restor_80:near
  75.  
  76.     extrn    kget_xmaddr:near
  77.     
  78.     extrn    exitflag:byte
  79.     extrn    Target:word
  80.     extrn    TargLo:word
  81.     extrn    TargHi:word
  82.  
  83.     .code
  84.  
  85. main    proc
  86.  
  87.     ; start up program: set up segments (DS=ES=SS), relocate stack,
  88.     ; print header info.
  89.     call    start_prog
  90.  
  91.     ; save the current machine state in a "new" loadall table,
  92.     call    save2new
  93.  
  94. mainloop:
  95.  
  96.     ; get address to peek at, from keyboard.
  97.     call    kget_xmaddr
  98.  
  99.     ; see if user wants to exit.
  100.     test    byte ptr exitflag,0FFh
  101.     jne    getout
  102.  
  103.     call    set_new        ; set up addresses in "new" loadall table
  104.  
  105.     call    a20_on        ; enable gate A20
  106.  
  107.     call    do_1_lda    ; go do a loadall
  108.  
  109.     ; we don't come back here until after a loadall has
  110.     ; been done, and we have jumped all over the place.
  111.  
  112.     call    a20_off        ; disable gate A20
  113.  
  114.     ; now look at the data we got
  115.     call    showdata
  116.  
  117.     jmp    short    mainloop    ; loop back for more
  118.  
  119. getout:
  120.  
  121.     call    fini_prog    ; finish up for exit
  122.  
  123.     mov    ax,4C00h
  124.     int    21h        ; DOS call to exit
  125.  
  126. main    endp
  127.  
  128.  
  129. ;    ----------------------------------------------
  130. ;    ----------------------------------------------
  131.  
  132.  
  133.     ; set up the table of values to be loaded into the registers
  134.     ; by the first loadall.  IE: new machine state.
  135.     ; This is the routine that you mung to get to wierd
  136.     ; and wonderful new machine states.
  137.     ;
  138.     ; Currently, in this demo, we are setting the data segment
  139.     ; to point way up in extended memory.
  140.  
  141. set_new    proc    near
  142.     pusha
  143.     push    es
  144.     push    ds
  145.  
  146.     ; since we have already gone through all the work of
  147.     ; setting up a whole table, the "new_Reg_Buf" table,
  148.     ; we can just mung the new table...
  149.  
  150.     ; *** we will set DS to point where user wants to see,
  151.     ; possibly way above 1 MB ***
  152.     ; this combines with the setting of newDSDC
  153.     mov    ax,Target
  154.     mov    newDS,ax
  155.  
  156.     ; set up the Data Segment Descriptor Cache
  157.     mov    ax,TargLo            ; the low 2 bytes
  158.     mov    word ptr newDSDC,ax
  159.     mov    ax,TargHi            ; the highest byte
  160.     mov    byte ptr newDSDC + 2,al
  161.  
  162.     pop    ds
  163.     pop    es
  164.     popa
  165.     ret
  166. set_new    endp
  167.  
  168.  
  169. ;    -----------------------------------------------
  170.  
  171.  
  172.     ; this routine first saves the block of low-memory data
  173.     ; at 80:0, and then invokes a loadall, to warp
  174.     ; the machine to its new state.
  175.  
  176. do_1_lda    proc    near
  177.  
  178.     call    save_80        ; save area 80:0
  179.  
  180.     ; set the new instruction pointer to point to the routine
  181.     ; which is to start after the loadall.
  182.     mov    si,offset after_ldall
  183.     mov    newIP,si
  184.  
  185.     ; now save current sp, with 1 return addr on stack
  186.     mov    newSP,sp
  187.  
  188.     ; set ds:si to point to the new loadall register table
  189.     ; ds should be okay without changes
  190.     mov    si,offset new_Reg_Buf
  191.  
  192.     jmp    do_loadall
  193.  
  194. do_1_lda    endp
  195.  
  196.  
  197. ;    ---------------------------------------------------
  198.  
  199.  
  200.     ;  this is the code that starts executing after doing
  201.     ;  the first loadall.
  202.  
  203.     ;  The Data Segment is now way out there, by the way.
  204.  
  205. after_ldall    proc    near
  206.  
  207.     ; Let's go peek at the ram disk through the back door...
  208.     ; get a block of data down from extended memory
  209.     call    get_hi_data
  210.  
  211.     ; now go un-do everything.
  212.     ; This jump to the following code may seem superfluous,
  213.     ; but it does two things:
  214.     ;
  215.     ; 1. tests that CS is set correctly.  If we have a bad newCS
  216.     ; setting, but a good newCSDC setting, and a good newIP
  217.     ; setting, we will still get here, but will die when
  218.     ; the first jump occurs.
  219.     ;
  220.     ; 2. allows moving subroutines around in later versions
  221.     ; of this code.
  222.  
  223.     jmp    unldall
  224.  
  225. after_ldall    endp
  226.  
  227.  
  228. ;    ---------------------------------------------------------------
  229.  
  230.  
  231.     ; This is the code that restores the original
  232.     ; state of the machine.
  233.  
  234. unldall        proc    near
  235.  
  236.  
  237.     ; GET THIS!
  238.     ; This is tricky: if we were going to copy another
  239.     ; loadall table down to low memory, to do a 2nd loadall
  240.     ; to restore the original state of the machine,
  241.     ; we would need to set DS to point to
  242.     ; the segment containing the old loadall table of original
  243.     ; values, to copy it down to low ram, for the next loadall,
  244.     ; to restore the machine state back to normal.
  245.     ; That is, copy a block of data from DS:SI to ES:DI.
  246.     ;
  247.     ; But we can't, because DS currently points to outer
  248.     ; space: way above 1 MB (like to 2 or 3 MB), so there
  249.     ; is NO way that DS can point to the loadall table.
  250.     ; So we can't copy the table down to low ram,
  251.     ; to get home again.
  252.     ;
  253.     ; But there is a work-around:  and it's so simple, it's
  254.     ; unfortunate:  any time we change a segment in our
  255.     ; currently warped state, we loose the highest 4 address
  256.     ; bits in the corresponding Descriptor Cache.
  257.  
  258.     ; Since the current ES is the same as the old DS,
  259.     ; we just do this:
  260.  
  261.     mov    ax,ES
  262.     mov    DS,ax
  263.  
  264.     ; NOW we can get at our original data segment.
  265.  
  266.     ; But wait a minute: if that is all there is
  267.     ; to getting DS back to normal space, and we just got
  268.     ; DS back to normal, why do we have to do another
  269.     ; loadall to get DS back to normal?
  270.  
  271.     ; We don't.  And we won't.  We're already there.
  272.  
  273.     ; just restore the block of DOS data to 80:0
  274.     call    restor_80
  275.  
  276.     ; and re-enable interrupts
  277.     sti
  278.  
  279.     ; and we're back from OZ.
  280.  
  281.     ; now return, using the return address that has been left
  282.     ; sitting on the stack all this while...
  283.     ; We go back to main, after the call to lda_1
  284.  
  285.     ret
  286.  
  287. unldall        endp
  288.  
  289. ;    --------------------------------------------------
  290.  
  291.  
  292.     ; copy a block of data from extended memory to local buff.
  293.     ; ES has already been set up with the local data segment.
  294.     ; DS is in outer space.
  295.  
  296. get_hi_data    proc    near
  297.     pusha
  298.  
  299.     mov    di,offset testbuff    ; point to destination buffer
  300.     xor    si,si            ; start reading at block start
  301.  
  302.     ; from ds:si to es:di
  303.     ; ds is way out there, si is zero
  304.     ; es:di is local buff
  305.  
  306.     mov    cx,BUFFSIZE    ; set size of area
  307.     rep movsw
  308.  
  309.     popa
  310.     ret
  311. get_hi_data    endp
  312.  
  313.  
  314. ;    ---------------------------------------------------------------
  315.  
  316.  
  317.     ; show data
  318.  
  319. showdata    proc    near
  320.     pusha
  321.  
  322.     ; we must push these vars on the stack like this:
  323.     ; the display routine was written in C.
  324.  
  325.     push    TargHi            ; addr the data came from, hi part
  326.     push    TargLo            ; same, low part
  327.     push    offset testbuff        ; where the data is now.
  328.     call    ha_displa        ; do screen display
  329.     add    sp,6            ; clean up stack
  330.  
  331.     popa
  332.     ret
  333. showdata    endp
  334.  
  335.     even
  336. ;    ----------------------------------------------------
  337. ;    ----------------------------------------------------
  338.  
  339.     .data
  340.  
  341.  
  342. ; buffer for yanking down stuff from extended
  343. ; memory (or where-ever), and seeing what you got.
  344. testbuff    dw    BUFFSIZE dup (0)
  345.  
  346.  
  347.  
  348. ;    ****************************************************
  349.  
  350.     ; temporary start-up and exit stack,
  351.     ; to keep everybody else happy
  352.     .stack    16
  353.  
  354.     end    main
  355.  
  356. ;    *****************  end of file  *******************
  357.  
  358.