mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-01-25 23:31:42 +00:00
First cut at support for targetting the Atari 2600.
This commit is contained in:
parent
bb0e7aa992
commit
0093c7b7d9
@ -8,6 +8,8 @@ History of SixtyPical
|
|||||||
be used in most places where literal values can be used.
|
be used in most places where literal values can be used.
|
||||||
* Specifying multiple SixtyPical source files will produce a single
|
* Specifying multiple SixtyPical source files will produce a single
|
||||||
compiled result from their combination.
|
compiled result from their combination.
|
||||||
|
* Rudimentary support for Atari 2600 prelude in a 4K cartridge image,
|
||||||
|
and start of an example program in `eg/atari2600` directory.
|
||||||
|
|
||||||
0.14
|
0.14
|
||||||
----
|
----
|
||||||
|
@ -81,6 +81,12 @@ def process_input_files(filenames, options):
|
|||||||
start_addr = 0x1001
|
start_addr = 0x1001
|
||||||
prelude = [0x0b, 0x10, 0xc9, 0x07, 0x9e, 0x34,
|
prelude = [0x0b, 0x10, 0xc9, 0x07, 0x9e, 0x34,
|
||||||
0x31, 0x30, 0x39, 0x00, 0x00, 0x00]
|
0x31, 0x30, 0x39, 0x00, 0x00, 0x00]
|
||||||
|
elif options.prelude == 'atari2600':
|
||||||
|
output_format = 'crtbb'
|
||||||
|
start_addr = 0xf000
|
||||||
|
prelude = [0x78, 0xd8, 0xa2, 0xff, 0x9a, 0xa9,
|
||||||
|
0x00,0x95, 0x00, 0xca, 0xd0, 0xfb]
|
||||||
|
|
||||||
elif options.prelude:
|
elif options.prelude:
|
||||||
raise NotImplementedError("Unknown prelude: {}".format(options.prelude))
|
raise NotImplementedError("Unknown prelude: {}".format(options.prelude))
|
||||||
|
|
||||||
@ -94,6 +100,14 @@ def process_input_files(filenames, options):
|
|||||||
emitter.emit(Byte(byte))
|
emitter.emit(Byte(byte))
|
||||||
compiler = Compiler(emitter)
|
compiler = Compiler(emitter)
|
||||||
compiler.compile_program(program)
|
compiler.compile_program(program)
|
||||||
|
|
||||||
|
# If we are outputting a cartridge with boot and BRK address
|
||||||
|
# at the end, pad to ROM size minus 4 bytes, and emit addresses.
|
||||||
|
if output_format == 'crtbb':
|
||||||
|
emitter.pad_to_size(4096 - 4)
|
||||||
|
emitter.emit(Word(start_addr))
|
||||||
|
emitter.emit(Word(start_addr))
|
||||||
|
|
||||||
if options.debug:
|
if options.debug:
|
||||||
pprint(emitter.accum)
|
pprint(emitter.accum)
|
||||||
else:
|
else:
|
||||||
@ -119,15 +133,15 @@ if __name__ == '__main__':
|
|||||||
)
|
)
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"--output-format", type=str, default='prg',
|
"--output-format", type=str, default='prg',
|
||||||
help="Executable format to produce. Options are: prg (.PRG file "
|
help="Executable format to produce. Options are: prg, crtbb. "
|
||||||
"for Commodore 8-bit). Default: prg."
|
"Default: prg."
|
||||||
)
|
)
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"--prelude", type=str,
|
"--prelude", type=str,
|
||||||
help="Insert a snippet before the compiled program "
|
help="Insert a snippet of code before the compiled program so that "
|
||||||
"so that it can be LOADed and RUN on a certain platforms. "
|
"it can be booted automatically on a particular platform. "
|
||||||
"Also sets the origin and format. "
|
"Also sets the origin and format. "
|
||||||
"Options are: c64 or vic20."
|
"Options are: c64, vic20, atari2600."
|
||||||
)
|
)
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"--debug",
|
"--debug",
|
||||||
|
@ -38,4 +38,11 @@ In the [vic20](vic20/) directory are programs that run on the
|
|||||||
Commodore VIC-20. The directory itself contains some simple demos,
|
Commodore VIC-20. The directory itself contains some simple demos,
|
||||||
for example [hearts.60p](vic20/hearts.60p).
|
for example [hearts.60p](vic20/hearts.60p).
|
||||||
|
|
||||||
|
### atari2600
|
||||||
|
|
||||||
|
In the [vic20](vic20/) directory are programs that run on the
|
||||||
|
Atari 2600 (4K cartridge). The directory itself contains a simple
|
||||||
|
demo, [atari-2600-example.60p](atari2600/atari-2600-example.60p).
|
||||||
|
(Doesn't work yet.)
|
||||||
|
|
||||||
[Ophis]: http://michaelcmartin.github.io/Ophis/
|
[Ophis]: http://michaelcmartin.github.io/Ophis/
|
||||||
|
168
eg/atari2600/atari-2600-example.60p
Normal file
168
eg/atari2600/atari-2600-example.60p
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// atari-2600-example.60p - SixtyPical translation of atari-2600-example.oph
|
||||||
|
|
||||||
|
byte VSYNC @ $00
|
||||||
|
byte VBLANK @ $01
|
||||||
|
byte WSYNC @ $02
|
||||||
|
byte NUSIZ0 @ $04
|
||||||
|
byte NUSIZ1 @ $05
|
||||||
|
byte COLUPF @ $08
|
||||||
|
byte COLUBK @ $09
|
||||||
|
byte PF0 @ $0D
|
||||||
|
byte PF1 @ $0E
|
||||||
|
byte PF2 @ $0F
|
||||||
|
byte SWCHA @ $280
|
||||||
|
byte INTIM @ $284
|
||||||
|
byte TIM64T @ $296
|
||||||
|
byte CTRLPF @ $0A
|
||||||
|
byte COLUP0 @ $06
|
||||||
|
byte COLUP1 @ $07
|
||||||
|
byte GP0 @ $1B
|
||||||
|
byte GP1 @ $1C
|
||||||
|
byte HMOVE @ $2a
|
||||||
|
byte RESP0 @ $10
|
||||||
|
byte RESP1 @ $11
|
||||||
|
|
||||||
|
byte colour @ $80
|
||||||
|
byte luminosity @ $81
|
||||||
|
byte joystick_delay @ $82
|
||||||
|
|
||||||
|
byte table[8] image_data : "ZZZZUUUU"
|
||||||
|
// %01111110
|
||||||
|
// %10000001
|
||||||
|
// %10011001
|
||||||
|
// %10100101
|
||||||
|
// %10000001
|
||||||
|
// %10100101
|
||||||
|
// %10000001
|
||||||
|
// %01111110
|
||||||
|
|
||||||
|
|
||||||
|
define vertical_blank routine
|
||||||
|
outputs VSYNC, WSYNC, TIM64T
|
||||||
|
trashes a, x, z, n
|
||||||
|
{
|
||||||
|
ld x, $00
|
||||||
|
ld a, $02
|
||||||
|
st a, WSYNC
|
||||||
|
st a, WSYNC
|
||||||
|
st a, WSYNC
|
||||||
|
st a, VSYNC
|
||||||
|
st a, WSYNC
|
||||||
|
st a, WSYNC
|
||||||
|
ld a, $2C
|
||||||
|
st a, TIM64T
|
||||||
|
ld a, $00
|
||||||
|
st a, WSYNC
|
||||||
|
st a, VSYNC
|
||||||
|
}
|
||||||
|
|
||||||
|
define display_frame routine
|
||||||
|
inputs INTIM, image_data
|
||||||
|
outputs WSYNC, HMOVE, VBLANK, RESP0, GP0, PF0, PF1, PF2, COLUPF, COLUBK
|
||||||
|
trashes a, x, y, z, n
|
||||||
|
{
|
||||||
|
repeat {
|
||||||
|
ld a, INTIM
|
||||||
|
} until z
|
||||||
|
|
||||||
|
//; (After that loop finishes, we know the accumulator must contain 0.)
|
||||||
|
|
||||||
|
st a, WSYNC
|
||||||
|
st a, HMOVE
|
||||||
|
st a, VBLANK
|
||||||
|
|
||||||
|
//;
|
||||||
|
//; Wait for $3f (plus one?) scan lines to pass, by waiting for
|
||||||
|
//; WSYNC that many times.
|
||||||
|
//;
|
||||||
|
|
||||||
|
ld x, $3F
|
||||||
|
repeat {
|
||||||
|
st a, WSYNC
|
||||||
|
dec x
|
||||||
|
} until z // FIXME orig loop used "bpl _wsync_loop"
|
||||||
|
st a, WSYNC
|
||||||
|
|
||||||
|
//;
|
||||||
|
//; Delay while the raster scans across the screen. The more
|
||||||
|
//; we delay here, the more to the right the player will be when
|
||||||
|
//; we draw it.
|
||||||
|
//;
|
||||||
|
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
//// nop
|
||||||
|
|
||||||
|
//;
|
||||||
|
//; OK, *now* display the player.
|
||||||
|
//;
|
||||||
|
|
||||||
|
st a, RESP0
|
||||||
|
|
||||||
|
//;
|
||||||
|
//; Loop over the rows of the sprite data, drawing each to the screen
|
||||||
|
//; over four scan lines.
|
||||||
|
//;
|
||||||
|
//; TODO understand this better and describe it!
|
||||||
|
//;
|
||||||
|
|
||||||
|
ld y, $07
|
||||||
|
for y down to 0 {
|
||||||
|
ld a, image_data + y
|
||||||
|
st a, GP0
|
||||||
|
|
||||||
|
st a, WSYNC
|
||||||
|
st a, WSYNC
|
||||||
|
st a, WSYNC
|
||||||
|
st a, WSYNC
|
||||||
|
} // FIXME original was "dec y; bpl _image_loop"
|
||||||
|
|
||||||
|
ld a, $00
|
||||||
|
st a, GP0
|
||||||
|
|
||||||
|
//;
|
||||||
|
//; Turn off screen display and clear display registers.
|
||||||
|
//;
|
||||||
|
|
||||||
|
ld a, $02
|
||||||
|
st a, WSYNC
|
||||||
|
st a, VBLANK
|
||||||
|
ld a, $00
|
||||||
|
st a, PF0
|
||||||
|
st a, PF1
|
||||||
|
st a, PF2
|
||||||
|
st a, COLUPF
|
||||||
|
st a, COLUBK
|
||||||
|
}
|
||||||
|
|
||||||
|
define main routine
|
||||||
|
inputs image_data, INTIM
|
||||||
|
outputs CTRLPF, colour, luminosity, NUSIZ0, VSYNC, WSYNC, TIM64T, HMOVE, VBLANK, RESP0, GP0, PF0, PF1, PF2, COLUPF, COLUBK
|
||||||
|
trashes a, x, y, z, n
|
||||||
|
{
|
||||||
|
ld a, $00
|
||||||
|
st a, CTRLPF
|
||||||
|
ld a, $0c
|
||||||
|
st a, colour
|
||||||
|
ld a, $0a
|
||||||
|
st a, luminosity
|
||||||
|
ld a, $00
|
||||||
|
st a, NUSIZ0
|
||||||
|
repeat {
|
||||||
|
call vertical_blank
|
||||||
|
call display_frame
|
||||||
|
// call read_joystick
|
||||||
|
} forever
|
||||||
|
}
|
340
eg/atari2600/atari-2600-example.oph
Normal file
340
eg/atari2600/atari-2600-example.oph
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
;
|
||||||
|
; atari-2600-example.oph
|
||||||
|
; Skeleton code for an Atari 2600 ROM,
|
||||||
|
; plus an example of reading the joystick.
|
||||||
|
; By Chris Pressey, November 2, 2012.
|
||||||
|
;
|
||||||
|
; This work is in the public domain. See the file UNLICENSE for more info.
|
||||||
|
;
|
||||||
|
; Based on Chris Cracknell's Atari 2600 clock (also in the public domain):
|
||||||
|
; http://everything2.com/title/An+example+of+Atari+2600+source+code
|
||||||
|
;
|
||||||
|
; to build and run in Stella:
|
||||||
|
; ophis atari-2600-example.oph -o example.bin
|
||||||
|
; stella example.bin
|
||||||
|
;
|
||||||
|
; More useful information can be found in the Stella Programmer's Guide:
|
||||||
|
; http://alienbill.com/2600/101/docs/stella.html
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Useful system addresses (TODO: briefly describe each of these.)
|
||||||
|
;
|
||||||
|
|
||||||
|
.alias VSYNC $00
|
||||||
|
.alias VBLANK $01
|
||||||
|
.alias WSYNC $02
|
||||||
|
.alias NUSIZ0 $04
|
||||||
|
.alias NUSIZ1 $05
|
||||||
|
.alias COLUPF $08
|
||||||
|
.alias COLUBK $09
|
||||||
|
.alias PF0 $0D
|
||||||
|
.alias PF1 $0E
|
||||||
|
.alias PF2 $0F
|
||||||
|
.alias SWCHA $280
|
||||||
|
.alias INTIM $284
|
||||||
|
.alias TIM64T $296
|
||||||
|
.alias CTRLPF $0A
|
||||||
|
.alias COLUP0 $06
|
||||||
|
.alias COLUP1 $07
|
||||||
|
.alias GP0 $1B
|
||||||
|
.alias GP1 $1C
|
||||||
|
.alias HMOVE $2a
|
||||||
|
.alias RESP0 $10
|
||||||
|
.alias RESP1 $11
|
||||||
|
|
||||||
|
;
|
||||||
|
; Cartridge ROM occupies the top 4K of memory ($F000-$FFFF).
|
||||||
|
; Thus, typically, the program will occupy all that space too.
|
||||||
|
;
|
||||||
|
; Zero-page RAM we can use with impunity starts at $80 and goes
|
||||||
|
; upward (at least until $99, but probably further.)
|
||||||
|
;
|
||||||
|
|
||||||
|
.alias colour $80
|
||||||
|
.alias luminosity $81
|
||||||
|
.alias joystick_delay $82
|
||||||
|
|
||||||
|
.org $F000
|
||||||
|
|
||||||
|
;
|
||||||
|
; Standard prelude for Atari 2600 cartridge code.
|
||||||
|
;
|
||||||
|
; Get various parts of the machine into a known state:
|
||||||
|
;
|
||||||
|
; - Disable interrupts
|
||||||
|
; - Clear the Decimal flag
|
||||||
|
; - Initialize the Stack Pointer
|
||||||
|
; - Zero all bytes in Zero Page memory
|
||||||
|
;
|
||||||
|
|
||||||
|
start:
|
||||||
|
sei
|
||||||
|
cld
|
||||||
|
ldx #$FF
|
||||||
|
txs
|
||||||
|
lda #$00
|
||||||
|
|
||||||
|
zero_loop:
|
||||||
|
sta $00, x
|
||||||
|
dex
|
||||||
|
bne zero_loop
|
||||||
|
|
||||||
|
; and fall through to...
|
||||||
|
|
||||||
|
;
|
||||||
|
; Initialization.
|
||||||
|
;
|
||||||
|
; - Clear the Playfield Control register.
|
||||||
|
; - Set the player (sprite) colour to light green (write to COLUP0.)
|
||||||
|
; - Set the player (sprite) size/repetion to normal (write to NUSIZ0.)
|
||||||
|
;
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta CTRLPF
|
||||||
|
lda #$0c
|
||||||
|
sta colour
|
||||||
|
lda #$0a
|
||||||
|
sta luminosity
|
||||||
|
lda #$00
|
||||||
|
sta NUSIZ0
|
||||||
|
|
||||||
|
; and fall through to...
|
||||||
|
|
||||||
|
;
|
||||||
|
; Main loop.
|
||||||
|
;
|
||||||
|
; A typical main loop consists of:
|
||||||
|
; - Waiting for the frame to start (vertical blank period)
|
||||||
|
; - Displaying stuff on the screen (the _display kernel_)
|
||||||
|
; - Doing any processing you like (reading joysticks, updating program state,
|
||||||
|
; etc.), as long as you get it all done before the next frame starts!
|
||||||
|
;
|
||||||
|
|
||||||
|
main:
|
||||||
|
jsr vertical_blank
|
||||||
|
jsr display_frame
|
||||||
|
jsr read_joystick
|
||||||
|
jmp main
|
||||||
|
|
||||||
|
;
|
||||||
|
; Vertical blank routine.
|
||||||
|
;
|
||||||
|
; In brief: wait until it is time for the next frame of video.
|
||||||
|
; TODO: describe this in more detail.
|
||||||
|
;
|
||||||
|
|
||||||
|
vertical_blank:
|
||||||
|
ldx #$00
|
||||||
|
lda #$02
|
||||||
|
sta WSYNC
|
||||||
|
sta WSYNC
|
||||||
|
sta WSYNC
|
||||||
|
sta VSYNC
|
||||||
|
sta WSYNC
|
||||||
|
sta WSYNC
|
||||||
|
lda #$2C
|
||||||
|
sta TIM64T
|
||||||
|
lda #$00
|
||||||
|
sta WSYNC
|
||||||
|
sta VSYNC
|
||||||
|
rts
|
||||||
|
|
||||||
|
;
|
||||||
|
; Display kernal.
|
||||||
|
;
|
||||||
|
; First, wait until it's time to display the frame.
|
||||||
|
;
|
||||||
|
|
||||||
|
.scope
|
||||||
|
display_frame:
|
||||||
|
lda INTIM
|
||||||
|
bne display_frame
|
||||||
|
|
||||||
|
;
|
||||||
|
; (After that loop finishes, we know the accumulator must contain 0.)
|
||||||
|
; Wait for the next scanline, zero HMOVE (for some reason; TODO discover
|
||||||
|
; this), then turn on the screen.
|
||||||
|
;
|
||||||
|
|
||||||
|
sta WSYNC
|
||||||
|
sta HMOVE
|
||||||
|
sta VBLANK
|
||||||
|
|
||||||
|
;
|
||||||
|
; Actual work in the display kernal is done here.
|
||||||
|
;
|
||||||
|
; This is a pathological approach to writing a display kernal.
|
||||||
|
; This wouldn't be how you'd do things in a game. So be it.
|
||||||
|
; One day I may improve it. For now, be happy that it displays
|
||||||
|
; anything at all!
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Wait for $3f (plus one?) scan lines to pass, by waiting for
|
||||||
|
; WSYNC that many times.
|
||||||
|
;
|
||||||
|
|
||||||
|
ldx #$3F
|
||||||
|
_wsync_loop:
|
||||||
|
sta WSYNC
|
||||||
|
dex
|
||||||
|
bpl _wsync_loop
|
||||||
|
sta WSYNC
|
||||||
|
|
||||||
|
;
|
||||||
|
; Delay while the raster scans across the screen. The more
|
||||||
|
; we delay here, the more to the right the player will be when
|
||||||
|
; we draw it.
|
||||||
|
;
|
||||||
|
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
;
|
||||||
|
; OK, *now* display the player.
|
||||||
|
;
|
||||||
|
|
||||||
|
sta RESP0
|
||||||
|
|
||||||
|
;
|
||||||
|
; Loop over the rows of the sprite data, drawing each to the screen
|
||||||
|
; over four scan lines.
|
||||||
|
;
|
||||||
|
; TODO understand this better and describe it!
|
||||||
|
;
|
||||||
|
|
||||||
|
ldy #$07
|
||||||
|
_image_loop:
|
||||||
|
lda image_data, y
|
||||||
|
sta GP0
|
||||||
|
|
||||||
|
sta WSYNC
|
||||||
|
sta WSYNC
|
||||||
|
sta WSYNC
|
||||||
|
sta WSYNC
|
||||||
|
dey
|
||||||
|
bpl _image_loop
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta GP0
|
||||||
|
|
||||||
|
;
|
||||||
|
; Turn off screen display and clear display registers.
|
||||||
|
;
|
||||||
|
|
||||||
|
lda #$02
|
||||||
|
sta WSYNC
|
||||||
|
sta VBLANK
|
||||||
|
lda #$00
|
||||||
|
sta PF0
|
||||||
|
sta PF1
|
||||||
|
sta PF2
|
||||||
|
sta COLUPF
|
||||||
|
sta COLUBK
|
||||||
|
|
||||||
|
rts
|
||||||
|
.scend
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Read the joystick and use it to modify the colour and luminosity
|
||||||
|
; of the player.
|
||||||
|
;
|
||||||
|
|
||||||
|
.scope
|
||||||
|
read_joystick:
|
||||||
|
lda joystick_delay
|
||||||
|
beq _continue
|
||||||
|
|
||||||
|
dec joystick_delay
|
||||||
|
rts
|
||||||
|
|
||||||
|
_continue:
|
||||||
|
lda SWCHA
|
||||||
|
and #$f0
|
||||||
|
cmp #$e0
|
||||||
|
beq _up
|
||||||
|
cmp #$d0
|
||||||
|
beq _down
|
||||||
|
cmp #$b0
|
||||||
|
beq _left
|
||||||
|
cmp #$70
|
||||||
|
beq _right
|
||||||
|
jmp _tail
|
||||||
|
|
||||||
|
_up:
|
||||||
|
inc luminosity
|
||||||
|
jmp _tail
|
||||||
|
_down:
|
||||||
|
dec luminosity
|
||||||
|
jmp _tail
|
||||||
|
_left:
|
||||||
|
dec colour
|
||||||
|
jmp _tail
|
||||||
|
_right:
|
||||||
|
inc colour
|
||||||
|
;jmp _tail
|
||||||
|
|
||||||
|
_tail:
|
||||||
|
lda colour
|
||||||
|
and #$0f
|
||||||
|
sta colour
|
||||||
|
|
||||||
|
lda luminosity
|
||||||
|
and #$0f
|
||||||
|
sta luminosity
|
||||||
|
|
||||||
|
lda colour
|
||||||
|
clc
|
||||||
|
rol
|
||||||
|
rol
|
||||||
|
rol
|
||||||
|
rol
|
||||||
|
ora luminosity
|
||||||
|
sta COLUP0
|
||||||
|
|
||||||
|
lda #$06
|
||||||
|
sta joystick_delay
|
||||||
|
|
||||||
|
rts
|
||||||
|
.scend
|
||||||
|
|
||||||
|
;
|
||||||
|
; Player (sprite) data.
|
||||||
|
;
|
||||||
|
; Because we loop over these bytes with the Y register counting *down*,
|
||||||
|
; this image is stored "upside-down".
|
||||||
|
;
|
||||||
|
|
||||||
|
image_data:
|
||||||
|
.byte %01111110
|
||||||
|
.byte %10000001
|
||||||
|
.byte %10011001
|
||||||
|
.byte %10100101
|
||||||
|
.byte %10000001
|
||||||
|
.byte %10100101
|
||||||
|
.byte %10000001
|
||||||
|
.byte %01111110
|
||||||
|
|
||||||
|
;
|
||||||
|
; Standard postlude for Atari 2600 cartridge code.
|
||||||
|
; Give BRK and boot vectors that point to the start of the code.
|
||||||
|
;
|
||||||
|
|
||||||
|
.advance $FFFC
|
||||||
|
.word start
|
||||||
|
.word start
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
usage="Usage: loadngo.sh (c64|vic20) [--dry-run] <source.60p>"
|
usage="Usage: loadngo.sh (c64|vic20|atari2600) [--dry-run] <source.60p>"
|
||||||
|
|
||||||
arch="$1"
|
arch="$1"
|
||||||
shift 1
|
shift 1
|
||||||
@ -18,6 +18,9 @@ elif [ "X$arch" = "Xvic20" ]; then
|
|||||||
else
|
else
|
||||||
emu="xvic"
|
emu="xvic"
|
||||||
fi
|
fi
|
||||||
|
elif [ "X$arch" = "Xatari2600" ]; then
|
||||||
|
prelude='atari2600'
|
||||||
|
emu='stella'
|
||||||
else
|
else
|
||||||
echo $usage && exit 1
|
echo $usage && exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -186,3 +186,14 @@ class Emitter(object):
|
|||||||
advance the address for the next label, but don't emit anything."""
|
advance the address for the next label, but don't emit anything."""
|
||||||
self.resolve_label(label)
|
self.resolve_label(label)
|
||||||
self.addr += label.length
|
self.addr += label.length
|
||||||
|
|
||||||
|
def size(self):
|
||||||
|
return sum(emittable.size() for emittable in self.accum)
|
||||||
|
|
||||||
|
def pad_to_size(self, size):
|
||||||
|
self_size = self.size()
|
||||||
|
if self_size > size:
|
||||||
|
raise IndexError("Emitter size {} exceeds pad size {}".format(self_size, size))
|
||||||
|
num_bytes = size - self_size
|
||||||
|
if num_bytes > 0:
|
||||||
|
self.accum.extend([Byte(0)] * num_bytes)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user