How to READ or WRITE one byte (8 bits) at once with Arduino UNO or Mega2560

With Google -> Search the datasheet: Atmel atmega640/v-1280/v-1281/v-2560/v-2561/v
On page 96, chapter 13.4.2, you'll find all the register addresses to achieve the ports A, B, C, D, E, F, G, H, J, K, L
Attention: The Board Mega 2560 is full wired (8bits) only for Port A,B,C, L
Port F, K are shared with Analog Adc0…Adc15
Port D, E, G, H are partially or not wired on the Board Atmega 2560

PORTA – Port A Data Register  write one byte
DDRA – Port A Data Direction Register -> setect Port direction ‘0’ Input, ‘1’ output
PINA – Port A Input Pins Address  read one byte

Since the standard Arduino instruction set does not have a Port write or Port read instruction, you must use pointers that target registers to read or write to a Port.
These 3 registers aim Port A for board Arduino 2560 or .UNO
Port A I/P Register address 0x22 read one byte full on port A
Port A Direction Register address 0X21 set Direction Input / Output
Port A O/P Register address 0x20 write one byte full on port A

Sketch example with Read Port A and Write Port B
To test -> prepare one wire connected to GND
Touch the Pin 22 … 29 with the wire  see the Monitoring Display to check if PortA display ‘0’ ‘1’

#include <Arduino.h>

// define all pointer Port A, Port B
volatile unsigned char* INportA = (unsigned char*) 0x20; // define pointer name INportA on register address 0x20
volatile unsigned char* portDDRA = (unsigned char*) 0x21; // define pointer name portDDRA on register address 0x21
volatile unsigned char* OUTportA = (unsigned char*) 0x22; // define pointer name OUTportA on register address 0x22

volatile unsigned char* INportB = (unsigned char*) 0x23; // define pointer name INportA on register address 0x23
volatile unsigned char* portDDRB = (unsigned char*) 0x24; // define pointer name portDDRA on register address 0x24
volatile unsigned char* OUTportB = (unsigned char*) 0x25; // define pointer name OUTportA on register address 0x25

byte a; // variable in RAM

void setup()
{
Serial.begin(9600); // prepare serial monitor 9600 bauds

pinMode (22, INPUT_PULLUP); // Selectt all 8 bits Port A with PullUp (Pin 22....29)
pinMode (23, INPUT_PULLUP);
pinMode (24, INPUT_PULLUP);
pinMode (25, INPUT_PULLUP);
pinMode (26, INPUT_PULLUP);
pinMode (27, INPUT_PULLUP);
pinMode (28, INPUT_PULLUP);
pinMode (29, INPUT_PULLUP);

*portDDRA = 0x00; // Set direction PortA INPUT '0'
*portDDRB = 0xFF; // Set direction PortB OUTPUT '1'
}

void loop()
{
// prepare one wire connected to GND
// touch the Pin 22 … 29 with the wire  see the Monitoring Display to check if PortA display ‘0’ ‘1’

a = *INportA; // READ byte PORTA digital pin A0(pin22)... A7(pin29) Arduino Mega 2560
Serial.println("Hello_IN Port A: "); // sort sur serial monitoring console
Serial.println(a,BIN); // Print out on serial monitoring console Binar format
delay (1000);
*OUTportB = a; // WRITE byte value..
delay (1000);
}

This sketch has been tested with success

Why not

void setup() {
  DDRA = 0x00; // Inputs
  DDRB = 0xff;  // Outputs
  PORTA = 0xff; // Enable pullups
  Serial.begin(115200);
}

void loop() {
  // prepare one wire connected to GND
  // touch the Pin 22 … 29 with the wire  see the Monitoring Display to check if PortA display ‘0’ ‘1’

  byte a = PINA; // READ byte PORTA digital pin A0(pin22)... A7(pin29) Arduino Mega 2560
  Serial.println("Hello_IN Port A: "); // sort sur serial monitoring console
  Serial.println(a, BIN); // Print out on serial monitoring console Binar format
  delay (1000);
  PORTB = a; // WRITE byte value..
  delay (1000);
}

All the registers and bit values listed in the datasheet (PORTA, PINA, DDRA, ... ) are defined in the avr-libc includes. For example:

The DDRx defines the I/O direction for each port pin. Writing input pins has no outside effect, except possibly en-/disabling the internal pullup resistor.

The external memory interface of the 2560 manages pin directions for the data port, at the cost of an extra address output cycle.

??

Writing the input pin register (e.g., PINA = 0xA5 ) toggles the bits in PORTA, which in output mode, (DDRA=0xff), toggles the outputs, and in input mode, (DDRA=0x00), toggles the pullup resistors.

void setup() {
  Serial.begin(115200);
  DDRA=0x00; // all inputs
  PORTA=0xff; // enable pullups
  Serial.print("PORTA:");Serial.println(PORTA,BIN);
  PINA = 0x55; // Toggle every other pin
  Serial.print("PINA:");Serial.println(PINA,BIN);
  Serial.print("PORTA:");Serial.println(PORTA,BIN);
  
  DDRA=0xff; // switch modes to outputs
  Serial.print("PORTA:");Serial.println(PORTA,BIN);
  Serial.print("PINA:");Serial.println(PINA,BIN);
  DDRA=0x00; // switch modes to inputs
  Serial.print("PORTA:");Serial.println(PORTA,BIN);
  Serial.print("PINA:");Serial.println(PINA,BIN);
}

void loop() {
}

with some floating pin inputs:

PORTA:11111111
PINA:10101010
PORTA:10101010
PORTA:10101010
PINA:10101010
PORTA:10101010
PINA:11101110

More specifically, writing a 1 to a PINx register bit toggles the matching bit on PORTx. It's a speed feature of AVR chips.