Detect ANSI in QB45 in DOSBOX - ansi

I have been using DOSbox and ANSI with some success, but I want to detect ANSI installed.
Ralf Brown description for detecting ANSI is:
--------V-2F1A00-----------------------------
INT 2F - DOS 4.0+ ANSI.SYS - INSTALLATION CHECK
AX = 1A00h
Return: AL = FFh if installed
Notes: AVATAR.SYS also responds to this call
documented for DOS 5+, but undocumented for DOS 4.x
And my code to detect ANSI is:
' detect ansi
InregsX.AX = &H1A00
CALL InterruptX(&H2F, InregsX, OutregsX)
PRINT "AX="; HEX$(OutregsX.AX)
IF (OutregsX.AX AND &HFF) = &HFF THEN
Ansi.Installed = -1
ELSE
Ansi.Installed = 0
END IF
IF Ansi.Installed THEN
PRINT "Ansi installed."
ELSE
PRINT "Ansi not installed."
END IF
which always displays "Ansi not installed."
is there some other way to detect ANSI??

I think you might resolve making the try to use ANSI codes.
The code below implements the function ansiOn% that returns 1 if an ansi string is written on the screen (used as console: see the code) as expected, otherwise returns 0.
The method that the function implements is to clear the screen and write a string that contains: the first char different from A$, the backward ANSI sequence for 1 char - CSI 1 D - and the content of A$. After the string is written, if the upper left char on the screen is A$ then ANSI is enabled.
DECLARE FUNCTION ansiOn% ()
ansi% = ansiOn%
CLS
PRINT "ANSI is";
IF ansi% = 0 THEN
PRINT "n't";
END IF
PRINT " enabled."
FUNCTION ansiOn%
CLS : A$ = "C"
OPEN "CON" FOR OUTPUT AS #1
PRINT #1, CHR$(ASC(A$) - 1); CHR$(27); "[1D"; A$;
CLOSE #1
IF CHR$(SCREEN(1, 1)) = A$ THEN
ansiOn% = 1
ELSE
ansiOn% = 0
END IF
END FUNCTION
I tried this code using QB45 in a DOS 6.22 VM and it works.

I wrote this code to detect ANSI:
Cls
Const A$ = "alpha"
Const B$ = "beta"
Open "CONS:" For Output As #1
Print #1, A$
Z$ = Chr$(27) + "[2J" ' ansi cls
Print #1, Z$; B$;
Close #1
For T = 1 To Len(B$)
T$ = T$ + Chr$(Screen(1, T))
Next
If T$ = B$ Then Print "ANSI detected."

Related

Simultaneously read and write to buffer

I am in the process of learning Julia and I'd like to do some buffer manipulation.
What I want to achieve is the following:
I've got a buffer that I can write to and read from at the same time, meaning that the speed with which I add a value to the Fifo buffer approximately equals the speed with which I read from the buffer. Reading and writing will happen in separate threads so it can occur simultaneously.
Additionally, I want to be able to control the values that I write into the buffer based on user input. For now, this is just a simple console prompt asking for a number, which I then want to write into the stream continously. The prompt refreshes and asks for a new number to write into the stream, but the prompt is non-blocking, meaning that in the background, the old number is written to the buffer until I enter a new number, which is then written to the buffer continuously.
This is my preliminary code for simulatenous reading and writing of the stream:
using Causal
CreateBuffer(size...) = Buffer{Fifo}(Float32, size...)
function writetobuffer(buf::Buffer, n::Float32)
while !isfull(buf)
write!(buf, fill(n, 2, 1))
end
end
function readfrombuffer(buf::Buffer)
while true
while !isempty(buf)
#show read(buf)
end
end
end
n_channels = 2
sampling_rate = 8192
duration = 2
n_frames = sampling_rate * duration
sbuffer = CreateBuffer(n_channels, n_frames)
print("Please enter a number: ")
n = parse(Float32, readline())
s1 = Threads.#spawn writetobuffer(sbuffer, n)
s2 = Threads.#spawn readfrombuffer(sbuffer)
s1 = fetch(s1)
s2 = fetch(s2)
I am not sure how to integrate the user input in a way that it keeps writing and reading the latest number the user put in. I looked at the documentation for channels, but didn't manage to get it working in a way that was non-blocking for the stream writing. I don't know that the correct approach is (channels, events, julia's multithreading) to enable this functionality.
How would I go on about to include this?
I managed to get it working, but I think it could be improved:
using Causal
CreateBuffer(size...) = Buffer{Fifo}(Float32, size...)
function writeToBuffer(buf::Buffer, n::Float32)
write!(buf, fill(n, 2, 1))
end
function readFromBuffer()
global soundbuffer
println("Starting")
sleep(0.5)
while true
while !isempty(soundbuffer)
read(soundbuffer)
end
end
println("Exiting...")
end
function askForInput()::Float32
print("Please enter a number: ")
a = parse(Float32, readline())
return(a)
end
function inputAndWrite()
global soundbuffer
old_num::Float32 = 440
new_num::Float32 = 440
while true
#async new_num = askForInput()
while (new_num == old_num)
writeToBuffer(soundbuffer, new_num)
end
old_num = new_num
println("Next iteration with number " * string(new_num))
end
end
n_channels = 2
sampling_rate = 8192
duration = 2
n_frames = sampling_rate * duration
soundbuffer = CreateBuffer(n_channels, n_frames)
s1 = Threads.#spawn inputAndWrite()
s2 = Threads.#spawn readFromBuffer()
s1 = fetch(s1)
s2 = fetch(s2)

How do you access name of a ProtoField after declaration?

How can I access the name property of a ProtoField after I declare it?
For example, something along the lines of:
myproto = Proto("myproto", "My Proto")
myproto.fields.foo = ProtoField.int8("myproto.foo", "Foo", base.DEC)
print(myproto.fields.foo.name)
Where I get the output:
Foo
An alternate method that's a bit more terse:
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* myproto")
print(string.sub(fieldString, i + 2, j - (1 + string.len("myproto")))
EDIT: Or an even simpler solution that works for any protocol:
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* ")
print(string.sub(fieldString, i + 2, j - 1))
Of course the 2nd method only works as long as there are no spaces in the field name. Since that's not necessarily always going to be the case, the 1st method is more robust. Here is the 1st method wrapped up in a function that ought to be usable by any dissector:
-- The field is the field whose name you want to print.
-- The proto is the name of the relevant protocol
function printFieldName(field, protoStr)
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* " .. protoStr)
print(string.sub(fieldString, i + 2, j - (1 + string.len(protoStr)))
end
... and here it is in use:
printFieldName(myproto.fields.foo, "myproto")
printFieldName(someproto.fields.bar, "someproto")
Ok, this is janky, and certainly not the 'right' way to do it, but it seems to work.
I discovered this after looking at the output of
print(tostring(myproto.fields.foo))
This seems to spit out the value of each of the members of ProtoField, but I couldn't figure out the correct way to access them. So, instead, I decided to parse the string. This function will return 'Foo', but could be adapted to return the other fields as well.
function getname(field)
--First, convert the field into a string
--this is going to result in a long string with
--a bunch of info we dont need
local fieldString= tostring(field)
-- fieldString looks like:
-- ProtoField(188403): Foo myproto.foo base.DEC 0000000000000000 00000000 (null)
--Split the string on '.' characters
a,b=fieldString:match"([^.]*).(.*)"
--Split the first half of the previous result (a) on ':' characters
a,b=a:match"([^.]*):(.*)"
--At this point, b will equal " Foo myproto"
--and we want to strip out that abreviation "abvr" part
--Count the number of times spaces occur in the string
local spaceCount = select(2, string.gsub(b, " ", ""))
--Declare a counter
local counter = 0
--Declare the name we are going to return
local constructedName = ''
--Step though each word in (b) separated by spaces
for word in b:gmatch("%w+") do
--If we hav reached the last space, go ahead and return
if counter == spaceCount-1 then
return constructedName
end
--Add the current word to our name
constructedName = constructedName .. word .. " "
--Increment counter
counter = counter+1
end
end

compare foreign language strings in scilab

I am trying to compare the input string with the strings present in the doc. I am using strcmp for the purpose. These are non-English strings. When the input string is English language, the output is correct. But for any Kannada (non-English language) word the output is the same. I am trying to write a program to check if the word is present in the database. Please guide me in what could be the problem.
The calling function is as below:
str_kan = handles.InputBox.String;
res = strcmp('str_kan','s1.text')
if res == 1 then handles.InputBox.String = string( ' present')
abort
else
handles.InputBox.String = string( 'not present')
abort
end
The whole program is as below:
global s1
f=figure('figure_position',[400,50],'figure_size',[640,480],'auto_resize','on','background',[33],'figure_name','Graphic window number %d','dockable','off','infobar_visible','off','toolbar_visible','off','menubar_visible','off','default_axes','on','visible','off');
handles.dummy = 0;
handles.InputBox=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tunga','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.0929487,0.6568182,0.4647436,0.1795455],'Relief','default','SliderStep',[0.01,0.1],'String','Enter a Kannada Word','Style','edit','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','InputBox','Callback','')
handles.CheckDB=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.1025641,0.4636364,0.4567308,0.1204545],'Relief','default','SliderStep',[0.01,0.1],'String','Check','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','CheckDB','Callback','CheckDB_callback(handles)')
f.visible = "on";
function CheckDB_callback(handles)
str_kan = handles.InputBox.String;
res = strcmp('str_kan','s1.text')
if res == 1 then handles.InputBox.String = string( ' present')
abort
else
handles.InputBox.String = string( 'not present')
abort
end
endfunction
Here is an example showing that, in Scilab, strcmp() does support UTF-8 extended characters:
--> strcmp(["aα" "aα" "aβ"], ["aα" "aβ" "aα"])
ans =
0. -1. 1.
The problem in the original posted code is the confusion between literal values as "Hello" and variables names as Hello="my text", as already noted by PTRK.

BBC Basic Cipher Help Needed

I am doing a school project in which I need to make a "sort of" vigenere cipher in which the user inputs both the keyword and plaintext. However the vigenere assumes a=0 whereas I am to assume a=1 and I have changed this accordingly for my program. However I am required to make my cipher work for both lower and upper case, How could I make this also work for lower case, it may be a stupid question but I'm very confused at this point and I'm new to programming, thanks.
REM Variables
plaintext$=""
PRINT "Enter the text you would like to encrypt"
INPUT plaintext$
keyword$=""
PRINT "Enter the keyword you wish to use"
INPUT keyword$
encrypted$= FNencrypt(plaintext$, keyword$)
REM PRINTING OUTPUTS
PRINT "Key = " keyword$
PRINT "Plaintext = " plaintext$
PRINT "Encrypted = " encrypted$
PRINT "Decrypted = " FNdecrypt(encrypted$, keyword$)
END
DEF FNencrypt(plain$, keyword$)
LOCAL i%, offset%, Ascii%, output$
FOR i% = 1 TO LEN(plain$)
Ascii% = ASCMID$(plain$, i%)
IF Ascii% >= 65 IF Ascii% <= 90 THEN
output$ += CHR$((66 + (Ascii% + ASCMID$(keyword$, offset%+1)) MOD 26))
ENDIF
offset% = (offset% + 1) MOD LEN(keyword$)
NEXT
= output$
DEF FNdecrypt(encrypted$, keyword$)
LOCAL i%, offset%, n%, o$
FOR i% = 1 TO LEN(encrypted$)
n% = ASCMID$(encrypted$, i%)
o$ += CHR$(64 + (n% + 26 - ASCMID$(keyword$, offset%+1)) MOD 26)
offset% = (offset% + 1) MOD LEN(keyword$)
NEXT
= output$
You can always convert from upper to lowercase and the Stringlib library contains a function for doing this.
First import stringlib at the top of your program:
import #lib$+"stringlib"
then convert strings using:
plaintext$ = fn_lower(plaintext$)

Porting to Python3: PyPDF2 mergePage() gives TypeError

I'm using Python 3.4.2 and PyPDF2 1.24 (also using reportlab 3.1.44 in case that helps) on windows 7.
I recently upgraded from Python 2.7 to 3.4, and am in the process of porting my code. This code is used to create a blank pdf page with links embedded in it (using reportlab) and merge it (using PyPDF2) with an existing pdf page. I had an issue with reportlab in that saving the canvas used StringIO which needed to be changed to BytesIO, but after doing that I ran into this error:
Traceback (most recent call last):
File "C:\cms_software\pdf_replica\builder.py", line 401, in merge_pdf_files
input_page.mergePage(link_page)
File "C:\Python34\lib\site-packages\PyPDF2\pdf.py", line 2013, in mergePage
self.mergePage(page2)
File "C:\Python34\lib\site-packages\PyPDF2\pdf.py", line 2059, in mergePage
page2Content = PageObject._pushPopGS(page2Content, self.pdf)
File "C:\Python34\lib\site-packages\PyPDF2\pdf.py", line 1973, in _pushPopGS
stream = ContentStream(contents, pdf)
File "C:\Python34\lib\site-packages\PyPDF2\pdf.py", line 2446, in __init
stream = BytesIO(b_(stream.getData()))
File "C:\Python34\lib\site-packages\PyPDF2\generic.py", line 826, in getData
decoded._data = filters.decodeStreamData(self)
File "C:\Python34\lib\site-packages\PyPDF2\filters.py", line 326, in decodeStreamData
data = ASCII85Decode.decode(data)
File "C:\Python34\lib\site-packages\PyPDF2\filters.py", line 264, in decode
data = [y for y in data if not (y in ' \n\r\t')]
File "C:\Python34\lib\site-packages\PyPDF2\filters.py", line 264, in
data = [y for y in data if not (y in ' \n\r\t')]
TypeError: 'in <string>' requires string as left operand, not int
Here is the line and the line above where the traceback mentions:
link_page = self.make_pdf_link_page(pdf, size, margin, scale_factor, debug_article_links)
if link_page != None:
input_page.mergePage(link_page)
Here are the relevant parts of that make_pdf_link_page function:
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=(size['width'], size['height']))
....# left out code here is just reportlab specifics for size and url stuff
can.linkURL(url, r1, thickness=1, color=colors.green)
can.rect(x1, y1, width, height, stroke=1, fill=0)
# create a new PDF with Reportlab that has the url link embedded
can.save()
packet.seek(0)
try:
new_pdf = PdfFileReader(packet)
except Exception as e:
logger.exception('e')
return None
return new_pdf.getPage(0)
I'm assuming it's a problem with using BytesIO, but I can't create the page with reportlab with StringIO. This is a critical feature that used to work perfectly with Python 2.7, so I'd appreciate any kind of feedback on this. Thanks!
UPDATE:
I've also tried changing from using BytesIO to just writing to a temp file, then merging. Unfortunately I got the same error.
Here is tempfile version:
import tempfile
temp_dir = tempfile.gettempdir()
temp_path = os.path.join(temp_dir, "tmp.pdf")
can = canvas.Canvas(temp_path, pagesize=(size['width'], size['height']))
....
can.showPage()
can.save()
try:
new_pdf = PdfFileReader(temp_path)
except Exception as e:
logger.exception('e')
return None
return new_pdf.getPage(0)
UPDATE:
I found an interesting bit of information on this. It seems if I comment out the can.rect and can.linkURL calls it will merge. So drawing anything on a page, then trying to merge it with my existing pdf is causing the error.
After digging in to PyPDF2 library code, I was able to find my own answer. For python 3 users, old libraries can be tricky. Even if they say they support python 3, they don't necessarily test everything. In this case, the problem was with the class ASCII85Decode in filters.py in PyPDF2. For python 3, this class needs to return bytes. I borrowed the code for this same type of function from pdfminer3k, which is a port for python 3 of pdfminer. If you exchange the ASCII85Decode() class for this code, it will work:
import struct
class ASCII85Decode(object):
def decode(data, decodeParms=None):
if isinstance(data, str):
data = data.encode('ascii')
n = b = 0
out = bytearray()
for c in data:
if ord('!') <= c and c <= ord('u'):
n += 1
b = b*85+(c-33)
if n == 5:
out += struct.pack(b'>L',b)
n = b = 0
elif c == ord('z'):
assert n == 0
out += b'\0\0\0\0'
elif c == ord('~'):
if n:
for _ in range(5-n):
b = b*85+84
out += struct.pack(b'>L',b)[:n-1]
break
return bytes(out)

Resources