diff --git a/include/block.a02 b/include/block.a02 new file mode 100644 index 0000000..4e34803 --- /dev/null +++ b/include/block.a02 @@ -0,0 +1,321 @@ +;C02 library block.h02 assembly language subroutines +;Requires External Zero Page Variables +;BLKLO, BLKHI, DSTLO, DSTHI, SRCLO, SRCHI +;External Variables +;BLKSLO, BLKSHI, BLKELO, BLKEHI, BLKLEN, TEMP0, TEMP1, TEMP2 +;External Routines +;MEMCMP, MEMCPY, MEMSRC, SETDST, SETSRC + +;blkbgn(&b) - Set Block Start Address +;Args: X,Y = Address +;Sets: BLKSLO, BLKSHI = Block Start Address +;Affects: Z, N +BLKBGN: STX BLKSLO ;Save Block Start Low Byte + STY BLKSHI ;Save Block Start High Byte + RTS + +;blkend(&b) - Set Block End Address (+1) +;Args: X,Y = Address +;Sets: BLKELO, BLKEHI = Block End Address +;Affects: Z, N +BLKEND: STX BLKELO ;Save Block End Low Byte + STY BLKEHI ;Save Block End High Byte + RTS + +;blkrst() - Reset Block Segment Pointer to Start Address +;Uses: BLKSLO, BLKSHI = Block Start Address +;Sets: BLKLO, BLKHI = Block Pointer +;Affects: Z, N +;Returns: X = Block Pointer Low Byte +; Y = Block Pointer High Byte +BLKRST: LDX BLKSLO ;Load X with Block Start Low Byte + LDY BLKSHI ;Load X with Block Start High Byte +;Set Block Address +BLKSXY: STX BLKLO ;Store X in Block Pointer Low Byte + STY BLKHI ;Store Y in Block Pointer High Byte + RTS ;Exit Routine + +;blkset(c) - Set All Bytes in Block to Character c +;Args: c - Value to Set all Bytes to +;Uses: BLKSLO, BLKSHI = Block Start Address +; BLKELO, BLKEHI = Block End Address +; +;Returns: A - Value of Argument n +BLKSET: JSR BLKRST ;Reset Block Pointer + LDY #0 ;Initialize Index +BLKSEL: LDX BLKHI ;Get Block Pointer High Byte + CPX BLKEHI ;Compare to Block End High Byte + BNE BLKSES ; If Equal + LDX BLKLO ; Get Block Pointer Low Byte + CPX BLKELO ; Compare to Block End Low Byte + BEQ BLKSEX ; If Equal Exit Routine +BLKSES: STA (BLKLO),Y ;Store Value at Block Pointer Address + INC BLKLO ;Increment Block Pointer Low Byte + BNE BLKSEL ;If Not End of Page, Loop + INC BLKHI ;Increment Block Pointer High Byte + JMP BLKSEL ;If Not End of Memory, Loop +BLKSEX: RTS ;Return + +;blkput(n, &m) - Append n Bytes of m to Block +;Args: n = Number of Bytes to Append +; m = Array of Bytes to Append +;Uses: BLKELO, BLKEHI = Block End Address +;Sets: DSTLO, DSTHI = Pointer to Bytes in Block +; SRCHI, SRCLO = Pointer to m +; TEMP0 = Number of Bytes to Append +;Updates: BLKLO, BLKHI = Block Pointer +;Returns: A=$FF - Append Successful +; A=$00 - Block Overflow +BLKPUT: JSR SETSRC ;Save Source Pointer + JSR MEMSRA ;Save Number of Bytes to Append + JSR BLKSDP ;Set Destination to Block Pointer + JMP BLKNCP ;Move Block Pointer and Copy + +;blkget(n, &m) - Read n Bytes of Block into Array m +;Args: n = Number of Bytes to Read +; m = Array to Read Bytes into +;Uses: BLKELO, BLKEHI = Block End Address +;Sets: DSTLO, DSTHI = Pointer to Bytes in Block +; SRCHI, SRCLO = Pointer to m +; TEMP0 = Number of Bytes to Append +;Updates: BLKLO, BLKHI = Block Pointer +;Returns: A=$FF - Append Successful +; A=$00 - Block Overflow +BLKGET: JSR SETDST ;Set Destination Pointer + JSR MEMSRA ;Save Number of Bytes to Append + JSR BLKSSP ;Set Source Pointer to Block Pointer +BLKNCP: JSR BLKNXT ;Move Block Pointer + BEQ BLKRTS ;If Past End of Block, Return False + JMP BLKCPY ;Else Copy Bytes + +;blkmem(n, &m) - Search for n Bytes of m in Block +;Args: n = Segment Size to Search in Bytes +; m = Array of Bytes to Search For +;Sets: DSTLO, DSTHI = Pointer to Segment in Block +; SRCHI, SRCLO = Pointer to m +; TEMP0 = Number of Bytes to Append +;Returns: A=$FF - Bytes found +; A=$00 - Bytes not found +BLKMEM: JSR MEMSRC ;Initialize Source, Index, and Count + JSR BLKSDB ;Set Destination Pointer To Block Start +BLKMEL: LDY #0 ;Initialize Index + JSR MEMCML ;Compare Source to Destination + BEQ BLKTRU ;If Equal, Exit TRUE + JSR BLKDSN ;Move Destination Pointer + BNE BLKMEL ;If Not Past Block End, Loop + ;Else +BLKFLS: LDA #$00 ; Return FALSE + RTS + +;blkseg(n) - Set Block Segment Length +;Args: n - Segment Length +;Sets: TEMP0 = Segment Size +;Returns: A=$FF - Segment Length Successfully Set +; A=$00 - Error: Segment Length not Set +BLKSEG: STA BLKLEN ;Store Argument in Block Length + ORA #0 ;If Segment Length is Zero + BEQ BLKFLS ; Return False + ;Else +BLKTRU: LDA #$FF ; Return TRUE +BLKRTS: RTS + +;blkdsn() - Move Destination Pointer to Next Segment +;Uses: BLKLEN - Block Segment Length +;Updates: DSTLO, DSTHI = Block Pointer +;Affects: C,N,Z +;Returns: A=$FF - Destination Pointer Moved +; A=$00 - Error: Pointer Overflow or Length 0 +BLKDSN: LDA BLKLEN ;Get Segment Length + BEQ BLKRTS ;If 0 Return False + CLC + ADC DSTLO ;Add to Destination Low Byte + STA DSTLO + LDA DSTHI ;Add Carry + ADC #0 ;to Destination High Byte + STA DSTHI ;If Destination High Byte + CMP BLKEHI ; < Block End High Byte + BCC BLKTRU ; Return True + LDA DSTLO ;Else + JMP BLKNXL ; Check Destination Low Byte + +;blknxt(n) - Move Block Pointer to Next Segment +;Uses: BLKLEN - Block Segment Length +;Updates: BLKLO, BLKHI = Block Pointer +;Affects: C,N,Z +;Returns: A=$FF - Destination Pointer Moved +; A=$00 - Error: Pointer Overflow or Length 0 +BLKNXT: LDA BLKLEN ;Get Segment Length + BEQ BLKRTS ;If 0 Return False + CLC + ADC BLKLO ;Add to Block Pointer Low Byte + STA BLKLO + LDA BLKHI ;Add Carry + ADC #0 ;to Block Pointer High Byte + STA BLKHI ;If Block Pointer High Byte + CMP BLKEHI ; < Block End High Byte + BCC BLKTRU ; Exit True + LDA BLKLO ;Else If Destination Low Byte +BLKNXL: CMP BLKELO ; < Block End low Byte + BCC BLKTRU ; Return True + BCS BLKFLS ;Else Return False + +;blkprv(n) - Move Block Pointer to Previous Segment +;Uses: BLKLEN - Block Segment Length +;Updates: BLKLO, BLKHI = Block Pointer +;Affects: C,N,Z +;Returns: A=$FF - Destination Pointer Moved +; A=$00 - Error: Pointer Overflow or Length 0 +BLKPRV: LDA BLKLEN ;Get Segment Length + BEQ BLKRTS ;If 0 Return False + SEC + SBC BLKLO ;Add to Block Pointer Low Byte + STA BLKLO + LDA BLKHI ;Add Carry + SBC #0 ;to Block Pointer High Byte + STA BLKHI ;If Block Pointer High Byte + CMP BLKEHI ; >= Block Start High Byte + BCS BLKTRU ; Exit True + LDA BLKLO ;Else If Destination Low Byte +BLKPRL: CMP BLKELO ; >= Block End low Byte + BCS BLKTRU ; Return True + BCC BLKFLS ;Else Return False + +;blksrt(&m) - Sort Block +;Args: m = Array of at least n Bytes for Temporary Storage +;Sets: TEMP1,TEMP2 = Pointer to Array m +;Uses: BLKLO, BLKHI = Block Pointer +; BLKSLO, BLKSHI = Block Start Address +; BLKELO, BLKEHI = Block End Address +; BLKLEN = Block Segment Size +; DSTLO, DSTHI = Pointer to Segment in Block +; SRCHI, SRCLO = Pointer to Segment in Block +;Affects: A,Y,C,N,Z +BLKSRT: LDA BLKLEN ;Get Segment Length + BEQ BLKRTS ;If 0 Return + STA TEMP0 ;Else Set Memory Swap Byte Count + JSR BLKRST ;Set Block Pointer to Block Start +BLKSRP: LDY #0 ;If First Byte of + LDA (BLKLO),Y ; Current Segment is Null + BEQ BLKRTS ; Return + JSR BLKSSP ;Copy Block Pointer to Source Pointer + JSR BLKSDP ;Copy Block Pointer and Destination Pointer +BLKSRD: JSR BLKDSN ;Move Destination Pointer + BCS BLKSRC ;If Not Past Block End + LDY #0 ; + LDA (DSTLO),Y ;and Destination String Populated + BEQ BLKSRC ; + JSR STRCML ; Compare Destination String with Source String + BPL BLKSRD ; If Destination < Source + JSR BLKSSD ; Set Source Pointer to Destination Pointer + JMP BLKSRD ; Check Next Destination Segment +BLKSRC: LDA SRCHI ;If Source Pointer + CMP BLKHI ; <> Block Pointer + BNE BLKSRS + LDA SRCLO + CMP BLKLO + BEQ BLKSRN +BLKSRS: JSR BLKSWL ; Swap Source and Pointer +BLKSRN: JSR BLKNXT ;Move Block Pointer + BNE BLKSRP ;If Not Past End, Check Next Segment + RTS ;Return + +;blkstr(n, &s) - Search for String s in Block and +; Copy Segment to Destination Array if Found +;Args: n = Segment Size to Search in Bytes +; s = String +;Sets: SRCLO,SRCHI = Pointer to Segment in String (if found) +; TEMP0 = Segment Size +; TEMP1,TEMP2 = Destination String Pointer +;Affects: Y,C +;Returns: A=$FF,N=1,Z=0 if Found +; A=$00,N=0,Z=1 if Not Found +BLKSTR: JSR MEMSRC ;Initialize Source, Index, and Count + JSR BLKDSS ;Save Destination Pointer + JSR BLKSDB ;Set Destination Pointer To Block Start +BLKSTL: LDY #0 ;Initialize Index + JSR STRCML ;Compare Source to Destination + BEQ BLKSTS ;If Not Equal + JSR BLKDSN ; Move Destination Pointer + BNE BLKSTL ; If Not Past Block End, Loop +BLKSTF: JSR BLKDSR ; Else Restore Destination String and Return + LDA #$00 ; and Return FALSE + RTS ;Else +BLKSTS: JSR BLKSSD ; Set Source Pointer to Destination Pointer + JSR BLKDSR ; Restore Destination String Pointer +BLKCPY: LDY #0 ; Initialize Index + JSR MEMCPL ; Copy Segment to Destination String + LDA #$FF ; Return TRUE + RTS + +;blkswp(n, &m) - Swap n Bytes of Array with Block Segment +;Args: n = Number of bytes to swap +; m = Array to swap bytes from +;Sets: TEMP0 = Number of Bytes to Swap +;Uses: BLKLO, BLKHI = Block Pointer +; DSTLO, DSTHI = Pointer to Temporary Storage Array +;Affects: A,Y,C,N,Z +BLKSWP: JSR MEMSRC ;Set Source Address and Index +BLKSWL: JSR BLKSDP ;Set Destination Pointer to Block Pointer + LDY #0 ;Initialize Index + JMP MEMSWL ;Swap Bytes + +;blkdsb() - Set Destination Pointer to Block Start Address +;Uses: BLKSLO, BLKSHI = Block Start Address +;Sets: DSTLO, DSTHI = Block Pointer +;Affects: N,Z +;Returns: X = Block Pointer Low Byte +; Y = Block Pointer High Byte +BLKSDB: LDX BLKSLO ;Load Block Start Low Byte + LDY BLKSHI ;Load Block Start High Bytes + JMP SETDST ;Set Destination and Return + +;blksds() - Set Source Pointer to Destination Pointer +;Uses: SRCLO,SRCHI = Source Array Pointer +;Sets: DSTLO,DSTHI = Destination Array Pointer +;Affects: X,N,Z +;Returns: Y = 0 +BLKSSD: LDX DSTLO + LDY DSTHI + JMP SETSRC + +;blkssp() - Set Source Pointer to Block Pointer +;Uses: BLKLO,BLKHI = Block Segment Pointer +;Sets: SRCLO,SRCHI = Source Array Pointer +;Affects: X,N,Z +;Returns: Y = 0 +BLKSSP: LDX BLKLO + LDY BLKHI + JMP SETSRC ;Set Source and Return + +;blksdp() - Set Destination Pointer to Block Pointer +;Uses: BLKLO,BLKHI = Block Segment Pointer +;Sets: DSTLO,DSTHI = Destination Array Pointer +;Affects: N,Z +;Returns: X = Block Pointer Low Byte +; Y = Block Pointer High Byte +BLKSDP: LDX BLKLO + LDY BLKHI + JMP SETDST ;Set Destination and Return + +;blkdss() - Save Destination Pointer +;Uses: DSTLO, DSTHI = Destination Array Pointer +;Sets: TEMP1, TEMP2 = Temporary Storage +;Affects: X,Y,N,Z +BLKDSS: LDX DSTLO ;Save Destination Address + LDY DSTHI +;Save X and Y Registers +BLKXYS: STX TEMP1 + STY TEMP2 + RTS + +;blkdsr() - Restore Destination Pointer +;Uses: TEMP1, TEMP2 = Temporary Storage +;Sets: DSTLO, DSTHI = Destination Array Pointer +;Affects: A,N,Z +;Returns: X = Block Pointer Low Byte +; Y = Block Pointer High Byte +BLKDSR: LDX TEMP1 ;Restore Destination Address + LDY TEMP2 + JMP SETDST ;Set Destination and Return + + diff --git a/include/block.h02 b/include/block.h02 new file mode 100644 index 0000000..59d1e98 --- /dev/null +++ b/include/block.h02 @@ -0,0 +1,61 @@ +/****************************************** + * block - Block Memory Functions for C02 * + ******************************************/ + +/* Set Block Start Address * + * Args: &b - Start Address */ +void blkbgn(); + +/* Set Destination Pointer to Block Start */ +void blkdst(); + +/* Set Block End Address * + * Args: &b - End Address */ +void blkend(); + +/* Read Bytes from Block * + * Args: n - Number of bytes to read * + * &m - Array containing bytes to read * + * Returns: A=$FF if bytes were written * + * $00 if block was overflowed */ +char blkget(); + +/* Search Block for Array Contents * + * Args: n - Search segment size * + * &m - Array containing bytes to search for * + * Returns: A=$FF if found * + * $00 if not found */ +char blkmem(); + +/* Write Bytes to Block * + * Args: n - Number of bytes to write * + * &m - Array containing bytes to write * + * Returns: A=$FF if bytes were written * + * $00 if block was overflowed */ +char blkput(); + +/* Set Block Pointer to Block Start */ +void blkrst(); + +/* Fill Block with Character * + * Args: c - Character to fill block with * + * Returns: Fill character */ +char blkset(); + +/* Sort Segments in Block * + * Args: &m - Array containing bytes to swap */ +char blksrt(); + +/* Search Block for String * + * Args: n - Search segment size * + * &m - Array containing bytes to search for * + * Returns: A=$FF if found * + * $00 if not found */ +char blkstr(); + +/* Swap Bytes in Array with Block Segment * + * Args: n - Search segment size * + * &m - Array containing bytes to swap */ +char blkswp(); + + diff --git a/include/c64.a02 b/include/c64.a02 new file mode 100644 index 0000000..82674ad --- /dev/null +++ b/include/c64.a02 @@ -0,0 +1,293 @@ +; c02 Program Initialization Code for Unexpanded VIC-20 + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +; EQU $00 ;USR JMP +adray1 EQU $03 ;Vector: Convert Floating Point to Signed Integer +adray2 EQU $05 ;Vector: Convert Integet to Floating Point +charac EQU $07 ;Search Character for Scanning BASIC Text Input +endchr EQU $08 ;Search Character for Statement Terminator or Quote +trmpos EQU $09 ;Column Position of Cursor before Last SPC or TAB +verckb EQU $0A ;Flag: Load or Verify (BASIC) +count EQU $0B ;Index into Text Input Buffer/Number of Array Subscripts +dimflg EQU $0C ;Flags for Routines that Locate or Build an Array +valtyp EQU $0D ;Type of Data (String or Numeric) +intflg EQU $0E ;Type of Numeric Data (Integer or Floating Point) +garbfl EQU $0F ;Flag for LIST, Garbage Collection, and Program Terminators +subflg EQU $10 ;Subscript Reference to Array or User Defined Function Call +inpflg EQU $11 ;Is Data Input to GET, READ, or INPUT? +tansgn EQU $12 ;Sign of Result of TAN or SIN Function +channl EQU $13 ;Current I/O Channel (CMD Logical File) Number +linnum EQU $14 ;Integer Line Number Value +temppt EQU $16 ;Pointer to Next Availabale Space in Temporary String Stack +lastpt EQU $17 ;Pointer to Address of Last String in Temporary String Stack +tempst EQU $19 ;Descriptor Stack for Temporary Strings +index EQU $22 ;Miscellaneous Temporary Pointers and Save Area +; $24 +resho EQU $26 ;Floating Point Multiplication Work Area +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +frespc EQU $35 ;Temporary Pointer for Strings +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +curlin EQU $39 ;Current BASIC Line Number +oldlin EQU $3B ;Previous BASIC Line Number +oldtxt EQU $3D ;Pointer to Address of Current BASIC Statement +datlin EQU $3F ;Current DATA Line Number +datptr EQU $41 ;Pointer to Address of Current DATA Item +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +varnam EQU $45 ;Current Variable Name +varpnt EQU $47 ;Pointer to Current BASIC Variable Value +forpnt EQU $49 ;Temporary Pointer to Index Variable Used by FOR +opptr EQU $4B ;Math Operator Table Displacement +opmask EQU $4D ;Mask for Comparison Operator +defpnt EQU $4E ;Pointer to Current FN Descriptor +dscpnt EQU $50 ;Temporary Pointer to Current String Descriptor +; $52 ;current string length +four6 EQU $53 ;Constant for Garbage Collection +jmper EQU $54 ;Jump to Function Instruction +; $57 ;BASIC Numeric Work Area +fac1 EQU $61 ;Floating Point Accumulator #1 +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +sgnflg EQU $67 ;Number of Terms in Series Evaluation +bits EQU $68 ;Floating Point Accumulator #1: Overflow Digit +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +facov EQU $70 ;Low Order Mantissa Byte of Floating Point Accumulator #1 +fbufpt EQU $71 ;Series Evaluation Pointer +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +rndx EQU $8B ;RND Function Seed Value +status EQU $90 ;Kernal I/O Status Word +stkey EQU $91 ;Flag: Was STOP Key Pressed +svxt EQU $92 ;Timing Constant for Tape Reads +verck EQU $93 ;Flag: Load or Verify (Kernal) +c3po EQU $94 ;Flag: Serial Bus - Output Character was Buffered +bsour EQU $95 ;Buffered Character for Serial Bus +syno EQU $96 ;Cassette Block Synchronization Number +xsav EQU $97 ;Temporary .X Register Save Area +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +prty EQU $9B ;Tape Character Parity +dpsw EQU $9C ;Flag: Tape Byte Received +msflg EQU $9D ;Flag: Kernal Message Control +ptr1 EQU $9E ;Tape Pass 1 Error Log Index +ptr2 EQU $9F ;Tape Pass 2 Error Log Correction Index +time EQU $A0 ;Software Jiffy Clock +; EQU $A3 ;Temporary Data Storage Area +cntdn EQU $A5 ;Cassette Synchronization Character Countdown +bufpnt EQU $A6 ;Count of Characters in Tape I/O Buffer +inbit EQU $A7 ;RS-232 Input Bits/Tape I/O Miscellaneous Flag +bitci EQU $A8 ;RS-232 Input Bit Count/Tape Error Flag +rinone EQU $A9 ;RS-232 Flag: Check for Start Bit/Tape Character Type Flag +ridata EQU $AA ;RS-232 Input Byte Buffer +riprty EQU $AB ;RS-232 Input Parity/Cassette Leader Counter +sal EQU $AC ;Pointer to Starting Address of Load/Screen Scrolling +eal EQU $AE ;Pointer to Ending Address of Load (End of Program) +cmp0 EQU $B0 ;Used to Determine Value of SVXT +; EQU $B1 ;Used in Timing of Tape Reads +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +bitts EQU $B4 ;RS-232 Output Bit Count/Tape Load Receive Flag +nxtbit EQU $B5 ;RS-232 Next Bit to Send/Tape EOT Flag +rodata EQU $B6 ;RS-232 Output Byte Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +roprt EQU $BD ;RS-232 Output Parity/Tape Character Being Read or Sent +fsblk EQU $BE ;Cassette Read/Write Block Count +mych EQU $BF ;Tape Input Byte Buffer +cas1 EQU $C0 ;Tape Motor Interlock +stal EQU $C1 ;I/O Start Address +memuss EQU $C3 ;Tape Load Temporary Address +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +indx EQU $C8 ;Pointer: End of Logical Line for Input +lxsp EQU $C9 ;Cursor X.Y Position at Start of Input +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +blnsw EQU $CC ;Cursor Blink Enable +blnct EQU $CD ;Timer Countdown to Blink Cursor +gdbln EQU $CE ;Character Under Cursor +blnon EQU $CF ;Flag: Was Last Cursor Blink On or Off +crsw EQU $D0 ;Flag: Input from Keyboard or Screen +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +qtsw EQU $D4 ;Flag: Editor in Quote Mode? +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +; EQU $D7 ;Temporary Storage for ASCII Value of Last Character Printed +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +user EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +keytab EQU $F5 ;Vector: Keyboard Decode Table +ribuf EQU $F7 ;Pointer: RS-232 Input Buffer +robuf EQU $F8 ;Pointer: RS-232 Output Buffer +frekzp EQU $FB ;Four Free Bytes of Zero Page for User Programs +baszpt EQU $FF ;BASIC Temporary Data for Floating Point to ASCII Conversion + +;Page 1 Locations +bad EQU $0100 ;Tape Input Error Log +; EQU $013F ;Microprocessor Stack + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +timout EQU $0285 ;Flag: Kernal Variable for IEEE Timeout +color EQU $0286 ;Current Foreground Color Text +gdcol EQU $0287 ;Color of Character Under Cursor +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +delay EQU $028C ;Counter for Timing Delay Until First Key Repeat Begins +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +lstshf EQU $028E ;Last Pattern SHIFT/CTRL/Logo Keypress +keylog EQU $028F ;Vector to Keyboard Table Setup Routine +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress +autodn EQU $0292 ;Flag: Screen Scroll Enabled +m51ctr EQU $0293 ;RS-232: Mock 6551 Control Register +m51cdr EQU $0294 ;RS-232: Mock 6551 Command Register +m51adj EQU $0295 ;RS-232: Non-Standard Bit Timing (Not Implemented) +rsstat EQU $0297 ;RS-232: Mock 6551 Status Register +bitnum EQU $0298 ;RS-232: Number of Bits Left to be Sent/Received +baudof EQU $0299 ;RS-232: Time Required to Send a Bit +ridbe EQU $029B ;RS-232: Index to End of Receive Buffer +ridbs EQU $029C ;RS-232: Index to Start of Receive Buffer +rodbs EQU $029D ;RS-232: Index to Start of Transmit Buffer +rodbe EQU $029E ;RS-232: Index to End of Transmit Buffer +irqtmp EQU $029F ;Save Area for IRQ Vector During Cassette I/O +enabl EQU $02A1 ;RS-232 Interrupts Enabled +; EQU $02A2 ;CIA #1 Control Register B Activity During Cassette I/O +; EQU $02A3 ;Save Area for CIA #1 Interrupt Control Register +; EQU $02A4 ;Save Area for CIA #1 Control Register A +; EQU $02A5 ;Temporary Index to Next Line for Screen Scrolling +; EQU $02A6 ;PAL/NTSC Flag +; EQU $02A7 ;Unused +; EQU $02C0 ;Sprite 11 + +;BASIC Indirect Vector Table +ierror EQU $0300 ;Vector to Print BASIC Error Message Routine +imain EQU $0302 ;Vector to Main BASIC Program Loop +icrnch EQU $0304 ;Vector to Crunch ASCII Keyword into Tokens +iqplop EQU $0306 ;Vector to List BASIC Token as ASCII Text +igone EQU $0308 ;Vector to Execute Next BASIC Token +ieval EQU $030A ;Vector to Evaluate Single-Term Arithmetic Expression + +;Register Storage Area +sareg EQU $030C ;Storage Area for .A Register (Accumulator) +sxreg EQU $030D ;Storage Area for .X Index Register +syreg EQU $030E ;Storage Area for .Y Index Register +spreg EQU $030F ;Storage Area for .P (Status) Register + +;Miscellaneous Vectors +usrpok EQU $0310 ;JMP Instruction for User Function +usradd EQU $0311 ;Address of USR Routine +; EQU $0313 ;Unused +cinv EQU $0314 ;Vector to IRQ Interrupt Routine +cbinv EQU $0316 ;Vector: BRK Instruction Interrupt +nminv EQU $0318 ;Vector: Non-Maskabke Interrupt + +;Kernal Indirect Vectors +iopen EQU $031A ;Vector to Kernal OPEN Routine +iclose EQU $031C ;Vector to Kernal CLOSE Routine +ichkin EQU $031E ;Vector to Kernal CHKIN Routine +ickout EQU $0320 ;Vector to Kernal CKOUT Routine +iclrch EQU $0322 ;Vector to Kernal CLRCHN Routine +ibasin EQU $0324 ;Vector to Kernal CHRIN Routine +ibsout EQU $0326 ;Vector to Kernal CHROUT Routine +istop EQU $0328 ;Vector to Kernal STOP Routine +igetin EQU $032A ;Vector to Kernal GETIN Routine +iclall EQU $032C ;Vector to Kernal CLALL Routine +usrcmd EQU $032E ;Vector to User Defined Command (Unused) +iload EQU $0330 ;Vector to Kernal LOAD Routine +isave EQU $0332 ;Vector to Kernal SAVE Routine + +; $0334 ;Unused +tbuffer EQU $033C ;Cassette I/O Buffer +; $03FC ;Unused + +vicscn EQU $0400 ;Video Screen Memory Area +; $07F8 ;Sprite Shape Data Pointers +; $0800 ;BASIC Program Text +; $8000 ;Autostart ROM Cartridge + +vicclr EQU $D800 ;Color RAM + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start Directly Above Stack +basic: DC $0C, $10 ; Pointer to Next Line (4109) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + + JMP main ;Execute Program + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Read Character from Console + + +;Wait for Character from Console +getkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/ctype.a02 b/include/ctype.a02 new file mode 100644 index 0000000..ca7f7f6 --- /dev/null +++ b/include/ctype.a02 @@ -0,0 +1,120 @@ +;ctype.h02 assembly language subroutines +; +;C02 Functions modify Accumulator and Flags +; ISxxxx will load $FF into Accumulator to and Set Carry if True +; and load $00 into Accumulator to and clear Carry if False +; toxxxx set Carry if character IS converted, otherwISe clear Carry +;Machine Language Subroutines modify Flags but not Accumulator +; Carry will be Set if True and Cleared if False +;Index RegISters are not modified by any routines + +;Character Test Functions - Set Accumulator +ISALNM: JSR ISALN ;Is Alphanumeric Character + BVC ISBTF +ISALPH: JSR ISALP; ;Is Alphabetic Character + BVC ISBTF +ISBDGT: JSR ISBIN ;Is Binary Digit + BVC ISBTF +ISCTRL: JSR ISCTL ;Is Control Character + BVC ISBTF +ISDIGT: JSR ISDGT ;Is Digit + BVC ISBTF +ISGRPH: JSR ISGRP ;Is Graphical Character + BVC ISBTF +ISHDGT: JSR ISHEX ;Is Hex Digit + BVC ISBTF +ISLOWR: JSR ISLWR ;Is Lowercase Character + BVC ISBTF +ISPNCT: JSR ISPNC ;Is Punctuation Character + BVC ISBTF +ISPRNT: JSR ISPRT ;Is Printable Character + BVC ISBTF +ISSPCE: JSR ISSPC ;Is White Space Character + BVC ISBTF +ISUPPR: JSR ISUPR ;Is Uppercase Character + BVC ISBTF + +;Internal Routines - Set Accumulator based on Carry Flag +ISBTF: BCC ISFLS ;If Carry Set +ISTRU: LDA #$FF ; Return TRUE + RTS ;Else +ISFLS: LDA #$00 ; Return FALSE + RTS + +;C02/ML Character Conversion Routines +tolowr: JSR ISUPR ;If Char IS Not Upper Case + BCC ISRTS ; Return + ORA #$20 ;Else Set Bit 5 + RTS ; and Return + +touppr: JSR ISLWR ;If Char IS Not Lower Case + BCC ISRTS ; Return + AND #$DF ;Else Clear Bit 5 + RTS ; and Return + +;Machine Language Subroutines - Set/Clear Carry, Preserve Accumulator +ISALN: JSR ISDGT ;If Char IS Digit + BCS ISRTS ; Return Carry Set + ;Else +ISALP: JSR ISUPR ;If Char IS Upper Case + BCS ISRTS ; Return Carry Set + ;Else +ISLWR: CMP #$61 ;If Char < 'a' + BCC ISRTS ; Return with Carry Clear + CMP #$7B ;Else If Char >= '{' + JMP ISBCS ; Return with Carry Clear Else Return with Carry Set + +ISUPR: CMP #$41 ;If Char < 'A' + BCC ISRTS ; Return with Carry Clear + CMP #$5B ;Else If Char >= '[' +ISBCS: BCS ISCLC ; Return with Carry Clear + BCC ISSEC ;Else Return with Carry Set + +ISSEC: SEC ;Set Carry + BCS ISRTS ; and Return + +ISCLC: CLC ;Clear Carry +ISRTS: CLV ;Clear Overflow - for C02 calls + RTS ;Return from Subroutine + +ISCTL: CMP #$7F ;If Char = DEL + BEQ ISSEC ; Return Carry Set + CMP #$20 ;Else If Char < ' ' + JMP ISBCS ; Return Carry Set Else Return Carry Clear + +ISBIN: CMP #$32 ;If Char >= '2' + + BCS ISCLC ; Return Carry Clear + ;Else +ISDGT: CMP #$30 ;If Char < '0' + BCC ISRTS ; Return Carry Clear + CMP #$3A ;Else If Char >= ':' + JMP ISBCS ; Return FALSE Else Return TRUE + +ISPNC: JSR ISALN ;If Char IS Alphanumeric + BCS ISCLC ; Return Carry Clear + ;Else +ISGRP: CMP #$20 ;If Char IS Space + BEQ ISCLC ; Return Carry Clear + ;Else +ISPRT: CMP #$80 ;If Char IS High ASCII + BCS ISCLC ; Return Carry Clear + JSR ISCTL ;If Char IS Not Control + JMP ISBCS ; Return Carry Clear Else Return Carry Set + +ISSPC: CMP #$20 ;If Char IS ' ' + BEQ ISSEC ; Return Carry Set + CMP #$09 ;If Char < '\t' + BCC ISRTS ; Return Carry Clear + CMP #$0E ;Else If Char > '\r' + JMP ISBCS ; Return Carry Clear Else Return Carry Set + +ISHEX: CMP #$41 ;If Char < 'A' + BCC ISDGT ; Check for Digit + CMP #$47 ;Else If Char < 'G' + BCC ISSEC ; Return Carry Set + CMP #$61 ;Else If Char < 'a' + BCC ISRTS ; Return Carry Clear + CMP #$67 ;Else If Char >= 'g' + JMP ISBCS ; Return Carry Clear Else Return Carry Set + diff --git a/include/ctype.h02 b/include/ctype.h02 new file mode 100644 index 0000000..ba908b4 --- /dev/null +++ b/include/ctype.h02 @@ -0,0 +1,80 @@ +/************************************** + * ctype - Character Typing Functions * + **************************************/ + +/* Check for Alphanumeric Character * + * (Alphabetic or Digit) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isalnm(); + +/* Checks for Alphabetic Character * + * (Upper Case or Lower Case) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isalph(); + +/* Checks for Control Character * + * (Less than Space or Delete) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isctrl(); + +/* Checks for Digit Character * + * (In range 0-9) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isdigt(); + +/* Checks for Graphical Character * + * (Printable except Space) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isgrph(); + +/* Checks for Hex Digit Character * + * (In range 0-9, A-F, or a-f) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char ishdgt(); + +/* Checks for Lower Case Character * + * (In range a-z) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char islowr(); + +/* Checks for Printable Character * + * (Not High ASCII nor Control) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isprnt(); + +/* Checks for Punctuation Character * + * (Printable not Alphanumeric) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char ispnct(); + +/* Checks for White Space Character * + * (Space, Tab, NL, VT, FF, CR) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isspce(); + +/* Checks for Upper Case Character * + * (In range A-Z) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +char isuppr(); + +/* Convert Character to Lower Case * + * Args: c - Character to Convert * + * Returns: Converted Character */ +char tolowr(); + +/* Convert Character to Upper Case * + * Args: c - Character to Convert * + * Returns: Converted Character */ +char touppr(); + diff --git a/include/ctype1.a02 b/include/ctype1.a02 new file mode 100644 index 0000000..7440dd4 --- /dev/null +++ b/include/ctype1.a02 @@ -0,0 +1,146 @@ + PROCESSOR 6502 + ORG $0200 +; ctype.h02 assembly language subroutines +; + + +isalnm: LDX #0 ;ALNUM + BPL ctype +isalph: LDX #1 ;ALPHA + BPL ctype +isctrl: LDX #2 ;CNTRL + BPL ctype +isdigt: LDX #3 ;DIGIT + BPL ctype +isgrph: LDX #4 ;GRAPH + BPL ctype +islowr: LDX #5 ;LOWER + BPL ctype +isprnt: LDX #6 ;PRINT + BPL ctype +ispnct: LDX #7 ;PUNCT + BPL ctype +isspce: LDX #8 ;SPACE + BPL ctype +isuppr: LDX #9 ;UPPER + BPL ctype +isxdgt: LDX #10 ;HXDGT + +ctype: TAY ;Save Character + AND #$80 ;If High Bit Set + BNE cflse ; Return False + LDA cchar,Y ;Get Character Bit Mask + AND cmask,X ;If it Matches Test Bit Mask + BNE ctrue ; Return True + +cflse: LDA #0 ;Return False + RTS + +ctrue: LDA #$FF ;Return True + RTS + +;Informational Only +;CNTRL EQU %00000001 ;Control Character +;SPACE EQU %00000010 ;White Space +;BLANK EQU %00000100 ;Blank +;PUNCT EQU %00001000 ;Punctuation +;DIGIT EQU %00010000 ;Decimal Digit +;HEXDC EQU %00100000 ;Hexadecimal Digit +;UPPER EQU %01000000 ;Upper Case +;LOWER EQU %10000000 ;Lower Case + +;Character Test Bit Masks +cmask: DB %11010000 ;ALNUM = DIGIT + UPPER + LOWER + DB %11000000 ;ALPHA = UPPER + LOWER + DB %00000001 ;CNRTL + DB %00010000 ;DIGIT + DB %11011000 ;GRAPH = PUNCT + DIGIT + UPPER + LOWER + DB %10000000 ;LOWER + DB %11011100 ;PRINT = BLANK + PUNCT + DIGIT + UPPER + LOWER + DB %00001000 ;PUNCT + DB %00000010 ;SPACE + DB %01000000 ;UPPER + DB %00110000 ;HXDGT = DIGIT + HEXDC + +;Character Set Bit Masks +cchar: DB %00000001 ;00 NUL CNTRL + DB %00000001 ;01 SOH CNTRL + DB %00000001 ;02 STX CNTRL + DB %00000001 ;03 ETX CNTRL + DB %00000001 ;04 EOT CNTRL + DB %00000001 ;05 ENQ CNTRL + DB %00000001 ;06 ACK CNTRL + DB %00000001 ;07 BEL CNTRL + DB %00000001 ;08 BS CNTRL + DB %00000011 ;09 HT CNRTL + SPACE + DB %00000011 ;0A LF CNRTL + SPACE + DB %00000011 ;0B VT CNRTL + SPACE + DB %00000011 ;0C FF CNRTL + SPACE + DB %00000011 ;0D CR CNRTL + SPACE + DB %00000001 ;0E SS CNRTL + DB %00000001 ;0F SI CNRTL + DB %00000001 ;10 DLE CNRTL + DB %00000001 ;11 DC1 CNRTL + DB %00000001 ;12 DC2 CNRTL + DB %00000001 ;13 DC3 CNRTL + DB %00000001 ;14 DC4 CNRTL + DB %00000001 ;15 NAK CNRTL + DB %00000001 ;16 SYN CNRTL + DB %00000001 ;17 ETB CNRTL + DB %00000001 ;18 CAN CNRTL + DB %00000001 ;19 EM CNRTL + DB %00000001 ;1A SUB CNRTL + DB %00000001 ;1B ESC CNRTL + DB %00000001 ;1C FS CNRTL + DB %00000001 ;1D GS CNRTL + DB %00000001 ;1E RS CNRTL + DB %00000001 ;1F US CNRTL + DB %00000110 ;20 SPC SPACE + BLANK + DB %00001000 ;21 ! PUNCT + DB %00001000 ;22 " PUNCT + DB %00001000 ;23 # PUNCT + DB %00001000 ;24 $ PUNCT + DB %00001000 ;25 % PUNCT + DB %00001000 ;26 & PUNCT + DB %00001000 ;27 ' PUNCT + DB %00001000 ;28 ( PUNCT + DB %00001000 ;29 ) PUNCT + DB %00001000 ;2A * PUNCT + DB %00001000 ;2B + PUNCT + DB %00001000 ;2C , PUNCT + DB %00001000 ;2D - PUNCT + DB %00001000 ;2E . PUNCT + DB %00001000 ;2F / PUNCT + DB %00110000 ;30 0 DIGIT + HEX + DB %00110000 ;31 1 DIGIT + HEX + DB %00110000 ;32 2 DIGIT + HEX + DB %00110000 ;33 3 DIGIT + HEX + DB %00110000 ;34 4 DIGIT + HEX + DB %00110000 ;35 5 DIGIT + HEX + DB %00110000 ;36 6 DIGIT + HEX + DB %00110000 ;37 7 DIGIT + HEX + DB %00110000 ;38 8 DIGIT + HEX + DB %00110000 ;39 9 DIGIT + HEX + DB %00001000 ;3A : PUNCT + DB %00001000 ;3B ; PUNCT + DB %00001000 ;3C < PUNCT + DB %00001000 ;3D = PUNCT + DB %00001000 ;3E > PUNCT + DB %00001000 ;3F ? PUNCT + + +;char tolwr(char c) - Convert to Lower Case +; sets Carry if if Converted +tolwr: JSR isupc ;If Char is Not Upper Case + BCC isrts ; Return + ORA $20 ;Else Set Bit 6 + RTS ; and Return + +;char toupr(char c) - Convert to Upper Case +; sets Carry if if Converted +toupr: JSR islwr ;If Char is Not Lower Case + BCC isrts ; Return + AND $DF ;Else Clear Bit 6 + RTS ; and Return + + diff --git a/include/ctype.asm b/include/ctypeV.a02 similarity index 50% rename from include/ctype.asm rename to include/ctypeV.a02 index 4de0650..54a1a1b 100644 --- a/include/ctype.asm +++ b/include/ctypeV.a02 @@ -1,3 +1,5 @@ + PROCESSOR 6502 + ORG $0200 ; ctype.h02 assembly language subroutines ; ; All calls replace Accumulator and set Flags @@ -7,55 +9,63 @@ ; toxxxx set Carry if character is converted, otherwise clear Carry ;Character Test Routines -isalnm: PHA - JSR isdigt ;If Char is Digit - PLA - BCS istru ; Return TRUE +isalnm: JSR isdigt ;If Char is Digit + BCS isrts ; Return TRUE ;Else -isalph: JSR isupc ;If Char is Upper Case - BCS istru ; Return TRUE +isalph: JSR isuppr ;If Char is Upper Case + BCS isrts ; Return TRUE ;Else islowr: JSR islwc ;If Char is Lower Case - JMP isbtf ; Return TRUE Else Return FALSE + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return TRUE isuppr: JSR isupc ;If Char is Uppercase -isbtf: BCS istru ; Return TRUE - BCC isfls ;Else Return FALSE + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return TRUE -isctrl: CMP #$7F ;If Char = DEL +isctrl: CLV ;Clear Overflow + CMP #$7F ;If Char = DEL BEQ istru ; Return TRUE CMP #$20 ;Else If Char < ' ' - JMP isbft ; Return TRUE Else Return FALSE + BVC isbft ; Return TRUE Else Return FALSE +; BCC istru ; Return TRUE +; BCS isfls ;Else Return FALSE -isdigt: CMP #$30 ;If Char < '0' +isdigt: CLV ;Clear Overflow + CMP #$30 ;If Char < '0' BCC isfls ; Return FALSE CMP #$3A ;Else If Char >= ':' - JMP isbft ; Return FALSE Else Return TRUE + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return True -ispnct: PHA - JSR isalnm ;If Char is Alphanumeric - PLA - BCS isfls ; Return FALSE +ispnct: JSR isalnm ;If Char is Alphanumeric + BNE isfls ; Return FALSE ;Else isgrph: CMP #$20 ;If Char is Space BEQ isfls ; Return FALSE ;Else -isprnt: CMP #$80 ;If Char is High ASCII - BCS isfls ; Return FALSE - JSR isctrl ;If Char is Not Control - JMP isbft ; Return TRUE Else Return FALSE +isprnt: JSR isctrl ;If Char is Not Control + BVC isbft ; Return TRUE Else Return FALSE +; BCC istru ; Return TRUE +; BCS isfls ;Else Return FALSE -isspce: CMP #$20 ;If Char is ' ' +isspc: CLV ;Clear Overflow + CMP #$20 ;If Char is ' ' BEQ istru ; Return TRUE CMP #$09 ;If Char < '\t' BCC isfls ; Return TRUE CMP #$0E ;Else If Char > '\r' - JMP isbft ; Return FALSE Else Return TRUE + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return TRUE isxdgt: JSR touppr ;Convert to Uppercase CMP #$41 ;If Char < 'A' BCC isdigt ; Check for Digit - CMP #$47 ;Else If Char >= 'G' + CMP #$5B ;Else If Char >= 'G' isbft: BCS isfls ; Return FALSE ;Else istru: LDA #$FF ;Return TRUE @@ -67,25 +77,28 @@ isclc: CLC ;Clear Carry isrts: RTS ;Return from Subroutine ;Internal Test Routines - Do Not Change Accumulator -islwc: CMP #$61 ;If Char < 'a' +islwc: CLV ;Clear Overflow for Calling Routine + CMP #$61 ;If Char < 'a' BCC isrts ; Return with Carry Clear CMP #$7B ;Else If Char >= '{' - JMP isbcs ; Return with Carry Clear Else Return with Carry Set + BCS isclc ; Return with Carry Clear + BCC issec ;Else Return with Carry Set -isupc: CMP #$41 ;If Char < 'A' +isupc: CLV ;Clear Overflow for Calling Routine + CMP #$41 ;If Char < 'A' BCC isrts ; Return with Carry Clear CMP #$5B ;Else If Char >= '[' -isbcs: BCS isclc ; Return with Carry Clear - BCC issec ;Else Return with Carry Set + BCS isclc ; Return with Carry Clear + BCC issec ;Else Return with Carry Set ;Character Conversion Routines tolowr: JSR isupc ;If Char is Not Upper Case BCC isrts ; Return - ORA #$20 ;Else Set Bit 5 + ORA $20 ;Else Set Bit 6 RTS ; and Return touppr: JSR islwc ;If Char is Not Lower Case BCC isrts ; Return - AND #$DF ;Else Clear Bit 5 + AND $DF ;Else Clear Bit 6 RTS ; and Return diff --git a/include/file.h02 b/include/file.h02 new file mode 100644 index 0000000..106e65f --- /dev/null +++ b/include/file.h02 @@ -0,0 +1,120 @@ +/****************************************** + * file - Standard File Functions for C02 * + ******************************************/ + +/* File Setup - System Specific * + * Args: system dependent * + * Returns: system dependent */ +char fsetup(); + +/* Set File Name - System Specific * + * Args: system dependent * + * Returns: system dependent */ +char fsname(); + +/* Load File - System Specific * + * Args: system dependent * + * Returns: system dependent */ +char fsload(); + +/* Save File - System Specific * + * Args: system dependent * + * Returns: system dependent */ +char fssave(); + +/* Open File - System Specific * + * Args: system dependent * + * Returns: system dependent */ +char fsopen(); + +/* Open File * + * Opens File Specified by Name * + * Args: m - mode * + * &f - string containing filename * + * Returns: file pointer if successful * + 0 if an error occurs */ +char fopen(); + +/* Close File * + * Closes File Opened to File Pointer * + * Args: fp - file pointer * +* Returns: 0 if successful * + 255 if an error occurred */ +char fclose(); + +/* End of File * + * Check for End of File Condition * + * Args: fp - file pointer * +* Returns: 0 if not at end of file * + 255 if end of file reached */ +char feof(); + +/* File Error * + * Check File Error Indicator * + * Args: fp - file pointer * +* Returns: system dependent error number * + 0 if no error */ +char ferror(); + +/* Flush File Buffer * + * Flush File Output Buffer * + * Args: fp - file pointer * + * Returns: system dependent error number * + 0 if no error */ +char fflush(); + +/* Read Character from File * + * Args: fp - file pointer * + * Returns: ASCII value of character * + * system dependent garbage * + character if past end of file */ +char fgetc(); + +/* Write Character to File * + * Args: fp - file pointer * + * c - ASCII character to write * + * Returns: ASCII value of character */ +char fputc(); + +/* Read String from File * + * Buffers up to 128 characters * + * until C/R is pressed * + * Args: fp - file pointer * + * &s - string read from file * + * Returns: length of string * + * 255 if error during write */ +char fgets(); + +/* Write String to File * + * Writes up to 128 characters of a * + * null terminated string * + * Args: fp - file pointer * + * &s - string to print from * + * Returns: ending position in string * + * 255 if error during write */ +char fputs(); + +/* Write Line to File * + * Write String to File followed by C/R * + * Args: fp - file pointer * + * &s - string to print from * + * Returns: ending position in string * + * 255 if error during write */ +char fputln(); + +/* Sets Array for fread() and fwrite() * + * Args: &s - Destination string */ +void fsdst(); + +/* Read Bytes from File * + * Reads until EOF is reached * + * Args: fp - file pointer * + * n - number of bytes to read * + * Returns: number of bytes read */ +char fread(); + +/* Write Bytes to File * + * Args: fp - file pointer * + * n - number of bytes to write * + * Returns: number of bytes written */ +char fwrite(); diff --git a/include/hdr.a02 b/include/hdr.a02 new file mode 100644 index 0000000..435de20 --- /dev/null +++ b/include/hdr.a02 @@ -0,0 +1,7 @@ +; Minimal Assembly Language Header for C02 + ORG $0200 ;Program Start Address + +START: JMP MAIN ;Execute Program + +EXIT: BRK ;Usually BRK if returning to Monitor + diff --git a/include/header.a02 b/include/header.a02 new file mode 100644 index 0000000..e8492ed --- /dev/null +++ b/include/header.a02 @@ -0,0 +1,111 @@ +; Program initialization code for C02 programs +; Template for System Specific Code + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key ($08=Backspace, $7F=Delete) +ESCKEY EQU $1B ;Escape/Stop Key ($03=Ctrl-C, $1B=Escape) +RTNKEY EQU $0D ;Return/Enter Key ($0D=Carriage Return) +NULKEY EQU $00 ;No Key was Pressed ($00=Null) + +;Zero Page Locations +SRCLO EQU $00 ;Source String Pointer (stdio.asm) +SRCHI EQU $01 +DSTLO EQU $02 ;Destination String Pointer (string.asm) +DSTHI EQU $03 + +STKSAV EQU $0D ;Stack Pointer Storage +RDSEED EQU $0E ;Pseudo-RANDOM Seed +RANDOM EQU $0F ;Pseudo-RANDOM Number Storage +TEMP0 EQU $10 ;Temporary Storage +TEMP1 EQU $11 +TEMP2 EQU $12 + +BLKSLO EQU $20 ;Block Start Address +BLKSHI EQU $21 +BLKELO EQU $22 ;Block End Address +BLKEHI EQU $23 + + ORG $0200 ;Program Start Address + +START: NOP ;System specific initialization code + TXS ;If an RTS is used to return to the Operating System, + STX STKSAV ; the Stack Pointer should be preserved + JMP MAIN ;Execute Program + +;Poll Character from Keyboard +PLKEY: INC RDSEED ;Cycle the Random Seed (if not provided by system) + NOP ;Code Read from Keyboad + RTS + +;Read Character from Console +GETKEY; ;Usually Drops into RDKEY, but may need to call RDKEY + ; then clean/convert returned value (e.g. Apple-1) + +;Wait for Character from Console +RDKEY: JSR PLKEY ;Usually calls PLKEY + BEQ RDKEY ; until a non-zero is returned + RTS + +;Delete Previous Character +DELCHR: RTS ;Code to move Cursor to left and clear that position + ;May work differently on systems that don't support this + +;Advance Cursor to Next line +NEWLIN: RTS ;Code to move Cursor to beginning of next line + ;May emit Carriage Return, Line Feed, or both + +;Print Character to Screen +PRCHR: RTS ;Code to write ASCII character to Screen + +;Exit Program and Return to Operating System or Monitor +EXIT: BRK ;Usually BRK if returning to Monitor + LDX STKSAV ;If an RTS is used to return to the Operating System, + TXS ; the Stack Pointer should be restored to original state + RTS ; in case program exits in the middle of a Function + +;Note: The following two functions replicate calls available +;in the Apple-1 monitor and are included for test purposes +;They will likely be removed before the final release + +;Print Byte as Two-Digit Hex Number to Console +PRBYTE: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR PRHEX ; and Print it + PLA ;Restore Accumulator + ; and fall into PRHEX + +;Print Low Nybble as Hex Digit to Console +PRHEX: AND #$0F ;Strip High Nybb + SED ;Set Decimal Flag for + CLC ; Addition Wizardry + ADC #$90 ;Convert to $90-$99,$00-$05 + ADC #$40 ;Convert to $30-$39,$41-$46 + CLD ;Clear Decimal Flag + JMP PRCHR ;Print Hex Digit and Return + +;Alternate Code for Systems with Interrupts that don't CLD +PRHEX: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC PRHEXC ; + ADC #$06 ; Convert ':' to 'A'... +PRHEXC: ADC #$30 ;Convert to ASCII Character + JMP PRCHR ;Print Hex Digit and Return + + +;Functions to set String Pointers +;Used by memory, stdio, stdlin, string, and stringx libraries + +;Initialize Destination String Pointer and Index +SETDST: STX DSTLO ;Save Destination String Pointer + STY DSTHI + RTS + +;Initialize Source String Pointer and Index +SETSRC: STX SRCLO ;Save Source String Pointer + STY SRCHI + LDY #$00 ;Initialize Index Into String + RTS + diff --git a/include/header.h02 b/include/header.h02 new file mode 100644 index 0000000..773bc1c --- /dev/null +++ b/include/header.h02 @@ -0,0 +1,37 @@ +/* System Specific C02 Header File Template */ + +/* This header contains standardized Constants, * + * Variables, and Function Calls tailored to a * + * a specific platform. */ + +/* System Specific ASCII Key Codes */ +const DELKEY; //Delete/Backspace Key +const ESCKEY; //Escape/Stop Key +const RTNKEY; //Return/Enter Key +const NULKEY //No Key was Pressed + +/* Zero Page Variables used as Pointers */ +char strlo,strhi; //String pointer for String and I/O functions +char dstlo,dsthi; //Secondary string pointer for String functions + +/* Ephemeral Library Variables * + * Available for use in program code, but may * + * be obliterated by Function Calls. * + * May be Zero Page, but not required */ +char temp0,temp1; //Temporary variables + +/* Static Library Variables * + * Must be preserved between function calls * + * May be Zero Page, but not required */ +char random; //Last Result of Pseudo-Random Number Generator +char rdseed; //System Seed for Pseudo-Random Number Generator + +//System Subroutines +char plkey(); //Poll Console for character +char rdkey(); //Wait for character from Console +char getkey(); //Read ASCII character from Console +void newlin(); //Advance cursor to beginning of next line +void prchr(); //Print ASCII character to Console +void prbyte(); //Print Accumulator as Hexadadecimal number +void prhex(); //Print Low Nybble of Accumulator as Hex Digit + diff --git a/include/kernal.a02 b/include/kernal.a02 new file mode 100644 index 0000000..19907b0 --- /dev/null +++ b/include/kernal.a02 @@ -0,0 +1,42 @@ +;acptr() - Get data from the serial bus +;Returns: A = Received Character +;Preparatory routines: TALK, TKSA +;Error returns: See READST +;Stack requirements: 13 +;Registers affected: A, X +ACPTR = $FFA5 ;Alias to ACPTR Routine + +;chkin(lfn) - Open a channel for input +;Arguments: A = Logical File Number +; Preparatory routines: (OPEN) +; Error returns: +; Stack requirements: None +; Registers affected: A, X +CHKIN: TAX ;Transfer Channel# to Accumulator + JMP $FFC6 ;Execute CHKIN Routine + +;chkout(lfn) - Open a channel for output +;Arguments: A = Logical File Number +; Preparatory routines: (OPEN) +; Error returns: 0,3,5,7 (See READST) +; Stack requirements: 4+ +; Registers affected: A, X +CHKOUT: TAX ;Transfer Channel# to Accumulator + JMP $FFC9 ;Execute CHKOU7T Routine + +;chrin() - Get a character from the input channel +;Returns: A = Byte Received +; Preparatory routines: (OPEN, CHKIN) +; Error returns: 0 (See READST) +; Stack requirements: 7+ +; Registers affected: A, X +CHRIN = $FFCF ;Alias to CHRIN Routine + +;chrout(chr) - Output a character +;Arguments: A = Character to Send +; Preparatory routines: (CHKOUT,OPEN) +; Error returns: 0 (See READST) +; Stack requirements: 8+ +; Registers affected: A +CHRIN = $FFD2 ;Alias to CHROUT Routine + diff --git a/include/kernal.h02 b/include/kernal.h02 new file mode 100644 index 0000000..1043c2b --- /dev/null +++ b/include/kernal.h02 @@ -0,0 +1,45 @@ +/* CBM Kernal Header File */ + +//Zero Page Variables + +//Kernal Routines I/O +char acptr(); //Input byte from serial port +void chkin(); //Open channel for input +void chkout(); //Open channel for output +char chrin(); //Input Character to Channel +void chrout(); //Output Character to Channel +ciout(); //Output byte to serial port +cint(); //Initialize screen editor +clall(); //Initialize screen editor +close(); //Close a specified logical file +clrchn(); //Close input and output channels +char getin(); //Read Character from Keyboard Buffer +iobase(); //Return base address of I/O devices +ioinit(); //Initialize input/output +listen(); //Command devices on the serial bus to LISTEN +load(); //Load RAM from a device +membot(); //Read/set the bottom of memory +memtop(); //Read/set the top of memory +open(); //Open a logical file +plot(); //Read/set X,Y cursor position +ramtas(); //Initialize RAM, allocate tape buffer, set screen +rdtim(); //Read real time clock +readst(); //Read I/O Status Word +restor(); //Restore default I/O vectors +save(); //Save RAM to device +scnkey(); //Scan keyboard +screen(); //Return X,Y organization of screen +second(); //Send secondary address after LISTEN +setlfs(); //Set logical, first, and second addresses +setmsg(); //Control KERNAL messages +setnam(); //Set file name +settim(); //Set real time clock +settmo(); //Set timeout on serial bus +stop(); //Scan stop key +talk(); //Command serial bus device to TALK +tksa(); //Send secondary address after TALK +udtim(); //Increment real time clock +unlsn(); //Command serial bus to UNLISTEN +untlk(); //Command serial bus to UNTALK +vector(); //Read/set vectored I/O + diff --git a/include/memory.a02 b/include/memory.a02 new file mode 100644 index 0000000..fa67040 --- /dev/null +++ b/include/memory.a02 @@ -0,0 +1,123 @@ +; C02 library memory.h02 assembly language subroutines +; Requires external routines SETSRC and SETDST +; Requires the following RAM locations be defined +; external zero page byte pairs SRCLO,SRCHI and DSTLO,DSTHI +; and external bytes TEMP0 and TEMP1 + +;memchr(c, n) - Find Character in Destination Array +;Args: A = Character to look for +; Y = Number of Elements to Search +;Uses: DSTLO,DSTHI = Pointer to Destination Array +;Sets: TEMP1 = Character being searched for +; TEMP0 = Number of bytes +;Affects: N,Z +;Returns: A = Position in Array, C=1 if found +; A = $FF, C=0 if not found +; Y = Position of last character scanned +MEMCHR: STA TEMP1 ;Save Search Character + STY TEMP0 ;Save Count + BEQ MEMCLC ;If 0, Return Not Found + LDY #$00 ;Initialize Index +MEMCHL: LDA (DSTLO),Y ;Get Next Character + CMP TEMP1 ;Compare Character + BEQ MEMCLX ;If Found, Return Index + INY ;Increment Counter + CPY TEMP0 ;If < Count, Loop + BCC MEMCHL ;Else +MEMCLC: CLC ;Clear Carry + LDA #$FF ;Load -1 into Accumulater + RTS ;and Return +MEMCLX: TYA ;Return Index into String + RTS + +;memdst(&r) - Set Destination Array +; Called before strcat(), memcmp(), memcpy(), strstr() +;Args: X,Y = Pointer to destination Array +;Sets: DSTLO,DSTHI = Pointer to destination Array +;Affects: N,Z +MEMDST EQU SETDST ;Aliased to System Header function + +;Set Source Address and Number of Characters +;Args: X,Y = Pointer to Source Array +;Sets: DSTLO,DSTHI = Pointer to destination Array +; TEMP0 - Number of Characters +;Affects: A,N,Z +MEMSRC: JSR SETSRC ;Initialize Source Array and Index +MEMSRA: STA TEMP0 ;Store Number Of Character + ORA #0 ;If Number of Characters + BNE MEMSRX ; Equals 0 + PLA ; Pull Return Address off Stack + PLA ; Aborting Calling Routine +MEMSRX: RTS ;Return + +;memcmp(n, &r) - Compare Array (to Destination Array) +;Requires: DSTLO, DSTHI - Pointer to destination Array +;Args: A = Number of Bytes to Compare +; X,Y = Pointer to source Array +;Sets: TEMP0 = Number of Bytes to Compare +;Affects N +;Returns A=$01 and C=1 if Destination > Source +; A=$00 and Z=1 if Destination = Source +; A=$FF and C=0 if Destination < Source +; Y=Position of first character that differs +MEMCMP: JSR MEMSRC ;Initialize Source, Index, and Count +MEMCML: LDA (DSTLO),Y ;Load Destination Character + CMP (SRCLO),Y ;Compare Against Source Character + BNE MEMCMX ;If Equal + INY ; Increment Offset + CPY TEMP0 ; If < Count + BCC MEMCML ; Loop +MEMCMZ: LDA #$00 ; Else + RTS ; Return 0 +MEMCMX: BCC MEMCLC ;If Source < Destination Return -1 + LDA #$01 ;Else Return 1 +MEMCMR: RTS ; + +;memcpy(n, &r) - Copy Array (to Destination Array) +;Requires: DSTLO, DSTHI - Pointer to destination Array +;Args: A = Number of bytes to copy +; X,Y = Pointer to source Array +;Sets: TEMP0 = Number of bytes to copy +;Affects: A,Y,C,N,Z +MEMCPY: JSR MEMSRC ;Initialize Source, Index, and Count +MEMCPL: LDA (SRCLO),Y ;Get Character from Source Array + STA (DSTLO),Y ;Copy to Destination Array + INY ; Increment Index + CPY TEMP0 ;If < Count + BCC MEMCPL ; Loop + RTS ;Else Return + +;memset(c, n) - Fill Destination Array +;Args: A = Character to fill with +; Y = Number of bytes to fill +;Uses: DSTLO,DSTHI = Pointer to Destination Array +;Sets: TEMP0 = Number of bytes +;Affects: N,Z +MEMSET: STY TEMP0 ;Save Count + CPY #0 ;If 0 + BEQ MEMSEX ; Return + LDY #$00 ;Initialize Index +MEMSEL: STA (DSTLO),Y ;Store Character at Index + INY ;Increment Counter + CPY TEMP0 ;If < Count, Loop + BCC MEMSEL ;Else +MEMSEX: RTS + +;memswp(n, &r) - Swap Array (with Destination Array) +;Requires: DSTLO, DSTHI - Pointer to destination Array +;Args: A = Number of bytes to swap +; X,Y = Pointer to source array +;Sets: TEMP0 = Number of bytes to swap +;Affects: A,X,Y,C,N,Z +MEMSWP: JSR MEMSRC ;Initialize Source, Index, and Count +MEMSWL: lDA (DSTLO),Y ;Get Character from Destination Array + TAX ;Save in X Register + LDA (SRCLO),Y ;Get Character from Source Array + STA (DSTLO),Y ;Copy to Destination Array + TXA ;Restore Saved Character + STA (SRCLO),Y ;Copy to Source Array + INY ; Increment Index + CPY TEMP0 ;If < Count + BCC MEMSWL ; Loop + RTS ;Else Return + diff --git a/include/memory.h02 b/include/memory.h02 new file mode 100644 index 0000000..18444c2 --- /dev/null +++ b/include/memory.h02 @@ -0,0 +1,39 @@ +/********************************************* + * memory - Array Handling Routines for C02 * + *********************************************/ + +/* Sets Destination Array for subsequent function calls * + * Args: &s - Destination string */ +void memdst(); + +/* Find Character in Destination Array * + * Args: c - Character to find * + * n - Number of bytes to search * + * Uses: Destination array specified by memdst() * + * Returns: Position of c in s * + * $FF if not found */ +char memchr(); + +/* Compare Destination Array against Source Array * + * Args: n - Number of bytes to compare * + * &s - Source array * + * Uses: Destination array specified by memdst() * + * Returns: Result of comparison * + * -1 = Destination < Source * + * 0 = Destination = Source * + * 1 = Destination > Source */ +char memcmp(); + +/* Copy Source Array to Destination Array * + * Args: n - Number of bytes to copy * + * &s - Source string * + * Sets: Destination string specified by memdst() */ +char memcpy(); + +/* Fill Destination Array with Character * + * Args: c - Character to fill array with * + * n - Number of bytes to fill * + * Uses: Destination array specified by memdst() * + * Returns: Number of characters copied */ +char memset(); + diff --git a/include/notes.txt b/include/notes.txt new file mode 100644 index 0000000..634c506 --- /dev/null +++ b/include/notes.txt @@ -0,0 +1,6 @@ +Library Compiled Code Size: +ctype.asm 181 bytes +stdio.asm 83 bytes +stdlib,asm 191 bytes +string.asm 162 bytes + diff --git a/include/old/c64.asm b/include/old/c64.asm new file mode 100644 index 0000000..82674ad --- /dev/null +++ b/include/old/c64.asm @@ -0,0 +1,293 @@ +; c02 Program Initialization Code for Unexpanded VIC-20 + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +; EQU $00 ;USR JMP +adray1 EQU $03 ;Vector: Convert Floating Point to Signed Integer +adray2 EQU $05 ;Vector: Convert Integet to Floating Point +charac EQU $07 ;Search Character for Scanning BASIC Text Input +endchr EQU $08 ;Search Character for Statement Terminator or Quote +trmpos EQU $09 ;Column Position of Cursor before Last SPC or TAB +verckb EQU $0A ;Flag: Load or Verify (BASIC) +count EQU $0B ;Index into Text Input Buffer/Number of Array Subscripts +dimflg EQU $0C ;Flags for Routines that Locate or Build an Array +valtyp EQU $0D ;Type of Data (String or Numeric) +intflg EQU $0E ;Type of Numeric Data (Integer or Floating Point) +garbfl EQU $0F ;Flag for LIST, Garbage Collection, and Program Terminators +subflg EQU $10 ;Subscript Reference to Array or User Defined Function Call +inpflg EQU $11 ;Is Data Input to GET, READ, or INPUT? +tansgn EQU $12 ;Sign of Result of TAN or SIN Function +channl EQU $13 ;Current I/O Channel (CMD Logical File) Number +linnum EQU $14 ;Integer Line Number Value +temppt EQU $16 ;Pointer to Next Availabale Space in Temporary String Stack +lastpt EQU $17 ;Pointer to Address of Last String in Temporary String Stack +tempst EQU $19 ;Descriptor Stack for Temporary Strings +index EQU $22 ;Miscellaneous Temporary Pointers and Save Area +; $24 +resho EQU $26 ;Floating Point Multiplication Work Area +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +frespc EQU $35 ;Temporary Pointer for Strings +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +curlin EQU $39 ;Current BASIC Line Number +oldlin EQU $3B ;Previous BASIC Line Number +oldtxt EQU $3D ;Pointer to Address of Current BASIC Statement +datlin EQU $3F ;Current DATA Line Number +datptr EQU $41 ;Pointer to Address of Current DATA Item +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +varnam EQU $45 ;Current Variable Name +varpnt EQU $47 ;Pointer to Current BASIC Variable Value +forpnt EQU $49 ;Temporary Pointer to Index Variable Used by FOR +opptr EQU $4B ;Math Operator Table Displacement +opmask EQU $4D ;Mask for Comparison Operator +defpnt EQU $4E ;Pointer to Current FN Descriptor +dscpnt EQU $50 ;Temporary Pointer to Current String Descriptor +; $52 ;current string length +four6 EQU $53 ;Constant for Garbage Collection +jmper EQU $54 ;Jump to Function Instruction +; $57 ;BASIC Numeric Work Area +fac1 EQU $61 ;Floating Point Accumulator #1 +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +sgnflg EQU $67 ;Number of Terms in Series Evaluation +bits EQU $68 ;Floating Point Accumulator #1: Overflow Digit +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +facov EQU $70 ;Low Order Mantissa Byte of Floating Point Accumulator #1 +fbufpt EQU $71 ;Series Evaluation Pointer +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +rndx EQU $8B ;RND Function Seed Value +status EQU $90 ;Kernal I/O Status Word +stkey EQU $91 ;Flag: Was STOP Key Pressed +svxt EQU $92 ;Timing Constant for Tape Reads +verck EQU $93 ;Flag: Load or Verify (Kernal) +c3po EQU $94 ;Flag: Serial Bus - Output Character was Buffered +bsour EQU $95 ;Buffered Character for Serial Bus +syno EQU $96 ;Cassette Block Synchronization Number +xsav EQU $97 ;Temporary .X Register Save Area +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +prty EQU $9B ;Tape Character Parity +dpsw EQU $9C ;Flag: Tape Byte Received +msflg EQU $9D ;Flag: Kernal Message Control +ptr1 EQU $9E ;Tape Pass 1 Error Log Index +ptr2 EQU $9F ;Tape Pass 2 Error Log Correction Index +time EQU $A0 ;Software Jiffy Clock +; EQU $A3 ;Temporary Data Storage Area +cntdn EQU $A5 ;Cassette Synchronization Character Countdown +bufpnt EQU $A6 ;Count of Characters in Tape I/O Buffer +inbit EQU $A7 ;RS-232 Input Bits/Tape I/O Miscellaneous Flag +bitci EQU $A8 ;RS-232 Input Bit Count/Tape Error Flag +rinone EQU $A9 ;RS-232 Flag: Check for Start Bit/Tape Character Type Flag +ridata EQU $AA ;RS-232 Input Byte Buffer +riprty EQU $AB ;RS-232 Input Parity/Cassette Leader Counter +sal EQU $AC ;Pointer to Starting Address of Load/Screen Scrolling +eal EQU $AE ;Pointer to Ending Address of Load (End of Program) +cmp0 EQU $B0 ;Used to Determine Value of SVXT +; EQU $B1 ;Used in Timing of Tape Reads +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +bitts EQU $B4 ;RS-232 Output Bit Count/Tape Load Receive Flag +nxtbit EQU $B5 ;RS-232 Next Bit to Send/Tape EOT Flag +rodata EQU $B6 ;RS-232 Output Byte Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +roprt EQU $BD ;RS-232 Output Parity/Tape Character Being Read or Sent +fsblk EQU $BE ;Cassette Read/Write Block Count +mych EQU $BF ;Tape Input Byte Buffer +cas1 EQU $C0 ;Tape Motor Interlock +stal EQU $C1 ;I/O Start Address +memuss EQU $C3 ;Tape Load Temporary Address +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +indx EQU $C8 ;Pointer: End of Logical Line for Input +lxsp EQU $C9 ;Cursor X.Y Position at Start of Input +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +blnsw EQU $CC ;Cursor Blink Enable +blnct EQU $CD ;Timer Countdown to Blink Cursor +gdbln EQU $CE ;Character Under Cursor +blnon EQU $CF ;Flag: Was Last Cursor Blink On or Off +crsw EQU $D0 ;Flag: Input from Keyboard or Screen +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +qtsw EQU $D4 ;Flag: Editor in Quote Mode? +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +; EQU $D7 ;Temporary Storage for ASCII Value of Last Character Printed +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +user EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +keytab EQU $F5 ;Vector: Keyboard Decode Table +ribuf EQU $F7 ;Pointer: RS-232 Input Buffer +robuf EQU $F8 ;Pointer: RS-232 Output Buffer +frekzp EQU $FB ;Four Free Bytes of Zero Page for User Programs +baszpt EQU $FF ;BASIC Temporary Data for Floating Point to ASCII Conversion + +;Page 1 Locations +bad EQU $0100 ;Tape Input Error Log +; EQU $013F ;Microprocessor Stack + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +timout EQU $0285 ;Flag: Kernal Variable for IEEE Timeout +color EQU $0286 ;Current Foreground Color Text +gdcol EQU $0287 ;Color of Character Under Cursor +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +delay EQU $028C ;Counter for Timing Delay Until First Key Repeat Begins +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +lstshf EQU $028E ;Last Pattern SHIFT/CTRL/Logo Keypress +keylog EQU $028F ;Vector to Keyboard Table Setup Routine +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress +autodn EQU $0292 ;Flag: Screen Scroll Enabled +m51ctr EQU $0293 ;RS-232: Mock 6551 Control Register +m51cdr EQU $0294 ;RS-232: Mock 6551 Command Register +m51adj EQU $0295 ;RS-232: Non-Standard Bit Timing (Not Implemented) +rsstat EQU $0297 ;RS-232: Mock 6551 Status Register +bitnum EQU $0298 ;RS-232: Number of Bits Left to be Sent/Received +baudof EQU $0299 ;RS-232: Time Required to Send a Bit +ridbe EQU $029B ;RS-232: Index to End of Receive Buffer +ridbs EQU $029C ;RS-232: Index to Start of Receive Buffer +rodbs EQU $029D ;RS-232: Index to Start of Transmit Buffer +rodbe EQU $029E ;RS-232: Index to End of Transmit Buffer +irqtmp EQU $029F ;Save Area for IRQ Vector During Cassette I/O +enabl EQU $02A1 ;RS-232 Interrupts Enabled +; EQU $02A2 ;CIA #1 Control Register B Activity During Cassette I/O +; EQU $02A3 ;Save Area for CIA #1 Interrupt Control Register +; EQU $02A4 ;Save Area for CIA #1 Control Register A +; EQU $02A5 ;Temporary Index to Next Line for Screen Scrolling +; EQU $02A6 ;PAL/NTSC Flag +; EQU $02A7 ;Unused +; EQU $02C0 ;Sprite 11 + +;BASIC Indirect Vector Table +ierror EQU $0300 ;Vector to Print BASIC Error Message Routine +imain EQU $0302 ;Vector to Main BASIC Program Loop +icrnch EQU $0304 ;Vector to Crunch ASCII Keyword into Tokens +iqplop EQU $0306 ;Vector to List BASIC Token as ASCII Text +igone EQU $0308 ;Vector to Execute Next BASIC Token +ieval EQU $030A ;Vector to Evaluate Single-Term Arithmetic Expression + +;Register Storage Area +sareg EQU $030C ;Storage Area for .A Register (Accumulator) +sxreg EQU $030D ;Storage Area for .X Index Register +syreg EQU $030E ;Storage Area for .Y Index Register +spreg EQU $030F ;Storage Area for .P (Status) Register + +;Miscellaneous Vectors +usrpok EQU $0310 ;JMP Instruction for User Function +usradd EQU $0311 ;Address of USR Routine +; EQU $0313 ;Unused +cinv EQU $0314 ;Vector to IRQ Interrupt Routine +cbinv EQU $0316 ;Vector: BRK Instruction Interrupt +nminv EQU $0318 ;Vector: Non-Maskabke Interrupt + +;Kernal Indirect Vectors +iopen EQU $031A ;Vector to Kernal OPEN Routine +iclose EQU $031C ;Vector to Kernal CLOSE Routine +ichkin EQU $031E ;Vector to Kernal CHKIN Routine +ickout EQU $0320 ;Vector to Kernal CKOUT Routine +iclrch EQU $0322 ;Vector to Kernal CLRCHN Routine +ibasin EQU $0324 ;Vector to Kernal CHRIN Routine +ibsout EQU $0326 ;Vector to Kernal CHROUT Routine +istop EQU $0328 ;Vector to Kernal STOP Routine +igetin EQU $032A ;Vector to Kernal GETIN Routine +iclall EQU $032C ;Vector to Kernal CLALL Routine +usrcmd EQU $032E ;Vector to User Defined Command (Unused) +iload EQU $0330 ;Vector to Kernal LOAD Routine +isave EQU $0332 ;Vector to Kernal SAVE Routine + +; $0334 ;Unused +tbuffer EQU $033C ;Cassette I/O Buffer +; $03FC ;Unused + +vicscn EQU $0400 ;Video Screen Memory Area +; $07F8 ;Sprite Shape Data Pointers +; $0800 ;BASIC Program Text +; $8000 ;Autostart ROM Cartridge + +vicclr EQU $D800 ;Color RAM + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start Directly Above Stack +basic: DC $0C, $10 ; Pointer to Next Line (4109) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + + JMP main ;Execute Program + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Read Character from Console + + +;Wait for Character from Console +getkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/old/ctype.asm b/include/old/ctype.asm new file mode 100644 index 0000000..01be9ea --- /dev/null +++ b/include/old/ctype.asm @@ -0,0 +1,114 @@ +;ctype.h02 assembly language subroutines +; +;C02 Functions modify Accumulator and Flags +; isxxxx will load $FF into Accumulator to and Set Carry if True +; and load $00 into Accumulator to and clear Carry if False +; toxxxx set Carry if character is converted, otherwise clear Carry +;Machine Language Subroutines modify Flags but not Accumulator +; Carry will be Set if True and Cleared if False +;Index Registers are not modified by any routines + +;Character Test Functions - Set Accumulator +isalnm: JSR isaln ;Is Alphanumeric Character + BVC isbtf +isalph: JSR isalp; ;Is Alphabetic Character + BVC isbtf +isctrl: JSR isctl ;Is Control Character + BVC isbtf +isdigt: JSR isdgt ;Is Digit + BVC isbtf +isgrph: JSR isgrp ;Is Graphical Character + BVC isbtf +ishdgt: JSR ishex ;Is Hex Digit + BVC isbtf +islowr: JSR islwr ;Is Lowercase Character + BVC isbtf +ispnct: JSR ispnc ;Is Punctuation Character + BVC isbtf +isprnt: JSR isprt ;Is Printable Character + BVC isbtf +isspce: JSR isspc ;Is White Space Character + BVC isbtf +isuppr: JSR isupr ;Is Uppercase Character + BVC isbtf + +;Internal Routines - Set Accumulator based on Carry Flag +isbtf: BCC isfls ;If Carry Set +istru: LDA #$FF ; Return TRUE + RTS ;Else +isfls: LDA #$00 ; Return FALSE + RTS + +;C02/ML Character Conversion Routines +tolowr: JSR isupr ;If Char is Not Upper Case + BCC isrts ; Return + ORA #$20 ;Else Set Bit 5 + RTS ; and Return + +touppr: JSR islwr ;If Char is Not Lower Case + BCC isrts ; Return + AND #$DF ;Else Clear Bit 5 + RTS ; and Return + +;Machine Language Subroutines - Set/Clear Carry, Preserve Accumulator +isaln: JSR isdgt ;If Char is Digit + BCS isrts ; Return Carry Set + ;Else +isalp: JSR isupr ;If Char is Upper Case + BCS isrts ; Return Carry Set + ;Else +islwr: CMP #$61 ;If Char < 'a' + BCC isrts ; Return with Carry Clear + CMP #$7B ;Else If Char >= '{' + JMP isbcs ; Return with Carry Clear Else Return with Carry Set + +isupr: CMP #$41 ;If Char < 'A' + BCC isrts ; Return with Carry Clear + CMP #$5B ;Else If Char >= '[' +isbcs: BCS isclc ; Return with Carry Clear + BCC issec ;Else Return with Carry Set + +issec: SEC ;Set Carry + BCS isrts ; and Return + +isclc: CLC ;Clear Carry +isrts: CLV ;Clear Overflow - for C02 calls + RTS ;Return from Subroutine + +isctl: CMP #$7F ;If Char = DEL + BEQ issec ; Return Carry Set + CMP #$20 ;Else If Char < ' ' + JMP isbcs ; Return Carry Set Else Return Carry Clear + +isdgt: CMP #$30 ;If Char < '0' + BCC isrts ; Return Carry Clear + CMP #$3A ;Else If Char >= ':' + JMP isbcs ; Return FALSE Else Return TRUE + +ispnc: JSR isaln ;If Char is Alphanumeric + BCS isclc ; Return Carry Clear + ;Else +isgrp: CMP #$20 ;If Char is Space + BEQ isclc ; Return Carry Clear + ;Else +isprt: CMP #$80 ;If Char is High ASCII + BCS isclc ; Return Carry Clear + JSR isctl ;If Char is Not Control + JMP isbcs ; Return Carry Clear Else Return Carry Set + +isspc: CMP #$20 ;If Char is ' ' + BEQ issec ; Return Carry Set + CMP #$09 ;If Char < '\t' + BCC isrts ; Return Carry Clear + CMP #$0E ;Else If Char > '\r' + JMP isbcs ; Return Carry Clear Else Return Carry Set + +ishex: CMP #$41 ;If Char < 'A' + BCC isdgt ; Check for Digit + CMP #$47 ;Else If Char < 'G' + BCC issec ; Return Carry Set + CMP #$61 ;Else If Char < 'a' + BCC isrts ; Return Carry Clear + CMP #$67 ;Else If Char >= 'g' + JMP isbcs ; Return Carry Clear Else Return Carry Set + diff --git a/include/old/ctype.h02 b/include/old/ctype.h02 new file mode 100644 index 0000000..f14bd30 --- /dev/null +++ b/include/old/ctype.h02 @@ -0,0 +1,80 @@ +/************************************** + * ctype - Character Typing Functions * + **************************************/ + +/* Check for Alphanumeric Character * + * (Alphabetic or Digit) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isalnm(); + +/* Checks for Alphabetic Character * + * (Upper Case or Lower Case) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isalph(); + +/* Checks for Control Character * + * (Less than Space or Delete) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isctrl(); + +/* Checks for Digit Character * + * (In range 0-9) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isdigt(); + +/* Checks for Graphical Character * + * (Printable except Space) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isgrph(); + +/* Checks for Hex Digit Character * + * (In range 0-9, A-F, or a-f) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte ishdgt(); + +/* Checks for Lower Case Character * + * (In range a-z) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte islowr(); + +/* Checks for Printable Character * + * (Not High ASCII nor Control) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isprnt(); + +/* Checks for Punctuation Character * + * (Printable not Alphanumeric) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte ispnct(); + +/* Checks for White Space Character * + * (Space, Tab, NL, VT, FF, CR) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isspce(); + +/* Checks for Upper Case Character * + * (In range A-Z) * + * Args: c - Character to Check * + * Returns: TRUE or FALSE */ +byte isuppr(); + +/* Convert Character to Lower Case * + * Args: c - Character to Convert * + * Returns: Converted Character */ +byte tolowr(); + +/* Convert Character to Upper Case * + * Args: c - Character to Convert * + * Returns: Converted Character */ +byte touppr(); + diff --git a/include/old/ctype.txt b/include/old/ctype.txt new file mode 100644 index 0000000..1c57f74 --- /dev/null +++ b/include/old/ctype.txt @@ -0,0 +1,114 @@ +Character Checking and Conversion Functions for C02 + +This library provides functions for classifying ASCII characters, as +well as converting upper-case characters to lower-case characters +and vice-versa. + +The character classification functions return a value of -1 ($FF) +for TRUE, and 0 for FALSE. All these functions return FALSE when +testing high ASCII characters (127 - 255) + + #include + +The following functions are defined: + + b = isalnm(c); Returns TRUE if c is alphanumeric, otherwise FALSE. + + An alphanumeric character is a letter (A-Z or a-z), + or a digit (0-9). + + Note: Calls internal routine isaln, which in turn + calls internal routines isdgt and isalp. + + b = isalph(c); Returns TRUE if c is alphabetic, otherwise FALSE. + + An alphabetic character is a letter (A-Z or a-z). + + Note: Call internal routine isalp, which in turn + calls internal routines isupr and islwr. + + b = isctrl(c); Returns TRUE if c is a control characte, otherwise FALSE. + + A control character is a character with ASCII code + 0 through 31 or 127. + + Note: Calls internal routine isctl. + + b = isdigt(c); Returns TRUE if c is a digit, otherwise FALSE. + + A digit is a character in the range 0 through 9. + + Note: Calls internal routine isdgt. + + b = isgrph(c); Returns TRUE if c is graphical, otherwise FALSE. + + A graphical character is any character in the + range ! through |. + + Note: Calls internal routine isgrp, which in turn + calls internal routine isprt. + + b = ishdgt(c); Returns TRUE if c is a hex digit, otherwise FALSE. + + A hex digit is a character in the range 0 through 9. + A through F, or a through f. + + Note: Calls internal routine ishex, which in turn + calls internal routine isdgt. + + b = islowr(c); Returns TRUE if c is lowercase, otherwise FALSE. + + An alphabetic character is a letter in the range + a through z. + + Note: Call internal routine islwr. + + b = ispnct(c); Returns TRUE if c is punctuation, otherwise FALSE. + + A punctuation character is any graphical character + that is not aplhapnumeric. + + Note: Calls internal routine ispnc, which in turn + calls internal routines isalp and isgrp. + + b = isprnt(c); Returns TRUE if c is printable, otherwise FALSE. + + A printable character is any character in the + range Space through |. + + Note: Calls internal routine isprt. + + b = isspce(c); Returns TRUE if c is white space, otherwise FALSE. + + The white space characters are Tab (9), Line Feed (10), + Vertical Tab (11), Form Feed (12), Carriage Return (13), + and Space (32). + + Note: Calls internal routine isspc. + + b = isuppr(c); Returns TRUE if c is upper case, otherwise FALSE. + + An uppercase character is a letter in the range + A through Z. + + Note: Call internal routine isupr. + + t = tolowr(c); Returns lower case version of c if it is an upper case + character, otherwise c. + + Note: Calls internal routine isupr. + + t = touppr(c); Returns upper case version of c if it is a lower case + character, otherwise c. + + Note: Calls internal routine islwr. + +Note: This library has no external dependencies. + +Implementation: The standard method of implementing the ctype library is to +use a bit mask table of 128 bytes (one for each standard ASCII character). + +This library instead uses a series of comparisons in the internal routines, +which leave the accumulator unmodified, and occupies approximately 128 bytes +of memory. + diff --git a/include/old/ctype1.asm b/include/old/ctype1.asm new file mode 100644 index 0000000..7440dd4 --- /dev/null +++ b/include/old/ctype1.asm @@ -0,0 +1,146 @@ + PROCESSOR 6502 + ORG $0200 +; ctype.h02 assembly language subroutines +; + + +isalnm: LDX #0 ;ALNUM + BPL ctype +isalph: LDX #1 ;ALPHA + BPL ctype +isctrl: LDX #2 ;CNTRL + BPL ctype +isdigt: LDX #3 ;DIGIT + BPL ctype +isgrph: LDX #4 ;GRAPH + BPL ctype +islowr: LDX #5 ;LOWER + BPL ctype +isprnt: LDX #6 ;PRINT + BPL ctype +ispnct: LDX #7 ;PUNCT + BPL ctype +isspce: LDX #8 ;SPACE + BPL ctype +isuppr: LDX #9 ;UPPER + BPL ctype +isxdgt: LDX #10 ;HXDGT + +ctype: TAY ;Save Character + AND #$80 ;If High Bit Set + BNE cflse ; Return False + LDA cchar,Y ;Get Character Bit Mask + AND cmask,X ;If it Matches Test Bit Mask + BNE ctrue ; Return True + +cflse: LDA #0 ;Return False + RTS + +ctrue: LDA #$FF ;Return True + RTS + +;Informational Only +;CNTRL EQU %00000001 ;Control Character +;SPACE EQU %00000010 ;White Space +;BLANK EQU %00000100 ;Blank +;PUNCT EQU %00001000 ;Punctuation +;DIGIT EQU %00010000 ;Decimal Digit +;HEXDC EQU %00100000 ;Hexadecimal Digit +;UPPER EQU %01000000 ;Upper Case +;LOWER EQU %10000000 ;Lower Case + +;Character Test Bit Masks +cmask: DB %11010000 ;ALNUM = DIGIT + UPPER + LOWER + DB %11000000 ;ALPHA = UPPER + LOWER + DB %00000001 ;CNRTL + DB %00010000 ;DIGIT + DB %11011000 ;GRAPH = PUNCT + DIGIT + UPPER + LOWER + DB %10000000 ;LOWER + DB %11011100 ;PRINT = BLANK + PUNCT + DIGIT + UPPER + LOWER + DB %00001000 ;PUNCT + DB %00000010 ;SPACE + DB %01000000 ;UPPER + DB %00110000 ;HXDGT = DIGIT + HEXDC + +;Character Set Bit Masks +cchar: DB %00000001 ;00 NUL CNTRL + DB %00000001 ;01 SOH CNTRL + DB %00000001 ;02 STX CNTRL + DB %00000001 ;03 ETX CNTRL + DB %00000001 ;04 EOT CNTRL + DB %00000001 ;05 ENQ CNTRL + DB %00000001 ;06 ACK CNTRL + DB %00000001 ;07 BEL CNTRL + DB %00000001 ;08 BS CNTRL + DB %00000011 ;09 HT CNRTL + SPACE + DB %00000011 ;0A LF CNRTL + SPACE + DB %00000011 ;0B VT CNRTL + SPACE + DB %00000011 ;0C FF CNRTL + SPACE + DB %00000011 ;0D CR CNRTL + SPACE + DB %00000001 ;0E SS CNRTL + DB %00000001 ;0F SI CNRTL + DB %00000001 ;10 DLE CNRTL + DB %00000001 ;11 DC1 CNRTL + DB %00000001 ;12 DC2 CNRTL + DB %00000001 ;13 DC3 CNRTL + DB %00000001 ;14 DC4 CNRTL + DB %00000001 ;15 NAK CNRTL + DB %00000001 ;16 SYN CNRTL + DB %00000001 ;17 ETB CNRTL + DB %00000001 ;18 CAN CNRTL + DB %00000001 ;19 EM CNRTL + DB %00000001 ;1A SUB CNRTL + DB %00000001 ;1B ESC CNRTL + DB %00000001 ;1C FS CNRTL + DB %00000001 ;1D GS CNRTL + DB %00000001 ;1E RS CNRTL + DB %00000001 ;1F US CNRTL + DB %00000110 ;20 SPC SPACE + BLANK + DB %00001000 ;21 ! PUNCT + DB %00001000 ;22 " PUNCT + DB %00001000 ;23 # PUNCT + DB %00001000 ;24 $ PUNCT + DB %00001000 ;25 % PUNCT + DB %00001000 ;26 & PUNCT + DB %00001000 ;27 ' PUNCT + DB %00001000 ;28 ( PUNCT + DB %00001000 ;29 ) PUNCT + DB %00001000 ;2A * PUNCT + DB %00001000 ;2B + PUNCT + DB %00001000 ;2C , PUNCT + DB %00001000 ;2D - PUNCT + DB %00001000 ;2E . PUNCT + DB %00001000 ;2F / PUNCT + DB %00110000 ;30 0 DIGIT + HEX + DB %00110000 ;31 1 DIGIT + HEX + DB %00110000 ;32 2 DIGIT + HEX + DB %00110000 ;33 3 DIGIT + HEX + DB %00110000 ;34 4 DIGIT + HEX + DB %00110000 ;35 5 DIGIT + HEX + DB %00110000 ;36 6 DIGIT + HEX + DB %00110000 ;37 7 DIGIT + HEX + DB %00110000 ;38 8 DIGIT + HEX + DB %00110000 ;39 9 DIGIT + HEX + DB %00001000 ;3A : PUNCT + DB %00001000 ;3B ; PUNCT + DB %00001000 ;3C < PUNCT + DB %00001000 ;3D = PUNCT + DB %00001000 ;3E > PUNCT + DB %00001000 ;3F ? PUNCT + + +;char tolwr(char c) - Convert to Lower Case +; sets Carry if if Converted +tolwr: JSR isupc ;If Char is Not Upper Case + BCC isrts ; Return + ORA $20 ;Else Set Bit 6 + RTS ; and Return + +;char toupr(char c) - Convert to Upper Case +; sets Carry if if Converted +toupr: JSR islwr ;If Char is Not Lower Case + BCC isrts ; Return + AND $DF ;Else Clear Bit 6 + RTS ; and Return + + diff --git a/include/old/ctypeV.asm b/include/old/ctypeV.asm new file mode 100644 index 0000000..54a1a1b --- /dev/null +++ b/include/old/ctypeV.asm @@ -0,0 +1,104 @@ + PROCESSOR 6502 + ORG $0200 +; ctype.h02 assembly language subroutines +; +; All calls replace Accumulator and set Flags +; Index Registers are not Modified +; isxxxx will load $FF into Accumulator to and Set Carry if True +; and load $00 into Accumulator to and clear Carry if False +; toxxxx set Carry if character is converted, otherwise clear Carry + +;Character Test Routines +isalnm: JSR isdigt ;If Char is Digit + BCS isrts ; Return TRUE + ;Else +isalph: JSR isuppr ;If Char is Upper Case + BCS isrts ; Return TRUE + ;Else +islowr: JSR islwc ;If Char is Lower Case + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return TRUE + +isuppr: JSR isupc ;If Char is Uppercase + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return TRUE + +isctrl: CLV ;Clear Overflow + CMP #$7F ;If Char = DEL + BEQ istru ; Return TRUE + CMP #$20 ;Else If Char < ' ' + BVC isbft ; Return TRUE Else Return FALSE +; BCC istru ; Return TRUE +; BCS isfls ;Else Return FALSE + +isdigt: CLV ;Clear Overflow + CMP #$30 ;If Char < '0' + BCC isfls ; Return FALSE + CMP #$3A ;Else If Char >= ':' + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return True + +ispnct: JSR isalnm ;If Char is Alphanumeric + BNE isfls ; Return FALSE + ;Else +isgrph: CMP #$20 ;If Char is Space + BEQ isfls ; Return FALSE + ;Else +isprnt: JSR isctrl ;If Char is Not Control + BVC isbft ; Return TRUE Else Return FALSE +; BCC istru ; Return TRUE +; BCS isfls ;Else Return FALSE + +isspc: CLV ;Clear Overflow + CMP #$20 ;If Char is ' ' + BEQ istru ; Return TRUE + CMP #$09 ;If Char < '\t' + BCC isfls ; Return TRUE + CMP #$0E ;Else If Char > '\r' + BVC isbft ; Return FALSE Else Return TRUE +; BCS isfls ; Return FALSE +; BCC istru ;Else Return TRUE + +isxdgt: JSR touppr ;Convert to Uppercase + CMP #$41 ;If Char < 'A' + BCC isdigt ; Check for Digit + CMP #$5B ;Else If Char >= 'G' +isbft: BCS isfls ; Return FALSE + ;Else +istru: LDA #$FF ;Return TRUE +issec: SEC ;Set Carry + RTS ;and Return + +isfls: LDA #$00 ;Return FALSE +isclc: CLC ;Clear Carry +isrts: RTS ;Return from Subroutine + +;Internal Test Routines - Do Not Change Accumulator +islwc: CLV ;Clear Overflow for Calling Routine + CMP #$61 ;If Char < 'a' + BCC isrts ; Return with Carry Clear + CMP #$7B ;Else If Char >= '{' + BCS isclc ; Return with Carry Clear + BCC issec ;Else Return with Carry Set + +isupc: CLV ;Clear Overflow for Calling Routine + CMP #$41 ;If Char < 'A' + BCC isrts ; Return with Carry Clear + CMP #$5B ;Else If Char >= '[' + BCS isclc ; Return with Carry Clear + BCC issec ;Else Return with Carry Set + +;Character Conversion Routines +tolowr: JSR isupc ;If Char is Not Upper Case + BCC isrts ; Return + ORA $20 ;Else Set Bit 6 + RTS ; and Return + +touppr: JSR islwc ;If Char is Not Lower Case + BCC isrts ; Return + AND $DF ;Else Clear Bit 6 + RTS ; and Return + diff --git a/include/old/file.a02 b/include/old/file.a02 new file mode 100644 index 0000000..0362f9c --- /dev/null +++ b/include/old/file.a02 @@ -0,0 +1,155 @@ +; Requires external routines SETSRC and SETDST +; Requires the following RAM locations be defined +; external zero page byte pairs SRCLO,SRCHI and DSTLO,DSTHI +; and external bytes TEMP0 and TEMP1 + +;fsetup(fn, fs, fd) - Set Parameters for fsopen() +;Args: A = Logical file number +; Y = Secondary address (255 for None) +; X = Device 0=Keyboard, 1=Cassette, 2=RS232, 3=Screen +; 4-7=Printers, 8-15=Disks, 31=All Devices +;Affects None +FSETUP EQU SETLFS ;Set up a logical file + +;fsname(n, &s) - Set Filename for Load, Open, Save +;Args: A = Length of filename string +; X,Y = Pointer to string containing filename +;Affects: A,X,Y +;Returns: A = 1,2,3,4,6,240 (see FERROR) + +;fsload(v, &a) - Load Memory from File +;Prereqs: fsetup(), fsname() +;Args: A = Mode 0=Load, 1=Verify +; Y,X = Address to Load File +;Stack: 9 +;Affects: A,X,Y +;Sets: STATUS = 0,4,5,8,9 (see FERROR) +FSLOAD EQU LOAD ;Load RAM from device + +;fssave(v, &a) - Save Memory to File +;Prereqs: fsdst fsetup(), fsname() +;Requires: DSTLO, DSTHI - Start Address +;Args: Y,X = End Address +;Stack: 9 +;Affects: A,X,Y +;Sets: STATUS = 0,4,5,8,9 (see FERROR) +FSSAVE: LDA #SRCLO ;Load Pointer to Start Address + JMP SAVE ;Save memory to device + +;fsopen() - Open +;Prereqs: fsetup(), fsname() +;Affects: A,X,Y +;Sets: STATUS = 1,2,3,4,6,240 (see FERROR) +STRCHR: JSR SETNAM ;Set file name + JMP OPEN ;Open File + +;fopen(n, &s) - Open File with Specified Name +;Not Implemented + +;fclose(fn) - Close File +;Args: A = Logical file number +;Returns: A = 0,240 (see FERROR) +FCLOSE EQU CLOSE ;Close a logical file + +;feof(fn) - Check for End of File +;Args: A = Logical file number +;Affects: A,X +;Returns: A = 0,240 (see FERROR) +FEOF: JSR READST ;Read status word + AND #$C0 ;$40=End of File, $80 End of Tape + BEQ FRTS ;If Not 0 +FERR: LDA #$FF ; Set Generic Error Condition +FRTS: RTS ;Return from Subroutine + +;ferror(fn) - Check for Error +;Args: A = Logical file number +;Affects: A,X +;Returns: A = Error Bit Mask +; Bit Cassette Read Serial Bus I/O Tape Load/Verify +; $01 Write Timeout +; $02 Read Timeout +; $04 Short Block Short Block +; $08 Long Block Long Block +; $10 Read Error Any Mismatch +; $20 Checksum Err Checksum Err +; $40 End of File EOI Line +; $80 End of Tape Device Not Present End of Tape +FERROR EQU READST ;Read status word + +;fflush() - Flush file buffer +; No-Op - Not Needed +FFLUSH: RTS + +;fgetc(fn) - Read character from file +;Args: A = Logical file number +;Stack: 9 +;Affects: A,X +;Returns: A = 0,240 (see FERROR) +FGETC: TAX ;Move logical file number to X register + JSR CHKIN ;Open channel for input + JSR CHRIN ;Get character from input channel + PHA ;Save read character + JSR CLRCHN ;Clear I/O channels + PLA ;Retrieve read Character + RTS + +;fputc(fn) - Write character from file +;Args: A = Logical file number +; Y = Character to Write +;Stack: 9 +;Affects: A,X +;Returns: A = 0,240 (see FERROR) +FPUTC: TAX ;Move logical file number to X register + JSR CHKOUT ;Open channel for input + TYA ;Move character to accumulator +FPUTCH: JSR CHROUT ;Output a character + JMP CLRCHN ;Clear I/O channels and return + +;fgets(fn, &s) - Read string from file +;Requires: DSTLO, DSTHI - Pointer to destination string +;Args: A = Logical file number +; Y,X = Pointer to String +;Stack: 9 +;Affects: X,Y +;Returns: A = Number of bytes read +FGETS: JSR SETDST ;Save string address & initialize pointer + TAX ;Move logical file number to X register + JSR CHKIN ;Open channel for input +FGETSL: JSR CHRIN ;Get character from input channel + PHA ;Save read character + JSR READST ;Read status word + BNE FGETSX ;If Not 0, Exit + PLA ;Retrieve read character + STA SRCLO,Y ;Store character in string + CMP $0D ;If Carriage Return + BEQ FGETSX ; Then Exit + INY ;Increment pointer + BPL FGETSL ;and loop if less than 128 +FGETSX: LDA #$00 ;Terminate String + STA (SRCLO),Y ; +FGETSY: JSR CLRCHN ;Clear I/O channels + TYA ;Return string length + RTS + +;fputs(fn, &s) - Write String to File +;Requires: DSTLO, DSTHI - Pointer to source string +;Args: A = Logical file number +; Y,X = Pointer to String +;Stack: 9 +;Affects: X,Y +;Returns: A = Number of bytes written +FPUTS: JSR SETDST ;Save string address & initialize pointer + TAX ;Move logical file number to X register + JSR CHKIN ;Open channel for input +FPUTSL: LDA SRCLO,Y ;Load next character + PHA ;Save write character + JSR CHROUT ;Write character to output channel + PLA ;Retrieve write character + CMP $0D ;If Carriage Return + BEQ FGETSY ; Then Exit + JSR READST ;Read status word + BNE FGETSY ;If Not 0, Exit + INY ;Increment pointer + BPL FPUTSL ;If less than 128 then loop + BMI FGESTY ;Else exit + diff --git a/include/old/header.asm b/include/old/header.asm new file mode 100644 index 0000000..cfbfb4f --- /dev/null +++ b/include/old/header.asm @@ -0,0 +1,89 @@ +; Program initialization code for C02 programs +; Template for System Specific Code + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key ($08=Backspace, $7F=Delete) +ESCKEY EQU $1B ;Escape/Stop Key ($03=Ctrl-C, $1B=Escape) +RTNKEY EQU $0D ;Return/Enter Key ($0D=Carriage Return) +NULKEY EQU $00 ;No Key was Pressed ($00=Null) + +;Zero Page Locations +strlo EQU $00 ;String Pointer (stdio.asm and string.asm) +strhi EQU $01 +strlo EQU $02 ;Source String Pointer (string.asm) +strhi EQU $04 + +rdseed EQU $0E ;Pseudo-Random Seed +random EQU $0F ;Pseudo-Random Number Storage +temp0 EQU $10 ;Temporary Storage +temp1 EQU $11 ; + + ORG $0200 ;Program Start Address + +start: NOP ;System specific initialization code + TXS ;If an RTS is used to return to the Operating System, + STX stksav ; the Stack Pointer should be preserved + JMP main ;Execute Program + +;Read Character from Console +getkey; ;Usually Drops into rdkey, but may need to call rdkey + ; then clean/convert returned value (e.g. Apple-1) + +;Poll Character from Keyboard +plkey: INC rdseed ;Cycle the Random Seed (if not provided by system) + NOP ;Code Read from Keyboad + RTS + +;Wait for Character from Console +rdkey: JSR plkey ;Usually calls plkey + BEQ rdkey ; until a non-zero is returned + RTS + +;Delete Previous Character +delchr: RTS ;Code to move Cursor to left and clear that position + ;May work differently on systems that don't support this + +;Advance Cursor to Next line +newlin: RTS ;Code to move Cursor to beginning of next line + ;May emit Carriage Return, Line Feed, or both + +;Print Character to Screen +prchr: RTS ;Code to write ASCII character to Screen + +;Exit Program and Return to Operating System or Monitor +exit: BRK ;Usually BRK if returning to Monitor + LDX stksav ;If an RTS is used to return to the Operating System, + TXS ; the Stack Pointer should be restored to original state + RTS ; in case program exits in the middle of a Function + +;Note: The following two functions replicate calls available +;in the Apple-1 monitor and are included for test purposes +;They will likely be removed before the final release + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybb + SED ;Set Decimal Flag for + CLC ; Addition Wizardry + ADC #$90 ;Convert to $90-$99,$00-$05 + ADC #$40 ;Convert to $30-$39,$41-$46 + CLD ;Clear Decimal Flag + JMP prchr ;Print Hex Digit and Return + +;Alternate Code for Systems with Interrupts that don't CLD +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + diff --git a/include/old/header.h02 b/include/old/header.h02 new file mode 100644 index 0000000..4161a97 --- /dev/null +++ b/include/old/header.h02 @@ -0,0 +1,37 @@ +/* System Specific C02 Header File Template */ + +/* This header contains standardized Constants, * + * Variables, and Function Calls tailored to a * + * a specific platform. */ + +/* System Specific ASCII Key Codes */ +const DELKEY; //Delete/Backspace Key +const ESCKEY; //Escape/Stop Key +const RTNKEY; //Return/Enter Key +const NULKEY //No Key was Pressed + +/* Zero Page Variables used as Pointers */ +char strlo,strhi; //String pointer for String and I/O functions +char srclo,srchi; //Secondary string pointer for String functions + +/* Ephemeral Library Variables * + * Available for use in program code, but may * + * be obliterated by Function Calls. * + * May be Zero Page, but not required */ +char temp0,temp1; //Temporary variables + +/* Static Library Variables * + * Must be preserved between function calls * + * May be Zero Page, but not required */ +char random; //Last Result of Pseudo-Random Number Generator +char rdseed; //System Seed for Pseudo-Random Number Generator + +//System Subroutines +char plkey(); //Poll Console for character +char rdkey(); //Wait for character from Console +char getkey(); //Read ASCII character from Console +void newlin(); //Advance cursor to beginning of next line +void prchr(); //Print ASCII character to Console +void prbyte(); //Print Accumulator as Hexadadecimal number +void prhex(); //Print Low Nybble of Accumulator as Hex Digit + diff --git a/include/old/header.txt b/include/old/header.txt new file mode 100644 index 0000000..4766ba2 --- /dev/null +++ b/include/old/header.txt @@ -0,0 +1,101 @@ +System Specific Header File Specification + +The very first directive of the program must be + + #include + +where header.h02 is the system specific header file, (e.g. apple1.h02, +vic20.h02, etc.). + +Note: This will probably be replaced with a command line parameter +(e.g. '-s apple1', '-s vic20', etc...) to allow program portability. + +For compatability with the C02 Standard Library, the following functions +must be defined + + c = plkey(); Polls keyboard and returns raw ASCII character + corresponding to last/current pressed key. + + Returns constant NULKEY (usually 0) if no key was + pressed. + + c = rdkey(); Waits for a keypress and returns the raw ASCII + character corresponding to the pressed key. + + Note: Usually a loop that calls plkey(), but may + also directly call a system subroutine. + + c = getkey(); Waits for a keypress and returns the cleaned + ASCII value corresponding to the pressed key. + + Note: Calls rdkey() followed by any necessary + character code conversions. This can be due to + high-bit being set by keyboard decoder, + non-standard key mappings, keys that generate + escape sequences, etc... + + newlin(); Advances the cursor to the beginning of then + next line. + + Note: Depending on the system, this will usually + output a Carriage Return, Line Feed, both. + + prchr(c); Writes character c to the screen. + + Note: May directly access memory-mapped I/O + or may call a system subroutine. + + r = getstr(&s); Reads a maximum of 128 characters from keyboard + until a carriage return is received, storing the + entered characters as null-terminated string s. + + Allows corrections using Backspace/Delete. + + Pressing the Escape/Abort key terminates entry, + leaving the string in an undefined state. + + Returns number of characters entered, or 255 + if entry was aborted. + + r = outstr(n, &s): Writes up to 128 characters of null-terminated + string s to the screen, starting at position n. + + Returns position of null terminator in string. + + r = putstr(&s): Writes up to 128 characters of null-terminated + string s to the screen and advances the cursor to + the beginning of the next line. + + Returns number of characters printed. + + Note: Calls putstr(0, &s) followed by newlin(). + +along with the Zero Page locations (each pair of which must be sequential) + + strlo, strhi String Pointer for stdio.asm and string.asm + srclo, rcshi Secondary String Pointer for string.asm + +the following locations that may be Zero Page, but don't have to before + + temp0, temp1 Temporary variables used by stdlib.asm + +and the following locations that must be preserved between function calls + + random Storage for the Random Number Generator + + Contains the last number generated and is used to + generate the next number in the sequence + + rdseed Seed for Pseudo-Random Number Generator + + Usually a counter or timer. If one is not provided + by the system, should be generated by incrementing + in the plkey(), rdkey() functions. + +and the constants + + DELKEY ASCII code for Delete/Backspace key (usually DEL or BS) + ESCKEY ASCII code for Escape/Abort key (usually ESC) + NULKEY Returned if no Key was Pressed + RTNKEY ASCII code for Return/Enter key (usually CR) + diff --git a/include/old/notes.txt b/include/old/notes.txt new file mode 100644 index 0000000..634c506 --- /dev/null +++ b/include/old/notes.txt @@ -0,0 +1,6 @@ +Library Compiled Code Size: +ctype.asm 181 bytes +stdio.asm 83 bytes +stdlib,asm 191 bytes +string.asm 162 bytes + diff --git a/include/old/plus4.a02 b/include/old/plus4.a02 new file mode 100644 index 0000000..c169208 --- /dev/null +++ b/include/old/plus4.a02 @@ -0,0 +1,101 @@ +; c02 Program Initialization Code for Commodore Plus/4 & 16 + +;ASCII Control Codes Equivalents +CR EQU $0D ;Carriage Return +LF EQU $11 ;Line Feed (Cursor Down) +DEL EQU $14 ;Delete +HT EQU $1D ;Horizontal Tab (Cursor Right) +VT EQU $91 ;Vertical Tab (Cursor Up) +FF EQU $93 ;Form Feed (Clear Screen) +BS EQU $9D ;Backspace (Cursor Left) + +;PETSCII Key Mappings +DELKEY EQU $14 ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +strlo EQU $FE ;String Pointer (stdio.asm) +strhi EQU $FF ; + +;Other RAM Locations +tbffr EQU $0333 ;Cassette I/O Buffer + +;Video RAM and ROM +vidscn EQU $0C00 ;Video Screen Memory Area +chrrom EQU $D000 ;Character Generator ROM +vidclr EQU $0800 ;Color RAM + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start +basic: DC $0C, $10 ; Pointer to Next Line (4108) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + +start: TSX ;Get Stack Pointer + STX user15 ;and Save for Exit + JMP main ;Execute Program + +exit: LDX user15 ;Retrieve Saved Stack Pointer + TXS ;and Restore It + RTS ;Return to BASIC + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Get Character from Keyboard +getkey: + +;Wait for Character from Keyboard +rdkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Delete Previous Character +delchr: LDA #$9D ;Load Cursor Left into Accumulator + JSR prchr ; and Print it + LDA #$14 ;Load Delete into Accumulater + JMP prchr ; and Print it + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + JMP prchr ; and Print it + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/old/py65.asm b/include/old/py65.asm new file mode 100644 index 0000000..20ce326 --- /dev/null +++ b/include/old/py65.asm @@ -0,0 +1,80 @@ +; py65mon program initialization code for c02 programs + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $1B ;Escape/Stop Key (Escape) +RTNKEY EQU $0D ;Return/Enter Key (Carriage Return) + +;Zero Page Locations +strlo EQU $30 ;String Pointer (stdio.asm) +strhi EQU $31 +dstlo EQU $32 ;Source String Pointer (string.asm) +dsthi EQU $33 + +rdseed EQU $3E ;Pseudo-Random Seed +random EQU $3F ;Pseudo-Random Number Storage +temp0 EQU $40 ;Temporary Storage +temp1 EQU $41 +temp2 EQU $42 + +;Memory Mapped I/O +putc EQU $F001 ;Write Character to Console +getc EQU $F004 ;Read Character from Console + + ORG $0200 ;Start Directly Above Stack + +start: JMP main ;Execute Program + +;Poll Character from Keyboard +plkey: INC rdseed ;Cycle the Random Seed (if not provided by system) + LDA getc ;Read Character from Console + RTS + +;Read Character from Console +getkey; ;Same As rdkey + +;Wait for Character from Console +rdkey: JSR plkey ;Read Character from Console + BEQ rdkey ; Loop if None Received + RTS + +;Delete Previous Character +delchr: LDA #$08 ;Load Backspace into Accumulator + JSR prchr ; and Print it + LDA #$20 ;Load Space into Accumulater + JSR prchr ; and Print it + LDA #$08 ;Load Backspace into Accumulator + JMP prchr ; and Print it + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + JSR prchr ; and Print it + LDA #$0A ;Load L/F into Accumulater + ; and fall into prchr + +;Print Character to Console +prchr: STA putc ;Write Character to Console + RTS + +exit: BRK ;Return to Monitor + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybb + SED ;Set Decimal Flag for + CLC ; Addition Wizardry + ADC #$90 ;Convert to $90-$99,$00-$05 + ADC #$40 ;Convert to $30-$39,$41-$46 + CLD ;Clear Decimal Flag + JMP prchr ;Print Hex Digit and Return + + diff --git a/include/old/py65.h02 b/include/old/py65.h02 new file mode 100644 index 0000000..49ebe76 --- /dev/null +++ b/include/old/py65.h02 @@ -0,0 +1,19 @@ +/* py65mon Header File */ + +//Zero Page Variables +char strlo,strhi; //String Pointer for stdio.h02 and string.h02 +char dstlo,dsthi; //String Pointer for string.h02 + +//Memory Mapped I/O +char putc; //Write Character to Console +char getc; //Read Character from Console + +//System Subroutines +char plkey(); //Poll Console for character +char rdkey(); //Wait for character from Console +char getkey(); //Read ASCII character from Console +void newlin(); //Advance cursor to beginning of next line +void prchr(); //Print ASCII character to Console +void prbyte(); //Print Accumulator as Hexadadecimal number +void prhex(); //Print Low Nybble of Accumulator as Hex Digit + diff --git a/include/old/py65.txt b/include/old/py65.txt new file mode 100644 index 0000000..1b1add6 --- /dev/null +++ b/include/old/py65.txt @@ -0,0 +1,42 @@ +C02 Header File for py65mon + +At the beginning of the program use the directive + + #include + +This must be the first include directive. + +Defined zero-page memory locations (variables): + + strlo, strhi String Pointer (used by stdio library). + +Defined functions: + + delchr(); Moves cursor one character to the left and + deletes character in that position. + + Note: Writes backspace, space, backspace + via prchr($08), prchr($20), and prchr($08). + + c = getkey(); Waits for keypress and returns ASCII code of + key that was pressed. + + Note: Aliased to rdkey(). + + newlin(); Advances the cursor to the beginning of then + next line. + + Note: Writes carriage return and line feed + via prchr($0D) and prchr($0A). + + + c = rdkey(); Waits for keypress and returns ASCII code of + key that was pressed. + + Note: Continuously reads from memory location + getc until a non-zero value is returned. + + prchr(c); Prints character to screen. + + Note: Writes argument to memory location putc. + diff --git a/include/old/stdio.asm b/include/old/stdio.asm new file mode 100644 index 0000000..cf3efa9 --- /dev/null +++ b/include/old/stdio.asm @@ -0,0 +1,58 @@ +; C02 library stdio.h02 assembly language subroutines +; Requires external routines getkey, prchr, delchr, and newlin +; external zero page locations strlo and strhi +; and external constants DELKEY, ESCKEY, and RTNKEY + +;char getchr() +getchr: JMP getkey ;Call external getkey routine + +;void putchr(c) +putchr: JMP prchr ;Call external print character + +;char getstr(&s) +getstr: STX strlo ;Save Pointer in Store Index + STY strhi + LDY #$00 ;Initialize character offset +getstl: JSR getchr ;Get Keypress +getstd: CMP #DELKEY ;If Delete + BNE getste ;Then + TYA ; If Offset is Zero + BEQ getstl ; Get Next Character + DEY ; Else Decrement Offset + JSR delchr ; Delete Previous Character + JMP getstl ; and Get Next Character +getste: CMP #ESCKEY ;Else If Escape + BNE getstc ;Then + LDY #$FF ; Return -1 + BNE getsty +getstc: CMP #RTNKEY ;Else If Not Carriage Return + BEQ getstx + JSR putchr ; Echo Character + STA (strlo),Y ; Store Character at offset + INY ; increment offset and + BPL getstl ; loop if less than 128 +getstx: JSR newlin ;Else Advance Cursor to Next Line + LDA #$00 ; Terminate String + STA (strlo),Y ; and +getsty: TYA ; Return String Length + RTS + +;char outstr(n, &s) +outstr: LDA #$00 ;Set Start Position to 0 + ;and fall into outsub +;char outsub(n, &s) +outsub: STX strlo ;Save pointer in Store Index + STY strhi + TAY ;Initialize character offset +outsul: LDA (strlo),Y ;Read next character in string + BEQ outsux ;If Not 0 + JSR putchr ; Print character at offset, + INY ; increment offset, and + BPL outsul ; loop if less than 128 +outsux: TAY ;Return number of + RTS ; characters printed + +;char putstr(*s) +putstr: JSR outstr ;Write string to screen + JMP newlin ;Call external newline routine and return + diff --git a/include/old/stdio.h02 b/include/old/stdio.h02 new file mode 100644 index 0000000..a4dee45 --- /dev/null +++ b/include/old/stdio.h02 @@ -0,0 +1,36 @@ +/***************************************** + * stdio - Standard I/O Routines for C02 * + *****************************************/ + +/* Read Character from Keyboard * + * Waits for Keypress * + * Returns: ASCII value of Key */ +char getchr(); + +/* Write Character to Screen * + * Args: c - ASCII character to write */ +void putchr(); + +/* Read String from Keyboard * + * Buffers string until C/R is pressed * + * Args: &s - string read from keyboard * + * Returns: length of string */ +char getstr(); + +/* Write String to Screen * + * Args: &s - string to print from * + * Returns: ending position in string */ +char outstr(); + +/* Write Partial String to Screen * + * Args: n - starting position in string * + * &s - string to print from * + * Returns: ending position in string */ +char outsub(); + +/* Write String to Screen and Move * + * Cursor to Beginning of Next Line * + * Args: &s - string to print to screen * + * Returns: number of characters printed */ +char putstr(); + diff --git a/include/old/stdio.txt b/include/old/stdio.txt new file mode 100644 index 0000000..7d73f46 --- /dev/null +++ b/include/old/stdio.txt @@ -0,0 +1,72 @@ +Standard Input/Output Functions for Apple 1 + +At the beginning of the program use the directives + + #include + +The following functions are defined: + + c = getchr(); Waits for a keypress and returns the cleaned + ASCII value corresponding to the pressed key. + + Note: Calls getkey() from system library. + + putchr(c); Writes character c to the screen. + + Note: Calls prchr() from system library. + + r = getstr(&s); Reads a maximum of 128 characters from keyboard + until the Return/Enter key is pressed, storing the + entered characters as null-terminated string s. + + Allows corrections using Backspace/Delete. + + Pressing the Escape/Abort key terminates entry, + leaving the string in an undefined state. + + Returns number of characters entered, or 255 + if entry was aborted. + + Note: Calls getchr() in a loop and uses constants + DELKEY, RTNKEY, and ESCKEY from the system library. + + r = outstr(&s): Writes up to 128 characters of null-terminated + string s to the screen. + + Returns position of null terminator in string. + + Note: Calls outsub(0, &s). + + r = outsub(n, &s): Writes up to 128 characters of null-terminated + string s to the screen, starting at position n. + + Returns position of null terminator in string. + + Note: Calls putchr() in a loop. + + r = putstr(&s): Writes up to 128 characters of null-terminated + string s to the screen and advances the cursor to + the beginning of the next line. + + Returns number of characters printed. + + Note: Calls outstr(&s) followed by newlin(). + +Note: This library expects the following functions to be defined: + + getkey(); Wait for and read ASCII character from keyboard + prchr(); Print ASCII character to screen + delchr(); Backspace and delete previous character on screen + newlin(); Advance cursor to beginning of next line + +along with the sequential Zero Page locations + + strlo: String Pointer (low byte) + strhi: String Pointer (high byte) + +and the assembler constants + + DELKEY Delete/Backspace key ASCII code (usually DEL or BS) + ESCKEY Escape/Abort key ASCII code (usually ESC) + RTNKEY Return/Enter key ASCII code (usually CR) + diff --git a/include/old/stdlib.asm b/include/old/stdlib.asm new file mode 100644 index 0000000..dafa58e --- /dev/null +++ b/include/old/stdlib.asm @@ -0,0 +1,142 @@ +; C02 library stdlib.h02 assembly language subroutines +; Requires +; external zero page locations strlo and strhi +; and external locations random, temp0, and temp1. + +;Return Absolute Value of Accumulator +abs: CMP #$80 ;If Negative (High Bit Set) + BCC absx ; Carry will Already be Set + EOR #$FF ; One's Complement + ADC #$00 ; and Increment (Carry set by CMP) +absx: RTS + +;Multiply A times Y +;Uses temp0, temp1 +;Affects A,N,Z,C +mult: STA temp0 ;Store Multiplicand + STY temp1 ;Store Multiplier +;Multiply temp0 times temp1 +multt: LDA #$00 ;Initialize Accumulator + BEQ multe ;Enter Loop +multa: CLC + ADC temp0 ;Add Multiplicand +multl: ASL temp0 ;Shift Multiplicand Left +multe: LSR temp1 ;Shift Multiplier Right + BCS multa ;If Bit Shifted Out, Add Multiplicand + BNE multl ;Loop if Any 1 Bits Left + RTS + +;Divide A by Y +;Used temp0,temp1 +;Affects A,X,N,Z,C +div: STA temp0 ;Store Dividend + STY temp1 ;Store Divisor +;Divide temp0 by temp1 +divt: LDA #$00 ;Clear Accumulator + LDX #$07 ;Load Loop Counter + CLC +divl: ROL temp0 ;Shift Bit Out of Dividend + ROL ; into Accumulator + CMP temp1 ;If Accumulator + BCC divs ; >= Divisor + SBC temp1 ;Subtract Divisor +divs: DEX ;Decrement Counter + BPL divl ; and Loop + ROL temp0 ;Shift Result into Dividend + LDA temp0 ;Load Result into Accumulator + RTS + +;Generate Pseudo-Random Number +;Uses random +;Affects A,N,Z,C +rand: LDA random ;Load Last Result + BNE randl ;If Zero + ADC #$01 ; Set to 1 +randl: ASL ;Shift the Seed + BCC randx ;If a one was shifted out + EOR #$1D ; Twiddle the bite +randx: STA random ;Save the Seed + RTS + +;Seed Pseudo-Random Number Generator +rands: STA random ;Store Seed + RTS + +;Convert ASCII to Byte +;Uses temp0, temp1 +;Affects A,X,Y,N,Z,C +atoc: STX strlo ;Save String Pointer + STY strhi + LDY #$00 ;Initialize Index Into String + STY temp0 ;Initialize Result +atocl: LDA (strlo),Y ;Get Next Character + CMP #$30 ;If Less Than '0' + BCC atocx ; Exit + CMP #$3A ;If Greater Than '9' + BCS atocx ; Exit + AND #$0F ;Convert to Binary Nybble + STA temp1 ; and Save It + LDA temp0 ;Load Result + ASL ;Multiply by 5 by + ASL ; Multiplying by 4 + ADC temp0 ; And Adding Itself + ASL ;Multiply that by 2 + ADC temp1 ;Add Saved Nybble + STA temp0 ; and Store Result + INY ;Increment Index + BPL atocl ; and Loop +atocx: LDA temp0 ;Load Result + RTS ;And Return + +;Convert Byte to ASCII +;Uses strlo, strhi, temp0, temp1, temp2 +;Affects A,X,Y,N,Z +ctoa: STX strlo ;Save Pointer in Store Index + STY strhi + JSR cvbcd ;Convert Accumulator to BCD + LDY #$00 ;Set String Offset to 0 + LDA temp2 ;Get High Byte + BEQ ctoa1 ;If Not Zero + JSR ntoa ; Convert Low Nybble +ctoa1: LDA temp1 ;Get Low Byte + LSR ;Shift High Nybble + LSR ; into Low Nybble + LSR + LSR + BNE ctoa2 ;If Not Zero + CMP temp2 ; and High Byte + BEQ ctoa3 ; not Zero +ctoa2: JSR ntoa ; Convert It +ctoa3: LDA temp1 ;Get Low Byte + JSR ntoa ;Convert It + LDA #$00 + BEQ ctoax ;Terminate String +ntoa: AND #$0F ;Strip High Nybble + ORA #$30 ;Convert to ASCII digit +ctoax STA (strlo),Y ;Store in String + INY ;and Increment Offset + RTS + +;Convert Binary Number in Accumulator to Binary Coded Decimal +;Uses temp0 +;Returns BCD in temp1,temp and A,X = 0 +cvbcd: STA temp0 ;Save Binary Value + LDA #0 ;Clear BCD Bytes + STA temp1 + STA temp2 + LDX #8 ;Process 8 bits of Binary + SEI ;Disable Interupts + SED ;Set Decimal Mode +cvbcdl: ASL temp0 ;Shift High Bit Into Carry + LDA temp1 ;Add BCD Low Byte to Itself + ADC temp1 ; Plus Bit Shifted out of Binary + STA temp1 ; Effectively Multiplying It by 2 + LDA temp2 ;Add BCD High Byte to Itself + ADC temp2 ; Plus Bit Shifted out of Low Byte + STA temp2 ; Effectively Multiplying It by 2 + DEX ;Decrement Counter and + BNE cvbcdl ; Process Next Bit + CLD ;Clear Decimal Mode + CLI ;Enable Interrupts + RTS + diff --git a/include/old/stdlib.h02 b/include/old/stdlib.h02 new file mode 100644 index 0000000..b19027c --- /dev/null +++ b/include/old/stdlib.h02 @@ -0,0 +1,50 @@ +/********************************************* + * stdlib - Standard Library Routines for C02 * + *********************************************/ + +/* Convert String to Byte * + * Args: &s - string * + * Returns: Number Represented by String */ +//char strtob(); + +/* Terminate Program Abnormally */ +//void abort(); + +/* Terminate Program Normally */ +//void exit(); + +/* Absolute Value * + * Args: b - Byte to get absolute value of * + * Returns: Absolute value of b */ +byte abs(); + +/* Convert ASCII String to Byte * + * Args: &s - String to Convert * + * Returns: Numeric value of string */ +char atoc(); + +/* Convert Unsigned Byte to ASCII String * + * Args: c - Unsigned Byte to Convert * + * &s - String to populate */ +void ctoa(); + +/* Divide Unsigned Bytes * + * Args: n - Numerator * + * d - Denominator * + * Returns: Numerator / Denominator */ +char div(); + +/* Multiply Unsigned Bytes * + * Args: n - Multiplicand * + * d - Multiplier * + * Returns: Multiplicand * Multiplier */ +char mult(); + +/* Generate Pseudo-Random Number * + * Returns: Random number between 1 and 255 */ +char rand(); + +/* Seed Pseudo-Random Number Generator * + * Args: n - Seed number */ +void srand(); + diff --git a/include/old/string.asm b/include/old/string.asm new file mode 100644 index 0000000..422bb5c --- /dev/null +++ b/include/old/string.asm @@ -0,0 +1,163 @@ +; C02 library string.h02 assembly language subroutines +; Requires the following RAM locations be defined +; zero page: strlo,strhi, and srclo,srchi +; anywhere: temp0 and temp0 + +;Internal Call - Initialize Source String +;Args: X,Y = Pointer to source string +;Sets: strlo,strhi = Pointer to source string +;Affects: N,Z +;Returns: Y = #$00 +strini: STX strlo ;Save String Pointer + STY strhi + LDY #$00 ;Initialize Index Into String + RTS + +;strcmp(&s) - Compare String (to Destination String) +;Requires: dstlo, dsthi - Pointer to destination string +;Args: X,Y = Pointer to source string +;Affects N,Z +;Returns A=$01 and C=1 if Destination > Source +; A=$00 and Z=1, C=1 if Destination = Source +; A=$FF and C=0 if Destination < Source +; Y=Position of first character that differs +strcmp: JSR strini ;Initialize Source String +strcml: LDA (dstlo),Y ;Load Destination Character + CMP (strlo),Y ;Compare Against Source Character + BNE strcmx; ;If Equal + ORA (strlo),Y ;OR with Source Character + BEQ strcmr ; If Both are 0, Return 0 + INY ;Increment Offset + BPL strcml ; and Loop if < 128 +strcmx: BCC strclx ;If Source < Destination + LDA #$01 ;Else Return 1 +strcmr: RTS ; + +;strchr(c, &s) - Find Character in String +;Args: A = Character to look for +; X,Y = Pointer to string to search in +;Sets: strlo,strhi = Pointer to string +; temp0 = Character being searched for +;Affects: N,Z +;Returns: A = Position in string, C=1 if found +; A = $FF, C=0 if not found +; Y = Position of last character scanned +strchr: JSR strini ;Initialize Source String + STA temp0; ;Save Character +chrstl: LDA (strlo),Y ;Get Next Character + BEQ strclc ;If NUL, Return $FF and Carry Clear + CMP temp0 ;Compare Character + BEQ strlex ;If Found, Return Index + INY ;Increment Counter + BPL chrstl ; and Loop if < 128 + ;Else Return $FF and Carry Clear +strclc: CLC ;Clear Carry +strclx: LDA #$FF ;Load -1 into Accumulater + RTS ;and Return + +;strlen(&s) - Return Length of String +;Args: X,Y - Pointer to string +;Sets: strlo,strhi = Pointer to source string +;Affects: N,Z +;Returns: A,Y = Length of string +strlen: JSR strini ;Initialize Source String +strlel: LDA (strlo),Y ;Get Next Character + BEQ strlex ;If <> NUL + INY ; Increment Index + BPL strlel ; and Loop if < 128 +strlex: TYA ;Transfer Index to Accumulator + RTS ;and Return + +;strset(&s) - Set Destination String +; Called before strcat(), strcmp(), strcpy(), strstr() +;Args: X,Y = Pointer to destination string +;Sets: strlo,strhi = Pointer to destination string +;Affects: N,Z +strset: STX dstlo ;Save String Pointer + STY dsthi + RTS + +;strcat(&s) Concatenate String (to Destination String) +;Requires: dstlo, dsthi - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: strlo,strhi = Pointer to source string +; temp0 = Length of source prior to concatenation +;Affects: C,N,Z +;Returns: A,Y = Total length of concatenated string +strcat: JSR strini ;Initialize Source String +strcal: LDA (dstlo),Y ;Find end of Destination String + BEQ strcax ; + INY ; + BPL strcal ; +strcax: STY temp0 ;Subtract Destination String Length + LDA strlo ; from Source String Pointer + SEC + SBC temp0 + STA strlo + LDA strhi + SBC #$00 + STA strhi + JMP strcpl ;Execute String Copy + +;strcpy(&s) - Copy String (to Destination String) +;Requires: dstlo, dsthi - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: strlo,strhi = Pointer to source string +;Affects: N,Z +;Returns: A,Y = Number of characters copies +strcpy: JSR strini ;Initialize Source String +strcpl: LDA (strlo),Y ;Get Character from Source String + STA (dstlo),Y ;Copy to Destination String + BEQ strcpx ;If <> NUL + INY ; Increment Index + BPL strcpl ; and Loop if < 128 +strcpx: TYA ;Transfer Index to Accumulator + RTS ;and Return + +;strcut(n, &s) - Copy from Position n to End of Source (into Destination) +;Requires: dstlo, dsthi - Pointer to destination string +;Args: A = Starting position in start string +; X,Y = Pointer to source string +;Sets: strlo,strhi = Pointer to specified position source string +;Affects: N,Z +;Returns: A,Y = Length of copied string +strcut: JSR strini ;Initialize Source String + CLC + ADC strlo ;Move Source Pointer + STA strlo ; to Specified Position in String + BCC strcpl + INC strhi + JMP strcpl ;and Jump Into String Copy Loop + +;strstr(&s) - Search for String (in Destination String) +;Requires: dstlo, dsthi - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: dstlo,dsthi = Pointer to position in source string +; End of string if not found +; strlo,strhi = Pointer to source string +; temp0 = Last position checked in destination string +;Affects: N,Z +;Returns: A = Position, C=1 if found +; A = $FF, C=0 if not found +; Y = Last position checked in source string +strstr: JSR strini ;Initialize Source String + STY temp0 ;Initialize Position +strstl: LDY #$00; ;Initialize Compare Offset + LDA (dstlo),Y ;Get Start Character in Destination + BEQ strclc ;If NUL return $FF and Carry Clear + JSR strcml ;Jump into Compare Loop + BEQ strstx ;If Not Equal + BMI strstn ; If Source is Greater + LDA (strlo),Y ; If at End of Source String + BEQ strstx ; Return Current Position +strstn: INC temp0 ; Else Increment Position + BMI strclc ; If > 127 return $FF and Carry Clear + INC dstlo ; Increment Source Pointer + BNE strstl + INC dsthi ; If not End of Memory + BNE strstl ; Loop + BEQ strclc ; Else return $FF and Carry Clear +strstx: SEC ;Else Set Carry + LDA temp0 ; Load Position + RTS ; and Return + diff --git a/include/old/string.h02 b/include/old/string.h02 new file mode 100644 index 0000000..92dd208 --- /dev/null +++ b/include/old/string.h02 @@ -0,0 +1,58 @@ +/********************************************* + * string - String Handling Routines for C02 * + *********************************************/ + +/* Find Charaacter in String * + * Args: c - Character to find * + * &s - String to search * + * Returns: c in s * + * $FF if not found */ +byte strchr(); + +/* Get Length of String * + * Args: s - string * + * Returns: Length of string */ +char strlen(); + +/* Sets Destination String for * + * functions that use two strings * + * Args: s - Destination string */ +void strset(); + +/* Concatenate Destination String to Source String * + * Args: s - Source string * + * Sets: Destination string specified by strset() * + * Returns: Total Length of concatenated string */ +char strcat(); + +/* Compare Destination String against Source String * + * Args: s - Source string * + * Uses: Destination string specified by strset() * + * Returns: Result of comparison * + * -1 = Destination < Source * + * 0 = Destination = Source * + * 1 = Destination > Source */ +byte strcmp(); + +/* Copy Source String to Destination String * + * Args: s - Source string * + * Sets: Destination string specified by strset() * + * Returns: Number of characters copied */ +char strcpy(); + +/* Copy Part of Source String to Destination String * + * Args: n - Starting point in source string * + * s - Source string * + * Sets: Destination string specified by strset() * + * Returns: Number of characters copied */ +char strcut(); + +/* Find String in String * + * Args: &s - String to Find * + * Uses: String to search specified by strset() * + * Sets: strset() pointer to position of string * + * End of string if not found * + * Returns: Position of s in Destination string * + * $FF if not found */ +byte strstr(); + diff --git a/include/old/string.txt b/include/old/string.txt new file mode 100644 index 0000000..f2c5672 --- /dev/null +++ b/include/old/string.txt @@ -0,0 +1,78 @@ +String Manipulation Functions for C02 + +Strings are zero-terminated arrays of type char with a maximum length +of 128 characters. + +The first character in a string is at position 0, and the last character +is at position length - 1. + +Since all of the routines stop processing at the 128th character, a 128 +character string does not require a zero terminator. + +Usage: at the beginning of the program use the directives + + #include + +The following functions are defined: + + p = strchr(c, &s); Searches string s for character c. + + Returns position of character in string, or 255 + if character was not found. + + n = strlen(&s); Determines length of string s. + + Returns length of string. + + strset(&s); Sets string s as the source string for subsequent + strcat(). strcmp(), strcpy(), and strstr() calls. + + Note: Sets variables srclo and srchi as a pointer + to the string. + + n = strcat(&s); Concatenates destination string s onto the end of + source string set by prior setstr() call. + + Returns total length of concatenated string. + + Note: srclo and srchi are left pointing to the + source string. + + b = strcmp(&s); Compares destination string s against source + string set by prior setstr() call. + + Returns -1 if source < destination, 0 if + source = destination, and 1 if source > destination. + + Note: srclo and srchi are left pointing to the + source string. + + n = strcpy(&s); Copies destination string s into source string + set by prior setstr() call, replacing previous + contents. + + Returns number of characters copied. + + Note: srclo and srchi are left pointing to the + source string. + + p = strstr(&s); Searches for destination string s in source string + set by prior setstr() call. + + Returns position of destination string in source + string, or 255 if character was not found. + + Note: srclo and srchi are left pointing to the + address of the position of the destination string + in the source string. + +Note: This library expects the following Zero Page locations to be defined + + strlo, strhi Destination String Pointer + srclo, srchi String Pointer (high byte) + +as well as the memory location + + temp0 Temporary storage + + diff --git a/include/old/vic20.asm b/include/old/vic20.asm new file mode 100644 index 0000000..1b689b9 --- /dev/null +++ b/include/old/vic20.asm @@ -0,0 +1,119 @@ +; c02 Program Initialization Code for Unexpanded VIC-20 + +;ASCII Control Codes Equivalents +CR EQU $0D ;Carriage Return +LF EQU $11 ;Line Feed (Cursor Down) +DEL EQU $14 ;Delete +HT EQU $1D ;Horizontal Tab (Cursor Right) +VT EQU $91 ;Vertical Tab (Cursor Up) +FF EQU $93 ;Form Feed (Clear Screen) +BS EQU $9D ;Backspace (Cursor Left) + +;PETSCII Key Mappings +DELKEY EQU $14 ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +strlo EQU $FB ;String Pointer (stdio.asm) +strhi EQU $FC ;Free Byte for User Programs +usrzp3 EQU $FD ;Free Byte for User Programs +usrzp4 EQU $FE ;Free Byte for User Programs + +;Other RAM Locations +user0 EQU $0310 ;Free Byte for User Programs +user1 EQU $0311 ;Free Byte for User Programs +user2 EQU $0312 ;Free Byte for User Programs +user3 EQU $0313 ;Free Byte for User Programs +user4 EQU $0334 ;Free Byte for User Programs +user5 EQU $0335 ;Free Byte for User Programs +user6 EQU $0336 ;Free Byte for User Programs +user7 EQU $0337 ;Free Byte for User Programs +user8 EQU $0338 ;Free Byte for User Programs +user9 EQU $0339 ;Free Byte for User Programs +user10 EQU $033A ;Free Byte for User Programs +user11 EQU $033B ;Free Byte for User Programs +tbffr EQU $033C ;Cassette I/O Buffer +user12 EQU $03FC ;Free Byte for User Programs +user13 EQU $03FD ;Free Byte for User Programs +user14 EQU $03FE ;Free Byte for User Programs +user15 EQU $03FF ;Free Byte for User Programs + +;Video RAM and ROM +vicscn EQU $1E00 ;Video Screen Memory Area (Unexpanded) +chrrom EQU $8000 ;Character Generator ROM +vicclr EQU $9600 ;Color RAM (Unexpanded) + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start +basic: DC $0C, $10 ; Pointer to Next Line (4108) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + +start: TSX ;Get Stack Pointer + STX user15 ;and Save for Exit + JMP main ;Execute Program + +exit: LDX user15 ;Retrieve Saved Stack Pointer + TXS ;and Restore It + RTS ;Return to BASIC + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Get Character from Keyboard +getkey: + +;Wait for Character from Keyboard +rdkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Delete Previous Character +delchr: LDA #$9D ;Load Cursor Left into Accumulator + JSR prchr ; and Print it + LDA #$14 ;Load Delete into Accumulater + JMP prchr ; and Print it + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + JMP prchr ; and Print it + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/old/vic20all.asm b/include/old/vic20all.asm new file mode 100644 index 0000000..9b36ff6 --- /dev/null +++ b/include/old/vic20all.asm @@ -0,0 +1,242 @@ +; c02 Program Initialization Code for Unexpanded VIC-20 + +;PETSCII Control Codes +WHT EQU $05 ;White +CR EQU $0D ;Carriage Return +LWRCS EQU $0E ;Switch to Lower Case +LF EQU $11 ;Cursor Down (Line Feed) +RVSON EQU $12 ;Reverse On +HOME EQU $13 ;Cursor Home +DEL EQU $14 ;Delete +RED EQU $1C ;Red +HT EQU $1D ;Cursor Right (Horizontal Tab) +GRN EQU $1E ;Green +BLU EQU $1F ;Blue +UPRCS EQU $8E ;Switch to Upper Case +BLK EQU $90 ;Black +VT EQU $91 ;Cursor Up (Vertical Tab) +RVSOFF EQU $92 ;Reverse Off +CLR EQU $93 ;Clear Screen +INST EQU $94 ;Insert +PUR EQU $9C ;Purple +BS EQU $9D ;Cursor Left (Backspace) +YEL EQU $9E ;Yellow +CYN EQU $9F ;Cyan + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +usradd EQU $01 ;Address of USR Routine +linnum EQU $14 ;Integer Line Number Value +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +status EQU $90 ;Kernal I/O Status Word +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +time EQU $A0 ;Software Jiffy Clock +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +pntc EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +usrzp1 EQU $FB ;Free Byte for User Programs +usrzp2 EQU $FC ;Free Byte for User Programs +usrzp3 EQU $FD ;Free Byte for User Programs +usrzp4 EQU $FE ;Free Byte for User Programs + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +color EQU $0286 ;Current Foreground Color Text +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress + +user0 EQU $0310 ;Free Byte for User Programs +user1 EQU $0311 ;Free Byte for User Programs +user2 EQU $0312 ;Free Byte for User Programs +user3 EQU $0313 ;Free Byte for User Programs +user4 EQU $0334 ;Free Byte for User Programs +user5 EQU $0335 ;Free Byte for User Programs +user6 EQU $0336 ;Free Byte for User Programs +user7 EQU $0337 ;Free Byte for User Programs +user8 EQU $0338 ;Free Byte for User Programs +user9 EQU $0339 ;Free Byte for User Programs +user10 EQU $033A ;Free Byte for User Programs +user11 EQU $033B ;Free Byte for User Programs +tbffr EQU $033C ;Cassette I/O Buffer +user12 EQU $03FC ;Free Byte for User Programs +user13 EQU $03FD ;Free Byte for User Programs +user14 EQU $03FE ;Free Byte for User Programs +user15 EQU $03FF ;Free Byte for User Programs + +;Basic and Screen RAM +bas3k EQU $0400 ;Basic Start (3K Expansion Area) +basunx EQU $1000 ;Basic Start (Unexpanded)/Video Screen +bas8k EQU $1200 ;Basic Start (3K Expansion Area) +vicscx EQU $1000 ;Video Screen Memory Area (8K+ Expansion) +vicscu EQU $1E00 ;Video Screen Memory Area (Unexpanded) +exblk1 EQU $2000 ;8K Expansion RAM/ROM Block 1 +exblk2 EQU $4000 ;8K Expansion RAM/ROM Block 2 +exblk3 EQU $6000 ;8K Expansion RAM/ROM Block 3 + +chrrom EQU $8000 ;Character Generator ROM + +vicclx EQU $9400 ;Color RAM (8K+ Expansion) +vicclu EQU $9600 ;Color RAM (Unexpanded) + +;VIC Chip Registers +vicsch EQU $9000 ;Interlace Mode + Horizontal Screen Origin +vicscv EQU $9001 ;Vertical Screen Origin +viccol EQU $9002 ;Screen Memory Location + Number of Video Columns +vicrow EQU $9003 ;Raster Value + Number of Video Rows + Character Size +vicrst EQU $9004 ;Raster Value +vicloc EQU $9005 ;Screen Memory Location + Character Memory Location +viclph EQU $9006 ;Light Pen - Horizontal +viclpv EQU $9007 ;Light Pen - Vertical +vicpd1 EQU $9008 ;Paddle 1 +vicpd2 EQU $9009 ;Paddle 2 +vicbsf EQU $900A ;Bass Sound Switch and Frequency +vicasf EQU $900B ;Alto Sound Switch and Frequency +vicssf EQU $900C ;Soprano Sound Switch and Frequency +vicnsf EQU $900D ;Noise Switch and Frequency +vicavl EQU $900E ;Auxillary Color + Sound Volume +vicclr EQU $900F ;Screen Color + Reverse Mode + Border Color + +;VIA #1 (NMI) +v1orb EQU $9110 ;Port B - User Port +v1ora EQU $9111 ;Port A +v1ddrb EQU $9112 ;Data Direction Register B +v1ddra EQU $9113 ;Data Direction Register A +v1t1l EQU $9114 ;Timer #1 Low +v1t1h EQU $9115 ;Timer #1 High +v1lt1l EQU $9116 ;Load Timer #1 Low +v1lt1h EQU $9117 ;Load Timer #1 High +v1t2l EQU $9118 ;Timer #1 Low +v1t2h EQU $9119 ;Timer #1 High +v1sr EQU $911A ;Shift Register +v1acr EQU $911B ;Auxillary Control Register +v1pcr EQU $911C ;Peripheral Control Register +v1ifr EQU $911D ;Interrupt Flag Register +v1ier EQU $911E ;Interrupt Enable Register +v1oran EQU $911F ;Port A (No Handshake) + +;VIA #2 (IRQ) +v2orb EQU $9210 ;Port B +v2ora EQU $9211 ;Port A +v2ddrb EQU $9212 ;Data Direction Register B +v2ddra EQU $9213 ;Data Direction Register A +v2t1l EQU $9214 ;Timer #1 Low +v2t1h EQU $9215 ;Timer #1 High +v2lt1l EQU $9216 ;Load Timer #1 Low +v2lt1h EQU $9217 ;Load Timer #1 High +v2t2l EQU $9218 ;Timer #1 Low +v2t2h EQU $9219 ;Timer #1 High +v2sr EQU $921A ;Shift Register +v2acr EQU $921B ;Auxillary Control Register +v2pcr EQU $921C ;Peripheral Control Register +v2ifr EQU $921D ;Interrupt Flag Register +v2ier EQU $921E ;Interrupt Enable Register +v2oran EQU $921F ;Port A (No Handshake) + +exprom EQU $8000 ;Cartridge Expansion ROM + + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start +basic: DC $0C, $10 ; Pointer to Next Line (4109) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + + JMP main ;Execute Program + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Read Character from Console + + +;Wait for Character from Console +getkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/old/vic3k.asm b/include/old/vic3k.asm new file mode 100644 index 0000000..f5035f2 --- /dev/null +++ b/include/old/vic3k.asm @@ -0,0 +1,158 @@ +; c02 Program Initialization Code for VIC-20 with 3K Expansion + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +usradd EQU $01 ;Address of USR Routine +linnum EQU $14 ;Integer Line Number Value +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +status EQU $90 ;Kernal I/O Status Word +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +time EQU $A0 ;Software Jiffy Clock +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +pntc EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +usrzp1 EQU $FB ;Free Byte for User Programs +usrzp2 EQU $FC ;Free Byte for User Programs +usrzp3 EQU $FD ;Free Byte for User Programs +usrzp4 EQU $FE ;Free Byte for User Programs + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +color EQU $0286 ;Current Foreground Color Text +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress + +user0 EQU $0310 ;Free Byte for User Programs +user1 EQU $0311 ;Free Byte for User Programs +user2 EQU $0312 ;Free Byte for User Programs +user3 EQU $0313 ;Free Byte for User Programs +user4 EQU $0334 ;Free Byte for User Programs +user5 EQU $0335 ;Free Byte for User Programs +user6 EQU $0336 ;Free Byte for User Programs +user7 EQU $0337 ;Free Byte for User Programs +user8 EQU $0338 ;Free Byte for User Programs +user9 EQU $0339 ;Free Byte for User Programs +user10 EQU $033A ;Free Byte for User Programs +user11 EQU $033B ;Free Byte for User Programs +tbffr EQU $033C ;Cassette I/O Buffer +user12 EQU $03FC ;Free Byte for User Programs +user13 EQU $03FD ;Free Byte for User Programs +user14 EQU $03FE ;Free Byte for User Programs +user15 EQU $03FF ;Free Byte for User Programs + +;Video RAM and ROM +vicscn EQU $1E00 ;Video Screen Memory Area (Unexpanded) +chrrom EQU $8000 ;Character Generator ROM +vicclr EQU $9600 ;Color RAM (Unexpanded) + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $0401 ;Start +basic: DC $0C, $04 ; Pointer to Next Line (1036) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $31, $30, $33 ,$38 ; "1038" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + +start: TSX ;Get Stack Pointer + STX user15 ;and Save for Exit + JMP main ;Execute Program + +exit: LDX user15 ;Retrieve Saved Stack Pointer + TXS ;and Restore It + RTS ;Return to BASIC + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Get Character from Keyboard +getkey: + +;Wait for Character from Keyboard +rdkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/old/vic8k.asm b/include/old/vic8k.asm new file mode 100644 index 0000000..fba2c9d --- /dev/null +++ b/include/old/vic8k.asm @@ -0,0 +1,158 @@ +; c02 Program Initialization Code for Vic-20 with at 8K Expansion + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +usradd EQU $01 ;Address of USR Routine +linnum EQU $14 ;Integer Line Number Value +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +status EQU $90 ;Kernal I/O Status Word +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +time EQU $A0 ;Software Jiffy Clock +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +pntc EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +usrzp1 EQU $FB ;Free Byte for User Programs +usrzp2 EQU $FC ;Free Byte for User Programs +usrzp3 EQU $FD ;Free Byte for User Programs +usrzp4 EQU $FE ;Free Byte for User Programs + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +color EQU $0286 ;Current Foreground Color Text +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress + +user0 EQU $0310 ;Free Byte for User Programs +user1 EQU $0311 ;Free Byte for User Programs +user2 EQU $0312 ;Free Byte for User Programs +user3 EQU $0313 ;Free Byte for User Programs +user4 EQU $0334 ;Free Byte for User Programs +user5 EQU $0335 ;Free Byte for User Programs +user6 EQU $0336 ;Free Byte for User Programs +user7 EQU $0337 ;Free Byte for User Programs +user8 EQU $0338 ;Free Byte for User Programs +user9 EQU $0339 ;Free Byte for User Programs +user10 EQU $033A ;Free Byte for User Programs +user11 EQU $033B ;Free Byte for User Programs +tbffr EQU $033C ;Cassette I/O Buffer +user12 EQU $03FC ;Free Byte for User Programs +user13 EQU $03FD ;Free Byte for User Programs +user14 EQU $03FE ;Free Byte for User Programs +user15 EQU $03FF ;Free Byte for User Programs + +;Video RAM and ROM +vicscn EQU $1000 ;Video Screen Memory Area (Unexpanded) +chrrom EQU $8000 ;Character Generator ROM +vicclr EQU $9400 ;Color RAM (Unexpanded) + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1201 ;Start +basic: DC $0C, $12 ; Pointer to Next Line (4108) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $36, $32 ,$32 ; "4622" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + +start: TSX ;Get Stack Pointer + STX user15 ;and Save for Exit + JMP main ;Execute Program + +exit: LDX user15 ;Retrieve Saved Stack Pointer + TXS ;and Restore It + RTS ;Return to BASIC + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Get Character from Keyboard +getkey: + +;Wait for Character from Keyboard +rdkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/plus4.a02 b/include/plus4.a02 new file mode 100644 index 0000000..c78aacd --- /dev/null +++ b/include/plus4.a02 @@ -0,0 +1,295 @@ +; c02 Program Initialization Code for Commodore Plus/4 + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +pdir EQU $00 ;7501 on-chip data-direction register +port EQU $01 ;7501 on-chip 8-bit Input/Output register +srchtk EQU $02 ;Token 'search' looks for (run-time stack) +zpvec1 EQU $03 ;Temp (renumber) +zpvec2 EQU $05 ;Temp (renumber) +charac EQU $07 ;Search Character for Scanning BASIC Text Input +endchr EQU $08 ;Search Character for Statement Terminator or Quote +trmpos EQU $09 ;Column Position of Cursor before Last SPC or TAB +verckb EQU $0A ;Flag: Load or Verify (BASIC) +count EQU $0B ;Index into Text Input Buffer/Number of Array Subscripts +dimflg EQU $0C ;Flags for Routines that Locate or Build an Array +valtyp EQU $0D ;Type of Data (String or Numeric) +intflg EQU $0E ;Type of Numeric Data (Integer or Floating Point) +garbfl EQU $0F ;Flag for LIST, Garbage Collection, and Program Terminators +subflg EQU $10 ;Subscript Reference to Array or User Defined Function Call +inpflg EQU $11 ;Is Data Input to GET, READ, or INPUT? +tansgn EQU $12 ;Sign of Result of TAN or SIN Function +channl EQU $13 ;Current I/O Channel (CMD Logical File) Number +linnum EQU $14 ;Integer Line Number Value +temppt EQU $16 ;Pointer to Next Availabale Space in Temporary String Stack +lastpt EQU $17 ;Pointer to Address of Last String in Temporary String Stack +tempst EQU $19 ;Descriptor Stack for Temporary Strings +index1 EQU $22 ;Miscellaneous Temporary Pointers and Save Area +index2 EQ4 $24 +resho EQU $26 ;Floating Point Multiplication Work Area +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +frespc EQU $35 ;Temporary Pointer for Strings +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +curlin EQU $39 ;Current BASIC Line Number +oldlin EQU $3B ;Previous BASIC Line Number +oldtxt EQU $3D ;Pointer to Address of Current BASIC Statement +datlin EQU $3F ;Current DATA Line Number +datptr EQU $41 ;Pointer to Address of Current DATA Item +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +varnam EQU $45 ;Current Variable Name +varpnt EQU $47 ;Pointer to Current BASIC Variable Value +forpnt EQU $49 ;Temporary Pointer to Index Variable Used by FOR +opptr EQU $4B ;Math Operator Table Displacement +opmask EQU $4D ;Mask for Comparison Operator +defpnt EQU $4E ;Pointer to Current FN Descriptor +dscpnt EQU $50 ;Temporary Pointer to Current String Descriptor +; $52 ;current string length +four6 EQU $53 ;Constant for Garbage Collection +jmper EQU $54 ;Jump to Function Instruction +; $57 ;BASIC Numeric Work Area +fac1 EQU $61 ;Floating Point Accumulator #1 +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +sgnflg EQU $67 ;Number of Terms in Series Evaluation +bits EQU $68 ;Floating Point Accumulator #1: Overflow Digit +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +facov EQU $70 ;Low Order Mantissa Byte of Floating Point Accumulator #1 +fbufpt EQU $71 ;Series Evaluation Pointer +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +rndx EQU $8B ;RND Function Seed Value +status EQU $90 ;Kernal I/O Status Word +stkey EQU $91 ;Flag: Was STOP Key Pressed +svxt EQU $92 ;Timing Constant for Tape Reads +verck EQU $93 ;Flag: Load or Verify (Kernal) +c3po EQU $94 ;Flag: Serial Bus - Output Character was Buffered +bsour EQU $95 ;Buffered Character for Serial Bus +syno EQU $96 ;Cassette Block Synchronization Number +xsav EQU $97 ;Temporary .X Register Save Area +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +prty EQU $9B ;Tape Character Parity +dpsw EQU $9C ;Flag: Tape Byte Received +msflg EQU $9D ;Flag: Kernal Message Control +ptr1 EQU $9E ;Tape Pass 1 Error Log Index +ptr2 EQU $9F ;Tape Pass 2 Error Log Correction Index +time EQU $A0 ;Software Jiffy Clock +; EQU $A3 ;Temporary Data Storage Area +cntdn EQU $A5 ;Cassette Synchronization Character Countdown +bufpnt EQU $A6 ;Count of Characters in Tape I/O Buffer +inbit EQU $A7 ;RS-232 Input Bits/Tape I/O Miscellaneous Flag +bitci EQU $A8 ;RS-232 Input Bit Count/Tape Error Flag +rinone EQU $A9 ;RS-232 Flag: Check for Start Bit/Tape Character Type Flag +ridata EQU $AA ;RS-232 Input Byte Buffer +riprty EQU $AB ;RS-232 Input Parity/Cassette Leader Counter +sal EQU $AC ;Pointer to Starting Address of Load/Screen Scrolling +eal EQU $AE ;Pointer to Ending Address of Load (End of Program) +cmp0 EQU $B0 ;Used to Determine Value of SVXT +; EQU $B1 ;Used in Timing of Tape Reads +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +bitts EQU $B4 ;RS-232 Output Bit Count/Tape Load Receive Flag +nxtbit EQU $B5 ;RS-232 Next Bit to Send/Tape EOT Flag +rodata EQU $B6 ;RS-232 Output Byte Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +roprt EQU $BD ;RS-232 Output Parity/Tape Character Being Read or Sent +fsblk EQU $BE ;Cassette Read/Write Block Count +mych EQU $BF ;Tape Input Byte Buffer +cas1 EQU $C0 ;Tape Motor Interlock +stal EQU $C1 ;I/O Start Address +memuss EQU $C3 ;Tape Load Temporary Address +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +indx EQU $C8 ;Pointer: End of Logical Line for Input +lxsp EQU $C9 ;Cursor X.Y Position at Start of Input +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +blnsw EQU $CC ;Cursor Blink Enable +blnct EQU $CD ;Timer Countdown to Blink Cursor +gdbln EQU $CE ;Character Under Cursor +blnon EQU $CF ;Flag: Was Last Cursor Blink On or Off +crsw EQU $D0 ;Flag: Input from Keyboard or Screen +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +qtsw EQU $D4 ;Flag: Editor in Quote Mode? +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +; EQU $D7 ;Temporary Storage for ASCII Value of Last Character Printed +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +user EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +keytab EQU $F5 ;Vector: Keyboard Decode Table +ribuf EQU $F7 ;Pointer: RS-232 Input Buffer +robuf EQU $F8 ;Pointer: RS-232 Output Buffer +frekzp EQU $FB ;Four Free Bytes of Zero Page for User Programs +baszpt EQU $FF ;BASIC Temporary Data for Floating Point to ASCII Conversion + +;Page 1 Locations +bad EQU $0100 ;Tape Input Error Log +; EQU $013F ;Microprocessor Stack + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +timout EQU $0285 ;Flag: Kernal Variable for IEEE Timeout +color EQU $0286 ;Current Foreground Color Text +gdcol EQU $0287 ;Color of Character Under Cursor +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +delay EQU $028C ;Counter for Timing Delay Until First Key Repeat Begins +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +lstshf EQU $028E ;Last Pattern SHIFT/CTRL/Logo Keypress +keylog EQU $028F ;Vector to Keyboard Table Setup Routine +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress +autodn EQU $0292 ;Flag: Screen Scroll Enabled +m51ctr EQU $0293 ;RS-232: Mock 6551 Control Register +m51cdr EQU $0294 ;RS-232: Mock 6551 Command Register +m51adj EQU $0295 ;RS-232: Non-Standard Bit Timing (Not Implemented) +rsstat EQU $0297 ;RS-232: Mock 6551 Status Register +bitnum EQU $0298 ;RS-232: Number of Bits Left to be Sent/Received +baudof EQU $0299 ;RS-232: Time Required to Send a Bit +ridbe EQU $029B ;RS-232: Index to End of Receive Buffer +ridbs EQU $029C ;RS-232: Index to Start of Receive Buffer +rodbs EQU $029D ;RS-232: Index to Start of Transmit Buffer +rodbe EQU $029E ;RS-232: Index to End of Transmit Buffer +irqtmp EQU $029F ;Save Area for IRQ Vector During Cassette I/O +enabl EQU $02A1 ;RS-232 Interrupts Enabled +; EQU $02A2 ;CIA #1 Control Register B Activity During Cassette I/O +; EQU $02A3 ;Save Area for CIA #1 Interrupt Control Register +; EQU $02A4 ;Save Area for CIA #1 Control Register A +; EQU $02A5 ;Temporary Index to Next Line for Screen Scrolling +; EQU $02A6 ;PAL/NTSC Flag +; EQU $02A7 ;Unused +; EQU $02C0 ;Sprite 11 + +;BASIC Indirect Vector Table +ierror EQU $0300 ;Vector to Print BASIC Error Message Routine +imain EQU $0302 ;Vector to Main BASIC Program Loop +icrnch EQU $0304 ;Vector to Crunch ASCII Keyword into Tokens +iqplop EQU $0306 ;Vector to List BASIC Token as ASCII Text +igone EQU $0308 ;Vector to Execute Next BASIC Token +ieval EQU $030A ;Vector to Evaluate Single-Term Arithmetic Expression + +;Register Storage Area +sareg EQU $030C ;Storage Area for .A Register (Accumulator) +sxreg EQU $030D ;Storage Area for .X Index Register +syreg EQU $030E ;Storage Area for .Y Index Register +spreg EQU $030F ;Storage Area for .P (Status) Register + +;Miscellaneous Vectors +usrpok EQU $0310 ;JMP Instruction for User Function +usradd EQU $0311 ;Address of USR Routine +; EQU $0313 ;Unused +cinv EQU $0314 ;Vector to IRQ Interrupt Routine +cbinv EQU $0316 ;Vector: BRK Instruction Interrupt +nminv EQU $0318 ;Vector: Non-Maskabke Interrupt + +;Kernal Indirect Vectors +iopen EQU $031A ;Vector to Kernal OPEN Routine +iclose EQU $031C ;Vector to Kernal CLOSE Routine +ichkin EQU $031E ;Vector to Kernal CHKIN Routine +ickout EQU $0320 ;Vector to Kernal CKOUT Routine +iclrch EQU $0322 ;Vector to Kernal CLRCHN Routine +ibasin EQU $0324 ;Vector to Kernal CHRIN Routine +ibsout EQU $0326 ;Vector to Kernal CHROUT Routine +istop EQU $0328 ;Vector to Kernal STOP Routine +igetin EQU $032A ;Vector to Kernal GETIN Routine +iclall EQU $032C ;Vector to Kernal CLALL Routine +usrcmd EQU $032E ;Vector to User Defined Command (Unused) +iload EQU $0330 ;Vector to Kernal LOAD Routine +isave EQU $0332 ;Vector to Kernal SAVE Routine + +; $0334 ;Unused +tbuffer EQU $033C ;Cassette I/O Buffer +; $03FC ;Unused + +vicscn EQU $0400 ;Video Screen Memory Area +; $07F8 ;Sprite Shape Data Pointers +; $0800 ;BASIC Program Text +; $8000 ;Autostart ROM Cartridge + +vicclr EQU $D800 ;Color RAM + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start Directly Above Stack +basic: DC $0C, $10 ; Pointer to Next Line (4109) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + + JMP main ;Execute Program + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Read Character from Console + + +;Wait for Character from Console +getkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/pointer.a02 b/include/pointer.a02 new file mode 100644 index 0000000..88df46f --- /dev/null +++ b/include/pointer.a02 @@ -0,0 +1,111 @@ +;C02 library pointer.h02 assembly language subroutines +;Requires External Zero Page Variables PTRLO, PTRHI, SRCLO, SRCHI +;External Routines MSETSRC + +;ptrset(&a) - Set Pointer Address +;Args: X,Y = Address +;Sets: PTRLO, PTRHI = Pointer +PTRSET: STX PTRLO ;Save Block Start Low Byte + STY PTRHI ;Save Block Start High Byte + RTS + +;ptrcmp(&a) - Compare Pointer to Address +;Requires: PTRLO, PTRHI - Pointer +;Args: X,Y = Address to Compare Against +;Affects N,Z +;Returns A=$01 and C=? if Pointer > Address +; A=$00 and Z=1, C=? if Pointer = Address +; A=$FF and C=? if Pointer < Address +PTRCMP: CPY PTRHI ;Compare High Bytes + BCC PTRCMN ;If Pointer > Address, Return 1 + BNE PTRCMF ;If Pointer < Address Return 1 + CPX PTRLO ;Compare Low Byte + BCC PTRCMN ;If Pointer > Address, Return 1 + BNE PTRCMF ;If Pointer < Address Return 1 +PTRCMZ: LDA #$00 ;Return 0 + RTS +PTRCMN: LDA #$01 ;Return 1 + RTS +PTRCMF: LDA #$FF ;Return 255 + RTS + +;ptrget() - Read Byte from Pointer Address +; and Increment Pointer +;Sets: PTRLO, PTRSHI = New pointer address +;Returns: A = Byte at pointer address +;Affects: Y, N, Z +PTRGET: LDY #0 ;Set Offset to 0 + LDA (PTRLO),Y ;Load Value at Pointer + +;ptrinc() - Increment Pointer Address +;Sets: PTRLO, PTRSHI = New pointer address +;Affects: N, Z +PTRINC: INC PTRLO ;Increment Pointer Low Byte + BNE PTRRET ;If Zero + INC PTRHI ; Increment Pointer High Byte +PTRRET: RTS ;Return from function + +;ptrput() - Write Byte from Pointer Address +; and Increment Pointer +;Args: A = Byte to write +;Sets: PTRLO, PTRSHI = New pointer address +;Affects: Y, N, Z +PTRPUT: LDY #0 ;Set Offset to 0 + STA (PTRLO),Y ;Load Value at Pointer + JMP PTRINC ;Increment Pointer + +;ptrdec() - Decrement Pointer Address +;Sets: PTRLO, PTRSHI = New pointer address +;Affects: Y, N, Z +PTRDEC: LDY PTRLO ;Get Pointer Low Byter + BNE PTRDEL ;If Zero + DEC PTRHI ; Deccrement Pointer High Byte +PTRDEL: DEC PTRLO ;Decrement Pointer Low Byte + RTS ;Return from function + +;ptradd() - Add Offset to Pointer +;Args: A = Number of bytes to add +;Sets: PTRLO, PTRSHI = New pointer address +;Affects: A, N, Z +PTRADD: CLC ;Add Offset to Low Byte + ADC PTRLO + STA PTRLO ;And Save It + BCC PTRRET ;If Carry + INC PTRHI ; Increment High Byte + RTS + +;ptrsub() - Subtract Offset from Pointer +;Args: A = Number of bytes to subtract +;Sets: PTRLO, PTRSHI = New pointer address +;Affects: A, N, Z +PTRSUB: STA TEMP0 ;Save Offset + LDA PTRLO ;Get Pointer Low Byte + SEC ;Subtract Offset + SBC TEMP0 ; + STA PTRLO ;And Save New Low Byte + BCS PTRRET ;If Borrow + DEC PTRHI ; Decrement High Byte + RTS + +;ptrsav(&a) - Save Pointer Address +;Args: X,Y = Address of Array to Save Pointer in +;Sets: SRCLO, SRCHI = Address of Array +PTRSAV: JSR SETSRC ;Save Address & Initialize Y Index + LDA PTRLO ;Get Pointer Low Byte + STA (SRCLO),Y ;Store In First Byte of Array\ + INY ;Increment Index + LDA PTRHI ;Get Pointer High Byte + STA (SRCLO),Y ;Store In Second Byte of Array + RTS + +;ptrrst(&a) - Restore Pointer Address +;Args: X,Y = Address of Array to Restore Address +;Sets: SRCLO, SRCHI = Address of Array +; PTRLO, PRTHI = Pointer Value Stores in Array +PTRRST: JSR SETSRC ;Save Address & Initialize Y Index + LDA (SRCLO),Y ;Get First Byte of Array + STA PTRLO ;Store in Pointer Low Byte + INY ;Increment Index + LDA (SRCLO),Y ;Get Second Byte of Array + STA PTRHI ;Store in Pointer High Byte + RTS diff --git a/include/pointer.h02 b/include/pointer.h02 new file mode 100644 index 0000000..ef34d89 --- /dev/null +++ b/include/pointer.h02 @@ -0,0 +1,47 @@ +/**************************************************** + * pointer - Pointer Manipulation Functions for C02 * + ****************************************************/ + +/* Set Pointer Address * + * Args: &a - Address */ +void ptrset(); + +/* Write byte to pointer address * + * and increment pointer * + * Args: b - Byte to write * / +void ptrput(); + +/* Read byte from pointer address * + * and increment pointer * + * Returns: Byte read from pointer */ +char ptrget(); + +/* Increment Pointer */ +void ptrinc(); + +/* Decrement Pointer */ +void ptrdec(); + +/* Add Offset to Pointer * + * Args: n - Number of bytes to add * / +void ptradd(); + +/* Subtract Offset from Pointer * + * Args: n - Number of bytes to subtract * / +void ptrsub(); + +/* Compare Pointer to Address * + * Args: &a - Address to compare against * + * Returns: Result of comparison * + * -1 = Pointer < Address * + * 0 = Pointer = Address * + * 1 = Pointer > Address */ +void ptrcmp(); + +/* Save Pointer Value * + * Args: &a - Address to save pointer to */ +void ptrsav(); + +/* Restore Pointer Value * + * Args: &a - Address to restore pointer from */ +void ptrrst(); diff --git a/include/py65.a02 b/include/py65.a02 new file mode 100644 index 0000000..6990bea --- /dev/null +++ b/include/py65.a02 @@ -0,0 +1,98 @@ +; py65mon program initialization code for c02 programs + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $1B ;Escape/Stop Key (Escape) +RTNKEY EQU $0D ;Return/Enter Key (Carriage Return) + +;Zero Page Locations +SRCLO EQU $30 ;Source String Pointer (stdio.a02) +SRCHI EQU $31 +DSTLO EQU $32 ;Destination String Pointer (string.a02) +DSTHI EQU $33 +BLKLO EQU $34 ;Block Segment Pointer (block.a02) +BLKHI EQU $35 + + +RDSEED EQU $3E ;Pseudo-RANDOM Seed +RANDOM EQU $3F ;Pseudo-RANDOM Number Storage +TEMP0 EQU $40 ;Temporary Storage +TEMP1 EQU $41 +TEMP2 EQU $42 +BLKSLO EQU $4A ;Block Start Address +BLKSHI EQU $4B +BLKELO EQU $4C ;Block End Address +BLKEHI EQU $4D +BLKLEN EQU $4E ;Block Segment Length + +;Memory Mapped I/O +PUTC EQU $F001 ;Write Character to Console +GETC EQU $F004 ;Read Character from Console + + ORG $0200 ;START Directly Above Stack + +START: JMP MAIN ;Execute Program + +;Poll Character from Keyboard +PLKEY: INC RDSEED ;Cycle the RANDOM Seed (if not provided by system) + LDA GETC ;Read Character from Console + RTS + +;Read Character from Console +GETKEY ;Same As RDKEY + +;Wait for Character from Console +RDKEY: JSR PLKEY ;Read Character from Console + BEQ RDKEY ; Loop if None Received + RTS + +;Delete Previous Character +DELCHR: LDA #$08 ;Load Backspace into Accumulator + JSR PRCHR ; and Print it + LDA #$20 ;Load Space into Accumulater + JSR PRCHR ; and Print it + LDA #$08 ;Load Backspace into Accumulator + JMP PRCHR ; and Print it + +;Advance Character to Next line +NEWLIN: LDA #$0D ;Load C/R into Accumulator + JSR PRCHR ; and Print it + LDA #$0A ;Load L/F into Accumulater + ; and fall into PRCHR + +;Print Character to Console +PRCHR: STA PUTC ;Write Character to Console + RTS + +EXIT: BRK ;Return to Monitor + +;Print Byte as Two-Digit Hex Number to Console +PRBYTE: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR PRHEX ; and Print it + PLA ;Restore Accumulator + ; and fall into PRHEX + +;Print Low Nybble as Hex Digit to Console +PRHEX: AND #$0F ;Strip High Nybb + SED ;Set Decimal Flag for + CLC ; Addition Wizardry + ADC #$90 ;Convert to $90-$99,$00-$05 + ADC #$40 ;Convert to $30-$39,$41-$46 + CLD ;Clear Decimal Flag + JMP PRCHR ;Print Hex Digit and Return + +;Initialize Destination String Pointer and Index +SETDST: STX DSTLO ;Save Destination String Pointer + STY DSTHI + RTS + +;Initialize Source String Pointer and Index +SETSRC: STX SRCLO ;Save Source String Pointer + STY SRCHI + LDY #$00 ;Initialize Index Into String + RTS + diff --git a/include/py65.h02 b/include/py65.h02 new file mode 100644 index 0000000..5b4a688 --- /dev/null +++ b/include/py65.h02 @@ -0,0 +1,26 @@ +/* py65mon Header File */ + +//System Pointer Variables +char srclo,srchi; //Source String Pointer for Library Functions +char dstlo,dsthi; //Destination String Pointer for Library Functions +char blklo,blkhi; //Block Segment Pointer + +//System Variables +char blkslo, blkshi; //Block Start Address +char blkelo, blkehi; //Block End Address +char blklen; //Block Segment Length +char temp0, temp1, temp2; //Temporary Variables + +//Memory Mapped I/O +char putc; //Write Character to Console +char getc; //Read Character from Console + +//System Subroutines +char plkey(); //Poll Console for character +char rdkey(); //Wait for character from Console +char getkey(); //Read ASCII character from Console +void newlin(); //Advance cursor to beginning of next line +void prchr(); //Print ASCII character to Console +void prbyte(); //Print Accumulator as Hexadadecimal number +void prhex(); //Print Low Nybble of Accumulator as Hex Digit + diff --git a/include/py65.txt b/include/py65.txt new file mode 100644 index 0000000..10a573e --- /dev/null +++ b/include/py65.txt @@ -0,0 +1,43 @@ +C02 Header File for py65mon + +At the beginning of the program use the directive + + #include + +This must be the first include directive. + +Defined zero-page memory locations (variables): + + srclo, srchi Source String Pointer (used by library functions). + dstlo, dsthi Destination String Pointer (used by library functions). + +Defined functions: + + delchr(); Moves cursor one character to the left and + deletes character in that position. + + Note: Writes backspace, space, backspace + via prchr($08), prchr($20), and prchr($08). + + c = getkey(); Waits for keypress and returns ASCII code of + key that was pressed. + + Note: Aliased to rdkey(). + + newlin(); Advances the cursor to the beginning of then + next line. + + Note: Writes carriage return and line feed + via prchr($0D) and prchr($0A). + + + c = rdkey(); Waits for keypress and returns ASCII code of + key that was pressed. + + Note: Continuously reads from memory location + getc until a non-zero value is returned. + + prchr(c); Prints character to screen. + + Note: Writes argument to memory location putc. + diff --git a/include/screen.h02 b/include/screen.h02 new file mode 100644 index 0000000..1004bb2 --- /dev/null +++ b/include/screen.h02 @@ -0,0 +1,55 @@ +/******************************************** + * screen - Screen Control Routines for C02 * + ********************************************/ + +/* Set Background Color * + * Args: color - background color code */ +void bkgclr(); + +/* Clear the Screen */ +void clrscn(); + +/* Move Cursor Down */ +void crsrdn(); + +/* Move Cursor to Top Left of Screen */ +void crsrhm(); + +/* Move Cursor Left */ +void crsrlf(); + +/* Move Cursor Right */ +void crsrrt(); + +/* Move Cursor Up */ +void crsrup(); + +/* Get Character at Current Position * + * Returns: ASCII code of character */ +char curchr(); + +/* Move Cursor to Specified Coordinates * + * Args: column - screen column (0 = left) * + * row - screen line (0 = top) */ +void mvcrsr(); + +/* Get Cursor Horizontal Position * + * Returns: current cursor column */ +char scncol(); + +/* Get Screen Height in Columns * + * Returns: screen height */ +char scnhgt(); + +/* Get Cursor Vertical Position * + * Returns: current cursor row */ +char scnrow(); + +/* Get Screen Width in Columns * + * Returns: screen width */ +char scnwid(); + +/* Set Text Color * + * Args: color - text color code */ +void txtclr(); + diff --git a/include/stdio.a02 b/include/stdio.a02 new file mode 100644 index 0000000..0b28573 --- /dev/null +++ b/include/stdio.a02 @@ -0,0 +1,54 @@ +; C02 library stdio.h02 assembly language subroutines +; Requires external routines GETKEY, prchr, delchr, and NEWLIN +; external zero page locations SRCLO and SRCHI +; and external constants DELKEY, ESCKEY, and RTNKEY +;char getchr() +GETCHR EQU GETKEY ;Alias to external GETKEY routine + +;void putchr(c) +PUTCHR EQU PRCHR ;Alias to external PRCHR Routine + +;char getstr(&s) +GETSTR: JSR SETSRC ;Initialize Source String +GETSTL: JSR GETCHR ;Get Keypress +GETSTD: CMP #DELKEY ;If Delete + BNE GETSTE ;Then + TYA ; If Offset is Zero + BEQ GETSTL ; Get Next Character + DEY ; Else Decrement Offset + JSR DELCHR ; Delete Previous Character + JMP GETSTL ; and Get Next Character +GETSTE: CMP #ESCKEY ;Else If Escape + BNE GETSTC ;Then + LDY #$FF ; Return -1 + BNE GETSTY +GETSTC: CMP #RTNKEY ;Else If Not Carriage Return + BEQ GETSTX + JSR PUTCHR ; Echo Character + STA (SRCLO),Y ; Store Character at offset + INY ; increment offset and + BPL GETSTL ; loop if less than 128 +GETSTX: JSR NEWLIN ;Else Advance Cursor to Next Line + LDA #$00 ; Terminate String + STA (SRCLO),Y ; and +GETSTY: TYA ; Return String Length + RTS + +;char outstr(n, &s) +OUTSTR: LDA #$00 ;Set Start Position to 0 + ;and fall into outsub +;char outsub(n, &s) +OUTSUB: JSR SETSRC ;Initialize Source String + TAY ;Initialize character offset +OUTSUL: LDA (SRCLO),Y ;Read next character in string + BEQ OUTSUX ;If Not 0 + JSR PUTCHR ; Print character at offset, + INY ; increment offset, and + BPL OUTSUL ; loop if less than 128 +OUTSUX: TAY ;Return number of + RTS ; characters printed + +;char putstr(*s) +PUTSTR: JSR OUTSTR ;Write string to screen + JMP NEWLIN ;Call external NEWLINe routine and return + diff --git a/include/stdio.h02 b/include/stdio.h02 new file mode 100644 index 0000000..a4dee45 --- /dev/null +++ b/include/stdio.h02 @@ -0,0 +1,36 @@ +/***************************************** + * stdio - Standard I/O Routines for C02 * + *****************************************/ + +/* Read Character from Keyboard * + * Waits for Keypress * + * Returns: ASCII value of Key */ +char getchr(); + +/* Write Character to Screen * + * Args: c - ASCII character to write */ +void putchr(); + +/* Read String from Keyboard * + * Buffers string until C/R is pressed * + * Args: &s - string read from keyboard * + * Returns: length of string */ +char getstr(); + +/* Write String to Screen * + * Args: &s - string to print from * + * Returns: ending position in string */ +char outstr(); + +/* Write Partial String to Screen * + * Args: n - starting position in string * + * &s - string to print from * + * Returns: ending position in string */ +char outsub(); + +/* Write String to Screen and Move * + * Cursor to Beginning of Next Line * + * Args: &s - string to print to screen * + * Returns: number of characters printed */ +char putstr(); + diff --git a/include/stdlib.a02 b/include/stdlib.a02 new file mode 100644 index 0000000..0bddc1d --- /dev/null +++ b/include/stdlib.a02 @@ -0,0 +1,176 @@ +; C02 library stdlib.h02 assembly language subroutines +; Requires +; external zero page locations SRCLO and srchi +; and external locations RANDOM, RDSEED, TEMP0, TEMP1, and TEMP2. + +;Return ABSolute Value of Accumulator +ABS: CMP #$80 ;If Negative (High Bit Set) + BCC ABSX ; Carry will Already be Set + EOR #$FF ; One's Complement + ADC #$00 ; and Increment (Carry set by CMP) +ABSX: RTS + +;Return Higher of A and Y +;Uses TEMP0 +;Affects A,N,Z,C +MAX: STY TEMP0 ;Save Second Parameter + CMP TEMP0 ;If First Parameter + BCC MAXX ; Greater than Second Parameter + TYA ;Copy Second Parameter into Accumulator +MAXX: RTS + +;Return Lower of A and & +;Uses TEMP0 +;Affects A,N,Z,C +MIN: STY TEMP0 ;Save Second Parameter + CMP TEMP0 ;If First Parameter + BCS MINX ; Less than Second Parameter + TYA ;Copy Second Parameter into Accumulator +MINX: RTS + +;Multiply A times Y +;Uses TEMP0, TEMP1 +;Affects A,N,Z,C +MULT: STA TEMP0 ;Store Multiplicand + STY TEMP1 ;Store Multiplier +;Multiply TEMP0 times TEMP1 +MULTT: LDA #$00 ;Initialize Accumulator + BEQ MULTE ;Enter Loop +MULTA: CLC + ADC TEMP0 ;Add Multiplicand +MULTL: ASL TEMP0 ;Shift Multiplicand Left +MULTE: LSR TEMP1 ;Shift Multiplier Right + BCS MULTA ;If Bit Shifted Out, Add Multiplicand + BNE MULTL ;Loop if Any 1 Bits Left + RTS + +;Divide A by Y +;Used TEMP0,TEMP1 +;Affects A,X,N,Z,C +DIV: STA TEMP0 ;Store Dividend + STY TEMP1 ;Store Divisor +;Divide TEMP0 by TEMP1 +DIVT: LDA #$00 ;Clear Accumulator + LDX #$07 ;Load Loop Counter + CLC +DIVL: ROL TEMP0 ;Shift Bit Out of Dividend + ROL ; into Accumulator + CMP TEMP1 ;If Accumulator + BCC DIVS ; >= Divisor + SBC TEMP1 ;Subtract Divisor +DIVS: DEX ;Decrement Counter + BPL DIVL ; and Loop + ROL TEMP0 ;Shift Result into Dividend + LDA TEMP0 ;Load Result into Accumulator + RTS + +;Generate Pseudo-Random Number between 1 and 255 +;Uses RANDOM (must be non-zero on entry) +;Affects A,N,Z,C +RAND: LDA RANDOM ;Load Last Result + ASL ;Shift the Seed + BCC RANDX ;If a one was shifted out + EOR #$1D ; Twiddle the bite +RANDX: STA RANDOM ;Save the Seed + RTS + +;Seed Pseudo-Random Number Generator +;Uses RDSEED (if A is zero) +;Affects A,N,Z,C +;Sets RANDOM +RANDS: ORA #$00 ;If Passed Value not 0 + BNE RANDX ; Store in Seed and Return + LDA RDSEED ;Load System Generated Seed + BNE RANDX ;If Not 0, Store and Return + ADC #$01 ;Else Add 1 or 2 + BNE RANDX ; then Store and Return + +;Return A Shifted Y Bytes to the Left +;Affects A,Y,N,Z,C +SHIFTL: ASL ;Shift Byte to Left + DEY ;Decrement Counter + BNE SHIFTL ; and Loop if Not 0 + RTS + +;Return A Shifted Y Bytes to the Right +;Affects A,Y,N,Z,C +SHIFTR: LSR ;Shift Byte to Right + DEY ;Decrement Counter + BNE SHIFTL ; and Loop if Not 0 + RTS + +;Convert ASCII to Byte +;Uses TEMP0, TEMP1 +;Affects A,X,Y,N,Z,C +ATOC: JSR SETSRC ;Initialize Source String + STY TEMP0 ;Initialize Result +ATOCL: LDA (SRCLO),Y ;Get Next Character + CMP #$30 ;If Less Than '0' + BCC ATOCX ; Exit + CMP #$3A ;If Greater Than '9' + BCS ATOCX ; Exit + AND #$0F ;Convert to Binary Nybble + STA TEMP1 ; and Save It + LDA TEMP0 ;Load Result + ASL ;Multiply by 5 by + ASL ; Multiplying by 4 + ADC TEMP0 ; And Adding Itself + ASL ;Multiply that by 2 + ADC TEMP1 ;Add Saved Nybble + STA TEMP0 ; and Store Result + INY ;Increment Index + BPL ATOCL ; and Loop +ATOCX: LDA TEMP0 ;Load Result + RTS ;And Return + +;Convert Byte to ASCII +;Uses SRCLO, srchi, TEMP0, TEMP1, TEMP2 +;Affects A,X,Y,N,Z +CTOA: JSR SETSRC ;Initialize Source String + JSR CVBCD ;Convert Accumulator to BCD + ;LDY #$00 ;Set String Offset to 0 + LDA TEMP2 ;Get High Byte + BEQ CTOAL ;If Not Zero + JSR CTOAN ; Convert Low Nybble +CTOAL: LDA TEMP1 ;Get Low Byte + LSR ;Shift High Nybble + LSR ; into Low Nybble + LSR + LSR + BNE CTOA2 ;If Not Zero + CMP TEMP2 ; and High Byte + BEQ CTOA3 ; not Zero +CTOA2: JSR CTOAN ; Convert It +CTOA3: LDA TEMP1 ;Get Low Byte + JSR CTOAN ;and Convert Low Nybble + LDA #$00 + BEQ CTOAX ;Terminate String +CTOAN: AND #$0F ;Strip High Nybble + ORA #$30 ;Convert to ASCII digit +CTOAX: STA (SRCLO),Y ;Store in String + INY ;and Increment Offset + RTS + +;Convert Binary Number in Accumulator to Binary Coded Decimal +;Uses TEMP0 +;Returns BCD in TEMP1,temp and A,X = 0 +CVBCD: STA TEMP0 ;Save Binary Value + LDA #0 ;Clear BCD Bytes + STA TEMP1 + STA TEMP2 + LDX #8 ;Process 8 bits of Binary + SEI ;Disable Interupts + SED ;Set Decimal Mode +CVBCDL: ASL TEMP0 ;Shift High Bit Into Carry + LDA TEMP1 ;Add BCD Low Byte to Itself + ADC TEMP1 ; Plus Bit Shifted out of Binary + STA TEMP1 ; Effectively Multiplying It by 2 + LDA TEMP2 ;Add BCD High Byte to Itself + ADC TEMP2 ; Plus Bit Shifted out of Low Byte + STA TEMP2 ; Effectively Multiplying It by 2 + DEX ;Decrement Counter and + BNE CVBCDL ; Process Next Bit + CLD ;Clear Decimal Mode + CLI ;Enable Interrupts + RTS + diff --git a/include/stdlib.h02 b/include/stdlib.h02 new file mode 100644 index 0000000..b6d26c6 --- /dev/null +++ b/include/stdlib.h02 @@ -0,0 +1,69 @@ +/********************************************* + * stdlib - Standard Library Routines for C02 * + *********************************************/ + +/* Terminate Program Abnormally */ +//void abort(); + +/* Terminate Program Normally */ +//void exit(); + +/* Absolute Value * + * Args: b - Byte to get absolute value of * + * Returns: Absolute value of b */ +char abs(); + +/* Convert ASCII String to Unsigned Byte * + * Args: &s - String to Convert * + * Returns: Numeric value of string */ +char atoc(); + +/* Convert Unsigned Byte to ASCII String * + * Args: c - Unsigned Byte to Convert * + * &s - String to populate */ +void ctoa(); + +/* Divide Unsigned Bytes * + * Args: n - Numerator * + * d - Denominator * + * Returns: Numerator / Denominator */ +char div(); + +/* Maximum of Two Bytes * + * Args: b - First Byte * + * c - Second Byte * + * Returns: Greater of the Two */ +char max(); + +/* Minimum of Two Bytes * + * Args: b - First Byte * + * c - Second Byte * + * Returns: Lesser of the Two */ +char min(); + +/* Multiply Unsigned Bytes * + * Args: d - Multiplicand * + * r - Multiplier * + * Returns: Multiplicand * Multiplier */ +char mult(); + +/* Generate Pseudo-Random Number * + * Returns: Random number between 1 and 255 */ +char rand(); + +/* Shift Byte Left * + * Args: b - Byte to Shift * + * n - Number of Bits to Shift * + * Returns: Shifted Byte */ +char shiftl(); + +/* Shift Byte Right * + * Args: b - Byte to Shift * + * n - Number of Bits to Shift * + * Returns: Shifted Byte */ +char shiftr(); + +/* Seed Pseudo-Random Number Generator * + * Args: n - Seed number */ +void srand(); + diff --git a/include/string.a02 b/include/string.a02 new file mode 100644 index 0000000..33baaad --- /dev/null +++ b/include/string.a02 @@ -0,0 +1,176 @@ +; C02 library string.h02 assembly language subroutines +; Requires external routines SETSRC and SETDST +; Requires the following RAM locations be defined +; external zero page byte pairs SRCLO,SRCHI and DSTLO,DSTHI +; and external bytes TEMP0 and TEMP1 + +;strcmp(&s) - Compare String (to Destination String) +;Requires: DSTLO, DSTHI - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: SRCLO,SRCHI = Pointer to string +;Affects N,Z +;Returns A=$01 and C=1 if Destination > Source +; A=$00 and Z=1, C=1 if Destination = Source +; A=$FF and C=0 if Destination < Source +; Y=Position of first character that differs +STRCMP: JSR SETSRC ;Initialize Source String +STRCML: LDA (DSTLO),Y ;Load Destination Character + CMP (SRCLO),Y ;Compare Against Source Character + BNE STRCMX ;If Equal + ORA (SRCLO),Y ; OR with Source Character + BEQ STRCMR ; If Both are 0, Return 0 + INY ; Increment Offset + BPL STRCML ; and Loop if < 128 +STRCMX: BCC STRCLX ;If Source < Destination, Return $FF & Carry Clear + LDA #$01 ;Else Return 1 and Carry Set +STRCMR: RTS ; + +;strchr(c, &s) - Find First Occurance of Character in String +;Args: A = Character to look for +; X,Y = Pointer to string to search in +;Sets: SRCLO,SRCHI = Pointer to string +; TEMP0 = Character being searched for +;Affects: N,Z +;Returns: A = Position in string, C=1 if found +; A = $FF, C=0 if not found +; Y = Position of last character scanned +STRCHR: JSR SETSRC ;Initialize Source String +STRCHA: STA TEMP0; ;Save Search Character (alternate entry point) +STRCHL: LDA (SRCLO),Y ;Get Next Character + BEQ STRCLC ;If NUL, Return $FF and Carry Clear + CMP TEMP0 ;Compare Character + BEQ STRLEX ;If Found, Return Index + INY ;Increment Counter and Loop if < 128 + BPL STRCHL ;Else Return $FF and Carry Clear +STRCLC: CLC ;Clear Carry +STRCLX: LDA #$FF ;Load -1 into Accumulater + RTS ;and Return + +;strlen(&s) - Return Length of String +;Args: X,Y - Pointer to string +;Sets: SRCLO,SRCHI = Pointer to source string +;Affects: N,Z +;Returns: A,Y = Length of string +STRLEN: JSR SETSRC ;Initialize Source String +STRLEL: LDA (SRCLO),Y ;Get Next Character + BEQ STRLEX ;If <> NUL + INY ; Increment Index + BPL STRLEL ; and Loop if < 128 +STRLEX: TYA ;Transfer Index to Accumulator + RTS ;and Return + +;strdst(&s) - Set Destination String +; Called before strcat(), strcmp(), strcpy(), strstr() +;Args: X,Y = Pointer to destination string +;Sets: SRCLO,SRCHI = Pointer to destination string +;Affects: N,Z +STRDST EQU SETDST ;Aliased to System Header function + +;strcat(&s) Concatenate String (to Destination String) +;Requires: DSTLO, DSTHI - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: SRCLO,SRCHI = Pointer to source string +; TEMP0 = Length of source prior to concatenation +;Affects: C,N,Z +;Returns: A,Y = Total length of concatenated string +STRCAT: JSR SETSRC ;Initialize Source String +STRCAL: LDA (DSTLO),Y ;Find end of Destination String + BEQ STRCAX ; + INY ; + BPL STRCAL ; +STRCAX: STY TEMP0 ;Subtract Destination String Length + LDA SRCLO ; from Source String Pointer + SEC + SBC TEMP0 + STA SRCLO + LDA SRCHI + SBC #$00 + STA SRCHI + JMP STRCPL ;Execute String Copy + +;strcpy(&s) - Copy String (to Destination String) +;Requires: DSTLO, DSTHI - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: SRCLO,SRCHI = Pointer to source string +;Affects: N,Z +;Returns: A,Y = Number of characters copies +STRCPY: JSR SETSRC ;Initialize Source String +STRCPL: LDA (SRCLO),Y ;Get Character from Source String + STA (DSTLO),Y ;Copy to Destination String + BEQ STRCPX ;If <> NUL + INY ; Increment Index + BPL STRCPL ; and Loop if < 128 +STRCPX: TYA ;Transfer Index to Accumulator + RTS ;and Return + +;strcut(n, &s) - Copy from Position n to End of Source (into Destination) +;Requires: DSTLO, DSTHI - Pointer to destination string +;Args: A = Starting position in start string +; X,Y = Pointer to source string +;Sets: SRCLO,SRCHI = Pointer to specified position in source string +;Affects: N,Z +;Returns: A,Y = Length of copied string +STRCUT: JSR SETSRC ;Initialize Source String + CLC + ADC SRCLO ;Move Source Pointer + STA SRCLO ; to Specified Position in String + BCC STRCPL + INC SRCHI + JMP STRCPL ;and Jump Into String Copy Loop + +;strstr(&s) - Search for String (in Destination String) +;Requires: DSTLO, DSTHI - Pointer to destination string +;Args: X,Y = Pointer to search string +;Sets: DSTLO,DSTHI = Pointer to position in source string +; End of string if not found +; SRCLO,SRCHI = Pointer to source string +; TEMP0 = Last position checked in destination string +;Affects: N,Z +;Returns: A = Position, C=1 if found +; A = $FF, C=0 if not found +; Y = Last position checked in source string +STRSTR: JSR SETSRC ;Initialize Source String + STY TEMP0 ;Initialize Position +STRSTL: LDY #$00; ;Initialize Compare Offset + LDA (DSTLO),Y ;Get Start Character in Destination + BEQ STRCLC ;If NUL return $FF and Carry Clear + JSR STRCML ;Jump into Compare Loop + BEQ STRSTX ;If Not Equal + BMI STRSTN ; If Source is Greater + LDA (SRCLO),Y ; If at End of Source String + BEQ STRSTX ; Return Current Position +STRSTN: INC TEMP0 ; Else Increment Position + BMI STRCLC ; If > 127 return $FF and Carry Clear + INC DSTLO ; Increment Source Pointer + BNE STRSTL + INC DSTHI ; If not End of Memory + BNE STRSTL ; Loop + BEQ STRCLC ; Else return $FF and Carry Clear +STRSTX: SEC ;Else Set Carry + LDA TEMP0 ; Load Position + RTS ; and Return + +;strrch(c, &s) - Find Last Occurance Character in String +;Args: A = Character to look for +; X,Y = Pointer to string to search in +;Sets: SRCLO,SRCHI = Pointer to string +; TEMP0 = Character being searched for +; TEMP1 = Position of character +;Affects: Y,C,N,Z +;Returns: A = Position of last occurance in string +; A = $FF if not found +; Y = Position of last character scanned +STRRCH: JSR SETSRC ;Initialize Source String + STA TEMP0; ;Save Search Character (alternate entry point) + LDA #$FF ;Initialize Position + STA TEMP1 ; to 255 +STRRCL: LDA (SRCLO),Y ;Get Next Character + BEQ STRRCX ;If NUL, Exit with Position + CMP TEMP0 ;Compare Character + BNE STRRCS ;If Found + STY TEMP1 ; Store Counter +STRRCS: INY ;Increment Counter + BPL STRRCL ; and Loop if < 128 +STRRCX: LDA TEMP1 ;Load Position Accumulater + RTS ; and Return + diff --git a/include/string.h02 b/include/string.h02 new file mode 100644 index 0000000..167f305 --- /dev/null +++ b/include/string.h02 @@ -0,0 +1,58 @@ +/********************************************* + * string - String Handling Routines for C02 * + *********************************************/ + +/* Find Charaacter in String * + * Args: c - Character to find * + * &s - String to search * + * Returns: c in s * + * $FF if not found */ +char strchr(); + +/* Get Length of String * + * Args: s - string * + * Returns: Length of string */ +char strlen(); + +/* Sets Destination String for * + * functions that use two strings * + * Args: &s - Destination string */ +void strdst(); + +/* Concatenate Destination String to Source String * + * Args: &s - Source string * + * Sets: Destination string specified by strdst() * + * Returns: Total Length of concatenated string */ +char strcat(); + +/* Compare Destination String against Source String * + * Args: &s - Source string * + * Uses: Destination string specified by strdst() * + * Returns: Result of comparison * + * -1 = Destination < Source * + * 0 = Destination = Source * + * 1 = Destination > Source */ +char strcmp(); + +/* Copy Source String to Destination String * + * Args: &s - Source string * + * Sets: Destination string specified by strdst() * + * Returns: Number of characters copied */ +char strcpy(); + +/* Copy Part of Source String to Destination String * + * Args: n - Starting point in source string * + * &s - Source string * + * Sets: Destination string specified by strdst() * + * Returns: Number of characters copied */ +char strcut(); + +/* Find String in String * + * Args: &s - String to Find * + * Uses: String to search specified by strdst() * + * Sets: strdst() pointer to position of string * + * End of string if not found * + * Returns: Position of s in Destination string * + * $FF if not found */ +char strstr(); + diff --git a/include/stringx.a02 b/include/stringx.a02 new file mode 100644 index 0000000..e58d016 --- /dev/null +++ b/include/stringx.a02 @@ -0,0 +1,75 @@ +; C02 library stringx.h02 assembly language subroutines +; Requires the subroutines and definitions from string.asm + +;Common Code - Initialize Variables +STRXSI: JSR SETSRC ;Initialize Source String + STY TEMP1 ;Save Destination Pointer + LDX #0 ;Set End of String Flag + RTS ; and Return + +;Common Code - Check Next Character in Destination String +STRXSL: LDY TEMP1 + LDA (DSTLO),Y ;Get Next Character in Destination String + BEQ STRXST ;If NUL, Return from Calling Routine + LDY #0 ;Initialize Source Pointer + JMP STRCHA ;Search for Character in Source and Return + +;Common Code - Exit with Result +STRXST: PLA ;Pop Return Address Off Stack + PLA ; to force exit from Calling Routine +STRXSX: TXA ;Load End of String Flag into Accumulator + BNE STRXSR ;If 0 Then +STRXSP: LDA TEMP1 ; Load Character Position into Accumulator +STRXSR: RTS ;Return + +;strpbk(&s) - Return position of first character in Destination +; also contained in Source +;Requires: DSTLO, dsthi - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: srclo,srchi = Pointer to source string +; TEMP1 = Position of last character checked +;Uses: TEMP0 +;Affects: C,X,Y +;Returns: A = Position of first character that matches +; $FF if no characters matched +STRPBK: JSR STRXSI ;Initialize Variables + DEX ;Change End of String Flag to $FF + BNE STRBRL ;Jump into strbrk subroutine + +;strbrk(&s) - Return length of Destination with characters +; not contained in Source +;Requires: DSTLO, dsthi - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: srclo,srchi = Pointer to source string +; TEMP1 = Return value +;Uses: TEMP0 +;Affects: C,X,Y +;Returns: A = Length of matching string segment +; Z = 1 if no characters matched +; N = 1 if > 127 characters matched +STRCSP: ;Alias to strbrk +STRBRK: JSR STRXSI ;Initialize Variables +STRBRL: JSR STRXSL ;and Search for Character in Source String + BCS STRXSP ;If Not Found + INC TEMP1 ; Increment Destination Pointer + BPL STRBRL ; and Loop if < 128 + BMI STRXSX ;and Return Not Found + +;strspn(&s) - Return length of Destination with characters +; contained in Source +;Requires: DSTLO, dsthi - Pointer to destination string +;Args: X,Y = Pointer to source string +;Sets: srclo,srchi = Pointer to source string +; TEMP1 = Return value +;Uses: TEMP0 +;Affects: C,X,Y +;Returns: A = Length of matching string segment +; Z = 1 if no characters matched +; N = 1 if > 127 characters matched +STRSPN: JSR STRXSI ;Initialize Variables +STRSPL: JSR STRXSL ;and Search for Character in Source String + BCC STRXSP ;If Found + INC TEMP1 ; Increment Destination Pointer + BPL STRSPL ; and Loop if < 128 + BMI STRXSP ;Else Return Position + diff --git a/include/stringx.h02 b/include/stringx.h02 new file mode 100644 index 0000000..54a5dcb --- /dev/null +++ b/include/stringx.h02 @@ -0,0 +1,30 @@ +/******************************************************* + * stringx - Extended String Handling Routines for C02 * + *******************************************************/ + +/* Find Span of Characters not matching String * + * Args: &s - String of characters to match * + * Uses: String to parse specified by strdst() * + * Sets: temp1 - Result * + * Returns: Number of consecutive characters in * + * Destination that are not in Source */ +char strbrk(); +char strcsp(); //Alias + +/* Find Span of Characters matching String * + * Args: &s - String of characters to match * + * Uses: String to parse specified by strdst() * + * Sets: temp1 - Result * + * Returns: Number of consecutive characters in * + * Destination that are also in Source */ +char strspn(); + +/* Find First Character matching String * + * Args: &s - String of characters to match * + * Uses: String to parse specified by strdst() * + * Sets: temp1 - Result * + * Returns: Position of first character in * + * Destination that is also in Source * + * $FF if not found */ +char strpbk(); + diff --git a/include/strptn.a02 b/include/strptn.a02 new file mode 100644 index 0000000..bdf7177 --- /dev/null +++ b/include/strptn.a02 @@ -0,0 +1,83 @@ +;Wildcard String Match Function for C02 + + +;C02 Wrapper for Pattern Matcher Routine +;Args: X,Y = Pointer to Pattern String +;Requires: DSTLO,DSTHI = pointer to null-terminated String +;Calls: SETSRC, PTTRN +;Returns: A=$FF if match + +;Match passed string against pattern pointed to by src +STRPTN: JSR SETSRC ;Initialize source string variables + JSR PTTRN ;Do pattern match + BMI STRPTM ;If string length exceeded + BCS STRPTX ;or no match found +STRPTM: INX ; Change X from $FF to $00 +STRPTX: TXA ;Set Result to TRUE or FALSE + RTS ;and Return + +;Pattern Matcher by Paul Guertin, 30 August 2000 +;from http://6502.org/source/strings/patmatch.htm +; +;Modifications by Curtis F Kaylor, 23 May 2017 +;changed labels to conform to c02 library standards +;moved index storage to memory to allow indirect reference to pattern +;added exit with N=1 if strings exceed 128 characters +; +;Requires: SRCLO,SRCHI = pointer to null-terminated Pattern +; DSTLO,DSTHI = pointer to null-terminated String +;Sets: X - $FF +; TEMP0 - index into pattern +; TEMP1 - index into string +;Uses: 4 bytes of stack for each '*' in pattern +;Affects: A,Y,Z +;Returns: C - 1 if String matches Pattern, otherwise 0 +; N - 1 if String or Pattern longer than 127 characters, otherwise 0 + +PTTRNQ EQU "?" ;Question mark Matches exactly 1 character +PTTRNA EQU "*" ;Matches any number of characters (including 0) + +PTTRN: LDX #$00 ;Initialize pattern pointer to 0 + STX TEMP0 + DEX ;Initialize string pointer to 255 + STX TEMP1 +PTTRNL: LDY TEMP0 + LDA (SRCLO),Y ;Get next pattern character + CMP #PTTRNA ;If it's a '*' + BEQ PTTRNS ; Jump to star match + INC TEMP1 ;Else point to next string character + LDY TEMP1 + CMP #PTTRNQ ;If it's a '?' + BNE PTTRNR ; Replace with string character + LDA (DSTLO),Y ; If End of String + BEQ PTTRNX ; Exit with no match found +PTTRNR: CMP (DSTLO),Y ;If pattern character <> string character + BNE PTTRNX ; Exit with no match found + INC TEMP0 ;Else point to next pattern character + BMI PTTRNX ;If max length exceeded, exit no match + CMP #0 ;If not string terminator + BNE PTTRNL ; Check loop +PTTRNF: RTS ;Else exit with match found + +PTTRNS: INC TEMP0 ;Skip '*' in pattern + LDY TEMP0 + CMP (SRCLO),Y ;If next pattern character is '*' + BEQ PTTRNS ; loop back to skip +PTTRNT: LDA TEMP0 ;Push pointer into pattern + PHA ; onto stack + LDA TEMP1 ;Push pointer into string + PHA ; onto stack + JSR PTTRNL ;Recursive call to match rest of string + PLA ;Pop pointer into string + STA TEMP1 ; off of stack + PLA ;Pop pointer into pattern + STA TEMP0 ; off of stack + BCS PTTRNF ;If rest of string matched, exit with match + INC TEMP1 ;Skip next string character + BMI PTTRNX ;If max length not exceeded + LDY TEMP1 + LDA (DSTLO),Y ;and not string terminator terminator + BNE PTTRNT ; loop to pattern check +PTTRNX: CLC ;Clear carry + RTS ; and return + diff --git a/include/vic20.a02 b/include/vic20.a02 new file mode 100644 index 0000000..1b689b9 --- /dev/null +++ b/include/vic20.a02 @@ -0,0 +1,119 @@ +; c02 Program Initialization Code for Unexpanded VIC-20 + +;ASCII Control Codes Equivalents +CR EQU $0D ;Carriage Return +LF EQU $11 ;Line Feed (Cursor Down) +DEL EQU $14 ;Delete +HT EQU $1D ;Horizontal Tab (Cursor Right) +VT EQU $91 ;Vertical Tab (Cursor Up) +FF EQU $93 ;Form Feed (Clear Screen) +BS EQU $9D ;Backspace (Cursor Left) + +;PETSCII Key Mappings +DELKEY EQU $14 ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +strlo EQU $FB ;String Pointer (stdio.asm) +strhi EQU $FC ;Free Byte for User Programs +usrzp3 EQU $FD ;Free Byte for User Programs +usrzp4 EQU $FE ;Free Byte for User Programs + +;Other RAM Locations +user0 EQU $0310 ;Free Byte for User Programs +user1 EQU $0311 ;Free Byte for User Programs +user2 EQU $0312 ;Free Byte for User Programs +user3 EQU $0313 ;Free Byte for User Programs +user4 EQU $0334 ;Free Byte for User Programs +user5 EQU $0335 ;Free Byte for User Programs +user6 EQU $0336 ;Free Byte for User Programs +user7 EQU $0337 ;Free Byte for User Programs +user8 EQU $0338 ;Free Byte for User Programs +user9 EQU $0339 ;Free Byte for User Programs +user10 EQU $033A ;Free Byte for User Programs +user11 EQU $033B ;Free Byte for User Programs +tbffr EQU $033C ;Cassette I/O Buffer +user12 EQU $03FC ;Free Byte for User Programs +user13 EQU $03FD ;Free Byte for User Programs +user14 EQU $03FE ;Free Byte for User Programs +user15 EQU $03FF ;Free Byte for User Programs + +;Video RAM and ROM +vicscn EQU $1E00 ;Video Screen Memory Area (Unexpanded) +chrrom EQU $8000 ;Character Generator ROM +vicclr EQU $9600 ;Color RAM (Unexpanded) + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start +basic: DC $0C, $10 ; Pointer to Next Line (4108) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + +start: TSX ;Get Stack Pointer + STX user15 ;and Save for Exit + JMP main ;Execute Program + +exit: LDX user15 ;Retrieve Saved Stack Pointer + TXS ;and Restore It + RTS ;Return to BASIC + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Get Character from Keyboard +getkey: + +;Wait for Character from Keyboard +rdkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Delete Previous Character +delchr: LDA #$9D ;Load Cursor Left into Accumulator + JSR prchr ; and Print it + LDA #$14 ;Load Delete into Accumulater + JMP prchr ; and Print it + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + JMP prchr ; and Print it + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/vic20.h02 b/include/vic20.h02 new file mode 100644 index 0000000..ca7ad52 --- /dev/null +++ b/include/vic20.h02 @@ -0,0 +1,19 @@ +/* py65mon Header File */ + +//Zero Page Variables + +//Kernal Routines Memory Mapped I/O +char chrin(); //Input Character to Channel +void chrout(); //Output Character to Channel +char getin(); //Read Character from Keyboard Buffer + + +//System Subroutines +char plkey(); //Poll Console for character +char rdkey(); //Wait for character from Console +char getkey(); //Read ASCII character from Console +void newlin(); //Advance cursor to beginning of next line +void prchr(); //Print ASCII character to Console +void prbyte(); //Print Accumulator as Hexadadecimal number +void prhex(); //Print Low Nybble of Accumulator as Hex Digit + diff --git a/include/vic20/file.a02 b/include/vic20/file.a02 new file mode 100644 index 0000000..0362f9c --- /dev/null +++ b/include/vic20/file.a02 @@ -0,0 +1,155 @@ +; Requires external routines SETSRC and SETDST +; Requires the following RAM locations be defined +; external zero page byte pairs SRCLO,SRCHI and DSTLO,DSTHI +; and external bytes TEMP0 and TEMP1 + +;fsetup(fn, fs, fd) - Set Parameters for fsopen() +;Args: A = Logical file number +; Y = Secondary address (255 for None) +; X = Device 0=Keyboard, 1=Cassette, 2=RS232, 3=Screen +; 4-7=Printers, 8-15=Disks, 31=All Devices +;Affects None +FSETUP EQU SETLFS ;Set up a logical file + +;fsname(n, &s) - Set Filename for Load, Open, Save +;Args: A = Length of filename string +; X,Y = Pointer to string containing filename +;Affects: A,X,Y +;Returns: A = 1,2,3,4,6,240 (see FERROR) + +;fsload(v, &a) - Load Memory from File +;Prereqs: fsetup(), fsname() +;Args: A = Mode 0=Load, 1=Verify +; Y,X = Address to Load File +;Stack: 9 +;Affects: A,X,Y +;Sets: STATUS = 0,4,5,8,9 (see FERROR) +FSLOAD EQU LOAD ;Load RAM from device + +;fssave(v, &a) - Save Memory to File +;Prereqs: fsdst fsetup(), fsname() +;Requires: DSTLO, DSTHI - Start Address +;Args: Y,X = End Address +;Stack: 9 +;Affects: A,X,Y +;Sets: STATUS = 0,4,5,8,9 (see FERROR) +FSSAVE: LDA #SRCLO ;Load Pointer to Start Address + JMP SAVE ;Save memory to device + +;fsopen() - Open +;Prereqs: fsetup(), fsname() +;Affects: A,X,Y +;Sets: STATUS = 1,2,3,4,6,240 (see FERROR) +STRCHR: JSR SETNAM ;Set file name + JMP OPEN ;Open File + +;fopen(n, &s) - Open File with Specified Name +;Not Implemented + +;fclose(fn) - Close File +;Args: A = Logical file number +;Returns: A = 0,240 (see FERROR) +FCLOSE EQU CLOSE ;Close a logical file + +;feof(fn) - Check for End of File +;Args: A = Logical file number +;Affects: A,X +;Returns: A = 0,240 (see FERROR) +FEOF: JSR READST ;Read status word + AND #$C0 ;$40=End of File, $80 End of Tape + BEQ FRTS ;If Not 0 +FERR: LDA #$FF ; Set Generic Error Condition +FRTS: RTS ;Return from Subroutine + +;ferror(fn) - Check for Error +;Args: A = Logical file number +;Affects: A,X +;Returns: A = Error Bit Mask +; Bit Cassette Read Serial Bus I/O Tape Load/Verify +; $01 Write Timeout +; $02 Read Timeout +; $04 Short Block Short Block +; $08 Long Block Long Block +; $10 Read Error Any Mismatch +; $20 Checksum Err Checksum Err +; $40 End of File EOI Line +; $80 End of Tape Device Not Present End of Tape +FERROR EQU READST ;Read status word + +;fflush() - Flush file buffer +; No-Op - Not Needed +FFLUSH: RTS + +;fgetc(fn) - Read character from file +;Args: A = Logical file number +;Stack: 9 +;Affects: A,X +;Returns: A = 0,240 (see FERROR) +FGETC: TAX ;Move logical file number to X register + JSR CHKIN ;Open channel for input + JSR CHRIN ;Get character from input channel + PHA ;Save read character + JSR CLRCHN ;Clear I/O channels + PLA ;Retrieve read Character + RTS + +;fputc(fn) - Write character from file +;Args: A = Logical file number +; Y = Character to Write +;Stack: 9 +;Affects: A,X +;Returns: A = 0,240 (see FERROR) +FPUTC: TAX ;Move logical file number to X register + JSR CHKOUT ;Open channel for input + TYA ;Move character to accumulator +FPUTCH: JSR CHROUT ;Output a character + JMP CLRCHN ;Clear I/O channels and return + +;fgets(fn, &s) - Read string from file +;Requires: DSTLO, DSTHI - Pointer to destination string +;Args: A = Logical file number +; Y,X = Pointer to String +;Stack: 9 +;Affects: X,Y +;Returns: A = Number of bytes read +FGETS: JSR SETDST ;Save string address & initialize pointer + TAX ;Move logical file number to X register + JSR CHKIN ;Open channel for input +FGETSL: JSR CHRIN ;Get character from input channel + PHA ;Save read character + JSR READST ;Read status word + BNE FGETSX ;If Not 0, Exit + PLA ;Retrieve read character + STA SRCLO,Y ;Store character in string + CMP $0D ;If Carriage Return + BEQ FGETSX ; Then Exit + INY ;Increment pointer + BPL FGETSL ;and loop if less than 128 +FGETSX: LDA #$00 ;Terminate String + STA (SRCLO),Y ; +FGETSY: JSR CLRCHN ;Clear I/O channels + TYA ;Return string length + RTS + +;fputs(fn, &s) - Write String to File +;Requires: DSTLO, DSTHI - Pointer to source string +;Args: A = Logical file number +; Y,X = Pointer to String +;Stack: 9 +;Affects: X,Y +;Returns: A = Number of bytes written +FPUTS: JSR SETDST ;Save string address & initialize pointer + TAX ;Move logical file number to X register + JSR CHKIN ;Open channel for input +FPUTSL: LDA SRCLO,Y ;Load next character + PHA ;Save write character + JSR CHROUT ;Write character to output channel + PLA ;Retrieve write character + CMP $0D ;If Carriage Return + BEQ FGETSY ; Then Exit + JSR READST ;Read status word + BNE FGETSY ;If Not 0, Exit + INY ;Increment pointer + BPL FPUTSL ;If less than 128 then loop + BMI FGESTY ;Else exit + diff --git a/include/vic20/screen.a02 b/include/vic20/screen.a02 new file mode 100644 index 0000000..7f88062 --- /dev/null +++ b/include/vic20/screen.a02 @@ -0,0 +1,152 @@ +;Screen Control Assembly Lanuage Routines for C02 + +;Vic Display Colors +BLACK EQU 0 Black +WHITE EQU 1 White +RED EQU 2 Red +CYAN EQU 3 Cyan +MAGNTA EQU 4 Purple +GREEN EQU 5 Green +BLUE EQU 6 Blue +YELLOW EQU 7 Yellow + +;PETSCII Color Codes +CTLBLK EQU 144 Black +CTLWHT EQU 5 White +CTLRED EQU 28 Red +CTLCYN EQU 159 Cyan +CTLPUR EQU 156 Purple +CTLGRN EQU 30 Green +CTLBLU EQU 32 Blue +CTLYLW EQU 158 Yellow + +;PETSCII Screen Control Codes +CLEAR EQU 147 Clear (CLR) +DELETE EQU 20 Delete (DEL) +DOWN EQU 17 Cursor Down +ENTER EQU 13 Return +FN1 EQU 133 Function Key 1 (F1) +FN2 EQU 137 Function Key 2 (F2) +FN3 EQU 134 Function Key 3 (F3) +FN4 EQU 138 Function Key 4 (F4) +FN5 EQU 135 Function Key 5 (F5) +FN6 EQU 139 Function Key 6 (F6) +FN7 EQU 136 Function Key 7 (F7) +FN8 EQU 140 Function Key 8 (F8) +HOME EQU 19 Home +INSERT EQU 148 Insert +LEFT EQU 157 Cursor Left +RIGHT EQU 29 Cursor Left +RVSOFF EQU 146 Reverse Off +RVSON EQU 18 Reverse On +UP EQU 145 Cursor Up + +;PETSCII Box Drawing Characters +BTMLFT EQU 173 Bottom Left Corner +BTMRGT EQU 189 Bottom Right Corner +BTMTEE EQU 177 Bottom to Cetter Tee +CTRCRS EQU 123 Center Cross +HRZLIN EQU 96 Horizontal Line +LFTTEE EQU 171 Left To Center T +RGHTEE EQU 179 Right To Center T +TOPLFT EQU 176 Top Left Corner +TOPRGT EQU 174 Top Right Corner +TOPTEE EQU 178 Top to Center T +VRTLIN EQU 98 Verical Line + +;PETSII Color Table +CLRTBL: DB CTLBLK,CTLWHT,CTLRED,CTLCYN,CTLPUR,CTLGRN,CTLBLU,CTLYLW + +;Set Background Color +;Args: A = Vic Color Code +;Uses: TEMP0 - Temporary Storage +;Affects: A,C,N,Z +BKGCLR: LSR ;Shift Color Code 4 Bits Left + LSR + LSR + LSR + STA TEMP0 ;Save it + LDA $900F ;Read VIC Color Control Register + AND #$15 ;Strip Existing Backround Color + ORA ;Add in Background Color + STA $900F ;Write back to VIC Chip + RTS + +;Set Text Color +;Args: A = Vic color code +;Affects: A,X,C,N,Z +TXTCLR: TAX ;Transfer Color Code to Index + LDA CLRTBL,X ;Load PETSCII Color Control Character + JMP PRCHR ;Print Character and Return + +;Clear Screen +;Affects A,C,N,Z +CLRSCN: LDA #CLEAR ;Load Clear Screen Character + JMP PRCHR ;Print it and Return + +;Move Cursor Down +;Affects A,C,N,Z +CRSRDN: LDA #DOWN ;Load Cursor Down Character + JMP PRCHR ;Print it and Return + +;Move Cursor To Home Position +;Affects A,C,N,Z +CRSRHM: LDA #HOME ;Load Cursor Home Character + JMP PRCHR ;Print it and Return + +;Move Cursor Left +;Affects A,C,N,Z +CRSRLF: LDA #LEFT ;Load Cursor Left Character + JMP PRCHR ;Print it and Return + +;Move Cursor Right +;Affects A,C,N,Z +CRSRRT: LDA #RIGHT ;Load Cursor Left Character + JMP PRCHR ;Print it and Return + +;Move Cursor Up +;Affects A,C,N,Z +CRSRUP: LDA #UP ;Load Cursor Left Character + JMP PRCHR ;Print it and Return + +;Move Cursor to Specified Coordinates +;Args: A = screen column (0 = top) +; Y = screen line (0 = left) +MVCRSR: TAX ;Transfer Column to X Register + CLC ;Clear Carry Flag + JMP $FFF0 ;Call PLOT Kernal Routine and Return + +;Get Cursor Horizontal Position +;Returns: A = current cursor column +; Y = current cursor row +; X = current cursor column +SCNCOL: SEC ;Set Carry Flag + JSR $FFF0 ;Call PLOT Kernal Routine + TXA ;Transfer Column to Accumulator + RTS + +;Get Screen Height in Rows +;Returns: A = height of screen in rows +; Y = height of screen in rows +; X = width of screen in columns +SCNGHT: JSR $FFED ;Call SCREEN Kernal Routine + TYA ;Transfer Height to Accumulator + RTS + +;Get Cursor Vertical Position +;Returns: A = current cursor row +; Y = current cursor row +; X = current cursor column +SCNROW: SEC ;Set Carry Flag + JSR $FFF0 ;Call PLOT Kernal Routine + TYA ;Transfer Row to Accumulator + RTS + +;Get Screen Width in Rows +;Returns: A = width of screen in columns +; Y = height of screen in rows +; X = width of screen in columns +SCNWID: JSR $FFED ;Call SCREEN Kernal Routine + TXA ;Transfer Width to Accumulator + RTS + diff --git a/include/vic20all.a02 b/include/vic20all.a02 new file mode 100644 index 0000000..9b36ff6 --- /dev/null +++ b/include/vic20all.a02 @@ -0,0 +1,242 @@ +; c02 Program Initialization Code for Unexpanded VIC-20 + +;PETSCII Control Codes +WHT EQU $05 ;White +CR EQU $0D ;Carriage Return +LWRCS EQU $0E ;Switch to Lower Case +LF EQU $11 ;Cursor Down (Line Feed) +RVSON EQU $12 ;Reverse On +HOME EQU $13 ;Cursor Home +DEL EQU $14 ;Delete +RED EQU $1C ;Red +HT EQU $1D ;Cursor Right (Horizontal Tab) +GRN EQU $1E ;Green +BLU EQU $1F ;Blue +UPRCS EQU $8E ;Switch to Upper Case +BLK EQU $90 ;Black +VT EQU $91 ;Cursor Up (Vertical Tab) +RVSOFF EQU $92 ;Reverse Off +CLR EQU $93 ;Clear Screen +INST EQU $94 ;Insert +PUR EQU $9C ;Purple +BS EQU $9D ;Cursor Left (Backspace) +YEL EQU $9E ;Yellow +CYN EQU $9F ;Cyan + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +usradd EQU $01 ;Address of USR Routine +linnum EQU $14 ;Integer Line Number Value +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +status EQU $90 ;Kernal I/O Status Word +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +time EQU $A0 ;Software Jiffy Clock +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +pntc EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +usrzp1 EQU $FB ;Free Byte for User Programs +usrzp2 EQU $FC ;Free Byte for User Programs +usrzp3 EQU $FD ;Free Byte for User Programs +usrzp4 EQU $FE ;Free Byte for User Programs + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +color EQU $0286 ;Current Foreground Color Text +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress + +user0 EQU $0310 ;Free Byte for User Programs +user1 EQU $0311 ;Free Byte for User Programs +user2 EQU $0312 ;Free Byte for User Programs +user3 EQU $0313 ;Free Byte for User Programs +user4 EQU $0334 ;Free Byte for User Programs +user5 EQU $0335 ;Free Byte for User Programs +user6 EQU $0336 ;Free Byte for User Programs +user7 EQU $0337 ;Free Byte for User Programs +user8 EQU $0338 ;Free Byte for User Programs +user9 EQU $0339 ;Free Byte for User Programs +user10 EQU $033A ;Free Byte for User Programs +user11 EQU $033B ;Free Byte for User Programs +tbffr EQU $033C ;Cassette I/O Buffer +user12 EQU $03FC ;Free Byte for User Programs +user13 EQU $03FD ;Free Byte for User Programs +user14 EQU $03FE ;Free Byte for User Programs +user15 EQU $03FF ;Free Byte for User Programs + +;Basic and Screen RAM +bas3k EQU $0400 ;Basic Start (3K Expansion Area) +basunx EQU $1000 ;Basic Start (Unexpanded)/Video Screen +bas8k EQU $1200 ;Basic Start (3K Expansion Area) +vicscx EQU $1000 ;Video Screen Memory Area (8K+ Expansion) +vicscu EQU $1E00 ;Video Screen Memory Area (Unexpanded) +exblk1 EQU $2000 ;8K Expansion RAM/ROM Block 1 +exblk2 EQU $4000 ;8K Expansion RAM/ROM Block 2 +exblk3 EQU $6000 ;8K Expansion RAM/ROM Block 3 + +chrrom EQU $8000 ;Character Generator ROM + +vicclx EQU $9400 ;Color RAM (8K+ Expansion) +vicclu EQU $9600 ;Color RAM (Unexpanded) + +;VIC Chip Registers +vicsch EQU $9000 ;Interlace Mode + Horizontal Screen Origin +vicscv EQU $9001 ;Vertical Screen Origin +viccol EQU $9002 ;Screen Memory Location + Number of Video Columns +vicrow EQU $9003 ;Raster Value + Number of Video Rows + Character Size +vicrst EQU $9004 ;Raster Value +vicloc EQU $9005 ;Screen Memory Location + Character Memory Location +viclph EQU $9006 ;Light Pen - Horizontal +viclpv EQU $9007 ;Light Pen - Vertical +vicpd1 EQU $9008 ;Paddle 1 +vicpd2 EQU $9009 ;Paddle 2 +vicbsf EQU $900A ;Bass Sound Switch and Frequency +vicasf EQU $900B ;Alto Sound Switch and Frequency +vicssf EQU $900C ;Soprano Sound Switch and Frequency +vicnsf EQU $900D ;Noise Switch and Frequency +vicavl EQU $900E ;Auxillary Color + Sound Volume +vicclr EQU $900F ;Screen Color + Reverse Mode + Border Color + +;VIA #1 (NMI) +v1orb EQU $9110 ;Port B - User Port +v1ora EQU $9111 ;Port A +v1ddrb EQU $9112 ;Data Direction Register B +v1ddra EQU $9113 ;Data Direction Register A +v1t1l EQU $9114 ;Timer #1 Low +v1t1h EQU $9115 ;Timer #1 High +v1lt1l EQU $9116 ;Load Timer #1 Low +v1lt1h EQU $9117 ;Load Timer #1 High +v1t2l EQU $9118 ;Timer #1 Low +v1t2h EQU $9119 ;Timer #1 High +v1sr EQU $911A ;Shift Register +v1acr EQU $911B ;Auxillary Control Register +v1pcr EQU $911C ;Peripheral Control Register +v1ifr EQU $911D ;Interrupt Flag Register +v1ier EQU $911E ;Interrupt Enable Register +v1oran EQU $911F ;Port A (No Handshake) + +;VIA #2 (IRQ) +v2orb EQU $9210 ;Port B +v2ora EQU $9211 ;Port A +v2ddrb EQU $9212 ;Data Direction Register B +v2ddra EQU $9213 ;Data Direction Register A +v2t1l EQU $9214 ;Timer #1 Low +v2t1h EQU $9215 ;Timer #1 High +v2lt1l EQU $9216 ;Load Timer #1 Low +v2lt1h EQU $9217 ;Load Timer #1 High +v2t2l EQU $9218 ;Timer #1 Low +v2t2h EQU $9219 ;Timer #1 High +v2sr EQU $921A ;Shift Register +v2acr EQU $921B ;Auxillary Control Register +v2pcr EQU $921C ;Peripheral Control Register +v2ifr EQU $921D ;Interrupt Flag Register +v2ier EQU $921E ;Interrupt Enable Register +v2oran EQU $921F ;Port A (No Handshake) + +exprom EQU $8000 ;Cartridge Expansion ROM + + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1001 ;Start +basic: DC $0C, $10 ; Pointer to Next Line (4109) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $31, $31 ,$30 ; "4110" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + + JMP main ;Execute Program + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Read Character from Console + + +;Wait for Character from Console +getkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor + diff --git a/include/vic3k.a02 b/include/vic3k.a02 new file mode 100644 index 0000000..904117f --- /dev/null +++ b/include/vic3k.a02 @@ -0,0 +1,96 @@ +;c02 Program Initialization Code for VIC-20 with 3K Expansion + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +RDSEED EQU $A2 ;Software Jiffy Clock (Low Byte) +SRCLO EQU $D1 ;Pointer to Address of Current Screen Line +SRCHI EQU $D2 ;Pointer to Address of Current Screen Line +DSTLO EQU $FB ;Free Byte for User Programs +DSTHI EQU $FC ;Free Byte for User Programs +BLKLO EQU $FD ;Free Byte for User Programs +BLKHI EQU $FE ;Free Byte for User Programs + +USER0 EQU $0310 ;Free Byte for User Programs +USER1 EQU $0311 ;Free Byte for User Programs +USER2 EQU $0312 ;Free Byte for User Programs +USER3 EQU $0313 ;Free Byte for User Programs +USER4 EQU $0334 ;Free Byte for User Programs +USER5 EQU $0335 ;Free Byte for User Programs +USER6 EQU $0336 ;Free Byte for User Programs +BLKSLO EQU $0337 ;Free Byte for User Programs +BLKSHI EQU $0338 ;Free Byte for User Programs +BLKELO EQU $0339 ;Free Byte for User Programs +BLKEHI EQU $033A ;Free Byte for User Programs +STKSAV EQU $033B ;Free Byte for User Programs +TBFFR EQU $033C ;Cassette I/O Buffer +TEMP0 EQU $03FC ;Free Byte for User Programs +TEMP1 EQU $03FD ;Free Byte for User Programs +TEMP2 EQU $03FE ;Free Byte for User Programs +TEMP3 EQU $03FF ;Free Byte for User Programs + +;Video RAM and ROM +VICSCN EQU $1E00 ;Video Screen Memory Area (Unexpanded) +CHRROM EQU $8000 ;Character Generator ROM +VICCLR EQU $9600 ;Color RAM (Unexpanded) + +;Machine Language Basic Stub + ORG $0401 ;Start +BASIC: DC $0C, $04 ; Pointer to Next Line (1036) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $31, $30, $33 ,$38 ; "1038" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + +START: TSX ;Get Stack Pointer + STX STKSAV ;and Save for Exit + JMP main ;Execute Program + +EXIT: LDX STKSAV ;Retrieve Saved Stack Pointer + TXS ;and Restore It + RTS ;Return to BASIC + +;Poll Keyboard for Character +PLKEY EQU $FFE4 ;Aliased to Kernal GETIN Routine + +;Get Character from Keyboard +GETKEY: EQU RDKEY + +;Wait for Character from Keyboard +RDKEY: JSR PLKEY ;Poll Keyboard + BEQ GETKEY ;If No Key, Loop + RTS + +;Delete Previous Character +DELCHR: LDA #DELKEY ;Load Delete Character + JMP PRCHR :Print and Return + +;Advance Character to Next line +NEWLIN: LDA #RTNKEY ;Load C/R into Accumulator + +;Print Character to Console +PRCHR EQU $FFD2 ;Aliased to Kernal CHROUT Routine + +;Print Byte as Two-Digit Hex Number to Console +PRBYTE: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +PRHEX: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC PRHEXC ; + ADC #$06 ; Convert ':' to 'A'... +PRHEXC: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + diff --git a/include/vic8k.a02 b/include/vic8k.a02 new file mode 100644 index 0000000..fba2c9d --- /dev/null +++ b/include/vic8k.a02 @@ -0,0 +1,158 @@ +; c02 Program Initialization Code for Vic-20 with at 8K Expansion + +;System Specific ASCII Key Mappings +DELKEY EQU $7F ;Delete/Backspace Key (Delete) +ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP) +RTNKEY EQU $0D ;Return/Enter Key (RETURN) + +;Zero Page Locations +usradd EQU $01 ;Address of USR Routine +linnum EQU $14 ;Integer Line Number Value +txttab EQU $2B ;Pointer to Start of BASIC Program Text +vartab EQU $2D ;Pointer to Start of BASIC Variable Storage Area +arytab EQU $2F ;Pointer to Start of BASIC Array Storage Area +strend EQU $31 ;Pointer to Start of Free RAM +fretop EQU $33 ;Pointer to Bottom of String Text Storage Area +memsiz EQU $37 ;Pointer to Highest Address Used by BASIC +inpptr EQU $43 ;Pointer to Source of GET, READ, or INPUT Information +facexp EQU $61 ;Floating Point Accumulator #1: Exponent +facho EQU $62 ;Floating Point Accumulator #1: Mantissa +facsgn EQU $66 ;Floating Point Accumulator #1: Sign +fac2 EQU $69 ;Floating Point Accumulator #2 +argexp EQU $69 ;Floating Point Accumulator #2: Exponent +argho EQU $6E ;Floating Point Accumulator #2: Mantissa +argsgn EQU $6F ;Floating Point Accumulator #2: Sign +chrget EQU $73 ;Subroutine: Get Next BASIC Text Character +chrgot EQU $79 ;Entry Point: Get Current BASIC Text Character +txtptr EQU $7A ;Pointer to Current BASIC Text Character +pointb EQU $7C ;Entry Point: Test Character in Accumulator +exit EQU $8A ;RTS at end of CHRGET, CHRGOT, and POINTB Routines +status EQU $90 ;Kernal I/O Status Word +ldtnd EQU $98 ;Number of Open I/O Files, Index to End of File Tables +dfltn EQU $99 ;Default Input Device (Set to 0 for Keyboard) +dflto EQU $9A ;Default Output (CMD) Device (Set to 3 for Screen) +time EQU $A0 ;Software Jiffy Clock +tape1 EQU $B2 ;Pointer: Start of Tape Buffer +fnlen EQU $B7 ;Length of Current Filename +la EQU $B8 ;Current Logical File Number +sa EQU $B9 ;Current Secondary Address +fa EQU $BA ;Current Device Number +fnadr EQU $BB ;Pointer: Current Filename +lste EQU $C5 ;Matrix Coordinate of Last Key Pressed +ndx EQU $C6 ;Number of Characters in Keyboard Buffer +rvs EQU $C7 ;Flag: Print Reverse Characters +sfdx EQU $CB ;Matrix Coordinate of Current Key Pressed +pnt EQU $D1 ;Pointer to Address of Current Screen Line +pntr EQU $D3 ;Cursor Column on Current Line +lnmx EQU $D5 ;Maximum Length of Physical Screen Line +tblx EQU $D6 ;Current Cursor Physical Line Number +insrt EQU $D8 ;Insert Mode (Number of Inserts) +ldtb1 EQU $D9 ;Screen Line Link Table +pntc EQU $F3 ;Pointer to Address of Current Screen Color RAM Location +usrzp1 EQU $FB ;Free Byte for User Programs +usrzp2 EQU $FC ;Free Byte for User Programs +usrzp3 EQU $FD ;Free Byte for User Programs +usrzp4 EQU $FE ;Free Byte for User Programs + +;Basic and Kernal Working Storage +buf EQU $0200 ;BASIC Line Editor Input Buffer +lat EQU $0259 ;Kernal Table of Active Logical File Numbers +fat EQU $0263 ;Kernal Table of Device Numbers for Each Logical File +sat EQU $026D ;Kernal Table of Secondary Addressed for Each Logical File +keyd EQU $0277 ;Keyboard Buffer (Queue) +memstr EQU $0281 ;Pointer: Operating System Start of Memory +memsiz EQU $0283 ;Pointer: Operating System End of Memory +color EQU $0286 ;Current Foreground Color Text +hibase EQU $0288 ;Top Page of Screen Memory +xmax EQU $0289 ;Maximum Keyboard Buffer Size +rptflg EQU $028A ;Flag: Which Key Will Repeat? +kount EQU $028B ;Counter for Timing Delay Between Key Repeats +shflag EQU $028D ;Flag: SHIFT/CTRL/Logo Keypress +mode EQU $0291 ;Flag: Change Character Sets with SHIFT/Logo Keypress + +user0 EQU $0310 ;Free Byte for User Programs +user1 EQU $0311 ;Free Byte for User Programs +user2 EQU $0312 ;Free Byte for User Programs +user3 EQU $0313 ;Free Byte for User Programs +user4 EQU $0334 ;Free Byte for User Programs +user5 EQU $0335 ;Free Byte for User Programs +user6 EQU $0336 ;Free Byte for User Programs +user7 EQU $0337 ;Free Byte for User Programs +user8 EQU $0338 ;Free Byte for User Programs +user9 EQU $0339 ;Free Byte for User Programs +user10 EQU $033A ;Free Byte for User Programs +user11 EQU $033B ;Free Byte for User Programs +tbffr EQU $033C ;Cassette I/O Buffer +user12 EQU $03FC ;Free Byte for User Programs +user13 EQU $03FD ;Free Byte for User Programs +user14 EQU $03FE ;Free Byte for User Programs +user15 EQU $03FF ;Free Byte for User Programs + +;Video RAM and ROM +vicscn EQU $1000 ;Video Screen Memory Area (Unexpanded) +chrrom EQU $8000 ;Character Generator ROM +vicclr EQU $9400 ;Color RAM (Unexpanded) + +;Kernal Routines +chrin EQU $FFCF ;Input Character to Channel +chrout EQU $FFD2 ;Output Character to Channel +getin EQU $FFE4 ;Read Character from Keyboard Buffer + +;Machine Language Basic Stub + ORG $1201 ;Start +basic: DC $0C, $12 ; Pointer to Next Line (4108) + DC $00, $00 ; Line Number (0) + DC $9E ; SYS + DC $20 ; ' ' + DC $34, $36, $32 ,$32 ; "4622" + DC $00 ;End of Line Marker + DC $00, $00 ;End of Basic Program + +start: TSX ;Get Stack Pointer + STX user15 ;and Save for Exit + JMP main ;Execute Program + +exit: LDX user15 ;Retrieve Saved Stack Pointer + TXS ;and Restore It + RTS ;Return to BASIC + +;Poll Keyboard for Character +plkey EQU getin ;Read Character from Keyboard Buffer + +;Get Character from Keyboard +getkey: + +;Wait for Character from Keyboard +rdkey: JSR plkey ;Poll Keyboard + BEQ getkey ;If No Key, Loop + RTS + +;Delete Previous Character +delchr: RTS + +;Advance Character to Next line +newlin: LDA #$0D ;Load C/R into Accumulator + +;Print Character to Console +prchr EQU chrout ; + +;Print Byte as Two-Digit Hex Number to Console +prbyte: PHA ;Save Accumulater + LSR ;Shift Hi Nybble to Low Nybble + LSR + LSR + LSR + JSR prhex ; and Print it + PLA ;Restore Accumulator + ; and fall into prhex + +;Print Low Nybble as Hex Digit to Console +prhex: AND #$0F ;Strip High Nybble + CMP #$0A ;If Low Nybble >= 10 + BCC prhexc ; + ADC #$06 ; Convert ':' to 'A'... +prhexc: ADC #$30 ;Convert to ASCII Character + JMP prchr ;Print Hex Digit and Return + +exit: RTS ;Return to Monitor +