From ece3f266ea2c4000bca96b75f6cb9832e5147335 Mon Sep 17 00:00:00 2001 From: fumiama Date: Tue, 30 Mar 2021 23:18:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + main.asm | 37 ++++++ platform/README.txt | 42 ++++++ platform/c64_0.oph | 74 +++++++++++ platform/c64header.oph | 10 ++ platform/c64kernal.oph | 67 ++++++++++ platform/libbasic64.oph | 287 ++++++++++++++++++++++++++++++++++++++++ platform/nes.oph | 15 +++ platform/stella.oph | 127 ++++++++++++++++++ platform/vic20.oph | 5 + platform/vic20x.oph | 5 + printinput.asm | 33 +++++ printinput.prg | Bin 0 -> 55 bytes snake.prg | Bin 0 -> 80 bytes 14 files changed, 703 insertions(+) create mode 100644 .gitignore create mode 100644 main.asm create mode 100755 platform/README.txt create mode 100755 platform/c64_0.oph create mode 100755 platform/c64header.oph create mode 100755 platform/c64kernal.oph create mode 100755 platform/libbasic64.oph create mode 100755 platform/nes.oph create mode 100755 platform/stella.oph create mode 100755 platform/vic20.oph create mode 100755 platform/vic20x.oph create mode 100644 printinput.asm create mode 100644 printinput.prg create mode 100644 snake.prg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/main.asm b/main.asm new file mode 100644 index 0000000..d19a166 --- /dev/null +++ b/main.asm @@ -0,0 +1,37 @@ +.outfile "snake.prg" +.require "platform/c64_0.oph" +.require "platform/c64kernal.oph" + +.alias go_u #1 ; 上 +.alias go_d #2 ; 下 +.alias go_l #4 ; 左 +.alias go_r #8 ; 右 + +.data zp +.space d 1 ; 方向 值定义如上 +.space c 1 ; 长度 最大255 最小0 +.text + +main: +.scope + lda #147 ;清屏 + jsr chrout + + rts +.scend + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; getdir 返回一个方向到d +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +getdir: +.macro + jsr chrin + sta d +.macend + + +.checkpc $A000 ; text段边界 +.data zp ; 零页段边界 +.checkpc $80 +.data +.checkpc $D000 ; data段边界 \ No newline at end of file diff --git a/platform/README.txt b/platform/README.txt new file mode 100755 index 0000000..52d0cad --- /dev/null +++ b/platform/README.txt @@ -0,0 +1,42 @@ +This directory holds files likely to be of use to you in developing your own +programs. The contents of each file is summarized below. + + +c64_0.oph: A Commodore 64 equivalent to a modern compiler's "crt0.s" - it + contains a .PRG file header, a short BASIC program that launches + the machine language program, and a prologue and epilogue that + prepare memory for your use and then clean it up again when you + are done. Memory locations $02 through $8F on the zero page are + available for your use, and the program lives at the beginning + a contiguous block of RAM from $0800 through $CFFF. The BASIC + ROM is swapped out of memory (leaving $A000-$BFFF as RAM) for + the duration of your program. BASIC's working storage on the + zero page is backed up in the RAM underneath the KERNAL ROM + while your program runs. + +c64kernal.oph: A collection of standard aliases for the KERNAL routines on the + Commodore 64. Names for these routines have been chosen to match + the Commodore 64 Programmer's Reference Guide. Additional useful + constants are defined for the character codes for color changes + and case-changing. + +libbasic64.oph:A still-experimental set of macros and routines for exploiting + the software floating point routines in the Commodore 64 + BASIC ROM. + +c64header.oph: A much simpler Commodore 64 header that does nothing but jump + directly to your code. Useful for small programs or those that + intend to interface with BASIC. + +vic20.oph: A simple header for the unexpanded VIC-20. Equivalent in + behavior to c64header.oph. + +vic20x.oph: A simple header like the two above, but for expanded VIC-20. + +nes.oph: A somewhat skeletal collection of aliases for the PPU registers + on the Nintendo Entertainment System. These names were chosen + to match the constant names given on the NESdev Wiki. + +stella.oph: A collection of aliases for the registers of the Atari 2600. + These names were taken from the "Stella Programmer's Guide" and + are in wide use amongst developers and code analysts alike. diff --git a/platform/c64_0.oph b/platform/c64_0.oph new file mode 100755 index 0000000..8118033 --- /dev/null +++ b/platform/c64_0.oph @@ -0,0 +1,74 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Commodore 64 Basic Runtime File +;; +;; Include this at the TOP of your C64 program, and it will handle +;; hiding away the BASIC ROM and data and restoring it at the end. +;; +;; You will have a contiguous block of RAM from $0800 to $CFFF, and +;; Zero Page access from $02 to $8F in the segment "zp". + +.include "c64header.oph" + +.data zp ; Zero Page memory segment. +.org $0002 + +.text + +.scope + ; Cache BASIC zero page underneath the KERNAL, while also + ; making RAM copies of the NMI routines + ldx #$00 +* lda $00, x + sta $e000, x + inx + bne - + + ; Swap out the BASIC ROM for RAM + lda $01 + and #$fe + ora #$06 + sta $01 + + ; Run the real program + jsr _main + + ; Swap out KERNAL to expose cached BASIC ZP values + ; Block IRQs during this period. NMIs cannot be blocked, + ; but we copied enough of the processing code into the + ; RAM under the KERNAL that we can disable NMI processing + ; during this period + sei ; Disable IRQs + lda #$c1 ; Defang NMIs + sta $318 + + lda $01 ; Swap out KERNAL + and #$fd + sta $01 + + ; Restore BASIC zero page + ldx #$8E +* lda $e001, x + sta $01, x + dex + bne - + + ; Restore BASIC ROM, KERNAL, and interrupts + lda $01 + ora #$07 + sta $01 + lda #$47 ; Restore NMI vector + sta $318 + cli ; Re-enable interrupts + + ; Back to BASIC. We do this by clearing the keyboard + ; buffer and then jumping through the warm start + ; vector. This will more cleanly handle case where + ; the program has somehow modified BASIC's state, + ; such as running through PUCRUNCH or a onefiler. + stx $c6 ; .X is zero from previous loop + jmp ($a002) + +_main: + ; Program follows... +.scend diff --git a/platform/c64header.oph b/platform/c64header.oph new file mode 100755 index 0000000..87eab4d --- /dev/null +++ b/platform/c64header.oph @@ -0,0 +1,10 @@ +.word $0801 +.org $0801 + +; BASIC program that just calls our machine language code +.scope + .word _next, 10 ; Next line and current line number + .byte $9e,"2061",0 ; SYS 2061 +_next: .word 0 ; End of program +.scend + ; Program follows... diff --git a/platform/c64kernal.oph b/platform/c64kernal.oph new file mode 100755 index 0000000..be39cee --- /dev/null +++ b/platform/c64kernal.oph @@ -0,0 +1,67 @@ +; KERNAL routine aliases (C64) + +.alias acptr $ffa5 +.alias chkin $ffc6 +.alias chkout $ffc9 +.alias chrin $ffcf +.alias chrout $ffd2 +.alias ciout $ffa8 +.alias cint $ff81 +.alias clall $ffe7 +.alias close $ffc3 +.alias clrchn $ffcc +.alias getin $ffe4 +.alias iobase $fff3 +.alias ioinit $ff84 +.alias listen $ffb1 +.alias load $ffd5 +.alias membot $ff9c +.alias memtop $ff99 +.alias open $ffc0 +.alias plot $fff0 +.alias ramtas $ff87 +.alias rdtim $ffde +.alias readst $ffb7 +.alias restor $ff8a +.alias save $ffd8 +.alias scnkey $ff9f +.alias screen $ffed +.alias second $ff93 +.alias setlfs $ffba +.alias setmsg $ff90 +.alias setnam $ffbd +.alias settim $ffdb +.alias settmo $ffa2 +.alias stop $ffe1 +.alias talk $ffb4 +.alias tksa $ff96 +.alias udtim $ffea +.alias unlsn $ffae +.alias untlk $ffab +.alias vector $ff8d + +; Character codes for the colors. +.alias color'0 144 +.alias color'1 5 +.alias color'2 28 +.alias color'3 159 +.alias color'4 156 +.alias color'5 30 +.alias color'6 31 +.alias color'7 158 +.alias color'8 129 +.alias color'9 149 +.alias color'10 150 +.alias color'11 151 +.alias color'12 152 +.alias color'13 153 +.alias color'14 154 +.alias color'15 155 + +; ...and reverse video +.alias reverse'on 18 +.alias reverse'off 146 + +; ...and character set +.alias upper'case 142 +.alias lower'case 14 diff --git a/platform/libbasic64.oph b/platform/libbasic64.oph new file mode 100755 index 0000000..b738edb --- /dev/null +++ b/platform/libbasic64.oph @@ -0,0 +1,287 @@ +;;; LIBBASIC64.OPH + +;;; This is a collection of routines inside the BASIC ROM that can +;;; be repurposed to do floating-point math inside your machine +;;; language programs. It is currently VERY EXPERIMENTAL. The documentation +;;; available for this is spotty at best and disassembly confirms that +;;; a lot of hidden invariants may lurk. + +;;; BASIC function equivalents. These operate on FAC1 and are pretty +;;; clean overall. They take their input in FAC1 and put their output +;;; there too. While it is not *guaranteed* it is probably best to +;;; assume that these functions trash the value in FAC2. + .alias abs_fac1 $bc58 + .alias atn_fac1 $e30e + .alias cos_fac1 $e264 + .alias exp_fac1 $bfed + .alias int_fac1 $bccc + .alias log_fac1 $b9ea + .alias rnd_fac1 $e097 + .alias sgn_fac1 $bc39 + .alias sin_fac1 $e26b + .alias tan_fac1 $e2b4 + +;;; Getting useful information into the FACs + + ;; Treat the accumulator as a signed byte, load that value + ;; into FAC1 + .alias ld_fac1_a $bc3c + + ;; Load the signed 16-bit value with A as the *high* byte and + ;; Y as the *low* byte into FAC1. This is backwards from pretty + ;; much everything else. + .alias ld_fac1_s16 $b391 + + ;; Load a 5-byte value from memory into FAC1. + .alias ld_fac1_mem $bba2 + + ;; Copy FAC2 into FAC1. + .alias ld_fac1_fac2 $bbfc + + ;; Translate FAC1 into a string that is at $0100. + .alias fac1_to_string $bddd + + ;; Convert FAC1 into a 32-bit *big-endian* signed integer at + ;; $62-$65 (where the mantissa usually goes in FAC1). + .alias fac1_to_s32 $bc9b + + ;; Store out FAC1 to $57-$5B, converting it back into the five-byte + ;; floating-point format. + .alias fac1_to_57 $bbca + + ;; Do the same but at $5c-$60. + .alias fac1_to_5c $bbc7 + + ;; Load a 5-byte value into FAC2. + .alias ld_fac2_mem $ba8c + + ;; Copy FAC1 to FAC2. FAC1 has some extra precision that is + ;; rounded away when you do this. + .alias ld_fac2_fac1 $bc0c + +;;; Comparison operator. + ;; Like sgn_fac1, but returns the -1/0/1 in the accumulator as + ;; an integer. + .alias fac1_sign $bc2b + +;;; FP operators. These are all FAC2 OP FAC1 with the result in FAC1. +;;; PRECONDITIONS: All of these operations but AND and OR require you to +;;; have the contents of $61 in the accumulator. calling one of the ld_fac* +;;; routines will do that for you automatically. f_add_op also requires that +;;; $6F be set properly; only ld_fac2_mem does this. + .alias f_add_op $b86a + .alias f_subtract_op $b853 + .alias f_multiply_op $ba2b + .alias f_divide_op $bb12 + .alias f_pow_op $bf7b + .alias f_and_op $afe9 + .alias f_or_op $afe6 + +;;; Memory-based FP operations. All are MEM OP FAC1. These are usually safer +;;; than the *_op routines. + .alias f_add_mem $b867 + .alias f_subtract_mem $b850 + .alias f_multiply_mem $ba28 + .alias f_divide_mem $bb0f + +;;; Useful FP constants that live in the ROM. It's plausible that ld_fac1_a +;;; or ld_fac1_s16 would be more convenient than ld_fac1_mem with f_1 or f_10, +;;; but when doing memory-based generic stuff, these will still be useful. + .alias f_0_5 $bf11 ; 0.5 + .alias f_1 $b9bc ; 1.0 + .alias f_pi $aea8 ; 3.1415926 + .alias f_10 $baf9 ; 10.0 + +;;; Macros for using these routines more safely. + +;; Copy 5-byte values around in memory without touching the FACs. +.macro f_move + ldx #$00 +_fmvlp: lda _2,x + sta _1,x + inx + cpx #$05 + bne _fmvlp +.macend + +;;; These next few macros really exist just to save us the trouble of loading +;;; addresses into registers +.macro print_str + lda #<_1 + ldy #>_1 + jsr strout +.macend + +.macro ld_fac1 + lda #<_1 + ldy #>_1 + jsr ld_fac1_mem +.macend + +.macro ld_fac2 + lda #<_1 + ldy #>_1 + jsr ld_fac2_mem +.macend + +.macro st_fac1 + lda #<_1 + ldy #>_1 + jsr fac1_to_mem +.macend + +.macro fp_load + `ld_fac1 _1 +.macend + +.macro fp_store + `st_fac1 _1 +.macend + +.macro fp_print + `ld_fac1 _1 + jsr fac1out +.macend + +.macro fp_read + lda #<_1 + ldy #>_1 + jsr ld_fac1_string +.macend + +;;; Arithmetic macros. These serve mainly to make the operations work left- +;;; to-right as one generally would prefer. They also guarantee the obscure +;;; preconditions hold. + +.macro fp_add + lda #<_1 + ldy #>_1 + jsr f_add_mem +.macend + +.macro fp_subtract + jsr ld_fac2_fac1 + `ld_fac1 _1 + jsr f_subtract_op +.macend + +.macro fp_multiply + lda #<_1 + ldy #>_1 + jsr f_multiply_mem +.macend + +.macro fp_divide + jsr ld_fac2_fac1 + `ld_fac1 _1 + jsr f_divide_op +.macend + +.macro fp_pow + jsr ld_fac2_fac1 + `ld_fac1 _1 + jsr f_pow_op +.macend + +.macro fp_and + `ld_fac2 _1 + jsr f_and_op +.macend + +.macro fp_or + `ld_fac2 _1 + jsr f_or_op +.macend + +;;; Utility routine for converting the system clock to a floating point +;;; value. +ld_fac1_ti: + jsr $ffde ; RDTIM + sty $63 + stx $64 + sta $65 + ;; Once the requirements on .Y and $68 are better + ;; understood, this might be exportable as + ;; ld_fac1_s32, but there are still some dragons + ;; lurking + ldy #$00 ; Clear out intermediary values + sta $62 + sta $68 + jmp $bcd5 + +;;; FAC1 can only be stored out to two locations. We'd prefer to be able +;;; to store anywhere. This routine is a support routine that allows that. +;;; It will normally only be called by the fp_store macro. +fac1_to_mem: + sta $fd + sty $fe + jsr fac1_to_5c + ldy #$00 +* lda $5c,y + sta ($fd),y + iny + cpy #$05 + bne - + rts + +;;; The VAL function uses the CHRGET routine copied to the zero page to read +;;; strings in. That's a fragile operation if we don't want to confuse BASIC +;;; later, so this routine juggles the values we need to preserve. It will +;;; normally only be called by the fp_read macro. +ld_fac1_string: + ldx $7a + sta $7a + txa + pha + lda $7b + pha + sty $7b + jsr $79 + jsr $bcf3 + pla + sta $7b + pla + sta $7a + rts + +;;; Print out the contents of FAC1. +fac1out: + ldy #$00 ; Clean out overflow + sty $68 + sty $70 + jsr fac1_to_string + ldy #$01 + ;; Skip the first character if it's not "-" + lda $100 + sec + sbc #$2d + beq strout + lda #$01 + ;; Fall through to strout + +;;; The BASIC ROM already has a STROUT routine - $ab1e - but +;;; it makes use of BASIC's own temporary string handling. We +;;; don't want it to ever touch its notion of temporary strings +;;; here, so we provide our own short routine to do this. +strout: sta $fd + sty $fe + ldy #$00 +* lda ($fd),y + beq + + jsr $ffd2 ; CHROUT + iny + bne - +* rts + +;;; Execute RND(-TI), seeding the random number generator the traditional way. +randomize: + jsr ld_fac1_ti + lda #$ff + sta $66 ; Force sign negative + jmp rnd_fac1 ; RND(-TI) + + +;;; Return RND(1), a fresh random number between 0 and 1. +rnd: lda #$01 + jsr ld_fac1_a + jmp rnd_fac1 diff --git a/platform/nes.oph b/platform/nes.oph new file mode 100755 index 0000000..e85b13f --- /dev/null +++ b/platform/nes.oph @@ -0,0 +1,15 @@ +; NES-related headers. Unlike the C64 and Stella developers, there is +; no standard nomenclature for these registers. It's not uncommon to +; see them hardcoded. + +; PPU registers have reasonably standard names, at least. + +.alias PPUCTRL $2000 ; PPU Control Register #1 +.alias PPUMASK $2001 ; PPU Control Register #2 +.alias PPUSTATUS $2002 ; PPU Status Register +.alias OAMADDR $2003 ; SPR-RAM Address Register +.alias OAMDATA $2004 ; SPR-RAM I/O Register +.alias PPUSCROLL $2005 ; VRAM Address Register #1 (Panning control) +.alias PPUADDR $2006 ; VRAM Address Register #2 (Direct Address control) +.alias PPUDATA $2007 ; VRAM I/O Register +.alias OAMDMA $4014 ; Sprite DMA Register diff --git a/platform/stella.oph b/platform/stella.oph new file mode 100755 index 0000000..f4492e5 --- /dev/null +++ b/platform/stella.oph @@ -0,0 +1,127 @@ +; Register mnemonics for the Atari 2600 VCS +; +; Taken from the "Stella Programming Guide", at +; http://www.alienbill.com/2600/101/docs/stella.html + +; Writable TIA addresses + +.alias VSYNC $00 ; vertical sync set-clear +.alias VBLANK $01 ; vertical blank set-clear +.alias WSYNC $02 ; wait for leading edge of horizontal blank +.alias RSYNC $03 ; reset horizontal sync counter +.alias NUSIZ0 $04 ; number-size player-missile 0 +.alias NUSIZ1 $05 ; number-size player-missile 1 +.alias COLUP0 $06 ; color-lum player 0 +.alias COLUP1 $07 ; color-lum player 1 +.alias COLUPF $08 ; color-lum playfield +.alias COLUBK $09 ; color-lum background +.alias CTRLPF $0A ; control playfield ball size and collisions +.alias REFP0 $0B ; reflect player 0 +.alias REFP1 $0C ; reflect player 1 +.alias PF0 $0D ; playfield register byte 0 +.alias PF1 $0E ; playfield register byte 1 +.alias PF2 $0F ; playfield register byte 2 +.alias RESP0 $10 ; reset player 0 +.alias RESP1 $11 ; reset player 1 +.alias RESM0 $12 ; reset missile 0 +.alias RESM1 $13 ; reset missile 1 +.alias RESBL $14 ; reset ball +.alias AUDC0 $15 ; audio control 0 +.alias AUDC1 $16 ; audio control 1 +.alias AUDF0 $17 ; audio frequency 0 +.alias AUDF1 $18 ; audio frequency 1 +.alias AUDV0 $19 ; audio volume 0 +.alias AUDV1 $1A ; audio volume 1 +.alias GRP0 $1B ; Graphics player 0 +.alias GRP1 $1C ; Graphics player 1 +.alias ENAM0 $1D ; Graphics enable missile 0 +.alias ENAM1 $1E ; Graphics enable missile 1 +.alias ENABL $1F ; Graphics enable ball +.alias HMP0 $20 ; horizontal motion player 0 +.alias HMP1 $21 ; horizontal motion player 1 +.alias HMM0 $22 ; horizontal motion missile 0 +.alias HMM1 $23 ; horizontal motion missile 1 +.alias HMBL $24 ; horizontal motion ball +.alias VDELP0 $25 ; vertical delay player 0 +.alias VDELP1 $26 ; vertical delay player 1 +.alias VDELBL $27 ; vertical delay ball +.alias RESMP0 $28 ; reset missile 0 to player 0 +.alias RESMP1 $29 ; reset missile 1 to player 1 +.alias HMOVE $2A ; apply horizontal motion +.alias HMCLR $2B ; clear horizontal motion registers +.alias CXCLR $2C ; clear collision latches + +; Readable TIA addresses + +.alias CXM0P $00 ; read collision missile 0 players +.alias CXM1P $01 ; read collision missile 1 players +.alias CXP0FB $02 ; read collision player 0 playfield/ball +.alias CXP1FB $03 ; read collision player 1 playfield/ball +.alias CXM0FB $04 ; read collision missile 0 playfield/ball +.alias CXM1FB $05 ; read collision missile 1 playfield/ball +.alias CXBLPF $06 ; read collision ball playfield +.alias CXPPMM $07 ; read collision player/player missile/missile +.alias INPT0 $08 ; read pot port +.alias INPT1 $09 ; read pot port +.alias INPT2 $0A ; read pot port +.alias INPT3 $0B ; read pot port +.alias INPT4 $0C ; read input +.alias INPT5 $0D ; read input + +; PIA addresses + +.alias SWCHA $280 ; Port A data register (read/write) +.alias SWACNT $281 ; Port A data direction register (0=input, 1=output) +.alias SWCHB $282 ; Port B - console switches (read-only) +.alias SWBCNT $283 ; Port B data direction register (hardwired to 0) +.alias INTIM $284 ; Timer output (read only) +.alias TIM1T $294 ; Set 1-clock interval (838 nsec/interval) +.alias TIM8T $295 ; Set 8-clock interval (6.7 usec/interval) +.alias TIM64T $296 ; Set 64-clock interval (53.6 usec/interval +.alias T1024T $297 ; Set 1025-clock interval (858.2 usec/interval) + +; These macros are adapted from DASM's old macro.h. Credit and description are +; replicated from there. + +;------------------------------------------------------------------------------- +; VERTICAL_SYNC +; Original author: Manuel Polik +; Inserts the code required for a proper 3 scanline +; vertical sync sequence +; +; Note: Alters the accumulator +; +; IN: +; OUT: A = 1 + +.macro vertical'sync + lda #$02 + sta WSYNC + sta VSYNC + sta WSYNC + sta WSYNC + lsr + sta WSYNC + sta VSYNC +.macend + +;------------------------------------------------------------------------------- +; CLEAN_START +; Original author: Andrew Davie +; Standardised start-up code, clears stack, all TIA registers and RAM to 0 +; Sets stack pointer to $FF, and all registers to 0 +; Sets decimal mode off, sets interrupt flag (kind of un-necessary) +; Use as very first section of code on boot (ie: at reset) +; Code written to minimise total ROM usage - uses weird 6502 knowledge :) +.macro clean'start + sei + cld + ldx #$00 + txa + tay +_clear'stack: + dex + txs + pha + bne _clear'stack +.macend diff --git a/platform/vic20.oph b/platform/vic20.oph new file mode 100755 index 0000000..e56bd26 --- /dev/null +++ b/platform/vic20.oph @@ -0,0 +1,5 @@ +;;; Minimal header file for unexpanded VIC-20. +;;; It translates to 10 SYS4109. +.word $1001 +.org $1001 +.byte $0b,$10,$0a,$00,$9e,$34,$31,$30,$39,$00,$00,$00 diff --git a/platform/vic20x.oph b/platform/vic20x.oph new file mode 100755 index 0000000..6e50aa7 --- /dev/null +++ b/platform/vic20x.oph @@ -0,0 +1,5 @@ +;;; Minimal header file for expanded VIC-20. +;;; It translates to 10 SYS4621. +.word $1201 +.org $1201 +.byte $0b,$12,$0a,$00,$9e,$34,$36,$32,$31,$00,$00,$00 diff --git a/printinput.asm b/printinput.asm new file mode 100644 index 0000000..2d32108 --- /dev/null +++ b/printinput.asm @@ -0,0 +1,33 @@ +.outfile "printinput.prg" +.require "platform/c64header.oph" +.require "platform/c64kernal.oph" + +.data +.org $C000 +.space _na 1 ; a的临时存放处 + +.text +main: +* jsr getin + beq skip + jsr printbyte + lda #13 ; 换行 + jsr chrout +skip: + jmp - + +printbyte: + sta _na + txa + pha + ldx #7 ; 打印8bit +* lda #$30 ; a = '0' + asl _na ; 左移一位,溢出到c + bcc + ; if(c == 0) goto 下一个星号 + adc #0 ; else a = a + c + 0 +* jsr chrout ; putchar(a) + dex ; x-- + bne -- ; if(x != 0) goto 上两个星号 + pla + tax + rts \ No newline at end of file diff --git a/printinput.prg b/printinput.prg new file mode 100644 index 0000000000000000000000000000000000000000..c69491340f76d84923f9e87f0e339736f3968589 GIT binary patch literal 55 zcmZSN;O5|Bm}g{QX2`(6pz!4X2Mz^Uj+ML$m;U?ka`ZAB=<-;^zS4k?;lKo@Oa`Fn LsS6)7RwV!crg#%B literal 0 HcmV?d00001 diff --git a/snake.prg b/snake.prg new file mode 100644 index 0000000000000000000000000000000000000000..ce37aa2667052689dc371d65c1558baf21752d85 GIT binary patch literal 80 zcmZSN;O5|Bm}g{QX2`(6u!vzR!(4_3FE0F8%BcB|ldY9e!IPt6<-uMFW}v{|R>nnr idl?^0WjqB^z{%dqxY8Xc714GqhiSpe$qJYLCjbBz>>bJg literal 0 HcmV?d00001