home *** CD-ROM | disk | FTP | other *** search
- ; PMODE v2.4 shell for PMODE v3.0
- ; By Tran (a.k.a. Thomas Pytel).
-
- .386p
-
- LOWMIN = 0 ; minimum free low memory (in K)
- EXTMIN = 0 ; minimum free extended memory (in K)
- SELECTORS = 8 ; extra selectors for allocation
- STAKMAIN = 100h ; main execution stream stack size (in para)
- STAKRMODE = 10h ; real mode call stack size (in para)
- STAKPMODE = 20h ; protected mode call stack size (in para)
- MODENESTING = 8 ; max number of nested mode switches
-
- RMODENUM = (MODENESTING+1) shr 1
- PMODENUM = MODENESTING shr 1
- STAKSIZE = STAKMAIN+(PMODENUM*STAKPMODE)+(RMODENUM*STAKRMODE)
-
- .errnz STAKSIZE gt 0fffh ; error if stack greater than 64k
-
- PMODE_TEXT segment para public use16 'CODE'
- PMODE_TEXT ends
- code16 segment para public use16
- code16 ends
- code32 segment para public use32
- code32 ends
- codeend segment para stack use32 'stack'
- codeend ends
-
- extrn _pm_info:far, _pm_init:far
- extrn _pm_pagetables:byte, _pm_selectors:word, _pm_rmstacklen:word
- extrn _pm_pmstacklen:word, _pm_rmstacks:byte, _pm_pmstacks:byte
- extrn _pm_callbacks:byte
-
- ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ; Real mode and 16bit code
- ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- code16 segment para public use16
- assume cs:code16, ds:code16
- org 0
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 16 bit common system data
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- exiterrmsgtbl dw errmsg0,errmsg2,d_errmsg0,errmsg4,d_errmsg3,d_errmsg1
-
- errmsg0 db '386 or better not detected!!!',7,'$'
- errmsg1 db 'Not enough low memory!!!',7,'$'
- errmsg2 db 'System is already in V86 mode, and no VCPI or DPMI found!!!',7,'$'
- errmsg3 db 'Not enough extended memory!!!',7,'$'
- errmsg4 db 'Couldn''t enable A20 gate!!!',7,'$'
- errmsg5 db 'Extended memory allocation failure. (weird eh???)',7,'$'
-
- nullint db 0cfh ; IRET instruction
- exitrout dw exit ; exit routine, modified if XMS, VCPI
- pmbuflen dw ? ; length of PMODE low buffer
-
- savedstakoff dw ? ; current saved stack offset
- savedstakseg dw ? ; current saved stack segment
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 16 bit common system code
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ;═════════════════════════════════════════════════════════════════════════════
- intreal: ; real mode int, load FS and GS here
- pushf
- ;-----------------------------------------------------------------------------
- callreal: ; real mode call, load FS and GS here
- push cs
- push offset icreald
- mov fs,cs:v86r_fs
- mov gs,cs:v86r_gs
- mov eax,cs:v86r_eax
- mov ecx,cs:v86r_ecx
- mov edx,cs:v86r_edx
- mov ebx,cs:v86r_ebx
- mov esi,cs:v86r_esi
- mov edi,cs:v86r_edi
- mov ebp,cs:v86r_ebp
- ;-----------------------------------------------------------------------------
- icreal: ; real mode int, call, or IRQ
- db 66h,68h ; PUSH destination addx
- icrealm1 dd ? ;
- icrealm0 db ? ; CLI or STI
- retf
- ;-----------------------------------------------------------------------------
- icreald: ; done with real int or call
- cli
- pushf
- pop cs:v86r_flags
- mov cs:v86r_eax,eax
- mov cs:v86r_ecx,ecx
- mov cs:v86r_edx,edx
- mov cs:v86r_ebx,ebx
- mov cs:v86r_esi,esi
- mov cs:v86r_edi,edi
- mov cs:v86r_ebp,ebp
- mov cs:v86r_ds,ds
- mov cs:v86r_es,es
- mov cs:v86r_fs,fs
- mov cs:v86r_gs,gs
- icreald2:
- mov ax,cs
- mov ds,ax
- icrealm2 label word ; return to pmode modifiable to JMP
- ;-----------------------------------------------------------------------------
- mov ebx,ds:dp_savedstakoff ; DPMI return to pmode
- mov dx,ds:dp_savedstaksel
- mov edi,offset dp_int3_d
- mov si,ds:_selcode
- mov cx,dx
- mov ax,ds:_seldata
- jmp ds:d_switchaddx
- ;═════════════════════════════════════════════════════════════════════════════
- int32: ; real mode INT32: EDX=off
- pushad
- push ds es fs gs
- cli
- mov ax,cs
- mov ds,ax
- mov ds:p_cpmodem0,edx
- mov al,[esp+45]
- shr al,1
- and al,1
- add al,0fah
- mov ds:p_cpmodem1,al
- push savedstakoff
- push savedstakseg
- movzx ebx,ds:nextmodestack
- lea eax,[ebx-STAKPMODE*16]
- mov ds:nextmodestack,ax
- add ebx,ds:realstackbase
- mov savedstakseg,ss
- int32m0 label word ; jump to pmode, modifiable
- ;-----------------------------------------------------------------------------
- sub sp,ds:dp_savelen
- mov savedstakoff,sp
- mov ax,ss ; DPMI jump to pmode
- mov es,ax
- mov di,sp
- xor al,al
- call d_saveaddx
- mov ax,ds:_seldata
- mov cx,ax
- mov dx,ax
- mov edi,offset p_cpmode0
- mov si,ds:_selcode
- jmp ds:d_switchaddx
- ;═════════════════════════════════════════════════════════════════════════════
- int32d0: ; DPMI done with pmode call
- mov di,sp
- mov al,1
- call d_saveaddx
- add sp,ds:dp_savelen
- ;-----------------------------------------------------------------------------
- int32d2: ; done from all
- pop savedstakseg
- pop savedstakoff
- add ds:nextmodestack,STAKPMODE*16
- mov bx,ds:v86r_flags
- mov ax,[esp+44]
- and ax,not 8d5h
- and bx,8d5h
- or ax,bx
- mov [esp+44],ax
- pop gs fs es ds
- popad
- iret
- ;─────────────────────────────────────────────────────────────────────────────
- pregetlomem: ; Get low memory or abort
- add eax,ds:_lomembase
- mov ebx,ds:_lomemtop
- cmp eax,ebx
- ja short pregetlomema
- mov ecx,eax
- xchg eax,ds:_lomembase
- sub ebx,ecx
- cmp ebx,LOWMIN*1024
- jb short pregetlomema
- ret
- pregetlomema:
- mov dx,offset errmsg1
- ;─────────────────────────────────────────────────────────────────────────────
- exit16err: ; Exit program with message
- mov ah,9
- int 21h
- jmp exitrout
- ;-----------------------------------------------------------------------------
- exit: ; Guess what???
- mov ah,4ch
- mov al,ds:_exitcode
- int 21h
- ;═════════════════════════════════════════════════════════════════════════════
- start16: ; Program begins here
- cli
- cld
- push cs
- pop ds
-
- push es ; set up PMODE variables
- mov ax,PMODE_TEXT
- mov es,ax
- mov es:_pm_pagetables,(EXTMIN/4096)+1
- mov es:_pm_selectors,3+SELECTORS
- mov es:_pm_rmstacklen,STAKRMODE
- mov es:_pm_rmstacks,MODENESTING/2
- xor eax,eax
- mov es:_pm_pmstacklen,ax
- mov es:_pm_pmstacks,al
- mov es:_pm_callbacks,al
- pop es
-
- call _pm_info ; get protected mode info
- mov si,ax
- mov dx,exiterrmsgtbl[si]
- jc exit16err ; if error, exit with error message
-
- mov pmbuflen,bx
- or ds:_sysbyte0,ch ; set system type byte
-
- mov ax,es ; set up a bunch of pointers
- movzx eax,ax
- shl eax,4
- mov ds:_pspa,eax
- mov eax,code16
- shl eax,4
- mov ds:_code16a,eax
- or dword ptr ds:gdt32code16[2],eax
- or dword ptr ds:gdt32data16[2],eax
- mov ebx,code32
- shl ebx,4
- mov ds:_code32a,ebx
- or dword ptr ds:gdt32code32[2],ebx
- or dword ptr ds:gdt32data32[2],ebx
- mov eax,codeend
- shl eax,4
- sub eax,ebx
- mov ds:_lomembase,eax
- mov ds:realstackbase,eax
- movzx eax,word ptr es:[2]
- shl eax,4
- sub eax,ebx
- mov ds:_lomemtop,eax
-
- mov eax,STAKSIZE*16 ; get stack memory
- call pregetlomem
-
- push es ; save PSP seg (DPMI chek kills ES)
- pop fs
-
- jmp d_start
-
- ;─────────────────────────────────────────────────────────────────────────────
- ; BL=low PIC val, BH=high PIC val
- setintslots: ; set int nums in table to PIC vals
- mov edi,offset ds:intslottbl
- mov cl,8
- setintslotsl0:
- mov [di],bl
- inc di
- inc bl
- dec cl
- jnz setintslotsl0
- mov cl,8
- setintslotsl1:
- mov [di],bh
- inc di
- inc bh
- dec cl
- jnz setintslotsl1
- ret
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 16 bit DPMI system data
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- d_errmsg0 db 'DPMI host is not 32bit!!!',7,'$'
- d_errmsg1 db 'Ran out of DPMI descriptors!!!',7,'$'
- d_errmsg2 db 'Couldn''t set DPMI descriptors as needed!!!',7,'$'
- d_errmsg3 db 'Couldn''t enter 32bit protected mode!!!',7,'$'
-
- d_memhandlep db 0 ; 1=memory handle present, 0=not
-
- d_enterpmode dw ?,? ; DPMI switch to pmode addx
- d_pspsel dw ? ; stupid PSP selector
- d_oldenvsegsel dw ? ; stupid selector we dont want
-
- d_memhandle dw ?,? ; DPMI memory block handle
-
- d_switchaddx dd ? ; switch to pmode addx
- d_saveaddx dd ? ; save/restore state addx
-
- d_nintoff dd offset dp_irq0,offset dp_irq1,offset dp_irq2,offset dp_irq3
- dd offset dp_irq4,offset dp_irq5,offset dp_irq6,offset dp_irq7
- dd offset dp_irq8,offset dp_irq9,offset dp_irqa,offset dp_irqb
- dd offset dp_irqc,offset dp_irqd,offset dp_irqe,offset dp_irqf
- dd offset dp_int33,offset dp_int32,offset dp_int33,offset dp_int32
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 16 bit DPMI system code
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ;═════════════════════════════════════════════════════════════════════════════
- d_retreal: ; Return to real mode
- cmp d_memhandlep,0 ; free memory block if present
- je short d_retrealf0
- mov di,d_memhandle[0]
- mov si,d_memhandle[2]
- mov ax,502h
- int 31h
- d_retrealf0:
- mov ax,205h ; restore all int vektorz needed
- mov edi,19
- d_retreall0:
- mov bl,ds:intslottbl[edi]
- lea ebp,[edi*2+edi]
- mov edx,dword ptr ds:dp_ointbuf[ebp*2]
- mov cx,word ptr ds:dp_ointbuf[ebp*2+4]
- int 31h
- sub di,1
- jnc d_retreall0
- jmp short d_exit
- ;─────────────────────────────────────────────────────────────────────────────
- d_exit16err: ; DPMI Exit with error message
- mov ds:v86r_ds,code16
- mov ds:v86r_ah,9
- mov ax,300h
- mov bx,21h
- xor cx,cx
- mov edi,offset ds:v86r_edi
- push ds
- pop es
- int 31h
- ;─────────────────────────────────────────────────────────────────────────────
- d_exit: ; DPMI exit to real mode
- mov es,d_pspsel ; restore env selector
- mov ax,d_oldenvsegsel
- mov es:[2ch],ax
- jmp exit
- ;═════════════════════════════════════════════════════════════════════════════
- d_start: ; Start in a crappy DPMI system
- movzx eax,pmbuflen ; get mem for DPMI low memory block
- shl eax,4
- call pregetlomem
- shr eax,4
- add ax,code32
- mov es,ax
-
- call _pm_init ; switch to protected mode
-
- cli ; I don't trust myself
- mov dx,offset d_errmsg3
- jc exit16err
- mov ds:v86r_dx,offset d_errmsg1 ; prepare for abort maybe
- pop ax ; swap old env seg with selector
- xchg ax,es:[2ch]
- mov d_oldenvsegsel,ax
- mov d_pspsel,es ; store stupid selectors
- mov ds:data16sel,ds
- mov ds:code16sel,cs
-
- push ds ; no more need for PSP
- pop es
- mov ax,3 ; get selector increment value
- int 31h
- mov bx,ax
- xor ax,ax ; get needed selectors
- mov cx,3+SELECTORS
- int 31h
- jc d_exit16err
-
- mov si,ax ; set up descriptors
- mov ds:_selcode,ax
- lea ecx,[eax+ebx]
- mov ds:_seldata,cx
- lea ebp,[ecx+ebx]
- mov ds:_selzero,bp
- lea eax,[ebp+ebx]
- if SELECTORS ne 0
- mov ds:selectorbase,ax
- mov ds:selectorinc,bx
- endif
- mov ds:v86r_dx,offset d_errmsg2
-
- mov ax,cs ; set DPL fields of descriptors
- lar ax,ax
- and ah,60h
- or byte ptr ds:gdt32code32[5],ah
- or byte ptr ds:gdt32data32[5],ah
- or byte ptr ds:gdt32zero32[5],ah
-
- mov ax,0ch ; set descriptors from GDT
- mov bx,si
- mov edi,offset ds:gdt32code32
- int 31h
- jc d_exit16err
- mov bx,cx
- mov edi,offset ds:gdt32data32
- int 31h
- jc d_exit16err
- mov bx,bp
- mov edi,offset ds:gdt32zero32
- int 31h
- jc d_exit16err
- if SELECTORS ne 0
- mov bx,ds:selectorbase ; set up extra allocatable selectors
- mov dx,SELECTORS
- d_startl1:
- int 31h
- jc d_exit16err
- add bx,ds:selectorinc
- dec dx
- jnz d_startl1
- endif
- mov es,cx ; ES, FS, and GS what they should be
- mov fs,cx
- mov gs,bp
-
- mov edi,ds:_lomembase ; chek and get extended memory
- mov eax,ds:_lomemtop
- sub eax,edi
- cmp eax,48
- mov ds:v86r_dx,offset errmsg1
- jb d_exit16err
- mov ax,500h
- int 31h
- mov eax,es:[edi]
- lea edx,[eax+1024]
- mov ds:v86r_dx,offset errmsg3
- d_startl2:
- sub edx,1024
- jnc short d_startf2
- xor edx,edx
- d_startf2:
- cmp edx,EXTMIN*1024
- jb d_exit16err
- or edx,edx
- jz short d_startf1
- mov cx,dx
- shld ebx,edx,16
- mov ax,501h
- int 31h
- jc d_startl2
- mov ds:d_memhandle[0],di
- mov ds:d_memhandle[2],si
- mov ds:d_memhandlep,1
-
- shl ebx,16
- mov bx,cx
- sub ebx,ds:_code32a
- mov ds:_himembase,ebx
- add ebx,edx
- mov ds:_himemtop,ebx
- d_startf1:
-
- mov ax,305h ; get save/restore state addxs
- int 31h
- mov ds:dp_savelen,ax
- mov dword ptr ds:dp_saveaddx[0],edi
- mov word ptr ds:dp_saveaddx[4],si
- mov word ptr d_saveaddx[0],cx
- mov word ptr d_saveaddx[2],bx
- mov ax,306h ; get switch mode addxs
- int 31h
- mov dword ptr ds:dp_switchaddx[0],edi
- mov word ptr ds:dp_switchaddx[4],si
- mov word ptr d_switchaddx[0],cx
- mov word ptr d_switchaddx[2],bx
-
- mov ax,400h ; set IRQ handlers to PIC values
- int 31h
- xchg dl,dh
- mov bx,dx
- call setintslots
-
- mov ah,2 ; backup and set all int vektorz
- mov si,ds:_selcode
- mov edi,19
- d_startl0:
- mov bl,ds:intslottbl[edi]
- mov al,4
- int 31h
- lea ebp,[edi*2+edi]
- mov dword ptr ds:dp_ointbuf[ebp*2],edx
- mov word ptr ds:dp_ointbuf[ebp*2+4],cx
- mov al,5
- mov edx,d_nintoff[edi*4]
- mov cx,si
- int 31h
- sub di,1
- jnc d_startl0
-
- mov ax,es ; set up needed regs & go on to 32bit
- mov ss,ax
- add esp,ds:realstackbase
- mov ds,ax
- push dword ptr cs:_selcode
- push offset p_start
- db 66h,0cbh ; 32bit RETF
-
- code16 ends
-
- ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ; 32bit pmode code
- ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- code32 segment para public use32
- assume cs:code32, ds:code32
- org 0
-
- extrn _main:near
-
- public _exit, _ret, _getmem, _getlomem, _gethimem, _lomemsize, _himemsize
- public _getirqmask, _setirqmask, _getselector, _freeselector, _rmpmirqset
- public _rmpmirqfree
-
- public v86r_eax, v86r_ebx, v86r_ecx, v86r_edx, v86r_esi, v86r_edi, v86r_ebp
- public v86r_ax, v86r_bx, v86r_cx, v86r_dx, v86r_si, v86r_di, v86r_bp
- public v86r_al, v86r_ah, v86r_bl, v86r_bh, v86r_cl, v86r_ch, v86r_dl, v86r_dh
- public v86r_ds, v86r_es, v86r_fs, v86r_gs
- public _selcode, _seldata, _selzero, _lomembase, _lomemtop, _himembase
- public _himemtop, _pspa, _code16a, _code32a, _getirqvect, _setirqvect
- public _sysbyte0, _irqmode, _setselector, _exitcode
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 32 bit common system data
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- _lomembase dd ? ; low mem base for allocation
- _lomemtop dd ? ; top of low mem
- _himembase dd 0 ; high mem base for allocation
- _himemtop dd 0 ; top of high mem
- _pspa dd ? ; offset of start of PSP from 0
- _code16a dd ? ; offset of start of 16bit code from 0
- _code32a dd ? ; offset of start of 32bit code from 0
- _selcode dw 8 ; code segment selector
- _seldata dw 10h ; data segment alias for code
- _selzero dw 18h ; data segment starting at 0:0
- _irqmode dw 0ffffh ; IRQ mode bits: 0=normal, 1=safe
- db 0ffh ; misc byte, has to follow _irqmode
- _sysbyte0 db 0 ; system bits:
- ; 0-1: 0=raw, 1=XMS, 2=VCPI, 3=DPMI
- _exitcode db 0 ; exit code for int21h ah=4ch
-
- align 4
- _getirqvect dd dp_getirqvect ; get IRQ handler offset routine addx
- _setirqvect dd dp_setirqvect ; set IRQ handler offset routine addx
- _setselector dd dp_setselector ; set a selector addx offset addx
-
- gdt32 dq 0
- gdt32code32 db 0ffh,0ffh,0,0,0,9ah,0cfh,0
- gdt32data32 db 0ffh,0ffh,0,0,0,92h,0cfh,0
- gdt32zero32 db 0ffh,0ffh,0,0,0,92h,0cfh,0
- gdt32code16 db 0ffh,0ffh,0,0,0,9ah,0,0
- gdt32data16 db 0ffh,0ffh,0,0,0,92h,0,0
- gdt32task db 0ffh,0ffh,0,0,0,89h,0,0
- gdt32vcpi dq 3 dup(?)
- if SELECTORS ne 0
- gdt32free db SELECTORS dup(0ffh,0ffh,0,0,0,92h,0cfh,0)
- endif
-
- v86r_edi label dword ; vregs for pmode<>real communication
- v86r_di dw ?, ? ; needz to stay this way cuz its a
- v86r_esi label dword ; stupid DPMI structure thingy
- v86r_si dw ?, ?
- v86r_ebp label dword
- v86r_bp dw ?, ?
- dd 0
- v86r_ebx label dword
- v86r_bx label word
- v86r_bl db ?
- v86r_bh db ?, ?,?
- v86r_edx label dword
- v86r_dx label word
- v86r_dl db ?
- v86r_dh db ?, ?,?
- v86r_ecx label dword
- v86r_cx label word
- v86r_cl db ?
- v86r_ch db ?, ?,?
- v86r_eax label dword
- v86r_ax label word
- v86r_al db ?
- v86r_ah db ?, ?,?
- v86r_flags dw ?
- v86r_es dw ?
- v86r_ds dw ?
- v86r_fs dw ?
- v86r_gs dw ?
- dd 0,0
-
- oint1bvect dd ? ; old real int 1bh vektor (ctrl+break)
- oint32vect dd ? ; old real int 32h vector
- oirqmask dw ? ; old port 21h and 0a1h masks
- intslottbl db 8,9,0ah,0bh,0ch,0dh,0eh,0fh,70h,71h,72h,73h,74h,75h,76h,77h
- db 35h,34h,33h,32h,31h,0,1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh
-
- if SELECTORS ne 0
- selectorbase dw 50h
- selectorinc dw 8
- selectorfree db SELECTORS dup(0)
- endif
-
- code16off dw d_retreal ; offset in 16bit of exit function
- code16sel dw 20h ; 16bit pmode code selector
- data16sel dw 28h ; 16bit pmode data selector
-
- nextmodestack dw (STAKSIZE-STAKMAIN)*16 ; stack for next mode switch
- realstackbase dd ? ; linear ptr to beginning of codeend
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 32 bit common system code
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ;═════════════════════════════════════════════════════════════════════════════
- p_cpmode0: ; call pmode, load FS and GS
- mov fs,_seldata
- mov gs,_selzero
- ;-----------------------------------------------------------------------------
- p_cpmode: ; call pmode routine from real
- push offset p_cpmoded
- cld
- mov eax,v86r_eax
- mov ecx,v86r_ecx
- mov edx,v86r_edx
- mov ebx,v86r_ebx
- mov esi,v86r_esi
- mov edi,v86r_edi
- mov ebp,v86r_ebp
- db 68h ; PUSH destination address
- p_cpmodem0 dd ? ;
- p_cpmodem1 db ? ; CLI or STI
- ret
- ;-----------------------------------------------------------------------------
- p_cpmoded: ; call to pmode done
- cli
- pushf
- pop v86r_flags
- mov v86r_eax,eax
- mov v86r_ecx,ecx
- mov v86r_edx,edx
- mov v86r_ebx,ebx
- mov v86r_esi,esi
- mov v86r_edi,edi
- mov v86r_ebp,ebp
- mov ecx,_code16a
- p_cpmodem2 label word ; return to real, modifiable to JMP
- ;-----------------------------------------------------------------------------
- movzx ebx,gs:savedstakoff[ecx] ; DPMI return to real mode
- mov dx,gs:savedstakseg[ecx]
- mov ax,code16
- mov cx,dx
- mov si,ax
- mov edi,offset int32d0
- jmp dp_switchaddx
- ;═════════════════════════════════════════════════════════════════════════════
- p_start: ; common 32bit start
- mov eax,gs:[1bh*4] ; neutralize crtl+break
- mov oint1bvect,eax
- db 65h,67h,0c7h,6 ; MOV DWORD PTR GS:[1bh*4],code16:nullint
- dw 1bh*4,nullint,code16 ;
- mov eax,gs:[32h*4] ; set up for new real mode INT32
- mov oint32vect,eax
- db 65h,67h,0c7h,6 ; MOV DWORD PTR GS:[32h*4],code16:int32
- dw 32h*4,int32,code16 ;
- in al,21h ; save old PIC masks
- mov ah,al
- in al,0a1h
- mov oirqmask,ax
- jmp _main ; go to main code
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Allocate any mem, (first cheks low, then high)
- ; In:
- ; EAX - size requested
- ; Out:
- ; CF=0 - memory allocated
- ; CF=1 - not enough mem
- ; EAX - linear pointer to mem or ?
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _getmem:
- push eax
- call _getlomem
- jnc short getmemd
- pop eax
- jmp short _gethimem
- getmemd:
- add esp,4
- _ret: ; generic RET instruction
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Allocate some low mem
- ; In:
- ; EAX - size requested
- ; Out:
- ; CF=0 - memory allocated
- ; CF=1 - not enough mem
- ; EAX - linear pointer to mem or ?
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _getlomem:
- add eax,_lomembase
- cmp eax,_lomemtop
- ja short getmemerr
- xchg eax,_lomembase
- clc
- ret
- getmemerr:
- stc
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Allocate some high mem
- ; In:
- ; EAX - size requested
- ; Out:
- ; CF=0 - memory allocated
- ; CF=1 - not enough mem
- ; EAX - linear pointer to mem or ?
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gethimem:
- add eax,_himembase
- cmp eax,_himemtop
- ja short getmemerr
- xchg eax,_himembase
- clc
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Get amount of free low mem
- ; Out:
- ; EAX - number of bytes free
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _lomemsize:
- mov eax,_lomemtop
- sub eax,_lomembase
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Get amount of free high mem
- ; Out:
- ; EAX - number of bytes free
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _himemsize:
- mov eax,_himemtop
- sub eax,_himembase
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Get status of IRQ mask bit
- ; In:
- ; BL - IRQ num (0-15)
- ; Out:
- ; AL - status: 0=enabled, 1=disabled
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _getirqmask:
- push ax
- in al,0a1h
- mov ah,al
- in al,21h
- xchg cl,bl
- shr ax,cl
- xchg cl,bl
- and al,1
- mov [esp],al
- pop ax
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Set status of IRQ mask bit
- ; In:
- ; BL - IRQ num (0-15)
- ; AL - status: 0=enabled, 1=disabled
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _setirqmask:
- push ax bx cx dx
- mov cl,bl
- mov bx,0fffeh
- movzx dx,al
- rol bx,cl
- shl dx,cl
- in al,0a1h
- mov ah,al
- in al,21h
- and ax,bx
- or ax,dx
- out 21h,al
- mov al,ah
- out 0a1h,al
- pop dx cx bx ax
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Set a real mode IRQ vect to redirect to pmode
- ; In:
- ; BL - IRQ number
- ; EDX - offset of IRQ handler
- ; EDI -> 21 byte buffer for code stub created
- ; Out:
- ; EAX - old seg:off of real mode IRQ handler
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- rmpmirqsetd0:
- db 66h,52h ; PUSH EDX
- db 66h,0bah,?,?,?,? ; MOV EDX,?
- db 0cdh,32h ; INT 32h
- db 66h,5ah ; POP EDX
- db 0cfh ; IRET
- db 9ch ; PUSHFD
- db 0eh ; PUSH CS
- db 0e8h,?,?,?,? ; CALL ?
- db 0c3h ; RET
- ;-----------------------------------------------------------------------------
- _rmpmirqset:
- push esi edi
- mov esi,offset rmpmirqsetd0
- lea eax,[edi+13]
- mov [esi+4],eax
- add eax,7
- sub eax,edx
- neg eax
- mov [esi+16],eax
- mov eax,edi
- movsd
- movsd
- movsd
- movsd
- movsd
- movsb
- add eax,_code32a
- shl eax,12
- shr ax,12
- movzx edi,bl
- cmp edi,8
- jb short rmpmirqsetf0
- add edi,60h
- rmpmirqsetf0:
- xchg eax,gs:[edi*4+20h]
- pop edi esi
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Reset a real more IRQ vect back to normal (just sets real mode IRQ vect)
- ; In:
- ; BL - IRQ number
- ; EAX - seg:off of real mode IRQ handler
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _rmpmirqfree:
- push ebx
- movzx ebx,bl
- cmp bl,8
- jb short rmpmirqfreef0
- add bl,60h
- rmpmirqfreef0:
- mov gs:[ebx*4+20h],eax
- pop ebx
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Allocate a selector
- ; Out:
- ; CF=1 - selector not allocated
- ; CF=0 - selector allocated
- ; AX - 4G data selector or ?
- ; Notes:
- ; The selector returned is for a 4G r/w data segment with an undefined base
- ; address.
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _getselector:
- if SELECTORS eq 0
- stc
- ret
- else
- push ecx edi
- mov edi,offset selectorfree
- mov ecx,SELECTORS
- mov al,0
- repne scasb
- jne short getselectorf0
- mov byte ptr [edi-1],1
- sub ecx,SELECTORS-1
- neg ecx
- imul cx,selectorinc
- mov ax,selectorbase
- add ax,cx
- clc
- jmp short getselectorf1
- getselectorf0:
- stc
- getselectorf1:
- pop edi ecx
- ret
- endif
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Free an allocated selector
- ; In:
- ; AX - selector
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _freeselector:
- if SELECTORS ne 0
- push eax dx
- sub ax,selectorbase
- xor dx,dx
- div selectorinc
- movzx eax,ax
- mov selectorfree[eax],0
- pop dx eax
- endif
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Exit to real mode
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _exit:
- cli
- mov eax,oint1bvect ; restore ctrl+break
- mov gs:[1bh*4],eax
- mov eax,oint32vect ; restore real mode int 32h vector
- mov gs:[32h*4],eax
- mov ax,oirqmask ; restore PIC masks
- out 0a1h,al
- mov al,ah
- out 21h,al
- push code16sel ; go to 16bit pmode exit code
- push code16off
- mov ds,data16sel
- db 66h,0cbh ; 16bit RETF
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 32 bit DPMI system data
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- dp_switchaddx df ? ; switch to real mode addx
- dp_saveaddx df ? ; save/restore state addx
- dp_savelen dw 0,0 ; length of state buffer
- dp_savedstakoff dd ? ; current saved stack offset
- dp_savedstaksel dw ? ; current saved stack selector
-
- dp_ointbuf df 20 dup(?) ; saved interrupt addx buffer
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; 32 bit DPMI system code
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ;═════════════════════════════════════════════════════════════════════════════
- dp_int32: ; DPMI INT32/34: CX:DX=seg:off
- pushad
- shl ecx,16
- mov cx,dx
- mov bp,offset callreal
- mov dl,1
- jmp short dp_int3_
- ;═════════════════════════════════════════════════════════════════════════════
- dp_int33: ; DPMI INT33/35: AL=int num
- pushad
- movzx eax,al
- mov ecx,gs:[eax*4]
- mov bp,offset intreal
- xor dl,dl
- ;-----------------------------------------------------------------------------
- dp_int3_: ; DPMI int or call to real mode
- mov ax,900h
- int 31h
- push ax
- and al,dl
- add al,0fah
- mov ebx,_code16a
- mov gs:icrealm0[ebx],al
- mov gs:icrealm1[ebx],ecx
- push dp_savedstakoff
- push dp_savedstaksel
- movzx ebx,nextmodestack
- lea eax,[ebx-STAKRMODE*16]
- mov nextmodestack,ax
- mov ax,ss
- mov es,ax
- sub esp,dword ptr dp_savelen
- mov edi,esp
- xor al,al
- call dp_saveaddx
- mov dp_savedstakoff,esp
- mov dp_savedstaksel,ss
- mov dx,codeend
- mov ax,v86r_ds
- mov cx,v86r_es
- movzx edi,bp
- mov si,code16
- jmp dp_switchaddx
- ;-----------------------------------------------------------------------------
- dp_int3_d: ; done with real mode int or call
- mov edi,esp
- mov al,1
- call dp_saveaddx
- add esp,dword ptr dp_savelen
- pop dp_savedstaksel
- pop dp_savedstakoff
- add nextmodestack,STAKRMODE*16
- mov bx,v86r_flags
- pop ax
- int 31h
- mov ax,ds
- mov es,ax
- mov fs,ax
- mov gs,_selzero
- mov ax,[esp+40]
- and ax,not 8d5h
- and bx,8d5h
- or ax,bx
- mov [esp+40],ax
- popad
- iretd
- ;═════════════════════════════════════════════════════════════════════════════
- ; DPMI IRQ redirectors (needed to make all IRQ vector selectors = CS)
- dp_irq0:
- jmp cs:dp_ointbuf[0]
- dp_irq1:
- jmp cs:dp_ointbuf[6]
- dp_irq2:
- jmp cs:dp_ointbuf[12]
- dp_irq3:
- jmp cs:dp_ointbuf[18]
- dp_irq4:
- jmp cs:dp_ointbuf[24]
- dp_irq5:
- jmp cs:dp_ointbuf[30]
- dp_irq6:
- jmp cs:dp_ointbuf[36]
- dp_irq7:
- jmp cs:dp_ointbuf[42]
- dp_irq8:
- jmp cs:dp_ointbuf[48]
- dp_irq9:
- jmp cs:dp_ointbuf[54]
- dp_irqa:
- jmp cs:dp_ointbuf[60]
- dp_irqb:
- jmp cs:dp_ointbuf[66]
- dp_irqc:
- jmp cs:dp_ointbuf[72]
- dp_irqd:
- jmp cs:dp_ointbuf[78]
- dp_irqe:
- jmp cs:dp_ointbuf[84]
- dp_irqf:
- jmp cs:dp_ointbuf[90]
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; DPMI get IRQ handler offset
- ; In:
- ; BL - IRQ num (0-0fh)
- ; Out:
- ; EDX - offset of IRQ handler
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- dp_getirqvect:
- push ax ebx cx
- movzx ebx,bl
- mov bl,intslottbl[ebx]
- mov ax,204h
- int 31h
- pop cx ebx ax
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; DPMI set IRQ handler offset
- ; In:
- ; BL - IRQ num (0-0fh)
- ; EDX - offset of IRQ handler
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- dp_setirqvect:
- push ax ebx cx
- movzx ebx,bl
- mov bl,intslottbl[ebx]
- mov cx,cs
- mov ax,205h
- int 31h
- pop cx ebx ax
- ret
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Set the base addx for a selector
- ; In:
- ; AX - selector
- ; EDX - linear base addx for selector
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- dp_setselector:
- if SELECTORS ne 0
- push ax bx ecx
- shld ecx,edx,16
- mov bx,ax
- mov ax,7
- int 31h
- pop ecx bx ax
- endif
- ret
-
- code32 ends
-
- ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ; End of program (must be at end of program or you will suffer)
- ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- codeend segment para stack use32 'stack'
- db STAKSIZE*16 dup(?)
- codeend ends
- end start16
-
-