diff --git a/docs/api/target-platforms.md b/docs/api/target-platforms.md index a71b1725..1b139102 100644 --- a/docs/api/target-platforms.md +++ b/docs/api/target-platforms.md @@ -3,8 +3,8 @@ # Target platforms Currently, Millfork supports creating disk- or tape-based programs -for Commodore, Apple, BBC and Atari 8-bit computers, NEC PC-88, ZX Spectrum 48k, -and cartridge-based programs for Famicom/NES and Atari 2600, +for Commodore, Apple, BBC and Atari 8-bit computers, NEC PC-88, ZX Spectrum 48k, CP/M, +and cartridge-based programs for Commodore 64, VIC-20, Famicom/NES and Atari 2600, but it may be expanded to support other 6502-based and Z80-based platforms in the future. To add a custom platform yourself, see [the custom platform adding guide](./custom-platform.md). @@ -15,6 +15,10 @@ The following platforms are currently supported: * `c64` – Commodore 64 +* `c64_crt8k` – Commodore 64, 8K ROM cartridge + +* `c64_crt16k` – Commodore 64, 16K ROM cartridge + * `c64_scpu` – Commodore 64 with SuperCPU in emulation mode * `c64_scpu16` – Commodore 64 with SuperCPU in native, 16-bit mode (very buggy) @@ -33,6 +37,8 @@ Read [the LUnix programming guide](./lunix-programming-guide.md) for more info. * `vic20_8k` – Commodore VIC-20 with 8K or 16K memory expansion +* `vic20_a000` – Commodore VIC-20, 8K ROM cartridge at $A000 + * `c128` – Commodore 128 in its native mode * `pet` – Commodore PET @@ -55,7 +61,7 @@ Read [the BBC Micro programming guide](./bbcmicro-programming-guide.md) for more The compiler only emits raw binaries, not disk images. Read [the Apple 2 programming guide](./apple2-programming-guide.md) for more info. -* `pc88` – NEC PC-88 (no ROM routines are mapped yet) +* `pc88` – NEC PC-88 * `zxspectrum` – Sinclair ZX Spectrum 48k diff --git a/docs/index.md b/docs/index.md index 174cee13..3f2aa70d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,8 +39,12 @@ * [`stdlib` module](stdlib/stdlib.md) +* [Modules for reading input devices](stdlib/input.md) + * [Other cross-platform modules](stdlib/other.md) +* [Definitions available on only some platforms](stdlib/frequent.md) + * [C64-only modules](stdlib/c64.md) * [NES-only modules](stdlib/nes.md) diff --git a/docs/stdlib/c64.md b/docs/stdlib/c64.md index d159ae04..867feb1d 100644 --- a/docs/stdlib/c64.md +++ b/docs/stdlib/c64.md @@ -8,16 +8,53 @@ The `c64_kernal` module is imported automatically on the C64 target. TODO -## `c64_basic` module +## c64_basic module TODO -## `c1531_mouse` module +## c64_hardware + +TODO + +## c1531_mouse The `c1531_mouse` module implements a Commodore 1531 proportional mouse driver compatible with the `mouse` module. -#### `void c1531_mouse ()` +#### `void c1531_mouse()` Updates the state of the mouse. +## c1531_mouse_default + +Defines the `c1531` module as the default module for reading mouse input. + +#### `alias read_mouse = c1531_mouse` + +## c64_joy + +The `c64_joy` module implements a joystick driver compatible with the `joy` module. + +#### `void read_joy2()` + +Reads the joystick from the port 2. + +#### `void read_joy1()` + +Reads the joystick from the port 1. + +#### `void read_also_joy2()` + +Reads the joystick from the port 2 and adds its readouts to the current readouts. + +#### `void read_also_joy1()` + +Reads the joystick from the port 1 and adds its readouts to the current readouts. + +## c64_joy2_default + +Defines the joystick in port 2 as the default joystick. + +#### `alias read_joy = read_joy2` + + diff --git a/docs/stdlib/frequent.md b/docs/stdlib/frequent.md new file mode 100644 index 00000000..1d855de7 --- /dev/null +++ b/docs/stdlib/frequent.md @@ -0,0 +1,42 @@ +[< back to index](../index.md) + +Definitions on the following list are frequently provided by the default automatically-imported modules. + +However, as they are not the part of the standard library, they might not be available on all targets: + +#### `void putchar(byte char)` + +Prints a single character. + +Available for: all computer targets. + +#### `void new_line()` + +Moves the cursor to the next line. + +Available for: all computer targets. + +#### `void bell()` + +Beeps. + +Available for: Apple 2, ZX Spectrum. + +#### `void set_bg_color(byte color)` + +Sets the screen background color. + +Available for: C64, VIC-20, C64, C264 series. + +#### `void set_border(byte color)` + +Sets the screen border color. + +Available for: VIC-20, C64, C264 series, ZX Spectrum. + +#### `const byte black, white, red, green, blue, cyan, purple, yellow` + +Various colour constants. + +Available for: VIC-20, C64, C264 series, ZX Spectrum. + diff --git a/docs/stdlib/input.md b/docs/stdlib/input.md new file mode 100644 index 00000000..f573298d --- /dev/null +++ b/docs/stdlib/input.md @@ -0,0 +1,66 @@ +[< back to index](../index.md) + +## joy + +The module contains global variables representing the state of the one-button joystick. +If the program is not using any joystick driver, the state of these variables is undefined. + +#### `sbyte input_dx` + +Horizontal joystick movement. 1 if right, -1 if left, 0 if neither. + +#### `sbyte input_dy` + +Vertical joystick movement. 1 if right, -1 if left, 0 if neither. + +#### `byte input_btn` + +1 if main button pressed, 0 id not pressed. + +#### `void reset_joy()` + +Resets the state variables. +For platforms with more than one button, this resets only the main button state. + +## null_joy_default + +This module set the default joystick to no joystick. + +#### `alias read_joy` + +## mouse + +The `mouse` module automatically imports the `x_coord` module. + +The module contains global variables representing the state of the mouse. +If the program is not using any mouse driver, the state of these variables is undefined. + +#### `x_coord mouse_x` + +Mouse X position. + +#### `byte mouse_y` + +Mouse Y position. + +#### `byte mouse_lbm` + +1 if the left mouse button is being pressed, 0 otherwise + +#### `byte mouse_rbm` + +1 if the right mouse button is being pressed, 0 otherwise + +## `x_coord` module + +#### `alias x_coord` + +The type for representing horizontal screen coordinates. +It's `byte` if the screen is 256 pixels wide or less, +or `word` if the screen is more that 256 pixels wide. + +## null_mouse_default + +This module set the default joystick to no joystick. + +#### `void read_mouse()` diff --git a/docs/stdlib/nes.md b/docs/stdlib/nes.md index 45fc60ab..15a26d92 100644 --- a/docs/stdlib/nes.md +++ b/docs/stdlib/nes.md @@ -2,13 +2,13 @@ # NES/Famicom-oriented modules -## `nes_hardware` module +## nes_hardware The `nes_hardware` module is imported automatically on NES targets. TODO -## `nes_mmc4` module +## nes_mmc4 The `nes_mmc4` module is imported automatically on the NES MMC4 target. and contains routines related to MMC4 bankswitching. @@ -37,4 +37,51 @@ Switches nametable mirroring to vertical. #### `void set_horizontal_mirroring()` -Switches nametable mirroring to horizontal. \ No newline at end of file +Switches nametable mirroring to horizontal. + +## nes_joy + +Provides an interface for reading joypads that is compatible with the `joy` module. + +#### `alias input_a = input_btn` + +1 if A button pressed, 0 id not pressed. + +#### `byte input_b` + +1 if B button pressed, 0 id not pressed. + +#### `byte input_select` + +1 if Select button pressed, 0 id not pressed. + +#### `byte input_start` + +1 if Start button pressed, 0 id not pressed. + +#### `void read_joy1()` + +Reads the joypad from the port 1. + +#### `void read_joy2()` + +Reads the joypad from the port 2. + +#### `void read_also_joy1()` + +Reads the joypad from the port 1 and adds its readouts to the current readouts. + +#### `void read_also_joy2()` + +Reads the joypad from the port 2 and adds its readouts to the current readouts. + +#### `void nes_reset_joy()` + +Resets the state variables. +Unlike `reset_joy`, this resets all the NES button states. + +## nes_joy1_default + +Defines the joystick in port 1 as the default joystick. + +#### `alias read_joy = read_joy1` diff --git a/docs/stdlib/other.md b/docs/stdlib/other.md index 666c73a4..c66f3114 100644 --- a/docs/stdlib/other.md +++ b/docs/stdlib/other.md @@ -1,6 +1,6 @@ [< back to index](../index.md) -## `stdio` module +## stdio The `stdio` module automatically imports the `string` module. It requires an implementation of `void putchar(byte a)` and therefore works only on targets with console output. @@ -14,40 +14,9 @@ Prints a string of length `len` located at address `str`. Prints a null-terminated string located at address `str`. If the string is longer than 255 bytes, then the behaviour is undefined (might even crash). -## `string` module +## string #### `byte strzlen(pointer str)` Calculates the length of a null-terminated string. If the string is longer than 255 bytes, then the behaviour is undefined (might even crash). - -## `mouse` module - -The `mouse` module automatically imports the `x_coord` module. - -The module contains global variables representing the state of the mouse. -If the program is not using any mouse driver, the state of these variables is undefined. - -#### `x_coord mouse_x` - -Mouse X position. - -#### `byte mouse_y` - -Mouse Y position. - -#### `byte mouse_lbm` - -1 if the left mouse button is being pressed, 0 otherwise - -#### `byte mouse_rbm` - -1 if the right mouse button is being pressed, 0 otherwise - -## `x_coord` module - -#### `alias x_coord` - -The type for representing horizontal screen coordinates. -It's `byte` if the screen is 256 pixels wide or less, -or `word` if the screen is more that 256 pixels wide. \ No newline at end of file diff --git a/docs/stdlib/stdlib.md b/docs/stdlib/stdlib.md index 9453a7e0..2ebf8269 100644 --- a/docs/stdlib/stdlib.md +++ b/docs/stdlib/stdlib.md @@ -1,6 +1,6 @@ [< back to index](../index.md) -## `stdlib` module +## stdlib The `stdlib` module is automatically imported on most targets. @@ -30,4 +30,4 @@ Returns an ASCII representation of the lower nibble of the given byte. #### `macro asm void panic()` -Crashes the program. \ No newline at end of file +Crashes the program. diff --git a/examples/README.md b/examples/README.md index 23fa8b62..3d486a7e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,9 +2,11 @@ ## Cross-platform examples -* [Hello world](hello_world/hello_world.mfk) (C64/C16/PET/VIC-20/Atari/Apple II/BBC Micro) – simple text output +* [Hello world](hello_world/hello_world.mfk) (C64/C16/PET/VIC-20/Atari/Apple II/BBC Micro/PC-88) – simple text output -* [Text encodings](c64/text_encodings.mfk) (C64/ZX Spectrum)– examples of text encoding features +* [Text encodings](c64/text_encodings.mfk) (C64/ZX Spectrum) – examples of text encoding features + +* [Bell](apple2/bell.mfk) (Apple II/ZX Spectrum) – a program that goes \*ding!\* ## Commodore 64 examples @@ -30,10 +32,6 @@ * [MMC4 example](nes/nestest_mmc4.mfk) – the same thing as above, but uses a MMC4 mapper just to test bankswitching -## Apple II examples - -* [Bell](apple2/bell.mfk) – a program that goes \*ding!\* - ## Atari 2600 examples * [Colors](vcs/colors.mfk) – simple static rasterbars diff --git a/examples/hello_world/hello_world.mfk b/examples/hello_world/hello_world.mfk index 3302ca86..9e8c610f 100644 --- a/examples/hello_world/hello_world.mfk +++ b/examples/hello_world/hello_world.mfk @@ -5,9 +5,21 @@ import stdio array hello_world = "hello world" -void main(){ +void main() { + +#if CBM_64 || CBM_264 + set_bg_color(green) +#endif +#if CBM_64 || CBM_264 || ZX_SPECTRUM + set_border(red) +#endif + putstr(hello_world, hello_world.length) - putchar(13) + new_line() putstrz("hello world again"z) + +#if not(CPM) while(true){} +#endif + } \ No newline at end of file diff --git a/examples/nes/nestest.mfk b/examples/nes/nestest.mfk index 3338572d..eafe1ea3 100644 --- a/examples/nes/nestest.mfk +++ b/examples/nes/nestest.mfk @@ -1,6 +1,8 @@ // Based upon the example code from NES 101 tutorial by Michael Martin // compile with -t nes_small +import nes_joy1_default + void main() { init_graphics() init_input() @@ -99,17 +101,14 @@ void update_sprite() { } void react_to_input() { - strobe_joypad() - if read_joypad1() & 1 != 0 { // A button + read_joy() + if input_a != 0 { // A button reverse_dx() } - read_joypad1() // B button - read_joypad1() // Select button - read_joypad1() // Start button - if read_joypad1() & 1 != 0 { // Up button + if input_dy < 0 { // Up button if oam_buffer[0] > 7 { oam_buffer[0] -= 1} } - if read_joypad1() & 1 != 0 { // Down button + if input_dy > 0 { // Down button if oam_buffer[0] < 223 { oam_buffer[0] += 1} } } diff --git a/include/a8_kernel.mfk b/include/a8_kernel.mfk index 98b7c8c9..ee9d899a 100644 --- a/include/a8_kernel.mfk +++ b/include/a8_kernel.mfk @@ -4,11 +4,15 @@ #endif asm void putchar(byte a) { - tax + ? tax lda $347 pha lda $346 pha - txa + ? txa rts -} \ No newline at end of file +} + +inline void new_line() { + putchar($9b) +} diff --git a/include/apple2_kernel.mfk b/include/apple2_kernel.mfk index d8e1396f..36a95d03 100644 --- a/include/apple2_kernel.mfk +++ b/include/apple2_kernel.mfk @@ -9,3 +9,4 @@ array hires_page_2 [$2000] @$4000 asm void bell() @$FBE4 extern asm void putchar(byte a) @$FDED extern +asm void new_line() @$FC62 extern diff --git a/include/bbc_kernal.mfk b/include/bbc_kernal.mfk index 232bd596..b8a57d4b 100644 --- a/include/bbc_kernal.mfk +++ b/include/bbc_kernal.mfk @@ -6,3 +6,7 @@ // OSASCI. Write a character (to screen) from A plus LF if (A)=&0D // Input: A = Byte to write. asm void putchar(byte a) @$FFE3 extern + +inline void new_line() { + putchar(13) +} diff --git a/include/c128_kernal.mfk b/include/c128_kernal.mfk index f30fbcd0..ecde3b35 100644 --- a/include/c128_kernal.mfk +++ b/include/c128_kernal.mfk @@ -6,4 +6,8 @@ // CHROUT. Write byte to default output. (If not screen, must call OPEN and CHKOUT beforehands.) // Input: A = Byte to write. -asm void putchar(byte a) @$FFD2 extern \ No newline at end of file +asm void putchar(byte a) @$FFD2 extern + +inline void new_line() { + putchar(13) +} diff --git a/include/c1531_default.mfk b/include/c1531_default.mfk new file mode 100644 index 00000000..3589a572 --- /dev/null +++ b/include/c1531_default.mfk @@ -0,0 +1,3 @@ +import c1541 + +alias read_mouse = c1531_mouse diff --git a/include/c264_kernal.mfk b/include/c264_kernal.mfk index 12ef5bcc..1a25ede2 100644 --- a/include/c264_kernal.mfk +++ b/include/c264_kernal.mfk @@ -5,4 +5,8 @@ // CHROUT. Write byte to default output. (If not screen, must call OPEN and CHKOUT beforehands.) // Input: A = Byte to write. -asm void putchar(byte a) @$FFD2 extern \ No newline at end of file +asm void putchar(byte a) @$FFD2 extern + +inline void new_line() { + putchar(13) +} diff --git a/include/c264_ted.mfk b/include/c264_ted.mfk index 0fd6a750..ccc53553 100644 --- a/include/c264_ted.mfk +++ b/include/c264_ted.mfk @@ -2,6 +2,35 @@ #warn c264_ted module should be only used on C264-compatible targets #endif +byte ted_cursor_hi @$FF0C +byte ted_cursor_lo @$FF0D +byte ted_color0 @$FF15 +byte ted_color1 @$FF16 +byte ted_color2 @$FF17 +byte ted_color3 @$FF18 +byte ted_border @$FF19 +byte ted_raster_y @$FF1D +byte ted_raster_x @$FF1E + +alias ted_bg_color = ted_color0 + +macro void set_bg_color(byte color) { + ted_color0 = color +} + +macro void set_border(byte color) { + ted_border = color +} + +inline void set_ted_cursor(word position) { + ted_cursor_hi = position.hi + ted_cursor_lo = position.lo +} + +inline word get_ted_cursor() { + return ted_cursor_hi:position.lo +} + const byte black = 0 const byte white = $71 const byte red = $22 diff --git a/include/c64_joy.mfk b/include/c64_joy.mfk new file mode 100644 index 00000000..18ab9df0 --- /dev/null +++ b/include/c64_joy.mfk @@ -0,0 +1,38 @@ +// standard joystick driver for Commodore 64 + +#if not(CBM_64) +#warn c64_joy module should be only used on C64-compatible targets +#endif + +import joy +import c64_cia + +inline void read_joy2 () { + reset_joy() + read_also_joy2() +} +inline void read_joy1 () { + reset_joy() + read_also_joy1() +} +void read_also_joy2() { + poke($dc02, 0) + byte value + value = peek($dc00) + if value & 1 == 0 { input_dy -= 1 } + if value & 2 == 0 { input_dy += 1 } + if value & 4 == 0 { input_dx -= 1 } + if value & 8 == 0 { input_dx += 1 } + if value & 16 == 0 { input_btn += 1 } +} + +void read_also_joy1() { + poke($dc03, 0) + byte value + value = peek($dc01) + if value & 1 == 0 { input_dy -= 1 } + if value & 2 == 0 { input_dy += 1 } + if value & 4 == 0 { input_dx -= 1 } + if value & 8 == 0 { input_dx += 1 } + if value & 16 == 0 { input_btn += 1 } +} diff --git a/include/c64_joy2_default.mfk b/include/c64_joy2_default.mfk new file mode 100644 index 00000000..742a1169 --- /dev/null +++ b/include/c64_joy2_default.mfk @@ -0,0 +1,5 @@ +// set C64 joystick in port 2 as the default + +import c64_joy + +alias read_joy = read_joy2 diff --git a/include/c64_kernal.mfk b/include/c64_kernal.mfk index 5efc3796..efe18592 100644 --- a/include/c64_kernal.mfk +++ b/include/c64_kernal.mfk @@ -4,6 +4,10 @@ // Input: A = Byte to write. asm void putchar(byte a) @$FFD2 extern +inline void new_line() { + putchar(13) +} + // OPEN. Open file. (Must call SETLFS and SETNAM beforehands.) asm void open() @$FFC0 extern diff --git a/include/c64_vic.mfk b/include/c64_vic.mfk index 6e801a71..edc35e4d 100644 --- a/include/c64_vic.mfk +++ b/include/c64_vic.mfk @@ -131,6 +131,14 @@ macro void vic_bitmap_2000() { vic_mem |= 8 } +macro void set_bg_color(byte color) { + vic_bg_color0 = color +} + +macro void set_border(byte color) { + vic_border = color +} + // x, y < 8 // default: x=0, y=3 void vic_set_scroll(byte x, byte y) { diff --git a/include/cpm_bdos.mfk b/include/cpm_bdos.mfk index d43da432..3655ef37 100644 --- a/include/cpm_bdos.mfk +++ b/include/cpm_bdos.mfk @@ -8,10 +8,15 @@ inline asm void exit() { } inline asm void putchar (byte e) { ? mvi c, 2 - call 5 + call 5 ? ret } +inline void new_line() { + putchar(13) + putchar(10) +} + inline asm byte getchar() { ? mvi c, 1 call 5 diff --git a/include/joy.mfk b/include/joy.mfk new file mode 100644 index 00000000..7a8b78d6 --- /dev/null +++ b/include/joy.mfk @@ -0,0 +1,16 @@ +// Generic module for joystick/gamepad support + +// Horizontal movement: -1 for left, 1 for right +sbyte input_dx + +// Vertical movement: -1 for up, 1 for down +sbyte input_dy + +// Main button: 1 pressed, 0 not pressed +byte input_btn + +void reset_joy() { + input_dx = 0 + input_dy = 0 + input_btn = 0 +} \ No newline at end of file diff --git a/include/loader_a000.mfk b/include/loader_a000.mfk new file mode 100644 index 00000000..28e1c45c --- /dev/null +++ b/include/loader_a000.mfk @@ -0,0 +1,10 @@ +segment(prgrom) +array __vectors @$A000 = [ + main.addr.lo, + main.addr.hi, + main.addr.lo, + main.addr.hi +] + +segment(prgrom) +array __boot_signature @$A004 = [$41, $30, $C3, $C2, $CD] diff --git a/include/nes_joy.mfk b/include/nes_joy.mfk new file mode 100644 index 00000000..02739f5b --- /dev/null +++ b/include/nes_joy.mfk @@ -0,0 +1,47 @@ +// standard joystick driver for NES + +import joy +import nes_hardware + +alias input_a = input_btn +byte input_b +byte input_select +byte input_start + +macro void read_joy1() { + nes_reset_joy() + read_also_joy2() +} + +macro void read_joy2() { + nes_reset_joy() + read_also_joy1() +} + +void nes_reset_joy() { + input_b = 0 + input_select = 0 + input_start = 0 + reset_joy() +} + +inline void read_also_joy1() { + strobe_joypad() + __parse_nes_joypad(read_joypad1()) +} + +inline void read_also_joy2() { + strobe_joypad() + __parse_nes_joypad(read_joypad2()) +} + +void __parse_nes_joypad(byte b) { + if read_joypad1() & 1 != 0 { input_a += 1 } + if read_joypad1() & 1 != 0 { input_b += 1 } + if read_joypad1() & 1 != 0 { input_select += 1 } + if read_joypad1() & 1 != 0 { input_start += 1 } + if read_joypad1() & 1 != 0 { input_dy -= 1 } + if read_joypad1() & 1 != 0 { input_dy += 1 } + if read_joypad1() & 1 != 0 { input_dx -= 1 } + if read_joypad1() & 1 != 0 { input_dx += 1 } +} \ No newline at end of file diff --git a/include/nes_joy1_default.mfk b/include/nes_joy1_default.mfk new file mode 100644 index 00000000..7998c3d6 --- /dev/null +++ b/include/nes_joy1_default.mfk @@ -0,0 +1,5 @@ +// set NES joypad in port 1 as the default + +import nes_joy + +alias read_joy = read_joy1 diff --git a/include/null_joy_default.mfk b/include/null_joy_default.mfk new file mode 100644 index 00000000..efeb0b81 --- /dev/null +++ b/include/null_joy_default.mfk @@ -0,0 +1,5 @@ +// set no joystick as the default + +import joy + +alias read_joy = reset_joy diff --git a/include/null_mouse_default.mfk b/include/null_mouse_default.mfk new file mode 100644 index 00000000..ca083704 --- /dev/null +++ b/include/null_mouse_default.mfk @@ -0,0 +1,10 @@ +// set no mouse as the default + +import mouse + +void read_mouse() { + mouse_x = 0 + mouse_y = 0 + mouse_lbm = 0 + mouse_rbm = 0 +} diff --git a/include/pc88.ini b/include/pc88.ini index c1cbf08b..a8305f17 100644 --- a/include/pc88.ini +++ b/include/pc88.ini @@ -3,7 +3,7 @@ [compilation] arch=z80 encoding=jisx -modules=default_panic,stdlib +modules=default_panic,stdlib,pc88 [allocation] ; TODO: find a more optimal start address diff --git a/include/pc88.mfk b/include/pc88.mfk new file mode 100644 index 00000000..ac33dbb1 --- /dev/null +++ b/include/pc88.mfk @@ -0,0 +1,11 @@ + +#if not(NEC_PC_88) +#warn pc88 module should be only used on PC-88 targets +#endif + +asm void putchar(byte a) @$3e0d extern + +inline void new_line() { + putchar(13) + putchar(10) +} diff --git a/include/vic20.ini b/include/vic20.ini index 12799477..d1acb84a 100644 --- a/include/vic20.ini +++ b/include/vic20.ini @@ -2,7 +2,7 @@ arch=nmos encoding=petscii screen_encoding=petscr -modules=loader_1001,vic20_kernal,default_panic,stdlib +modules=loader_1001,vic20_kernal,vic20_hardware,default_panic,stdlib [allocation] diff --git a/include/vic20_3k.ini b/include/vic20_3k.ini index ea574329..84a7f61d 100644 --- a/include/vic20_3k.ini +++ b/include/vic20_3k.ini @@ -2,7 +2,7 @@ arch=nmos encoding=petscii screen_encoding=petscr -modules=loader_0401,vic20_kernal,default_panic,stdlib +modules=loader_0401,vic20_kernal,vic20_hardware,default_panic,stdlib [allocation] diff --git a/include/vic20_8k.ini b/include/vic20_8k.ini index 22c8e4aa..65fe5ddd 100644 --- a/include/vic20_8k.ini +++ b/include/vic20_8k.ini @@ -2,7 +2,7 @@ arch=nmos encoding=petscii screen_encoding=petscr -modules=loader_1201,vic20_kernal,default_panic,stdlib +modules=loader_1201,vic20_kernal,vic20_hardware,,default_panic,stdlib [allocation] diff --git a/include/vic20_a000.ini b/include/vic20_a000.ini new file mode 100644 index 00000000..52d160e5 --- /dev/null +++ b/include/vic20_a000.ini @@ -0,0 +1,34 @@ +; VIC-20 +; 8K ROM cartridge at $A000 + +[compilation] +arch=nmos +encoding=petscii +screen_encoding=petscr +modules=vic20_kernal,default_panic,stdlib,vic20_hardware,loader_a000 +ro_arrays=true + + +[allocation] +zp_pointers=$C1,$C3,$FB,$FD,$39,$3B,$3D,$43,$4B +segments=default,prgrom +default_code_segment=prgrom +segment_default_start=$1000 +segment_default_end=$1fff +segment_prgrom_start=$a000 +segment_prgrom_end=$bfff + +[define] +CBM=1 +CBM_VIC=1 +WIDESCREEN=0 +KEYBOARD=1 +JOYSTICKS=1 +HAS_BITMAP_MODE=1 + +[output] +style=single +format=$00,$a0,prgrom:$a000:$bfff +extension=crt + + diff --git a/include/vic20_hardware.mfk b/include/vic20_hardware.mfk new file mode 100644 index 00000000..007385eb --- /dev/null +++ b/include/vic20_hardware.mfk @@ -0,0 +1,42 @@ +#if not(CBM_VIC) +#warn vic20_hardware module should be only used on VIC-20-compatible targets +#endif + +volatile byte vic_raster @$9004 +byte vic_freq1 @$900a +byte vic_freq2 @$900b +byte vic_freq3 @$900c +byte vic_volume @$9003 +byte vic_colors @$900f + +macro void set_volume(byte volume) { + vic_volume &= $f0 + vic_volume |= volume & $f +} + +macro void set_bg_color(byte color) { + vic_colors &= $f + vic_colors |= color << 4 +} + +macro void set_border(byte color) { + vic_colors &= $f8 + vic_colors |= color & 7 +} + +const byte black = 0 +const byte white = 1 +const byte red = 2 +const byte cyan = 3 +const byte purple = 4 +const byte green = 5 +const byte blue = 6 +const byte yellow = 7 +const byte orange = 8 +const byte light_orange = 9 +const byte light_red = 10 +const byte light_cyan = 11 +const byte light_purple = 12 +const byte light_green = 13 +const byte light_blue = 14 +const byte light_yellow = 15 \ No newline at end of file diff --git a/include/vic20_kernal.mfk b/include/vic20_kernal.mfk index 53ba2f01..0f8c7bce 100644 --- a/include/vic20_kernal.mfk +++ b/include/vic20_kernal.mfk @@ -6,4 +6,8 @@ // CHROUT. Write byte to default output. (If not screen, must call OPEN and CHKOUT beforehands.) // Input: A = Byte to write. -asm void putchar(byte a) @$FFD2 extern \ No newline at end of file +asm void putchar(byte a) @$FFD2 extern + +inline void new_line() { + putchar(13) +} diff --git a/include/zxspectrum.mfk b/include/zxspectrum.mfk index 9b4c2526..eb423086 100644 --- a/include/zxspectrum.mfk +++ b/include/zxspectrum.mfk @@ -10,11 +10,22 @@ inline asm void putchar(byte a) { ? ret } +inline void new_line() { + putchar(13) +} + inline asm void set_border(byte a) { out (254),a ? ret } +inline asm void bell() { + ? ld hl,$6A + ? ld de,$105 + ? call $3B5 + ? ret +} + const byte black = 0 const byte blue = 1 const byte red = 2