[Coco] Re 6309 microprocessor project 01-22-2004

John Collyer johncollyer at zoominternet.net
Fri Jan 23 11:33:20 EST 2004


One of the main reasons I wanted to make the emulator 32-bits is I had lots of ideas for the emulator, but with it being in a 16-bit environment I really had no room for growth.  I envisioned the emulator with cut&paste from inside the debug facility and from inside the emulator text mode screens too.  I also wanted to improve the way the debug facility worked and I wanted lots more options, like drag&drop.  My philosophy is release no code until it works, and I try to stick to this philosophy as much as possible.

John Collyer.

The enhanced instruction opcode $11FF will as before let you run code,
but this code will be Intel 80x86 32 bit flat assembly code.

You return to the emulator after your finished with the code by specifying a 80x86 return instruction. The 80x86 code should be located right after the enhanced instruction opcode $11FF in memory.  All this can be accomplished because win32 lets us allocate memory designated as read/write/execute.  If you are concerned about security you can set a switch not allowing enhanced opcodes.

You interface with enhanced instruction opcode by using opcode $11FF and register x pointing to a memory block containing your 80x86 virtual registers (Register X contains the address of the first virtual register in the memory block of your 80x86 virtual registers).

The virtual registers should be defined as follows and must be in this order in the memory block.  Use one of the 6309's assembler or compiler packages for your computer.

All values you store in the virtual 80x86 32-bit registers will be converted between little endian and big endian for you automatically by the special opcode's interface.

    v86_eax fcb 0,0,0,0         * virtual 80x86 32 bit registers
    v86_ebx fcb 0,0,0,0         * must be in this order in 8k
    v86_ecx fcb 0,0,0,0         * memory block, along with the
    v86_edx fcb 0,0,0,0         * 80x86 hand assembly 32-bit code
    v86_edi fcb 0,0,0,0         * everything must be in 8k boundary
    v86_esi fcb 0,0,0,0         *

The 80x86 code should be placed right after the opcode $11FF in your program as data.  How you get the 80x86 code into data and the correctness of that data remains the programmers problem and the enhanced instruction opcode is only a interface allowing you to execute data that contains 80x86 code.

When you finish executing the 80x86 code use a "ret" instruction to return to your program.  You must load the 80x86 register "esi" with the size of your 32-bit program code size before issuing a "RET" instruction.  You can assume that the 80x86 32-bit registers contain the values of your virtual 80x86 32-bit registers on entry into the 32-bit code.

Do not change or use the 80x86 32-bit or 16-bit registers ebp or esp, except to push and pop registers in a orderly manner.  This means you must pop what you push.  Make sure that you save the 80x86 eflags register, so you can leave it as you found it.

Take all the precautions you need to insure your 80x86 32-bit assembly language does no harm to the coco3x emulator.

  Here is a example:

  BeginEx pshs u              *
          leau v86_eax,pcr    * Point to My virtual registers
          ldy #24             * sizeof virtual register data block
          ldq #$0FFFFFFFF     * This is simulated register data
  storedata stq ,u            * Save data in virtual registers block
          leau 4,u            * Point to next virtual register in block
          leay -1,y           * count it
          bne storedata       * store all data
          leax v86_eax,pcr    * Point to My virtual registers data block
          fdb $11FF           * Call the 80x86 32-bit code below.
                              *
  * My 32-bit code            * 
                              *
          fcb $00,$00         * mov eax,0         ;simulate 32-bit code
          fcb $BE,$00,$00     *                   ;
          fcb $00,$08         * mov esi,8         ;need 32-bit code size in esi
          fcb $C3             * ret               ;on return to 16-bit 6309 code

  * We returned from 80x86 32-bit code here

          ldq v86_eax         * Get virtual register eax
          tstw                * Any return value?
          beq quit            * No,
          exg w,d             * Exchange words
          stq v86_eax         * Save it

  quit    os9 F$Exit          * Done

          end BeginEx         * done with example

  * My virtual 32-bit 80x86 registers

  v86_eax fcb 0,0,0,0         * 32 bit register
  v86_ebx fcb 0,0,0,0         * 32 bit register
  v86_ecx fcb 0,0,0,0         * 32 bit register
  v86_edx fcb 0,0,0,0         * 32 bit register
  v86_edi fcb 0,0,0,0         * 32 bit register
  v86_esi fcb 0,0,0,0         * 32 bit register

Notes:

You must keep this order for the 80x86 32-bit virtual registers and you must load the 6309's register "x" with a pointer to the data block of virtual 80x86 32-bit registers, to call the enhanced instruction opcode $11FF correctly.  The enhanced opcode $11FF saves the 80x86 32-bit registers, into your data block for the virtual 80x86 32-bit registers you defined before it returns to your 6309 program code.  This interface to Intel 80x86 32-bit assembly language is very limited, and extreme caution should be used when using this interface.  You will only have ring 3 instructions available, so any runtime or protection errors which occur will most likely crash the coco3x emulator, and maybe crash Windows 9x/Me/NT/XP.

The obvious reason for this interface is to allow you to manipulate registers, pointers, and win32 data with the native 80x86 32-bit code.  This could make using the win32 file functions more easily to control, but this could also be a direct interface into actual doing anything you'd like to inside of Windows 9x/Me/NT/XP, but typically only as a ring 3 application could actually do.


The special opcode $11FF's source code:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                        ;
yff:    cmp word ptr native,564ah       ;if navtive instructions
        jnz yff_off                     ;else bad instruction
        test secur,-1                   ;if security = on
        jz yff_off                      ;
        push ebx                        ;save registers
        push ecx                        ;
        push edx                        ;
        push edi                        ;
        push ebp                        ;
        push esi                        ;
        mov eax,offset yff_return       ;get return address
        push eax                        ;push it
        getptr                          ;find jump to code
        push eax                        ;push it
        mov si,regx                     ;get parameters
        getptr                          ;make 32-bits
        mov dd_aux1,eax                 ;save it for later
        mov ebx,[eax+4]                 ;load real register
        bswap ebx                       ;make little endian
        mov ecx,[eax+8]                 ;load real register
        bswap ecx                       ;make little endian
        mov edx,[eax+12]                ;load real register
        bswap edx                       ;make little endian
        mov edi,[eax+16]                ;load real register
        bswap edi                       ;make little endian
        mov esi,[eax+20]                ;load real register
        bswap esi                       ;make little endian
        mov eax,[eax]                   ;load real register
        bswap eax                       ;make little endian
        ret                             ;jump to 32-bit code
                                        ;
yff_return:                             ;return from 32-bit code
        push esi                        ;push 32-bit code size
        push eax                        ;push register
        mov eax,dd_aux1                 ;get parameter pointer
        bswap ebx                       ;make big endian
        mov [eax+4],ebx                 ;save parameter
        bswap ecx                       ;make big endian
        mov [eax+8],ecx                 ;save parameter
        bswap edx                       ;make big endian
        mov [eax+12],edx                ;save parameter
        bswap edi                       ;make big endian
        mov [eax+16],edi                ;save parameter
        bswap esi                       ;make big endian
        mov [eax+20],esi                ;save parameter
        mov esi,eax                     ;copy parameter pointer
        pop eax                         ;restore register
        bswap eax                       ;make big endian
        mov [esi],eax                   ;save parameter
        pop eax                         ;pop 32-bit code size
        pop esi                         ;pop program counter
        add esi,eax                     ;add 32-bit code size to program counter
        and esi,0ffffh                  ;make program counter 16-bits
        pop ebp                         ;restore registers
        pop edi                         ;
        pop edx                         ;
        pop ecx                         ;
        pop ebx                         ;
        jmp main                        ;return
yff_off:                                ;else bad instruction,
        jmp bad                         ;jump to bad instruction label
                                        ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://five.pairlist.net/pipermail/coco/attachments/20040123/e62a113a/attachment-0001.html>


More information about the Coco mailing list