Autor Wątek: Proste i przyjemne procedurki asemblerowe dla początkujących  (Przeczytany 36126 razy)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4540
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #90 dnia: 2014.03.10, 09:27:07 »
Abrimaal: Nie wiem czy dobrze zrozumiałem intencje, ale może coś takiego:

LB B,8
XOR A
loop:
ADD A,4 ; gdzie w A jest licznik
...
DJNZ loop

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #91 dnia: 2014.03.10, 10:10:49 »
Może chce sobie tą wartość wyliczać ?
To prawie dobrze tylko po co ruszać CY i na końcu brakuje AND
LD A,B
RLCA
RLCA
CPL
AND 31
W wyniku mamy wartości A 0..27 dla B 8..1

EDIT: Sorki, poprawiłem. Za dużo piszę dla 8051, a tam są trochę inne nazwy. Na nieszczęście niektóre mają ten sam mnemonik, a inną funkcję.
« Ostatnia zmiana: 2014.03.10, 10:44:37 wysłana przez pear »
ZX/Enterprise/CPC/Robotron/C128D

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #92 dnia: 2014.03.12, 21:03:52 »
Podrzucę coś aby temat nie umarł.

Lustrzane odbicie bajta:
LD A,N
LD B,0
REPT 8
RLCA
RR B
ENDR
LD A,B
 

Tak naprawdę na to powinna być osobna specjalna instrukcja Z80 ale niestety nie ma :)

Można natomiast ze sporą oszczędnością czasową korzystać z wcześniej przygotowanej tablicy 256 bajtów ulokowanej pod "równym" adresem (czyli początek tablicy: H=cośtam, L=0), np. :

LD A,N
LD H,254
LD L,A
LD A,(HL)

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #93 dnia: 2014.03.13, 09:36:33 »
No i kicha. Przez kilka godzin się zastanawiałem, czy jest jakiś krótszy albo szybszy sposób.
No i chyba zmarnowałem ten czas, bo te dwa sposoby już podałeś :)
Jedyne co zyskałem, to zrobiłem sobie tylko poranną rozgrzewkę :)
ZX/Enterprise/CPC/Robotron/C128D

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4540
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #94 dnia: 2014.03.13, 09:48:34 »
Tablicowanie różnych czasochłonnych obliczeń jest już standardem, zwłaszcza jak zajmuję niewiele miejsca. Zdarza się tez że tablicuje się dane przy inicjacji programu - np w intrach z organiczeniami wielkości.


RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #95 dnia: 2014.03.13, 10:20:17 »
Cytuj
No i kicha. Przez kilka godzin się zastanawiałem, czy jest jakiś krótszy albo szybszy sposób.
No i chyba zmarnowałem ten czas, bo te dwa sposoby już podałeś :)
Jedyne co zyskałem, to zrobiłem sobie tylko poranną rozgrzewkę :)

Pear, jak chcesz możesz spróbować takie zadanie:

- wyznaczamy na ekranie jego fragment (parametry: współrzędne rogu, szerokość wysokość) i robimy na ekranie lustro tego fragmentu.

Mam taki kod w jednej mojej grze więc wkrótce mogę podrzucić ale na pewno coś w nim można zoptymalizować.


Phonex

  • *****
  • Wiadomości: 1261
  • Miejsce pobytu:
    Warszawa
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #96 dnia: 2014.03.13, 11:16:04 »
No i kicha. Przez kilka godzin się zastanawiałem, czy jest jakiś krótszy albo szybszy sposób.
...
Ja też nie wymyśliłem szybszego sposobu na odbicie lustrzane. W HyperDrive mam tak:
  LD A, n
  LD BC, $0800
loop
  RRA
  RL C
  DJNZ loop
  LD A, C
Wolniej, ale nie szkodzi, bo jest to procedurka tworząca "tablicę" w pewnym sensie, na początku tworzony jest podwójny zestaw fontów - normalny plus odbity w poziomie, dla wygody przeplecione - bajt normalny, bajt odbity. Odbity w pionie jest tworzony na bieżąco w trakcie kopiowania znaków.

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #97 dnia: 2014.03.13, 20:17:03 »
Jak obiecałem - lustrzane odbicie fragmentu ekranu.

To już nie jest takie krótkie i dla początkującego może być trudne ale może komuś się przyda.

Komentarze pisałem kiedyś tam po angielsku jak kogoś coś zaciekawi a nie będzie wiedział - niech pyta :)
Wywołanie np:
LD HL,16384
LD BC 5*256+5
CALL MirrorArea1
      

MirrorArea1
PUSH HL  ;area corner
PUSH BC   ;size in chars (B-width,C-height)


LD A,L ; A=l0
ADD A,B ; A=l0+B
DEC A ; A=l0+B-1
LD E,A ; E=l0+B-1
LD D,H

;if B is even (E.g. 8)the loop should be egzecuted B/2 times(4)
;if B is odd  (E.g. 11)the loop should be egzecuted B/2+1 times(6)

  XOR A;
  SRL B
  ADC A,B
  LD B,A

;mirrors one line of characters
MirrorArea2
PUSH BC
PUSH HL
PUSH DE

LD C,8

;mirrors 2 characters
MirrorArea3
LD A,(HL) ;byte with address in HL is mirrored and stored in B
LD B,0
              REPT 8
RLCA
RR B
              ENDR

LD A,(DE)
PUSH BC
LD C,0
              REPT 8
RLCA
RR C
              ENDR
POP BC ;byte with address in DE is mirrored and stored in A


LD (HL),A
LD A,B
LD (DE),A  ;mirrored HL and DE bytes are swapped
INC H
INC D        ;nex pixel line           

DEC C
JR NZ, MirrorArea3

POP DE
POP HL
INC L
DEC E ; goes to another pair of chars

POP BC
DJNZ MirrorArea2

POP BC
POP HL

;goes to another line of chars
LD A,L
ADD A,32
LD L,A

;checks if mirrored line goes to next screen segment
JR NC, MirrorArea4
LD A,H
ADD A,8
LD H,A

MirrorArea4
DEC C ; decreases number of lines to do
JR NZ, MirrorArea1 ; begin routine from the start for another char line
              RET

sect0r

  • *****
  • Wiadomości: 698
  • Miejsce pobytu:
    Oltedal/NO
  • speccyholic
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #98 dnia: 2014.03.14, 22:45:54 »
Animacja na 128k. Na razie po angielsku, może kiedyś ktoś na emeryturze przetłumaczy.
128 ANIMATION
from ZX Computing, December 1986

Toni Baker shows how the 128's extra memory
can be used for super smooth animation.


As I sit here at my TV screen I am looking at an amazing effect which
I would not have thought possible only a few months ago. A
multi-faceted spiked shape is rotating before my eyes, taking about
five seconds for each revolution. The shape - which can only be
adequately described as a first-stellated dodecahedron - is drawn as a
framework, so that I can see the back of the shape as well as the
front. It's rather incredible - but beautiful.

But, what is most astonishing of all is that the effect is being
produced by none other than the ZX Spectrum! The secret lies in the
vast untapped resources of memory on the Spectrum 128, making It
possible to store whole screens, and recall them in sequence. Full
screen high resolution animation is at last possible.

Even more astonishing is the knowledge that the BASIC program which
drew the individual frames was knocked up in only a few hours. The
skeletal appearance of the rotating figure is a consequence of the
simplicity of the BASIC program. Had I spent a few days playing with
an art studio program I could have achieved full colour shading with
light glinting off each facet as it passes the screen - but that kind
of modification I shall leave to you. There are many methods of
drawing screen pictures, but the animation effect was produced by a
little piece of machine code of my own.


Memory map

To understand how the program works it is necessary to know all about
the organisation of the memory on the Spectrum 128. This is very
simple, so I shall now explain it. Memory on the 128 is arranged in
PAGES. There are eight such pages, numbered from zero to seven, and
each page of memory contains 16K. Hence we have 16 * 8 = 128K of
memory altogether. In addition there are two ROMs, but these aren't
important as far as this program is concerned.

Addresses in paged memory begin at C000 and end at FFFF. Thus for each
page of RAM the addresses overlap. Address CDEF on page zero is not
the same thing as address CDEF on page one. They are different
locations, despite having the same address. How then is it possible to
access all of this memory if it's all superimposed on top of itself
with the same address referring to any one of eight pages?

The answer is a technique called PAGING. Only one 16K page may be
"paged in" at a time. "Paged in" means that a page may be accessed -
it may be PEEKed or POKEd or used in the normal way. If a page is NOT
paged in then it may not be accessed at all (with just two exceptions
- which we'll come to later).

Because the addresses overlap, only one page may be paged in at a
time. At all times, one of the pages will be paged in. When you use
the computer normally, either in BASIC or machine code then page zero
will be paged in, and it is important for any machine code program to
restore page zero before returning to BASIC.

As traditional machine- codeists will know, memory on the Spectrum
appears to start at 4000h and go continuously all the way up to FFFF,
and then stop. Below 4000h is the ROM, or at least one of the ROMs!
But appears is the operative word. Memory is organised in eight 16K
pages as I've explained, and the appearance of a continuous stretch of
RAM from 4000h to FFFF is a 48K illusion, and it's all brought about
by hardware, not software.


Pages

The first chunk of memory runs from 4000h to 7FFF. This chunk is in
fact RAM page five! The second chunk runs from 8000h to BFFF - this is
RAM page two! The last chunk, which runs from C000 to FFFF is RAM page
zero. In practice this means that If you page in RAM page five then
addresses C000 to FFFF will access precisely the same memory locations
as addresses 4000 to 7FFF. POKEing an address in the range C000 to
FFFF will actually POKE the corresponding address in the range 4000 to
7FFF. In a similar fashion, if page two is paged in then PEEKing an
address in the range C000 to FFFF will PEEK the corresponding address
in the range 8000 to BFFF. Thus the appearance of continuity is
maintained. For the machine code programmer it means that pages two
and five are special. They appear to be fixed in memory, and have
fixed addresses less than C000. Pages two and five are, in fact,
always paged in, and this is an advantage.

Page five is special in another way too - a more familiar way. It
stores the screen. POKEing an address in the range 4000 to 57FF (or an
address in the range C000 to D7FF when page five is paged in) will
directly POKE the screen. This you know, but the Spectrum 128 has not
one but TWO memory mapped screens. Let us for a while explore this concept.


Screens

There are two screens, but only one of them may be visible on your TV
at any one time. Normally this is screen zero. Screen zero is said to
be ACTIVE whenever its contents appear on the TV, and similarly screen
one is said to be ACTIVE whenever ITS contents appear on the TV.
Screen one is stored in page seven, and this is a hardware
manifestation, not a software one, so you cannot change the location
of screen one. In this way page seven is special too. Locations C000
to D7FF store the screen bytes, while locations D800 to DAFF store the
attributes, but remember these addresses refer to RAM page seven, not
to RAM page zero, so it is not sufficient to POKE the addresses. Page
seven must be paged in first.

As far as the screens are concerned, it doesn't make any difference
which page is paged in. Screen zero or screen one may be active
regardless of whichever page of RAM is paged in. Only one screen may
be active at a time (fairly obviously), and it is impossible to
deactivate both screens at once - so either one or the other will
always be showing on the TV.

This means that it is possible to create flicker free animation! If
you draw on screen one whilst screen zero is active then only screen
zero will appear on the screen. Once the drawing is complete then you
can activate screen one and the TV picture will change INSTANTLY!!!
Now, with screen one active, you can draw on screen zero - only screen
one (the previously completed drawing) will be showing on the TV. When
this drawing is complete you can reactivate screen zero. Once again
the TV image will change INSTANTLY with no flicker whatsoever. This,
then, is the principle of my program.

When we write Spectrum 128 addresses down it is conventional to use a
five digit hexadecimal number, rather than a four digit number. The
first digit refers to the RAM page number. In this way I could
uniquely refer to address BEAD on page four as address 48EAD. This
would be distinct from, say, 6BEAD, which refers to address BEAD on
RAM page six. Whilst the machine code instruction set makes it
impossible to refer to such locations directly (eg LD A,(4C000) is
impossible) it is nonetheless a useful notation for we human beings.
In this notation we could say that screen one occupies addresses 7C000
to 7DAFF inclusive (including the attribute bytes).

This notation has its disadvantages too. Because RAM page five is
permanently mapped in at 4000 to 7FFF then we can describe the
position of screen zero in one of two different ways - either as 4000
to 5AFF, or as 50000 to 5DAFF. Both of these descriptions refer to the
same chunk of memory.

For completeness, I should add that there are also two 16K ROMs,
although, as has already been stated, the ROMs aren't really relevant
to this program. The two ROMs each occupy addresses 0000 to 3FFF, so,
as with the RAM pages, only one ROM may be paged in at a time. Using
the same convention as for the RAM pages we can uniquely specify a ROM
address as a five digit hexadecimal number, so that 01234 refers to
address 1234 in ROM zero, whereas 11234 refers to address 1234 in ROM
one. Surprisingly, the ROM which appears to be paged in normally
(which you can PEEK either from BASIC or machine code) is actually ROM
page ONE, not zero. This ROM is the same as the old 16K ROM which was
present on 16K and 48K Spectrums, with just a couple of changes.

Enough of ROMs - let's get back to RAM pages and screens. Exactly HOW
do you page them? The answer is the OUT instruction, and a new system
variable called BANK_M. Its address is 5B5C (or 5DB5C to keep harping
on about the same point over and over again). Figure one will explain
exactly what each of its bits is for. In machine code it is possible
to change RAM page, or to change which screen is active, by the simple
procedure of loading BC with 7FFD, loading the A register with a value
constructed from Figure one, and then performing two steps - in this
order:
(i) Store the value from the A register in the system variable (BANK_M);
(ii) then use the machine code instruction OUT (C),A.
The order of the last two instructions is important. If you put these
the wrong way round then the system will go wrong if an interrupt
occurs between the two instructions - this way round it's quite safe.
It is also possible to change ROM page by this method, but interrupts
must be disabled whilst the last two instructions are carried out in
this case.


--

Figure 1. The meaning of the bits of the system variable BANK_M at
address 5B5C. When output to port 7FFD will change pages as follows:

 --- --- --- --- --- --- --- ---
|   |   |   |   |   |   |   |   |
 --- --- --- --- --- --- --- ---
\___ ___/ |   |   | \_____ _____/
    |     |   |   |       |
    |     |   |   |       |
    |     |   |   |       \--------  Bits 2,1,0 = RAM page currently paged in
    |     |   |   \----------------  Bit 3      = Screen number currently active
    |     |   \--------------------  Bit 4      = ROM number currently paged in
    |     \------------------------  Bit 5      = Must be reset always
    \------------------------------  Bits 7,6   = Not used

--


M/C

The program makes use of all of these techniques. The machine code
program is extraordinarily simple, provided you understand the screen
and paging system that I have just described. I have achieved
animation by storing twelve complete screen images throughout the vast
spread of memory available. The attribute bytes in this case are not
saved since they are the same for each frame, but you could adapt the
program to store the attribute bytes as well with no difficulty. I
have stored two complete frames on RAM pages zero, one, two, three,
four and six. I have not used page five because page five contains
screen zero and the BASIC program, along with the system variables,
the machine stack (following the BASIC CLEAR instruction) and so on. I
have not used page seven because page seven contains screen one and a
whole host of new system variables and stuff. Even numbered frames are
stored at address C000 on the relevant page, whIle odd numbered frames
are stored at address D800 on the same page.

Unfortunately it isn't possible to use the machine code LDIR
instruction to transfer bytes from one page of memory to another if
both pages have the same addresses. For instance suppose there were a
frame stored at address 4C000, and I wished to transfer it to address
7C000. The LDIR instruction is not possible. It is possible to load
one byte at a time, provided you change pages between the fetch and
the store, and then back again afterwards, but this takes a
phenomenally long time in machine code terms. To get round the problem
I have made use of a temporary buffer at address 6800 (that is 5E800).
The above example would be solved by paging in page four, using LDIR
to transfer the frame from 4C000 down to 6800, and then paging in page
seven and using LDIR once more - this time to transfer from the buffer
at 6800 up to 7C000.

The machine code is in three parts. It is stored at address B000,
which corresponds to address 2F000. Note that although page two is in
fact used to store screens, these screens occupy locations 2C000 to
2EFFF only. Locations above this are free for machine code and will
not be overwritten by the various frames.


Page A

The first part of the code is called PAGE_A (address B001). It pages
in the required RAM page and activates the required screen, as
specified by the A register, but without changing the current ROM.
This is quite boringly simple. The second piece of code is STORE_FRAME
(address B011) and is called from BASIC to transfer the image
currently on the screen (screen zero that is - the normal screen used
by BASIC) into its specific place in memory. The last piece of code is
called ANIMATE (address B03D) and it is this program which animates
the twelve stored frames at a rate of twelve frames per second. This
rate is completely flicker free and gives one second of continuous
full screen free flowing movement. If the twelve frames are designed
to repeat in a cycle, as in my example, then you have a cycle of
continuous movement which goes on forever. Fortunately my program does
allow you to break out by pressing BREAK.

The BASIC which I have included is an example of how to use the
ANIMATE routine. The outer FOR/NEXT loop, FOR I = 0 TO 11, will draw a
quite pretty geometric figure from twelve different angles. Line 320
will call the machine code STORE_FRAME routine which will store each
picture in memory once it is drawn. Finally, line 340 will call the
ANIMATE routine to set the picture moving. You can adapt, or even
change the BASIC program altogether if you like. The most impressive
thing you could do would be to create twelve full screen pictures
using an art studio type program, and save these on tape once they are
drawn. Then you can rewrite my BASIC program to simply load screen
images from tape and store them in memory one at a time as they are loaded.

This program is quite interesting from a machine code point of view,
and quite impressive from a visual point of view. It is my offering
for the Winter Solstice - a present to you all (or at least those of
you who've got a Spectrum 128 - the Plus Twos out now and you never
know - you might get one as a present this season). Happy Solstice
everyone.



#B000 00       FRAME_NO    DEFB #00
#B001 4F       PAGE_A      LD   C,A          ;C:= required page/screen number
#B002 3A5C5B               LD   A,(BANK_M)   ;A:= current  page/screen number
#B005 E6F0                 AND  #F0
#B007 B1                   OR   C
#B008 01FD7F               LD   BC,#7FFD     ;BC:= port reqd to change page/scr
#B00B 325C5B               LD   (BANK_M),A   ;Store new page/screen
#B00E ED79                 OUT  (C),A
#B010 C9                   RET

#B011 1100C0   STORE_FRAME LD   DE,#C000     ;DE:= addr of even numbered frames
#B014 3A00B0               LD   A,(FRAME_NO) ;A:= frame number to store
#B017 F5                   PUSH AF
#B018 CB3F                 SRL  A            ;Divide by two
#B01A 3002                 JR   NC,ST_FR_2
#B01C 16D8                 LD   D,#D8        ;DE:= addr of odd numbered frames
#B01E FE05     ST_FR_2     CP   #05
#B020 2001                 JR   NZ,ST_FR_3
#B022 3C                   INC  A            ;Note that page 5 must be skipped
#B023 CD01B0   ST_FR_3     CALL PAGE_A       ;Select RAM page A/Screen zero
#B026 210040               LD   HL,#4000     ;HL: points to screen zero
#B029 010018               LD   BC,#1800
#B02C EDB0                 LDIR              ;Store screen in memory
#B02E AF                   XOR  A            ;A:= 00
#B02F CD01B0               CALL PAGE_A       ;Restore RAM page zero/Screen zero
#B032 F1                   POP  AF           ;A:= frame number
#B033 3C                   INC  A            ;A:= next frame number
#B034 FE0C                 CP   #0C
#B036 2001                 JR   NZ,ST_FR_4   ;Jump unless all frames stored
#B038 AF                   XOR  A            ;In which case start again
#B039 3200B0   ST_FR_4     LD   (FRAME_NO),A ;Store new frame number
#B03C C9                   RET               ;Return

#B03D 3E07     ANIMATE     LD   A,#07
#B03F CD01B0               CALL PAGE_A       ;Store RAM page 7/Screen zero
#B042 210058               LD   HL,#5800     ;HL: points to attribute file
#B045 1100D8               LD   DE,#D800     ;DE: points to screen 1 attributes
#B048 010003               LD   BC,#0300
#B04B EDB0                 LDIR              ;Copy attributes into screen 1
#B04D 76       ANIM_LOOP   HALT              ;Wait till next frame
#B04E 2100C0               LD   HL,#C000     ;HL:= addr of even numbered frames
#B051 3A00B0               LD   A,(FRAME_NO) ;A:= frame number to display
#B054 F5                   PUSH AF
#B055 17                   RLA
#B056 17                   RLA
#B057 17                   RLA
#B058 E608                 AND  #08
#B05A 4F                   LD   C,A          ;C:= 00 (even frames) or 08 (odd)
#B05B F1                   POP  AF
#B05C F5                   PUSH AF
#B05D CB3F                 SRL  A            ;A:= page number on which this
                                              frame is stored
#B05F 3002                 JR   NC,ANIM_2
#B061 26D8                 LD   H,#D8        ;HL:= addr of odd numbered frames
#B063 FE05     ANIM_2      CP   #05
#B065 2001                 JR   NZ,ANIM_3
#B067 3C                   INC  A            ;Note that page 5 must be skipped
#B068 B1       ANIM_3      OR   C            ;Incorporate screen bit
#B069 C5                   PUSH BC
#B06A CD01B0               CALL PAGE_A       ;Select RAM page on which frame is
                                             ;stored, and either screen 0 (even
                                             ;frames or screen 1 (odd frames)
#B06D 110068               LD   DE,#6800
#B070 010018               LD   BC,#1800
#B073 EDB0                 LDIR              ;Copy frame into buffer
#B075 C1                   POP  BC
#B076 79                   LD   A,C          ;A:= 00 (evens) or 08 (odds)
#B077 0F                   RRCA
#B078 0F                   RRCA
#B079 EE07                 XOR  #07
#B07B B1                   OR   C            ;A:= 07 (evens) or 0D (odds)
#B07C CD01B0               CALL PAGE_A       ;For even frames select screen 0
                                             ;and RAM page 7; for odd frames
                                             ;select screen 1 and RAM page 5
#B07F 210068               LD   HL,#6800     ;HL: points to copy of frame to
                                             ;display
#B082 1100C0               LD   DE,#C000     ;DE:= address of screen (Note that
                                             ;address C000 on RAM page 5 is the
                                             ;same as address 4000 normally)
#B085 010018               LD   BC,#1800
#B088 EDB0                 LDIR              ;Copy the frame into the screen
                                             ;not being displayed
#B08A F1                   POP  AF           ;A:= frame number
#B08B 3C                   INC  A            ;A:= next frame number
#B08C FE0C                 CP   #0C
#B08E 2001                 JR   NZ,ANIM_4    ;Jump unless all frames displayed
#B090 AF                   XOR  A            ;In which case start again
#B091 3200B0   ANIM_4      LD   (FRAME_NO),A ;Store new frame number
#B094 CD541F               CALL BREAK_KEY    ;Is BREAK key pressed?
#B097 38B4                 JR   C,ANIM_LOOP  ;Loop back to display next frame
                                             ;unless BREAK pressed
#B099 AF                   XOR  A
#B09A CD01B0               CALL PAGE_A       ;Restore RAM page 0/Screen 0
#B09D CF                   RST  #08          ;Generate error report
#B09E 0C                   DEFB #0C          ;"D BREAK - CONT repeats"
Szarak # DivIDE+ # MasakratorFM DeluXe by Zaxon

trojacek

  • *****
  • Wiadomości: 6846
  • Miejsce pobytu:
    Warszawa
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #99 dnia: 2014.03.15, 00:14:55 »
Moim zdaniem to jedynie opis metody zwanej page flipping lub ping-pong buffering.

Ilyad

  • *****
  • Wiadomości: 580
  • Miejsce pobytu:
    Białystok, IV Rzesza Pospolita
Odp: Proste i przyjemne procedurki asemblerowe dla początkujących
« Odpowiedź #100 dnia: 2014.04.27, 12:42:10 »
użyteczna stronka w języku polskim do nauki assemblera z-80:

http://edu.i-lo.tarnow.pl/inf/retro/004_z80_inst/index.php
ZX-81, ZX-Pand AY, 48k "gumiak", 48K+, 128K + "Toster", +2 "szarak" 1024k Profi, Masakrator FM, DivIDE 2K11, ZX Evolution rev. C, ZX-Uno, C64, C16 64K, Plus4 + 1541 Ultimate II + SD2IEC