Working Python version for Commodore.
This commit is contained in:
commit
2a48f52979
51 changed files with 3095 additions and 0 deletions
9
c64view/viewer/__init__.py
Normal file
9
c64view/viewer/__init__.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"""6502 viewer programs, assembled on demand by assemble.py."""
|
||||
|
||||
from .assemble import ( # noqa: F401
|
||||
AssemblerError,
|
||||
SOURCES,
|
||||
assemble_stub,
|
||||
build_viewer_prg,
|
||||
have_xa,
|
||||
)
|
||||
BIN
c64view/viewer/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
c64view/viewer/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
c64view/viewer/__pycache__/assemble.cpython-313.pyc
Normal file
BIN
c64view/viewer/__pycache__/assemble.cpython-313.pyc
Normal file
Binary file not shown.
82
c64view/viewer/assemble.py
Normal file
82
c64view/viewer/assemble.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
"""Assemble the 6502 viewer stubs with `xa` and build self-contained viewer PRGs.
|
||||
|
||||
Each viewer is a small ML stub originating at $0801 (behind a BASIC SYS 2061
|
||||
autostart). The picture data is appended after the stub, zero-padded so the
|
||||
bitmap lands exactly at $2000, screen RAM at $3F40, etc. The whole thing loads
|
||||
in a single pass -- no second disk access -- so it works identically on real
|
||||
hardware and in any emulator regardless of device configuration.
|
||||
|
||||
`xa -o` emits raw bytes starting at the origin without the 2-byte CBM load
|
||||
address, which we prepend here.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
VIEWER_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
LOAD_ADDR = 0x0801
|
||||
DATA_ADDR = 0x2000 # where appended picture data must land
|
||||
|
||||
# mode/viewer key -> source filename
|
||||
SOURCES = {
|
||||
"hires": "hires.s",
|
||||
"multicolor": "multicolor.s",
|
||||
"fli": "fli.s",
|
||||
"fli_ntsc": "fli_ntsc.s",
|
||||
"interlace": "interlace.s",
|
||||
}
|
||||
|
||||
_cache: dict[str, bytes] = {}
|
||||
|
||||
|
||||
class AssemblerError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def have_xa() -> bool:
|
||||
return shutil.which("xa") is not None
|
||||
|
||||
|
||||
def assemble_stub(viewer_key: str) -> bytes:
|
||||
"""Assemble a viewer stub to raw bytes (origin $0801, no load-address prefix)."""
|
||||
if viewer_key in _cache:
|
||||
return _cache[viewer_key]
|
||||
if not have_xa():
|
||||
raise AssemblerError(
|
||||
"The 'xa' (xa65) assembler was not found on PATH.\n"
|
||||
"Install it with: sudo apt install xa65 (Debian/Ubuntu)\n"
|
||||
"or build from https://www.floodgap.com/retrotech/xa/")
|
||||
|
||||
src = os.path.join(VIEWER_DIR, SOURCES[viewer_key])
|
||||
if not os.path.exists(src):
|
||||
raise AssemblerError(f"viewer source missing: {src}")
|
||||
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
out = os.path.join(td, "viewer.bin")
|
||||
proc = subprocess.run(["xa", "-o", out, src], capture_output=True, text=True)
|
||||
if proc.returncode != 0:
|
||||
raise AssemblerError(f"xa failed for {src}:\n{proc.stdout}{proc.stderr}")
|
||||
with open(out, "rb") as f:
|
||||
raw = f.read()
|
||||
_cache[viewer_key] = raw
|
||||
return raw
|
||||
|
||||
|
||||
def build_viewer_prg(viewer_key: str, data: bytes, data_addr: int = DATA_ADDR) -> bytes:
|
||||
"""Combine the assembled stub + padding + picture ``data`` into one PRG.
|
||||
|
||||
``data`` is the block that must reside from ``data_addr`` upward (bitmap,
|
||||
screen, colour RAM, background, ...).
|
||||
"""
|
||||
stub = assemble_stub(viewer_key)
|
||||
pad_len = (data_addr - LOAD_ADDR) - len(stub)
|
||||
if pad_len < 0:
|
||||
raise AssemblerError(
|
||||
f"viewer stub {viewer_key} is {len(stub)} bytes, exceeds the "
|
||||
f"{data_addr - LOAD_ADDR} bytes available before ${data_addr:04x}")
|
||||
payload = stub + bytes(pad_len) + bytes(data)
|
||||
return bytes([LOAD_ADDR & 0xFF, (LOAD_ADDR >> 8) & 0xFF]) + payload
|
||||
151
c64view/viewer/fli.s
Normal file
151
c64view/viewer/fli.s
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
; c64view -- FLI multicolor viewer (self-contained)
|
||||
;
|
||||
; Re-points the VIC video matrix ($D018) and forces a badline ($D011 yscroll)
|
||||
; on every visible raster line via a cycle-timed loop, giving per-line colour.
|
||||
;
|
||||
; Memory layout of appended data (loads from $4000):
|
||||
; $4000+L*$400 screen RAM for line L (L=0..7), 1000 bytes each
|
||||
; $6000 bitmap 8000 (offset $2000 in VIC bank 1)
|
||||
; $8000 colour RAM 1000 (copied to $D800)
|
||||
; $83E8 background 1
|
||||
;
|
||||
; assembled by viewer/assemble.py via xa
|
||||
|
||||
; BASIC autostart, SYS 2061
|
||||
* = $0801
|
||||
.word basicend
|
||||
.word 10
|
||||
.byte $9e
|
||||
.byte "2061"
|
||||
.byte 0
|
||||
basicend:
|
||||
.word 0 ; ML begins at $080D
|
||||
|
||||
start:
|
||||
sei
|
||||
|
||||
; copy colour RAM $8000 -> $D800 (1024 bytes)
|
||||
ldx #0
|
||||
ccopy:
|
||||
lda $8000,x
|
||||
sta $d800,x
|
||||
lda $8100,x
|
||||
sta $d900,x
|
||||
lda $8200,x
|
||||
sta $da00,x
|
||||
lda $8300,x
|
||||
sta $db00,x
|
||||
inx
|
||||
bne ccopy
|
||||
|
||||
; build per-line tables. d018tab = ((line AND 7) << 4) OR $08
|
||||
; d011tab = $38 OR (line AND 7) = BMM+DEN+RSEL plus yscroll
|
||||
ldx #0
|
||||
btab:
|
||||
txa
|
||||
and #$07
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
ora #$08
|
||||
sta d018tab,x
|
||||
; yscroll must equal (raster AND 7) to force a badline; the first
|
||||
; displayed raster is 51, so line x maps to raster 51+x.
|
||||
txa
|
||||
clc
|
||||
adc #$03
|
||||
and #$07
|
||||
ora #$38
|
||||
sta d011tab,x
|
||||
inx
|
||||
bne btab
|
||||
|
||||
; VIC bank 1 ($4000-$7FFF)
|
||||
lda $dd00
|
||||
and #$fc
|
||||
ora #$02
|
||||
sta $dd00
|
||||
|
||||
lda $83e8
|
||||
sta $d021 ; background
|
||||
lda #$00
|
||||
sta $d020 ; border black
|
||||
lda #$d8
|
||||
sta $d016 ; multicolor on
|
||||
|
||||
; raster IRQ setup
|
||||
lda #<irq1
|
||||
sta $0314
|
||||
lda #>irq1
|
||||
sta $0315
|
||||
lda #$7f
|
||||
sta $dc0d ; disable CIA timer IRQs
|
||||
sta $dd0d
|
||||
lda $dc0d
|
||||
lda $dd0d
|
||||
lda #$01
|
||||
sta $d01a ; enable raster IRQ
|
||||
lda #$30
|
||||
sta $d012 ; line 48
|
||||
lda $d011
|
||||
and #$7f
|
||||
sta $d011
|
||||
asl $d019 ; ack
|
||||
cli
|
||||
hang:
|
||||
jmp hang
|
||||
|
||||
; first IRQ, arrives with jitter on line 48, sets up the stabilised one
|
||||
irq1:
|
||||
lda #<irq2
|
||||
sta $0314
|
||||
lda #>irq2
|
||||
sta $0315
|
||||
inc $d012 ; fire again next line (49)
|
||||
asl $d019 ; ack
|
||||
tsx
|
||||
cli
|
||||
; burn the rest of the line so irq2 fires inside this NOP slide
|
||||
.dsb 40,$ea ; 40 NOPs
|
||||
|
||||
; stabilised IRQ on line 49, runs the FLI loop
|
||||
irq2:
|
||||
txs ; restore sp from irq1
|
||||
; cancel the remaining 0/1-cycle jitter: read the raster twice; the
|
||||
; branch is 2 or 3 cycles depending on alignment, normalising entry.
|
||||
lda $d012
|
||||
cmp $d012
|
||||
beq jl
|
||||
jl:
|
||||
; fixed delay so the first store lands before the c-access window
|
||||
ldx #$0d
|
||||
d0: dex
|
||||
bne d0
|
||||
nop
|
||||
nop
|
||||
|
||||
ldx #$00
|
||||
fliloop:
|
||||
lda d011tab,x ; force badline (yscroll = line&7)
|
||||
sta $d011
|
||||
lda d018tab,x ; point video matrix at screen[line]
|
||||
sta $d018
|
||||
inx
|
||||
cpx #200
|
||||
bne fliloop
|
||||
|
||||
; bottom border: leave bitmap on but stop forcing badlines
|
||||
lda #<irq1
|
||||
sta $0314
|
||||
lda #>irq1
|
||||
sta $0315
|
||||
lda #$30
|
||||
sta $d012
|
||||
asl $d019
|
||||
jmp $ea81 ; restore regs + RTI
|
||||
|
||||
d018tab:
|
||||
.dsb 256,0
|
||||
d011tab:
|
||||
.dsb 256,0
|
||||
155
c64view/viewer/fli_ntsc.s
Normal file
155
c64view/viewer/fli_ntsc.s
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
; c64view -- FLI multicolor viewer, NTSC timing (self-contained)
|
||||
;
|
||||
; Same as fli.s but the inner loop is one NOP (2 cycles) longer so it self-syncs
|
||||
; to the NTSC 65-cycle raster line (25 free CPU cycles per badline) vs PAL's 63.
|
||||
;
|
||||
; Re-points the VIC video matrix ($D018) and forces a badline ($D011 yscroll)
|
||||
; on every visible raster line via a cycle-timed loop, giving per-line colour.
|
||||
;
|
||||
; Memory layout of appended data (loads from $4000):
|
||||
; $4000+L*$400 screen RAM for line L (L=0..7), 1000 bytes each
|
||||
; $6000 bitmap 8000 (offset $2000 in VIC bank 1)
|
||||
; $8000 colour RAM 1000 (copied to $D800)
|
||||
; $83E8 background 1
|
||||
;
|
||||
; assembled by viewer/assemble.py via xa
|
||||
|
||||
; BASIC autostart, SYS 2061
|
||||
* = $0801
|
||||
.word basicend
|
||||
.word 10
|
||||
.byte $9e
|
||||
.byte "2061"
|
||||
.byte 0
|
||||
basicend:
|
||||
.word 0 ; ML begins at $080D
|
||||
|
||||
start:
|
||||
sei
|
||||
|
||||
; copy colour RAM $8000 -> $D800 (1024 bytes)
|
||||
ldx #0
|
||||
ccopy:
|
||||
lda $8000,x
|
||||
sta $d800,x
|
||||
lda $8100,x
|
||||
sta $d900,x
|
||||
lda $8200,x
|
||||
sta $da00,x
|
||||
lda $8300,x
|
||||
sta $db00,x
|
||||
inx
|
||||
bne ccopy
|
||||
|
||||
; build per-line tables. d018tab = ((line AND 7) << 4) OR $08
|
||||
; d011tab = $38 OR (line AND 7) = BMM+DEN+RSEL plus yscroll
|
||||
ldx #0
|
||||
btab:
|
||||
txa
|
||||
and #$07
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
ora #$08
|
||||
sta d018tab,x
|
||||
; yscroll must equal (raster AND 7) to force a badline; the first
|
||||
; displayed raster is 51, so line x maps to raster 51+x.
|
||||
txa
|
||||
clc
|
||||
adc #$03
|
||||
and #$07
|
||||
ora #$38
|
||||
sta d011tab,x
|
||||
inx
|
||||
bne btab
|
||||
|
||||
; VIC bank 1 ($4000-$7FFF)
|
||||
lda $dd00
|
||||
and #$fc
|
||||
ora #$02
|
||||
sta $dd00
|
||||
|
||||
lda $83e8
|
||||
sta $d021 ; background
|
||||
lda #$00
|
||||
sta $d020 ; border black
|
||||
lda #$d8
|
||||
sta $d016 ; multicolor on
|
||||
|
||||
; raster IRQ setup
|
||||
lda #<irq1
|
||||
sta $0314
|
||||
lda #>irq1
|
||||
sta $0315
|
||||
lda #$7f
|
||||
sta $dc0d ; disable CIA timer IRQs
|
||||
sta $dd0d
|
||||
lda $dc0d
|
||||
lda $dd0d
|
||||
lda #$01
|
||||
sta $d01a ; enable raster IRQ
|
||||
lda #$30
|
||||
sta $d012 ; line 48
|
||||
lda $d011
|
||||
and #$7f
|
||||
sta $d011
|
||||
asl $d019 ; ack
|
||||
cli
|
||||
hang:
|
||||
jmp hang
|
||||
|
||||
; first IRQ, arrives with jitter on line 48, sets up the stabilised one
|
||||
irq1:
|
||||
lda #<irq2
|
||||
sta $0314
|
||||
lda #>irq2
|
||||
sta $0315
|
||||
inc $d012 ; fire again next line (49)
|
||||
asl $d019 ; ack
|
||||
tsx
|
||||
cli
|
||||
; burn the rest of the line so irq2 fires inside this NOP slide
|
||||
.dsb 40,$ea ; 40 NOPs
|
||||
|
||||
; stabilised IRQ on line 49, runs the FLI loop
|
||||
irq2:
|
||||
txs ; restore sp from irq1
|
||||
; cancel the remaining 0/1-cycle jitter: read the raster twice; the
|
||||
; branch is 2 or 3 cycles depending on alignment, normalising entry.
|
||||
lda $d012
|
||||
cmp $d012
|
||||
beq jl
|
||||
jl:
|
||||
; fixed delay so the first store lands before the c-access window
|
||||
ldx #$0d
|
||||
d0: dex
|
||||
bne d0
|
||||
nop
|
||||
nop
|
||||
|
||||
ldx #$00
|
||||
fliloop:
|
||||
lda d011tab,x ; force badline (yscroll = line&7)
|
||||
sta $d011
|
||||
lda d018tab,x ; point video matrix at screen[line]
|
||||
sta $d018
|
||||
nop ; NTSC extra 2 cycles for 65 cycle line
|
||||
inx
|
||||
cpx #200
|
||||
bne fliloop
|
||||
|
||||
; bottom border: leave bitmap on but stop forcing badlines
|
||||
lda #<irq1
|
||||
sta $0314
|
||||
lda #>irq1
|
||||
sta $0315
|
||||
lda #$30
|
||||
sta $d012
|
||||
asl $d019
|
||||
jmp $ea81 ; restore regs + RTI
|
||||
|
||||
d018tab:
|
||||
.dsb 256,0
|
||||
d011tab:
|
||||
.dsb 256,0
|
||||
80
c64view/viewer/hires.s
Normal file
80
c64view/viewer/hires.s
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
; c64view -- hires bitmap viewer (self-contained)
|
||||
;
|
||||
; The picture data is appended to this program by the exporter and loads in one
|
||||
; pass. Fixed memory layout after load:
|
||||
; $0801 this program (BASIC stub + ML, padded up to $2000)
|
||||
; $2000 bitmap 8000 (VIC reads here directly)
|
||||
; $3F40 screen 1000 (copied to $0400)
|
||||
;
|
||||
; assembled by viewer/assemble.py via xa
|
||||
|
||||
; BASIC autostart, SYS 2061
|
||||
* = $0801
|
||||
.word basicend
|
||||
.word 10
|
||||
.byte $9e
|
||||
.byte "2061"
|
||||
.byte 0
|
||||
basicend:
|
||||
.word 0 ; ML begins at $080D
|
||||
|
||||
SRC = $fb
|
||||
DST = $fd
|
||||
|
||||
start:
|
||||
lda #$0b
|
||||
sta $d011 ; blank during setup
|
||||
|
||||
; copy screen RAM $3F40 -> $0400
|
||||
lda #$40
|
||||
sta SRC
|
||||
lda #$3f
|
||||
sta SRC+1
|
||||
lda #$00
|
||||
sta DST
|
||||
lda #$04
|
||||
sta DST+1
|
||||
jsr copy1024
|
||||
|
||||
lda $dd00
|
||||
ora #$03
|
||||
sta $dd00 ; VIC bank 0
|
||||
lda #$00
|
||||
sta $d020
|
||||
lda #$18
|
||||
sta $d018 ; screen $0400, bitmap $2000
|
||||
lda #$c8
|
||||
sta $d016 ; hires (multicolor off)
|
||||
lda #$3b
|
||||
sta $d011 ; bitmap mode, display on
|
||||
lda #$ff
|
||||
sta $cc
|
||||
|
||||
waitkey:
|
||||
jsr $ffe4
|
||||
beq waitkey
|
||||
|
||||
lda #$1b
|
||||
sta $d011
|
||||
lda #$c8
|
||||
sta $d016
|
||||
lda #$15
|
||||
sta $d018
|
||||
lda #$00
|
||||
sta $cc
|
||||
jsr $e544
|
||||
rts
|
||||
|
||||
copy1024:
|
||||
ldx #4
|
||||
ldy #0
|
||||
cploop:
|
||||
lda (SRC),y
|
||||
sta (DST),y
|
||||
iny
|
||||
bne cploop
|
||||
inc SRC+1
|
||||
inc DST+1
|
||||
dex
|
||||
bne cploop
|
||||
rts
|
||||
139
c64view/viewer/interlace.s
Normal file
139
c64view/viewer/interlace.s
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
; c64view -- multicolor interlace viewer (self-contained)
|
||||
;
|
||||
; Shows two multicolor frames on alternating fields by flipping the VIC bank in a
|
||||
; once-per-frame raster IRQ (no cycle-exact timing needed, so it is robust).
|
||||
; Frame A lives in bank 0 (bitmap $2000, screen $0400); frame B in bank 1 (bitmap
|
||||
; $6000, screen $4400). Both use $D018=$18; only the $DD00 bank bit toggles.
|
||||
;
|
||||
; Memory layout of appended data (loads from $2000):
|
||||
; $2000 bitmap A 8000
|
||||
; $3F40 screen A 1000 (copied to $0400)
|
||||
; $4400 screen B 1000 (in place, bank 1 video matrix)
|
||||
; $6000 bitmap B 8000
|
||||
; $8000 colour RAM 1000 (copied to $D800)
|
||||
; $83E8 background 1
|
||||
;
|
||||
; assembled by viewer/assemble.py via xa
|
||||
|
||||
; BASIC autostart, SYS 2061
|
||||
* = $0801
|
||||
.word basicend
|
||||
.word 10
|
||||
.byte $9e
|
||||
.byte "2061"
|
||||
.byte 0
|
||||
basicend:
|
||||
.word 0
|
||||
|
||||
SRC = $fb
|
||||
DST = $fd
|
||||
|
||||
start:
|
||||
sei
|
||||
|
||||
; screen A $3F40 -> $0400
|
||||
lda #$40
|
||||
sta SRC
|
||||
lda #$3f
|
||||
sta SRC+1
|
||||
lda #$00
|
||||
sta DST
|
||||
lda #$04
|
||||
sta DST+1
|
||||
jsr copy1024
|
||||
|
||||
; colour RAM $8000 -> $D800
|
||||
lda #$00
|
||||
sta SRC
|
||||
lda #$80
|
||||
sta SRC+1
|
||||
lda #$00
|
||||
sta DST
|
||||
lda #$d8
|
||||
sta DST+1
|
||||
jsr copy1024
|
||||
|
||||
lda $83e8
|
||||
sta $d021 ; background
|
||||
lda #$00
|
||||
sta $d020 ; border black
|
||||
lda $dd00
|
||||
and #$fc
|
||||
ora #$03
|
||||
sta $dd00 ; start on VIC bank 0 (frame A)
|
||||
lda #$18
|
||||
sta $d018 ; screen $x400, bitmap $x000+$2000
|
||||
lda #$d8
|
||||
sta $d016 ; multicolor on
|
||||
lda #$3b
|
||||
sta $d011 ; bitmap mode, display on
|
||||
|
||||
; frame-flip raster IRQ near the bottom border
|
||||
lda #<irq
|
||||
sta $0314
|
||||
lda #>irq
|
||||
sta $0315
|
||||
lda #$7f
|
||||
sta $dc0d
|
||||
sta $dd0d
|
||||
lda $dc0d
|
||||
lda $dd0d
|
||||
lda #$01
|
||||
sta $d01a
|
||||
lda #$fa
|
||||
sta $d012 ; line 250
|
||||
lda $d011
|
||||
and #$7f
|
||||
sta $d011
|
||||
asl $d019
|
||||
cli
|
||||
|
||||
waitkey:
|
||||
jsr $ffe4 ; GETIN (scanned via our IRQ -> $ea31)
|
||||
beq waitkey
|
||||
|
||||
; restore text mode + KERNAL IRQ
|
||||
sei
|
||||
lda #$00
|
||||
sta $d01a ; disable raster IRQ
|
||||
lda #$81
|
||||
sta $dc0d ; re-enable CIA timer IRQ
|
||||
lda #$31
|
||||
sta $0314
|
||||
lda #$ea
|
||||
sta $0315
|
||||
lda #$1b
|
||||
sta $d011
|
||||
lda #$c8
|
||||
sta $d016
|
||||
lda #$15
|
||||
sta $d018
|
||||
lda $dd00
|
||||
ora #$03
|
||||
sta $dd00
|
||||
asl $d019
|
||||
cli
|
||||
jsr $e544 ; clear screen
|
||||
rts
|
||||
|
||||
; once per frame, flip bank 0 <-> bank 1, then let the KERNAL IRQ finish
|
||||
irq:
|
||||
lda $dd00
|
||||
eor #$01
|
||||
sta $dd00
|
||||
asl $d019 ; ack raster IRQ
|
||||
jmp $ea31 ; KERNAL housekeeping (keyboard) + RTI
|
||||
|
||||
copy1024:
|
||||
ldx #4
|
||||
ldy #0
|
||||
cploop:
|
||||
lda (SRC),y
|
||||
sta (DST),y
|
||||
iny
|
||||
bne cploop
|
||||
inc SRC+1
|
||||
inc DST+1
|
||||
dex
|
||||
bne cploop
|
||||
rts
|
||||
98
c64view/viewer/multicolor.s
Normal file
98
c64view/viewer/multicolor.s
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
; c64view -- multicolor (Koala) bitmap viewer (self-contained)
|
||||
;
|
||||
; The picture data is appended to this program by the exporter and loads in one
|
||||
; pass, so no second disk access is needed. Fixed memory layout after load:
|
||||
; $0801 this program (BASIC stub + ML, padded up to $2000)
|
||||
; $2000 bitmap 8000 (VIC reads here directly)
|
||||
; $3F40 screen 1000 (copied to $0400)
|
||||
; $4328 colram 1000 (copied to $D800)
|
||||
; $4710 background 1
|
||||
;
|
||||
; assembled by viewer/assemble.py via xa
|
||||
|
||||
; BASIC autostart, SYS 2061
|
||||
* = $0801
|
||||
.word basicend
|
||||
.word 10
|
||||
.byte $9e
|
||||
.byte "2061"
|
||||
.byte 0
|
||||
basicend:
|
||||
.word 0 ; ML begins at $080D
|
||||
|
||||
SRC = $fb
|
||||
DST = $fd
|
||||
|
||||
start:
|
||||
lda #$0b
|
||||
sta $d011 ; blank screen during setup
|
||||
|
||||
; copy screen RAM $3F40 -> $0400
|
||||
lda #$40
|
||||
sta SRC
|
||||
lda #$3f
|
||||
sta SRC+1
|
||||
lda #$00
|
||||
sta DST
|
||||
lda #$04
|
||||
sta DST+1
|
||||
jsr copy1024
|
||||
|
||||
; copy colour RAM $4328 -> $D800
|
||||
lda #$28
|
||||
sta SRC
|
||||
lda #$43
|
||||
sta SRC+1
|
||||
lda #$00
|
||||
sta DST
|
||||
lda #$d8
|
||||
sta DST+1
|
||||
jsr copy1024
|
||||
|
||||
; program the VIC-II
|
||||
lda $dd00
|
||||
ora #$03
|
||||
sta $dd00 ; VIC bank 0 ($0000-$3FFF)
|
||||
lda $4710
|
||||
sta $d021 ; background colour
|
||||
lda #$00
|
||||
sta $d020 ; border black
|
||||
lda #$18
|
||||
sta $d018 ; screen $0400, bitmap $2000
|
||||
lda #$d8
|
||||
sta $d016 ; multicolor mode on
|
||||
lda #$3b
|
||||
sta $d011 ; bitmap mode, display on
|
||||
lda #$ff
|
||||
sta $cc ; disable cursor blink
|
||||
|
||||
waitkey:
|
||||
jsr $ffe4 ; GETIN
|
||||
beq waitkey
|
||||
|
||||
; restore text mode and return to BASIC
|
||||
lda #$1b
|
||||
sta $d011
|
||||
lda #$c8
|
||||
sta $d016
|
||||
lda #$15
|
||||
sta $d018
|
||||
lda #$00
|
||||
sta $cc
|
||||
jsr $e544 ; clear screen
|
||||
rts
|
||||
|
||||
; copy 1024 bytes from (SRC) to (DST)
|
||||
copy1024:
|
||||
ldx #4
|
||||
ldy #0
|
||||
cploop:
|
||||
lda (SRC),y
|
||||
sta (DST),y
|
||||
iny
|
||||
bne cploop
|
||||
inc SRC+1
|
||||
inc DST+1
|
||||
dex
|
||||
bne cploop
|
||||
rts
|
||||
Loading…
Add table
Add a link
Reference in a new issue