PyDC converter (was: dragon 32 cassette format ?)

Hardware Hacking, Programming and Game Solutions/Cheats
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: dragon 32 cassette format ?

Post by jedie »

Thanks!

I have build a own ASCII table, with:

Code: Select all

for i in xrange(32,90):
    print "%-3s %r %s" % (
        i, chr(i), bin(i)
    )
result:

Code: Select all

32  ' ' 0b100000
33  '!' 0b100001
34  '"' 0b100010
35  '#' 0b100011
36  '$' 0b100100
37  '%' 0b100101
38  '&' 0b100110
39  "'" 0b100111
40  '(' 0b101000
41  ')' 0b101001
42  '*' 0b101010
43  '+' 0b101011
44  ',' 0b101100
45  '-' 0b101101
46  '.' 0b101110
47  '/' 0b101111
48  '0' 0b110000
49  '1' 0b110001
50  '2' 0b110010
51  '3' 0b110011
52  '4' 0b110100
53  '5' 0b110101
54  '6' 0b110110
55  '7' 0b110111
56  '8' 0b111000
57  '9' 0b111001
58  ':' 0b111010
59  ';' 0b111011
60  '<' 0b111100
61  '=' 0b111101
62  '>' 0b111110
63  '?' 0b111111
64  '@' 0b1000000
65  'A' 0b1000001
66  'B' 0b1000010
67  'C' 0b1000011
68  'D' 0b1000100
69  'E' 0b1000101
70  'F' 0b1000110
71  'G' 0b1000111
72  'H' 0b1001000
73  'I' 0b1001001
74  'J' 0b1001010
75  'K' 0b1001011
76  'L' 0b1001100
77  'M' 0b1001101
78  'N' 0b1001110
79  'O' 0b1001111
80  'P' 0b1010000
81  'Q' 0b1010001
82  'R' 0b1010010
83  'S' 0b1010011
84  'T' 0b1010100
85  'U' 0b1010101
86  'V' 0b1010110
87  'W' 0b1010111
88  'X' 0b1011000
89  'Y' 0b1011001

So it seems that my bin data from the WAV files are wrong :cry:
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
Rink
Posts: 236
Joined: Mon Sep 05, 2011 7:01 pm

Re: dragon 32 cassette format ?

Post by Rink »

Whilst I'm not 100% sure what you're up to - have you tried running a .cas file through dc.exe to convert it to a wav and using this with your Python code?

That way you have a file (.cas) which you can open in a hex editor to compare with, and you'd know that the .wav correctly represents that binary.

After the 0x55 leader bytes, there's three bytes, and then the tape name (which is ASCII readable).

E.g. adventur.cas
0x55 ... 0x55 0x3C 0x00 0x0F ADVENT...

So if your Python script is correctly decoding that and displaying the tape name, then you're probably doing ok.
User avatar
robcfg
Posts: 1533
Joined: Sat Apr 04, 2009 10:16 pm
Location: Stockholm, Sweden
Contact:

Re: dragon 32 cassette format ?

Post by robcfg »

You don't need a table, when you pack every 8 bits into bytes as I showed you, you already have the right value.

Remember that you're working with bytes, not characters. Sure, if you take a look at the file, you can read the text, but that's because a byte's value is the same as a symbol in the ASCII table, nothing else.

Maybe my code doesn't work for you, because you are storing the values as characters ('1') instead of numbers (1). If you are storing the numbers 0 and 1, the code should work correctly translating every 8 bits into bytes that you should just write to the .cas file.

Don't forget that every value is a byte long, don't save an integer as it's greater in size and would make the .cas file invalid.
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: dragon 32 cassette format ?

Post by jedie »

robcfg wrote:That is easy,

Code: Select all

from array import *

bits = array('B',[1,0,1,0,1,0,1,0])
byte = 0

for bit in range(8):
    byte = byte | (bits[bit] << bit)

print '%#X' % byte
Simpler:

Code: Select all

bits = [1,0,1,0,1,0,1,0]
byte = 0
for no, bit in enumerate(bits):
    byte = byte | (bit << no)

print byte, hex(byte), bin(byte)
Output is:

Code: Select all

85 0x55 0b1010101
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
User avatar
robcfg
Posts: 1533
Joined: Sat Apr 04, 2009 10:16 pm
Location: Stockholm, Sweden
Contact:

Re: dragon 32 cassette format ?

Post by robcfg »

Sure,

I just used an array to be able to show that it worked, but the procedure is the same.

Be sure not to discard any byte, as the files are rarely in ascii format, they are binarized basic.

Now, if you convert your bits to bytes, and save them to a .cas file, you should be able to load it on an emulator.

If you have any problem, please post the output cas file so we can take a look and see what's going on.
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: dragon 32 cassette format ?

Post by jedie »

thanks for your help...

Unfortunately, my knowledge about bits and bytes are bad...

I found a interesting python code here: http://www.coco3.com/community/2010/12/ ... cas-files/
Description is: converter binary files to .cas used on CoCo2 emulators like XRoar

Origin code: http://pastebin.com/GCw1NAeY
I cleanup the code and make it public here: http://pastebin.com/wMHqLN9N But didn't really test it.

This helps me to understand the information from http://www.cs.unc.edu/~yakowenk/coco/te ... ormat.html in a better way ;)
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: dragon 32 cassette format ?

Post by jedie »

Are the binary data "Big Endian", "Little Endian" or "Middle Endian" ?
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: dragon 32 cassette format ?

Post by jedie »

I'm a step future! :D

I can see this:

Code: Select all

...
01000100 0x22  34 '"'
00010010 0x48  72 'H'
10100010 0x45  69 'E'
00110010 0x4c  76 'L'
00110010 0x4c  76 'L'
11110010 0x4f  79 'O'
00000100 0x20  32 ' '
11101010 0x57  87 'W'
11110010 0x4f  79 'O'
01001010 0x52  82 'R'
00110010 0x4c  76 'L'
00100010 0x44  68 'D'
10000100 0x21  33 '!'
01000100 0x22  34 '"'
...
IMHO it's because of:

Code: Select all

-    START_LEADER = "01010101"
+    START_LEADER = "10101010" 
and the wrong Byte-Order...
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
User avatar
robcfg
Posts: 1533
Joined: Sat Apr 04, 2009 10:16 pm
Location: Stockholm, Sweden
Contact:

Re: dragon 32 cassette format ?

Post by robcfg »

The code I sent you already takes care of the bits order.

Be aware that you're not getting a fully readable basic program, you need to save all the bytes as they are to the .cas file, and then load it in an emulator.

Also, as I told you, if you attach your .cas files to your replies, we can see better what's happening.
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: dragon 32 cassette format ?

Post by jedie »

My destination is not to create a CAS file. I will get a plain text BAS file ;)

Later i would like to implement a BAS2WAV converter. So you can edit a BASIC programm on PC in a normal Text editor. Change it and recreate the WAV file.

A dictionary of the BASIC tokens have i made:

Code: Select all

BASIC_TOKENS = {
    128: " FOR ",     # 0x80
    129: " GO ",      # 0x81
    130: " REM ",     # 0x82
    131: "'",         # 0x83
    132: " ELSE ",    # 0x84
    133: " IF ",      # 0x85
    134: " DATA ",    # 0x86
    135: " PRINT ",   # 0x87
    136: " ON ",      # 0x88
    137: " INPUT ",   # 0x89
    138: " END ",     # 0x8a
    139: " NEXT ",    # 0x8b
    140: " DIM ",     # 0x8c
    141: " READ ",    # 0x8d
    142: " LET ",     # 0x8e
    143: " RUN ",     # 0x8f
    144: " RESTORE ", # 0x90
    145: " RETURN ",  # 0x91
    146: " STOP ",    # 0x92
    147: " POKE ",    # 0x93
    148: " CONT ",    # 0x94
    149: " LIST ",    # 0x95
    150: " CLEAR ",   # 0x96
    151: " NEW ",     # 0x97
    152: " DEF ",     # 0x98
    153: " CLOAD ",   # 0x99
    154: " CSAVE ",   # 0x9a
    155: " OPEN ",    # 0x9b
    156: " CLOSE ",   # 0x9c
    157: " LLIST ",   # 0x9d
    158: " SET ",     # 0x9e
    159: " RESET ",   # 0x9f
    160: " CLS ",     # 0xa0
    161: " MOTOR ",   # 0xa1
    162: " SOUND ",   # 0xa2
    163: " AUDIO ",   # 0xa3
    164: " EXEC ",    # 0xa4
    165: " SKIPF ",   # 0xa5
    166: " DELETE ",  # 0xa6
    167: " EDIT ",    # 0xa7
    168: " TRON ",    # 0xa8
    169: " TROFF ",   # 0xa9
    170: " LINE ",    # 0xaa
    171: " PCLS ",    # 0xab
    172: " PSET ",    # 0xac
    173: " PRESET ",  # 0xad
    174: " SCREEN ",  # 0xae
    175: " PCLEAR ",  # 0xaf
    176: " COLOR ",   # 0xb0
    177: " CIRCLE ",  # 0xb1
    178: " PAINT ",   # 0xb2
    179: " GET ",     # 0xb3
    180: " PUT ",     # 0xb4
    181: " DRAW ",    # 0xb5
    182: " PCOPY ",   # 0xb6
    183: " PMODE ",   # 0xb7
    184: " PLAY ",    # 0xb8
    185: " DLOAD ",   # 0xb9
    186: " RENUM ",   # 0xba
    187: " TAB(",     # 0xbb
    188: " TO ",      # 0xbc
    189: " SUB ",     # 0xbd
    190: " FN ",      # 0xbe
    191: " THEN ",    # 0xbf
    192: " NOT ",     # 0xc0
    193: " STEP ",    # 0xc1
    194: " OFF ",     # 0xc2
    195: "+",         # 0xc3
    196: "-",         # 0xc4
    197: "*",         # 0xc5
    198: "/",         # 0xc6
    199: "^",         # 0xc7
    200: " AND ",     # 0xc8
    201: " OR ",      # 0xc9
    202: ">",         # 0xca
    203: "=",         # 0xcb
    204: "<",         # 0xcc
    205: " USING ",   # 0xcd
}

The complete data block looks now like this:

Code: Select all

00111100 0x3c  60 '<'
10000000  0x1   1 '\x01'
01001100 0x32  50 '2'
01111000 0x1e  30 '\x1e'
01001000 0x12  18 '\x12'
00000000  0x0   0 '\x00'
01010000  0xa  10 '\n'
00000001 0x80 128 ' FOR '
00000100 0x20  32 ' '
10010010 0x49  73 'I'
00000100 0x20  32 ' '
11010011 0xcb 203 '='
00000100 0x20  32 ' '
10001100 0x31  49 '1'
00000100 0x20  32 ' '
00111101 0xbc 188 ' TO '
00000100 0x20  32 ' '
10001100 0x31  49 '1'
00001100 0x30  48 '0'
00000000  0x0   0 '\x00'
01111000 0x1e  30 '\x1e'
10010100 0x29  41 ')'
00000000  0x0   0 '\x00'
00101000 0x14  20 '\x14'
11100001 0x87 135 ' PRINT '
00000100 0x20  32 ' '
10010010 0x49  73 'I'
11011100 0x3b  59 ';'
01000100 0x22  34 '"'
00010010 0x48  72 'H'
10100010 0x45  69 'E'
00110010 0x4c  76 'L'
00110010 0x4c  76 'L'
11110010 0x4f  79 'O'
00000100 0x20  32 ' '
11101010 0x57  87 'W'
11110010 0x4f  79 'O'
01001010 0x52  82 'R'
00110010 0x4c  76 'L'
00100010 0x44  68 'D'
10000100 0x21  33 '!'
01000100 0x22  34 '"'
00000000  0x0   0 '\x00'
01111000 0x1e  30 '\x1e'
10001100 0x31  49 '1'
00000000  0x0   0 '\x00'
01111000 0x1e  30 '\x1e'
11010001 0x8b 139 ' NEXT '
00000100 0x20  32 ' '
10010010 0x49  73 'I'
00000000  0x0   0 '\x00'
00000000  0x0   0 '\x00'
00000000  0x0   0 '\x00'
11101010 0x57  87 'W'
Seems there are some "control bits" or "meta information"... In this there must be exist the "data length" and the "checksum" information.
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
Post Reply