Memory management directives

RASM memory modes

By default, RASM opens a temporary memory space of 64K. You can write into it, at the end of the assembly, a binary file will be produced from the first byte written to the last!

If you open a specific memory space with the BANK directive, then RASM will switch to cartridge mode

Best practices and choice of memory mode

Always specify the type of work you want to do, there are some modes of configuration and verification of the memory.

BUILDCPR

Switches RASM to cartridge mode, BANK 0 to 31 are accessible, to override the limitation see the compilation command -xpr

BUILDTAPE

Switches RASM to tape output mode, the binary produced in the default BANK will be exported in CDT format

BUILDSNA v2

Bascule RASM en mode snapshot, l'utilisation de la mémoire peut se faire soit par BANK de 16K numérotés de 0 à 259 (mais toujours vues comme des espaces indépendants de 64K par commodité), soit par BANKSET de 64K (numérotés de 0 à 64)

L'option "v2" permet de générer des snapshots plus simples que la carte M4 saura lire, les snapshots v3 étant plutôt réservés aux émulateurs pour le moment.

BUILDZX

Switches RASM to memory snapshot mode for the ZX, accessible banks range from 0 to 7

Note: You need to use RUN directive with 2 parameters in order to set PC and SP in the snapshot!

BUILDZX
BANK 0
RUN #8000,#4000 ; entry-point #8000, stack location #4000

BUILDROM concat

Switches RASM to ROM creation mode, the concat option allows a concatenated export of the ROMs in a single file (easier to manage large projects if the emulator is smart enough to understand that you have to spread out the following ROMs)

BUILDOBJ

Switches RASM to creation mode of binary objects that can be manipulated by a link editor (prototype)

Memory compilation directives

RUN address, ga_config

The RUN directive allows RASM to modify the value of PC and ROM connections during a snapshot export, but also to specify in an AMSDOS binary export or on DSK, the start address of the binary

ORG logical_address,physical_address

The ORG directive is used to indicate the starting address of the code and data to be assembled. RASM allows the use of several ORGs within the same memory space, but it always checks that the different zones do not overlap. The logical address is the address used for jump calculations while the physical address is the actual address where the binary is written.

org #8000
ld hl,$ ; code écrit en #8000 => LD HL,#8000
org #100
nop
org #8000,$
ld hl,$ ; code writtent in #101 but with logical address #8000 => LD HL,#8000

The use of the physical address desynchronizes the logical address from the physical address, to return to the physical address, it is necessary to write

org $
org #100
nop
org #8000,$
ld hl,$ ; LD HL,#8000
org $
ld hl,$ ; LD HL,#104

ALIGN limit,filler

If the write address of the current code is not a multiple of the alignment value, the address is increased accordingly. By default, this instruction does not produce any bytes on the output. However, the workspaces are initialized to zero. It is possible to specify a fill value with the second parameter.

org #8001
align 2 ; aligner le code sur l'adresse paire suivante, ici #8002
align 256,#55 ; aligner le code sur l'adresse multiple de 256 suivante, ici #8100, et remplir l'intervale avec #55

CONFINE value

This directive ensures that the space that follows can be addressed without a high-byte change. It is a more efficient way to optimize the placement of small arrays than a memory alignment. If an alignment is performed, the directive produces a warning. The value of the parameter is in fact between 1 and 256

LIMIT limit

This directive allows to impose a lower assembly limit than the 65536 bytes. To protect a memory area, it is preferable to use the PROTECT

PROTECT start_address,end_address

This directive allows to prevent the writing of data in the area delimited by the parameters start and end of the current memory space. It is possible to define as many exclusion zones as you want for the same memory space. These spaces cannot overlap. If data is written to them during assembly, an error will be generated.

SUMMEM start_address,end_address

This directive calculates the sum of the bytes between address_start and address_end and writes the result to the location of the directive. The calculation is done on the current bank and the result is 1 byte.

XORMEM start_address,end_address

This directive is similar to SUMMEM but applies the XOR operator to the bytes between address_start and address_end and writes the result to the location of the directive. The calculation is done on the current bank and the result is 1 byte.

checkrom
xor a ; initialiser le XORMEM
ld hl,0
ld bc,#1000
.computexor
xor (hl)
inc hl
ld d,a
dec bc
ld a,b
or c
ld a,d
jr nz,.computexor
ld hl,checksum
cp (hl)
jr nz,rom_KO
jr rom_OK
checkum xormem 0,#1000

CIPHERMEM start_address,end_address,method,key

Data encryption function

  • The first method is initialized on the first byte and then XORs all the values of the interval.
  • The second method initializes on the low weight of the current address, this allows the first byte not to be in clear, except for a starting address multiple of 256!
  • The third method XORs each value with the low weight of their respective address

BANK management

RASM allows you to work in as many memory spaces as you want. To open a 64K memory space (there is always one open by default), we use the BANK directive without any parameter. To associate a memory space with ROM or RAM, we can use any of the 256 available slots, and even 260 in snapshot mode (64K+4M)

BANK number

Selecting a bank number will set RASM to cartridge mode by default. If you want to access the banks of a snapshot or the ROMs, you must first declare your intention with the BUILDSNA or BUILDROM commands. The cartridge mode is basically limited to 32 ROMs. If you exceed ROM 31, RASM will automatically switch to extended cartridge mode like XPR (experimental and only supported under the hood ;)

Using BANK without parameter will open a new temporary space of 64K which will be "lost" except if you use SAVE directive obviously

WARNING: Select a BANK always open a 64K memory space whereas only 16K will be written in ROM/cartridge/snapshot mode. To let you compile at any address, the beginning of this 16K space will be the first written byte. I recommend you to read the output log to check the start address. If you need to start your code/data after the logical address of the ROM/RAM bank, you may output a NOP at the beginning (common values are 0, #4000,#8000, #C000 …)

REBANK

This directive allows you to return to the previous bank (whether it is static or temporary). There is no history, only the previous bank used is known.

BANKSET number

Using this directive let you gather RAM bank by 64K set (bank 0,1,2,3 together, …) when using BUILDSNA directive. Memory space will be absolute whereas BANK is always relative to the first byte written.

ROMBANK number|Lower

When using BUILDSNA directive, BANK and BANKSET let you compile in RAM up to 4160k
You may compile in ROM with ROMBANK directive
New chunks will be added to the SNA file. See with your favorite emulator dealer ;)

you may see Super snapshot section

ROMBANK n ;  with a value from 0 to 255 let you compile in one of the 256 standard CPC ROM
ROMBANK lower ; compile in lower ROM

{BANK} prefix

At any time, you can prefix a label with the {BANK} tag which will return the ROM number, useful for generic toggles.

BANK 0
ld a,{bank}hello ; LD A,1 car le label hello est en BANK 1
BANK 1
hello nop

{PAGE} prefix

At any time, you can prefix a label with the {PAGE} tag. Instead of returning the value of the label, you will have the 16-bit value to send to the Gate Array to connect the correct memory page

BANK 0
ld bc,{page}hello ; LD BC,#7FC5
BANK 5
hello nop

{PAGESET} prefix

Similar to the {PAGE} prefix, the {PAGESET} prefix returns the value to give to the Gate Array to connect the 64K of the corresponding BANKSET to the BANK

Thus, a PAGESET request on a label located in the 64K extension of a 6128 will return #7FC2

Snapshot dedicated directives

SETCPC model

Choose CPC model

  • 0 : CPC 464
  • 1 : CPC 664
  • 2 : CPC 6128
  • 4 : 464 Plus
  • 5 : 6128 Plus
  • 6 : GX-4000

SETCRTC model

Choose the CRTC model for the snapshot. The allowed values are from 0 to 4. As a reminder, CPCs have CRTC 0,1,2 or 4 and Plus or GX-4000 have all CRTC 3

SNASET param

SETSNA registre, valeur ; usage à 2 paramètres
SETSNA CRTC_REG, index, valeur ; usage à 3 paramètres

Different parameters of the snapshot are accessible in writing with 2 parameters, the register and the value:
Z80_AF, Z80_F, Z80_A, Z80_BC, Z80_B, Z80_C, Z80_DE, Z80_E, Z80_D, Z80_HL, Z80_H, Z80_L, Z80_I, Z80_R, Z80_IFF0, Z80_IFF1, Z80_IX, Z80_IY
Z80_IXL, Z80_IXH, Z80_IYL, Z80_IYH, Z80_SP, Z80_PC
Z80_AFX, Z80_FX, Z80_AX, Z80_BCX, Z80_BX, Z80_CX, Z80_DEX, Z80_EX, Z80_DX, Z80_HLX, Z80_HX, Z80_LX
GA_PEN, GA_ROMCFG,GA_RAMCFG,CRTC_SEL,ROM_UP,PPI_A,PPI_B,PPI_C,PPI_CTL,PSG_SEL
CPC_TYPE,INT_NUM,FDD_MOTOR,FDD_TRACK,CRTC_TYPE,CRTC_HCC,CRTC_CLC,CRTC_RLC,CRTC_VAC
CRTC_HSWC,CRTC_VSWC,CRTC_STATE,GA_VSC,GA_ISC,INT_REQ

The Gate Array, CRTC and AY registers are accessed using 3 parameters: The component, the register index, and the value
GA_PAL, CRTC_REG, PSG_REG

Refer to the documentation of the snapshot format to find your way around ;)

Sauf mention contraire, le contenu de cette page est protégé par la licence Creative Commons Attribution-ShareAlike 3.0 License