开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育

Re: Source code?

 

Scott,

I never put a lot of time and effort into perfecting XModem operations.? I got it running and moved on.

I don't have the time for this.? For example, I've spent the last 2 nights going to sleep at 2am, waking at 7.
Tonight I really wanted to get to bed by 11, but it's nearly 1am already... why?

Cheers,
Josh



On Tuesday, November 26, 2019, 2:41:40 PM EST, scotty264b@... <scotty264b@...> wrote:


Josh:
You may want to provide the newer version of XMODEM on the DISK-A.BIN image since assembles to only 4KB in size rather than the 8KB that is currently provided.?
?
TheXMODEM.cfg file you recently provided works correctly but why tell XMODEM that the Z80 is running at 2MHz instead of 4MHz?
?
I have attached the ZIP'd V2.4 XMODEM.COM executable ans source code to this message.
?
Peace and blessings.


Re: Source code?

 

Josh:
You may want to provide the newer version of XMODEM on the DISK-A.BIN image since assembles to only 4KB in size rather than the 8KB that is currently provided.?
?
TheXMODEM.cfg file you recently provided works correctly but why tell XMODEM that the Z80 is running at 2MHz instead of 4MHz?
?
I have attached the ZIP'd V2.4 XMODEM.COM executable ans source code to this message.
?
Peace and blessings.


Re: Source code?

 

Hi Lee:
Thanks for replying. I was looking for the source code for XMODEM. The executable is already provided in the DISK-A.BIN image and it is the "Martin Eberhard" version. There are a few source code files out there called "XMODEM" but Martin's seems to be much easier to configure for different hardware. As for being "unconfigured", it uses its program defaults unless an XMODEM.CFG file is provided.

I'm also looking into KERMIT since KERMIT will take multiple file names for sending and receiving. I managed to get KERMIT running under SCO XENIX a few weeks ago. I can use the Linux version of KERMIT to interface with the XENIX virtual machine and all works well. There is a V4.11 available as source code and HEX overlays for CP/M. The HEATH H8 config overlay seems like it will work with a little modification because it directly supports the 8250 ACE.

Peace and blessings.


Re: Single-stepping without FRONT PANEL

 

Scott,

Yes, I think that should work.? Just follow the schematic portions of the front panel for the timer interrupt.

Please understand that the single step feature works as follows:
-Hijack the Interrupt
-Wait for a timer interrupt to "start the clock"
-Wait for just enough cycles to pass so that when control is returned to the user program, there's only time for 1 instruction before the next interrupt
-Return to the user program (there's only time for 1 instruction to execute)
-On the following interrupt (after execute 1 instruction) display registers, restore normal timer interrupt.


Now, I'm not sure what I'm doing with HW_LIST, sorry, I can't remember this level of detail, but you can look through the source code and see if it's being tested during single step for feature enable/disable.

Cheers,
Josh



On Monday, November 25, 2019, 4:35:38 p.m. CST, scotty264b@... <scotty264b@...> wrote:


Hello All:
I have Z80MC + SIO card. No FP.
If I wish to implement the single-step feature of the ZMC monitor, is it as easy as providing a 1KHz interrupt (derived and thus sync'd with Z80 clock) and changing the "HW_LIST" at memory address 0xFF95 to 0x03 (SIO + FP)?

Can I use single-step in the console mode or must I use the FP?

Thank you.

Peace and blessings.


Re: Source code?

 

Hi Scott,

XModem by Martin Eberhard uses a config file.?
The DISK-A image at Lee's website has recently (Nov 2019) been updated with the correct config file to use SIO address.

SURVEY, I don't know this program.? It was just something found with CP/M so I included it.

MON-32K is an early version of my monitor that I used on my IMSAI, it won't work with the Z80MC, it should just be deleted.
Sorry, I certainly didn't do a very good job at cleaning / testing the CP/M image files.? Little time, many projects, I hope you understand.

Cheers,
Josh



On Monday, November 25, 2019, 4:35:37 p.m. CST, scotty264b@... <scotty264b@...> wrote:


Hello All:
I have the Z80MC w/ SIO (no FP).

I know there are some Z80MC specific programs supplied within the DISK-A.BIN image but I see no source code for them.

I see no files populating the "Files" section of this group, how does one obtain the source code for:
XMODEM modified for Z80MC SIO support
SURVEY
MON-32K (which does not work on my Z80MC)

Peace and blessings.


Re: Single-stepping without FRONT PANEL

 

scotty264b@... wrote:
I have Z80MC + SIO card. No FP.
If I wish to implement the single-step feature of the ZMC monitor, is it
as easy as providing a 1KHz interrupt (derived and thus sync'd with Z80
clock) and changing the "HW_LIST" at memory address 0xFF95 to 0x03 (SIO
+ FP)?

Can I use single-step in the console mode or must I use the FP?
Hi Scotty,

The CP/M DDT.COM debugger can single-step without using interrupts; thus, no front panel or timer is needed. But it requires that the program you are tracing is in RAM (i.e. not the ROM). Also, it can't trace programs in the BIOS, BDOS, or CCP.

Note that we just added DDT-V6.COM to the DISK-1 image; it is patched to change the breakpoint instruction from RST7 to RST6 so it doesn't conflict with hardware interrupts.

The Z80MC monitor uses hardware to single-step, so it can trace even programs in ROM. (That's necessary for debugging the ROM monitor, and CP/M itself.) The hardware to do this is on the Front Panel. Specifically, it needs the timer and its interrupt.

To single-step, the monitor waits for a timer interrupt. It saves the state of the Z80, and then waits "just right" so there is only time to execute *one* instruction before the next timer interrupt. *Then* it lets the Z80 execute that instruction.

The result is that the Z80 executes one instruction, and gets interrupted. The monitor can then save, examine, and change registers, memory, I/O ports, etc.

If you don't have a Front Panel, you can breadboard the timer (74HC4040, 74HC393, and two inverters). It might even be possible to simplify it to just a 74HC4020 and a couple transistors as inverters.

Lee
--
ICEs have the same problem as lightbulbs. Why innovate and make
better ones when the current ones burn out often enough to keep
you in business? -- Hunter Cressall
--
Lee Hart, 814 8th Ave N, Sartell MN 56377, www.sunrise-ev.com


Re: Source code?

 

scotty264b@... wrote:
Okay, I found a version of XMODEM that assembles and works properly.

It seems that the one provided with the SDcard images is V2.2 (7 Oct
2014 @ 8KB), while the one I found is V2.4 (4 August 2016 @ 4KB). I've
assembled it with ASMX (Bruce Tomlin), uploaded it and used it with the
Z80MC XMODEM.CFG supplied by Josh.
Hi Scotty,

Thanks for alerting us. Glad you found it.

The XMODEM on the DISK-A image was the *unconfigured* one. Josh added the configured one, and I put it in the DISK-A image. So it should be there to prevent this problem in the future. (Let me know if it's still not right)

Lee


--
ICEs have the same problem as lightbulbs. Why innovate and make
better ones when the current ones burn out often enough to keep
you in business? -- Hunter Cressall
--
Lee Hart, 814 8th Ave N, Sartell MN 56377, www.sunrise-ev.com


Re: Source code?

 

Okay, I found a version of XMODEM that assembles and works properly.

It seems that the one provided with the SDcard images is V2.2 (7 Oct 2014 @ 8KB), while the one I found is V2.4 (4 August 2016 @ 4KB). I've assembled it with ASMX (Bruce Tomlin), uploaded it and used it with the Z80MC XMODEM.CFG supplied by Josh.

I've attached the source code to this message.

Peace and blessings.


Single-stepping without FRONT PANEL

 

Hello All:
I have Z80MC + SIO card. No FP.
If I wish to implement the single-step feature of the ZMC monitor, is it as easy as providing a 1KHz interrupt (derived and thus sync'd with Z80 clock) and changing the "HW_LIST" at memory address 0xFF95 to 0x03 (SIO + FP)?

Can I use single-step in the console mode or must I use the FP?

Thank you.

Peace and blessings.


Source code?

 

Hello All:
I have the Z80MC w/ SIO (no FP).

I know there are some Z80MC specific programs supplied within the DISK-A.BIN image but I see no source code for them.

I see no files populating the "Files" section of this group, how does one obtain the source code for:
XMODEM modified for Z80MC SIO support
SURVEY
MON-32K (which does not work on my Z80MC)

Peace and blessings.


Re: An idea!

 

I guess binary would have to be 1's and 2's then! LoL...
I have no idea how the hell that would work, but it's funny to try thinking about it.




On Sunday, November 24, 2019, 4:30:13 PM EST, ajparent1/kb1gmx <kb1gmx@...> wrote:


Roman numerals require a larger jump as there is no numeral for 0-zero.

That had to wait for the Arabic mathmatitions to invent.

Think of computing without the concept of zero.

Allison


Re: An idea!

 

Roman numerals require a larger jump as there is no numeral for 0-zero.

That had to wait for the Arabic mathmatitions to invent.

Think of computing without the concept of zero.

Allison


Re: An idea!

 

joshbensadon via Groups.Io wrote:
Here's a weird thought... what would computer programming look like if
we still used Roman Numerals?
We switched from decimal to binary when we started inventing computers. That was necessitated by the hardware. So if the Romans invented computers, I suspect they would have invented binary as well.

But... do computers need numbers at all? There are analog computers that don't quantize values. There are also neural nets, and fuzzy logic, and optical computers that process data in very different ways. There is still debate over exactly how our brains work!

Lee
--
ICEs have the same problem as lightbulbs. Why innovate and make
better ones when the current ones burn out often enough to keep
you in business? -- Hunter Cressall
--
Lee Hart, 814 8th Ave N, Sartell MN 56377, www.sunrise-ev.com


Re: Running and returning

 

Wow, ok, that's a bug I didn't know about..? I'll post that to my v16 to-do list.

Josh.


On Thursday, November 21, 2019, 11:54:01 a.m. CST, Bob Kay via Groups.Io <rekircher@...> wrote:


All good information, and definitely some things to play with, but the problem isn't failure to preserve the registers but unable to modify the registers via the "r" command after returning via VMAIN_MENU.

For instance if I place a JP 0042h (C3 42 00) in location 8000, then issue a "g 8000" command, it comes right back to the monitor. I am now unable to change any registers via the "R" command.? If I type "rhl=0000" then redisplay the registers, HL hasn't changed to 0000.? Similarly for all the other registers.

-Bob


On 11/21/2019 10:09 AM, joshbensadon via Groups.Io wrote:

Bob Kircher wrote in,


"If I were to write a program to run on the Z80MC in high memory (not?
under CPM) what is the preferred way to return to the monitor?? I had?
been using JP 0042H ( JP VMAIN_MENU ) but I recently discovered I can?
not change any registers after I get back to the monitor.? I can also?
return by jumping to location zero but I'd better be quick about hitting?
the M key else I accidentally boot CP/M."


Great question, worth posting to the forum.

I'm not 100% sure what I wrote and debugged but having a quick look at the source code it appears only execution to 0000 will save the registers.

As such, when executing the G command, the monitor places 0000 on stack as the return address.? So your code needs to only RET to get back to the monitor.
LD HL,0 ;10 Set Default return address as 0000 (Restart/Save Registers)
PUSH HL ;11? ?& Put on stack


Now, it should know/resolve the restart type and not prompt you to press M for monitor... but I'm not sure if that works... certainly won't be the only bug in the system.? If you really want, you can fake the M key by entering it into the buffer yourself before returning to 0000.

Here's a snipit of the code that saves the bit banged character to the buffer.??


IRXD_SAVE LD? A,H ;4 ;Fetch received byte
LD? HL,(RXBHEAD) ;16 ;Advance Head Ptr of RX Buffer, Head = Head + 1
INC L ;4
LD? (RXBHEAD),HL ;16
LD? (HL),A ;7 ;Save Received byte into RX Buffer


Actually, instead of faking the M key, you can set the SOFT_RST_FLAG value (I think the firmware might already be doing this.. but I cant' figure out where).

When the firmware boots up, it runs code to check this flag as follows.
If you set this flag to 0xD1 (single step return), it should return to the monitor and automatically dump the registers.
;Determine why the CPU is executing A RESET.
;? -Power on (RAM signature will be wrong)
;? -F-0 Reset Switch (one of the switches will still be pressed)
;? -RST 0 (look for C7 at previous location given by stack)
;? -External /RESET OR User program branches to 0000
;
;RC_TYPE
;0 COLD RESET (NO RAM SIGNATURE)
;1 F-E Soft Reset (SOFT_RST_FLAG = FE)
;2 Single Step (SOFT_RST_FLAG = D1)
;3 <Ctrl>-C (SOFT_RST_FLAG = CC)
;4 HALT (SOFT_RST_FLAG = 76)
;5 F-0 (F or 0 key on FP still down)
;6 RST0 ( M(PC-1) = C7)
;7 HARD RESET (Default if SOFT_RST_FLAG not set)



Hopefully the RET should work fine, but if not, it's definitely one of the things I will be addressing in the next version of firmware.

Regards,
Josh




Re: Running and returning

 

开云体育

All good information, and definitely some things to play with, but the problem isn't failure to preserve the registers but unable to modify the registers via the "r" command after returning via VMAIN_MENU.

For instance if I place a JP 0042h (C3 42 00) in location 8000, then issue a "g 8000" command, it comes right back to the monitor. I am now unable to change any registers via the "R" command.? If I type "rhl=0000" then redisplay the registers, HL hasn't changed to 0000.? Similarly for all the other registers.

-Bob


On 11/21/2019 10:09 AM, joshbensadon via Groups.Io wrote:

Bob Kircher wrote in,


"If I were to write a program to run on the Z80MC in high memory (not?
under CPM) what is the preferred way to return to the monitor?? I had?
been using JP 0042H ( JP VMAIN_MENU ) but I recently discovered I can?
not change any registers after I get back to the monitor.? I can also?
return by jumping to location zero but I'd better be quick about hitting?
the M key else I accidentally boot CP/M."


Great question, worth posting to the forum.

I'm not 100% sure what I wrote and debugged but having a quick look at the source code it appears only execution to 0000 will save the registers.

As such, when executing the G command, the monitor places 0000 on stack as the return address.? So your code needs to only RET to get back to the monitor.
LD HL,0 ;10 Set Default return address as 0000 (Restart/Save Registers)
PUSH HL ;11? ?& Put on stack


Now, it should know/resolve the restart type and not prompt you to press M for monitor... but I'm not sure if that works... certainly won't be the only bug in the system.? If you really want, you can fake the M key by entering it into the buffer yourself before returning to 0000.

Here's a snipit of the code that saves the bit banged character to the buffer.??


IRXD_SAVE LD? A,H ;4 ;Fetch received byte
LD? HL,(RXBHEAD) ;16 ;Advance Head Ptr of RX Buffer, Head = Head + 1
INC L ;4
LD? (RXBHEAD),HL ;16
LD? (HL),A ;7 ;Save Received byte into RX Buffer


Actually, instead of faking the M key, you can set the SOFT_RST_FLAG value (I think the firmware might already be doing this.. but I cant' figure out where).

When the firmware boots up, it runs code to check this flag as follows.
If you set this flag to 0xD1 (single step return), it should return to the monitor and automatically dump the registers.
;Determine why the CPU is executing A RESET.
;? -Power on (RAM signature will be wrong)
;? -F-0 Reset Switch (one of the switches will still be pressed)
;? -RST 0 (look for C7 at previous location given by stack)
;? -External /RESET OR User program branches to 0000
;
;RC_TYPE
;0 COLD RESET (NO RAM SIGNATURE)
;1 F-E Soft Reset (SOFT_RST_FLAG = FE)
;2 Single Step (SOFT_RST_FLAG = D1)
;3 <Ctrl>-C (SOFT_RST_FLAG = CC)
;4 HALT (SOFT_RST_FLAG = 76)
;5 F-0 (F or 0 key on FP still down)
;6 RST0 ( M(PC-1) = C7)
;7 HARD RESET (Default if SOFT_RST_FLAG not set)



Hopefully the RET should work fine, but if not, it's definitely one of the things I will be addressing in the next version of firmware.

Regards,
Josh




Re: An idea!

 

Hi Rich,

Yeah, I think it was even less than 2 years.? I believe I saw ads for IMSAI as early as Feb 1976 (13 months after ALTAIR's announcement Jan 1975).

On the topic of Octal vs HEX.? I might make some enemies here, but I believe HEX is better.
The original owner of my Altair put (zippo) tape over every other 4 switches (HEX visual cues).

While the 8080 instruction set is geared towards Octal, I will dare to say it's easier to enter a program in HEX.
Because in HEX, you only need to remember 2 characters.? I am guessing someone with a good memory (not me) could probably read and retain 8 bytes of data then enter them into the computer, while the same person might only be able to do 4 bytes of Octal.
The only con about HEX are the letter codes... but with a little practice, those become 2nd nature.

Besides, I've never been a fan of 377 377, I mean, how can 377 377 be the same as 177777 ?
I think most will agree HEX just fits in nicer.? Now if only we can change the alphabet..? 26 is such an odd number!

Here's a weird thought... what would computer programming look like if we still used Roman Numerals?

X? Print "Hello"
XX Goto X

LoL



Re: Running and returning

 

Bob Kircher wrote in,


"If I were to write a program to run on the Z80MC in high memory (not?
under CPM) what is the preferred way to return to the monitor?? I had?
been using JP 0042H ( JP VMAIN_MENU ) but I recently discovered I can?
not change any registers after I get back to the monitor.? I can also?
return by jumping to location zero but I'd better be quick about hitting?
the M key else I accidentally boot CP/M."


Great question, worth posting to the forum.

I'm not 100% sure what I wrote and debugged but having a quick look at the source code it appears only execution to 0000 will save the registers.

As such, when executing the G command, the monitor places 0000 on stack as the return address.? So your code needs to only RET to get back to the monitor.

LD HL,0 ;10 Set Default return address as 0000 (Restart/Save Registers)
PUSH HL ;11? ?& Put on stack


Now, it should know/resolve the restart type and not prompt you to press M for monitor... but I'm not sure if that works... certainly won't be the only bug in the system.? If you really want, you can fake the M key by entering it into the buffer yourself before returning to 0000.

Here's a snipit of the code that saves the bit banged character to the buffer.??


IRXD_SAVE LD? A,H ;4 ;Fetch received byte
LD? HL,(RXBHEAD) ;16 ;Advance Head Ptr of RX Buffer, Head = Head + 1
INC L ;4
LD? (RXBHEAD),HL ;16
LD? (HL),A ;7 ;Save Received byte into RX Buffer


Actually, instead of faking the M key, you can set the SOFT_RST_FLAG value (I think the firmware might already be doing this.. but I cant' figure out where).

When the firmware boots up, it runs code to check this flag as follows.
If you set this flag to 0xD1 (single step return), it should return to the monitor and automatically dump the registers.

;Determine why the CPU is executing A RESET.
;? -Power on (RAM signature will be wrong)
;? -F-0 Reset Switch (one of the switches will still be pressed)
;? -RST 0 (look for C7 at previous location given by stack)
;? -External /RESET OR User program branches to 0000
;
;RC_TYPE
;0 COLD RESET (NO RAM SIGNATURE)
;1 F-E Soft Reset (SOFT_RST_FLAG = FE)
;2 Single Step (SOFT_RST_FLAG = D1)
;3 <Ctrl>-C (SOFT_RST_FLAG = CC)
;4 HALT (SOFT_RST_FLAG = 76)
;5 F-0 (F or 0 key on FP still down)
;6 RST0 ( M(PC-1) = C7)
;7 HARD RESET (Default if SOFT_RST_FLAG not set)



Hopefully the RET should work fine, but if not, it's definitely one of the things I will be addressing in the next version of firmware.

Regards,
Josh



Re: An idea!

 

开云体育

Just compare the Altair to the IMSAI front panels. They are separated by 2-3 years and the grouping changed from an octal grouping to a hex grouping.

I’ve seen a few Altairs in which the user put colored toggle caps (remember those from Radio Shack?) on the switches to improve the toggling speed through visual cues. That’s why I think the IMSAI front panel is a stroke of genius — the visual cues and grouping made toggling easier (IMHO).


Get
?


From: [email protected] on behalf of joshbensadon via Groups.Io <joshbensadon@...>
Sent: Thursday, November 21, 2019 9:26 AM
To: [email protected]; [email protected]
Subject: Re: [Z8MC] An idea!
?
I should note... the original idea of using colours for HEX / Octal wasn't mine, I got it from the IMSAI 8080, the switches could be re-arranged for HEX or Octal.? I'm not sure if that was an original idea in 1976 either, it really never ceases to amaze me of how many ideas for modern computers came from the 50's and 60's.??

Paul,

I should have mentioned that the Altaid is capable of running CP/M.? It does not have the flexibility that is available with the Z80MC, but the firmware expects 512K of RAM.? NO SD card, just a big RAM disk.? The first 64K of RAM is for system and the remaining 448K is used as a RAM Disk.? You may Xmodem load/save this RAM Disk image.? It comes with 2 programs preloaded, PIP and XM (Xmodem to transfer individual files to/from the disk).
XM is a simplified small version of Martin Eberhard's XModem.?



Josh




On Wednesday, November 20, 2019, 2:44:18 p.m. CST, Paul Bigwood <paul@...> wrote:


Lee,
?
I was very interested in the G Barrow 8080 S100 board octal display and keypad. A Google search turned up the user manual with cct and rom code.

I first learnt octal coding when i worked at DEC as a field service engineer in the uk in the '80s, and had forgotten how opcodes could be decoded and encoded easier using octal compared to hex.?

Octal was very popular when the 8080 first came out.?

I wondered if it is possible to space the address bus and data bus LEDs in octal spacing rather than binary/hex making it easier to enter and read the LEDS in octal. e.g. Data LEDs and switches are spaced?
Like this? XX XXX XXX? rather than XXXXXXXX. Same applies for Address bus. Vis
Address bus XX XXX XXX XX XXX XXX rather than the XXXXXXXXXXXXXXXX.

Is it planned to add a SD card for cp/m??

Best regards

Paul G3WYW?







As i understand the existing code,? the bus input switches toggle the associated?

R
?



Sent from Samsung tablet.


Re: An idea!

 

I should note... the original idea of using colours for HEX / Octal wasn't mine, I got it from the IMSAI 8080, the switches could be re-arranged for HEX or Octal.? I'm not sure if that was an original idea in 1976 either, it really never ceases to amaze me of how many ideas for modern computers came from the 50's and 60's.??

Paul,

I should have mentioned that the Altaid is capable of running CP/M.? It does not have the flexibility that is available with the Z80MC, but the firmware expects 512K of RAM.? NO SD card, just a big RAM disk.? The first 64K of RAM is for system and the remaining 448K is used as a RAM Disk.? You may Xmodem load/save this RAM Disk image.? It comes with 2 programs preloaded, PIP and XM (Xmodem to transfer individual files to/from the disk).
XM is a simplified small version of Martin Eberhard's XModem.?



Josh




On Wednesday, November 20, 2019, 2:44:18 p.m. CST, Paul Bigwood <paul@...> wrote:


Lee,
?
I was very interested in the G Barrow 8080 S100 board octal display and keypad. A Google search turned up the user manual with cct and rom code.

I first learnt octal coding when i worked at DEC as a field service engineer in the uk in the '80s, and had forgotten how opcodes could be decoded and encoded easier using octal compared to hex.?

Octal was very popular when the 8080 first came out.?

I wondered if it is possible to space the address bus and data bus LEDs in octal spacing rather than binary/hex making it easier to enter and read the LEDS in octal. e.g. Data LEDs and switches are spaced?
Like this? XX XXX XXX? rather than XXXXXXXX. Same applies for Address bus. Vis
Address bus XX XXX XXX XX XXX XXX rather than the XXXXXXXXXXXXXXXX.

Is it planned to add a SD card for cp/m??

Best regards

Paul G3WYW?







As i understand the existing code,? the bus input switches toggle the associated?

R
?



Sent from Samsung tablet.


Re: An idea!

 

Paul Bigwood wrote:
It would be good if the ROM monitor could .support both Hex and Octal,
but understand the issues.
It's one of those "someday..." things. My Heathkit H8 and H89 computers both support both octal and hex displays. The H8 uses two different ROMs (2K each). The H89 has a bigger ROM (4K) that has a "radix" command to select octal or hex.

I was thinking of a SD card for program storage under cp/m, but now
realise your design objective for this computer to be truly retro, so
'cassette' storage is required.
It's not required, but it's there for that "vintage feel".

However, the Altaid's RAM has battery back-up. You initially load it via the serial port (from a PC etc.) Once it's loaded, the battery maintains data even with the power off.

Looking forward to the kit being available soon.
So are we! :-)

Lee

--
ICEs have the same problem as lightbulbs. Why innovate and make
better ones when the current ones burn out often enough to keep
you in business? -- Hunter Cressall
--
Lee Hart, 814 8th Ave N, Sartell MN 56377, www.sunrise-ev.com