시스템 사양 선택 | 2번 |
---|
안녕하세요, 안정화를 달리는 여러분.
최근에 해외 블로그에서 Preset Variable Method라는 것을 읽어보고 제 노트북 터치패드를 이것저것 만져보다가 어떤 식으로 작동하는지 이해해서 여러분께 소개해보고자 합니다.
*주의* 굳이 이 방법을 알아야 커맥을 안정화시킬 수 있는 것은 아닙니다. 방법이야 다양하죠. 단지 저는 이 방법이 논리적으로 타당하기 때문에 소개하려고 합니다. 어렵거나 왜 하는지 이해가 안 된다면 끝까지 읽을 필요는 없습니다^^
그래도 읽어보고자 하신다면 감사하고, 용어나 제가 사용하는 특정 문구에 대한 이해에 도움이 되기 위해 이전 글을 참고해주세요.
What is the preset variable method?
무언가가 미리 설정되었다는 말이고, 한국에서는 뭐라고 불러야할지...Preset Method라고만 불러도 상관은 없을 것 같습니다.
어쨌든 ACPI 테이블의 장치 설정에 있어서 부트로더를 통한 직접적인 이름 변경 없이 어떤 변수의 값을 할당하고 장치의 내용을 완전히 새로 쓴 SSDT를 추가함으로써 원하는 장치 설정을 이루어낼 수 있는 방법입니다.
이를 설명하기 위해서 먼저 알아야 하는 것은 _STA입니다.
Status Object: _STA
DSDT (간혹 SSDT)를 보면 장치 (Device) 하위항목에_STA라는 것을 자주 볼 수 있습니다. 이는 status를 나타냅니다. 특정 장치의 상태는 ON인지, OFF인지를 결정하는 Object입니다. 대표적으로 Name (_STA,값)과 Method (_STA){Return(값)}으로 많이 사용되는데, 값에 들어가는 숫자가 0이라면 OFF, 다른 숫자라면 각종 다른 형태의 ON을 나타냅니다.
예 1: 노트북 화면 밝기
Device (_SB.PCI0.GFX0.PNLF)
{
Name (_ADR, Zero) // _ADR: Address
Name (_HID, EisaId ("APP0002")) // _HID: Hardware ID
Name (_CID, "backlight") // _CID: Compatible ID
Name (_UID, Zero) // _UID: Unique ID
Name (_STA, 0x0B)* // _STA: Status
...
}
위 Name (_STA)* 부분에서 노트북 화면 밝기에 사용되는 가상장치를 활성화시킵니다.
예 2: I2C 터치패드
Device (_SB.PCI0.I2C1.ETPD)
{...
Method (_STA, 0, NotSerialized)** // _STA: Status
{
If (LOr (LNotEqual (TPIF, One), LAnd (DSYN, One)))
{
Return (Zero)
}
Return (0x0F)
}...}
Method (_STA)**에서 터치패드 ETPD 장치를 활성화시킬지 비활성화 시킬지 결정합니다.
둘 다 _STA라는 이름과 해당하는 값이 중요하고, Method로 활성화되었는지, 아니면 Integer로 활성화되었는지는 별로 중요하지 않습니다. 만약 제가 노트북 화면 밝기를 Method로 설정하고 싶다면 Name (_STA)*를 Method (_STA)***로 변경할 수 있겠죠.
예 3: 노트북 화면밝기: Method로 변경
Device (_SB.PCI0.GFX0.PNLF)
{
Name (_ADR, Zero) // _ADR: Address
Name (_HID, EisaId ("APP0002")) // _HID: Hardware ID
Name (_CID, "backlight") // _CID: Compatible ID
Name (_UID, Zero) // _UID: Unique ID
Method (_STA, 0,NotSerialized)*** // _STA: Status
{
Return (0x0B)
}
...
}
Method를 사용한다면 여러 If 조건을 넣을 수 있기 때문에, 특정 조건을 만족시켰을 때만 장치를 활성화시키는 코드를 작성할 수 있습니다.
Rename _STA to XSTA
장치를 새로이 추가한다면 _STA를 ON으로 설정하면 활성화되지만, 기존에 있는 장치를 비활성화 시키고 이를 대체하는 장치를 추가할 때 (또는 _STA 내용을 다른 형식으로 바꾸고 싶을 때) _STA를 추가한다면 기존 _STA와 충돌할 가능성이 있습니다. 이 경우를 방지하기 위해, 장치를 활성화/비활성화 시킬 때 고전적으로 자주 사용하는 핫패치 방법은 _STA를 XSTA로 바꾸고 새로운 _STA를 SSDT로 추가하는 것입니다.
만약 제가 IOReg에서 활성화된 터치패드를 비활성화 시키고자 했다면 Method 헤더와 같이 _STA를 XSTA로 바꾸어주어 이 Method 정의에 한해서만 XSTA라는 이름을 사용합니다. 그렇다면 DSDT에서는 Method (_STA,0,NotSerialized)라는 문구를 전혀 찾아볼 수 없고, 이 때 저는 External Declaration과 함께 Method (_STA)를 SSDT에 추가하여 장치를 비활성화 시킬 수 있습니다.
상세하게는 아래과 같습니다.
DSDT 내용: config.plist에서 Method(_STA,0,NotSerialized)**->Method(XSTA,0,NotSerialized)****로 바꾸어줍니다.
Device (_SB.PCI0.I2C1.ETPD)
{...
Method (XSTA, 0, NotSerialized)****
{
If (LOr (LNotEqual (TPIF, One), LAnd (DSYN, One)))
{
Return (Zero)
}
Return (0x0F)
}...}
Method (_STA)**가 없으니, ETPD 장치의 상태에 대해 말해주는 부분이 DSDT에서는 전혀 찾아볼 수 없습니다.
SSDT 내용: Method (_STA)**를 재정의^하는데, Return(0)^^을 통해 장치를 비활성화 시킵니다.
External (_SB.PCI0.I2C1.ETPD,DeviceObj)
Scope (_SB.PCI0.I2C1.ETPD)
{
Method (_STA, 0, NotSerialized)^ // _STA: Status
{
Return (Zero)^^
}
}
이렇게 ETPD를 비활성화 시킬 수 있습니다.
What's the point?
이 방법으로 터치패드는 충분히 비활성화 시킬 수 있습니다. 결국 목적만 달성하면 되긴 하지만, 혹시 중간 과정에서 저게 뭘까 하는 부분이 있지 않나요? 바로 기존 Method (_STA)의 내용입니다.
Method (_STA, 0, NotSerialized)
{
If (LOr (LNotEqual (TPIF, One), LAnd (DSYN, One)))
{
Return (Zero)
}
Return (0x0F)
}
저는 이 내용과 전혀 상관 없이 _STA를 새로 설정했습니다. 이렇게만 하면 끝이긴 하지만, 최종적으로 얻는 ACPI 테이블에서 쓸데 없는 내용 없고 간결하고 의미 있는 코드만을 구성한 것이 아니죠. 아무 곳에서도 사용되지 않는 Method(XSTA)****라는 것이 값자기 튀어나온 셈이니까요. 불필요한 코드는 아예 없는 것이 논리적입니다.
The content of Method (_STA)
그렇다면 논리적인 방법은 무엇일까요. 먼저 Method (_STA)의 내용을 분석해봅시다. 두 부분으로 나누어져 있습니다.
첫 번째 부분
If (LOr (LNotEqual (TPIF, One), LAnd (DSYN, One)))%
{
Return (Zero)%%
}
두 번째 부분
Return (0x0F)%%%
ACPI 스펙에 따르면 Method라는 것은 한 가지 값을 Return한다고 합니다. 그렇다면 위 If 문%에 해당하는 조건을 만족한다면 Return (Zero)%%가 되겠고, If 문%에 해당하지 않는다면 아래처럼 Return (0x0F)%%%가 되겠습니다. 위의 경우에는 장치가 비활성화되고, 아래의 경우 장치가 활성화됩니다.
If문%은 세부적으로 보자면 LOr, LNotEqual, 그리고 LAnd 같은 것들을 알아야 하는데...(이걸 설명하기 위해 제가 물리학을 전공한 것은 아니지만ㅋ) 제가 학교에서 배운 수준으로 말씀드리자면 L은 Logic의 줄임말로, 이것들을 Logic Gate라고 보시면 됩니다. 영어로 배워서...한글로는 논리 게이트 이런 식으로 부르는 것 같습니다.
LOr: 둘 중 하나만 true라면 전체는 true가 됩니다. 반대는 false 입니다
LNotEqual: 둘이 같지 않으면 true가 됩니다. 반대는 false 입니다.
LAnd: 둘 다 true여야 true입니다. 곱셈인데, 마치 true=1, false=0이라면 true=1을 얻기 위해서는 1*1이 있어야겠죠.
다른 Logic Gate들이 있겠지만, 다 설명하자면 끝도 없고, 저도 2주 정도만 배운 내용이고 오래 전에 배운 내용이라 기억이 잘 나지 않습니다ㅠ 만약 다른 ACPI 테이블에서 보지 못했던 Logic Gate가 있으면 저는 그게 무엇인지 검색해보겠죠.
LOr이 어떤 값을 주는지 보기 위해서는 그 안 숫자가 1인지 0인지를 알아야 합니다. 그래서 LNotEqual과 LAnd를 먼저 보겠습니다.
LNotEqual
LNotEqual(TPIF*,One**)
TPIF*가 One**이 아니라면 이 값은 true가 되고, TPIF*가 One**이라면 이 값은 false가 됩니다.
LAnd
LAnd (DSYN^, One^^)
DYSN^과 One^^이 1과 1로 같으면 1입니다. DYSN^이 0이라면 0과 1으로 결과는 0을 얻게 됩니다.
LOr
LOr (LNotEqual (TPIF, One), LAnd (DSYN, One))
LNotEqual (TPIF, One)과 LAnd (DSYN, One) 중 하나라도 1이라면 LOr 결과는 1로 true입니다.
다시 정리하자면, 이 If문%이 만족되면 장치는 비활성화되고, 만족되지 않는다면 장치는 활성화됩니다.
What then?
여기까지 Method(_STA)의 내용에 대해서 알아보았습니다. 어떤 조건이 있으면 장치가 활성화되는지, 비활성화되는지 알 수 있죠.
그런데 이 장치는 이미 활성화되어 있습니다. 그렇다면 If문%이 만족되지 않았다는 것을 알 수 있습니다. 만약 부팅 초기에 If문%을 만족시키는 설정을 한다면 이 장치는 IOReg에서 비활성화 될 수 있을 것입니다. 그렇다면 다시 Logic Gate를 보며 어떻게 설정하면 될지를 생각해봅시다.
LOr: 결론은 0 즉 false이기 때문에 If%문이 만족되지 않았던 것일텐데, 이는 안의 LNotEqual (TPIF, One)나 LAnd (DSYN, One) 둘 중 하나도 1이 아니기 때문에 그렇다고 유추할 수 있습니다. 둘 다 0이겠죠.
LOr (LNotEqual (TPIF, One), LAnd (DSYN, One))
LNotEqual: 0이 되기 위해서는 TPIF*는 One**이어야 합니다.
LNotEqual(TPIF*,One**)
LAnd: 0이 되기 위해서는 DSYN^은 One^^이 아니어야 합니다.
LAnd (DSYN^, One^^)
LOr을 true로 설정하기 위해서는 TPIF*를 One**이 아닌 다른 값으로 설정하거나 DSYN^을 One^^과 같은 값으로 설정하면 됩니다. 그런데 제가 제 DSDT를 살펴보니, DYSN^은 다른 부분에서도 많이 활용되고 있습니다. TPIF*는 이곳 딱 한번 사용됩니다. 그렇다면 잘못 설정했다가 부팅불능에 빠질 수 있는 DYSN^을 설정하기보다는 TPIF*를 설정하는 것이 좋겠습니다.
Presetting the variable TPIF
TPIF*는 One**이 아니면 됩니다. 저는 Zero를 선택하겠습니다.
DefinitionBlock ("", "SSDT", 2, "hack", "touchp", 0)
{
TPIF*=0
}
그런데 TPIF*가 어디 소속인지 알아야 DSDT와 SSDT간 정보를 정확하게 주고 받을 수 있습니다. DSDT를 보시면 _SB Scope%에 있습니다.
Scope (_SB)%
{
OperationRegion (ASIO, SystemMemory, ASIB, 0x09)
Field (ASIO, AnyAcc, NoLock, Preserve)
{
ASIS, 32,
TPIF*, 8,
TPDI, 8,
TPLP, 8,
TPLI, 8,
TPHI, 8
}
}
그렇다면 External Declaration%%과 scope% 경로를 추가합니다.
DefinitionBlock ("", "SSDT", 2, "hack", "touchp", 0)
{
External (_SB.TPIF,FieldUnitObj)%%
Scope (_SB)%
{
TPIF*=0
}
}
끝...?
이렇게 하면 터치패드 비활성화 목적은 달성한건데...왜 한 거죠?
물론 앞에도 말씀드렸지만, 논리적인 ACPI 테이블을 구성하기 위해서입니다.
그러면 도대체 왜 터치패드를 비활성화 할까요?
장치 내용을 논리적으로 수정해서 새로운 터치패드 장치로 추가하기 위해서 입니다.
Creating a new device
I2C 터치패드는 애플과 완전히 호환되지 않기 때문에 켁스트 설치가 필요한데요. 설치만 하면 작동하는 1 %를 제외한 99 %의 유저들은 터치패드에 관한 ACPI 코드를 수정해주어야 합니다. GPIO pin도 계산해서 여러 값을 할당해야 하고, SBFx Object를 추가하거나, Method(_CRS)의 Return 값을 변경해야 합니다. 기존의 방법으로는 이런 것들을 추가하는 과정에서 DSDT를 직접 수정하거나 SSDT를 추가하겠죠. DSDT 수정을 택한다면 특별히 추가적으로 할 일은 없지만 이전 글에도 언급했듯이, 바이오스 세팅이나 노트북 구성을 변경한다면 다시 패치해주어야 합니다. SSDT에 추가 내용을 할당한다면 부트로더를 통해 이 Object들의 헤더와 함께 이름을 바꾸어 기존 정의가 다른 곳에서 사용되지 않도록 하고 패치된 Object들을 SSDT에 추가해줍니다.
그런데 저는 이미 기존 터치패드를 TPIF*=0을 통해 비활성화 했습니다. 그렇다면 새로운 터치패드 장치를 추가해서, 여러 Object 내용을 직접 수정해주면 아주 논리적인 ACPI 테이블을 구성할 수 있을 것입니다.
다음과 같이 새로운 터치패드 장치를 추가합니다. 충돌이 일어나지 않기 위해 이름을 ETXX^로 바꾸었습니다.
DefinitionBlock ("", "SSDT", 2, "hack", "elan", 0)
{
Device (_SB.PCI0.I2C1.ETXX)^
{
...
Method (_STA, 0, NotSerialized)^^ // _STA: Status
{
If (LOr (LNotEqual (TPIF, One), LAnd (DSYN, One)))
{
Return (Zero)
}
Return (0x0F)
}
}
Method (_CRS, 0, Serialized)^^^ // _CRS: Current Resource Settings
{
Name (SBFI, ResourceTemplate ()
{
I2cSerialBusV2 (0x0015, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C1",
0x00, ResourceConsumer, , Exclusive,
)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, )
{
0x0000006D,
}
})
Return (SBFI)
}
}
이중에서 Method (_STA)^^는 변경해주어야 합니다. 왜냐하면 TPIF*를 이미 preset했기 때문에 Method(_STA)^^를 그대로 가져온다면 이 추가한 장치 역시 비활성화 될 것입니다. Method(_CRS)^^^ 또한 패치해야 합니다. ASUS노트북의 터치패드를 Polling Mode로 안정적으로 사용하기 위해 Interrupt를 삭제하고, SBFI를 제 경우 VoodooI2CHID가 알맞게 인식하는 이름인 SBFB로 바꾸어주어야 합니다.
이외에도 충돌되는 경우가 있는지 확인하고 USTP=1^^^^이라는 Integer Object를 정의해야 합니다. 장치 작동 중 Initialization이 제대로 이루어질 수 있도록 _SB.PCI0.I2C1.ETXX 경로 중에 넣는 것이 좋을텐데, 루트 경로에는 이미 8비트짜리 동일한 이름의 FieldUnitObj****가 있습니다.
OperationRegion (GNVS, SystemMemory, 0x9ADE3000, 0x0745)
Field (GNVS, AnyAcc, Lock, Preserve)
{...
USTP, 8,****
...
}
따라서 루트 경로에 새로 USTP^^^^를 생성하기 위해서는 기존 이름을 다른 것으로 바꾸어주어야 합니다. 그렇지만 주제에 알맞게 ACPI Rename을 최소화한다는 것에서 부족한 점이 있죠.
루트 경로 이외에 충돌될만한 곳이 없기 때문에 I2C1 경로에 USTP^^^^를 생성하면 별도 config.plist rename이 필요 없습니다.
여기까지 읽어주신 감사한 분들께서는 어떻게 패치해야 되는지 아주 잘 아실겁니다. 다음과 같습니다.
DefinitionBlock ("", "SSDT", 2, "hack", "elan", 0)
{
Scope(_SB.PCI0.I2C1)
{
Name (USTP, One)^^^^
}
Device (_SB.PCI0.I2C1.ETXX)^
{
...
Method (_STA, 0, NotSerialized)^^ // _STA: Status
{
Return (0x0F)
}
Method (_CRS, 0, Serialized)^^^ // _CRS: Current Resource Settings
{
Name (SBFB, ResourceTemplate ()
{
I2cSerialBusV2 (0x0015, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C1",
0x00, ResourceConsumer, , Exclusive,
)
})
Return (SBFB)
}
물론 컴파일 눌러보고 에러 뜨면 External Declaration을 추가해야 합니다.
이제 끝났다고 보시면 됩니다. 다만 ACPI Table은 결합해도 상관이 없기 때문에 TPIF=0와 위 "elan" SSDT를 더해 하나로 저장하면 더 간편하겠죠. 끝끝...?
"Why" again?
여기까지 "논리적"으로 ACPI 테이블을 구성하는 방법을 알아보았습니다. 굳이 라고 생각하는 분도 계실것이고, 복잡하다고 생각하는 분들도 계실거구요. 사실 OpenCore에 최적화된 방법이라고 보시면 됩니다. 윈도우, 리눅스, macOS를 전부 부팅 가능하게 하는 통합 ACPI 구성. 제가 작성한 ETXX 패치는 몇 개의 If (_OSI ("Darwin"))만 작성한다면 윈도우와 macOS에 전혀 충돌이 없는 터치패드 코드가 됩니다. TPIF를 macOS인 경우에만 Zero로 설정하고, USTP=1 또한 그러하고, ETXX의 _STA Method 또한 macOS의 경우에 Return (0x0F), 윈도우의 경우에 Return (0)로 설정하면 됩니다. 리눅스는 아예 안 쓰기 때문에 테스트는 안할거지만, 애초에 충돌되는 코드가 없습니다.
오픈코어 최적화 방식이긴 하지만, 그래도 여전히 클로버에서 사용해도 문제가 전혀 없고, 자기 ACPI 테이블 공부하는데 많은 도움이 됩니다. 그리고 삽질로서 논리적인 ACPI 테이블을 구성한 셈이구요. 셀프박수 치셔도^^
제가 사용한 DSDT 테이블, 작성한 SSDT 첨부합니다. SSDT에는 I2C0 장치를 비활성화 하는 Method (_STA)와 I2C1 optimization이 추가로 들어있습니다. I2C0의 경우 preset variable이 기존 할당된 값에 매칭이 되고 macOS를 부팅한 경우가 동시에 만족되면 장치를 비활성화 시키는 Method (_STA)를 생성하고, optimization 내용으로는 I2C1에 FMCN과 SSCN을 수동할당했습니다. PVM예제파일.zip
그리고 여기까지 기존 장치를 비활성화, 새로운 패치된 장치를 활성화시켰는데, Preset Variable Method는 이것에만 제한되지 않고, 해당 변수를 사용하는 모든 if문에 적용 가능합니다. 제가 사용해볼 만한 조건이 없는 것 같아서 나중에 찾아서 기회가 되면 소개하는 걸루...
끝끝끝!
Update 2020.02.23.
VoodooI2CHID는 ACPI에서 APIC이나 GPIO가 활성화되지 않으면 Polling Mode로 작동합니다. 물론 이 때 Voodoo.github.io의 설명서에 따라 SBFB에 해당하는 Object가 _CRS에서 Return되어야 하지만, 그 이름이 SBFB인지, SBFI인지는 상관 없습니다. ASUS 노트북 사용자는 아시겠지만, 본인의 DSDT를 보면 GPIO는 처음부터 비활성화 되어있고, _CRS에서 SBFB에 해당하는 SBFI가 Return되므로 VoodooI2C와 VoodooI2CHID가 제대로 설치되면 터치패드는 무조건 작동합니다. 여기에 추가적으로 SSCN과 FMCN이 활성화되어야 하는데, ASUS는 이를 활성화시키는 USTP를 숨겨놓았으므로, 직접 Name(USTP,1)을 정의해주면 되는데, Root scope (\)에 이미 FieldUnitObject USTP가 있으므로, 이를 피해 I2C가 활성화될 수 있는 경로 중 하나에만 작업을 해주면 됩니다. 그래서 저는 \_SB.PCI0.I2C1에 USTP를 정의했으며, polling mode 완벽 작동입니다. OS 새로 설치하거나 업데이트 시 오픈코어 사용하거나 클로버 사용자는 캐시 리빌드 해주셔야지만 터치패드 작동합니다. 아래 1번 댓글 통해서 SSDT 다운로드 가능합니다. 이 본문은 나름 Preset Variable Method 사용에 도움이 되므로 그대로 사용하셔도 되고, 새로운 SSDT로 간단하게 터치패드 사용하셔도 됩니다.
Credits
Daliansky, williambj1, acidanthera
https://github.com/daliansky/OC-little/tree/master/01-2-%E9%A2%84%E7%BD%AE%E5%8F%98%E9%87%8F%E6%B3%95 이 글은 번역기로 보시면 됩니다. 크롬 내장 번역기는 한글로 보면 매우 이상하고 영어는 준수합니다.
https://github.com/acidanthera/OpenCorePkg/blob/master/Docs/Configuration.pdf
#ACPI_Rename_대신_Preset_Variable_Method,#TPIF_TPIF,#STA_Method,#STA,#One,#I2C0,#TPIF,#The_content_of_Method,#Return,#장치
"님의 댓글"
이 댓글을 신고 하시겠습니까?
제목 | 조회 수 | 날짜 | 글쓴이 |
---|---|---|---|
macOS Sequoia 15.0.1 24A348 정식버젼 고스트 이미지 OC 1.0.2 ft: 전체공개 +29 | 938 | 24.10.1121:10 | 좌절금지 |
오픈코어 1.0.2 +23 | 575 | 24.10.0900:22 | 줌바이퍼 |
[중급편] 노트북 해킨 +16 | 1403 | 24.07.1219:19 | Stultus |
macOS Ventura 13.7 22H123 정식버젼 고스트 이미지 OC 1.0.1 ft: 전체 공개 +17 | 575 | 24.09.1917:09 | 좌절금지 |
macOS Sonoma 14.7 23H124 정식버젼 고스트 이미지 OC 1.0.1 ft: 전체공개 +31 | 909 | 24.09.1723:58 | 좌절금지 |
[초급편] 문제 스스로 해결하기 +20 | 4003 | 24.03.2920:07 | Stultus |
[입문편] 첫 해킨 길라잡이 +40 | 5087 | 24.01.1218:54 | Stultus |
[필독 - 안정화] macOS 해킨토시 설치 후 안정화 작업 목록 및 글타래 모음 총정리 📋 +67 | 5.1만 | 23.01.0913:39 | shl628 |
Hot AMD Sequoia용 AppleALC 1.9.2 +3 | 107 | 24.10.2319:04 | 사노라맨 |
Hot [Sequoia 15.0.1, OC r1.0.2] ASUS TUF B550-PLUS / RYZEN 5 5600X / RX470 +2 | 104 | 24.10.2322:26 | 뿌엥 |
Hot OCLP로 지원되지 않는 기기/dGPU를 사용하는 해킨토시의 사이드카 품질 문제 해결방법 +1 | 120 | 24.10.2321:29 | 해킨도전자 |
104 | 24.10.2322:26 | 뿌엥 | |
120 | 24.10.2321:29 | 해킨도전자 | |
107 | 24.10.2319:04 | 사노라맨 | |
786 | 24.10.1412:27 | shl628 | |
671 | 24.10.1316:00 | 수박 | |
344 | 24.10.1222:56 | Stultus | |
938 | 24.10.1121:10 | 좌절금지 | |
733 | 24.10.1115:53 | 수박 | |
575 | 24.10.0900:22 | 줌바이퍼 | |
1403 | 24.07.1219:19 | Stultus | |
1213 | 24.10.0500:31 | 줌바이퍼 | |
569 | 24.10.0410:49 | Tamy | |
749 | 24.09.2923:48 | 머트 | |
628 | 24.09.2822:28 | 머트 | |
463 | 24.09.2808:22 | Tamy | |
894 | 24.09.2321:32 | Stultus | |
994 | 24.09.2210:59 | 좌절금지 | |
644 | 24.09.2203:23 | 누림어멈 | |
1191 | 24.09.1919:17 | 좌절금지 | |
575 | 24.09.1917:09 | 좌절금지 | |
498 | 24.09.1813:37 | Stultus | |
909 | 24.09.1723:58 | 좌절금지 | |
601 | 24.09.1722:40 | 좌절금지 | |
453 | 24.09.1717:13 | 맥가즈아 | |
562 | 24.09.1708:13 | 김경석 | |
234 | 24.09.1617:47 | Panictosh | |
768 | 24.09.1504:35 | Tamy | |
584 | 24.09.1319:18 | Stultus | |
706 | 24.09.1019:44 | 치토 | |
484 | 24.09.0118:13 | 머핀X | |
462 | 24.09.0112:54 | 해킨도전자 | |
546 | 24.08.3115:34 | 머핀X | |
306 | 24.08.2601:42 | 화정큐삼 | |
305 | 24.08.2422:59 | 하나브 | |
318 | 24.08.2316:25 | 화정큐삼 | |
415 | 24.08.1810:56 | CanBe | |
363 | 24.08.1800:04 | 화정큐삼 | |
300 | 24.08.1722:03 | 화정큐삼 | |
201 | 24.08.1710:14 | jbhlyk | |
312 | 24.08.1622:06 | Stultus | |
218 | 24.08.1511:16 | hackillious | |
169 | 24.08.1421:30 | 세유니 | |
419 | 24.08.1419:58 | Stultus | |
377 | 24.08.1311:26 | 오디세이 | |
270 | 24.08.1115:46 | 좌절금지 | |
186 | 24.08.1111:21 | 티타보르 | |
233 | 24.08.1022:46 | Stultus | |
538 | 24.08.1022:10 | 오디세이 | |
168 | 24.08.1019:05 | jbhlyk | |
200 | 24.08.0923:20 | RogerT |