Word Unperfect
public
Read
Owner: themaster
Branch: main
Commits: 0
Git CLI clone URL
git clone https://www.xt-emporium.com/git/word-unperfect.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
word-unperfect
/
rev
/
wp_record_ring.c
File editor
#include "wp_record_ring.h" #include <string.h> void wp_record_ring_result_clear(WpRecordRingResult *result) { if (result != NULL) { memset(result, 0, sizeof(*result)); } } void wp_record_ring_result_merge(WpRecordRingResult *dst, const WpRecordRingResult *src) { if (dst == NULL || src == NULL) { return; } dst->primary_compactions += src->primary_compactions; dst->primary_bytes_dropped += src->primary_bytes_dropped; dst->primary_bytes_moved += src->primary_bytes_moved; dst->secondary_slides += src->secondary_slides; dst->secondary_bytes_shifted += src->secondary_bytes_shifted; dst->secondary_bytes_reserved += src->secondary_bytes_reserved; dst->secondary_space_probes += src->secondary_space_probes; dst->secondary_space_satisfied += src->secondary_space_satisfied; dst->secondary_space_failures += src->secondary_space_failures; dst->overlay_advance_calls += src->overlay_advance_calls; dst->overlay_advance_completed += src->overlay_advance_completed; dst->overlay_advance_blocked += src->overlay_advance_blocked; dst->gate_raise_calls += src->gate_raise_calls; dst->overlay_resume_calls += src->overlay_resume_calls; dst->rom_flag_pulses += src->rom_flag_pulses; dst->record_block_bumps += src->record_block_bumps; dst->scale_fixed_point_bumps += src->scale_fixed_point_bumps; dst->far_bump_calls += src->far_bump_calls; dst->far_bump_passthroughs += src->far_bump_passthroughs; dst->far_bump_blocked += src->far_bump_blocked; if (src->scratch_depth_max > dst->scratch_depth_max) { dst->scratch_depth_max = src->scratch_depth_max; } dst->primary_underflow = dst->primary_underflow || src->primary_underflow; dst->secondary_gate_closed = dst->secondary_gate_closed || src->secondary_gate_closed; dst->secondary_insufficient_space = dst->secondary_insufficient_space || src->secondary_insufficient_space; dst->gate_already_raised = dst->gate_already_raised || src->gate_already_raised; dst->advance_blocked_by_gate = dst->advance_blocked_by_gate || src->advance_blocked_by_gate; dst->old_record_used_bytes = src->old_record_used_bytes; dst->new_record_used_bytes = src->new_record_used_bytes; dst->old_secondary_used_bytes = src->old_secondary_used_bytes; dst->new_secondary_used_bytes = src->new_secondary_used_bytes; dst->old_record_buffer_space = src->old_record_buffer_space; dst->new_record_buffer_space = src->new_record_buffer_space; dst->old_record_stream_cursor = src->old_record_stream_cursor; dst->new_record_stream_cursor = src->new_record_stream_cursor; dst->record_stream_cursor_highwater = src->record_stream_cursor_highwater; dst->computed_block_offset_low = src->computed_block_offset_low; dst->computed_block_offset_high = src->computed_block_offset_high; } bool wp_record_ring_compact_primary_by_2kb(WpLayoutGlobals *wl, WpRecordRingResult *out_result) { WpRecordRingResult result; uint8_t *cursor; uint8_t *base; size_t remaining; wp_record_ring_result_clear(&result); if (wl == NULL) { if (out_result != NULL) { *out_result = result; } return false; } result.old_record_used_bytes = (uint16_t)wl->record_used_bytes; result.old_record_buffer_space = (uint16_t)wl->record_buffer_space; if (wl->record_used_bytes < (int)WP_RECORD_RING_BLOCK_BYTES || wl->primary_record.as_record_p == NULL) { result.primary_underflow = true; result.new_record_used_bytes = (uint16_t)wl->record_used_bytes; result.new_record_buffer_space = (uint16_t)wl->record_buffer_space; if (out_result != NULL) { *out_result = result; } return false; } cursor = (uint8_t *)wl->primary_record.as_record_p; base = cursor - (size_t)wl->record_used_bytes; remaining = (size_t)wl->record_used_bytes - WP_RECORD_RING_BLOCK_BYTES; if (remaining != 0U) { memmove(base, base + WP_RECORD_RING_BLOCK_BYTES, remaining); } wl->record_used_bytes -= (int)WP_RECORD_RING_BLOCK_BYTES; wl->primary_record.as_record_p = (uint16_t *)(cursor - WP_RECORD_RING_BLOCK_BYTES); wl->record_buffer_space = (uint16_t)(wl->record_buffer_space + WP_RECORD_RING_BLOCK_BYTES); result.primary_compactions = 1U; result.primary_bytes_dropped = WP_RECORD_RING_BLOCK_BYTES; result.primary_bytes_moved = remaining; result.new_record_used_bytes = (uint16_t)wl->record_used_bytes; result.new_record_buffer_space = (uint16_t)wl->record_buffer_space; if (out_result != NULL) { *out_result = result; } return true; } bool wp_record_ring_slide_secondary_by_2kb(WpLayoutGlobals *wl, WpRecordRingResult *out_result) { WpRecordRingResult result; WpRecordRingResult primary; uint8_t *old_start; uint8_t *new_start; size_t old_used; bool original_less_than_block; bool may_slide; wp_record_ring_result_clear(&result); if (wl == NULL) { if (out_result != NULL) { *out_result = result; } return false; } result.old_record_used_bytes = (uint16_t)wl->record_used_bytes; result.old_secondary_used_bytes = (uint16_t)wl->secondary_record_used_bytes; result.old_record_buffer_space = (uint16_t)wl->record_buffer_space; if (wl->secondary_record_stream_gate_54a9 == 0) { result.secondary_gate_closed = true; result.new_record_used_bytes = (uint16_t)wl->record_used_bytes; result.new_secondary_used_bytes = (uint16_t)wl->secondary_record_used_bytes; result.new_record_buffer_space = (uint16_t)wl->record_buffer_space; if (out_result != NULL) { *out_result = result; } return false; } original_less_than_block = wl->record_buffer_space < WP_RECORD_RING_BLOCK_BYTES; if (wl->record_buffer_space > WP_RECORD_RING_BLOCK_BYTES) { may_slide = true; } else { if (wp_record_ring_compact_primary_by_2kb(wl, &primary)) { wp_record_ring_result_merge(&result, &primary); } else { result.primary_underflow = result.primary_underflow || primary.primary_underflow; } may_slide = !original_less_than_block; } if (!may_slide || wl->secondary_record.as_secondary_p == NULL) { result.secondary_insufficient_space = !may_slide; result.new_record_used_bytes = (uint16_t)wl->record_used_bytes; result.new_secondary_used_bytes = (uint16_t)wl->secondary_record_used_bytes; result.new_record_buffer_space = (uint16_t)wl->record_buffer_space; if (out_result != NULL) { *out_result = result; } return false; } old_start = wl->secondary_record.as_secondary_p; new_start = old_start - WP_RECORD_RING_BLOCK_BYTES; old_used = (size_t)wl->secondary_record_used_bytes; if (old_used != 0U) { memmove(new_start, old_start, old_used); } memset(new_start + old_used, 0, WP_RECORD_RING_BLOCK_BYTES); wl->secondary_record.as_secondary_p = new_start; wl->record_buffer_space = (uint16_t)(wl->record_buffer_space - WP_RECORD_RING_BLOCK_BYTES); wl->secondary_record_used_bytes += (int)WP_RECORD_RING_BLOCK_BYTES; result.secondary_slides = 1U; result.secondary_bytes_shifted = old_used; result.secondary_bytes_reserved = WP_RECORD_RING_BLOCK_BYTES; result.new_record_used_bytes = (uint16_t)wl->record_used_bytes; result.new_secondary_used_bytes = (uint16_t)wl->secondary_record_used_bytes; result.new_record_buffer_space = (uint16_t)wl->record_buffer_space; if (out_result != NULL) { *out_result = result; } return true; } bool wp_record_ring_check_secondary_space(WpLayoutGlobals *wl, uint16_t required_bytes, WpRecordRingResult *out_result) { WpRecordRingResult result; WpRecordRingResult slide; wp_record_ring_result_clear(&result); if (wl == NULL) { if (out_result != NULL) { *out_result = result; } return false; } result.old_record_used_bytes = (uint16_t)wl->record_used_bytes; result.old_secondary_used_bytes = (uint16_t)wl->secondary_record_used_bytes; result.old_record_buffer_space = (uint16_t)wl->record_buffer_space; result.secondary_space_probes = 1U; if ((uint16_t)wl->secondary_record_used_bytes < required_bytes) { if (wp_record_ring_slide_secondary_by_2kb(wl, &slide)) { wp_record_ring_result_merge(&result, &slide); } else { wp_record_ring_result_merge(&result, &slide); } } if ((uint16_t)wl->secondary_record_used_bytes >= required_bytes) { result.secondary_space_satisfied = 1U; } else { result.secondary_space_failures = 1U; } result.new_record_used_bytes = (uint16_t)wl->record_used_bytes; result.new_secondary_used_bytes = (uint16_t)wl->secondary_record_used_bytes; result.new_record_buffer_space = (uint16_t)wl->record_buffer_space; if (out_result != NULL) { *out_result = result; } return result.secondary_space_failures == 0U; } bool wp_record_ring_raise_gate_and_overlay_call(WpLayoutGlobals *wl, WpRecordRingResult *out_result) { WpRecordRingResult result; int depth; wp_record_ring_result_clear(&result); if (wl == NULL) { if (out_result != NULL) { *out_result = result; } return false; } /* Host-safe port of shell_record_raise_gate_and_overlay_call @ 4000:1b9d. * The DOS routine sets gate_char_0805 to 3, increments the overlay scratch * nesting byte, resumes the core overlay, and then decrements the scratch * byte. The host port preserves the visible state transitions and counts * the overlay resume rather than jumping into 16-bit overlay code. */ result.gate_raise_calls = 1U; result.overlay_resume_calls = 1U; wl->gate_char_0805 = 3; wl->scratch_char_0804 = (char)(wl->scratch_char_0804 + 1); depth = (int)(signed char)wl->scratch_char_0804; if (depth > result.scratch_depth_max) { result.scratch_depth_max = depth; } wl->scratch_char_0804 = (char)(wl->scratch_char_0804 - 1); result.new_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; result.record_stream_cursor_highwater = (uint16_t)wl->record_stream_cursor_highwater_496c; if (out_result != NULL) { *out_result = result; } return true; } bool wp_record_ring_overlay_advance_stream_block(WpLayoutGlobals *wl, WpRecordRingResult *out_result) { WpRecordRingResult result; uint32_t block_offset; int depth; int next_cursor; wp_record_ring_result_clear(&result); if (wl == NULL) { if (out_result != NULL) { *out_result = result; } return false; } /* Host-safe port of shell_record_overlay_advance_stream_block @ 4000:1926. * The recovered routine derives a DX:AX 2KB block offset from * record_stream_cursor_543a, pulses ROM I/O flag 0x20 around the firmware * initializer, and advances the stream cursor unless gate_char_0805 has * been raised. The host version records those transitions without trying * to call DOS/overlay firmware. */ result.overlay_advance_calls = 1U; result.old_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; block_offset = (uint32_t)(uint16_t)wl->record_stream_cursor_543a * WP_RECORD_RING_BLOCK_BYTES; result.computed_block_offset_low = (uint16_t)block_offset; result.computed_block_offset_high = (uint16_t)(block_offset >> 16); wl->record_stream_offset_low = result.computed_block_offset_low; wl->record_stream_offset_high = result.computed_block_offset_high; wl->scratch_char_0804 = (char)(wl->scratch_char_0804 + 1); depth = (int)(signed char)wl->scratch_char_0804; if (depth > result.scratch_depth_max) { result.scratch_depth_max = depth; } wl->rom_io_flags_c9e0 = (uint8_t)(wl->rom_io_flags_c9e0 | 0x20U); result.rom_flag_pulses = 1U; wl->rom_io_flags_c9e0 = (uint8_t)(wl->rom_io_flags_c9e0 & (uint8_t)~0x20U); if (wl->gate_char_0805 != 0) { result.overlay_advance_blocked = 1U; result.gate_already_raised = true; result.advance_blocked_by_gate = true; wl->scratch_char_0804 = (char)(wl->scratch_char_0804 - 1); result.new_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; result.record_stream_cursor_highwater = (uint16_t)wl->record_stream_cursor_highwater_496c; if (out_result != NULL) { *out_result = result; } return false; } next_cursor = wl->record_stream_cursor_543a + 1; wl->record_stream_cursor_543a = next_cursor; if (wl->record_stream_cursor_highwater_496c < next_cursor) { wl->record_stream_cursor_highwater_496c = next_cursor; } wl->scratch_char_0804 = (char)(wl->scratch_char_0804 - 1); result.overlay_advance_completed = 1U; result.new_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; result.record_stream_cursor_highwater = (uint16_t)wl->record_stream_cursor_highwater_496c; if (out_result != NULL) { *out_result = result; } return true; } bool wp_record_ring_far_bump_indices_if_ax(WpLayoutGlobals *wl, int16_t ax, bool carry_flag, WpRecordRingResult *out_result) { WpRecordRingResult result; WpRecordRingResult advance; wp_record_ring_result_clear(&result); if (wl == NULL) { if (out_result != NULL) { *out_result = result; } return false; } result.far_bump_calls = 1U; result.old_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; /* Host-safe port of shell_record_far_bump_indices_if_ax @ 4000:1911. * AX == -1 is a passthrough sentinel. Otherwise, a set carry flag routes * through shell_record_overlay_advance_stream_block first; if that path is * still blocked, the record-block and scale indices are not advanced. */ if (ax == (int16_t)-1) { result.far_bump_passthroughs = 1U; result.new_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; result.record_stream_cursor_highwater = (uint16_t)wl->record_stream_cursor_highwater_496c; if (out_result != NULL) { *out_result = result; } return true; } if (carry_flag) { if (!wp_record_ring_overlay_advance_stream_block(wl, &advance)) { wp_record_ring_result_merge(&result, &advance); result.far_bump_blocked = 1U; result.new_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; result.record_stream_cursor_highwater = (uint16_t)wl->record_stream_cursor_highwater_496c; if (out_result != NULL) { *out_result = result; } return false; } wp_record_ring_result_merge(&result, &advance); } wl->record_block_index = wl->record_block_index + 1U; wl->scale_fixed_point_51c4 = (int)(wl->scale_fixed_point_51c4 + 1); result.record_block_bumps += 1U; result.scale_fixed_point_bumps += 1U; result.new_record_stream_cursor = (uint16_t)wl->record_stream_cursor_543a; result.record_stream_cursor_highwater = (uint16_t)wl->record_stream_cursor_highwater_496c; if (out_result != NULL) { *out_result = result; } return true; }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
main
Visibility
public
Your access
Read
Remote
None
File activity
View file history