Trying to understand vi65

Discuss all aspects of programming here. From 8-bit through to modern architectures.
Post Reply
User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Trying to understand vi65

Post by pau1ie » Fri Nov 02, 2018 12:31 am

Ive compiled the code, and can't get anything to display, (It displays the empty lines) but apart from that it does seem to work to an extent.

Ive been debugging it using the b-em debugger, trying to work out where the "--empty--" text would be written. I'm looking at v0.1 in the hope it would be easier to understand, and notice in a.asm there is a procedure emptybuf which stores the location if nolinetxt (But -4 for some reason) into the displaylow procedure by calling setstatus. But then it does weird things

So in file a.asm here: https://sourceforge.net/p/vi65/code/HEA ... v0.1/a.asm

At line 1740, Why is it doing

Code: Select all

		sta registers.first+registers.file
		sta registers.last+registers.file
This compiles to
sta $254e ; registers.file (See below), so why registers.first?
sta $2550 ; No idea what is going on here.

Here is a portion of the dasm compiled code from the part where registers is defined near the end of the file, which also confuses me because it has a similar construct which seems to produce different results.

Code: Select all

>2542		00 00				newline		.word registers.nl
>2544		00 00						.word registers.nl
>2546		00						.byte 0
=9550						prgend		= registers+registers.file
.2547						registers
=9543						first		= *+0
=9545						last		= *+2
=9547						len		= *+4
=9548						lines		= *+5
>2547	0000	42 25				nl		.word newline
>2549	0002	42 25						.word newline
>254b	0004	00						.byte 0
>254c	0005	01 00						.word 1
>254e	0007					file		.fill 7
>2555	000e					unnamed		.fill 7
.255c						registersend
.255c						marks
=$255c						line		= *
=9566						column		= *+2
>255c	0000							.fill 3*26		;a-z
>25aa	004e					start		.fill 3
>25ad	0051					end		.fill 3
.25b0						endmarks
.25b0						references
=9648						next		= *+0
=9650						prev		= *+2
=9652						len		= *+4
=9653						reg		= *+5
>25b0	0000					load		.fill 6
>25b6	0006					temp		.fill 6
>25bc	000c					start		.fill 6
>25c2	0012					end		.fill 6
>25c8	0018					insert		.fill 6
>25ce						filename	.fill width-2
>25f4						zpsave		.fill zpend-zpstart
.261a						memory
I don't understand where the =95?? and =96?? addresses are coming from. It looks like it wants to write to these addresses, but this is paged rom area.

So I suppose my questions are:
What is the expression that looks like it is adding two addresses trying to do (e.g. registers+registers.file)
Are the numbers e.g. 9550 in the first column of above addresses
If so, where do they come from, and how do I change them to something more sensible.

I have changed the program slightly, maybe I should upload it to github.

User avatar
jgharston
Posts: 3470
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Trying to understand vi65

Post by jgharston » Fri Nov 02, 2018 9:10 am

Maybe it really does need all that memory. If you target a system with sideways and shadow RAM, you can get 48K of program space by forcing a shadow screen mode and selecting an empty bank of sideways RAM, giving you &0000-&BFFF as working memory. Note that you won't be able to load/save the bit at &8000-&BFFF as the filing system will be paged in at that point, so you'll need to use OSGBPB via a buffer.

I read through the code last week and got thoroughly confused. :(

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

acorn
Posts: 13
Joined: Fri Dec 23, 2016 10:18 am
Contact:

Re: Trying to understand vi65

Post by acorn » Fri Nov 02, 2018 10:05 am

pau1ie wrote:
Fri Nov 02, 2018 12:31 am
I don't understand
I have changed the program slightly, maybe I should upload it to github.
Hi!

The original author is still active (ie. organizes the annual Arok Party). Perhaps he is in the best position to help you along with the port: soci on c64.rulez.org (from a.asm).

https://csdb.dk/scener/?id=3603

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Fri Nov 02, 2018 2:39 pm

jgharston wrote:
Fri Nov 02, 2018 9:10 am
Maybe it really does need all that memory.
I assumed that memoryend at line (say) 173 told it where the memory ends, and the *=801-2 at line 170 says where to start. I copied this section and put some numbers in that seemed sensible for the BBC B. There is some use of zero page, and seems to be some other bits of memory allocated, which I moved to places which are used by Basic, so hopefully will be available for this. What I am confused about is were the assembler gets this number from, as I can't see it being assigned anywhere.
jgharston wrote:
Fri Nov 02, 2018 9:10 am
I read through the code last week and got thoroughly confused. :(
I feel better that it isn't just me, but then again if you are confused, maybe I am more foolish than I thought to use this as a way to learn assembler!
acorn wrote:
Fri Nov 02, 2018 10:05 am
The original author is still active
Thanks - I might try that.

User avatar
jgharston
Posts: 3470
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Trying to understand vi65

Post by jgharston » Fri Nov 02, 2018 8:19 pm

In a couple of weeks I'll have 15 hours to kill on an aeroplane, so I could have a bash at it then.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Mon Nov 05, 2018 11:22 pm

I'm still staring at this.

There is text that gets displayed in the status line at 'banner'.
This is referred to in displaytxt.asm at displayinit.
This calls setstatus which stores the two bytes of the address in displaylow.st1 and st2.
Then it calls the display subroutine, which is back in a.asm. I guess this is what is supposed to paint the screen from the buffer - I suspect I will have to look at this in more detail later.
Then it jumps to displaylow, which is the part I am interested in because that is where the address of the message to display has been written. I am not sure what it does in the first few lines, (Stores the start of the screen in a variable "screen")

Anyway, when it gets to the part I am interested in, it just writes them to currentline, and jumps to paintone.
Now, paintone refers to a cache variable at $0800 in the apple. "Inside the apple II" tells me this is page2 of video memory used for displaying the secondary text screen, but this is rarely used. I had assumed then that this was just being used for memory, but maybe it is supposed to be used for screen memory.

Looking down the paintone procedure I see a lot of if statements. I haven't worked out what they are all for, so haven't filled in the BBC ones. I suppose it shouldn't be surprising I don't get anything displayed! I'll have to look at this in more detail later.

Coeus
Posts: 1191
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: Trying to understand vi65

Post by Coeus » Tue Nov 06, 2018 10:33 pm

pau1ie wrote:
Mon Nov 05, 2018 11:22 pm
Anyway, when it gets to the part I am interested in, it just writes them to currentline, and jumps to paintone.
Now, paintone refers to a cache variable at $0800 in the apple. "Inside the apple II" tells me this is page2 of video memory used for displaying the secondary text screen, but this is rarely used. I had assumed then that this was just being used for memory, but maybe it is supposed to be used for screen memory.
...
I did have a look at vi65 briefly when it was first mentioned. My initial impression was that most of the ports run bare on the hardware, i.e. they read the keyboard, perform key bounce and repeat logic and write characters to screen memory rather than using an OS.

So it seems to me there are three options for this display code:

1. Add to the conditional compilation in displaytxt.asm to create a version for the Mode 7 screen.
2. Add to conditional compilation in one of the displaygfx modules for one of the non-mode-7 screens.
3. Create a display module that uses the BBC MOS for text output and which can therefore work in any mode.

Assuming option 3 performs well enough it should be the best one as it is the most flexible. Not only does it give the user a choice of modes it would also work with screen shadow memory on the Master and B+ That means you don't necessarily need to understand how the subroutines in any of the existing display modules work, just what they are expected to do so you can write a version that is specific to the BBC. For example, paintone may just be a call to OSWRCH if the 'one' refers to one character.
Last edited by Coeus on Tue Nov 06, 2018 10:34 pm, edited 1 time in total.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Wed Nov 07, 2018 9:36 am

Y
Coeus wrote:
Tue Nov 06, 2018 10:33 pm
So it seems to me there are three options for this display code:
Yes, I intend to try something between 1 and 3, i.e. target mode 7 to start with but use the MOS where possible. Then it would work on other modes apart from the width and height are hard coded. This could be dealt with later. As you say it seems to write directly to screen memory, so I thought it would work in mode 7, already. As I say, I do get it to write the dashes (There is no tilde in mode 7) for blank lines, so I am not sure what is going wrong here.

I am pretty sure I have got input at least partially working because if I press "I" and trace with a debugger it calls the insert procedure.

I am trying to understand what it is doing at present so I can adapt it. It is slow progress because I am learning as I go.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Wed Nov 07, 2018 11:12 pm

Had another look this evening. The string is "vi65 soci/singular" and it is supposed to be displayed in the status line once vi65 initialises. This happens at paintone.m1 in displaytxt.asm. "lda (currenttext),y" where currenttext is the start of the string, and y is the position we are concerned with (the 'v' in this case) This enters a load of conditinal compilation. Apple2 would EOR it with 80 (To make sure it is 7 bit) Others do more complicated things. I haven't changed this part, so it does the commodore stuff, and at the end a contains $16, which is a control code. I suspect this is why nothing is being displayed. Indeed it is written to the current memory location at sta (screen),y after the APPLE2) && width==80 conditional.

So I need to add a BBC part of the IF statement after m1 that does nothing (Maybe eventually it needs to ensure control characters don't mess anything up), and I will get something on the screen.

I am using the debugger in b-em. I found breakr useful to break on read of the string. I got the memory address from the dasm file which is created as part of the compilation.

I'm busy tomorrow, so probably the next chance to play with this will be abug.

[Edit - typos!]
Last edited by pau1ie on Wed Nov 07, 2018 11:14 pm, edited 1 time in total.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sat Nov 10, 2018 6:05 pm

That worked - I now display the text on the status line. It is in upper case, until I removed the -a from the TASS command line. Nothing else happens on screen though.

I think I would like to try moving the cursor next. At present it stubbornly stays where it was when the *vi command was run. It should be at the top left of the screen. I guess the place to start looking is displaytxt.asm at the cursor procedure. I think it is just writing the cursor directly to screen memory. The apple 2 version writes to c00f to enable the alternative character set which allows inverse characters, maybe that is what it is using as a cursor, which is why (So far as I can see) it loads the location, does an EOR with 128 then stores it again. So I probably just need to remove all that and just use the OS routine to move the cursor, probably using VDU codes.

That worked!

Next I think I want to see why when I press "I" I don't see a change in the status line (I think it should say "-- insert --")

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sat Nov 10, 2018 10:31 pm

Procedure keylookup is responsible for controlling what happens on a key press. This is a bit clever because there is an array of keys to search and an array of procedures to call based on the key. It pushes the address of the procedure to call on to the stack as if it was done by a jsr, then returns. When I press "i" on my keyboard, caps lock is on in b-em, so it gets an I, which should call kI, which is in insert.asm.

When I get to keylookup, A contains $49, which is I, so I got something right! It searches through the array to find I, which it does, and jumps t kI as predicted. So far so good!

It decrements tochar.mode. Is this how it records edit or insert?

It jumps to motion_uparrow - This procedure is actually the procedure for the caret key and moves the cursor to the first non blank character of the current line, which will be tricky because there is no text in the editor, but it decides column 0 is the correct place to be.

Then it falls through to insertmode and sets the status line memory address in x and a, and calls setstatus, which just writes the address of the message in the displaylow.st1 and st2, which as I found earlier is written by displaylow.

Then it calls setmark, which marks the current position. (as if you had done m)

Then it falls back to the loop which waits for a keypress. The screen hasn't been updated.

Not a lot has happened between setstatus and waitkey, there should be a display in there. I see in the apple conditional it calls display and cursorup repeatedly while in the loop waiting for a keypress. I expect that is what I am missing.

Brilliant! It works. The cursor goes down the screen rather than across, but I can fix that! I can press keys and see output!

Next I will try and get the cursor to stay in the right place.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sat Nov 10, 2018 10:58 pm

That was quite easy, I just needed to swap x and y. This vi is the type where it scrolls the display right if you go past the end. The cursor doesn't keep up if I do that. I suspect it also doesn't work if I scroll down past the end of the page, but I think I want to get the first screen working first of all.

Next I need to try to get escape to work. At the moment it just inserts a box. That will wait till tomorrow - I think we are about to be kicked out...

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 11, 2018 9:47 pm

To get escape working. I understand that there is an error which you have to clear when escape is pressed (Though I could disable this with osbyte &c8). This is done and the program continues, but it just inserts a square into the buffer which is ascii FF. This is because I had assumed that osbyte wouldn't mess with the registers, but it does. Saving a on the stack and restoring it afterwards, and now escape works.

I do get rubbish over the screen (Code counting down and moving the cursor to the right) if I hit keys that shouldn't do anything. I have an R on the screen in memory location 7c57 which is just about to be overwritten, so if I breakw on that location I should find the culprit It is the cursor attempting to move.

That took ages to debug. I was overwriting an instruction because I thought cursor.size was allocating memory, but actually it was just a pointer, so it was overwriting an instruction rather than its argument. I don't use this at the moment as I am not sure you can change the cursor size in mode 7.

So now it seems to be working pretty well. issues are pressing 9 inserts l, cursor position is incorrect on the screen unless you are at the start of the file (I assume I am using the offset from the start of the file rather than the start of the screen). Colon and delete don't work. I haven't even looked at load and save, so they won't work either. But pretty much everything else does work, so I am pleased with progress.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 11, 2018 11:38 pm

9 doesn't work because it triggers the code for control-y. Control-y is defined as asc(y)(=121)-k_control (where k_control is 64), which is 57. Character "9". I need character 25, control needs to be 121-25 = 96 (hex 60). This is another area I had let default to commodore. I suppose I should check the values of the remaining key codes.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 11, 2018 11:47 pm

Now 9 and delete work. I need to change the cursor keys so they return keycodes rather than selecting text to copy.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Tue Nov 13, 2018 12:00 am

I want to work out how to find the current cursor position on the screen. I know that line and column contain the line and column of the cursor with respect to the start of the file, so works initially.

Some reading of the source reveals that cursor.in+1 has the x location, and paintone.u+1 has the y location. Now the cursor stays in the correct place on the screen even when scrolling.

Next I would like to get the colon command working.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Wed Nov 14, 2018 9:10 pm

It turns out that getting the colon command to work was as easy as working out which character maps to colon in b-em.

Current bugs are:
  • Arrow keys don't work (Just need to change the mode)
  • Loading doesn't work
  • Saving doesn't work
  • Quitting doesn't work
  • Screen updates (Apart from the cursor) are done directly to RAM rather than through the OS.
  • Like many games it rudely overwrites BASIC memory, so will need CTRL-BREAK to exit (This is why quitting doesn't work)
I'm going to work on loading and saving next.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 18, 2018 10:22 pm

I'm confused by this. If you do :e file it ought to load a file. (Which you can do with :f) it goes to the edit routine in cmdline.asm. This does jsr file which sets the filename, then jumps to load, which is in a.asm. This calls checkname, which I think makes sure the file name isn't blank, which it isn't.

Back in the load routine it seems to be clearing the memory structures from the previous file, it calls free_register. I'm not sure what this is doing, I'll assume it is just resetting everything. Then it calls insertref in insert.asm. The comment says cursor + to x ref, presumably this is resetting the cursor location.

Next we have the conditional compilation part. The Apple II version seems to be setting up things so that the out of memory message is displayed if there is an error, but I am not sure how this works, because inside the apple ii doesnt mention the memory locations d8, 9d5a. Then it jumps to open which is in io.asm.

The entire procedure is conditionally compiled. The apple ii part sends *open filename" and "READ" to the output, which presumably is pro dos. As I understand it, this redirects the keyboard input to the file. However, the documentation taken from cmdline.asm says
File is loaded in the background,
the loaded part can be edited imediately.
Therefore it must know what is coming from the keyboard and what is coming from the disc. I am not clear how it does this. I do notice however there are two places in the loop where the apple ii reads the keyboard (i,e, memory location c000), and the second I don't seem to use with the BBC, so maybe this is where the file is read.

User avatar
pau1ie
Posts: 668
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 18, 2018 11:54 pm

I've just realised, variable loading is 1 if a file is loading, and 0 if not. If we are loading it runs load.part from the display procedure, which calls savebuffer. This is set in the load procedure, and reset in the loop when the file is closed. There is still more to learn about this though because I think buffers contain lines, and I am still not clear how it is checking for the line end, unless it has a buffer for loading from file and a buffer for keyboard editing and it is switching between them...

Post Reply