Skip to content

Commit d372d6b

Browse files
authored
Merge pull request #978 from boriel-basic/feature/banking_library
Feature/banking library
2 parents d006f46 + 3e54f79 commit d372d6b

8 files changed

Lines changed: 449 additions & 1 deletion

File tree

docs/library.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,12 @@ Will print 64 characters to a line (grid, not proportional), and 32 lines of tex
126126
Upping the standard 768 character screen to 2048 characters of text on one screen at once.
127127
Works in a similar way to print42. This version uses screen tables.
128128

129-
####Compression / Decompression Library
129+
#### Memory Banking
130+
131+
* [memorybank.bas](library/memorybank.md)
132+
<br /> Library to access RAM banks and get advantage of extra RAM in 128k models.
133+
134+
#### Compression / Decompression Library
130135

131136
* [megaLZDepack.bas](library/megalz.bas.md)
132137
<br /> Routine wrapping the megaLZ decompression algorithm.

docs/library/memorybank.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# MemoryBank
2+
3+
The MemoryBank library allows you to manage paged memory on 128K and later/compatible models.
4+
5+
This library includes three commands:
6+
- [SetBank](memorybank/setbank.md): Sets the specified bank to memory location $c000.
7+
- [GetBank](memorybank/getbank.md): Returns the memory bank that is located at memory location $c000.
8+
- [SetCodeBank](memorybank/setcodebank.md): Copies the specified memory bank to location $8000
9+
10+
Only works on 128K and later/compatible models.
11+
12+
**Danger:** If our program exceeds the address $c000 it may cause problems, use this library at your own risk.
13+
14+
15+
## Menory banks
16+
- $c000 > Bank 0 to Bank 7
17+
- $8000 > Bank 2 (fixed)
18+
- $4000 > Bank 5 (screen)
19+
- $0000 > ROM
20+
21+
Banks 2 and 5 are permanently fixed at addresses $8000 and $4000, so it is not common to use them.
22+
23+
Banks 1, 3, 5 and 7 are banks in contention with the ULA, their use is not recommended in processes requiring maximum speed.
24+
25+
## See also
26+
- [SetBank](memorybank/setbank.md)
27+
- [GetBank](memorybank/getbank.md)
28+
- [SetCodeBank](memorybank/setcodebank.md)

docs/library/memorybank/getbank.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# GetBank
2+
3+
## Syntax
4+
5+
```
6+
#include <memorybank.bas>
7+
8+
PRINT "Current bank at $c000: ";GetBank()
9+
```
10+
11+
## Description
12+
Returns the memory bank located at $c000 based on the system variable BANKM.
13+
14+
Only works on 128K and compatible models.
15+
16+
**Danger:** If our program exceeds the address $c000 it may cause problems, use this function at your own risk.
17+
18+
19+
## Memory banks
20+
- $c000 > Bank 0 to Bank 7
21+
- $8000 > Bank 2 (fixed)
22+
- $4000 > Bank 5 (screen)
23+
- $0000 > ROM
24+
25+
Banks 2 and 5 are permanently fixed at addresses $8000 and $4000, so it is not common to use them.
26+
Banks 1, 3, 5 and 7 are banks in contention with the ULA, their use is not recommended in processes requiring maximum speed.
27+
28+
29+
## Examples
30+
31+
```basic
32+
#include "memorybank.bas"
33+
34+
DIM n AS UByte
35+
36+
' Fill banks with data
37+
FOR n = 0 TO 7
38+
SetBank(n)
39+
PRINT AT n,0;"Bank: ";n;
40+
POKE $c000,n
41+
PRINT " > ";GetBank();
42+
NEXT n
43+
44+
' Read banks
45+
FOR n = 0 TO 7
46+
SetBank(n)
47+
PRINT AT n,15;PEEK($c000);
48+
NEXT n
49+
```
50+
51+
## See also
52+
- [SetBank](setbank.md)
53+
- [SetCodeBank](setcodebank.md)

docs/library/memorybank/setbank.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# SetBank
2+
3+
## Syntax
4+
5+
```
6+
#include <memorybank.bas>
7+
8+
SetBank(3)
9+
```
10+
11+
## Description
12+
Place the bank indicated by bankNumber in the memory slot between $c000 and $ffff and updates the system variable BANKM.
13+
14+
Only works on 128K and compatible models.
15+
16+
**Danger:** If our program exceeds the address $c000 it may cause problems, use this function at your own risk.
17+
18+
19+
## Memory banks
20+
- $c000 > Bank 0 to Bank 7
21+
- $8000 > Bank 2 (fixed)
22+
- $4000 > Bank 5 (screen)
23+
- $0000 > ROM
24+
25+
Banks 2 and 5 are permanently fixed at addresses $8000 and $4000, so it is not common to use them.
26+
Banks 1, 3, 5 and 7 are banks in contention with the ULA, their use is not recommended in processes requiring maximum speed.
27+
28+
29+
## Examples
30+
31+
```basic
32+
#include <memorybank.bas>
33+
34+
DIM n AS UByte
35+
36+
' Fill banks with data
37+
FOR n = 0 TO 7
38+
SetBank(n)
39+
PRINT AT n,0;"Bank: ";n;
40+
POKE $c000,n
41+
NEXT n
42+
43+
' Read banks
44+
FOR n = 0 TO 7
45+
SetBank(n)
46+
PRINT AT n,10;PEEK($c000);
47+
NEXT n
48+
```
49+
50+
## See also
51+
- [GetBank](getbank.md)
52+
- [SetCodeBank](setcodebank.md)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# SetCodeBank
2+
3+
## Syntax
4+
5+
```
6+
#include <memorybank.bas>
7+
8+
SetCodeBank(3)
9+
```
10+
11+
## Description
12+
Place the bank indicated by bankNumber in the memory slot between $c000 and $ffff and updates the system variable BANKM.
13+
This command is applicable to the architecture described in chapter 14 of the Boriel Basic for ZX Spectrum book.
14+
15+
Only works on 128K and compatible models.
16+
17+
**Danger:** If our program exceeds the address $c000 it may cause problems, use this function at your own risk.
18+
Bank 2 is destroyed in this operation, apart from the contents of $8000 to $bfff, so it should not be used.
19+
20+
21+
## Memory banks
22+
- $c000 > Bank 0 to Bank 7
23+
- $8000 > Bank 2 (fixed)
24+
- $4000 > Bank 5 (screen)
25+
- $0000 > ROM
26+
27+
Banks 2 and 5 are permanently fixed at addresses $8000 and $4000, so it is not common to use them.
28+
Banks 1, 3, 5 and 7 are banks in contention with the ULA, their use is not recommended in processes requiring maximum speed.
29+
30+
31+
## Examples
32+
33+
```
34+
#include <memorybank.bas>
35+
36+
DIM n, b AS UByte
37+
38+
' Fill banks with data
39+
FOR n = 0 TO 7
40+
SetBank(n)
41+
PRINT AT n,0;"Bank: ";n;
42+
POKE $c000,n
43+
NEXT n
44+
45+
' SetCodeBank
46+
FOR n = 0 TO 7
47+
PRINT AT n+1,16;">";n;
48+
SetCodeBank(n)
49+
IF n = 2 THEN
50+
PRINT ">SKIP";
51+
ELSE
52+
b = PEEK($8000)
53+
PRINT ">";b;
54+
IF b = n THEN
55+
PRINT ">OK";
56+
ELSE
57+
PRINT ">ERROR";
58+
END IF
59+
END IF
60+
NEXT n
61+
```
62+
63+
## See also
64+
- [SetBank](setbank.md)
65+
- [GetBank](getbank.md)

examples/memory_banking.bas

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
' ---------------------------------------------------------
2+
' - MemoryBank.bas library Test ---------------------------
3+
' ---------------------------------------------------------
4+
' Compile at 24576
5+
6+
7+
#include "memorybank.bas"
8+
9+
10+
Main()
11+
DO:LOOP
12+
13+
14+
SUB Main()
15+
CLS
16+
Test_SetBank()
17+
PAUSE 0
18+
CLS
19+
SetBankSample()
20+
END SUB
21+
22+
23+
SUB Test_SetBank()
24+
DIM n, b AS UByte
25+
26+
' SetBank and GetBank
27+
FOR n = 0 TO 7
28+
PRINT AT n+1,0;"Bank: ";n;
29+
SetBank(n)
30+
PRINT ">";GetBank();
31+
POKE $c000,n
32+
NEXT n
33+
34+
' Test banks
35+
FOR n = 0 TO 7
36+
PRINT AT n+1,9;">";n;
37+
SetBank(n)
38+
b = PEEK($c000)
39+
IF b = n THEN
40+
PRINT ">OK";
41+
ELSE
42+
PRINT ">ERROR";
43+
END IF
44+
NEXT n
45+
46+
' SetCodeBank
47+
FOR n = 0 TO 7
48+
PRINT AT n+1,16;">";n;
49+
SetCodeBank(n)
50+
IF n = 2 THEN
51+
PRINT ">SKIP";
52+
ELSE
53+
b = PEEK($8000)
54+
PRINT ">";b;
55+
IF b = n THEN
56+
PRINT ">OK";
57+
ELSE
58+
PRINT ">ERROR";
59+
END IF
60+
END IF
61+
NEXT n
62+
END SUB
63+
64+
65+
SUB SetBankSample()
66+
DIM n, b AS UByte
67+
68+
' Fill banks with data
69+
FOR n = 0 TO 7
70+
SetBank(n)
71+
PRINT AT n,0;"Bank: ";n;
72+
POKE $c000,n
73+
NEXT n
74+
75+
' Read banks
76+
FOR n = 0 TO 7
77+
SetBank(n)
78+
PRINT AT n,10;PEEK($c000);
79+
NEXT n
80+
81+
END SUB
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
' ----------------------------------------------------------------
2+
' This file is released under the MIT License
3+
'
4+
' Copyleft (k) 2023
5+
' by Juan Segura (a.k.a. Duefectu) <http://zx.duefectucorp.com>
6+
'
7+
' Memory bank switch tools
8+
' ----------------------------------------------------------------
9+
10+
#ifndef __LIBRARY_MEMORYBANK__
11+
12+
REM Avoid recursive / multiple inclusion
13+
14+
#define __LIBRARY_MEMORYBANK__
15+
16+
17+
' ----------------------------------------------------------------
18+
' Place the bank indicated by bankNumber in the memory slot
19+
' between $c000 and $ffff and updates the system variable BANKM.
20+
' Only works on 128K and compatible models.
21+
' Danger: If our program exceeds the address $c000 it may cause
22+
' problems, use this function at your own risk.
23+
' Parameters:
24+
' bankNumber (UByte): Bank number to place at $c000
25+
' ----------------------------------------------------------------
26+
SUB FASTCALL SetBank(bankNumber AS UByte)
27+
ASM
28+
; A = bankNumber to place at $c000
29+
ld d,a ; D = bankNumber
30+
ld a,($5b5c) ; Read BANKM system variable
31+
and %11111000 ; Reset bank bits
32+
or d ; Set bank bits to bankNumber
33+
ld bc,$7ffd ; Memory Bank control port
34+
di ; Disable interrupts
35+
ld ($5b5c),a ; Update BANKM system variable
36+
out (c),a ; Set the bank
37+
ei ; Enable interrupts
38+
END ASM
39+
END SUB
40+
41+
42+
' ----------------------------------------------------------------
43+
' Returns the memory bank located at $c000 based on the system
44+
' variable BANKM.
45+
' Only works on 128K and compatible models.
46+
' Returns:
47+
' UByte: Bank number placed at $c000
48+
' ----------------------------------------------------------------
49+
FUNCTION FASTCALL GetBank() AS UByte
50+
RETURN PEEK $5b5c bAND %111
51+
END FUNCTION
52+
53+
54+
' ----------------------------------------------------------------
55+
' Place the bank indicated by bankNumber in the memory slot
56+
' between $c000 and $ffff, copy the contents to $8000-$bfff and
57+
' restore the bank that was at $c000 before you started.
58+
' Only works on 128K and compatible models.
59+
' Danger: The contents of memory located between $8000 and $bfff
60+
' are lost, and if our program exceeds the address $8000 it may
61+
' cause problems, use this function at your own risk.
62+
' Parameters:
63+
' bankNumber (UByte): Bank number to place at $8000
64+
' ----------------------------------------------------------------
65+
SUB SetCodeBank(bankNumber AS UByte)
66+
DIM b AS UByte
67+
68+
b = GetBank()
69+
SetBank(bankNumber)
70+
71+
ASM
72+
; Copy from $c000-$ffff to $8000-$bfff
73+
ld hl,$c000
74+
ld de,$8000
75+
ld bc,$4000
76+
ldir
77+
END ASM
78+
79+
SetBank(b)
80+
END SUB
81+
82+
#endif

0 commit comments

Comments
 (0)