سخت افزار Atari 2600 بر اساس راهنمای استلا -- وی سینک و وی بلنک و آبجکتهای سبعه

ash|ae|ash

کاربر سایت
Jul 22, 2013
94
آتاری ۲۶۰۰ که با نام Atari VCS در سال ۱۹۷۸ عرضه شد اولین کنسولی بود که از پروسسور ۶۵۰۲ استفاده میکرد و دومین کنسولی بود که از کارتریج به عنوان رسانه استفاده میکرد. به عبارتی ۲۶۰۰ الگوی کنسولهای مدرن بود. اما برنامه نویسی برای این کنسول به سادگی برنامه نویسی برای کنسولهای مدرن نیست. برای نوشتن یک بازی برای PS4 کافیست از یک انجین مثل آنریل،‌ یونیتی یا گودو استفاده کنید. البته یک API Key لازم دارید تا انجین بتواند به شما اکسکیوتیبلهای کنسول را بدهد. انجینهای مدرن بازی سازی را تبدیل کرده اند به یک جهاد هنری تا یک جهاد برنامه نویسی. اما ۲۶۰۰ اصلا اینگونه نیست. در ۲۶۰۰ هشت کیلوبایت رم بیشتر نیست،‌ یک سی پی یو با یک رجیستر اکولومیتر و دو رجیستر ایندکس و یک استک. و دو آی سی جانبی.

همراه ۲۶۰۰ هیچ راهنمایی نیست. این وظیفه ی برنامه نویس است که کنسول را مهندسی معکوس کند و ببیند داخل آن چه خبر است. و خیلی از برنامه نویس ها همین کار را کردند. برنامه نویسهایی که از Stella Guide خبر نداشتند.

در سال ۱۹۷۸ چندماه بعد از عرضه ی کنسول برنامه نویسی به نام استیو رایت آمد و Stella Guide را نوشت. این راهنما حاوی است از تمامی مشخصات کنسول تا بتوان با اسمبلی ۶۵۰۲ رجیسترهای لازمه را بارگذاری کرد تا کنسول کاری را که میخواهیم انجام دهد.

به گفته ی این راهنما ۲۶۰۰ یک فریم تلوزیون را به ۲۶۲ خط فرضی افقی تقسیم میکند که هر ۲۲۸ تعداد کلاک را بین هم تقسیم کرده اند. و این ۲۲۸ کلاک ۳.۵۸ مگاهرتز روی هم میگیرد. حالا میرسیم به VSYNC و VBLANK. یک فریم ۳ خط عمودی وی سینک دارد و ۳۷ خط عمودی وی بلنک. و ۱۹۲ خط که خود تصویر را رسم میکنند. هر اسکن لاین در NTSC سی خط اوراسکن دارد.

خط های افقی اتوماتیک کلاک میشوند یعنی دو آی سی که در مورد آنها صحبت خواهیم کرد وظیفه ی به کنترل گرفتن خطهای افقی را دارند. اما خط های عمودی با اسمبلی کنترل میشوند. اگر این روزها یک کراس اسمبلر ۲۶۰۰ پیدا کنید یک فرمان به نام VSYNC دارند. این فرمان تنها کاری که میکند رجیستر مخصوص وی سینک در پروسسور را پر میکند. اگر وی سینک true یا 0x11 باشد یعنی وی سینک را انجام بده.

حال به آی سی TIA میرسیم. نام این آی سی یعنی Television Interface Adapter. با وارد کردن دیتای هر خط عمودی در رجیستری چیپ TIA کنسول موفق به رسم یک خط میشود. فرض کنید TIA یک کارت گرافیک است. هر خط ۷۶ سایکل میکروپروسسور را میگیرد.اما نگران نباشید چون میکروپروسسو ۳.۵ مگاهرتز است و میتواند اینکار را انجام دهد.

اما ۳ خط وی سینک،‌ ۳۷ خط وی بلنک، و ۳۰ خط اورسکن چه؟ اینها در TIA کار نمیکنند،‌ یعنی TIA به آنها کاری ندارد و روی تلوزیون هم ترسیم نمیشوند. پس برای همین میتوان از ۵۳۲۰ سایکل باقیمانده ی این خطوط برای منطق بازی استفاده کرد.

به بخش پیوستها بروید تا دیاگرام این چیزهایی که توضیح داده ام را ببینید.

اینجاست که وارد محدودیتهای کنسول میشویم. کنسول میتوانید یک پس زمینه،‌ یک محیط بازی،‌ یک پلیر ۱ و یک پلیر ۲،‌ یک موشک ۱ و یک موشک ۲ داشته باشد. گیج شده اید؟ تمام اشخاصی که برای ۲۶۰۰ در این روزها بازی مینویسند گیج میشوند. پس اسپرایت چه؟ پس هیت باکس چه؟ بدانید که ۲۶۰۰ چهل و سه سال پیش عرضه شده و در آن زمان بازیهایی مانند Space Invaders و Pac-Man هنوز این صنعت را معنی نداده بودند. پس مهندسان آتاری بر اساس بازیهایی مانند Pong و Tank این کنسول را طراحی کردند. من به این آبجکتها میگویم «آبجکتهای سبعه» (سبع یعنی هفت) اما شما هرچی خواستید بهش بگویید.

هر کدام از آبجکتهای سبعه رجیستر خودشان را در TIA دارند.

و کنترلر. هر دکمه ی کنترلر آدرس هکسادسیمال (شانزده شانزدهی) خودش را دارد. این آدرس آدرس حافظه میباشد. با زدن هر دکمه این آدرس ۰ یا۱ میشود یعنی دکمه زده شده یا نه. میتوان با اینستراکشن BNE این را چک کرد.

گفتم ۲۶۰۰ دو آی سی دارد. آی سی دیگر PIA است. این آی سی را برخلاف TIA که طراح آن MOS Technologies بوده،‌ یک آی سی آماده است.

اطلاعات بیشتر را میتوانید در راهنمای استلا پیدا کنید.

در اخر میخواهم کد بازی پانگ که تنها ۲۵۶ بایت است و برای این کنسول در دهه ی نود توسط یک آدم خوش ذوق نوشته شده به اشتراک بگذارم:

Code:
; SMALLPONG v2.1 (255 bytes)
; Brad Smith
; 6/29/2008

; 16-bit instruction set, begin at 100h
use16
org 100h

; constants

SCREEN_WIDTH =        320
SCREEN_HEIGHT =     200
SCREEN_X_MID =        SCREEN_WIDTH / 2
SCREEN_Y_MID =        SCREEN_HEIGHT / 2
SCREEN_SIZE =        SCREEN_WIDTH * SCREEN_HEIGHT

PADDLE_SIZE =        10
;PADDLE_LEFT_X =        0
PADDLE_RIGHT_X =    SCREEN_WIDTH - 1
PADDLE_TOP =        1
PADDLE_MID =        SCREEN_Y_MID - (PADDLE_SIZE/2)
PADDLE_BOTTOM =     (SCREEN_HEIGHT-1) - PADDLE_SIZE

BALL_MID_X =        SCREEN_X_MID
BALL_MID_Y =        SCREEN_Y_MID
BALL_TOP =        PADDLE_TOP
BALL_BOTTOM =        (PADDLE_BOTTOM + PADDLE_SIZE) - 1

AI_THRESHOLD =        SCREEN_WIDTH - 90

; main program
start:
    ; set up VGA mode 13h
        mov    al, 013h
        int    10h
        ; store video register in es (will stay constant from here on)
        push    word 0A000h
        pop    es

    ; clear the screen
        ;xor     di, di ; di = 0
        ;mov     cx, SCREEN_SIZE
        ;xor     al, al ; al = 0
        ;repz    stosb

    ; setup stack
        push    word PADDLE_MID
        push    word BALL_MID_X
        push    word BALL_MID_Y

    game_loop:

    ; wait for vsync
        vsync_active:
        mov    dx, 03DAh    ; input status port for checking retrace
        in    al, dx
        test    al, 8
        jnz    vsync_active    ; Bit 3 on signifies activity
        vsync_retrace:
        in    al, dx
        test    al, 8
        jz    vsync_retrace    ; Bit 3 off signifies retrace

    ; draw game part 1
        ; clear old ball
               ; STACK: ball_y, ball_x, paddle_left_y
        pop    ax ; STACK: ball_x, paddle_left_y
        pop    bx ; STACK: paddle_left_y
        xor    dl, dl ; dl = 0
        call    put_pixel

    ; update game state part
        ; right paddle AI
            ; bx = ball_x
            cmp    bx, AI_THRESHOLD
            mov    cx, bx ; move bal_x to cx
            mov    bx, [paddle_right_y]
            jl    skip_ai
            ; ax = ball_y
            sub    al, (PADDLE_SIZE / 2)
            cmp    ax, bx
            je    end_ai
            jg    ai_dn
            ;ai_up:
            dec    bx
            jmp    end_ai
            ai_dn:
            inc    bx
            end_ai:
            add    al, (PADDLE_SIZE / 2)
            skip_ai:
            call    clamp_paddle
            mov    [paddle_right_y], bx
        ; move ball vertical
            ; ax = ball_y
            add    al, [ball_dy]
            ; mov     [ball_y], ax
            ; bounce vertical
            cmp    al, BALL_TOP
            jne    ball_not_top
            neg    byte [ball_dy]
            ball_not_top:
            cmp    al, BALL_BOTTOM
            jne    ball_not_bottom
            neg    byte [ball_dy]
            ball_not_bottom:
        ; move ball horizontal
            add    cx, [ball_dx]
        ; check for right paddle collision / goal
            ; ax = ball_y
            ; bx = paddle_right_y
            ; cx = ball_x
            mov    dx, PADDLE_RIGHT_X
            call    collide_paddle
        ; left paddle moved by player
            pop    bx ; STACK: EMPTY
            ; get movement state
                push    ax ; STACK: ball_y
                ; get shift registers
                mov    ah, 02h
                int    16h
                ; test for CTRL
                test    al, 4
                jz    no_ctrl
                inc    bx ; move paddle down
                no_ctrl:
                ; test for ALT
                test    al, 8
                jz    no_alt
                dec    bx ; move paddle up
                no_alt:
                pop    ax ; STACK: EMPTY
            call    clamp_paddle
            push    bx ; STACK: paddle_left_y
        ; check for left paddle collision / goal
            ; ax = ball_y
            ; bx = paddle_left
            xor    dx, dx ; dx = PADDLE_LEFT_X
            call    collide_paddle
    ; end update game state

    ; draw game part 2
        ; draw ball
        ; ax = ball_y
        xchg    bx, cx ; bx = ball_x, cx = paddle_left_y
        mov    dl, 15
        call    put_pixel
        push    bx ax ; STACK: ball_x, ball_y, paddle_left_y
        ; draw left paddle
        mov    ax, cx ; ax = paddle_left_y
        xor    bx, bx ; bx = PADDLE_LEFT_X
        call    draw_paddle
        ; draw right paddle
        mov    ax, [paddle_right_y]
        mov    bx, PADDLE_RIGHT_X
        mov    dl, 15
        call    draw_paddle
    ; end draw game part 2

    ; continue game if no regular keypresses
    mov    ah, 1
    int    16h
    jz    game_loop

    ; [ 2 bytes ]
    ; exit if a key has been pressed
    int    20h

; global data

screen_width:    dw    SCREEN_WIDTH
paddle_right_y: dw    PADDLE_MID
ball_dx:    dw    1
ball_dy:    db    -1

; subroutines

; put_pixel
; plots a pixel at bx,ax with color dl
; (registers preserved)
put_pixel:
    push    ax bx dx
    mul    word [screen_width]
    add    bx, ax
    pop    dx
    mov    [es:bx], dl
    pop    bx ax
    ret

; draw_paddle
; draws a paddle (position: bx,ax colour: dl)
draw_paddle:
    mov    cx, PADDLE_SIZE
    draw_paddle_loop:
        call    put_pixel
        inc    ax
        loop    draw_paddle_loop
    xor    dl, dl ; dl = 0
    call    put_pixel
    sub    al, PADDLE_SIZE+1
    call    put_pixel
    ret

; clamp_paddle
;   clamps bx to [PADDLE_TOP,PADDLE_BOTTOM]
clamp_paddle:
    cmp    bl, PADDLE_TOP - 1
    jne    not_top
    mov    bl, PADDLE_TOP
    not_top:
    cmp    bl, PADDLE_BOTTOM + 1
    jne    not_bottom
    mov    bl, PADDLE_BOTTOM
    not_bottom:
    ret

; collide_paddle
;   collides paddle with ball
;   ax = ball_y
;   bx = paddle_y
;   cx = ball_x
;   dx = PADDLE_X
collide_paddle:
    cmp    cx, dx
    jne    no_collide
    cmp    ax, bx
    jl    new_ball
    push    bx
    add    bl, PADDLE_SIZE
    cmp    ax, bx
    pop    bx
    jge    new_ball
    neg    word [ball_dx]
    ret
    new_ball:
    ; "randomize" ball_x
    add    al, 97
    and    ax, 127
    add    ax, BALL_MID_Y - 64
    mov    cx, BALL_MID_X
    ; don't bother resetting ball_dx/dy
    ; just send ball to player who just lost
    no_collide:
    ret

; END OF FILE
; Brad Smith, 2008
 

Attachments

  • vcs.png
    vcs.png
    62.2 KB · مشاهده: 1

Pzt_Kami

کاربر سایت
Sep 27, 2007
394
نام
کامبیز
عالی و سپاس از شما دوست گرامی برای این متن جالب. فکر میکنم آتاری ازون دست کنسولهایی هست که فقط دهه شصتیا ( وا البته قدیمی ترها) به معنای واقعی میشناسنش و باهاش خاطره دارن. برای شخص من که این اولین کنسولی بود که دیدم و داشتم (گرچه 1-2تا از آشناها کنسول تی وی گیم که قدیمی تر بود رو هم داشتن)
 
  • Like
Reactions: amir_amd and 3DO

کاربرانی که این قسمت را مشاهده می‌کنند

Top
رمز عبور خود را فراموش کرده اید؟
or ثبت‌نام سریع از طریق سرویس‌های زیر