===SPRGES=== SprGes es un grupo de programas que tenía por objeto acabar con el límite de memoria que Qbasic imponía a las matrices de gráficos. A través de un programa residente en memoria (TSR) vinculado a un controlador de interrupción se reservaba memoria para gráficos de modo MCGA (320x200, 256 colores, el mejor modo gráfico para juegos usando gráficos VGA estándar). El programa estaba creado en una mezcla de [[:es:cutressembler:start|CSEMBL]] (para la parte del TSR) y basic (para el juego en cuestión). (Puede ver los componentes Qbasic en [[es:basic:qbasic:sprges]]) Una versión compilada (funciona solo en sistemas anteriores a XP, que soporten archivos .COM, y podría ser peligroso ejecutarla en Windows) puede descargarse de [[http://jgmoyay.apagada.com]]. El programa se compone de 3 archivos com: * sprges3 (TSR gestor de gráficos, 32x32 pixels, pantalla MDPA 320x200x256). * Sprges16 (TSR gestor de gráficos, 16x16 pixels, pantalla MDPA 320x200x256). * RMSPRG (Elimina de memoria el TSR) * Sprges3 :sprgest_001 ;Parte previa. ;Carga del programa en una Int libre ;DOS get vector 60h MOV AX, 3560 INT 21 CMP BX,0 JNZ %VERR% PUSH ES POP BX CMP BX,0 JNZ %VERR% PUSH CS POP DS MOV DX,%VTSRINI% MOV AH,25 INT 21 MOV DX,%DES_INI_MAPA% ;El mapa ocupa 8000h (256x128) bytes. ;Lo ideal ser¡a que ocupase 64Kb (256x256), pero entonces no podr¡a cargarse a ;la vez que el programa (tama¤o m ximo de programa .COM=64Kb) ADD DX, 8000 PUSH DX MOV DX,%VTXTINI% MOV AH,9 INT 21 POP DX INT 27 INT 20 :VERR MOV DX, %VERRM% MOV AH,9 INT 21 INT 20 :VERRM DB "ERROR: INT 60h ESTµ SIENDO UTILIZADA POR OTRO PROGRAMA." 0D 0A DB "INSTALACIàN ABORTADA" 24 :VTXTINI DB "SPRGEST.COM (GESTOR DE MAPAS PARA EL JUEGO MOYALABE) INSTALADO" 0D 0A 24 :VTSRINI JMP %VTSRINI2% ;Lo que sigue es una cadena de identificaci¢n. DB "SPR_GEST" DW %DES_INI_MAPA% :VTSRINI2 ;SPR_GEST ;Llamada: AX=Y; BX=Y; sprites ubicados en CX:DX; INT 60 ;RUTINA PRINCIPAL PUSH DS PUSH ES PUSH AX PUSH BX PUSH CX PUSH DX ;Me aseguro de que DS y CS tengan el mismo valor. PUSH CS POP DS ;IF AX<0 CMP AX,0 JGE %SG001% XOR AX,AX ;END IF :SG001 ;IF AX>F9 CMP AX,F9 JLE %SG002% MOV AX,F9 ;END IF :SG002 ;IF BX<0 CMP BX,0 JGE %SG003% XOR BX,BX ;END IF :SG003 ;IF BX>77 CMP BX,77 JLE %SG004% MOV BX,77 ;END IF :SG004 PUSH AX PUSH BX XOR BH,BH :BUCLE1 ; XOR BH,BH CAMBIADO A MµS ARRIBA XOR AH,AH INC BL ;La siguiente l¡nea evita que AL crezca sin parar. PUSH AX :BUCLE2 ; XOR AH,AH CAMBIADO A MµS ARRIBA ;Las dos l¡neas siguientes las cambio para ;evitar efectos indeseados: ;ADD AL,AH ;ADD BL,BH INC AL PUSH AX PUSH BX MOV [%PONERV1%],AH MOV [%PONERV2%],BH XOR AH,AH XOR BH,BH CALL %PONER% POP BX POP AX INC AH CMP AH,6 JL %BUCLE2% POP AX INC BH CMP BH,8 JL %BUCLE1% POP BX POP AX ;DEVUELVO LOS VALORES INICIALES A TODOS LOS REGISTROS ;QUE PUEDAN HABER CAMBIADO: POP DX POP CX POP BX POP AX POP ES POP DS IRET :PONER ;XMAPA,YMAPA=BL,AL ;XPANT,YPANT=[PONERV2],[PONERV1] PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS PUSH ES PUSH CX POP ES MOV CL,8 XCHG AX,BX ;Me gusta m s SHL que MUL SHL AX,CL ;Lo que hemos hecho ha sido multiplicar por ;256 el valor de AL y a¤adirlo a BX. ADD BX,AX ADD BX,%DES_INI_MAPA% ;Ponemos en AX el n£mero de SPRITE: MOV AL,[BX] MOV AH,0 ;multiplicamos AX por 64 (Seg*64=DESP*(32*32)) MOV CL,6 ;AQUÖ PONÖA "SHR..." SHL AX,CL PUSH ES POP CX ADD AX,CX PUSH AX POP ES ;Lo que hemos hecho es cambiar el segmento y no el desplazamiento. ;Esto se debe a que los sprites variable que vamos a utilizar ocupan ;m s de 64Kb. ;Los sprites se cargar n desde un programa BASIC. XOR AX,AX XOR BX,BX MOV AX, [%PONERV2%] MOV BX, [%PONERV1%] ;ESTO ESTABA MAL: ;;Cambio CL de 5 a 4 (2^4=32) ;2^5=32 MOV CL,5 SHL AX,CL XCHG AX,BX SHL AX,CL XCHG BX,DX ;AX: Y_COORD (PONERV1) ;DX: X_COORD (PONERV2) MOV CX,140 ;Multiplica AX por CX: ;140h= 20*16=320 ;MUL cambia el valor de DX PUSH DX MUL CX POP DX ;FIN_BLOQUE... ;;La coord. inicial del sprite es B800:(AX+DX) ;LA COORDENADA INICIAL ES A000:(AX+DX) PUSH AX ;MOV AX,B800 MOV AX,A000 PUSH AX POP DS POP AX ADD DX,AX MOV CX,DX ;(DS:CX) XOR DX,DX :BUC3 XOR AX,AX :BUC4 ES: MOV AH,[BX] XCHG BX,CX MOV [BX],AH XCHG BX,CX INC CX INC BX INC AL CMP AL,20 JL %BUC4% INC DL ADD CX,120 ;120=140h-20h=320-32 CMP DL,20 JL %BUC3% POP ES POP DS POP DX POP CX POP BX POP AX RET :PONERV1 DW 0 :PONERV2 DW 0 :DES_INI_MAPA dB "MAPA___$MAPA___$MAPA___$MAPA___$" dB "[ MAZE MAP INFORMATION ]" DB "[INFORMACIàN DE MAPEADO] dB "MAPA___$MAPA___$MAPA___$MAPA___$" * Sprges16 ;SPRGESTV.2 16x16 :sprgest_001 ;Parte previa. ;Carga del programa en una Int libre MOV DX,%VTXTPRES% MOV AH,9 INT 21 ;DOS get vector 60h MOV AX, 3560 INT 21 CMP BX,0 JNZ %VERR% PUSH ES POP BX CMP BX,0 JNZ %VERR% PUSH CS POP DS MOV DX,%VTSRINI% MOV AH,25 INT 21 MOV DX,%DES_INI_MAPA% ;El mapa ocupa 8000h (256x128) bytes. ;Lo ideal ser¡a que ocupase 64Kb (256x256), pero entonces no podr¡a cargarse a ;la vez que el programa (tama¤o m ximo de programa .COM=64Kb) ADD DX, 8000 PUSH DX MOV DX,%VTXTINI% MOV AH,9 INT 21 POP DX INT 27 INT 20 :VERR MOV DX, %VERRM% MOV AH,9 INT 21 INT 20 :VTXTPRES DB "SPRGE16.COM V.2/16 Gestor sprites 16x16 modo 13h." :VERRM DB "ERROR: INT 60h ESTµ SIENDO UTILIZADA POR OTRO PROGRAMA." 0D 0A DB "INSTALACIàN ABORTADA" 24 :VTXTINI DB "SPRGE16.COM instalado. / 33 Kilobytes reservados." 0D 0A 24 :VTSRINI JMP %VTSRINI2% ;Lo que sigue es una cadena de identificaci¢n. DB "SPRGE16" DW %DES_INI_MAPA% :VTSRINI2 ;SPR_GEST_V2._16x16 ;Llamada: AX=Y; BX=Y; sprites ubicados en CX:DX; INT 60 ;RUTINA PRINCIPAL PUSH DS PUSH ES PUSH AX PUSH BX PUSH CX PUSH DX ;Me aseguro de que DS y CS tengan el mismo valor. PUSH CS POP DS ;IF AX<0 CMP AX,0 JGE %SG001% XOR AX,AX ;END IF :SG001 ;IF AX>79 CMP AX,79 JLE %SG002% MOV AX,79 ;END IF :SG002 ;IF BX<0 CMP BX,0 JGE %SG003% XOR BX,BX ;END IF :SG003 ;IF BX>F7 CMP BX,F7 JLE %SG004% MOV BX,F7 ;END IF :SG004 PUSH AX PUSH BX XOR BH,BH :BUCLE1 ; XOR BH,BH CAMBIADO A MµS ARRIBA XOR AH,AH :BUCLE2 ; XOR AH,AH CAMBIADO A MµS ARRIBA ADD AL,AH ADD BL,BH PUSH AX PUSH BX MOV [%PONERV1%],AH MOV [%PONERV2%],BH XOR AH,AH XOR BH,BH CALL %PONER% POP BX POP AX INC AH CMP AH,C JL %BUCLE2% INC BH CMP BH,10 JL %BUCLE1% POP BX POP AX ;DEVUELVO LOS VALORES INICIALES A TODOS LOS REGISTROS ;QUE PUEDAN HABER CAMBIADO: POP DX POP CX POP BX POP AX POP ES POP DS IRET :PONER ;XMAPA,YMAPA=BL,AL ;XPANT,YPANT=[PONERV2],[PONERV1] PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS PUSH ES PUSH CX POP ES MOV CL,8 XCHG AX,BX ;Me gusta m s SHL que MUL SHL AX,CL ;Lo que hemos hecho ha sido multiplicar por ;256 el valor de AL y a¤adirlo a BX. ADD BX,AX ADD BX,[%DES_INI_MAPA%] ;No me f¡o de la siguente l¡nea: ;MOV BX,[BX] (la quito) ;AX ya se ha corrido 8 veces a la izq. ;Es decir, ya se ha multiplicado por 16 PUSH ES POP CX ADD AX,CX PUSH AX POP ES ;Lo que hemos hecho es cambiar el segmento y no el desplazamiento. ;Esto se debe a que los sprites variable que vamos a utilizar ocupan ;m s de 64Kb. ;Los sprites se cargar n desde un programa BASIC. XOR AX,AX XOR BX,BX MOV AL, [%PONERV2%] MOV BL, [%PONERV1%] 'Cambio CL de 5 a 4 (2^4=32) MOV CL,4 SHL AX,CL XCHG AX,BX SHL AX,CL XCHG BX,DX ;AX: Y_COORD ;DX: X_COORD MOV CX,140 ;Multiplica AX por CX: MUL CX ;FIN_BLOQUE... ;;La coord. inicial del sprite es B800:(AX+DX) ;LA COORDENADA INICIAL ES A000:(AX+DX) PUSH AX ;MOV AX,B800 MOV AX,A000 PUSH AX POP DS POP AX ADD DX,AX MOV CX,DX ;(DS:CX) XOR DX,DX :BUC3 XOR AX,AX :BUC4 ES: MOV AH,[BX] XCHG BX,CX MOV [BX],AH XCHG BX,CX INC CX INC BX INC AL CMP AL,10 JLE %BUC4% INC DL ADD CX,12F ;130=140h-20h=320-16 CMP DL,10 JL %BUC3% POP ES POP DS POP DX POP CX POP BX POP AX RET :PONERV1 DW 0 :PONERV2 DW 0 :DES_INI_MAPA dB "MAPA___$MAPA___$MAPA___$MAPA___$" dB "[ MAZE MAP INFORMATION ]" DB "[INFORMACIàN DE MAPEADO] dB "MAPA___$MAPA___$MAPA___$MAPA___$" * RMSPRG