Welcome, Guest. Please login or register.


Author Topic: Just started coding for the Enterprise 128 and have a couple of questions (Read 7336 times)

Offline Sdw

  • User
  • *
  • Posts: 50
Hello!

I just recently purchased an Enterprise 128, and I've started to take the first steps into coding for it (doing crossdevelopment on PC with sjasmplus and using ep128emu for testing).
I am mainly interested in coding demos (you can see some of my work for other platforms on my website http://www.ag1976.com/prods.html) and as such, I am looking to code as close to the "bare metal" as possible.

I found a some code that I think originated here, called "SAMPLE.ASM" that I started with. It worked fine for some basic stuff, but moving forward I found that I really need to have static RAM/VRAM addresses, using the EXOS allocator-stuff where I don't know which address in VRAM I'm going to get is not good when for example doing dynamic LPTs where I want to have a bunch of precalculated addresses.

Instead, I have come up with a base code that looks something like this:

Code: [Select]
MACRO EXOS n
rst 30h
db  n
ENDM

ORG 0xf0

;16 bytes EXOS file header (not needed in Enterprise assemblers)
db 0,5 ;type 5 = machine code application program
dw pend-0x100 ;16 bit length
db 0,0,0,0,0,0,0,0,0,0,0,0 ;not used bytes

;start of program, loaded at 100h
di
ld hl,exit
ld (0xbff8),hl ;set the exos warm restart address
ld sp,0x0100

; Set border color to black
ld a,0
out (0x81),a

; Bank in video RAM at 0x8000 and 0xc000
ld   a,0xfe
out (0xb2),a  
inc a        
out (0xb3),a

ld   bc,lpt_end-lpt_start
ld   hl,lpt_start
ld   de,0xc000
ldir

; Set LPT pointer to 0xc000
ld a,0
out (0x82),a
ld a,0x0c
or 0xc0
out (0x83),a

ld de,0x8000
ld bc,80*200
fillscreen:
ld a,c
ld (de),a
inc de
dec bc
ld a,b
or c
jr nz,fillscreen
ld a,0
inf:
out (0x81),a
inc a
jp inf

waitvbl:  
in   a,(0b4h)
   bit  4,a
   jr   z,waitvbl
ret

exit:          
;exit routine at error or reset
di
ld sp,0x0100 ;set user stack
ld a,255 ;system segment
out (0xb2),a ;to page 2.
ld hl,exit
ld (0xbff8),hl ;set warm restart address
ld hl,(0xbff4) ;exos lpt address
set 6,h ;convert to video address
ld b,4 ;rotate with 4 bits
elpt:          
srl h
rr l
djnz elpt
ld a,l ;low byte
out (0x82),a ;send to nick
ld a,h ;high 4 bits
or 0xc0 ;enable nick running
;switch to the new lpt
;at the end of current frame
out (0x83),a ;send to nick
ld a,0xf5 ;restore original
ld hl,0x1837 ;exos irq routine
ld (0x38),a ;starting
ld (0x39),hl
ld c,40h ;reset code=40 deallocate all user ram
EXOS 0 ;exos reset
ld a,1 ;rom 1.
out (0xb3),a ;to page 3.
ld a,6 ;6. function= enterprise logo screen
jp 0xc00d ;exit to rom

lpt_start:
db 256-200 ; 200 lines
db 0x72 ; Mode
db 11,51 ; Margins
dw 0x8000
dw 0x0000
block 8,0
   ; 50 lines of border, this is the bottom margin,
db 256-50,0x12,63,0,0,0,0,0,0,0,0,0,0,0,0,0
; 3 black lines, syncronization off
   db 256-3,16,63,0,0,0,0,0,0,0,0,0,0,0,0,0              
   ; 4 lines, syncronization on
   db 256-4,16,6,63,0,0,0,0,0,0,0,0,0,0,0,0
   ; 1 line, syncronization will switch off at half of line
   ; the nick chip generate video irq at this line
db 256-1,0x90,63,32,0,0,0,0,0,0,0,0,0,0,0,0            
;4 black lines
db 256-4,0x12,6,63,0,0,0,0,0,0,0,0,0,0,0,0
;50 lines of border, this is the top margin,  
db 256-50,0x13,63,0,0,0,0,0,0,0,0,0,0,0,0,0
lpt_end:

pend:
END

I have retained the reset-routine, but instead of allocating memory, I have envisioned doing the following setup

0000-3FFF Normal RAM
4000-7FFF Normal RAM
8000-BFFF VRAM bank 3 (so VRAM address matched normal RAM address)
C000-FFFF VRAM bank 4 (so VRAM address matched normal RAM address)

That way I have everything on fixed addresses and my precalced tables will work fine.

To achieve this I have left the first two banks untouched, working under the assumption that when loading the .COM from tape, normal RAM will be available here (and I will have to make sure that my program max covers 0x0100-0x7FFF), and then once the program has loaded I switch in VRAM in bank 3 and 4.

This seems to work fine both in ep128emu and on my real HW, but when I put the emulator in Enterprise64 mode it runs, but waaaay slower. I am guessing it has something to do with code running from VRAM-capable RAM being slower, or? Is this a problem, do people usually target EP64, or is it "ok" to release EP128 compatible only?

Also reading in some other threads on the forum, there were some talks about strange expansions and harddrives etc. that might use certain memory areas. Could this be a problem, do I need to ship my demo (once it's finished...) with a warning to not use anything other than standard Ep128?

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Hello!
Welcome here!


Quote
you can see some of my work for other platforms on my website
Wow, many very nice demos! :smt038

Quote
I put the emulator in Enterprise64 mode it runs, but waaaay slower. I am guessing it has something to do with code running from VRAM-capable RAM being slower, or?
Yes, in the VRAM the Nick chip have the priority, and Z80 clock halted, when both want to access the VRAM.

Quote
Is this a problem, do people usually target EP64, or is it "ok" to release EP128 compatible only?
Don't problem, I think about 95% of existing Enterprise softwares run only on EP128.

Quote
Also reading in some other threads on the forum, there were some talks about strange expansions and harddrives etc. that might use certain memory areas. Could this be a problem, do I need to ship my demo (once it's finished...) with a warning to not use anything other than standard Ep128?
This is more problematic :-) Todays the main storage on real machines are the SD card or floppy.
But if I understood right at the loading your program not need to use Bank 4. Just zero fill it, then don't possible to return to the system, only cold reset possible. (The problem when hot reset done with broken system data.)

(But if possible, more better when proper exit from the program possible :-)
Allocate FEh segment for the Bank 3 are easy.
If the Bank 4 used only for the LPT table, then possible partial allocate the FFh segment. Another way use FCh as LPT segment (many-many programs do it, because 0000h LPT video address can be used, easy to send out to Nick). Change LPT segment only touch the video addresses when set the LPT address to the Nick.
Tricky way: copy the full FFh segment to another, and at the exit copy back. Then hot reset don't possible, but with STOP key can possible proper exit.)

Offline geco

  • EP addict
  • *
  • Posts: 7082
  • Country: hu
    • Támogató Támogató
Welcome here

I checked your link there are a lot of great demos for several platforms :smt041
Did you write all of them in assembly ?
I just ask because as I see there are at least 4 different CPU's. :)

Offline endi

  • EP addict
  • *
  • Posts: 7298
  • Country: hu
  • grafikus, játékfejlesztõ, programozás, scifi, tudományok, vallás
    • Honlapom
Vigyázat! Szektás vagyok! :)

Offline Sdw

  • User
  • *
  • Posts: 50
Thanks for the welcome guys!

Quote
This is more problematic :-) Todays the main storage on real machines are the SD card or floppy.

Yes, I read that there were such things available, which is cool! However, with the price of the Enterprise128 being quite high, and I guess these solutions being quite expensive and rare, I have to stick with loading from tape-port via my PC for now. :)
But of course I will try to write my code so that thee demo does work for everyone else as well.

Quote
But if I understood right at the loading your program not need to use Bank 4. Just zero fill it, then don't possible to return to the system, only cold reset possible. (The problem when hot reset done with broken system data.)

(But if possible, more better when proper exit from the program possible :-)
Allocate FEh segment for the Bank 3 are easy.
If the Bank 4 used only for the LPT table, then possible partial allocate the FFh segment. Another way use FCh as LPT segment (many-many programs do it, because 0000h LPT video address can be used, easy to send out to Nick). Change LPT segment only touch the video addresses when set the LPT address to the Nick.
Tricky way: copy the full FFh segment to another, and at the exit copy back. Then hot reset don't possible, but with STOP key can possible proper exit.)

OK, so if I understand correctly, I should zero-fill the 0xc000-0xffff bank, directly when I enter my program, that is, I shouldn't switch anything specific into it, but just assume that what is at those addresses are what should be zerofilled?

Also, since it seems like I can ignore the EP64, I am thinking that perhaps I could have a memory layout like this:

0x0000-0x3FFF My program loads here, no bank switching
0x4000-0x7FFF My program loads here, no bank switching
0x8000-0xBFFF My program loads here, no bank switching
0xC000-0xFFFF Zerofill first, then bank in two different VRAM segments depending on if working on gfx data or LPT data

So first of all, is it possible to load such a large .COM file ie. 48kb-256 bytes large?

Then, can I (after zerofilling the RAM) safely bank in any VRAM page in the last page (the one controlled by port b3)?
I am thinking that I then first bank in page FE
ld a,00xfe
out (0xb3),a
 (so that is VRAM 8000-BFFF) into the top bank, fill it with gfx data, then I bank in VRAM page FF
ld a,00xff
out (0xb3),a
(VRAM C000-FFFF) into the top bank, fill it with LPT data, and everything is ready?
Or do the VRAM page with gfx data also need to be banked in and visible to the CPU for the LPT to be able to display it?
Does this look like a good plan, or should I use other VRAM pages?

Finally - a question of IRQs. I want to set up a VBL-IRQ that is called once per frame. Does that mean that I should use the LPT-IRQ-bit in one of the rows, or is there a better way?

Sorry for all the questions!

I have to say that so far I really like the Enterprise128, the LPT system is really cool, with the possibility to change how wide the screen is, and the different gfx/characters modes are also really nice.
Coming from C64 primarily, I do miss the sprites though! :)

Quote
I checked your link there are a lot of great demos for several platforms :smt041
Did you write all of them in assembly ?
I just ask because as I see there are at least 4 different CPU's. :)
Yeah, I have dabbled in several different CPUs.
My main background is C64, so 6502-assembler is the one I know best. I know Z80 fairly well, and then there are others (68000, 6809 etc.) that I can code in a bit, but not very good at all! :)

Offline endi

  • EP addict
  • *
  • Posts: 7298
  • Country: hu
  • grafikus, játékfejlesztõ, programozás, scifi, tudományok, vallás
    • Honlapom
please convert your z80 demos and games to ep!
especially the zx81 ones :) (EP has character mode)
Vigyázat! Szektás vagyok! :)

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
Welcome!

Wow, nice demos! And so many different hardware, even one of my favourites: C64DTV :)

Yes, I read that there were such things available, which is cool! However, with the price of the Enterprise128 being quite high, and I guess these solutions being quite expensive and rare, I have to stick with loading from tape-port via my PC for now. :)

I think the "new standard" nowadays maybe the SD card solution (it sticks into the cartridge port where IS-BASIC resides normally, but no need to worry, as the SD card cartridge also contains flash, so it can even act as the old function of the cartridge port we can say, and a bonus, that you can modify the content), which is quite modern, but fast and big enough. And not so much expensive, well, I have no exact idea, but about 30 EUR or such, maybe? Others here may know this better :)

I think, the key factor of EP besides the hardware is its OS. Well, yes OS, especially compared to other 8 bit machines it feels "odd" maybe at the first sight how complex it is, with even "device drivers" etc. But it's also the solution that a brand new mass storage device (like the SD card cartridge) does not need modification of the original ROMs and usually it doesn't cause compatibility problems with software etc, which is often not so easy topic on other 8 bit systems. Just check the situation out with eg IDEDOS on C64 ... (don't get me wrong, C64 is still my favourite as being the first computer of mine).

Quote
OK, so if I understand correctly, I should zero-fill the 0xc000-0xffff bank, directly when I enter my program, that is, I shouldn't switch anything specific into it, but just assume that what is at those addresses are what should be zerofilled?

Be careful with the notions, "0xc000-0xffff bank" (actually "page 3") can be anything, it depends what of the Enterprise 4Mbyte address space is "mapped" (which 16K segment, for page 3 it's I/O port 0xB3) to that Z80 page. I guess you mean here, that segment $FF (the last 16K of VRAM, also called "system segment" as the OS - EXOS - stores its things there) is mapped to page 3, right?

Having a "complex" and "dynamic" OS (ie it can have different EXOS_ROMs etc) also mean that it's not so much possible to tell the exact memory addresses of certain things. But for sure, you can still drive the computer "directly" when you may not need EXOS etc at all, overwriting stuffs, if you want. However keep in mind, that you may have problems if you need to load extra stuffs then (next part of demo, etc) if you trashed the OS out ... Surely you can instruct the hardware directly for load, but this is the situation where you meet the problem that many different storage techniques are/were used, which is transparent through the EXOS, but of course it is not, if you do it yourself.

Quote
(VRAM C000-FFFF) into the top bank, fill it with LPT data, and everything is ready?
Or do the VRAM page with gfx data also need to be banked in and visible to the CPU for the LPT to be able to display it?

No, even no VRAM at all needed to be banked in for the Nick (it's true for the LPT as well, or for everything which is read by Nick chip itself). The described page/segment and "mapping" method is _ONLY_ for the CPU strictly. Nick as the video chip *always* sees the 64K VRAM (in case of EP64 this is the only RAM in the system without expansion, that's why EP64 is slower than an EP128 which also has an internal memory expansion panel installed for additional 64K which is not VRAM thus faster). And it always sees linearly. CPU address "mapping" does not mean anything for the Nick, it also wants "Nick addresses". Eg, if you send 0xFC to port 0xB3, then for the Z80, you can see the first byte of VRAM at address 0xC000, but for the Nick it's the address 0. Actually, I think it's cool, you can have even *no* VRAM segment is paged in at all, Nick will still display its stuffs of course! And it's also true, that the VRAM can be seen by the CPU at segments 0xFC, 0xFD, 0xFE and 0xFF. The non-VRAM RAM areas (not so much in Ep64 without expansion of course) can have different layout, even at non-continuous segments (!) that's why you should allocate memory via EXOS, as the OS knows (it scans at the "boot" time) where usable RAM segments are, it's depend on memory expansion solutions, etc. But for VRAM, you can know where it is, even without EXOS (it's another thing, that it's nice to use EXOS anyway if you plan to have "EXOS compatible" software at least - but to be honest: for a really "serious" demo I can imagine that you need every bytes of the RAM and it won't be EXOS compatible, so you need cold reset / etc solution then).

Quote
Finally - a question of IRQs. I want to set up a VBL-IRQ that is called once per frame. Does that mean that I should use the LPT-IRQ-bit in one of the rows, or is there a better way?

What is VBL? Vertical Blanking maybe? You can have set IRQ for any LPB of the LPT even for more one, just one thing should be known: you can't have IRQ for two (or more) continuous LPBs as it wouldn't produce an "edge" (IRQ itself is level triggered on the Z80, but I mean at Dave/Nick level) of the signal between the two LPBs. Also it seems (and "AFAIK") IRQ is generated actually at the _end_ of the LPB which was configured with VINT bit for video interrupt.

Quote
Sorry for all the questions!

Why? :) It's always cool to talk about things like this, and helping each other!

Quote
I have to say that so far I really like the Enterprise128, the LPT system is really cool, with the possibility to change how wide the screen is, and the different gfx/characters modes are also really nice.
Coming from C64 primarily, I do miss the sprites though! :)

I agree. Nick is quite smart stuff, and LPT allows nice tricks done by the hardware then without any CPU usage (as with doing raster interrupts on C64 to modify settings, etc). You can even try things, to show the same content at two (or more) places throughout the screen even with tricky LPT to do one instance as "upside-down" or with different palette - or for example animations played by hardware (surely the size of VRAM is a limiting factor here) etc. And it's kinda cool that you have 256 colours to choose from, as well. But well, yes, sprites are missing, sometimes badly missing ... Nick has "EXTCOL" inputs (external colour) so there can be image data "fed" digitally, AFAIK "sprite module" was even planned as an add-on with attached onto the EXTCOL inputs of the Nick chip.

Quote
Yeah, I have dabbled in several different CPUs.
My main background is C64, so 6502-assembler is the one I know best. I know Z80 fairly well, and then there are others (68000, 6809 etc.) that I can code in a bit, but not very good at all! :)

This was about my situation as well.
« Last Edit: 2016.July.13. 13:35:47 by lgb »

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
And one more thing over my previous mega-post :)

http://ep.lgb.hu/epdesc.txt

Though I am not the best writer (that's sure ...), I've tried to write some "big picture of the EP" like document some time ago. I am not sure if it's useful for you at all. Hopefully my text does not contain any false information at least :-D

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
So first of all, is it possible to load such a large .COM file ie. 48kb-256 bytes large?
Yes, only some paging needed at the start:
LD A,(0BFFDh) ;USR_P1
OUT (0B1H),A
LD A,(0BFFEh) ;USR_P2
OUT (0B2H),A

Quote
Then, can I (after zerofilling the RAM) safely bank in any VRAM page in the last page (the one controlled by port b3)?
Yes. But first page in, then zero fill :-)

Quote
Or do the VRAM page with gfx data also need to be banked in and visible to the CPU for the LPT to be able to display it?
No. Once you setup the LPT/GFX then video pages can be paged out. Nick chip access these are invidualy.
Trick: if you use multiscreen LPT tables, then possible play small animation with the Nick chip, without any CPU usage. Look the NASA&GUY demos, most of these use this trick, Nick play the animation, and CPU the sound.
Interlace mode also use two screen LPT table, then it is also done without CPU usage.

Quote
Does this look like a good plan, or should I use other VRAM pages?
If you don't want to use more than 48K VRAM then use only FC/FD/FE, then no problem with system compatibility. I suggest use the FF only when the others not enough. But if you use only simply LPT table, then possible partialy allocate the FFh, the few first kilobytes are free, then possible don't owerwrite the system.

Proper allocate for FC/FD/FE/partial FF are possible (if not free then exit program).

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
LD A,(0BFFDh) ;USR_P1
OUT (0B1H),A
LD A,(0BFFEh) ;USR_P2
OUT (0B2H),A

Just one note, what was not so much understandable for me here when I first met this question back to some years: These addresses (like 0xbffd etc) actually refers to the system segment (that is segment 0xff). By default, when EXOS loads a program, page 2 (0x8000-0xbfff for Z80) is set (by EXOS) for segment 0xff (what would mean to output 0xff to i/o port 0xb2), that's why you can see code like that with these addresses. You can page system segment as page 3, thus the code fragment above would need eg 0FFFDh instead of 0BFFDh. However be careful, as some of these information assumes page 2, especially if they are addresses (not in this example though) then it's important which page is meant on.

I am not so much sure, but if your program is large enough (ie more than 32K-256 bytes) it would not happen, as page 2 is also set for the loaded program's RAM segment. If I am correct, if not, Zozo will correct me, I guess :)

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
I am not so much sure, but if your program is large enough (ie more than 32K-256 bytes) it would not happen, as page 2 is also set for the loaded program's RAM segment. If I am correct, if not, Zozo will correct me, I guess :)

When the program is started, page 1 is the last segment that was loaded (the same as page 0 if the program is not larger than 15.75 kilobytes), and page 2 is the system segment.

By the way, with the help of epcompress, it is possible to load a program that would otherwise require 4 pages. It can also have all the segments already paged in at start-up, or emulate the EXOS paging.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
When the program is started, page 1 is the last segment that was loaded (the same as page 0 if the program is not larger than 15.75 kilobytes), and page 2 is the system segment.
Yes, and the real segment numbers stored at the USR_Px variables.

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
When the program is started, page 1 is the last segment that was loaded (the same as page 0 if the program is not larger than 15.75 kilobytes), and page 2 is the system segment.

Hmm, thanks, I haven't known that :) I mean the setting of page 1 in this way ...
« Last Edit: 2016.July.13. 22:57:03 by lgb »

Offline Sdw

  • User
  • *
  • Posts: 50
Wow, thank you all for your help and info, I am very grateful for this!

I am still a bit confused, it might be that some suggestions here are referring to the "correct" way to do it (ie. with EXOS allocation) and some are not?

If we just assume that for my demo I will be a bit "mean" and skip the possibility to do a soft-reset etc. so you will need to power off the machine once you finished watching my demo.

We can also assume that I put a 'di' instruction somewhere at the beginning of my program, and I will not do an 'ei', or at least not until I have pointed to my own IRQs.
To me (in my admittedly limited knowledge) it seems then that there should be no risk of me messing up any EXOS stuff or expansions, since I have in essence taken control of the system, and no code that isn't my own is going to be run until the machine has been powered off?

What can I assume then?
If my binary loaded so that it covered all the way up into bank 3 (0x8000-0xBFFF), can I assume that when it starts running:
1) Bank 1-3 are visible to my program, and are put into non-VRAM-banks (we assume it is running on a EP128)? Or can the loader load them into "background" banks and then start without having them visible to my program?
2) I can switch VRAM banks 1-3 into my bank 4 and use that freely? Shouldn't I really be able to use VRAM bank 4 as well, since the system is never going to run again?

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
To me (in my admittedly limited knowledge) it seems then that there should be no risk of me messing up any EXOS stuff or expansions, since I have in essence taken control of the system, and no code that isn't my own is going to be run until the machine has been powered off?
Yes. If you disabled the EXOS IRQ, and you don't want load additional data, then you can owerwrite system.

Quote
1) Bank 1-3 are visible to my program, and are put into non-VRAM-banks (we assume it is running on a EP128)? Or can the loader load them into "background" banks and then start without having them visible to my program?
At the start there are in the background. Then needed this little code which are page in the segments. Now I added check for non-VRAM state:
Code: ZiLOG Z80 Assembler
  1. IN A,(0B0H)
  2. CP 0FCH
  3. JP NC,EXIT
  4. LD A,(0BFFDh) ;USR_P1
  5. CP 0FCH
  6. JP NC,EXIT
  7. OUT (0B1H),A
  8. LD A,(0BFFEh) ;USR_P2
  9. CP 0FCH
  10. JP NC,EXIT
  11. OUT (0B2H),A

Quote
2) I can switch VRAM banks 1-3 into my bank 4 and use that freely? Shouldn't I really be able to use VRAM bank 4 as well, since the system is never going to run again?
Yes. From the VRAM 4 (FFh) segment, the first ~6-7K are also free, if more needed the zero fill it.

I will make modified SAMPLE.ASM for these parameters.