본문 바로가기

어셈블리 대신 C로 아미가 키보드 입력

반응형

⚡ 한 줄 요약:
아미가·아타리 ST의 키보드 입력은 예전엔 68000 어셈블리로 하드웨어를 직접 두드렸지만,
지금은 vbcc C 컴파일러로 GEMDOS/BIOS 함수(Cconin 등)만 호출하면 된다 — 어셈블리는 이제 '필수'가 아니라 '무슨 일이 일어나는지 이해하는 용도'다.

 

 

📑 목차

 

 

🕹️ 무슨 일인지

레트로 게임 개발 커뮤니티 retrogamecoders에 아미가(Amiga)와 아타리 ST(Atari ST)를 C로 프로그래밍하는 튜토리얼 시리즈가 이어지고 있다.
이번 편의 주제는 가장 기본이면서도 은근히 까다로운 키보드 입력 읽기(reading keyboard input)와 화면 에코(echo)다.
컴파일러는 크로스 개발이 편한 vbcc를 쓴다.

포인트는 이거다.
두 기계 모두 CPU는 같은 Motorola 68000인데, 키 한 글자를 받아오는 방식이 서로 완전히 다르다.
옛날엔 이걸 다 어셈블리로 짰지만, 지금은 C 함수 한 줄로 끝난다.
그 C 한 줄이 내부에서 어떤 어셈블리로 번역되는지가 이 글의 핵심이다.

 

 

🧩 배경 — C 한 줄과 어셈블리 트랩

고급 언어 C로 짜도, 키보드 같은 하드웨어 접근은 결국 OS가 제공하는 시스템 콜로 내려간다.
68000에서 이 시스템 콜은 trap 명령으로 구현된다.
즉 C 라이브러리 함수는 어셈블리 trap 명령을 감싼 얇은 껍데기에 가깝다.

  • 아타리 ST: TOS/GEMDOS가 trap #1, BIOS가 trap #13. 키 입력은 Cconin(에코 포함)·Cnecin(에코 없음)·Bconin 같은 함수로 부른다.
  • 아미가: 이벤트/메시지 기반. Intuition의 IDCMPRAWKEY(원시 스캔코드)나 VANILLAKEY(ASCII 변환값) 메시지를 받는다. 단순 콘솔 입력이면 dos.libraryRead().

 

구분 아미가 (Amiga) 아타리 ST (Atari ST)
CPU Motorola 68000 Motorola 68000
입력 모델 이벤트/메시지 (IDCMP) 트랩/시스템콜 (GEMDOS·BIOS)
키 이벤트 RAWKEY / VANILLAKEY Cconin / Bconin
에코 처리 콘솔 디바이스가 담당 GEMDOS Cconin이 담당
C에서 접근 dos.library Read(), Intuition osbind.h 트랩 매크로

 

 

 

⌨️ 개발자에게 주는 의미

이게 40년 전 기계 얘기로만 끝나지 않는다.
"C 함수 = 어셈블리 시스템 콜의 래퍼"라는 구조는 지금도 똑같다.
리눅스의 getchar()가 결국 read() 시스템 콜 → syscall 명령으로 내려가는 것과 판박이다.
다만 레트로 기계는 추상화 층이 얇아서 C와 어셈블리 사이의 거리가 눈에 보인다는 게 학습 가치다.

또 하나.
아미가의 이벤트 기반(메시지 큐) vs 아타리의 블로킹 트랩(함수 호출) 대비는 오늘날 이벤트 루프 vs 동기 I/O 논쟁의 원형이다.
게임처럼 입력을 놓치면 안 되는 프로그램에서 왜 폴링·메시지 구조가 필요한지, 이 낡은 기계가 가장 명료하게 보여준다.

 

 

🔧 실무 적용 — Cconin 한 줄이 트랩이 되기까지

아타리 ST에서 키 한 글자를 에코까지 포함해 읽는 C 코드는 이렇게 짧다.

/* Atari ST — GEMDOS Cconin(함수번호 1): 키 입력까지 블로킹 + 자동 에코 */
#include <osbind.h>   /* vbcc의 Atari TOS 타깃용 트랩 바인딩 헤더 */

long r  = Cconin();      /* 하위 8비트 = ASCII, 상위 워드 = 스캔코드 */
char ch = (char)(r & 0xFF);

Cconin() 매크로가 컴파일되면 실제로는 아래 68000 어셈블리로 펼쳐진다.

    move.w  #1,-(sp)   ; GEMDOS 함수번호 1 = Cconin
    trap    #1         ; GEMDOS 진입 (여기서 OS로 제어권)
    addq.l  #2,sp      ; 스택에 밀어넣은 워드 정리
    ; 반환: D0.b = ASCII 코드, D0의 상위 워드 = 키 스캔코드

에코가 필요 없으면 Cconin 대신 Cnecin(함수번호 8)으로 바꾸면 된다 — 게임에서 화면에 글자가 찍히면 안 될 때 쓴다.
아미가라면 접근이 다르다.
Intuition 창을 열고 IDCMP 플래그에 VANILLAKEY를 켠 뒤 GetMsg()로 메시지를 꺼내 Code(ASCII)를 읽는 구조라, "함수 호출"이 아니라 "메시지 수신 루프"가 된다.

⚠️ 함수 시그니처·헤더 이름(osbind.h, 함수번호)은 vbcc 버전과 사용하는 라이브러리(vclib·mintlib 등)에 따라 다를 수 있다. 실제 빌드 전 해당 툴체인 공식 문서·헤더 확인을 권장한다.

 

 

✅ 체크포인트 (그래서 뭘 해보나)

  • 아타리 ST부터 만져봐라: Cconin(에코) ↔ Cnecin(무에코) 한 글자만 바꿔 실행해 보면 "C 함수 = OS 트랩"이 손에 잡힌다.
  • 역어셈블 떠봐라: vbcc로 빌드한 뒤 오브젝트를 디스어셈블(vda/objdump류)해 trap #1이 실제로 박히는지 눈으로 확인 — 어셈블리 학습의 가장 빠른 지름길.
  • 두 모델을 비교하라: 아미가 IDCMP 이벤트 루프와 아타리 블로킹 트랩을 나란히 짜 보면, 오늘날 이벤트 드리븐 I/O의 뿌리가 보인다.

 

 

📚 참고

 

 

📊 오늘의 개발 트렌드 (자동 집계)

GitHub·Hacker News·Hugging Face·App Store·Cloudflare Radar에서 매일 자동으로 모은 개발 트렌드입니다. (2026-07-21 18:12 기준)

🐙 GitHub 급상승

  • bojieli/ai-agent-book (+4,434★/일) — 《深入理解 AI Agent:设计原理与工程实践》(李博杰 著)开源主仓库:全书正文、编译版 PDF 与按章配套代码
  • tirth8205/code-review-graph (+1,833★/일) — Local-first code intelligence graph for MCP and CLI. Builds a persiste
  • 1jehuang/jcode (+568★/일) — The most intelligent agent harness for code

📰 Hacker News 화제

🤗 Hugging Face 트렌딩 모델

💰 App Store 매출 TOP (한국)

  • YouTube — Google
  • ChatGPT — OpenAI OpCo, LLC
  • 카카오톡 KakaoTalk — Daum Corp.

🌐 가장 많이 방문되는 웹 (Cloudflare Radar)

반응형