Re: [Ql-Users] SAV files

2010-01-04 Thread gdgqler

On 3 Jan 2010, at 19:33, Norman Dunbar wrote:

 
 On 03/01/10 19:20, Dilwyn Jones wrote:
 Does anyone have information on the format of _sav basic files (as used
 by Liberation Software's QSAVE utility and the equivalent command in
 SBASIC)?
 I'm thinking that I might have some information somewhere. However, I
 once wrote a SB program to decode a _SAV file and 'print' the output in
 SuperBasic - I was attempting to write a librarian program that could
 extract procs and FNs from a _SAV (plus dependencies) and write them out
 as normal SuperBasic code. (ASCII in other words!)
 
 If I can find the code I'll send it over.
 
 Failing that, Jan Jones or Tony Tebby's docs have all the details - a
 _SAV is simply a tokenised SUperBasic program in the format it is stored
 internally in the 'program file' area.
 
 George will probably know all the details from his work on the Turbo stuff.
 


I don't know the exact form of _SAV files but they are pretty certainly copies 
of the tokenised program. The tokens used by SMSQ/E incorporate Minerva 
additions to the original QL SuperBASIC as described by Jan Jones, and these 
will be in SMSQ/E _SAV files.

George
___
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm


Re: [Ql-Users] SAV files

2010-01-03 Thread Norman Dunbar
Evening Dilwyn,

On 03/01/10 19:20, Dilwyn Jones wrote:
 Does anyone have information on the format of _sav basic files (as used
 by Liberation Software's QSAVE utility and the equivalent command in
 SBASIC)?
I'm thinking that I might have some information somewhere. However, I
once wrote a SB program to decode a _SAV file and 'print' the output in
SuperBasic - I was attempting to write a librarian program that could
extract procs and FNs from a _SAV (plus dependencies) and write them out
as normal SuperBasic code. (ASCII in other words!)

If I can find the code I'll send it over.

Failing that, Jan Jones or Tony Tebby's docs have all the details - a
_SAV is simply a tokenised SUperBasic program in the format it is stored
internally in the 'program file' area.

George will probably know all the details from his work on the Turbo stuff.


Cheers,
Norman.
___
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm


Re: [Ql-Users] SAV files

2010-01-03 Thread Dilwyn Jones

Thanks, Norman.

Dilwyn Jones

- Original Message - 
From: Norman Dunbar nor...@dunbar-it.co.uk

To: ql-us...@q-v-d.com
Sent: Sunday, January 03, 2010 7:33 PM
Subject: Re: [Ql-Users] SAV files




Evening Dilwyn,

On 03/01/10 19:20, Dilwyn Jones wrote:
Does anyone have information on the format of _sav basic files (as 
used
by Liberation Software's QSAVE utility and the equivalent command 
in

SBASIC)?
I'm thinking that I might have some information somewhere. However, 
I
once wrote a SB program to decode a _SAV file and 'print' the output 
in
SuperBasic - I was attempting to write a librarian program that 
could
extract procs and FNs from a _SAV (plus dependencies) and write them 
out

as normal SuperBasic code. (ASCII in other words!)

If I can find the code I'll send it over.

Failing that, Jan Jones or Tony Tebby's docs have all the details - 
a
_SAV is simply a tokenised SUperBasic program in the format it is 
stored

internally in the 'program file' area.

George will probably know all the details from his work on the Turbo 
stuff.



Cheers,
Norman.
___
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm








No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 9.0.725 / Virus Database: 270.14.124/2598 - Release Date: 
01/03/10 09:41:00




___
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm


Re: [Ql-Users] SAV files

2010-01-03 Thread Norman Dunbar
Dilwyn,

attached is a file that decodes a SAV file - as promised. Hope you can
read my code after all these years!

Cheers,
Norman.
1000 REMark _SAV file decoder
1005 :
1010 CLS
1015 PRINT 'SAV File Decoder'\\
1020 INPUT 'Which _sav file ? ';sav$
1025 IF sav$ = '' THEN STOP: END IF 
1030 :
1035 initialise
1040 decode_header
1045 IF NOT quit
1050decode_name_table
1055decode_program
1060 END IF 
1065 RELEASE_HEAP float_buffer
1070 CLOSE #3
1075 :
1080 DEFine PROCedure decode_header
1085   LOCal head$(4), name_table_length
1090   quit = 0
1095   OPEN_IN #3,sav$
1100   head$ = FETCH_BYTES(#3, 4)
1105   IF (head$  'Q1'  CHR$(0)  CHR$(0)) AND (head$  'Q1'  CHR$(2)  
CHR$(192))
1110   PRINT head$, head$(1);head$(2)!!CODE(head$(3))!CODE(head$(4))\
1115  PRINT sav$  ' is not a SAV file, or has a new flag.'
1120  CLOSE #3
1125  quit = 1
1130  RETurn 
1135   END IF 
1140   name_table_entries = GET_WORD(#3)
1145   name_table_length = GET_WORD(#3)
1150   program_lines = GET_WORD(#3)
1155   max_name_size = name_table_length - (4 * name_table_entries) / 
name_table_entries
1160   :
1165   PRINT sav$
1170   PRINT 'Number of name table entries : '; name_table_entries
1175   PRINT 'Name table length: '; name_table_length
1180   PRINT 'Number of program lines  : '; program_lines
1185   PRINT
1190   :
1195   DIM name_table$(name_table_entries -1, max_name_size)
1200   float_buffer = RESERVE_HEAP(6)
1205   quit = (float_buffer  1)
1210 END DEFine decode_header
1215 :
1220 DEFine PROCedure decode_name_table
1225   LOCal x, name_type, line_no, name_length, name$, lose_it$(1)
1230   LOCal num_procs, num_fns
1235   num_procs = 0
1240   num_fns = 0
1245   FOR x = 0 TO name_table_entries -1
1250 name_type = GET_WORD(#3)
1255 line_no = GET_WORD(#3)
1260 name_length = GET_WORD(#3)
1265 name$ = FETCH_BYTES(#3, name_length)
1270 IF name_length  1
1275lose_it$ = INKEY$(#3)
1280 END IF 
1285 IF name_type = 5122 THEN num_procs = num_procs + 1
1290 IF name_type = 5377 AND name_type = 5379
1295num_fns = num_fns + 1
1300 END IF 
1305 PRINT x;'  Name type = '; HEX$(name_type, 16)  '  ';
1310 PRINT 'Line number = '; line_no  '  ';
1315 PRINT 'Name length = '; name_length; '  ';
1320 PRINT 'Name = '  name$  ''
1325 name_table$(x) = name$
1330   END FOR x
1335   PRINT 'There are '  num_procs  ' PROCs'
1340   PRINT 'There are '  num_fns  ' FNs'
1345 END DEFine decode_name_table
1350 :
1355 :
1360 DEFine PROCedure decode_program
1365   LOCal x, type_byte, program_line
1370   :
1375   REMark WORD = size change
1380   REMark LONG = $8D00.line number
1385   REMark rest of line
1390   :
1395   REPeat program_line
1400 IF EOF(#3) THEN EXIT program_line: END IF 
1405 line_size = line_size + GET_WORD(#3)
1410 IF line_size  65536 THEN line_size = line_size - 65536: END IF 
1415 IF GET_WORD(#3)  HEX('8d00')
1420PRINT 'Program out of step.'
1425CLOSE #3
1430STOP
1435 END IF 
1440 PRINT GET_WORD(#3); ' ';
1445 line_done = 0
1450 REPeat line_contents
1455   type_byte = CODE(INKEY$(#3))
1460   SELect ON type_byte
1465 = HEX('80'): multi_spaces
1470 = HEX('81'): keywords
1475 = HEX('84'): symbols
1480 = HEX('85'): operators
1485 = HEX('86'): monadics
1490 = HEX('88'): names
1495 = HEX('8B'): strings
1500 = HEX('8C'): text
1505 = HEX('8E'): separators
1510 = REMAINDER : floating_points
1515   END SELect 
1520   IF line_done THEN EXIT line_contents: END IF 
1525 END REPeat line_contents
1530   END REPeat program_line
1535 END DEFine decode_program
1540 :
1545 :
1550 DEFine PROCedure multi_spaces
1555   :
1560   REMark $80.nn = print nn spaces
1565   :
1570   PRINT FILL$(' ', GET_BYTE(#3));
1575 END DEFine multi_spaces
1580 :
1585 :
1590 DEFine PROCedure keywords
1595   :
1600   REMark $81.nn = keyword$(nn)
1605   :
1610   PRINT keyword$(GET_BYTE(#3));' ';
1615 END DEFine keywords
1620 :
1625 :
1630 DEFine PROCedure symbols
1635   LOCal sym
1640   :
1645   REMark $84.nn = symbol$(nn)
1650   :
1655   sym = GET_BYTE(#3)
1660   PRINT symbol$(sym);
1665   line_done = (sym = 10)
1670 END DEFine symbols
1675 :
1680 :
1685 DEFine PROCedure operators
1690   :
1695   REMark $85.nn = operator$(nn)
1700   :
1705   PRINT operator$(GET_BYTE(#3));
1710 END DEFine operators
1715 :
1720 :
1725 DEFine PROCedure monadics
1730   :
1735   REMark $86.nn = monadic$(nn)
1740   :
1745   PRINT monadic$(GET_BYTE(#3));
1750 END DEFine monadic
1755 :
1760 :
1765 DEFine PROCedure names
1770   LOCal ignore
1775   :
1780   REMark $8800. = name_table$()
1785   :
1790   ignore = GET_BYTE(#3)
1795   ignore = GET_WORD(#3)
1800   IF ignore  32768 THEN ignore = ignore - 32768: END IF 
1805   PRINT name_table$(ignore);
1810 END DEFine names
1815 :
1820 :
1825 DEFine PROCedure strings
1830   LOCal delim$(1), size
1835   :
1840   

Re: [Ql-Users] SAV files

2010-01-03 Thread Norman Dunbar
On 03/01/10 19:52, Norman Dunbar wrote:
 Dilwyn,
 
 attached is a file that decodes a SAV file - as promised. Hope you can
 read my code after all these years!
 
 Cheers,
 Norman.
 

Sorry folks, didn't mean to send that to everyone. However, now you have
it, if you want to use it, you'll need DJToolkit to be able to run it.

Cheers,
Norman.
___
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm


Re: [Ql-Users] SAV files

2010-01-03 Thread Ralf Reköndt

Evening,

as TT has rerwritten QLIBs QLOAD/QSAVE plus QMERGE, it should be seen in the 
source codes of SMSQ/E.



Failing that, Jan Jones or Tony Tebby's docs have all the details - a
_SAV is simply a tokenised SUperBasic program in the format it is stored
internally in the 'program file' area.


No (AFAIK). This (strict) way was done via TT's Software Production Kit 
(FBOOT/FSAVE/FLOAD, released via Sinclair, the early used copy protection).


QLOAD seems to use another way as it also works, if needed resident 
extensions are absent. TTs way crashes.


Cheers...Ralf 


___
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm


Re: [Ql-Users] SAV files

2010-01-03 Thread P Witte

Dilwyn Jones writes:


Does anyone have information on the format of _sav basic files (as used 
by Liberation Software's QSAVE utility and the equivalent command in 
SBASIC)?


Heres (an incomplete) decode of the file structure. Below that an 
example file. HTH


Per

QSAVE file structure
March 22nd 2001

*
Head
dc.w 'Q1'00   flag

dc.w $0380   02   ? version ? This with SMSQ/E2.xx
  $0380 = Hex  bin  ?
 $02C0, $ from Norman - dont know 
what it 	  implies, perhaps vanilla?


dc.w count   04   number of names

dc.w source-names06   size of name list

dc.w lines   08   number of lines in program

*
names0A   start names list


For each name:

dc.w type00   bits 0..11 as for name-table entry
  bits 12..15 ?
  bit #12: var is paramter
  bit #13: var is ?
dc.w valp02   value pointer? Always 0?

dc.w nlen04   name length

dc.b namechars   06.. name bytes, padded to even number


*
source

actual tokenised SB program file

---

Example code of test program (SMSQ/E):

10 REMark Test
20 number=1
30 PRINT number
40 number = two


dc.w'Q1'flag

dc.w$0380   ? vers? Ive seen 0B40, 0100, 120,.

dc.w3   count names

dc.wsource-namessize of name list

dc.w4   line count

names
dc.w$0800
dc.w$
dc.w5,'PRINT '

dc.w$0202 type Top bit or two set on some, for some reason
dc.w$
dc.w6,'number'

dc.w$0202 type
dc.w$
dc.w3,'two '

source
dc.w$0010
dc.w$8D00   line number
dc.w10  10
dc.w$811E   REMarkREMark
dc.w$8C00   rem text
dc.w4,'Test'   Test
dc.w$840A   eol
dc.w$0002   ?

dc.w$8D00
dc.w20  20
dc.w$8800  namenumber
dc.w$0001  name index
dc.w$8401  = =
dc.w$F801
dc.l $4000  float1
dc.w$840A  eol

dc.w$FFFE  ?
dc.w$8D00  line number
dc.w30  30
dc.w$8800  namePRINT
dc.w$  name index
dc.w$8001  one space
dc.w$8800  namenumber
dc.w$0001  name index
dc.w$840A  eol

dc.w$0004  ?
dc.w$8D00  line num
dc.w40
dc.w$8800  namenumber
dc.w$0001  index
dc.w$8001  space
dc.w$8401  = =
dc.w$8001  space
dc.w$8800  name two
dc.w$0002  index
dc.w$840A  eol


___
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm