Program Club

Commodore 64에서 화면 테두리에 그리기

proclub 2020. 12. 31. 22:19
반응형

Commodore 64에서 화면 테두리에 그리기


확인. 25 년 이래 호기심이 많고 속임수를 이해하고 싶어서 닫히지 않기를 바랍니다.

commodore 64에서 국경은 6569 VIC에 의해 처리되지 않았습니다. 커서가 이동 한 중앙 영역에 픽셀을 그리는 것이 전부였습니다. 테두리는 항상 똑같 았지만 정확하게 기억한다면 poke 53280으로 색상을 변경할 수 있습니다.

그럼에도 불구하고 나는 완전히 주소를 지정할 수있는 것처럼 테두리에 그래픽이있는 게임 인트로를 분명히 기억합니다. 나는 그것이 어떻게 작동하는지 이해하려고 노력했지만 요점을 얻지 못했습니다. 전설에 따르면 어떤 상황에서는 국경에 그릴 수있는 스프라이트를 영리하게 사용했다고합니다.하지만 이것이 도시의 전설인지는 모르겠습니다.

편집 : 제공된 링크 중 하나에서 이것을 읽으십시오.

스프라이트는 수직 래스터 라인에 걸쳐 다중화되었습니다 (8 개 이상의 스프라이트, 때로는 최대 120 개의 스프라이트). Group Crest가 2007 년 5 월 Krestage 3를 출시하기 전까지는 한 래스터 라인에 8 개 이하의 스프라이트가 나타날 수 없다는 일반적인 인식이 있었지만 새로운 Y 좌표를 할당하면 화면 아래 더 아래로 다시 나타납니다.

이건 사악하다 .... 래스터를 이기고 스프라이트가 도착하기 전에 위치를 변경합니다 ...


첫째, 스프라이트 만 테두리 영역에 표시되거나 비디오 뱅크의 마지막 바이트 (보통 $ 3fff)에서 읽은 반복되는 8 비트 패턴 (8 픽셀 너비)으로 표시 될 수 있습니다. 이러한 스프라이트 또는 8 비트 패턴은 VIC 칩이 테두리를 "표시하지 않도록"속일 때만 볼 수 있습니다. 아래를 참조하십시오.

테두리는 스프라이트보다 우선 순위가 높으므로 일반적으로 테두리 영역에 스프라이트를 그릴 때 테두리가 스프라이트를 덮습니다. 약간의 VIC 칩 속임수로 테두리를 끌 수 있습니다.

위쪽 및 아래쪽 테두리를 아주 쉽게 해제 할 수 있으며 (아래에서 설명하겠습니다) 매우 중요한 타이밍에 측면 테두리를 해제 할 수 있습니다.

먼저 VIC 칩이 c64에서 작동하는 방법에 대한 정보입니다.

VIC 칩은 전체 화면이 그려 질 때까지 화면을 왼쪽 상단에서 오른쪽 상단으로 그리고 한 줄 아래로 그리고 왼쪽에서 오른쪽으로 다시 그립니다. 이 다시 그리기는 초당 50 회 (PAL 장치의 경우) 또는 (NTSC 장치의 경우) 초당 60 회 수행합니다.

주어진 시간에 래스터의 수직 위치를 포함하는 8 비트 VIC 레지스터가 있습니다. $ d012. 실제로 가능한 위치는 255 개 이상이므로 9 번째 비트는 비트 7 (가장 높은 비트) 또는 레지스터 $ d011에 저장됩니다. 따라서 언제든지 이러한 레지스터를 읽고 래스터의 수직 위치를 찾을 수 있습니다. 래스터의 x 위치를 읽을 수있는 레지스터가 없습니다.

VIC 칩의 또 다른 멋진 기능은 하드웨어 스크롤링을 사용할 때 문제를 해결하는 데 사용되었습니다. 기본 수직 스크롤링은 하드웨어 레지스터를 사용하여 화면을 수직으로 0-7 픽셀 이동함으로써 이루어졌습니다. 한도 (스크롤 방향에 따라 0 또는 7)에 도달하면 각 문자 블록 (8x8 픽셀)을 세로로 한 블록 이동하고 위쪽 (또는 아래쪽 방향에 따라)에 표시 할 새 데이터를 그립니다. 이것은 8 픽셀의 스크롤마다 화면에 데이터가 "팝"표시된다는 점을 제외하면 매우 잘 작동합니다. 이 문제를 해결하려면 $ d011 레지스터에서 비트 3을 지워 테두리 영역을 세로로 8 픽셀 씩 늘릴 수 있습니다. 이를 24 행 모드라고합니다. 기본적으로 화면은 8x8 픽셀 문자의 25 행으로 설정되었습니다. 24 행 모드에서는 맨 아래 행에 문자를 그릴 수 있으며 테두리로 가려집니다.

따라서 위쪽 및 아래쪽 테두리를 끄는 방법은 다음과 같습니다.

1) 화면을 25 열 모드로 설정

2) 래스터가 $ f2와 $ fa 사이의 수직 위치에 도달 할 때까지 기다립니다 (24 행 모드와 25 행 모드 모두에서 테두리가 시작되는 위치 사이의 8 픽셀).

3) 화면을 24 행 모드로 설정 ... 테두리의 수직 시작을 현재 래스터 위치 위로 이동

4) 수직 래스터 위치 ($ fa)까지 기다립니다.

5) 각 프레임 반복

3 단계) VIC 칩이 이미 테두리 그리기를 시작했다고 생각하도록 속여 그리기 시작하지 않습니다. Voila, 상단 및 하단 테두리가 열려 있습니다.

측면 테두리와 관련하여 다른 레지스터로 동일한 작업을 수행 할 수 있지만 래스터의 수평 이동이 수직 이동보다 훨씬 빠르기 때문에 타이밍이 훨씬 더 타이트해야합니다. 그리고 고려해야 할 또 다른 문제는 지터입니다. <-여기서는 설명하지 않겠습니다. 이 문제에 대한 자세한 설명을 보려면 웹에서 "Stable Raster C64"를 검색하십시오.


Krestage 3이 한 작업 (질문에서 언급했듯이)이 다릅니다.

트릭의 한 단계는 "종이"(작업 영역 사각형, 테두리 안에있는 것)의 바닥이 그려 질 때 테두리를 엉망으로 만드는 것입니다. 이렇게하면 상단 및 하단 테두리에 스프라이트가 있습니다.

더 높은 수준은 위의 JohnD의 답변에서 설명한대로 모든 래스터 라인에서 종이의 오른쪽 가장자리에서 그것을 엉망으로 만드는 것입니다. 이렇게하면 왼쪽 및 오른쪽 테두리에 스프라이트가 있습니다.

이 중 어느 것도 한 줄에 8 개 이상의 스프라이트를 가질 수 없습니다. 그것은 단지 Krest 마술입니다.

지금까지 VIC 칩에 대한 최고의 리소스 (내가 알고있는)는 Christian Bauer의 "MOS 6567/6569 비디오 컨트롤러 (VIC-II) 및 Commodore 64에서의 응용 프로그램" 이며 유용한 부록은 "The memory accesses of the Marko Mäkelä의 MOS 6569 VIC-II 및 MOS 8566 VIC-IIe 비디오 인터페이스 컨트롤러 "
주의 사항 : 이것은 다소 기술적이며 일부 VIC 효과를 직접 프로그래밍 한 후에는 이해하기가 더 쉬울 수 있습니다.

링크가 끊어지면 제목별로 기사를 검색하면 끝없이 복제됩니다.


간단한 BASIC 프로그램으로 위쪽 및 아래쪽 테두리를 열 수 있습니다.

    1 poke56334,0 : poke53266,212 : poke53265,27 : poke16383,0
    2 시간 = 53265 : i = 53273 : h1 = 19 : h2 = 27 : i1 = 1
    3 pokei, i1 : waiti, i1 : pokeh, h1 : pokeh, h2 : goto3

나는 여기 어둠 속에서 찌를 것입니다 (이것을 직접했습니다). 위키피디아에서 찾았습니다.

c64demo 부분은 그 설명 :

데모에서 불가능하다고 생각되는 효과는 대부분 MOS 기술 VIC-II 칩과 관련된 문서화되지 않은 부작용으로 인해 달성되었습니다 . VIC 속임수에 대한 몇 가지 예 :

언급 된 해킹 중 하나는 다음과 같습니다.

스프라이트 스크롤러가 테두리에 배치되었습니다. 하드웨어가 화면 주위에 테두리를 그리지 않도록 속임으로써 스프라이트를이 영역으로 이동하여 표시 할 수 있습니다.

물론 질문의 흥미로운 부분은 그것이 어떻게 이루어 졌는지입니다. 해킹을 사용하는 데모를 검색 할 때 소스 코드가 포함 된 데모 데이터베이스살펴 보는 것이 좋습니다 .


"IT WAS 53280, DUDE."라고 정자로 기입하십시오.


내가 이해하는 바에 따르면 이것은 스프라이트에서만 가능합니다.

스프라이트는 테두리 영역에있을 수 있으며 테두리는 위에 그려집니다. 약간의 속임수를 통해 테두리를 제거 할 수 있습니다.


테두리의 그래픽 : 스프라이트 또는 $ 3FFF 효과 사용 (실제로는 스프라이트가 아님). 자세히 알아 보려면 여기에서 사용할 수있는 것보다 훨씬 더 많은 공간과 시간이 필요합니다.


기본에서 테두리에 스프라이트를 가져올 수도 있습니다. 테두리의 BASIC 스프라이트

iirc, 비디오 칩을 혼동하여 26 번째 줄의 텍스트를 그릴 수있는 방법도있었습니다.


마이크로 소프트 비행 시뮬레이터는 국경에 그렸다. 우선, 적시에 테두리 색상을 변경하여 테두리 그리기 효과를 얻을 수 있습니다. 예를 들어 LOGO에는 Turtle 그래픽을위한 분할 화면 모드가 있는데, 화면은 위의 HiRes 그래픽과 아래의 몇 줄의 텍스트 사이에서 전환되었습니다. 프레임도 색이 달랐습니다. 따라서 효과가 프레임까지 확장되는 수평선 효과, 아래의 녹색 목초지 및 위의 푸른 하늘 (비행 시뮬레이터에서와 같이)을 쉽게 수행 할 수 있습니다.

와일드 프레임 깜박임 프로그램을 실행하면

   C000 LDX #00
        STX D020
        INX
        STX D020
        DEX
        BEQ C002

그런 다음 10-20 픽셀 정도마다 색상이 변경됩니다. 그것은 당신이 얻을 수있는 가장 빠른 변화라고 생각합니다. 따라서 테두리에 수평선을 그릴 수 있습니다.테두리 색상의 가장 빠른 변경

그리고 $ D012의 VIC와 $ D011의 비트 7에서 동일한 수직 라인 레지스터를 사용하여 시간을 측정 할 수 있습니다. 해당 레지스터에서 현재 스캔 라인을 읽을 수 있습니다. 그러나 그것에 쓰기를하고 레지스터 $ D01A에서 로우 비트를 활성화하면 VIC는 스캔이 해당 라인에 도달 할 때 신호를 보내고 IRQ를 수행합니다. 이것이 화면 분할 효과가 완성되는 방법입니다.

여기에 예가 있습니다. 먼저 인터럽트 루틴을 설정했습니다.

   C000 SEI        ; disable interrupt
        LDA #1F    ; set interrupt routine to C01F
        STA 0314   ; set low byte
        LDA #C0    ; high byte
        STA 0315   ; set
        LDA #C0    ; raster position for horizon
        STA D012   ; set to raster position interrupt
        LDA D011   ; and for the high bit of the raster position
        AND #7F    ; clear the high bit
        STA D011   ; and set the cleared high bit
        LDA #F1    ; enable the raster interrupt
        STA D01A   ; in the appropriate register
        CLI        ; allow interrupt
        RTS        ; return from subroutine

그리고 여기 내 실제 인터럽트 루틴이 있습니다.

   C01F LDA D019   ; load VIC interrupt register
        STA D019   ; and clear it
        BMI C02E   ; if highest bit is set, go to our routine
        LDA DC0D   ; else disable CIA interrupt
        CLI        ; enable interrupt
        JMP EA31   ; continue with normal system interrupt routine

   C02E LDA D012   ; load current vertical scan line
        CMP #01    ; is it just about the first line?
        BCS C042   ; if not jump to bottom part
        LDA #03    ; cyan
        STA D020   ; set border color (sky)
        LDA #C0    ; horizon level 
        STA D012   ; set vertical scan interrupt to occur at horizon
        JMP EA81   ; continue with normal interrupt minus cursor blink

   C042 LDA #00    ; black to draw a piece of horizontal line on the horizon
        STA D020   ; set border color
        LDX #08    ; a short busy loop
   C049 DEX
        BNE C049
        LDA #01    ; white to draw on the right side horizon
        STA D020   ; set border color
        LDC #02    ; very short busy loop
   C053 DEX
        BNE C053
        LDA #05    ; finally green as the grass
        STA D020   ; set border color
        LDA #00    ; next scan line interrupt at top of screen
        STA DO12   ; set scan line interrupt
        JMP EA81   ; continue normal interrupt sans cursor blink 

다음과 같은 영광스러운 결과 : 수평선에 그려진 두 개의 선 세그먼트가있는 분할 화면

참조 URL : https://stackoverflow.com/questions/1750210/draw-on-screen-border-in-commodore-64

반응형