@@ -531,6 +531,7 @@ bool x65_quickload_xex(x65_t* sys, chips_range_t data) {
531531 return false;
532532 }
533533 const uint8_t * ptr = (uint8_t * )data .ptr ;
534+ const uint8_t * const end = ptr + data .size ;
534535
535536 bool reset_lo_loaded = false;
536537 bool reset_hi_loaded = false;
@@ -543,50 +544,50 @@ bool x65_quickload_xex(x65_t* sys, chips_range_t data) {
543544 return false;
544545 }
545546
546- while (ptr < ((uint8_t * )data .ptr + data .size )) {
547- size_t data_left = (uint8_t * )data .ptr + data .size - ptr ;
548- if (data_left < 4 ) {
547+ while (ptr < end ) {
548+ if ((size_t )(end - ptr ) >= 2 && ptr [0 ] == 0xff && ptr [1 ] == 0xff ) {
549+ // optional block header marker
550+ ptr += 2 ;
551+ }
552+ if ((size_t )(end - ptr ) < 4 ) {
549553 LOG_ERROR ("File truncated" );
550554 return false;
551555 }
552- if (ptr [0 ] == 0xff && ptr [1 ] == 0xff ) {
553- // skip header
554- ptr += 2 ;
555- data_left -= 2 ;
556- if (data_left < 4 ) {
557- LOG_ERROR ("File truncated" );
558- return false;
559- }
560- }
561556
562557 const uint16_t start_addr = ptr [1 ] << 8 | ptr [0 ];
563558 ptr += 2 ;
564559 const uint16_t end_addr = ptr [1 ] << 8 | ptr [0 ];
565560 ptr += 2 ;
566561
567- const bool skip_chunk = start_addr == 0xFC00 && load_bank == 0x00 ;
568- LOG_INFO ("%s block: $%04X-$%04X" , skip_chunk ? "Skipping" : "Loading" , start_addr , end_addr );
569-
570- data_left = (uint8_t * )data .ptr + data .size - ptr ;
571- if (data_left < (end_addr - start_addr + 1 ) || start_addr > end_addr ) {
562+ if (start_addr > end_addr ) {
563+ LOG_ERROR ("Invalid block header: $%04X-$%04X" , start_addr , end_addr );
564+ return false;
565+ }
566+ // compare against the delta, never the length: a $0000-$FFFF block is 0x10000 bytes long,
567+ // which does not fit a 16-bit count, but end_addr - start_addr always does
568+ if ((size_t )(end - ptr ) <= (size_t )(end_addr - start_addr )) {
572569 LOG_ERROR ("Block truncated" );
573570 return false;
574571 }
572+
575573 if (start_addr == end_addr && start_addr == 0xFFFE ) {
576574 load_bank = * ptr ++ ;
577575 LOG_INFO ("Loading to bank: $%02X" , load_bank );
576+ continue ;
578577 }
579- else if (skip_chunk ) {
580- ptr += (end_addr - start_addr + 1 );
581- }
582- else {
583- uint16_t addr = start_addr ;
584- while (addr <= end_addr && addr >= start_addr ) {
578+
579+ const bool skip_chunk = start_addr == 0xFC00 && load_bank == 0x00 ;
580+ LOG_INFO ("%s block: $%04X-$%04X" , skip_chunk ? "Skipping" : "Loading" , start_addr , end_addr );
581+
582+ uint16_t addr = start_addr ;
583+ do {
584+ const uint8_t value = * ptr ++ ;
585+ if (!skip_chunk ) {
585586 if (addr == 0xfffc ) reset_lo_loaded = true;
586587 if (addr == 0xfffd ) reset_hi_loaded = true;
587- mem_wr (sys , load_bank , addr ++ , * ptr ++ );
588+ mem_wr (sys , load_bank , addr , value );
588589 }
589- }
590+ } while ( addr ++ < end_addr );
590591 }
591592
592593 if (reset_lo_loaded && reset_hi_loaded ) {
0 commit comments