문제

화면의 테두리 영역에서 스프라이트를 보여주는 멋진 C64 데모를 보았습니다. 가능하지 않아야합니다. 나는 그들이 어떻게 든 그래픽 칩을 속일 수 있다고 생각합니다. 그들은 정확히 어떻게 했습니까?

도움이 되었습니까?

해결책

예, 어셈블러가 필요합니다. 인터럽트 타이밍 트릭입니다. 빅은 테두리에 스프라이트를 보여줄 수 있지만 프레임이 숨겨져있어 스프라이트가 그 뒤에 미끄러질 수 있습니다. VIC가 표시하는 스캔 라인에 연결되어 있습니다. 하위/위 경계의 경우 매우 간단합니다.

  • 교단을 프로그래밍하고, 특정 스캔 라인, 7 픽셀 또는 하단 테두리 앞에서 이와 유사한 것으로 동기화되었습니다.
  • 국경을 더 작게 만들도록 Vic에서 레지스터를 설정하십시오. (그렇게 할 수있는 레지스터가 있습니다.)
  • Vic은 이제 국경이 이미 시작되었고 페인트 칠을 시작하지 않는다고 생각합니다.
  • -> 바닥에 테두리가 없습니다.
  • 실제 테두리 후에 또 다른 인터럽트를 프로그래밍하여 원본으로 다시 설정하십시오.

왼쪽/오른쪽 경계의 스프라이트의 경우 모든 스캔 라인에 대해 프로세스가 반복되어야하기 때문에 더 복잡합니다.

  • 프로그래밍 특정 스캔 라인에서 시작하도록 동기화 된 인터럽트.
  • 그런 다음 오른쪽 테두리 앞에서 7 픽셀이 될 때까지 NOPS를 수행하십시오.
  • 국경을 더 작게 만들도록 Vic에서 레지스터를 설정하십시오.
  • -> 오른쪽에는 테두리가 없습니다.
  • 실제 테두리가있을 때까지 NOPS를 수행하고 레지스터를 원래 값으로 다시 설정하십시오.
  • 다시 2 단계까지 NOPS를 수행하십시오.

문제는이 모든 Nops가 바쁘고 기다리는주기를 훔치는 것입니다.

하단 테두리의 스프라이트 스크롤러에서 코드를 찾을 수있었습니다. 코드는 다음과 같습니다. (데모에서 찢어졌습니다.)

C198  78        SEI
C199  20 2E C1  JSR C12E     # clear sprite area
C19C  20 48 C1  JSR C148     # init VIC
C19F  A9 BF     LDA #BF      # set up IRQ in C1BF
C1A1  A2 C1     LDX #C1
C1A3  8D 14 03  STA 0314
C1A6  8E 15 03  STX 0315
C1A9  A9 1B     LDA #1B
C1AB  8D 11 D0  STA D011
C1AE  A9 F7     LDA #F7
C1B0  8D 12 D0  STA D012
C1B3  A9 01     LDA #01
C1B5  8D 1A D0  STA D01A
C1B8  A9 7F     LDA #7F
C1BA  8D 0D DC  STA DC0D
C1BD  58        CLI
C1BE  60        RTS

----------------------------------
# init VIC
C148  A2 00     LDX #00
C14A  BD 88 C1  LDA C188,X
C14D  9D 00 D0  STA D000,X   # set first 16 values from table
C150  E8        INX
C151  E0 10     CPX #10
C153  D0 F5     BNE C14A
C155  A9 FF     LDA #FF
C157  8D 15 D0  STA D015
C15A  A9 00     LDA #00
C15C  8D 1C D0  STA D01C
C15F  A9 FF     LDA #FF
C161  8D 17 D0  STA D017
C164  8D 1D D0  STA D01D
C167  A9 C0     LDA #C0
C169  8D 10 D0  STA D010
C16C  A9 F8     LDA #F8
C16E  A2 00     LDX #00
C170  9D F8 07  STA 07F8,X
C173  18        CLC
C174  69 01     ADC #01
C176  E8        INX
C177  E0 08     CPX #08
C179  D0 F5     BNE C170
C17B  A9 0E     LDA #0E
C17D  A2 00     LDX #00
C17F  9D 27 D0  STA D027,X
C182  E8        INX
C183  E0 08     CPX #08
C185  D0 F8     BNE C17F
C187  60        RTS

----------------------------------
# data set into VIC registers
C188  00 F7 30 F7 60 F7 90 F7
C190  C0 F7 F0 F7 20 F7 50 F7

----------------------------------
# main IRQ routine
C1BF  A2 08     LDX #08
C1C1  CA        DEX
C1C2  D0 FD     BNE C1C1
C1C4  A2 28     LDX #28      # 40 or so lines
C1C6  EA        NOP          # "timing"
C1C7  EA        NOP
C1C8  EA        NOP
C1C9  EA        NOP
C1CA  CE 16 D0  DEC D016     # fiddle register
C1CD  EE 16 D0  INC D016
C1D0  AC 12 D0  LDY D012
C1D3  88        DEY
C1D4  EA        NOP
C1D5  98        TYA
C1D6  29 07     AND #07
C1D8  09 18     ORA #18
C1DA  8D 11 D0  STA D011
C1DD  24 EA     BIT   EA
C1DF  EA        NOP
C1E0  EA        NOP
C1E1  CA        DEX
C1E2  10 E4     BPL C1C8     # repeat next line
C1E4  A9 1B     LDA #1B
C1E6  8D 11 D0  STA D011
C1E9  A9 01     LDA #01
C1EB  8D 19 D0  STA D019
C1EE  20 00 C0  JSR C000   # call main code
C1F1  4C 31 EA  JMP EA31   # finish IRQ

다른 팁

그것은 모두 타이밍에 의존했습니다. C64는 화면을 그리는 동안 전자 빔의 정확한 수직 위치를 쿼리하는 방법을 가지고있었습니다. 새 라인이 시작되면 몇 사이클을 기다려야했습니다 (NOP 명령을 사용하여 시간을 가질 수 있음). 그런 다음 스크린 모드 (및 테두리 너비)를 설정하는 VideoChip의 하드웨어 레지스터를 설정해야했습니다. 정확히 올바르게 타이밍을하고 모든 스캔 라인을 다시 수행함으로써 전체 부작이 사라졌습니다.

바닥 테두리는 비슷한 속임수로 사라졌습니다. 수직 테두리가 시작된 정확한 스캔 라인에서도 해당 프레임의 하단 테두리를 비활성화 한 비디오 모드를 설정해야했습니다.

실제로이 모든 일은 조립에서 이루어져야했습니다. 그렇지 않으면 타이밍을 정확히 올바르게 얻을 수 없습니다.

부수적으로, 나는 부작용 속임수가 1001 승무원 (네덜란드 그룹)에게 인정되었다고 생각합니다. 누가 첫 번째 바닥 테두리 트릭을 뽑았는지 잘 모르겠습니다.

C64에서 국경을 여는 주제에 대한 좋은 튜토리얼은 Pasi Ojala의 훌륭한 기사를 확인하십시오. C = 해킹 문제 6.

너무 기술적이지 않고 TRICK은 VIC 칩의 기능을 사용하여 25/24 행과 40/38 열의 텍스트/그래픽을 전환 할 수 있으며, 정확한 순간 에이 스위치를 만들기 위해 VIC를 속이는 데 도움이됩니다. 실제로는 그렇지 않을 때 이미 국경을 켜고 있습니다. 코드 예제에 대한보다 철저한 설명은 위의 기사를 확인하십시오.

그것은 오래 전입니다.

모니터의 빈도에 의존하는 솔루션이 있다는 것을 알고 있습니다.

CRT를 사용하면 현재 픽셀이 일반 화면 외부에 있더라도 알려져 있습니다. 그래서 당신은 광선을 조작 할 수 있습니다.

내 정크 파일 어딘가에 C64 책이 있어야합니다.

Offtopic이지만 VIC20 (C64의 전신)과의 그래픽은 재미있었습니다. 각 픽셀을 조작 할 방법은 없었지만 기존 문자를 변경할 수 있습니다. 그래서 당신은 0에서 ... 모든 문자로 화면을 채우고 문자를 변경하여 픽셀을 화면으로 설정했습니다. ;-).

타이밍이 핵심이었습니다. CRT의 빔이 왼쪽에서 오른쪽으로 이동함에 따라 오버 스캔 (테두리) 색상을 변경하여 이미지는 테두리에서 생성되었습니다. 이미지를 생성하는 데 필요한 두 가지 타이밍 신호가 있습니다 - 세로 새로 고침 및 수평 새로 고침. 수평 및 수직 새로 고침이 발생하는시기를 감지함으로써 일련의 어셈블러 지침을 시작하여 테두리 색상을 변경하여 이미지를 생성 할 수 있습니다. 테두리 픽셀 당 CPU 시계 진드기 수를 해결하고이를 사용하여 올바른 지점에서 테두리 색상을 변경하는 코드를 작성해야합니다.

CPU 오버 헤드가 사용자 입력 및 게임 상태를 처리하기 위해 시간 리프트가 있기 때문에 게임을 작성하는 데는 잘 작동하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top