Category : Files from Magazines
Archive   : PJ76.ZIP
Filename : TOMCOM.ASM

 
Output of file : TOMCOM.ASM contained in archive : PJ76.ZIP
;****************************************************************
;*
;* TOMCOM.ASM - .COM program to relax segment limit on GS in
;* real-address mode.
;*
;* Assembled using Microsoft Macro Assembler 5.1
;*
;****************************************************************

;* Need to use 80386 protected mode instructions
.386P

;
; JUMPFAR does a far jump in USE16 segments
;
JUMPFAR MACRO PARM1,PARM2
DB 0EAH ; jump far direct
DW (OFFSET PARM1) ; to this offset
DW PARM2 ; in this segment
ENDM

CMOS_ADDR EQU 0070H
CMOS_DATA EQU 0071H

SYS_PROT_CS EQU 0008H
SYS_REAL_SEG EQU 0010H
SYS_MONDO_SEG EQU 0018H

cr equ 0dh
lf equ 0ah
dos_call equ 21h
print_func equ 09h

cseg segment use16 public 'code'
assume cs:cseg,ds:cseg,es:cseg,ss:cseg

org 100h
begin:
;
; Setup Environment
;
mov sp,offset stk_top ; setup stack
mov ax,cs ; store program segment

; WARNING: Self-modifying code. Not needed if done in ROM.
mov word ptr cs:self_mod_cs,ax

mov ds,ax ; set ds := cs
jmp init_com ; go do the work

;---------------------------------------------------------------
;
; Variables
;
;---------------------------------------------------------------
com_gdt_ptr dq ? ; for LGDT
; Limit Base Rights LimitHi
com_gdt dw 00000h, 00000h, 00000h, 00000h ; unusable
dw 0FFFFh, 00000h, 09A00h, 00000h ; code seg
dw 0FFFFh, 00000h, 09200h, 00000h ; data seg
dw 0FFFFh, 00000h, 09200h, 0008Fh ; mondo seg (4Gb)
com_gdt_end label word
;---------------------------------------------------------------

load_msg db 'Segment Helper Loaded',cr,lf
db 'Use extended register and GS: to activate',cr,lf,'$'

fixup_Msg db 'System Altered',cr,lf,'$'

db 255 dup(0ffh) ;local stack
stk_top db (0ffh)



;****************************************************************
;* Go to protected mode to relax limit on GS *
;* Entry - none
;* Exit - gs: invisible selector information fixed up
;* ds & ss: set to cs (ok for COM file)
;* WARNING: MUST EXECUTE BELOW 1M, GATE A20 NOT DISABLED
;****************************************************************
kill_seg_limit proc near

mov ax, cs ; get linear address
movzx eax, ax
shl eax,4

mov ebx, eax ; store copy of CS linear
mov word ptr cs:com_gdt+10, ax ; store in code segment desc
mov word ptr cs:com_gdt+18, ax ; store in data segment desc
ror eax, 16 ; swap words
mov byte ptr cs:com_gdt+12, al ; bits 16-23
mov byte ptr cs:com_gdt+20, al ; bits 16-23
;
; Setup Limit and Base for GDTR
;
add ebx, offset com_gdt
mov word ptr cs:com_gdt_ptr, (offset com_gdt_end - com_gdt - 1)
mov dword ptr cs:com_gdt_ptr+2, ebx

; store flags for restoring after cli
pushf
; do NOT allow interrupts as IDT is not valid in protected mode
cli
; disable NMI's here
in al,CMOS_ADDR
mov ah,al
or al, 080H ; don't disturb rest of 70
out CMOS_ADDR, al
and ah, 080H
mov ch, ah ; store old state of NMI mask

lgdt fword ptr cs:com_gdt_ptr ; assume DOS isn't using this

mov bx, cs ; save com segment

mov eax,cr0
or al,01 ; set PE bit
mov cr0,eax ; protection enabled
jumpfar ksl_pmode,SYS_PROT_CS ; purge queue and fix CS

ksl_pmode:
mov ax, SYS_REAL_SEG ; prepare limits on segments
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
;
; Here are the instructions that makes it all possible
;
mov ax, SYS_MONDO_SEG ; gs will now be 4G
mov gs, ax

mov eax,cr0
and al,NOT 01 ; clear PE bit
mov cr0,eax ; protection disabled
;
; the following relies on self-modification performed at beginning
; of program. The following macro would be useful here for ROM code only,
; so it is manually expanded to facilitate the (yech) self-modification.
;
; jumpfar ksl_rmode,SYS_REAL_CSEG ; purge queue and fix CS
;
DB 0EAH ; jump far direct
DW (OFFSET ksl_rmode) ; to this offset
; (please don't send me to programmer's hell for this one)
self_mod_cs DW ? ; in this segment
ksl_rmode:
mov ss, bx ; get seg regs back
mov ds, bx
xor ax, ax ; clear unused to be cleanly
mov es, ax
mov fs, ax
mov gs, ax
;
; back in Real Mode, IDT is ok again
;
in al,CMOS_ADDR
and al, 07FH
or al, ch ; restore old state of NMI mask
out CMOS_ADDR, al
;
; note that 386 does not have POPF problem
;
popf ; restore IRQ mask

ret

kill_seg_limit endp



;**************************************************************
;* Main Control Routine Starts Here *
;**************************************************************
initialize proc near
assume ds:cseg
;
init_com:

;display message and then relax limit checking on GS
;
mov dx,offset load_msg
mov ah,print_func
int dos_call
;
; fix gs
;
call kill_seg_limit

mov dx,offset fixup_Msg
mov ah,print_func
int dos_call
;
;check amount of memory to retain
;
mov ax,4C00h ;Terminate with return code function
int dos_call
;
initialize endp
;----------------------------------------------------------


cseg ends
end begin


  3 Responses to “Category : Files from Magazines
Archive   : PJ76.ZIP
Filename : TOMCOM.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/