;-------------------------------------------------------------- 
;This is an assembly source code example, on how to use LXPIC
;as a subroutine using intrasegment calls to LXPIC. This
;enables you to write tiny COM files which display pictures as
;you like it. See 'PROGRAMMERS INTERFACE' in LXPIC.DOC for
;further information.
;
;This example shows, how to fill a whole screen with an icon.  
;To provide LXPIC with a picture filename, the command tail of
;DEMO is simply copied to the command tail of LXPIC. To see,
;how DEMO works, proceed as follows:
;
;-Create the directory C:\PIC
;-Copy LXPIC.COM, LXPIC.ICN and DEMO.COM to C:\PIC
;-Change the directory to C:\PIC 
;-Enter DEMO LXPIC.ICN at the command line.
;-Press any key to exit DEMO
;
;If you want to change the code of DEMO.ASM, you have to 
;assemble and link as follows, to create the new DEMO.COM file:
;
;Using Turbo Assembler/Linker
;
; tasm demo.asm;             (creates demo.obj)
; tlink /t demo.obj;         (creates demo.com)
;
;Using Microsoft Assembler/Linker
;
; masm demo.asm;             (creates demo.obj)
; link demo.obj;             (creates demo.exe)
; exe2bin demo.exe demo.com  (creates demo.com)
;
;You must create a COM file. You cannot use the intermediate
;EXE file, because of different PSP length and structure.
;------------------------------------------------------------------------------

.186                   ;allow pusha and popa 
cseg   segment 'code'
assume cs:cseg,ds:cseg,es:cseg
org    100h

MODE   EQU   00000000b ;0,0,0,HPRES,AZOOM,CENTER,INVERS,CLS
ZOOM   EQU   0         ;no zoom
LINE   EQU   0         ;start pixelline
COLUMN EQU   0         ;start pixelcolumn
X_DEL  EQU   48        ;advance X_DEL pixelcolumns
Y_DEL  EQU   36        ;advance Y_DEL pixellines
ITFADR EQU   0458h     ;interface start adresse

  start:               ;start of program
call   load            ;load LXPIC
jc     ende            ;load error
call   select          ;select picture file
jc     ende            ;select file error
call   screen          ;get/set screen mode
mov    cx,LINE         ;start pixelline
mov    dx,COLUMN       ;start pixelcolumn
  _loop:
mov    ah,MODE         ;mode byte
mov    al,ZOOM         ;zoom factor
call   picture         ;fill in interface and display picture

 ;---------------------;multiple output start
 add    dx,X_DEL       ;increment column
 cmp    dx,640         ;screen width reached?
 jl     _loop          ;no, display next
 xor    dx,dx          ;restart with column 0
 add    cx,Y_DEL       ;increment line
 cmp    cx,200         ;screen hight reached?
 jl     _loop          ;no, display next
 ;---------------------;multiple output end

call   wait_key        ;wait for any key
  ende:
mov    ah,4ch          ;exit program...
int    21h             ;...using DOS

;--------------------------------------------------------------
;------SUBROUTINES---------------------------------------------
;--------------------------------------------------------------
  screen:              ;get/set screen mode
mov    ah,0fh          ;get actual sreen mode
int    10h
mov    smode,al        ;store actual screen mode
mov    ax,6            ;set CGA graphics mode
int    10h
ret
;--------------------------------------------------------------
  wait_key:            ;wait for any key
xor    ax,ax
int    16h             ;waits for key
xor    ah,ah           ;ah=0
mov    al,smode        ;get old screen mode
int    10h             ;set old screen mode
ret
smode  db 0            ;place to store screen mode
;--------------------------------------------------------------
  picture:             ;fill in interface and display picture
pusha
push   es
push   ds

;----------------------;fill in interface
push   ds
xor    bx,bx
mov    ds,bx           ;ds=0
mov    bx,ITFADR       ;bx=offset interface
mov    byte ptr[bx+0],3;set selection flag=return via RET
mov    [bx+1],ah       ;set mode
mov    [bx+2],al       ;set zoom
mov    [bx+3],cx       ;set pixelline
mov    [bx+5],dx       ;set pixelcolumn
pop    ds 
;----------------------;display picture
lea    bx,lxpic        ;offset LXPIC
mov    ax,param        ;segment adresse LXPIC
sub    ax,16           ;segment adresse PSP
mov    es,ax           ;load es with PSP
mov    ds,ax           ;load ds with PSP
call   bx              ;intrasegment CALL LXPIC
pop    ds              ;restore ds for lea dx,error
or     al,al           ;al=LXPIC return code
je     pic_e           ;if al=0
lea    dx,error        ;if al not 0: display error...
mov    ah,9            ;...using DOS
int    21h
  pic_e:
pop    es
popa
ret
error  db'LXPIC error$';error text 
;--------------------------------------------------------------
  select:              ;select a picture filename
pusha
mov    si,80h          ;offset DEMO command tail
lea    di,tail         ;offset LXPIC command tail
xor    ch,ch           ;ch=0      
mov    cl,[si]         ;has DEMO command tail...
or     cl,cl           ;...length=0?
je     sel_e           ;yes, display syntax
add    cx,2            ;else copy the whole tail...
rep    movsb           ;...from DEMO to LXPIC 
clc                    ;no carry flag
popa
ret
  sel_e:
lea    dx,syntax       ;display syntax...
mov    ah,9            ;...using DOS
int    21h
stc                    ;set carry flag
popa
ret
syntax db'Syntax: DEMO [path]file.[BMP|GIF|ICN|PCX]$'
;--------------------------------------------------------------
  load:                ;load LXPIC within same segment
pusha
lea    ax,lxpic        ;convert LXPIC offset...
shr    ax,4            ;...in paragraphs...
mov    bx,cs           ;...and add CS
add    ax,bx           ;absolute LXPIC segment load address...
mov    param,ax        ;...as 1.param
lea    bx,param        ;load param offset
lea    dx,_lxpic       ;load pathname offset of LXPIC
mov    ax,4b03h        ;load LXPIC at segment:0000
int    21h
jnc    load_e          ;no load error
mov    ah,9            ;display error...
int    21h             ;...using DOS
stc                    ;set carry flag
  load_e:
popa
ret

;---load Data--------------------------------------------------
_lxpic db 'C:\PIC\LXPIC.COM',0,'not found$'
param  dw 0,0

;---PSP and LXPIC code placeholder-----------------------------
ALIGN  16                   ;dummy PSP starts at this segment
tail   equ this word+ 80h   ;command tail in dummy LXPIC PSP
lxpic  equ this word+100h   ;LXPIC code starts here

cseg   ends
       end start
