Metropoli BBS
VIEWER: setup.asm MODE: TEXT (CP437)
; Setup v1.01
;═══════════════════════════════════════════════════════════════════════════════

ideal
P286
model	Huge
jumps

stack	256

segment MyCode

		assume	cs:MyCode,ds:MyData

PspAddress	dw	?
SizeOfProg      dw      ?
TopOfData       dw      0
GConfigFile	db	'GSETUP.CFG',0
SetupScr        db      'SETUP.INF',0
ScrHandle	dw	0

proc            Main
Start:          mov     [cs:PspAddress],es
                mov     ax,zzzzzseg
                inc     ax
                mov     [cs:TopOfData],ax

                mov     ax,MyData
                mov     ds,ax
                call    DetermineDisplay
                call    SetEnv
                call    SetMode
@@LoadDriver:   mov     si,offset SetupScr
                call    PutName
                push    ds
                mov     dx,offset GDirectory
                mov     cx,seg GDirectory
                mov     ds,cx
                mov     ax,3D00h
                int     21h
                jb      @@NoFind
                mov     [cs:ScrHandle],ax
                mov     bx,ax
                call    GetDecodeSizes
                mov     ax,[cs:Screen]
                mov     es,ax
                mov     di,0
                mov     bx,[cs:ScrHandle]
                call    Decode
                mov     bx,[cs:ScrHandle]
                mov     ah,3Eh
                int     21h
                pop     ds
                jmp     @@ScrLoaded
@@NoFind:       pop     ds
                mov     dx,offset NoScrFound
                call    Error
@@ScrLoaded:	call	ReadGConfig
		call	MainKey
@@Exit:         call    RestoreMode
                call    Terminate
endp            Main

UpLo		db	1,6,1,7,1,7,1,5,1,5,1,2
XY		db	14,11,33,12,50,12,12,23,31,23,57,20

proc		WriteAll
		mov	ax,[cs:Screen]
		mov	es,ax
		mov	si,offset GUSPort
		mov	cx,6
		mov	bx,0
@@Looper:	xor	ah,ah
		mov	al,[Byte cs:bx+XY+1]
		mov	dx,160
		mul	dx
		xor	dh,dh
		mov	dl,[cs:bx+XY]
		add	ax,dx
		add	ax,dx
                mov     di,ax
		mov	ax,[cs:si]
		add	al,'0'
		mov	ah,15
		stosw
		add	bx,2
		add	si,2
		loop	@@Looper
		ret
endp            WriteAll

proc		UpcaseKey
                cmp     al,'a'
                jb      @@NoKey
                cmp     al,'z'
                ja      @@NoKey
                and     al,01011111b
@@NoKey:        ret
endp            UpcaseKey

macro		SetXY	X1, Y1
		mov	ah,2
		mov	bh,0
		mov	dh,Y1
		mov	dl,X1
		int	10h
endm		SetXY

proc		GetValue
		shl	bx,1
		push	bx
		SetXY	[cs:bx+XY] [cs:bx+XY+1]
		pop	bx
@@KeyLoop:	mov	ah,0
		int	16h
		cmp	al,27
		jnz	@@CheckRet
		ret
@@CheckRet:	cmp	al,13
		jnz	@@CheckInside
		ret
@@CheckInside:	sub	al,'0'
		cmp	al,[cs:bx+UpLo]
		jb	@@KeyLoop
		cmp	al,[cs:bx+UpLo+1]
		ja	@@KeyLoop
		mov	[cs:di],al
		ret
endp            GetValue

proc            MainKey
@@KeyLoop:	call	WriteAll
		SetXY	69 12
		mov	ah,0
		int	16h
		call	UpcaseKey
		cmp	ax,3B00h
		jnz	@@TryLoad
		call	WriteGConfig
		jmp	@@KeyLoop
@@TryLoad:	cmp	ax,3C00h
		jnz	@@TryPort
		call	ReadGConfig
                jmp     @@KeyLoop
@@TryPort:      cmp     al,'P'
		jnz	@@TryGF1
		mov	di,offset GUSPort
		mov	bx,0
		call	GetValue
		jmp	@@KeyLoop
@@TryGF1:	cmp	al,'G'
		jnz	@@TryMIDI
		mov	di,offset GUSIRQ
		mov	bx,1
		call	GetValue
		jmp	@@KeyLoop
@@TryMIDI:	cmp	al,'M'
		jnz	@@TryIn
		mov	di,offset GUSMIDI
		mov	bx,2
		call	GetValue
                jmp     @@KeyLoop
@@TryIn:	cmp	al,'I'
		jnz	@@TryOut
		mov	di,offset DMAIn
		mov	bx,3
		call	GetValue
                jmp     @@KeyLoop
@@TryOut:	cmp	al,'O'
		jnz	@@TryTerm
		mov	di,offset DMAOut
		mov	bx,4
		call	GetValue
                jmp     @@KeyLoop
@@TryTerm:	cmp	al,'T'
		jnz	@@TryQuit
		mov	di,offset TerminateFlag
		mov	bx,5
		call	GetValue
                jmp     @@KeyLoop
@@TryQuit:	cmp	al,'Q'
		jnz	@@KeyLoop
		ret
endp            MainKey

include         "env.asm"

OldMode 	db	0
CurMode 	db	0
Screen		dw	0B800h

proc            RestoreMode
		xor	ah,ah
		mov	al,[cs:OldMode]
		int	10h
		ret
endp		RestoreMode

proc            SetMode near
		xor	ah,ah
		mov	al,[cs:CurMode]
		int	10h
		ret
endp		SetMode

proc            DetermineDisplay near
		mov	ax,0f00h
		int	10h
		mov	[cs:OldMode],al
		cmp	al,7			; Are we in monochrome mode?
		jz	@@Monochrome
		mov	[Word cs:Screen],0B800h
		mov	[Byte cs:CurMode],3
		ret
@@Monochrome:	mov	[Word cs:Screen],0B000h
		mov	[Byte cs:CurMode],7
		ret
endp		DetermineDisplay


;─────────────────────────────────────────────────────────────────────Decode────
N       = 4096                  ; size of ring buffer
F	= 18			; upper limit for match_length
THRESHOLD = 2			; encode string into position and length
				; if match_length is greater than this

flags	dw	0
textbuf dw	0

; bx - Handle
; cx - Num Bytes Long
; es:di - output
textsize	dd	0
codesize	dd	0

proc		GetDecodeSizes
		push	ds bx
		mov	ax,cs
                mov     ds,ax
                mov     ah,3Fh
		mov	cx,8
		mov	dx,offset textsize
		int	21h
		mov	si,[Word cs:textsize+2]
		mov	di,[Word cs:textsize]
		mov	dx,[Word cs:codesize+2]
		mov	cx,[Word cs:codesize]
		pop	bx ds
		ret
endp            GetDecodeSizes

proc            Decode
		push	ds
		mov	dx,[cs:TopOfData]
		mov	[cs:textbuf],dx
		add	dx,(N+F-1)/4+1

		mov	ds,dx		; Load buffer
		mov	dx,0
		mov	ah,3Fh
		int	21h
		mov	si,0

		push	cx es
;               for (i = 0;i < N - F;i++) text_buf[i] = ' ';
		mov	di,0
		mov	ax,[cs:textbuf]
		mov	es,ax
		mov	cx,N-F
		mov	al,' '
		rep	stosb
		pop	es cx
		mov	di,0

;		r = N - F; flags = 0;
                mov     [Word cs:flags],0
;		 mov	 [Word cs:r],N-F
		mov	bx,N-F		; R
;  for (;;)
;  {
;		if (((flags >>= 1) & 256) == 0)
@@DecodeLoop:   shr     [Word cs:flags],1
		mov	ax,[Word cs:flags]
		and	ax,256
		jnz	@@NextFlagCheck

;		{
;		  if ((c = getc(in)) == EOF) break;
		lodsb
		cmp	si,cx
		jnb	@@Finish
;		  flags = c | 0xff00;	 /* uses higher byte cleverly to count eight */
                or      ah,0ffh
		mov	[Word cs:flags],ax
;		}
;		if (flags & 1)
@@NextFlagCheck:mov	ax,[cs:flags]
		and	ax,1
		jz	@@FlagCh2
;		{
;		  if ((c = getc(in)) == EOF) break;
		lodsb
		cmp	si,cx
		jg	@@Finish
;		  putc(c, out); text_buf[r++] = c; r &= (N - 1);
                stosb
		push	es
		mov	es,[cs:textbuf]
		mov	[es:bx],al
		inc	bx
		pop	es
		and	bx,N-1
		jmp	@@DecodeLoop
;		}
;		else
;		{
;		  if ((i = getc(in)) == EOF) break;
@@FlagCh2:	xor	ah,ah
		lodsb
		cmp	si,cx
		jg	@@Finish
                mov     dx,ax                           ; i = DX
;		  if ((j = getc(in)) == EOF) break;
		lodsb					; j = AX
		cmp	si,cx
		jg	@@Finish
;                 i |= ((j & 0xf0) << 4);
		push	ax
		and	ax,0f0h
		shl	ax,4
		or	dx,ax
		pop	ax
;		  j = (j & 0x0f) + THRESHOLD;
		and	ax,0fh
		add	ax,THRESHOLD
;		  for (k = 0;k <= j;k++)
		mov	bp,0			; k
@@kloop:
		push	ax			; Save j
;                 {
;		  c = text_buf[(i + k) & (N - 1)];
		push	es bx
		mov	es,[cs:textbuf]
		mov	bx,dx			; i
		add	bx,bp			; +k
		and	bx,N-1
		mov	al,[es:bx]
		pop	bx es
;		  putc(c, out);
                stosb
;		  text_buf[r++] = c; r &= (N - 1);
		push	es
		mov	es,[cs:textbuf]
		mov	[es:bx],al
		inc	bx
		pop	es
                and     bx,N-1
		inc	bp			; k++
		pop	ax
		cmp	bp,ax			; k<=j
		jle	@@kloop
		jmp	@@DecodeLoop
@@Finish:	pop	ds
		ret
endp            Decode

proc		Terminate far
		mov	ax,4C00h
		int	21h
endp            Terminate

proc		Error near
		call	RestoreMode
                mov     ax,MyData
		mov	ds,ax
		mov	ah,9
                int     21h
		call	Terminate
endp            Error

; si - Filename offset
proc            PutName
		push	ds es
		mov	ax,MyData
                mov     es,ax
		mov	di,[es:PutFilename]
		mov	ax,cs
                mov     ds,ax
                mov     cx,12
		rep	movsb
		mov	al,0
		stosb
		pop	es ds
		ret
endp            PutName

proc		WriteGConfig
		push	ds
		mov	ax,MyData
		mov	ds,ax
		mov	si,offset GConfigFile
                call    PutName
		mov	dx,offset GDirectory
                mov     cx,seg GDirectory
		mov	ds,cx
		mov	cx,0
		mov	ah,3Ch
		int	21h
		jb	@@NoWrite
		push	ax
		mov	ax,[cs:GUSPort]
                shl     ax,4
                add     ax,200h
                mov     [cs:GUSPort],ax
                mov     bx,[cs:GUSIRQ]
                mov     al,[cs:bx+GUSIRQList]
                mov     [Byte cs:GUSIRQ],al
                mov     bx,[cs:GUSMIDI]
                mov     al,[cs:bx+GUSIRQList]
                mov     [Byte cs:GUSMIDI],al
                dec     [Word cs:TerminateFlag]
		pop	bx
		mov	cx,11
		mov	ax,cs
		mov	ds,ax
		mov	dx,offset GUSPort
		mov	ah,40h
                int     21h
		mov	ah,3Eh
                int     21h
		mov	ax,[cs:GUSPort]
		sub	ax,200h
		shr	ax,4
		mov	[cs:GUSPort],ax
		mov	bx,[cs:GUSIRQ]
		mov	al,[cs:bx+IRQGUSList]
		mov	[Byte cs:GUSIRQ],al
		mov	bx,[cs:GUSMIDI]
		mov	al,[cs:bx+IRQGUSList]
		mov	[Byte cs:GUSMIDI],al
                inc     [Word cs:TerminateFlag]
@@NoWrite:      pop     ds
		ret
endp		WriteGConfig

proc		ReadGConfig
		push	ds
		mov	ax,MyData
		mov	ds,ax
		mov	si,offset GConfigFile
		call	PutName
		mov	dx,offset GDirectory
                mov     cx,seg GDirectory
		mov	ds,cx
		mov	ax,3D00h
		int	21h
		jb	@@NoRead
		mov	bx,ax
		mov	cx,11
		mov	ax,cs
		mov	ds,ax
		mov	dx,offset GUSPort
		mov	ax,3F00h
                int     21h
		mov	ah,3Eh
                int     21h
		mov	ax,[cs:GUSPort]
		sub	ax,200h
		shr	ax,4
		mov	[cs:GUSPort],ax
		mov	bx,[cs:GUSIRQ]
		mov	al,[cs:bx+IRQGUSList]
		mov	[Byte cs:GUSIRQ],al
		mov	bx,[cs:GUSMIDI]
		mov	al,[cs:bx+IRQGUSList]
		mov	[Byte cs:GUSMIDI],al
		inc	[Word cs:TerminateFlag]
@@NoRead:       pop     ds
		ret
endp		ReadGConfig

IRQGUSList	db	0,0,1,2,0,3,0,4,0,0,0,5,6,0,0,7

ends            MyCode

segment MyData
NoEnvFound	db	'1: The environment variable GUSMOD was not found.',13,10,'$'
NoScrFound	db	'2: SETUP.INF not found.',13,10,'$'

GDirectory	db	80 dup (0)
GEnv		db	6,"GUSMOD"
PutFilename	dw	0
ends	MyData

segment zzzzzseg
	db	16 dup (?)
ends	zzzzzseg

        end     Start


[ RETURN TO DIRECTORY ]