[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