init files

This commit is contained in:
AArt1256 2025-11-13 19:07:39 +03:00
commit 8197a022bd
1409 changed files with 139317 additions and 0 deletions

133
shared/basic.inc Executable file
View file

@ -0,0 +1,133 @@
.ifndef _BASIC_INC_
_BASIC_INC_ = 1
BASIC_ROM = $a000
BASIC_ROM_SIZE = $2000
LINNUM = $14
FBUFFR = $0100; floating point string buffer written by FOUT
TOKEN_SYS = $9e
PETSCII_RETURN = $0d
PETSCII_LO_UP_CASE = $0e
PETSCII_BLINK = $0f; C128 80 columns
PETSCII_CLEAR = $93
PETSCII_BLACK = $90
PETSCII_WHITE = $05
PETSCII_RED = $1c
PETSCII_CYAN = $9f
PETSCII_PURPLE = $9c
PETSCII_GREEN = $1e
PETSCII_BLUE = $1f
PETSCII_YELLOW = $9e
PETSCII_ORANGE = $81
PETSCII_BROWN = $95
PETSCII_LIGHTRED = $96
PETSCII_DARKGREY = $97
PETSCII_GREY = $98
PETSCII_LIGHTGREEN = $99
PETSCII_LIGHTBLUE = $9a
PETSCII_LIGHTGREY = $9b
.if .defined(PLATFORM) & (PLATFORM = 16)
NEW = $8a7b; Perform NEW
CLR = $8a9a; PErform CLR
STROUT = $9088; Output String
GIVAYF = $9471; Convert Integer in (AC/YR) to FAC
NORMALIZE = $952b; Normalize FAC#1
INT24TOMANTISSA = $9534; Integer in (YR/XR/AR) to FAC mantissa MSBs
N32768 = $986c; Constant -32768 in floating point
FLPINT = $9871; FAC#1 to Integer in A/Y
AYINT = $9886; FAC#1 to Positive Integer
STRLIT = $9b74; Set Up String
FADDH = $a062; Add 0.5 to FAC#1
FADD = $a066; Perform Addition
FSUB = $a06c; Perform Subtraction
FMULT = $a078; Perform Multiply of float in (AC/YR) with FAC
CONUPK = $a0dc; Move floating point number from memory to FAC#2
MUL10 = $a162; Multiply FAC#1 by 10
TENC = $a179; Constant 10 in floating point
DIV10 = $a183; Divide FAC#1 by 10
FDIVM = $a18c; Divide FAC#2 by float in (AC/YR), result in FAC#1
FDIV = $a194; Divide float in (AC/YR) by FAC#1, result in FAC#1
FDIVT = $a197; Divide FAC#2 by FAC#1, result in FAC#1
MOVFM = $a221; Move floating point number from memory to FAC#1
MOV2M = $a259; Store FAC#1 in memory at (XR/YR)
MOVAF = $a291; Copy FAC#1 to FAC#2
LINPRT = $a45f; Print integer in A/X
FOUT = $a46f; Convert FAC#1 to ASCII String
.elseif .defined(PLATFORM) & (PLATFORM = 128)
NEW = $51d9; Perform NEW
CLR = $51f8; Perform CLR
STROUT = $55e2; Output String
NORMALIZE = $7a14; Normalize FAC#1
INT24TOMANTISSA = $7a1d; Integer in (YR/XR/AR) to FAC#1 mantissa MSBs
FLPINT = $849f; FAC#1 to Integer in A/Y
GIVAYF = $84c9; Convert Integer in (AC/YR) to FAC
STRLIT = $869a; Set Up String
FADDH = $8a0e; Add 0.5 to FAC#1
FMULT = $8a08; Perform Multiply of float in (AC/YR) with FAC
FDIV = $8a1e; Divide float in (AC/YR) by FAC#1, result in FAC#1
CONUPK = $8a89; Move floating point number from memory to FAC#2
MUL10 = $8b17; Multiply FAC#1 by 10
DIV10 = $8b38; Divide FAC#1 by 10
FDIVM = $8b3f; Divide FAC#2 by float in (AC/YR), result in FAC#1
FDIVT = $8b4c; Divide FAC#2 by FAC#1, result in FAC#1
MOVFM = $8bd4; Move floating point number from memory to FAC#1
MOV2M = $8c00; Store FAC#1 in memory at (XR/YR)
MOVAF = $8c38; Copy FAC#1 to FAC#2
LINPRT = $8e32; Print integer in A/X
FOUT = $8e42; Convert FAC#1 to ASCII String
.else
NEW = $a644; Perform NEW
CLR = $a660; Perform CLR
STROUT = $ab1e; Output String
NORMALIZE = $af7e; Normalize FAC#1
INT24TOMANTISSA = $af87; GETTIM + 3, Integer in (YR/XR/AR) to FAC#1 mantissa MSBs
N32768 = $b1a5; Constant -32768 in floating point
FLPINT = $b1aa; FAC#1 to Integer in A/Y
AYINT = $b1bf; FAC#1 to Positive Integer
GIVAYF = $b391; Convert Integer in (AC/YR) to FAC
STRLIT = $b487; Set Up String
FADDH = $b849; Add 0.5 to FAC#1
FSUB = $b850; Perform Subtraction
FADD = $b867; Perform Addition
FMULT = $ba28; Perform Multiply of float in (AC/YR) with FAC
CONUPK = $ba8c; Move floating point number from memory to FAC#2
MUL10 = $bae2; Multiply FAC#1 by 10
TENC = $baf9; Constant 10 in floating point
DIV10 = $bafe; Divide FAC#1 by 10
FDIVM = $bb05; Divide FAC#2 by float in (AC/YR), result in FAC#1
FDIV = $bb0f; Divide float in (AC/YR) by FAC#1, result in FAC#1
FDIVT = $bb12; Divide FAC#2 by FAC#1, result in FAC#1
MOVFM = $bba2; Move floating point number from memory to FAC#1
MOV2M = $bbd4; Store FAC#1 in memory at (XR/YR)
MOVAF = $bc0c; Copy FAC#1 to FAC#2
LINPRT = $bdcd; Print integer in A/X
FOUT = $bddd; Convert FAC#1 to ASCII String
PIVAL = $aea8; Constant PI in floating point
GETADR = $b7f7; Convert FAC to Integer in LINNUM
FONE = $b9bc; Floating point constant: 1
.endif
.macro LOAD_ADDRESS
.word * + $02
.endmacro; LOAD_ADDRESS
.macro BASIC_STARTLINE linenumber
.assert * = $0801, warning, "***** PC is not $0801 *****"
.word $080d, linenumber
.byte TOKEN_SYS, "2061", $00, $00, $00
.endmacro; BASIC_STARTLINE
.endif; !_BASIC_INC_

429
shared/cia.inc Executable file
View file

@ -0,0 +1,429 @@
; MOS6526
.ifndef _VIA_INC_
.ifndef _CIA_INC_
_CIA_INC_ = 1
.if (::PLATFORM = 64) | (::PLATFORM = 128) ; cia.inc defines C-64 and 1581 symbols, so it might be included along with, e.g., ted.inc
; C-64 keyboard matrix positions
STOP_COLUMN = %01111111
STOP_ROW = %01111111
LEFT_SHIFT_COLUMN = %11111101
LEFT_SHIFT_ROW = %01111111
ALL_COLUMNS = %00000000
NO_ROWS = %11111111
.endif
; the two CIAs in the C-64
CIA1_BASE = $dc00
CIA_PIO0 = %00000001
CIA_PIO1 = %00000010
CIA_PIO2 = %00000100
CIA_PIO3 = %00001000
CIA_PIO4 = %00010000
CIA_PIO5 = %00100000
CIA_PIO6 = %01000000
CIA_PIO7 = %10000000
CIA1_PRA = CIA1_BASE + $00; Port register A
KBD_COLUMN0 = ~CIA_PIO0
KBD_COLUMN1 = ~CIA_PIO1
KBD_COLUMN2 = ~CIA_PIO2
KBD_COLUMN3 = ~CIA_PIO3
KBD_COLUMN4 = ~CIA_PIO4
KBD_COLUMN5 = ~CIA_PIO4
KBD_COLUMN6 = ~CIA_PIO5
KBD_COLUMN7 = ~CIA_PIO5
JOY2_UP = ~CIA_PIO0
JOY2_DOWN = ~CIA_PIO1
JOY2_LEFT = ~CIA_PIO2
JOY2_RIGHT = ~CIA_PIO3
JOY2_FIRE = ~CIA_PIO4
PADDLE_ENPORT1 = CIA_PIO6
PADDLE_ENPORT2 = CIA_PIO7
PADDLE_EN_MASK = CIA_PIO5 | CIA_PIO4 | CIA_PIO3 | CIA_PIO2 | CIA_PIO1 | CIA_PIO0
CIA1_PRB = CIA1_BASE + $01; Port register B
KBD_ROW0 = ~CIA_PIO0
KBD_ROW1 = ~CIA_PIO1
KBD_ROW2 = ~CIA_PIO2
KBD_ROW3 = ~CIA_PIO3
KBD_ROW4 = ~CIA_PIO4
KBD_ROW5 = ~CIA_PIO5
KBD_ROW6 = ~CIA_PIO6
KBD_ROW7 = ~CIA_PIO7
JOY1_UP = ~CIA_PIO0
JOY1_DOWN = ~CIA_PIO1
JOY1_LEFT = ~CIA_PIO2
JOY1_RIGHT = ~CIA_PIO3
JOY1_FIRE = ~CIA_PIO4
CIA1_DDRA = CIA1_BASE + $02; Data direction register A
CIA_PIO0_OUTPUT = CIA_PIO0
CIA_PIO0_INPUT = %00000000
CIA_PIO1_OUTPUT = CIA_PIO1
CIA_PIO1_INPUT = %00000000
CIA_PIO2_OUTPUT = CIA_PIO2
CIA_PIO2_INPUT = %00000000
CIA_PIO3_OUTPUT = CIA_PIO3
CIA_PIO3_INPUT = %00000000
CIA_PIO4_OUTPUT = CIA_PIO4
CIA_PIO4_INPUT = %00000000
CIA_PIO5_OUTPUT = CIA_PIO5
CIA_PIO5_INPUT = %00000000
CIA_PIO6_OUTPUT = CIA_PIO6
CIA_PIO6_INPUT = %00000000
CIA_PIO7_OUTPUT = CIA_PIO7
CIA_PIO7_INPUT = %00000000
CIA1_DDRB = CIA1_BASE + $03; Data direction register B
CIA1_TA_LO = CIA1_BASE + $04; Timer A, low byte
CIA1_TA_HI = CIA1_BASE + $05; Timer A, high byte
CIA1_TB_LO = CIA1_BASE + $06; Timer B, low byte
CIA1_TB_HI = CIA1_BASE + $07; Timer B, high byte
CIA1_TOD_10S = CIA1_BASE + $08; Time of day, 1/10 seconds
CIA1_TOD_SEC = CIA1_BASE + $09; Time of day, seconds
CIA1_TOD_MIN = CIA1_BASE + $0a; Time of day, minutes
CIA1_TOD_HRS = CIA1_BASE + $0b; Time of day, hours
TOD_AMPM = %10000000
TOD_AM = %00000000
TOD_PM = %10000000
TOD_HRS_MASK = %00011111
CIA1_SDR = CIA1_BASE + $0c; Serial data register
CIA1_ICR = CIA1_BASE + $0d; Interrupt control register
TIMERA_IRQ = %00000001
TIMERB_IRQ = %00000010
TOD_IRQ = %00000100
SERIAL_IRQ = %00001000
FLAG1_IRQ = %00010000
EVERY_IRQ = %01111111
CIA_INTERRUPT = %10000000
CIA_CLR_INTF = %00000000
CIA_SET_INTF = %10000000
CIA1_CRA = CIA1_BASE + $0e; Control Register A
TIMER_STOP = %00000000
TIMER_START = %00000001
OUTPUT_TO_PB6 = %00000010
OUTPUT_PULSE = %00000000
OUTPUT_TOGGLE = %00000100
CONTINUOUS = %00000000
ONE_SHOT = %00001000
FORCE_LOAD = %00010000
COUNT_PHI2 = %00000000
COUNT_CNT = %00100000
IOMODE_INPUT = %00000000
IOMODE_OUTPUT = %01000000
TOD_FREQ_60HZ = %00000000
TOD_FREQ_50HZ = %10000000
TOD_FREQ_MASK = TOD_FREQ_50HZ
CIA1_CRB = CIA1_BASE + $0f; Control Register B
;TIMER_STOP = %00000000
;TIMER_START = %00000001
OUTPUT_TO_PB7 = %00000010
;OUTPUT_PULSE = %00000000
;OUTPUT_TOGGLE = %00000100
;CONTINUOUS = %00000000
;ONE_SHOT = %00001000
;FORCE_LOAD = %00010000
;COUNT_PHI2 = %00000000
COUNT_CNT_POS = %00100000
COUNT_TA_UNDF = %01000000
COUNT_TA_UFCN = %01100000
COUNT_CRB_MASK = COUNT_TA_UFCN
TOD_SET_CLOCK = %00000000
TOD_SET_ALARM = %10000000
CIA2_BASE = $dd00
;CIA_PIO0 = %00000001
;CIA_PIO1 = %00000010
;CIA_PIO2 = %00000100
;CIA_PIO3 = %00001000
;CIA_PIO4 = %00010000
;CIA_PIO5 = %00100000
;CIA_PIO6 = %01000000
;CIA_PIO7 = %10000000
CIA2_PRA = CIA2_BASE + $00; Port register A
VIC2_BANK = %00000011
VIC2_BANK0 = %00000000
VIC2_BANK1 = CIA_PIO0
VIC2_BANK2 = CIA_PIO1
VIC2_BANK3 = CIA_PIO1 | CIA_PIO0
VIC2_BANK_SHIFT = 0
VIC2_BANK_MASK = VIC2_BANK
.define VIC2_MAKE_BANK(address) .lobyte(((address & $c000) >> 14) ^ 3)
RS232_TXD = CIA_PIO2
SERIAL_ATN_OUT = CIA_PIO3
SERIAL_CLK_OUT = CIA_PIO4
SERIAL_DATA_OUT = CIA_PIO5
SERIAL_CLK_IN = CIA_PIO6
SERIAL_DATA_IN = CIA_PIO7
CIA2_PRB = CIA2_BASE + $01; Port register B
RS232_RXD = CIA_PIO0
RS232_RTS = CIA_PIO1
RS232_DTR = CIA_PIO2
RS232_RING = CIA_PIO3
RS232_CARRIER = CIA_PIO4
USERPORT_PB5 = CIA_PIO5
RS232_CTS = CIA_PIO6
RS232_DSR = CIA_PIO7
CIA2_DDRA = CIA2_BASE + $02; Data direction register A
;CIA_PIO0_OUTPUT = CIA_PIO0
;CIA_PIO0_INPUT = %00000000
;CIA_PIO1_OUTPUT = CIA_PIO1
;CIA_PIO1_INPUT = %00000000
CIA_VIC2_BANK_OUTPUT = CIA_PIO0 | CIA_PIO1
CIA_VIC2_BANK_INPUT = %00000000
;CIA_PIO2_OUTPUT = CIA_PIO2
;CIA_PIO2_INPUT = %00000000
CIA_RS232_TXD_OUTPUT = CIA_PIO2
CIA_RS232_TXD_INPUT = %00000000
;CIA_PIO3_OUTPUT = CIA_PIO3
;CIA_PIO3_INPUT = %00000000
CIA_SERIAL_ATN_OUT_OUTPUT = CIA_PIO3
CIA_SERIAL_ATN_OUT_INPUT = %00000000
;CIA_PIO4_OUTPUT = CIA_PIO4
;CIA_PIO4_INPUT = %00000000
CIA_SERIAL_CLK_OUT_OUTPUT = CIA_PIO4
CIA_SERIAL_CLK_OUT_INPUT = %00000000
;CIA_PIO5_OUTPUT = CIA_PIO5
;CIA_PIO5_INPUT = %00000000
CIA_SERIAL_DATA_OUT_OUTPUT = CIA_PIO5
CIA_SERIAL_DATA_OUT_INPUT = %00000000
;CIA_PIO6_OUTPUT = CIA_PIO6
;CIA_PIO6_INPUT = %00000000
CIA_SERIAL_CLK_IN_OUTPUT = CIA_PIO6
CIA_SERIAL_CLK_IN_INPUT = %00000000
;CIA_PIO7_OUTPUT = CIA_PIO7
;CIA_PIO7_INPUT = %00000000
CIA_SERIAL_DATA_IN_OUTPUT = CIA_PIO7
CIA_SERIAL_DATA_IN_INPUT = %00000000
CIA2_DDRB = CIA2_BASE + $03; Data direction register B
CIA2_TA_LO = CIA2_BASE + $04; Timer A, low byte
CIA2_TA_HI = CIA2_BASE + $05; Timer A, high byte
CIA2_TB_LO = CIA2_BASE + $06; Timer B, low byte
CIA2_TB_HI = CIA2_BASE + $07; Timer B, high byte
CIA2_TOD_10S = CIA2_BASE + $08; Time of day, 1/10 seconds
CIA2_TOD_SEC = CIA2_BASE + $09; Time of day, seconds
CIA2_TOD_MIN = CIA2_BASE + $0a; Time of day, minutes
CIA2_TOD_HRS = CIA2_BASE + $0b; Time of day, hours
;TOD_AMPM = %10000000
;TOD_AM = %00000000
;TOD_PM = %10000000
;TOD_HRS_MASK = %00011111
CIA2_SDR = CIA2_BASE + $0c; Serial data register
CIA2_ICR = CIA2_BASE + $0d; Interrupt control register
TIMERA_NMI = %00000001
TIMERB_NMI = %00000010
TOD_NMI = %00000100
SERIAL_NMI = %00001000
FLAG1_NMI = %00010000
EVERY_NMI = %01111111
;CIA_INTERRUPT = %10000000
;CIA_CLR_INTF = %00000000
;CIA_SET_INTF = %10000000
CIA2_CRA = CIA2_BASE + $0e; Control Register A
;TIMER_STOP = %00000000
;TIMER_START = %00000001
;OUTPUT_TO_PB6 = %00000010
;OUTPUT_PULSE = %00000000
;OUTPUT_TOGGLE = %00000100
;CONTINUOUS = %00000000
;ONE_SHOT = %00001000
;FORCE_LOAD = %00010000
;COUNT_PHI2 = %00000000
;COUNT_CNT = %00100000
SERIAL_INPUT = %00000000
SERIAL_OUTPUT = %01000000
;TOD_FREQ_60HZ = %00000000
;TOD_FREQ_50HZ = %10000000
CIA2_CRB = CIA2_BASE + $0f; Control Register B
;TIMER_STOP = %00000000
;TIMER_START = %00000001
;OUTPUT_TO_PB7 = %00000010
;OUTPUT_PULSE = %00000000
;OUTPUT_TOGGLE = %00000100
;CONTINUOUS = %00000000
;ONE_SHOT = %00001000
;FORCE_LOAD = %00010000
;COUNT_PHI2 = %00000000
;COUNT_CNT_POS = %00100000
;COUNT_TA_UNDF = %01000000
;COUNT_TA_UFCN = %01100000
;COUNT_CRB_MASK = COUNT_TA_UFCN
;TOD_SET_CLOCK = %00000000
;TOD_SET_ALARM = %10000000
; the CIA in the 1571 (not CR) and 1581
; on 1571, only the fast serial interface is connected
; on 1571CR, only the fast serial interface is implemented (MOS5710)
CIA_BASE = $4000
;CIA_PIO0 = %00000001
;CIA_PIO1 = %00000010
;CIA_PIO2 = %00000100
;CIA_PIO3 = %00001000
;CIA_PIO4 = %00010000
;CIA_PIO5 = %00100000
;CIA_PIO6 = %01000000
;CIA_PIO7 = %10000000
CIA_PRA = CIA_BASE + $00; Port register A
SIDE_SELECT = CIA_PIO0
DISK_INSERTED = CIA_PIO1
DISK_IS_INSERTED = %00000000
NO_DISK_IS_INSERTED = DISK_INSERTED
MOTOR = CIA_PIO2
MOTOR_ON = %00000000
MOTOR_OFF = MOTOR
DEVICE_NUMBER = CIA_PIO3 | CIA_PIO4
DEVICE_NUMBER_8 = %00000000
DEVICE_NUMBER_9 = CIA_PIO3
DEVICE_NUMBER_10 = CIA_PIO4
DEVICE_NUMBER_11 = CIA_PIO3 | CIA_PIO4
DEVICE_NUMBER_SHIFT = 3
DEVICE_NUMBER_MASK = DEVICE_NUMBER
POWER_LED = CIA_PIO5
DRIVE_LED = CIA_PIO6
DISK_CHANGE = CIA_PIO7
DISK_CHANGED = %00000000
NO_DISK_CHANGED = DISK_CHANGE
CIA_PRB = CIA_BASE + $01; Port register B
DATA_IN = CIA_PIO0
DATA_OUT = CIA_PIO1
CLK_IN = CIA_PIO2
CLK_OUT = CIA_PIO3
ATNA_ENABLE_OUT = CIA_PIO4
FSM_BUS_DRIVER_DIRECTION = CIA_PIO5
FSM_BUS_DRIVER_INPUT = %00000000
FSM_BUS_DRIVER_OUTPUT = FSM_BUS_DRIVER_DIRECTION
WRITE_PROTECT = CIA_PIO6
ATN_IN = CIA_PIO7
CIA_DDRA = CIA_BASE + $02; Data direction register A
;CIA_PIO0_OUTPUT = CIA_PIO0
;CIA_PIO0_INPUT = %00000000
;CIA_PIO1_OUTPUT = CIA_PIO1
;CIA_PIO1_INPUT = %00000000
;CIA_PIO2_OUTPUT = CIA_PIO2
;CIA_PIO2_INPUT = %00000000
;CIA_PIO3_OUTPUT = CIA_PIO3
;CIA_PIO3_INPUT = %00000000
;CIA_PIO4_OUTPUT = CIA_PIO4
;CIA_PIO4_INPUT = %00000000
;CIA_PIO5_OUTPUT = CIA_PIO5
;CIA_PIO5_INPUT = %00000000
;CIA_PIO6_OUTPUT = CIA_PIO6
;CIA_PIO6_INPUT = %00000000
;CIA_PIO7_OUTPUT = CIA_PIO7
;CIA_PIO7_INPUT = %00000000
CIA_DDRB = CIA_BASE + $03; Data direction register B
DATA_IN_OUTPUT = CIA_PIO0
DATA_IN_INPUT = %00000000
DATA_OUT_OUTPUT = CIA_PIO1
DATA_OUT_INPUT = %00000000
CLK_IN_OUTPUT = CIA_PIO2
CLK_IN_INPUT = %00000000
CLK_OUT_OUTPUT = CIA_PIO3
CLK_OUT_INPUT = %00000000
ATNA_ENABLE_OUT_OUTPUT = CIA_PIO4
ATNA_ENABLE_OUT_INPUT = %00000000
FSM_BUS_DRIVER_DIRECTION_OUTPUT = CIA_PIO5
FSM_BUS_DRIVER_DIRECTION_INPUT = %00000000
WRITE_PROTECT_OUTPUT = CIA_PIO6
WRITE_PROTECT_INPUT = %00000000
CIA_ATN_IN_OUTPUT = CIA_PIO7
CIA_ATN_IN_INPUT = %00000000
CIA_TA_LO = CIA_BASE + $04; Timer A, low byte
CIA_TA_HI = CIA_BASE + $05; Timer A, high byte
CIA_TB_LO = CIA_BASE + $06; Timer B, low byte
CIA_TB_HI = CIA_BASE + $07; Timer B, high byte
CIA_TOD_10S = CIA_BASE + $08; Time of day, 1/10 seconds
CIA_TOD_SEC = CIA_BASE + $09; Time of day, seconds
CIA_TOD_MIN = CIA_BASE + $0a; Time of day, minutes
CIA_TOD_HRS = CIA_BASE + $0b; Time of day, hours
;TOD_AMPM = %10000000
;TOD_AM = %00000000
;TOD_PM = %10000000
;TOD_HRS_MASK = %00011111
CIA_SDR = CIA_BASE + $0c; Serial data register
CIA_ICR = CIA_BASE + $0d; Interrupt control register
;TIMERA_IRQ = %00000001
;TIMERB_IRQ = %00000010
;TOD_IRQ = %00000100
;SERIAL_IRQ = %00001000
;FLAG1_IRQ = %00010000
;EVERY_IRQ = %01111111
;CIA_INTERRUPT = %10000000
;CIA_CLR_INTF = %00000000
;CIA_SET_INTF = %10000000
CIA_CRA = CIA_BASE + $0e; Control Register A
;TIMER_STOP = %00000000
;TIMER_START = %00000001
;OUTPUT_TO_PB6 = %00000010
;OUTPUT_PULSE = %00000000
;OUTPUT_TOGGLE = %00000100
;CONTINUOUS = %00000000
;ONE_SHOT = %00001000
;FORCE_LOAD = %00010000
;COUNT_PHI2 = %00000000
;COUNT_CNT = %00100000
;IOMODE_INPUT = %00000000
;IOMODE_OUTPUT = %01000000
;TOD_FREQ_60HZ = %00000000
;TOD_FREQ_50HZ = %10000000
;TOD_FREQ_MASK = TOD_FREQ_50HZ
CIA_CRB = CIA_BASE + $0f; Control Register B
;TIMER_STOP = %00000000
;TIMER_START = %00000001
;OUTPUT_TO_PB7 = %00000010
;OUTPUT_PULSE = %00000000
;OUTPUT_TOGGLE = %00000100
;CONTINUOUS = %00000000
;ONE_SHOT = %00001000
;FORCE_LOAD = %00010000
;COUNT_PHI2 = %00000000
;COUNT_CNT_POS = %00100000
;COUNT_TA_UNDF = %01000000
;COUNT_TA_UFCN = %01100000
;COUNT_CRB_MASK = COUNT_TA_UFCN
;TOD_SET_CLOCK = %00000000
;TOD_SET_ALARM = %10000000
.endif; !_CIA_INC_
.endif; !_VIA_INC_

410
shared/cpu.inc Executable file
View file

@ -0,0 +1,410 @@
; MOS6502/6510/8500/8502
.ifndef _CPU_INC_
_CPU_INC_ = 1
.ifndef PLATFORM
PLATFORM = 64
.endif
.if PLATFORM = 16
CLOCK_PAL = 886723; Hz - single clock
.define CYCLES_PER_SECOND_PAL .byte $c3, $87, $0d, $00; 886723 - single clock
CLOCK_NTSC = 894886; Hz - single clock
.define CYCLES_PER_SECOND_NTSC .byte $a6, $a7, $0d, $00; 894886 - single clock
.else
CLOCK_PAL = 985248; Hz
.define CYCLES_PER_SECOND_PAL .byte $a0, $08, $0f, $00; 985248
CLOCK_NTSC = 1022727; Hz
.define CYCLES_PER_SECOND_NTSC .byte $07, $9b, $0f, $00; 1022727
.endif
OPC_BRK = $00
OPC_ORA_ZPXI = $01
OPC_JAM = $02; unofficial
OPC_SLO_ZPXI = $03; unofficial
;OPC_NOP = $04; unofficial
OPC_ORA_ZP = $05
OPC_ASL_ZP = $06
OPC_SLO_ZP = $07; unofficial
OPC_PHP = $08
OPC_ORA_IMM = $09
OPC_ASL = $0a
OPC_ANC_IMM = $0b; unofficial
OPC_NOP_ABS = $0c
OPC_ORA_ABS = $0d
OPC_ASL_ABS = $0e
OPC_SLO_ABS = $0f; unofficial
OPC_BPL = $10
OPC_ORA_ZPIY = $11
;OPC_JAM = $12; unofficial
OPC_SLO_ZPIY = $13; unofficial
OPC_NOP_ZPX = $14; unofficial
OPC_ORA_ZPX = $15
OPC_ASL_ZPX = $16
OPC_SLO_ZPX = $17; unofficial
OPC_CLC = $18
OPC_ORA_ABSY = $19
;OPC_NOP = $1a; unofficial
OPC_SLO_ABSY = $1b; unofficial
OPC_NOP_ABSX = $1c; unofficial
OPC_ORA_ABSX = $1d
OPC_ASL_ABSX = $1e
OPC_SLO_ABSX = $1f; unofficial
OPC_JSR_ABS = $20
OPC_AND_ZPXI = $21
;OPC_JAM = $22; unofficial
OPC_RLA_ZPXI = $23; unofficial
OPC_BIT_ZP = $24
OPC_AND_ZP = $25
OPC_ROL_ZP = $26
OPC_RLA_ZP = $27; unofficial
OPC_PLP = $28
OPC_AND_IMM = $29
OPC_ROL = $2a
;OPC_ANC_IMM = $2b; unofficial
OPC_BIT_ABS = $2c
OPC_AND_ABS = $2d
OPC_ROL_ABS = $2e
OPC_RLA_ABS = $2f; unofficial
OPC_BMI = $30
OPC_AND_ZPIY = $31
;OPC_JAM = $32; unofficial
OPC_RLA_ZPIY = $33; unofficial
;OPC_NOP_ZPX = $34
OPC_AND_ZPX = $35
OPC_ROL_ZPX = $36
OPC_RLA_ZPX = $37; unofficial
OPC_SEC = $38
OPC_AND_ABSY = $39
;OPC_NOP = $3a; unofficial
OPC_RLA_ABSY = $3b; unofficial
;OPC_NOP_ABSX = $3c
OPC_AND_ABSX = $3d
OPC_ROL_ABSX = $3e
OPC_RLA_ABSX = $3f; unofficial
OPC_RTI = $40
OPC_EOR_ZPXI = $41
;OPC_JAM = $42; unofficial
OPC_SRE_ZPXI = $43; unofficial
OPC_NOP_ZP = $44
OPC_EOR_ZP = $45
OPC_LSR_ZP = $46
OPC_SRE_ZP = $47; unofficial
OPC_PHA = $48
OPC_EOR_IMM = $49
OPC_LSR = $4a
OPC_ASL_IMM = $4b
OPC_JMP_ABS = $4c
OPC_EOR_ABS = $4d
OPC_LSR_ABS = $4e
OPC_SRE_ABS = $4f; unofficial
OPC_BVC = $50
OPC_EOR_ZPIY = $51
;OPC_JAM = $52; unofficial
OPC_SRE_ZPIY = $53; unofficial
;OPC_NOP_ZPX = $54; unofficial
OPC_EOR_ZPX = $55
OPC_LSR_ZPX = $56
OPC_SRE_ZPX = $57; unofficial
OPC_CLI = $58
OPC_EOR_ABSY = $59
;OPC_NOP = $5a
OPC_SRE_ABSY = $5b; unofficial
;OPC_NOP_ABSX = $5c
OPC_EOR_ABSX = $5d
OPC_LSR_ABSX = $5e
OPC_SRE_ABSX = $5f; unofficial
OPC_RTS = $60
OPC_ADC_ZPIX = $61
;OPC_JAM = $62; unofficial
OPC_RRA_ZPIX = $63; unofficial
;OPC_NOP_ZP = $64; unofficial
OPC_ADC_ZP = $65
OPC_ROR_ZP = $66
OPC_RRA_ZP = $67; unofficial
OPC_PLA = $68
OPC_ADC_IMM = $69
OPC_ROR = $6a
OPC_ARR_IMM = $6b; unofficial
OPC_JMP_ABSI = $6c
OPC_ADC_ABS = $6d
OPC_ROR_ABS = $6e
OPC_RRA_ABS = $6f; unofficial
OPC_BVS = $70
OPC_ADC_ZPIY = $71
;OPC_JAM = $72; unofficial
OPC_RRA_ZPIY = $73; unofficial
;OPC_NOP_ZPX = $74; unofficial
OPC_ADC_ZPX = $75
OPC_ROR_ZPX = $76
OPC_RRA_ZPX = $77; unofficial
OPC_SEI = $78
OPC_ADC_ABSY = $79
;OPC_NOP = $7a; unofficial
OPC_RRA_ABSY = $7b; unofficial
;OPC_NOP_ABSX = $7c; unofficial
OPC_ADC_ABSX = $7d
OPC_ROR_ABSX = $7e
OPC_RRA_ABSX = $7f; unofficial
OPC_NOP_IMM = $80; unofficial
OPC_STA_ZPXI = $81
;OPC_NOP_IMM = $82
OPC_SAX_ZPXI = $83; unofficial
OPC_STY_ZP = $84
OPC_STA_ZP = $85
OPC_STX_ZP = $86
OPC_SAX_ZP = $87; unofficial
OPC_DEY = $88
;OPC_NOP_IMM = $89; unofficial
OPC_TXA = $8a
OPC_XAA_IMM = $8b; unofficial
OPC_STY_ABS = $8c
OPC_STA_ABS = $8d
OPC_STX_ABS = $8e
OPC_SAX_ABS = $8f; unofficial
OPC_BCC = $90
OPC_STA_ZPIY = $91
;OPC_JAM = $92; unofficial
OPC_AHX_ZPIY = $93; unofficial
OPC_STY_ZPX = $94
OPC_STA_ZPX = $95
OPC_STY_ZPY = $96
OPC_SAX_ZPY = $97; unofficial
OPC_TYA = $98
OPC_STA_ABSY = $99
OPC_TXS = $9a
OPC_TAS_ABSY = $9b; unofficial
OPC_SHF_ABSX = $9c; unofficial
OPC_STA_ABSX = $9d
OPC_SHX_ABSY = $9e; unofficial
OPC_AHX_ABSY = $9f; unofficial
OPC_LDY_IMM = $a0
OPC_LDA_ZPXI = $a1
OPC_LDX_IMM = $a2
OPC_LAX_ZPXI = $a3; unofficial
OPC_LDY_ZP = $a4
OPC_LDA_ZP = $a5
OPC_LDX_ZP = $a6
OPC_LAX_ZP = $a7
OPC_TAY = $a8
OPC_LDA_IMM = $a9
OPC_TAX = $aa
OPC_LAX_IMM = $ab; unofficial
OPC_LDY_ABS = $ac
OPC_LDA_ABS = $ad
OPC_LDX_ABS = $ae
OPC_LAX_ABS = $af; unofficial
OPC_BCS = $b0
OPC_LDA_ZPIY = $b1
;OPC_JAM = $b2; unofficial
;OPC_LAX_ZPI = $b3; unofficial
OPC_LDY_ZPX = $b4
OPC_LDA_ZPX = $b5
OPC_LDX_ZPY = $b6
OPC_LAX_ZPY = $b7; unofficial
OPC_CLV = $b8
OPC_LDA_ABSY = $b9
OPC_TSX = $ba
OPC_LAS_ABSY = $bb
OPC_LDY_ABSX = $bc
OPC_LDA_ABSX = $bd
OPC_LDX_ABSY = $be
OPC_LAX_ABSY = $bf; unofficial
OPC_CPY_IMM = $c0
OPC_CMP_ZPXI = $c1
;OPC_NOP_IMM = $c2; unofficial
OPC_DCP_ZPXI = $c3; unofficial
OPC_CPY_ZP = $c4
OPC_CMP_ZP = $c5
OPC_DEC_ZP = $c6
OPC_DCP_ZP = $c7; unofficial
OPC_INY = $c8
OPC_CMP_IMM = $c9
OPC_DEX = $ca
OPC_SBX_IMM = $cb; unofficial
OPC_CPY_ABS = $cc
OPC_CMP_ABS = $cd
OPC_DEC_ABS = $ce
OPC_DCP_ABS = $cf; unofficial
OPC_BNE = $d0
OPC_CMP_ZPIY = $d1
;OPC_JAM = $d2; unofficial
OPC_DCP_ZPIY = $d3; unofficial
;OPC_NOP_ZPX = $d4; unofficial
OPC_CMP_ZPX = $d5
OPC_DEC_ZPX = $d6
OPC_DCP_ZPX = $d7; unofficial
OPC_CLD = $d8
OPC_CMP_ABSY = $d9
;OPC_NOP = $da; unofficial
OPC_DCP_ABSY = $db; unofficial
;OPC_NOP_ABSX = $dc; unofficial
OPC_CMP_ABSX = $dd
OPC_DEC_ABSX = $de
OPC_DCP_ABSX = $df; unofficial
OPC_CPX_IMM = $e0
OPC_SBC_ZPXI = $e1
;OPC_NOP_IMM = $e2; unofficial
OPC_ISC_ZPXI = $e3; unofficial
OPC_CPX_ZP = $e4
OPC_SBC_ZP = $e5
OPC_INC_ZP = $e6
OPC_ISC_ZP = $e7; unofficial
OPC_INX = $e8
OPC_SBC_IMM = $e9
OPC_NOP = $ea
;OPC_SBC_IMM = $eb
OPC_CPX_ABS = $ec
OPC_SBC_ABS = $ed
OPC_INC_ABS = $ee
OPC_ISC_ABS = $ef; unofficial
OPC_BEQ = $f0
OPC_SBC_ZPIY = $f1
;OPC_JAM = $f2; unofficial
OPC_ISC_ZPIY = $f3; unofficial
;OPC_NOP_ZPX = $f4; unofficial
OPC_SBC_ZPX = $f5
OPC_INC_ZPX = $f6
OPC_ISC_ZPX = $f7; unofficial
OPC_SED = $f8
OPC_SBC_ABSY = $f9
;OPC_NOP = $fa; unofficial
OPC_ISC_ABSY = $fb; unofficial
;OPC_NOP_ABSX = $fc; unofficial
OPC_SBC_ABSX = $fd
OPC_INC_ABSX = $fe
OPC_ISC_ABSX = $ff; unofficial
NEGATIVE = $80; N flag
OVERFLOW = $40; V flag
BREAK = $10; B flag
DECIMAL = $08; D flag
INTERRUPT = $04; I flag
ZERO = $02; Z flag
CARRY = $01; C flag
FLAG_N = $80; N flag
FLAG_V = $40; V flag
FLAG_B = $10; B flag
FLAG_D = $08; D flag
FLAG_I = $04; I flag
FLAG_Z = $02; Z flag
FLAG_C = $01; C flag
IO_PORT_DIRECTION = $00
.if PLATFORM = 16
IO_PORT_SERIAL_DATA_OUT_OUTPUT = %00000001
IO_PORT_SERIAL_DATA_OUT_INPUT = %00000000
IO_PORT_SERIAL_CLK_OUT_OUTPUT = %00000010
IO_PORT_SERIAL_CLK_OUT_INPUT = %00000000
IO_PORT_SERIAL_ATN_OUT_OUTPUT = %00000100
IO_PORT_SERIAL_ATN_OUT_INPUT = %00000000
IO_PORT_CST_MTR_OUTPUT = %00001000
IO_PORT_CST_MTR_INPUT = %00000000
IO_PORT_CST_RD_OUTPUT = %00010000
IO_PORT_CST_RD_INPUT = %00000000
IO_PORT_SERIAL_CLK_IN_OUTPUT = %01000000
IO_PORT_SERIAL_CLK_IN_INPUT = %00000000
IO_PORT_CST_WRT_INPUT = IO_PORT_SERIAL_CLK_IN_INPUT
IO_PORT_CST_WRT_OUTPUT = IO_PORT_SERIAL_CLK_IN_OUTPUT
IO_PORT_SERIAL_DATA_IN_OUTPUT = %10000000
IO_PORT_SERIAL_DATA_IN_INPUT = %00000000
IO_PORT_CST_SENSE_INPUT = IO_PORT_SERIAL_DATA_IN_INPUT
IO_PORT_CST_SENSE_OUTPUT = IO_PORT_SERIAL_DATA_IN_OUTPUT
.else
LORAM_OUTPUT = %00000001
LORAM_INPUT = %00000000
HIRAM_OUTPUT = %00000010
HIRAM_INPUT = %00000000
CHAREN_OUTPUT = %00000100
CHAREN_INPUT = %00000000
CASSETTE_WRITE_OUTPUT = %00001000
CASSETTE_WRITE_INPUT = %00000000
CASSETTE_SENSE_OUTPUT = %00010000
CASSETTE_SENSE_INPUT = %00000000
CASSETTE_MOTOR_OUTPUT = %00100000
CASSETTE_MOTOR_INPUT = %00000000
IO_PORT_DIRECTION_DEFAULT = CASSETTE_MOTOR_OUTPUT | CASSETTE_SENSE_OUTPUT | CASSETTE_WRITE_OUTPUT | CHAREN_OUTPUT | HIRAM_OUTPUT | LORAM_OUTPUT
.endif
IO_PORT = $01
.if PLATFORM = 16
IO_PORT_SERIAL_DATA_OUT = %00000001
IO_PORT_CST_SENSE_OUT = %00000001
IO_PORT_SERIAL_CLK_OUT = %00000010
IO_PORT_CST_WRT_OUT = %00000010
IO_PORT_SERIAL_ATN_OUT = %00000100
IO_PORT_CST_MTR = %00001000
IO_PORT_CST_MTR_OFF = IO_PORT_CST_MTR
IO_PORT_CST_MTR_ON = %00000000
IO_PORT_CST_RD = %00010000
IO_PORT_SERIAL_CLK_IN = %01000000
IO_PORT_CST_WRT_IN = %01000000
IO_PORT_SERIAL_DATA_IN = %10000000
IO_PORT_CST_SENSE_IN = %10000000
.else
CASSETTE_WRITE = %00001000
CASSETTE_SENSE = %00010000
CASSETTE_MOTOR = %00100000
.if PLATFORM = 128
CPU_D800_BANK_0 = %00000000
CPU_D800_BANK_1 = %00000001
VIC_D800_BANK_0 = %00000000
VIC_D800_BANK_1 = %00000010
CHARGEN_ENABLED = %00000000
CHARGEN_DISABLED = %00000100
CAPS_LOCK_OFF = %01000000; ASCII for German C-128
CAPS_LOCK_ON = %00000000; DIN for German C-128
IO_PORT_CHARGEN_ENABLED = CAPS_LOCK_OFF | CASSETTE_SENSE | CASSETTE_MOTOR | CHARGEN_ENABLED | VIC_D800_BANK_1 | CPU_D800_BANK_1; $77
IO_PORT_CHARGEN_DISABLED = CAPS_LOCK_OFF | CASSETTE_SENSE | CASSETTE_MOTOR | CHARGEN_DISABLED | VIC_D800_BANK_1 | CPU_D800_BANK_1; $73
.else
LORAM = %00000001
HIRAM = %00000010
CHAREN = %00000100
MEMCONFIG_IO_KERNAL_BASIC = CASSETTE_SENSE | CASSETTE_MOTOR | CHAREN | HIRAM | LORAM; $37
MEMCONFIG_IO_KERNAL = CASSETTE_SENSE | CASSETTE_MOTOR | CHAREN | HIRAM | 0 ; $36
MEMCONFIG_IO = CASSETTE_SENSE | CASSETTE_MOTOR | CHAREN | 0 | LORAM; $35
MEMCONFIG_ALL_RAM_2 = CASSETTE_SENSE | CASSETTE_MOTOR | CHAREN | 0 | 0 ; $34
MEMCONFIG_CHARGEN_KERNAL_BASIC = CASSETTE_SENSE | CASSETTE_MOTOR | 0 | HIRAM | LORAM; $33
MEMCONFIG_CHARGEN_KERNAL = CASSETTE_SENSE | CASSETTE_MOTOR | 0 | HIRAM | 0 ; $32
MEMCONFIG_CHARGEN = CASSETTE_SENSE | CASSETTE_MOTOR | 0 | 0 | LORAM; $31
MEMCONFIG_ALL_RAM = CASSETTE_SENSE | CASSETTE_MOTOR | 0 | 0 | 0 ; $30
.endif
.endif
STACK = $0100
NMI_VECTOR = $fffa
NMI_VECTORLO = $fffa
NMI_VECTORHI = $fffb
RESET_VECTOR = $fffc
RESET_VECTORLO = $fffc
RESET_VECTORHI = $fffd
IRQ_VECTOR = $fffe
IRQ_VECTORLO = $fffe
IRQ_VECTORHI = $ffff
.macro SKIPBYTE
.byte OPC_BIT_ZP
.endmacro
.macro SKIPBYTE_NOP
.byte OPC_NOP_IMM
.endmacro
.macro SKIPWORD
.byte OPC_BIT_ABS
.endmacro
.macro SKIPWORD_NOP
.byte OPC_NOP_ABS
.endmacro
.endif; !_CPU_INC_

26
shared/float.inc Normal file
View file

@ -0,0 +1,26 @@
.ifndef _FLOAT_INC_
_FLOAT_INC_ = 1
.include "basic.inc"
.include "kernal.inc"
.macro UINT16TOFAC
ldy #$00
jsr INT24TOMANTISSA
sec
jsr NORMALIZE
.endmacro
.macro INT32TOFAC arg
lda arg + $00
ldx arg + $01
ldy arg + $02
jsr INT24TOMANTISSA
lda arg + $03
sta FACHO
sec
jsr NORMALIZE
.endmacro
.endif; FLOAT_INC

239
shared/kernal.inc Executable file
View file

@ -0,0 +1,239 @@
.ifndef _KERNAL_INC_
_KERNAL_INC_ = 1
DEVICE_SCREEN = $03
.if .defined(PLATFORM) & (PLATFORM = 128)
BANK = $02
PC = $03
S_REG = $05
A_REG = $06
X_REG = $07
Y_REG = $08
TEMPST = $1b; temporary string descriptor stack
TEMPST_LEN = 0
TEMPST_PTR = 1
INDEX1 = $24; utility pointer area
VARTAB = $2f; start of BASIC variables
FRETOP = $35; pointer: bottom of string storage
FACEXP = $63; FAC exponent
FACHO = $64; FAC mantissa
.else
INDEX1 = $22; utility pointer area
VARTAB = $2d; start of BASIC variables
FRETOP = $33; pointer: bottom of string storage
FRESPC = $35; utility string pointer
FACEXP = $61; FAC exponent
FACHO = $62; FAC mantissa
STRDSC = $64; temporary string descriptor
STRDSC_LEN = 0
STRDSC_PTR = 1
FACSGN = $66; FAC sign
.endif
STATUS = $90
VERCK = $93
CINV = $0314
CBINV = $0316
C3PO = $94; serial bus output char buffered flag
BSOUR = $95; char buffer for serial bus
.if .defined(PLATFORM) & (PLATFORM = 16)
KERNAL_ROM = $8000
KERNAL_ROM_SIZE = $8000
LDTND = $97; logical file index/open files count
DFLTN = $98; default input device
DFLTO = $99; default output device
MSGFLG = $9a
EAL = $9d; end address lo
EAH = $9e; end address hi
R2D2 = $a6; serial bus EOI flag
BSOUR1 = $a8; serial bus shift counter
COUNT = $aa; serial bus counter
FNLEN = $ab; length of current file name
LA = $ac; logical file number
SA = $ad; current secondary address
FA = $ae; current I/O device
FNADR = $af; current file name
MEMUSS = $b4; load ram base
PNT = $c8; current screen line address
PNTR = $ca; cursor column on current line
QTSW = $cb; quote switch
USE4DY = $f9
IBASIN = $0322; CHRIN vector
IBSOUT = $0324; CHROUT vector
ILOAD = $032e; LOAD vector
COLOR = $053b
PALETTE = $07f9
PALETTE_DEFAULT = $ff
PALETTE_USER = $00
CLRSCR = $d88b
NOEOI = $e19f; send byte on serial bus
CHECKPARALLEL = $eda9; check if drive is parallel
LUKING = $f160
LODING = $f189
ERROR9 = $f28b
NLOAD = $f04a
KPREND = $fcc3; restore registers and return from IRQ handler
.else; !(.defined(PLATFORM) & (PLATFORM = 16))
KERNAL_ROM = $e000
KERNAL_ROM_SIZE = $2000
LDTND = $98; logical file index/open files count
DFLTN = $99; default input device
DFLTO = $9a; default output device
MSGFLG = $9d
R2D2 = $a3; serial bus EOI flag
BSOUR1 = $a4; serial bus shift counter
COUNT = $a5; serial bus counter
EAL = $ae; end address lo
EAH = $af; end address hi
FNLEN = $b7; length of current file name
LA = $b8; logical file number
SA = $b9; current secondary address
FA = $ba; current I/O device
FNADR = $bb; current file name
STAL = $c1; start address lo
STAH = $c2; start address hi
MEMUSS = $c3; load ram base
.if .defined(PLATFORM) & (PLATFORM = 128)
FNBANK = $c7; filename bank
MODE = $d7
PNT = $e0; current screen line address
USER = $e2; current screen line colour address
PNTR = $ec; cursor column on current line
COLOR = $f1
QTSW = $f4; quote switch
BUF = $0200; BASIC and monitor input buffer
PALNTS = $0a03; 0: NTSC, 1: PAL
ENABL = $0a0f; RS232 activity flags
SERIAL = $0a1c
BLNON = $0a26; on/off blink flag
BLNSW = $0a27; cursor blink enable
BLNCT = $0a28; count to toggle cursor
GDBLN = $0a29; char under cursor
GDCOL = $0a2a; original colour under cursor
VM1 = $0a2c; VIC text screen and character base ($d018 shadow)
.else; !(.defined(PLATFORM) & (PLATFORM = 128))
BLNSW = $cc; cursor blink enable
BLNCT = $cd; count to toggle cursor
GDBLN = $ce; char under cursor
BLNON = $cf; on/off blink flag
PNT = $d1; current screen line address
PNTR = $d3; cursor column on current line
QTSW = $d4; quote switch
LDTB1 = $d9
USER = $f3; current screen line colour address
COLOR = $0286
GDCOL = $0287; original colour under cursor
ENABL = $02a1; RS232 activity flags
PALNTS = $02a6; 0: NTSC, 1: PAL
.endif; !(.defined(PLATFORM) & (PLATFORM = 128))
NMINV = $0318
IOPEN = $031a
ICLOSE = $031c
ICHKIN = $031e
ICHKOUT = $0320
ICLRCH = $0322
IBASIN = $0324
IBSOUT = $0326
ISTOP = $0328
IGETIN = $032a
ICLALL = $032c
USRCMD = $032e
ILOAD = $0330
ISAVE = $0332
.if .defined(PLATFORM) & (PLATFORM = 128)
PRINT = $c72d
CURSORON = $cb21
DSPP = $cc34; reset cursor blink count, set colour pointer, put a char on the screen
NOEOI = $e3ae; send byte on serial bus
LUKING = $f50f
LODING = $f533
ERROR9 = $f694
SETBANK = $f73f
KPREND = $ff33; restore registers and return from IRQ handler
SWAPPER = $ff5f
JSRFAR = $ff6e
FETCH = $ff74
.else; !(.defined(PLATFORM) & (PLATFORM = 128))
POLYX = $e059
CLRSCR = $e544
DSPP = $ea13; reset cursor blink count, set colour pointer, put a char on the screen
DSPP2 = $ea1c; put a char on the screen
SCOLOR = $ea24; synchronise colour pointer
KEY = $ea31; keyboard/cursor handler
KPREND = $ea7e; ack timer, restore registers and return from IRQ handler
ROWSLO = $ecf0
NOEOI = $ed5a; send byte on serial bus
NLOAD = $f4a5
LUKING = $f5af
LODING = $f5d2
ERROR9 = $f713
.endif; !(.defined(PLATFORM) & (PLATFORM = 128))
.endif; !(.defined(PLATFORM) & (PLATFORM = 16))
SECND = $ff93
SA_LISTEN = $20
SA_UNLISTEN = $3f
SA_TALK = $40
SA_UNTALK = $5f
SA_OPENCHANNEL = $60
SA_CLOSE = $e0
SA_OPEN = $f0
TKSA = $ff96
ACPTR = $ffa5
CIOUT = $ffa8
UNTLK = $ffab
UNLSN = $ffae
LISTN = $ffb1
TALK = $ffb4
READSS = $ffb7
KERNAL_STATUS_EOF = %01000000
KERNAL_STATUS_EOF_BURST = %00011111
KERNAL_STATUS_ERROR_BURST = %00000010; >= 2
SETLFS = $ffba
COMMAND_ERROR_CHANNEL = $0f
SETNAM = $ffbd
OPEN = $ffc0
OPEN_TOOMANYFILES = $01
OPEN_FILEOPEN = $02
OPEN_FILENOTOPEN = $03
OPEN_FILENOTFOUND = $04
OPEN_DEVICENOTPRESENT = $05
OPEN_NOTINPUTFILE = $06
OPEN_NOTOUTPUTFILE = $07
OPEN_MISSINGFILENAME = $08
OPEN_ILLEGALDEVICENUMBER = $09
CLOSE = $ffc3
CHKIN = $ffc6
CKOUT = $ffc9
CLRCH = $ffcc
BASIN = $ffcf
BSOUT = $ffd2
LOAD = $ffd5
SAVE = $ffd8
CLALL = $ffe7
.endif; !_KERNAL_INC_

36
shared/mmu.inc Normal file
View file

@ -0,0 +1,36 @@
; MOS8722
.ifndef _MMU_INC_
_MMU_INC_ = 1
MMU_PCRA = $d501; Preconfiguration Register A
MMU_PCRB = $d502; Preconfiguration Register B
MMU_PCRC = $d503; Preconfiguration Register C
MMU_PCRD = $d504; Preconfiguration Register D
MMU_RCR = $d506; RAM Configuration Register
VIC_BANK_0 = %00000000
SHARED_RAM_LO = %00000100
SHARED_RAM_1K = %00000000
SHARED_RAM_4K = %00000001
SHARED_RAM_8K = %00000010
SHARED_RAM_16K = %00000011
MMU_CR = $ff00; Configuration Register
BANK_0 = %00000000
BANK_1 = %01000000
SYSTEM_ROM = %00000000
HIGH_RAM = %00110000 ; $c000-$ffff
BASIC_HI = %00000000
MID_RAM = %00001100 ; $8000-$bfff
BASIC_LO = %00000000
LOW_RAM = %00000010 ; $4000-$7fff
IO_SPACE = %00000000
RAM_ROM = %00000001
MMU_LCRA = $ff01; Load Configuration Register A
MMU_LCRB = $ff02; Load Configuration Register B
MMU_LCRC = $ff03; Load Configuration Register C
MMU_LCRD = $ff04; Load Configuration Register D
.endif; !_MMU_INC_

10
shared/pio.inc Normal file
View file

@ -0,0 +1,10 @@
; MOS6529
.ifndef _PIO_INC_
_PIO_INC_ = 1
PIO_USER_PORT = $fd10
PIO_KEYBOARD_COLUMN = $fd30
.endif

194
shared/standard.inc Normal file
View file

@ -0,0 +1,194 @@
.ifndef _STANDARD_INC_
_STANDARD_INC_ = 1
.include "cpu.inc"; SKIPWORD
;; binary arithmetics
.define IS_POWER_OF_2(value) (((value) & ((value) - 1)) = 0)
.define ALIGN(value, align) (((value) + (align) - 1) & ~((align) - 1))
.define TOP_BIT(value) (-1 + ((value) >= $1) + ((value) >= $2) + ((value) >= $4) + ((value) >= $8) + ((value) >= $10) + ((value) >= $20) + ((value) >= $40) + ((value) >= $80) + ((value) >= $0100) + ((value) >= $0200) + ((value) >= $0400) + ((value) >= $0800) + ((value) >= $1000) + ((value) >= $2000) + ((value) >= $4000) + ((value) >= $8000))
; rounds up to nearest power of 2
.define PAD(value) (1 + (((value) > $1) * $1) + (((value) > $2) * $2) + (((value) > $4) * $4) + (((value) > $8) * 8) + (((value) > $10) * $10) + (((value) > $20) * $20) + (((value) > $40) * $40) + (((value) > $80) * $80) + (((value) > $100) * $100) + (((value) > $200) * $200) + (((value) > $400) * $400) + (((value) > $800) * $800) + (((value) > $1000) * $1000) + (((value) > $2000) * $2000) + (((value) > $4000) * $4000) + (((value) > $8000) * $8000))
;; subroutine calling using the stack
; arguments are always pushed and popped with 16-bit sizes
.macro PUSH_ARG value
.ifnblank value
.if (.match (.left (1, {value}), #))
lda #<(.right (.tcount ({value}) - 1, {value}))
pha
lda #>(.right (.tcount ({value}) - 1, {value}))
pha
.else
lda value + 0
pha
lda value + 1
pha
.endif
.endif
.endmacro
.macro POP_ARG
pla
tay
pla
.endmacro
.macro CALL address, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
.local postcall
lda #>(postcall - 1)
pha
lda #<(postcall - 1)
pha
tsx
PUSH_ARG arg8
PUSH_ARG arg7
PUSH_ARG arg6
PUSH_ARG arg5
PUSH_ARG arg4
PUSH_ARG arg3
PUSH_ARG arg2
PUSH_ARG arg1
txa
pha
jmp address
postcall:
.endmacro
.macro VARARGS_START
pla
tax
.endmacro
.macro VARARGS_END
txs
.endmacro
;; memory manipulation
.macro MEMSET address, size, value
.ifref __memset_impl
CALL __memset_impl, address, size, value
.else
.local __post_memset_impl
CALL __memset_impl, address, size, value; for .ifref detection
jmp __post_memset_impl
; this implementation is optimized for
; fast inner loops at reasonable overhead
; (only one write access per loop pass)
__memset_impl:
; not re-entrant
.scope
VARARGS_START
POP_ARG
sta memsetlo
sty memsethi
POP_ARG
sta memsetsizelo
sty memsetsizehi
POP_ARG
sta memsetvalue
VARARGS_END
; check if region to fill starts on a page boundary
memsetlo = * + $01
ldx #$00
beq memsetpage
; if not, fill <256 bytes at the beginning of the region
sec
lda #$00
sbc memsetlo; number of bytes until next page boundary
sec
memsetsizelo = * + $01
sbc #$00
tax
lda #$00
sbc memsetsizehi
bcc :++
; region is between two page boundaries
lda memsetlo
sta :+ + $01
lda memsethi
sta :+ + $02
: sta a:$00,x
dex
bne :-
rts; that's it
: ; region stretches beyond at least one page boundary
lda memsethi
sta :+ + $02
lda memsetvalue
ldx memsetlo
: sta a:$00,x
inx
bne :-
sec; update memsetsize
;ldx #$00
txa
sbc memsetlo
sta :+ + $01
lda memsetsizelo
: sbc #$00
sta memsetsizelo
bcs :+
dec memsetsizehi
:
; fill whole pages
memsetpage:
memsetsizehi = * + $01
ldy #$00
beq memsetend
lda memsethi
sta :+ + $02
memsetvalue = * + $01
lda #$00
;ldx #$00
: sta a:$00,x
inx
bne :-
inc :- + $02
dey
bne :-
lda :- + $02
SKIPWORD
memsetend: ; fill remaining <256 bytes
memsethi = * + $01
lda #$00
sta :+ + $03
lda memsetvalue
ldx memsetsizelo
inx
: dex
sta a:$00,x
bne :-
rts
.endscope
__post_memset_impl:
.endif; __memset_impl
.endmacro
.endif; !_STANDARD_INC_

279
shared/ted.inc Executable file
View file

@ -0,0 +1,279 @@
; MOS7360/8360
.ifndef _TED_INC_
_TED_INC_ = 1
CYCLES_PER_LINE_PAL = 57; single clock
CYCLES_PER_LINE_NTSC = 57; single clock
DISPLAY_LINES_PAL = 312
DISPLAY_LINES_NTSC = 262
VSYNC_LINE_PAL = 257
VSYNC_LINE_NTSC = 229
SCREEN_COLUMNS = 40
SCREEN_ROWS = 25
SCREEN_SIZE = SCREEN_COLUMNS * SCREEN_ROWS
BITMAP_BACKGROUND = 0
BITMAP_SIZE = SCREEN_SIZE * 8
.define MAKE_HIRES_COLOURS(one_bits, zero_bits) (((zero_bits) << 4) | ((one_bits) & $0f))
.define MAKE_HIRES_INTENSITIES(one_bits, zero_bits) (((one_bits) & $f0) | ((zero_bits) >> 4))
.if PLATFORM = 16 ; cia.inc defines C-64 and 1581 symbols, so it might be included along with, e.g., ted.inc
; keyboard matrix positions
STOP_COLUMN = %01111111
STOP_ROW = %01111111
LEFT_SHIFT_COLUMN = %11111101
LEFT_SHIFT_ROW = %01111111
ALL_COLUMNS = %00000000
NO_ROWS = %11111111
.endif
TED_ROM_BANK_BASE = $fdd0
TED_ROM_BANK_0 = TED_ROM_BANK_BASE + 0
TED_ROM_BANK_1 = TED_ROM_BANK_BASE + 1
TED_ROM_BANK_2 = TED_ROM_BANK_BASE + 2
TED_ROM_BANK_3 = TED_ROM_BANK_BASE + 3
TED_ROM_BANK_4 = TED_ROM_BANK_BASE + 4
TED_ROM_BANK_5 = TED_ROM_BANK_BASE + 5
TED_ROM_BANK_6 = TED_ROM_BANK_BASE + 6
TED_ROM_BANK_7 = TED_ROM_BANK_BASE + 7
TED_ROM_BANK_8 = TED_ROM_BANK_BASE + 8
TED_ROM_BANK_9 = TED_ROM_BANK_BASE + 9
TED_ROM_BANK_10 = TED_ROM_BANK_BASE + 10
TED_ROM_BANK_11 = TED_ROM_BANK_BASE + 11
TED_ROM_BANK_12 = TED_ROM_BANK_BASE + 12
TED_ROM_BANK_13 = TED_ROM_BANK_BASE + 13
TED_ROM_BANK_14 = TED_ROM_BANK_BASE + 14
TED_ROM_BANK_15 = TED_ROM_BANK_BASE + 15
TED_BASE = $ff00
CHARSET_ADDR_UPPERGRAPHIC = $d000
CHARSET_ADDR_UPPERLOWER = $d400
ROM_CHARSET_UPGFX = CHARSET_ADDR_UPPERGRAPHIC
ROM_CHARSET_UPLOW = CHARSET_ADDR_UPPERLOWER
COLOUR_BLACK = $00
COLOUR_WHITE = $01
COLOUR_RED = $02
COLOUR_CYAN = $03
COLOUR_VIOLET = $04
COLOUR_PURPLE = COLOUR_VIOLET
COLOUR_LILAC = COLOUR_VIOLET
COLOUR_GREEN = $05
COLOUR_BLUE = $06
COLOUR_YELLOW = $07
COLOUR_ORANGE = $08
COLOUR_BROWN = $09
COLOUR_LIGHTRED = $0a
INTENSITY_0 = $00
INTENSITY_1 = $10
INTENSITY_2 = $20
INTENSITY_3 = $30
INTENSITY_4 = $40
INTENSITY_5 = $50
INTENSITY_6 = $60
INTENSITY_7 = $70
BLINK = $80
COLOUR_DARKGREY = COLOUR_WHITE | INTENSITY_3
COLOUR_MEDIUMGREY = COLOUR_WHITE | INTENSITY_4
TED_COUNTER1_LO = TED_BASE + $00
TED_COUNTER1_HI = TED_BASE + $01
TED_COUNTER2_LO = TED_BASE + $02
TED_COUNTER2_HI = TED_BASE + $03
TED_COUNTER3_LO = TED_BASE + $04
TED_COUNTER3_HI = TED_BASE + $05
TED_CTRL1 = TED_BASE + $06; Control register 1
SCROLLY_0 = %00000000
SCROLLY_1 = %00000001
SCROLLY_2 = %00000010
SCROLLY_3 = %00000011
SCROLLY_4 = %00000100
SCROLLY_5 = %00000101
SCROLLY_6 = %00000110
SCROLLY_7 = %00000111
SCROLLY_MASK = %00000111
LINES_24 = %00000000
LINES_25 = %00001000
DISPLAY_ENABLE = %00010000
DISPLAY_DISABLE = %00000000
TEXT_MODE = %00000000
BITMAP_MODE = %00100000
EBCM_MODE = %01000000
INVALID_MODE = %01100000
TED_CTRL2 = TED_BASE + $07; Control register 2
SCROLLX_0 = %00000000
SCROLLX_1 = %00000001
SCROLLX_2 = %00000010
SCROLLX_3 = %00000011
SCROLLX_4 = %00000100
SCROLLX_5 = %00000101
SCROLLX_6 = %00000110
SCROLLX_7 = %00000111
SCROLLX_MASK = %00000111
COLUMNS_38 = %00000000
COLUMNS_40 = %00001000
SINGLECOLOUR_MODE = %00000000
MULTICOLOUR_MODE = %00010000
FREEZE = %00100000
PAL_NTSC_MASK = %01000000
NTSC = PAL_NTSC_MASK
PAL = %00000000
TED_KEYBOARD_LATCH = TED_BASE + $08
TED_IRR = TED_BASE + $09
RASTER_IRQ = %00000010
LIGHTPEN_IRQ = %00000100
COUNTER_1_IRQ = %00001000
COUNTER_2_IRQ = %00010000
COUNTER_3_IRQ = %01000000
TED_IMR = TED_BASE + $0a
IRQ_RASTERLINE_MSB = %00000001
;RASTER_IRQ = %00000010
;LIGHTPEN_IRQ = %00000100
;COUNTER_1_IRQ = %00001000
;COUNTER_2_IRQ = %00010000
;COUNTER_3_IRQ = %01000000
TED_IRQ_RASTERLINE = TED_BASE + $0b
TED_CURSOR_HI = TED_BASE + $0c
TED_CURSOR_LO = TED_BASE + $0d
TED_BITMAP_ADDR = TED_BASE + $12
CHARSET_BITMAP_IN_ROM_MASK = %00000100
CHARSET_BITMAP_IN_ROM = CHARSET_BITMAP_IN_ROM_MASK
CHARSET_BITMAP_IN_RAM = %00000000
BITMAP_ADDR_MASK = %00111000
BITMAP_ADDR_SHIFT = 3
BITMAP_ADDR_RSHIFT = 10
.define MAKE_BITMAP_ADDR(address) .lobyte(.lobyte((address) >> BITMAP_ADDR_RSHIFT) & BITMAP_ADDR_MASK)
TED_CHARGEN_ADDR = TED_BASE + $13
ROM_IS_ENABLED = %00000001
FORCE_SINGLE_CLOCK = %00000010
ALLOW_DOUBLE_CLOCK = %00000000
CHARGEN_ADDR_MASK = %11111100
CHARGEN_ADDR_RSHIFT = 8
.define MAKE_CHARGEN_ADDR(address) .lobyte(.lobyte((address) >> CHARGEN_ADDR_RSHIFT) & CHARGEN_ADDR_MASK)
TED_SCREEN_ADDR = TED_BASE + $14
SCREEN_ADDR_MASK = %11111000
SCREEN_ADDR_SHIFT = 3
SCREEN_ADDR_RSHIFT = 8
.define MAKE_SCREEN_ADDR(address) .lobyte(((address) >> SCREEN_ADDR_RSHIFT) & SCREEN_ADDR_MASK)
TED_BGCOLOUR = TED_BASE + $15; Background colour
BGCOLOUR = TED_BGCOLOUR
TED_BGCOLOUR0 = TED_BGCOLOUR; Background colour 0
TED_BGCOLOUR1 = TED_BASE + $16; Background colour 1
TED_MULTICOLOUR0 = TED_BGCOLOUR1; Multicolour 1
TED_BGCOLOUR2 = TED_BASE + $17; Background colour 2
TED_MULTICOLOUR1 = TED_BGCOLOUR2; Multicolour 2
TED_BGCOLOUR3 = TED_BASE + $18; Background colour 3
TED_BORDERCOLOUR = TED_BASE + $19; Overscan colour
BORDERCOLOUR = TED_BORDERCOLOUR
TED_RASTERLINE_MSB = TED_BASE + $1c
TED_RASTERLINE_MSB_MASK = %00000001
TED_RASTERLINE = TED_BASE + $1d
RASTERLINE = TED_RASTERLINE
TED_RASTERCOLUMN = TED_BASE + $1e
TED_VERTSUBCOUNT = TED_BASE + $1f
VERTSUBCOUNT_MASK = %00000111
VERTSUBCOUNT_0 = %00000000
VERTSUBCOUNT_1 = %00000001
VERTSUBCOUNT_2 = %00000010
VERTSUBCOUNT_3 = %00000011
VERTSUBCOUNT_4 = %00000100
VERTSUBCOUNT_5 = %00000101
VERTSUBCOUNT_6 = %00000110
VERTSUBCOUNT_7 = %00000111
TED_ROM_ENABLE = TED_BASE + $3e; the RAM/ROM state also determines where TED fetches screen chars,
TED_RAM_ENABLE = TED_BASE + $3f; but not bitmap data (always RAM) and chargen (register $12, bit 2)
.macro WAIT_VBL
.scope
.local loop
.local pal
.local done
loop: lda TED_RASTERLINE
ldx TED_RASTERLINE_MSB
cmp TED_RASTERLINE
bne loop
bit TED_CTRL2
bvc pal
cmp #.lobyte(VSYNC_LINE_NTSC)
bne loop
txa
and #%00000001
cmp #.hibyte(VSYNC_LINE_NTSC)
bne loop
beq done
pal: cmp #.lobyte(VSYNC_LINE_PAL)
bne loop
txa
and #%00000001
cmp #.hibyte(VSYNC_LINE_PAL)
bne loop
done:
.endscope
.endmacro
.macro DISPLAY_HIRES_BITMAP bitmap, screen
WAIT_VBL
lda #BITMAP_MODE | DISPLAY_ENABLE | LINES_25 | SCROLLY_3
sta TED_CTRL1
lda TED_BITMAP_ADDR
and #.lobyte(~(BITMAP_ADDR_MASK | CHARSET_BITMAP_IN_ROM))
ora #MAKE_BITMAP_ADDR(bitmap)
sta TED_BITMAP_ADDR
lda TED_SCREEN_ADDR
and #.lobyte(~SCREEN_ADDR_MASK)
ora #MAKE_SCREEN_ADDR(screen)
sta TED_SCREEN_ADDR
.endmacro
; requires forced slow clock
.macro STABILIZE_RASTER
.local delay
.local delays
lda TED_RASTERCOLUMN
lsr
lsr
and #%00000111
sta delay
delay = * + $01
bpl delays
delays: lda #OPC_LDA_IMM
lda #OPC_LDA_IMM
lda #OPC_LDA_IMM
lda OPC_NOP
.endmacro
.endif; !_TED_INC_

15
shared/vdc.inc Normal file
View file

@ -0,0 +1,15 @@
; MOS8563/8568
.ifndef _VDC_INC_
_VDC_INC_ = 1
VDC_SR = $d600; Status Register
VRT = %00100000; vertical retrace
VDC_CR = $d600; Configuration Register
FG_BG = $1a; Foreground Colour/Background Colour
RED = $08
VDC_DR = $d601; Data Register
.endif; !_VDC_INC_

386
shared/via.inc Executable file
View file

@ -0,0 +1,386 @@
; MOS6522
.ifndef _VIA_INC_
_VIA_INC_ = 1
.ifdef CX500
; The Century Planning Corp. CX-500/Tecmate NPH-501C drive is not a 1541 clone, as the
; VIAs are located at $3800 and $5c00 due to simplified address decoding logics, and the ROM
; including the position of the GCR encoding and decoding tables is entirely different as well.
VIA1_BASE = $3800
.else
VIA1_BASE = $1800
.endif
VIA_PIO0 = %00000001
VIA_PIO1 = %00000010
VIA_PIO2 = %00000100
VIA_PIO3 = %00001000
VIA_PIO4 = %00010000
VIA_PIO5 = %00100000
VIA_PIO6 = %01000000
VIA_PIO7 = %10000000
VIA1_PRB = VIA1_BASE + $00; Port register B
VIA1_ORB = VIA1_PRB; Output Register B
VIA1_IRB = VIA1_PRB; Input Register B
DATA_IN = VIA_PIO0
DATA_OUT = VIA_PIO1
CLK_IN = VIA_PIO2
CLK_OUT = VIA_PIO3
ATNA_OUT = VIA_PIO4
DEVICE_NUMBER = VIA_PIO5 | VIA_PIO6
DEVICE_NUMBER_8 = %00000000
DEVICE_NUMBER_9 = VIA_PIO5
DEVICE_NUMBER_10 = VIA_PIO6
DEVICE_NUMBER_11 = VIA_PIO5 | VIA_PIO6
DEVICE_NUMBER_SHIFT = 5
DEVICE_NUMBER_MASK = DEVICE_NUMBER
ATN_IN = VIA_PIO7
; works only on 1571(CR)
VIA1_PRA = VIA1_BASE + $01; Port register A
VIA1_ORA = VIA1_PRA; Output Register A
VIA1_IRA = VIA1_PRA; Input Register A
TRACK_0 = %00000001
FAST_SERIAL_DIR = %00000010
FAST_SERIAL_INPUT = %00000000
FAST_SERIAL_OUTPUT = FAST_SERIAL_DIR
SIDE_SELECT = %00000100
SIDE_A = %00000000
SIDE_B = SIDE_SELECT
TWO_MHZ = %00100000
BYTE_READY = %10000000
VIA1_DDRB = VIA1_BASE + $02; Data direction register B
VIA_PIO0_OUTPUT = VIA_PIO0
VIA_PIO0_INPUT = %00000000
VIA_DATA_IN_OUTPUT = VIA_PIO0
VIA_DATA_IN_INPUT = %00000000
VIA_PIO1_OUTPUT = VIA_PIO1
VIA_PIO1_INPUT = %00000000
VIA_DATA_OUT_OUTPUT = VIA_PIO1
VIA_DATA_OUT_INPUT = %00000000
VIA_PIO2_OUTPUT = VIA_PIO2
VIA_PIO2_INPUT = %00000000
VIA_CLK_IN_OUTPUT = VIA_PIO2
VIA_CLK_IN_INPUT = %00000000
VIA_PIO3_OUTPUT = VIA_PIO3
VIA_PIO3_INPUT = %00000000
VIA_CLK_OUT_OUTPUT = VIA_PIO3
VIA_CLK_OUT_INPUT = %00000000
VIA_PIO4_OUTPUT = VIA_PIO4
VIA_PIO4_INPUT = %00000000
VIA_ATNA_OUT_OUTPUT = VIA_PIO4
VIA_ATNA_OUT_INPUT = %00000000
VIA_PIO5_OUTPUT = VIA_PIO5
VIA_PIO5_INPUT = %00000000
VIA_PIO6_OUTPUT = VIA_PIO6
VIA_PIO6_INPUT = %00000000
VIA_DEVICE_NUMBER_OUTPUT = VIA_PIO5 | VIA_PIO6
VIA_DEVICE_NUMBER_INPUT = %00000000
VIA_PIO7_OUTPUT = VIA_PIO7
VIA_PIO7_INPUT = %00000000
VIA_ATN_IN_OUTPUT = VIA_PIO7
VIA_ATN_IN_INPUT = %00000000
VIA1_DDRA = VIA1_BASE + $03; Data direction register A
VIA1_T1C_L = VIA1_BASE + $04; Timer 1 Lo
VIA1_T1_LO = VIA1_T1C_L
VIA1_T1C_H = VIA1_BASE + $05; Timer 1 Hi
VIA1_T1_HI = VIA1_T1C_H
VIA1_T1L_L = VIA1_BASE + $06; Timer 1 Latch Lo
VIA1_T1_LATCH_LO = VIA1_T1L_L
VIA1_T1L_H = VIA1_BASE + $07; Timer 1 Latch Hi
VIA1_T1_LATCH_HI = VIA1_T1L_H
VIA1_T2C_L = VIA1_BASE + $08; Timer 2 Lo
VIA1_T2_LO = VIA1_T2C_L
VIA1_T2C_H = VIA1_BASE + $09; Timer 2 Hi
VIA1_T2_HI = VIA1_T2C_H
VIA1_SR = VIA1_BASE + $0a; Shift Register
VIA1_ACR = VIA1_BASE + $0b; Auxiliary Control Register
PA_LATCHING_ENABLE = %00000001
PA_LATCHING_ENABLED = PA_LATCHING_ENABLE
PA_LATCHING_DISABLE = %00000000
PA_LATCHING_DISABLED = PA_LATCHING_DISABLE
PB_LATCHING_ENABLE = %00000010
PB_LATCHING_ENABLED = PB_LATCHING_ENABLE
PB_LATCHING_DISABLE = %00000000
PB_LATCHING_DISABLED = PB_LATCHING_DISABLE
SHIFT_REG_CONTROL = %00011100
SHIFT_DISABLE = %00000000
SHIFT_DISABLED = SHIFT_DISABLE
SHIFT_IN_T2 = %00000100
SHIFT_IN_02 = %00001000
SHIFT_IN_EXTCLK = %00001100
SHIFT_OUT_FREERUN_T2 = %00010000
SHIFT_OUT_T2 = %00010100
SHIFT_OUT_02 = %00011000
SHIFT_OUT_EXTCLK = %00011100
SHIFT_REG_CONTROL_SHIFT = 2
SHIFT_REG_CONTROL_MASK = SHIFT_REG_CONTROL
T2_CONTROL = %00100000
T2_TIMED_INTERRUPT = %00000000
T2_COUNTDOWN_PULSE_PB6 = T2_CONTROL
T1_CONTROL = %11000000
T1_ONE_SHOT = %00000000
T1_FREE_RUNNING = %01000000
T1_ONE_SHOT_PB7_OUT = %10000000
T1_FREE_RUNNING_INVERT_PB7_OUT = %11000000
T1_CONTROL_SHIFT = 6
T1_CONTROL_MASK = T1_CONTROL
VIA1_PCR = VIA1_BASE + $0c; Peripheral Control Register
CA1_INTERRUPT_CONTROL = %00000001
CA1_IRQ_ON_POS_ACTIVE_EDGE = CA1_INTERRUPT_CONTROL
CA1_IRQ_ON_NEG_ACTIVE_EDGE = %00000000
ATN_IN_IRQ_ON_POS_ACTIVE_EDGE = CA1_IRQ_ON_POS_ACTIVE_EDGE
ATN_IN_IRQ_ON_NEG_ACTIVE_EDGE = CA1_IRQ_ON_NEG_ACTIVE_EDGE
CA2_INTERRUPT_CONTROL = %00001110
CA2_INPUT_IRQ_NEG_ACT_EDGE = %00000000
CA2_INPUT_IND_IRQ_NEG_EDGE = %00000010
CA2_INPUT_IRQ_POS_ACT_EDGE = %00000100
CA2_INPUT_IND_IRQ_POS_EDGE = %00000110
CA2_OUTPUT_HANDSHAKE = %00001000
CA2_OUTPUT_PULSE = %00001010
CA2_OUTPUT_LOW = %00001100
CA2_OUTPUT_HIGH = %00001110
CA2_INTERRUPT_CONTROL_SHIFT = 1
CA2_INTERRUPT_CONTROL_MASK = CB2_INTERRUPT_CONTROL
CB1_INTERRUPT_CONTROL = %00010000
CB1_IRQ_ON_POS_ACTIVE_EDGE = CB1_INTERRUPT_CONTROL
CB1_IRQ_ON_NEG_ACTIVE_EDGE = %00000000
CB2_INTERRUPT_CONTROL = %11100000
CB2_INPUT_IRQ_NEG_ACT_EDGE = %00000000
CB2_INPUT_IND_IRQ_NEG_EDGE = %00100000
CB2_INPUT_IRQ_POS_ACT_EDGE = %01000000
CB2_INPUT_IND_IRQ_POS_EDGE = %01100000
CB2_OUTPUT_HANDSHAKE = %10000000
CB2_OUTPUT_PULSE = %10100000
CB2_OUTPUT_LOW = %11000000
CB2_OUTPUT_HIGH = %11100000
CB2_INTERRUPT_CONTROL_SHIFT = 5
CB2_INTERRUPT_CONTROL_MASK = CB2_INTERRUPT_CONTROL
VIA1_IFR = VIA1_BASE + $0d; Interrupt Flag Register
IRQ_CA2_ACTIVE_EDGE = %00000001
IRQ_CA1_ACTIVE_EDGE = %00000010
IRQ_ATN_ASSERTED = IRQ_CA1_ACTIVE_EDGE
IRQ_SHIFT_REG = %00000100
IRQ_CB2_ACTIVE_EDGE = %00001000
IRQ_CB1_ACTIVE_EDGE = %00010000
IRQ_TIMER_2 = %00100000
IRQ_TIMER_1 = %01000000
IRQS_PENDING = %10000000
VIA1_IER = VIA1_BASE + $0e; Interrupt Enable Register
;IRQ_CA2_ACTIVE_EDGE = %00000001
;IRQ_CA1_ACTIVE_EDGE = %00000010
;IRQ_SHIFT_REG = %00000100
;IRQ_CB2_ACTIVE_EDGE = %00001000
;IRQ_CB1_ACTIVE_EDGE = %00010000
;IRQ_TIMER_2 = %00100000
;IRQ_TIMER_1 = %01000000
IRQ_ALL_FLAGS = %01111111
IRQ_SET_FLAGS = %10000000
IRQ_CLEAR_FLAGS = %00000000
VIA1_PRA_NO_HANDSHAKE = VIA1_BASE + $0f; Port register A without Handshake
VIA1_ORA_NO_HANDSHAKE = VIA1_PRA_NO_HANDSHAKE; Output Register A without Handshake
VIA1_IRA_NO_HANDSHAKE = VIA1_PRA_NO_HANDSHAKE; Input Register A without Handshake
.ifdef CX500
VIA2_BASE = $5c00
.else
VIA2_BASE = $1c00
.endif
VIA2_PRB = VIA2_BASE + $00; Port register B
VIA2_ORB = VIA2_PRB; Output Register B
VIA2_IRB = VIA2_PRB; Input Register B
TRACK_STEP = VIA_PIO0 | VIA_PIO1
TRACK_STEP_SHIFT = 0
TRACK_STEP_MASK = TRACK_STEP
MOTOR = VIA_PIO2
BUSY_LED = VIA_PIO3
WRITE_PROTECT = VIA_PIO4
BITRATE = VIA_PIO5 | VIA_PIO6
BITRATE_SHIFT = 5
BITRATE_MASK = BITRATE
SYNC_MARK = VIA_PIO7
VIA2_PRA = VIA2_BASE + $01; Port register A
VIA2_ORA = VIA2_PRA; Output Register A
VIA2_IRA = VIA2_PRA; Input Register A
VIA2_DDRB = VIA2_BASE + $02; Data direction register B
;VIA_PIO0_OUTPUT = VIA_PIO0
;VIA_PIO0_INPUT = %00000000
;VIA_PIO1_OUTPUT = VIA_PIO1
;VIA_PIO1_INPUT = %00000000
VIA_TRACK_STEP_OUTPUT = VIA_PIO0 | VIA_PIO1
VIA_TRACK_STEP_INPUT = %00000000
;VIA_PIO2_OUTPUT = VIA_PIO2
;VIA_PIO2_INPUT = %00000000
VIA_MOTOR_OUTPUT = VIA_PIO2
VIA_MOTOR_INPUT = %00000000
;VIA_PIO3_OUTPUT = VIA_PIO3
;VIA_PIO3_INPUT = %00000000
VIA_BUSY_LED_OUTPUT = VIA_PIO3
VIA_BUSY_LED_INPUT = %00000000
;VIA_PIO4_OUTPUT = VIA_PIO4
;VIA_PIO4_INPUT = %00000000
VIA_WRITE_PROTECT_OUTPUT = VIA_PIO4
VIA_WRITE_PROTECT_INPUT = %00000000
;VIA_PIO5_OUTPUT = VIA_PIO5
;VIA_PIO5_INPUT = %00000000
;VIA_PIO6_OUTPUT = VIA_PIO6
;VIA_PIO6_INPUT = %00000000
VIA_BITRATE_OUTPUT = VIA_PIO5 | VIA_PIO6
VIA_BITRATE_INPUT = %00000000
;VIA_PIO7_OUTPUT = VIA_PIO7
;VIA_PIO7_INPUT = %00000000
VIA_SYNC_MARK_OUTPUT = VIA_PIO7
VIA_SYNC_MARK_INPUT = %00000000
VIA2_DDRA = VIA2_BASE + $03; Data direction register A
VIA2_T1C_L = VIA2_BASE + $04; Timer 1 Lo
VIA2_T1_LO = VIA2_T1C_L
VIA2_T1C_H = VIA2_BASE + $05; Timer 1 Hi
VIA2_T1_HI = VIA2_T1C_H
VIA2_T1L_L = VIA2_BASE + $06; Timer 1 Latch Lo
VIA2_T1_LATCH_LO = VIA2_T1L_L
VIA2_T1L_H = VIA2_BASE + $07; Timer 1 Latch Hi
VIA2_T1_LATCH_HI = VIA2_T1L_H
VIA2_T2C_L = VIA2_BASE + $08; Timer 2 Lo
VIA2_T2_LO = VIA2_T2C_L
VIA2_T2C_H = VIA2_BASE + $09; Timer 2 Hi
VIA2_T2_HI = VIA2_T2C_H
VIA2_SR = VIA2_BASE + $0a; Shift Register
VIA2_ACR = VIA2_BASE + $0b; Auxiliary Control Register
;PA_LATCHING_ENABLE = %00000001
;PA_LATCHING_ENABLED = PA_LATCHING_ENABLE
;PA_LATCHING_DISABLED = %00000000
;PB_LATCHING_ENABLE = %00000010
;PB_LATCHING_ENABLED = PB_LATCHING_ENABLE
;PB_LATCHING_DISABLED = %00000000
;SHIFT_REG_CONTROL = %00011100
;SHIFT_DISABLED = %00000000
;SHIFT_IN_T2 = %00000100
;SHIFT_IN_02 = %00001000
;SHIFT_IN_EXTCLK = %00001100
;SHIFT_OUT_FREERUN_T2 = %00010000
;SHIFT_OUT_T2 = %00010100
;SHIFT_OUT_02 = %00011000
;SHIFT_OUT_EXTCLK = %00011100
;SHIFT_REG_CONTROL_SHIFT = 2
;SHIFT_REG_CONTROL_MASK = SHIFT_REG_CONTROL
;T2_CONTROL = %00100000
;T2_TIMED_INTERRUPT = %00000000
;T2_COUNTDOWN_PULSE_PB6 = T2_CONTROL
;T1_CONTROL = %11000000
;T1_ONE_SHOT = %00000000
;T1_FREE_RUNNING = %01000000
;T1_ONE_SHOT_PB7_OUT = %10000000
;T1_FREE_RUNNING_INVERT_PB7_OUT = %11000000
;T1_CONTROL_SHIFT = 6
;T1_CONTROL_MASK = T1_CONTROL
VIA2_PCR = VIA2_BASE + $0c; Peripheral Control Register
;CA1_INTERRUPT_CONTROL = %00000001
;CA1_IRQ_ON_POS_ACTIVE_EDGE = CA1_INTERRUPT_CONTROL
;CA1_IRQ_ON_NEG_ACTIVE_EDGE = %00000000
BYTE_READY_IRQ_ON_POS_ACTIVE_EDGE = CA1_IRQ_ON_POS_ACTIVE_EDGE
BYTE_READY_IRQ_ON_NEG_ACTIVE_EDGE = CA1_IRQ_ON_NEG_ACTIVE_EDGE
;CA2_INTERRUPT_CONTROL = %00001110
;CA2_INPUT_IRQ_NEG_ACT_EDGE = %00000000
;CA2_INPUT_IND_IRQ_NEG_EDGE = %00000010
;CA2_INPUT_IRQ_POS_ACT_EDGE = %00000100
;CA2_INPUT_IND_IRQ_POS_EDGE = %00000110
;CA2_OUTPUT_HANDSHAKE = %00001000
;CA2_OUTPUT_PULSE = %00001010
;CA2_OUTPUT_LOW = %00001100
;CA2_OUTPUT_HIGH = %00001110
BYTE_SYNC_DISABLE = CA2_OUTPUT_LOW
BYTE_SYNC_DISABLED = BYTE_SYNC_DISABLE
BYTE_SYNC_ENABLE = CA2_OUTPUT_HIGH
BYTE_SYNC_ENABLED = BYTE_SYNC_ENABLE
;CA2_INTERRUPT_CONTROL_SHIFT = 1
;CA2_INTERRUPT_CONTROL_MASK = CB2_INTERRUPT_CONTROL
;CB1_INTERRUPT_CONTROL = %00010000
;CB1_IRQ_ON_POS_ACTIVE_EDGE = CB1_INTERRUPT_CONTROL
;CB1_IRQ_ON_NEG_ACTIVE_EDGE = %00000000
;CB2_INTERRUPT_CONTROL = %11100000
;CB2_INPUT_IRQ_NEG_ACT_EDGE = %00000000
;CB2_INPUT_IND_IRQ_NEG_EDGE = %00100000
;CB2_INPUT_IRQ_POS_ACT_EDGE = %01000000
;CB2_INPUT_IND_IRQ_POS_EDGE = %01100000
;CB2_OUTPUT_HANDSHAKE = %10000000
;CB2_OUTPUT_PULSE = %10100000
;CB2_OUTPUT_LOW = %11000000
;CB2_OUTPUT_HIGH = %11100000
WRITE_MODE = CB2_OUTPUT_LOW
READ_MODE = CB2_OUTPUT_HIGH
;CB2_INTERRUPT_CONTROL_SHIFT = 5
;CB2_INTERRUPT_CONTROL_MASK = CB2_INTERRUPT_CONTROL
VIA2_IFR = VIA2_BASE + $0d; Interrupt Flag Register
;IRQ_CA2_ACTIVE_EDGE = %00000001
;IRQ_CA1_ACTIVE_EDGE = %00000010
;IRQ_SHIFT_REG = %00000100
;IRQ_CB2_ACTIVE_EDGE = %00001000
;IRQ_CB1_ACTIVE_EDGE = %00010000
;IRQ_TIMER_2 = %00100000
;IRQ_TIMER_1 = %01000000
;IRQS_PENDING = %10000000
VIA2_IER = VIA2_BASE + $0e; Interrupt Enable Register
;IRQ_CA2_ACTIVE_EDGE = %00000001
;IRQ_CA1_ACTIVE_EDGE = %00000010
;IRQ_SHIFT_REG = %00000100
;IRQ_CB2_ACTIVE_EDGE = %00001000
;IRQ_CB1_ACTIVE_EDGE = %00010000
;IRQ_TIMER_2 = %00100000
;IRQ_TIMER_1 = %01000000
;IRQ_ALL_FLAGS = %01111111
;IRQ_SET_FLAGS = %10000000
;IRQ_CLEAR_FLAGS = %00000000
VIA2_PRA_NO_HANDSHAKE = VIA2_BASE + $0f; Port register A without Handshake
VIA2_ORA_NO_HANDSHAKE = VIA2_PRA_NO_HANDSHAKE; Output Register A without Handshake
VIA2_IRA_NO_HANDSHAKE = VIA2_PRA_NO_HANDSHAKE; Input Register A without Handshake
; the VIA in the CMD FD
VIA_BASE = $4000
VIA_PRA = VIA_BASE + $01; Port register A
VIA_T1C_L = VIA_BASE + $04; Timer 1 Lo
VIA_T1C_H = VIA_BASE + $05; Timer 1 Hi
VIA_T2C_H = VIA_BASE + $09; Timer 2 Hi
VIA_SR = VIA_BASE + $0a; Shift Register
VIA_ACR = VIA_BASE + $0b; Auxiliary Control Register
VIA_IER = VIA_BASE + $0e; Interrupt Enable Register
.endif; !_VIA_INC_

234
shared/vic.inc Normal file
View file

@ -0,0 +1,234 @@
; MOS6567/MOS6569
.ifndef _VIC_INC_
_VIC_INC_ = 1
.include "cia.inc"
CYCLES_PER_LINE_PAL = 63
CYCLES_PER_LINE_NTSC = 64
DISPLAY_LINES_PAL = 312
DISPLAY_LINES_NTSC = 263
VSYNC_LINE_PAL = 0
VSYNC_LINE_NTSC = 20
SCREEN_COLUMNS = 40
SCREEN_ROWS = 25
SCREEN_SIZE = SCREEN_COLUMNS * SCREEN_ROWS
BITMAP_BACKGROUND = 0
BITMAP_SIZE = SCREEN_SIZE * 8
.define MAKE_HIRES_COLOURS(one_bits, zero_bits) (((zero_bits) << 4) | (one_bits))
SPRITE_WIDTH = 24
SPRITE_POINTERS = $03f8
.define MAKE_SPRITE_POINTER(address) (.lobyte((address) >> 6))
VIC2_IDLE_PATTERN = $3fff
VIC2_BASE = $d000
CHARSET_ADDR_UPPERGRAPHIC = $d000
CHARSET_ADDR_UPPERLOWER = $d800
ROM_CHARSET_UPGFX = CHARSET_ADDR_UPPERGRAPHIC
ROM_CHARSET_UPLOW = CHARSET_ADDR_UPPERLOWER
VIC2_COLOURRAM = $d800
COLOUR_BLACK = $00
COLOUR_WHITE = $01
COLOUR_RED = $02
COLOUR_CYAN = $03
COLOUR_VIOLET = $04
COLOUR_PURPLE = COLOUR_VIOLET
COLOUR_LILAC = COLOUR_VIOLET
COLOUR_GREEN = $05
COLOUR_BLUE = $06
COLOUR_YELLOW = $07
COLOUR_ORANGE = $08
COLOUR_BROWN = $09
COLOUR_LIGHTRED = $0a
COLOUR_DARKGREY = $0b
COLOUR_MEDIUMGREY = $0c
COLOUR_LIGHTGREEN = $0d
COLOUR_LIGHTBLUE = $0e
COLOUR_LIGHTGREY = $0f
SPRITE_0 = %00000001
SPRITE_1 = %00000010
SPRITE_2 = %00000100
SPRITE_3 = %00001000
SPRITE_4 = %00010000
SPRITE_5 = %00100000
SPRITE_6 = %01000000
SPRITE_7 = %10000000
SPRITE0_X = VIC2_BASE + $00; Sprite 0, x-coordinate bits 0-7
SPRITE0_Y = VIC2_BASE + $01; Sprite 0, y-coordinate
SPRITE1_X = VIC2_BASE + $02; Sprite 1, x-coordinate bits 0-7
SPRITE1_Y = VIC2_BASE + $03; Sprite 1, y-coordinate
SPRITE2_X = VIC2_BASE + $04; Sprite 2, x-coordinate bits 0-7
SPRITE2_Y = VIC2_BASE + $05; Sprite 2, y-coordinate
SPRITE3_X = VIC2_BASE + $06; Sprite 3, x-coordinate bits 0-7
SPRITE3_Y = VIC2_BASE + $07; Sprite 3, y-coordinate
SPRITE4_X = VIC2_BASE + $08; Sprite 4, x-coordinate bits 0-7
SPRITE4_Y = VIC2_BASE + $09; Sprite 4, y-coordinate
SPRITE5_X = VIC2_BASE + $0a; Sprite 5, x-coordinate bits 0-7
SPRITE5_Y = VIC2_BASE + $0b; Sprite 5, y-coordinate
SPRITE6_X = VIC2_BASE + $0c; Sprite 6, x-coordinate bits 0-7
SPRITE6_Y = VIC2_BASE + $0d; Sprite 6, y-coordinate
SPRITE7_X = VIC2_BASE + $0e; Sprite 7, x-coordinate bits 0-7
SPRITE7_Y = VIC2_BASE + $0f; Sprite 7, y-coordinate
SPRITES_X_MSB = VIC2_BASE + $10; Sprites 0-7, x-coordinates bit 8
VIC2_CTRL1 = VIC2_BASE + $11; Control register 1
SCROLLY_0 = %00000000
SCROLLY_1 = %00000001
SCROLLY_2 = %00000010
SCROLLY_3 = %00000011
SCROLLY_4 = %00000100
SCROLLY_5 = %00000101
SCROLLY_6 = %00000110
SCROLLY_7 = %00000111
SCROLLY_MASK = %00000111
LINES_24 = %00000000
LINES_25 = %00001000
DISPLAY_ENABLE = %00010000
DISPLAY_DISABLE = %00000000
BITMAP_MODE = %00100000
TEXT_MODE = %00000000
EBCM_MODE = %01000000
RASTERLINE_BIT8 = %10000000
RASTERLINE_BIT8_SHIFT = 7
RASTERLINE_MSB = %10000000
RASTERLINE_MSB_SHIFT = 7
VIC2_RASTERLINE = VIC2_BASE + $12; Current raster line, raster IRQ trigger line
RASTERLINE = VIC2_RASTERLINE
MAX_RASTERLINE_PAL = $0137
MAX_RASTERLINE_NTSC = $0105
VIC2_STROBE_X = VIC2_BASE + $13; Light pen x-position
VIC2_STROBE_Y = VIC2_BASE + $14; Light pen y-position
VIC2_SPR_ENABLE = VIC2_BASE + $15; Enabled sprites
VIC2_CTRL2 = VIC2_BASE + $16; Control register 2
SCROLLX_0 = %00000000
SCROLLX_1 = %00000001
SCROLLX_2 = %00000010
SCROLLX_3 = %00000011
SCROLLX_4 = %00000100
SCROLLX_5 = %00000101
SCROLLX_6 = %00000110
SCROLLX_7 = %00000111
SCROLLX_MASK = %00000111
COLUMNS_38 = %00000000
COLUMNS_40 = %00001000
SINGLECOLOUR_MODE = %00000000
MULTICOLOUR_MODE = %00010000
VIC2_SPR_EXPANDY = VIC2_BASE + $17; y-expanded sprites
VIC2_ADDR = VIC2_BASE + $18; Character set and bitmap locations
SCREEN_MASK = %11110000
CHARSET_UPPERGRAPHIC = %00000100; $d000
CHARSET_UPPERLOWER = %00000110; $d800
CHARSET_MASK = %00001110
BITMAP_MASK = %00001000
.define VIC2_MAKE_ADDR(screen, charset_or_bitmap) .lobyte(((screen & $3fff) >> 6) | ((charset_or_bitmap & $3fff) >> 10))
VIC2_IRR = VIC2_BASE + $19; Interrupt Request Register
RASTER_IRQ = %00000001
SPR_BGR_COLL_IRQ = %00000010
SPR_SPR_COLL_IRQ = %00000100
LIGHTPEN_IRQ = %00001000
IRQ_FLAG = %10000000
VIC2_IMR = VIC2_BASE + $1a; Interrupt Mask Register
NO_INTERRUPTS = %00000000
;RASTER_IRQ = %00000001
;SPR_BGR_COLL_IRQ = %00000010
;SPR_SPR_COLL_IRQ = %00000100
;LIGHTPEN_IRQ = %00001000
VIC2_BG_PRIORITY = VIC2_BASE + $1b; Sprite-to-background priority
VIC2_SPR_MCOLOUR = VIC2_BASE + $1c; Sprites multicolour enabled
VIC2_SPR_EXPANDX = VIC2_BASE + $1d; Sprites x-expansion
VIC2_SPR_COLL = VIC2_BASE + $1e; Sprite-to-sprite collision
VIC2_SPR_BG_COLL = VIC2_BASE + $1f; Sprite-to-background collision
VIC2_BORDERCOLOUR = VIC2_BASE + $20; Overscan colour
BORDERCOLOUR = VIC2_BORDERCOLOUR
VIC2_BGCOLOUR = VIC2_BASE + $21; Background colour
BGCOLOUR = VIC2_BGCOLOUR
VIC2_BGCOLOUR0 = VIC2_BGCOLOUR; Background colour 0
VIC2_BGCOLOUR1 = VIC2_BASE + $22; Background colour 1
VIC2_MULTICOLOUR0 = VIC2_BGCOLOUR1; Multicolour 1
VIC2_BGCOLOUR2 = VIC2_BASE + $23; Background colour 2
VIC2_MULTICOLOUR1 = VIC2_BGCOLOUR2; Multicolour 2
VIC2_BGCOLOUR3 = VIC2_BASE + $24; Background colour 3
VIC2_SPR_MCOLOUR0 = VIC2_BASE + $25; Sprite multicolour 0
VIC2_SPR_MCOLOUR1 = VIC2_BASE + $26; Sprite multicolour 1
VIC2_SPR0_COLOUR = VIC2_BASE + $27; Sprite colour 0
VIC2_SPR1_COLOUR = VIC2_BASE + $28; Sprite colour 1
VIC2_SPR2_COLOUR = VIC2_BASE + $29; Sprite colour 2
VIC2_SPR3_COLOUR = VIC2_BASE + $2a; Sprite colour 3
VIC2_SPR4_COLOUR = VIC2_BASE + $2b; Sprite colour 4
VIC2_SPR5_COLOUR = VIC2_BASE + $2c; Sprite colour 5
VIC2_SPR6_COLOUR = VIC2_BASE + $2d; Sprite colour 6
VIC2_SPR7_COLOUR = VIC2_BASE + $2e; Sprite colour 7
VIC2_C128_EXT_KB = VIC2_BASE + $2f; Expanded keyboard matrix line
C128_EXT_KB = VIC2_C128_EXT_KB
VIC2_C128_CLOCK = VIC2_BASE + $30; Extended clock control
C128_CLOCK = VIC2_C128_CLOCK
C128_TWO_MHZ = %00000001
C128_INC_LINECNTR = %00000010
; c = 0: NTSC, c = 1: PAL
.macro WAIT_VBL
.scope
.local loop
lda #VSYNC_LINE_NTSC
bcc loop
lda #VSYNC_LINE_PAL
loop: cmp VIC2_RASTERLINE
bne loop
bit VIC2_CTRL1
bmi loop
cmp VIC2_RASTERLINE
bne loop
.endscope
.endmacro
.macro DISPLAY_HIRES_BITMAP bitmap, screen
WAIT_VBL
lda #BITMAP_MODE | DISPLAY_ENABLE | LINES_25 | SCROLLY_3
sta VIC2_CTRL1
lda #SINGLECOLOUR_MODE | COLUMNS_40 | SCROLLX_0
sta VIC2_CTRL2
lda #VIC2_MAKE_ADDR(screen, bitmap)
sta VIC2_ADDR
lda CIA2_PRA
and #.lobyte(~VIC2_BANK_MASK)
ora #VIC2_MAKE_BANK(bitmap)
sta CIA2_PRA
.endmacro
.endif; !_VIC_INC_