; clock_t clock (void);
;
- .export _clock
.constructor initclock
+ .export _clock
.forceimport ticktock ; make sure that tickcount changes
- .importzp sreg
-
- .include "extzp.inc"
-
-.proc _clock
- lda tickcount+3
- sta sreg+1
- lda tickcount+2
- sta sreg
- ldx tickcount+1
- lda tickcount
- rts
-.endproc
+ .importzp tickcount, sreg
; Make the process clock start at zero.
.segment "ONCE"
initclock:
- lda #0
- ldx #3
-@lp: sta tickcount,x
+ ldx #4 - 1
+@lp: stz tickcount,x
dex
bpl @lp
rts
+
+; ------------------------------------------------------------------------
+.code
+
+; This function might be interrupted while it is reading the several bytes of
+; the clock. They are read again if that happens. (We do not want to stop
+; interrupts because that might cause glitches in interrupt-driven graphics
+; and sound.)
+
+.proc _clock
+ lda tickcount
+ ldy tickcount+3
+ sty sreg+1
+ ldy tickcount+2
+ sty sreg
+ ldx tickcount+1
+ cmp tickcount
+ bne _clock ; clock changed; reread it
+ rts
+.endproc
.include "extzp.inc"
_clrscr:
- st0 #VDC_MAWR
- st1 #<$0000
- st2 #>$0000
-
+ VREG VDC_MAWR, $0000
st0 #VDC_VWR
+
ldy #$40
rowloop:
ldx #$80
colloop:
- lda #' ' ; low byte of char. index
- sta VDC_DATA_LO
- lda #$02 ; background color, high nybble of char. index
- sta VDC_DATA_HI
-
+ st1 #' ' ; low byte of char. index
+ st2 #$02 ; background color, high nybble of char. index
dex
bne colloop
dey
rts
_bgcolor:
+ and #$0F
ldx BGCOLOR ; get old value
sta BGCOLOR ; set new value
asl a
.constructor initconio, 24
- .import vce_init
- .import psg_init
.import vdc_init
+ .import psg_init
.import colors
.importzp ptr1, tmp1
.include "pce.inc"
.include "extzp.inc"
- .macpack longbranch
.segment "ONCE"
initconio:
- jsr vce_init
+ jsr vdc_init
jsr psg_init
- jsr conio_init
- jsr set_palette
-
- st0 #VDC_CR
- st1 #<$0088
- st2 #>$0088
- rts
+ jsr load_font
set_palette:
stz VCE_ADDR_LO
stz VCE_ADDR_HI
- ldx #0
-@lp:
- ldy #16 ; size of a pallette
-@lp1:
- lda colors,x
+ clx
+@lp: ldy #16 ; size of a palette
+
+@lp1: lda colors,x
sta VCE_DATA_LO
lda colors+1,x
sta VCE_DATA_HI
inx
inx
- cpx #16 * 2
- jne @lp
+ cpx #16 * 2 ; 16 palettes
+ bne @lp
-; Set background to black.
-
- stz VCE_ADDR_LO
- stz VCE_ADDR_HI
- stz VCE_DATA_LO
- stz VCE_DATA_HI
+ sty BGCOLOR ; white on black
+ iny
+ sty CHARCOLOR
+ VREG VDC_CR, $0088 ; enable background and vertical-blank interrupt
rts
-;----------------------------------------------------------------------------
-; The character tiles use only two colors from each pallette. Color zero
-; comes from pallette zero; color one is different in each pallette. The
-; color of a character is set by choosing one of the 16 pallettes.
-
-conio_init:
- ; Load font
- st0 #VDC_MAWR
- st1 #<$2000
- st2 #>$2000
-
- ; pointer to font data
- lda #<font
- sta ptr1
- lda #>font
- sta ptr1+1
+; Load the conio font into the VDC.
+load_font:
+ VREG VDC_MAWR, $2000
+ st0 #VDC_VWR
- st0 #VDC_VWR ; VWR
+ stz tmp1 ; #%00000000
+ bsr copy ; make normal characters
- lda #0
- sta tmp1
- jsr copy
+ dec tmp1 ; #%11111111
+; bsr copy ; make reversed characters
+; rts ; (fall through)
- lda #<font
+; Point to the font data.
+copy: lda #<font
+ ldx #>font
sta ptr1
- lda #>font
- sta ptr1+1
-
- lda #$FF
- sta tmp1
- jsr copy
-
- ldx #0 ; white on black
- stx BGCOLOR
- inx
- stx CHARCOLOR
-
- rts
+ stx ptr1+1
-copy:
ldy #$80 ; 128 chars
charloop:
ldx #$08 ; 8 bytes/char
lda (ptr1)
eor tmp1
sta VDC_DATA_LO ; bitplane 0
- stz VDC_DATA_HI ; bitplane 1
+ st2 #>$0000 ; bitplane 1
- clc ; increment font pointer
- lda ptr1
- adc #$01
- sta ptr1
- lda ptr1+1
- adc #$00
- sta ptr1+1
- dex
+ inc ptr1 ; increment font pointer
+ bne @noC
+ inc ptr1+1
+@noC: dex
bne lineloop ; next bitplane-0 byte
+
ldx #$08 ; fill bitplanes 2 and 3 with 0
fillloop:
st1 #<$0000
st2 #>$0000
dex
bne fillloop ; next byte
+
dey
bne charloop ; next character
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
+ .forceimport initconio ; force conio initiation
.import gotoxy
.import PLOT
_cputc: cmp #$0D ; CR?
bne L1
- lda #0
- sta CURS_X
- beq plot ; Recalculate pointer
+ stz CURS_X
+ bra plot ; Recalculate pointer
L1: cmp #$0A ; LF?
beq newline ; Recalculate pointer
cputdirect:
jsr putchar ; Write the character to the screen
-; Advance cursor position
+; Move the cursor (rightwards) to the next position.
advance:
ldy CURS_X
iny
cpy xsize
bne L3
- jsr newline ; new line
- ldy #0 ; + CR
+ inc CURS_Y ; new line
+ cly ; + CR
L3: sty CURS_X
- jmp plot
-
-newline:
- inc CURS_Y
; Set cursor position; calculate VRAM pointer.
clc
jmp PLOT ; Set the new cursor
+newline:
+ inc CURS_Y
+ bra plot
+
; Write one character to the screen without doing anything else.
putchar:
- ora RVS ; Set revers bit
-
- tax
+ ora RVS ; Set reverse bit
- st0 #VDC_MAWR ; Memory Address Write
+ st0 #VDC_MAWR ; Memory-Address Write
+ ldy SCREEN_PTR
+ ldx SCREEN_PTR+1
+ sty VDC_DATA_LO
+ stx VDC_DATA_HI
- lda SCREEN_PTR
- sta VDC_DATA_LO
-
- lda SCREEN_PTR+1
- sta VDC_DATA_HI
-
- st0 #VDC_VWR ; VWR
-
- txa
+ st0 #VDC_VWR
sta VDC_DATA_LO ; character
lda CHARCOLOR ; pallette number
asl a
asl a
asl a
-
- ora #$02
+ ora #>$0200 ; high nybble of char. index
sta VDC_DATA_HI
rts
-
-;-------------------------------------------------------------------------------
-; force the init constructor to be imported
-
- .import initconio
-conio_init = initconio
;
-; Startup code for cc65 (PCEngine version)
+; Start-up code for cc65 (PC-Engine version)
;
; by Groepaz/Hitmen <groepaz@gmx.net>,
-; based on code by Ullrich von Bassewitz <uz@cc65.org>.
+; based on code by Ullrich von Bassewitz <uz@cc65.org>
;
-; 2018-02-11, Greg King
+; 2018-02-24, Greg King
;
.export _exit
- .export __STARTUP__ : absolute = 1 ; Mark as startup
+ .export __STARTUP__ : absolute = 1 ; Mark as start-up
.import initlib, donelib
.import push0, _main
- .import IRQStub
+ .import IRQStub, __nmi
+ .importzp sp
; Linker-generated
.import __CARTSIZE__
.include "pce.inc"
.include "extzp.inc"
- .importzp sp
-
; ------------------------------------------------------------------------
-; Place the startup code in a special segment.
+; Place the start-up code in a special segment.
.segment "STARTUP"
- ; Initialize CPU
+ ; Initialize the CPU.
start: sei
nop
csh ; Set high-speed CPU mode
nop
- ; Set up stack and memory mapping.
+ ; Set up the stack and the memory mapping.
ldx #$FF ; Stack top ($21FF)
txs
;lda #$00 ; (The reset default)
;tam #%10000000 ; $E000-$FFFF Hucard/Syscard bank 0
- ; Initialize hardware
+ ; Initialize the hardware.
stz TIMER_CTRL ; Timer off
- lda #$07
+ lda #%00000111
sta IRQ_MASK ; Interrupts off
- stz IRQ_STATUS ; Acknowledge timer
- ; FIXME; I don't know why the heck this one doesn't work when called from a constructor. :/
+ ; FIXME; I don't know why the heck this one doesn't work when called from a constructor. -Groepaz :-/
+.if 0 ; It now seems to work (at least, in Mednafen). -Greg King
.import vdc_init
jsr vdc_init
+.endif
- ; Turn on background and VD interrupt/IRQ1
- lda #$05
+ ; Allow interrupts from the VDC.
+ lda #%00000101
sta IRQ_MASK ; IRQ1 = on
; Copy the .data segment to RAM
sta sp
stx sp+1
- ; Call module constructors
+ ; Call the module constructors.
jsr initlib
- cli ; allow IRQ only after constructors have run
+ stz IRQ_STATUS ; Clear IRQs
+ cli ; Allow IRQ only after constructors have run
; Pass an empty command line
jsr push0 ; argc
ldy #4 ; Argument size
jsr _main ; Call the user's code
- ; Call module destructors. This is also the _exit entry.
-_exit: jsr donelib ; Run module destructors
+ ; Call the module destructors. This is also the exit() entry.
+_exit: jsr donelib
- ; reset the PCEngine (start over)
+ ; Reset the PCEngine (start over).
jmp start
-_nmi: rti
-
.export initmainargs
initmainargs:
rts
.word IRQStub ; $FFF6 IRQ2 (External IRQ, BRK)
.word IRQStub ; $FFF8 IRQ1 (VDC)
.word IRQStub ; $FFFA Timer
- .word _nmi ; $FFFC NMI
+ .word __nmi ; $FFFC NMI
.word start ; $FFFE reset
jsr popa ; Get X
sta CURS_X ; Set X
jmp plot ; Set the cursor position
-
-;-------------------------------------------------------------------------------
-; force the init constructor to be imported
-
- .import initconio
-conio_init = initconio
-
; IRQ handling (PCE version)
;
- .export initirq, doneirq, IRQStub
+ .export initirq, doneirq, IRQStub, __nmi
.import __INTERRUPTOR_COUNT__, callirq_y
pla
plx
@L1: ply
- rti
+__nmi: rti
JOY_COUNT = 4 ; Number of joysticks we support
+.bss
+
+padbuffer: .res JOY_COUNT
+
.code
; ------------------------------------------------------------------------
COUNT:
lda #<JOY_COUNT
- ldx #>JOY_COUNT
+ clx ; ldx #>JOY_COUNT
rts
; ------------------------------------------------------------------------
joy1:
lda padbuffer,x
- ldx #0
rts
read_joy:
sta padbuffer,y ; store new value
iny
- cpy #$05
+ cpy #.sizeof(padbuffer)
bcc nextpad
rts
-
-.bss
-
-padbuffer:
- .res 4
.include "pce.inc"
.include "extzp.inc"
-PLOT:
- bcs @getpos
+PLOT: bcs @getpos
tya
;clc ; already cleared
- adc _plotlo,x
+ adc plotlo,x
sta SCREEN_PTR
- lda _plothi,x
- adc #0
+ cla
+ adc plothi,x
sta SCREEN_PTR+1
@getpos:
ldx CURS_Y
.rodata
-_plotlo:
- .repeat screenrows,line
+plotlo: .repeat screenrows,line
.byte <($0000+(line*$80))
.endrepeat
-_plothi:
- .repeat screenrows,line
+plothi: .repeat screenrows,line
.byte >($0000+(line*$80))
.endrepeat
-
-;-------------------------------------------------------------------------------
-; force the init constructor to be imported
-
- .import initconio
-conio_init = initconio
.segment "ONCE"
psg_init:
- clx
stz PSG_GLOBAL_PAN ; Silence global balance
+ ldx #6 - 1
psg_clear_loop:
stx PSG_CHAN_SELECT ; Select channel
stz PSG_LFO_FREQ ; Clear LFO frequency
stz PSG_LFO_CTRL ; Clear LFO control
- cly
+ ldy #$20
psg_clear_waveform:
stz PSG_CHAN_DATA ; Clear waveform byte
- iny
- cpy #$20
+ dey
bne psg_clear_waveform
- inx
- cpx #$06
- bne psg_clear_loop
+ dex
+ bpl psg_clear_loop
rts
;
-; Ullrich von Bassewitz, 07.08.1998
+; 1998-08-07, Ullrich von Bassewitz
+; 2015-11-23, Greg King
;
-; unsigned char revers (unsigned char onoff);
+; unsigned char __fastcall__ revers (unsigned char onoff);
;
.export _revers
- .include "extzp.inc"
+ .importzp RVS
.proc _revers
- ldx #$00 ; Assume revers off
- tay ; Test onoff
- beq L1 ; Jump if off
- ldx #$80 ; Load on value
- ldy #$00 ; Assume old value is zero
-L1: lda RVS ; Load old value
- stx RVS ; Set new value
- beq L2 ; Jump if old value zero
- iny ; Make old value = 1
-L2: ldx #$00 ; Load high byte of result
- tya ; Load low byte, set CC
+ cmp #$01 ; False or true?
+ cla
+ ror a ; Either $00 or $80
+ ldy RVS ; Load old value
+ sta RVS ; Set new value
+ tya
+ asl a
+ rol a ; Either $00 or $01
+ clx
rts
.endproc
- .interruptor ticktock, 24
+ .interruptor ticktock
- .include "pce.inc"
.include "extzp.inc"
ticktock:
; Set CTA to zero
stz VCE_ADDR_LO
stz VCE_ADDR_HI
- ldy #$01
+
+ ldy #$01 ; Only background palettes
vce_clear_bank:
- ldx #$00
+ clx ; ldx #<$0100 ; <(16 * 16)
vce_clear_color:
stz VCE_DATA_LO ; Clear color (LSB)
stz VCE_DATA_HI ; Clear color (MSB)
vdc_init:
lda VDC_CTRL
- VREG $00, $0000 ; MAWR
- VREG $01, $0000 ; MARR
- VREG $05, $0000 ; CR
- VREG $06, $0000 ; RCR
- VREG $07, $0000 ; BXR
- VREG $08, $0000 ; BYR
- VREG $09, $0070 ; MWR
- VREG $0C, $1702 ; CRTC - VSR
- VREG $0D, $00DF ; CRTC - VDS
- VREG $0E, $000C ; CRTC - VDE
- VREG $0F, $0000 ; DCR
+ VREG VDC_CR , $0000 ; disable display and interrupts
+ VREG VDC_BXR, $0000 ; no scrolling
+ VREG VDC_BYR, $0000
+ VREG VDC_MWR, $0070 ; 128 x 64 tiles (1024 x 512 pixels)
+ VREG VDC_VSR, $1702 ; CRTC
+ VREG VDC_VDR, $00DF ; CRTC - VDS
+ VREG VDC_VCR, $000C ; CRTC - VDE
+ VREG VDC_DCR, $0000
.if HIRES
-
- VREG $0A, $0C02 ; CRTC - HSR
- VREG $0B, $043C ; CRTC - HDS
+ VREG VDC_HSR, $0C02 ; CRTC
+ VREG VDC_HDR, $043C ; CRTC - HDS
lda #$06
- sta VCE_CTRL
-
.else
-
- VREG $0A, $0202 ; CRTC - HSR
- VREG $0B, $041F ; CRTC - HDS
+ VREG VDC_HSR, $0202 ; CRTC
+ VREG VDC_HDR, $041F ; CRTC - HDS
lda #$04
- sta VCE_CTRL
-
.endif
+ sta VCE_CTRL
lda VDC_CTRL
rts
+;----------------------------------------------------------------------------
+; VGA font for the PC-Engine conio implementation
-; VGA charset for the PC-Engine conio implementation
+; The character tiles use only two colors from each pallette. Color zero
+; comes from pallette zero; color one is different in each pallette. The
+; color of a character is set by choosing one of the 16 pallettes.
.byte $00, $00, $00, $00, $00, $00, $00, $00