Welcome, Guest. Please login or register.


Author Topic: How to begin assembly on Enterprise (Read 14220 times)

Offline ssr86

  • EP user
  • *
  • Posts: 359
  • Country: pl
  • OS:
  • Windows NT 6.2 Windows NT 6.2
  • Browser:
  • Firefox 39.0 Firefox 39.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #75 on: 2015.August.14. 16:18:08 »
Only under the system operations. In your program can you page in anything to Page1-3. (on P0 normaly are the Page 0 segment, where the EXOS entry point and IRQ handler at the start.)

So in order to make use of the $ff segment with exos calls (for loading from file) I have to load all data to another segment and later move it to the $ff segment, right?

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 40.0 Firefox 40.0
    • View Profile
    • http://lgb.hu/
Re: How to begin assembly on Enterprise
« Reply #76 on: 2015.August.14. 16:40:39 »
So in order to make use of the $ff segment with exos calls (for loading from file) I have to load all data to another segment and later move it to the $ff segment, right?

You wrote, you need 2 video segments. Then you should not use segment $FF but some other, so you won't have these problems (there is 64K video RAM so there are four 16K sized video segments: $FC, $FD, $FE, $FF). $FF is the system segment, so if you overwrite it, you probably won't be able to use any EXOS function, no keyboard handling (by EXOS) etc whatsoever, also warm reset won't work, etc. The best way: use EXOS segment allocation call, thus you can be sure a segment is "yours". Unfortunately there is no EXOS call to allocate a _video_ segment. Common technique is to allocate segments (and remember them!) in a loop till you got enough video segments (segnum >= $FC) then free segments you don't need from the stored allocated ones created throughout the allocator loop.

Of course it's possible to "take over" the machine and use memory as you want, but then you may need to forget EXOS and you need to do everything at your own (direct hardware access). It can be painful if you need file access later too (especially because doing hardware level EXDOS card access won't work if the user has some other solution - like the SD card cartridge - where compatibility is provided at software level). But if you can pre-load anything before the "take over" it can be OK. Though on EP the "elegant" way that you don't need to "cold reset" the machine, the RAM disk is not cleared, etc, but it requires to keep system segment intact ...
« Last Edit: 2015.August.14. 17:26:44 by lgb »

Offline ssr86

  • EP user
  • *
  • Posts: 359
  • Country: pl
  • OS:
  • Windows NT 6.2 Windows NT 6.2
  • Browser:
  • Firefox 39.0 Firefox 39.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #77 on: 2015.August.14. 20:28:54 »
You wrote, you need 2 video segments. Then you should not use segment $FF but some other, so you won't have these problems (there is 64K video RAM so there are four 16K sized video segments: $FC, $FD, $FE, $FF). $FF is the system segment, so if you overwrite it, you probably won't be able to use any EXOS function, no keyboard handling (by EXOS) etc whatsoever, also warm reset won't work, etc.
But it seems that the system segment must always be mapped... And so I can't really use any other video segment then...
When I don't map $ff then my screen doesn't render - seems that there're some problems with LPT processing...
Is it normal, or am I just doing something wrong?
Quote
The best way: use EXOS segment allocation call, thus you can be sure a segment is "yours". Unfortunately there is no EXOS call to allocate a _video_ segment. Common technique is to allocate segments (and remember them!) in a loop till you got enough video segments (segnum >= $FC) then free segments you don't need from the stored allocated ones created throughout the allocator loop.
I'm actually doing something similar as I'm "basing" my code on geco's rick dangerous 2 loader.
Quote
Of course it's possible to "take over" the machine and use memory as you want, but then you may need to forget EXOS and you need to do everything at your own (direct hardware access). It can be painful if you need file access later too (especially because doing hardware level EXDOS card access won't work if the user has some other solution - like the SD card cartridge - where compatibility is provided at software level). But if you can pre-load anything before the "take over" it can be OK. Though on EP the "elegant" way that you don't need to "cold reset" the machine, the RAM disk is not cleared, etc, but it requires to keep system segment intact ...
I think I'd prefer to do it the "elegant" way...

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 40.0 Firefox 40.0
    • View Profile
    • http://lgb.hu/
Re: How to begin assembly on Enterprise
« Reply #78 on: 2015.August.14. 20:40:03 »
But it seems that the system segment must always be mapped... And so I can't really use any other video segment then...

First of all, you have four Z80 pages to map any segment of the 256 to. Second: you don't need system segment always mapped in. If you call an EXOS function or IRQ is serviced, it will be mapped in, and on return, your original mapping is restored. What you "should" always paged in is P0 (zero page segment from 0-3FFF) because eg the "head" of the IRQ routine is there. If you disable interrupts and you don't need to call EXOS functions for a while you don't even need P0 paged in. System segment is needed by EXOS, so if your code runs nobody is interested if system segment is mapped in or not. What I meant, that you should not overwrite system segment. If's another question that you can map some other segment with writing port $B3 and you can write there of course, since in memory it won't be written into the system segment ($FF) of course.


Quote
When I don't map $ff then my screen doesn't render - seems that there're some problems with LPT processing...

No! Important rule: the Z80 as the CPU sees memory "through" the Dave memory segment mapper (ports B0-B3 to set). But Nick *always* see the video RAM (segments $FC-$FF) regardless what you map in for the CPU. So the address Nick address 0 (eg for LD1 pointer in some LPB) *always* means the 0th byte in segment $FC even if that segment is not mapped in for the CPU at all! In other words: Nick uses another memory layout scheme, and sees 64K at the end of the EP memory space (thus segments $FC-$FF) linearly and always. The segment mapping is for the CPU _only_!

Offline ssr86

  • EP user
  • *
  • Posts: 359
  • Country: pl
  • OS:
  • Windows NT 6.2 Windows NT 6.2
  • Browser:
  • Firefox 39.0 Firefox 39.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #79 on: 2015.August.14. 20:57:42 »
No! Important rule: the Z80 as the CPU sees memory "through" the Dave memory segment mapper (ports B0-B3 to set). But Nick *always* see the video RAM (segments $FC-$FF) regardless what you map in for the CPU. So the address Nick address 0 (eg for LD1 pointer in some LPB) *always* means the 0th byte in segment $FC even if that segment is not mapped in for the CPU at all! In other words: Nick uses another memory layout scheme, and sees 64K at the end of the EP memory space (thus segments $FC-$FF) linearly and always. The segment mapping is for the CPU _only_!

Thanks! That was my problem - I set the lpt pointer with the address as in my mapped memory instead of the "absolute" nick memory address...
Sorry for being stupid...
(I'm happy I asked because I wouldn't have found the cause by myself)
« Last Edit: 2015.August.14. 21:05:01 by ssr86 »

Offline ssr86

  • EP user
  • *
  • Posts: 359
  • Country: pl
  • OS:
  • Windows NT 6.2 Windows NT 6.2
  • Browser:
  • Firefox 39.0 Firefox 39.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #80 on: 2015.August.15. 03:48:23 »
Sorry, it's me again...
How should "allocate segment and load data from a file into it" go?
If I use a segment allocation routine with exos 24 then I can't do exos 1 because I get insufficient memory.
All works when I don't do the allocation.
Using exos 25 for freeing the segments I won't need doesn't help.
I'm quite frustrated.
As you can see I don't really have a clue what I'm doing...

Online geco

  • EP addict
  • *
  • Posts: 5347
  • Country: hu
  • OS:
  • Linux Linux
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #81 on: 2015.August.15. 10:59:07 »
Sorry, it's me again...
How should "allocate segment and load data from a file into it" go?
If I use a segment allocation routine with exos 24 then I can't do exos 1 because I get insufficient memory.
All works when I don't do the allocation.
Using exos 25 for freeing the segments I won't need doesn't help.
I'm quite frustrated.
As you can see I don't really have a clue what I'm doing...
If you use the video RAM request code from the loader then only 1 problem can be there, it saves the allocated segments into a place specified by HL, possibly this area is overwritten, and therefore EXOS 25 will not free up any page, so all of your segments remained in use therefore no free space for EXOS for loading.
Video RAM allocation is working in the following way:
Ask a free segment and store it at position HL, checks if it is not smaller than FC segment, if it is smaller then ask a new one until it reach FC-FF range, if you got FF the return code will be 7Fh it shows that you tried to allocate the system segment, and FF segment is also reserved by you, so if you try to load now something it will fail with insufficient memory, this is the reason why if you got the video RAM the allocated pages will be freed up by EXOS 25 calls it reads the pages from stored HL address.
Loader of Rick Dangerous is Istvanv's loader :), mine loaders are not so documented :)
If you upload the loader, we can help you easier :)

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 40.0 Firefox 40.0
    • View Profile
    • http://lgb.hu/
Re: How to begin assembly on Enterprise
« Reply #82 on: 2015.August.15. 11:31:42 »
Sorry, it's me again...
How should "allocate segment and load data from a file into it" go?
If I use a segment allocation routine with exos 24 then I can't do exos 1 because I get insufficient memory.
All works when I don't do the allocation.
Using exos 25 for freeing the segments I won't need doesn't help.
I'm quite frustrated.
As you can see I don't really have a clue what I'm doing...

It means you allocated all of the memory, so EXOS does not enough RAM for the data structure needed for the new channel to be open. What I've already told: if you need video segment you need to allocate all of the RAM (within a loop) and wait for having a video segment allocated (segnum >= $FC). However the problem here that you allocated segments then you don't really need, just to wait for a suitable (in our case: video-) segment. Thus, after getting the right segment you need to free the unneeded allocated segments. That is, in the loop, you need to store allocated segment numbers, and after you got a video segment you need that stored segment numbers to be used in the free segment EXOS call (excluding the segment you really need! of course). If you need just a "regular" segment, of course a single segment allocation EXOS call is enough, no need for loop, etc. Another thing: if you don't have any "whole segment" free, the segment allocation EXOS call return with "shared segment". That is, eg system segment is "splitted" (named as "EXOS boundary") and returned to the caller, but then you can only use a part of it, as the other part (above the EXOS boundary value) is used as the system segment. However, in this case, the system segment cannot be grown (towards the lower addresses) thus EXOS functions needs more system segment area will fail.

http://ep.homeserver.hu/Dokumentacio/Konyvek/EXOS_2.1_technikal_information/exos/kernel/Ch11.html

See here, EXOS function 24 description.

Also please note that page 0 (0-3FFF) is always allocated, if your program needs 16K of memory you don't need to do extra stuff. If your program to be loaded is longer than 16K, also you have an already allocated segment for page 1 (4000-7FFF) otherwise the program cannot be loaded at all, of course.

Quote
Thanks! That was my problem - I set the lpt pointer with the address as in my mapped memory instead of the "absolute" nick memory address...
Sorry for being stupid...

You shouldn't feel bad. The "problem" with EP128/EXOS that is has got quite "advanced" operating system compared to most of the other 8 bit computers. At least for me it felt quite "complicated" at first, and I also needed time to get to use to it, also some time is needed to understand its "philosophy", and for first it can be really felt as being "too complex" even for a minimal program like print something on the screen (eg open video page, whatever), compared to other 8 bit systems. But EXOS/etc is also the bright side of EP128, that it really have an unique software with quite "modern" (well, compared to its age) behaviour and features.
« Last Edit: 2015.August.15. 11:38:48 by lgb »

Offline ssr86

  • EP user
  • *
  • Posts: 359
  • Country: pl
  • OS:
  • Windows NT 6.2 Windows NT 6.2
  • Browser:
  • Firefox 40.0 Firefox 40.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #83 on: 2015.August.15. 15:14:16 »
The loader looks like this:
Code: [Select]
loader:

        ld      a,0ffh
        out     (0b2h),a
        ld      hl,resetRoutine
        ld      (0bff8h),hl

        call    allocateMemory

ld c,$ff ; free system segment
exos 25  ;

call load_screen1_segment_data
call load_screen2_segment_data

ret


load_screen1_segment_data:

        ld a,(screen1_segment)
        out ($b3),a

        xor     a
        ld      de,dat1prg
        exos    1
         jp      nz,resetRoutine


        ld      de,0c000h
        ld      bc,9803
        exos    6

        jp      nz,resetRoutine

        xor     a
        exos    3

        ret

load_screen2_segment_data:

        ld a,(screen2_segment)
        out ($b3),a
        xor     a
        ld      de,dat1prg
        exos    1
        jp      nz,resetRoutine

        ld      de,0c000h
        ld      bc,14672
        exos    6
        jp      nz,resetRoutine

        xor     a
        exos    3

        ret


dat0prg    db    8,"dat0.prg"
dat1prg    db    8,"dat1.prg"

resetRoutine
        di ;soft reset routine
        ld      sp,0100h
        ld      a,0ffh
        out     (0b2h),a
        ld      c,40h
        exos    0
        ld      a,01h
        out     (0b3h), a
        ld      a,06h
        jp      0c00dh

allocateMemory
              ld de,segment_table+1
              ld hl,segment_table
              ld (hl),0
              ld bc,8
              ldir

ei
              ld hl,segment_table

am1
              exos 24   

              add a,a
              jr nz,am2

              ld (hl),c   
              inc l

              jr nz,am1   

am2:
;-----------------------
; for 1st video buffer (in-game)
call getVideoSegment
jr nc,resetRoutine
ld (screen1_segment),a

; get 2nd video buffer segment (in-game)
call getVideoSegment
jr nc,resetRoutine
ld (screen2_segment),a

; get additional video buffer segment
call getVideoSegment
jr nc,resetRoutine
ld (additional_video_segment),a

;----

; free unused segments:
ld hl,segment_table
am111:
call free_segment
inc l
jr nz,am111
ret
free_segment
xor a
cp (hl)
ret z
ld c,(hl)
ld (hl),a
exos 25
ret

getVideoSegment:
; numer segmentu zwracany w A
                ld a,$fb
                ld hl,segment_table
gvs1:
                cp (hl)
                jr c,gvs2
                inc l
                jp nz,gvs1
                ret
gvs2:
                ld a,(hl)
                ld (hl),0
                ret

screen1_segment equ $7fe0
screen2_segment equ $7fe1
additional_video_segment equ $7fe2

additional_normal_segment equ $7fe3


sharesegment_sizes equ $7fe0
sharesegment_table equ $7ff0
segment_table equ $7ff0+8

Quote
If you use the video RAM request code from the loader then only 1 problem can be there, it saves the allocated segments into a place specified by HL, possibly this area is overwritten, and therefore EXOS 25 will not free up any page, so all of your segments remained in use therefore no free space for EXOS for loading.
I checked and it isn't overwriting the segment_table area and really tries to free the unused segments (returns result 0 for each exos 25). But I had to free $ff to get no memory errors when opening channel and loading... Although I freed $fa and $fb earlier... But it's only a workaround...

Quote
Loader of Rick Dangerous is Istvanv's loader :), mine loaders are not so documented :)
Sorry Istvan

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 40.0 Firefox 40.0
    • View Profile
    • http://lgb.hu/
Re: How to begin assembly on Enterprise
« Reply #84 on: 2015.August.15. 17:34:50 »
I checked and it isn't overwriting the segment_table area and really tries to free the unused segments (returns result 0 for each exos 25). But I had to free $ff to get no memory errors when opening channel and loading... Although I freed $fa and $fb earlier... But it's only a workaround...

Well, I guess the problem here that you allocate all the segments in the system throughout your loop, in this situation the next allocate segment will not fail but provides the so called shared segment, the system segment itself, "split" at an address (this is called the EXOS boundary) between the system (ie EXOS) and you. The segment allocation EXOS call (function 24) can result in three "type of outcome":

1. If there is at least one free segment, it will be allocated for you, segment number is returned, status of the call is OK

2. If there is no free segment left, but shared segment is not allocated yet, then the call itself will return with status "error" as "SHARE" (can't remember the exact code for this in register A now), but actually it's not an error like other kind of error, but only a fact, that no "whole" free segment in the system remain so the system segment is provided for the user with the EXOS boundary in DE showing the address where it is split (so above that address within the segment should not be written otherwise your overwrite EXOS areas ...). However if you exploit this, system segment can't "grow" (downwards) anymore, thus functions need more memory by EXOS will fail (like maybe the open channel ...). There is EXOS call where you can set EXOS boundary so leave some additional memory for EXOS, since in case of shared segment is allocated, the EXOS boundary (I guess) is set in a way that all the non-used memory can be used within the shared segment by the user (so can't grow by EXOS). As far as I know, shared segment is not needed to be segment $FF, it's possible that already more than 16K of memory is used by EXOS, then the shared segment situation will happen in segment $FE for example. So don't assume register C is $FF in case of shared segment, but use value i register C.

3. There is no free "whole" segment and _also_ the shared segment is already allocated, in this case "NOSEG" error is returned.

Some may think that segment allocation actually can have only two results, allocated segment, or error, but it's not the case as you can see.

Anyway: if you need the workaround to free segment $FF it means that you exhausted all of the segments in the system, and even shared segment _is_ allocated, so you need to free. I guess, if you stop your allocation loop when you got the first video seg (C >= $FC). well, if you need only one video segment of course :) Anyway, I write just too much, I'm sorry :)

What I am not sure about at all: what happens if you allocate ALL segments (including the shared!) and then free all the segments, but not the shared segment. In this case though many segments can be available, _I guess_ EXOS won't work too much, because system segment can't grow downwards (I don't know if EXOS has the ability to "jump" over and continue its tasks at a lower numbered video segment, I guess it can't, since the rule that there is exactly one shared segment or none in the system, but if EXOS would be able to do this, you can also create another shared segment then). Well, EXOS is quite complicated sometimes :) But in a good way, just not so easy to understand. At least, this is _my_ opinion :)

Online geco

  • EP addict
  • *
  • Posts: 5347
  • Country: hu
  • OS:
  • Linux Linux
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #85 on: 2015.August.16. 12:09:33 »
The problem was in allocate segment part, FF segment was not stored in the table, therefore it was not freed up, you can use the original code just enter an extra LD C,0FFh, EXOS 25 after memory allocation, or here is the modified allocateMemory.
I changed another thing the size of the table was 8, it works only on EP128, I increased to 256 it works an expanded EP to 4MB also, which can not exist in the reality, because there is no EP without ROM :)

Code: [Select]
allocateMemory
              ld de,segment_table+1
              ld hl,segment_table
              ld (hl),0
              ld bc,00ffh
              ldir

ei
              ld hl,segment_table

am1
               exos 24
               ld (hl),c
inc hl
               jr z,am1 ;exit when reach FF segment (EXOS 24 returns with 7fh in A and FF in C, and F is NZ)

am2:
;-----------------------
; for 1st video buffer (in-game)
         ld hl,segment_table
call getVideoSegment
jr nc,resetRoutine
ld (screen1_segment),a

; get 2nd video buffer segment (in-game)
call getVideoSegment
jr nc,resetRoutine
ld (screen2_segment),a

; get additional video buffer segment
call getVideoSegment
jr nc,resetRoutine
ld (additional_video_segment),a

;----

; free unused segments:
ld hl,segment_table
am111:
call free_segment
inc l
jr nz,am111
ret

free_segment
xor a
cp (hl)
ret z
ld c,(hl)
ld (hl),a
exos 25
ret

getVideoSegment:
; numer segmentu zwracany w A
                ld a,$fb
gvs1:
                cp (hl)
                jr c,gvs2
                inc l
                jp nz,gvs1
                ret
gvs2:
                ld a,(hl)
                ld (hl),0
                ret

screen1_segment equ $7fe0
screen2_segment equ $7fe1
additional_video_segment equ $7fe2

additional_normal_segment equ $7fe3


sharesegment_sizes equ $7fe0
sharesegment_table equ $7ff0
segment_table equ $7e00 ;number of max segments is 256

Offline ergoGnomik

  • EP lover
  • *
  • Posts: 771
  • Country: hu
  • Stray cat from Commodore alley
  • OS:
  • Windows NT 6.3 Windows NT 6.3
  • Browser:
  • Firefox 39.0 Firefox 39.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #86 on: 2015.August.16. 13:24:36 »
Lehet, valakinek kellene írni egy alap keretrendszert amit bárki használhatna, és megfelelne a rendszerbarát programozás követelményeinek. Egy minimális "library"-t ami tartalmazná a tiszta program indítást és leállítást, valamint az alap memória menedzsment (foglalás-felszabadítás) és I/O (betöltés-mentés) hívásokat.

Offline ssr86

  • EP user
  • *
  • Posts: 359
  • Country: pl
  • OS:
  • Windows NT 6.2 Windows NT 6.2
  • Browser:
  • Firefox 40.0 Firefox 40.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #87 on: 2015.September.12. 21:19:19 »
When I'm loading my main file and it takes about 3 segments of data, is it always:
loading into $f8 -> switch page1 to $f9 -> fill it -> switch page1 to $fa -> load the rest
or should I save the segment numbers somewhere, because it could load my data into $fb instead of $fa for example?

Online geco

  • EP addict
  • *
  • Posts: 5347
  • Country: hu
  • OS:
  • Linux Linux
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #88 on: 2015.September.14. 09:31:37 »
When I'm loading my main file and it takes about 3 segments of data, is it always:
loading into $f8 -> switch page1 to $f9 -> fill it -> switch page1 to $fa -> load the rest
or should I save the segment numbers somewhere, because it could load my data into $fb instead of $fa for example?
It is better to save the segment numbers if you plan to change the pages.

Offline ssr86

  • EP user
  • *
  • Posts: 359
  • Country: pl
  • OS:
  • Windows NT 6.2 Windows NT 6.2
  • Browser:
  • Firefox 40.0 Firefox 40.0
    • View Profile
Re: How to begin assembly on Enterprise
« Reply #89 on: 2015.September.14. 19:30:42 »
It is better to save the segment numbers if you plan to change the pages.
How do I get their numbers when I'm loading a single big file?