Toqueteando las tripas del OCS en ASM. Nivel -1

Avatar de Usuario
Mlake
Mensajes: 21
Registrado: 27 Mar 2019 19:54
Agradecido : 14 veces
Agradecimiento recibido: 71 veces

Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Mlake » 05 Abr 2019 02:50

Saludos a todos

Abro el hilo con la idea de introducir a los curiosos del Amiga que quieren conocer las tripas del cacharro, pero les da vertigo eso de bitplanes, data fetching, color subcarrier, ciclos, scanlines.....
Para poder empezar con el Ensamblador, hay que conocer el Hard por narices. :geek:

Me gustaria que fuese algo sencillo, que cualquiera pueda entenderlo . Sobre todo a los que se estan inciando pero creen que "bajar al cobre" es una odisea.
A los que ya dominan el tema, quiero que comprendan que la cantidad de burradas que puedan aparecer son para intentar explicar conceptos, sobre todo al principio. :lol:

Una de las razones de este hilo es quitarle el miedo a la gente. De paso aprovechar los comentarios de los foreros para refrescarnos cosas, aprender, compartir, quitarnos el oxido...

Vamos a empezar y perdon por las posibles patadas al diccionario.

Introduccion (Nuestra querida tele de tubo)

¿Y que importancia tiene el monitor para tener que empezar por aqui?
Pues resulta que la orquesta que marca el ritmo de trabajo del Amiga es la señal del rayo.
Seguro que todos hemos visto como funciona un monitor/tv de tubo.
Un "cañon" dispara hacia la pantalla y generamos las lineas de imagen, cuando termina vuelve a subir y repetimos la operacion.


Imagen
Todos esos movimientos tienen unos tiempos estandarizados (los famosos PAL, NTSC,etc).
Teniendo eso claro, podemos ver como se plasma la imagen en pantalla.


Imagen
Ese marco negro (overscan) tiene una razon de ser.
La tecnologia de tubo tiene muchos años... con tantos fabricantes y con mejores/peores tecnologias, no existian bordes homogeneos y se dejaba una zona de "seguridad" para no perder imagen. Asi podias ver la imagen aunque el tubo fuera casi redondo.

Ya sabemos como funciona un monitor. Ahora tenemos que alimentar esa señal.....

Racing the beam

Para poder dibujar en pantalla, hay que decirle a los electrones en que momento deben cambiar de color para que (linea tras linea) nos muestre la imagen deseada. Hoy en dia las gpu lo hacen sin que nos enteremos,sin necesidad de lineas, todo digital directo al LCD.
En tiempos donde la tecnologia (y sobre todo la memoria) era carisima, lo mas basico podria ser algo asi. Una CPU, algo de memoria y lo necesario para convertir de digital a analogico.


Imagen
Con lo que sabemos podemos deducir que la CPU se dedica a pintar una imagen durante la parte visible, pero durante el overscan (y lo que tarda en volver a subir el rayo de electrones ) tenemos tiempo para exigirle trabajo.
¿Que pasa si aumentamos el presupuesto/tecnologia y ponemos hard dedicado y mas memoria?


Imagen

Ya tenemos otro escenario. El procesador de video nos genera la imagen pero no es gratis.
Tenemos que tener datos en rom (caracteres, tiles de un cartucho, etc....) o gastar tiempo en llenar su ram. Ademas de eso, el vdp pide una serie de comandos para saber que hacer con los tiles/caracteres, como los tiene que ordenar, que paleta le asignamos, cuantos planos necesitamos.....
Al final ganamos una barbaridad de tiempo respecto a lo anterior, pero seguimos sin solventar el problema principal.... la CPU tiene que estar "achuchando" al VDP.
Y ahora viene el Amiga y te hace esto. :-P

Imagen

En ese momento te vienen dos cosas a la cabeza. La memoria del sistema la tiene el chipset, por lo que la imagen se puede independizar en el sentido moderno de la palabra. Pero, si estamos en la CPU.... ¿como entro en la ram? ¿Ahora tengo que pedir permiso? :oops:

Vamos a tener que empezar a ponernos las botas porque nos metemos en el fango.
La tecnica de usar el overscan para hacer el trabajo y usar la zona visible para "pintar" es pan comido para nosotros ¿verdad?. Pero cuando miramos la imagen de un A500 (por ejemplo) enchufado a un LCD o usamos algun emulador, pasa algo raro....

Imagen
Si la imagen no está centrada podemos deducir que algo mantiene ocupado al amiga durante ese tiempo y no le deja dibujar.
Aqui viene la madre del cordero.... :evil:

Imagen



Por ahora no nos interesan los datos, solo entender la idea.
El dibujo es una "linea temporal" de lo que hace el chipset mientras el rayo va cruzando la pantalla de izda a dcha. Los cuadrados numerados 1/3/5/2/4/6 (tanto negros como blancos) son el tiempo en el que estamos pintando la imagen, asi que practicamente todo lo que no es pintar (audio, sprites,etc....) se hace al principio. Por eso la imagen sale desplazada.

¿por que es importante saber esto? porque el chipset es el que domina la ram (de ahi la famosa CHIP-RAM amiguera).
Obviamente los diseñadores no eran tontos y crearon una memoria "directa" a la CPU (FAST-RAM), pero ahora no interesa poque el A500 pelado no lleva fastram.
La razon por la que empiezo por el acceso a memoria (data fetching) es que despues es mas facil explicar los scroll, los sprites, los modulos, etc....

Vamos a simplificar la cosa con esta idea.

Imagen


Esto es un DMA casero que nos hemos inventado, dividimos el tiempo de trabajo en Slots.
A su vez lo hemos superpuesto a la imagen de pantalla para saber que ocurre a medida que el rayo pasa por el monitor.
En el 0 vemos que nos toca el audio, el chipset deja pasar un word (16bits) de la ram al audio.
En el 1 hay un hueco para la CPU, ahi podemos meternos en la ram.
En el 2, el chipset pasa otro word para pintar los sprites.
En el 3 tenemos otro hueco para trabajar
4. otro word para sprites....
5. otro hueco para nosotros.....
6. Aqui empieza el jaleo. Bitplane 1
La imagen del Amiga es planar. Eso quiere decir que cada pixel es un bit, un word son 16 pixels,facil. ¿Como le damos color a esos puntos? Pues poniendo otro punto "encima" a modo de capa. Mas colores, mas capas.
Si tenemos tres planos, podemos hacer 3 capas.
1 capa/bitplane (0 o 1) -> 2 colores
2 capas/bitplanes (0/0 0/1 1/0 1/1) -> 4 colores
3 capas bitplanes (0/0/0 0/1/0 1/0/0 1/1/0 0/0/1 0/1/1 1/0/1 1/1/1) -> 8 colores
Si queremos los 8 colores, tenemos que decirle al chipset que mande las tres capas, asi que son tres slots en los que no podemos hacer nada.
7. Bitplane 2
8 bitplane 3
Si nos fijamos, al haber cargado los primeros 16 pixels de los bitplanes, se empieza a generar la imagen en pantalla.
9 Aqui volvemos a tener otro hueco.
10 Ser repite el ciclo, bitplane 1
11 bitplane 2
12 bitplane3
.
.
.
No parece tan dificil el concepto ¿no? Dividimos el trabajo en words y le damos a cada componente un hueco para meter lo suyo.
Si encima nuestro DMA nos deja modificar su rutina (hasta cierto punto), podemos hacer cosas como la de abajo, sacrificar los sprites a cambio de mas pantalla. O al reves, reducirla para tener mas hueco de trabajo.

Imagen


Con estos ejemplos podemos hacernos una idea basica de como funciona los DMAs. para saber cuando podemos trabajar y cuando tenemos que hacer el amiga trabaje por nosotros.
Todo esto ha sido muy por encima pero podemos empezar a mirar la primera imagen con un poco menos de miedo.
Podemos ojear los slots para trabajar el disco, el audio, los sprites, los bitplanes..... No sigue el orden de nuestro ejemplo pero se puede intrepretar mejor que al principio.
Tenemos que saber lo que esta haciendo el cacharro para saber que podemos (o no) hacer nosotros desde la CPU. De nada nos vale hacer una rutina chula si el rayo de electrones nos adelanta porque nos hemos quedado sin tiempo.

Si alguno empieza a entender el "ritmo" del OCS despues de esta explicacion, se preguntara ¿por que la CPU tiene los huecos impares? o ¿por que los bitplanes van en ese orden y no en otro? La respuesta es sencilla....
Por temas de señal de video y de como se maneja el color del monitor, el chipset trabaja a 3.5Mhz +- y por consiguiente, el 68000 va a 7 Mhz +- (el doble). ¿Con esto que conseguimos? Muy sencillo.....
El micro tarda 4 ciclos en mover un dato, al ir el doble de rapido, esos 4 ciclos duran los que 2 ciclos/slots del DMA. Asi que aun teniendo todos los slots para mi, siempre voy a perder uno porque no me da tiempo a mover los datos, el rayo pasa y no se puede desperdiciar el tiempo. Ese hueco (los pares) los intenta aprovechar el chipset para hacer sus cosas (sprites, disco, audio....)
Y a medida que le exiges al amiga, vas perdiendo slots y no te interesa estar con los brazos cruzados sin poder acceder a memoria hasta que vuelves al overscan o al momento en el que rayo vuelve a subir, que es donde tienes que hacer todo lo que puedas porque los bitplanes estan apagados.

Todo se basa en meter words aqui y alla.


Como todos los cacharros de la epoca, si quieres hacer algo solo tienes que leer/escribir una direccion y listo.
Hay 2 zonas clave. La del OCS ($DFFxxx) y las CIAs ($BFExxx,$BFDxxx)
Un ejemplo tipico seria: Quiero cambiar el color de fondo, pues word que te pego a X direccion ($DFF180 en este caso) y voilá.
Para organizar todo este batiburrillo hay una parte de Agnus especializada en automatizar muchas de estas llamadas y que es indispensable para darle esa famosa indepencia del chipset,el COPPER. Que vendra a ser como una especie de "POKEador" de words que es capaz de saber en que posicion esta el rayo del monitor, con todo lo que eso trae.
¿Que quieres cambiar de color en la linea X? Nada de poner interrupciones... el lo hace donde quiera (o casi). ¿Que quiero abrir o cerrar bitplanes/dmas/etc en una parte de la pantalla para poder sacar unos slots extras? Sin problema... ¿Se me han acabado los sprites que se habian cargado al inicio de la linea? Los creo sobre la marcha....

Ese será el Capitulo 1, por ahora terminamos la introduccion.
Lo suyo es tener el manual de hardware a mano (pdf,web,papel...) y empezar a conocer las capacidades partiendo de esta idea de words, lineas, slots, etc...
En principio esto esta pensado para usar el A500 que muchos tenemos en casa, en mi caso con una gotek por comodidad. ASMTwo de Scoopex va de lujo.

Avatar de Usuario
Chema
Mensajes: 2124
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 1520 veces
Agradecimiento recibido: 484 veces
Contactar:

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Chema » 05 Abr 2019 08:54

Qué idea más genial has tenido. Seguiré este hilo con mucha atención... mil gracias!

Avatar de Usuario
minter
Mensajes: 2289
Registrado: 22 Jul 2014 18:51
Agradecido : 1948 veces
Agradecimiento recibido: 824 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor minter » 05 Abr 2019 08:57

Fantástico!
Un curso de iniciación de Amiga!
Me parece complicadísimo como funciona este ordenador. A ver si ahora, explicado de una manera entretenida, me entero como va.

Avatar de Usuario
Chema
Mensajes: 2124
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 1520 veces
Agradecimiento recibido: 484 veces
Contactar:

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Chema » 05 Abr 2019 12:04

minter escribió:Fantástico!
Un curso de iniciación de Amiga!
Me parece complicadísimo como funciona este ordenador. A ver si ahora, explicado de una manera entretenida, me entero como va.


+1
Empecé a leerme el Hardware Reference Manual y perdí cordura por un tubo :)

Supongo que es cosa de ir metiéndole mano poco a poco y tener algo de paciencia. Pero de mano es difícil de tragar. Por eso, entre estos posts y el curso de Fernando Cabrera de Amiga Wave espero enterarme un poco -grin

Avatar de Usuario
Mlake
Mensajes: 21
Registrado: 27 Mar 2019 19:54
Agradecido : 14 veces
Agradecimiento recibido: 71 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Mlake » 07 Abr 2019 19:45

CAP1 Nuestro primer "programa", conociendo el copper.

La estructura basica de un programa es la siguiente.

Organizamos la memoria-> Desactivamos el SO-> Hacemos nuestras cosas-> Restauramos el SO-> Salimos.

Como aun estamos verdes, vamos a intentar tocar el hard sin hacerle "daño" al SO. Asi evitamos liarnos al principio. Como siempre lo que queremos es hacernos una idea y despues entrar en profundidad.
La idea es simple, vamos a cambiar el color de fondo a mitad de pantalla. Queremos pasar del Azul workbech a negro.

Procedamos....

Imagen

Organizar memoria.

Al inicio del programa, tenemos que planear en que lugar de la memoria queremos colocar nuestro codigo/datos.
Tenemos 512KB a nuestra disposicion pero como aun no sabemos donde poner nuestro codigo sin hacer un destrozo, podemos dejarle al SO que nos lo coloque automaticamente.
La memoria que ocupa el programa se divide en trozos (hunks), podemos especificar lo que contienen para que el Amiga se pueda se pueda manejar mejor.

En ASM seria algo asi:

ORG $30000 ->Version Hardcore donde le decimos al micro que cargue el programa en la posicion $30000, si hay algo importante en esa zona, nos lo cepillamos.

SECTION programa,CODE_C ->Version soft donde creamos un hunk de tipo codigo y le decimos al SO que nos lo coloque donde crea conveniente dentro de la memoria chip. Podemos poner nombre a esos pedazos, en este caso lo llamamos "programa". CODE especifica el tipo de hunk (codigo) y la C indica que tiene que ir a Chipmem.
Si os quereis liar la manta a la cabeza y ver todos los tipos/usos, podeis visitar este link. Pero no vale la pena complicarse cuando lo importante del hilo es usar el hard y dejar el sistema lo mas a un lado posible.
http://amiga-dev.wikidot.com/file-format:hunk



Ya tenemos sitio para nuesto programa. Primer paso completado sin dificultad.


Desactivamos el SO

Como no vamos a tocar nada critico, lo dejamos de momento. Mas tarde, cuando aprendamos a apagar/encender los DMAs, interrupciones, etc.... le daremos caña.

Nuestro programa

Creamos un punto para esperar al rayo (espera:). Como vimos en la introduccion, el trabajo hay que hacerlo al ritmo del monitor.
Tenemos que saber donde estan los electrones y el chipset pone a nuestra disposicion una direccion de memoria que nos dice por donde anda....

$DFF006 alias VHPOSR (vertical horizontal posicion lectura)
Ese word tiene dos bytes ($dff006 y $dff007), uno para la Y otro para la X. Como solo nos interesa el interesa el primero y no el word completo, comparamos ese byte nada mas.

OJO. Debe quedar claro como funcionan las llamadas al chipset.

Al igual que VHPOSR ($DFF006). Hay un monton de direcciones de comunicacion, unas de lectura (direccion del joy, posicion del rayo, el estado de los DMA....) y otras son de escritura (colores, direcciones que apuntan a nuestros graficos, parametros para que el chipset haga cosas en general....). Esto es la base de todo.

http://amiga-dev.wikidot.com/information:hardware
Se que es un coñazo y hay que cargar con el libro a cuestas, pero no queda otra. Las iremos usando poco a poco y con calma, explicando cada vez que salga una nueva. Pero el tocho hay que ojearlo sí o sí.


¿Por que hemos comparado con #$AC (AC=172) y no con 128 que es la mitad de nuestra pantalla (256 lineas PAL)? Porque tambien se incluye el overscan.

Para el Amiga, la imagen PAL por defecto empieza en la linea $2C y acaba en la $12C, ahi estan las 256 lineas que buscamos. Este descuadre (vimos que el chipset solo nos daba un byte y ahi nesitamos un bit mas) nos traera algun quebradero de cabeza mas adelante.....
La mitad entre $2c y $12C es $AC. ¿Por que uso hexadecimal y no decimal? todos esos numeros los vamos a usar mucho, y aunque a veces no sean intuitivos, nos van a servir de contexto muchas veces para entender cosas o para hacernos una idea de que esta haciendo el amiga en ese momento. Hay muchos como 2C,12C,81,C1,38,D0,AC,FFFE,DF,07... que ahora son simples digitos pero seguro que los iniciados son capaces de decirte porque los he puesto.




Volvamos al turron.

Estabamos comparando continuamente hasta que el rayo llega y podemos salir del bucle "espera". !Ahi cambiamos de color!

¿Como lo hacemos?
Lo que ya sabemos, buscamos en el manual la direccion del color de fondo ($DFF180 alias COLOR00) y le metemos lo necesario. En este caso los colores del amiga se meten en un Word en formato $RGB. El blanco seria $FFF y el negro $000.
Una vez que hemos hecho el cambio, la imagen se vuelve negra y volvemos a tener libertad de trabajo.


Seguimos con otra "lectura" a $bfe001 ¿Vamos a volver al leer el OCS? Casi....
Esta vez toca la CIAA (mirad el link anterior) que funciona de la misma forma, solo que está en otra zona de la memoria y trabaja en bytes en lugar de words. Esto nos hace intuir que no anda bajo los dominios de chipset sino de la CPU.

$BFE001 alias CIAAPRA nos da informacion del boton del raton y su bit 6 nos dice si hemos pulsado el izdo. En lugar de una comparacion como tal, usamos un "bit test" (btst) y si el 6 no esta encendido regresamos al loop original para volver a repetir todo el rollo de esperar a la linea AC, cambiar de color, comprobar raton, volver al inicio, esperar a la linea......
No ha sido dificil ¿verdad?


Ahora nos toca salir, como no hemos tocado nada del SO podemos irnos sin mas. Simplemente limpio D0 antes de salir. No hace falta pero es algo que le gusta al workbench y no cuesta nada.


Ahora que le vamos pillando el punto a esto de esperar al raster y darle caña al chipset, vamos a rizar el rizo....

Imagen

Lo primero que llama la atencion en el codigo es eso de INCLUDE "custom.i".
No nos afecta en nuestra aventura, solo es un archivo donde estan almacenados todos los alias de los custom chips que forman el OCS. Cuando pongo custom+alias el ensamblador lo interpretará como $DFF000+offset del alias que conocemos. Asi podemos hacernos una idea mas rapida y "recordable" de que zona del amiga estamos "atacando".




Esta vez tenemos dos esperas, la primera parada en la linea $AC y la segunda en la $BC (16 mas abajo), en una cambiamos a negro ($FFF) y en la otra volvemos al Azul workbench ($05A). Testeamos el raton y si no se ha pulsado, repetimos.
Esta vez ha sido mas sencillo, hemos aprendido a hablar con el chipset.
Primer objetivo conseguido.

Seguro que si algun forero ya sabe manejarse con los motorola 68000, estara haciendo experimentos con esa barra negra que hemos creado usando una tabla de senos/cosenos. -grin

Ahora vamos a plantearnos todo lo que hemos estado haciendo.

Estamos conduciendo un coche, estamos pendientes a la carretera (el trabajo), al retrovisor (el CRT), al bolsillo (slots).... tiene que haber alguna forma de agilizar esto porque el camino va a ser largo. Que mejor que un compañero de viaje.

El Copper


Para no liarnos mucho, el copper va a ser la herramienta que vamos a usar para evitarnos todas esas esperas y llamadas al OCS.
Imaginalo como un musico al que le damos una partitura que empieza a tocarse en cuanto el rayo empieza a correr.Su mision basica es ESPERAR a una posicion del rayo y MOVER un word al chipset (sea un dato o una orden).

Imagina un escenario como este, donde solo tenemos un bitplane (cada pixel es 0 o 1, solo tenemos 2 colores)

Imagen

¿Como es posible que hayan 3? Escribiendole al copper la siguiente lista:

coperlista:
mueve a COLOR00 (el alias del $DFF180 al que le hemos quitado el "custom+" ya que las $DFF no caben en el word) el valor $000 (negro)
mueve a COLOR01 el valor $888 (gris)
espera a la linea que quieras (en este caso cualquiera que sea bajo la luna )
mueve a COLOR01 el valor $00f (azul)
para en cuanto llegues al final del frame porque no tenemos mas instrucciones para ti.

Un momento, ¿si solo puedo esperar y mover, como lo paro? Pues engañandolo para que se quede esperando una posicion imposible. ¿Y por que lo tengo parar? Porque si lo dejas, seguiria procesando todo lo que se va encontrando en memoria (a lo mejor tu propios graficos, restos de otros programas....).

¿Como creamos esa partitura? Muy simple, cada "nota" son dos words.

Destripando una copperlist.

coperlista1:
dc.w 1,2,3,4,5,6,7,8,9,10

coperlista2:
dc.w 1,2,
dc.w 3,4
dc.w 5,6
dc.w 7,8
dc.w 9,10

Estos dos grupos son iguales, simplemente expresamos lo mismo de distinta forma. La memoria es realmente una cadena como "coperlista1", pero podemos expresarla como en "coperlista2" para poder ubicarnos mejor y mostrar el trabajo por parejas. Explico esto porque mas adelante nos puede ayudar a entender cosas.


dc.w COLOR00,$000

Esta es facil, mover a color00 el negro. Realmente seria $0180,$000 pero como tenemos cargado el achivo de alias (custom.i) no hace falta memorizar el numero concreto.

dc.w $ac01,$fffe

Esta es mas rara. La posicion del rayo vimos que ocupa un word en formato $YYXX, asi que esta instruccion significa "espera a la linea AC, posicion 01".
¿por que 01 y no 00? Porque sabemos que los pares siempre estan ocupados y no podriamos colar al copper en ese hueco.
El primer word la posicion, en el segundo tenemos el ESPERA/WAIT.


¿Y como lo paro al terminar? pues dandole la posicion $FFFF a la que nunca podemos llegar.


Si volvemos al ejemplo quedaria algo asi:


copperlist:
dc.w color00,$000 color00 negro
dc.w color1,$888 color01 gris
dc.w $ac01,$fffe espera la posicion AC,01
dc.w color01,$00f color01 azul
dc.w $ffff,$fffe espero al "infinito". Paramos. ESTA IMPORTANTISIMA




Ya tenemos nuestra primera lista de copper. Crearlas es sencillo y le quitan todo el trabajo a la CPU que teniamos en nuestro primer programa. Pero entenderlas a fondo necesita otro capitulo,como hace para no confundir una espera con un moviento o con otra orden, el $fffe que usamos como "comando" hay que cogerlo con pinzas.... cosas como la resolucion horizontal, etc...

Avatar de Usuario
Mlake
Mensajes: 21
Registrado: 27 Mar 2019 19:54
Agradecido : 14 veces
Agradecimiento recibido: 71 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Mlake » 07 Abr 2019 21:35

Gracias por el recibimiento. -drinks

Os dejo un ADF (no se si infrinjo alguna norma) con las herramientas y fuentes para toquetear en el Amiga o en UAE. Intetaremos ser compatibles con AGA o modelos "raros".

ASMTwo de Photon, sigue el rollo ASM One, SEKA.... Sencillito y poco exigente, nada de IDEs complejos.
Ojo el que se siente comodo con su SDK de confianza en windows/linux o prefiere algo mas complejo en su amiga mas actual, adelante. Vamos a hacer codigos sencillos. Solo queremos aprender a andar por el chipset.

El disco arranca solo, para ahorrar algunos KB.

http://s000.tinyupload.com/index.php?file_id=06535813212099133683

El funcionamiento es basico:

Lo primero que nos pregunta es que memoria queremos usar (por aquello de montar los hunks)
Nos interesa la chip de momento
Fast ram sabemos lo que es, Absoluta es para ir de bad boys y gestionar la memoria nosotros mismos.

Nos pide una cantidad, con 10k nos sobra.

Imagen

¡¡¡Sí, ademas tenemos "el mega" en el A500!!! -thumbup
No todo el monte es oregano con esta memoria, pero eso lo explicaremos otro dia. -rofl

Los comandos basicos:
Esc para entrar y salir del editor
A ensamblar
J saltar (si lo ejecumatos justo despues de ensamblar, salta a nuestro programa y lo ejecuta)
W salvar
R cargar
WO crear ejecutable.
! Salir

Avatar de Usuario
kikems
Mensajes: 2963
Registrado: 30 May 2013 19:23
Agradecido : 817 veces
Agradecimiento recibido: 1102 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor kikems » 08 Abr 2019 11:22

Está fantástico, me encanta.

jjsaenz1969
Mensajes: 423
Registrado: 21 Oct 2016 15:45
Agradecido : 108 veces
Agradecimiento recibido: 119 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor jjsaenz1969 » 08 Abr 2019 14:37

Igual estoy equivocado, pero no hacen falta los includes para poder programar en ensamblador para Amiga.

Avatar de Usuario
Mlake
Mensajes: 21
Registrado: 27 Mar 2019 19:54
Agradecido : 14 veces
Agradecimiento recibido: 71 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Mlake » 08 Abr 2019 22:36

jjsaenz1969 escribió:Igual estoy equivocado, pero no hacen falta los includes para poder programar en ensamblador para Amiga.

Lo primero gracias por la pregunta/comentario. Me parece muy importante el feedback para saber si las cosas estan claras o no. -drinks

¿Los includes son necesarios?
Respuesta corta, no.
Respuesta larga, sí porque vas a conseguir codigos mas ordenados y legibles. Pero no solo en asm, en cualquier lenguaje.

De hecho en el primer ejemplo hemos puesto las direcciones "a pelo" sin usar archivos externos.

Podemos dejar de usarlos y centrarnos en el numero, pero advierto que va a ser mucho mas difícil. El proximo capitulo lo haremos asi, a ver que tal.

Avatar de Usuario
htdreams
Mensajes: 630
Registrado: 12 Nov 2012 19:34
Agradecido : 32 veces
Agradecimiento recibido: 42 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor htdreams » 08 Abr 2019 23:31

Acabo de llegar a este hilo, que aún no había visto.

Me quito el sombrero, yo también le estuve echando un ojo a la programación de amiga, de primeras en alto nivel, a través de blitz basic2, con el que se hacen cosas chulas, pero cuando me quise meter a más bajo nivel me entraron sudores fríos (como a chema, más o menos XD)

No dispongo de tiempo para morder ahora esto tan jugoso, pero queda apuntado y de vez en cuando seguiré el hilo, muchísimas gracias!!

Eso si, en el amiga wave de este domingo pasado se comentaba acerca de la complejidad de programar las máquinas de 16 bits, y de como se está viendo ahora maravillas en 8 bits... sin duda el salto de complejidad afecta muy mucho

Yo conozco por encima la forma de trabajo del msx, y en su día programé ensamblador para cosillas de la scene en x86 32bits, y la verdad es que me parecía todo mucho más fácil (también hay que decir que usar vga con los modosX y el dma de la SB para el audio te simplificaba cosas, claro XD)

Avatar de Usuario
Mlake
Mensajes: 21
Registrado: 27 Mar 2019 19:54
Agradecido : 14 veces
Agradecimiento recibido: 71 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Mlake » 09 Abr 2019 03:00

CAP 1B El copper en profundidad.

Como vimos en el capitulo antrerior nuestra idea era crear instrucciones a base de una pareja de words para que el copper actue.
Lo basico es ESPERAR (wait) y MOVER (move).
coperlista:
dc.w $0180,$0fff color 0 a negro
dc.w $0182,$0888 color 1 a gris
dc.w $ac01,$fffe espera en posicion $AC,$01
dc.w $0182,$00f color 1 a azul
dc.w $ffff,$fffe espera a la posicion V=$ff H=$ff (infinito) PARAMOS EL COPPER

¿Como hace el copper para distinguir las intrucciones?Muy facil.

Primer WORD
Si es par, es una direccion de chipset. Si es impar lo toma como una posicion de CRT. Facil.

Segundo WORD.
Si el primero era una direccion par, entonces este word es el valor que hay que MOVER. Listo.

Pero si el primero era una direccion impar (CRT), deberiamos esperar... ¿no?
Casi. Como dijimos antes el copper espera y mueve.... pero es que ademas SALTA.
No vamos a ver como funciona, pero si tenemos que saber como distinguirlas y no meter la pata. ¿Como lo hacemos? Igual que en el primer caso. Si es par, ESPERAMOS. Si es impar, SALTAMOS.
Por eso al esperar usabamos FFFE, porque es par.

¿Y por que ese y no un numero par cualquiera? porque realmente ese numero es una mascara, y quiere decir que queremos usar los word ($YYXX) completos. Si solo quisieramos usar la $YY, meteriamos $FF00 que es par (espera) y desecha el byte $XX.

dc.w $AC01,$FF00 ESPERA a la linea AC ignorando la horizontal (porque es par)
dc.w $AC01,$FF01 SALTA si estamos la linea AC ignorando la horizontal (porque es impar)

El trabajo en vertical se ve facil, pero ¿y el horizontal? Con un byte no llego a 320 pixels de ancho y si encima pierdo un bit para saber si es wait o skip (por aquello de tener que poner par o impar) menudo negocio....

Esto lo vimos en la intro, para que el copper mueva algo tenemos tenemos que gastar slots/pixels/tiempo... (dos en el caso del copper que son 2 words).

La horizontal usable (que no en pantalla) es de $00 a $E2, es decir 226 posiciones de parada, quitale la mitad (los pares) para poder meterte, como vimos en la introduccion, el copper gasta dos ciclos a 4 pixels en baja,se tarda 8 pixels por movimiento.
Asi podemos entender que no haga falta tener una resolucion horizontal con mas bytes, porque aunque quisieramos hilar mas fino, el copper tarda un tiempo en buscar hueco y el rayo nos deja atras por unos miseros pixels. De hecho muchas veces no se usa la horizontal tal cual, sino que se empieza a trabajar desde un punto y tu mismo vas calculando donde se van a ejecutar las demas usando eso de contar cada los pixels que vas a gastar.

Espero que no se haya hecho muy coñazo. Solo nos falta probar nuesta primera copperlist. Pero no es tan sencillo como parece.


Imagen

Seguro que alguno se dio cuenta en el primer dia que cuando cambiamos a negro, él solo se volvia a poner azul cuando deberia haberse quedado asi hasta nueva orden.....
La razon es que el sistema ya tiene funcionando una coperlist que se encarga del interfaz grafico, ella se encarga de volver a restaurar el color al empezar el frame. Podriamos cargar la nuestra con una linea de codigo pero..... ¿como vuelvo al sistema si me lo he cargado cepilladome la suya? Tenemos que hablar con el SO para saber la direccion de la que está usando, para poder restaurarla nosotros al salir.

Esto nos va a obligar a hacer una parada rapida en el kernel y seguir nuestro camino. Con suerte lo mismo podemos empezar a montar un playfield.

Proxima parada, graphics.library,secuestro del copper y nuestros primeros pixels
.

Avatar de Usuario
Chema
Mensajes: 2124
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 1520 veces
Agradecimiento recibido: 484 veces
Contactar:

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Chema » 09 Abr 2019 14:49

¡Quiero tiempo libre para empezar a probar! -banghead -banghead

Avatar de Usuario
Mlake
Mensajes: 21
Registrado: 27 Mar 2019 19:54
Agradecido : 14 veces
Agradecimiento recibido: 71 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Mlake » 11 Abr 2019 18:50

CAP2 Parada en Exec para apoderarnos del copper.

Hemos apretado el codigo para meterlo en la captura pero creo que se entiende lo que vamos a hacer.

Imagen

Buscamos hueco en memoria.

En lugar de incluir el custom.i para tener todos los alias del chipset, he puesto a mano solo los que vamos a usar.
inicio:

Empezamos lanzando una rutina llamada OSoff que nos "apaga" el SO. (Lo explicamos mas abajo)

Activamos nuestra copperlist
http://amiga-dev.wikidot.com/hardware:cop1lch

Esto es sencillo. Para que el copper sepa donde tiene sus ordenes necesita una direccion que apunte a una copperlist. De eso se encargan $DFF080 y $DFF082 (alias COP1LCH y COP1LCL). Está dividida en dos porque sabemos que el chipset se maneja en words. Explico esto porque desde la CPU podemos mandar una doble palabra sin problema y llenar la direccion completa, pero el copper (al mover words) siempre va a necesitar una mitad alta (H) y una mitad baja (L) para todo lo que sea apuntar a direcciones (leer bitmaps, sprites, offsets de memoria para copiar cosas....).
Una vez escrita la direccion, la copperlist se ejecutará en cuanto el rayo vuelva a empezar el nuevo frame. Hemos inciado nuestra lista.


Llegados aqui, tenemos nuestro loop. Como tenemos trabajando al copper, solo tenemos que estar pendientes del raton para salir.

Volvemos a activar el SO al salir y listo.

Debajo tenemos la copperlist con lo que habiamos hecho en el anterior capitulo. Esperabamos a mitad de pantalla, cambiamos a negro, esperamos 16 lineas mas abajo ($AC/$BC),volviamos al azul workbench y esperabamos al "infinito" para parar el copper.

Lo ejecutamos y tenemos esto.

Imagen

¿Que ha pasado? Pues lo esperable.... La copper es el que automatiza el trabajo (bitmaps de la imagen, interrupciones del raton, sprites...), asi que todo se ha quedado parado porque nuestra lista es demasiado "sencilla". De hecho, para los que se fijaron al detalle en el codigo, tuvimos que poner el color workbench a mano al principio del copperlist.

¿Entonces toca "resetear"? no, esta vez hemos estado cucos y hemos hecho los deberes.


Una visita furtiva a Exec.

Exec es la parte intima del SO, se encarga de comunicarnos a nosotros con el sistema, se encarga de la multitarea, manejo de memoria, interrupciones y librerias.
Nuestro plan va a ser el siguiente.

Vamos a coger el estado de las interrupciones y la configuracion del DMA que hay en ese momento, los guardaremos en unas variables/posiciones de memoria. Eso lo podemos hacer con lo que sabemos.

Despues pasaremos al Exec, le diremos que abra la libreria de los graficos y alli encontraremos la direccion de la copperlist en uso. No podemos leerla desde COP1LCH porque es una direccion de escritura, ese es el motivo de nuestra incursion.

Una vez encontrada, la guardamos en otra variable junto a las demas.

Despues de esto, apagamos todo y nos hacemos con el control del Amiga.

Esta es la teoria, ahora a llevarlo a la practica.

Imagen
Imagen


Como siempre hay que abrir el manual y buscar un par de direcciones nuevas.
DMACON, INTENA e INTREQ . Estos son de escritura y tienen su version de lectura : DMACONR, INTENAR e INTREQR.

Estos se encargan de encender y apagar DMAs e interrupcciones.
http://amiga-dev.wikidot.com/hardware:dmaconr
http://amiga-dev.wikidot.com/hardware:intenar
http://amiga-dev.wikidot.com/hardware:intreqr

Como explicamos en la introduccion, el chipset gestiona la memoria dividiendo el tiempo del DMA en slots, nosotros podemos controlar el acceso a distintos componentes para tener mas espacio para hacer cosas. Podemos cerrar/abrir el audio, copper, bitplanes, audio, sprites.....

Las interrupciones son como en otros cacharros. El sistema te propone unas situaciones (llegada del Vblank,señal de input en el teclado....) y tambien se pueden encender/apagar.

Nuestra mision es hacer copia (por eso usamos la version R, de lectura). Leemos y guardamos en olddmacon, oldintena y oldintreq.


Como habeis leido en el link, para encender/apagar hay que usar el bit 15 y despues elegir las zonas a cambiar.Por eso no basta con hacer una copia.
Nosotros vamos a recibir un word con los bits que estan encendidos (hasta ahi claro), pero para darles uso hay que activar el bit "maestro", por eso OReamos con $8000, porque asi activamos el bit 15 dejando el resto intacto.

Antes de OR Despues de OR
%0xxxxxxxx %1xxxxxxxx

De esta forma, cuando restauremos, iran con el bit encendido y el amiga entenderá que lo que quieres es encender y no apagar (si no hubieramos OReado).

Primer obstaculo superado, ahora a por el copper.



El Exec se encuentra al principio de la memoria $00000004 y funciona a base de offsets (LVO).

Cada funcion que es capaz de ejecutar se hace dandole unos parametros y saltando a un offset.
Vamos a abrir una libreria asi que tiene que saber 2 cosas, que libreria abrir y cual es el offset de la funcion OldOpenLibrary().

El nombre de la libreria es graphics.library y la tenemos declarada en un string (gfxlib).
El offset de OldOpenLibrary es -408

Ahora viene el funcionamiento de Exec.

Lo primero, cargar la direccion base ($4) en A6. Hasta ahi claro.

Una vez hecho esto y antes de saltar al offset, hay que darle unos parametros y para eso se usan los registros.
Esto es comun a todas las funciones.

Vamos a saltar a -408 (OldOpenLibrary), asi que hay que ver que parametros admite.En este caso solo 1.
La direccion del string con el nombre de la lib tiene que estar en A1.

En funciones mas complejas te puede decir, puen pon en A1 tal cosa, en D0 otra, en A2 otra... y asi. Todo esto antes de dar el salto.


Una vez hecho el salto (funcion), nos devuelven un resultado siguiendo la misma idea. en A1 te dejo esto, en D0 lo otro,en D1 lo que sea....
Ahora que hemos recibido la direccion de la libreria en D0. Podemos detriparla....

Lo unico que nos interesa es saber donde esta la coperlist original y eso se consigue en el offset 38 de esa libreria. Dicho y hecho, metemos D0 en A1 y en 38(A1) aparece el objeto del deseo. Copiamos el longword con las dos mitades y lo guardamos en la variable oldcopper.

Tenemos todo, es hora de irnos.

¿Por que use A1 para la libreria? porque nos va a servir como parametro para otra funcion, CloseLibrary() que tiene un offset (salto) de -414.
Asi cerramos la libreria antes de irnos.
Como hicimos antes, la base del Exec en A6, parametro en A1 y salto a -414(A6)

Mision completa ¿Y ahora?
Ahora apagamos todo, interrupciones y DMAs.
Como no usaremos interrupciones, solo pondremos los DMA a nuestro gusto. En este caso dejaremos apagados los sprites y la musica. No los estamos usando y ganaremos unos slots.
Con el libro en la mano vemos como funciona la cosa.
El bit 15 dice si encendemos o apagamos y el resto que hayan elegido 1 siguen la orden.
$7FFF, bit maesto apagado y todos los demas seleccionados. Resultado, todos se apagan
$87c0, bit maesto encendido, Todo encendido salvo audio, sprites y cosas del blitter.

Listo
Muchos de los que pilotan con el SO, aprovechan para desablitar multitarea, liberar memoria, esperar unos frames para los que usan RTG y mas... pero solo queria entrar a hacer lo justo y no liar al personal. Despues cerramos por las bravas y toqueteamos el hard (que es de lo que va el hilo)
Hemos apagado el SO y para volverlo a encender, solo hay que copiar los valores originales y OReados a dmacon, intena,etc... restaurar copperlist original y fin.

Son dos rutinillas que aunque cueste pillarles el rollo, las puedes copiar/pegar y no molestan porque solo las llamas una vez, al entrar/salir del programa.

Solo queda un detalle y es el vaitVB, basicamente es una rutina que espera a llegar al final del frame. Ese es el momento para hacer muchas tareas de limpieza sin que afecten a la imagen. En este caso la hemos usado para hacer que los cambios en intena/dma/etc no hicieran "cosas raras".
Si aun estas como al principio y solo quieres trabajar con el copper, no te olvides de pegar estas rutinas (OSon, OSoff, waitVB). Despreocupate del resto.



POKEando copperlist.

Imagino que ya os habeis cansado de hacer pruebas con el "ejemplo3" asi que vamos un paso mas alla. Editar nuestras listas sobre la marcha.
Nuestra triste barra solo necesitaba unos puntos para ser generada, y tenemos la CPU muerta de risa. ¿Por que no cambiar los puntos cada vez que termina un frame y asi le damos vida a nuestra triste ""rasterbar""?

Imagen

¡¡¡De aqui a la Posadas chavales!!! -grin

Imagen

No tiene mucha ciencia, D7 contiene la posicion, d6 la velocidad y D5 el ancho de la barra.

Sumamos la velocidad a la posicion comprobando los bordes
El resultado final lo copiamos a las zonas necesarias dentro de nuesta lista .

Hasta aqui facil, lo unico a tener en cuenta es que entre animaciones, tenemos que volver a esperar a que acabe el frame. De otra forma, el programa calcularia demasiado rapido la posicion que tiene que copiar y no le daria tiempo al rayo a dibujar.

Imagen


Una vez pillas el truco, puedes editar las listas para lo que necesites. O incluso generar una sobre la marcha.

Como premio por aguantar la chapa, que menos que darle un final digno a nuestra barra.

Imagen


Hasta pronto fiel amiga. -drinks

Avatar de Usuario
Chema
Mensajes: 2124
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 1520 veces
Agradecimiento recibido: 484 veces
Contactar:

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Chema » 11 Abr 2019 21:24

Despacio, despacio, que voy lento pero seguro...

Ya me he hecho el primer capítulo -thumbup
curso1.png
curso1.png (16.82 KiB) Visto 298 veces


Estoy con un toolchain cruzado (vasm y vbcc) y juntando C y ASM, así que tengo que adaptar cosas. El custom.i incluido en la libería no trae símbolos para custom ni para colorXX.

Hice move.l #$dff000, a0
y luego accedí a los registros con vhposr(a0) y color+00(a0)

Venga, es mi primer programa en asm para Amiga!!!

Avatar de Usuario
Mlake
Mensajes: 21
Registrado: 27 Mar 2019 19:54
Agradecido : 14 veces
Agradecimiento recibido: 71 veces

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Mlake » 11 Abr 2019 21:41

Chema escribió:Despacio, despacio, que voy lento pero seguro...

Ya me he hecho el primer capítulo -thumbup

Estoy con un toolchain cruzado (vasm y vbcc) y juntando C y ASM, así que tengo que adaptar cosas. El custom.i incluido en la libería no trae símbolos para custom ni para colorXX.

Hice move.l #$dff000, a0
y luego accedí a los registros con vhposr(a0) y color+00(a0)

Venga, es mi primer programa en asm para Amiga!!!

La version del custom.i en el adf que puse, estaba "tuneada" para poder explicarlo con custom+alias.Tu opcion es la correcta,cargar custom en una direccion y tirar de offset. :wink:

Para aprender veo mas visual la que puse. En los demas ejemplos incluyo directamente en el codigo de los alias del chipset que vamos a usar.

Lo unico complicado hasta ahora es apagar el SO. Quiza te sea mas facil usar C para eso.
Lo demas seguro que lo sacas del tiron. -thumbup



El link del ADF esta actualizado al ultimo ejemplo.

Avatar de Usuario
Chema
Mensajes: 2124
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 1520 veces
Agradecimiento recibido: 484 veces
Contactar:

Re: Toqueteando las tripas del OCS en ASM. Nivel -1

Mensajepor Chema » 12 Abr 2019 00:45

Hala. Ya hice mi primera copperlist :) a ver si mañana hago el ejemplo 4...

Muchas gracias por todo. Esta es la manera de ir aprendiendo. Eso sí, si el copper es realmente una chorrada comparado con el blitter... no quiero ni pensarlo XD


Volver a “Software & OS Amiga”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado