2000 ;Trident only compatible version w EQU word ptr putpix MACRO LOCAL nonew adc dx,0 cmp dx,curbk jz nonew mov curbk,dx shl dx,12 mov ax,workseg1 add ax,dx mov es,ax ; mov curbk,dx ; newbank nonew: mov dl,gs:[si] mov es:[di],dl ENDM newbank MACRO cli mov dx,3c4h ;switch to BPS mode mov al,0bh out dx,al inc dl in al,dx dec dl mov ah,byte ptr [curbk] xor ah,2 mov dx,3c4h mov al,0eh out dx,ax sti ENDM newbank2 MACRO cli mov dx,3c4h ;switch to BPS mode mov al,0bh out dx,al inc dl in al,dx dec dl mov ah,byte ptr fs:[curbk] xor ah,2 mov dx,3c4h mov al,0eh out dx,ax sti ENDM DOSSEG .MODEL SMALL .386 .STACK 100h ..DATA ;----- XMS data ---- movestruct STRUCT len dd 0 ; 32-bit number of bytes to transfer shand dw 0 ; Handle of source block soff dd 0 ; 32-bit offset into source block dhand dw 0 ; Handle of dest block doff dd 0 ; 32-bit offset into dest block movestruct ENDS mstruc movestruct <> xmsdriver dd ? xmshandle1 dw ? xmshandle2 dw ? freemem dw ? totmem dw ? xmserror db 'No XMS driver installed! Aborting...',13,10,'$' noxmsmem db 'Not enough XMS memory! Please free up some more...',13,10,'$' ;--------- backname db 'LITHOUSE.FST',0 spritename db 'SPRIT256.FST',0 handle dw ? wdth dw ? hght dw ? palbuf db 768 dup (?) pal_set dw 0 vidseg dw 0a000h workseg1 dw ? spriteseg dw ? curbk dw 0 pos_tab dd 5+5*640, 8+10*640, 17+20*640, 30+30*640, 40+40*640, 50+50*640 dd 70+70*640, 90+90*640, 90+150*640, 90+190*640, 90+250*640, 0000ffffh tab_offs dw 0 cur_pos dd ? kuk dd ? ..CODE start: mov ax,@data mov ds,ax call shrink call xms_setup cmp ax,0 jnz xms_exists mov ah,09 mov dx,offset xmserror int 21h jmp quit xms_exists: call xms_freemem cmp freemem,600 jae enough_xmsmem mov ah,09 mov dx,offset noxmsmem int 21h jmp quit enough_xmsmem: call xms_alloc call set_svga call dis_clock call load_back call makework call load_sprites mov es,workseg1 mainlp: call do_it call update_screen call vsync call vsync call restore_workscreen mov ah,01 int 16h jz mainlp call xms_free call ena_clock call set_text quit: mov ax,4c00h int 21h do_it PROC mov bx,tab_offs cmp w[pos_tab[bx]],0ffffh jnz go_on3 mov tab_offs,0 mov bx,0 go_on3: mov si,0+772 mov dx,w[pos_tab[bx]] mov w[cur_pos],dx mov dx,w[pos_tab[bx+2]] mov w[cur_pos+2],dx mov cx,83 lp31: push cx mov cx,100 lp32: mov dl,gs:[si] cmp dl,0 jz skip_empty3 mov dx,w[cur_pos+2] mov di,w[cur_pos] putpix skip_empty3: inc si add cur_pos,1 loop lp32 pop cx add si,203-100 add cur_pos,640-100 loop lp31 add tab_offs,4 ret do_it ENDP load_hdr PROC NEAR mov cx,2 ;get width and height of image mov dx,offset wdth call readf mov cx,2 mov dx,offset hght call readf mov cx,768 mov dx,offset palbuf call readf cmp pal_set,1 jz skip_setpal mov ah,10h ;set all 256 palette regs mov al,12h mov bx,0 mov cx,256 mov dx,@data mov es,dx mov dx,offset palbuf int 10h mov pal_set,1 skip_setpal: ret load_hdr ENDP load_back PROC NEAR call dis_refresh mov dx,offset backname call openf call load_hdr mov curbk,0 newbank mov cx,4 load_lp: push cx mov ah,3fh mov bx,handle mov cx,0ffffh push ds mov ds,vidseg mov dx,0 int 21h pop ds mov ah,3fh mov bx,handle mov cx,1 push ds mov ds,vidseg mov dx,0 int 21h pop ds pop cx inc curbk newbank loop load_lp mov ah,3fh mov bx,handle mov cx,45056 push ds mov ds,vidseg mov dx,0 int 21h pop ds call closef call ena_refresh ret load_back ENDP load_sprites PROC NEAR mov ah,48h ;malloc mov bx,1200 int 21h mov spriteseg,ax mov dx,offset spritename call openf mov ah,3fh mov bx,handle mov cx,17621 mov dx,0 push ds mov ds,spriteseg int 21h pop ds call closef mov gs,spriteseg ret load_sprites ENDP restore_workscreen PROC mov mstruc.len,65536 mov dx,xmshandle1 mov mstruc.shand,dx mov mstruc.soff,0 mov mstruc.dhand,0 mov dx,workseg1 mov w[mstruc.doff+2],dx mov w[mstruc.doff],0 mov cx,4 from_xms: push cx call xms_move add mstruc.soff,65536 add w[mstruc.doff+2],1000h pop cx loop from_xms mov mstruc.len,45056 call xms_move ret restore_workscreen ENDP update_screen PROC mov ax,ds mov fs,ax push es mov es,vidseg push ds mov bx,workseg1 mov ds,bx mov si,0 mov di,0 mov fs:[curbk],0 newbank2 mov cx,4 rlp: push cx mov cx,65536/4 rep movsd pop cx inc fs:[curbk] newbank2 mov si,0 mov di,0 add bx,1000h mov ds,bx loop rlp mov cx,45056/4 rep movsd pop ds pop es ret update_screen ENDP makework PROC mov ah,48h ;malloc 307200 bytes (mycket de...) mov bx,19200 int 21h mov workseg1,ax mov es,ax mov bx,ax mov ax,ds mov fs,ax push ds mov ds,vidseg mov si,0 mov di,0 mov fs:[curbk],0 newbank2 mov cx,4 worklp: push cx mov cx,65536/4 rep movsd pop cx inc fs:[curbk] newbank2 mov si,0 mov di,0 add bx,1000h mov es,bx loop worklp mov cx,45056/4 rep movsd pop ds ;G”r en kopia av workscreen1 i XMS mov cx,4 mov mstruc.len,65536 mov mstruc.shand,0 mov dx,workseg1 mov w[mstruc.soff+2],dx mov w[mstruc.soff],0 mov dx,xmshandle1 mov mstruc.dhand,dx mov mstruc.doff,0 to_xms: push cx call xms_move add mstruc.doff,65536 add w[mstruc.soff+2],1000h pop cx loop to_xms mov mstruc.len,45056 call xms_move ret makework ENDP shrink PROC mov ah,4aH ;Mshrink mov bx,64000/16 ;Bytes left for program int 21H ret shrink ENDP openf PROC mov ah,3dh mov al,0 int 21h mov handle,ax ret openf ENDP readf PROC mov ah,3fh mov bx,handle int 21h ret readf ENDP closef PROC NEAR mov ah,3eh mov bx,handle int 21h ret closef ENDP dis_refresh PROC NEAR mov ah,12h mov al,1 mov bl,36h int 10h ret dis_refresh ENDP ena_refresh PROC NEAR mov ah,12h mov al,0 mov bl,36h int 10h ret ena_refresh ENDP dis_clock PROC NEAR cli mov dx,21h in al,dx or al,1 out dx,al sti ret dis_clock ENDP ena_clock PROC NEAR cli mov dx,21h in al,dx and al,0feh out dx,al sti ret ena_clock ENDP set_svga PROC mov ax,5dh int 10h cli mov dx,3ceh ;set pagesize to 64k mov al,6 out dx,al inc dl in al,dx dec dl or al,4 mov ah,al mov al,6 out dx,ax sti ret set_svga ENDP set_text PROC mov ax,3 int 10h ret set_text ENDP vsync PROC NEAR mov dx,3dah wt1: in al,dx test al,00001000b jnz wt1 wt2: in al,dx test al,00001000b ;wait until bit is 1 jz wt2 ;indicating vertical blank started ret vsync ENDP xms_setup PROC mov ax,4300h ; XMS Driver installation check int 2fh cmp al,80h ; returns 80h if installed jz xmsfound mov ax,0 ; XMS Driver not present jmp exit_setup xmsfound: mov ax,4310h ; get address of XMS driver int 2fh mov w[xmsdriver],bx ; store offset mov w[xmsdriver+2],es ; store segment mov ax,1 exit_setup: ret xms_setup ENDP xms_freemem PROC mov ah,8 call xmsdriver 38f mov freemem,ax mov totmem,dx ret xms_freemem ENDP xms_alloc PROC mov ah,09 mov dx,300 ; 300 kb, one 640x480x256 screen call xmsdriver ; call the XMS driver mov xmshandle1,dx ; save handle ret xms_alloc ENDP xms_free PROC mov ah,0ah mov dx,xmshandle1 ; handle number to free call xmsdriver ; call the XMS driver ret xms_free ENDP xms_move PROC cli mov ah,0bh xor bl,bl ;reset error code to zero mov si,offset mstruc ; Point ds:si to structure call xmsdriver ; call the XMS driver sti ret xms_move ENDP END start  . 0