Advertisement
NightFox

Pages Detection

Apr 25th, 2020
1,699
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;***********************************************************
  2. ;
  3. ;   MSX DIAGNOSTICS
  4. ;   Version 1.1.6
  5. ;   ASM Z80 MSX
  6. ;   Rutinas del VDP
  7. ;   (cc) 2018-2020 Cesar Rincon "NightFox"
  8. ;   https://nightfoxandco.com
  9. ;
  10. ;***********************************************************
  11.  
  12.  
  13.  
  14. ; ----------------------------------------------------------
  15. ;  Detecta el layout de slots y RAM instalada
  16. ; ----------------------------------------------------------
  17.  
  18. FUNCTION_MEMORY_GET_CONFIG:
  19.  
  20.     call FUNCTION_MEMORY_GET_SLOT_LAYOUT        ; Configuracion de SLOTS
  21.     call FUNCTION_MEMORY_GET_MEMORY_LAYOUT      ; Configuracion de memoria
  22.     ret
  23.  
  24.  
  25.  
  26.  
  27. ; ----------------------------------------------------------
  28. ;  Detecta el layout de slots
  29. ; ----------------------------------------------------------
  30.  
  31. FUNCTION_MEMORY_GET_SLOT_LAYOUT:
  32.  
  33.     ; B = Contador del bucle
  34.     ; C = Contador del numero de SLOT
  35.  
  36.     ; Recorre los slots y marca si estan expandidos
  37.     ld bc, $0400                            ; B = 4 slots  /  C = Empieza en el slot 0
  38.     @@SLOT_CHECK_LOOP:
  39.  
  40.         ld d, 0                             ; Verificacion de slot expandido
  41.         ld e, c                             ; Sumale el nº de slot (DE)
  42.         ld hl, $FCC1                        ; A la direccion de informacion
  43.         add hl, de                          ; de slots expandidos
  44.  
  45.         ld a, [hl]                          ; Lectura del estado del slot
  46.  
  47.         ld hl, SLOT_EXPANDED                ; Variable para almacenar el resultado
  48.         add hl, de                          ; Sumale el nº de slot (continua guardado en DE)      
  49.  
  50.         bit 7, a                            ; Esta expandido?
  51.         jr z, @@SLOT_CHECK_NOT_EXPANDED     ; Si no esta expandido, saltate esta parte
  52.  
  53.         ; Marca que es un slot expandido
  54.         ld [hl], $0B                        ; Guarda que es expandido (11)
  55.         jr @@SLOT_CHECK_LOOP_END            ; Salta al final del bucle
  56.  
  57.         ; Slot no expandido
  58.         @@SLOT_CHECK_NOT_EXPANDED:
  59.         ld [hl], $00                        ; Guarda que NO es expandido (0)
  60.  
  61.         @@SLOT_CHECK_LOOP_END:
  62.         inc c                               ; Siguiente slot
  63.         djnz @@SLOT_CHECK_LOOP              ; Fin del bucle principal (SLOTS)
  64.  
  65.     ; Final de la funcion
  66.     ret
  67.  
  68.  
  69.  
  70. ; ----------------------------------------------------------
  71. ;  Detecta el layout de memoria
  72. ; ----------------------------------------------------------
  73.  
  74. FUNCTION_MEMORY_GET_MEMORY_LAYOUT:
  75.  
  76.     ; Pon a 0 el contador de RAM
  77.     ld hl, RAM_DETECTED     ; Variable BCD
  78.     ld b, 3                 ; 3 bytes (6 digitos)
  79.     @@RESET_RAM_COUNTER:
  80.         xor a
  81.         ld [hl], a
  82.         inc hl
  83.         djnz @@RESET_RAM_COUNTER
  84.  
  85.     ; Pon a 0 los indicadores de bancos
  86.     ld hl, RAM_SLOT_0
  87.     ld b, 16            ; 4 slots x 4 sub-slots
  88.     @@RESET_RAM_BANKS_COUNTER:
  89.         xor a
  90.         ld [hl], a
  91.         inc hl
  92.         djnz @@RESET_RAM_BANKS_COUNTER
  93.  
  94.     ; Recorre los slots y marca si estan expandidos
  95.     ld bc, $0400                            ; B = 4 slots  /  C = Empieza en el slot 0
  96.     @@SLOT_CHECK_LOOP:
  97.  
  98.         ; Preserva los contadores del bucle
  99.         push bc
  100.  
  101.         ld a, c         ; Registra el ID de slot
  102.         and $03         ; Bitmask del nº de slot (xxxxxx11)
  103.         ld [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)], a
  104.  
  105.         ; El slot esta expandido?
  106.         ld hl, SLOT_EXPANDED        ; Lee el flag de expansion (!0 = Expandido)
  107.         ld d, 0                     ; Del nº de slot
  108.         ld e, c
  109.         add hl, de                  ; Sumale el offset del nº de slot
  110.         ld a, [hl]
  111.         or a
  112.         jp z, @@SLOT_IS_NOT_EXPANDED
  113.  
  114.         ; Slot expandido
  115.         ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]
  116.         set 7, a
  117.         ld [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)], a
  118.  
  119.         ; Bucle de SUB-SLOTS
  120.         ld bc, $0400                        ; B = 4 slots  /  C = Empieza en el sub-slot 0
  121.         @@SUBSLOT_CHECK_LOOP:
  122.  
  123.             ; Preserva los contadores del bucle
  124.             push bc
  125.  
  126.             ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]   ; Lee la informacion de SLOT y FLAG (1xxxxx11)
  127.             and $83     ; BITMASK (1xxxxx11)
  128.             sla c       ; Bitshift << 2
  129.             sla c       ; Para colocar el nº de sub-slot en la posicion correcta (xxxx11xx)
  130.             or c        ; Añade la informacion al ID de slot
  131.             ld [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)], a   ; Y guarda el ID completo
  132.  
  133.             call FUNCION_MEMORY_GET_SLOT_RAM    ; Busca toda la RAM en ese SUB-SLOT
  134.  
  135.             pop bc                              ; Restaura los contadores del bucle
  136.             inc c                               ; Siguiente slot
  137.             djnz @@SUBSLOT_CHECK_LOOP           ; Fin del bucle secundario (SUB-SLOTS)
  138.  
  139.         jr @@SLOT_CHECK_LOOP_END                ; Salta al final del bucle principal
  140.  
  141.  
  142.         ; El slot no esta expandido
  143.         @@SLOT_IS_NOT_EXPANDED:
  144.         call FUNCION_MEMORY_GET_SLOT_RAM        ; Busca toda la RAM en ese SLOT
  145.  
  146.         @@SLOT_CHECK_LOOP_END:
  147.         pop bc                              ; Restaura los contadores del bucle
  148.         inc c                               ; Siguiente slot
  149.         djnz @@SLOT_CHECK_LOOP              ; Fin del bucle principal (SLOTS)
  150.  
  151.     ; Fin de la funcion
  152.     ret
  153.  
  154.  
  155.  
  156. ; ----------------------------------------------------------
  157. ; Funcion para detectar toda la RAM posible
  158. ; ----------------------------------------------------------
  159.  
  160. FUNCION_MEMORY_GET_SLOT_RAM:
  161.  
  162.     ; Paginas 0, 1 y 2 sin mapper
  163.     call FUNCION_MEMORY_GET_RAM_PAGES012_NO_MAPPER
  164.     ; Pagina 3 sin mapper
  165.     call FUNCION_MEMORY_GET_RAM_PAGE3_NO_MAPPER
  166.  
  167.     ; Vuelve
  168.     ret
  169.  
  170.  
  171.  
  172. ; ----------------------------------------------------------
  173. ; Funcion para detectar la RAM en las
  174. ; paginas 0, 1 y 2 SIN MAPPER
  175. ; ----------------------------------------------------------
  176.  
  177. FUNCION_MEMORY_GET_RAM_PAGES012_NO_MAPPER:
  178.  
  179.     ld hl, $0000        ; Direccion inicial de la pagina
  180.     ld [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)], hl
  181.     ld b, $0C           ; Paginas del 0 al 3 en pasos de 4kb (12 X 4)
  182.  
  183.     @@CHECK_PAGES_LOOP:
  184.  
  185.         push bc         ; Preserva los contadores del bucle
  186.  
  187.         di              ; Deshabilita las interrupciones
  188.  
  189.         ; Paso 1, lee 1 byte
  190.         ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]       ; ID de slot
  191.         ld hl, [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)]    ; Direccion de la pagina
  192.         call $000C      ; Lee un byte del slot con la ID en A de la direccion HL (RDSLT)
  193.         ld b, a         ; Respaldo del byte leido
  194.         cpl             ; Invierte los bits
  195.  
  196.         ; Paso 2, escribelo invertido
  197.         ld e, a         ; Byte a escribir
  198.         ld c, a
  199.         ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]       ; ID de slot
  200.         ld hl, [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)]    ; Direccion de la pagina
  201.         push bc
  202.         call $0014      ; Escribe un byte (E) en el slot con la ID en A en la direccion HL (WRSLT)
  203.  
  204.         ; Paso 3, vuelvelo a leer y compara si es el mismo que has escrito
  205.         ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]       ; ID de slot
  206.         ld hl, [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)]    ; Direccion de la pagina
  207.         call $000C      ; Lee un byte del slot con la ID en A de la direccion HL (RDSLT)
  208.         pop bc
  209.         cp c                        ; Son iguales ?
  210.         jr nz, @@NOT_RAM            ; No lo son, es ROM
  211.  
  212.         ; Paso 4, restaua el byte original en su sitio
  213.         ld e, b         ; Byte a escribir (restaura el original)
  214.         ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]       ; ID de slot
  215.         ld hl, [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)]    ; Direccion de la pagina
  216.         call $0014      ; Escribe un byte (E) en el slot con la ID en A en la direccion HL (WRSLT)
  217.  
  218.         ; Paso 5, Suma 4kb de esta pagina
  219.         call FUNCTION_MEMORY_COUNTER_ADD_4KB
  220.  
  221.         @@NOT_RAM:
  222.  
  223.         ei              ; Habilita las interrupciones
  224.  
  225.         pop bc          ; Restaura el contador del bucle
  226.  
  227.         ld hl, [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)]
  228.         ld de, $1000        ; Siguiente pagina
  229.         add hl, de
  230.         ld [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)], hl
  231.        
  232.         djnz @@CHECK_PAGES_LOOP
  233.  
  234.     ; Fin de la funcion
  235.     ret
  236.  
  237.  
  238.  
  239. ; ----------------------------------------------------------
  240. ; Funcion para detectar la RAM en la pagina 3
  241. ; en todos los slots/sub-slots, sin mapper
  242. ; ----------------------------------------------------------
  243.  
  244. FUNCION_MEMORY_GET_RAM_PAGE3_NO_MAPPER:
  245.  
  246.     ; Informa de la direccion inicial de memoria del test
  247.     ld hl, $C000        ; Direccion inicial de la pagina
  248.     ld [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)], hl
  249.  
  250.     ld b, 4     ; 4 segmentos de 4kb
  251.     @@CHECK_CHUNKS_LOOP:
  252.  
  253.         ; Preserva los registros del contador
  254.         push bc
  255.         push hl
  256.  
  257.         ; Copia de seguridad en BC de la configuracion de slots
  258.         di              ; Desconecta las interrupciones
  259.         in a, [$A8]     ; Configuracion de slots
  260.         ld b, a         ; Y guardalo en B
  261.         ld a, [$FFFF]   ; Configuracion de subslots
  262.         cpl             ; Complementalo
  263.         ld c, a         ; Y guardalo en C
  264.         exx             ; Manda el set de registros a la sombra, trabaja con los alternativos
  265.  
  266.         ; Seleccion de la direccion de memoria a analizar
  267.         ld hl, [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)]
  268.  
  269.         ; Seleccion de slots
  270.         ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]
  271.         rrca
  272.         rrca
  273.         and $C0
  274.         ld b, a         ; Configuracion deseada de slot en B
  275.  
  276.         ; Esta expandido?
  277.         ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]
  278.         bit 7, a
  279.         jr z, @@NOT_EXPANDED
  280.  
  281.         ; Esta expandido
  282.         sla a               ; Coloca los bits de sub-slot en los bits 6 y 7 (<< 4)
  283.         sla a
  284.         sla a
  285.         sla a
  286.         and $C0             ; Bitmask de esos bits
  287.         ld c, a             ; Guardalo en C
  288.         in a, [$A8]         ; Lee la configuracion de slots actual
  289.         and $3F             ; Guarda la configuracion de las paginas 0 a 2
  290.         or b                ; Añade la configuracion de la pagina 3 de slots
  291.         out [$A8], a        ; Selecciona esa configuracion de slots
  292.         ld a, [$FFFF]       ; Lee la configuracion de sub-slots
  293.         cpl                 ; Complementala
  294.         and $3F             ; Guarda la configuracion de las pagina 0 a 2
  295.         or c                ; Añade la configuracion de la pagina 3 de sub-slots
  296.         ld [$FFFF], a       ; Aplica la configuracion de sub-slots
  297.         jr @@TEST_IF_RAM
  298.  
  299.         ; No esta expandido
  300.         @@NOT_EXPANDED:
  301.         in a, [$A8]         ; Lee la configuracion de slots actual
  302.         and $3F             ; Guarda la configuracion de las paginas 0 a 2
  303.         or b                ; Añade la configuracion de la pagina 3 de slots
  304.         out [$A8], a        ; Selecciona esa configuracion de slots
  305.  
  306.         ; Verifica si el primer byte de la pagina es RAM
  307.         @@TEST_IF_RAM:
  308.         ld a, [hl]          ; Lee un byte
  309.         ld b, a             ; Guardalo el valor leido en B
  310.         cpl                 ; Saca el complementario (invierte todos los bits)
  311.         ld c, a             ; Guarda el complementario en C
  312.         ld [hl], a          ; Vuelve a escribirlo
  313.         ld a, [hl]          ; Y leelo nuevamente
  314.         cp c                ; Comparalo con el valor que acabas de escribir
  315.         jr nz, @@NOT_RAM    ; Si no coincide, no es RAM
  316.         ld a, b             ; Y restaura el valor original del byte
  317.         ld [hl], a
  318.         ld a, $FF           ; Indica que es RAM
  319.         jr @@RESTORE_SLOTS_CONFIG
  320.  
  321.         @@NOT_RAM:
  322.         ld a, $00           ; Indica que no es RAM
  323.  
  324.         @@RESTORE_SLOTS_CONFIG:
  325.         exx                 ; Recupera el set de registros de la sombra, trabaja con los normales
  326.         ld e, a             ; Guarda si es RAM ($FF) en E
  327.         ld a, b             ; Restaura la configuracion de slots
  328.         out [$A8], a
  329.         ld a, c             ; Y la configuracion de subslots
  330.         ld [$FFFF], a
  331.  
  332.         ei                  ; Habilita las interrupciones
  333.         ld a, $FF           ; Era RAM?
  334.         cp e
  335.         jr nz, @@LOOP_ENDS
  336.         call FUNCTION_MEMORY_COUNTER_ADD_4KB        ; Si era RAM, marcalo
  337.  
  338.         ; Fin de la funcion
  339.         @@LOOP_ENDS:
  340.  
  341.         pop hl          ; Recupera los registros del contador
  342.         pop bc
  343.  
  344.         ld de, $1000    ; Siguiente segmento de memoria
  345.         add hl, de
  346.         ld [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)], hl
  347.  
  348.         djnz @@CHECK_CHUNKS_LOOP        ; Fin del bucle
  349.  
  350.     ; Sal de la funcion
  351.     ret
  352.  
  353.  
  354.  
  355.  
  356. ; ----------------------------------------------------------
  357. ; Funcion para sumas 4kb al contador de RAM
  358. ; ----------------------------------------------------------
  359.  
  360. FUNCTION_MEMORY_COUNTER_ADD_4KB:
  361.  
  362.     ; Sumando
  363.     ld hl, NGN_RAM_BUFFER
  364.     ld [hl], $04
  365.     inc hl
  366.     ld [hl], $00
  367.     inc hl
  368.     ld [hl], $00
  369.     ; Numero base
  370.     ld de, RAM_DETECTED
  371.     ld hl, NGN_RAM_BUFFER
  372.     ; Realiza la suma
  373.     call NGN_BCD_ADD
  374.     ; Marca el banco de memoria
  375.     call FUNCTION_MEMORY_MARK_RAM_BANK
  376.     ; Vuelve
  377.     ret
  378.  
  379.  
  380. ; ----------------------------------------------------------
  381. ; Funcion para marcar bancos de RAM en los slots
  382. ; ----------------------------------------------------------
  383.  
  384. FUNCTION_MEMORY_MARK_RAM_BANK:
  385.  
  386.     ; Lee la direccion actual
  387.     ld hl, [(NGN_RAM_BUFFER + MEMORY_PAGE_ADDR)]
  388.     ; Marca el BIT de la pagina actual en C
  389.     ; Calcula el numero de pagina
  390.     ld a, h
  391.     ld b, 6
  392.     @@GET_PAGE_NUMBER:
  393.         srl a       ; >> 1
  394.         djnz @@GET_PAGE_NUMBER
  395.     ld b, a             ; Guarda el resultado en B (numero de pagina)
  396.     ld c, 1             ; Marca de la pagina 0 (bit 0) por defecto en C
  397.     or a
  398.     jr z, @@BITS_SET    ; Si es la pagina 0, salta esta parte
  399.  
  400.     @@SET_BITS:         ; Desplaza tantos bits como numero de paginas
  401.         sla c           ; Siguiente bit << 1
  402.         djnz @@SET_BITS
  403.  
  404.     @@BITS_SET:             ; C = RESULTADO
  405.     ; Busca la variable que guarda el slot actual
  406.     ld hl, RAM_SLOT_0
  407.     ; Calcula el offset segun el slot
  408.     ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]
  409.     and $03     ; bitmask del slot
  410.     ld b, a     ; Prepara el desplazamiento
  411.     or a
  412.     jr z, @@NO_SLOT_OFFSET
  413.     ld de, $0004
  414.     @@CALCULATE_SLOT_OFFSET:
  415.         add hl, de
  416.         djnz @@CALCULATE_SLOT_OFFSET
  417.     @@NO_SLOT_OFFSET:
  418.     ; Calcula el offset segun el sub-slot
  419.     ld a, [(NGN_RAM_BUFFER + MEMORY_SLOT_ID)]
  420.     srl a       ; Desplazamiento del sub-slot
  421.     srl a
  422.     and $03     ; Bitmask del subslot
  423.     ld b, a     ; Prepara el desplazamiento
  424.     or a
  425.     jr z, @@NO_SUBSLOT_OFFSET
  426.     @@CALCULATE_SUBSLOT_OFFSET:
  427.         inc hl
  428.         djnz @@CALCULATE_SUBSLOT_OFFSET
  429.     @@NO_SUBSLOT_OFFSET:
  430.  
  431.     ld a, [hl]      ; Carga el registro de paginas del slot/sub-slot
  432.     or c            ; Añadelas
  433.     and $0F         ; Bitmask de los 4 primeros bits
  434.     ld [hl], a      ; Actualiza el registro
  435.  
  436.     ; Sal de la funcion
  437.     ret
  438.  
  439.  
  440.  
  441.    
  442.  
  443. ;***********************************************************
  444. ; Fin del archivo
  445. ;***********************************************************
  446. MEMORY_ROUTINES_EOF:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement