Script Reference - ISpillMyDrink/OpenSuperClone GitHub Wiki
A language support extension for Visual Studio Code can be found at OSCScript Language Support.
π‘ All commands, operators, operands, and variables in the script must be separated by a space.
# Valid syntax:
seti $a = 1
# Invalid syntax:
seti $a=1
π‘ All commands must either be completely uppercase or completely lowercase, but they cannot be mixed!
# Valid syntax:
seti $a = 1
SETI $a = 1
# Invalid syntax:
SETi $a = 1
π‘ All numbers written in the script are assumed to be in decimal format, unless specified as hex by a proceeding 0x. The exception is when setting the buffer all numbers are assumed to be in hex.
π‘ Most if not all commands will accept variables in place of numbers or strings.
π‘ Lines starting with a # will be considered comments. A comment cannot be added to the end of a line.
Default Variables
There are several variables that are automatically created and used by the program. You should not use these variables to store data as they will get overwritten by the program during operation.
-
error_levelSome commands will return data in this variable. The data is command specific. -
io_sense_keySense key - part of the key code qualifier. Only for passthrough. -
io_ascAdditional sense code - part of the key code qualifier. Only for passthrough. -
io_ascqAdditional sense code qualifier - part of the key code qualifier. Only for passthrough. -
io_statusThis is the SCSI status byte as defined by the SCSI standard. Only for passthrough. -
io_masked_statusRefer to The Linux SCSI Generic (sg) HOWTO. Only for passthrough. -
io_msg_statusRefer to The Linux SCSI Generic (sg) HOWTO. Only for passthrough. -
io_sb_len_wrNumber of bytes in the sense buffer. Only for passthrough. -
io_host_statusRefer to The Linux SCSI Generic (sg) HOWTO. Only for passthrough. -
io_driver_statusRefer to The Linux SCSI Generic (sg) HOWTO. Only for passthrough. -
io_residRefer to The Linux SCSI Generic (sg) HOWTO. Only for passthrough. -
io_durationNumber of milliseconds the SCSI command took to complete. Only for passthrough. -
io_infoRefer to The Linux SCSI Generic (sg) HOWTO. Only for passthrough. -
ata_return_errorATA error register data. -
ata_return_countATA count register data. -
ata_return_lbaATA LBA register data combined into one value. -
ata_return_deviceATA device register data. -
ata_return_statusATA status register data. -
timeValue returned fromgettimecommand. -
dateValue returned fromgettimecommand. -
data_transferredReturns the number of bytes transferred. This can be an indication if data was transferred or not, but is not a guarantee that data was actually transferred. -
command_statusReturn value from a command. Any value other than 0 indicates the command failed to complete at the driver level, and any sense key or register data may not be present or useful. 1 is for passthrough only. 0x20 and up are for direct IO only. There are major and minor values that are combined to form the full value. Values are listed in hex.Major values:
1= Passthrough error (IOCTL driver reported an error)2x= Busy or DRQ timeout while waiting to send the command3x= Soft reset timeout, command did not complete in time4x= Soft reset timeout, drive is not ready after reset5x= General timeout, command did not complete in time6x= No DRQ, DRQ was not set when it was expected7x= Wrong device detected, something switched the device8xor higher = Something bad went wrong when processingMinor values:
x1= Exceeded reset timeoutx2= Exceeded general timeout -
bus_master_statusBus master status. Only for direct mode when performing DMA commands. -
direct_modeReturns 1 if using direct and 0 if using passthrough mode. -
ahci_modeReturns 1 if using AHCI and 0 if using passthrough mode.
Commands
echo
Print to screen. Text can be output using quotes, either single or double. Quotes of the opposite type inside the original quotes will be output to the screen. Both string and number variables can be output. There must be a space between quotes and variables. Variables must be outside the quotes.
echo "This will print the variable a=" $a " and then the variable b=" $b
echo "This will print single 'quotes' within the line"
seti
Set a number variable. All variables must start with $. All number variables are integers of type long long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807).
Simple math with two operands and one operator are also possible. Available operators are:
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulo
& Bitwise AND
| Bitwise OR
^ Bitwise Exclusive OR
< Bitwise Shift Left
> Bitwise Shift Right
# Set the value of $a to 3
seti $a = 3
# Set the value of $b to the value of $a + 1 = 4
seti $b = $a + 1
# Set the value of $c to the value of $a * $b = 12
seti $c = $a * $b
There are a couple of special cases for the seti command. The first is the ability to extract a number from a string variable. The format is seti $number = $string location, where $string is the string variable containing the number to be extracted, and location is the placement of the number inside the string (zero-indexed). The location is based on spaces or tabs between the numbers. The location can be a number variable itself. If the number to be extracted starts with 0x it will be processed as hex, otherwise it will be processed as decimal unless forced using the hex command.
# Create a string variable
sets $string = "The number is 10 !"
# Set the value of $number to the 3rd word of $string
seti $number = $string 3
The second special case is extracting a number from the buffer or scratchpad (or sensebuffer, but
words are not supported for sensebuffer). You can only extract a byte, word, double word, or
quad word. The format is seti $number = buffer location type, where location is the
starting byte location in the buffer, and type is either b, w, dw, qw. If no type is specified it will
assume the type is byte. Note that the words are little endian, so a buffer value of 11 22 33 44
would be double word value 0x44332211. This can be useful for extracting information from the
identify device results.
# Exctract byte 234 from the buffer
seti $number = buffer 234
# Extract double word from the buffer starting at byte 234
seti $number = buffer 234 dw
sets
Set a string variable. All variables must start with $. The format is similar to the echo command, except instead of screen output the string ends up in the variable.
seti $a = 1
seti $b = 2
# Set the value of string to "a=1 and b=2"
sets $string = "a=" $a " and b=" $b
One special case is extracting part of the buffer into a string variable. The format is sets $string = buffer location length, where location is the byte position in the buffer and length is the number of bytes to copy.
# Extract first 40 characters from the buffer starting at byte 54
sets $string = buffer 54 40
exit
The script will terminate with an exit code. The format is exit number, where number is a value from 0-255. Note that the program already uses some of the lower numbers for program error codes, so it is advised you use numbers 16-255.
end
The script will terminate with a normal exit code of 0.
hex
This forces many commands to default to processing numbers as hex instead of decimal. It will affect the output of the echo command and also the sets command. Be very careful using the hex command, as it can cause undesired results if left turned on. It is recommended to only use it before a command such as echo to get the desired results from the command, and then use the decimal command to turn it back off.
seti $number = 0x7f
echo "The number in decimal is " $number
hex
echo "The number in hex is 0x" $number
decimal
decimal
This turns off the hex command and puts the default number processing back to decimal. It does not force numbers to be processed as decimal, if they are proceeded by 0x they are still processed as hex.
setbuffer
Manually set the buffer contents. The buffer contains the data that is either sent to or received from the drive. The format is setbuffer offset, where offset is a number (can be a variable) that is the location in the buffer to start. The lines following the setbuffer command are the actual data, to be ended by the endbuffer command. The data must be in the format of byte- space-byte-space-byte, and the data is always processed as hex. There is no set number of bytes per row, the next row will just pick up where the last row left off. A row can start with an additional offset (which will be an additional offset to the supplied buffer offset). To use the additional offset start the line with a hex number followed by a colon.
# Start setting the buffer at offset 128 (0x80)
setbuffer 0x80
0 1 2 3 4 5 6 7
8 9 a b c d e f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
# The next line will jump to offset 256 (0x100)
80: 20 21 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
endbuffer
endbuffer
Required for ending the setbuffer command.
printbuffer
Prints the buffer to the screen. The format is printbuffer offset size, where offset is the starting buffer offset, and size is the number of bytes to be printed. You cannot print past the end of the current buffer size.
# Show the first 256 bytes of the buffer
printbuffer 0 256
stringtobuffer
Puts a string into the buffer contents. The format is stringtobuffer offset size $string, where offset is the buffer offset, size is the maximum copy size, and $string is the string variable name. If size is greater than the length of the string then the whole string will be copied into the buffer, and the copy will stop at the end of the string. If size is smaller than the length of the string then it will only copy up to the size limit and the rest of the string is ignored.
sets $string = "This is a string"
# Copy the whole string (up to 64 bytes) to the buffer starting at offset 0x10
stringtobuffer 0x10 64 $string
# Copy only the first 7 characters to the beginning of the buffer
stringtobuffer 0 7 $string
clearbuffer
Clears (erases) the entire buffer contents to zero.
buffersize
Sets a new buffer size. This erases (destroys) the current buffer contents. The format is buffersize size, where size is the new size of the buffer in bytes. The default starting buffer size is 512. The maximum buffer size is 33554432 (512 x 65536).
# Increase the buffer size to 4096
buffersize 4096
writebuffer
Write the buffer or part of the buffer to a file. The format is writebuffer filename bufferoffset fileoffset size, where filename is the name of the file to write to, bufferoffset is the byte offset of the starting point in the buffer, fileoffset is the byte offset of the write point in the file, and size is the size in bytes to be written. If the file does not exist it will be created. This will overwrite the designated data in the file, but will not erase any other data in the file, meaning you can keep adding data to the file at different offsets.
# Write the first 512 bytes of the buffer to the file image.bin
writebuffer image.bin 0 0 512
# Write 512 bytes to the second sector of the file
writebuffer image.bin 0 512 512
readbuffer
Read a part of a file to the buffer. The format is readbuffer filename bufferoffset fileoffset size, where filename is the name of the file to read from, bufferoffset is the byte offset of the starting point in the buffer, fileoffset is the byte offset of the read point in the file, and size is the size in bytes to be read.
# Read the first 512 bytes of image.bin to the start of the buffer
readbuffer image.bin 0 0 512
# Read the second 512 bytes of image.bin to the buffer
readbuffer image.bin 0 512 512
direction
Set the direction of the data transfer to either none, to, from, or tofrom. This is often required for proper processing of both SCSI and ATA passthrough commands by the Linux kernel. The proper direction needed for a command can be found in the SCSI or ATA documentation respectively. Note that for ATA commands this is set by the setreadpio, setreaddma, setwritepio, and setwritedma commands respectively, so you do not need to set it directly. You do need to set it with SCSI commands.
# Set the direction to read data from the drive
direction from
scsi6cmd
Perform a SCSI 6 command. Format is scsi6cmd b0 b1 b2 b3 b4 b5, where b0-b5 are the actual bytes of the command.
scsi10cmd
Perform a SCSI 10 command. Format is scsi10cmd b0 b1 b2 b3 b4 b5 b6 b7 b8 b9, where b0-b9 are the actual bytes of the command.
# Perform SCSI capacity 10 command
direction from
scsi10cmd 0x25 0 0 0 0 0 0 0 0 0
scsi12cmd
Perform a SCSI 12 command. Format is scsi12cmd b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15, where b0-b15 are the actual bytes of the command.
# Perform SCSI capacity 16 command
direction from
scsi16cmd 0x94 0x10 0 0 0 0 0 0 0 0 0 0 0 0x12 0 0
printsensebuffer
Prints the SCSI return sense buffer to the screen. The format is printsensebuffer offset size, where offset is the sense buffer offset, and size is the number of bytes to be printed. The maximum sense buffer size is 256.
# Display the contents of the sense buffer that was returned, if any
printsensebuffer 0 $io_sb_len_wr
setreadpio
Prepare for PIO read. Required before performing this type of ATA command. If the buffer size is set to zero prior to this command, then it will setup for a non-data command. If you wish to perform a non-data command you should set the buffer size to zero before performing this command.
setwritepio
Prepare for PIO write. Required before performing this type of ATA command. If the buffer size is set to zero prior to this command, then it will setup for a non-data command. If you wish to perform a non-data command you should set the buffer size to zero before performing this command. The non-data command is the same as when performing a non-data setreadpio command.
setreaddma
Prepare for DMA read. Required before performing this type of ATA command.
setwritedma
Prepare for DMA write. Required before performing this type of ATA command.
ata28cmd
ATA 28 bit command. The format is ata28cmd b0 b1 b2 b3 b4 b5 b6, where b0-b6 are the actual bytes of the command according to ATA documentation. Note that the device bit of the device field will be set for you according to the device being accessed, in either passthrough or direct IO modes.
b0 = features
b1 = count
b2 = lba low
b3 = lba mid
b4 = lba high
b5 = device
b6 = command
# Perform ata_identify_device command
buffersize 512
setreadpio
ata28cmd 0 0 0 0 0 0xa0 0xec
# Print the result of the command
printbuffer 0 512
ata48cmd
ATA 48 bit command. The format is ata48cmd w0 w1 w2 w3 w4 b5 b6, where w0-w4 are the actual words of the command according to ATA documentation, and b5-b6 are the device and commands bytes. The words are in standard format and not flipped (not little endian), meaning that 0x0001 has a value of 1. Note that the device bit of the device field will be set for you according to the device being accessed, in either passthrough or direct IO modes, so it does not matter what value you give that bit. Also remember that the LBA order is reversed from the 28 bit command.
w0 = features
w1 = count
w2 = lba high
w3 = lba mid
w4 = lba low
b5 = device
b6 = command
# Perform ata_identify_device command
buffersize 512
setreadpio
ata48cmd 0 0 0 0 0 0xa0 0xec
# Print the result of the command
printbuffer 0 512
writelog
Write a string variable to a text file as a line. This will append the string to the end of the existing file. The format is writelog filename string, where filename is the name of the file to be written to, and string is the variable to be written. If the file does not exist it will be created.
sets $line1 = "This is the first line"
sets $line2 = "This is the second line"
writelog logfile.txt $line1
writelog logfile.txt $line2
gettime
This gets the current time and date and sets two variables. Number variable $time will have the time in microseconds since the Epoch (1970-01-01 00:00:00 +0000 (UTC)). String variable $date will contain the current date and time.
# Display the time since Epoch and the current date
gettime
echo "Time: " $time
echo "Date: " $date
# Display the time elapsed
gettime
seti $start_time = $time
# Do some program stuff here that takes time
gettime
seti $elapsed_time = $time - start_time
echo "Time elapsed: " $elapsed_time
reopendisk
Only for passthrough, has no effect with direct IO. Closes and reopens the current disk. This seems to perform a soft reset on the drive, which can be helpful in certain cases where it may not respond properly after performing certain commands.
if
Conditional if statement. The format is if value1 condition value2, where value1 and value2 are number or string variables and condition is the comparison to be made. The values can be actual numbers (or strings) or variables. If using an actual string (word), do not use quotes, and there cannot be spaces in the string. To compare strings with spaces in them you must set and compare string variables. Complex statements are not allowed (more than one condition). Math is also not allowed within the statement. Multiple if statements can be nested. Each if statement must be ended with the endif command. Everything in between the if and endif is executed if the condition is true.
Available conditions are:
< Less than
> Greater than
= Equal
!= Not Equal
<= Less than or equal
=> Greater than or equal
π‘ Note that only equal and not equal are allowed when comparing strings.
seti $high = 100
if $a > 1
echo "a is greater than 1"
if $a > 10
echo "a is greater than 10"
if $a > $high
echo "a is greater than" $high
endif
endif
endif
endif
Marks the end of an if statement.
else
Statement to be processed when the if and any elseif statement are false.
if $a > 0
echo "a is greater than 0"
else
echo "a is less than or equal to 0"
endif
elseif
Conditional statement to be processed when the if or preceding elseif statements are false. The format is the same as the if statement.
if $a > 10
echo "a is greater than 10"
elseif $a < 0
echo "a is less than 0"
elseif $a = 5
echo "a is equal to 5"
else
echo "a is between 0 and 10 but is not 5"
endif
subroutine
Marks the start of a subroutine. The format is subroutine name, where name is the name of the subroutine. The subroutine must be ended with the endsubroutine command.
subroutine show_sense_buffer
if $direct_mode = 0
echo "Sense buffer:"
printsensebuffer 0 $io_sb_len_wr
endif
endsubroutine
endsubroutine
Marks the end of a subroutine.
gosub
Calls a subroutine. The format is gosub name, where name is the name of the subroutine. When the subroutine ends by either the endsubroutine or returnsub command, program execution will resume on the line following the gosub command.
ata28cmd 0 0 0 0 0 0xa0 0xec
gosub show_ata_return
printbuffer 0 512
returnsub
Returns from the current subroutine. This is meant to be used with conditional statements, to be able to exit the subroutine before reaching the endsubroutine command.
subroutine do_something
if $error_level != 0
returnsub
endif
printbuffer 0 512
endsubroutine
while
Conditional loop. The format is the same as the if command. The while command must be ended with the done command. If the while condition is true then the code between the while and done commands is executed. When the done command is reached, the while condition is checked again to see if it is true or false. When the condition is false the code continues on after the done command, otherwise it loops back to the beginning of the while command.
# Count from 1 to 10
seti $count = 1
while $count <= 10
echo "The count is " $count
seti $count = $count + 1
done
done
Marks the end of the while command.
break
Breaks out of the current while command. The is meant to be used with conditional statements, to be able to exit the loop without having to get all the way to the done command, or to exit when the condition is still true.
# Count from 1 to 10
seti $count = 1
# This while statement is always true so would loop forever without break
while 1 = 1
echo "The count is " $count
seti $count = $count + 1
if $count > 10
break
endif
done
setscratchpad
Manually set the scratchpad contents. The format and use is the same as the setbuffer command. The scratchpad is a second buffer that you can use. The difference between the buffer and scratchpad is that the scratchpad is not used for direct disk command data transfers. It is just for storing and manipulating any data you wish. The lines following the setscratchpad command are the actual data, to be ended by the endscratchpad command.
π‘ There is one important difference from the setbuffer command. The setscratchpad command will allow for values greater than 255. When this happens, it sets a quad word in the scratchpad, instead of just one byte. This is in place to make it easier to write variable values to a file. So be careful with this!
endscratchpad
Required for ending the setscratchpad command.
printscratchpad
Print the scratchpad to the screen. The format and use is the same as the printbuffer command.
stringtoscratchpad
Puts a string into the scratchpad contents. The format and use is the same as the stringtobuffer command.
clearscratchpad
Clears (erases) the entire scratchpad contents to zeros.
scratchpadsize
Sets a new scratchpad size. The format and use is the same as the buffersize command.
writescratchpad
Write the scratchpad to a file. The format and use is the same as the writebuffer command.
readscratchpad
Read a part of a file to the scratchpad. The format and use is the same as the readbuffer command.
copyscratchpadtobuffer
Copies a part of the scatchpad to the buffer. The format is copyscratchpadtobuffer scratchoffset bufferoffset size, where scratchoffset is the starting offset of the scratchpad, bufferoffset is the starting offset of the buffer, and size is the number of bytes to copy.
# Copy 512 bytes from scratchpad to buffer
copyscratchpadtobuffer 0 0 512
copybuffertoscratchpad
Copies a part of the buffer to the scratchpad. The format is copybuffertoscratchpad bufferoffset scratchoffset size, where bufferoffset is the starting offset of the buffer, scratchoffset is the starting offset of the scratchpad, and size is the number of bytes to copy.
# Copy 512 bytes from the buffer to the scratchpad
copybuffertoscratchpad 0 0 512
variablecheck
Check if a variable has been set and what type it is. The format is variablecheck $variable, where $variable is the name of the variable to be checked. The purpose of this is to check if a variable was set properly on the command line. The result is returned in $error_level. A value of 0 means the variable was not set. A value of 1 means the variable is of number type but only set in script. A value of 2 means the variable is of string type but only set in script. A value of 17 means the variable is of number type and is set on the command line. A value of 18 means the variable is of string type and is set on the command line.
# Check variable type for $input
variablecheck $input
if $error_level = 0
echo "Variable not set"
elseif $error_level = 1
echo "Variable is number but not set on command line"
elseif $error_level = 2
echo "Variable is string but not set on command line"
elseif $error_level = 17
echo "Variable is number and was set on command line"
elseif $error_level = 18
echo "Variable is string and was set on command line"
endif
getfilesize
Get the size of a file. The format is getfilesize filename, where filename is the name (with optional path) of the file. Filename can be the raw file name or a string that contains the file name. The raw file name cannot contain spaces. If there are spaces, the file name must be in a string. The size of the file in bytes is returned in $error_level. If the file does not exist or there is some other error then $error_level will contain -1.
# Get the size of "test.txt"
getfilesize test.txt
if $error_level = -1
echo "File not found"
endif
deletefile
Delete a file. The format is deletefile filename, where filename is the name (with optional path) of the file. Filename can be the raw file name or a string that contains the file name. The raw file name cannot contain spaces. If there are spaces, the file name must be in a string.
# Delete test.txt
deletefile test.txt
callcommand
Perform a command line command. The format is callcommand command, where command is the command line command to be performed. The command can be a string variable, or a single word command. For commands that contain multiple words, you must use a string variable.
# Perform the command "ls -a"
sets $command = "ls -a"
callcommand $command
userinput
Get user input from keyboard. The format is userinput variable, where variable is the string variable where the user input is placed. This will pause the program waiting for the user to type something and then press enter.
echo "What would you like to do?"
echo "1) Perform action 1"
echo "2) Perform action 2"
echo "3) Perform action 3"
echo "Enter your choice:
userinput $choicestring
# Extract the first number from the string
seti $choice = $choicestring 0
if $choice = 1
echo "Your choice was 1"
elseif $choice = 2
echo "Your choice was 2"
elseif $choice = 3
echo "Your choice was 3"
else
echo "Invalid choice"
endif
wordflipbuffer
Flip the bytes within words from little endian to normal. The format is wordflipbuffer offset size, where offset is the offset in the buffer to start the flip and size is how many bytes to flip. If the size is an odd number the last byte will not be flipped. This command is useful for getting some proper readable information from the identify device command, such as the model and serial number.
# Perform ata_identify_device command
buffersize 512
setreadpio
ata48cmd 0 0 0 0 0 0xa0 0xec
# Flip the buffer
wordflipbuffer 0 512
# Print model and serial of the drive
sets $model = buffer 54 40
echo "Model= " $model
sets $serial = buffer 20 20
echo "Serial= " $serial
wordflipscratchpad
Flip the bytes within words from little endian to normal. The format and use is the same as the wordflipbuffer command.
getstatus
This will update the status and error registers ($ata_return_error, $ata_return_status, and $ata_alternate_status). This only works for direct IO. For passthrough it attempts to send the proper protocol, but it would appear that Linux does not support that protocol and returns sense data of "invalid field in CDB".
softreset
This performs a soft reset of the device. Note that this will reset both devices on the controller. This only works for direct IO. For passthrough it attempts to send the proper protocol, but it would appear that Linux does not support that protocol and returns sense data of "invalid field in CDB". To perform a soft reset using passthrough, use the reopendisk command.
usleep
Sleep for x amount of microseconds. The format is usleep microseconds. This is a way to make the program sleep without using CPU, perhaps waiting for a drive to become ready.
echo "Sleeping for 5 seconds"
usleep 5000000
echo "Done"
softtimeout
Only for direct IO, has no effect with passthrough. When performing an ATA command, the time to wait before sending a soft reset. The format is softtimeout microseconds. The default is 15000000 (15s). This is used to automatically perform a soft reset if a command times out, so that it does not have to be done manually. If this happens, the register status will reflect the status after the soft reset. The soft reset waits for the drive to be ready up to the value of resettimeout after performing the reset before returning. If you donβt want to perform a soft reset when it times out, set the softtimeout value greater than the value of generaltimeout.
resettimeout
Only for direct IO, has no effect with passthrough. When performing an ATA command, the time to wait for the drive to be ready after a soft reset before returning. The format is resettimeout microseconds. The default is 15000000 (15s).
busytimeout
Only for direct IO, has no effect with passthrough. When performing an ATA command, the time to wait before giving up if the device is busy prior to issuing the command. The format is busytimeout microseconds. The default is 15000000 (15s). If you donβt want the device to time out for being busy, set this value greater than the value of generaltimeout.
generaltimeout
This timer is mostly for direct IO, but can also influence passthrough in some circumstances. When performing a command, the time to wait before giving up if the command has not finished. The format is generaltimeout microseconds. The default is 30000000 (30s).
loadscript
Loads a different script into memory. The format is loadscript script, where script is the script file to be loaded. This is mostly designed for a menu driven system. All current variables will be passed on to the new script. The new script will start from the beginning.
previousscript
Loads the previous script into memory, if there was one. This is designed for a menu driven system. When returning to the previous script, the previous script will start from the beginning. All current varaibles will be passed on to the previous script.
include
This will append another script file to the end (bottom) the current one in memory. The format is include script, where script is the script file to be loaded. This is useful for including common subroutines without having to copy them into every script.
upline
Used for display purposes. Move the cursor up one line. This is useful for repeating data on the screen without scrolling.