nmarshall commited on
Commit
09af7e8
·
1 Parent(s): 245c80a

qvm: packed mode controls

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -385,3 +385,6 @@ Research progress: RE-563 [report](research/QVM_RELOAD_REQUEST.md); remaining na
385
 
386
 
387
  Research progress: RE-564 [report](research/QVM_INTERACTION_REQUEST.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
385
 
386
 
387
  Research progress: RE-564 [report](research/QVM_INTERACTION_REQUEST.md); remaining native/content/runtime/platform scope stays open.
388
+
389
+
390
+ Research progress: RE-565 [report](research/QVM_PACKED_CONTROLS.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -743,3 +743,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
743
 
744
 
745
  **RE-564 — Interaction trace and direct action consumers:** 49918 chooses a contents-bit33554432 trace action or direct state128/256 action, applies ordered timers/events/animations, and uses a health-gated first16-slot item19 search to select750 versus1500. [Evidence](research/QVM_INTERACTION_REQUEST.md).
 
 
 
 
743
 
744
 
745
  **RE-564 — Interaction trace and direct action consumers:** 49918 chooses a contents-bit33554432 trace action or direct state128/256 action, applies ordered timers/events/animations, and uses a health-gated first16-slot item19 search to select750 versus1500. [Evidence](research/QVM_INTERACTION_REQUEST.md).
746
+
747
+
748
+ **RE-565 — Packed mode availability edge latch and resource countdown:** 50250 edge-latches button128 into state32768/event15;50309 permits availability on mode flag4 or nonzero magazine;50397 drains with the full dt when its countdown reaches zero. [Evidence](research/QVM_PACKED_CONTROLS.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -697,3 +697,6 @@ Research progress: RE-563 [report](research/QVM_RELOAD_REQUEST.md); remaining na
697
 
698
 
699
  Research progress: RE-564 [report](research/QVM_INTERACTION_REQUEST.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
697
 
698
 
699
  Research progress: RE-564 [report](research/QVM_INTERACTION_REQUEST.md); remaining native/content/runtime/platform scope stays open.
700
+
701
+
702
+ Research progress: RE-565 [report](research/QVM_PACKED_CONTROLS.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -521,3 +521,8 @@ RE-549–558 each has its own code/tests/report/documentation commit. All759 tes
521
  ## 2026-10-20 — RE-564 Interaction trace and direct action consumers (separate task commit)
522
 
523
  49918 chooses a contents-bit33554432 trace action or direct state128/256 action, applies ordered timers/events/animations, and uses a health-gated first16-slot item19 search to select750 versus1500. 47 fixtures independently check gate priority, signed height division, trace geometry, first matching inventory slot including excluded slot16, timer/state/animation effects and event order. Full suite: 779 tests pass. Report regenerates byte-identically (345178 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
521
  ## 2026-10-20 — RE-564 Interaction trace and direct action consumers (separate task commit)
522
 
523
  49918 chooses a contents-bit33554432 trace action or direct state128/256 action, applies ordered timers/events/animations, and uses a health-gated first16-slot item19 search to select750 versus1500. 47 fixtures independently check gate priority, signed height division, trace geometry, first matching inventory slot including excluded slot16, timer/state/animation effects and event order. Full suite: 779 tests pass. Report regenerates byte-identically (345178 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
524
+
525
+
526
+ ## 2026-10-20 — RE-565 Packed mode availability edge latch and resource countdown (separate task commit)
527
+
528
+ 50250 edge-latches button128 into state32768/event15;50309 permits availability on mode flag4 or nonzero magazine;50397 drains with the full dt when its countdown reaches zero. Seven chained latch ticks,30 availability probes and44 resource fixtures independently check release/rearm, queue wrap, packed addressing, signed multiplication/subtraction wrap and clamps. Full suite: 783 tests pass. Report regenerates byte-identically (191549 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -737,3 +737,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
737
 
738
 
739
  - [x] RE-564 Interaction trace and direct action consumers ([report](research/QVM_INTERACTION_REQUEST.md)).
 
 
 
 
737
 
738
 
739
  - [x] RE-564 Interaction trace and direct action consumers ([report](research/QVM_INTERACTION_REQUEST.md)).
740
+
741
+
742
+ - [x] RE-565 Packed mode availability edge latch and resource countdown ([report](research/QVM_PACKED_CONTROLS.md)).
docs/research/QVM_PACKED_CONTROLS.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Packed mode availability edge latch and resource countdown
2
+
3
+ RE-565. Reproduce with `python3 scripts/analyze_qvm_packed_controls.py`; check with `python3 scripts/test_qvm_packed_controls.py`. The [machine report](qvm-packed-controls.json) retains source identity and bounded fixtures.
4
+
5
+ Three complete bounded leaves now execute with source traces.50250 emits event15 only on an unlatched button128 press, sets state32768, leaves a held press latched, and clears the latch on release.50309 returns1 if the selected52-byte mode record flags+4 contain4, otherwise returns whether packed magazine bits8..15 are nonzero. The mode address is4244+432×id+52×mode, with ID low byte and mode bits16..23.
6
+
7
+ 50397 subtracts integer global35023932 from nonzero PS196, clamps negative countdown to0, then if zero subtracts mode+28 rate×the full tick dt from PS188 and clamps negative resource to0. For timer15, dt16, resource1000 and rate2, the result is968. It does not drain only one unit of elapsed time. Signed32 multiplication/subtraction wrap follows the VM instruction semantics; negative and overflow values are explicit synthetic boundary fixtures, not asserted legal gameplay inputs.
8
+
9
+ Image mode flags are retained for selected initialized records; marked flags overrides isolate the no-magazine exception. All resource rates are explicitly supplied. Remaining: identify the resource and its writers, validate legal rates and live mode initialization, and integrate these leaves with the actual weapon prefix and subsequent state machine.
10
+
11
+ No original executable/full QVM/native collision/physics/rendering executes. Native responses and legal input domains are supplied or unverified where stated; full runtime/macOS/Linux Rust/Bevy/Solari gameplay remains open.
docs/research/README.md CHANGED
@@ -298,3 +298,6 @@ The extension collector adds five focused tests for native tail calls, command-r
298
 
299
 
300
  [RE-564: Interaction trace and direct action consumers](QVM_INTERACTION_REQUEST.md). Reproduce with `python3 scripts/analyze_qvm_interaction_request.py`; check with `python3 scripts/test_qvm_interaction_request.py`.
 
 
 
 
298
 
299
 
300
  [RE-564: Interaction trace and direct action consumers](QVM_INTERACTION_REQUEST.md). Reproduce with `python3 scripts/analyze_qvm_interaction_request.py`; check with `python3 scripts/test_qvm_interaction_request.py`.
301
+
302
+
303
+ [RE-565: Packed mode availability edge latch and resource countdown](QVM_PACKED_CONTROLS.md). Reproduce with `python3 scripts/analyze_qvm_packed_controls.py`; check with `python3 scripts/test_qvm_packed_controls.py`.
docs/research/qvm-packed-controls.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_packed_controls.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """50250 edge latch,50309 availability and50397 resource countdown."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source,execute
6
+ from qvm_suffix_support import seed,state,handlers,weapon_config
7
+ from analyze_qvm_acceleration import PS,FRAME
8
+ from analyze_qvm import write_json
9
+ LOCAL=0x6f000000
10
+ STOPS={50250:50307,50309:50395,50397:50523}
11
+
12
+ def control(ins,m,entry,cmd=(0,0,0)):
13
+ initial=state(m);packed=initial['packed'];address=4244+432*(packed&255)+52*((packed>>16)&255)
14
+ cfg={'address':address,'flags':m.get(address+4,0)&0xffffffff,'rate':m.get(address+28,0)&0xffffffff}
15
+ m,c,r=execute(ins,entry+1,STOPS[entry],m,cmd,LOCAL+(entry-50250)*0x100,handlers())
16
+ return m,{'entry':entry,'initial':initial,'buttons':m[FRAME+20],'dt':m[35023932],'mode_config':cfg,'execution':r,'final':state(m)}
17
+
18
+ def main():
19
+ q,raw,h,ins=source();edge=[];m=weapon_config(seed(raw,h),raw,h);m[PS+108]=0xffffffff
20
+ for button in [128,128,0,128,0,0,128]:m[FRAME+20]=button;m,p=control(ins,m,50250);edge.append(p)
21
+ avail=[]
22
+ for ident,mode,mag in itertools.product([1,14,22,23],[0,1,2],[0,1]):
23
+ m=weapon_config(seed(raw,h),raw,h);m[PS+312]=ident|(mode<<16)|(mag<<8);avail.append(control(ins,m,50309)[1])
24
+ for flags,mag in itertools.product([0,4,5],[0,1]):
25
+ m=weapon_config(seed(raw,h),raw,h);m[PS+312]=1|(mag<<8);m[4244+432+4]=flags;p=control(ins,m,50309)[1];p['supplied_mode_override']=True;avail.append(p)
26
+ resources=[]
27
+ for timer,resource,dt in [(0,1000,16),(15,1000,16),(16,1000,16),(17,1000,16),(-1,10,16),(0,10,0),(0,-1,16),(0,0,200),(1,10,200),(0,10,16),(0,0x7fffffff,200)]:
28
+ for rate in [0,2,-1,0x7fffffff]:
29
+ m=weapon_config(seed(raw,h),raw,h);m.update({PS+312:1,PS+196:timer,PS+188:resource,35023932:dt,4244+432+28:rate});resources.append(control(ins,m,50397)[1])
30
+ write_json(Path('docs/research/qvm-packed-controls.json'),{'source':q['source'],'sha256':q['sha256'],'edge_sequence':edge,'availability':avail,'resources':resources,'limits':'Complete bounded50250/50309/50397. Image mode flags plus marked overrides; all resource rates/countdowns are supplied finite32-bit values. No weapon firing/full runtime or resource semantic validation.'})
31
+ if __name__=='__main__':main()
scripts/test_qvm_packed_controls.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest,copy
2
+ from pathlib import Path
3
+ from test_qvm_torso_selector import signed
4
+ from test_qvm_water_events import enqueue
5
+
6
+ def i32(x):return signed(x&0xffffffff)
7
+
8
+ def resource_state(p):
9
+ a=copy.deepcopy(p['initial']);timer=signed(a['resource_timer']);timer=i32(timer-p['dt']) if timer else timer;timer=max(timer,0);resource=signed(a['resource'])
10
+ if timer==0:resource=i32(resource-i32(signed(p['mode_config']['rate'])*p['dt']))
11
+ a['resource_timer']=timer;a['resource']=max(resource,0);return a
12
+ class PackedControlsTests(unittest.TestCase):
13
+ @classmethod
14
+ def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-packed-controls.json').read_text())
15
+ def test_edge_sequence_release_rearm_and_queue_wrap(self):
16
+ rows=self.r['edge_sequence'];self.assertEqual(len(rows),7)
17
+ for j,p in enumerate(rows):
18
+ a=copy.deepcopy(p['initial']);pressed=bool(p['buttons']&128);event=pressed and not a['state220']&32768;a['state220']=(a['state220']|32768) if pressed else a['state220']&~32768;a['queue']=enqueue(a['queue'],[15] if event else []);self.assertEqual(a,p['final']);self.assertEqual([c['args']['8'] for c in p['execution']['calls']],[15] if event else [])
19
+ if j:self.assertEqual(p['initial'],rows[j-1]['final'])
20
+ def test_availability_mode_flag_overrides_zero_magazine(self):
21
+ self.assertEqual(len(self.r['availability']),30)
22
+ for p in self.r['availability']:self.assertEqual(p['execution']['return'],int(bool(p['mode_config']['flags']&4 or p['initial']['packed']&65280)));self.assertEqual(p['initial'],p['final']);self.assertEqual(p['execution']['calls'],[])
23
+ def test_resource_signed_wrap_clamp_and_full_dt(self):
24
+ self.assertEqual(len(self.r['resources']),44)
25
+ for p in self.r['resources']:self.assertEqual(p['final'],resource_state(p));self.assertEqual(p['execution']['calls'],[])
26
+ rows=[p for p in self.r['resources'] if p['initial']['resource_timer']==15 and p['mode_config']['rate']==2];self.assertEqual(rows[0]['final']['resource'],968)
27
+ def test_mode_address_uses_id_and_mode_bytes(self):
28
+ for p in self.r['availability']+self.r['resources']:
29
+ packed=p['initial']['packed'];self.assertEqual(p['mode_config']['address'],4244+432*(packed&255)+52*((packed>>16)&255));self.assertEqual(p['initial']['packed'],p['final']['packed'])
30
+ if __name__=='__main__':unittest.main()