Coleco Adam EOS binary?
Coleco Adam EOS binary?
Has anyone tried to use z88dk to create EOS programs for the Coleco Adam? I need to write some client side firmware for the FujiNet port we are doing for the Adam.
-Thom
-Thom
Re: Coleco Adam EOS binary?
The Adam is a subtype of the +cpm target so there's no EOS support.
I'm taking things easy at the moment, so I'm not planning to work on it from scratch, but I'll happily take code donations and fix things up.
I'm taking things easy at the moment, so I'm not planning to work on it from scratch, but I'll happily take code donations and fix things up.
Re: Coleco Adam EOS binary?
Well, from what I see, it would be very close to the Colecovision target.
The DDP format is basically 256 1K blocks written sequentially, with no headers.
When EOS starts up, it loads block 0 into $C800 and immediately jumps to it. The boot loader then does more EOS calls to bring the program into memory (e.g. at location $8000)
Is there an outline of what I would need to do to make a new "adam" or "coleco" subtype "eos" ?
-Thom
The DDP format is basically 256 1K blocks written sequentially, with no headers.
When EOS starts up, it loads block 0 into $C800 and immediately jumps to it. The boot loader then does more EOS calls to bring the program into memory (e.g. at location $8000)
Is there an outline of what I would need to do to make a new "adam" or "coleco" subtype "eos" ?
-Thom
Re: Coleco Adam EOS binary?
So my findings, I was able to produce a bootable tape, by doing the following:
1. Hello world app, built with +coleco and makeapp, chopped off the empty part of the ROM. Padded to 4096 bytes.
2. wrote a naive EOS boot loader to load the binary into 8000H, assembled with z88dk-z80asm -b, padded out to 1024 bytes:
3. used dd to make a fill file to fill out the rest of the 256 blocks
4. cat boot.bin hello fill >hello.ddp
5. booted the result on my hardware
demo vid:
https://youtu.be/2l1du-Xr1Qk
It's worth noting that I am setting the MIOC (port 7F) to memory map option 3, which makes it similar to a ColecoVision, but with 32K of RAM at $8000. This was done to make it easy to get started.
Have read the configuration file documentation, but would love some thoughts on how to proceed.
-Thom
1. Hello world app, built with +coleco and makeapp, chopped off the empty part of the ROM. Padded to 4096 bytes.
2. wrote a naive EOS boot loader to load the binary into 8000H, assembled with z88dk-z80asm -b, padded out to 1024 bytes:
Code: Select all
; boot loader
; EOSDEF -- Library of essential routines for EOS
EosStart EQU 0fc30h ;EOSStart: reset EOS
ConsDisp EQU 0fc33h ;ConsoleDisplay: A=character to display (raw output)
ConsInit EQU 0fc36h ;ConsoleInitialize: D=top E=left B=width C=height HL=start
ConsOut EQU 0fc39h ;ConsOut: A=character to display, with escape characters
ReadKeyboard EQU 0fc6ch ;ReadKeyboard: Returns A=key
GotoWP EQU 0fce7h ;GotoWP: Starts SmartWRITER
PutAscii EQU 0fd17h ;PutASCII: Fills out characters 0x20 to 0x7e
WriteReg EQU 0fd20h ;WriteVDPRegister: B=reg, C=value
FillVRam EQU 0fd26h ;FillVRam: HL=start, A=character, DE=length
WriteVRam EQU 0fd1ah ;WriteVRam: HL=ram address, BC=length, DE=vram address
ReadVRam EQU 0fd1dh ;ReadVRam: HL=ram address, BC=length, DE=vram address
InitTable EQU 0fd29h ;InitializeVDPTable: A=table #, HL=location
LoadAscii EQU 0fd38h ;LoadASCII: HL=first character, BC=count of characters, DE=vram destination
Read1Block EQU 0fcf3h ;Actually ReadBlock Input: A=device, HL=memory, BCDE=block
Write1Block EQU 0fcf6h ;Actually WriteBlock Output: A=device, HL=memory, BCDE=block
CurrentDev EQU 0fd6fh ;Current device ID
DiskA EQU 04h
DiskB EQU 05h
TapeA EQU 08h
TapeB EQU 18h
DefPatternTable EQU 0h
DefNameTable EQU 1800h
DefSprAttrTable EQU 1b00h
DefColorTable EQU 2000h
DefSprPatTable EQU 3800h
ORG $C800
Boot:
LD A,B
LD (CurrentDev),A
CALL Text
LD HL,MsgBlock0
LD DE,32*4+16-(14/2)+DefNameTable
LD BC,14
CALL WriteVRam
LD A,(CurrentDev)
LD BC,0
LD DE,1
LD HL,8000H
CALL Read1Block
LD HL,MsgBlock1
LD DE,32*4+16-(14/2)+DefNameTable
LD BC,14
CALL WriteVRam
LD A,(CurrentDev)
LD BC,0
LD DE,2
LD HL,8400H
CALL Read1Block
LD HL,MsgBlock2
LD DE,32*4+16-(14/2)+DefNameTable
LD BC,14
CALL WriteVRam
LD A,(CurrentDev)
LD BC,0
LD DE,3
LD HL,8800H
CALL Read1Block
LD HL,MsgBlock3
LD DE,32*4+16-(14/2)+DefNameTable
LD BC,14
CALL WriteVRam
LD A,(CurrentDev)
LD BC,0
LD DE,4
LD HL,8C00H
CALL Read1Block
LD HL,MsgBlock4
LD DE,32*4+16-(14/2)+DefNameTable
LD BC,14
CALL WriteVRam
LD A,3
OUT (7fh),A
LD A,(CurrentDev)
LD B,A
RST 0
Text:
InitVDP:
LD BC,0000h ;Graphic mode 1
CALL WriteReg
LD BC,01e0h ;Graphic mode 1
CALL WriteReg
LD BC,705h ;Clear background color
CALL WriteReg
LD A,0 ;Table of sprite attributes
LD HL,1b00h
CALL InitTable
LD A,1 ;Table of sprite patterns
LD HL,3800h
CALL InitTable
LD A,2 ;Name table
LD HL,1800h
CALL InitTable
LD A,3 ;Pattern table
LD HL,0
CALL InitTable
LD A,4 ;Color table
LD HL,2000h
CALL InitTable
CALL LoadAscii
LD HL,2000h ;Color table
LD A,0f0h ;White on black -- or green
LD DE,10h ;first half of table
CALL FillVRam
LD HL,2010h ;Color table
LD A,07fh ;Black on White -- or red
LD DE,10h ;first half of table
CALL FillVRam
LD BC,1f17h ;31x23
LD DE,0 ;Upper left corner
LD HL,3800h ;Name table
CALL ConsInit
RET
MsgBlock0:
DB "BLOCK 0 Loaded"
MsgBlock1:
DB "BLOCK 1 Loaded"
MsgBlock2:
DB "BLOCK 2 Loaded"
MsgBlock3:
DB "BLOCK 3 Loaded"
MsgBlock4:
DB "BLOCK 4 Loaded"
4. cat boot.bin hello fill >hello.ddp
5. booted the result on my hardware
demo vid:
https://youtu.be/2l1du-Xr1Qk
It's worth noting that I am setting the MIOC (port 7F) to memory map option 3, which makes it similar to a ColecoVision, but with 32K of RAM at $8000. This was done to make it easy to get started.
Have read the configuration file documentation, but would love some thoughts on how to proceed.
-Thom
Re: Coleco Adam EOS binary?
That's brilliant - after inserting the DDP it just auto boots? The missing bits are:
1. Config file
2. Autogenerating the bootstrap
3. Some appmake magic
Bonus missing bit:
4. EOS library for console in/out
So config file:
SUBTYPE adam -Cz+adam -startup=2
Generating the bootstrap:
We're passing through -startup=2 to indicate that we want an Adam header, so if you take a look at (for example) lib/target/pc88/classic you can see there's a split based on startup value to either allram or monitor mode. For the Adam, there's probably not much point defined CRT_ORG_BSS since everything is RAM? So another little divergence there.
Within allram.asm there's an include of the bootstrap.asm which by analogy is the code you pasted in. For the pc88 we load the size of the binary rounded up to 256 bytes (the references to __DATA_END_tail)
Appmake:
Take a look at the pc88disc.c file - that shows the way to load the bootstrap and the actual binary. You'll need to add a bit to appmake.h to add the converter into the list but that side of things is relatively trivial. I'm surprised there's no checksum since I think DDP is a tape?
1. Config file
2. Autogenerating the bootstrap
3. Some appmake magic
Bonus missing bit:
4. EOS library for console in/out
So config file:
SUBTYPE adam -Cz+adam -startup=2
Generating the bootstrap:
We're passing through -startup=2 to indicate that we want an Adam header, so if you take a look at (for example) lib/target/pc88/classic you can see there's a split based on startup value to either allram or monitor mode. For the Adam, there's probably not much point defined CRT_ORG_BSS since everything is RAM? So another little divergence there.
Within allram.asm there's an include of the bootstrap.asm which by analogy is the code you pasted in. For the pc88 we load the size of the binary rounded up to 256 bytes (the references to __DATA_END_tail)
Appmake:
Take a look at the pc88disc.c file - that shows the way to load the bootstrap and the actual binary. You'll need to add a bit to appmake.h to add the converter into the list but that side of things is relatively trivial. I'm surprised there's no checksum since I think DDP is a tape?
Re: Coleco Adam EOS binary?
Putting this here for reference, EOS provides a set of console routines to set up a tty like window, and write to it:
-16-
CONSOLE OUTPUT
INITIALIZE CONSOLE
JUMP TABLE ADDRESS: FC36
ENTRY: B number of columns (0 to 31)
C number of lines (0 to 23)
D home column
E home row
HL pointer to pattern name table
EXIT: all registers lost
DESCRIPTION:
This routine is used to set up a WINDOW for screen display. Registers B and C contain the, number of rows and columns while registers D and E contain the upper left corner of the window. The other parameter required is base address of the Pattern Name Table. If you have previously set up VDP, you should have NOTED what that address was. If you; are using a routine in conjunction with SmartBasic, the default pattern name table address is 1800H.
The routine stores lines and columns, sets up minimum and maximum values for ROW and COLUMN based on the supplied parameters. You can set up many windows and jump around between them by repeating calls to this routine. When this routine exits, the default cursor (an underline) is placed in the top left corner of the window. You can then send a move_cursor command (see console display page 18) to place it at the appropriate location in the window.
EXAMPLES:
This routine sets up a 12 line window in the centre of the screen:
-17-
CONSOLE OUTPUT.
CONSOLE DISPLAY REGULAR
JUMP TABLE ADDRESS: FC33
ENTRY: A character to send
EXIT: all registers preserved including A
DESCRIPTION:
This routine prints whatever character is in the accumulator to the screen. It presumes that the VDP has been set up and that a window has been defined. It will print ALL characters including the graphic representation of the control codes (0-31). If you wish to send a control CODE, use the routine on the next page.
The routine first sends the character to video RAM. Then it advances the cursor position, going to the next line if required. If the cursor is on the last line, the screen is scrolled.
EXAMPLES:
This subroutine is used to print an incoming message in register HL. It presumes that the string to print is followed by a null (ASCII 00).
-18-
CONSOLE OUTPUT
CONSOLE DISPLAY SPECIAL
JUMP TABLE ADDRESS: FC39
ENTRY: A character to print or PLACE CURSOR request
D column to go to if PLACE CURSOR
E row ,to go t9 if PLACE CURSOR
EXIT: all registers preserved including A
DESCRIPTION:
This routine, like console display on previous page will print a character on the defined window. It begins however by checking for 12 special control codes. If it finds one of these, it executes the following control functions:
CONTROL KEYBOARD FUNCTION
CRARACTER EQUIVALENT PERFORMED
08 BACKSPACE move cursor left one
0A ^J move cursor down one line (line feed)
0C ^L clear screen and home cursor
0D RETURN return cursor to start of line
(must send line feed if new line wanted)
16 ^V delete to end of line
18 ^X delete to end of screen
1C ^\ place cursor at position DE
80 HOME home the cursor (no clear)
A0 up arrow move up
Al right arrow move right
A2 down arrow move down
A3 left arrow move left
Note that there is no CURSOR ON or CURSOR OFF. In EOS-5, you can replace 3 bytes starting at F658 with. ZEROS to turn the cursor off. Be sure to remember the values in order to turn it back on again.
EXAMPLES:
When the string STRING is printed, it will send the cursor home, skip 2 lines, print HELLO, and clear the rest of the screen. Note that the first two lines would not be erased by this operation:
Also attaching the EOS programming manual.
-16-
CONSOLE OUTPUT
INITIALIZE CONSOLE
JUMP TABLE ADDRESS: FC36
ENTRY: B number of columns (0 to 31)
C number of lines (0 to 23)
D home column
E home row
HL pointer to pattern name table
EXIT: all registers lost
DESCRIPTION:
This routine is used to set up a WINDOW for screen display. Registers B and C contain the, number of rows and columns while registers D and E contain the upper left corner of the window. The other parameter required is base address of the Pattern Name Table. If you have previously set up VDP, you should have NOTED what that address was. If you; are using a routine in conjunction with SmartBasic, the default pattern name table address is 1800H.
The routine stores lines and columns, sets up minimum and maximum values for ROW and COLUMN based on the supplied parameters. You can set up many windows and jump around between them by repeating calls to this routine. When this routine exits, the default cursor (an underline) is placed in the top left corner of the window. You can then send a move_cursor command (see console display page 18) to place it at the appropriate location in the window.
EXAMPLES:
This routine sets up a 12 line window in the centre of the screen:
Code: Select all
LD B,20 ;20 columns.
LD C,12 ;12 rows.
LD D,6 ;home column.
LD E,6 ;home row.
LD HL, 1800H ;or whatever your pattern address is.
CALL FC36 ;set up the screen.
CONSOLE OUTPUT.
CONSOLE DISPLAY REGULAR
JUMP TABLE ADDRESS: FC33
ENTRY: A character to send
EXIT: all registers preserved including A
DESCRIPTION:
This routine prints whatever character is in the accumulator to the screen. It presumes that the VDP has been set up and that a window has been defined. It will print ALL characters including the graphic representation of the control codes (0-31). If you wish to send a control CODE, use the routine on the next page.
The routine first sends the character to video RAM. Then it advances the cursor position, going to the next line if required. If the cursor is on the last line, the screen is scrolled.
EXAMPLES:
This subroutine is used to print an incoming message in register HL. It presumes that the string to print is followed by a null (ASCII 00).
Code: Select all
PRTSTR:
LD A, (HL)
OR A
RET Z ;the string was over.
CALL FC33 ;print the thing.
INC HL ;remember HL was preserved.
JR PRTSTR ;loop until end of string.
CONSOLE OUTPUT
CONSOLE DISPLAY SPECIAL
JUMP TABLE ADDRESS: FC39
ENTRY: A character to print or PLACE CURSOR request
D column to go to if PLACE CURSOR
E row ,to go t9 if PLACE CURSOR
EXIT: all registers preserved including A
DESCRIPTION:
This routine, like console display on previous page will print a character on the defined window. It begins however by checking for 12 special control codes. If it finds one of these, it executes the following control functions:
CONTROL KEYBOARD FUNCTION
CRARACTER EQUIVALENT PERFORMED
08 BACKSPACE move cursor left one
0A ^J move cursor down one line (line feed)
0C ^L clear screen and home cursor
0D RETURN return cursor to start of line
(must send line feed if new line wanted)
16 ^V delete to end of line
18 ^X delete to end of screen
1C ^\ place cursor at position DE
80 HOME home the cursor (no clear)
A0 up arrow move up
Al right arrow move right
A2 down arrow move down
A3 left arrow move left
Note that there is no CURSOR ON or CURSOR OFF. In EOS-5, you can replace 3 bytes starting at F658 with. ZEROS to turn the cursor off. Be sure to remember the values in order to turn it back on again.
EXAMPLES:
When the string STRING is printed, it will send the cursor home, skip 2 lines, print HELLO, and clear the rest of the screen. Note that the first two lines would not be erased by this operation:
Code: Select all
LD HL,STRING
REPEAT:
LD A, (HL)
OR A
JR Z,CONT
CALL FC39
INC HL
JR REPEAT
STRING: DB 80H,A2H,A2H, 'HELLO' ,18H,0
CONT:
;Program continues here
You do not have the required permissions to view the files attached to this post.
Re: Coleco Adam EOS binary?
Thanks for the examples and headstart, you made it very easy to bring it all together.
This evening I've committed support for -subtype=adam under the +coleco target.
Generated programs can make use of the full 64k RAM of the machine. The only EOS function that's supported by z88dk at the moment is reading the keyboard, apart from that it's just like a regular VDP based machine from the z88dk perspective.
This evening I've committed support for -subtype=adam under the +coleco target.
Generated programs can make use of the full 64k RAM of the machine. The only EOS function that's supported by z88dk at the moment is reading the keyboard, apart from that it's just like a regular VDP based machine from the z88dk perspective.
Re: Coleco Adam EOS binary?
Thank you so much. I'm starting to put together test code.
-Thom
-Thom
Re: Coleco Adam EOS binary?
Ok, first bit of test code:
compiled with:
gives the following output:
Gonna investigate, am guessing the the vdp tables aren't initialized.
-Thom
Code: Select all
#include <stdio.h>
void main(void)
{
printf("Hello World\n");
}
Code: Select all
zcc +coleco -subtype=adam -create-app test.c
-Thom
You do not have the required permissions to view the files attached to this post.
Re: Coleco Adam EOS binary?
I think that's a missing font. Add -pragma-redirect:CRT_FONT=_font_8x8_zx_system for example to the command line.
Re: Coleco Adam EOS binary?
Yup, that was it. I need to figure out how to mix together the default system font and add some custom characters.
You do not have the required permissions to view the files attached to this post.
Re: Coleco Adam EOS binary?
Given that we've switched to allram mode, the easiest thing to do is to extract the font from ROM and add it into your program.
See: https://github.com/z88dk/z88dk/wiki/Cla ... ustom-font for details
See: https://github.com/z88dk/z88dk/wiki/Cla ... ustom-font for details
Re: Coleco Adam EOS binary?
A test program that draws a Smartkeys UI (am working on a proportional font output for the rest of the display)
-Thom
https://github.com/tschak909/adam-smartkeys-test
-Thom
https://github.com/tschak909/adam-smartkeys-test
You do not have the required permissions to view the files attached to this post.
Re: Coleco Adam EOS binary?
and a bit more sculpting.. done with test programs for the day.
You do not have the required permissions to view the files attached to this post.
Re: Coleco Adam EOS binary?
Have written a test program that tests input, and things get a little weird, typed characters are garbled (possible font mismatch?)
Code is here: https://github.com/tschak909/adam-qcopy ... ain/main.c
Code is here: https://github.com/tschak909/adam-qcopy ... ain/main.c
You do not have the required permissions to view the files attached to this post.
Re: Coleco Adam EOS binary?
I just can’t read docs properly. I checked for nz not z as a return condition from EOS and my test program just cared that a key was pressed not the value of the key.
It looks like an easy fix so I’ll test and push something later this evening.
Sorry about that.
It looks like an easy fix so I’ll test and push something later this evening.
Sorry about that.