needs lib/str lib/type lib/struct unit drv/acpi : ?err ?abort"ACPI error" ; : csum[] ( a u -- n ) 0 rot> 0 do c@+ rot + swap loop drop ; : ck[]# ( a u -- ) csum[] $ff and ?err ; struct RSDP { [uchar,8] signature ; uchar checksum ; [uchar,6] oemid ; uchar revision ; uint rsdtaddr length xsdtaddr ; uchar extchecksum ; } variable ptr ptr RSDP bindstruct create expected ,"RSD PTR " : rsdp# ( -- ) signature expected 2 []= not ?err ptr @ 20 ck[]# revision if ptr @ 36 ck[]# then ; struct Header { uint signature length ; uchar revision checksum ; [uchar,6] oemid ; [uchar,8] oemtableid ; uint oemrevision creatorid creatorrevision ; } : cktbl# ( tbl -- ) dup length ck[]# ; $40 const MAXTBLCNT create roottbls MAXTBLCNT 4* allot0 : acpi$ ( rsdpaddr -- ) ptr ! rsdp# RSDP.revision 2 < ?abort"ACPI too old for this driver" xsdtaddr dup cktbl# dup length ( tbl n ) Header typesz consume[] 8/ ( entries u ) MAXTBLCNT 1- min 0 do ( a ) dup @ roottbls i 4* + ! 8+ loop drop ; : .acpi ( -- ) ."RDSP " ptr @ .x nl> roottbls begin @+ ?dup while 4 rtype spc> repeat ; : findtable ( sig -- tbl-or-0 ) roottbls begin @+ ?dup while be@ oover <> while repeat ( sig a+4 ) nip 4- @ else ( sig a ) 2drop 0 then ; extends Header struct FADT { uint firmwarectrl dsdt ; } \ ... : DSDT# ( -- tbl ) n"FACP" findtable dup not ?err dsdt ;