This is in the pcfullduplexserial object. Ok, there are two new variables.
and at the end of the code, in pasm
FIT $1F0
new_bit_ticks0 long 0-0
new_bit_ticks1 long 0-0
My understanding of spin and pasm is somewhat limited, but are they not local variables to this object? They are defined in the object and all variables are local to the object and you only posted one object so presumably no other object uses these variables. So how does another object pass variables through to this object?
BTW - yes that code compiles and works but I'm not sure how to change this variable.
v0.9.32: Add ports $28 (40) and $29 (41) to set the baud rate of SIO port #0 and #1. The value written is multiplied by 1200 and clkfreq/value/1200 is then written to the bit_ticks values of the SIO object, which in turn reads the (new) values before receiving any character.
You may be right. Of course in 'strine, we might say; Stone the crows, you beauty, you little ripper, she's bonzer, mate.
run that through babelfish and see what mangled translation comes out *grin*.
I'm going to celebrate by playing Mampf ManII on the prop.
Addit: just got an email from China saying the new boards are on the way - RS485, sound, ECB bus, RCA socket for TV. Hopefully I can get one soldered up in the next week or so and get some audio on these games.
Dr_Acula said...
You may be right. Of course in 'strine, we might say; Stone the crows, you beauty, you little ripper, she's bonzer, mate.
run that through babelfish and see what mangled translation comes out *grin*.
I'm going to celebrate by playing Mampf ManII on the prop.
Addit: just got an email from China saying the new boards are on the way - RS485, sound, ECB bus, RCA socket for TV. Hopefully I can get one soldered up in the next week or so and get some audio on these games.
G'day bloke! Let's have some cans of bloody ice cool Foster's VBs on that matter.
pullmoll said...
To run CP/M you can download the latest code from this thread. There's also a hard disk image and a boot.dsk that needs to copied to an SD card. Extract the zip and add the ./lib path to BST's compiler preferences (library search path), then compile cpm.spin to RAM (F10) or EEPROM (F11).
Now i ran into problems... I've downloaded qz80-0.9.32 and tried to compile it...
my computer said...
bstc.linux -Orx -ls -b -e -p0 -d/dev/ttyUSB0 -L../lib -o cpm cpm.spin
Brads Spin Tool Compiler v0.15.3 - Copyright 2008,2009 All rights reserved
Compiled for i386 Linux at 08:17:46 on 2009/07/20
Loading Object cpm
Loading Object io
Loading Object fatfs
Loading Object spi_warp
Loading Object pcFullDuplexSerial2FC
Loading Object Keyboard
Loading Object tv80
I've tried to change it to vt100_colour and vt100_mono and the TV shows a lot of garbage, what happened here?
Heres the top of my cpm.spin http://uc.pastebin.com/KzGPBPQ2
And yes, the SD-config is right, i've changed it. SD-Card works with propdos.
my other thread said...
Instead of VGA & TV i have only a TV out on Pins 16,17 and 18. Pin 19 has a jumper + resistor for the fourth TV-pin (aural subcarrier i think, it isn't needed).
I've tested the TV-Out and Keyboard with propdos => works fine.
I've added a 16bit SPI Port Portexpander (MC23S17) for GPIO and two Atari Joysticks [noparse]:)[/noparse]
If i try to run the Parallax Graphics Demo, nothing shows up on TV and 4 LEDs, connected to the Expander are turned on. The expander is located at Pins 20,21,22,23. The Source is modified like this:
Did you get the vt100 part working? It could be either;
1) The vt100 file is in a sub folder. pullmoll keeps some files in sub folders so go through them all and see if it is there
2) it could be that the #define for vga is not catching all the changes when you go from vga to tv. I'm not using tv so I haven't tested this code but I think pullmoll has a tv board.
Re the errors on booting, you are getting very close. I suspect the files b.dsk and c.dsk are not on the sd card. Have these been copied over?
dracula said...
Did you get the vt100 part working?
I don't know...
dracula said...
1) The vt100 file is in a sub folder. pullmoll keeps some files in sub folders so go through them all and see if it is there
In the source "vt100.spin" is specified, but i can only find vt100_mono and vt100_colour. If i change the source to on of these, the above described error occurs.
dracula said...
2) it could be that the #define for vga is not catching all the changes when you go from vga to tv. I'm not using tv so I haven't tested this code but I think pullmoll has a tv board.
It would be very very nice if he or any other with a working tv-qz80 could have a look at this http://uc.pastebin.com/KzGPBPQ2
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
some say the devil is dead... ...tish army!
@bazi: I hadn't tested the TV80 driver for some time. The vt100_mono.spin object is the one that should be included with TV. The error you see is some missing hard drive images. You can just copy a.dsk to b.dsk and c.dsk and later "era *.*" on b: and c:
Dr_Acula said...
I think I'll go hide under a rock for a while...
Oi! find your own rock, this one's taken!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"I mean, if I went around sayin' I was an emperor just because some moistened bint had lobbed a scimitar at me they'd put me away!"
I've been doing some experiments with batch files on KyeDOS and one of the things needed for batch files is the ability to write them. I think there are one (or two) text editors around for the propeller but not sure if they are fat32 compatible yet.
Anyway, there are many text editors in CP/M, and now that it is so easy to change from CP/M to a spin DOS and back again, I figured it might be easier to move files in and out of the CP/M disk image.
In other words, replicate the SIMH commands of R.COM and W.COM
But it is not so simple!
The main problem is you can't have two files open at once. So you might open the disk image file for reading, but how do you then open the file in the FAT KyeDOS for writing?
(As an aside, how does PIP do that when moving files between disk images? Does it open and close each file in turn?)
There might be several ways to do this. I think you have some raw FAT32 driver code already in the qZ80?
One solution might be to move a file to high external ram, then reboot the propeller and write a program in spin to read that high ram back. (the ram should stay static, even after a reboot). To do that, one might think about a small CP/M program in C or Basic that takes a file and moves it to high ram. And to do that, one might need new OUT and IN commands to poke and peek to high ram.
I wrote some for the zicog - code below
' this all works but takes up spin space and might end up using the space for other things
PRI Peek_Ram | a ' read the value in a ram location
' pass address in DMA 80H=LSB, 81H=middle byte, 82H=MSB
PeekPokeSetup
a:=buff<<8 | buff[noparse][[/noparse]0] ' 0 to 65535 combine two bytes
RamLatches.DoCmd("R", @buff, a, 1) ' value to buff[noparse][[/noparse]0] ' need to use buffcog with no @
io_data:=buff[noparse][[/noparse]0]
HighLatchZero
PRI Poke_Ram | a ' read the value in a ram location
' pass address in DMA 80H=LSB, 81H=middle byte, 82H=MSB
PeekPokeSetup
a:=buff<<8 | buff[noparse][[/noparse]0] ' 0 to 65535 combine two bytes
buff[noparse][[/noparse]0]:=io_data ' put io_data in buff array ready to output
RamLatches.DoCmd("W", @buff, a, 1) ' write io_data which is in buff[noparse][[/noparse]0] ' need to use buffcog with no @
HighLatchZero
PRI PeekPokeSetup
RamLatches.DoCmd("R", @buff, $80, 3) ' read 3 bytes from DMA area to buff array ' need to use buffcog with no @
HighLatchByte :=buff << 16 ' multiply by 65536 to get high byte
RamLatches.DoCmd("H", 0, HighLatchByte, 0) ' setup high byte
' ------------------------------------------------------------------
PUB HighLatchZero ' led off and bank 0
HighLatchByte :=%00000000_00000000_00000000_00000000 ' xxxxxxxx_nnnnnnnn_xxxxxxxx_xxxxxxxx where n is A16 to A23
RamLatches.DoCmd("H", 0, HighLatchByte, 0) ' restore for CP/M
and the complete RamLatches object:
''Dracblade driver for talking to a ram chip via three latches
'' Modified code from Cluso's triblade
' DoCmd(command_, hub_address, ram_address, block_length)
' R - read bytes at address n up (n to n+block_length) where n =0 to 65535 (ie lower 64k of the sram chip)
' W - write bytes at address n up
' I - initialise
' N - Led on
' F - Led off
' H - set high latch to value in ramaddress A16 to A23 (will include the led)
VAR
' communication params(5) between cog driver code - only "command" and "errx" are modified by the driver
long command, hubaddrs, ramaddrs, blocklen, errx, cog ' rendezvous between spin and assembly (can be used cog to cog)
' command = R, W, N, F H =0 when operation completed by cog
' hubaddrs = hub address for data buffer
' ramaddrs = ram address for data ($0000 to $FFFF)
' blocklen = ram buffer length for data transfer
' errx = returns =0 (false=good), else <>0 (true & error code)
' cog = cog no of driver (set by spin start routine)
PUB start : err_
' Initialise the Drac Ram driver. No actual changes to ram as the read/write routines handle this
command := "I"
cog := 1 + cognew(@tbp2_start, @command)
if cog == 0
err_ := $FF ' error = no cog
else
repeat while command ' driver cog sets =0 when done
err_ := errx ' driver cog sets =0 if no error, else xx = error code
PUB stop
if cog
cogstop(cog~ - 1)
PUB DoCmd(command_, hub_address, ram_address, block_length) : err_
' Do the command: R, W, N, F, H
hubaddrs := hub_address ' hub address start
ramaddrs := ram_address ' ram address start
blocklen := block_length ' block length
command := command_ ' must be last !!
' Wait for command to complete and get status
repeat while command ' driver cog sets =0 when done
err_ := errx ' driver cog sets =0 if no error, else xx = error code
DAT
'' +--------------------------------------------------------------------------+
'' | Dracblade Ram Driver (with grateful acknowlegements to Cluso) |
'' +--------------------------------------------------------------------------+
org 0
tbp2_start ' setup the pointers to the hub command interface (saves execution time later
' +-- These instructions are overwritten as variables after start
comptr mov comptr, par ' -| hub pointer to command
hubptr mov hubptr, par ' | hub pointer to hub address
ramptr add hubptr, #4 ' | hub pointer to ram address
lenptr mov ramptr, par ' | hub pointer to length
errptr add ramptr, #8 ' | hub pointer to error status
cmd mov lenptr, par ' | command I/R/W/G/P/Q
hubaddr add lenptr, #12 ' | hub address
ramaddr mov errptr, par ' | ram address
len add errptr, #16 ' | length
err nop ' -+ error status returned (=0=false=good)
' Initialise hardware (unlike the triblade, just tristates everything and read/write set the pins)
init mov err, #0 ' reset err=false=good
mov dira,zero ' tristate the pins
done wrlong err, errptr ' status =0=false=good, else error x
wrlong zero, comptr ' command =0 (done)
' wait for a command (pause short time to reduce power)
pause mov ctr, delay wz ' if =0 no pause
if_nz add ctr, cnt
if_nz waitcnt ctr, #0 ' wait for a short time (reduces power)
rdlong cmd, comptr wz ' command ?
if_z jmp #pause ' not yet
' decode command
cmp cmd, #"R" wz ' R = read block
if_z jmp #rdblock
cmp cmd, #"W" wz ' W = write block
if_z jmp #wrblock
cmp cmd, #"N" wz ' N= led on
if_z jmp #led_turn_on
cmp cmd, #"F" wz ' F = led off
if_z jmp #led_turn_off
cmp cmd, #"H" wz ' H sets the high latch
if_z jmp #sethighlatch
mov err, cmd ' error = cmd (unknown command)
jmp #done
tristate mov dira,zero ' all inputs to zero
jmp #done
' turn led on
led_turn_on or HighLatch,ledpin ' set the led pin high
jmp #OutputHighLatch ' send this out
led_turn_off andn HighLatch,ledpin ' set the led pin low
jmp #OutputHighLatch ' send this out
' set high address bytes with command H, pass value in third variable of the DoCmd
' 4 bytes - masks off all but bits 16 to 23
sethighlatch call #ram_open ' gets address value in 'address'
shr address,#16 ' shift right by 16 places
and address,#$FF ' ensure rest of bits zero
mov HighLatch,address ' put value into HighLatch
jmp #OutputHighLatch ' and output it
'---------------------------------------------------------------------------------------------------------
'Memory Access Functions
rdblock call #ram_open ' get variables from hub variables
rdloop call #read_memory_byte ' read byte from address into data_8
wrbyte data_8,hubaddr ' write data_8 to hubaddr ie copy byte to hub
add hubaddr,#1 ' add 1 to hub address
add address,#1 ' add 1 to ram address
djnz len,#rdloop ' loop until done
jmp #init ' reinitialise
wrblock call #ram_open
wrloop rdbyte data_8, hubaddr ' copy byte from hub
call #write_memory_byte ' write byte from data_8 to address
add hubaddr,#1 ' add 1 to hub address
add address,#1 ' add 1 to ram address
djnz len,#wrloop ' loop until done
jmp #init ' reinitialise
ram_open rdlong hubaddr, hubptr ' get hub address
rdlong ramaddr, ramptr ' get ram address
rdlong len, lenptr ' get length
mov err, #5 ' err=5
mov address,ramaddr ' cluso's variable 'ramaddr' to dracblade variable 'address'
ram_open_ret ret
read_memory_byte call #RamAddress ' sets up the latches with the correct ram address
mov dira,LatchDirection2 ' for reads so P0-P7 tristate till do read
mov outa,GateHigh ' actually ReadEnable but they are the same
andn outa,GateHigh ' set gate low
nop ' short delay to stabilise
nop
mov data_8, ina ' read SRAM
and data_8, #$FF ' extract 8 bits
or outa,GateHigh ' set the gate high again
read_memory_byte_ret ret
write_memory_byte call #RamAddress ' sets up the latches with the correct ram address
mov outx,data_8 ' get the byte to output
and outx, #$FF ' ensure upper bytes=0
or outx,WriteEnable ' or with correct 138 address
mov outa,outx ' send it out
andn outa,GateHigh ' set gate low
nop ' no nop doesn't work, one does, so put in two to be sure
nop ' another NOP
or outa,GateHigh ' set it high again
write_memory_byte_ret ret
RamAddress ' sets up the ram latches. Assumes high latch A16-A18 low so only accesses 64k of ram
mov dira,LatchDirection ' set up the pins for programming latch chips
mov outx,address ' get the address into a temp variable
and outx,#$FF ' mask the low byte
or outx,LowAddress ' or with 138 low address
mov outa,outx ' send it out
andn outa,GateHigh ' set gate low
' ?? a NOP
or outa,GateHigh ' set it high again
' now repeat for the middle byte
mov outx,address ' get the address into a temp variable
shr outx,#8 ' shift right by 8 places
and outx,#$FF ' mask the low byte
or outx,MiddleAddress ' or with 138 middle address
mov outa,outx ' send it out
andn outa,GateHigh ' set gate low
or outa,GateHigh ' set it high again
RamAddress_ret ret
OutputHighLatch ' sends out HighLatch to the 374 that does A16-19, led and the 4 spare outputs
mov dira,latchdirection ' setup active pins 138 and bus
mov outa,HighLatch ' send out HighLatch
or outa,HighAddress ' or with the high address
andn outa,GateHigh ' set gate low
or outa,GateHigh ' set the gate high again
OutputHighLatch_ret jmp #tristate ' set pins tristate
delay long 80 ' waitcnt delay to reduce power (#80 = 1uS approx)
ctr long 0 ' used to pause execution (lower power use) & byte counter
GateHigh long %00000000_00000000_00000001_00000000 ' HC138 gate high, all others must be low
Outx long 0 ' for temp use, same as n in the spin code
LatchDirection long %00000000_00000000_00001111_11111111 ' 138 active, gate active and 8 data lines active
LatchDirection2 long %00000000_00000000_00001111_00000000 ' for reads so data lines are tristate till the read
LowAddress long %00000000_00000000_00000101_00000000 ' low address latch = xxxx010x and gate high xxxxxxx1
MiddleAddress long %00000000_00000000_00000111_00000000 ' middle address latch = xxxx011x and gate high xxxxxxx1
HighAddress long %00000000_00000000_00001001_00000000 ' high address latch = xxxx100x and gate high xxxxxxx1
'ReadEnable long %00000000_00000000_00000001_00000000 ' /RD = xxxx000x and gate high xxxxxxx1
' commented out as the same as GateHigh
WriteEnable long %00000000_00000000_00000011_00000000 ' /WE = xxxx001x and gate high xxxxxxx1
Zero long %00000000_00000000_00000000_00000000 ' for tristating all pins
data_8 long %00000000_00000000_00000000_00000000 ' so code compatability with zicog driver
address long %00000000_00000000_00000000_00000000 ' address for ram chip
ledpin long %00000000_00000000_00000000_00001000 ' to turn on led
HighLatch long %00000000_00000000_00000000_00000000 ' static value for the 374 latch that does the led, hA16-A19 and the other 4 outputs
So first question, is there room in the qZ80 for a similar piece of code (pasm or spin?)?
But the second question - is there a smarter way to move files in and out of CP/M disk images?
eg just brainstorming, you have code that dumps data to a print spooler. Maybe you could capture that somehow?
Or maybe not do it through the ram? Maybe open and close files many times (Kye's driver has an "append" function).
Thinking big picture, now it is possible with KyeDOS to open and close spin files so easily (mix and match PropBasic, Catalina, CP/M), and with your ctrl-alt-del shutdown for CP/M, it ought to be possible to use some of the programs in CP/M to do some on-board propeller development, eg writing batch files.
DR_A: You don't need to have two file open at the same time to move a file from FAT to CP/M or vice versa.
There is no need for any FAT files to be open when the Z80 emu is accessing it's CP/M files.
That's because when Z80 emulation accesses CP/M files it ends up going through the I/O simulation layer, in Spin,
that ends up doing low level block read and write on the SD card. The actual FAT file being accessed need not
be open at this time. In fact it should NOT be open at this time, you can't allow FAT and CP/M access to the same
file at the same time that would be a disaster.
So when CP/M writes out a CP/M file through the SIMH style host port, as done by W.COM it is only necessary
for the I/O emulation to detect those port accesses, open the appropriate file in FAT and write it out.
Same for reads from the FAT host.
Not sure how qZ80 handles CP/M file access but that is the case with ZiCog. If qZ80 keeps the CP/M disk files open
all the time and uses seek to read/write the CP/M blocks then you would have a problem.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Dr_A: Oh yeah, being able to use WordStar or such editor on the Prop without ever really being aware that
you have started CP/M to do so would be great.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
There might be several ways to do this. I think you have some raw FAT32 driver code already in the qZ80?
I use my own fatfs.spin code in conjunction with hairmnstr's spi_warp.spin to read from FAT16 and FAT32 SD cards.
Dr_Acula said...
So first question, is there room in the qZ80 for a similar piece of code (pasm or spin?)?
There are ports to access the unused (in MP/M) portions of the RAM. It's documented in the history at the first page. I guess you want to access all RAM except the first 64K in one sequence?
Dr_Acula said...
But the second question - is there a smarter way to move files in and out of CP/M disk images?
Not unless there is code to write to the SD either in my fatfs.spin or in e.g. Kye's driver. Switching to that one means a lot of work in all emulations, though, which is why I would not want to do that lightheartedly... also Kye's code is certainly going to overflow the hub RAM in some of the emulations - the ones which already use up almost all of the hub RAM.
Dr_Acula said...
Your thoughts would be most appreciated.
Well, if writing to the SD isn't too complicated, I can try to do that. Writing a file involves some steps, though:
1) find an existing file by the given name and unlink (erase) it.
2) find an empty directory slot ($e5) or append a new slot. For fat16 that may fail when writing the root directory. Otherwise it may involve allocating a new cluster to the current directory.
3) create a new directory entry and find a first free cluster to enter into the structure.
4) write to the sectors belonging to the cluster and when another cluster is required, create the cluster chain (in both copies of the FAT).
5) on closing the file write the end mark to the current cluster in the FAT (== max. cluster number for the fat type) and modify the directory entry to have the correct size, perhaps update date/time fields.
These steps involve a little bit of work and I'm not sure if/when I find time to try to add them.
If writing was possible, I would suggest to add a fake port that receives a filename, a nul byte, a "W" for write, the size of the file (4 bytes long value) and then the file data. Reading should be possible through the same port by just specifying "R" for read. After that you could read the 4 byte file size from the port followed by the file data.
It may be possible to squeeze yet another port handler call into io.spin, though it's very tight in there already. I have to find some code duplication to eliminate.
'**********************************************************************************************
'
' Set baud rate of SIO #0 to data * 1200 baud
'
output_baud0
mov lmm_pc, #lmm_baud0
jmp #lmm_command0
'**********************************************************************************************
'
' Set baud rate of SIO #1 to data * 1200 baud
'
output_baud1
mov lmm_pc, #lmm_baud1
jmp #lmm_command0
Well, that's not all of the code.. it's just the code that dispatches to the LMM code baud0 or baud1. I can only add more LMM code, because the cog is full. In order to add yet another port handler, I need to free 2 cog longs for the dispatcher and even that will be impossible rather sooner than later.
Yes, maybe moving files with a "W.COM" and "R.COM" might be too complicated.
If you are really desperate for space, you could remove references to the N8VEM modem port (addit - no, still need this. but there are other solutions)
n8vem_data_port = $68 ' modem data port
n8vem_stat_port = $6d ' modem status port
and I could rewrite xmodemp.asm so it used these ports instead:
constat_port = $10 ' console 0 status port (on SIO #0 or Keyboard / VGA)
condata_port = $11 ' console 0 data port (on SIO #0 or Keyboard / VGA)
punstat_port = $12 ' punch 1 status port
pundata_port = $13 ' punch/reader 1 data port
con1stat_port = $14 ' console 1 status port (on Keyboard / VGA or SIO #0)
con1data_port = $15 ' console 1 data port (on Keyboard / VGA or SIO #0)
con2stat_port = $16 ' console 2 status port (on SIO #1)
con2data_port = $17 ' console 2 data port (on SIO #1)
There may be some advantages to this anyway, as currently the data comes in on user0, so if you do an xmodem to user2, I'm currently sending instructions to first change to user0, then xmodem, then PIP it to user2, then change back to user2. I haven't tested it yet, but maybe three versions of xmodem, xm0, xm1 and xm2 for each user?
Addit: No don't delete the N8VEM ports - I still haven't got a replacement to work. Files still seem to end up in user 0. Need to edit xmodem code. Hmm - still need the N8VEM ports anyway for the CP/M version.
It may just be a matter of changing variables MODCTLP, MODDATP and MODDATO in this xmodem code
;If you are using an external modem (not S-100 plug-in)
;change these equates for your modem port requirements
;
.IF EXTMOD
MODCTLP:.EQU 06DH ; PUT YOUR MODEM STATUS PORT HERE
MODSNDB:.EQU 20H ; YOUR BIT TO TEST FOR SEND
MODSNDR:.EQU 20H ; YOUR VALUE WHEN READY
MODRCVB:.EQU 01H ; YOUR BIT TO TEST FOR RECEIVE
MODRCVR:.EQU 01H ; YOUR VALUE WHEN READY
MODDCDB:.EQU 02H ; CARRIER DETECT BIT *** DSR change status bit
MODDCDA:.EQU 00H ; VALUE WHEN ACTIVE *** 0 = no change since
MODDATP:.EQU 068H ; YOUR MODEM DATA IN PORT
MODDATO:.EQU 068H ; YOUR MODEM DATA OUT PORT
MODCTL2:.EQU 0C1H ; SECOND CONTROL/STATUS PORT.
.ENDIF ; END OF EXTERNAL MODEM .EQUATES
BUT - maybe there is another way. You could xmodem the files between the PC and MP/M. Then you could reboot back into KyeDOS and xmodem the file between the PC and KyeDOS. Ok, that is two steps, but it would work with code already written.
The reason I'm not doing this is that MP/M keeps crashing. And, I think that might be related to the interrupt timing.
So I have gone through the code looking for variables that might affect the interrupt. First I tried changing variable timer_delta from 20x80000. At 20x80000 the probability of booting MP/M to the 0A> command prompt is 10/12. With timer_delta changed to 2*80000 the probability is 8/12 and at 200*80000 it is 8/12. Conclusion - timer_delta is not associated with this error.
But I did have more luck adjusting the variable i1000 which appears in this code:
output_simh_set_timer_delta
rdlong x, #0 ' get clkfreq
mov y, i1000 ' divide by 1000
mov lmm_pc, #lmm_div32
call #lmm_func
rdword x, simh_params ' get delta in milliseconds
mov lmm_pc, #lmm_mul32
call #lmm_func
mov timer_delta, x ' delta in cycles
The default is 1000 at which the probability of booting MP/M is 10/12. Change to 100 and it is 12/12. Change to 10000 and it is 0/12.
Next is to work out is the threshold is a sudden change or more gradual. So I changed this variable to several different values and did lots of reboots.
Then I plotted this on an x,y scatter plot using Excel. I think from this I can say that 100 is safe.
My theory is that some interrupts are taking longer than others, and that another interrupt is arriving before the first one is finished. That is just a theory though.
Also, changing the variable i1000 is a crude fix. Much better to change the value in the interrupt timer - but I think that is hidden in the modified source code for MP/M (I think pullmoll did change that code because part of the bootup for MP/M says "MP/M XIOS (qZ80 propeller V1.11 3HDs, Banked 15 Apr 10)"
So what I am doing now is testing with i1000 set at 100, and seeing if xmodem transfers are more reliable.
If they are.... then there is less of a need to try to write W.COM and R.COM - because you can always use xmodem and the PC and KyeDOS.
Addit: got xmodem working on a different user. There is a variable RECU hidden away in the code. See attached. So now it can download to a particular user without having to PIP it over. Am still using the N8VEM port numbers - I need to test if it will work using the proper SIO port numbers.
As an aside, changing i1000 to 100 has also fixed the unreliable PIP problem - all PIPs seem to go through reliably now.
I tried changing the ports to the SIO for port1 but it does not work. So definitely need the N8VEM ports 6D and 68.
But direct downloads to user area 1 and 2 is much quicker now for code development eg C and SBasic where the compilation is being done on the PC SIMH
I'm now slowly working through the xmodem source code rewriting it for the different serial ports. It is complicated because the bits to test for input are different to a 16550 uart, and reading bytes works differently eg if you read a data byte from a uart it clears that byte, but if you read it from the software port it does not clear the byte. So it will need a few new lines of code. But when this is working, it will make downloads easier.
@Dr_Acula: So you are effectively reducing the interrupt rate to 1/10th of the specified rate. The interrupt rate was set to 50 Hz, so it will now be running at 5 Hz. Not sure if and why MP/M works (better, at all) with this setting. The cleaner solution to change the rate would be to modify MPMXIOS.MAC and set the ticks to 5 there.
Yes, the interrupt rate is now 5 per second. And MP/M is now *much* more reliable - no mysterious hangs, crashes etc.
How do you recompile MP/M - is it with the standard version on the SIMH or do you have a modified version of MPMXIOS? If so, is that modified version on the A disk?
Yes, there's the modified version on the A.DSK. You can edit it in Wordstar non-document mode and change the ticks value to 5. Then there's a submit file; I think it was mpm.sub, so do mpm should do the work.
Would you be able to re-release the A.DSK with MPM recompiled with the ticks set to 5?
(Or I can create a file if you like).
It has greatly increased the reliability of MPM.
Attached is the latest version of xmodem for user 1. This has been tested with my vb.net program, and Teraterm and Hyperterminal. Baud rate is 38400. I have had some success at 57600 but occ errors creep in on user 2 at 57600. Maybe the cable is a bit long? Anyway, there really is not much point going over 38400 as the write speed of the sd card is the limiting factor.
Changing the ticks from 50 to 5 has also fixed the strange bug where the LCD display would not work if the baud rate of the serial port 1 was 38400 (but would work at every other rate).
Lots of things working nicely now.
Of course, if you can xmodem files to and from user 1, you can then send them to user 0 or user 2 with
PIP MYFILE.TXT[noparse][[/noparse]G2]=PIP MYFILE.TXT[noparse][[/noparse]G1]
To make things easier, one could think about including XM1.COM on the A.DSK in the User 1 area.
Almost cracked it. Attached is xmodem for user 2. Works perfectly with Hypterterminal at 38k. Can send using Teraterm from the board to the PC. But can't receive via Teraterm - it hangs at packet 16 when it goes off to save data on the sd card.
Teraterm has some other odd things too - it collects up the NAKs at startup, then if there are 5 NAKs that have accumulated, it sends the first packet 5 times. The proper protocol is supposed to clear those NAKs as they come in.
The secret was to change the bit flags
MODCTLP:.EQU 016H ; PUT YOUR MODEM STATUS PORT HERE
MODSNDB:.EQU 02H ; YOUR BIT TO TEST FOR SEND xxxxxx1x
MODSNDR:.EQU 02H ; YOUR VALUE WHEN READY 1 when ready 00000010 when ready
MODRCVB:.EQU 01H ; YOUR BIT TO TEST FOR RECEIVE xxxxxxx1
MODRCVR:.EQU 01H ; YOUR VALUE WHEN READY 00000001
MODDCDB:.EQU 02H ; CARRIER DETECT BIT xxxxxx1x use bit 2, always assumes carrier on
MODDCDA:.EQU 02H ; VALUE WHEN ACTIVE 00000010
MODDATP:.EQU 017H ; YOUR MODEM DATA IN PORT
MODDATO:.EQU 017H ; YOUR MODEM DATA OUT PORT
MODCTL2:.EQU 017H ; SECOND CONTROL/STATUS PORT.
and to rewrite the Gobble code
;Gobble up garbage chars from the line
;prior to receive or send
;
; IN A,(MODDATP)
; IN A,(MODDATP)
CALL GOBBLETWO
and to remove gobble code in RECV
;----> RECV: Receive a character
;
;Timeout time is in B, in seconds. Entry via
;"RECVDG" deletes garbage characters on the
;line. For example, having just sent a sector,
;calling RECVDG will delete any line-noise-induced
;characters "long" before the ACK/NAK would
;be received.
;
RECVDG: .EQU $ ; RECEIVE W/GARBAGE DELETE
; IN A,(MODDATP) ; GET A CHAR
; IN A,(MODDATP) ; ..TOTALLY PURGE UART
; CALL GOBBLETWO ; code from MP/M instead *** no this causes problems with Send so comment it out **
and to specifically only gobble two bytes, not indefinitely
GOBBLETWO: ; only gobble twice - same as the original xmodem
; this is quite time critical, and some terminals like Teraterm don't like delays
IN A,(MODCTLP) ; status byte for port2
AND 01H ; and with xxxxxxx1
CP 01H ; test bit 1, 0 if no bit, 1 if there is a bit
RET NZ ; return if nothing
IN A,(MODDATP) ; get the byte and discard
; do again
IN A,(MODCTLP) ; status byte for port2
AND 01H ; and with xxxxxxx1
CP 01H ; test bit 1, 0 if no bit, 1 if there is a bit
RET NZ ; return if nothing
IN A,(MODDATP) ; get the byte and discard
RET
The practical outcome is we now have XM1.COM for talking to serial port 1, and XM2.COM for talking to serial port 2.
I've also attached the version of hyperterminal that I've been using as I think some versions of Windows do not have this.
Addit: ShamCom seems to work too. Though they call upload download and vice versa.
Another addit: The last screen shot is extremly nerdy. It shows MBASIC running on user 0. And at the same time, MBASIC is being downloaded to user 1 from Teraterm, and MBASIC is also being downloaded to user 2 using Hyperterminal. I have no idea how MP/M sorts out where those packets need to go but they are all getting there. It is nifty watching the download leds flashing. Hmm - a parallel chip running a serial operating system emulating parallel operating systems. Yummy!
Addit: A question for Pullmoll.
I'm working on a program running in User2 that can take packets from a serial port and pass them through to User0. I've got some things working, and I've sent a ^P to user0 from user2 and that is working fine with a DIR. All the bytes are coming back via this little bit of code
Procedure ReadPrintBuffer
var a,b=integer
a=inp(12H) rem is there a character ready?
If a = 3 Then
begin
b=inp(13H) rem read the data from the print buffer
OutPort2 b rem send out the second serial port
End
End
The only problem is not everything seems to come back. If I run MBASIC, nothing comes back from within MBASIC. But when I go back to CP/M, all the CP/M bytes do go out (eg DIR and other CP/M programs)
It seems that ^P is not capturing all the bytes that are going to the local vga screen. Specifically, it won't capture bytes from within other programs.
I'm wondering if there is another way to capture bytes, perhaps capturing them from the code going to the vga monitor, rather than from within CP/M?
Would it cost much in code to send all bytes to the vga screen, also to a circular buffer somewhere? Maybe just a head and tail pointer, and put the buffer in ram. Maybe not even switched on with a ^P - just always send them to this buffer too - I don't think it would slow down the vga screen much.
The only problem is not everything seems to come back. If I run MBASIC, nothing comes back from within MBASIC. But when I go back to CP/M, all the CP/M bytes do go out (eg DIR and other CP/M programs)
It seems that ^P is not capturing all the bytes that are going to the local vga screen. Specifically, it won't capture bytes from within other programs.
I'm wondering if there is another way to capture bytes, perhaps capturing them from the code going to the vga monitor, rather than from within CP/M?
Would it cost much in code to send all bytes to the vga screen, also to a circular buffer somewhere? Maybe just a head and tail pointer, and put the buffer in ram. Maybe not even switched on with a ^P - just always send them to this buffer too - I don't think it would slow down the vga screen much.
Your thoughts would be most appreciated.
I think the other programs may use another BDOS function to emit characters, one which can not be redirected to another device.
If the BIOS honours the IO byte (I think it was at $0004), then it should still be possible to redirect everything that usually goes to conout to e.g. printer - and thus our ring buffer, but I think the BIOS just ignores this byte. It would mean to add some code to MPMXIOS to switch outputs depending on the bits in the io byte.
I think I could add code to store bytes that go to the vt100 terminal in another ring buffer. This would work in either setup, keyboard/VGA on user 0 or user 1 (or unused in CP/M). I'll see when I find time to add something like this.
Comments
I'm awfully sorry, but I don't understand that at all
This is in the pcfullduplexserial object. Ok, there are two new variables.
and at the end of the code, in pasm
My understanding of spin and pasm is somewhat limited, but are they not local variables to this object? They are defined in the object and all variables are local to the object and you only posted one object so presumably no other object uses these variables. So how does another object pass variables through to this object?
BTW - yes that code compiles and works but I'm not sure how to change this variable.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 6/12/2010 8:24:07 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 6/12/2010 1:00:35 PM GMT
To use:
MBASIC
then
OUT (41),1
and the second serial port is now 1200 baud.
Now I need to study how the code works. Sehr kluger, vielen dank.
addit: found the code. So neat.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 6/12/2010 1:38:51 PM GMT
run that through babelfish and see what mangled translation comes out *grin*.
I'm going to celebrate by playing Mampf ManII on the prop.
Addit: just got an email from China saying the new boards are on the way - RS485, sound, ECB bus, RCA socket for TV. Hopefully I can get one soldered up in the next week or so and get some audio on these games.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 6/12/2010 1:47:15 PM GMT
G'day bloke! Let's have some cans of bloody ice cool Foster's VBs on that matter.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 6/12/2010 2:47:36 PM GMT
Now i ran into problems... I've downloaded qz80-0.9.32 and tried to compile it... I've tried to change it to vt100_colour and vt100_mono and the TV shows a lot of garbage, what happened here?
Heres the top of my cpm.spin http://uc.pastebin.com/KzGPBPQ2
And yes, the SD-config is right, i've changed it. SD-Card works with propdos.
// edit:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
some say the devil is dead... ...tish army!
Post Edited (bazi) : 6/12/2010 7:26:21 PM GMT
1) The vt100 file is in a sub folder. pullmoll keeps some files in sub folders so go through them all and see if it is there
2) it could be that the #define for vga is not catching all the changes when you go from vga to tv. I'm not using tv so I haven't tested this code but I think pullmoll has a tv board.
Re the errors on booting, you are getting very close. I suspect the files b.dsk and c.dsk are not on the sd card. Have these been copied over?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
It would be very very nice if he or any other with a working tv-qz80 could have a look at this http://uc.pastebin.com/KzGPBPQ2
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
some say the devil is dead... ...tish army!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
ROTFLOL!
Mind you, all bets might be off soon - Australia is playing Germany very soon in the World Cup.
@bazi
you should have:
vt100.spin
vt100_colour.spin
vt100_mono.spin
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
I've seen it. I'm not usually a soccer fan, but that game was great. I think we will be champions after the games
Not really. The vt100.spin was the code for 1 byte per character which is the same as vt100_mono.spin.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Aaaargh. 4-Nil. On behalf of all Australians, I think I'll go hide under a rock for a while...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Oi! find your own rock, this one's taken!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"I mean, if I went around sayin' I was an emperor just because some moistened bint had lobbed a scimitar at me they'd put me away!"
I've been doing some experiments with batch files on KyeDOS and one of the things needed for batch files is the ability to write them. I think there are one (or two) text editors around for the propeller but not sure if they are fat32 compatible yet.
Anyway, there are many text editors in CP/M, and now that it is so easy to change from CP/M to a spin DOS and back again, I figured it might be easier to move files in and out of the CP/M disk image.
In other words, replicate the SIMH commands of R.COM and W.COM
But it is not so simple!
The main problem is you can't have two files open at once. So you might open the disk image file for reading, but how do you then open the file in the FAT KyeDOS for writing?
(As an aside, how does PIP do that when moving files between disk images? Does it open and close each file in turn?)
There might be several ways to do this. I think you have some raw FAT32 driver code already in the qZ80?
One solution might be to move a file to high external ram, then reboot the propeller and write a program in spin to read that high ram back. (the ram should stay static, even after a reboot). To do that, one might think about a small CP/M program in C or Basic that takes a file and moves it to high ram. And to do that, one might need new OUT and IN commands to poke and peek to high ram.
I wrote some for the zicog - code below
and the complete RamLatches object:
So first question, is there room in the qZ80 for a similar piece of code (pasm or spin?)?
But the second question - is there a smarter way to move files in and out of CP/M disk images?
eg just brainstorming, you have code that dumps data to a print spooler. Maybe you could capture that somehow?
Or maybe not do it through the ram? Maybe open and close files many times (Kye's driver has an "append" function).
Thinking big picture, now it is possible with KyeDOS to open and close spin files so easily (mix and match PropBasic, Catalina, CP/M), and with your ctrl-alt-del shutdown for CP/M, it ought to be possible to use some of the programs in CP/M to do some on-board propeller development, eg writing batch files.
Your thoughts would be most appreciated.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
There is no need for any FAT files to be open when the Z80 emu is accessing it's CP/M files.
That's because when Z80 emulation accesses CP/M files it ends up going through the I/O simulation layer, in Spin,
that ends up doing low level block read and write on the SD card. The actual FAT file being accessed need not
be open at this time. In fact it should NOT be open at this time, you can't allow FAT and CP/M access to the same
file at the same time that would be a disaster.
So when CP/M writes out a CP/M file through the SIMH style host port, as done by W.COM it is only necessary
for the I/O emulation to detect those port accesses, open the appropriate file in FAT and write it out.
Same for reads from the FAT host.
Not sure how qZ80 handles CP/M file access but that is the case with ZiCog. If qZ80 keeps the CP/M disk files open
all the time and uses seek to read/write the CP/M blocks then you would have a problem.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
you have started CP/M to do so would be great.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I use my own fatfs.spin code in conjunction with hairmnstr's spi_warp.spin to read from FAT16 and FAT32 SD cards.
There are ports to access the unused (in MP/M) portions of the RAM. It's documented in the history at the first page. I guess you want to access all RAM except the first 64K in one sequence?
Not unless there is code to write to the SD either in my fatfs.spin or in e.g. Kye's driver. Switching to that one means a lot of work in all emulations, though, which is why I would not want to do that lightheartedly... also Kye's code is certainly going to overflow the hub RAM in some of the emulations - the ones which already use up almost all of the hub RAM.
Well, if writing to the SD isn't too complicated, I can try to do that. Writing a file involves some steps, though:
1) find an existing file by the given name and unlink (erase) it.
2) find an empty directory slot ($e5) or append a new slot. For fat16 that may fail when writing the root directory. Otherwise it may involve allocating a new cluster to the current directory.
3) create a new directory entry and find a first free cluster to enter into the structure.
4) write to the sectors belonging to the cluster and when another cluster is required, create the cluster chain (in both copies of the FAT).
5) on closing the file write the end mark to the current cluster in the FAT (== max. cluster number for the fat type) and modify the directory entry to have the correct size, perhaps update date/time fields.
These steps involve a little bit of work and I'm not sure if/when I find time to try to add them.
If writing was possible, I would suggest to add a fake port that receives a filename, a nul byte, a "W" for write, the size of the file (4 bytes long value) and then the file data. Reading should be possible through the same port by just specifying "R" for read. After that you could read the 4 byte file size from the port followed by the file data.
It may be possible to squeeze yet another port handler call into io.spin, though it's very tight in there already. I have to find some code duplication to eliminate.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 6/19/2010 11:58:50 AM GMT
Well, that's not all of the code.. it's just the code that dispatches to the LMM code baud0 or baud1. I can only add more LMM code, because the cog is full. In order to add yet another port handler, I need to free 2 cog longs for the dispatcher and even that will be impossible rather sooner than later.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
If you are really desperate for space, you could remove references to the N8VEM modem port (addit - no, still need this. but there are other solutions)
and I could rewrite xmodemp.asm so it used these ports instead:
There may be some advantages to this anyway, as currently the data comes in on user0, so if you do an xmodem to user2, I'm currently sending instructions to first change to user0, then xmodem, then PIP it to user2, then change back to user2. I haven't tested it yet, but maybe three versions of xmodem, xm0, xm1 and xm2 for each user?
Addit: No don't delete the N8VEM ports - I still haven't got a replacement to work. Files still seem to end up in user 0. Need to edit xmodem code. Hmm - still need the N8VEM ports anyway for the CP/M version.
It may just be a matter of changing variables MODCTLP, MODDATP and MODDATO in this xmodem code
BUT - maybe there is another way. You could xmodem the files between the PC and MP/M. Then you could reboot back into KyeDOS and xmodem the file between the PC and KyeDOS. Ok, that is two steps, but it would work with code already written.
The reason I'm not doing this is that MP/M keeps crashing. And, I think that might be related to the interrupt timing.
So I have gone through the code looking for variables that might affect the interrupt. First I tried changing variable timer_delta from 20x80000. At 20x80000 the probability of booting MP/M to the 0A> command prompt is 10/12. With timer_delta changed to 2*80000 the probability is 8/12 and at 200*80000 it is 8/12. Conclusion - timer_delta is not associated with this error.
But I did have more luck adjusting the variable i1000 which appears in this code:
The default is 1000 at which the probability of booting MP/M is 10/12. Change to 100 and it is 12/12. Change to 10000 and it is 0/12.
Next is to work out is the threshold is a sudden change or more gradual. So I changed this variable to several different values and did lots of reboots.
Then I plotted this on an x,y scatter plot using Excel. I think from this I can say that 100 is safe.
My theory is that some interrupts are taking longer than others, and that another interrupt is arriving before the first one is finished. That is just a theory though.
Also, changing the variable i1000 is a crude fix. Much better to change the value in the interrupt timer - but I think that is hidden in the modified source code for MP/M (I think pullmoll did change that code because part of the bootup for MP/M says "MP/M XIOS (qZ80 propeller V1.11 3HDs, Banked 15 Apr 10)"
So what I am doing now is testing with i1000 set at 100, and seeing if xmodem transfers are more reliable.
If they are.... then there is less of a need to try to write W.COM and R.COM - because you can always use xmodem and the PC and KyeDOS.
Addit: got xmodem working on a different user. There is a variable RECU hidden away in the code. See attached. So now it can download to a particular user without having to PIP it over. Am still using the N8VEM port numbers - I need to test if it will work using the proper SIO port numbers.
As an aside, changing i1000 to 100 has also fixed the unreliable PIP problem - all PIPs seem to go through reliably now.
I tried changing the ports to the SIO for port1 but it does not work. So definitely need the N8VEM ports 6D and 68.
But direct downloads to user area 1 and 2 is much quicker now for code development eg C and SBasic where the compilation is being done on the PC SIMH
I'm now slowly working through the xmodem source code rewriting it for the different serial ports. It is complicated because the bits to test for input are different to a 16550 uart, and reading bytes works differently eg if you read a data byte from a uart it clears that byte, but if you read it from the software port it does not clear the byte. So it will need a few new lines of code. But when this is working, it will make downloads easier.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 6/20/2010 11:00:33 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
How do you recompile MP/M - is it with the standard version on the SIMH or do you have a modified version of MPMXIOS? If so, is that modified version on the A disk?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Initial tests = 100% bootup over 12 tries.
How cool is this - recompiling a propeller operating system on the propeller itself?!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
This is how it is supposed to be: boot strapping. You can be happy that you don't have to enter the initial loader into a hex console
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Would you be able to re-release the A.DSK with MPM recompiled with the ticks set to 5?
(Or I can create a file if you like).
It has greatly increased the reliability of MPM.
Attached is the latest version of xmodem for user 1. This has been tested with my vb.net program, and Teraterm and Hyperterminal. Baud rate is 38400. I have had some success at 57600 but occ errors creep in on user 2 at 57600. Maybe the cable is a bit long? Anyway, there really is not much point going over 38400 as the write speed of the sd card is the limiting factor.
Changing the ticks from 50 to 5 has also fixed the strange bug where the LCD display would not work if the baud rate of the serial port 1 was 38400 (but would work at every other rate).
Lots of things working nicely now.
Of course, if you can xmodem files to and from user 1, you can then send them to user 0 or user 2 with
PIP MYFILE.TXT[noparse][[/noparse]G2]=PIP MYFILE.TXT[noparse][[/noparse]G1]
To make things easier, one could think about including XM1.COM on the A.DSK in the User 1 area.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 6/22/2010 12:38:05 AM GMT
Teraterm has some other odd things too - it collects up the NAKs at startup, then if there are 5 NAKs that have accumulated, it sends the first packet 5 times. The proper protocol is supposed to clear those NAKs as they come in.
The secret was to change the bit flags
and to rewrite the Gobble code
and to remove gobble code in RECV
and to specifically only gobble two bytes, not indefinitely
The practical outcome is we now have XM1.COM for talking to serial port 1, and XM2.COM for talking to serial port 2.
I've also attached the version of hyperterminal that I've been using as I think some versions of Windows do not have this.
Addit: ShamCom seems to work too. Though they call upload download and vice versa.
Another addit: The last screen shot is extremly nerdy. It shows MBASIC running on user 0. And at the same time, MBASIC is being downloaded to user 1 from Teraterm, and MBASIC is also being downloaded to user 2 using Hyperterminal. I have no idea how MP/M sorts out where those packets need to go but they are all getting there. It is nifty watching the download leds flashing. Hmm - a parallel chip running a serial operating system emulating parallel operating systems. Yummy!
Addit: A question for Pullmoll.
I'm working on a program running in User2 that can take packets from a serial port and pass them through to User0. I've got some things working, and I've sent a ^P to user0 from user2 and that is working fine with a DIR. All the bytes are coming back via this little bit of code
The only problem is not everything seems to come back. If I run MBASIC, nothing comes back from within MBASIC. But when I go back to CP/M, all the CP/M bytes do go out (eg DIR and other CP/M programs)
It seems that ^P is not capturing all the bytes that are going to the local vga screen. Specifically, it won't capture bytes from within other programs.
I'm wondering if there is another way to capture bytes, perhaps capturing them from the code going to the vga monitor, rather than from within CP/M?
Would it cost much in code to send all bytes to the vga screen, also to a circular buffer somewhere? Maybe just a head and tail pointer, and put the buffer in ram. Maybe not even switched on with a ^P - just always send them to this buffer too - I don't think it would slow down the vga screen much.
Your thoughts would be most appreciated.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 6/25/2010 8:34:49 AM GMT
I think the other programs may use another BDOS function to emit characters, one which can not be redirected to another device.
If the BIOS honours the IO byte (I think it was at $0004), then it should still be possible to redirect everything that usually goes to conout to e.g. printer - and thus our ring buffer, but I think the BIOS just ignores this byte. It would mean to add some code to MPMXIOS to switch outputs depending on the bits in the io byte.
I think I could add code to store bytes that go to the vt100 terminal in another ring buffer. This would work in either setup, keyboard/VGA on user 0 or user 1 (or unused in CP/M). I'll see when I find time to add something like this.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
But only when you have time!
What projects are you working on at the moment?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Windowze driver for the Canon EOS 550D to be accessed by an existing scanner software. Paid work pays...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects