-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rc2014 - subtype for NASCOM Basic (RAM) - enhancement request #256
Comments
For the input side of the basic driver, does the rom's getchar routine handle line editing and character echo while editing? So when you call the rom getchar, the line editing has been performed, person has pressed enter and then getchar will read from the edit buffer one char at a time until the buffer is empty? This is also the assumption with your original acia drivers where the terminal software on the pi (or pc) allows local editing of a line before sending it. Something that could be added later as an option is, if it is possible to do raw character io, ie the input sends a character immediately without editing and local echo, then z88dk can do the line editing too. An advantage of this is the z88dk drivers can be configured to manage windows on screen and do things like password mode for input. Is it possible to gather a command line from basic? Are there any special steps that have to be taken when returning to basic? Registers that have to be preserved, eg. Does the basic rom reserve any registers in its interrupt routines? Is it ok if z88dk is using the index registers and the exx set? |
The NASCOM Basic assembly interface is very simple, and consists of nothing more than an ability to jump "out" of Basic into a user's assembly language routine. A function On initialisation the Parameters can be passed into and out of the users assembly language routine, by using the provided functions. The This information above and below can be found in the NASCOM Basic Manual on Page 5,21. Note that the actual location of
NASCOM Basic provides no additional support to the user's assembly function. On return from the The NASCOM Basic character Once the user has left Basic for the dark side of assembler, they are pretty much on their own. Any line editing functions from Basic are unavailable to the assembly (or C) function. The only justification for using the existing NASCOM Basic character functions is that they are locked into the ROM via the For z88dk, all of the STDIO would need to be brought along, if interactive line editing or screen management was required. |
Everything is pretty much ready to go, I'm just trying to figure out how to balance the subtype=.. and startup values. There are two startups now, startup=0 uses acia drivers and startup=16 uses the basic drivers. I think I may add another one that uses none - it will make sense if display hw starts showing up and people would rather display directly instead of pay for stdio. All of these crts can have their driver instantiations user-supplied at compile time but these things are about convenience. IF the origin of the compile is address 0 then the rc2014_page_zero code is used. This places the acia isr at 0x38 by default but this can be changed at compile time using the right pragma. This means if you compile using, say, startup=0 which uses the acia drivers and your org is not 0, you will still be using the acia anyway assuming you've got the acia isr running somehow. Independently of the crts, you can have a rom, compressed rom or ram compile. For the basic drivers, a rom compile can still make sense if someone keeps basic in the lower 8k and then has something that pages in other roms in some portion of the top 56k. So you could compile a rom program for that 56k that uses the basic acia driver in the bottom 8k. So subtype=rom, rom_zx7, ram, basic are not sufficient to specify a compile. I think we're left with specifying a startup number to choose the right crt (acia, basic or none) and then a subtype=rom, rom_zx7 (you really don't like romc ? :P ), ram to choose the type of build. I think I will do this tonight and this can be revisited if a better idea comes up. |
It seems sensible to leave all of the options open, by having the matrix of I just wrote myself a couple of clarification paragraphs,... and then erased them. I think I now see why it is worth reflecting for a few hours on the right way to define these I believe, the only difference between The hardware differences created by different serial I/O, or other hardware interfaces, can be signalled by Having an issue with #266, sorry I couldn't test what's already committed. |
I've been having a look at the current status, and (if I read it correctly) the |
Yes a startup case in rc2014_crt.asm.m4 has to be set and a default configuration has to be set in crt_config.inc. For basic it should be a ram model compile and I'm not sure yet if the stack should be part of the output binary and what the default org should be. I'm looking at the possibility of doing something like "-subtype=acia,rom" and "-subtype=basic,ram" with defaults if either is missing. Right now multiple subtypes will work so this would be a shortcut. |
Things are committed now. There are only three subtypes: In all compiles
BASIC COMPILE
These options choose a ram model compile (a single monolithic binary is produced) with org 0x9000, stack pointer at the top of ram and a heap created between the end of the program and the bottom of the stack. If "CRT_ABPASS" is defined, it is taken as the address of the ABPASS routine to call to return C's return value to basic. On exit, im1 will be set and interrupts enabled (someone may want to use im2 mode). For command line, I haven't done that yet but I am wondering if it's possible to pass the address of a basic string so that the crt could parse that into argv and argc. I didn't spot a VARPTR command or similar that would give the address of a basic string? Any of the default options can be changed with a pragma. For example, since the location of the c program is defined by the user's answer to memory? at startup, you can compile for any address by changing the value of "CRT_ORG_CODE". You can collect pragmas in a file, eg like this: "zpragma.inc"
Then add "-pragma-include:zpragma.inc" to the compile line. ACIA COMPILE The default is ORG 0, ram org 32768 (data section then bss), compressed rom compile, stack at the top of ram, heap between the end of bss and the bottom of the stack. With org=0, the rc2014 page zero code will be brought in which installs the acia isr at 0x38 by default. Again, like above, anything can be changed via pragmas. Eg, if you have an all-ram 64k bank, you can change to a ram model compile by setting CRT_MODEL=0 (and CRT_ORG_DATA=0, CRT_ORG_BSS=0 to make a monolithic binary). This will save some memory compared to rom model compiles. If you move org away from 0 (CRT_ORG_CODE), the page zero code will not be included. The acia drivers will assume that the acia isr is running. Description of the pragmas. |
Self explanatory. 😄 SBC - Grant Searle
ACIA - feilipu
z88dk
Cold or Warm start, or HexLoadr (C|W|H) ? C
Memory top? 36863
Z80 BASIC Ver 4.7b
Copyright (C) 1978 by Microsoft
3233 Bytes free
Ok
SBC - Grant Searle
ACIA - feilipu
z88dk
Cold or Warm start, or HexLoadr (C|W|H) ?
HexLoadr:
****************#
****************#
****************#
.
... a lot of lines...
.
****************#
****************#
***********#
Done
Ok
doke &h8224, &h9000
Ok
print usr(0)
Eliza
Creative Computing
Morristown, New Jersey
Converted to C by Payton Byrd
Hi! I'm Eliza.
What's your problem?
?
I see.
?
I'm not sure I understand you fully.
?
Come, come ... elucidate your thoughts.
?
|
I'm not sure how NASCOM Basic defines strings. I will have to do homework on that. I'll spend some time playing around with the If the target customer is one of the 600+ rc2014 owners (less those 20 or so active on the forum that have built their own hardware and own their own EEPROM programmers) then there are really only 2 hardware configurations of interest.
|
Nice first time. I assume the typed text is echoed at the terminal? |
I'm completely new to the land of C and recently built an RC2014. I've since written a snake game for the RC2014 using a library that exposes the NASCOM Basic This has come along and blown my mind because the basic subtype is what I was working towards - excellent work! I have a few quick questions about what this target exposes and how. I presume now I can use You can see what I exposed and how in this repo: https://github.com/blaknite/rc2014-uart Thanks for your hard work and I look forward to your response! |
Well, no. Which is odd. It didn't occur to me with eliza, because she gives random answers, no matter what you type. But I also tried clisp and when it didn't show my characters, I assumed it was user (my) failure. The I'll do some testing with a simple character echo program, and update this comment. |
The Grant Searle NASCOM Basic provides the fullness of the Rx buffer, using CKINCHAR LD A,(serBufUsed)
CP $0
RET Spend some time on the z88dk.org wiki site, there's mountains info on stdio there. Note the RC2014 Target is only connected to the Although there are how-to guides on the z88dk wiki, I wrote a simple recipe so that I can quickly find the incantations to rebuild both sdcc and z88dk from scratch. When I trash something it is easiest to just rebuild from scratch. |
Excellent, thanks @feilipu. Everything in stdio looks to be what I'm after, I'm just unsure if they are blocking or not. Just to clarify, I will still have to expose |
At the moment |
No worries, that gives me a good idea of where it's at.
Will do. Does all this get included in the nightly build? I will probably give it a test run tonight and see what's what. |
Spencer has responded that there are about 180 64kByte RAM boards, and about 50 56kB RAM ROMs sold / delivered. Most of the 64kB RAM boards went to people who purchased CPM flash cards too. This means the rough statistics are:
IMHO, there's no compelling reason to do more than you've already done with |
@blaknite the best way (IMHO) to use z88dk is to build it yourself, off a git clone of the main repository. I've been tracking it for about 8 months now, and have never seen it left in a broken state. |
Everything in stdio will work and so will lower level operations on file descriptors. Keep in mind file io is not complete and you can't do things like open and close files except for memory stream files. Right now the drivers are blocking and use However, newlib has another cross-platform input interface to read input devices like keys, joysticks and mice directly in a non-blocking manner called the input library. If what you have in mind is for games, it may fit into an input lib implementation. Recently a volunteer started writing about the zx spectrum and using newlib as he was learning and he recently covered part of the input library which you can maybe read to get an idea of what it is (he did get the in_inkey description a little wrong - it can return any ascii key on the keyboard, shifted or not). Character io through a serial interface probably doesn't match with many of the functions in the input lib (unless you're getting key up and down events) but some of them could probably be implemented. I'll take a look at how you did things.
The driver is very simple. I'm assuming that you're connected to a terminal program on a PC or pi so that when you type, it only sends an entire line at a time so that editing is taken care of at the terminal with local echo on. So that's where the display happens. Should the input driver be doing an echo? The drivers can be made more complicated by having the terminal send individual characters as they happen so that there is no delay, no local echo and no line editing at the sender. Then the z88dk driver will be responsible for line editing, whether that's the c library or the nascom rom. If it's the c library, the requirement is z88dk must be able to do backspace. If the terminal can do cursor placement on screen we can go further and z88dk can manage multiple windows on screen. Each of these steps means larger binary sizes.
yes right now you have to do this yourself.
Yes the current state is built every night. The build failed last night but hopefully it is cleared up for tonight.
Ok, there is a separate cpm target in both the newlib and classic. Classic is able to do file io for cpm as well. |
NASCOM Basic generates an echo, so mostly terminals leave the local echo off. But, I think that C generally doesn't do an echo, by default. Not sure what the answer right answer for the rc2014 is, in this case. Probably better to keep it simple where possible. |
With the way it's implemented now (it is assumed the connected terminal is in line mode with local echo), it won't be possible to detect live keypresses like @blaknite wants to do. So I think we may have to change to at least a minimal line editing driver done by the c library. This will be similar to the direct io drivers for cpm (dcio). I should have some time tomorrow evening to try it. |
Since @blaknite and other RC2014 users are the ones who will be doing the most actual programming with z88dk it makes sense to fulfil his (their) desires wherever possible. 😄 I guess the only (obvious) point to remember is that Spencer won't change the default ROM, because it is now a default on every shipped product, so any (Though Spencer did mention on the forum that he might change the default to 56kB Basic. I'll have to persuade him to include the 56kB HexLoadr as the default when he goes to 64kB RAM only. 😄 ) Otherwise, it is just a better project to build a much improved non-blocking buffered optimised ACIA driver for the "clean slate" |
I was disappointed that Startrek wouldn't fit into 32kB, so I added the HexLoadr to my 56kB NASCOM Basic build. It is not the default ROM, but it will reach a few people, I'm sure. I'm very happy to report that it was straight forward to configure the This enabled Startrek to fit into the rc2014 with 64kB RAM module. Uploading the 82kB HEX file generating 31kB of code (0x3000 through to 0xA820) takes only a few seconds, as the HexLoadr runs at line rate. |
Will it fit if you move the org down further? At 0x9000 it seems there is still 3k left to basic. I was thinking about moving the default org down further so there isn't so much space left unused.
Another thing is you can strip the bss section from the output binary if you get the crt to zero bss before starting main. This will reduce the size of the produced ihx file:
I was thinking of making that the default too. |
#pragma output CRT_ORG_CODE = 0x8400
#pragma output CRT_ORG_BSS = -1
#pragma output CRT_INITIALIZE_BSS = 1 SBC - Grant Searle
ACIA - feilipu
z88dk
Cold or Warm start, or HexLoadr (C|W|H) ? C
Memory top? 33791
Z80 BASIC Ver 4.7b
Copyright (C) 1978 by Microsoft
161 Bytes free
Ok
SBC - Grant Searle
ACIA - feilipu
z88dk
Cold or Warm start, or HexLoadr (C|W|H) ?
HexLoadr:
######################## - a lot of hash - ##############################
Done
Ok
doke &h8224, &h8400
Ok
print usr(0)
*************************************
* *
* *
* * * Super Star Trek * * *
* *
* *
*************************************
Do you need instructions (y/n):
------*------
------------- `--- ------'
`-------- --' / /
\\------- --
'-----------'
The USS Enterprise --- NCC - 1701 It seems so. |
Issue #270 is causing the "CRT_ORG_BSS = -1" pragma not to properly separate the bss section from the output binary. |
I get a compiled binary size of 30775 bytes which includes CODE,DATA,BSS (the pragma to separate BSS is not working otherwise you would add the code binary size to the bss binary size to arrive at the same number). What's not included is the heap or the stack but there is a pragma in startrek.c that eliminates the heap so all that is left is the stack. 65536 - 0x8400 - 30775 = 969 bytes for the stack which is plenty. 256 is comfortable for programs that use floats and don't have deep recursion. When a command line comes into play, either argv and argc are created on the stack (the crt makes a copy from the original location) or they are created in the original source. If the former happens, you also need stack space to store argv,argc. |
Just to note that There needs to be space available to Basic for the user to type or upload a Basic program, that will poke the assembled version of a HexLoad program into free RAM. Then this HexLoad program can load the z88dk C binary (Hex). I'll have a look at the standard version on the RC2014 repository, and see if I can simplify the program and at least calculate how much space it needs to reserve in Basic, and free RAM. |
I've redone the hexload program in the RC2014 repository, to suit the The Basic The active asm The existing default origin of It might be reasonable to have default the C stack start at |
It sounds like 0x9000 is a good default org and the idea to move the stack below the code is probably a good one - I'll just have to revisit how the heap is sized by default. I've committed some new drivers to test under There is an example program "password.c" that does password mode and edit buffer stuffing that should work with this driver. The drivers assume that nascom rst 0x8, 0x10, 0x18 only alter the main register set (af, bc, de, hl). If more are altered, then some crashes may occur and push/pop pairs will have to be added. The drivers add about 900 bytes to program size. Let me know if it's working! |
Compiling and running the But, it is not working as expected. Part of the problem may be my terminal set up. I had a bit of trouble finding a terminal that sent the characters immediately, and settled on GtkTerm 0.99.7-rc1. The screen shot shows the The
The backspace gives:
For sanity checking and comparison, with the NASCOM Basic command line on the GtkTerm, backspace moves the cursor back one space, but doesn't delete the character to be removed. The Edit. I'm also playing with The only combination (that I found) that generates response is |
I'm trying to get it to match native nascom basic. If you get proper display with the basic rom including line editing, that's what I am trying to duplicate. I may have made a mistake in treating the attached terminal like an ascii terminal. Maybe it should be treated like a vt terminal so that backspace is not ascii code 12 but rather an escape sequence. I'm not sure why you are getting a LF after every character echoed during input. The "_" is the cursor btw. I'll have another go tomorrow - been a bit busy the past few days and maybe this time I will take a closer look at the nascom rom to find out how it's doing line editing. |
@feilipu Do you mind trying the basic_dcio compile again? I've been reading the nascom source and I can see that the backspace character is different so I've changed that and I've accommodated the CHAR_CR code only that is sent by the terminal when pressing ENTER. Other than that I can't see anything wrong. There is something strange in the nascom source, however. After printing a CR/LF it sends a bunch of NUL characters. I think this may be to fill up the terminal's input buffer to force output to screen. If that's the case, is it true you do not typically see any typed characters on screen when entering a line in basic? You mainly only see it after enter is pressed? |
Well, to the best of my knowledge, it is now 100% fixed, and this issue can be closed off from my point of view. 🙇♂️ Still it would be good to get a second opinion from someone else with a RC2014, and who is writing games or such like @blaknite.
Using GtkTerm 0.99.7-rc1, I don't see the NULL characters when examining the output in HEX over the USB serial interface, so perhaps they're simply destined for old NASCOM hardware? Anyway, they don't influence the outcome. Perhaps the only loose end left at this stage is to move the default stack origin down to I'll put another note up on the RC2014 forum. |
Finally :) I think there are a few issues before this can be tied up:
|
I think all the issues in above TO DO list are either done, or relate to general terminal handing code (not specific to RC2014). Its time to open a new issue if there are new broken things appearing in the future. |
The RC2014 is expandable, via multiple 3rd party cards, but the basic RC2014 Full Monty, or RC2014 Mini consists of 32kB RAM from
0x8000
, with 8kB NASCOM Basic located from0x0000
. Additionally an optional 64kB RAM board provides 56kB RAM from0x2000
.The ROM contains NASCOM Basic, which provides a simple interface via
RST08
for transmitting bytes, andRST10
for receiving bytes via the inbuilt ACIA board. Both calls are blocking, and will not return until a byte is either transmitted or received.The current
+rc2014
implementation supports-subtype=rom
and-subtype=rom_zx7
, both for generating a complete ROM replacement from any C program.This is an enhancement request to provide an additional
+rc2014
RAM implementation;-subtype=basic
, to allow C programs and the z88dk STDIO library to interface with the NASCOM Basic ROM character I/O.The point of this enhancement is to allow owners of the Full Monty or Mini RC2014 to access z88dk without purchasing any additional hardware. Programs in Intel HEX code generated using z88dk
appmake +glue
can be uploaded to the RAM of the RC2014 using either a Basic language HEX uploader using the default ROM, or an integrated HexLoadr in an enhanced ROM.rc_00_output_basic.asm.txt
rc_00_input_basic.asm.txt
I've had a crack at writing the character drivers to take advantage of the available
RST
jumps, but I'm not sure how to configure the rest of the z88dk platform to take advantage of a new subtype, and ensure that the correct character drivers are included with the subtype selection. I hope this is of some help.The text was updated successfully, but these errors were encountered: